ARM IAS: support GNU extension for ldrd, strd
authorSaleem Abdulrasool <compnerd@compnerd.org>
Fri, 10 Jan 2014 04:38:35 +0000 (04:38 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Fri, 10 Jan 2014 04:38:35 +0000 (04:38 +0000)
The GNU assembler has an extension that allows for the elision of the paired
register (dt2) for the LDRD and STRD mnemonics.  Add support for this in the
assembly parser.  Canonicalise the usage during the instruction parsing from
the specified version.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198915 91177308-0d34-0410-b5e6-96231b3b80d8

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

index b80eefd398c726acfa2f9fe757e61a336dbb3201..ad134d3f99c37745afd2f49df1565c36fdd5c7e5 100644 (file)
@@ -2280,6 +2280,12 @@ let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
   def LDRD : AI3ld<0b1101, 0, (outs GPR:$Rt, GPR:$Rt2), (ins addrmode3:$addr),
                    LdMiscFrm, IIC_iLoad_d_r, "ldrd", "\t$Rt, $Rt2, $addr", []>,
              Requires<[IsARM, HasV5TE]>;
+
+  // GNU Assembler extension (compatibility)
+  let isAsmParserOnly = 1 in
+    def LDRD_PAIR : AI3ld<0b1101, 0, (outs GPRPairOp:$Rt), (ins addrmode3:$addr),
+                          LdMiscFrm, IIC_iLoad_d_r, "ldrd", "\t$Rt, $addr", []>,
+                    Requires<[IsARM, HasV5TE]>;
 }
 
 def LDA : AIldracq<0b00, (outs GPR:$Rt), (ins addr_offset_none:$addr),
@@ -2545,13 +2551,22 @@ def STRH : AI3str<0b1011, (outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm,
                [(truncstorei16 GPR:$Rt, addrmode3:$addr)]>;
 
 // Store doubleword
-let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
+let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in {
   def STRD : AI3str<0b1111, (outs), (ins GPR:$Rt, GPR:$Rt2, addrmode3:$addr),
                     StMiscFrm, IIC_iStore_d_r, "strd", "\t$Rt, $Rt2, $addr", []>,
              Requires<[IsARM, HasV5TE]> {
     let Inst{21} = 0;
   }
 
+  // GNU Assembler extension (compatibility)
+  let isAsmParserOnly = 1 in
+    def STRD_PAIR : AI3str<0b1111, (outs), (ins GPRPairOp:$Rt, addrmode3:$addr),
+                           StMiscFrm, IIC_iStore_d_r, "strd", "\t$Rt, $addr", []>,
+                    Requires<[IsARM, HasV5TE]> {
+      let Inst{21} = 0;
+    }
+}
+
 // Indexed stores
 multiclass AI2_stridx<bit isByte, string opc,
                       InstrItinClass iii, InstrItinClass iir> {
index c4f7b01352aaf6b0543c45ff7054a7803224bb3b..bebbab5327be2f8bc0fdda6f9e96971c05efafc3 100644 (file)
@@ -5445,6 +5445,19 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
     }
   }
 
+  // GNU Assembler extension (compatibility)
+  if ((Mnemonic == "ldrd" || Mnemonic == "strd") && !isThumb() &&
+      Operands.size() == 4) {
+    ARMOperand *Op = static_cast<ARMOperand *>(Operands[2]);
+    assert(Op->isReg() && "expected register argument");
+    assert(MRI->getMatchingSuperReg(Op->getReg(), ARM::gsub_0,
+                                    &MRI->getRegClass(ARM::GPRPairRegClassID))
+           && "expected register pair");
+    Operands.insert(Operands.begin() + 3,
+                    ARMOperand::CreateReg(Op->getReg() + 1, Op->getStartLoc(),
+                                          Op->getEndLoc()));
+  }
+
   // FIXME: As said above, this is all a pretty gross hack.  This instruction
   // does not fit with other "subs" and tblgen.
   // Adjust operands of B9.3.19 SUBS PC, LR, #imm (Thumb2) system instruction
@@ -8793,6 +8806,11 @@ unsigned ARMAsmParser::validateTargetOperandClass(MCParsedAsmOperand *AsmOp,
              "expression value must be representiable in 32 bits");
     }
     break;
+  case MCK_GPRPair:
+    if (Op->isReg() &&
+        MRI->getRegClass(ARM::GPRRegClassID).contains(Op->getReg()))
+      return Match_Success;
+    break;
   }
   return Match_InvalidOperand;
 }
index ad35dd26a04ad0e02ba08da14bd47ddde81073ca..f41c779b8f6bf91b7b4cb47ffc5488cbf63ceac9 100644 (file)
@@ -485,3 +485,14 @@ Lbaz: .quad 0
 @ CHECK: strht r8, [r1], #-25          @ encoding: [0xb9,0x81,0x61,0xe0]
 @ CHECK: strht r5, [r3], r4            @ encoding: [0xb4,0x50,0xa3,0xe0]
 @ CHECK: strht r6, [r8], -r0           @ encoding: [0xb0,0x60,0x28,0xe0]
+
+@------------------------------------------------------------------------------
+@ GNU Assembler Compatibility
+@------------------------------------------------------------------------------
+
+       ldrd r0, [sp]
+       strd r0, [sp]
+
+@ CHECK: ldrd r0, r1, [sp]              @ encoding: [0xd0,0x00,0xcd,0xe1]
+@ CHECK: strd r0, r1, [sp]              @ encoding: [0xf0,0x00,0xcd,0xe1]
+