mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-13 06:34:24 +00:00
Sketch out PowerPC ELF writer. This is enough to get clang -integrated-as
to compile a working hello world on FreeBSD/PPC32. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136689 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
086da7e680
commit
2c0d69fad0
@ -290,6 +290,23 @@ enum {
|
||||
R_MICROBLAZE_COPY = 21
|
||||
};
|
||||
|
||||
enum {
|
||||
R_PPC_NONE = 0, /* No relocation. */
|
||||
R_PPC_ADDR32 = 1,
|
||||
R_PPC_ADDR24 = 2,
|
||||
R_PPC_ADDR16 = 3,
|
||||
R_PPC_ADDR16_LO = 4,
|
||||
R_PPC_ADDR16_HI = 5,
|
||||
R_PPC_ADDR16_HA = 6,
|
||||
R_PPC_ADDR14 = 7,
|
||||
R_PPC_ADDR14_BRTAKEN = 8,
|
||||
R_PPC_ADDR14_BRNTAKEN = 9,
|
||||
R_PPC_REL24 = 10,
|
||||
R_PPC_REL14 = 11,
|
||||
R_PPC_REL14_BRTAKEN = 12,
|
||||
R_PPC_REL14_BRNTAKEN = 13,
|
||||
R_PPC_REL32 = 26
|
||||
};
|
||||
|
||||
// ARM Specific e_flags
|
||||
enum { EF_ARM_EABIMASK = 0xFF000000U };
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include "../Target/X86/MCTargetDesc/X86FixupKinds.h"
|
||||
#include "../Target/ARM/MCTargetDesc/ARMFixupKinds.h"
|
||||
#include "../Target/PowerPC/MCTargetDesc/PPCFixupKinds.h"
|
||||
|
||||
#include <vector>
|
||||
using namespace llvm;
|
||||
@ -446,6 +447,14 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
|
||||
|
||||
uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) +
|
||||
Fixup.getOffset();
|
||||
switch ((unsigned)Fixup.getKind()) {
|
||||
case PPC::fixup_ppc_ha16:
|
||||
case PPC::fixup_ppc_lo16:
|
||||
RelocOffset += 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!hasRelocationAddend())
|
||||
Addend = 0;
|
||||
@ -1252,6 +1261,9 @@ MCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
|
||||
return new ARMELFObjectWriter(MOTW, OS, IsLittleEndian); break;
|
||||
case ELF::EM_MBLAZE:
|
||||
return new MBlazeELFObjectWriter(MOTW, OS, IsLittleEndian); break;
|
||||
case ELF::EM_PPC:
|
||||
case ELF::EM_PPC64:
|
||||
return new PPCELFObjectWriter(MOTW, OS, IsLittleEndian); break;
|
||||
default: llvm_unreachable("Unsupported architecture"); break;
|
||||
}
|
||||
}
|
||||
@ -1503,6 +1515,64 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
|
||||
return Type;
|
||||
}
|
||||
|
||||
//===- PPCELFObjectWriter -------------------------------------------===//
|
||||
|
||||
PPCELFObjectWriter::PPCELFObjectWriter(MCELFObjectTargetWriter *MOTW,
|
||||
raw_ostream &_OS,
|
||||
bool IsLittleEndian)
|
||||
: ELFObjectWriter(MOTW, _OS, IsLittleEndian) {
|
||||
}
|
||||
|
||||
PPCELFObjectWriter::~PPCELFObjectWriter() {
|
||||
}
|
||||
|
||||
unsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target,
|
||||
const MCFixup &Fixup,
|
||||
bool IsPCRel,
|
||||
bool IsRelocWithSymbol,
|
||||
int64_t Addend) {
|
||||
// determine the type of the relocation
|
||||
unsigned Type;
|
||||
if (IsPCRel) {
|
||||
switch ((unsigned)Fixup.getKind()) {
|
||||
default:
|
||||
llvm_unreachable("Unimplemented");
|
||||
case PPC::fixup_ppc_br24:
|
||||
Type = ELF::R_PPC_REL24;
|
||||
break;
|
||||
case FK_PCRel_4:
|
||||
Type = ELF::R_PPC_REL32;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch ((unsigned)Fixup.getKind()) {
|
||||
default: llvm_unreachable("invalid fixup kind!");
|
||||
case PPC::fixup_ppc_br24:
|
||||
Type = ELF::R_PPC_ADDR24;
|
||||
break;
|
||||
case PPC::fixup_ppc_brcond14:
|
||||
Type = ELF::R_PPC_ADDR14_BRTAKEN; // XXX: or BRNTAKEN?_
|
||||
break;
|
||||
case PPC::fixup_ppc_ha16:
|
||||
Type = ELF::R_PPC_ADDR16_HA;
|
||||
break;
|
||||
case PPC::fixup_ppc_lo16:
|
||||
Type = ELF::R_PPC_ADDR16_LO;
|
||||
break;
|
||||
case PPC::fixup_ppc_lo14:
|
||||
Type = ELF::R_PPC_ADDR14;
|
||||
break;
|
||||
case FK_Data_4:
|
||||
Type = ELF::R_PPC_ADDR32;
|
||||
break;
|
||||
case FK_Data_2:
|
||||
Type = ELF::R_PPC_ADDR16;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Type;
|
||||
}
|
||||
|
||||
//===- MBlazeELFObjectWriter -------------------------------------------===//
|
||||
|
||||
MBlazeELFObjectWriter::MBlazeELFObjectWriter(MCELFObjectTargetWriter *MOTW,
|
||||
|
@ -395,6 +395,21 @@ class ELFObjectWriter : public MCObjectWriter {
|
||||
|
||||
};
|
||||
|
||||
//===- PPCELFObjectWriter -------------------------------------------===//
|
||||
|
||||
class PPCELFObjectWriter : public ELFObjectWriter {
|
||||
public:
|
||||
PPCELFObjectWriter(MCELFObjectTargetWriter *MOTW,
|
||||
raw_ostream &_OS,
|
||||
bool IsLittleEndian);
|
||||
|
||||
virtual ~PPCELFObjectWriter();
|
||||
protected:
|
||||
virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
|
||||
bool IsPCRel, bool IsRelocWithSymbol,
|
||||
int64_t Addend);
|
||||
};
|
||||
|
||||
//===- MBlazeELFObjectWriter -------------------------------------------===//
|
||||
|
||||
class MBlazeELFObjectWriter : public ELFObjectWriter {
|
||||
|
@ -10,14 +10,40 @@
|
||||
#include "llvm/MC/MCAsmBackend.h"
|
||||
#include "MCTargetDesc/PPCMCTargetDesc.h"
|
||||
#include "MCTargetDesc/PPCFixupKinds.h"
|
||||
#include "llvm/MC/MCELFObjectWriter.h"
|
||||
#include "llvm/MC/MCMachObjectWriter.h"
|
||||
#include "llvm/MC/MCSectionMachO.h"
|
||||
#include "llvm/MC/MCObjectWriter.h"
|
||||
#include "llvm/MC/MCValue.h"
|
||||
#include "llvm/Object/MachOFormat.h"
|
||||
#include "llvm/Support/ELF.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Target/TargetRegistry.h"
|
||||
using namespace llvm;
|
||||
|
||||
static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
|
||||
switch (Kind) {
|
||||
default:
|
||||
llvm_unreachable("Unknown fixup kind!");
|
||||
case FK_Data_1:
|
||||
case FK_Data_2:
|
||||
case FK_Data_4:
|
||||
return Value;
|
||||
case PPC::fixup_ppc_brcond14:
|
||||
return Value & 0x3ffc;
|
||||
case PPC::fixup_ppc_br24:
|
||||
return Value & 0x3fffffc;
|
||||
#if 0
|
||||
case PPC::fixup_ppc_hi16:
|
||||
return (Value >> 16) & 0xffff;
|
||||
#endif
|
||||
case PPC::fixup_ppc_ha16:
|
||||
return ((Value >> 16) + ((Value & 0x8000) ? 1 : 0)) & 0xffff;
|
||||
case PPC::fixup_ppc_lo16:
|
||||
return Value & 0xffff;
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
class PPCMachObjectWriter : public MCMachObjectTargetWriter {
|
||||
public:
|
||||
@ -31,6 +57,13 @@ public:
|
||||
MCValue Target, uint64_t &FixedValue) {}
|
||||
};
|
||||
|
||||
class PPCELFObjectWriter : public MCELFObjectTargetWriter {
|
||||
public:
|
||||
PPCELFObjectWriter(bool Is64Bit, Triple::OSType OSType, uint16_t EMachine,
|
||||
bool HasRelocationAddend, bool isLittleEndian)
|
||||
: MCELFObjectTargetWriter(Is64Bit, OSType, EMachine, HasRelocationAddend) {}
|
||||
};
|
||||
|
||||
class PPCAsmBackend : public MCAsmBackend {
|
||||
const Target &TheTarget;
|
||||
public:
|
||||
@ -109,6 +142,42 @@ namespace {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class ELFPPCAsmBackend : public PPCAsmBackend {
|
||||
Triple::OSType OSType;
|
||||
public:
|
||||
ELFPPCAsmBackend(const Target &T, Triple::OSType OSType) :
|
||||
PPCAsmBackend(T), OSType(OSType) { }
|
||||
|
||||
void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
|
||||
uint64_t Value) const {
|
||||
Value = adjustFixupValue(Fixup.getKind(), Value);
|
||||
if (!Value) return; // Doesn't change encoding.
|
||||
|
||||
unsigned Offset = Fixup.getOffset();
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
|
||||
bool is64 = getPointerSize() == 8;
|
||||
return createELFObjectWriter(new PPCELFObjectWriter(
|
||||
/*Is64Bit=*/is64,
|
||||
OSType,
|
||||
is64 ? ELF::EM_PPC64 : ELF::EM_PPC,
|
||||
/*addend*/ true, /*isLittleEndian*/ false),
|
||||
OS, /*IsLittleEndian=*/false);
|
||||
}
|
||||
|
||||
virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
|
||||
@ -118,5 +187,5 @@ MCAsmBackend *llvm::createPPCAsmBackend(const Target &T, StringRef TT) {
|
||||
if (Triple(TT).isOSDarwin())
|
||||
return new DarwinPPCAsmBackend(T);
|
||||
|
||||
return 0;
|
||||
return new ELFPPCAsmBackend(T, Triple(TT).getOS());
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
|
||||
if (Triple(TT).isOSDarwin())
|
||||
return createMachOStreamer(Ctx, MAB, OS, Emitter, RelaxAll);
|
||||
|
||||
return NULL;
|
||||
return createELFStreamer(Ctx, MAB, OS, Emitter, RelaxAll, NoExecStack);;
|
||||
}
|
||||
|
||||
static MCInstPrinter *createPPCMCInstPrinter(const Target &T,
|
||||
|
Loading…
x
Reference in New Issue
Block a user