LLVM 19.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
18#include "Sparc.h"
19#include "SparcInstrInfo.h"
20#include "SparcTargetMachine.h"
27#include "llvm/IR/Mangler.h"
28#include "llvm/MC/MCAsmInfo.h"
29#include "llvm/MC/MCContext.h"
30#include "llvm/MC/MCInst.h"
31#include "llvm/MC/MCStreamer.h"
32#include "llvm/MC/MCSymbol.h"
35using namespace llvm;
36
37#define DEBUG_TYPE "asm-printer"
38
39namespace {
40 class SparcAsmPrinter : public AsmPrinter {
41 SparcTargetStreamer &getTargetStreamer() {
42 return static_cast<SparcTargetStreamer &>(
43 *OutStreamer->getTargetStreamer());
44 }
45 public:
46 explicit SparcAsmPrinter(TargetMachine &TM,
47 std::unique_ptr<MCStreamer> Streamer)
48 : AsmPrinter(TM, std::move(Streamer)) {}
49
50 StringRef getPassName() const override { return "Sparc Assembly Printer"; }
51
52 void printOperand(const MachineInstr *MI, int opNum, raw_ostream &OS);
53 void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &OS,
54 const char *Modifier = nullptr);
55
56 void emitFunctionBodyStart() override;
57 void emitInstruction(const MachineInstr *MI) override;
58
59 static const char *getRegisterName(MCRegister Reg) {
61 }
62
63 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
64 const char *ExtraCode, raw_ostream &O) override;
65 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
66 const char *ExtraCode, raw_ostream &O) override;
67
68 void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI,
69 const MCSubtargetInfo &STI);
70
71 };
72} // end of anonymous namespace
73
75 MCSymbol *Sym, MCContext &OutContext) {
77 OutContext);
78 const SparcMCExpr *expr = SparcMCExpr::create(Kind, MCSym, OutContext);
79 return MCOperand::createExpr(expr);
80
81}
83 MCContext &OutContext) {
84 return createSparcMCOperand(SparcMCExpr::VK_Sparc_WDISP30, Label, OutContext);
85}
86
88 MCSymbol *GOTLabel, MCSymbol *StartLabel,
89 MCSymbol *CurLabel,
90 MCContext &OutContext)
91{
92 const MCSymbolRefExpr *GOT = MCSymbolRefExpr::create(GOTLabel, OutContext);
93 const MCSymbolRefExpr *Start = MCSymbolRefExpr::create(StartLabel,
94 OutContext);
95 const MCSymbolRefExpr *Cur = MCSymbolRefExpr::create(CurLabel,
96 OutContext);
97
98 const MCBinaryExpr *Sub = MCBinaryExpr::createSub(Cur, Start, OutContext);
99 const MCBinaryExpr *Add = MCBinaryExpr::createAdd(GOT, Sub, OutContext);
100 const SparcMCExpr *expr = SparcMCExpr::create(Kind,
101 Add, OutContext);
102 return MCOperand::createExpr(expr);
103}
104
105static void EmitCall(MCStreamer &OutStreamer,
106 MCOperand &Callee,
107 const MCSubtargetInfo &STI)
108{
110 CallInst.setOpcode(SP::CALL);
111 CallInst.addOperand(Callee);
112 OutStreamer.emitInstruction(CallInst, STI);
113}
114
115static void EmitRDPC(MCStreamer &OutStreamer, MCOperand &RD,
116 const MCSubtargetInfo &STI) {
117 MCInst RDPCInst;
118 RDPCInst.setOpcode(SP::RDASR);
119 RDPCInst.addOperand(RD);
120 RDPCInst.addOperand(MCOperand::createReg(SP::ASR5));
121 OutStreamer.emitInstruction(RDPCInst, STI);
122}
123
124static void EmitSETHI(MCStreamer &OutStreamer,
125 MCOperand &Imm, MCOperand &RD,
126 const MCSubtargetInfo &STI)
127{
128 MCInst SETHIInst;
129 SETHIInst.setOpcode(SP::SETHIi);
130 SETHIInst.addOperand(RD);
131 SETHIInst.addOperand(Imm);
132 OutStreamer.emitInstruction(SETHIInst, STI);
133}
134
135static void EmitBinary(MCStreamer &OutStreamer, unsigned Opcode,
136 MCOperand &RS1, MCOperand &Src2, MCOperand &RD,
137 const MCSubtargetInfo &STI)
138{
139 MCInst Inst;
140 Inst.setOpcode(Opcode);
141 Inst.addOperand(RD);
142 Inst.addOperand(RS1);
143 Inst.addOperand(Src2);
144 OutStreamer.emitInstruction(Inst, STI);
145}
146
147static void EmitOR(MCStreamer &OutStreamer,
148 MCOperand &RS1, MCOperand &Imm, MCOperand &RD,
149 const MCSubtargetInfo &STI) {
150 EmitBinary(OutStreamer, SP::ORri, RS1, Imm, RD, STI);
151}
152
153static void EmitADD(MCStreamer &OutStreamer,
154 MCOperand &RS1, MCOperand &RS2, MCOperand &RD,
155 const MCSubtargetInfo &STI) {
156 EmitBinary(OutStreamer, SP::ADDrr, RS1, RS2, RD, STI);
157}
158
159static void EmitSHL(MCStreamer &OutStreamer,
160 MCOperand &RS1, MCOperand &Imm, MCOperand &RD,
161 const MCSubtargetInfo &STI) {
162 EmitBinary(OutStreamer, SP::SLLri, RS1, Imm, RD, STI);
163}
164
165
166static void EmitHiLo(MCStreamer &OutStreamer, MCSymbol *GOTSym,
169 MCOperand &RD,
170 MCContext &OutContext,
171 const MCSubtargetInfo &STI) {
172
173 MCOperand hi = createSparcMCOperand(HiKind, GOTSym, OutContext);
174 MCOperand lo = createSparcMCOperand(LoKind, GOTSym, OutContext);
175 EmitSETHI(OutStreamer, hi, RD, STI);
176 EmitOR(OutStreamer, RD, lo, RD, STI);
177}
178
179void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI,
180 const MCSubtargetInfo &STI)
181{
182 MCSymbol *GOTLabel =
183 OutContext.getOrCreateSymbol(Twine("_GLOBAL_OFFSET_TABLE_"));
184
185 const MachineOperand &MO = MI->getOperand(0);
186 assert(MO.getReg() != SP::O7 &&
187 "%o7 is assigned as destination for getpcx!");
188
189 MCOperand MCRegOP = MCOperand::createReg(MO.getReg());
190
191
192 if (!isPositionIndependent()) {
193 // Just load the address of GOT to MCRegOP.
194 switch(TM.getCodeModel()) {
195 default:
196 llvm_unreachable("Unsupported absolute code model");
197 case CodeModel::Small:
198 EmitHiLo(*OutStreamer, GOTLabel,
200 MCRegOP, OutContext, STI);
201 break;
202 case CodeModel::Medium: {
203 EmitHiLo(*OutStreamer, GOTLabel,
205 MCRegOP, OutContext, STI);
207 OutContext));
208 EmitSHL(*OutStreamer, MCRegOP, imm, MCRegOP, STI);
210 GOTLabel, OutContext);
211 EmitOR(*OutStreamer, MCRegOP, lo, MCRegOP, STI);
212 break;
213 }
214 case CodeModel::Large: {
215 EmitHiLo(*OutStreamer, GOTLabel,
217 MCRegOP, OutContext, STI);
219 OutContext));
220 EmitSHL(*OutStreamer, MCRegOP, imm, MCRegOP, STI);
221 // Use register %o7 to load the lower 32 bits.
222 MCOperand RegO7 = MCOperand::createReg(SP::O7);
223 EmitHiLo(*OutStreamer, GOTLabel,
225 RegO7, OutContext, STI);
226 EmitADD(*OutStreamer, MCRegOP, RegO7, MCRegOP, STI);
227 }
228 }
229 return;
230 }
231
232 MCSymbol *StartLabel = OutContext.createTempSymbol();
233 MCSymbol *EndLabel = OutContext.createTempSymbol();
234 MCSymbol *SethiLabel = OutContext.createTempSymbol();
235
236 MCOperand RegO7 = MCOperand::createReg(SP::O7);
237
238 // <StartLabel>:
239 // <GET-PC> // This will be either `call <EndLabel>` or `rd %pc, %o7`.
240 // <SethiLabel>:
241 // sethi %hi(_GLOBAL_OFFSET_TABLE_+(<SethiLabel>-<StartLabel>)), <MO>
242 // <EndLabel>:
243 // or <MO>, %lo(_GLOBAL_OFFSET_TABLE_+(<EndLabel>-<StartLabel>))), <MO>
244 // add <MO>, %o7, <MO>
245
246 OutStreamer->emitLabel(StartLabel);
247 if (!STI.getTargetTriple().isSPARC64() ||
248 STI.hasFeature(Sparc::TuneSlowRDPC)) {
249 MCOperand Callee = createPCXCallOP(EndLabel, OutContext);
250 EmitCall(*OutStreamer, Callee, STI);
251 } else {
252 // TODO find out whether it is possible to store PC
253 // in other registers, to enable leaf function optimization.
254 // (On the other hand, approx. over 97.8% of GETPCXes happen
255 // in non-leaf functions, so would this be worth the effort?)
256 EmitRDPC(*OutStreamer, RegO7, STI);
257 }
258 OutStreamer->emitLabel(SethiLabel);
260 GOTLabel, StartLabel, SethiLabel,
261 OutContext);
262 EmitSETHI(*OutStreamer, hiImm, MCRegOP, STI);
263 OutStreamer->emitLabel(EndLabel);
265 GOTLabel, StartLabel, EndLabel,
266 OutContext);
267 EmitOR(*OutStreamer, MCRegOP, loImm, MCRegOP, STI);
268 EmitADD(*OutStreamer, MCRegOP, RegO7, MCRegOP, STI);
269}
270
271void SparcAsmPrinter::emitInstruction(const MachineInstr *MI) {
272 Sparc_MC::verifyInstructionPredicates(MI->getOpcode(),
273 getSubtargetInfo().getFeatureBits());
274
275 switch (MI->getOpcode()) {
276 default: break;
277 case TargetOpcode::DBG_VALUE:
278 // FIXME: Debug Value.
279 return;
280 case SP::GETPCX:
281 LowerGETPCXAndEmitMCInsts(MI, getSubtargetInfo());
282 return;
283 }
285 MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();
286 do {
287 MCInst TmpInst;
288 LowerSparcMachineInstrToMCInst(&*I, TmpInst, *this);
289 EmitToStreamer(*OutStreamer, TmpInst);
290 } while ((++I != E) && I->isInsideBundle()); // Delay slot check.
291}
292
293void SparcAsmPrinter::emitFunctionBodyStart() {
294 if (!MF->getSubtarget<SparcSubtarget>().is64Bit())
295 return;
296
297 const MachineRegisterInfo &MRI = MF->getRegInfo();
298 const unsigned globalRegs[] = { SP::G2, SP::G3, SP::G6, SP::G7, 0 };
299 for (unsigned i = 0; globalRegs[i] != 0; ++i) {
300 unsigned reg = globalRegs[i];
301 if (MRI.use_empty(reg))
302 continue;
303
304 if (reg == SP::G6 || reg == SP::G7)
305 getTargetStreamer().emitSparcRegisterIgnore(reg);
306 else
307 getTargetStreamer().emitSparcRegisterScratch(reg);
308 }
309}
310
311void SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
312 raw_ostream &O) {
313 const DataLayout &DL = getDataLayout();
314 const MachineOperand &MO = MI->getOperand (opNum);
316
317#ifndef NDEBUG
318 // Verify the target flags.
319 if (MO.isGlobal() || MO.isSymbol() || MO.isCPI()) {
320 if (MI->getOpcode() == SP::CALL)
322 "Cannot handle target flags on call address");
323 else if (MI->getOpcode() == SP::SETHIi)
333 "Invalid target flags for address operand on sethi");
334 else if (MI->getOpcode() == SP::TLS_CALL)
338 "Cannot handle target flags on tls call address");
339 else if (MI->getOpcode() == SP::TLS_ADDrr)
344 "Cannot handle target flags on add for TLS");
345 else if (MI->getOpcode() == SP::TLS_LDrr)
347 "Cannot handle target flags on ld for TLS");
348 else if (MI->getOpcode() == SP::TLS_LDXrr)
350 "Cannot handle target flags on ldx for TLS");
351 else if (MI->getOpcode() == SP::XORri)
354 "Cannot handle target flags on xor for TLS");
355 else
363 "Invalid target flags for small address operand");
364 }
365#endif
366
367
368 bool CloseParen = SparcMCExpr::printVariantKind(O, TF);
369
370 switch (MO.getType()) {
372 O << "%" << StringRef(getRegisterName(MO.getReg())).lower();
373 break;
374
376 O << MO.getImm();
377 break;
379 MO.getMBB()->getSymbol()->print(O, MAI);
380 return;
382 PrintSymbolOperand(MO, O);
383 break;
385 O << GetBlockAddressSymbol(MO.getBlockAddress())->getName();
386 break;
388 O << MO.getSymbolName();
389 break;
391 O << DL.getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_"
392 << MO.getIndex();
393 break;
395 MO.getMetadata()->printAsOperand(O, MMI->getModule());
396 break;
397 default:
398 llvm_unreachable("<unknown operand type>");
399 }
400 if (CloseParen) O << ")";
401}
402
403void SparcAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum,
404 raw_ostream &O, const char *Modifier) {
405 printOperand(MI, opNum, O);
406
407 // If this is an ADD operand, emit it like normal operands.
408 if (Modifier && !strcmp(Modifier, "arith")) {
409 O << ", ";
410 printOperand(MI, opNum+1, O);
411 return;
412 }
413
414 if (MI->getOperand(opNum+1).isReg() &&
415 MI->getOperand(opNum+1).getReg() == SP::G0)
416 return; // don't print "+%g0"
417 if (MI->getOperand(opNum+1).isImm() &&
418 MI->getOperand(opNum+1).getImm() == 0)
419 return; // don't print "+0"
420
421 O << "+";
422 printOperand(MI, opNum+1, O);
423}
424
425/// PrintAsmOperand - Print out an operand for an inline asm expression.
426///
427bool SparcAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
428 const char *ExtraCode,
429 raw_ostream &O) {
430 if (ExtraCode && ExtraCode[0]) {
431 if (ExtraCode[1] != 0) return true; // Unknown modifier.
432
433 switch (ExtraCode[0]) {
434 default:
435 // See if this is a generic print operand
436 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
437 case 'f':
438 case 'r':
439 break;
440 }
441 }
442
443 printOperand(MI, OpNo, O);
444
445 return false;
446}
447
448bool SparcAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
449 unsigned OpNo,
450 const char *ExtraCode,
451 raw_ostream &O) {
452 if (ExtraCode && ExtraCode[0])
453 return true; // Unknown modifier
454
455 O << '[';
456 printMemOperand(MI, OpNo, O);
457 O << ']';
458
459 return false;
460}
461
462// Force static initialization.
467}
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:135
Symbol * Sym
Definition: ELF_riscv.cpp:479
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
static std::string getRegisterName(const TargetRegisterInfo *TRI, Register Reg)
Definition: MIParser.cpp:1414
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const char LLVMTargetMachineRef TM
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
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.
Definition: AsmPrinter.h:84
virtual void emitInstruction(const MachineInstr *)
Targets should implement this to emit instructions.
Definition: AsmPrinter.h:567
virtual void emitFunctionBodyStart()
Targets can override this to emit stuff before the first basic block in the function.
Definition: AsmPrinter.h:551
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.
Definition: DataLayout.h:110
Binary assembler expressions.
Definition: MCExpr.h:492
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:536
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:621
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:194
Context object for machine code objects.
Definition: MCContext.h:76
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
void addOperand(const MCOperand Op)
Definition: MCInst.h:210
void setOpcode(unsigned Op)
Definition: MCInst.h:197
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:134
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:162
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
Streaming machine code generation interface.
Definition: MCStreamer.h:212
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:192
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:397
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:40
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition: MCSymbol.cpp:58
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
Instructions::const_iterator const_instr_iterator
Representation of each machine instruction.
Definition: MachineInstr.h:69
MachineOperand class - Representation of each machine instruction operand.
int64_t getImm() const
const MDNode * getMetadata() const
MachineBasicBlock * getMBB() const
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
const BlockAddress * getBlockAddress() const
unsigned getTargetFlags() const
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
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,...
void printAsOperand(raw_ostream &OS, const Module *M=nullptr) const
Print as operand.
Definition: AsmWriter.cpp:5149
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:81
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=SP::NoRegAltName)
static const SparcMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
Definition: SparcMCExpr.cpp:27
static bool printVariantKind(raw_ostream &OS, VariantKind Kind)
Definition: SparcMCExpr.cpp:43
bool is64Bit() const
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::string lower() const
Definition: StringRef.cpp:111
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:76
bool isSPARC64() const
Tests whether the target is 64-bit SPARC (big endian).
Definition: Triple.h:984
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Target & getTheSparcTarget()
Target & getTheSparcV9Target()
void LowerSparcMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, AsmPrinter &AP)
@ Add
Sum of integers.
Target & getTheSparcelTarget()
ArrayRef< int > lo(ArrayRef< int > Vuu)
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...