diff options
author | Jim Grosbach <grosbach@apple.com> | 2010-11-30 22:40:36 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2010-11-30 22:40:36 +0000 |
commit | 2d3e5c1aec7aefa82cd080bdd6eebbcbb4a360b5 (patch) | |
tree | d3dc72dff7c4b7a183ca9b38e2b82a79ebe08c9e /llvm/lib/Target/ARM/ARMAsmBackend.cpp | |
parent | 1922a8dbea97a6a5110f4cc62f8af1c077f5c4da (diff) | |
download | bcm5719-llvm-2d3e5c1aec7aefa82cd080bdd6eebbcbb4a360b5.tar.gz bcm5719-llvm-2d3e5c1aec7aefa82cd080bdd6eebbcbb4a360b5.zip |
Fix handling of ARM negative pc-relative fixups for loads and stores.
llvm-svn: 120480
Diffstat (limited to 'llvm/lib/Target/ARM/ARMAsmBackend.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/ARMAsmBackend.cpp | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/llvm/lib/Target/ARM/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/ARMAsmBackend.cpp index e7ff8bd1fab..6267a5af990 100644 --- a/llvm/lib/Target/ARM/ARMAsmBackend.cpp +++ b/llvm/lib/Target/ARM/ARMAsmBackend.cpp @@ -131,8 +131,8 @@ static unsigned getFixupKindNumBytes(unsigned Kind) { switch (Kind) { default: llvm_unreachable("Unknown fixup kind!"); case FK_Data_4: return 4; - case ARM::fixup_arm_pcrel_12: return 2; - case ARM::fixup_arm_vfp_pcrel_12: return 1; + case ARM::fixup_arm_pcrel_12: return 3; + case ARM::fixup_arm_vfp_pcrel_12: return 3; case ARM::fixup_arm_branch: return 3; } } @@ -143,14 +143,36 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { llvm_unreachable("Unknown fixup kind!"); case FK_Data_4: return Value; - case ARM::fixup_arm_pcrel_12: + case ARM::fixup_arm_pcrel_12: { + bool isAdd = true; // ARM PC-relative values are offset by 8. - return Value - 8; + Value -= 8; + if ((int64_t)Value < 0) { + Value = -Value; + isAdd = false; + } + assert ((Value < 4096) && "Out of range pc-relative fixup value!"); + Value |= isAdd << 23; + return Value; + } case ARM::fixup_arm_branch: - case ARM::fixup_arm_vfp_pcrel_12: // These values don't encode the low two bits since they're always zero. // Offset by 8 just as above. return (Value - 8) >> 2; + case ARM::fixup_arm_vfp_pcrel_12: { + // Offset by 8 just as above. + Value = Value - 8; + bool isAdd = true; + if ((int64_t)Value < 0) { + Value = -Value; + isAdd = false; + } + // These values don't encode the low two bits since they're always zero. + Value >>= 2; + assert ((Value < 256) && "Out of range pc-relative fixup value!"); + Value |= isAdd << 23; + return Value; + } } } |