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 | b205c029a4e65760d66e0c5baf9e43dab3547dc3 (patch) | |
| tree | 4c908c6318ad8ab510928e75bcfe768d3e99ca89 /llvm/lib/Target/ARM | |
| parent | 104543052561b372d16da2593fa2ca5c0cf138cc (diff) | |
| download | bcm5719-llvm-b205c029a4e65760d66e0c5baf9e43dab3547dc3.tar.gz bcm5719-llvm-b205c029a4e65760d66e0c5baf9e43dab3547dc3.zip | |
Improve encoding support for BLX with immediat eoperands, and fix a BLX decoding bug this uncovered.
llvm-svn: 138675
Diffstat (limited to 'llvm/lib/Target/ARM')
| -rw-r--r-- | llvm/lib/Target/ARM/ARMCodeEmitter.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstrInfo.td | 10 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 9 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp | 16 |
4 files changed, 25 insertions, 12 deletions
diff --git a/llvm/lib/Target/ARM/ARMCodeEmitter.cpp b/llvm/lib/Target/ARM/ARMCodeEmitter.cpp index 7d4eb6f18f9..8f28c43173d 100644 --- a/llvm/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/llvm/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/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index d20e944ddf5..56a4d831e16 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/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/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 6b87dfd0df7..c3ad2907c94 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/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/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp index 19a37356b22..94aeb59089d 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp +++ b/llvm/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. |

