LLVM 24.0.0git
SparcAsmPrinter.cpp
Go to the documentation of this file.
1//===-- SparcAsmPrinter.cpp - Sparc LLVM assembly writer ------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains a printer that converts from our internal representation
10// of machine-dependent LLVM code to GAS-format SPARC assembly language.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SparcAsmPrinter.h"
19#include "Sparc.h"
20#include "SparcInstrInfo.h"
21#include "SparcTargetMachine.h"
30#include "llvm/IR/Mangler.h"
31#include "llvm/MC/MCAsmInfo.h"
32#include "llvm/MC/MCContext.h"
33#include "llvm/MC/MCInst.h"
34#include "llvm/MC/MCStreamer.h"
35#include "llvm/MC/MCSymbol.h"
39using namespace llvm;
40
41#define DEBUG_TYPE "asm-printer"
42
43namespace {
44class SparcAsmPrinter : public AsmPrinter {
45 SparcTargetStreamer &getTargetStreamer() {
46 return static_cast<SparcTargetStreamer &>(
47 *OutStreamer->getTargetStreamer());
48 }
49
50public:
51 explicit SparcAsmPrinter(TargetMachine &TM,
52 std::unique_ptr<MCStreamer> Streamer)
53 : AsmPrinter(TM, std::move(Streamer), ID) {}
54
55 StringRef getPassName() const override { return "Sparc Assembly Printer"; }
56
57 void printOperand(const MachineInstr *MI, int opNum, raw_ostream &OS);
58 void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &OS);
59
60 void emitFunctionBodyStart() override;
61 void emitInstruction(const MachineInstr *MI) override;
62
63 static const char *getRegisterName(MCRegister Reg) {
65 }
66
67 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
68 const char *ExtraCode, raw_ostream &O) override;
69 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
70 const char *ExtraCode, raw_ostream &O) override;
71 void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override;
72
73 void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI,
74 const MCSubtargetInfo &STI);
75
76 MCOperand lowerOperand(const MachineOperand &MO) const;
77
78private:
79 void lowerToMCInst(const MachineInstr *MI, MCInst &OutMI);
80
81public:
82 static char ID;
83};
84} // end of anonymous namespace
85
87 MCContext &OutContext) {
88 const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Sym, OutContext);
89 auto *expr = MCSpecifierExpr::create(MCSym, Kind, OutContext);
90 return MCOperand::createExpr(expr);
91}
93 MCContext &OutContext) {
94 return MCOperand::createExpr(MCSymbolRefExpr::create(Label, OutContext));
95}
96
98 MCSymbol *StartLabel, MCSymbol *CurLabel,
99 MCContext &OutContext) {
100 const MCSymbolRefExpr *GOT = MCSymbolRefExpr::create(GOTLabel, OutContext);
101 const MCSymbolRefExpr *Start = MCSymbolRefExpr::create(StartLabel,
102 OutContext);
103 const MCSymbolRefExpr *Cur = MCSymbolRefExpr::create(CurLabel,
104 OutContext);
105
106 const MCBinaryExpr *Sub = MCBinaryExpr::createSub(Cur, Start, OutContext);
107 const MCBinaryExpr *Add = MCBinaryExpr::createAdd(GOT, Sub, OutContext);
108 auto *expr = MCSpecifierExpr::create(Add, Spec, OutContext);
109 return MCOperand::createExpr(expr);
110}
111
112static void EmitCall(MCStreamer &OutStreamer,
113 MCOperand &Callee,
114 const MCSubtargetInfo &STI)
115{
117 CallInst.setOpcode(SP::CALL);
118 CallInst.addOperand(Callee);
119 OutStreamer.emitInstruction(CallInst, STI);
120}
121
122static void EmitRDPC(MCStreamer &OutStreamer, MCOperand &RD,
123 const MCSubtargetInfo &STI) {
124 MCInst RDPCInst;
125 RDPCInst.setOpcode(SP::RDASR);
126 RDPCInst.addOperand(RD);
127 RDPCInst.addOperand(MCOperand::createReg(SP::ASR5));
128 OutStreamer.emitInstruction(RDPCInst, STI);
129}
130
131static void EmitSETHI(MCStreamer &OutStreamer,
132 MCOperand &Imm, MCOperand &RD,
133 const MCSubtargetInfo &STI)
134{
135 MCInst SETHIInst;
136 SETHIInst.setOpcode(SP::SETHIi);
137 SETHIInst.addOperand(RD);
138 SETHIInst.addOperand(Imm);
139 OutStreamer.emitInstruction(SETHIInst, STI);
140}
141
142static void EmitBinary(MCStreamer &OutStreamer, unsigned Opcode,
143 MCOperand &RS1, MCOperand &Src2, MCOperand &RD,
144 const MCSubtargetInfo &STI)
145{
146 MCInst Inst;
147 Inst.setOpcode(Opcode);
148 Inst.addOperand(RD);
149 Inst.addOperand(RS1);
150 Inst.addOperand(Src2);
151 OutStreamer.emitInstruction(Inst, STI);
152}
153
154static void EmitOR(MCStreamer &OutStreamer,
155 MCOperand &RS1, MCOperand &Imm, MCOperand &RD,
156 const MCSubtargetInfo &STI) {
157 EmitBinary(OutStreamer, SP::ORri, RS1, Imm, RD, STI);
158}
159
160static void EmitADD(MCStreamer &OutStreamer,
161 MCOperand &RS1, MCOperand &RS2, MCOperand &RD,
162 const MCSubtargetInfo &STI) {
163 EmitBinary(OutStreamer, SP::ADDrr, RS1, RS2, RD, STI);
164}
165
166static void EmitSHL(MCStreamer &OutStreamer,
167 MCOperand &RS1, MCOperand &Imm, MCOperand &RD,
168 const MCSubtargetInfo &STI) {
169 EmitBinary(OutStreamer, SP::SLLri, RS1, Imm, RD, STI);
170}
171
172static void emitHiLo(MCStreamer &OutStreamer, MCSymbol *GOTSym, uint16_t HiKind,
173 uint16_t LoKind, MCOperand &RD, MCContext &OutContext,
174 const MCSubtargetInfo &STI) {
175 MCOperand hi = createSparcMCOperand(HiKind, GOTSym, OutContext);
176 MCOperand lo = createSparcMCOperand(LoKind, GOTSym, OutContext);
177 EmitSETHI(OutStreamer, hi, RD, STI);
178 EmitOR(OutStreamer, RD, lo, RD, STI);
179}
180
181void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI,
182 const MCSubtargetInfo &STI)
183{
184 MCSymbol *GOTLabel =
185 OutContext.getOrCreateSymbol(Twine("_GLOBAL_OFFSET_TABLE_"));
186
187 const MachineOperand &MO = MI->getOperand(0);
188 assert(MO.getReg() != SP::O7 &&
189 "%o7 is assigned as destination for getpcx!");
190
191 MCOperand MCRegOP = MCOperand::createReg(MO.getReg());
192
193
194 if (!isPositionIndependent()) {
195 // Just load the address of GOT to MCRegOP.
196 switch(TM.getCodeModel()) {
197 default:
198 llvm_unreachable("Unsupported absolute code model");
199 case CodeModel::Small:
200 emitHiLo(*OutStreamer, GOTLabel, ELF::R_SPARC_HI22, ELF::R_SPARC_LO10,
201 MCRegOP, OutContext, STI);
202 break;
203 case CodeModel::Medium: {
204 emitHiLo(*OutStreamer, GOTLabel, ELF::R_SPARC_H44, ELF::R_SPARC_M44,
205 MCRegOP, OutContext, STI);
207 OutContext));
208 EmitSHL(*OutStreamer, MCRegOP, imm, MCRegOP, STI);
209 MCOperand lo =
210 createSparcMCOperand(ELF::R_SPARC_L44, GOTLabel, OutContext);
211 EmitOR(*OutStreamer, MCRegOP, lo, MCRegOP, STI);
212 break;
213 }
214 case CodeModel::Large: {
215 emitHiLo(*OutStreamer, GOTLabel, ELF::R_SPARC_HH22, ELF::R_SPARC_HM10,
216 MCRegOP, OutContext, STI);
218 OutContext));
219 EmitSHL(*OutStreamer, MCRegOP, imm, MCRegOP, STI);
220 // Use register %o7 to load the lower 32 bits.
221 MCOperand RegO7 = MCOperand::createReg(SP::O7);
222 emitHiLo(*OutStreamer, GOTLabel, ELF::R_SPARC_HI22, ELF::R_SPARC_LO10,
223 RegO7, OutContext, STI);
224 EmitADD(*OutStreamer, MCRegOP, RegO7, MCRegOP, STI);
225 }
226 }
227 return;
228 }
229
230 MCSymbol *StartLabel = OutContext.createTempSymbol();
231 MCSymbol *EndLabel = OutContext.createTempSymbol();
232 MCSymbol *SethiLabel = OutContext.createTempSymbol();
233
234 MCOperand RegO7 = MCOperand::createReg(SP::O7);
235
236 // <StartLabel>:
237 // <GET-PC> // This will be either `call <EndLabel>` or `rd %pc, %o7`.
238 // <SethiLabel>:
239 // sethi %hi(_GLOBAL_OFFSET_TABLE_+(<SethiLabel>-<StartLabel>)), <MO>
240 // <EndLabel>:
241 // or <MO>, %lo(_GLOBAL_OFFSET_TABLE_+(<EndLabel>-<StartLabel>))), <MO>
242 // add <MO>, %o7, <MO>
243
244 OutStreamer->emitLabel(StartLabel);
245 if (!STI.getTargetTriple().isSPARC64() ||
246 STI.hasFeature(Sparc::TuneSlowRDPC)) {
247 MCOperand Callee = createPCXCallOP(EndLabel, OutContext);
248 EmitCall(*OutStreamer, Callee, STI);
249 } else {
250 // TODO find out whether it is possible to store PC
251 // in other registers, to enable leaf function optimization.
252 // (On the other hand, approx. over 97.8% of GETPCXes happen
253 // in non-leaf functions, so would this be worth the effort?)
254 EmitRDPC(*OutStreamer, RegO7, STI);
255 }
256 OutStreamer->emitLabel(SethiLabel);
257 MCOperand hiImm = createPCXRelExprOp(ELF::R_SPARC_PC22, GOTLabel, StartLabel,
258 SethiLabel, OutContext);
259 EmitSETHI(*OutStreamer, hiImm, MCRegOP, STI);
260 OutStreamer->emitLabel(EndLabel);
261 MCOperand loImm = createPCXRelExprOp(ELF::R_SPARC_PC10, GOTLabel, StartLabel,
262 EndLabel, OutContext);
263 EmitOR(*OutStreamer, MCRegOP, loImm, MCRegOP, STI);
264 EmitADD(*OutStreamer, MCRegOP, RegO7, MCRegOP, STI);
265}
266
267MCOperand SparcAsmPrinter::lowerOperand(const MachineOperand &MO) const {
268 switch (MO.getType()) {
269 default:
270 llvm_unreachable("unknown operand type");
271 break;
273 if (MO.isImplicit())
274 break;
275 return MCOperand::createReg(MO.getReg());
276
278 return MCOperand::createImm(MO.getImm());
279
285 auto RelType = MO.getTargetFlags();
286 const MCSymbol *Symbol = nullptr;
287 switch (MO.getType()) {
288 default:
291 Symbol = MO.getMBB()->getSymbol();
292 break;
294 Symbol = getSymbol(MO.getGlobal());
295 break;
297 Symbol = GetBlockAddressSymbol(MO.getBlockAddress());
298 break;
300 Symbol = GetExternalSymbolSymbol(MO.getSymbolName());
301 break;
303 Symbol = GetCPISymbol(MO.getIndex());
304 break;
305 }
306
307 const MCExpr *expr = MCSymbolRefExpr::create(Symbol, OutContext);
308 if (RelType)
309 expr = MCSpecifierExpr::create(expr, RelType, OutContext);
310 return MCOperand::createExpr(expr);
311 }
312
314 break;
315 }
316 return MCOperand();
317}
318
319void SparcAsmPrinter::lowerToMCInst(const MachineInstr *MI, MCInst &OutMI) {
320 OutMI.setOpcode(MI->getOpcode());
321
322 for (const MachineOperand &MO : MI->operands()) {
323 MCOperand MCOp = lowerOperand(MO);
324 if (MCOp.isValid())
325 OutMI.addOperand(MCOp);
326 }
327}
328
329void SparcAsmPrinter::emitInstruction(const MachineInstr *MI) {
330 Sparc_MC::verifyInstructionPredicates(MI->getOpcode(),
331 getSubtargetInfo().getFeatureBits());
332 if (MI->isBundle()) {
333 const MachineBasicBlock *MBB = MI->getParent();
335 while (I != MBB->instr_end() && I->isInsideBundle()) {
337 ++I;
338 }
339 return;
340 }
341
342 switch (MI->getOpcode()) {
343 default: break;
344 case TargetOpcode::DBG_VALUE:
345 // FIXME: Debug Value.
346 return;
347 case SP::CASArr:
348 case SP::SWAPrr:
349 case SP::SWAPri:
350 case SP::LDSTUBrr:
351 case SP::LDSTUBri:
352 case SP::LDSTUBArr:
353 if (MF->getSubtarget<SparcSubtarget>().fixTN0011())
354 OutStreamer->emitCodeAlignment(Align(16), getSubtargetInfo());
355 break;
356 case SP::GETPCX:
357 LowerGETPCXAndEmitMCInsts(MI, getSubtargetInfo());
358 return;
359 }
361 MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();
362 do {
363 MCInst TmpInst;
364 lowerToMCInst(&*I, TmpInst);
365 EmitToStreamer(*OutStreamer, TmpInst);
366 } while ((++I != E) && I->isInsideBundle()); // Delay slot check.
367}
368
369void SparcAsmPrinter::emitFunctionBodyStart() {
370 if (!MF->getSubtarget<SparcSubtarget>().is64Bit())
371 return;
372
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];
377 if (MRI.use_empty(reg))
378 continue;
379
380 if (reg == SP::G6 || reg == SP::G7)
381 getTargetStreamer().emitSparcRegisterIgnore(reg);
382 else
383 getTargetStreamer().emitSparcRegisterScratch(reg);
384 }
385}
386
387void SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
388 raw_ostream &O) {
389 const DataLayout &DL = getDataLayout();
390 const MachineOperand &MO = MI->getOperand(opNum);
391 switch (MO.getType()) {
393 O << "%" << StringRef(getRegisterName(MO.getReg())).lower();
394 break;
395
397 O << MO.getImm();
398 break;
400 MO.getMBB()->getSymbol()->print(O, MAI);
401 return;
403 PrintSymbolOperand(MO, O);
404 break;
406 O << GetBlockAddressSymbol(MO.getBlockAddress())->getName();
407 break;
409 O << MO.getSymbolName();
410 break;
412 O << DL.getInternalSymbolPrefix() << "CPI" << getFunctionNumber() << "_"
413 << MO.getIndex();
414 break;
416 MO.getMetadata()->printAsOperand(O, MMI->getModule());
417 break;
418 default:
419 llvm_unreachable("<unknown operand type>");
420 }
421}
422
423void SparcAsmPrinter::PrintSymbolOperand(const MachineOperand &MO,
424 raw_ostream &O) {
425 const unsigned RelType = MO.getTargetFlags();
426 StringRef Specifier = Sparc::getSpecifierName(RelType);
427 if (!Specifier.empty())
428 O << '%' << Specifier << '(';
430 if (!Specifier.empty())
431 O << ')';
432}
433
434void SparcAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum,
435 raw_ostream &O) {
436 printOperand(MI, opNum, O);
437
438 if (MI->getOperand(opNum+1).isReg() &&
439 MI->getOperand(opNum+1).getReg() == SP::G0)
440 return; // don't print "+%g0"
441 if (MI->getOperand(opNum+1).isImm() &&
442 MI->getOperand(opNum+1).getImm() == 0)
443 return; // don't print "+0"
444
445 O << "+";
446 printOperand(MI, opNum+1, O);
447}
448
449/// PrintAsmOperand - Print out an operand for an inline asm expression.
450///
451bool SparcAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
452 const char *ExtraCode,
453 raw_ostream &O) {
454 if (ExtraCode && ExtraCode[0]) {
455 if (ExtraCode[1] != 0) return true; // Unknown modifier.
456
457 switch (ExtraCode[0]) {
458 default:
459 // See if this is a generic print operand
460 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
461 case 'L': // Low order register of a twin word register operand
462 case 'H': // High order register of a twin word register operand
463 {
464 const SparcSubtarget &Subtarget = MF->getSubtarget<SparcSubtarget>();
465 const MachineOperand &MO = MI->getOperand(OpNo);
466 const SparcRegisterInfo *RegisterInfo = Subtarget.getRegisterInfo();
467 Register MOReg = MO.getReg();
468
469 Register HiReg, LoReg;
470 if (!SP::IntPairRegClass.contains(MOReg)) {
471 // If we aren't given a register pair already, find out which pair it
472 // belongs to. Note that here, the specified register operand, which
473 // refers to the high part of the twinword, needs to be an even-numbered
474 // register.
475 MOReg = RegisterInfo->getMatchingSuperReg(MOReg, SP::sub_even,
476 &SP::IntPairRegClass);
477 if (!MOReg) {
478 SMLoc Loc;
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)");
485 return true;
486 }
487 }
488
489 HiReg = RegisterInfo->getSubReg(MOReg, SP::sub_even);
490 LoReg = RegisterInfo->getSubReg(MOReg, SP::sub_odd);
491
493 switch (ExtraCode[0]) {
494 case 'L':
495 Reg = LoReg;
496 break;
497 case 'H':
498 Reg = HiReg;
499 break;
500 }
501
503 return false;
504 }
505 case 'r': {
506 const MachineOperand &MO = MI->getOperand(OpNo);
507 if (MO.isImm() && MO.getImm() == 0) {
508 O << "%g0";
509 return false;
510 }
511 break;
512 }
513 case 'f':
514 break;
515 }
516 }
517
518 printOperand(MI, OpNo, O);
519
520 return false;
521}
522
523bool SparcAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
524 unsigned OpNo,
525 const char *ExtraCode,
526 raw_ostream &O) {
527 if (ExtraCode && ExtraCode[0])
528 return true; // Unknown modifier
529
530 O << '[';
531 printMemOperand(MI, OpNo, O);
532 O << ']';
533
534 return false;
535}
536
537char SparcAsmPrinter::ID = 0;
538
539INITIALIZE_PASS(SparcAsmPrinter, "sparc-asm-printer", "Sparc Assembly Printer",
540 false, false)
541
542// Force static initialization.
544LLVMInitializeSparcAsmPrinter() {
548}
549
552 SparcAsmPrinter &AsmPrinter = static_cast<SparcAsmPrinter &>(
553 MAM.getResult<AsmPrinterAnalysis>(M).getPrinter());
556 return PreservedAnalyses::all();
557}
558
562 SparcAsmPrinter &AsmPrinter = static_cast<SparcAsmPrinter &>(
564 .getCachedResult<AsmPrinterAnalysis>(*MF.getFunction().getParent())
565 ->getPrinter());
568 return PreservedAnalyses::all();
569}
570
573 SparcAsmPrinter &AsmPrinter = static_cast<SparcAsmPrinter &>(
574 MAM.getResult<AsmPrinterAnalysis>(M).getPrinter());
577 return PreservedAnalyses::all();
578}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t Imm
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static const Function * getParent(const Value *V)
#define X(NUM, ENUM, NAME)
Definition ELF.h:665
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_ABI
Definition Compiler.h:211
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
static std::string getRegisterName(const TargetRegisterInfo *TRI, Register Reg)
Register Reg
Promote Memory to Register
Definition Mem2Reg.cpp:110
ModuleAnalysisManager MAM
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
MachineRegisterInfo & MRI
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:480
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.
Definition AsmPrinter.h:95
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.
Definition AsmPrinter.h:478
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.
Definition MCExpr.h:298
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:342
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition MCExpr.h:427
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
Context object for machine code objects.
Definition MCContext.h:83
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
void addOperand(const MCOperand Op)
Definition MCInst.h:215
void setOpcode(unsigned Op)
Definition MCInst.h:201
Instances of this class represent operands of the MCInst class.
Definition MCInst.h:40
static MCOperand createExpr(const MCExpr *Val)
Definition MCInst.h:166
static MCOperand createReg(MCRegister Reg)
Definition MCInst.h:138
static MCOperand createImm(int64_t Val)
Definition MCInst.h:145
bool isValid() const
Definition MCInst.h:64
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.cpp:743
Streaming machine code generation interface.
Definition MCStreamer.h:222
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.
Definition MCExpr.h:190
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:213
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
LLVM_ABI void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition MCSymbol.cpp:59
LLVM_ABI MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
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
int64_t getImm() 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.
LLVM_ABI void printAsOperand(raw_ostream &OS, const Module *M=nullptr) const
Print as operand.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
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.
Definition StringRef.h:56
Primary interface to the complete machine description for the target machine.
bool isSPARC64() const
Tests whether the target is 64-bit SPARC (big endian).
Definition Triple.h:1189
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#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.
@ Add
Sum of integers.
LLVM_ABI void setupMachineFunctionAsmPrinter(MachineFunctionAnalysisManager &MFAM, MachineFunction &MF, AsmPrinter &AsmPrinter)
Target & getTheSparcelTarget()
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
ArrayRef< int > lo(ArrayRef< int > Vuu)
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...