1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 11:33:24 +02:00

Fix roundtripping of Thumb BL/BLX instructions with immediate offsets instead of labels.

llvm-svn: 138874
This commit is contained in:
Owen Anderson 2011-08-31 18:30:20 +00:00
parent 4dddfb237c
commit f30633abbf
2 changed files with 40 additions and 3 deletions

View File

@ -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);
}

View File

@ -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
@------------------------------------------------------------------------------