extern void amd64g_dirtyhelper_OUT ( ULong portno, ULong data,
ULong sz/*1,2 or 4*/ );
+extern void amd64g_dirtyhelper_SxDT ( void* address,
+ ULong op /* 0 or 1 */ );
+
//extern void amd64g_dirtyhelper_CPUID_sse0 ( VexGuestAMD64State* );
//extern void amd64g_dirtyhelper_CPUID_sse1 ( VexGuestAMD64State* );
//extern void amd64g_dirtyhelper_CPUID_sse2 ( VexGuestAMD64State* );
# endif
}
+/* CALLED FROM GENERATED CODE */
+/* DIRTY HELPER (non-referentially-transparent) */
+/* Horrible hack. On non-amd64 platforms, do nothing. */
+/* op = 0: call the native SGDT instruction.
+ op = 1: call the native SIDT instruction.
+*/
+void amd64g_dirtyhelper_SxDT ( void *address, ULong op ) {
+# if defined(__x86_64__)
+ switch (op) {
+ case 0:
+ __asm__ __volatile__("sgdt (%0)" : : "r" (address) : "memory");
+ break;
+ case 1:
+ __asm__ __volatile__("sidt (%0)" : : "r" (address) : "memory");
+ break;
+ default:
+ vpanic("amd64g_dirtyhelper_SxDT");
+ }
+# else
+ /* do nothing */
+ UChar* p = (UChar*)address;
+ p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = 0;
+ p[6] = p[7] = p[8] = p[9] = 0;
+# endif
+}
/*---------------------------------------------------------------*/
/*--- Helpers for MMX/SSE/SSE2. ---*/
DIP("{f}emms\n");
break;
+ /* =-=-=-=-=-=-=-=-=- SGDT and SIDT =-=-=-=-=-=-=-=-=-=-= */
+ case 0x01: /* 0F 01 /0 -- SGDT */
+ /* 0F 01 /1 -- SIDT */
+ {
+ /* This is really revolting, but ... since each processor
+ (core) only has one IDT and one GDT, just let the guest
+ see it (pass-through semantics). I can't see any way to
+ construct a faked-up value, so don't bother to try. */
+ modrm = getUChar(delta);
+ addr = disAMode ( &alen, vbi, pfx, delta, dis_buf, 0 );
+ delta += alen;
+ if (epartIsReg(modrm)) goto decode_failure;
+ if (gregLO3ofRM(modrm) != 0 && gregLO3ofRM(modrm) != 1)
+ goto decode_failure;
+ switch (gregLO3ofRM(modrm)) {
+ case 0: DIP("sgdt %s\n", dis_buf); break;
+ case 1: DIP("sidt %s\n", dis_buf); break;
+ default: vassert(0); /*NOTREACHED*/
+ }
+
+ IRDirty* d = unsafeIRDirty_0_N (
+ 0/*regparms*/,
+ "amd64g_dirtyhelper_SxDT",
+ &amd64g_dirtyhelper_SxDT,
+ mkIRExprVec_2( mkexpr(addr),
+ mkU64(gregLO3ofRM(modrm)) )
+ );
+ /* declare we're writing memory */
+ d->mFx = Ifx_Write;
+ d->mAddr = mkexpr(addr);
+ d->mSize = 6;
+ stmt( IRStmt_Dirty(d) );
+ break;
+ }
+
/* =-=-=-=-=-=-=-=-=- unimp2 =-=-=-=-=-=-=-=-=-=-= */
default:
extern void x86g_dirtyhelper_OUT ( UInt portno, UInt data,
UInt sz/*1,2 or 4*/ );
+extern void x86g_dirtyhelper_SxDT ( void* address,
+ UInt op /* 0 or 1 */ );
+
extern VexEmWarn
x86g_dirtyhelper_FXRSTOR ( VexGuestX86State*, HWord );
# endif
}
+/* CALLED FROM GENERATED CODE */
+/* DIRTY HELPER (non-referentially-transparent) */
+/* Horrible hack. On non-x86 platforms, do nothing. */
+/* op = 0: call the native SGDT instruction.
+ op = 1: call the native SIDT instruction.
+*/
+void x86g_dirtyhelper_SxDT ( void *address, UInt op ) {
+# if defined(__i386__)
+ switch (op) {
+ case 0:
+ __asm__ __volatile__("sgdt (%0)" : : "r" (address) : "memory");
+ break;
+ case 1:
+ __asm__ __volatile__("sidt (%0)" : : "r" (address) : "memory");
+ break;
+ default:
+ vpanic("x86g_dirtyhelper_SxDT");
+ }
+# else
+ /* do nothing */
+ UChar* p = (UChar*)address;
+ p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = 0;
+# endif
+}
/*---------------------------------------------------------------*/
/*--- Helpers for MMX/SSE/SSE2. ---*/
DIP("emms\n");
break;
+ /* =-=-=-=-=-=-=-=-=- SGDT and SIDT =-=-=-=-=-=-=-=-=-=-= */
+ case 0x01: /* 0F 01 /0 -- SGDT */
+ /* 0F 01 /1 -- SIDT */
+ {
+ /* This is really revolting, but ... since each processor
+ (core) only has one IDT and one GDT, just let the guest
+ see it (pass-through semantics). I can't see any way to
+ construct a faked-up value, so don't bother to try. */
+ modrm = getUChar(delta);
+ addr = disAMode ( &alen, sorb, delta, dis_buf );
+ delta += alen;
+ if (epartIsReg(modrm)) goto decode_failure;
+ if (gregOfRM(modrm) != 0 && gregOfRM(modrm) != 1)
+ goto decode_failure;
+ switch (gregOfRM(modrm)) {
+ case 0: DIP("sgdt %s\n", dis_buf); break;
+ case 1: DIP("sidt %s\n", dis_buf); break;
+ default: vassert(0); /*NOTREACHED*/
+ }
+
+ IRDirty* d = unsafeIRDirty_0_N (
+ 0/*regparms*/,
+ "x86g_dirtyhelper_SxDT",
+ &x86g_dirtyhelper_SxDT,
+ mkIRExprVec_2( mkexpr(addr),
+ mkU32(gregOfRM(modrm)) )
+ );
+ /* declare we're writing memory */
+ d->mFx = Ifx_Write;
+ d->mAddr = mkexpr(addr);
+ d->mSize = 6;
+ stmt( IRStmt_Dirty(d) );
+ break;
+ }
+
/* =-=-=-=-=-=-=-=-=- unimp2 =-=-=-=-=-=-=-=-=-=-= */
default: