mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-17 21:35:07 +00:00
Fix Thumb2 BCC encoding and fixups.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121329 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2871768f40
commit
fb20d89075
@ -127,6 +127,21 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
|
||||
// These values don't encode the low two bits since they're always zero.
|
||||
// Offset by 8 just as above.
|
||||
return 0xffffff & ((Value - 8) >> 2);
|
||||
case ARM::fixup_t2_branch: {
|
||||
Value = Value - 6;
|
||||
Value >>= 1; // Low bit is not encoded.
|
||||
|
||||
uint64_t out = 0;
|
||||
Value |= (Value & 0x80000) << 7; // S bit
|
||||
Value |= (Value & 0x40000) >> 7; // J2 bit
|
||||
Value |= (Value & 0x20000) >> 4; // J1 bit
|
||||
Value |= (Value & 0x1F800) << 5; // imm6 field
|
||||
Value |= (Value & 0x007FF); // imm11 field
|
||||
|
||||
uint64_t swapped = (out & 0xFFFF0000) >> 16;
|
||||
swapped |= (out & 0x0000FFFF) << 16;
|
||||
return swapped;
|
||||
}
|
||||
case ARM::fixup_arm_thumb_bl: {
|
||||
// The value doesn't encode the low bit (always zero) and is offset by
|
||||
// four. The value is encoded into disjoint bit positions in the destination
|
||||
@ -273,6 +288,7 @@ static unsigned getFixupKindNumBytes(unsigned Kind) {
|
||||
return 3;
|
||||
|
||||
case FK_Data_4:
|
||||
case ARM::fixup_t2_branch:
|
||||
case ARM::fixup_t2_pcrel_10:
|
||||
case ARM::fixup_arm_thumb_bl:
|
||||
return 4;
|
||||
|
@ -23,7 +23,7 @@ enum Fixups {
|
||||
// (so it's encoded as an 8-bit immediate).
|
||||
fixup_arm_pcrel_10,
|
||||
// fixup_t2_pcrel_10 - Equivalent to fixup_arm_pcrel_10, accounting for
|
||||
// the byteswapped encoding of Thumb2 instructions.
|
||||
// the short-swapped encoding of Thumb2 instructions.
|
||||
fixup_t2_pcrel_10,
|
||||
// fixup_arm_adr_pcrel_12 - 12-bit PC relative relocation for the ADR
|
||||
// instruction.
|
||||
@ -31,6 +31,9 @@ enum Fixups {
|
||||
// fixup_arm_branch - 24-bit PC relative relocation for direct branch
|
||||
// instructions.
|
||||
fixup_arm_branch,
|
||||
// fixup_t2_branch - 20-bit PC relative relocation for Thumb2 direct branch
|
||||
// instructions.
|
||||
fixup_t2_branch,
|
||||
|
||||
// fixup_arm_thumb_bl - Fixup for Thumb BL/BLX instructions.
|
||||
fixup_arm_thumb_bl,
|
||||
|
@ -3023,13 +3023,16 @@ def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
|
||||
let Inst{31-27} = 0b11110;
|
||||
let Inst{15-14} = 0b10;
|
||||
let Inst{12} = 0;
|
||||
|
||||
bits<4> p;
|
||||
let Inst{25-22} = p;
|
||||
|
||||
bits<20> target;
|
||||
let Inst{26} = target{19};
|
||||
let Inst{11} = target{18};
|
||||
let Inst{13} = target{17};
|
||||
let Inst{21-16} = target{16-11};
|
||||
let Inst{10-0} = target{10-0};
|
||||
bits<21> target;
|
||||
let Inst{26} = target{20};
|
||||
let Inst{11} = target{19};
|
||||
let Inst{13} = target{18};
|
||||
let Inst{21-16} = target{17-12};
|
||||
let Inst{10-0} = target{11-1};
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,6 +51,7 @@ public:
|
||||
{ "fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_arm_adr_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_arm_branch", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_t2_branch", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_arm_thumb_cp", 1, 8, MCFixupKindInfo::FKF_IsPCRel },
|
||||
@ -454,6 +455,9 @@ getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,
|
||||
uint32_t ARMMCCodeEmitter::
|
||||
getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
const ARMSubtarget &Subtarget = TM.getSubtarget<ARMSubtarget>();
|
||||
if (Subtarget.isThumb2())
|
||||
return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_branch, Fixups);
|
||||
return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_branch, Fixups);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user