OSDN Git Service

add simple support for addrmode5 operands, allowing
authorChris Lattner <sabre@nondot.org>
Fri, 29 Oct 2010 00:27:31 +0000 (00:27 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 29 Oct 2010 00:27:31 +0000 (00:27 +0000)
vldr.64 to work.  I have no idea if this is fully right, but
it is in the right direction.

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

lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
test/MC/ARM/arm_instructions.s

index dd38119..40c099e 100644 (file)
@@ -456,12 +456,18 @@ def addrmode4 : Operand<i32>,
   let MIOperandInfo = (ops GPR:$addr, i32imm);
 }
 
+def ARMMemMode5AsmOperand : AsmOperandClass {
+  let Name = "MemMode5";
+  let SuperClasses = [];
+}
+
 // addrmode5 := reg +/- imm8*4
 //
 def addrmode5 : Operand<i32>,
                 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
   let PrintMethod = "printAddrMode5Operand";
   let MIOperandInfo = (ops GPR:$base, i32imm);
+  let ParserMatchClass = ARMMemMode5AsmOperand;
 }
 
 // addrmode6 := reg with optional writeback
index 88b2c61..648b54a 100644 (file)
@@ -153,9 +153,6 @@ public:
 
   };
   
-  //ARMOperand(KindTy K, SMLoc S, SMLoc E)
-  //  : Kind(K), StartLoc(S), EndLoc(E) {}
-  
   ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
     Kind = o.Kind;
     StartLoc = o.StartLoc;
@@ -205,16 +202,16 @@ public:
   }
 
   bool isCondCode() const { return Kind == CondCode; }
-
   bool isImm() const { return Kind == Immediate; }
-
   bool isReg() const { return Kind == Register; }
-
-  bool isToken() const {return Kind == Token; }
+  bool isToken() const { return Kind == Token; }
+  bool isMemory() const { return Kind == Memory; }
 
   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
-    // Add as immediates when possible.
-    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
+    // Add as immediates when possible.  Null MCExpr = 0.
+    if (Expr == 0)
+      Inst.addOperand(MCOperand::CreateImm(0));
+    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
       Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
     else
       Inst.addOperand(MCOperand::CreateExpr(Expr));
@@ -236,6 +233,24 @@ public:
     assert(N == 1 && "Invalid number of operands!");
     addExpr(Inst, getImm());
   }
+  
+  
+  bool isMemMode5() const {
+    // FIXME: Is this right?  What about postindexed and Writeback?
+    if (!isMemory() || Mem.OffsetIsReg || Mem.OffsetRegShifted ||
+        Mem.Preindexed || Mem.Negative)
+      return false;
+    
+    return true;
+  }
+  
+  void addMemMode5Operands(MCInst &Inst, unsigned N) const {
+    assert(N == 2 && isMemMode5() && "Invalid number of operands!");
+    
+    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
+    assert(!Mem.OffsetIsReg && "invalid mode 5 operand");
+    addExpr(Inst, Mem.Offset);
+  }
 
   virtual void dump(raw_ostream &OS) const;
 
@@ -508,7 +523,7 @@ ARMOperand *ARMAsmParser::ParseMemory() {
     bool OffsetRegShifted = false;
     enum ShiftType ShiftType;
     const MCExpr *ShiftAmount;
-    const MCExpr *Offset;
+    const MCExpr *Offset = 0;
 
     const AsmToken &NextTok = Parser.getTok();
     if (NextTok.isNot(AsmToken::EndOfStatement)) {
index d538594..18a8cfa 100644 (file)
@@ -16,3 +16,7 @@ bx lr
 @ CHECK: encoding: [0xa0,0x0d,0xe1,0xf2]
 vqdmull.s32     q8, d17, d16
 
+@ CHECK: vldr.64       d17, [r0]
+@ CHECK: encoding: [0x00,0x0b,0x10,0xed]
+vldr.64        d17, [r0]
+