/* CALLED FROM GENERATED CODE: CLEAN HELPER */
/* Calculate just the carry flag from the supplied thunk parameters. */
-__attribute((regparm(3)))
+VEX_REGPARM(3)
UInt x86g_calculate_eflags_c ( UInt cc_op,
UInt cc_dep1,
UInt cc_dep2,
&& e->Iex.Const.con->Ico.U32 == n );
}
-IRExpr* guest_x86_spechelper ( HChar* function_name,
- IRExpr** args )
+IRExpr* guest_x86_spechelper ( HChar* function_name,
+ IRExpr** args,
+ IRStmt** precedingStmts,
+ Int n_precedingStmts )
{
# define unop(_op,_a1) IRExpr_Unop((_op),(_a1))
# define binop(_op,_a1,_a2) IRExpr_Binop((_op),(_a1),(_a2))
return result;
}
+UInt x86g_calculate_aad_aam ( UInt flags_and_AX, UInt opcode )
+{
+ UInt r_AL = (flags_and_AX >> 0) & 0xFF;
+ UInt r_AH = (flags_and_AX >> 8) & 0xFF;
+ UInt r_O = (flags_and_AX >> (16 + X86G_CC_SHIFT_O)) & 1;
+ UInt r_S = (flags_and_AX >> (16 + X86G_CC_SHIFT_S)) & 1;
+ UInt r_Z = (flags_and_AX >> (16 + X86G_CC_SHIFT_Z)) & 1;
+ UInt r_A = (flags_and_AX >> (16 + X86G_CC_SHIFT_A)) & 1;
+ UInt r_C = (flags_and_AX >> (16 + X86G_CC_SHIFT_C)) & 1;
+ UInt r_P = (flags_and_AX >> (16 + X86G_CC_SHIFT_P)) & 1;
+ UInt result = 0;
+
+ switch (opcode) {
+ case 0xD4: { /* AAM */
+ r_AH = r_AL / 10;
+ r_AL = r_AL % 10;
+ break;
+ }
+ case 0xD5: { /* AAD */
+ r_AL = ((r_AH * 10) + r_AL) & 0xff;
+ r_AH = 0;
+ break;
+ }
+ default:
+ vassert(0);
+ }
+
+ r_O = 0; /* let's say (undefined) */
+ r_C = 0; /* let's say (undefined) */
+ r_A = 0; /* let's say (undefined) */
+ r_S = (r_AL & 0x80) ? 1 : 0;
+ r_Z = (r_AL == 0) ? 1 : 0;
+ r_P = calc_parity_8bit( r_AL );
+
+ result = ( (r_O & 1) << (16 + X86G_CC_SHIFT_O) )
+ | ( (r_S & 1) << (16 + X86G_CC_SHIFT_S) )
+ | ( (r_Z & 1) << (16 + X86G_CC_SHIFT_Z) )
+ | ( (r_A & 1) << (16 + X86G_CC_SHIFT_A) )
+ | ( (r_C & 1) << (16 + X86G_CC_SHIFT_C) )
+ | ( (r_P & 1) << (16 + X86G_CC_SHIFT_P) )
+ | ( (r_AH & 0xFF) << 8 )
+ | ( (r_AL & 0xFF) << 0 );
+ return result;
+}
+
/* CALLED FROM GENERATED CODE */
/* DIRTY HELPER (non-referentially-transparent) */
# 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. ---*/