diff options
-rw-r--r-- | include/llvm/MC/MCCodeEmitter.h | 5 | ||||
-rw-r--r-- | lib/MC/MCAssembler.cpp | 11 | ||||
-rw-r--r-- | lib/Target/ARM/ARMAsmBackend.cpp | 4 | ||||
-rw-r--r-- | lib/Target/ARM/ARMMCCodeEmitter.cpp | 3 |
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 }, |