In Thumb2, direct branches can be encoded as either a "short" conditional branch with a null predicate, or

as a "long" direct branch.  While the mnemonics are the same, they encode the branch offset differently, and
the Darwin assembler appears to prefer the "long" form for direct branches.  Thus, in the name of bitwise
equivalence, provide encoding and fixup support for it.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121710 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Owen Anderson
2010-12-13 19:31:11 +00:00
parent 56a2535474
commit c266600bec
8 changed files with 73 additions and 8 deletions
+33 -2
View File
@@ -57,7 +57,8 @@ public:
MCFixupKindInfo::FKF_IsAligned},
{ "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_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_arm_thumb_blx", 7, 21, MCFixupKindInfo::FKF_IsPCRel },
@@ -122,6 +123,12 @@ public:
uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
SmallVectorImpl<MCFixup> &Fixups) const;
/// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit
/// immediate Thumb2 direct branch target.
uint32_t getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
SmallVectorImpl<MCFixup> &Fixups) const;
/// getAdrLabelOpValue - Return encoding info for 12-bit immediate
/// ADR label target.
uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
@@ -499,10 +506,34 @@ getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
// coupling between MC and TM anywhere we can help it.
const ARMSubtarget &Subtarget = TM.getSubtarget<ARMSubtarget>();
if (Subtarget.isThumb2())
return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_branch, Fixups);
return
::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups);
return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_branch, Fixups);
}
/// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit
/// immediate branch target.
uint32_t ARMMCCodeEmitter::
getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
SmallVectorImpl<MCFixup> &Fixups) const {
unsigned Val =
::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_uncondbranch, Fixups);
bool I = (Val & 0x800000);
bool J1 = (Val & 0x400000);
bool J2 = (Val & 0x200000);
if (I ^ J1)
Val &= ~0x400000;
else
Val |= 0x400000;
if (I ^ J2)
Val &= ~0x200000;
else
Val |= 0x200000;
return Val;
}
/// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label
/// target.
uint32_t ARMMCCodeEmitter::