summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMMCCodeEmitter.cpp
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2010-12-13 19:31:11 +0000
committerOwen Anderson <resistor@mac.com>2010-12-13 19:31:11 +0000
commit578074b2f3b5eedc7e3f391bb717ada05a1dde65 (patch)
treefd4c156c00858f68568c90c4771d4489a983eb89 /llvm/lib/Target/ARM/ARMMCCodeEmitter.cpp
parentf588c516b7e6063ea6e25e49c50bf7d16eb3592a (diff)
downloadbcm5719-llvm-578074b2f3b5eedc7e3f391bb717ada05a1dde65.tar.gz
bcm5719-llvm-578074b2f3b5eedc7e3f391bb717ada05a1dde65.zip
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. llvm-svn: 121710
Diffstat (limited to 'llvm/lib/Target/ARM/ARMMCCodeEmitter.cpp')
-rw-r--r--llvm/lib/Target/ARM/ARMMCCodeEmitter.cpp35
1 files changed, 33 insertions, 2 deletions
diff --git a/llvm/lib/Target/ARM/ARMMCCodeEmitter.cpp b/llvm/lib/Target/ARM/ARMMCCodeEmitter.cpp
index 833bd22c748..7f34ee96e37 100644
--- a/llvm/lib/Target/ARM/ARMMCCodeEmitter.cpp
+++ b/llvm/lib/Target/ARM/ARMMCCodeEmitter.cpp
@@ -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::
OpenPOWER on IntegriCloud