[llvm-commits] [llvm] r138488 - in /llvm/trunk: lib/Target/ARM/ARMInstrThumb.td lib/Target/ARM/AsmParser/ARMAsmParser.cpp test/MC/ARM/basic-thumb-instructions.s test/MC/ARM/thumb-diagnostics.s utils/TableGen/EDEmitter.cpp

Jim Grosbach grosbach at apple.com
Wed Aug 24 14:22:15 PDT 2011


Author: grosbach
Date: Wed Aug 24 16:22:15 2011
New Revision: 138488

URL: http://llvm.org/viewvc/llvm-project?rev=138488&view=rev
Log:
Thumb parsing and encoding support for ADD SP instructions.

Fix the test FIXME and add parsing support for the ADD (SP plus immediate)
and ADD (SP plus register) instruction forms.

Modified:
    llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
    llvm/trunk/test/MC/ARM/basic-thumb-instructions.s
    llvm/trunk/test/MC/ARM/thumb-diagnostics.s
    llvm/trunk/utils/TableGen/EDEmitter.cpp

Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=138488&r1=138487&r2=138488&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Wed Aug 24 16:22:15 2011
@@ -78,8 +78,17 @@
 }
 
 // Scaled 4 immediate.
-def t_imm_s4 : Operand<i32> {
+def t_imm0_1020s4_asmoperand: AsmOperandClass { let Name = "Imm0_1020s4"; }
+def t_imm0_1020s4 : Operand<i32> {
   let PrintMethod = "printThumbS4ImmOperand";
+  let ParserMatchClass = t_imm0_1020s4_asmoperand;
+  let OperandType = "OPERAND_IMMEDIATE";
+}
+
+def t_imm0_508s4_asmoperand: AsmOperandClass { let Name = "Imm0_508s4"; }
+def t_imm0_508s4 : Operand<i32> {
+  let PrintMethod = "printThumbS4ImmOperand";
+  let ParserMatchClass = t_imm0_508s4_asmoperand;
   let OperandType = "OPERAND_IMMEDIATE";
 }
 
@@ -305,35 +314,39 @@
 // This is rematerializable, which is particularly useful for taking the
 // address of locals.
 let isReMaterializable = 1 in
-def tADDrSPi : T1pI<(outs tGPR:$dst), (ins GPRsp:$sp, t_imm_s4:$rhs), IIC_iALUi,
-                   "add", "\t$dst, $sp, $rhs", []>,
+def tADDrSPi : T1pI<(outs tGPR:$dst), (ins GPRsp:$sp, t_imm0_1020s4:$imm),
+                    IIC_iALUi, "add", "\t$dst, $sp, $imm", []>,
                T1Encoding<{1,0,1,0,1,?}> {
   // A6.2 & A8.6.8
   bits<3> dst;
-  bits<8> rhs;
+  bits<8> imm;
   let Inst{10-8} = dst;
-  let Inst{7-0}  = rhs;
+  let Inst{7-0}  = imm;
   let DecoderMethod = "DecodeThumbAddSpecialReg";
 }
 
 // ADD sp, sp, #<imm7>
-def tADDspi : T1pIt<(outs GPRsp:$Rdn), (ins GPRsp:$Rn, t_imm_s4:$rhs),
-                     IIC_iALUi, "add", "\t$Rdn, $rhs", []>,
+def tADDspi : T1pIt<(outs GPRsp:$Rdn), (ins GPRsp:$Rn, t_imm0_508s4:$imm),
+                     IIC_iALUi, "add", "\t$Rdn, $imm", []>,
               T1Misc<{0,0,0,0,0,?,?}> {
   // A6.2.5 & A8.6.8
-  bits<7> rhs;
-  let Inst{6-0} = rhs;
+  bits<7> imm;
+  let Inst{6-0} = imm;
   let DecoderMethod = "DecodeThumbAddSPImm";
 }
 
+// Can optionally specify SP as a three operand instruction.
+def : tInstAlias<"add${p} sp, sp, $imm",
+                 (tADDspi SP, t_imm0_508s4:$imm, pred:$p)>;
+
 // SUB sp, sp, #<imm7>
 // FIXME: The encoding and the ASM string don't match up.
-def tSUBspi : T1pIt<(outs GPRsp:$Rdn), (ins GPRsp:$Rn, t_imm_s4:$rhs),
-                    IIC_iALUi, "sub", "\t$Rdn, $rhs", []>,
+def tSUBspi : T1pIt<(outs GPRsp:$Rdn), (ins GPRsp:$Rn, t_imm0_508s4:$imm),
+                    IIC_iALUi, "sub", "\t$Rdn, $imm", []>,
               T1Misc<{0,0,0,0,1,?,?}> {
   // A6.2.5 & A8.6.214
-  bits<7> rhs;
-  let Inst{6-0} = rhs;
+  bits<7> imm;
+  let Inst{6-0} = imm;
   let DecoderMethod = "DecodeThumbAddSPImm";
 }
 
@@ -350,13 +363,13 @@
 }
 
 // ADD sp, <Rm>
