mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-01 15:17:25 +00:00
[Sparc] Add initial implementation of MC Code emitter for sparc.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198533 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
add_llvm_library(LLVMSparcDesc
|
||||
SparcMCTargetDesc.cpp
|
||||
SparcAsmBackend.cpp
|
||||
SparcMCAsmInfo.cpp
|
||||
SparcMCCodeEmitter.cpp
|
||||
SparcMCTargetDesc.cpp
|
||||
SparcMCExpr.cpp
|
||||
SparcTargetStreamer.cpp
|
||||
)
|
||||
|
||||
101
lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
Normal file
101
lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
//===-- SparcAsmBackend.cpp - Sparc Assembler Backend ---------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/MC/MCAsmBackend.h"
|
||||
#include "MCTargetDesc/SparcMCTargetDesc.h"
|
||||
#include "MCTargetDesc/SparcFixupKinds.h"
|
||||
#include "llvm/MC/MCFixupKindInfo.h"
|
||||
#include "llvm/MC/MCObjectWriter.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
class SparcAsmBackend : public MCAsmBackend {
|
||||
|
||||
public:
|
||||
SparcAsmBackend(const Target &T) : MCAsmBackend() {}
|
||||
|
||||
unsigned getNumFixupKinds() const {
|
||||
return Sparc::NumTargetFixupKinds;
|
||||
}
|
||||
|
||||
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
|
||||
const static MCFixupKindInfo Infos[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 }
|
||||
};
|
||||
|
||||
if (Kind < FirstTargetFixupKind)
|
||||
return MCAsmBackend::getFixupKindInfo(Kind);
|
||||
|
||||
assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
|
||||
"Invalid kind!");
|
||||
return Infos[Kind - FirstTargetFixupKind];
|
||||
}
|
||||
|
||||
bool mayNeedRelaxation(const MCInst &Inst) const {
|
||||
// FIXME.
|
||||
return false;
|
||||
}
|
||||
|
||||
/// fixupNeedsRelaxation - Target specific predicate for whether a given
|
||||
/// fixup requires the associated instruction to be relaxed.
|
||||
bool fixupNeedsRelaxation(const MCFixup &Fixup,
|
||||
uint64_t Value,
|
||||
const MCRelaxableFragment *DF,
|
||||
const MCAsmLayout &Layout) const {
|
||||
// FIXME.
|
||||
assert(0 && "fixupNeedsRelaxation() unimplemented");
|
||||
return false;
|
||||
}
|
||||
void relaxInstruction(const MCInst &Inst, MCInst &Res) const {
|
||||
// FIXME.
|
||||
assert(0 && "relaxInstruction() unimplemented");
|
||||
}
|
||||
|
||||
bool writeNopData(uint64_t Count, MCObjectWriter *OW) const {
|
||||
// FIXME: Zero fill for now.
|
||||
for (uint64_t i = 0; i != Count; ++i)
|
||||
OW->Write8(0);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class ELFSparcAsmBackend : public SparcAsmBackend {
|
||||
public:
|
||||
ELFSparcAsmBackend(const Target &T, Triple::OSType OSType) :
|
||||
SparcAsmBackend(T) { }
|
||||
|
||||
void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
|
||||
uint64_t Value) const {
|
||||
assert(0 && "applyFixup not implemented yet");
|
||||
}
|
||||
|
||||
MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
|
||||
assert(0 && "Object Writer not implemented yet");
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
|
||||
MCAsmBackend *llvm::createSparcAsmBackend(const Target &T,
|
||||
const MCRegisterInfo &MRI,
|
||||
StringRef TT,
|
||||
StringRef CPU) {
|
||||
return new ELFSparcAsmBackend(T, Triple(TT).getOS());
|
||||
}
|
||||
36
lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
Normal file
36
lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
Normal file
@@ -0,0 +1,36 @@
|
||||
//===-- SparcFixupKinds.h - Sparc Specific Fixup Entries --------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SPARC_FIXUPKINDS_H
|
||||
#define LLVM_SPARC_FIXUPKINDS_H
|
||||
|
||||
#include "llvm/MC/MCFixup.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace Sparc {
|
||||
enum Fixups {
|
||||
// fixup_sparc_call30 - 30-bit PC relative relocation for call
|
||||
fixup_sparc_call30 = FirstTargetFixupKind,
|
||||
|
||||
/// fixup_sparc_br22 - 22-bit PC relative relocation for
|
||||
/// branches
|
||||
fixup_sparc_br22,
|
||||
|
||||
/// fixup_sparc_br22 - 22-bit PC relative relocation for
|
||||
/// branches on icc/xcc
|
||||
fixup_sparc_br19,
|
||||
|
||||
// Marker
|
||||
LastTargetFixupKind,
|
||||
NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
131
lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
Normal file
131
lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
//===-- SparcMCCodeEmitter.cpp - Convert Sparc code to machine code -------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the SparcMCCodeEmitter class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "mccodeemitter"
|
||||
#include "SparcMCTargetDesc.h"
|
||||
#include "MCTargetDesc/SparcFixupKinds.h"
|
||||
#include "llvm/MC/MCCodeEmitter.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
|
||||
|
||||
namespace {
|
||||
class SparcMCCodeEmitter : public MCCodeEmitter {
|
||||
SparcMCCodeEmitter(const SparcMCCodeEmitter &) LLVM_DELETED_FUNCTION;
|
||||
void operator=(const SparcMCCodeEmitter &) LLVM_DELETED_FUNCTION;
|
||||
MCContext &Ctx;
|
||||
|
||||
public:
|
||||
SparcMCCodeEmitter(MCContext &ctx): Ctx(ctx) {}
|
||||
|
||||
~SparcMCCodeEmitter() {}
|
||||
|
||||
void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
|
||||
// getBinaryCodeForInstr - TableGen'erated function for getting the
|
||||
// binary encoding for an instruction.
|
||||
uint64_t getBinaryCodeForInstr(const MCInst &MI,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
|
||||
/// getMachineOpValue - Return binary encoding of operand. If the machine
|
||||
/// operand requires relocation, record the relocation and return zero.
|
||||
unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
|
||||
unsigned getCallTargetOpValue(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII,
|
||||
const MCRegisterInfo &MRI,
|
||||
const MCSubtargetInfo &STI,
|
||||
MCContext &Ctx) {
|
||||
return new SparcMCCodeEmitter(Ctx);
|
||||
}
|
||||
|
||||
void SparcMCCodeEmitter::
|
||||
EncodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
unsigned Bits = getBinaryCodeForInstr(MI, Fixups);
|
||||
|
||||
// Output the constant in big endian byte order.
|
||||
for (unsigned i = 0; i != 4; ++i) {
|
||||
OS << (char)(Bits >> 24);
|
||||
Bits <<= 8;
|
||||
}
|
||||
|
||||
++MCNumEmitted; // Keep track of the # of mi's emitted.
|
||||
}
|
||||
|
||||
|
||||
unsigned SparcMCCodeEmitter::
|
||||
getMachineOpValue(const MCInst &MI, const MCOperand &MO,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
|
||||
if (MO.isReg())
|
||||
return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
|
||||
|
||||
if (MO.isImm())
|
||||
return MO.getImm();
|
||||
|
||||
assert(MO.isExpr());
|
||||
const MCExpr *Expr = MO.getExpr();
|
||||
int64_t Res;
|
||||
if (Expr->EvaluateAsAbsolute(Res))
|
||||
return Res;
|
||||
|
||||
assert(0 && "Unhandled expression!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned SparcMCCodeEmitter::
|
||||
getCallTargetOpValue(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
const MCOperand &MO = MI.getOperand(OpNo);
|
||||
if (MO.isReg() || MO.isImm())
|
||||
return getMachineOpValue(MI, MO, Fixups);
|
||||
|
||||
Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
|
||||
(MCFixupKind)Sparc::fixup_sparc_call30));
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned SparcMCCodeEmitter::
|
||||
getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
const MCOperand &MO = MI.getOperand(OpNo);
|
||||
if (MO.isReg() || MO.isImm())
|
||||
return getMachineOpValue(MI, MO, Fixups);
|
||||
|
||||
Sparc::Fixups fixup = Sparc::fixup_sparc_br22;
|
||||
if (MI.getOpcode() == SP::BPXCC)
|
||||
fixup = Sparc::fixup_sparc_br19;
|
||||
|
||||
Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
|
||||
(MCFixupKind)fixup));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include "SparcGenMCCodeEmitter.inc"
|
||||
@@ -136,6 +136,18 @@ extern "C" void LLVMInitializeSparcTargetMC() {
|
||||
TargetRegistry::RegisterMCSubtargetInfo(TheSparcV9Target,
|
||||
createSparcMCSubtargetInfo);
|
||||
|
||||
// Register the MC Code Emitter.
|
||||
TargetRegistry::RegisterMCCodeEmitter(TheSparcTarget,
|
||||
createSparcMCCodeEmitter);
|
||||
TargetRegistry::RegisterMCCodeEmitter(TheSparcV9Target,
|
||||
createSparcMCCodeEmitter);
|
||||
|
||||
//Register the asm backend.
|
||||
TargetRegistry::RegisterMCAsmBackend(TheSparcTarget,
|
||||
createSparcAsmBackend);
|
||||
TargetRegistry::RegisterMCAsmBackend(TheSparcV9Target,
|
||||
createSparcAsmBackend);
|
||||
|
||||
TargetRegistry::RegisterAsmStreamer(TheSparcTarget,
|
||||
createMCAsmStreamer);
|
||||
TargetRegistry::RegisterAsmStreamer(TheSparcV9Target,
|
||||
|
||||
@@ -15,11 +15,27 @@
|
||||
#define SPARCMCTARGETDESC_H
|
||||
|
||||
namespace llvm {
|
||||
class MCAsmBackend;
|
||||
class MCCodeEmitter;
|
||||
class MCContext;
|
||||
class MCInstrInfo;
|
||||
class MCRegisterInfo;
|
||||
class MCSubtargetInfo;
|
||||
class Target;
|
||||
class StringRef;
|
||||
|
||||
extern Target TheSparcTarget;
|
||||
extern Target TheSparcV9Target;
|
||||
|
||||
MCCodeEmitter *createSparcMCCodeEmitter(const MCInstrInfo &MCII,
|
||||
const MCRegisterInfo &MRI,
|
||||
const MCSubtargetInfo &STI,
|
||||
MCContext &Ctx);
|
||||
MCAsmBackend *createSparcAsmBackend(const Target &T,
|
||||
const MCRegisterInfo &MRI,
|
||||
StringRef TT,
|
||||
StringRef CPU);
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
// Defines symbolic names for Sparc registers. This defines a mapping from
|
||||
|
||||
Reference in New Issue
Block a user