1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[Sparc] Lower and MachineInstr to MC and print assembly using MCInstPrinter.

llvm-svn: 198030
This commit is contained in:
Venkatraman Govindaraju 2013-12-26 01:49:59 +00:00
parent 7e519426f2
commit 8c2d10768d
12 changed files with 417 additions and 71 deletions

View File

@ -23,6 +23,7 @@ add_llvm_target(SparcCodeGen
SparcSelectionDAGInfo.cpp
SparcJITInfo.cpp
SparcCodeEmitter.cpp
SparcMCInstLower.cpp
)
add_subdirectory(TargetInfo)

View File

@ -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
{

View File

@ -2,4 +2,5 @@ add_llvm_library(LLVMSparcDesc
SparcMCTargetDesc.cpp
SparcMCAsmInfo.cpp
SparcMCExpr.cpp
SparcTargetStreamer.cpp
)

View File

@ -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

View File

@ -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);
}

View 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);
}

View File

@ -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 {

View File

@ -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];
}

View File

@ -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,

View 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);
}
}

View 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

View File

@ -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