37#define DEBUG_TYPE "asm-printer"
43 *OutStreamer->getTargetStreamer());
47 std::unique_ptr<MCStreamer> Streamer)
149 EmitBinary(OutStreamer, SP::ORri, RS1, Imm, RD, STI);
155 EmitBinary(OutStreamer, SP::ADDrr, RS1, RS2, RD, STI);
161 EmitBinary(OutStreamer, SP::SLLri, RS1, Imm, RD, STI);
175 EmitOR(OutStreamer, RD, lo, RD, STI);
178void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(
const MachineInstr *
MI,
182 OutContext.getOrCreateSymbol(
Twine(
"_GLOBAL_OFFSET_TABLE_"));
186 "%o7 is assigned as destination for getpcx!");
191 if (!isPositionIndependent()) {
193 switch(
TM.getCodeModel()) {
199 MCRegOP, OutContext, STI);
204 MCRegOP, OutContext, STI);
207 EmitSHL(*OutStreamer, MCRegOP, imm, MCRegOP, STI);
209 GOTLabel, OutContext);
210 EmitOR(*OutStreamer, MCRegOP, lo, MCRegOP, STI);
216 MCRegOP, OutContext, STI);
219 EmitSHL(*OutStreamer, MCRegOP, imm, MCRegOP, STI);
224 RegO7, OutContext, STI);
225 EmitADD(*OutStreamer, MCRegOP, RegO7, MCRegOP, STI);
231 MCSymbol *StartLabel = OutContext.createTempSymbol();
232 MCSymbol *EndLabel = OutContext.createTempSymbol();
233 MCSymbol *SethiLabel = OutContext.createTempSymbol();
245 OutStreamer->emitLabel(StartLabel);
249 EmitCall(*OutStreamer, Callee, STI);
257 OutStreamer->emitLabel(SethiLabel);
259 GOTLabel, StartLabel, SethiLabel,
261 EmitSETHI(*OutStreamer, hiImm, MCRegOP, STI);
262 OutStreamer->emitLabel(EndLabel);
264 GOTLabel, StartLabel, EndLabel,
266 EmitOR(*OutStreamer, MCRegOP, loImm, MCRegOP, STI);
267 EmitADD(*OutStreamer, MCRegOP, RegO7, MCRegOP, STI);
271 Sparc_MC::verifyInstructionPredicates(
MI->getOpcode(),
272 getSubtargetInfo().getFeatureBits());
274 switch (
MI->getOpcode()) {
276 case TargetOpcode::DBG_VALUE:
283 OutStreamer->emitCodeAlignment(
Align(16), &getSubtargetInfo());
286 LowerGETPCXAndEmitMCInsts(
MI, getSubtargetInfo());
294 EmitToStreamer(*OutStreamer, TmpInst);
295 }
while ((++
I != E) &&
I->isInsideBundle());
298void SparcAsmPrinter::emitFunctionBodyStart() {
303 const unsigned globalRegs[] = { SP::G2, SP::G3, SP::G6, SP::G7, 0 };
304 for (
unsigned i = 0; globalRegs[i] != 0; ++i) {
305 unsigned reg = globalRegs[i];
306 if (
MRI.use_empty(reg))
309 if (reg == SP::G6 || reg == SP::G7)
310 getTargetStreamer().emitSparcRegisterIgnore(reg);
312 getTargetStreamer().emitSparcRegisterScratch(reg);
316void SparcAsmPrinter::printOperand(
const MachineInstr *
MI,
int opNum,
336 PrintSymbolOperand(MO, O);
345 O <<
DL.getPrivateGlobalPrefix() <<
"CPI" << getFunctionNumber() <<
"_"
354 if (CloseParen)
O <<
")";
357void SparcAsmPrinter::printMemOperand(
const MachineInstr *
MI,
int opNum,
361 if (
MI->getOperand(opNum+1).isReg() &&
362 MI->getOperand(opNum+1).getReg() == SP::G0)
364 if (
MI->getOperand(opNum+1).isImm() &&
365 MI->getOperand(opNum+1).getImm() == 0)
374bool SparcAsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
375 const char *ExtraCode,
377 if (ExtraCode && ExtraCode[0]) {
378 if (ExtraCode[1] != 0)
return true;
380 switch (ExtraCode[0]) {
393 if (!SP::IntPairRegClass.
contains(MOReg)) {
398 MOReg = RegisterInfo->getMatchingSuperReg(MOReg, SP::sub_even,
399 &SP::IntPairRegClass);
402 OutContext.reportError(
403 Loc,
"Hi part of pair should point to an even-numbered register");
404 OutContext.reportError(
405 Loc,
"(note that in some cases it might be necessary to manually "
406 "bind the input/output registers instead of relying on "
407 "automatic allocation)");
412 HiReg = RegisterInfo->getSubReg(MOReg, SP::sub_even);
413 LoReg = RegisterInfo->getSubReg(MOReg, SP::sub_odd);
416 switch (ExtraCode[0]) {
439bool SparcAsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
441 const char *ExtraCode,
443 if (ExtraCode && ExtraCode[0])
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define LLVM_EXTERNAL_VISIBILITY
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static std::string getRegisterName(const TargetRegisterInfo *TRI, Register Reg)
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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 createSparcMCOperand(SparcMCExpr::VariantKind Kind, MCSymbol *Sym, MCContext &OutContext)
static MCOperand createPCXCallOP(MCSymbol *Label, MCContext &OutContext)
static void EmitSHL(MCStreamer &OutStreamer, MCOperand &RS1, MCOperand &Imm, MCOperand &RD, const MCSubtargetInfo &STI)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcAsmPrinter()
static void EmitCall(MCStreamer &OutStreamer, MCOperand &Callee, const MCSubtargetInfo &STI)
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 MCOperand createPCXRelExprOp(SparcMCExpr::VariantKind Kind, MCSymbol *GOTLabel, MCSymbol *StartLabel, MCSymbol *CurLabel, MCContext &OutContext)
static void EmitADD(MCStreamer &OutStreamer, MCOperand &RS1, MCOperand &RS2, MCOperand &RD, const MCSubtargetInfo &STI)
static void EmitHiLo(MCStreamer &OutStreamer, MCSymbol *GOTSym, SparcMCExpr::VariantKind HiKind, SparcMCExpr::VariantKind LoKind, MCOperand &RD, MCContext &OutContext, const MCSubtargetInfo &STI)
This class is intended to be used as a driving class for all asm writers.
virtual void emitInstruction(const MachineInstr *)
Targets should implement this to emit instructions.
virtual void emitFunctionBodyStart()
Targets can override this to emit stuff before the first basic block in the function.
virtual bool PrintAsmMemoryOperand(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 as...
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.
A parsed version of the target data layout string in and methods for querying it.
Binary assembler expressions.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static 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)
Wrapper class representing physical registers. Should be passed by value.
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)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
Instructions::const_iterator const_instr_iterator
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
const MDNode * getMetadata() const
MachineBasicBlock * getMBB() const
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_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)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
Represents a location in source code.
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=SP::NoRegAltName)
static const SparcMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
static bool printVariantKind(raw_ostream &OS, VariantKind Kind)
const SparcRegisterInfo * getRegisterInfo() const override
StringRef - Represent a constant reference to a string, i.e.
std::string lower() const
Primary interface to the complete machine description for the target machine.
bool isSPARC64() const
Tests whether the target is 64-bit SPARC (big endian).
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
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.
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheSparcTarget()
Target & getTheSparcV9Target()
void LowerSparcMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, AsmPrinter &AP)
Target & getTheSparcelTarget()
ArrayRef< int > lo(ArrayRef< int > Vuu)
This struct is a compact representation of a valid (non-zero power of two) alignment.
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...