static ULong calculate_RCR ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz );
/* --- DIRTY HELPERS --- */
-static ULong loadF80le ( UInt );
-static void storeF80le ( UInt, ULong );
+static ULong loadF80le ( VexGuestX86State*, UInt );
+static void storeF80le ( VexGuestX86State*, UInt, ULong );
+static void dirtyhelper_CPUID ( VexGuestX86State* st );
/* This file contains helper functions for x86 guest code.
return (Addr64)(Addr32)(& loadF80le);
if (vex_streq(function_name, "calculate_RCR"))
return (Addr64)(Addr32)(& calculate_RCR);
+ if (vex_streq(function_name, "dirtyhelper_CPUID"))
+ return (Addr64)(Addr32)(& dirtyhelper_CPUID);
vex_printf("\nx86 guest: can't find helper: %s\n", function_name);
vpanic("x86guest_findhelper");
}
/* CALLED FROM GENERATED CODE */
/* DIRTY HELPER (reads guest memory) */
-static ULong loadF80le ( UInt addrU )
+static ULong loadF80le ( VexGuestX86State* st, UInt addrU )
{
ULong f64;
convert_f80le_to_f64le ( (UChar*)addrU, (UChar*)&f64 );
/* CALLED FROM GENERATED CODE */
/* DIRTY HELPER (writes guest memory) */
-static void storeF80le ( UInt addrU, ULong f64 )
+static void storeF80le ( VexGuestX86State* st, UInt addrU, ULong f64 )
{
convert_f64le_to_f80le( (UChar*)&f64, (UChar*)addrU );
}
return (((ULong)eflags_in) << 32) | ((ULong)arg);
}
+
+/* CALLED FROM GENERATED CODE */
+/* DIRTY HELPER (modifies guest state) */
+/* Claim to be a P54C P133 (pre-MMX Pentium) */
+static void dirtyhelper_CPUID ( VexGuestX86State* st )
+{
+ if (st->guest_EAX == 0) {
+ st->guest_EAX = 0x1;
+ st->guest_EBX = 0x756e6547;
+ st->guest_ECX = 0x6c65746e;
+ st->guest_EDX = 0x49656e69;
+ } else {
+ st->guest_EAX = 0x52b;
+ st->guest_EBX = 0x0;
+ st->guest_ECX = 0x0;
+ st->guest_EDX = 0x1bf;
+ }
+}
+
/*---------------------------------------------------------------*/
/*--- end guest-x86/ghelpers.c ---*/
/*---------------------------------------------------------------*/
-
#define OFFB_FPREGS offsetof(VexGuestX86State,guest_FPREG[0])
#define OFFB_FPTAGS offsetof(VexGuestX86State,guest_FPTAG[0])
#define OFFB_EAX offsetof(VexGuestX86State,guest_EAX)
+#define OFFB_EBX offsetof(VexGuestX86State,guest_EBX)
+#define OFFB_ECX offsetof(VexGuestX86State,guest_ECX)
+#define OFFB_EDX offsetof(VexGuestX86State,guest_EDX)
#define OFFB_CC_OP offsetof(VexGuestX86State,guest_CC_OP)
#define OFFB_CC_SRC offsetof(VexGuestX86State,guest_CC_SRC)
#define OFFB_CC_DST offsetof(VexGuestX86State,guest_CC_DST)
break;
case 5: { /* FLD extended-real */
- /* Uses dirty helper: ULong loadF80le ( UInt ) */
- /* addr holds the address. First, do a dirty call to
+ /* Uses dirty helper:
+ ULong loadF80le ( VexGuestX86State*, UInt )
+ addr holds the address. First, do a dirty call to
get hold of the data. */
/* give details of args, and where to call */
IRDirty* d;
//--
/* =-=-=-=-=-=-=-=-=- CPUID -=-=-=-=-=-=-=-=-=-=-= */
- case 0xA2: /* CPUID */
- vex_printf("vex x86->IR: hacked CPUID\n");
- putIReg(4, R_EAX, mkU32(0));
- putIReg(4, R_EBX, mkU32(0x756e6547));
- putIReg(4, R_ECX, mkU32(0x49656e69));
- putIReg(4, R_EDX, mkU32(0x6c65746e));
+ case 0xA2: { /* CPUID */
+ /* Uses dirty helper:
+ void dirtyhelper_CPUID ( VexGuestX86State* )
+ declared to mod eax, wr ebx, ecx, edx
+ */
+ /* give details of args, and where to call */
+ IRDirty* d;
+ d = emptyIRDirty();
+ d->name = "dirtyhelper_CPUID";
+ d->args = LibVEX_Alloc(1 * sizeof(IRTemp));
+ d->args[0] = NULL;
+ d->tmp = INVALID_IRTEMP;
+ /* declare that we're not accessing memory */
+ d->mFx = Ifx_None;
+ d->mAddr = NULL;
+ d->mSize = 0;
+ /* declare guest state effects */
+ d->nFxState = 4;
+ d->fxState[0].fx = Ifx_Modify;
+ d->fxState[0].offset = OFFB_EAX;
+ d->fxState[0].size = 4;
+ d->fxState[1].fx = Ifx_Write;
+ d->fxState[1].offset = OFFB_EBX;
+ d->fxState[1].size = 4;
+ d->fxState[2].fx = Ifx_Write;
+ d->fxState[2].offset = OFFB_ECX;
+ d->fxState[2].size = 4;
+ d->fxState[3].fx = Ifx_Write;
+ d->fxState[3].offset = OFFB_EDX;
+ d->fxState[3].size = 4;
+ /* execute the dirty call, side-effecting guest state */
+ stmt( IRStmt_Dirty(d) );
break;
+ }
+
//-- if (!VG_(cpu_has_feature)(VG_X86_FEAT_CPUID))
//-- goto decode_failure;
//--