mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-09 01:38:03 +00:00
Fix roundtripping of Thumb BL/BLX instructions with immediate offsets instead of labels.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138874 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c9a9b44285
commit
559c277aa9
@ -465,11 +465,34 @@ static uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Thumb BL and BLX use a strange offset encoding where bits 22 and 21 are
|
||||
// determined by negating them and XOR'ing them with bit 23.
|
||||
static int32_t encodeThumbBLOffset(int32_t offset) {
|
||||
offset >>= 1;
|
||||
uint32_t S = (offset & 0x800000) >> 23;
|
||||
uint32_t J1 = (offset & 0x400000) >> 22;
|
||||
uint32_t J2 = (offset & 0x200000) >> 21;
|
||||
J1 = (~J1 & 0x1);
|
||||
J2 = (~J2 & 0x1);
|
||||
J1 ^= S;
|
||||
J2 ^= S;
|
||||
|
||||
offset &= ~0x600000;
|
||||
offset |= J1 << 22;
|
||||
offset |= J2 << 21;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
/// getThumbBLTargetOpValue - Return encoding info for immediate branch target.
|
||||
uint32_t ARMMCCodeEmitter::
|
||||
getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bl, Fixups);
|
||||
const MCOperand MO = MI.getOperand(OpIdx);
|
||||
if (MO.isExpr())
|
||||
return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bl,
|
||||
Fixups);
|
||||
return encodeThumbBLOffset(MO.getImm());
|
||||
}
|
||||
|
||||
/// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate
|
||||
@ -477,7 +500,11 @@ getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
|
||||
uint32_t ARMMCCodeEmitter::
|
||||
getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_blx, Fixups);
|
||||
const MCOperand MO = MI.getOperand(OpIdx);
|
||||
if (MO.isExpr())
|
||||
return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_blx,
|
||||
Fixups);
|
||||
return encodeThumbBLOffset(MO.getImm());
|
||||
}
|
||||
|
||||
/// getThumbBRTargetOpValue - Return encoding info for Thumb branch target.
|
||||
@ -486,7 +513,8 @@ getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
const MCOperand MO = MI.getOperand(OpIdx);
|
||||
if (MO.isExpr())
|
||||
return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_br, Fixups);
|
||||
return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_br,
|
||||
Fixups);
|
||||
return (MO.getImm() >> 1);
|
||||
}
|
||||
|
||||
|
@ -117,6 +117,15 @@ _func:
|
||||
@ CHECK: b #1838 @ encoding: [0x97,0xe3]
|
||||
@ CHECK: b #-420 @ encoding: [0x2e,0xe7]
|
||||
|
||||
@------------------------------------------------------------------------------
|
||||
@ BL/BLX
|
||||
@------------------------------------------------------------------------------
|
||||
blx #884800
|
||||
blx #1769600
|
||||
|
||||
@ CHECK: blx #884800 @ encoding: [0xd8,0xf0,0x20,0xe8]
|
||||
@ CHECK: blx #1769600 @ encoding: [0xb0,0xf1,0x40,0xe8]
|
||||
|
||||
@------------------------------------------------------------------------------
|
||||
@ BICS
|
||||
@------------------------------------------------------------------------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user