[llvm] r236324 - [Sparc] Repair fixups in little endian mode.
James Y Knight
jyknight at google.com
Fri May 1 10:13:03 PDT 2015
Author: jyknight
Date: Fri May 1 12:13:02 2015
New Revision: 236324
URL: http://llvm.org/viewvc/llvm-project?rev=236324&view=rev
Log:
[Sparc] Repair fixups in little endian mode.
Differential Revision: http://reviews.llvm.org/D9434
Added:
llvm/trunk/test/MC/Sparc/sparc-little-endian.s
Modified:
llvm/trunk/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
Modified: llvm/trunk/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp?rev=236324&r1=236323&r2=236324&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp (original)
+++ llvm/trunk/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp Fri May 1 12:13:02 2015
@@ -98,16 +98,23 @@ static unsigned adjustFixupValue(unsigne
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);
}
};
Added: llvm/trunk/test/MC/Sparc/sparc-little-endian.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Sparc/sparc-little-endian.s?rev=236324&view=auto
==============================================================================
--- llvm/trunk/test/MC/Sparc/sparc-little-endian.s (added)
+++ llvm/trunk/test/MC/Sparc/sparc-little-endian.s Fri May 1 12:13:02 2015
@@ -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
More information about the llvm-commits
mailing list