-def tADDspr : T1pIt<(outs GPRsp:$Rdn), (ins GPRsp:$Rn, GPR:$rhs), IIC_iALUr,
-                  "add", "\t$Rdn, $rhs", []>,
+def tADDspr : T1pIt<(outs GPRsp:$Rdn), (ins GPRsp:$Rn, GPR:$Rm), IIC_iALUr,
+                  "add", "\t$Rdn, $Rm", []>,
               T1Special<{0,0,?,?}> {
   // A8.6.9 Encoding T2
-  bits<4> Rdn;
+  bits<4> Rm;
   let Inst{7} = 1;
-  let Inst{6-3} = Rdn;
+  let Inst{6-3} = Rm;
   let Inst{2-0} = 0b101;
   let DecoderMethod = "DecodeThumbAddSPReg";
 }

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=138488&r1=138487&r2=138488&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Wed Aug 24 16:22:15 2011
@@ -412,6 +412,22 @@
   bool isCondCode() const { return Kind == CondCode; }
   bool isCCOut() const { return Kind == CCOut; }
   bool isImm() const { return Kind == Immediate; }
+  bool isImm0_1020s4() const {
+    if (Kind != Immediate)
+      return false;
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+    if (!CE) return false;
+    int64_t Value = CE->getValue();
+    return ((Value & 3) == 0) && Value >= 0 && Value <= 1020;
+  }
+  bool isImm0_508s4() const {
+    if (Kind != Immediate)
+      return false;
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+    if (!CE) return false;
+    int64_t Value = CE->getValue();
+    return ((Value & 3) == 0) && Value >= 0 && Value <= 508;
+  }
   bool isImm0_255() const {
     if (Kind != Immediate)
       return false;
@@ -791,6 +807,22 @@
     addExpr(Inst, getImm());
   }
 
+  void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    // The immediate is scaled by four in the encoding and is stored
+    // in the MCInst as such. Lop off the low two bits here.
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
+  }
+
+  void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    // The immediate is scaled by four in the encoding and is stored
+    // in the MCInst as such. Lop off the low two bits here.
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
+  }
+
   void addImm0_255Operands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
     addExpr(Inst, getImm());
@@ -2883,6 +2915,21 @@
       static_cast<ARMOperand*>(Operands[4])->isReg() &&
       static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
     return true;
