case ELF::EM_SPARC:
case ELF::EM_SPARC32PLUS:
- return Triple::sparc;
+ return IsLittleEndian ? Triple::sparcel : Triple::sparc;
case ELF::EM_SPARCV9:
return Triple::sparcv9;
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;
return true;
}
-
extern "C" void LLVMInitializeSparcAsmParser() {
RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget);
RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target);
+ RegisterMCAsmParser<SparcAsmParser> C(TheSparcelTarget);
}
#define GET_REGISTER_MATCHER
#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;
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);
}
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,
/// 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;
}
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);
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";
}
};
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);
}
};
}
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);
}
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;
#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;
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()) {
// 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);
// Register the MC codegen info.
TargetRegistry::RegisterMCCodeGenInfo(TheSparcTarget,
- createSparcMCCodeGenInfo);
+ createSparcMCCodeGenInfo);
TargetRegistry::RegisterMCCodeGenInfo(TheSparcV9Target,
- createSparcV9MCCodeGenInfo);
-
+ createSparcV9MCCodeGenInfo);
+ TargetRegistry::RegisterMCCodeGenInfo(TheSparcelTarget,
+ createSparcMCCodeGenInfo);
}
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
extern "C" void LLVMInitializeSparcAsmPrinter() {
RegisterAsmPrinter<SparcAsmPrinter> X(TheSparcTarget);
RegisterAsmPrinter<SparcAsmPrinter> Y(TheSparcV9Target);
+ RegisterAsmPrinter<SparcAsmPrinter> Z(TheSparcelTarget);
}
// 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)
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();
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) {}
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);
};
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");
}