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)
// 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"; }
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),
Requires<[IsARM, IsNotDarwin]> {
bits<24> func;
let Inst{23-0} = func;
+ let DecoderMethod = "DecodeBranchImmInstruction";
}
// ARMv5T and above
}
// 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;
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,
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;
/// 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.
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.
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)
@------------------------------------------------------------------------------
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
#------------------------------------------------------------------------------
MISC("br_target", "kOperandTypeARMBranchTarget"); // ?
MISC("bl_target", "kOperandTypeARMBranchTarget"); // ?
+ MISC("blx_target", "kOperandTypeARMBranchTarget"); // ?
MISC("t_bltarget", "kOperandTypeARMBranchTarget"); // ?
MISC("t_blxtarget", "kOperandTypeARMBranchTarget"); // ?