+  // Register-register 'add' for thumb does not have a cc_out operand
+  // when it's an ADD Rdm, SP, {Rdm|#imm} instruction.
+  if (isThumb() && Mnemonic == "add" && Operands.size() == 6 &&
+      static_cast<ARMOperand*>(Operands[3])->isReg() &&
+      static_cast<ARMOperand*>(Operands[4])->isReg() &&
+      static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP &&
+      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
+    return true;
+  // Register-register 'add' for thumb does not have a cc_out operand
+  // when it's an ADD SP, #imm.
+  if (isThumb() && Mnemonic == "add" && Operands.size() == 5 &&
+      static_cast<ARMOperand*>(Operands[3])->isReg() &&
+      static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP &&
+      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
+    return true;
 
   return false;
 }

Modified: llvm/trunk/test/MC/ARM/basic-thumb-instructions.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/basic-thumb-instructions.s?rev=138488&r1=138487&r2=138488&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/basic-thumb-instructions.s (original)
+++ llvm/trunk/test/MC/ARM/basic-thumb-instructions.s Wed Aug 24 16:22:15 2011
@@ -45,11 +45,29 @@
 
 
 @------------------------------------------------------------------------------
-@ FIXME: ADD (SP plus immediate)
+@ ADD (SP plus immediate)
 @------------------------------------------------------------------------------
+        add sp, #4
+        add sp, #508
+        add sp, sp, #4
+        add r2, sp, #8
+        add r2, sp, #1020
+
+@ CHECK: add	sp, #4                  @ encoding: [0x01,0xb0]
+@ CHECK: add	sp, #508                @ encoding: [0x7f,0xb0]
+@ CHECK: add	sp, #4                  @ encoding: [0x01,0xb0]
+@ CHECK: add	r2, sp, #8              @ encoding: [0x02,0xaa]
+@ CHECK: add	r2, sp, #1020           @ encoding: [0xff,0xaa]
+
+
 @------------------------------------------------------------------------------
-@ FIXME: ADD (SP plus register)
+@ ADD (SP plus register)
 @------------------------------------------------------------------------------
+        add sp, r3
+        add r2, sp, r2
+
+@ CHECK: add	sp, r3                  @ encoding: [0x9d,0x44]
+@ CHECK: add	r2, sp, r2              @ encoding: [0x6a,0x44]
 
 
 @------------------------------------------------------------------------------

Modified: llvm/trunk/test/MC/ARM/thumb-diagnostics.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/thumb-diagnostics.s?rev=138488&r1=138487&r2=138488&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/thumb-diagnostics.s (original)
+++ llvm/trunk/test/MC/ARM/thumb-diagnostics.s Wed Aug 24 16:22:15 2011
@@ -118,3 +118,22 @@
 @ CHECK-ERRORS: error: instruction requires a CPU feature not currently enabled
 @ CHECK-ERRORS:         svc #256
 @ CHECK-ERRORS:         ^
+
+
+@ Out of range immediate for ADD SP instructions
+        add sp, #-1
+        add sp, #3
+        add sp, sp, #512
+        add r2, sp, #1024
+@ CHECK-ERRORS: error: invalid operand for instruction
+@ CHECK-ERRORS:         add sp, #-1
+@ CHECK-ERRORS:                 ^
+@ CHECK-ERRORS: error: invalid operand for instruction
+@ CHECK-ERRORS:         add sp, #3
+@ CHECK-ERRORS:                 ^
+@ CHECK-ERRORS: error: invalid operand for instruction
+@ CHECK-ERRORS:         add sp, sp, #512
+@ CHECK-ERRORS:                     ^
+@ CHECK-ERRORS: error: invalid operand for instruction
+@ CHECK-ERRORS:         add r2, sp, #1024
+@ CHECK-ERRORS:                     ^

Modified: llvm/trunk/utils/TableGen/EDEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/EDEmitter.cpp?rev=138488&r1=138487&r2=138488&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/EDEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/EDEmitter.cpp Wed Aug 24 16:22:15 2011
@@ -603,7 +603,8 @@
   IMM("pkh_lsl_amt");
   IMM("pkh_asr_amt");
   IMM("jt2block_operand");
-  IMM("t_imm_s4");
+  IMM("t_imm0_1020s4");
+  IMM("t_imm0_508s4");
   IMM("pclabel");
   IMM("adrlabel");
   IMM("t_adrlabel");





More information about the llvm-commits mailing list