From: Julian Seward Date: Fri, 1 Mar 2013 21:13:24 +0000 (+0000) Subject: Handle WFE and SEV, needed for spinlock hinting. X-Git-Tag: svn/VALGRIND_3_9_0^2~106 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=615fc3df453caf579ced7b18da6c0550bbceffab;p=thirdparty%2Fvalgrind.git Handle WFE and SEV, needed for spinlock hinting. git-svn-id: svn://svn.valgrind.org/vex/trunk@2688 --- diff --git a/VEX/priv/guest_arm_toIR.c b/VEX/priv/guest_arm_toIR.c index 566f95fdf2..f96b3a74e6 100644 --- a/VEX/priv/guest_arm_toIR.c +++ b/VEX/priv/guest_arm_toIR.c @@ -16569,10 +16569,32 @@ DisResult disInstr_THUMB_WRK ( /* ================ 16-bit misc cases ================ */ - /* ------ NOP ------ */ - if (INSN0(15,0) == 0xBF00) { - DIP("nop\n"); - goto decode_success; + switch (INSN0(15,0)) { + case 0xBF00: + /* ------ NOP ------ */ + DIP("nop\n"); + goto decode_success; + case 0xBF20: + /* ------ WFE ------ */ + /* WFE gets used as a spin-loop hint. Do the usual thing, + which is to continue after yielding. */ + stmt( IRStmt_Exit( unop(Iop_32to1, mkexpr(condT)), + Ijk_Yield, + IRConst_U32((guest_R15_curr_instr_notENC + 2) + | 1 /*CPSR.T*/), + OFFB_R15T )); + DIP("wfe\n"); + goto decode_success; + case 0xBF40: + /* ------ SEV ------ */ + /* Treat this as a no-op. Any matching WFEs won't really + cause the host CPU to snooze; they just cause V to try to + run some other thread for a while. So there's no point in + really doing anything for SEV. */ + DIP("sev\n"); + goto decode_success; + default: + break; /* fall through */ } /* ----------------------------------------------------------- */ diff --git a/VEX/priv/host_arm_defs.c b/VEX/priv/host_arm_defs.c index fe458b8f0b..70e2751705 100644 --- a/VEX/priv/host_arm_defs.c +++ b/VEX/priv/host_arm_defs.c @@ -3304,7 +3304,7 @@ Int emit_ARMInstr ( /*MB_MOD*/Bool* is_profInc, case Ijk_ClientReq: trcval = VEX_TRC_JMP_CLIENTREQ; break; case Ijk_Sys_syscall: trcval = VEX_TRC_JMP_SYS_SYSCALL; break; //case Ijk_Sys_int128: trcval = VEX_TRC_JMP_SYS_INT128; break; - //case Ijk_Yield: trcval = VEX_TRC_JMP_YIELD; break; + case Ijk_Yield: trcval = VEX_TRC_JMP_YIELD; break; //case Ijk_EmWarn: trcval = VEX_TRC_JMP_EMWARN; break; //case Ijk_MapFail: trcval = VEX_TRC_JMP_MAPFAIL; break; case Ijk_NoDecode: trcval = VEX_TRC_JMP_NODECODE; break; diff --git a/VEX/priv/host_arm_isel.c b/VEX/priv/host_arm_isel.c index 22c4efb791..c74613bab5 100644 --- a/VEX/priv/host_arm_isel.c +++ b/VEX/priv/host_arm_isel.c @@ -6121,6 +6121,7 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt ) case Ijk_NoRedir: case Ijk_Sys_syscall: case Ijk_TInval: + case Ijk_Yield: { HReg r = iselIntExpr_R(env, IRExpr_Const(stmt->Ist.Exit.dst)); addInstr(env, ARMInstr_XAssisted(r, amR15T, cc, @@ -6212,6 +6213,7 @@ static void iselNext ( ISelEnv* env, case Ijk_NoRedir: case Ijk_Sys_syscall: case Ijk_TInval: + case Ijk_Yield: { HReg r = iselIntExpr_R(env, next); ARMAMode1* amR15T = ARMAMode1_RI(hregARM_R8(), offsIP);