diff options
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 7 | ||||
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 15 | ||||
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp | 31 |
3 files changed, 36 insertions, 17 deletions
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index f881b8fea5..ec123cbc17 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 f1c5ce8bc5..3fd06a998b 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 ecbc6411c8..434eb28c69 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<MCFixup> &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<MCFixup> &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<MCFixup> &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' |