mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-27 13:30:05 +00:00
[Sparc] Lower and MachineInstr to MC and print assembly using MCInstPrinter.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198030 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f3aeebf4c7
commit
76a1dca38d
@ -23,6 +23,7 @@ add_llvm_target(SparcCodeGen
|
||||
SparcSelectionDAGInfo.cpp
|
||||
SparcJITInfo.cpp
|
||||
SparcCodeEmitter.cpp
|
||||
SparcMCInstLower.cpp
|
||||
)
|
||||
|
||||
add_subdirectory(TargetInfo)
|
||||
|
@ -23,8 +23,7 @@
|
||||
using namespace llvm;
|
||||
|
||||
#define GET_INSTRUCTION_NAME
|
||||
// Uncomment the following line once we are ready to use MCAsmWriter.
|
||||
//#include "SparcGenAsmWriter.inc"
|
||||
#include "SparcGenAsmWriter.inc"
|
||||
|
||||
void SparcInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const
|
||||
{
|
||||
|
@ -2,4 +2,5 @@ add_llvm_library(LLVMSparcDesc
|
||||
SparcMCTargetDesc.cpp
|
||||
SparcMCAsmInfo.cpp
|
||||
SparcMCExpr.cpp
|
||||
SparcTargetStreamer.cpp
|
||||
)
|
||||
|
@ -19,5 +19,5 @@
|
||||
type = Library
|
||||
name = SparcDesc
|
||||
parent = Sparc
|
||||
required_libraries = MC SparcInfo Support
|
||||
required_libraries = MC SparcAsmPrinter SparcInfo Support
|
||||
add_to_library_groups = Sparc
|
||||
|
@ -13,6 +13,8 @@
|
||||
|
||||
#include "SparcMCTargetDesc.h"
|
||||
#include "SparcMCAsmInfo.h"
|
||||
#include "SparcTargetStreamer.h"
|
||||
#include "InstPrinter/SparcInstPrinter.h"
|
||||
#include "llvm/MC/MCCodeGenInfo.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
@ -86,6 +88,28 @@ static MCCodeGenInfo *createSparcV9MCCodeGenInfo(StringRef TT, Reloc::Model RM,
|
||||
X->InitMCCodeGenInfo(RM, CM, OL);
|
||||
return X;
|
||||
}
|
||||
|
||||
static MCStreamer *
|
||||
createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
|
||||
bool isVerboseAsm, bool useLoc, bool useCFI,
|
||||
bool useDwarfDirectory, MCInstPrinter *InstPrint,
|
||||
MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst) {
|
||||
SparcTargetAsmStreamer *S = new SparcTargetAsmStreamer(OS);
|
||||
|
||||
return llvm::createAsmStreamer(Ctx, S, OS, isVerboseAsm, useLoc, useCFI,
|
||||
useDwarfDirectory, InstPrint, CE, TAB,
|
||||
ShowInst);
|
||||
}
|
||||
|
||||
static MCInstPrinter *createSparcMCInstPrinter(const Target &T,
|
||||
unsigned SyntaxVariant,
|
||||
const MCAsmInfo &MAI,
|
||||
const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI,
|
||||
const MCSubtargetInfo &STI) {
|
||||
return new SparcInstPrinter(MAI, MII, MRI);
|
||||
}
|
||||
|
||||
extern "C" void LLVMInitializeSparcTargetMC() {
|
||||
// Register the MC asm info.
|
||||
RegisterMCAsmInfo<SparcELFMCAsmInfo> X(TheSparcTarget);
|
||||
@ -106,4 +130,15 @@ extern "C" void LLVMInitializeSparcTargetMC() {
|
||||
// Register the MC subtarget info.
|
||||
TargetRegistry::RegisterMCSubtargetInfo(TheSparcTarget,
|
||||
createSparcMCSubtargetInfo);
|
||||
|
||||
TargetRegistry::RegisterAsmStreamer(TheSparcTarget,
|
||||
createMCAsmStreamer);
|
||||
TargetRegistry::RegisterAsmStreamer(TheSparcV9Target,
|
||||
createMCAsmStreamer);
|
||||
|
||||
// Register the MCInstPrinter
|
||||
TargetRegistry::RegisterMCInstPrinter(TheSparcTarget,
|
||||
createSparcMCInstPrinter);
|
||||
TargetRegistry::RegisterMCInstPrinter(TheSparcV9Target,
|
||||
createSparcMCInstPrinter);
|
||||
}
|
||||
|
40
lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp
Normal file
40
lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
//===-- SparcTargetStreamer.cpp - Sparc Target Streamer Methods -----------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides Sparc specific target streamer methods.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "SparcTargetStreamer.h"
|
||||
#include "InstPrinter/SparcInstPrinter.h"
|
||||
#include "llvm/Support/FormattedStream.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
// pin vtable to this file
|
||||
void SparcTargetStreamer::anchor() {}
|
||||
|
||||
SparcTargetAsmStreamer::SparcTargetAsmStreamer(formatted_raw_ostream &OS)
|
||||
: OS(OS) {}
|
||||
|
||||
void SparcTargetAsmStreamer::emitSparcRegisterIgnore(unsigned reg) {
|
||||
OS << "\t.register "
|
||||
<< "%" << StringRef(SparcInstPrinter::getRegisterName(reg)).lower()
|
||||
<< ", #ignore\n";
|
||||
}
|
||||
|
||||
void SparcTargetAsmStreamer::emitSparcRegisterScratch(unsigned reg) {
|
||||
OS << "\t.register "
|
||||
<< "%" << StringRef(SparcInstPrinter::getRegisterName(reg)).lower()
|
||||
<< ", #scratch\n";
|
||||
}
|
||||
|
||||
MCELFStreamer &SparcTargetELFStreamer::getStreamer() {
|
||||
return static_cast<MCELFStreamer &>(*Streamer);
|
||||
}
|
@ -23,12 +23,18 @@ namespace llvm {
|
||||
class FunctionPass;
|
||||
class SparcTargetMachine;
|
||||
class formatted_raw_ostream;
|
||||
class AsmPrinter;
|
||||
class MCInst;
|
||||
class MachineInstr;
|
||||
|
||||
FunctionPass *createSparcISelDag(SparcTargetMachine &TM);
|
||||
FunctionPass *createSparcDelaySlotFillerPass(TargetMachine &TM);
|
||||
FunctionPass *createSparcJITCodeEmitterPass(SparcTargetMachine &TM,
|
||||
JITCodeEmitter &JCE);
|
||||
|
||||
void LowerSparcMachineInstrToMCInst(const MachineInstr *MI,
|
||||
MCInst &OutMI,
|
||||
AsmPrinter &AP);
|
||||
} // end namespace llvm;
|
||||
|
||||
namespace llvm {
|
||||
|
@ -66,11 +66,6 @@ def : Proc<"ultrasparc3", [FeatureV9, FeatureV8Deprecated]>;
|
||||
def : Proc<"ultrasparc3-vis", [FeatureV9, FeatureV8Deprecated, FeatureVIS]>;
|
||||
|
||||
|
||||
def SparcAsmWriter : AsmWriter {
|
||||
string AsmWriterClassName = "AsmPrinter";
|
||||
bit isMCAsmWriter = 0;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Declare the target which we are implementing
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -78,6 +73,4 @@ def SparcAsmWriter : AsmWriter {
|
||||
def Sparc : Target {
|
||||
// Pull in Instruction Info:
|
||||
let InstructionSet = SparcInstrInfo;
|
||||
|
||||
let AssemblyWriters = [SparcAsmWriter];
|
||||
}
|
||||
|
@ -16,12 +16,17 @@
|
||||
#include "Sparc.h"
|
||||
#include "SparcInstrInfo.h"
|
||||
#include "SparcTargetMachine.h"
|
||||
#include "SparcTargetStreamer.h"
|
||||
#include "InstPrinter/SparcInstPrinter.h"
|
||||
#include "MCTargetDesc/SparcBaseInfo.h"
|
||||
#include "MCTargetDesc/SparcMCExpr.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/CodeGen/AsmPrinter.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
@ -31,6 +36,9 @@ using namespace llvm;
|
||||
|
||||
namespace {
|
||||
class SparcAsmPrinter : public AsmPrinter {
|
||||
SparcTargetStreamer &getTargetStreamer() {
|
||||
return static_cast<SparcTargetStreamer&>(OutStreamer.getTargetStreamer());
|
||||
}
|
||||
public:
|
||||
explicit SparcAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
|
||||
: AsmPrinter(TM, Streamer) {}
|
||||
@ -45,14 +53,11 @@ namespace {
|
||||
void printCCOperand(const MachineInstr *MI, int opNum, raw_ostream &OS);
|
||||
|
||||
virtual void EmitFunctionBodyStart();
|
||||
virtual void EmitInstruction(const MachineInstr *MI) {
|
||||
SmallString<128> Str;
|
||||
raw_svector_ostream OS(Str);
|
||||
printInstruction(MI, OS);
|
||||
OutStreamer.EmitRawText(OS.str());
|
||||
virtual void EmitInstruction(const MachineInstr *MI);
|
||||
|
||||
static const char *getRegisterName(unsigned RegNo) {
|
||||
return SparcInstPrinter::getRegisterName(RegNo);
|
||||
}
|
||||
void printInstruction(const MachineInstr *MI, raw_ostream &OS);// autogen'd.
|
||||
static const char *getRegisterName(unsigned RegNo);
|
||||
|
||||
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
unsigned AsmVariant, const char *ExtraCode,
|
||||
@ -61,24 +66,138 @@ namespace {
|
||||
unsigned AsmVariant, const char *ExtraCode,
|
||||
raw_ostream &O);
|
||||
|
||||
bool printGetPCX(const MachineInstr *MI, unsigned OpNo, raw_ostream &OS);
|
||||
|
||||
virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB)
|
||||
const;
|
||||
void EmitGlobalRegisterDecl(unsigned reg) {
|
||||
SmallString<128> Str;
|
||||
raw_svector_ostream OS(Str);
|
||||
OS << "\t.register "
|
||||
<< "%" << StringRef(getRegisterName(reg)).lower()
|
||||
<< ", "
|
||||
<< ((reg == SP::G6 || reg == SP::G7)? "#ignore" : "#scratch");
|
||||
OutStreamer.EmitRawText(OS.str());
|
||||
}
|
||||
|
||||
};
|
||||
} // end of anonymous namespace
|
||||
|
||||
#include "SparcGenAsmWriter.inc"
|
||||
static MCOperand createPCXCallOP(MCSymbol *Label,
|
||||
MCContext &OutContext)
|
||||
{
|
||||
const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Label,
|
||||
OutContext);
|
||||
const SparcMCExpr *expr = SparcMCExpr::Create(SparcMCExpr::VK_Sparc_None,
|
||||
MCSym, OutContext);
|
||||
return MCOperand::CreateExpr(expr);
|
||||
}
|
||||
|
||||
static MCOperand createPCXRelExprOp(SparcMCExpr::VariantKind Kind,
|
||||
MCSymbol *GOTLabel, MCSymbol *StartLabel,
|
||||
MCSymbol *CurLabel,
|
||||
MCContext &OutContext)
|
||||
{
|
||||
const MCSymbolRefExpr *GOT = MCSymbolRefExpr::Create(GOTLabel, OutContext);
|
||||
const MCSymbolRefExpr *Start = MCSymbolRefExpr::Create(StartLabel,
|
||||
OutContext);
|
||||
const MCSymbolRefExpr *Cur = MCSymbolRefExpr::Create(CurLabel,
|
||||
OutContext);
|
||||
|
||||
const MCBinaryExpr *Sub = MCBinaryExpr::CreateSub(Cur, Start, OutContext);
|
||||
const MCBinaryExpr *Add = MCBinaryExpr::CreateAdd(GOT, Sub, OutContext);
|
||||
const SparcMCExpr *expr = SparcMCExpr::Create(Kind,
|
||||
Add, OutContext);
|
||||
return MCOperand::CreateExpr(expr);
|
||||
}
|
||||
|
||||
static void EmitCall(MCStreamer &OutStreamer,
|
||||
MCOperand &Callee)
|
||||
{
|
||||
MCInst CallInst;
|
||||
CallInst.setOpcode(SP::CALL);
|
||||
CallInst.addOperand(Callee);
|
||||
OutStreamer.EmitInstruction(CallInst);
|
||||
}
|
||||
|
||||
static void EmitSETHI(MCStreamer &OutStreamer,
|
||||
MCOperand &Imm, MCOperand &RD)
|
||||
{
|
||||
MCInst SETHIInst;
|
||||
SETHIInst.setOpcode(SP::SETHIi);
|
||||
SETHIInst.addOperand(RD);
|
||||
SETHIInst.addOperand(Imm);
|
||||
OutStreamer.EmitInstruction(SETHIInst);
|
||||
}
|
||||
|
||||
static void EmitOR(MCStreamer &OutStreamer, MCOperand &RS1,
|
||||
MCOperand &Imm, MCOperand &RD)
|
||||
{
|
||||
MCInst ORInst;
|
||||
ORInst.setOpcode(SP::ORri);
|
||||
ORInst.addOperand(RD);
|
||||
ORInst.addOperand(RS1);
|
||||
ORInst.addOperand(Imm);
|
||||
OutStreamer.EmitInstruction(ORInst);
|
||||
}
|
||||
|
||||
void EmitADD(MCStreamer &OutStreamer,
|
||||
MCOperand &RS1, MCOperand &RS2, MCOperand &RD)
|
||||
{
|
||||
MCInst ADDInst;
|
||||
ADDInst.setOpcode(SP::ADDrr);
|
||||
ADDInst.addOperand(RD);
|
||||
ADDInst.addOperand(RS1);
|
||||
ADDInst.addOperand(RS2);
|
||||
OutStreamer.EmitInstruction(ADDInst);
|
||||
}
|
||||
|
||||
static void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI,
|
||||
MCStreamer &OutStreamer,
|
||||
MCContext &OutContext)
|
||||
{
|
||||
const MachineOperand &MO = MI->getOperand(0);
|
||||
MCSymbol *StartLabel = OutContext.CreateTempSymbol();
|
||||
MCSymbol *EndLabel = OutContext.CreateTempSymbol();
|
||||
MCSymbol *SethiLabel = OutContext.CreateTempSymbol();
|
||||
MCSymbol *GOTLabel =
|
||||
OutContext.GetOrCreateSymbol(Twine("_GLOBAL_OFFSET_TABLE_"));
|
||||
|
||||
assert(MO.getReg() != SP::O7 &&
|
||||
"%o7 is assigned as destination for getpcx!");
|
||||
|
||||
MCOperand MCRegOP = MCOperand::CreateReg(MO.getReg());
|
||||
MCOperand RegO7 = MCOperand::CreateReg(SP::O7);
|
||||
|
||||
// <StartLabel>:
|
||||
// call <EndLabel>
|
||||
// <SethiLabel>:
|
||||
// sethi %hi(_GLOBAL_OFFSET_TABLE_+(<SethiLabel>-<StartLabel>)), <MO>
|
||||
// <EndLabel>:
|
||||
// or <MO>, %lo(_GLOBAL_OFFSET_TABLE_+(<EndLabel>-<StartLabel>))), <MO>
|
||||
// add <MO>, %o7, <MO>
|
||||
|
||||
OutStreamer.EmitLabel(StartLabel);
|
||||
MCOperand Callee = createPCXCallOP(EndLabel, OutContext);
|
||||
EmitCall(OutStreamer, Callee);
|
||||
OutStreamer.EmitLabel(SethiLabel);
|
||||
MCOperand hiImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_HI,
|
||||
GOTLabel, StartLabel, SethiLabel,
|
||||
OutContext);
|
||||
EmitSETHI(OutStreamer, hiImm, MCRegOP);
|
||||
OutStreamer.EmitLabel(EndLabel);
|
||||
MCOperand loImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_LO,
|
||||
GOTLabel, StartLabel, EndLabel,
|
||||
OutContext);
|
||||
EmitOR(OutStreamer, MCRegOP, loImm, MCRegOP);
|
||||
EmitADD(OutStreamer, MCRegOP, RegO7, MCRegOP);
|
||||
}
|
||||
|
||||
void SparcAsmPrinter::EmitInstruction(const MachineInstr *MI)
|
||||
{
|
||||
MCInst TmpInst;
|
||||
|
||||
switch (MI->getOpcode()) {
|
||||
default: break;
|
||||
case TargetOpcode::DBG_VALUE:
|
||||
// FIXME: Debug Value.
|
||||
return;
|
||||
case SP::GETPCX:
|
||||
LowerGETPCXAndEmitMCInsts(MI, OutStreamer, OutContext);
|
||||
return;
|
||||
}
|
||||
LowerSparcMachineInstrToMCInst(MI, TmpInst, *this);
|
||||
OutStreamer.EmitInstruction(TmpInst);
|
||||
}
|
||||
|
||||
void SparcAsmPrinter::EmitFunctionBodyStart() {
|
||||
if (!TM.getSubtarget<SparcSubtarget>().is64Bit())
|
||||
@ -90,7 +209,11 @@ void SparcAsmPrinter::EmitFunctionBodyStart() {
|
||||
unsigned reg = globalRegs[i];
|
||||
if (MRI.use_empty(reg))
|
||||
continue;
|
||||
EmitGlobalRegisterDecl(reg);
|
||||
|
||||
if (reg == SP::G6 || reg == SP::G7)
|
||||
getTargetStreamer().emitSparcRegisterIgnore(reg);
|
||||
else
|
||||
getTargetStreamer().emitSparcRegisterScratch(reg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,46 +349,6 @@ void SparcAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum,
|
||||
printOperand(MI, opNum+1, O);
|
||||
}
|
||||
|
||||
bool SparcAsmPrinter::printGetPCX(const MachineInstr *MI, unsigned opNum,
|
||||
raw_ostream &O) {
|
||||
std::string operand = "";
|
||||
const MachineOperand &MO = MI->getOperand(opNum);
|
||||
switch (MO.getType()) {
|
||||
default: llvm_unreachable("Operand is not a register");
|
||||
case MachineOperand::MO_Register:
|
||||
assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
|
||||
"Operand is not a physical register ");
|
||||
assert(MO.getReg() != SP::O7 &&
|
||||
"%o7 is assigned as destination for getpcx!");
|
||||
operand = "%" + StringRef(getRegisterName(MO.getReg())).lower();
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned mfNum = MI->getParent()->getParent()->getFunctionNumber();
|
||||
unsigned bbNum = MI->getParent()->getNumber();
|
||||
|
||||
O << '\n' << ".LLGETPCH" << mfNum << '_' << bbNum << ":\n";
|
||||
O << "\tcall\t.LLGETPC" << mfNum << '_' << bbNum << '\n' ;
|
||||
|
||||
O << "\t sethi\t"
|
||||
<< "%hi(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum
|
||||
<< ")), " << operand << '\n' ;
|
||||
|
||||
O << ".LLGETPC" << mfNum << '_' << bbNum << ":\n" ;
|
||||
O << "\tor\t" << operand
|
||||
<< ", %lo(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum
|
||||
<< ")), " << operand << '\n';
|
||||
O << "\tadd\t" << operand << ", %o7, " << operand << '\n';
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SparcAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum,
|
||||
raw_ostream &O) {
|
||||
int CC = (int)MI->getOperand(opNum).getImm();
|
||||
O << SPARCCondCodeToString((SPCC::CondCodes)CC);
|
||||
}
|
||||
|
||||
/// PrintAsmOperand - Print out an operand for an inline asm expression.
|
||||
///
|
||||
bool SparcAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
|
141
lib/Target/Sparc/SparcMCInstLower.cpp
Normal file
141
lib/Target/Sparc/SparcMCInstLower.cpp
Normal file
@ -0,0 +1,141 @@
|
||||
//===-- SparcMCInstLower.cpp - Convert Sparc MachineInstr to MCInst -------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains code to lower Sparc MachineInstrs to their corresponding
|
||||
// MCInst records.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Sparc.h"
|
||||
#include "MCTargetDesc/SparcBaseInfo.h"
|
||||
#include "MCTargetDesc/SparcMCExpr.h"
|
||||
#include "llvm/CodeGen/AsmPrinter.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/Target/Mangler.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
|
||||
static MCOperand LowerSymbolOperand(const MachineInstr *MI,
|
||||
const MachineOperand &MO,
|
||||
AsmPrinter &AP) {
|
||||
|
||||
SparcMCExpr::VariantKind Kind;
|
||||
const MCSymbol *Symbol = 0;
|
||||
|
||||
unsigned TF = MO.getTargetFlags();
|
||||
|
||||
switch(TF) {
|
||||
default: llvm_unreachable("Unknown target flags on operand");
|
||||
case SPII::MO_NO_FLAG: Kind = SparcMCExpr::VK_Sparc_None; break;
|
||||
case SPII::MO_LO: Kind = SparcMCExpr::VK_Sparc_LO; break;
|
||||
case SPII::MO_HI: Kind = SparcMCExpr::VK_Sparc_HI; break;
|
||||
case SPII::MO_H44: Kind = SparcMCExpr::VK_Sparc_H44; break;
|
||||
case SPII::MO_M44: Kind = SparcMCExpr::VK_Sparc_M44; break;
|
||||
case SPII::MO_L44: Kind = SparcMCExpr::VK_Sparc_L44; break;
|
||||
case SPII::MO_HH: Kind = SparcMCExpr::VK_Sparc_HH; break;
|
||||
case SPII::MO_HM: Kind = SparcMCExpr::VK_Sparc_HM; break;
|
||||
case SPII::MO_TLS_GD_HI22: Kind = SparcMCExpr::VK_Sparc_TLS_GD_HI22; break;
|
||||
case SPII::MO_TLS_GD_LO10: Kind = SparcMCExpr::VK_Sparc_TLS_GD_LO10; break;
|
||||
case SPII::MO_TLS_GD_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_GD_ADD; break;
|
||||
case SPII::MO_TLS_GD_CALL: Kind = SparcMCExpr::VK_Sparc_TLS_GD_CALL; break;
|
||||
case SPII::MO_TLS_LDM_HI22: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_HI22; break;
|
||||
case SPII::MO_TLS_LDM_LO10: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_LO10; break;
|
||||
case SPII::MO_TLS_LDM_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_ADD; break;
|
||||
case SPII::MO_TLS_LDM_CALL: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_CALL; break;
|
||||
case SPII::MO_TLS_LDO_HIX22:Kind = SparcMCExpr::VK_Sparc_TLS_LDO_HIX22; break;
|
||||
case SPII::MO_TLS_LDO_LOX10:Kind = SparcMCExpr::VK_Sparc_TLS_LDO_LOX10; break;
|
||||
case SPII::MO_TLS_LDO_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_LDO_ADD; break;
|
||||
case SPII::MO_TLS_IE_HI22: Kind = SparcMCExpr::VK_Sparc_TLS_IE_HI22; break;
|
||||
case SPII::MO_TLS_IE_LO10: Kind = SparcMCExpr::VK_Sparc_TLS_IE_LO10; break;
|
||||
case SPII::MO_TLS_IE_LD: Kind = SparcMCExpr::VK_Sparc_TLS_IE_LD; break;
|
||||
case SPII::MO_TLS_IE_LDX: Kind = SparcMCExpr::VK_Sparc_TLS_IE_LDX; break;
|
||||
case SPII::MO_TLS_IE_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_IE_ADD; break;
|
||||
case SPII::MO_TLS_LE_HIX22: Kind = SparcMCExpr::VK_Sparc_TLS_LE_HIX22; break;
|
||||
case SPII::MO_TLS_LE_LOX10: Kind = SparcMCExpr::VK_Sparc_TLS_LE_LOX10; break;
|
||||
}
|
||||
|
||||
switch(MO.getType()) {
|
||||
default: llvm_unreachable("Unknown type in LowerSymbolOperand");
|
||||
case MachineOperand::MO_MachineBasicBlock:
|
||||
Symbol = MO.getMBB()->getSymbol();
|
||||
break;
|
||||
|
||||
case MachineOperand::MO_GlobalAddress:
|
||||
Symbol = AP.getSymbol(MO.getGlobal());
|
||||
break;
|
||||
|
||||
case MachineOperand::MO_BlockAddress:
|
||||
Symbol = AP.GetBlockAddressSymbol(MO.getBlockAddress());
|
||||
break;
|
||||
|
||||
case MachineOperand::MO_ExternalSymbol:
|
||||
Symbol = AP.GetExternalSymbolSymbol(MO.getSymbolName());
|
||||
break;
|
||||
|
||||
case MachineOperand::MO_ConstantPoolIndex:
|
||||
Symbol = AP.GetCPISymbol(MO.getIndex());
|
||||
break;
|
||||
}
|
||||
|
||||
const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol,
|
||||
AP.OutContext);
|
||||
const SparcMCExpr *expr = SparcMCExpr::Create(Kind, MCSym,
|
||||
AP.OutContext);
|
||||
return MCOperand::CreateExpr(expr);
|
||||
}
|
||||
|
||||
static MCOperand LowerOperand(const MachineInstr *MI,
|
||||
const MachineOperand &MO,
|
||||
AsmPrinter &AP) {
|
||||
switch(MO.getType()) {
|
||||
default: llvm_unreachable("unknown operand type"); break;
|
||||
case MachineOperand::MO_Register:
|
||||
if (MO.isImplicit())
|
||||
break;
|
||||
return MCOperand::CreateReg(MO.getReg());
|
||||
|
||||
case MachineOperand::MO_Immediate:
|
||||
return MCOperand::CreateImm(MO.getImm());
|
||||
|
||||
case MachineOperand::MO_MachineBasicBlock:
|
||||
case MachineOperand::MO_GlobalAddress:
|
||||
case MachineOperand::MO_BlockAddress:
|
||||
case MachineOperand::MO_ExternalSymbol:
|
||||
case MachineOperand::MO_ConstantPoolIndex:
|
||||
return LowerSymbolOperand(MI, MO, AP);
|
||||
|
||||
case MachineOperand::MO_RegisterMask: break;
|
||||
|
||||
}
|
||||
return MCOperand();
|
||||
}
|
||||
|
||||
void llvm::LowerSparcMachineInstrToMCInst(const MachineInstr *MI,
|
||||
MCInst &OutMI,
|
||||
AsmPrinter &AP)
|
||||
{
|
||||
|
||||
OutMI.setOpcode(MI->getOpcode());
|
||||
|
||||
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
||||
const MachineOperand &MO = MI->getOperand(i);
|
||||
MCOperand MCOp = LowerOperand(MI, MO, AP);
|
||||
|
||||
if (MCOp.isValid())
|
||||
OutMI.addOperand(MCOp);
|
||||
}
|
||||
}
|
47
lib/Target/Sparc/SparcTargetStreamer.h
Normal file
47
lib/Target/Sparc/SparcTargetStreamer.h
Normal file
@ -0,0 +1,47 @@
|
||||
//===-- SparcTargetStreamer.h - Sparc Target Streamer ----------*- C++ -*--===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SPARCTARGETSTREAMER_H
|
||||
#define SPARCTARGETSTREAMER_H
|
||||
|
||||
#include "llvm/MC/MCELFStreamer.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
|
||||
namespace llvm {
|
||||
class SparcTargetStreamer : public MCTargetStreamer {
|
||||
virtual void anchor();
|
||||
|
||||
public:
|
||||
/// Emit ".register <reg>, #ignore".
|
||||
virtual void emitSparcRegisterIgnore(unsigned reg) = 0;
|
||||
/// Emit ".register <reg>, #scratch".
|
||||
virtual void emitSparcRegisterScratch(unsigned reg) = 0;
|
||||
};
|
||||
|
||||
// This part is for ascii assembly output
|
||||
class SparcTargetAsmStreamer : public SparcTargetStreamer {
|
||||
formatted_raw_ostream &OS;
|
||||
|
||||
public:
|
||||
SparcTargetAsmStreamer(formatted_raw_ostream &OS);
|
||||
virtual void emitSparcRegisterIgnore(unsigned reg);
|
||||
virtual void emitSparcRegisterScratch(unsigned reg);
|
||||
|
||||
};
|
||||
|
||||
// This part is for ELF object output
|
||||
class SparcTargetELFStreamer : public SparcTargetStreamer {
|
||||
public:
|
||||
MCELFStreamer &getStreamer();
|
||||
virtual void emitSparcRegisterIgnore(unsigned reg) {}
|
||||
virtual void emitSparcRegisterScratch(unsigned reg) {}
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -11,7 +11,7 @@
|
||||
|
||||
; CHECK-LABEL: main:
|
||||
; CHECK: .cfi_startproc
|
||||
; CHECK: .cfi_def_cfa_register 30
|
||||
; CHECK: .cfi_def_cfa_register {{30|%fp}}
|
||||
; CHECK: .cfi_window_save
|
||||
; CHECK: .cfi_register 15, 31
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user