aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/Target/ARM/ARMCodeEmitter.cpp2
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td10
-rw-r--r--lib/Target/ARM/Disassembler/ARMDisassembler.cpp9
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp16
-rw-r--r--test/MC/ARM/basic-arm-instructions.s5
-rw-r--r--test/MC/Disassembler/ARM/basic-arm-instructions.txt9
-rw-r--r--utils/TableGen/EDEmitter.cpp1
7 files changed, 39 insertions, 13 deletions
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp
index 7d4eb6f..8f28c43 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 d20e944..56a4d83 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 6b87dfd..c3ad290 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 19a3735..94aeb59 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.
diff --git a/test/MC/ARM/basic-arm-instructions.s b/test/MC/ARM/basic-arm-instructions.s
index cd40456..ffb1f8a 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 807cf9e..fc7eda5 100644
--- a/test/MC/Disassembler/ARM/basic-arm-instructions.txt
+++ b/test/MC/Disassembler/ARM/basic-arm-instructions.txt
@@ -327,6 +327,15 @@
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 ce59ff7..dafa732 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"); // ?