summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/MC/MCCodeEmitter.h5
-rw-r--r--lib/MC/MCAssembler.cpp11
-rw-r--r--lib/Target/ARM/ARMAsmBackend.cpp4
-rw-r--r--lib/Target/ARM/ARMMCCodeEmitter.cpp3
4 files changed, 17 insertions, 6 deletions
diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h
index eac06ede2a..2588661b62 100644
--- a/include/llvm/MC/MCCodeEmitter.h
+++ b/include/llvm/MC/MCCodeEmitter.h
@@ -25,7 +25,10 @@ struct MCFixupKindInfo {
enum FixupKindFlags {
/// Is this fixup kind PCrelative? This is used by the assembler backend to
/// evaluate fixup values in a target independent manner when possible.
- FKF_IsPCRel = (1 << 0)
+ FKF_IsPCRel = (1 << 0),
+
+ // Should this fixup kind force a 4-byte aligned effective PC value?
+ FKF_IsAligned = (1 << 1)
};
/// A target specific name for the fixup kind. The names will be unique for
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index 323352ff8b..319f04cfe7 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -253,8 +253,15 @@ bool MCAssembler::EvaluateFixup(const MCObjectWriter &Writer,
if (IsResolved)
IsResolved = Writer.IsFixupFullyResolved(*this, Target, IsPCRel, DF);
- if (IsPCRel)
- Value -= Layout.getFragmentOffset(DF) + Fixup.getOffset();
+ if (IsPCRel) {
+ bool ShouldAlignPC = Emitter.getFixupKindInfo(
+ Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsAligned;
+ // PC should be aligned to a 4-byte value.
+ if (ShouldAlignPC)
+ Value -= Layout.getFragmentOffset(DF) + (Fixup.getOffset() & ~0x3);
+ else
+ Value -= Layout.getFragmentOffset(DF) + Fixup.getOffset();
+ }
return IsResolved;
}
diff --git a/lib/Target/ARM/ARMAsmBackend.cpp b/lib/Target/ARM/ARMAsmBackend.cpp
index 6be9f9288e..606437efbb 100644
--- a/lib/Target/ARM/ARMAsmBackend.cpp
+++ b/lib/Target/ARM/ARMAsmBackend.cpp
@@ -100,10 +100,10 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
}
case ARM::fixup_arm_ldst_pcrel_12:
// ARM PC-relative values are offset by 8.
- Value -= 6;
+ Value -= 4;
case ARM::fixup_t2_ldst_pcrel_12: {
// Offset by 4, adjusted by two due to the half-word ordering of thumb.
- Value -= 2;
+ Value -= 4;
bool isAdd = true;
if ((int64_t)Value < 0) {
Value = -Value;
diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp
index c81833b28f..4d8791c998 100644
--- a/lib/Target/ARM/ARMMCCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp
@@ -47,7 +47,8 @@ public:
const static MCFixupKindInfo Infos[] = {
// name off bits flags
{ "fixup_arm_ldst_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
- { "fixup_t2_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
+ { "fixup_t2_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel |
+ MCFixupKindInfo::FKF_IsAligned},
{ "fixup_arm_pcrel_10", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_arm_adr_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel },