]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
arm64: implement: LD1/ST1 (multi 1-elem structs, 2 regs, post index)
authorJulian Seward <jseward@acm.org>
Tue, 15 Jul 2014 11:08:42 +0000 (11:08 +0000)
committerJulian Seward <jseward@acm.org>
Tue, 15 Jul 2014 11:08:42 +0000 (11:08 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@2901

VEX/priv/guest_arm64_toIR.c

index 60ef7ea6e73d39406f4b25d923302c482445d0b4..1b91c61d396c19b1030f05e2c6aa9fa1cfbdddfc 100644 (file)
@@ -4690,6 +4690,37 @@ Bool dis_ARM64_load_store(/*MB_OUT*/DisResult* dres, UInt insn)
          storeLE(tEA_0,  getQReg128((vT+0) % 32));
          storeLE(tEA_16, getQReg128((vT+1) % 32));
       }
+      DIP("%s {v%u.%s, v%u.%s}, [%s]\n", isLD ? "ld1" : "st1",
+          (vT+0) % 32, name, (vT+1) % 32, name, nameIReg64orSP(rN));
+      return True;
+   }
+
+   /* -------- LD1/ST1 (multi 1-elem structs, 2 regs, post index) -------- */
+   /* Only a very few cases. */
+   /* 31        23
+      0100 1100 1101 1111 1010 00 n t LD1 {Vt.16b, V(t+1)%32.16b}, [Xn|SP], #32
+      0100 1100 1001 1111 1010 00 n t ST1 {Vt.16b, V(t+1)%32.16b}, [Xn|SP], #32
+   */
+   if (   (insn & 0xFFFFFC00) == 0x4CDFA000 // LD1
+       || (insn & 0xFFFFFC00) == 0x4C9FA000 // ST1
+      ) {
+      Bool   isLD = INSN(22,22) == 1;
+      UInt   rN   = INSN(9,5);
+      UInt   vT   = INSN(4,0);
+      IRTemp tEA  = newTemp(Ity_I64);
+      const HChar* name = "16b";
+      assign(tEA, getIReg64orSP(rN));
+      if (rN == 31) { /* FIXME generate stack alignment check */ }
+      IRExpr* tEA_0  = binop(Iop_Add64, mkexpr(tEA), mkU64(0));
+      IRExpr* tEA_16 = binop(Iop_Add64, mkexpr(tEA), mkU64(16));
+      if (isLD) {
+         putQReg128((vT+0) % 32, loadLE(Ity_V128, tEA_0));
+         putQReg128((vT+1) % 32, loadLE(Ity_V128, tEA_16));
+      } else {
+         storeLE(tEA_0,  getQReg128((vT+0) % 32));
+         storeLE(tEA_16, getQReg128((vT+1) % 32));
+      }
+      putIReg64orSP(rN, binop(Iop_Add64, mkexpr(tEA), mkU64(32)));
       DIP("%s {v%u.%s, v%u.%s}, [%s], #32\n", isLD ? "ld1" : "st1",
           (vT+0) % 32, name, (vT+1) % 32, name, nameIReg64orSP(rN));
       return True;