36 #define DEBUG_TYPE "asm-printer"
42 *OutStreamer->getTargetStreamer());
46 std::unique_ptr<MCStreamer> Streamer)
49 StringRef getPassName()
const override {
return "Sparc Assembly Printer"; }
53 const char *Modifier =
nullptr);
55 void EmitFunctionBodyStart()
override;
62 bool PrintAsmOperand(
const MachineInstr *MI,
unsigned OpNo,
63 unsigned AsmVariant,
const char *ExtraCode,
65 bool PrintAsmMemoryOperand(
const MachineInstr *MI,
unsigned OpNo,
66 unsigned AsmVariant,
const char *ExtraCode,
142 EmitBinary(OutStreamer, SP::ORri, RS1, Imm, RD, STI);
148 EmitBinary(OutStreamer, SP::ADDrr, RS1, RS2, RD, STI);
154 EmitBinary(OutStreamer, SP::SLLri, RS1, Imm, RD, STI);
168 EmitOR(OutStreamer, RD, lo, RD, STI);
171 void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(
const MachineInstr *
MI,
175 OutContext.getOrCreateSymbol(
Twine(
"_GLOBAL_OFFSET_TABLE_"));
179 "%o7 is assigned as destination for getpcx!");
184 if (!isPositionIndependent()) {
186 switch(
TM.getCodeModel()) {
192 MCRegOP, OutContext, STI);
197 MCRegOP, OutContext, STI);
200 EmitSHL(*OutStreamer, MCRegOP, imm, MCRegOP, STI);
202 GOTLabel, OutContext);
203 EmitOR(*OutStreamer, MCRegOP, lo, MCRegOP, STI);
209 MCRegOP, OutContext, STI);
212 EmitSHL(*OutStreamer, MCRegOP, imm, MCRegOP, STI);
217 RegO7, OutContext, STI);
218 EmitADD(*OutStreamer, MCRegOP, RegO7, MCRegOP, STI);
224 MCSymbol *StartLabel = OutContext.createTempSymbol();
225 MCSymbol *EndLabel = OutContext.createTempSymbol();
226 MCSymbol *SethiLabel = OutContext.createTempSymbol();
238 OutStreamer->EmitLabel(StartLabel);
240 EmitCall(*OutStreamer, Callee, STI);
241 OutStreamer->EmitLabel(SethiLabel);
243 GOTLabel, StartLabel, SethiLabel,
245 EmitSETHI(*OutStreamer, hiImm, MCRegOP, STI);
246 OutStreamer->EmitLabel(EndLabel);
248 GOTLabel, StartLabel, EndLabel,
250 EmitOR(*OutStreamer, MCRegOP, loImm, MCRegOP, STI);
251 EmitADD(*OutStreamer, MCRegOP, RegO7, MCRegOP, STI);
254 void SparcAsmPrinter::EmitInstruction(
const MachineInstr *MI)
259 case TargetOpcode::DBG_VALUE:
263 LowerGETPCXAndEmitMCInsts(MI, getSubtargetInfo());
271 EmitToStreamer(*OutStreamer, TmpInst);
272 }
while ((++I != E) && I->isInsideBundle());
275 void SparcAsmPrinter::EmitFunctionBodyStart() {
280 const unsigned globalRegs[] = { SP::G2, SP::G3, SP::G6, SP::G7, 0 };
281 for (
unsigned i = 0; globalRegs[
i] != 0; ++
i) {
282 unsigned reg = globalRegs[
i];
286 if (reg == SP::G6 || reg == SP::G7)
287 getTargetStreamer().emitSparcRegisterIgnore(reg);
289 getTargetStreamer().emitSparcRegisterScratch(reg);
304 "Cannot handle target flags on call address");
314 "Invalid target flags for address operand on sethi");
319 "Cannot handle target flags on tls call address");
320 else if (MI->
getOpcode() == SP::TLS_ADDrr)
325 "Cannot handle target flags on add for TLS");
326 else if (MI->
getOpcode() == SP::TLS_LDrr)
328 "Cannot handle target flags on ld for TLS");
329 else if (MI->
getOpcode() == SP::TLS_LDXrr)
331 "Cannot handle target flags on ldx for TLS");
335 "Cannot handle target flags on xor for TLS");
344 "Invalid target flags for small address operand");
381 if (CloseParen) O <<
")";
384 void SparcAsmPrinter::printMemOperand(
const MachineInstr *MI,
int opNum,
389 if (Modifier && !
strcmp(Modifier,
"arith")) {
408 bool SparcAsmPrinter::PrintAsmOperand(
const MachineInstr *MI,
unsigned OpNo,
410 const char *ExtraCode,
412 if (ExtraCode && ExtraCode[0]) {
413 if (ExtraCode[1] != 0)
return true;
415 switch (ExtraCode[0]) {
430 bool SparcAsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *MI,
431 unsigned OpNo,
unsigned AsmVariant,
432 const char *ExtraCode,
434 if (ExtraCode && ExtraCode[0])
438 printMemOperand(MI, OpNo, O);
A parsed version of the target data layout string in and methods for querying it. ...
StringRef getPrivateGlobalPrefix() const
const GlobalValue * getGlobal() const
static MCOperand createPCXRelExprOp(SparcMCExpr::VariantKind Kind, MCSymbol *GOTLabel, MCSymbol *StartLabel, MCSymbol *CurLabel, MCContext &OutContext)
instr_iterator instr_end()
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
MachineBasicBlock * getMBB() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
static MCOperand createExpr(const MCExpr *Val)
static bool printVariantKind(raw_ostream &OS, VariantKind Kind)
This class represents a function call, abstracting a target machine's calling convention.
MachineBasicBlock reference.
const char * getSymbolName() const
const MDNode * getMetadata() const
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with strcmp
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
static MCOperand createReg(unsigned Reg)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
static const char * getRegisterName(unsigned RegNo)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
static void EmitHiLo(MCStreamer &OutStreamer, MCSymbol *GOTSym, SparcMCExpr::VariantKind HiKind, SparcMCExpr::VariantKind LoKind, MCOperand &RD, MCContext &OutContext, const MCSubtargetInfo &STI)
Name of external global symbol.
static StringRef getName(Value *V)
Represent a reference to a symbol from inside an expression.
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Context object for machine code objects.
static std::string getRegisterName(const TargetRegisterInfo *TRI, unsigned Reg)
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Target & getTheSparcTarget()
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Expected< const typename ELFT::Sym * > getSymbol(typename ELFT::SymRange Symbols, uint32_t Index)
Instances of this class represent a single low-level machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
const MachineBasicBlock * getParent() const
static void EmitSHL(MCStreamer &OutStreamer, MCOperand &RS1, MCOperand &Imm, MCOperand &RD, const MCSubtargetInfo &STI)
Address of a global value.
unsigned getTargetFlags() const
Streaming machine code generation interface.
unsigned const MachineRegisterInfo * MRI
static void EmitBinary(MCStreamer &OutStreamer, unsigned Opcode, MCOperand &RS1, MCOperand &Src2, MCOperand &RD, const MCSubtargetInfo &STI)
static void EmitCall(MCStreamer &OutStreamer, MCOperand &Callee, const MCSubtargetInfo &STI)
const MachineOperand & getOperand(unsigned i) const
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant...
This class is intended to be used as a driving class for all asm writers.
Target & getTheSparcelTarget()
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
static void EmitOR(MCStreamer &OutStreamer, MCOperand &RS1, MCOperand &Imm, MCOperand &RD, const MCSubtargetInfo &STI)
Address of a basic block.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
self_iterator getIterator()
static void EmitADD(MCStreamer &OutStreamer, MCOperand &RS1, MCOperand &RS2, MCOperand &RD, const MCSubtargetInfo &STI)
Binary assembler expressions.
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void LLVMInitializeSparcAsmPrinter()
Iterator for intrusive lists based on ilist_node.
void setOpcode(unsigned Op)
MachineOperand class - Representation of each machine instruction operand.
static MCOperand createPCXCallOP(MCSymbol *Label, MCContext &OutContext)
Target & getTheSparcV9Target()
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
void LowerSparcMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, AsmPrinter &AP)
MCSubtargetInfo - Generic base class for all target subtargets.
static const SparcMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
RegisterAsmPrinter - Helper template for registering a target specific assembly printer, for use in the target machine initialization function.
This class implements an extremely fast bulk output stream that can only output to a stream...
static void EmitSETHI(MCStreamer &OutStreamer, MCOperand &Imm, MCOperand &RD, const MCSubtargetInfo &STI)
Primary interface to the complete machine description for the target machine.
void addOperand(const MCOperand &Op)
StringRef - Represent a constant reference to a string, i.e.
const BlockAddress * getBlockAddress() const
Address of indexed Constant in Constant Pool.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
Instances of this class represent operands of the MCInst class.
LLVM_NODISCARD std::string lower() const
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
static MCOperand createSparcMCOperand(SparcMCExpr::VariantKind Kind, MCSymbol *Sym, MCContext &OutContext)
bool use_empty(unsigned RegNo) const
use_empty - Return true if there are no instructions using the specified register.
Metadata reference (for debug info)