/* Assembly code stubs make this request */
#define VG_USERREQ__SIGNAL_RETURNS 0x4001
+/* CPU features */
+#define VG_X86_FEAT_FPU (0*32 + 0)
+#define VG_X86_FEAT_VME (0*32 + 1)
+#define VG_X86_FEAT_DE (0*32 + 2)
+#define VG_X86_FEAT_PSE (0*32 + 3)
+#define VG_X86_FEAT_TSC (0*32 + 4)
+#define VG_X86_FEAT_MSR (0*32 + 5)
+#define VG_X86_FEAT_PAE (0*32 + 6)
+#define VG_X86_FEAT_MCE (0*32 + 7)
+#define VG_X86_FEAT_CX8 (0*32 + 8)
+#define VG_X86_FEAT_APIC (0*32 + 9)
+#define VG_X86_FEAT_SEP (0*32 + 11)
+#define VG_X86_FEAT_MTRR (0*32 + 12)
+#define VG_X86_FEAT_PGE (0*32 + 13)
+#define VG_X86_FEAT_MCA (0*32 + 14)
+#define VG_X86_FEAT_CMOV (0*32 + 15)
+#define VG_X86_FEAT_PAT (0*32 + 16)
+#define VG_X86_FEAT_PSE36 (0*32 + 17)
+#define VG_X86_FEAT_CLFSH (0*32 + 19)
+#define VG_X86_FEAT_DS (0*32 + 21)
+#define VG_X86_FEAT_ACPI (0*32 + 22)
+#define VG_X86_FEAT_MMX (0*32 + 23)
+#define VG_X86_FEAT_FXSR (0*32 + 24)
+#define VG_X86_FEAT_SSE (0*32 + 25)
+#define VG_X86_FEAT_SSE2 (0*32 + 26)
+#define VG_X86_FEAT_SS (0*32 + 27)
+#define VG_X86_FEAT_HT (0*32 + 28)
+#define VG_X86_FEAT_TM (0*32 + 29)
+#define VG_X86_FEAT_PBE (0*32 + 31)
+
+#define VG_X86_FEAT_EST (1*32 + 7)
+#define VG_X86_FEAT_TM2 (1*32 + 8)
+#define VG_X86_FEAT_CNXTID (1*32 + 10)
+
+/* Used internally to mark whether CPUID is even implemented */
+#define VG_X86_FEAT_CPUID (2*32 + 0)
+
+/* The set of features we're willing to support for the client */
+#define VG_SUPPORTED_FEATURES \
+ ((1 << VG_X86_FEAT_FPU) | \
+ (1 << VG_X86_FEAT_TSC) | \
+ (1 << VG_X86_FEAT_CMOV) | \
+ (1 << VG_X86_FEAT_MMX) | \
+ (1 << VG_X86_FEAT_FXSR) | \
+ (1 << VG_X86_FEAT_SSE) | \
+ (1 << VG_X86_FEAT_SSE2))
+
/* Various environment variables we pay attention to */
/* The directory we look for all our auxillary files in */
For simulating the cpuid instruction, we will
issue a "real" cpuid instruction and then mask out
the bits of the features we do not support currently (3dnow mostly).
-
+ We also claim to not support most CPUID operations.
+
Dirk Mueller <mueller@kde.org>
http://www.sandpile.org/ia32/cpuid.htm
pushl %edx
movl 32(%esp), %eax
- cmpl $0x80000001, %eax
- je cpuid_no3dnow
+ /* eax==0 - max valid request+processor vendor */
+ cmpl $0, %eax
+ jne 1f
- cpuid
- jmp cpuid__99
+ movl $1, %eax /* only support request 1 */
+ movl valgrind_brand+0, %ebx
+ movl valgrind_brand+4, %edx
+ movl valgrind_brand+8, %ecx
+ jmp 99f
-cpuid_no3dnow:
- cpuid
-
- andl $0x3fffffff, %edx
+ /* eax==1 - CPU features and model ID */
+1: cmpl $1, %eax
+ jne 2f
+
+ cpuid /* get host CPU's capabilities */
+
+ movl $0111, %eax
+ movl $0, %ebx /* clear APIC id, CLFLUSH size, Brand ID */
+ movl $0, %ecx /* clear extended feature bits */
+ andl $VG_SUPPORTED_FEATURES, %edx /* mask off feature bits we don't support */
+ jmp 99f
+
+ /* eax=0x80000000 - extended cpuid functions */
+2: cmpl $0x80000000, %eax
+ jne 99f
-cpuid__99:
- movl %edx, 20(%esp)
+ /* leave eax==0x80000000 - we don't support any other extended operations */
+ movl valgrind_brand+0, %ebx /* AMD load the brand string again - */
+ movl valgrind_brand+4, %edx /* Intel leaves them "reserved" */
+ movl valgrind_brand+8, %ecx
+
+
+99: movl %edx, 20(%esp)
movl %ecx, 24(%esp)
movl %ebx, 28(%esp)
movl %eax, 32(%esp)
popl %ebx
popl %eax
ret
-
+.data
+valgrind_brand:
+ .ascii "ValgrindVCPU"
+.text
/* Fetch the FPU status register.
On entry:
Exports of vg_to_ucode.c
------------------------------------------------------------------ */
-#define VG_X86_FEAT_FPU (0*32 + 0)
-#define VG_X86_FEAT_VME (0*32 + 1)
-#define VG_X86_FEAT_DE (0*32 + 2)
-#define VG_X86_FEAT_PSE (0*32 + 3)
-#define VG_X86_FEAT_TSC (0*32 + 4)
-#define VG_X86_FEAT_MSR (0*32 + 5)
-#define VG_X86_FEAT_PAE (0*32 + 6)
-#define VG_X86_FEAT_MCE (0*32 + 7)
-#define VG_X86_FEAT_CX8 (0*32 + 8)
-#define VG_X86_FEAT_APIC (0*32 + 9)
-#define VG_X86_FEAT_SEP (0*32 + 11)
-#define VG_X86_FEAT_MTRR (0*32 + 12)
-#define VG_X86_FEAT_PGE (0*32 + 13)
-#define VG_X86_FEAT_MCA (0*32 + 14)
-#define VG_X86_FEAT_CMOV (0*32 + 15)
-#define VG_X86_FEAT_PAT (0*32 + 16)
-#define VG_X86_FEAT_PSE36 (0*32 + 17)
-#define VG_X86_FEAT_CLFSH (0*32 + 19)
-#define VG_X86_FEAT_DS (0*32 + 21)
-#define VG_X86_FEAT_ACPI (0*32 + 22)
-#define VG_X86_FEAT_MMX (0*32 + 23)
-#define VG_X86_FEAT_FXSR (0*32 + 24)
-#define VG_X86_FEAT_SSE (0*32 + 25)
-#define VG_X86_FEAT_SSE2 (0*32 + 26)
-#define VG_X86_FEAT_SS (0*32 + 27)
-#define VG_X86_FEAT_HT (0*32 + 28)
-#define VG_X86_FEAT_TM (0*32 + 29)
-#define VG_X86_FEAT_PBE (0*32 + 31)
-
-#define VG_X86_FEAT_EST (1*32 + 7)
-#define VG_X86_FEAT_TM2 (1*32 + 8)
-#define VG_X86_FEAT_CNXTID (1*32 + 10)
-
Bool VG_(cpu_has_feature)(UInt feat);
extern Int VG_(disBB) ( UCodeBlock* cb, Addr eip0 );
/*--- for now. ---*/
/*------------------------------------------------------------*/
-#define VG_N_FEATURE_WORDS 2
+#define VG_N_FEATURE_WORDS 3
static Int cpuid_level = -2; /* -2 -> not initialized */
static UInt cpu_features[VG_N_FEATURE_WORDS];
return;
}
+ cpu_features[2] |= (1 << (VG_X86_FEAT_CPUID%32));
+
cpuid_level = cpuid_eax(0);
if (cpuid_level >= 1)
/* =-=-=-=-=-=-=-=-=- CPUID -=-=-=-=-=-=-=-=-=-=-= */
case 0xA2: /* CPUID */
+ if (!VG_(cpu_has_feature)(VG_X86_FEAT_CPUID))
+ goto decode_failure;
+
t1 = newTemp(cb);
t2 = newTemp(cb);
t3 = newTemp(cb);