/* ================ 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 */
}
/* ----------------------------------------------------------- */
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;
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,
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);