]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Handle WFE and SEV, needed for spinlock hinting.
authorJulian Seward <jseward@acm.org>
Fri, 1 Mar 2013 21:13:24 +0000 (21:13 +0000)
committerJulian Seward <jseward@acm.org>
Fri, 1 Mar 2013 21:13:24 +0000 (21:13 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@2688

VEX/priv/guest_arm_toIR.c
VEX/priv/host_arm_defs.c
VEX/priv/host_arm_isel.c

index 566f95fdf2cfdc3afe1363440a23daf22e7aef73..f96b3a74e619ceadb30a712e898423695260d386 100644 (file)
@@ -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 */
    }
 
    /* ----------------------------------------------------------- */
index fe458b8f0ba2550151e611996648cf23480004bd..70e2751705319ec603337e6130a94409538123d1 100644 (file)
@@ -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;
index 22c4efb7913f787f27c9426b9b777ecc548948b5..c74613bab5e254107ea410ec9b4cf66b447e0508 100644 (file)
@@ -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);