[llvm-commits] [llvm] r161159 - in /llvm/trunk: lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/ARMInstrThumb2.td lib/Target/ARM/AsmParser/ARMAsmParser.cpp lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp lib/Target/ARM/InstPrinter/ARMInstPrinter.h lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp test/MC/ARM/basic-arm-instructions.s test/MC/ARM/basic-thumb2-instructions.s test/MC/Disassembler/ARM/basic-arm-instructions.txt test/MC/Disassembler/ARM/thumb2.txt

Jiangning Liu jiangning.liu at arm.com
Thu Aug 2 01:13:13 PDT 2012


Author: jiangning
Date: Thu Aug  2 03:13:13 2012
New Revision: 161159

URL: http://llvm.org/viewvc/llvm-project?rev=161159&view=rev
Log:
Fix #13241, a bug around shift immediate operand for ARM instruction ADR.

Modified:
    llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
    llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
    llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
    llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h
    llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
    llvm/trunk/test/MC/ARM/basic-arm-instructions.s
    llvm/trunk/test/MC/ARM/basic-thumb2-instructions.s
    llvm/trunk/test/MC/Disassembler/ARM/basic-arm-instructions.txt
    llvm/trunk/test/MC/Disassembler/ARM/thumb2.txt

Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=161159&r1=161158&r2=161159&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Thu Aug  2 03:13:13 2012
@@ -416,8 +416,11 @@
 }
 
 // ADR instruction labels.
+def AdrLabelAsmOperand : AsmOperandClass { let Name = "AdrLabel"; }
 def adrlabel : Operand<i32> {
   let EncoderMethod = "getAdrLabelOpValue";
+  let ParserMatchClass = AdrLabelAsmOperand;
+  let PrintMethod = "printAdrLabelOperand";
 }
 
 def neon_vcvt_imm32 : Operand<i32> {

Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=161159&r1=161158&r2=161159&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Thu Aug  2 03:13:13 2012
@@ -172,6 +172,7 @@
 // ADR instruction labels.
 def t2adrlabel : Operand<i32> {
   let EncoderMethod = "getT2AdrLabelOpValue";
+  let PrintMethod = "printAdrLabelOperand";
 }
 
 

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=161159&r1=161158&r2=161159&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Thu Aug  2 03:13:13 2012
@@ -796,6 +796,13 @@
     int64_t Value = CE->getValue();
     return Value > 0 && Value <= 32;
   }
+  bool isAdrLabel() const {
+    // If we have an immediate that's not a constant, treat it as a label
+    // reference needing a fixup. If it is a constant, but it can't fit 
+    // into shift immediate encoding, we reject it.
+    if (isImm() && !isa<MCConstantExpr>(getImm())) return true;
+    else return (isARMSOImm() || isARMSOImmNeg());
+  }
   bool isARMSOImm() const {
     if (!isImm()) return false;
     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
@@ -1644,6 +1651,22 @@
     Inst.addOperand(MCOperand::CreateImm(Imm));
   }
 
+  void addAdrLabelOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    assert(isImm() && "Not an immediate!");
+
+    // If we have an immediate that's not a constant, treat it as a label
+    // reference needing a fixup. 
+    if (!isa<MCConstantExpr>(getImm())) {
+      Inst.addOperand(MCOperand::CreateExpr(getImm()));
+      return;
+    }
+
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+    int Val = CE->getValue();
+    Inst.addOperand(MCOperand::CreateImm(Val));
+  }
+
   void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const {
     assert(N == 2 && "Invalid number of operands!");
     Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));

Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp?rev=161159&r1=161158&r2=161159&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp Thu Aug  2 03:13:13 2012
@@ -792,6 +792,25 @@
   llvm_unreachable("Unhandled PC-relative pseudo-instruction!");
 }
 
+void ARMInstPrinter::printAdrLabelOperand(const MCInst *MI, unsigned OpNum,
+                                  raw_ostream &O) {
+  const MCOperand &MO = MI->getOperand(OpNum);
+
+  if (MO.isExpr()) {
+    O << *MO.getExpr();
+    return;
+  }
+
+  int32_t OffImm = (int32_t)MO.getImm();
+
+  if (OffImm == INT32_MIN)
+    O << "#-0";
+  else if (OffImm < 0)
+    O << "#-" << -OffImm;
+  else
+    O << "#" << OffImm;
+}
+
 void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum,
                                             raw_ostream &O) {
   O << "#" << MI->getOperand(OpNum).getImm() * 4;

Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h?rev=161159&r1=161158&r2=161159&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h (original)
+++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h Thu Aug  2 03:13:13 2012
@@ -73,6 +73,7 @@
   void printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum, raw_ostream &O);
   void printPKHASRShiftImm(const MCInst *MI, unsigned OpNum, raw_ostream &O);
 
+  void printAdrLabelOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
   void printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
   void printThumbSRImm(const MCInst *MI, unsigned OpNum, raw_ostream &O);
   void printThumbITMask(const MCInst *MI, unsigned OpNum, raw_ostream &O);

Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp?rev=161159&r1=161158&r2=161159&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp Thu Aug  2 03:13:13 2012
@@ -641,8 +641,8 @@
   return Val;
 }
 
-/// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label
-/// target.
+/// getAdrLabelOpValue - Return encoding info for 12-bit shifted-immediate
+/// ADR label target.
 uint32_t ARMMCCodeEmitter::
 getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
                    SmallVectorImpl<MCFixup> &Fixups) const {
@@ -652,15 +652,23 @@
                                     Fixups);
   int32_t offset = MO.getImm();
   uint32_t Val = 0x2000;
-  if (offset < 0) {
+
+  if (offset == INT32_MIN) {
+    Val = 0x1000;
+    offset = 0;
+  } else if (offset < 0) {
     Val = 0x1000;
     offset *= -1;
   }
-  Val |= offset;
+
+  int SoImmVal = ARM_AM::getSOImmVal(offset);
+  assert(SoImmVal != -1 && "Not a valid so_imm value!");
+
+  Val |= SoImmVal;
   return Val;
 }
 
-/// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label
+/// getT2AdrLabelOpValue - Return encoding info for 12-bit immediate ADR label
 /// target.
 uint32_t ARMMCCodeEmitter::
 getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
@@ -670,14 +678,16 @@
     return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12,
                                     Fixups);
   int32_t Val = MO.getImm();
-  if (Val < 0) {
+  if (Val == INT32_MIN)
+    Val = 0x1000;
+  else if (Val < 0) {
     Val *= -1;
     Val |= 0x1000;
   }
   return Val;
 }
 
-/// getAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label
+/// getThumbAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label
 /// target.
 uint32_t ARMMCCodeEmitter::
 getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,

Modified: llvm/trunk/test/MC/ARM/basic-arm-instructions.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/basic-arm-instructions.s?rev=161159&r1=161158&r2=161159&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/basic-arm-instructions.s (original)
+++ llvm/trunk/test/MC/ARM/basic-arm-instructions.s Thu Aug  2 03:13:13 2012
@@ -141,6 +141,14 @@
 @ CHECK: adr	r2, #3                  @ encoding: [0x03,0x20,0x8f,0xe2]
 @ CHECK: adr	r2, #-3                 @ encoding: [0x03,0x20,0x4f,0xe2]
 
+        adr r1, #-0x0
+        adr r1, #-0x12000000
+        adr r1, #0x12000000
+
+@ CHECK: adr	r1, #-0                 @ encoding: [0x00,0x10,0x4f,0xe2]
+@ CHECK: adr	r1, #-301989888         @ encoding: [0x12,0x14,0x4f,0xe2]
+@ CHECK: adr	r1, #301989888          @ encoding: [0x12,0x14,0x8f,0xe2]
+
 
 @------------------------------------------------------------------------------
 @ ADD

Modified: llvm/trunk/test/MC/ARM/basic-thumb2-instructions.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/basic-thumb2-instructions.s?rev=161159&r1=161158&r2=161159&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/basic-thumb2-instructions.s (original)
+++ llvm/trunk/test/MC/ARM/basic-thumb2-instructions.s Thu Aug  2 03:13:13 2012
@@ -135,9 +135,11 @@
 
         subw r11, pc, #3270
         adr.w r11, #-826
+        adr.w r1, #-0x0
 
 @ CHECK: subw	r11, pc, #3270          @ encoding: [0xaf,0xf6,0xc6,0x4b]
 @ CHECK: adr.w	r11, #-826              @ encoding: [0xaf,0xf2,0x3a,0x3b]
+@ CHECK: adr.w	r1, #-0                 @ encoding: [0xaf,0xf2,0x00,0x01]
 
 @------------------------------------------------------------------------------
 @ AND (immediate)

Modified: llvm/trunk/test/MC/Disassembler/ARM/basic-arm-instructions.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/basic-arm-instructions.txt?rev=161159&r1=161158&r2=161159&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM/basic-arm-instructions.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM/basic-arm-instructions.txt Thu Aug  2 03:13:13 2012
@@ -169,9 +169,15 @@
 #------------------------------------------------------------------------------
 # CHECK: add	r2, pc, #3
 # CHECK: sub	r2, pc, #3
+# CHECK: sub	r1, pc, #0
+# CHECK: sub	r1, pc, #301989888
+# CHECK: add	r1, pc, #301989888
 
 0x03 0x20 0x8f 0xe2
 0x03 0x20 0x4f 0xe2
+0x00 0x10 0x4f 0xe2
+0x12 0x14 0x4f 0xe2
+0x12 0x14 0x8f 0xe2
 
 #------------------------------------------------------------------------------
 # AND

Modified: llvm/trunk/test/MC/Disassembler/ARM/thumb2.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/thumb2.txt?rev=161159&r1=161158&r2=161159&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM/thumb2.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM/thumb2.txt Thu Aug  2 03:13:13 2012
@@ -92,9 +92,11 @@
 #------------------------------------------------------------------------------
 # CHECK: subw r11, pc, #3270
 # CHECK: subw r11, pc, #826
+# CHECK: subw r1, pc, #0
 
 0xaf 0xf6 0xc6 0x4b
 0xaf 0xf2 0x3a 0x3b
+0xaf 0xf2 0x00 0x01
 
 #------------------------------------------------------------------------------
 # AND (immediate)





More information about the llvm-commits mailing list