]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
ARM back end: handle IRDefaults in dirty helper calls.
authorJulian Seward <jseward@acm.org>
Mon, 17 Dec 2012 21:55:21 +0000 (21:55 +0000)
committerJulian Seward <jseward@acm.org>
Mon, 17 Dec 2012 21:55:21 +0000 (21:55 +0000)
git-svn-id: svn://svn.valgrind.org/vex/branches/COMEM@2595

VEX/priv/host_arm_defs.c
VEX/priv/host_arm_defs.h
VEX/priv/host_arm_isel.c

index 28808a5ab6ee536140f1d287c3b157ea5e624a78..44cefaba5d6b6a8dbc873e082591f082e61d2f7f 100644 (file)
@@ -1227,13 +1227,14 @@ ARMInstr* ARMInstr_CMov ( ARMCondCode cond, HReg dst, ARMRI84* src ) {
    return i;
 }
 ARMInstr* ARMInstr_Call ( ARMCondCode cond, HWord target, Int nArgRegs,
-                          RetLoc rloc ) {
+                          RetLoc rloc, IRDefault dflt ) {
    ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
    i->tag                 = ARMin_Call;
    i->ARMin.Call.cond     = cond;
    i->ARMin.Call.target   = target;
    i->ARMin.Call.nArgRegs = nArgRegs;
    i->ARMin.Call.rloc     = rloc;
+   i->ARMin.Call.dflt     = dflt;
    vassert(rloc != RetLocINVALID);
    return i;
 }
@@ -1689,6 +1690,10 @@ void ppARMInstr ( ARMInstr* i ) {
          vex_printf("0x%lx [nArgRegs=%d, ",
                     i->ARMin.Call.target, i->ARMin.Call.nArgRegs);
          ppRetLoc(i->ARMin.Call.rloc);
+         if (i->ARMin.Call.dflt != Idflt_None) {
+            vex_printf(", ");
+            ppIRDefault(i->ARMin.Call.dflt);
+         }
          vex_printf("]");
          return;
       case ARMin_Mul:
@@ -3388,10 +3393,16 @@ Int emit_ARMInstr ( /*MB_MOD*/Bool* is_profInc,
             // preElse:
             //   b after:
             // else:
-            //   mvn r0, #0  // possibly
-            //   mvn r1, #0  // possibly
+            //   {mov,mvn} r0, #0  // possibly
+            //   {mov,mvn} r1, #0  // possibly
             // after:
 
+            /* Since we're generating default-return code in the else:
+               clause, there had better be a sane default-value
+               specification. */
+            vassert(i->ARMin.Call.dflt == Idflt_Zeroes
+                    || i->ARMin.Call.dflt == Idflt_Ones);
+
             // before:
             UInt* pBefore = p;
 
@@ -3421,16 +3432,33 @@ Int emit_ARMInstr ( /*MB_MOD*/Bool* is_profInc,
                = XX______(1 ^ i->ARMin.Call.cond, X1010) | (delta & 0xFFFFFF);
 
             /* Do the 'else' actions */
+            /* Useful:
+               e3a00000 mov r0, #0
+               e3a01000 mov r1, #0
+               e3e00000 mvn r0, #0
+               e3e01000 mvn r1, #0
+            */
             switch (i->ARMin.Call.rloc) {
-               case RetLocInt:
-                  *p++ = 0xE3E00000; break; // mvn r0, #0
-               case RetLoc2Int:
-                  // mvn r0, #0 ;  mvn r1, #0
-                  vassert(0); //ATC
-                  *p++ = 0xE3E00000; *p++ = 0xE3E01000; break;
+               case RetLocInt: {
+                  switch (i->ARMin.Call.dflt) {
+                     case Idflt_Ones:   *p++ = 0xE3E00000; break; // mvn r0, #0
+                     case Idflt_Zeroes: *p++ = 0xE3A00000; break; // mov r0, #0
+                     default: goto elsefail;
+                  }
+                  break;
+               }
+               case RetLoc2Int: {
+                  if (i->ARMin.Call.dflt == Idflt_Ones) {
+                     // mvn r0, #0 ;  mvn r1, #0
+                     vassert(0); //ATC
+                     *p++ = 0xE3E00000; *p++ = 0xE3E01000; break;
+                  }
+                  goto elsefail;
+               }
                case RetLocNone:
                case RetLocINVALID:
                default:
+               elsefail:
                   vassert(0);
             }
 
index 6f780334ea30c0a805233e9cc5fe900439ebcf5c..4341b3422e9e23a6fc5751c3107d70b17141e971 100644 (file)
@@ -725,6 +725,7 @@ typedef
             HWord       target;
             Int         nArgRegs; /* # regs carrying args: 0 .. 4 */
             RetLoc      rloc;     /* where the return value will be */
+            IRDefault   dflt;     /* default return, if conditional */
          } Call;
          /* (PLAIN) 32 *  32 -> 32:  r0    = r2 * r3
             (ZX)    32 *u 32 -> 64:  r1:r0 = r2 *u r3
@@ -970,7 +971,7 @@ extern ARMInstr* ARMInstr_XAssisted ( HReg dstGA, ARMAMode1* amR15T,
                                       ARMCondCode cond, IRJumpKind jk );
 extern ARMInstr* ARMInstr_CMov     ( ARMCondCode, HReg dst, ARMRI84* src );
 extern ARMInstr* ARMInstr_Call     ( ARMCondCode, HWord, Int nArgRegs,
-                                     RetLoc rloc );
+                                     RetLoc rloc, IRDefault dflt );
 extern ARMInstr* ARMInstr_Mul      ( ARMMulOp op );
 extern ARMInstr* ARMInstr_LdrEX    ( Int szB );
 extern ARMInstr* ARMInstr_StrEX    ( Int szB );
index 31375af9028a531749e44efb7a9994f4b9c28e3c..f9939441df5bd4204e255c77c0dbe639d3c2a17b 100644 (file)
@@ -379,7 +379,7 @@ static
 Bool doHelperCall ( ISelEnv* env,
                     Bool passBBP,
                     IRExpr* guard, IRCallee* cee, IRExpr** args,
-                    RetLoc rloc )
+                    RetLoc rloc, IRDefault dflt )
 {
    ARMCondCode cc;
    HReg        argregs[ARM_N_ARGREGS];
@@ -616,7 +616,7 @@ Bool doHelperCall ( ISelEnv* env,
       values.  But that's too much hassle. */
 
    /* Finally, the call itself. */
-   addInstr(env, ARMInstr_Call( cc, target, nextArgReg, rloc ));
+   addInstr(env, ARMInstr_Call( cc, target, nextArgReg, rloc, dflt ));
 
    return True; /* success */
 }
@@ -1371,7 +1371,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
          addInstr(env, mk_iMOVds_RR(hregARM_R0(), regL));
          addInstr(env, mk_iMOVds_RR(hregARM_R1(), regR));
          addInstr(env, ARMInstr_Call( ARMcc_AL, (HWord)Ptr_to_ULong(fn),
-                                      2, RetLocInt ));
+                                      2, RetLocInt, Idflt_None ));
          addInstr(env, mk_iMOVds_RR(res, hregARM_R0()));
          return res;
       }
@@ -1659,7 +1659,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
          HReg res = newVRegI(env);
          addInstr(env, mk_iMOVds_RR(hregARM_R0(), arg));
          addInstr(env, ARMInstr_Call( ARMcc_AL, (HWord)Ptr_to_ULong(fn),
-                                      1, RetLocInt ));
+                                      1, RetLocInt, Idflt_None ));
          addInstr(env, mk_iMOVds_RR(res, hregARM_R0()));
          return res;
       }
@@ -1722,7 +1722,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
       /* Marshal args, do the call, clear stack. */
       Bool ok = doHelperCall( env, False,
                               NULL, e->Iex.CCall.cee, e->Iex.CCall.args,
-                              RetLocInt );
+                              RetLocInt, Idflt_None );
       if (ok) {
          addInstr(env, mk_iMOVds_RR(dst, hregARM_R0()));
          return dst;
@@ -5929,7 +5929,8 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt )
       if (rloc == RetLocINVALID)
          break; /* will go to stmt_fail: */
 
-      Bool ok = doHelperCall( env, passBBP, d->guard, d->cee, d->args, rloc );
+      Bool ok = doHelperCall( env, passBBP, d->guard, d->cee, d->args,
+                              rloc, d->dflt );
       if (!ok)
          break; /* will go to stmt_fail: */