]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
mips: Fix SAVE instruction for nanoMIPS
authorAleksandar Rikalo <aleksandar.rikalo@rt-rk.com>
Tue, 14 Jan 2020 11:54:15 +0000 (11:54 +0000)
committerPetar Jovanovic <mips32r2@gmail.com>
Tue, 14 Jan 2020 11:54:15 +0000 (11:54 +0000)
During a save (push) instruction adjusting the SP is required before doing
a store, otherwise Memcheck reports warning because of a write operation
outside of the stack area.

VEX/priv/guest_nanomips_toIR.c

index 200089651066b8540394e46cf7e3d4f75a0894a1..67f2313d5f11bcfb9d94d2931884a2d855f5fb3b 100755 (executable)
@@ -980,17 +980,21 @@ static void nano_ppsr(DisResult *dres, UInt cins)
          DIP("save %u, r%u-r%u", u, (rt & 0x1fu) | (rt & 0x10u),
              ((rt + count - 1) & 0x1fu) | (rt & 0x10u));
 
+         IRTemp t1 = newTemp(Ity_I32);
+         assign(t1, getIReg(29));
+
+         putIReg(29, binop(Iop_Sub32, mkexpr(t1), mkU32(u)));
+
          while (counter != count) {
             Bool use_gp = (cins & 0x04) && (counter + 1 == count);
             UChar this_rt = use_gp ? 28 : (UChar)((rt + counter) & 0x1f)
                                           | (rt & 0x10);
             Int offset = -((counter + 1) << 2);
-            store(binop(Iop_Add32, getIReg(29), mkU32(offset)),
+            store(binop(Iop_Add32, mkexpr(t1), mkU32(offset)),
                   getIReg(this_rt));
             counter++;
          }
 
-         putIReg(29, binop(Iop_Sub32, getIReg(29), mkU32(u)));
          break;
       }
 
@@ -2328,14 +2332,17 @@ static void nano_p16sr(DisResult *dres, UShort cins)
       DIP("save %u, r%u-r%u", u, (rt & 0x1fu) | (rt & 0x10u),
           ((rt + count - 1) & 0x1fu) | (rt & 0x10u));
 
+      IRTemp t1 = newTemp(Ity_I32);
+      assign(t1, getIReg(29));
+
+      putIReg(29, binop(Iop_Sub32, mkexpr(t1), mkU32(u)));
+
       while (counter != count) {
          UChar this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
          Int offset = -((counter + 1) << 2);
-         store(binop(Iop_Add32, getIReg(29), mkU32(offset)), getIReg(this_rt));
+         store(binop(Iop_Add32, mkexpr(t1), mkU32(offset)), getIReg(this_rt));
          counter++;
       }
-
-      putIReg(29, binop(Iop_Sub32, getIReg(29), mkU32(u)));
    }
 }