[llvm-commits] [llvm] r120408 - in /llvm/trunk: lib/Target/ARM/ARMCodeEmitter.cpp lib/Target/ARM/ARMInstrThumb.td lib/Target/ARM/ARMMCCodeEmitter.cpp lib/Target/ARM/AsmParser/ARMAsmParser.cpp test/MC/ARM/thumb.s

Bill Wendling isanbard at gmail.com
Mon Nov 29 23:44:32 PST 2010


Author: void
Date: Tue Nov 30 01:44:32 2010
New Revision: 120408

URL: http://llvm.org/viewvc/llvm-project?rev=120408&view=rev
Log:
Add parsing for the Thumb t_addrmode_s4 addressing mode. This can almost
certainly be made more generic. But it does allow us to parse something like:

          ldr     r3, [r2, r4]

correctly in Thumb mode.

Modified:
    llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
    llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
    llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
    llvm/trunk/test/MC/ARM/thumb.s

Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=120408&r1=120407&r2=120408&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Tue Nov 30 01:44:32 2010
@@ -235,8 +235,10 @@
       const { return 0;}
     uint32_t getAddrMode3OffsetOpValue(const MachineInstr &MI, unsigned OpIdx)
       const { return 0;}
-    uint32_t getAddrMode3OpValue(const MachineInstr &MI, unsigned Op) const
-      { return 0; }
+    uint32_t getAddrMode3OpValue(const MachineInstr &MI, unsigned Op)
+      const { return 0; }
+    uint32_t getAddrModeS4OpValue(const MachineInstr &MI, unsigned Op)
+      const { return 0; }
     uint32_t getAddrMode5OpValue(const MachineInstr &MI, unsigned Op) const {
       // {17-13} = reg
       // {12}    = (U)nsigned (add == '1', sub == '0')

Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=120408&r1=120407&r2=120408&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Tue Nov 30 01:44:32 2010
@@ -74,6 +74,11 @@
 
 // Define Thumb specific addressing modes.
 
+def MemModeThumbAsmOperand : AsmOperandClass {
+  let Name = "MemModeThumb";
+  let SuperClasses = [];
+}
+
 // t_addrmode_rr := reg + reg
 //
 def t_addrmode_rr : Operand<i32>,
@@ -87,8 +92,10 @@
 //
 def t_addrmode_s4 : Operand<i32>,
                     ComplexPattern<i32, 3, "SelectThumbAddrModeS4", []> {
+  string EncoderMethod = "getAddrModeS4OpValue";
   let PrintMethod = "printThumbAddrModeS4Operand";
   let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg);
+  let ParserMatchClass = MemModeThumbAsmOperand;
 }
 
 // t_addrmode_s2 := reg + reg
@@ -489,8 +496,7 @@
   let Inst{7-0}   = imm;
 }
 
-// A8.6.16 B: Encoding T1
-// If Inst{11-8} == 0b1110 then UNDEFINED
+// The assembler uses 0xDEFE for a trap instruction.
 let isBarrier = 1, isTerminator = 1 in
 def tTRAP : TI<(outs), (ins), IIC_Br, 
                "trap", [(trap)]>, Encoding16 {
@@ -505,12 +511,26 @@
 def tLDR : T1pI4<(outs tGPR:$Rt), (ins t_addrmode_s4:$addr), IIC_iLoad_r,
                  "ldr", "\t$Rt, $addr",
                  [(set tGPR:$Rt, (load t_addrmode_s4:$addr))]>,
-           T1LdSt<0b100>;
+           T1LdSt<0b100> {
+  // A8.6.60
+  bits<3> Rt;
+  bits<8> addr;
+  let Inst{8-6} = addr{5-3};    // Rm
+  let Inst{5-3} = addr{2-0};    // Rn
+  let Inst{2-0} = Rt;
+}
 
-def tLDRi: T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoad_r,
-               "ldr", "\t$dst, $addr",
+def tLDRi: T1pI4<(outs tGPR:$Rt), (ins t_addrmode_s4:$addr), IIC_iLoad_r,
+               "ldr", "\t$Rt, $addr",
                []>,
-           T1LdSt4Imm<{1,?,?}>;
+           T1LdSt4Imm<{1,?,?}> {
+  // A8.6.57
+  bits<3> Rt;
+  bits<8> addr;
+  let Inst{10-6} = addr{7-3};   // imm5
+  let Inst{5-3}  = addr{2-0};   // Rn
+  let Inst{2-0}  = Rt;
+}
 
 def tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoad_bh_r,
                 "ldrb", "\t$dst, $addr",

Modified: llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp?rev=120408&r1=120407&r2=120408&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp Tue Nov 30 01:44:32 2010
@@ -136,6 +136,10 @@
   uint32_t getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
                                SmallVectorImpl<MCFixup> &Fixups) const;
 
