📄 ghelpers.c
字号:
{ Int cf, pf, af, zf, sf, of; \ DATA_UTYPE hi; \ DATA_UTYPE lo \ = NARROWtoU( ((DATA_UTYPE)CC_DEP1) \ * ((DATA_UTYPE)CC_DEP2) ); \ DATA_U2TYPE rr \ = NARROWto2U( \ ((DATA_U2TYPE)((DATA_UTYPE)CC_DEP1)) \ * ((DATA_U2TYPE)((DATA_UTYPE)CC_DEP2)) ); \ hi = NARROWtoU(rr >>/*u*/ DATA_BITS); \ cf = (hi != 0); \ pf = parity_table[(UChar)lo]; \ af = 0; /* undefined */ \ zf = (lo == 0) << 6; \ sf = lshift(lo, 8 - DATA_BITS) & 0x80; \ of = cf << 11; \ return cf | pf | af | zf | sf | of; \ } \}/*-------------------------------------------------------------*/#define ACTIONS_SMUL(DATA_BITS, DATA_STYPE, NARROWtoS, \ DATA_S2TYPE, NARROWto2S) \{ \ PREAMBLE(DATA_BITS); \ { Int cf, pf, af, zf, sf, of; \ DATA_STYPE hi; \ DATA_STYPE lo \ = NARROWtoS( ((DATA_STYPE)CC_DEP1) \ * ((DATA_STYPE)CC_DEP2) ); \ DATA_S2TYPE rr \ = NARROWto2S( \ ((DATA_S2TYPE)((DATA_STYPE)CC_DEP1)) \ * ((DATA_S2TYPE)((DATA_STYPE)CC_DEP2)) ); \ hi = NARROWtoS(rr >>/*s*/ DATA_BITS); \ cf = (hi != (lo >>/*s*/ (DATA_BITS-1))); \ pf = parity_table[(UChar)lo]; \ af = 0; /* undefined */ \ zf = (lo == 0) << 6; \ sf = lshift(lo, 8 - DATA_BITS) & 0x80; \ of = cf << 11; \ return cf | pf | af | zf | sf | of; \ } \}#if PROFILE_EFLAGSstatic Bool initted = False;/* C flag, fast route */static UInt tabc_fast[X86G_CC_OP_NUMBER];/* C flag, slow route */static UInt tabc_slow[X86G_CC_OP_NUMBER];/* table for calculate_cond */static UInt tab_cond[X86G_CC_OP_NUMBER][16];/* total entry counts for calc_all, calc_c, calc_cond. */static UInt n_calc_all = 0;static UInt n_calc_c = 0;static UInt n_calc_cond = 0;#define SHOW_COUNTS_NOW (0 == (0x3FFFFF & (n_calc_all+n_calc_c+n_calc_cond)))static void showCounts ( void ){ Int op, co; Char ch; vex_printf("\nTotal calls: calc_all=%u calc_cond=%u calc_c=%u\n", n_calc_all, n_calc_cond, n_calc_c); vex_printf(" cSLOW cFAST O NO B NB Z NZ BE NBE" " S NS P NP L NL LE NLE\n"); vex_printf(" -----------------------------------------------------" "----------------------------------------\n"); for (op = 0; op < X86G_CC_OP_NUMBER; op++) { ch = ' '; if (op > 0 && (op-1) % 3 == 0) ch = 'B'; if (op > 0 && (op-1) % 3 == 1) ch = 'W'; if (op > 0 && (op-1) % 3 == 2) ch = 'L'; vex_printf("%2d%c: ", op, ch); vex_printf("%6u ", tabc_slow[op]); vex_printf("%6u ", tabc_fast[op]); for (co = 0; co < 16; co++) { Int n = tab_cond[op][co]; if (n >= 1000) { vex_printf(" %3dK", n / 1000); } else if (n >= 0) { vex_printf(" %3d ", n ); } else { vex_printf(" "); } } vex_printf("\n"); } vex_printf("\n");}static void initCounts ( void ){ Int op, co; initted = True; for (op = 0; op < X86G_CC_OP_NUMBER; op++) { tabc_fast[op] = tabc_slow[op] = 0; for (co = 0; co < 16; co++) tab_cond[op][co] = 0; }}#endif /* PROFILE_EFLAGS *//* CALLED FROM GENERATED CODE: CLEAN HELPER *//* Calculate all the 6 flags from the supplied thunk parameters. Worker function, not directly called from generated code. */staticUInt x86g_calculate_eflags_all_WRK ( UInt cc_op, UInt cc_dep1_formal, UInt cc_dep2_formal, UInt cc_ndep_formal ){ switch (cc_op) { case X86G_CC_OP_COPY: return cc_dep1_formal & (X86G_CC_MASK_O | X86G_CC_MASK_S | X86G_CC_MASK_Z | X86G_CC_MASK_A | X86G_CC_MASK_C | X86G_CC_MASK_P); case X86G_CC_OP_ADDB: ACTIONS_ADD( 8, UChar ); case X86G_CC_OP_ADDW: ACTIONS_ADD( 16, UShort ); case X86G_CC_OP_ADDL: ACTIONS_ADD( 32, UInt ); case X86G_CC_OP_ADCB: ACTIONS_ADC( 8, UChar ); case X86G_CC_OP_ADCW: ACTIONS_ADC( 16, UShort ); case X86G_CC_OP_ADCL: ACTIONS_ADC( 32, UInt ); case X86G_CC_OP_SUBB: ACTIONS_SUB( 8, UChar ); case X86G_CC_OP_SUBW: ACTIONS_SUB( 16, UShort ); case X86G_CC_OP_SUBL: ACTIONS_SUB( 32, UInt ); case X86G_CC_OP_SBBB: ACTIONS_SBB( 8, UChar ); case X86G_CC_OP_SBBW: ACTIONS_SBB( 16, UShort ); case X86G_CC_OP_SBBL: ACTIONS_SBB( 32, UInt ); case X86G_CC_OP_LOGICB: ACTIONS_LOGIC( 8, UChar ); case X86G_CC_OP_LOGICW: ACTIONS_LOGIC( 16, UShort ); case X86G_CC_OP_LOGICL: ACTIONS_LOGIC( 32, UInt ); case X86G_CC_OP_INCB: ACTIONS_INC( 8, UChar ); case X86G_CC_OP_INCW: ACTIONS_INC( 16, UShort ); case X86G_CC_OP_INCL: ACTIONS_INC( 32, UInt ); case X86G_CC_OP_DECB: ACTIONS_DEC( 8, UChar ); case X86G_CC_OP_DECW: ACTIONS_DEC( 16, UShort ); case X86G_CC_OP_DECL: ACTIONS_DEC( 32, UInt ); case X86G_CC_OP_SHLB: ACTIONS_SHL( 8, UChar ); case X86G_CC_OP_SHLW: ACTIONS_SHL( 16, UShort ); case X86G_CC_OP_SHLL: ACTIONS_SHL( 32, UInt ); case X86G_CC_OP_SHRB: ACTIONS_SHR( 8, UChar ); case X86G_CC_OP_SHRW: ACTIONS_SHR( 16, UShort ); case X86G_CC_OP_SHRL: ACTIONS_SHR( 32, UInt ); case X86G_CC_OP_ROLB: ACTIONS_ROL( 8, UChar ); case X86G_CC_OP_ROLW: ACTIONS_ROL( 16, UShort ); case X86G_CC_OP_ROLL: ACTIONS_ROL( 32, UInt ); case X86G_CC_OP_RORB: ACTIONS_ROR( 8, UChar ); case X86G_CC_OP_RORW: ACTIONS_ROR( 16, UShort ); case X86G_CC_OP_RORL: ACTIONS_ROR( 32, UInt ); case X86G_CC_OP_UMULB: ACTIONS_UMUL( 8, UChar, toUChar, UShort, toUShort ); case X86G_CC_OP_UMULW: ACTIONS_UMUL( 16, UShort, toUShort, UInt, toUInt ); case X86G_CC_OP_UMULL: ACTIONS_UMUL( 32, UInt, toUInt, ULong, idULong ); case X86G_CC_OP_SMULB: ACTIONS_SMUL( 8, Char, toUChar, Short, toUShort ); case X86G_CC_OP_SMULW: ACTIONS_SMUL( 16, Short, toUShort, Int, toUInt ); case X86G_CC_OP_SMULL: ACTIONS_SMUL( 32, Int, toUInt, Long, idULong ); default: /* shouldn't really make these calls from generated code */ vex_printf("x86g_calculate_eflags_all_WRK(X86)" "( %u, 0x%x, 0x%x, 0x%x )\n", cc_op, cc_dep1_formal, cc_dep2_formal, cc_ndep_formal ); vpanic("x86g_calculate_eflags_all_WRK(X86)"); }}/* CALLED FROM GENERATED CODE: CLEAN HELPER *//* Calculate all the 6 flags from the supplied thunk parameters. */UInt x86g_calculate_eflags_all ( UInt cc_op, UInt cc_dep1, UInt cc_dep2, UInt cc_ndep ){# if PROFILE_EFLAGS if (!initted) initCounts(); n_calc_all++; if (SHOW_COUNTS_NOW) showCounts();# endif return x86g_calculate_eflags_all_WRK ( cc_op, cc_dep1, cc_dep2, cc_ndep );}/* CALLED FROM GENERATED CODE: CLEAN HELPER *//* Calculate just the carry flag from the supplied thunk parameters. */__attribute((regparm(3)))UInt x86g_calculate_eflags_c ( UInt cc_op, UInt cc_dep1, UInt cc_dep2, UInt cc_ndep ){# if PROFILE_EFLAGS if (!initted) initCounts(); n_calc_c++; tabc_fast[cc_op]++; if (SHOW_COUNTS_NOW) showCounts();# endif /* Fast-case some common ones. */ switch (cc_op) { case X86G_CC_OP_LOGICL: case X86G_CC_OP_LOGICW: case X86G_CC_OP_LOGICB: return 0; case X86G_CC_OP_SUBL: return ((UInt)cc_dep1) < ((UInt)cc_dep2) ? X86G_CC_MASK_C : 0; case X86G_CC_OP_SUBW: return ((UInt)(cc_dep1 & 0xFFFF)) < ((UInt)(cc_dep2 & 0xFFFF)) ? X86G_CC_MASK_C : 0; case X86G_CC_OP_SUBB: return ((UInt)(cc_dep1 & 0xFF)) < ((UInt)(cc_dep2 & 0xFF)) ? X86G_CC_MASK_C : 0; case X86G_CC_OP_INCL: case X86G_CC_OP_DECL: return cc_ndep & X86G_CC_MASK_C; default: break; }# if PROFILE_EFLAGS tabc_fast[cc_op]--; tabc_slow[cc_op]++;# endif return x86g_calculate_eflags_all_WRK(cc_op,cc_dep1,cc_dep2,cc_ndep) & X86G_CC_MASK_C;}/* CALLED FROM GENERATED CODE: CLEAN HELPER *//* returns 1 or 0 */UInt x86g_calculate_condition ( UInt/*X86Condcode*/ cond, UInt cc_op, UInt cc_dep1, UInt cc_dep2, UInt cc_ndep ){ UInt eflags = x86g_calculate_eflags_all_WRK(cc_op, cc_dep1, cc_dep2, cc_ndep); UInt of,sf,zf,cf,pf; UInt inv = cond & 1;# if PROFILE_EFLAGS if (!initted) initCounts(); tab_cond[cc_op][cond]++; n_calc_cond++; if (SHOW_COUNTS_NOW) showCounts();# endif switch (cond) { case X86CondNO: case X86CondO: /* OF == 1 */ of = eflags >> X86G_CC_SHIFT_O; return 1 & (inv ^ of); case X86CondNZ: case X86CondZ: /* ZF == 1 */ zf = eflags >> X86G_CC_SHIFT_Z; return 1 & (inv ^ zf); case X86CondNB: case X86CondB: /* CF == 1 */ cf = eflags >> X86G_CC_SHIFT_C; return 1 & (inv ^ cf); break; case X86CondNBE: case X86CondBE: /* (CF or ZF) == 1 */ cf = eflags >> X86G_CC_SHIFT_C; zf = eflags >> X86G_CC_SHIFT_Z; return 1 & (inv ^ (cf | zf)); break; case X86CondNS: case X86CondS: /* SF == 1 */ sf = eflags >> X86G_CC_SHIFT_S; return 1 & (inv ^ sf); case X86CondNP: case X86CondP: /* PF == 1 */ pf = eflags >> X86G_CC_SHIFT_P; return 1 & (inv ^ pf); case X86CondNL: case X86CondL: /* (SF xor OF) == 1 */ sf = eflags >> X86G_CC_SHIFT_S; of = eflags >> X86G_CC_SHIFT_O; return 1 & (inv ^ (sf ^ of)); break; case X86CondNLE: case X86CondLE: /* ((SF xor OF) or ZF) == 1 */ sf = eflags >> X86G_CC_SHIFT_S; of = eflags >> X86G_CC_SHIFT_O; zf = eflags >> X86G_CC_SHIFT_Z; return 1 & (inv ^ ((sf ^ of) | zf)); break; default: /* shouldn't really make these calls from generated code */ vex_printf("x86g_calculate_condition( %u, %u, 0x%x, 0x%x, 0x%x )\n", cond, cc_op, cc_dep1, cc_dep2, cc_ndep ); vpanic("x86g_calculate_condition"); }}/* VISIBLE TO LIBVEX CLIENT */UInt LibVEX_GuestX86_get_eflags ( /*IN*/VexGuestX86State* vex_state ){ UInt eflags = x86g_calculate_eflags_all_WRK( vex_state->guest_CC_OP, vex_state->guest_CC_DEP1, vex_state->guest_CC_DEP2, vex_state->guest_CC_NDEP ); UInt dflag = vex_state->guest_DFLAG; vassert(dflag == 1 || dflag == 0xFFFFFFFF); if (dflag == 0xFFFFFFFF) eflags |= (1<<10); if (vex_state->guest_IDFLAG == 1) eflags |= (1<<21); if (vex_state->guest_ACFLAG == 1) eflags |= (1<<18); return eflags;}/* VISIBLE TO LIBVEX CLIENT */voidLibVEX_GuestX86_put_eflag_c ( UInt new_carry_flag, /*MOD*/VexGuestX86State* vex_state ){ UInt oszacp = x86g_calculate_eflags_all_WRK( vex_state->guest_CC_OP, vex_state->guest_CC_DEP1, vex_state->guest_CC_DEP2, vex_state->guest_CC_NDEP ); if (new_carry_flag & 1) { oszacp |= X86G_CC_MASK_C; } else { oszacp &= ~X86G_CC_MASK_C;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -