[llvm-commits] [llvm] r136982 - in /llvm/trunk: lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/AsmParser/ARMAsmParser.cpp test/MC/ARM/arm-memory-instructions.s

Jim Grosbach grosbach at apple.com
Fri Aug 5 14:28:31 PDT 2011


Author: grosbach
Date: Fri Aug  5 16:28:30 2011
New Revision: 136982

URL: http://llvm.org/viewvc/llvm-project?rev=136982&view=rev
Log:
ARM indexed load assembly parsing and encoding.

More parsing support for indexed loads. Fix pre-indexed with writeback
parsing for register offsets and handle basic post-indexed offsets.

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

Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=136982&r1=136981&r2=136982&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Fri Aug  5 16:28:30 2011
@@ -665,11 +665,17 @@
   let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
 }
 
+def PostIdxRegShiftedAsmOperand : AsmOperandClass {
+  let Name = "PostIdxRegShifted";
+  let ParserMethod = "parsePostIdxReg";
+}
 def am2offset_reg : Operand<i32>,
                 ComplexPattern<i32, 2, "SelectAddrMode2OffsetReg",
                 [], [SDNPWantRoot]> {
   let EncoderMethod = "getAddrMode2OffsetOpValue";
   let PrintMethod = "printAddrMode2OffsetOperand";
+  // When using this for assembly, it's always as a post-index offset.
+  let ParserMatchClass = PostIdxRegShiftedAsmOperand;
   let MIOperandInfo = (ops GPR, i32imm);
 }
 

Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=136982&r1=136981&r2=136982&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Fri Aug  5 16:28:30 2011
@@ -232,7 +232,9 @@
 
     struct {
       unsigned RegNum;
-      unsigned Imm;
+      bool isAdd;
+      ARM_AM::ShiftOpc ShiftTy;
+      unsigned ShiftImm;
     } PostIdxReg;
 
     struct {
@@ -498,12 +500,15 @@
   bool isToken() const { return Kind == Token; }
   bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
   bool isMemory() const { return Kind == Memory; }
-  bool isPostIdxReg() const { return Kind == PostIndexRegister; }
   bool isShifterImm() const { return Kind == ShifterImmediate; }
   bool isRegShiftedReg() const { return Kind == ShiftedRegister; }
   bool isRegShiftedImm() const { return Kind == ShiftedImmediate; }
   bool isRotImm() const { return Kind == RotateImmediate; }
   bool isBitfield() const { return Kind == BitfieldDescriptor; }
+  bool isPostIdxRegShifted() const { return Kind == PostIndexRegister; }
+  bool isPostIdxReg() const {
+    return Kind == PostIndexRegister && PostIdxReg.ShiftTy == ARM_AM::no_shift;
+  }
   bool isMemNoOffset() const {
     if (Kind != Memory)
       return false;
@@ -858,7 +863,18 @@
   void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
     assert(N == 2 && "Invalid number of operands!");
     Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
-    Inst.addOperand(MCOperand::CreateImm(PostIdxReg.Imm));
+    Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd));
+  }
+
+  void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 2 && "Invalid number of operands!");
+    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
+    // The sign, shift type, and shift amount are encoded in a single operand
+    // using the AM2 encoding helpers.
+    ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
+    unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
+                                     PostIdxReg.ShiftTy);
+    Inst.addOperand(MCOperand::CreateImm(Imm));
   }
 
   void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
@@ -1027,11 +1043,15 @@
     return Op;
   }
 
-  static ARMOperand *CreatePostIdxReg(unsigned RegNum, unsigned Imm,
+  static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd,
+                                      ARM_AM::ShiftOpc ShiftTy,
+                                      unsigned ShiftImm,
                                       SMLoc S, SMLoc E) {
     ARMOperand *Op = new ARMOperand(PostIndexRegister);
     Op->PostIdxReg.RegNum = RegNum;
-    Op->PostIdxReg.Imm = Imm;
+    Op->PostIdxReg.isAdd = isAdd;
+    Op->PostIdxReg.ShiftTy = ShiftTy;
+    Op->PostIdxReg.ShiftImm = ShiftImm;
     Op->StartLoc = S;
     Op->EndLoc = E;
     return Op;
@@ -1093,9 +1113,12 @@
     OS << ">";
     break;
   case PostIndexRegister:
-    OS << "post-idx register " << (PostIdxReg.Imm ? "" : "-")
-       << PostIdxReg.RegNum
-       << ">";
+    OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
+       << PostIdxReg.RegNum;
+    if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
+      OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
+         << PostIdxReg.ShiftImm;
+    OS << ">";
     break;
   case ProcIFlags: {
     OS << "<ARM_PROC::";
@@ -1861,9 +1884,9 @@
 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
 parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
   // Check for a post-index addressing register operand. Specifically:
-  // postidx_reg := '+' register
-  //              | '-' register
-  //              | register
+  // postidx_reg := '+' register {, shift}
+  //              | '-' register {, shift}
+  //              | register {, shift}
 
   // This method must return MatchOperand_NoMatch without consuming any tokens
   // in the case where there is no match, as other alternatives take other
@@ -1891,7 +1914,11 @@
   }
   SMLoc E = Parser.getTok().getLoc();
 
-  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, S, E));
+  ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift;
+  unsigned ShiftImm = 0;
+
+  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy,
+                                                  ShiftImm, S, E));
 
   return MatchOperand_Success;
 }
@@ -2107,7 +2134,12 @@
                                            ShiftType, ShiftValue, isNegative,
                                            S, E));
 
-
+  // If there's a pre-indexing writeback marker, '!', just add it as a token
+  // operand.
+  if (Parser.getTok().is(AsmToken::Exclaim)) {
+    Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
+    Parser.Lex(); // Eat the '!'.
+  }
 
   return false;
 }

Modified: llvm/trunk/test/MC/ARM/arm-memory-instructions.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/arm-memory-instructions.s?rev=136982&r1=136981&r2=136982&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/arm-memory-instructions.s (original)
+++ llvm/trunk/test/MC/ARM/arm-memory-instructions.s Fri Aug  5 16:28:30 2011
@@ -24,3 +24,19 @@
 @ CHECK: ldr	r3, [r1], #-30          @ encoding: [0x1e,0x30,0x11,0xe4]
 
 
+ at ------------------------------------------------------------------------------
+@ LDR (register)
+ at ------------------------------------------------------------------------------
+        ldr r3, [r8, r1]
+        ldr r2, [r5, -r3]
+        ldr r1, [r5, r9]!
+        ldr r6, [r7, -r8]!
+        ldr r5, [r9], r2
+        ldr r4, [r3], -r6
+
+@ CHECK: ldr	r3, [r8, r1]            @ encoding: [0x01,0x30,0x98,0xe7]
+@ CHECK: ldr	r2, [r5, -r3]           @ encoding: [0x03,0x20,0x15,0xe7]
+@ CHECK: ldr	r1, [r5, r9]!           @ encoding: [0x09,0x10,0xb5,0xe7]
+@ CHECK: ldr	r6, [r7, -r8]!          @ encoding: [0x08,0x60,0x37,0xe7]
+@ CHECK: ldr	r5, [r9], r2            @ encoding: [0x02,0x50,0x99,0xe6]
+@ CHECK: ldr	r4, [r3], -r6           @ encoding: [0x06,0x40,0x13,0xe6]





More information about the llvm-commits mailing list