From: Owen Anderson Date: Fri, 26 Aug 2011 23:32:08 +0000 (+0000) Subject: Improve encoding support for BLX with immediat eoperands, and fix a BLX decoding... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=f1eab597b2316c6cfcabfcee98895fedb2071722;p=oota-llvm.git 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 --- diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index 7d4eb6f18f9..8f28c43173d 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 d20e944ddf5..56a4d831e16 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -344,9 +344,13 @@ def bl_target : Operand { // Encoded the same as branch targets. let EncoderMethod = "getARMBranchTargetOpValue"; let OperandType = "OPERAND_PCREL"; - let DecoderMethod = "DecodeBLTargetOperand"; } +def blx_target : Operand { + // 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 6b87dfd0df7..c3ad2907c94 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 19a37356b22..94aeb59089d 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 &Fixups) const; + uint32_t getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &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 &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. diff --git a/test/MC/ARM/basic-arm-instructions.s b/test/MC/ARM/basic-arm-instructions.s index cd4045610bd..ffb1f8a2016 100644 --- a/test/MC/ARM/basic-arm-instructions.s +++ b/test/MC/ARM/basic-arm-instructions.s @@ -364,13 +364,16 @@ Lforward: bl _bar blx _bar blls #28634268 + blx #32424576 + blx #16212288 @ CHECK: bl _bar @ encoding: [A,A,A,0xeb] @ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_uncondbranch @ CHECK: blx _bar @ encoding: [A,A,A,0xfa] @ fixup A - offset: 0, value: _bar, kind: fixup_arm_uncondbranch @ CHECK: blls #28634268 @ encoding: [0x27,0x3b,0x6d,0x9b] - +@ CHECK: blx #32424576 @ encoding: [0xa0,0xb0,0x7b,0xfa] +@ CHECK: blx #16212288 @ encoding: [0x50,0xd8,0x3d,0xfa] @------------------------------------------------------------------------------ @ BLX (register) @------------------------------------------------------------------------------ diff --git a/test/MC/Disassembler/ARM/basic-arm-instructions.txt b/test/MC/Disassembler/ARM/basic-arm-instructions.txt index 807cf9e46d2..fc7eda537ab 100644 --- a/test/MC/Disassembler/ARM/basic-arm-instructions.txt +++ b/test/MC/Disassembler/ARM/basic-arm-instructions.txt @@ -326,6 +326,15 @@ 0x32 0xff 0x2f 0xe1 0x32 0xff 0x2f 0x11 +#------------------------------------------------------------------------------ +# BLX (immediate) +#------------------------------------------------------------------------------ +# CHECK: blx #32424576 +# CHECK: blx #16212288 + +0xa0 0xb0 0x7b 0xfa +0x50 0xd8 0x3d 0xfa + #------------------------------------------------------------------------------ # BX #------------------------------------------------------------------------------ diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index ce59ff730e9..dafa7322a08 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -630,6 +630,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, MISC("br_target", "kOperandTypeARMBranchTarget"); // ? MISC("bl_target", "kOperandTypeARMBranchTarget"); // ? + MISC("blx_target", "kOperandTypeARMBranchTarget"); // ? MISC("t_bltarget", "kOperandTypeARMBranchTarget"); // ? MISC("t_blxtarget", "kOperandTypeARMBranchTarget"); // ?