Skip to content

Commit fb7f65b

Browse files
authored
[SPARC][IAS] Emit the correct ELF machine type (#96583)
Emit the correct machine type when writing out ELF objects. This patch is modeled on GCC's behavior: - `-m32` emits an object of type EM_SPARC; - `-m32 -mcpu=v9` emits EM_SPARC32PLUS (however, see below); and - `-m64` emits EM_SPARCV9. Note that GCC does not guarantee emission of EM_SPARC32PLUS objects, since GNU as doesn't support user control of emitted machine type. It will always autodetect the type based on the instruction mix: - If there's a V9 instruction inside, then emit EM_SPARC32PLUS; and - Emit EM_SPARC otherwise. For LLVM we choose deterministic behavior instead for simplicity.
1 parent 52cc7c0 commit fb7f65b

File tree

4 files changed

+31
-16
lines changed

4 files changed

+31
-16
lines changed

llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -131,15 +131,16 @@ static unsigned getFixupKindNumBytes(unsigned Kind) {
131131
namespace {
132132
class SparcAsmBackend : public MCAsmBackend {
133133
protected:
134-
const Target &TheTarget;
135134
bool Is64Bit;
135+
bool HasV9;
136136

137137
public:
138-
SparcAsmBackend(const Target &T)
139-
: MCAsmBackend(StringRef(T.getName()) == "sparcel"
138+
SparcAsmBackend(const MCSubtargetInfo &STI)
139+
: MCAsmBackend(STI.getTargetTriple().isLittleEndian()
140140
? llvm::endianness::little
141141
: llvm::endianness::big),
142-
TheTarget(T), Is64Bit(StringRef(TheTarget.getName()) == "sparcv9") {}
142+
Is64Bit(STI.getTargetTriple().isArch64Bit()),
143+
HasV9(STI.hasFeature(Sparc::FeatureV9)) {}
143144

144145
unsigned getNumFixupKinds() const override {
145146
return Sparc::NumTargetFixupKinds;
@@ -330,8 +331,8 @@ namespace {
330331
class ELFSparcAsmBackend : public SparcAsmBackend {
331332
Triple::OSType OSType;
332333
public:
333-
ELFSparcAsmBackend(const Target &T, Triple::OSType OSType) :
334-
SparcAsmBackend(T), OSType(OSType) { }
334+
ELFSparcAsmBackend(const MCSubtargetInfo &STI, Triple::OSType OSType)
335+
: SparcAsmBackend(STI), OSType(OSType) {}
335336

336337
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
337338
const MCValue &Target, MutableArrayRef<char> Data,
@@ -358,7 +359,7 @@ namespace {
358359
std::unique_ptr<MCObjectTargetWriter>
359360
createObjectTargetWriter() const override {
360361
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType);
361-
return createSparcELFObjectWriter(Is64Bit, OSABI);
362+
return createSparcELFObjectWriter(Is64Bit, HasV9, OSABI);
362363
}
363364
};
364365

@@ -368,5 +369,5 @@ MCAsmBackend *llvm::createSparcAsmBackend(const Target &T,
368369
const MCSubtargetInfo &STI,
369370
const MCRegisterInfo &MRI,
370371
const MCTargetOptions &Options) {
371-
return new ELFSparcAsmBackend(T, STI.getTargetTriple().getOS());
372+
return new ELFSparcAsmBackend(STI, STI.getTargetTriple().getOS());
372373
}

llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ using namespace llvm;
2121
namespace {
2222
class SparcELFObjectWriter : public MCELFObjectTargetWriter {
2323
public:
24-
SparcELFObjectWriter(bool Is64Bit, uint8_t OSABI)
25-
: MCELFObjectTargetWriter(Is64Bit, OSABI,
26-
Is64Bit ? ELF::EM_SPARCV9 : ELF::EM_SPARC,
27-
/*HasRelocationAddend*/ true) {}
24+
SparcELFObjectWriter(bool Is64Bit, bool HasV9, uint8_t OSABI)
25+
: MCELFObjectTargetWriter(
26+
Is64Bit, OSABI,
27+
Is64Bit ? ELF::EM_SPARCV9
28+
: (HasV9 ? ELF::EM_SPARC32PLUS : ELF::EM_SPARC),
29+
/*HasRelocationAddend*/ true) {}
2830

2931
~SparcELFObjectWriter() override = default;
3032

@@ -146,6 +148,6 @@ bool SparcELFObjectWriter::needsRelocateWithSymbol(const MCValue &,
146148
}
147149

148150
std::unique_ptr<MCObjectTargetWriter>
149-
llvm::createSparcELFObjectWriter(bool Is64Bit, uint8_t OSABI) {
150-
return std::make_unique<SparcELFObjectWriter>(Is64Bit, OSABI);
151+
llvm::createSparcELFObjectWriter(bool Is64Bit, bool HasV9, uint8_t OSABI) {
152+
return std::make_unique<SparcELFObjectWriter>(Is64Bit, HasV9, OSABI);
151153
}

llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ MCCodeEmitter *createSparcMCCodeEmitter(const MCInstrInfo &MCII,
3434
MCAsmBackend *createSparcAsmBackend(const Target &T, const MCSubtargetInfo &STI,
3535
const MCRegisterInfo &MRI,
3636
const MCTargetOptions &Options);
37-
std::unique_ptr<MCObjectTargetWriter> createSparcELFObjectWriter(bool Is64Bit,
38-
uint8_t OSABI);
37+
std::unique_ptr<MCObjectTargetWriter>
38+
createSparcELFObjectWriter(bool Is64Bit, bool HasV9, uint8_t OSABI);
3939

4040
// Defines symbolic names for Sparc v9 ASI tag names.
4141
namespace SparcASITag {
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
## Emit correct machine type depending on triple and cpu options.
2+
## - `-triple sparc` emits an object of type EM_SPARC;
3+
## - `-triple sparc -mcpu=v9` emits EM_SPARC32PLUS; and
4+
## - `-triple sparcv9` emits EM_SPARCV9.
5+
6+
# RUN: llvm-mc -filetype=obj -triple sparc %s -o - | llvm-readobj -h - | FileCheck --check-prefixes=SPARC %s
7+
# RUN: llvm-mc -filetype=obj -triple sparc -mcpu=v9 %s -o - | llvm-readobj -h - | FileCheck --check-prefixes=SPARC32PLUS %s
8+
# RUN: llvm-mc -filetype=obj -triple sparcv9 %s -o - | llvm-readobj -h - | FileCheck --check-prefixes=SPARCV9 %s
9+
10+
# SPARC: Machine: EM_SPARC (0x2)
11+
# SPARC32PLUS: Machine: EM_SPARC32PLUS (0x12)
12+
# SPARCV9: Machine: EM_SPARCV9 (0x2B)

0 commit comments

Comments
 (0)