summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2012-01-18 21:54:16 +0000
committerJim Grosbach <grosbach@apple.com>2012-01-18 21:54:16 +0000
commitcb80eb2e7577d539363c0b4ec9a4ca456af430be (patch)
treed92f05377ec8d0991003d66821951621e45adf8d /llvm/lib
parentd4dbd09d854f7e3834e95cd59f4c945afbd01109 (diff)
downloadbcm5719-llvm-cb80eb2e7577d539363c0b4ec9a4ca456af430be.tar.gz
bcm5719-llvm-cb80eb2e7577d539363c0b4ec9a4ca456af430be.zip
Thumb2 relaxation for LDR(literal).
If the fixup is out of range for the Thumb1 instruction, relax it to the Thumb2 encoding instead. rdar://10711829 llvm-svn: 148424
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp29
1 files changed, 20 insertions, 9 deletions
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index d24265a817c..adedc208d0e 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -152,7 +152,8 @@ public:
static unsigned getRelaxedOpcode(unsigned Op) {
switch (Op) {
default: return Op;
- case ARM::tBcc: return ARM::t2Bcc;
+ case ARM::tBcc: return ARM::t2Bcc;
+ case ARM::tLDRpciASM: return ARM::t2LDRpci;
}
}
@@ -166,14 +167,24 @@ bool ARMAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
uint64_t Value,
const MCInstFragment *DF,
const MCAsmLayout &Layout) const {
- // Relaxing tBcc to t2Bcc. tBcc has a signed 9-bit displacement with the
- // low bit being an implied zero. There's an implied +4 offset for the
- // branch, so we adjust the other way here to determine what's
- // encodable.
- //
- // Relax if the value is too big for a (signed) i8.
- int64_t Offset = int64_t(Value) - 4;
- return Offset > 254 || Offset < -256;
+ switch (Fixup.getKind()) {
+ default: assert(0 && "Unexpected fixup kind in fixupNeedsRelaxation()!");
+ case ARM::fixup_arm_thumb_bcc: {
+ // Relaxing tBcc to t2Bcc. tBcc has a signed 9-bit displacement with the
+ // low bit being an implied zero. There's an implied +4 offset for the
+ // branch, so we adjust the other way here to determine what's
+ // encodable.
+ //
+ // Relax if the value is too big for a (signed) i8.
+ int64_t Offset = int64_t(Value) - 4;
+ return Offset > 254 || Offset < -256;
+ }
+ case ARM::fixup_arm_thumb_cp: {
+ int64_t Offset = int64_t(Value) - 4;
+ return Offset > 4095 || Offset < 0;
+ }
+ }
+ llvm_unreachable("Invalid switch/cash!?");
}
void ARMAsmBackend::relaxInstruction(const MCInst &Inst, MCInst &Res) const {
OpenPOWER on IntegriCloud