/** * vim: set ts=8 sts=2 sw=2 tw=99 et: * ============================================================================= * SourcePawn JIT SDK * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License, version 3.0, as published by the * Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see . * * As a special exception, AlliedModders LLC gives you permission to link the * code of this program (as well as its derivative works) to "Half-Life 2," the * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software * by the Valve Corporation. You must obey the GNU General Public License in * all respects for all other code used. Additionally, AlliedModders LLC grants * this exception to all derivative works. AlliedModders LLC defines further * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), * or . * * Version: $Id$ */ #ifndef _include_sourcepawn_macroassembler_x86h__ #define _include_sourcepawn_macroassembler_x86h__ #include #include #include #include class MacroAssemblerX86 : public AssemblerX86 { public: static void GenerateFeatureDetection(MacroAssemblerX86 &masm) { masm.push(ebp); masm.movl(ebp, esp); masm.push(ebx); { // Get ECX, EDX feature bits at the first CPUID level. masm.movl(eax, 1); masm.cpuid(); masm.movl(eax, Operand(ebp, 8)); masm.movl(Operand(eax, 0), ecx); masm.movl(eax, Operand(ebp, 12)); masm.movl(Operand(eax, 0), edx); } // Zero out bits we're not guaranteed to get. masm.movl(eax, Operand(ebp, 16)); masm.movl(Operand(eax, 0), 0); Label skip_level_7; { // Get EBX feature bits at 7th CPUID level. masm.movl(eax, 0); masm.cpuid(); masm.cmpl(eax, 7); masm.j(below, &skip_level_7); masm.movl(eax, 7); masm.movl(ecx, 0); masm.cpuid(); masm.movl(eax, Operand(ebp, 16)); masm.movl(Operand(eax, 0), ebx); } masm.bind(&skip_level_7); masm.pop(ebx); masm.pop(ebp); masm.ret(); } static void RunFeatureDetection(void *code) { typedef void (*fn_t)(int *reg_ecx, int *reg_edx, int *reg_ebx); int reg_ecx, reg_edx, reg_ebx; ((fn_t)code)(®_ecx, ®_edx, ®_ebx); CPUFeatures features; features.fpu = !!(reg_edx & (1 << 0)); features.mmx = !!(reg_edx & (1 << 23)); features.sse = !!(reg_edx & (1 << 25)); features.sse2 = !!(reg_edx & (1 << 26)); features.sse3 = !!(reg_ecx & (1 << 0)); features.ssse3 = !!(reg_ecx & (1 << 9)); features.sse4_1 = !!(reg_ecx & (1 << 19)); features.sse4_2 = !!(reg_ecx & (1 << 20)); features.avx = !!(reg_ecx & (1 << 28)); features.avx2 = !!(reg_ebx & (1 << 5)); SetFeatures(features); } private: }; #endif // _include_sourcepawn_macroassembler_x86h__