41#define DEBUG_TYPE "asm-printer"
47 *OutStreamer->getTargetStreamer());
52 std::unique_ptr<MCStreamer>
Streamer)
55 StringRef getPassName()
const override {
return "Sparc Assembly Printer"; }
60 void emitFunctionBodyStart()
override;
163 EmitBinary(OutStreamer, SP::ADDrr, RS1, RS2, RD, STI);
178 EmitOR(OutStreamer, RD, lo, RD, STI);
181void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(
const MachineInstr *
MI,
185 OutContext.getOrCreateSymbol(Twine(
"_GLOBAL_OFFSET_TABLE_"));
187 const MachineOperand &MO =
MI->getOperand(0);
189 "%o7 is assigned as destination for getpcx!");
194 if (!isPositionIndependent()) {
196 switch(TM.getCodeModel()) {
200 emitHiLo(*OutStreamer, GOTLabel, ELF::R_SPARC_HI22, ELF::R_SPARC_LO10,
201 MCRegOP, OutContext, STI);
204 emitHiLo(*OutStreamer, GOTLabel, ELF::R_SPARC_H44, ELF::R_SPARC_M44,
205 MCRegOP, OutContext, STI);
208 EmitSHL(*OutStreamer, MCRegOP, imm, MCRegOP, STI);
211 EmitOR(*OutStreamer, MCRegOP, lo, MCRegOP, STI);
215 emitHiLo(*OutStreamer, GOTLabel, ELF::R_SPARC_HH22, ELF::R_SPARC_HM10,
216 MCRegOP, OutContext, STI);
219 EmitSHL(*OutStreamer, MCRegOP, imm, MCRegOP, STI);
222 emitHiLo(*OutStreamer, GOTLabel, ELF::R_SPARC_HI22, ELF::R_SPARC_LO10,
223 RegO7, OutContext, STI);
224 EmitADD(*OutStreamer, MCRegOP, RegO7, MCRegOP, STI);
230 MCSymbol *StartLabel = OutContext.createTempSymbol();
231 MCSymbol *EndLabel = OutContext.createTempSymbol();
232 MCSymbol *SethiLabel = OutContext.createTempSymbol();
244 OutStreamer->emitLabel(StartLabel);
248 EmitCall(*OutStreamer, Callee, STI);
256 OutStreamer->emitLabel(SethiLabel);
258 SethiLabel, OutContext);
259 EmitSETHI(*OutStreamer, hiImm, MCRegOP, STI);
260 OutStreamer->emitLabel(EndLabel);
262 EndLabel, OutContext);
263 EmitOR(*OutStreamer, MCRegOP, loImm, MCRegOP, STI);
264 EmitADD(*OutStreamer, MCRegOP, RegO7, MCRegOP, STI);
267MCOperand SparcAsmPrinter::lowerOperand(
const MachineOperand &MO)
const {
319void SparcAsmPrinter::lowerToMCInst(
const MachineInstr *
MI, MCInst &OutMI) {
322 for (
const MachineOperand &MO :
MI->operands()) {
323 MCOperand MCOp = lowerOperand(MO);
329void SparcAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
330 Sparc_MC::verifyInstructionPredicates(
MI->getOpcode(),
331 getSubtargetInfo().getFeatureBits());
332 if (
MI->isBundle()) {
342 switch (
MI->getOpcode()) {
344 case TargetOpcode::DBG_VALUE:
353 if (MF->getSubtarget<SparcSubtarget>().fixTN0011())
354 OutStreamer->emitCodeAlignment(
Align(16), getSubtargetInfo());
357 LowerGETPCXAndEmitMCInsts(
MI, getSubtargetInfo());
364 lowerToMCInst(&*
I, TmpInst);
365 EmitToStreamer(*OutStreamer, TmpInst);
366 }
while ((++
I !=
E) &&
I->isInsideBundle());
369void SparcAsmPrinter::emitFunctionBodyStart() {
370 if (!MF->getSubtarget<SparcSubtarget>().is64Bit())
373 const MachineRegisterInfo &
MRI = MF->getRegInfo();
374 const unsigned globalRegs[] = { SP::G2, SP::G3, SP::G6, SP::G7, 0 };
375 for (
unsigned i = 0; globalRegs[i] != 0; ++i) {
376 unsigned reg = globalRegs[i];
380 if (reg == SP::G6 || reg == SP::G7)
381 getTargetStreamer().emitSparcRegisterIgnore(reg);
383 getTargetStreamer().emitSparcRegisterScratch(reg);
387void SparcAsmPrinter::printOperand(
const MachineInstr *
MI,
int opNum,
389 const DataLayout &
DL = getDataLayout();
390 const MachineOperand &MO =
MI->getOperand(opNum);
403 PrintSymbolOperand(MO, O);
412 O <<
DL.getInternalSymbolPrefix() <<
"CPI" << getFunctionNumber() <<
"_"
423void SparcAsmPrinter::PrintSymbolOperand(
const MachineOperand &MO,
434void SparcAsmPrinter::printMemOperand(
const MachineInstr *
MI,
int opNum,
438 if (
MI->getOperand(opNum+1).isReg() &&
439 MI->getOperand(opNum+1).getReg() == SP::G0)
441 if (
MI->getOperand(opNum+1).isImm() &&
442 MI->getOperand(opNum+1).getImm() == 0)
451bool SparcAsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
452 const char *ExtraCode,
454 if (ExtraCode && ExtraCode[0]) {
455 if (ExtraCode[1] != 0)
return true;
457 switch (ExtraCode[0]) {
464 const SparcSubtarget &Subtarget = MF->getSubtarget<SparcSubtarget>();
465 const MachineOperand &MO =
MI->getOperand(OpNo);
470 if (!SP::IntPairRegClass.
contains(MOReg)) {
475 MOReg = RegisterInfo->getMatchingSuperReg(MOReg, SP::sub_even,
476 &SP::IntPairRegClass);
479 OutContext.reportError(
480 Loc,
"Hi part of pair should point to an even-numbered register");
481 OutContext.reportError(
482 Loc,
"(note that in some cases it might be necessary to manually "
483 "bind the input/output registers instead of relying on "
484 "automatic allocation)");
489 HiReg = RegisterInfo->getSubReg(MOReg, SP::sub_even);
490 LoReg = RegisterInfo->getSubReg(MOReg, SP::sub_odd);
493 switch (ExtraCode[0]) {
506 const MachineOperand &MO =
MI->getOperand(OpNo);
523bool SparcAsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
525 const char *ExtraCode,
527 if (ExtraCode && ExtraCode[0])
537char SparcAsmPrinter::ID = 0;
544LLVMInitializeSparcAsmPrinter() {
552 SparcAsmPrinter &
AsmPrinter =
static_cast<SparcAsmPrinter &
>(
562 SparcAsmPrinter &
AsmPrinter =
static_cast<SparcAsmPrinter &
>(
573 SparcAsmPrinter &
AsmPrinter =
static_cast<SparcAsmPrinter &
>(
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static const Function * getParent(const Value *V)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
static std::string getRegisterName(const TargetRegisterInfo *TRI, Register Reg)
Promote Memory to Register
ModuleAnalysisManager MAM
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
MachineRegisterInfo & MRI
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
static void printMemOperand(raw_ostream &OS, const MachineMemOperand &MMO, const MachineFunction *MF, const Module *M, const MachineFrameInfo *MFI, const TargetInstrInfo *TII, LLVMContext &Ctx)
static MCOperand createPCXRelExprOp(uint16_t Spec, MCSymbol *GOTLabel, MCSymbol *StartLabel, MCSymbol *CurLabel, MCContext &OutContext)
static MCOperand createPCXCallOP(MCSymbol *Label, MCContext &OutContext)
static void EmitSHL(MCStreamer &OutStreamer, MCOperand &RS1, MCOperand &Imm, MCOperand &RD, const MCSubtargetInfo &STI)
static void EmitCall(MCStreamer &OutStreamer, MCOperand &Callee, const MCSubtargetInfo &STI)
static MCOperand createSparcMCOperand(uint16_t Kind, MCSymbol *Sym, MCContext &OutContext)
static void EmitSETHI(MCStreamer &OutStreamer, MCOperand &Imm, MCOperand &RD, const MCSubtargetInfo &STI)
static void EmitOR(MCStreamer &OutStreamer, MCOperand &RS1, MCOperand &Imm, MCOperand &RD, const MCSubtargetInfo &STI)
static void EmitBinary(MCStreamer &OutStreamer, unsigned Opcode, MCOperand &RS1, MCOperand &Src2, MCOperand &RD, const MCSubtargetInfo &STI)
static void EmitRDPC(MCStreamer &OutStreamer, MCOperand &RD, const MCSubtargetInfo &STI)
static void emitHiLo(MCStreamer &OutStreamer, MCSymbol *GOTSym, uint16_t HiKind, uint16_t LoKind, MCOperand &RD, MCContext &OutContext, const MCSubtargetInfo &STI)
static void EmitADD(MCStreamer &OutStreamer, MCOperand &RS1, MCOperand &RS2, MCOperand &RD, const MCSubtargetInfo &STI)
std::unique_ptr< MCStreamer > && Streamer
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class is intended to be used as a driving class for all asm writers.
virtual void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS)
Print the MachineOperand as a symbol.
bool doInitialization(Module &M) override
Set up the AsmPrinter when we are working on a new module.
bool doFinalization(Module &M) override
Shut down the asmprinter.
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
This class represents a function call, abstracting a target machine's calling convention.
Binary assembler expressions.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
Instances of this class represent a single low-level machine instruction.
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
Instances of this class represent operands of the MCInst class.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
Wrapper class representing physical registers. Should be passed by value.
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const Triple & getTargetTriple() const
Represent a reference to a symbol from inside an expression.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
LLVM_ABI void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
LLVM_ABI MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
instr_iterator instr_end()
Instructions::const_iterator const_instr_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
const MDNode * getMetadata() const
MachineBasicBlock * getMBB() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
const BlockAddress * getBlockAddress() const
unsigned getTargetFlags() const
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
const char * getSymbolName() const
Register getReg() const
getReg - Returns the register number.
@ MO_Immediate
Immediate operand.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_GlobalAddress
Address of a global value.
@ MO_RegisterMask
Mask of preserved registers.
@ MO_BlockAddress
Address of a basic block.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_Register
Register operand.
@ MO_ExternalSymbol
Name of external global symbol.
@ MO_Metadata
Metadata reference (for debug info)
bool use_empty(Register RegNo) const
use_empty - Return true if there are no instructions using the specified register.
A Module instance is used to store all the information related to an LLVM module.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MFAM)
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MFAM)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=SP::NoRegAltName)
const SparcRegisterInfo * getRegisterInfo() const override
Represent a constant reference to a string, i.e.
Primary interface to the complete machine description for the target machine.
bool isSPARC64() const
Tests whether the target is 64-bit SPARC (big endian).
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
StringRef getSpecifierName(uint16_t S)
void emitInstruction(MCObjectStreamer &, const MCInst &Inst, const MCSubtargetInfo &STI)
This is an optimization pass for GlobalISel generic memory operations.
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
Target & getTheSparcTarget()
LLVM_ABI void setupModuleAsmPrinter(Module &M, ModuleAnalysisManager &MAM, AsmPrinter &AsmPrinter)
Target & getTheSparcV9Target()
@ Sub
Subtraction of integers.
LLVM_ABI void setupMachineFunctionAsmPrinter(MachineFunctionAnalysisManager &MFAM, MachineFunction &MF, AsmPrinter &AsmPrinter)
Target & getTheSparcelTarget()
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
ArrayRef< int > lo(ArrayRef< int > Vuu)
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...