diff options
author | Owen Anderson <resistor@mac.com> | 2011-08-26 23:32:08 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2011-08-26 23:32:08 +0000 |
commit | f1eab597b2316c6cfcabfcee98895fedb2071722 (patch) | |
tree | 164944f399e397b3156223d571d4ade3cab1c99e /lib/Target/ARM | |
parent | d7568e1c355f5e364eddafc15c6d5553559f32a5 (diff) |
Improve encoding support for BLX with immediat eoperands, and fix a BLX decoding bug this uncovered.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138675 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM')
-rw-r--r-- | lib/Target/ARM/ARMCodeEmitter.cpp | 2 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 10 | ||||
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 9 | ||||
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp | 16 |
4 files changed, 25 insertions, 12 deletions
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index 7d4eb6f18f..8f28c43173 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -189,6 +189,8 @@ namespace { unsigned Op) const { return 0; } unsigned getARMBranchTargetOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } + unsigned getARMBLXTargetOpValue(const MachineInstr &MI, unsigned Op) + const { return 0; } unsigned getCCOutOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } unsigned getSOImmOpValue(const MachineInstr &MI, unsigned Op) diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index d20e944ddf..56a4d831e1 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -344,9 +344,13 @@ def bl_target : Operand<i32> { // Encoded the same as branch targets. let EncoderMethod = "getARMBranchTargetOpValue"; let OperandType = "OPERAND_PCREL"; - let DecoderMethod = "DecodeBLTargetOperand"; } +def blx_target : Operand<i32> { + // Encoded the same as branch targets. + let EncoderMethod = "getARMBLXTargetOpValue"; + let OperandType = "OPERAND_PCREL"; +} // A list of registers separated by comma. Used by load/store multiple. def RegListAsmOperand : AsmOperandClass { let Name = "RegList"; } @@ -1657,6 +1661,7 @@ let isCall = 1, let Inst{31-28} = 0b1110; bits<24> func; let Inst{23-0} = func; + let DecoderMethod = "DecodeBranchImmInstruction"; } def BL_pred : ABI<0b1011, (outs), (ins bl_target:$func, variable_ops), @@ -1665,6 +1670,7 @@ let isCall = 1, Requires<[IsARM, IsNotDarwin]> { bits<24> func; let Inst{23-0} = func; + let DecoderMethod = "DecodeBranchImmInstruction"; } // ARMv5T and above @@ -1784,7 +1790,7 @@ let isBranch = 1, isTerminator = 1 in { } // BLX (immediate) -def BLXi : AXI<(outs), (ins br_target:$target), BrMiscFrm, NoItinerary, +def BLXi : AXI<(outs), (ins blx_target:$target), BrMiscFrm, NoItinerary, "blx\t$target", []>, Requires<[IsARM, HasV5T]> { let Inst{31-25} = 0b1111101; diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 6b87dfd0df..c3ad2907c9 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -69,8 +69,6 @@ static DecodeStatus DecodeCCOutOperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); static DecodeStatus DecodeSOImmOperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); -static DecodeStatus DecodeBLTargetOperand(llvm::MCInst &Inst, unsigned Val, - uint64_t Address, const void *Decoder); static DecodeStatus DecodeRegListOperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); static DecodeStatus DecodeSPRRegListOperand(llvm::MCInst &Inst, unsigned Val, @@ -766,13 +764,6 @@ static DecodeStatus DecodeSOImmOperand(llvm::MCInst &Inst, unsigned Val, return Success; } -static DecodeStatus DecodeBLTargetOperand(llvm::MCInst &Inst, unsigned Val, - uint64_t Address, const void *Decoder) { - Val <<= 2; - Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(Val))); - return Success; -} - static DecodeStatus DecodeSORegImmOperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder) { DecodeStatus S = Success; diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp index 19a37356b2..94aeb59089 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp @@ -118,6 +118,8 @@ public: /// branch target. uint32_t getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups) const; + uint32_t getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl<MCFixup> &Fixups) const; /// getAdrLabelOpValue - Return encoding info for 12-bit immediate /// ADR label target. @@ -544,8 +546,20 @@ getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, return MO.getImm() >> 2; } +uint32_t ARMMCCodeEmitter:: +getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl<MCFixup> &Fixups) const { + const MCOperand MO = MI.getOperand(OpIdx); + if (MO.isExpr()) { + if (HasConditionalBranch(MI)) + return ::getBranchTargetOpValue(MI, OpIdx, + ARM::fixup_arm_condbranch, Fixups); + return ::getBranchTargetOpValue(MI, OpIdx, + ARM::fixup_arm_uncondbranch, Fixups); + } - + return MO.getImm() >> 1; +} /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit /// immediate branch target. |