/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- SparcAsmPrinter.cpp - Sparc LLVM assembly writer ------------------===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This file contains a printer that converts from our internal representation |
11 | | // of machine-dependent LLVM code to GAS-format SPARC assembly language. |
12 | | // |
13 | | //===----------------------------------------------------------------------===// |
14 | | |
15 | | #include "InstPrinter/SparcInstPrinter.h" |
16 | | #include "MCTargetDesc/SparcMCExpr.h" |
17 | | #include "Sparc.h" |
18 | | #include "SparcInstrInfo.h" |
19 | | #include "SparcTargetMachine.h" |
20 | | #include "SparcTargetStreamer.h" |
21 | | #include "llvm/CodeGen/AsmPrinter.h" |
22 | | #include "llvm/CodeGen/MachineInstr.h" |
23 | | #include "llvm/CodeGen/MachineModuleInfoImpls.h" |
24 | | #include "llvm/CodeGen/MachineRegisterInfo.h" |
25 | | #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" |
26 | | #include "llvm/IR/Mangler.h" |
27 | | #include "llvm/MC/MCAsmInfo.h" |
28 | | #include "llvm/MC/MCContext.h" |
29 | | #include "llvm/MC/MCInst.h" |
30 | | #include "llvm/MC/MCStreamer.h" |
31 | | #include "llvm/MC/MCSymbol.h" |
32 | | #include "llvm/Support/TargetRegistry.h" |
33 | | #include "llvm/Support/raw_ostream.h" |
34 | | using namespace llvm; |
35 | | |
36 | | #define DEBUG_TYPE "asm-printer" |
37 | | |
38 | | namespace { |
39 | | class SparcAsmPrinter : public AsmPrinter { |
40 | 32 | SparcTargetStreamer &getTargetStreamer() { |
41 | 32 | return static_cast<SparcTargetStreamer &>( |
42 | 32 | *OutStreamer->getTargetStreamer()); |
43 | 32 | } |
44 | | public: |
45 | | explicit SparcAsmPrinter(TargetMachine &TM, |
46 | | std::unique_ptr<MCStreamer> Streamer) |
47 | 175 | : AsmPrinter(TM, std::move(Streamer)) {} |
48 | | |
49 | 0 | StringRef getPassName() const override { return "Sparc Assembly Printer"; } |
50 | | |
51 | | void printOperand(const MachineInstr *MI, int opNum, raw_ostream &OS); |
52 | | void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &OS, |
53 | | const char *Modifier = nullptr); |
54 | | |
55 | | void EmitFunctionBodyStart() override; |
56 | | void EmitInstruction(const MachineInstr *MI) override; |
57 | | |
58 | 136 | static const char *getRegisterName(unsigned RegNo) { |
59 | 136 | return SparcInstPrinter::getRegisterName(RegNo); |
60 | 136 | } |
61 | | |
62 | | bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, |
63 | | unsigned AsmVariant, const char *ExtraCode, |
64 | | raw_ostream &O) override; |
65 | | bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, |
66 | | unsigned AsmVariant, const char *ExtraCode, |
67 | | raw_ostream &O) override; |
68 | | |
69 | | void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI, |
70 | | const MCSubtargetInfo &STI); |
71 | | |
72 | | }; |
73 | | } // end of anonymous namespace |
74 | | |
75 | | static MCOperand createSparcMCOperand(SparcMCExpr::VariantKind Kind, |
76 | 37 | MCSymbol *Sym, MCContext &OutContext) { |
77 | 37 | const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Sym, |
78 | 37 | OutContext); |
79 | 37 | const SparcMCExpr *expr = SparcMCExpr::create(Kind, MCSym, OutContext); |
80 | 37 | return MCOperand::createExpr(expr); |
81 | 37 | |
82 | 37 | } |
83 | | static MCOperand createPCXCallOP(MCSymbol *Label, |
84 | 27 | MCContext &OutContext) { |
85 | 27 | return createSparcMCOperand(SparcMCExpr::VK_Sparc_None, Label, OutContext); |
86 | 27 | } |
87 | | |
88 | | static MCOperand createPCXRelExprOp(SparcMCExpr::VariantKind Kind, |
89 | | MCSymbol *GOTLabel, MCSymbol *StartLabel, |
90 | | MCSymbol *CurLabel, |
91 | | MCContext &OutContext) |
92 | 54 | { |
93 | 54 | const MCSymbolRefExpr *GOT = MCSymbolRefExpr::create(GOTLabel, OutContext); |
94 | 54 | const MCSymbolRefExpr *Start = MCSymbolRefExpr::create(StartLabel, |
95 | 54 | OutContext); |
96 | 54 | const MCSymbolRefExpr *Cur = MCSymbolRefExpr::create(CurLabel, |
97 | 54 | OutContext); |
98 | 54 | |
99 | 54 | const MCBinaryExpr *Sub = MCBinaryExpr::createSub(Cur, Start, OutContext); |
100 | 54 | const MCBinaryExpr *Add = MCBinaryExpr::createAdd(GOT, Sub, OutContext); |
101 | 54 | const SparcMCExpr *expr = SparcMCExpr::create(Kind, |
102 | 54 | Add, OutContext); |
103 | 54 | return MCOperand::createExpr(expr); |
104 | 54 | } |
105 | | |
106 | | static void EmitCall(MCStreamer &OutStreamer, |
107 | | MCOperand &Callee, |
108 | | const MCSubtargetInfo &STI) |
109 | 27 | { |
110 | 27 | MCInst CallInst; |
111 | 27 | CallInst.setOpcode(SP::CALL); |
112 | 27 | CallInst.addOperand(Callee); |
113 | 27 | OutStreamer.EmitInstruction(CallInst, STI); |
114 | 27 | } |
115 | | |
116 | | static void EmitSETHI(MCStreamer &OutStreamer, |
117 | | MCOperand &Imm, MCOperand &RD, |
118 | | const MCSubtargetInfo &STI) |
119 | 31 | { |
120 | 31 | MCInst SETHIInst; |
121 | 31 | SETHIInst.setOpcode(SP::SETHIi); |
122 | 31 | SETHIInst.addOperand(RD); |
123 | 31 | SETHIInst.addOperand(Imm); |
124 | 31 | OutStreamer.EmitInstruction(SETHIInst, STI); |
125 | 31 | } |
126 | | |
127 | | static void EmitBinary(MCStreamer &OutStreamer, unsigned Opcode, |
128 | | MCOperand &RS1, MCOperand &Src2, MCOperand &RD, |
129 | | const MCSubtargetInfo &STI) |
130 | 62 | { |
131 | 62 | MCInst Inst; |
132 | 62 | Inst.setOpcode(Opcode); |
133 | 62 | Inst.addOperand(RD); |
134 | 62 | Inst.addOperand(RS1); |
135 | 62 | Inst.addOperand(Src2); |
136 | 62 | OutStreamer.EmitInstruction(Inst, STI); |
137 | 62 | } |
138 | | |
139 | | static void EmitOR(MCStreamer &OutStreamer, |
140 | | MCOperand &RS1, MCOperand &Imm, MCOperand &RD, |
141 | 33 | const MCSubtargetInfo &STI) { |
142 | 33 | EmitBinary(OutStreamer, SP::ORri, RS1, Imm, RD, STI); |
143 | 33 | } |
144 | | |
145 | | static void EmitADD(MCStreamer &OutStreamer, |
146 | | MCOperand &RS1, MCOperand &RS2, MCOperand &RD, |
147 | 27 | const MCSubtargetInfo &STI) { |
148 | 27 | EmitBinary(OutStreamer, SP::ADDrr, RS1, RS2, RD, STI); |
149 | 27 | } |
150 | | |
151 | | static void EmitSHL(MCStreamer &OutStreamer, |
152 | | MCOperand &RS1, MCOperand &Imm, MCOperand &RD, |
153 | 2 | const MCSubtargetInfo &STI) { |
154 | 2 | EmitBinary(OutStreamer, SP::SLLri, RS1, Imm, RD, STI); |
155 | 2 | } |
156 | | |
157 | | |
158 | | static void EmitHiLo(MCStreamer &OutStreamer, MCSymbol *GOTSym, |
159 | | SparcMCExpr::VariantKind HiKind, |
160 | | SparcMCExpr::VariantKind LoKind, |
161 | | MCOperand &RD, |
162 | | MCContext &OutContext, |
163 | 4 | const MCSubtargetInfo &STI) { |
164 | 4 | |
165 | 4 | MCOperand hi = createSparcMCOperand(HiKind, GOTSym, OutContext); |
166 | 4 | MCOperand lo = createSparcMCOperand(LoKind, GOTSym, OutContext); |
167 | 4 | EmitSETHI(OutStreamer, hi, RD, STI); |
168 | 4 | EmitOR(OutStreamer, RD, lo, RD, STI); |
169 | 4 | } |
170 | | |
171 | | void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI, |
172 | | const MCSubtargetInfo &STI) |
173 | 31 | { |
174 | 31 | MCSymbol *GOTLabel = |
175 | 31 | OutContext.getOrCreateSymbol(Twine("_GLOBAL_OFFSET_TABLE_")); |
176 | 31 | |
177 | 31 | const MachineOperand &MO = MI->getOperand(0); |
178 | 31 | assert(MO.getReg() != SP::O7 && |
179 | 31 | "%o7 is assigned as destination for getpcx!"); |
180 | 31 | |
181 | 31 | MCOperand MCRegOP = MCOperand::createReg(MO.getReg()); |
182 | 31 | |
183 | 31 | |
184 | 31 | if (!isPositionIndependent()31 ) { |
185 | 4 | // Just load the address of GOT to MCRegOP. |
186 | 4 | switch(TM.getCodeModel()) { |
187 | 0 | default: |
188 | 0 | llvm_unreachable("Unsupported absolute code model"); |
189 | 2 | case CodeModel::Small: |
190 | 2 | EmitHiLo(*OutStreamer, GOTLabel, |
191 | 2 | SparcMCExpr::VK_Sparc_HI, SparcMCExpr::VK_Sparc_LO, |
192 | 2 | MCRegOP, OutContext, STI); |
193 | 2 | break; |
194 | 2 | case CodeModel::Medium: { |
195 | 2 | EmitHiLo(*OutStreamer, GOTLabel, |
196 | 2 | SparcMCExpr::VK_Sparc_H44, SparcMCExpr::VK_Sparc_M44, |
197 | 2 | MCRegOP, OutContext, STI); |
198 | 2 | MCOperand imm = MCOperand::createExpr(MCConstantExpr::create(12, |
199 | 2 | OutContext)); |
200 | 2 | EmitSHL(*OutStreamer, MCRegOP, imm, MCRegOP, STI); |
201 | 2 | MCOperand lo = createSparcMCOperand(SparcMCExpr::VK_Sparc_L44, |
202 | 2 | GOTLabel, OutContext); |
203 | 2 | EmitOR(*OutStreamer, MCRegOP, lo, MCRegOP, STI); |
204 | 2 | break; |
205 | 4 | } |
206 | 0 | case CodeModel::Large: { |
207 | 0 | EmitHiLo(*OutStreamer, GOTLabel, |
208 | 0 | SparcMCExpr::VK_Sparc_HH, SparcMCExpr::VK_Sparc_HM, |
209 | 0 | MCRegOP, OutContext, STI); |
210 | 0 | MCOperand imm = MCOperand::createExpr(MCConstantExpr::create(32, |
211 | 0 | OutContext)); |
212 | 0 | EmitSHL(*OutStreamer, MCRegOP, imm, MCRegOP, STI); |
213 | 0 | // Use register %o7 to load the lower 32 bits. |
214 | 0 | MCOperand RegO7 = MCOperand::createReg(SP::O7); |
215 | 0 | EmitHiLo(*OutStreamer, GOTLabel, |
216 | 0 | SparcMCExpr::VK_Sparc_HI, SparcMCExpr::VK_Sparc_LO, |
217 | 0 | RegO7, OutContext, STI); |
218 | 0 | EmitADD(*OutStreamer, MCRegOP, RegO7, MCRegOP, STI); |
219 | 0 | } |
220 | 4 | } |
221 | 4 | return; |
222 | 27 | } |
223 | 27 | |
224 | 27 | MCSymbol *StartLabel = OutContext.createTempSymbol(); |
225 | 27 | MCSymbol *EndLabel = OutContext.createTempSymbol(); |
226 | 27 | MCSymbol *SethiLabel = OutContext.createTempSymbol(); |
227 | 27 | |
228 | 27 | MCOperand RegO7 = MCOperand::createReg(SP::O7); |
229 | 27 | |
230 | 27 | // <StartLabel>: |
231 | 27 | // call <EndLabel> |
232 | 27 | // <SethiLabel>: |
233 | 27 | // sethi %hi(_GLOBAL_OFFSET_TABLE_+(<SethiLabel>-<StartLabel>)), <MO> |
234 | 27 | // <EndLabel>: |
235 | 27 | // or <MO>, %lo(_GLOBAL_OFFSET_TABLE_+(<EndLabel>-<StartLabel>))), <MO> |
236 | 27 | // add <MO>, %o7, <MO> |
237 | 27 | |
238 | 27 | OutStreamer->EmitLabel(StartLabel); |
239 | 27 | MCOperand Callee = createPCXCallOP(EndLabel, OutContext); |
240 | 27 | EmitCall(*OutStreamer, Callee, STI); |
241 | 27 | OutStreamer->EmitLabel(SethiLabel); |
242 | 27 | MCOperand hiImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_PC22, |
243 | 27 | GOTLabel, StartLabel, SethiLabel, |
244 | 27 | OutContext); |
245 | 27 | EmitSETHI(*OutStreamer, hiImm, MCRegOP, STI); |
246 | 27 | OutStreamer->EmitLabel(EndLabel); |
247 | 27 | MCOperand loImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_PC10, |
248 | 27 | GOTLabel, StartLabel, EndLabel, |
249 | 27 | OutContext); |
250 | 27 | EmitOR(*OutStreamer, MCRegOP, loImm, MCRegOP, STI); |
251 | 27 | EmitADD(*OutStreamer, MCRegOP, RegO7, MCRegOP, STI); |
252 | 27 | } |
253 | | |
254 | | void SparcAsmPrinter::EmitInstruction(const MachineInstr *MI) |
255 | 7.31k | { |
256 | 7.31k | |
257 | 7.31k | switch (MI->getOpcode()) { |
258 | 7.28k | default: break; |
259 | 0 | case TargetOpcode::DBG_VALUE: |
260 | 0 | // FIXME: Debug Value. |
261 | 0 | return; |
262 | 31 | case SP::GETPCX: |
263 | 31 | LowerGETPCXAndEmitMCInsts(MI, getSubtargetInfo()); |
264 | 31 | return; |
265 | 7.28k | } |
266 | 7.28k | MachineBasicBlock::const_instr_iterator I = MI->getIterator(); |
267 | 7.28k | MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end(); |
268 | 8.51k | do { |
269 | 8.51k | MCInst TmpInst; |
270 | 8.51k | LowerSparcMachineInstrToMCInst(&*I, TmpInst, *this); |
271 | 8.51k | EmitToStreamer(*OutStreamer, TmpInst); |
272 | 8.51k | } while ((++I != E) && 8.51k I->isInsideBundle()7.60k ); // Delay slot check. |
273 | 7.31k | } |
274 | | |
275 | 642 | void SparcAsmPrinter::EmitFunctionBodyStart() { |
276 | 642 | if (!MF->getSubtarget<SparcSubtarget>().is64Bit()) |
277 | 400 | return; |
278 | 242 | |
279 | 242 | const MachineRegisterInfo &MRI = MF->getRegInfo(); |
280 | 242 | const unsigned globalRegs[] = { SP::G2, SP::G3, SP::G6, SP::G7, 0 }; |
281 | 1.21k | for (unsigned i = 0; globalRegs[i] != 01.21k ; ++i968 ) { |
282 | 968 | unsigned reg = globalRegs[i]; |
283 | 968 | if (MRI.use_empty(reg)) |
284 | 936 | continue; |
285 | 32 | |
286 | 32 | if (32 reg == SP::G6 || 32 reg == SP::G732 ) |
287 | 6 | getTargetStreamer().emitSparcRegisterIgnore(reg); |
288 | 32 | else |
289 | 26 | getTargetStreamer().emitSparcRegisterScratch(reg); |
290 | 968 | } |
291 | 642 | } |
292 | | |
293 | | void SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum, |
294 | 161 | raw_ostream &O) { |
295 | 161 | const DataLayout &DL = getDataLayout(); |
296 | 161 | const MachineOperand &MO = MI->getOperand (opNum); |
297 | 161 | SparcMCExpr::VariantKind TF = (SparcMCExpr::VariantKind) MO.getTargetFlags(); |
298 | 161 | |
299 | | #ifndef NDEBUG |
300 | | // Verify the target flags. |
301 | | if (MO.isGlobal() || MO.isSymbol() || MO.isCPI()) { |
302 | | if (MI->getOpcode() == SP::CALL) |
303 | | assert(TF == SparcMCExpr::VK_Sparc_None && |
304 | | "Cannot handle target flags on call address"); |
305 | | else if (MI->getOpcode() == SP::SETHIi || MI->getOpcode() == SP::SETHIXi) |
306 | | assert((TF == SparcMCExpr::VK_Sparc_HI |
307 | | || TF == SparcMCExpr::VK_Sparc_H44 |
308 | | || TF == SparcMCExpr::VK_Sparc_HH |
309 | | || TF == SparcMCExpr::VK_Sparc_TLS_GD_HI22 |
310 | | || TF == SparcMCExpr::VK_Sparc_TLS_LDM_HI22 |
311 | | || TF == SparcMCExpr::VK_Sparc_TLS_LDO_HIX22 |
312 | | || TF == SparcMCExpr::VK_Sparc_TLS_IE_HI22 |
313 | | || TF == SparcMCExpr::VK_Sparc_TLS_LE_HIX22) && |
314 | | "Invalid target flags for address operand on sethi"); |
315 | | else if (MI->getOpcode() == SP::TLS_CALL) |
316 | | assert((TF == SparcMCExpr::VK_Sparc_None |
317 | | || TF == SparcMCExpr::VK_Sparc_TLS_GD_CALL |
318 | | || TF == SparcMCExpr::VK_Sparc_TLS_LDM_CALL) && |
319 | | "Cannot handle target flags on tls call address"); |
320 | | else if (MI->getOpcode() == SP::TLS_ADDrr) |
321 | | assert((TF == SparcMCExpr::VK_Sparc_TLS_GD_ADD |
322 | | || TF == SparcMCExpr::VK_Sparc_TLS_LDM_ADD |
323 | | || TF == SparcMCExpr::VK_Sparc_TLS_LDO_ADD |
324 | | || TF == SparcMCExpr::VK_Sparc_TLS_IE_ADD) && |
325 | | "Cannot handle target flags on add for TLS"); |
326 | | else if (MI->getOpcode() == SP::TLS_LDrr) |
327 | | assert(TF == SparcMCExpr::VK_Sparc_TLS_IE_LD && |
328 | | "Cannot handle target flags on ld for TLS"); |
329 | | else if (MI->getOpcode() == SP::TLS_LDXrr) |
330 | | assert(TF == SparcMCExpr::VK_Sparc_TLS_IE_LDX && |
331 | | "Cannot handle target flags on ldx for TLS"); |
332 | | else if (MI->getOpcode() == SP::XORri || MI->getOpcode() == SP::XORXri) |
333 | | assert((TF == SparcMCExpr::VK_Sparc_TLS_LDO_LOX10 |
334 | | || TF == SparcMCExpr::VK_Sparc_TLS_LE_LOX10) && |
335 | | "Cannot handle target flags on xor for TLS"); |
336 | | else |
337 | | assert((TF == SparcMCExpr::VK_Sparc_LO |
338 | | || TF == SparcMCExpr::VK_Sparc_M44 |
339 | | || TF == SparcMCExpr::VK_Sparc_L44 |
340 | | || TF == SparcMCExpr::VK_Sparc_HM |
341 | | || TF == SparcMCExpr::VK_Sparc_TLS_GD_LO10 |
342 | | || TF == SparcMCExpr::VK_Sparc_TLS_LDM_LO10 |
343 | | || TF == SparcMCExpr::VK_Sparc_TLS_IE_LO10 ) && |
344 | | "Invalid target flags for small address operand"); |
345 | | } |
346 | | #endif |
347 | | |
348 | 161 | |
349 | 161 | bool CloseParen = SparcMCExpr::printVariantKind(O, TF); |
350 | 161 | |
351 | 161 | switch (MO.getType()) { |
352 | 136 | case MachineOperand::MO_Register: |
353 | 136 | O << "%" << StringRef(getRegisterName(MO.getReg())).lower(); |
354 | 136 | break; |
355 | 161 | |
356 | 22 | case MachineOperand::MO_Immediate: |
357 | 22 | O << (int)MO.getImm(); |
358 | 22 | break; |
359 | 0 | case MachineOperand::MO_MachineBasicBlock: |
360 | 0 | MO.getMBB()->getSymbol()->print(O, MAI); |
361 | 0 | return; |
362 | 3 | case MachineOperand::MO_GlobalAddress: |
363 | 3 | getSymbol(MO.getGlobal())->print(O, MAI); |
364 | 3 | break; |
365 | 0 | case MachineOperand::MO_BlockAddress: |
366 | 0 | O << GetBlockAddressSymbol(MO.getBlockAddress())->getName(); |
367 | 0 | break; |
368 | 0 | case MachineOperand::MO_ExternalSymbol: |
369 | 0 | O << MO.getSymbolName(); |
370 | 0 | break; |
371 | 0 | case MachineOperand::MO_ConstantPoolIndex: |
372 | 0 | O << DL.getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" |
373 | 0 | << MO.getIndex(); |
374 | 0 | break; |
375 | 0 | case MachineOperand::MO_Metadata: |
376 | 0 | MO.getMetadata()->printAsOperand(O, MMI->getModule()); |
377 | 0 | break; |
378 | 0 | default: |
379 | 0 | llvm_unreachable("<unknown operand type>"); |
380 | 161 | } |
381 | 161 | if (161 CloseParen161 ) O << ")"3 ; |
382 | 161 | } |
383 | | |
384 | | void SparcAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum, |
385 | 11 | raw_ostream &O, const char *Modifier) { |
386 | 11 | printOperand(MI, opNum, O); |
387 | 11 | |
388 | 11 | // If this is an ADD operand, emit it like normal operands. |
389 | 11 | if (Modifier && 11 !strcmp(Modifier, "arith")0 ) { |
390 | 0 | O << ", "; |
391 | 0 | printOperand(MI, opNum+1, O); |
392 | 0 | return; |
393 | 0 | } |
394 | 11 | |
395 | 11 | if (11 MI->getOperand(opNum+1).isReg() && |
396 | 0 | MI->getOperand(opNum+1).getReg() == SP::G0) |
397 | 0 | return; // don't print "+%g0" |
398 | 11 | if (11 MI->getOperand(opNum+1).isImm() && |
399 | 8 | MI->getOperand(opNum+1).getImm() == 0) |
400 | 0 | return; // don't print "+0" |
401 | 11 | |
402 | 11 | O << "+"; |
403 | 11 | printOperand(MI, opNum+1, O); |
404 | 11 | } |
405 | | |
406 | | /// PrintAsmOperand - Print out an operand for an inline asm expression. |
407 | | /// |
408 | | bool SparcAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, |
409 | | unsigned AsmVariant, |
410 | | const char *ExtraCode, |
411 | 139 | raw_ostream &O) { |
412 | 139 | if (ExtraCode && 139 ExtraCode[0]0 ) { |
413 | 0 | if (ExtraCode[1] != 00 ) return true0 ; // Unknown modifier. |
414 | 0 |
|
415 | 0 | switch (ExtraCode[0]) { |
416 | 0 | default: |
417 | 0 | // See if this is a generic print operand |
418 | 0 | return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O); |
419 | 0 | case 'f': |
420 | 0 | case 'r': |
421 | 0 | break; |
422 | 139 | } |
423 | 139 | } |
424 | 139 | |
425 | 139 | printOperand(MI, OpNo, O); |
426 | 139 | |
427 | 139 | return false; |
428 | 139 | } |
429 | | |
430 | | bool SparcAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, |
431 | | unsigned OpNo, unsigned AsmVariant, |
432 | | const char *ExtraCode, |
433 | 11 | raw_ostream &O) { |
434 | 11 | if (ExtraCode && 11 ExtraCode[0]0 ) |
435 | 0 | return true; // Unknown modifier |
436 | 11 | |
437 | 11 | O << '['; |
438 | 11 | printMemOperand(MI, OpNo, O); |
439 | 11 | O << ']'; |
440 | 11 | |
441 | 11 | return false; |
442 | 11 | } |
443 | | |
444 | | // Force static initialization. |
445 | 61.8k | extern "C" void LLVMInitializeSparcAsmPrinter() { |
446 | 61.8k | RegisterAsmPrinter<SparcAsmPrinter> X(getTheSparcTarget()); |
447 | 61.8k | RegisterAsmPrinter<SparcAsmPrinter> Y(getTheSparcV9Target()); |
448 | 61.8k | RegisterAsmPrinter<SparcAsmPrinter> Z(getTheSparcelTarget()); |
449 | 61.8k | } |