1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 05:01:59 +01:00

Ensure conditional BL instructions for ARM are given the fixup fixup_arm_condbranch.

Patch by Tim Northover!

llvm-svn: 153737
This commit is contained in:
James Molloy 2012-03-30 09:15:32 +00:00
parent f3c23907f5
commit 70a6f5ebc7
8 changed files with 61 additions and 12 deletions

View File

@ -78,7 +78,8 @@ public:
{ "fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_arm_thumb_br", 0, 16, 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_blx", 0, 24, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_arm_thumb_blx", 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 || if (A && ((unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_blx ||
(unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_bl || (unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_bl ||
(unsigned)Fixup.getKind() == ARM::fixup_arm_blx || (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; IsResolved = false;
} }
@ -366,7 +368,8 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
case ARM::fixup_arm_condbranch: case ARM::fixup_arm_condbranch:
case ARM::fixup_arm_uncondbranch: 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: case ARM::fixup_arm_blx:
// These values don't encode the low two bits since they're always zero. // These values don't encode the low two bits since they're always zero.
// Offset by 8 just as above. // 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_ldst_pcrel_12:
case ARM::fixup_arm_pcrel_10: case ARM::fixup_arm_pcrel_10:
case ARM::fixup_arm_adr_pcrel_12: 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_blx:
case ARM::fixup_arm_condbranch: case ARM::fixup_arm_condbranch:
case ARM::fixup_arm_uncondbranch: case ARM::fixup_arm_uncondbranch:

View File

@ -178,7 +178,7 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
break; break;
} }
break; break;
case ARM::fixup_arm_bl: case ARM::fixup_arm_uncondbl:
case ARM::fixup_arm_blx: case ARM::fixup_arm_blx:
case ARM::fixup_arm_uncondbranch: case ARM::fixup_arm_uncondbranch:
switch (Modifier) { switch (Modifier) {
@ -190,6 +190,7 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
break; break;
} }
break; break;
case ARM::fixup_arm_condbl:
case ARM::fixup_arm_condbranch: case ARM::fixup_arm_condbranch:
Type = ELF::R_ARM_JUMP24; Type = ELF::R_ARM_JUMP24;
break; break;

View File

@ -59,8 +59,21 @@ enum Fixups {
// fixup_arm_thumb_br - 12-bit fixup for Thumb B instructions. // fixup_arm_thumb_br - 12-bit fixup for Thumb B instructions.
fixup_arm_thumb_br, fixup_arm_thumb_br,
// fixup_arm_bl - Fixup for ARM BL instructions. // The following fixups handle the ARM BL instructions. These can be
fixup_arm_bl, // 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 - Fixup for ARM BLX instructions.
fixup_arm_blx, fixup_arm_blx,

View File

@ -597,8 +597,12 @@ uint32_t ARMMCCodeEmitter::
getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx, getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
SmallVectorImpl<MCFixup> &Fixups) const { SmallVectorImpl<MCFixup> &Fixups) const {
const MCOperand MO = MI.getOperand(OpIdx); const MCOperand MO = MI.getOperand(OpIdx);
if (MO.isExpr()) if (MO.isExpr()) {
return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_bl, Fixups); 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; return MO.getImm() >> 2;
} }

View File

@ -82,7 +82,8 @@ static bool getARMFixupKindMachOInfo(unsigned Kind, unsigned &RelocType,
case ARM::fixup_arm_adr_pcrel_12: case ARM::fixup_arm_adr_pcrel_12:
case ARM::fixup_arm_condbranch: case ARM::fixup_arm_condbranch:
case ARM::fixup_arm_uncondbranch: 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: case ARM::fixup_arm_blx:
RelocType = unsigned(macho::RIT_ARM_Branch24Bit); RelocType = unsigned(macho::RIT_ARM_Branch24Bit);
// Report as 'long', even though that is not quite accurate. // Report as 'long', even though that is not quite accurate.

View File

@ -3,7 +3,7 @@
bl _printf bl _printf
@ CHECK: bl _printf @ encoding: [A,A,A,0xeb] @ CHECK: bl _printf @ encoding: [A,A,A,0xeb]
@ CHECK: @ fixup A - offset: 0, value: _printf, kind: fixup_arm_bl @ CHECK: @ fixup A - offset: 0, value: _printf, kind: fixup_arm_uncondbl
mov r9, :lower16:(_foo) mov r9, :lower16:(_foo)
movw r9, :lower16:(_foo) movw r9, :lower16:(_foo)

View File

@ -382,13 +382,16 @@ Lforward:
@------------------------------------------------------------------------------ @------------------------------------------------------------------------------
bl _bar bl _bar
bleq _bar
blx _bar blx _bar
blls #28634268 blls #28634268
blx #32424576 blx #32424576
blx #16212288 blx #16212288
@ CHECK: bl _bar @ encoding: [A,A,A,0xeb] @ CHECK: bl _bar @ encoding: [A,A,A,0xeb]
@ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_bl @ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_uncondbl
@ CHECK: bleq _bar @ encoding: [A,A,A,0x0b]
@ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_condbl
@ CHECK: blx _bar @ encoding: [A,A,A,0xfa] @ CHECK: blx _bar @ encoding: [A,A,A,0xfa]
@ fixup A - offset: 0, value: _bar, kind: fixup_arm_blx @ fixup A - offset: 0, value: _bar, kind: fixup_arm_blx
@ CHECK: blls #28634268 @ encoding: [0x27,0x3b,0x6d,0x9b] @ CHECK: blls #28634268 @ encoding: [0x27,0x3b,0x6d,0x9b]

View File

@ -0,0 +1,23 @@
// RUN: llvm-mc -triple=armv7-linux-gnueabi -filetype=obj %s -o - | \
// RUN: elf-dump | FileCheck -check-prefix=OBJ %s
bleq some_label
bl some_label
blx some_label
// OBJ: .rel.text
// OBJ: 'r_offset', 0x00000000
// OBJ-NEXT: 'r_sym', 0x000004
// OBJ-NEXT: 'r_type', 0x1d
// OBJ: 'r_offset', 0x00000004
// OBJ-NEXT: 'r_sym', 0x000004
// OBJ-NEXT: 'r_type', 0x1c
// OBJ: 'r_offset', 0x00000008
// OBJ-NEXT: 'r_sym', 0x000004
// OBJ-NEXT: 'r_type', 0x1c
// OBJ: .symtab
// OBJ: Symbol 4
// OBJ-NEXT: some_label