ARM STRD assembly parsing and encoding.
authorJim Grosbach <grosbach@apple.com>
Thu, 11 Aug 2011 20:28:23 +0000 (20:28 +0000)
committerJim Grosbach <grosbach@apple.com>
Thu, 11 Aug 2011 20:28:23 +0000 (20:28 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137342 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrFormats.td
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
test/MC/ARM/arm-memory-instructions.s

index 579f3835bcc49c13530c9993646c0baca9ab892d..343dee55622588b5674ea391dacc8f4bfabc1d74 100644 (file)
@@ -680,35 +680,6 @@ class AI3sthpr<dag oops, dag iops, Format f, InstrItinClass itin,
   let Inst{24}    = 1; // P bit
   let Inst{27-25} = 0b000;
 }
-class AI3stdpr<dag oops, dag iops, Format f, InstrItinClass itin,
-             string opc, string asm, string cstr, list<dag> pattern>
-  : I<oops, iops, AddrMode3, 4, IndexModePre, f, itin,
-      opc, asm, cstr, pattern> {
-  let Inst{4}     = 1;
-  let Inst{5}     = 1; // H bit
-  let Inst{6}     = 1; // S bit
-  let Inst{7}     = 1;
-  let Inst{20}    = 0; // L bit
-  let Inst{21}    = 1; // W bit
-  let Inst{24}    = 1; // P bit
-  let Inst{27-25} = 0b000;
-}
-
-// Post-indexed stores
-class AI3stdpo<dag oops, dag iops, Format f, InstrItinClass itin,
-             string opc, string asm, string cstr, list<dag> pattern>
-  : I<oops, iops, AddrMode3, 4, IndexModePost, f, itin,
-      opc, asm, cstr, pattern> {
-  let Inst{4}     = 1;
-  let Inst{5}     = 1; // H bit
-  let Inst{6}     = 1; // S bit
-  let Inst{7}     = 1;
-  let Inst{20}    = 0; // L bit
-  let Inst{21}    = 0; // W bit
-  let Inst{24}    = 0; // P bit
-  let Inst{27-25} = 0b000;
-}
-
 // addrmode4 instructions
 class AXI4<dag oops, dag iops, IndexMode im, Format f, InstrItinClass itin,
            string asm, string cstr, list<dag> pattern>
index c8eb0257313fb755d65983314551d1c3c3bec6c0..df86d12266edbefc1f2d27257d8b78ab5f3fe98f 100644 (file)
@@ -2369,42 +2369,35 @@ def STRH_POST: AI3stridx<0b1011, 0, 0, (outs GPR:$Rn_wb),
                      [(set GPR:$Rn_wb, (post_truncsti16 GPR:$Rt,
                                         GPR:$Rn, am3offset:$offset))]>;
 
-// For disassembly only
 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in {
-def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
-                     (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
-                     StMiscFrm, IIC_iStore_d_ru,
-                     "strd", "\t$src1, $src2, [$base, $offset]!",
-                     "$base = $base_wb", []> {
-  bits<4> src1;
-  bits<4> base;
-  bits<10> offset;
-  let Inst{23} = offset{8}; // U bit
-  let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm
-  let Inst{19-16} = base;
-  let Inst{15-12} = src1;
-  let Inst{11-8}  = offset{7-4};
-  let Inst{3-0}   = offset{3-0};
-
+def STRD_PRE : AI3ldstidx<0b1111, 0, 1, 1, (outs GPR:$Rn_wb),
+                          (ins GPR:$Rt, GPR:$Rt2, addrmode3:$addr),
+                          IndexModePre, StMiscFrm, IIC_iStore_d_ru,
+                          "strd", "\t$Rt, $Rt2, $addr!",
+                          "$addr.base = $Rn_wb", []> {
+  bits<14> addr;
+  let Inst{23}    = addr{8};      // U bit
+  let Inst{22}    = addr{13};     // 1 == imm8, 0 == Rm
+  let Inst{19-16} = addr{12-9};   // Rn
+  let Inst{11-8}  = addr{7-4};    // imm7_4/zero
+  let Inst{3-0}   = addr{3-0};    // imm3_0/Rm
   let DecoderMethod = "DecodeAddrMode3Instruction";
+  let AsmMatchConverter = "cvtStrdPre";
 }
 
-// For disassembly only
-def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
-                     (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
-                     StMiscFrm, IIC_iStore_d_ru,
-                     "strd", "\t$src1, $src2, [$base], $offset",
-                     "$base = $base_wb", []> {
-  bits<4> src1;
-  bits<4> base;
+def STRD_POST: AI3ldstidx<0b1111, 0, 1, 0, (outs GPR:$Rn_wb),
+                          (ins GPR:$Rt, GPR:$Rt2, addr_offset_none:$addr,
+                               am3offset:$offset),
+                          IndexModePost, StMiscFrm, IIC_iStore_d_ru,
+                          "strd", "\t$Rt, $Rt2, $addr, $offset",
+                          "$addr.base = $Rn_wb", []> {
   bits<10> offset;
-  let Inst{23} = offset{8}; // U bit
-  let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm
-  let Inst{19-16} = base;
-  let Inst{15-12} = src1;
-  let Inst{11-8}  = offset{7-4};
-  let Inst{3-0}   = offset{3-0};
-
+  bits<4> addr;
+  let Inst{23}    = offset{8};      // U bit
+  let Inst{22}    = offset{9};      // 1 == imm8, 0 == Rm
+  let Inst{19-16} = addr;
+  let Inst{11-8}  = offset{7-4};    // imm7_4/zero
+  let Inst{3-0}   = offset{3-0};    // imm3_0/Rm
   let DecoderMethod = "DecodeAddrMode3Instruction";
 }
 } // mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1
index 31d2b807edf7da112b54964b6198b0f70fb751ae..fc8a4847014e7058179b17dd0499cb55bc684532 100644 (file)
@@ -133,6 +133,8 @@ class ARMAsmParser : public MCTargetAsmParser {
                              const SmallVectorImpl<MCParsedAsmOperand*> &);
   bool cvtLdrdPre(MCInst &Inst, unsigned Opcode,
                   const SmallVectorImpl<MCParsedAsmOperand*> &);
+  bool cvtStrdPre(MCInst &Inst, unsigned Opcode,
+                  const SmallVectorImpl<MCParsedAsmOperand*> &);
   bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
                                   const SmallVectorImpl<MCParsedAsmOperand*> &);
 
@@ -2224,6 +2226,24 @@ cvtLdrdPre(MCInst &Inst, unsigned Opcode,
   return true;
 }
 
+/// cvtStrdPre - Convert parsed operands to MCInst.
+/// Needed here because the Asm Gen Matcher can't handle properly tied operands
+/// when they refer multiple MIOperands inside a single one.
+bool ARMAsmParser::
+cvtStrdPre(MCInst &Inst, unsigned Opcode,
+           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+  // Create a writeback register dummy placeholder.
+  Inst.addOperand(MCOperand::CreateImm(0));
+  // Rt, Rt2
+  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
+  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
+  // addr
+  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
+  // pred
+  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
+  return true;
+}
+
 /// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
 /// Needed here because the Asm Gen Matcher can't handle properly tied operands
 /// when they refer multiple MIOperands inside a single one.
@@ -2850,7 +2870,15 @@ validateInstruction(MCInst &Inst,
                    "destination operands must be sequential");
     return false;
   }
-  case ARM::STRD:
+  case ARM::STRD: {
+    // Rt2 must be Rt + 1.
+    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
+    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
+    if (Rt2 != Rt + 1)
+      return Error(Operands[3]->getStartLoc(),
+                   "source operands must be sequential");
+    return false;
+  }
   case ARM::STRD_PRE:
   case ARM::STRD_POST:
   case ARM::STREXD: {
@@ -2858,7 +2886,7 @@ validateInstruction(MCInst &Inst,
     unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg());
     unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg());
     if (Rt2 != Rt + 1)
-      return Error(Operands[4]->getStartLoc(),
+      return Error(Operands[3]->getStartLoc(),
                    "source operands must be sequential");
     return false;
   }
index 8af12063e020e358c6995ce4aa90dfb5486cc708..49b4216f8883acbed41f6905e5f13edf68c2d05a 100644 (file)
@@ -389,3 +389,42 @@ _func:
 @ CHECK: strbt r5, [r6], #-13          @ encoding: [0x0d,0x50,0x66,0xe4]
 @ CHECK: strbt r4, [r9], r5            @ encoding: [0x05,0x40,0xe9,0xe6]
 @ CHECK: strbt r3, [r8], -r2, lsl #3   @ encoding: [0x82,0x31,0x68,0xe6]
+
+
+@------------------------------------------------------------------------------
+@ STRD (immediate)
+@------------------------------------------------------------------------------
+        strd r1, r2, [r4]
+        strd r2, r3, [r6, #1]
+        strd r3, r4, [r7, #22]!
+        strd r4, r5, [r8], #7
+        strd r5, r6, [sp], #0
+        strd r6, r7, [lr], #+0
+        strd r7, r8, [r9], #-0
+
+@ CHECK: strd  r1, r2, [r4]            @ encoding: [0xf0,0x10,0xc4,0xe1]
+@ CHECK: strd  r2, r3, [r6, #1]        @ encoding: [0xf1,0x20,0xc6,0xe1]
+@ CHECK: strd  r3, r4, [r7, #22]!      @ encoding: [0xf6,0x31,0xe7,0xe1]
+@ CHECK: strd  r4, r5, [r8], #7        @ encoding: [0xf7,0x40,0xc8,0xe0]
+@ CHECK: strd  r5, r6, [sp], #0        @ encoding: [0xf0,0x50,0xcd,0xe0]
+@ CHECK: strd  r6, r7, [lr], #0        @ encoding: [0xf0,0x60,0xce,0xe0]
+@ CHECK: strd  r7, r8, [r9], #-0       @ encoding: [0xf0,0x70,0x49,0xe0]
+
+
+@------------------------------------------------------------------------------
+@ FIXME: STRD (label)
+@------------------------------------------------------------------------------
+
+@------------------------------------------------------------------------------
+@ STRD (register)
+@------------------------------------------------------------------------------
+        strd r8, r9, [r4, r1]
+        strd r7, r8, [r3, r9]!
+        strd r6, r7, [r5], r8
+        strd r5, r6, [r12], -r10
+
+@ CHECK: strd  r8, r9, [r4, r1]        @ encoding: [0xf1,0x80,0x84,0xe1]
+@ CHECK: strd  r7, r8, [r3, r9]!       @ encoding: [0xf9,0x70,0xa3,0xe1]
+@ CHECK: strd  r6, r7, [r5], r8        @ encoding: [0xf8,0x60,0x85,0xe0]
+@ CHECK: strd  r5, r6, [r12], -r10     @ encoding: [0xfa,0x50,0x0c,0xe0]
+