+  /// getAddrModeS4OpValue - Return encoding for t_addrmode_s4 operands.
+  uint32_t getAddrModeS4OpValue(const MCInst &MI, unsigned OpIdx,
+                                SmallVectorImpl<MCFixup> &Fixups) const;
+
   /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand.
   uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
                                SmallVectorImpl<MCFixup> &Fixups) const;
@@ -540,6 +544,26 @@
   return (Rn << 9) | Imm8 | (isAdd << 8) | (isImm << 13);
 }
 
+/// getAddrModeS4OpValue - Return encoding for t_addrmode_s4 operands.
+uint32_t ARMMCCodeEmitter::
+getAddrModeS4OpValue(const MCInst &MI, unsigned OpIdx,
+                     SmallVectorImpl<MCFixup> &Fixups) const {
+  // [Rn, Rm]
+  //   {5-3} = Rm
+  //   {2-0} = Rn
+  //
+  // [Rn, #imm]
+  //   {7-3} = imm5
+  //   {2-0} = Rn
+  const MCOperand &MO = MI.getOperand(OpIdx);
+  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
+  const MCOperand &MO2 = MI.getOperand(OpIdx + 2);
+  unsigned Rn = getARMRegisterNumbering(MO.getReg());
+  unsigned Imm5 = MO1.getImm();
+  unsigned Rm = getARMRegisterNumbering(MO2.getReg());
+  return (Rm << 3) | (Imm5 << 3) | Rn;
+}
+
 /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm12' operand.
 uint32_t ARMMCCodeEmitter::
 getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,

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=120408&r1=120407&r2=120408&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Tue Nov 30 01:44:32 2010
@@ -222,16 +222,30 @@
     if (!isMemory() || Mem.OffsetIsReg || Mem.OffsetRegShifted ||
         Mem.Writeback || Mem.Negative)
       return false;
+
     // If there is an offset expression, make sure it's valid.
-    if (!Mem.Offset)
-      return true;
+    if (!Mem.Offset) return true;
+
     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset);
-    if (!CE)
-      return false;
+    if (!CE) return false;
+
     // The offset must be a multiple of 4 in the range 0-1020.
     int64_t Value = CE->getValue();
     return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020);
   }
+  bool isMemModeThumb() const {
+    if (!isMemory() || (!Mem.OffsetIsReg && !Mem.Offset) || Mem.Writeback)
+      return false;
+
+    if (!Mem.Offset) return true;
+
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset);
+    if (!CE) return false;
+
+    // The offset must be a multiple of 4 in the range 0-124.
+    uint64_t Value = CE->getValue();
+    return ((Value & 0x3) == 0 && Value <= 124);
+  }
 
   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
     // Add as immediates when possible.  Null MCExpr = 0.
@@ -302,6 +316,21 @@
     }
   }
 
+  void addMemModeThumbOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 3 && isMemModeThumb() && "Invalid number of operands!");
+    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
+
+    if (Mem.Offset) {
+      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset);
+      assert(CE && "Non-constant mode offset operand!");
+      Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
+      Inst.addOperand(MCOperand::CreateReg(0));
+    } else {
+      Inst.addOperand(MCOperand::CreateImm(0));
+      Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
+    }
+  }
+
   virtual void dump(raw_ostream &OS) const;
 
   static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
@@ -592,8 +621,8 @@
     int OffsetRegNum;
     bool OffsetRegShifted;
     enum ShiftType ShiftType;
-    const MCExpr *ShiftAmount;
-    const MCExpr *Offset;
+    const MCExpr *ShiftAmount = 0;
+    const MCExpr *Offset = 0;
     if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount,
                              Offset, OffsetIsReg, OffsetRegNum, E))
       return true;

Modified: llvm/trunk/test/MC/ARM/thumb.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/thumb.s?rev=120408&r1=120407&r2=120408&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/thumb.s (original)
+++ llvm/trunk/test/MC/ARM/thumb.s Tue Nov 30 01:44:32 2010
@@ -32,3 +32,6 @@
 @ CHECK: uxth	r3, r6               @ encoding: [0xb3,0xb2]
 	uxtb	r3, r6
 	uxth	r3, r6
+
+@ CHECK: ldr	r3, [r1, r2]         @ encoding: [0x8b,0x58]
+	ldr	r3, [r1, r2]





More information about the llvm-commits mailing list