LLVM 17.0.0git
SystemZAsmPrinter.cpp
Go to the documentation of this file.
1//===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly printer -------------===//
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// Streams SystemZ assembly language and associated data, in the form of
10// MCInsts and MCExprs respectively.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SystemZAsmPrinter.h"
17#include "SystemZMCInstLower.h"
22#include "llvm/IR/Mangler.h"
23#include "llvm/MC/MCExpr.h"
26#include "llvm/MC/MCStreamer.h"
28
29using namespace llvm;
30
31// Return an RI instruction like MI with opcode Opcode, but with the
32// GR64 register operands turned into GR32s.
33static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) {
34 if (MI->isCompare())
35 return MCInstBuilder(Opcode)
36 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
37 .addImm(MI->getOperand(1).getImm());
38 else
39 return MCInstBuilder(Opcode)
40 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
41 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg()))
42 .addImm(MI->getOperand(2).getImm());
43}
44
45// Return an RI instruction like MI with opcode Opcode, but with the
46// GR64 register operands turned into GRH32s.
47static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) {
48 if (MI->isCompare())
49 return MCInstBuilder(Opcode)
50 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
51 .addImm(MI->getOperand(1).getImm());
52 else
53 return MCInstBuilder(Opcode)
54 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
55 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg()))
56 .addImm(MI->getOperand(2).getImm());
57}
58
59// Return an RI instruction like MI with opcode Opcode, but with the
60// R2 register turned into a GR64.
61static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) {
62 return MCInstBuilder(Opcode)
63 .addReg(MI->getOperand(0).getReg())
64 .addReg(MI->getOperand(1).getReg())
65 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()))
66 .addImm(MI->getOperand(3).getImm())
67 .addImm(MI->getOperand(4).getImm())
68 .addImm(MI->getOperand(5).getImm());
69}
70
71static const MCSymbolRefExpr *getTLSGetOffset(MCContext &Context) {
72 StringRef Name = "__tls_get_offset";
73 return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
75 Context);
76}
77
79 StringRef Name = "_GLOBAL_OFFSET_TABLE_";
80 return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
82 Context);
83}
84
85// MI is an instruction that accepts an optional alignment hint,
86// and which was already lowered to LoweredMI. If the alignment
87// of the original memory operand is known, update LoweredMI to
88// an instruction with the corresponding hint set.
89static void lowerAlignmentHint(const MachineInstr *MI, MCInst &LoweredMI,
90 unsigned Opcode) {
91 if (MI->memoperands_empty())
92 return;
93
94 Align Alignment = Align(16);
95 for (MachineInstr::mmo_iterator MMOI = MI->memoperands_begin(),
96 EE = MI->memoperands_end(); MMOI != EE; ++MMOI)
97 if ((*MMOI)->getAlign() < Alignment)
98 Alignment = (*MMOI)->getAlign();
99
100 unsigned AlignmentHint = 0;
101 if (Alignment >= Align(16))
102 AlignmentHint = 4;
103 else if (Alignment >= Align(8))
104 AlignmentHint = 3;
105 if (AlignmentHint == 0)
106 return;
107
108 LoweredMI.setOpcode(Opcode);
109 LoweredMI.addOperand(MCOperand::createImm(AlignmentHint));
110}
111
112// MI loads the high part of a vector from memory. Return an instruction
113// that uses replicating vector load Opcode to do the same thing.
114static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode) {
115 return MCInstBuilder(Opcode)
116 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
117 .addReg(MI->getOperand(1).getReg())
118 .addImm(MI->getOperand(2).getImm())
119 .addReg(MI->getOperand(3).getReg());
120}
121
122// MI stores the high part of a vector to memory. Return an instruction
123// that uses elemental vector store Opcode to do the same thing.
124static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) {
125 return MCInstBuilder(Opcode)
126 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
127 .addReg(MI->getOperand(1).getReg())
128 .addImm(MI->getOperand(2).getImm())
129 .addReg(MI->getOperand(3).getReg())
130 .addImm(0);
131}
132
133// The XPLINK ABI requires that a no-op encoding the call type is emitted after
134// each call to a subroutine. This information can be used by the called
135// function to determine its entry point, e.g. for generating a backtrace. The
136// call type is encoded as a register number in the bcr instruction. See
137// enumeration CallType for the possible values.
138void SystemZAsmPrinter::emitCallInformation(CallType CT) {
140 MCInstBuilder(SystemZ::BCRAsm)
141 .addImm(0)
142 .addReg(SystemZMC::GR64Regs[static_cast<unsigned>(CT)]));
143}
144
146 SystemZ_MC::verifyInstructionPredicates(MI->getOpcode(),
147 getSubtargetInfo().getFeatureBits());
148
150 MCInst LoweredMI;
151 switch (MI->getOpcode()) {
152 case SystemZ::Return:
153 LoweredMI = MCInstBuilder(SystemZ::BR)
154 .addReg(SystemZ::R14D);
155 break;
156
157 case SystemZ::Return_XPLINK:
158 LoweredMI = MCInstBuilder(SystemZ::B)
159 .addReg(SystemZ::R7D)
160 .addImm(2)
161 .addReg(0);
162 break;
163
164 case SystemZ::CondReturn:
165 LoweredMI = MCInstBuilder(SystemZ::BCR)
166 .addImm(MI->getOperand(0).getImm())
167 .addImm(MI->getOperand(1).getImm())
168 .addReg(SystemZ::R14D);
169 break;
170
171 case SystemZ::CondReturn_XPLINK:
172 LoweredMI = MCInstBuilder(SystemZ::BC)
173 .addImm(MI->getOperand(0).getImm())
174 .addImm(MI->getOperand(1).getImm())
175 .addReg(SystemZ::R7D)
176 .addImm(2)
177 .addReg(0);
178 break;
179
180 case SystemZ::CRBReturn:
181 LoweredMI = MCInstBuilder(SystemZ::CRB)
182 .addReg(MI->getOperand(0).getReg())
183 .addReg(MI->getOperand(1).getReg())
184 .addImm(MI->getOperand(2).getImm())
185 .addReg(SystemZ::R14D)
186 .addImm(0);
187 break;
188
189 case SystemZ::CGRBReturn:
190 LoweredMI = MCInstBuilder(SystemZ::CGRB)
191 .addReg(MI->getOperand(0).getReg())
192 .addReg(MI->getOperand(1).getReg())
193 .addImm(MI->getOperand(2).getImm())
194 .addReg(SystemZ::R14D)
195 .addImm(0);
196 break;
197
198 case SystemZ::CIBReturn:
199 LoweredMI = MCInstBuilder(SystemZ::CIB)
200 .addReg(MI->getOperand(0).getReg())
201 .addImm(MI->getOperand(1).getImm())
202 .addImm(MI->getOperand(2).getImm())
203 .addReg(SystemZ::R14D)
204 .addImm(0);
205 break;
206
207 case SystemZ::CGIBReturn:
208 LoweredMI = MCInstBuilder(SystemZ::CGIB)
209 .addReg(MI->getOperand(0).getReg())
210 .addImm(MI->getOperand(1).getImm())
211 .addImm(MI->getOperand(2).getImm())
212 .addReg(SystemZ::R14D)
213 .addImm(0);
214 break;
215
216 case SystemZ::CLRBReturn:
217 LoweredMI = MCInstBuilder(SystemZ::CLRB)
218 .addReg(MI->getOperand(0).getReg())
219 .addReg(MI->getOperand(1).getReg())
220 .addImm(MI->getOperand(2).getImm())
221 .addReg(SystemZ::R14D)
222 .addImm(0);
223 break;
224
225 case SystemZ::CLGRBReturn:
226 LoweredMI = MCInstBuilder(SystemZ::CLGRB)
227 .addReg(MI->getOperand(0).getReg())
228 .addReg(MI->getOperand(1).getReg())
229 .addImm(MI->getOperand(2).getImm())
230 .addReg(SystemZ::R14D)
231 .addImm(0);
232 break;
233
234 case SystemZ::CLIBReturn:
235 LoweredMI = MCInstBuilder(SystemZ::CLIB)
236 .addReg(MI->getOperand(0).getReg())
237 .addImm(MI->getOperand(1).getImm())
238 .addImm(MI->getOperand(2).getImm())
239 .addReg(SystemZ::R14D)
240 .addImm(0);
241 break;
242
243 case SystemZ::CLGIBReturn:
244 LoweredMI = MCInstBuilder(SystemZ::CLGIB)
245 .addReg(MI->getOperand(0).getReg())
246 .addImm(MI->getOperand(1).getImm())
247 .addImm(MI->getOperand(2).getImm())
248 .addReg(SystemZ::R14D)
249 .addImm(0);
250 break;
251
252 case SystemZ::CallBRASL_XPLINK64:
254 MCInstBuilder(SystemZ::BRASL)
255 .addReg(SystemZ::R7D)
256 .addExpr(Lower.getExpr(MI->getOperand(0),
258 emitCallInformation(CallType::BRASL7);
259 return;
260
261 case SystemZ::CallBASR_XPLINK64:
263 .addReg(SystemZ::R7D)
264 .addReg(MI->getOperand(0).getReg()));
265 emitCallInformation(CallType::BASR76);
266 return;
267
268 case SystemZ::CallBASR_STACKEXT:
270 .addReg(SystemZ::R3D)
271 .addReg(MI->getOperand(0).getReg()));
272 emitCallInformation(CallType::BASR33);
273 return;
274
275 case SystemZ::CallBRASL:
276 LoweredMI = MCInstBuilder(SystemZ::BRASL)
277 .addReg(SystemZ::R14D)
278 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
279 break;
280
281 case SystemZ::CallBASR:
282 LoweredMI = MCInstBuilder(SystemZ::BASR)
283 .addReg(SystemZ::R14D)
284 .addReg(MI->getOperand(0).getReg());
285 break;
286
287 case SystemZ::CallJG:
288 LoweredMI = MCInstBuilder(SystemZ::JG)
289 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
290 break;
291
292 case SystemZ::CallBRCL:
293 LoweredMI = MCInstBuilder(SystemZ::BRCL)
294 .addImm(MI->getOperand(0).getImm())
295 .addImm(MI->getOperand(1).getImm())
296 .addExpr(Lower.getExpr(MI->getOperand(2), MCSymbolRefExpr::VK_PLT));
297 break;
298
299 case SystemZ::CallBR:
300 LoweredMI = MCInstBuilder(SystemZ::BR)
301 .addReg(MI->getOperand(0).getReg());
302 break;
303
304 case SystemZ::CallBCR:
305 LoweredMI = MCInstBuilder(SystemZ::BCR)
306 .addImm(MI->getOperand(0).getImm())
307 .addImm(MI->getOperand(1).getImm())
308 .addReg(MI->getOperand(2).getReg());
309 break;
310
311 case SystemZ::CRBCall:
312 LoweredMI = MCInstBuilder(SystemZ::CRB)
313 .addReg(MI->getOperand(0).getReg())
314 .addReg(MI->getOperand(1).getReg())
315 .addImm(MI->getOperand(2).getImm())
316 .addReg(MI->getOperand(3).getReg())
317 .addImm(0);
318 break;
319
320 case SystemZ::CGRBCall:
321 LoweredMI = MCInstBuilder(SystemZ::CGRB)
322 .addReg(MI->getOperand(0).getReg())
323 .addReg(MI->getOperand(1).getReg())
324 .addImm(MI->getOperand(2).getImm())
325 .addReg(MI->getOperand(3).getReg())
326 .addImm(0);
327 break;
328
329 case SystemZ::CIBCall:
330 LoweredMI = MCInstBuilder(SystemZ::CIB)
331 .addReg(MI->getOperand(0).getReg())
332 .addImm(MI->getOperand(1).getImm())
333 .addImm(MI->getOperand(2).getImm())
334 .addReg(MI->getOperand(3).getReg())
335 .addImm(0);
336 break;
337
338 case SystemZ::CGIBCall:
339 LoweredMI = MCInstBuilder(SystemZ::CGIB)
340 .addReg(MI->getOperand(0).getReg())
341 .addImm(MI->getOperand(1).getImm())
342 .addImm(MI->getOperand(2).getImm())
343 .addReg(MI->getOperand(3).getReg())
344 .addImm(0);
345 break;
346
347 case SystemZ::CLRBCall:
348 LoweredMI = MCInstBuilder(SystemZ::CLRB)
349 .addReg(MI->getOperand(0).getReg())
350 .addReg(MI->getOperand(1).getReg())
351 .addImm(MI->getOperand(2).getImm())
352 .addReg(MI->getOperand(3).getReg())
353 .addImm(0);
354 break;
355
356 case SystemZ::CLGRBCall:
357 LoweredMI = MCInstBuilder(SystemZ::CLGRB)
358 .addReg(MI->getOperand(0).getReg())
359 .addReg(MI->getOperand(1).getReg())
360 .addImm(MI->getOperand(2).getImm())
361 .addReg(MI->getOperand(3).getReg())
362 .addImm(0);
363 break;
364
365 case SystemZ::CLIBCall:
366 LoweredMI = MCInstBuilder(SystemZ::CLIB)
367 .addReg(MI->getOperand(0).getReg())
368 .addImm(MI->getOperand(1).getImm())
369 .addImm(MI->getOperand(2).getImm())
370 .addReg(MI->getOperand(3).getReg())
371 .addImm(0);
372 break;
373
374 case SystemZ::CLGIBCall:
375 LoweredMI = MCInstBuilder(SystemZ::CLGIB)
376 .addReg(MI->getOperand(0).getReg())
377 .addImm(MI->getOperand(1).getImm())
378 .addImm(MI->getOperand(2).getImm())
379 .addReg(MI->getOperand(3).getReg())
380 .addImm(0);
381 break;
382
383 case SystemZ::TLS_GDCALL:
384 LoweredMI = MCInstBuilder(SystemZ::BRASL)
385 .addReg(SystemZ::R14D)
387 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSGD));
388 break;
389
390 case SystemZ::TLS_LDCALL:
391 LoweredMI = MCInstBuilder(SystemZ::BRASL)
392 .addReg(SystemZ::R14D)
394 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSLDM));
395 break;
396
397 case SystemZ::GOT:
398 LoweredMI = MCInstBuilder(SystemZ::LARL)
399 .addReg(MI->getOperand(0).getReg())
401 break;
402
403 case SystemZ::IILF64:
404 LoweredMI = MCInstBuilder(SystemZ::IILF)
405 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
406 .addImm(MI->getOperand(2).getImm());
407 break;
408
409 case SystemZ::IIHF64:
410 LoweredMI = MCInstBuilder(SystemZ::IIHF)
411 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
412 .addImm(MI->getOperand(2).getImm());
413 break;
414
415 case SystemZ::RISBHH:
416 case SystemZ::RISBHL:
417 LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG);
418 break;
419
420 case SystemZ::RISBLH:
421 case SystemZ::RISBLL:
422 LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG);
423 break;
424
425 case SystemZ::VLVGP32:
426 LoweredMI = MCInstBuilder(SystemZ::VLVGP)
427 .addReg(MI->getOperand(0).getReg())
428 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg()))
429 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()));
430 break;
431
432 case SystemZ::VLR32:
433 case SystemZ::VLR64:
434 LoweredMI = MCInstBuilder(SystemZ::VLR)
435 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
436 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()));
437 break;
438
439 case SystemZ::VL:
440 Lower.lower(MI, LoweredMI);
441 lowerAlignmentHint(MI, LoweredMI, SystemZ::VLAlign);
442 break;
443
444 case SystemZ::VST:
445 Lower.lower(MI, LoweredMI);
446 lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTAlign);
447 break;
448
449 case SystemZ::VLM:
450 Lower.lower(MI, LoweredMI);
451 lowerAlignmentHint(MI, LoweredMI, SystemZ::VLMAlign);
452 break;
453
454 case SystemZ::VSTM:
455 Lower.lower(MI, LoweredMI);
456 lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTMAlign);
457 break;
458
459 case SystemZ::VL32:
460 LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF);
461 break;
462
463 case SystemZ::VL64:
464 LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG);
465 break;
466
467 case SystemZ::VST32:
468 LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF);
469 break;
470
471 case SystemZ::VST64:
472 LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG);
473 break;
474
475 case SystemZ::LFER:
476 LoweredMI = MCInstBuilder(SystemZ::VLGVF)
477 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(0).getReg()))
478 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()))
479 .addReg(0).addImm(0);
480 break;
481
482 case SystemZ::LEFR:
483 LoweredMI = MCInstBuilder(SystemZ::VLVGF)
484 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
485 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
486 .addReg(MI->getOperand(1).getReg())
487 .addReg(0).addImm(0);
488 break;
489
490#define LOWER_LOW(NAME) \
491 case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break
492
493 LOWER_LOW(IILL);
494 LOWER_LOW(IILH);
495 LOWER_LOW(TMLL);
496 LOWER_LOW(TMLH);
497 LOWER_LOW(NILL);
498 LOWER_LOW(NILH);
499 LOWER_LOW(NILF);
500 LOWER_LOW(OILL);
501 LOWER_LOW(OILH);
502 LOWER_LOW(OILF);
503 LOWER_LOW(XILF);
504
505#undef LOWER_LOW
506
507#define LOWER_HIGH(NAME) \
508 case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break
509
510 LOWER_HIGH(IIHL);
511 LOWER_HIGH(IIHH);
512 LOWER_HIGH(TMHL);
513 LOWER_HIGH(TMHH);
514 LOWER_HIGH(NIHL);
515 LOWER_HIGH(NIHH);
516 LOWER_HIGH(NIHF);
517 LOWER_HIGH(OIHL);
518 LOWER_HIGH(OIHH);
519 LOWER_HIGH(OIHF);
520 LOWER_HIGH(XIHF);
521
522#undef LOWER_HIGH
523
524 case SystemZ::Serialize:
525 if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization())
526 LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
527 .addImm(14).addReg(SystemZ::R0D);
528 else
529 LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
530 .addImm(15).addReg(SystemZ::R0D);
531 break;
532
533 // We want to emit "j .+2" for traps, jumping to the relative immediate field
534 // of the jump instruction, which is an illegal instruction. We cannot emit a
535 // "." symbol, so create and emit a temp label before the instruction and use
536 // that instead.
537 case SystemZ::Trap: {
539 OutStreamer->emitLabel(DotSym);
540
542 const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
543 LoweredMI = MCInstBuilder(SystemZ::J)
544 .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
545 }
546 break;
547
548 // Conditional traps will create a branch on condition instruction that jumps
549 // to the relative immediate field of the jump instruction. (eg. "jo .+2")
550 case SystemZ::CondTrap: {
552 OutStreamer->emitLabel(DotSym);
553
555 const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
556 LoweredMI = MCInstBuilder(SystemZ::BRC)
557 .addImm(MI->getOperand(0).getImm())
558 .addImm(MI->getOperand(1).getImm())
559 .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
560 }
561 break;
562
563 case TargetOpcode::FENTRY_CALL:
564 LowerFENTRY_CALL(*MI, Lower);
565 return;
566
567 case TargetOpcode::STACKMAP:
568 LowerSTACKMAP(*MI);
569 return;
570
571 case TargetOpcode::PATCHPOINT:
572 LowerPATCHPOINT(*MI, Lower);
573 return;
574
575 case SystemZ::EXRL_Pseudo: {
576 unsigned TargetInsOpc = MI->getOperand(0).getImm();
577 Register LenMinus1Reg = MI->getOperand(1).getReg();
578 Register DestReg = MI->getOperand(2).getReg();
579 int64_t DestDisp = MI->getOperand(3).getImm();
580 Register SrcReg = MI->getOperand(4).getReg();
581 int64_t SrcDisp = MI->getOperand(5).getImm();
582
583 SystemZTargetStreamer *TS = getTargetStreamer();
584 MCSymbol *DotSym = nullptr;
585 MCInst ET = MCInstBuilder(TargetInsOpc).addReg(DestReg)
586 .addImm(DestDisp).addImm(1).addReg(SrcReg).addImm(SrcDisp);
588 SystemZTargetStreamer::EXRLT2SymMap::iterator I =
589 TS->EXRLTargets2Sym.find(ET_STI);
590 if (I != TS->EXRLTargets2Sym.end())
591 DotSym = I->second;
592 else
593 TS->EXRLTargets2Sym[ET_STI] = DotSym = OutContext.createTempSymbol();
597 MCInstBuilder(SystemZ::EXRL).addReg(LenMinus1Reg).addExpr(Dot));
598 return;
599 }
600
601 default:
602 Lower.lower(MI, LoweredMI);
603 break;
604 }
605 EmitToStreamer(*OutStreamer, LoweredMI);
606}
607
608// Emit the largest nop instruction smaller than or equal to NumBytes
609// bytes. Return the size of nop emitted.
610static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer,
611 unsigned NumBytes, const MCSubtargetInfo &STI) {
612 if (NumBytes < 2) {
613 llvm_unreachable("Zero nops?");
614 return 0;
615 }
616 else if (NumBytes < 4) {
617 OutStreamer.emitInstruction(
618 MCInstBuilder(SystemZ::BCRAsm).addImm(0).addReg(SystemZ::R0D), STI);
619 return 2;
620 }
621 else if (NumBytes < 6) {
622 OutStreamer.emitInstruction(
623 MCInstBuilder(SystemZ::BCAsm).addImm(0).addReg(0).addImm(0).addReg(0),
624 STI);
625 return 4;
626 }
627 else {
628 MCSymbol *DotSym = OutContext.createTempSymbol();
629 const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext);
630 OutStreamer.emitLabel(DotSym);
631 OutStreamer.emitInstruction(
632 MCInstBuilder(SystemZ::BRCLAsm).addImm(0).addExpr(Dot), STI);
633 return 6;
634 }
635}
636
637void SystemZAsmPrinter::LowerFENTRY_CALL(const MachineInstr &MI,
639 MCContext &Ctx = MF->getContext();
640 if (MF->getFunction().hasFnAttribute("mrecord-mcount")) {
642 OutStreamer->pushSection();
643 OutStreamer->switchSection(
644 Ctx.getELFSection("__mcount_loc", ELF::SHT_PROGBITS, ELF::SHF_ALLOC));
645 OutStreamer->emitSymbolValue(DotSym, 8);
646 OutStreamer->popSection();
647 OutStreamer->emitLabel(DotSym);
648 }
649
650 if (MF->getFunction().hasFnAttribute("mnop-mcount")) {
652 return;
653 }
654
655 MCSymbol *fentry = Ctx.getOrCreateSymbol("__fentry__");
656 const MCSymbolRefExpr *Op =
658 OutStreamer->emitInstruction(
659 MCInstBuilder(SystemZ::BRASL).addReg(SystemZ::R0D).addExpr(Op),
661}
662
663void SystemZAsmPrinter::LowerSTACKMAP(const MachineInstr &MI) {
664 auto *TII = MF->getSubtarget<SystemZSubtarget>().getInstrInfo();
665
666 unsigned NumNOPBytes = MI.getOperand(1).getImm();
667
668 auto &Ctx = OutStreamer->getContext();
669 MCSymbol *MILabel = Ctx.createTempSymbol();
670 OutStreamer->emitLabel(MILabel);
671
672 SM.recordStackMap(*MILabel, MI);
673 assert(NumNOPBytes % 2 == 0 && "Invalid number of NOP bytes requested!");
674
675 // Scan ahead to trim the shadow.
676 unsigned ShadowBytes = 0;
677 const MachineBasicBlock &MBB = *MI.getParent();
679 ++MII;
680 while (ShadowBytes < NumNOPBytes) {
681 if (MII == MBB.end() ||
682 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
683 MII->getOpcode() == TargetOpcode::STACKMAP)
684 break;
685 ShadowBytes += TII->getInstSizeInBytes(*MII);
686 if (MII->isCall())
687 break;
688 ++MII;
689 }
690
691 // Emit nops.
692 while (ShadowBytes < NumNOPBytes)
693 ShadowBytes += EmitNop(OutContext, *OutStreamer, NumNOPBytes - ShadowBytes,
695}
696
697// Lower a patchpoint of the form:
698// [<def>], <id>, <numBytes>, <target>, <numArgs>
699void SystemZAsmPrinter::LowerPATCHPOINT(const MachineInstr &MI,
701 auto &Ctx = OutStreamer->getContext();
702 MCSymbol *MILabel = Ctx.createTempSymbol();
703 OutStreamer->emitLabel(MILabel);
704
705 SM.recordPatchPoint(*MILabel, MI);
706 PatchPointOpers Opers(&MI);
707
708 unsigned EncodedBytes = 0;
709 const MachineOperand &CalleeMO = Opers.getCallTarget();
710
711 if (CalleeMO.isImm()) {
712 uint64_t CallTarget = CalleeMO.getImm();
713 if (CallTarget) {
714 unsigned ScratchIdx = -1;
715 unsigned ScratchReg = 0;
716 do {
717 ScratchIdx = Opers.getNextScratchIdx(ScratchIdx + 1);
718 ScratchReg = MI.getOperand(ScratchIdx).getReg();
719 } while (ScratchReg == SystemZ::R0D);
720
721 // Materialize the call target address
723 .addReg(ScratchReg)
724 .addImm(CallTarget & 0xFFFFFFFF));
725 EncodedBytes += 6;
726 if (CallTarget >> 32) {
728 .addReg(ScratchReg)
729 .addImm(CallTarget >> 32));
730 EncodedBytes += 6;
731 }
732
734 .addReg(SystemZ::R14D)
735 .addReg(ScratchReg));
736 EncodedBytes += 2;
737 }
738 } else if (CalleeMO.isGlobal()) {
739 const MCExpr *Expr = Lower.getExpr(CalleeMO, MCSymbolRefExpr::VK_PLT);
741 .addReg(SystemZ::R14D)
742 .addExpr(Expr));
743 EncodedBytes += 6;
744 }
745
746 // Emit padding.
747 unsigned NumBytes = Opers.getNumPatchBytes();
748 assert(NumBytes >= EncodedBytes &&
749 "Patchpoint can't request size less than the length of a call.");
750 assert((NumBytes - EncodedBytes) % 2 == 0 &&
751 "Invalid number of NOP bytes requested!");
752 while (EncodedBytes < NumBytes)
753 EncodedBytes += EmitNop(OutContext, *OutStreamer, NumBytes - EncodedBytes,
755}
756
757// The *alignment* of 128-bit vector types is different between the software
758// and hardware vector ABIs. If the there is an externally visible use of a
759// vector type in the module it should be annotated with an attribute.
760void SystemZAsmPrinter::emitAttributes(Module &M) {
761 if (M.getModuleFlag("s390x-visible-vector-ABI")) {
762 bool HasVectorFeature =
763 TM.getMCSubtargetInfo()->hasFeature(SystemZ::FeatureVector);
764 OutStreamer->emitGNUAttribute(8, HasVectorFeature ? 2 : 1);
765 }
766}
767
768// Convert a SystemZ-specific constant pool modifier into the associated
769// MCSymbolRefExpr variant kind.
772 switch (Modifier) {
777 }
778 llvm_unreachable("Invalid SystemCPModifier!");
779}
780
783 auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV);
784
785 const MCExpr *Expr =
786 MCSymbolRefExpr::create(getSymbol(ZCPV->getGlobalValue()),
787 getModifierVariantKind(ZCPV->getModifier()),
788 OutContext);
789 uint64_t Size = getDataLayout().getTypeAllocSize(ZCPV->getType());
790
791 OutStreamer->emitValue(Expr, Size);
792}
793
794static void printFormattedRegName(const MCAsmInfo *MAI, unsigned RegNo,
795 raw_ostream &OS) {
796 const char *RegName = SystemZInstPrinter::getRegisterName(RegNo);
797 if (MAI->getAssemblerDialect() == AD_HLASM) {
798 // Skip register prefix so that only register number is left
799 assert(isalpha(RegName[0]) && isdigit(RegName[1]));
800 OS << (RegName + 1);
801 } else
802 OS << '%' << RegName;
803}
804
805static void printOperand(const MCOperand &MCOp, const MCAsmInfo *MAI,
806 raw_ostream &OS) {
807 if (MCOp.isReg()) {
808 if (!MCOp.getReg())
809 OS << '0';
810 else
811 printFormattedRegName(MAI, MCOp.getReg(), OS);
812 } else if (MCOp.isImm())
813 OS << MCOp.getImm();
814 else if (MCOp.isExpr())
815 MCOp.getExpr()->print(OS, MAI);
816 else
817 llvm_unreachable("Invalid operand");
818}
819
820static void printAddress(const MCAsmInfo *MAI, unsigned Base,
821 const MCOperand &DispMO, unsigned Index,
822 raw_ostream &OS) {
823 printOperand(DispMO, MAI, OS);
824 if (Base || Index) {
825 OS << '(';
826 if (Index) {
828 if (Base)
829 OS << ',';
830 }
831 if (Base)
833 OS << ')';
834 }
835}
836
838 const char *ExtraCode,
839 raw_ostream &OS) {
841 const MachineOperand &MO = MI->getOperand(OpNo);
842 MCOperand MCOp;
843 if (ExtraCode) {
844 if (ExtraCode[0] == 'N' && !ExtraCode[1] && MO.isReg() &&
845 SystemZ::GR128BitRegClass.contains(MO.getReg()))
846 MCOp =
847 MCOperand::createReg(MRI.getSubReg(MO.getReg(), SystemZ::subreg_l64));
848 else
849 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS);
850 } else {
852 MCOp = Lower.lowerOperand(MO);
853 }
854 printOperand(MCOp, MAI, OS);
855 return false;
856}
857
859 unsigned OpNo,
860 const char *ExtraCode,
861 raw_ostream &OS) {
862 printAddress(MAI, MI->getOperand(OpNo).getReg(),
863 MCOperand::createImm(MI->getOperand(OpNo + 1).getImm()),
864 MI->getOperand(OpNo + 2).getReg(), OS);
865 return false;
866}
867
869 emitAttributes(M);
870}
871
873 if (TM.getTargetTriple().isOSzOS()) {
874 // Emit symbol for the end of function if the z/OS target streamer
875 // is used. This is needed to calculate the size of the function.
876 MCSymbol *FnEndSym = createTempSymbol("func_end");
877 OutStreamer->emitLabel(FnEndSym);
878
879 OutStreamer->pushSection();
880 OutStreamer->switchSection(getObjFileLowering().getPPA1Section());
881 emitPPA1(FnEndSym);
882 OutStreamer->popSection();
883
884 CurrentFnPPA1Sym = nullptr;
885 CurrentFnEPMarkerSym = nullptr;
886 }
887}
888
889static void emitPPA1Flags(std::unique_ptr<MCStreamer> &OutStreamer, bool VarArg,
890 bool StackProtector, bool FPRMask, bool VRMask) {
891 enum class PPA1Flag1 : uint8_t {
892 DSA64Bit = (0x80 >> 0),
893 VarArg = (0x80 >> 7),
895 };
896 enum class PPA1Flag2 : uint8_t {
897 ExternalProcedure = (0x80 >> 0),
898 STACKPROTECTOR = (0x80 >> 3),
899 LLVM_MARK_AS_BITMASK_ENUM(ExternalProcedure)
900 };
901 enum class PPA1Flag3 : uint8_t {
902 FPRMask = (0x80 >> 2),
904 };
905 enum class PPA1Flag4 : uint8_t {
906 EPMOffsetPresent = (0x80 >> 0),
907 VRMask = (0x80 >> 2),
908 ProcedureNamePresent = (0x80 >> 7),
909 LLVM_MARK_AS_BITMASK_ENUM(EPMOffsetPresent)
910 };
911
912 // Declare optional section flags that can be modified.
913 auto Flags1 = PPA1Flag1(0);
914 auto Flags2 = PPA1Flag2::ExternalProcedure;
915 auto Flags3 = PPA1Flag3(0);
916 auto Flags4 = PPA1Flag4::EPMOffsetPresent | PPA1Flag4::ProcedureNamePresent;
917
918 Flags1 |= PPA1Flag1::DSA64Bit;
919
920 if (VarArg)
921 Flags1 |= PPA1Flag1::VarArg;
922
923 if (StackProtector)
924 Flags2 |= PPA1Flag2::STACKPROTECTOR;
925
926 // SavedGPRMask, SavedFPRMask, and SavedVRMask are precomputed in.
927 if (FPRMask)
928 Flags3 |= PPA1Flag3::FPRMask; // Add emit FPR mask flag.
929
930 if (VRMask)
931 Flags4 |= PPA1Flag4::VRMask; // Add emit VR mask flag.
932
933 OutStreamer->AddComment("PPA1 Flags 1");
934 if ((Flags1 & PPA1Flag1::DSA64Bit) == PPA1Flag1::DSA64Bit)
935 OutStreamer->AddComment(" Bit 0: 1 = 64-bit DSA");
936 else
937 OutStreamer->AddComment(" Bit 0: 0 = 32-bit DSA");
938 if ((Flags1 & PPA1Flag1::VarArg) == PPA1Flag1::VarArg)
939 OutStreamer->AddComment(" Bit 7: 1 = Vararg function");
940 OutStreamer->emitInt8(static_cast<uint8_t>(Flags1)); // Flags 1.
941
942 OutStreamer->AddComment("PPA1 Flags 2");
943 if ((Flags2 & PPA1Flag2::ExternalProcedure) == PPA1Flag2::ExternalProcedure)
944 OutStreamer->AddComment(" Bit 0: 1 = External procedure");
945 if ((Flags2 & PPA1Flag2::STACKPROTECTOR) == PPA1Flag2::STACKPROTECTOR)
946 OutStreamer->AddComment(" Bit 3: 1 = STACKPROTECT is enabled");
947 else
948 OutStreamer->AddComment(" Bit 3: 0 = STACKPROTECT is not enabled");
949 OutStreamer->emitInt8(static_cast<uint8_t>(Flags2)); // Flags 2.
950
951 OutStreamer->AddComment("PPA1 Flags 3");
952 if ((Flags3 & PPA1Flag3::FPRMask) == PPA1Flag3::FPRMask)
953 OutStreamer->AddComment(" Bit 2: 1 = FP Reg Mask is in optional area");
954 OutStreamer->emitInt8(
955 static_cast<uint8_t>(Flags3)); // Flags 3 (optional sections).
956
957 OutStreamer->AddComment("PPA1 Flags 4");
958 if ((Flags4 & PPA1Flag4::VRMask) == PPA1Flag4::VRMask)
959 OutStreamer->AddComment(" Bit 2: 1 = Vector Reg Mask is in optional area");
960 OutStreamer->emitInt8(static_cast<uint8_t>(
961 Flags4)); // Flags 4 (optional sections, always emit these).
962}
963
964void SystemZAsmPrinter::emitPPA1(MCSymbol *FnEndSym) {
966 const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>();
967 const auto TargetHasVector = Subtarget.hasVector();
968
969 const SystemZMachineFunctionInfo *ZFI =
971 const auto *ZFL = static_cast<const SystemZXPLINKFrameLowering *>(
972 Subtarget.getFrameLowering());
973 const MachineFrameInfo &MFFrame = MF->getFrameInfo();
974
975 // Get saved GPR/FPR/VPR masks.
976 const std::vector<CalleeSavedInfo> &CSI = MFFrame.getCalleeSavedInfo();
977 uint16_t SavedGPRMask = 0;
978 uint16_t SavedFPRMask = 0;
979 uint8_t SavedVRMask = 0;
980 int64_t OffsetFPR = 0;
981 int64_t OffsetVR = 0;
982 const int64_t TopOfStack =
983 MFFrame.getOffsetAdjustment() + MFFrame.getStackSize();
984
985 // Loop over the spilled registers. The CalleeSavedInfo can't be used because
986 // it does not contain all spilled registers.
987 for (unsigned I = ZFI->getSpillGPRRegs().LowGPR,
988 E = ZFI->getSpillGPRRegs().HighGPR;
989 I && E && I <= E; ++I) {
990 unsigned V = TRI->getEncodingValue((Register)I);
991 assert(V < 16 && "GPR index out of range");
992 SavedGPRMask |= 1 << (15 - V);
993 }
994
995 for (auto &CS : CSI) {
996 unsigned Reg = CS.getReg();
997 unsigned I = TRI->getEncodingValue(Reg);
998
999 if (SystemZ::FP64BitRegClass.contains(Reg)) {
1000 assert(I < 16 && "FPR index out of range");
1001 SavedFPRMask |= 1 << (15 - I);
1002 int64_t Temp = MFFrame.getObjectOffset(CS.getFrameIdx());
1003 if (Temp < OffsetFPR)
1004 OffsetFPR = Temp;
1005 } else if (SystemZ::VR128BitRegClass.contains(Reg)) {
1006 assert(I >= 16 && I <= 23 && "VPR index out of range");
1007 unsigned BitNum = I - 16;
1008 SavedVRMask |= 1 << (7 - BitNum);
1009 int64_t Temp = MFFrame.getObjectOffset(CS.getFrameIdx());
1010 if (Temp < OffsetVR)
1011 OffsetVR = Temp;
1012 }
1013 }
1014
1015 // Adjust the offset.
1016 OffsetFPR += (OffsetFPR < 0) ? TopOfStack : 0;
1017 OffsetVR += (OffsetVR < 0) ? TopOfStack : 0;
1018
1019 // Get alloca register.
1020 uint8_t FrameReg = TRI->getEncodingValue(TRI->getFrameRegister(*MF));
1021 uint8_t AllocaReg = ZFL->hasFP(*MF) ? FrameReg : 0;
1022 assert(AllocaReg < 16 && "Can't have alloca register larger than 15");
1023 (void)AllocaReg;
1024
1025 // Build FPR save area offset.
1026 uint32_t FrameAndFPROffset = 0;
1027 if (SavedFPRMask) {
1028 uint64_t FPRSaveAreaOffset = OffsetFPR;
1029 assert(FPRSaveAreaOffset < 0x10000000 && "Offset out of range");
1030
1031 FrameAndFPROffset = FPRSaveAreaOffset & 0x0FFFFFFF; // Lose top 4 bits.
1032 FrameAndFPROffset |= FrameReg << 28; // Put into top 4 bits.
1033 }
1034
1035 // Build VR save area offset.
1036 uint32_t FrameAndVROffset = 0;
1037 if (TargetHasVector && SavedVRMask) {
1038 uint64_t VRSaveAreaOffset = OffsetVR;
1039 assert(VRSaveAreaOffset < 0x10000000 && "Offset out of range");
1040
1041 FrameAndVROffset = VRSaveAreaOffset & 0x0FFFFFFF; // Lose top 4 bits.
1042 FrameAndVROffset |= FrameReg << 28; // Put into top 4 bits.
1043 }
1044
1045 // Emit PPA1 section.
1046 OutStreamer->AddComment("PPA1");
1047 OutStreamer->emitLabel(CurrentFnPPA1Sym);
1048 OutStreamer->AddComment("Version");
1049 OutStreamer->emitInt8(0x02); // Version.
1050 OutStreamer->AddComment("LE Signature X'CE'");
1051 OutStreamer->emitInt8(0xCE); // CEL signature.
1052 OutStreamer->AddComment("Saved GPR Mask");
1053 OutStreamer->emitInt16(SavedGPRMask);
1054
1056 MFFrame.hasStackProtectorIndex(), SavedFPRMask != 0,
1057 TargetHasVector && SavedVRMask != 0);
1058
1059 OutStreamer->AddComment("Length/4 of Parms");
1060 OutStreamer->emitInt16(
1061 static_cast<uint16_t>(MFFrame.getMaxCallFrameSize() / 4)); // Parms/4.
1062 OutStreamer->AddComment("Length of Code");
1063 OutStreamer->emitAbsoluteSymbolDiff(FnEndSym, CurrentFnEPMarkerSym, 4);
1064
1065 // Emit saved FPR mask and offset to FPR save area (0x20 of flags 3).
1066 if (SavedFPRMask) {
1067 OutStreamer->AddComment("FPR mask");
1068 OutStreamer->emitInt16(SavedFPRMask);
1069 OutStreamer->AddComment("AR mask");
1070 OutStreamer->emitInt16(0); // AR Mask, unused currently.
1071 OutStreamer->AddComment("FPR Save Area Locator");
1072 OutStreamer->AddComment(Twine(" Bit 0-3: Register R")
1073 .concat(utostr(FrameAndFPROffset >> 28))
1074 .str());
1075 OutStreamer->AddComment(Twine(" Bit 4-31: Offset ")
1076 .concat(utostr(FrameAndFPROffset & 0x0FFFFFFF))
1077 .str());
1078 OutStreamer->emitInt32(FrameAndFPROffset); // Offset to FPR save area with
1079 // register to add value to
1080 // (alloca reg).
1081 }
1082
1083 // Emit saved VR mask to VR save area.
1084 if (TargetHasVector && SavedVRMask) {
1085 OutStreamer->AddComment("VR mask");
1086 OutStreamer->emitInt8(SavedVRMask);
1087 OutStreamer->emitInt8(0); // Reserved.
1088 OutStreamer->emitInt16(0); // Also reserved.
1089 OutStreamer->AddComment("VR Save Area Locator");
1090 OutStreamer->AddComment(Twine(" Bit 0-3: Register R")
1091 .concat(utostr(FrameAndVROffset >> 28))
1092 .str());
1093 OutStreamer->AddComment(Twine(" Bit 4-31: Offset ")
1094 .concat(utostr(FrameAndVROffset & 0x0FFFFFFF))
1095 .str());
1096 OutStreamer->emitInt32(FrameAndVROffset);
1097 }
1098
1099 // Emit offset to entry point optional section (0x80 of flags 4).
1100 OutStreamer->emitAbsoluteSymbolDiff(CurrentFnEPMarkerSym, CurrentFnPPA1Sym,
1101 4);
1102}
1103
1105 const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>();
1106
1107 if (Subtarget.getTargetTriple().isOSzOS()) {
1108 MCContext &OutContext = OutStreamer->getContext();
1109
1110 // Save information for later use.
1111 std::string N(MF->getFunction().hasName()
1112 ? Twine(MF->getFunction().getName()).concat("_").str()
1113 : "");
1114
1115 CurrentFnEPMarkerSym =
1116 OutContext.createTempSymbol(Twine("EPM_").concat(N).str(), true);
1117 CurrentFnPPA1Sym =
1118 OutContext.createTempSymbol(Twine("PPA1_").concat(N).str(), true);
1119
1120 // EntryPoint Marker
1121 const MachineFrameInfo &MFFrame = MF->getFrameInfo();
1122 bool IsUsingAlloca = MFFrame.hasVarSizedObjects();
1123
1124 // Set Flags
1125 uint8_t Flags = 0;
1126 if (IsUsingAlloca)
1127 Flags |= 0x04;
1128
1129 uint32_t DSASize = MFFrame.getStackSize();
1130
1131 // Combine into top 27 bits of DSASize and bottom 5 bits of Flags.
1132 uint32_t DSAAndFlags = DSASize & 0xFFFFFFE0; // (x/32) << 5
1133 DSAAndFlags |= Flags;
1134
1135 // Emit entry point marker section.
1136 OutStreamer->AddComment("XPLINK Routine Layout Entry");
1137 OutStreamer->emitLabel(CurrentFnEPMarkerSym);
1138 OutStreamer->AddComment("Eyecatcher 0x00C300C500C500");
1139 OutStreamer->emitIntValueInHex(0x00C300C500C500, 7); // Eyecatcher.
1140 OutStreamer->AddComment("Mark Type C'1'");
1141 OutStreamer->emitInt8(0xF1); // Mark Type.
1142 OutStreamer->AddComment("Offset to PPA1");
1143 OutStreamer->emitAbsoluteSymbolDiff(CurrentFnPPA1Sym, CurrentFnEPMarkerSym,
1144 4);
1145 if (OutStreamer->isVerboseAsm()) {
1146 OutStreamer->AddComment("DSA Size 0x" + Twine::utohexstr(DSASize));
1147 OutStreamer->AddComment("Entry Flags");
1148 if (Flags & 0x04)
1149 OutStreamer->AddComment(" Bit 2: 1 = Uses alloca");
1150 else
1151 OutStreamer->AddComment(" Bit 2: 0 = Does not use alloca");
1152 }
1153 OutStreamer->emitInt32(DSAAndFlags);
1154 }
1155
1157}
1158
1159// Force static initialization.
1162}
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock & MBB
static MCSymbolRefExpr::VariantKind getModifierVariantKind(ARMCP::ARMCPModifier Modifier)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:127
std::string Name
uint64_t Size
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define RegName(no)
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
LLVMContext & Context
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
#define LOWER_LOW(NAME)
static void lowerAlignmentHint(const MachineInstr *MI, MCInst &LoweredMI, unsigned Opcode)
static const MCSymbolRefExpr * getGlobalOffsetTable(MCContext &Context)
#define LOWER_HIGH(NAME)
static void printFormattedRegName(const MCAsmInfo *MAI, unsigned RegNo, raw_ostream &OS)
static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode)
static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZAsmPrinter()
static void printAddress(const MCAsmInfo *MAI, unsigned Base, const MCOperand &DispMO, unsigned Index, raw_ostream &OS)
static const MCSymbolRefExpr * getTLSGetOffset(MCContext &Context)
static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode)
static void emitPPA1Flags(std::unique_ptr< MCStreamer > &OutStreamer, bool VarArg, bool StackProtector, bool FPRMask, bool VRMask)
static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer, unsigned NumBytes, const MCSubtargetInfo &STI)
static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode)
static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode)
@ Flags
Definition: TextStubV5.cpp:93
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:467
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
Definition: AsmPrinter.cpp:379
MCSymbol * getSymbol(const GlobalValue *GV) const
Definition: AsmPrinter.cpp:662
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
Definition: AsmPrinter.cpp:398
TargetMachine & TM
Target machine description.
Definition: AsmPrinter.h:87
const MCAsmInfo * MAI
Target Asm Printer information.
Definition: AsmPrinter.h:90
MachineFunction * MF
The current machine function.
Definition: AsmPrinter.h:102
MCContext & OutContext
This is the context for the output file that we are streaming.
Definition: AsmPrinter.h:94
MCSymbol * createTempSymbol(const Twine &Name) const
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition: AsmPrinter.h:99
StackMaps SM
Definition: AsmPrinter.h:210
const DataLayout & getDataLayout() const
Return information about data layout.
Definition: AsmPrinter.cpp:383
virtual void emitFunctionEntryLabel()
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
Definition: AsmPrinter.cpp:393
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.
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Definition: DataLayout.h:500
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition: Function.h:187
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:644
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:56
unsigned getAssemblerDialect() const
Definition: MCAsmInfo.h:686
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:525
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
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:318
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition: MCContext.h:563
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:201
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
Definition: MCExpr.cpp:41
MCInstBuilder & addReg(unsigned Reg)
Add a new register operand.
Definition: MCInstBuilder.h:31
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Definition: MCInstBuilder.h:37
MCInstBuilder & addExpr(const MCExpr *Val)
Add a new MCExpr operand.
Definition: MCInstBuilder.h:55
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
int64_t getImm() const
Definition: MCInst.h:80
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:141
bool isImm() const
Definition: MCInst.h:62
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:69
bool isReg() const
Definition: MCInst.h:61
const MCExpr * getExpr() const
Definition: MCInst.h:114
bool isExpr() const
Definition: MCInst.h:65
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
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.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:423
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) 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:386
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
Abstract base class for all machine specific constantpool value subclasses.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
int getOffsetAdjustment() const
Return the correction for frame offsets.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
bool hasStackProtectorIndex() const
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Representation of each machine instruction.
Definition: MachineInstr.h:68
MachineOperand class - Representation of each machine instruction operand.
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Register getReg() const
getReg - Returns the register number.
const TargetRegisterInfo * getTargetRegisterInfo() const
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
MI-level patchpoint operands.
Definition: StackMaps.h:76
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
void recordPatchPoint(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a patchpoint instruction.
Definition: StackMaps.cpp:551
void recordStackMap(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a stackmap instruction.
Definition: StackMaps.cpp:541
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override
void emitFunctionBodyEnd() override
Targets can override this to emit stuff after the last basic block in the function.
void emitInstruction(const MachineInstr *MI) override
Targets should implement this to emit instructions.
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
void emitFunctionEntryLabel() override
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
void emitEndOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the end of their file...
A SystemZ-specific constant pool value.
static const char * getRegisterName(MCRegister Reg)
const TargetFrameLowering * getFrameLowering() const override
std::pair< MCInst, const MCSubtargetInfo * > MCInstSTIPair
const Triple & getTargetTriple() const
const MCSubtargetInfo * getMCSubtargetInfo() const
const MCRegisterInfo * getMCRegisterInfo() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool isOSzOS() const
Definition: Triple.h:516
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
std::string str() const
Return the twine contents as a std::string.
Definition: Twine.cpp:17
Twine concat(const Twine &Suffix) const
Definition: Twine.h:506
static Twine utohexstr(const uint64_t &Val)
Definition: Twine.h:404
bool hasName() const
Definition: Value.h:261
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:308
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.
@ SHF_ALLOC
Definition: ELF.h:1083
@ SHT_PROGBITS
Definition: ELF.h:995
unsigned getRegAsGR32(unsigned Reg)
const unsigned GR64Regs[16]
unsigned getRegAsGRH32(unsigned Reg)
unsigned getRegAsVR128(unsigned Reg)
unsigned getRegAsGR64(unsigned Reg)
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Target & getTheSystemZTarget()
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&... Ranges)
Concatenated range across two or more ranges.
Definition: STLExtras.h:1268
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...