diff options
author | James Molloy <james.molloy@arm.com> | 2012-03-30 09:15:32 +0000 |
---|---|---|
committer | James Molloy <james.molloy@arm.com> | 2012-03-30 09:15:32 +0000 |
commit | cb0809b82b126e79b99755ae4fc3d9733faea038 (patch) | |
tree | 850a983c467c93d3487f17578c8593da0ea98b8a /lib | |
parent | 1c80f56268fa91f9c0c4d0a32b5d61e7b900c6d4 (diff) | |
download | external_llvm-cb0809b82b126e79b99755ae4fc3d9733faea038.zip external_llvm-cb0809b82b126e79b99755ae4fc3d9733faea038.tar.gz external_llvm-cb0809b82b126e79b99755ae4fc3d9733faea038.tar.bz2 |
Ensure conditional BL instructions for ARM are given the fixup fixup_arm_condbranch.
Patch by Tim Northover!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153737 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 12 | ||||
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp | 3 | ||||
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h | 17 | ||||
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp | 8 | ||||
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp | 3 |
5 files changed, 33 insertions, 10 deletions
diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index ab40f45..3ba891d 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -78,7 +78,8 @@ public: { "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_bl", 0, 24, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_arm_uncondbl", 0, 24, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_arm_condbl", 0, 24, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_arm_blx", 0, 24, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_arm_thumb_blx", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, @@ -128,7 +129,8 @@ public: if (A && ((unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_blx || (unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_bl || (unsigned)Fixup.getKind() == ARM::fixup_arm_blx || - (unsigned)Fixup.getKind() == ARM::fixup_arm_bl)) + (unsigned)Fixup.getKind() == ARM::fixup_arm_uncondbl || + (unsigned)Fixup.getKind() == ARM::fixup_arm_condbl)) IsResolved = false; } @@ -366,7 +368,8 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { case ARM::fixup_arm_condbranch: case ARM::fixup_arm_uncondbranch: - case ARM::fixup_arm_bl: + case ARM::fixup_arm_uncondbl: + case ARM::fixup_arm_condbl: case ARM::fixup_arm_blx: // These values don't encode the low two bits since they're always zero. // Offset by 8 just as above. @@ -577,7 +580,8 @@ static unsigned getFixupKindNumBytes(unsigned Kind) { case ARM::fixup_arm_ldst_pcrel_12: case ARM::fixup_arm_pcrel_10: case ARM::fixup_arm_adr_pcrel_12: - case ARM::fixup_arm_bl: + case ARM::fixup_arm_uncondbl: + case ARM::fixup_arm_condbl: case ARM::fixup_arm_blx: case ARM::fixup_arm_condbranch: case ARM::fixup_arm_uncondbranch: diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp index 98a8bf5..aa649ba 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp @@ -178,7 +178,7 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, break; } break; - case ARM::fixup_arm_bl: + case ARM::fixup_arm_uncondbl: case ARM::fixup_arm_blx: case ARM::fixup_arm_uncondbranch: switch (Modifier) { @@ -190,6 +190,7 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, break; } break; + case ARM::fixup_arm_condbl: case ARM::fixup_arm_condbranch: Type = ELF::R_ARM_JUMP24; break; diff --git a/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h b/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h index 1827986..0085feb 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h +++ b/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h @@ -59,8 +59,21 @@ enum Fixups { // fixup_arm_thumb_br - 12-bit fixup for Thumb B instructions. fixup_arm_thumb_br, - // fixup_arm_bl - Fixup for ARM BL instructions. - fixup_arm_bl, + // The following fixups handle the ARM BL instructions. These can be + // conditionalised; however, the ARM ELF ABI requires a different relocation + // in that case: R_ARM_JUMP24 instead of R_ARM_CALL. The difference is that + // R_ARM_CALL is allowed to change the instruction to a BLX inline, which has + // no conditional version; R_ARM_JUMP24 would have to insert a veneer. + // + // MachO does not draw a distinction between the two cases, so it will treat + // fixup_arm_uncondbl and fixup_arm_condbl as identical fixups. + + // fixup_arm_uncondbl - Fixup for unconditional ARM BL instructions. + fixup_arm_uncondbl, + + // fixup_arm_condbl - Fixup for ARM BL instructions with nontrivial + // conditionalisation. + fixup_arm_condbl, // fixup_arm_blx - Fixup for ARM BLX instructions. fixup_arm_blx, diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp index e378a9c..10d1c48 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp @@ -597,8 +597,12 @@ uint32_t ARMMCCodeEmitter:: getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups) const { const MCOperand MO = MI.getOperand(OpIdx); - if (MO.isExpr()) - return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_bl, Fixups); + if (MO.isExpr()) { + if (HasConditionalBranch(MI)) + return ::getBranchTargetOpValue(MI, OpIdx, + ARM::fixup_arm_condbl, Fixups); + return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_uncondbl, Fixups); + } return MO.getImm() >> 2; } diff --git a/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp index 9d3da14..8057cb6 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp @@ -82,7 +82,8 @@ static bool getARMFixupKindMachOInfo(unsigned Kind, unsigned &RelocType, case ARM::fixup_arm_adr_pcrel_12: case ARM::fixup_arm_condbranch: case ARM::fixup_arm_uncondbranch: - case ARM::fixup_arm_bl: + case ARM::fixup_arm_uncondbl: + case ARM::fixup_arm_condbl: case ARM::fixup_arm_blx: RelocType = unsigned(macho::RIT_ARM_Branch24Bit); // Report as 'long', even though that is not quite accurate. |