From 96425c846494c1c20a4c931f4783571295ab170c Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Fri, 26 Aug 2011 18:09:22 +0000 Subject: [PATCH] Support an extension of ARM asm syntax to allow immediate operands to ADR instructions. This is helpful for disassembler testing, and indeed exposed a disassembler bug that is also fixed here. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138635 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrInfo.td | 7 +++-- .../ARM/Disassembler/ARMDisassembler.cpp | 15 +++++---- .../ARM/MCTargetDesc/ARMMCCodeEmitter.cpp | 31 +++++++++++++------ test/MC/ARM/basic-arm-instructions.s | 4 +++ test/MC/ARM/basic-thumb-instructions.s | 3 +- .../ARM/basic-arm-instructions.txt | 8 +++++ test/MC/Disassembler/ARM/thumb1.txt | 6 ++++ 7 files changed, 56 insertions(+), 18 deletions(-) diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index f881b8fea59..ec123cbc176 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -1583,12 +1583,15 @@ let neverHasSideEffects = 1, isReMaterializable = 1 in def ADR : AI1<{0,?,?,0}, (outs GPR:$Rd), (ins adrlabel:$label), MiscFrm, IIC_iALUi, "adr", "\t$Rd, $label", []> { bits<4> Rd; - bits<12> label; + bits<14> label; let Inst{27-25} = 0b001; + let Inst{24} = 0; + let Inst{23-22} = label{13-12}; + let Inst{21} = 0; let Inst{20} = 0; let Inst{19-16} = 0b1111; let Inst{15-12} = Rd; - let Inst{11-0} = label; + let Inst{11-0} = label{11-0}; } def LEApcrel : ARMPseudoInst<(outs GPR:$Rd), (ins i32imm:$label, pred:$p), 4, IIC_iALUi, []>; diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index f1c5ce8bc52..3fd06a998be 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -2310,12 +2310,15 @@ static DecodeStatus DecodeThumbAddSpecialReg(llvm::MCInst &Inst, uint16_t Insn, CHECK(S, DecodetGPRRegisterClass(Inst, dst, Address, Decoder)); - if (Inst.getOpcode() == ARM::tADR) - Inst.addOperand(MCOperand::CreateReg(ARM::PC)); - else if (Inst.getOpcode() == ARM::tADDrSPi) - Inst.addOperand(MCOperand::CreateReg(ARM::SP)); - else - return Fail; + switch(Inst.getOpcode()) { + case ARM::tADR: + break; + case ARM::tADDrSPi: + Inst.addOperand(MCOperand::CreateReg(ARM::SP)); + break; + default: + return Fail; + } Inst.addOperand(MCOperand::CreateImm(imm)); return S; diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp index ecbc6411c88..434eb28c698 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp @@ -570,9 +570,18 @@ getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, uint32_t ARMMCCodeEmitter:: getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl &Fixups) const { - assert(MI.getOperand(OpIdx).isExpr() && "Unexpected adr target type!"); - return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_adr_pcrel_12, - Fixups); + const MCOperand MO = MI.getOperand(OpIdx); + if (MO.isExpr()) + return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_adr_pcrel_12, + Fixups); + int32_t offset = MO.getImm(); + uint32_t Val = 0x2000; + if (offset < 0) { + Val = 0x1000; + offset *= -1; + } + Val |= offset; + return Val; } /// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label @@ -580,9 +589,11 @@ getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, uint32_t ARMMCCodeEmitter:: getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl &Fixups) const { - assert(MI.getOperand(OpIdx).isExpr() && "Unexpected adr target type!"); - return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12, - Fixups); + const MCOperand MO = MI.getOperand(OpIdx); + if (MO.isExpr()) + return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12, + Fixups); + return MO.getImm(); } /// getAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label @@ -590,9 +601,11 @@ getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, uint32_t ARMMCCodeEmitter:: getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl &Fixups) const { - assert(MI.getOperand(OpIdx).isExpr() && "Unexpected adr target type!"); - return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_thumb_adr_pcrel_10, - Fixups); + const MCOperand MO = MI.getOperand(OpIdx); + if (MO.isExpr()) + return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_thumb_adr_pcrel_10, + Fixups); + return MO.getImm(); } /// getThumbAddrModeRegRegOpValue - Return encoding info for 'reg + reg' diff --git a/test/MC/ARM/basic-arm-instructions.s b/test/MC/ARM/basic-arm-instructions.s index 1a262356fca..0a411b4ccdb 100644 --- a/test/MC/ARM/basic-arm-instructions.s +++ b/test/MC/ARM/basic-arm-instructions.s @@ -129,6 +129,8 @@ Lback: adr r2, Lback adr r3, Lforward Lforward: + adr r2, #3 + adr r2, #-3 @ CHECK: Lback: @ CHECK: adr r2, Lback @ encoding: [0bAAAAAAA0,0x20'A',0x0f'A',0b1110001A] @@ -136,6 +138,8 @@ Lforward: @ CHECK: adr r3, Lforward @ encoding: [0bAAAAAAA0,0x30'A',0x0f'A',0b1110001A] @ CHECK: @ fixup A - offset: 0, value: Lforward, kind: fixup_arm_adr_pcrel_12 @ CHECK: Lforward: +@ CHECK: adr r2, #3 @ encoding: [0x03,0x20,0x8f,0xe2] +@ CHECK: adr r2, #-3 @ encoding: [0x03,0x20,0x4f,0xe2] @------------------------------------------------------------------------------ diff --git a/test/MC/ARM/basic-thumb-instructions.s b/test/MC/ARM/basic-thumb-instructions.s index 91f8e15c1f4..d44ffeb7b7c 100644 --- a/test/MC/ARM/basic-thumb-instructions.s +++ b/test/MC/ARM/basic-thumb-instructions.s @@ -74,10 +74,11 @@ _func: @ ADR @------------------------------------------------------------------------------ adr r2, _baz + adr r2, #3 @ CHECK: adr r2, _baz @ encoding: [A,0xa2] @ fixup A - offset: 0, value: _baz, kind: fixup_thumb_adr_pcrel_10 - +@ CHECK: adr r2, #3 @ encoding: [0x03,0xa2] @------------------------------------------------------------------------------ @ ASR (immediate) diff --git a/test/MC/Disassembler/ARM/basic-arm-instructions.txt b/test/MC/Disassembler/ARM/basic-arm-instructions.txt index 306b906eabd..807cf9e46d2 100644 --- a/test/MC/Disassembler/ARM/basic-arm-instructions.txt +++ b/test/MC/Disassembler/ARM/basic-arm-instructions.txt @@ -164,6 +164,14 @@ 0x77 0x69 0x86 0xe0 0x65 0x40 0x84 0xe0 +#------------------------------------------------------------------------------ +# ADR +#------------------------------------------------------------------------------ +# CHECK: add r2, pc, #3 +# CHECK: sub r2, pc, #3 + +0x03 0x20 0x8f 0xe2 +0x03 0x20 0x4f 0xe2 #------------------------------------------------------------------------------ # AND diff --git a/test/MC/Disassembler/ARM/thumb1.txt b/test/MC/Disassembler/ARM/thumb1.txt index 3e0722d32ef..17c4bad239e 100644 --- a/test/MC/Disassembler/ARM/thumb1.txt +++ b/test/MC/Disassembler/ARM/thumb1.txt @@ -51,6 +51,12 @@ 0x9d 0x44 0x6a 0x44 +#------------------------------------------------------------------------------ +# ADR +#------------------------------------------------------------------------------ +# CHECK: adr r2, #3 +0x03 0xa2 + #------------------------------------------------------------------------------ # ASR (immediate) #------------------------------------------------------------------------------