mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
[Sparc] Repair fixups in little endian mode.
Differential Revision: http://reviews.llvm.org/D9434 llvm-svn: 236324
This commit is contained in:
parent
e416edad83
commit
3157c00641
@ -98,16 +98,23 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
|
||||
|
||||
namespace {
|
||||
class SparcAsmBackend : public MCAsmBackend {
|
||||
protected:
|
||||
const Target &TheTarget;
|
||||
bool IsLittleEndian;
|
||||
bool Is64Bit;
|
||||
|
||||
public:
|
||||
SparcAsmBackend(const Target &T) : MCAsmBackend(), TheTarget(T) {}
|
||||
SparcAsmBackend(const Target &T)
|
||||
: MCAsmBackend(), TheTarget(T),
|
||||
IsLittleEndian(StringRef(TheTarget.getName()) == "sparcel"),
|
||||
Is64Bit(StringRef(TheTarget.getName()) == "sparcv9") {}
|
||||
|
||||
unsigned getNumFixupKinds() const override {
|
||||
return Sparc::NumTargetFixupKinds;
|
||||
}
|
||||
|
||||
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
|
||||
const static MCFixupKindInfo Infos[Sparc::NumTargetFixupKinds] = {
|
||||
const static MCFixupKindInfo InfosBE[Sparc::NumTargetFixupKinds] = {
|
||||
// name offset bits flags
|
||||
{ "fixup_sparc_call30", 2, 30, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_br22", 10, 22, MCFixupKindInfo::FKF_IsPCRel },
|
||||
@ -146,12 +153,54 @@ namespace {
|
||||
{ "fixup_sparc_tls_le_lox10", 0, 0, 0 }
|
||||
};
|
||||
|
||||
const static MCFixupKindInfo InfosLE[Sparc::NumTargetFixupKinds] = {
|
||||
// name offset bits flags
|
||||
{ "fixup_sparc_call30", 0, 30, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_br22", 0, 22, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_br19", 0, 19, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_br16_2", 20, 2, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_br16_14", 0, 14, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_hi22", 0, 22, 0 },
|
||||
{ "fixup_sparc_lo10", 0, 10, 0 },
|
||||
{ "fixup_sparc_h44", 0, 22, 0 },
|
||||
{ "fixup_sparc_m44", 0, 10, 0 },
|
||||
{ "fixup_sparc_l44", 0, 12, 0 },
|
||||
{ "fixup_sparc_hh", 0, 22, 0 },
|
||||
{ "fixup_sparc_hm", 0, 10, 0 },
|
||||
{ "fixup_sparc_pc22", 0, 22, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_pc10", 0, 10, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_got22", 0, 22, 0 },
|
||||
{ "fixup_sparc_got10", 0, 10, 0 },
|
||||
{ "fixup_sparc_wplt30", 0, 30, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_tls_gd_hi22", 0, 22, 0 },
|
||||
{ "fixup_sparc_tls_gd_lo10", 0, 10, 0 },
|
||||
{ "fixup_sparc_tls_gd_add", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_gd_call", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_ldm_hi22", 0, 22, 0 },
|
||||
{ "fixup_sparc_tls_ldm_lo10", 0, 10, 0 },
|
||||
{ "fixup_sparc_tls_ldm_add", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_ldm_call", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_ldo_hix22", 0, 22, 0 },
|
||||
{ "fixup_sparc_tls_ldo_lox10", 0, 10, 0 },
|
||||
{ "fixup_sparc_tls_ldo_add", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_ie_hi22", 0, 22, 0 },
|
||||
{ "fixup_sparc_tls_ie_lo10", 0, 10, 0 },
|
||||
{ "fixup_sparc_tls_ie_ld", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_ie_ldx", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_ie_add", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_le_hix22", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_le_lox10", 0, 0, 0 }
|
||||
};
|
||||
|
||||
if (Kind < FirstTargetFixupKind)
|
||||
return MCAsmBackend::getFixupKindInfo(Kind);
|
||||
|
||||
assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
|
||||
"Invalid kind!");
|
||||
return Infos[Kind - FirstTargetFixupKind];
|
||||
if (IsLittleEndian)
|
||||
return InfosLE[Kind - FirstTargetFixupKind];
|
||||
|
||||
return InfosBE[Kind - FirstTargetFixupKind];
|
||||
}
|
||||
|
||||
void processFixupValue(const MCAssembler &Asm, const MCAsmLayout &Layout,
|
||||
@ -215,11 +264,6 @@ namespace {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is64Bit() const { return StringRef(TheTarget.getName()) == "sparcv9"; }
|
||||
bool isLittleEndian() const {
|
||||
return StringRef(TheTarget.getName()) == "sparcel";
|
||||
}
|
||||
};
|
||||
|
||||
class ELFSparcAsmBackend : public SparcAsmBackend {
|
||||
@ -239,14 +283,15 @@ namespace {
|
||||
// For each byte of the fragment that the fixup touches, mask in the bits
|
||||
// from the fixup value. The Value has been "split up" into the
|
||||
// appropriate bitfields above.
|
||||
for (unsigned i = 0; i != 4; ++i)
|
||||
Data[Offset + i] |= uint8_t((Value >> ((4 - i - 1)*8)) & 0xff);
|
||||
|
||||
for (unsigned i = 0; i != 4; ++i) {
|
||||
unsigned Idx = IsLittleEndian ? i : 3 - i;
|
||||
Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override {
|
||||
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType);
|
||||
return createSparcELFObjectWriter(OS, is64Bit(), isLittleEndian(), OSABI);
|
||||
return createSparcELFObjectWriter(OS, Is64Bit, IsLittleEndian, OSABI);
|
||||
}
|
||||
};
|
||||
|
||||
|
18
test/MC/Sparc/sparc-little-endian.s
Normal file
18
test/MC/Sparc/sparc-little-endian.s
Normal file
@ -0,0 +1,18 @@
|
||||
! RUN: llvm-mc %s -arch=sparcel -show-encoding | FileCheck %s
|
||||
! RUN: llvm-mc -arch=sparcel -filetype=obj < %s | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-OBJ
|
||||
|
||||
! CHECK-OBJ: .text:
|
||||
.BB0:
|
||||
|
||||
! Ensure instructions are emitted in reversed byte order:
|
||||
|
||||
! CHECK: call %g1 ! encoding: [0x00,0x40,0xc0,0x9f]
|
||||
! CHECK-OBJ: 0: 00 40 c0 9f call %g1
|
||||
call %g1
|
||||
|
||||
! ...and that fixups are applied to the correct bytes.
|
||||
|
||||
! CHECK: ba .BB0 ! encoding: [A,A,0b10AAAAAA,0x10]
|
||||
! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
|
||||
! CHECK-OBJ: 4: ff ff bf 10 ba 4194303
|
||||
ba .BB0
|
Loading…
Reference in New Issue
Block a user