mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
[Sparc] Really add sparcel architecture support.
Mostly copy-and-paste from Sparc v8 architecture. Differential Revision: http://reviews.llvm.org/D8741 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236146 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
58a854d447
commit
1b88927253
@ -928,7 +928,7 @@ unsigned ELFObjectFile<ELFT>::getArch() const {
|
||||
|
||||
case ELF::EM_SPARC:
|
||||
case ELF::EM_SPARC32PLUS:
|
||||
return Triple::sparc;
|
||||
return IsLittleEndian ? Triple::sparcel : Triple::sparc;
|
||||
case ELF::EM_SPARCV9:
|
||||
return Triple::sparcv9;
|
||||
|
||||
|
@ -337,6 +337,7 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
|
||||
TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
|
||||
dwarf::DW_EH_PE_udata8;
|
||||
break;
|
||||
case Triple::sparcel:
|
||||
case Triple::sparc:
|
||||
if (RelocM == Reloc::PIC_) {
|
||||
LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
|
||||
|
@ -907,10 +907,10 @@ bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void LLVMInitializeSparcAsmParser() {
|
||||
RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget);
|
||||
RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target);
|
||||
RegisterMCAsmParser<SparcAsmParser> C(TheSparcelTarget);
|
||||
}
|
||||
|
||||
#define GET_REGISTER_MATCHER
|
||||
|
@ -16,6 +16,8 @@
|
||||
#include "SparcSubtarget.h"
|
||||
#include "llvm/MC/MCDisassembler.h"
|
||||
#include "llvm/MC/MCFixedLenDisassembler.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
|
||||
using namespace llvm;
|
||||
@ -38,17 +40,15 @@ public:
|
||||
raw_ostream &VStream,
|
||||
raw_ostream &CStream) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
extern Target TheSparcTarget, TheSparcV9Target;
|
||||
extern Target TheSparcTarget, TheSparcV9Target, TheSparcelTarget;
|
||||
}
|
||||
|
||||
static MCDisassembler *createSparcDisassembler(
|
||||
const Target &T,
|
||||
const MCSubtargetInfo &STI,
|
||||
MCContext &Ctx) {
|
||||
static MCDisassembler *createSparcDisassembler(const Target &T,
|
||||
const MCSubtargetInfo &STI,
|
||||
MCContext &Ctx) {
|
||||
return new SparcDisassembler(STI, Ctx);
|
||||
}
|
||||
|
||||
@ -59,10 +59,10 @@ extern "C" void LLVMInitializeSparcDisassembler() {
|
||||
createSparcDisassembler);
|
||||
TargetRegistry::RegisterMCDisassembler(TheSparcV9Target,
|
||||
createSparcDisassembler);
|
||||
TargetRegistry::RegisterMCDisassembler(TheSparcelTarget,
|
||||
createSparcDisassembler);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const unsigned IntRegDecoderTable[] = {
|
||||
SP::G0, SP::G1, SP::G2, SP::G3,
|
||||
SP::G4, SP::G5, SP::G6, SP::G7,
|
||||
@ -208,16 +208,19 @@ static DecodeStatus DecodeSWAP(MCInst &Inst, unsigned insn, uint64_t Address,
|
||||
|
||||
/// Read four bytes from the ArrayRef and return 32 bit word.
|
||||
static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
|
||||
uint64_t &Size, uint32_t &Insn) {
|
||||
uint64_t &Size, uint32_t &Insn,
|
||||
bool IsLittleEndian) {
|
||||
// We want to read exactly 4 Bytes of data.
|
||||
if (Bytes.size() < 4) {
|
||||
Size = 0;
|
||||
return MCDisassembler::Fail;
|
||||
}
|
||||
|
||||
// Encoded as a big-endian 32-bit word in the stream.
|
||||
Insn =
|
||||
(Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
|
||||
Insn = IsLittleEndian
|
||||
? (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
|
||||
(Bytes[3] << 24)
|
||||
: (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) |
|
||||
(Bytes[0] << 24);
|
||||
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
@ -228,12 +231,12 @@ DecodeStatus SparcDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
|
||||
raw_ostream &VStream,
|
||||
raw_ostream &CStream) const {
|
||||
uint32_t Insn;
|
||||
|
||||
DecodeStatus Result = readInstruction32(Bytes, Address, Size, Insn);
|
||||
bool isLittleEndian = getContext().getAsmInfo()->isLittleEndian();
|
||||
DecodeStatus Result =
|
||||
readInstruction32(Bytes, Address, Size, Insn, isLittleEndian);
|
||||
if (Result == MCDisassembler::Fail)
|
||||
return MCDisassembler::Fail;
|
||||
|
||||
|
||||
// Calling the auto-generated decoder function.
|
||||
Result =
|
||||
decodeInstruction(DecoderTableSparc32, Instr, Insn, Address, this, STI);
|
||||
|
@ -216,9 +216,9 @@ namespace {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is64Bit() const {
|
||||
StringRef name = TheTarget.getName();
|
||||
return name == "sparcv9";
|
||||
bool is64Bit() const { return StringRef(TheTarget.getName()) == "sparcv9"; }
|
||||
bool isLittleEndian() const {
|
||||
return StringRef(TheTarget.getName()) == "sparcel";
|
||||
}
|
||||
};
|
||||
|
||||
@ -246,7 +246,7 @@ namespace {
|
||||
|
||||
MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override {
|
||||
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType);
|
||||
return createSparcELFObjectWriter(OS, is64Bit(), OSABI);
|
||||
return createSparcELFObjectWriter(OS, is64Bit(), isLittleEndian(), OSABI);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -106,7 +106,9 @@ unsigned SparcELFObjectWriter::GetRelocType(const MCValue &Target,
|
||||
}
|
||||
|
||||
MCObjectWriter *llvm::createSparcELFObjectWriter(raw_pwrite_stream &OS,
|
||||
bool Is64Bit, uint8_t OSABI) {
|
||||
bool Is64Bit,
|
||||
bool IsLittleEndian,
|
||||
uint8_t OSABI) {
|
||||
MCELFObjectTargetWriter *MOTW = new SparcELFObjectWriter(Is64Bit, OSABI);
|
||||
return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/false);
|
||||
return createELFObjectWriter(MOTW, OS, IsLittleEndian);
|
||||
}
|
||||
|
@ -18,12 +18,12 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
void SparcELFMCAsmInfo::anchor() { }
|
||||
void SparcELFMCAsmInfo::anchor() {}
|
||||
|
||||
SparcELFMCAsmInfo::SparcELFMCAsmInfo(StringRef TT) {
|
||||
IsLittleEndian = false;
|
||||
Triple TheTriple(TT);
|
||||
bool isV9 = (TheTriple.getArch() == Triple::sparcv9);
|
||||
IsLittleEndian = (TheTriple.getArch() == Triple::sparcel);
|
||||
|
||||
if (isV9) {
|
||||
PointerSize = CalleeSaveStackSlotSize = 8;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm;
|
||||
@ -78,16 +79,23 @@ MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII,
|
||||
return new SparcMCCodeEmitter(Ctx);
|
||||
}
|
||||
|
||||
void SparcMCCodeEmitter::
|
||||
EncodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const {
|
||||
void SparcMCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const {
|
||||
unsigned Bits = getBinaryCodeForInstr(MI, Fixups, STI);
|
||||
|
||||
// Output the constant in big endian byte order.
|
||||
for (unsigned i = 0; i != 4; ++i) {
|
||||
OS << (char)(Bits >> 24);
|
||||
Bits <<= 8;
|
||||
if (Ctx.getAsmInfo()->isLittleEndian()) {
|
||||
// Output the bits in little-endian byte order.
|
||||
for (unsigned i = 0; i != 4; ++i) {
|
||||
OS << (char)Bits;
|
||||
Bits >>= 8;
|
||||
}
|
||||
} else {
|
||||
// Output the bits in big-endian byte order.
|
||||
for (unsigned i = 0; i != 4; ++i) {
|
||||
OS << (char)(Bits >> 24);
|
||||
Bits <<= 8;
|
||||
}
|
||||
}
|
||||
unsigned tlsOpNo = 0;
|
||||
switch (MI.getOpcode()) {
|
||||
|
@ -146,8 +146,9 @@ extern "C" void LLVMInitializeSparcTargetMC() {
|
||||
// Register the MC asm info.
|
||||
RegisterMCAsmInfoFn X(TheSparcTarget, createSparcMCAsmInfo);
|
||||
RegisterMCAsmInfoFn Y(TheSparcV9Target, createSparcV9MCAsmInfo);
|
||||
RegisterMCAsmInfoFn Z(TheSparcelTarget, createSparcMCAsmInfo);
|
||||
|
||||
for (Target *T : {&TheSparcTarget, &TheSparcV9Target}) {
|
||||
for (Target *T : {&TheSparcTarget, &TheSparcV9Target, &TheSparcelTarget}) {
|
||||
// Register the MC instruction info.
|
||||
TargetRegistry::RegisterMCInstrInfo(*T, createSparcMCInstrInfo);
|
||||
|
||||
@ -176,8 +177,9 @@ extern "C" void LLVMInitializeSparcTargetMC() {
|
||||
|
||||
// Register the MC codegen info.
|
||||
TargetRegistry::RegisterMCCodeGenInfo(TheSparcTarget,
|
||||
createSparcMCCodeGenInfo);
|
||||
createSparcMCCodeGenInfo);
|
||||
TargetRegistry::RegisterMCCodeGenInfo(TheSparcV9Target,
|
||||
createSparcV9MCCodeGenInfo);
|
||||
|
||||
createSparcV9MCCodeGenInfo);
|
||||
TargetRegistry::RegisterMCCodeGenInfo(TheSparcelTarget,
|
||||
createSparcMCCodeGenInfo);
|
||||
}
|
||||
|
@ -31,16 +31,15 @@ class raw_ostream;
|
||||
|
||||
extern Target TheSparcTarget;
|
||||
extern Target TheSparcV9Target;
|
||||
extern Target TheSparcelTarget;
|
||||
|
||||
MCCodeEmitter *createSparcMCCodeEmitter(const MCInstrInfo &MCII,
|
||||
const MCRegisterInfo &MRI,
|
||||
MCContext &Ctx);
|
||||
MCAsmBackend *createSparcAsmBackend(const Target &T,
|
||||
const MCRegisterInfo &MRI,
|
||||
StringRef TT,
|
||||
StringRef CPU);
|
||||
MCAsmBackend *createSparcAsmBackend(const Target &T, const MCRegisterInfo &MRI,
|
||||
StringRef TT, StringRef CPU);
|
||||
MCObjectWriter *createSparcELFObjectWriter(raw_pwrite_stream &OS, bool Is64Bit,
|
||||
uint8_t OSABI);
|
||||
bool IsLIttleEndian, uint8_t OSABI);
|
||||
} // End llvm namespace
|
||||
|
||||
// Defines symbolic names for Sparc registers. This defines a mapping from
|
||||
|
@ -445,4 +445,5 @@ bool SparcAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
|
||||
extern "C" void LLVMInitializeSparcAsmPrinter() {
|
||||
RegisterAsmPrinter<SparcAsmPrinter> X(TheSparcTarget);
|
||||
RegisterAsmPrinter<SparcAsmPrinter> Y(TheSparcV9Target);
|
||||
RegisterAsmPrinter<SparcAsmPrinter> Z(TheSparcelTarget);
|
||||
}
|
||||
|
@ -22,11 +22,13 @@ extern "C" void LLVMInitializeSparcTarget() {
|
||||
// Register the target.
|
||||
RegisterTargetMachine<SparcV8TargetMachine> X(TheSparcTarget);
|
||||
RegisterTargetMachine<SparcV9TargetMachine> Y(TheSparcV9Target);
|
||||
RegisterTargetMachine<SparcelTargetMachine> Z(TheSparcelTarget);
|
||||
}
|
||||
|
||||
static std::string computeDataLayout(bool is64Bit) {
|
||||
// Sparc is big endian.
|
||||
std::string Ret = "E-m:e";
|
||||
static std::string computeDataLayout(const Triple &T, bool is64Bit) {
|
||||
// Sparc is typically big endian, but some are little.
|
||||
std::string Ret = T.getArch() == Triple::sparcel ? "e" : "E";
|
||||
Ret += "-m:e";
|
||||
|
||||
// Some ABIs have 32bit pointers.
|
||||
if (!is64Bit)
|
||||
@ -57,8 +59,8 @@ SparcTargetMachine::SparcTargetMachine(const Target &T, StringRef TT,
|
||||
const TargetOptions &Options,
|
||||
Reloc::Model RM, CodeModel::Model CM,
|
||||
CodeGenOpt::Level OL, bool is64bit)
|
||||
: LLVMTargetMachine(T, computeDataLayout(is64bit), TT, CPU, FS, Options, RM,
|
||||
CM, OL),
|
||||
: LLVMTargetMachine(T, computeDataLayout(Triple(TT), is64bit), TT, CPU, FS,
|
||||
Options, RM, CM, OL),
|
||||
TLOF(make_unique<SparcELFTargetObjectFile>()),
|
||||
Subtarget(TT, CPU, FS, *this, is64bit) {
|
||||
initAsmInfo();
|
||||
@ -116,12 +118,18 @@ SparcV8TargetMachine::SparcV8TargetMachine(const Target &T,
|
||||
|
||||
void SparcV9TargetMachine::anchor() { }
|
||||
|
||||
SparcV9TargetMachine::SparcV9TargetMachine(const Target &T,
|
||||
StringRef TT, StringRef CPU,
|
||||
StringRef FS,
|
||||
SparcV9TargetMachine::SparcV9TargetMachine(const Target &T, StringRef TT,
|
||||
StringRef CPU, StringRef FS,
|
||||
const TargetOptions &Options,
|
||||
Reloc::Model RM,
|
||||
CodeModel::Model CM,
|
||||
Reloc::Model RM, CodeModel::Model CM,
|
||||
CodeGenOpt::Level OL)
|
||||
: SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {
|
||||
}
|
||||
: SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
|
||||
|
||||
void SparcelTargetMachine::anchor() {}
|
||||
|
||||
SparcelTargetMachine::SparcelTargetMachine(const Target &T, StringRef TT,
|
||||
StringRef CPU, StringRef FS,
|
||||
const TargetOptions &Options,
|
||||
Reloc::Model RM, CodeModel::Model CM,
|
||||
CodeGenOpt::Level OL)
|
||||
: SparcTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
|
||||
|
@ -58,9 +58,18 @@ public:
|
||||
class SparcV9TargetMachine : public SparcTargetMachine {
|
||||
virtual void anchor();
|
||||
public:
|
||||
SparcV9TargetMachine(const Target &T, StringRef TT,
|
||||
StringRef CPU, StringRef FS,
|
||||
const TargetOptions &Options,
|
||||
SparcV9TargetMachine(const Target &T, StringRef TT, StringRef CPU,
|
||||
StringRef FS, const TargetOptions &Options,
|
||||
Reloc::Model RM, CodeModel::Model CM,
|
||||
CodeGenOpt::Level OL);
|
||||
};
|
||||
|
||||
class SparcelTargetMachine : public SparcTargetMachine {
|
||||
virtual void anchor();
|
||||
|
||||
public:
|
||||
SparcelTargetMachine(const Target &T, StringRef TT, StringRef CPU,
|
||||
StringRef FS, const TargetOptions &Options,
|
||||
Reloc::Model RM, CodeModel::Model CM,
|
||||
CodeGenOpt::Level OL);
|
||||
};
|
||||
|
@ -14,10 +14,13 @@ using namespace llvm;
|
||||
|
||||
Target llvm::TheSparcTarget;
|
||||
Target llvm::TheSparcV9Target;
|
||||
Target llvm::TheSparcelTarget;
|
||||
|
||||
extern "C" void LLVMInitializeSparcTargetInfo() {
|
||||
RegisterTarget<Triple::sparc, /*HasJIT=*/ true>
|
||||
X(TheSparcTarget, "sparc", "Sparc");
|
||||
RegisterTarget<Triple::sparcv9, /*HasJIT=*/ true>
|
||||
Y(TheSparcV9Target, "sparcv9", "Sparc V9");
|
||||
RegisterTarget<Triple::sparc, /*HasJIT=*/true> X(TheSparcTarget, "sparc",
|
||||
"Sparc");
|
||||
RegisterTarget<Triple::sparcv9, /*HasJIT=*/true> Y(TheSparcV9Target,
|
||||
"sparcv9", "Sparc V9");
|
||||
RegisterTarget<Triple::sparcel, /*HasJIT=*/true> Z(TheSparcelTarget,
|
||||
"sparcel", "Sparc LE");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user