LLVM 18.0.0git
MipsAsmPrinter.cpp
Go to the documentation of this file.
1//===- MipsAsmPrinter.cpp - Mips 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// This file contains a printer that converts from our internal representation
10// of machine-dependent LLVM code to GAS-format MIPS assembly language.
11//
12//===----------------------------------------------------------------------===//
13
14#include "MipsAsmPrinter.h"
20#include "Mips.h"
21#include "MipsMCInstLower.h"
22#include "MipsMachineFunction.h"
23#include "MipsSubtarget.h"
24#include "MipsTargetMachine.h"
25#include "MipsTargetStreamer.h"
28#include "llvm/ADT/StringRef.h"
29#include "llvm/ADT/Twine.h"
40#include "llvm/IR/Attributes.h"
41#include "llvm/IR/BasicBlock.h"
42#include "llvm/IR/DataLayout.h"
43#include "llvm/IR/Function.h"
44#include "llvm/IR/InlineAsm.h"
46#include "llvm/MC/MCContext.h"
47#include "llvm/MC/MCExpr.h"
48#include "llvm/MC/MCInst.h"
52#include "llvm/MC/MCSymbol.h"
53#include "llvm/MC/MCSymbolELF.h"
61#include <cassert>
62#include <cstdint>
63#include <map>
64#include <memory>
65#include <string>
66#include <vector>
67
68using namespace llvm;
69
70#define DEBUG_TYPE "mips-asm-printer"
71
73
74MipsTargetStreamer &MipsAsmPrinter::getTargetStreamer() const {
75 return static_cast<MipsTargetStreamer &>(*OutStreamer->getTargetStreamer());
76}
77
80
83 for (const auto &I : MipsFI->StubsNeeded) {
84 const char *Symbol = I.first;
85 const Mips16HardFloatInfo::FuncSignature *Signature = I.second;
86 if (StubsNeeded.find(Symbol) == StubsNeeded.end())
87 StubsNeeded[Symbol] = Signature;
88 }
89 MCP = MF.getConstantPool();
90
91 // In NaCl, all indirect jump targets must be aligned to bundle size.
93 NaClAlignIndirectJumpTargets(MF);
94
96
98
99 return true;
100}
101
102bool MipsAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) {
103 MCOp = MCInstLowering.LowerOperand(MO);
104 return MCOp.isValid();
105}
106
107#include "MipsGenMCPseudoLowering.inc"
108
109// Lower PseudoReturn/PseudoIndirectBranch/PseudoIndirectBranch64 to JR, JR_MM,
110// JALR, or JALR64 as appropriate for the target.
111void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer,
112 const MachineInstr *MI) {
113 bool HasLinkReg = false;
114 bool InMicroMipsMode = Subtarget->inMicroMipsMode();
115 MCInst TmpInst0;
116
117 if (Subtarget->hasMips64r6()) {
118 // MIPS64r6 should use (JALR64 ZERO_64, $rs)
119 TmpInst0.setOpcode(Mips::JALR64);
120 HasLinkReg = true;
121 } else if (Subtarget->hasMips32r6()) {
122 // MIPS32r6 should use (JALR ZERO, $rs)
123 if (InMicroMipsMode)
124 TmpInst0.setOpcode(Mips::JRC16_MMR6);
125 else {
126 TmpInst0.setOpcode(Mips::JALR);
127 HasLinkReg = true;
128 }
129 } else if (Subtarget->inMicroMipsMode())
130 // microMIPS should use (JR_MM $rs)
131 TmpInst0.setOpcode(Mips::JR_MM);
132 else {
133 // Everything else should use (JR $rs)
134 TmpInst0.setOpcode(Mips::JR);
135 }
136
137 MCOperand MCOp;
138
139 if (HasLinkReg) {
140 unsigned ZeroReg = Subtarget->isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
141 TmpInst0.addOperand(MCOperand::createReg(ZeroReg));
142 }
143
144 lowerOperand(MI->getOperand(0), MCOp);
145 TmpInst0.addOperand(MCOp);
146
147 EmitToStreamer(OutStreamer, TmpInst0);
148}
149
150// If there is an MO_JALR operand, insert:
151//
152// .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
153// tmplabel:
154//
155// This is an optimization hint for the linker which may then replace
156// an indirect call with a direct branch.
158 MCContext &OutContext,
160 MCStreamer &OutStreamer,
161 const MipsSubtarget &Subtarget) {
162 for (const MachineOperand &MO :
163 llvm::drop_begin(MI.operands(), MI.getDesc().getNumOperands())) {
164 if (MO.isMCSymbol() && (MO.getTargetFlags() & MipsII::MO_JALR)) {
165 MCSymbol *Callee = MO.getMCSymbol();
166 if (Callee && !Callee->getName().empty()) {
167 MCSymbol *OffsetLabel = OutContext.createTempSymbol();
168 const MCExpr *OffsetExpr =
169 MCSymbolRefExpr::create(OffsetLabel, OutContext);
170 const MCExpr *CaleeExpr =
171 MCSymbolRefExpr::create(Callee, OutContext);
172 OutStreamer.emitRelocDirective(
173 *OffsetExpr,
174 Subtarget.inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
175 CaleeExpr, SMLoc(), *TM.getMCSubtargetInfo());
176 OutStreamer.emitLabel(OffsetLabel);
177 return;
178 }
179 }
180 }
181}
182
184 // FIXME: Enable feature predicate checks once all the test pass.
185 // Mips_MC::verifyInstructionPredicates(MI->getOpcode(),
186 // getSubtargetInfo().getFeatureBits());
187
188 MipsTargetStreamer &TS = getTargetStreamer();
189 unsigned Opc = MI->getOpcode();
191
192 if (MI->isDebugValue()) {
195
197 return;
198 }
199 if (MI->isDebugLabel())
200 return;
201
202 // If we just ended a constant pool, mark it as such.
203 if (InConstantPool && Opc != Mips::CONSTPOOL_ENTRY) {
204 OutStreamer->emitDataRegion(MCDR_DataRegionEnd);
205 InConstantPool = false;
206 }
207 if (Opc == Mips::CONSTPOOL_ENTRY) {
208 // CONSTPOOL_ENTRY - This instruction represents a floating
209 // constant pool in the function. The first operand is the ID#
210 // for this instruction, the second is the index into the
211 // MachineConstantPool that this is, the third is the size in
212 // bytes of this constant pool entry.
213 // The required alignment is specified on the basic block holding this MI.
214 //
215 unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
216 unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex();
217
218 // If this is the first entry of the pool, mark it.
219 if (!InConstantPool) {
220 OutStreamer->emitDataRegion(MCDR_DataRegion);
221 InConstantPool = true;
222 }
223
224 OutStreamer->emitLabel(GetCPISymbol(LabelId));
225
226 const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
229 else
231 return;
232 }
233
234 switch (Opc) {
235 case Mips::PATCHABLE_FUNCTION_ENTER:
237 return;
238 case Mips::PATCHABLE_FUNCTION_EXIT:
240 return;
241 case Mips::PATCHABLE_TAIL_CALL:
243 return;
244 }
245
246 if (EmitJalrReloc &&
247 (MI->isReturn() || MI->isCall() || MI->isIndirectBranch())) {
249 }
250
252 MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();
253
254 do {
255 // Do any auto-generated pseudo lowerings.
256 if (emitPseudoExpansionLowering(*OutStreamer, &*I))
257 continue;
258
259 // Skip the BUNDLE pseudo instruction and lower the contents
260 if (I->isBundle())
261 continue;
262
263 if (I->getOpcode() == Mips::PseudoReturn ||
264 I->getOpcode() == Mips::PseudoReturn64 ||
265 I->getOpcode() == Mips::PseudoIndirectBranch ||
266 I->getOpcode() == Mips::PseudoIndirectBranch64 ||
267 I->getOpcode() == Mips::TAILCALLREG ||
268 I->getOpcode() == Mips::TAILCALLREG64) {
269 emitPseudoIndirectBranch(*OutStreamer, &*I);
270 continue;
271 }
272
273 // The inMips16Mode() test is not permanent.
274 // Some instructions are marked as pseudo right now which
275 // would make the test fail for the wrong reason but
276 // that will be fixed soon. We need this here because we are
277 // removing another test for this situation downstream in the
278 // callchain.
279 //
280 if (I->isPseudo() && !Subtarget->inMips16Mode()
281 && !isLongBranchPseudo(I->getOpcode()))
282 llvm_unreachable("Pseudo opcode found in emitInstruction()");
283
284 MCInst TmpInst0;
285 MCInstLowering.Lower(&*I, TmpInst0);
286 EmitToStreamer(*OutStreamer, TmpInst0);
287 } while ((++I != E) && I->isInsideBundle()); // Delay slot check
288}
289
290//===----------------------------------------------------------------------===//
291//
292// Mips Asm Directives
293//
294// -- Frame directive "frame Stackpointer, Stacksize, RARegister"
295// Describe the stack frame.
296//
297// -- Mask directives "(f)mask bitmask, offset"
298// Tells the assembler which registers are saved and where.
299// bitmask - contain a little endian bitset indicating which registers are
300// saved on function prologue (e.g. with a 0x80000000 mask, the
301// assembler knows the register 31 (RA) is saved at prologue.
302// offset - the position before stack pointer subtraction indicating where
303// the first saved register on prologue is located. (e.g. with a
304//
305// Consider the following function prologue:
306//
307// .frame $fp,48,$ra
308// .mask 0xc0000000,-8
309// addiu $sp, $sp, -48
310// sw $ra, 40($sp)
311// sw $fp, 36($sp)
312//
313// With a 0xc0000000 mask, the assembler knows the register 31 (RA) and
314// 30 (FP) are saved at prologue. As the save order on prologue is from
315// left to right, RA is saved first. A -8 offset means that after the
316// stack pointer subtration, the first register in the mask (RA) will be
317// saved at address 48-8=40.
318//
319//===----------------------------------------------------------------------===//
320
321//===----------------------------------------------------------------------===//
322// Mask directives
323//===----------------------------------------------------------------------===//
324
325// Create a bitmask with all callee saved registers for CPU or Floating Point
326// registers. For CPU registers consider RA, GP and FP for saving if necessary.
328 // CPU and FPU Saved Registers Bitmasks
329 unsigned CPUBitmask = 0, FPUBitmask = 0;
330 int CPUTopSavedRegOff, FPUTopSavedRegOff;
331
332 // Set the CPU and FPU Bitmasks
333 const MachineFrameInfo &MFI = MF->getFrameInfo();
335 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
336 // size of stack area to which FP callee-saved regs are saved.
337 unsigned CPURegSize = TRI->getRegSizeInBits(Mips::GPR32RegClass) / 8;
338 unsigned FGR32RegSize = TRI->getRegSizeInBits(Mips::FGR32RegClass) / 8;
339 unsigned AFGR64RegSize = TRI->getRegSizeInBits(Mips::AFGR64RegClass) / 8;
340 bool HasAFGR64Reg = false;
341 unsigned CSFPRegsSize = 0;
342
343 for (const auto &I : CSI) {
344 Register Reg = I.getReg();
345 unsigned RegNum = TRI->getEncodingValue(Reg);
346
347 // If it's a floating point register, set the FPU Bitmask.
348 // If it's a general purpose register, set the CPU Bitmask.
349 if (Mips::FGR32RegClass.contains(Reg)) {
350 FPUBitmask |= (1 << RegNum);
351 CSFPRegsSize += FGR32RegSize;
352 } else if (Mips::AFGR64RegClass.contains(Reg)) {
353 FPUBitmask |= (3 << RegNum);
354 CSFPRegsSize += AFGR64RegSize;
355 HasAFGR64Reg = true;
356 } else if (Mips::GPR32RegClass.contains(Reg))
357 CPUBitmask |= (1 << RegNum);
358 }
359
360 // FP Regs are saved right below where the virtual frame pointer points to.
361 FPUTopSavedRegOff = FPUBitmask ?
362 (HasAFGR64Reg ? -AFGR64RegSize : -FGR32RegSize) : 0;
363
364 // CPU Regs are saved below FP Regs.
365 CPUTopSavedRegOff = CPUBitmask ? -CSFPRegsSize - CPURegSize : 0;
366
367 MipsTargetStreamer &TS = getTargetStreamer();
368 // Print CPUBitmask
369 TS.emitMask(CPUBitmask, CPUTopSavedRegOff);
370
371 // Print FPUBitmask
372 TS.emitFMask(FPUBitmask, FPUTopSavedRegOff);
373}
374
375//===----------------------------------------------------------------------===//
376// Frame and Set directives
377//===----------------------------------------------------------------------===//
378
379/// Frame Directive
382
383 Register stackReg = RI.getFrameRegister(*MF);
384 unsigned returnReg = RI.getRARegister();
385 unsigned stackSize = MF->getFrameInfo().getStackSize();
386
387 getTargetStreamer().emitFrame(stackReg, stackSize, returnReg);
388}
389
390/// Emit Set directives.
392 switch (static_cast<MipsTargetMachine &>(TM).getABI().GetEnumValue()) {
393 case MipsABIInfo::ABI::O32: return "abi32";
394 case MipsABIInfo::ABI::N32: return "abiN32";
395 case MipsABIInfo::ABI::N64: return "abi64";
396 default: llvm_unreachable("Unknown Mips ABI");
397 }
398}
399
401 MipsTargetStreamer &TS = getTargetStreamer();
402
403 // NaCl sandboxing requires that indirect call instructions are masked.
404 // This means that function entry points should be bundle-aligned.
405 if (Subtarget->isTargetNaCl())
407
408 if (Subtarget->inMicroMipsMode()) {
410 TS.setUsesMicroMips();
412 } else
414
415 if (Subtarget->inMips16Mode())
417 else
419
421 OutStreamer->emitLabel(CurrentFnSym);
422}
423
424/// EmitFunctionBodyStart - Targets can override this to emit stuff before
425/// the first basic block in the function.
427 MipsTargetStreamer &TS = getTargetStreamer();
428
430
431 bool IsNakedFunction = MF->getFunction().hasFnAttribute(Attribute::Naked);
432 if (!IsNakedFunction)
434
435 if (!IsNakedFunction)
437
438 if (!Subtarget->inMips16Mode()) {
442 }
443}
444
445/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
446/// the last basic block in the function.
448 MipsTargetStreamer &TS = getTargetStreamer();
449
450 // There are instruction for this macros, but they must
451 // always be at the function end, and we can't emit and
452 // break with BB logic.
453 if (!Subtarget->inMips16Mode()) {
457 }
459 // Make sure to terminate any constant pools that were at the end
460 // of the function.
461 if (!InConstantPool)
462 return;
463 InConstantPool = false;
464 OutStreamer->emitDataRegion(MCDR_DataRegionEnd);
465}
466
469 MipsTargetStreamer &TS = getTargetStreamer();
470 if (MBB.empty())
472}
473
474/// isBlockOnlyReachableByFallthough - Return true if the basic block has
475/// exactly one predecessor and the control transfer mechanism between
476/// the predecessor and this block is a fall-through.
478 MBB) const {
479 // The predecessor has to be immediately before this block.
480 const MachineBasicBlock *Pred = *MBB->pred_begin();
481
482 // If the predecessor is a switch statement, assume a jump table
483 // implementation, so it is not a fall through.
484 if (const BasicBlock *bb = Pred->getBasicBlock())
485 if (isa<SwitchInst>(bb->getTerminator()))
486 return false;
487
488 // If this is a landing pad, it isn't a fall through. If it has no preds,
489 // then nothing falls through to it.
490 if (MBB->isEHPad() || MBB->pred_empty())
491 return false;
492
493 // If there isn't exactly one predecessor, it can't be a fall through.
495 ++PI2;
496
497 if (PI2 != MBB->pred_end())
498 return false;
499
500 // The predecessor has to be immediately before this block.
501 if (!Pred->isLayoutSuccessor(MBB))
502 return false;
503
504 // If the block is completely empty, then it definitely does fall through.
505 if (Pred->empty())
506 return true;
507
508 // Otherwise, check the last instruction.
509 // Check if the last terminator is an unconditional branch.
511 while (I != Pred->begin() && !(--I)->isTerminator()) ;
512
513 return !I->isBarrier();
514}
515
516// Print out an operand for an inline asm expression.
518 const char *ExtraCode, raw_ostream &O) {
519 // Does this asm operand have a single letter operand modifier?
520 if (ExtraCode && ExtraCode[0]) {
521 if (ExtraCode[1] != 0) return true; // Unknown modifier.
522
523 const MachineOperand &MO = MI->getOperand(OpNum);
524 switch (ExtraCode[0]) {
525 default:
526 // See if this is a generic print operand
527 return AsmPrinter::PrintAsmOperand(MI, OpNum, ExtraCode, O);
528 case 'X': // hex const int
529 if (!MO.isImm())
530 return true;
531 O << "0x" << Twine::utohexstr(MO.getImm());
532 return false;
533 case 'x': // hex const int (low 16 bits)
534 if (!MO.isImm())
535 return true;
536 O << "0x" << Twine::utohexstr(MO.getImm() & 0xffff);
537 return false;
538 case 'd': // decimal const int
539 if (!MO.isImm())
540 return true;
541 O << MO.getImm();
542 return false;
543 case 'm': // decimal const int minus 1
544 if (!MO.isImm())
545 return true;
546 O << MO.getImm() - 1;
547 return false;
548 case 'y': // exact log2
549 if (!MO.isImm())
550 return true;
551 if (!isPowerOf2_64(MO.getImm()))
552 return true;
553 O << Log2_64(MO.getImm());
554 return false;
555 case 'z':
556 // $0 if zero, regular printing otherwise
557 if (MO.isImm() && MO.getImm() == 0) {
558 O << "$0";
559 return false;
560 }
561 // If not, call printOperand as normal.
562 break;
563 case 'D': // Second part of a double word register operand
564 case 'L': // Low order register of a double word register operand
565 case 'M': // High order register of a double word register operand
566 {
567 if (OpNum == 0)
568 return true;
569 const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1);
570 if (!FlagsOP.isImm())
571 return true;
572 const InlineAsm::Flag Flags(FlagsOP.getImm());
573 const unsigned NumVals = Flags.getNumOperandRegisters();
574 // Number of registers represented by this operand. We are looking
575 // for 2 for 32 bit mode and 1 for 64 bit mode.
576 if (NumVals != 2) {
577 if (Subtarget->isGP64bit() && NumVals == 1 && MO.isReg()) {
578 Register Reg = MO.getReg();
579 O << '$' << MipsInstPrinter::getRegisterName(Reg);
580 return false;
581 }
582 return true;
583 }
584
585 unsigned RegOp = OpNum;
586 if (!Subtarget->isGP64bit()){
587 // Endianness reverses which register holds the high or low value
588 // between M and L.
589 switch(ExtraCode[0]) {
590 case 'M':
591 RegOp = (Subtarget->isLittle()) ? OpNum + 1 : OpNum;
592 break;
593 case 'L':
594 RegOp = (Subtarget->isLittle()) ? OpNum : OpNum + 1;
595 break;
596 case 'D': // Always the second part
597 RegOp = OpNum + 1;
598 }
599 if (RegOp >= MI->getNumOperands())
600 return true;
601 const MachineOperand &MO = MI->getOperand(RegOp);
602 if (!MO.isReg())
603 return true;
604 Register Reg = MO.getReg();
605 O << '$' << MipsInstPrinter::getRegisterName(Reg);
606 return false;
607 }
608 break;
609 }
610 case 'w':
611 // Print MSA registers for the 'f' constraint
612 // In LLVM, the 'w' modifier doesn't need to do anything.
613 // We can just call printOperand as normal.
614 break;
615 }
616 }
617
618 printOperand(MI, OpNum, O);
619 return false;
620}
621
623 unsigned OpNum,
624 const char *ExtraCode,
625 raw_ostream &O) {
626 assert(OpNum + 1 < MI->getNumOperands() && "Insufficient operands");
627 const MachineOperand &BaseMO = MI->getOperand(OpNum);
628 const MachineOperand &OffsetMO = MI->getOperand(OpNum + 1);
629 assert(BaseMO.isReg() &&
630 "Unexpected base pointer for inline asm memory operand.");
631 assert(OffsetMO.isImm() &&
632 "Unexpected offset for inline asm memory operand.");
633 int Offset = OffsetMO.getImm();
634
635 // Currently we are expecting either no ExtraCode or 'D','M','L'.
636 if (ExtraCode) {
637 switch (ExtraCode[0]) {
638 case 'D':
639 Offset += 4;
640 break;
641 case 'M':
642 if (Subtarget->isLittle())
643 Offset += 4;
644 break;
645 case 'L':
646 if (!Subtarget->isLittle())
647 Offset += 4;
648 break;
649 default:
650 return true; // Unknown modifier.
651 }
652 }
653
654 O << Offset << "($" << MipsInstPrinter::getRegisterName(BaseMO.getReg())
655 << ")";
656
657 return false;
658}
659
661 raw_ostream &O) {
662 const MachineOperand &MO = MI->getOperand(opNum);
663 bool closeP = false;
664
665 if (MO.getTargetFlags())
666 closeP = true;
667
668 switch(MO.getTargetFlags()) {
669 case MipsII::MO_GPREL: O << "%gp_rel("; break;
670 case MipsII::MO_GOT_CALL: O << "%call16("; break;
671 case MipsII::MO_GOT: O << "%got("; break;
672 case MipsII::MO_ABS_HI: O << "%hi("; break;
673 case MipsII::MO_ABS_LO: O << "%lo("; break;
674 case MipsII::MO_HIGHER: O << "%higher("; break;
675 case MipsII::MO_HIGHEST: O << "%highest(("; break;
676 case MipsII::MO_TLSGD: O << "%tlsgd("; break;
677 case MipsII::MO_GOTTPREL: O << "%gottprel("; break;
678 case MipsII::MO_TPREL_HI: O << "%tprel_hi("; break;
679 case MipsII::MO_TPREL_LO: O << "%tprel_lo("; break;
680 case MipsII::MO_GPOFF_HI: O << "%hi(%neg(%gp_rel("; break;
681 case MipsII::MO_GPOFF_LO: O << "%lo(%neg(%gp_rel("; break;
682 case MipsII::MO_GOT_DISP: O << "%got_disp("; break;
683 case MipsII::MO_GOT_PAGE: O << "%got_page("; break;
684 case MipsII::MO_GOT_OFST: O << "%got_ofst("; break;
685 }
686
687 switch (MO.getType()) {
689 O << '$'
691 break;
692
694 O << MO.getImm();
695 break;
696
698 MO.getMBB()->getSymbol()->print(O, MAI);
699 return;
700
702 PrintSymbolOperand(MO, O);
703 break;
704
707 O << BA->getName();
708 break;
709 }
710
712 O << getDataLayout().getPrivateGlobalPrefix() << "CPI"
713 << getFunctionNumber() << "_" << MO.getIndex();
714 if (MO.getOffset())
715 O << "+" << MO.getOffset();
716 break;
717
718 default:
719 llvm_unreachable("<unknown operand type>");
720 }
721
722 if (closeP) O << ")";
723}
724
726printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O) {
727 // Load/Store memory operands -- imm($reg)
728 // If PIC target the target is loaded as the
729 // pattern lw $25,%call16($28)
730
731 // opNum can be invalid if instruction has reglist as operand.
732 // MemOperand is always last operand of instruction (base + offset).
733 switch (MI->getOpcode()) {
734 default:
735 break;
736 case Mips::SWM32_MM:
737 case Mips::LWM32_MM:
738 opNum = MI->getNumOperands() - 2;
739 break;
740 }
741
742 printOperand(MI, opNum+1, O);
743 O << "(";
744 printOperand(MI, opNum, O);
745 O << ")";
746}
747
749printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O) {
750 // when using stack locations for not load/store instructions
751 // print the same way as all normal 3 operand instructions.
752 printOperand(MI, opNum, O);
753 O << ", ";
754 printOperand(MI, opNum+1, O);
755}
756
758printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
759 const char *Modifier) {
760 const MachineOperand &MO = MI->getOperand(opNum);
762}
763
765printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O) {
766 for (int i = opNum, e = MI->getNumOperands(); i != e; ++i) {
767 if (i != opNum) O << ", ";
768 printOperand(MI, i, O);
769 }
770}
771
773 MipsTargetStreamer &TS = getTargetStreamer();
774
775 // MipsTargetStreamer has an initialization order problem when emitting an
776 // object file directly (see MipsTargetELFStreamer for full details). Work
777 // around it by re-initializing the PIC state here.
779
780 // Try to get target-features from the first function.
782 Module::iterator F = M.begin();
783 if (FS.empty() && M.size() && F->hasFnAttribute("target-features"))
784 FS = F->getFnAttribute("target-features").getValueAsString();
785
786 // Compute MIPS architecture attributes based on the default subtarget
787 // that we'd have constructed.
788 // FIXME: For ifunc related functions we could iterate over and look
789 // for a feature string that doesn't match the default one.
790 const Triple &TT = TM.getTargetTriple();
792 const MipsTargetMachine &MTM = static_cast<const MipsTargetMachine &>(TM);
793 const MipsSubtarget STI(TT, CPU, FS, MTM.isLittleEndian(), MTM, std::nullopt);
794
795 bool IsABICalls = STI.isABICalls();
796 const MipsABIInfo &ABI = MTM.getABI();
797 if (IsABICalls) {
799 // FIXME: This condition should be a lot more complicated that it is here.
800 // Ideally it should test for properties of the ABI and not the ABI
801 // itself.
802 // For the moment, I'm only correcting enough to make MIPS-IV work.
803 if (!isPositionIndependent() && STI.hasSym32())
805 }
806
807 // Tell the assembler which ABI we are using
808 std::string SectionName = std::string(".mdebug.") + getCurrentABIString();
809 OutStreamer->switchSection(
811
812 // NaN: At the moment we only support:
813 // 1. .nan legacy (default)
814 // 2. .nan 2008
817
818 // TODO: handle O64 ABI
819
820 TS.updateABIInfo(STI);
821
822 // We should always emit a '.module fp=...' but binutils 2.24 does not accept
823 // it. We therefore emit it when it contradicts the ABI defaults (-mfpxx or
824 // -mfp64) and omit it otherwise.
825 if ((ABI.IsO32() && (STI.isABI_FPXX() || STI.isFP64bit())) ||
826 STI.useSoftFloat())
828
829 // We should always emit a '.module [no]oddspreg' but binutils 2.24 does not
830 // accept it. We therefore emit it when it contradicts the default or an
831 // option has changed the default (i.e. FPXX) and omit it otherwise.
832 if (ABI.IsO32() && (!STI.useOddSPReg() || STI.isABI_FPXX()))
834
835 // Switch to the .text section.
836 OutStreamer->switchSection(getObjFileLowering().getTextSection());
837}
838
839void MipsAsmPrinter::emitInlineAsmStart() const {
840 MipsTargetStreamer &TS = getTargetStreamer();
841
842 // GCC's choice of assembler options for inline assembly code ('at', 'macro'
843 // and 'reorder') is different from LLVM's choice for generated code ('noat',
844 // 'nomacro' and 'noreorder').
845 // In order to maintain compatibility with inline assembly code which depends
846 // on GCC's assembler options being used, we have to switch to those options
847 // for the duration of the inline assembly block and then switch back.
852 OutStreamer->addBlankLine();
853}
854
855void MipsAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
856 const MCSubtargetInfo *EndInfo) const {
857 OutStreamer->addBlankLine();
858 getTargetStreamer().emitDirectiveSetPop();
859}
860
861void MipsAsmPrinter::EmitJal(const MCSubtargetInfo &STI, MCSymbol *Symbol) {
862 MCInst I;
863 I.setOpcode(Mips::JAL);
864 I.addOperand(
866 OutStreamer->emitInstruction(I, STI);
867}
868
869void MipsAsmPrinter::EmitInstrReg(const MCSubtargetInfo &STI, unsigned Opcode,
870 unsigned Reg) {
871 MCInst I;
872 I.setOpcode(Opcode);
873 I.addOperand(MCOperand::createReg(Reg));
874 OutStreamer->emitInstruction(I, STI);
875}
876
877void MipsAsmPrinter::EmitInstrRegReg(const MCSubtargetInfo &STI,
878 unsigned Opcode, unsigned Reg1,
879 unsigned Reg2) {
880 MCInst I;
881 //
882 // Because of the current td files for Mips32, the operands for MTC1
883 // appear backwards from their normal assembly order. It's not a trivial
884 // change to fix this in the td file so we adjust for it here.
885 //
886 if (Opcode == Mips::MTC1) {
887 unsigned Temp = Reg1;
888 Reg1 = Reg2;
889 Reg2 = Temp;
890 }
891 I.setOpcode(Opcode);
892 I.addOperand(MCOperand::createReg(Reg1));
893 I.addOperand(MCOperand::createReg(Reg2));
894 OutStreamer->emitInstruction(I, STI);
895}
896
897void MipsAsmPrinter::EmitInstrRegRegReg(const MCSubtargetInfo &STI,
898 unsigned Opcode, unsigned Reg1,
899 unsigned Reg2, unsigned Reg3) {
900 MCInst I;
901 I.setOpcode(Opcode);
902 I.addOperand(MCOperand::createReg(Reg1));
903 I.addOperand(MCOperand::createReg(Reg2));
904 I.addOperand(MCOperand::createReg(Reg3));
905 OutStreamer->emitInstruction(I, STI);
906}
907
908void MipsAsmPrinter::EmitMovFPIntPair(const MCSubtargetInfo &STI,
909 unsigned MovOpc, unsigned Reg1,
910 unsigned Reg2, unsigned FPReg1,
911 unsigned FPReg2, bool LE) {
912 if (!LE) {
913 unsigned temp = Reg1;
914 Reg1 = Reg2;
915 Reg2 = temp;
916 }
917 EmitInstrRegReg(STI, MovOpc, Reg1, FPReg1);
918 EmitInstrRegReg(STI, MovOpc, Reg2, FPReg2);
919}
920
921void MipsAsmPrinter::EmitSwapFPIntParams(const MCSubtargetInfo &STI,
923 bool LE, bool ToFP) {
924 using namespace Mips16HardFloatInfo;
925
926 unsigned MovOpc = ToFP ? Mips::MTC1 : Mips::MFC1;
927 switch (PV) {
928 case FSig:
929 EmitInstrRegReg(STI, MovOpc, Mips::A0, Mips::F12);
930 break;
931 case FFSig:
932 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F14, LE);
933 break;
934 case FDSig:
935 EmitInstrRegReg(STI, MovOpc, Mips::A0, Mips::F12);
936 EmitMovFPIntPair(STI, MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE);
937 break;
938 case DSig:
939 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
940 break;
941 case DDSig:
942 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
943 EmitMovFPIntPair(STI, MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE);
944 break;
945 case DFSig:
946 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
947 EmitInstrRegReg(STI, MovOpc, Mips::A2, Mips::F14);
948 break;
949 case NoSig:
950 return;
951 }
952}
953
954void MipsAsmPrinter::EmitSwapFPIntRetval(
956 bool LE) {
957 using namespace Mips16HardFloatInfo;
958
959 unsigned MovOpc = Mips::MFC1;
960 switch (RV) {
961 case FRet:
962 EmitInstrRegReg(STI, MovOpc, Mips::V0, Mips::F0);
963 break;
964 case DRet:
965 EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
966 break;
967 case CFRet:
968 EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
969 break;
970 case CDRet:
971 EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
972 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F2, Mips::F3, LE);
973 break;
974 case NoFPRet:
975 break;
976 }
977}
978
979void MipsAsmPrinter::EmitFPCallStub(
980 const char *Symbol, const Mips16HardFloatInfo::FuncSignature *Signature) {
981 using namespace Mips16HardFloatInfo;
982
985 // Construct a local MCSubtargetInfo here.
986 // This is because the MachineFunction won't exist (but have not yet been
987 // freed) and since we're at the global level we can use the default
988 // constructed subtarget.
989 std::unique_ptr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo(
992
993 //
994 // .global xxxx
995 //
996 OutStreamer->emitSymbolAttribute(MSymbol, MCSA_Global);
997 const char *RetType;
998 //
999 // make the comment field identifying the return and parameter
1000 // types of the floating point stub
1001 // # Stub function to call rettype xxxx (params)
1002 //
1003 switch (Signature->RetSig) {
1004 case FRet:
1005 RetType = "float";
1006 break;
1007 case DRet:
1008 RetType = "double";
1009 break;
1010 case CFRet:
1011 RetType = "complex";
1012 break;
1013 case CDRet:
1014 RetType = "double complex";
1015 break;
1016 case NoFPRet:
1017 RetType = "";
1018 break;
1019 }
1020 const char *Parms;
1021 switch (Signature->ParamSig) {
1022 case FSig:
1023 Parms = "float";
1024 break;
1025 case FFSig:
1026 Parms = "float, float";
1027 break;
1028 case FDSig:
1029 Parms = "float, double";
1030 break;
1031 case DSig:
1032 Parms = "double";
1033 break;
1034 case DDSig:
1035 Parms = "double, double";
1036 break;
1037 case DFSig:
1038 Parms = "double, float";
1039 break;
1040 case NoSig:
1041 Parms = "";
1042 break;
1043 }
1044 OutStreamer->AddComment("\t# Stub function to call " + Twine(RetType) + " " +
1045 Twine(Symbol) + " (" + Twine(Parms) + ")");
1046 //
1047 // probably not necessary but we save and restore the current section state
1048 //
1049 OutStreamer->pushSection();
1050 //
1051 // .section mips16.call.fpxxxx,"ax",@progbits
1052 //
1054 ".mips16.call.fp." + std::string(Symbol), ELF::SHT_PROGBITS,
1056 OutStreamer->switchSection(M, nullptr);
1057 //
1058 // .align 2
1059 //
1060 OutStreamer->emitValueToAlignment(Align(4));
1061 MipsTargetStreamer &TS = getTargetStreamer();
1062 //
1063 // .set nomips16
1064 // .set nomicromips
1065 //
1068 //
1069 // .ent __call_stub_fp_xxxx
1070 // .type __call_stub_fp_xxxx,@function
1071 // __call_stub_fp_xxxx:
1072 //
1073 std::string x = "__call_stub_fp_" + std::string(Symbol);
1074 MCSymbolELF *Stub =
1075 cast<MCSymbolELF>(OutContext.getOrCreateSymbol(StringRef(x)));
1076 TS.emitDirectiveEnt(*Stub);
1077 MCSymbol *MType =
1078 OutContext.getOrCreateSymbol("__call_stub_fp_" + Twine(Symbol));
1079 OutStreamer->emitSymbolAttribute(MType, MCSA_ELF_TypeFunction);
1080 OutStreamer->emitLabel(Stub);
1081
1082 // Only handle non-pic for now.
1084 "should not be here if we are compiling pic");
1086 //
1087 // We need to add a MipsMCExpr class to MCTargetDesc to fully implement
1088 // stubs without raw text but this current patch is for compiler generated
1089 // functions and they all return some value.
1090 // The calling sequence for non pic is different in that case and we need
1091 // to implement %lo and %hi in order to handle the case of no return value
1092 // See the corresponding method in Mips16HardFloat for details.
1093 //
1094 // mov the return address to S2.
1095 // we have no stack space to store it and we are about to make another call.
1096 // We need to make sure that the enclosing function knows to save S2
1097 // This should have already been handled.
1098 //
1099 // Mov $18, $31
1100
1101 EmitInstrRegRegReg(*STI, Mips::OR, Mips::S2, Mips::RA, Mips::ZERO);
1102
1103 EmitSwapFPIntParams(*STI, Signature->ParamSig, LE, true);
1104
1105 // Jal xxxx
1106 //
1107 EmitJal(*STI, MSymbol);
1108
1109 // fix return values
1110 EmitSwapFPIntRetval(*STI, Signature->RetSig, LE);
1111 //
1112 // do the return
1113 // if (Signature->RetSig == NoFPRet)
1114 // llvm_unreachable("should not be any stubs here with no return value");
1115 // else
1116 EmitInstrReg(*STI, Mips::JR, Mips::S2);
1117
1119 OutStreamer->emitLabel(Tmp);
1122 const MCExpr *T_min_E = MCBinaryExpr::createSub(T, E, OutContext);
1123 OutStreamer->emitELFSize(Stub, T_min_E);
1124 TS.emitDirectiveEnd(x);
1125 OutStreamer->popSection();
1126}
1127
1129 // Emit needed stubs
1130 //
1131 for (std::map<
1132 const char *,
1134 it = StubsNeeded.begin();
1135 it != StubsNeeded.end(); ++it) {
1136 const char *Symbol = it->first;
1137 const Mips16HardFloatInfo::FuncSignature *Signature = it->second;
1138 EmitFPCallStub(Symbol, Signature);
1139 }
1140 // return to the text section
1142}
1143
1144void MipsAsmPrinter::EmitSled(const MachineInstr &MI, SledKind Kind) {
1145 const uint8_t NoopsInSledCount = Subtarget->isGP64bit() ? 15 : 11;
1146 // For mips32 we want to emit the following pattern:
1147 //
1148 // .Lxray_sled_N:
1149 // ALIGN
1150 // B .tmpN
1151 // 11 NOP instructions (44 bytes)
1152 // ADDIU T9, T9, 52
1153 // .tmpN
1154 //
1155 // We need the 44 bytes (11 instructions) because at runtime, we'd
1156 // be patching over the full 48 bytes (12 instructions) with the following
1157 // pattern:
1158 //
1159 // ADDIU SP, SP, -8
1160 // NOP
1161 // SW RA, 4(SP)
1162 // SW T9, 0(SP)
1163 // LUI T9, %hi(__xray_FunctionEntry/Exit)
1164 // ORI T9, T9, %lo(__xray_FunctionEntry/Exit)
1165 // LUI T0, %hi(function_id)
1166 // JALR T9
1167 // ORI T0, T0, %lo(function_id)
1168 // LW T9, 0(SP)
1169 // LW RA, 4(SP)
1170 // ADDIU SP, SP, 8
1171 //
1172 // We add 52 bytes to t9 because we want to adjust the function pointer to
1173 // the actual start of function i.e. the address just after the noop sled.
1174 // We do this because gp displacement relocation is emitted at the start of
1175 // of the function i.e after the nop sled and to correctly calculate the
1176 // global offset table address, t9 must hold the address of the instruction
1177 // containing the gp displacement relocation.
1178 // FIXME: Is this correct for the static relocation model?
1179 //
1180 // For mips64 we want to emit the following pattern:
1181 //
1182 // .Lxray_sled_N:
1183 // ALIGN
1184 // B .tmpN
1185 // 15 NOP instructions (60 bytes)
1186 // .tmpN
1187 //
1188 // We need the 60 bytes (15 instructions) because at runtime, we'd
1189 // be patching over the full 64 bytes (16 instructions) with the following
1190 // pattern:
1191 //
1192 // DADDIU SP, SP, -16
1193 // NOP
1194 // SD RA, 8(SP)
1195 // SD T9, 0(SP)
1196 // LUI T9, %highest(__xray_FunctionEntry/Exit)
1197 // ORI T9, T9, %higher(__xray_FunctionEntry/Exit)
1198 // DSLL T9, T9, 16
1199 // ORI T9, T9, %hi(__xray_FunctionEntry/Exit)
1200 // DSLL T9, T9, 16
1201 // ORI T9, T9, %lo(__xray_FunctionEntry/Exit)
1202 // LUI T0, %hi(function_id)
1203 // JALR T9
1204 // ADDIU T0, T0, %lo(function_id)
1205 // LD T9, 0(SP)
1206 // LD RA, 8(SP)
1207 // DADDIU SP, SP, 16
1208 //
1209 OutStreamer->emitCodeAlignment(Align(4), &getSubtargetInfo());
1210 auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
1211 OutStreamer->emitLabel(CurSled);
1213
1214 // Emit "B .tmpN" instruction, which jumps over the nop sled to the actual
1215 // start of function
1216 const MCExpr *TargetExpr = MCSymbolRefExpr::create(
1219 .addReg(Mips::ZERO)
1220 .addReg(Mips::ZERO)
1221 .addExpr(TargetExpr));
1222
1223 for (int8_t I = 0; I < NoopsInSledCount; I++)
1225 .addReg(Mips::ZERO)
1226 .addReg(Mips::ZERO)
1227 .addImm(0));
1228
1229 OutStreamer->emitLabel(Target);
1230
1231 if (!Subtarget->isGP64bit()) {
1233 MCInstBuilder(Mips::ADDiu)
1234 .addReg(Mips::T9)
1235 .addReg(Mips::T9)
1236 .addImm(0x34));
1237 }
1238
1239 recordSled(CurSled, MI, Kind, 2);
1240}
1241
1243 EmitSled(MI, SledKind::FUNCTION_ENTER);
1244}
1245
1247 EmitSled(MI, SledKind::FUNCTION_EXIT);
1248}
1249
1251 EmitSled(MI, SledKind::TAIL_CALL);
1252}
1253
1255 raw_ostream &OS) {
1256 // TODO: implement
1257}
1258
1259// Emit .dtprelword or .dtpreldword directive
1260// and value for debug thread local expression.
1261void MipsAsmPrinter::emitDebugValue(const MCExpr *Value, unsigned Size) const {
1262 if (auto *MipsExpr = dyn_cast<MipsMCExpr>(Value)) {
1263 if (MipsExpr && MipsExpr->getKind() == MipsMCExpr::MEK_DTPREL) {
1264 switch (Size) {
1265 case 4:
1266 OutStreamer->emitDTPRel32Value(MipsExpr->getSubExpr());
1267 break;
1268 case 8:
1269 OutStreamer->emitDTPRel64Value(MipsExpr->getSubExpr());
1270 break;
1271 default:
1272 llvm_unreachable("Unexpected size of expression value.");
1273 }
1274 return;
1275 }
1276 }
1278}
1279
1280// Align all targets of indirect branches on bundle size. Used only if target
1281// is NaCl.
1282void MipsAsmPrinter::NaClAlignIndirectJumpTargets(MachineFunction &MF) {
1283 // Align all blocks that are jumped to through jump table.
1284 if (MachineJumpTableInfo *JtInfo = MF.getJumpTableInfo()) {
1285 const std::vector<MachineJumpTableEntry> &JT = JtInfo->getJumpTables();
1286 for (const auto &I : JT) {
1287 const std::vector<MachineBasicBlock *> &MBBs = I.MBBs;
1288
1289 for (MachineBasicBlock *MBB : MBBs)
1291 }
1292 }
1293
1294 // If basic block address is taken, block can be target of indirect branch.
1295 for (auto &MBB : MF) {
1296 if (MBB.hasAddressTaken())
1298 }
1299}
1300
1301bool MipsAsmPrinter::isLongBranchPseudo(int Opcode) const {
1302 return (Opcode == Mips::LONG_BRANCH_LUi
1303 || Opcode == Mips::LONG_BRANCH_LUi2Op
1304 || Opcode == Mips::LONG_BRANCH_LUi2Op_64
1305 || Opcode == Mips::LONG_BRANCH_ADDiu
1306 || Opcode == Mips::LONG_BRANCH_ADDiu2Op
1307 || Opcode == Mips::LONG_BRANCH_DADDiu
1308 || Opcode == Mips::LONG_BRANCH_DADDiu2Op);
1309}
1310
1311// Force static initialization.
1317}
MachineBasicBlock & MBB
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:135
uint64_t Size
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
unsigned const TargetRegisterInfo * TRI
@ CDRet
@ NoFPRet
@ DRet
@ CFRet
@ FRet
@ DDSig
@ DFSig
@ FDSig
@ NoSig
@ FFSig
@ DSig
@ FSig
cl::opt< bool > EmitJalrReloc
static void emitDirectiveRelocJalr(const MachineInstr &MI, MCContext &OutContext, TargetMachine &TM, MCStreamer &OutStreamer, const MipsSubtarget &Subtarget)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsAsmPrinter()
cl::opt< bool > EmitJalrReloc
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
This file defines the SmallString class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:470
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
Definition: AsmPrinter.cpp:381
virtual void emitDebugValue(const MCExpr *Value, unsigned Size) const
Emit the directive and value for debug thread local expression.
Definition: AsmPrinter.cpp:895
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
Definition: AsmPrinter.cpp:401
TargetMachine & TM
Target machine description.
Definition: AsmPrinter.h:88
void emitXRayTable()
Emit a table with all XRay instrumentation points.
virtual void emitBasicBlockEnd(const MachineBasicBlock &MBB)
Targets can override this to emit stuff at the end of a basic block.
virtual MCSymbol * GetCPISymbol(unsigned CPID) const
Return the symbol for the specified constant pool entry.
virtual void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS)
Print the MachineOperand as a symbol.
const MCAsmInfo * MAI
Target Asm Printer information.
Definition: AsmPrinter.h:91
MachineFunction * MF
The current machine function.
Definition: AsmPrinter.h:103
virtual void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV)
void recordSled(MCSymbol *Sled, const MachineInstr &MI, SledKind Kind, uint8_t Version=0)
unsigned getFunctionNumber() const
Return a unique ID for the current function.
Definition: AsmPrinter.cpp:377
void emitGlobalConstant(const DataLayout &DL, const Constant *CV, AliasMapTy *AliasList=nullptr)
EmitGlobalConstant - Print a general LLVM constant to the .s file.
MCSymbol * CurrentFnSym
The symbol for the current function.
Definition: AsmPrinter.h:122
void emitAlignment(Align Alignment, const GlobalObject *GV=nullptr, unsigned MaxBytesToEmit=0) const
Emit an alignment directive to the specified power of two boundary.
MCContext & OutContext
This is the context for the output file that we are streaming.
Definition: AsmPrinter.h:95
bool isPositionIndependent() const
Definition: AsmPrinter.cpp:372
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
Definition: AsmPrinter.h:400
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition: AsmPrinter.h:100
MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const
Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.
const DataLayout & getDataLayout() const
Return information about data layout.
Definition: AsmPrinter.cpp:385
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
Definition: AsmPrinter.cpp:396
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.
LLVM Basic Block Representation.
Definition: BasicBlock.h:56
bool isLittleEndian() const
Layout endianness...
Definition: DataLayout.h:238
StringRef getPrivateGlobalPrefix() const
Definition: DataLayout.h:332
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:645
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:613
Context object for machine code objects.
Definition: MCContext.h:76
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:450
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:322
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition: MCContext.h:565
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
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
bool isPositionIndependent() const
MCSection * getTextSection() const
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
bool isValid() const
Definition: MCInst.h:60
MCRegister getRARegister() const
This method should return the register where the return address can be found.
This represents a section on linux, lots of unix variants and some bare metal systems.
Definition: MCSectionELF.h:26
Streaming machine code generation interface.
Definition: MCStreamer.h:212
virtual std::optional< std::pair< bool, std::string > > emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, SMLoc Loc, const MCSubtargetInfo &STI)
Record a relocation described by the .reloc directive.
Definition: MCStreamer.h:1097
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:424
Generic base class for all target subtargets.
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:389
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition: MCSymbol.cpp:58
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:206
bool isEHPad() const
Returns true if the block is a landing pad.
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
std::vector< MachineBasicBlock * >::const_iterator const_pred_iterator
bool hasAddressTaken() const
Test whether this block is used as something other than the target of a terminator,...
void setAlignment(Align A)
Set alignment of the basic block.
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
This class is a data container for one entry in a MachineConstantPool.
bool isMachineConstantPoolEntry() const
isMachineConstantPoolEntry - Return true if the MachineConstantPoolEntry is indeed a target specific ...
MachineConstantPoolValue * MachineCPVal
union llvm::MachineConstantPoolEntry::@195 Val
The constant itself.
const std::vector< MachineConstantPoolEntry > & getConstants() const
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
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
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Align getAlignment() const
getAlignment - Return the alignment of the function.
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...
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
Representation of each machine instruction.
Definition: MachineInstr.h:68
MachineOperand class - Representation of each machine instruction operand.
bool isMCSymbol() const
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
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.
Register getReg() const
getReg - Returns the register number.
MCSymbol * getMCSymbol() const
@ 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.
int64_t getOffset() const
Return the offset from the symbol in this operand.
void emitFunctionBodyStart() override
EmitFunctionBodyStart - Targets can override this to emit stuff before the first basic block in the f...
void emitDebugValue(const MCExpr *Value, unsigned Size) const override
Emit the directive and value for debug thread local expression.
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &O) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
void emitBasicBlockEnd(const MachineBasicBlock &MBB) override
Targets can override this to emit stuff at the end of a basic block.
void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI)
const char * getCurrentABIString() const
Emit Set directives.
void printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O)
void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS)
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
void emitFunctionBodyEnd() override
EmitFunctionBodyEnd - Targets can override this to emit stuff after the last basic block in the funct...
MipsMCInstLower MCInstLowering
void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O)
void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI)
void printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O, const char *Modifier=nullptr)
const MipsSubtarget * Subtarget
const MipsFunctionInfo * MipsFI
void emitEndOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the end of their file...
bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const override
isBlockOnlyReachableByFallthough - Return true if the basic block has exactly one predecessor and the...
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, const char *ExtraCode, raw_ostream &O) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI)
void emitFrameDirective()
Frame Directive.
void emitStartOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the start of their fi...
void printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O)
void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O)
void emitFunctionEntryLabel() override
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
void emitInstruction(const MachineInstr *MI) override
Targets should implement this to emit instructions.
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
std::map< const char *, const Mips16HardFloatInfo::FuncSignature * > StubsNeeded
static const char * getRegisterName(MCRegister Reg)
void Lower(const MachineInstr *MI, MCInst &OutMI) const
MCOperand LowerOperand(const MachineOperand &MO, int64_t offset=0) const
void Initialize(MCContext *C)
bool hasMips32r6() const
bool isFP64bit() const
bool isLittle() const
bool inMicroMipsMode() const
bool useSoftFloat() const
bool hasMips64r6() const
bool isNaN2008() const
bool useOddSPReg() const
bool inMips16Mode() const
bool hasSym32() const
bool isABI_FPXX() const
bool isABICalls() const
bool isGP64bit() const
bool isTargetNaCl() const
const MipsABIInfo & getABI() const
virtual void emitDirectiveSetReorder()
virtual void emitDirectiveSetNoMicroMips()
virtual void emitDirectiveEnd(StringRef Name)
virtual void emitDirectiveSetMacro()
virtual void emitDirectiveEnt(const MCSymbol &Symbol)
virtual void emitDirectiveSetNoMips16()
virtual void setPic(bool Value)
virtual void emitFrame(unsigned StackReg, unsigned StackSize, unsigned ReturnReg)
void updateABIInfo(const PredicateLibrary &P)
virtual void emitDirectiveNaNLegacy()
virtual void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff)
virtual void emitDirectiveSetMicroMips()
virtual void emitDirectiveSetNoMacro()
virtual void emitDirectiveModuleOddSPReg()
virtual void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff)
virtual void emitDirectiveSetNoReorder()
virtual void emitDirectiveOptionPic0()
virtual void emitDirectiveSetMips16()
virtual void emitDirectiveAbiCalls()
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
FunctionListType::iterator iterator
The Function iterators.
Definition: Module.h:90
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
Represents a location in source code.
Definition: SMLoc.h:23
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
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:78
const Triple & getTargetTriple() const
StringRef getTargetFeatureString() const
StringRef getTargetCPU() const
const Target & getTarget() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual Register getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Target - Wrapper for Target specific information.
MCSubtargetInfo * createMCSubtargetInfo(StringRef TheTriple, StringRef CPU, StringRef Features) const
createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
const std::string & str() const
Definition: Triple.h:414
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
static Twine utohexstr(const uint64_t &Val)
Definition: Twine.h:416
LLVM Value Representation.
Definition: Value.h:74
Iterator for intrusive lists based on ilist_node.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:672
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ SHT_PROGBITS
Definition: ELF.h:1000
@ SHF_ALLOC
Definition: ELF.h:1089
@ SHF_EXECINSTR
Definition: ELF.h:1092
StringRef selectMipsCPU(const Triple &TT, StringRef CPU)
Select the Mips CPU for the given triple and cpu name.
@ MO_GOT_CALL
MO_GOT_CALL - Represents the offset into the global offset table at which the address of a call site ...
Definition: MipsBaseInfo.h:44
@ MO_TPREL_HI
MO_TPREL_HI/LO - Represents the hi and low part of the offset from.
Definition: MipsBaseInfo.h:73
@ MO_GOT
MO_GOT - Represents the offset into the global offset table at which the address the relocation entry...
Definition: MipsBaseInfo.h:38
@ MO_JALR
Helper operand used to generate R_MIPS_JALR.
Definition: MipsBaseInfo.h:95
@ MO_GOTTPREL
MO_GOTTPREL - Represents the offset from the thread pointer (Initial.
Definition: MipsBaseInfo.h:69
@ MO_ABS_HI
MO_ABS_HI/LO - Represents the hi or low part of an absolute symbol address.
Definition: MipsBaseInfo.h:52
@ MO_TLSGD
MO_TLSGD - Represents the offset into the global offset table at which.
Definition: MipsBaseInfo.h:58
@ MO_GPREL
MO_GPREL - Represents the offset from the current gp value to be used for the relocatable object file...
Definition: MipsBaseInfo.h:48
@ MO_HIGHER
MO_HIGHER/HIGHEST - Represents the highest or higher half word of a 64-bit symbol address.
Definition: MipsBaseInfo.h:85
const char * MipsFCCToString(Mips::CondCode CC)
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:330
@ Offset
Definition: DWP.cpp:440
Target & getTheMips64Target()
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition: MathExtras.h:269
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:319
@ MCDR_DataRegionEnd
.end_data_region
Definition: MCDirectives.h:66
@ MCDR_DataRegion
.data_region
Definition: MCDirectives.h:62
Target & getTheMips64elTarget()
static const Align MIPS_NACL_BUNDLE_ALIGN
Definition: MipsMCNaCl.h:18
Target & getTheMipselTarget()
Target & getTheMipsTarget()
@ MCSA_Global
.type _foo, @gnu_unique_object
Definition: MCDirectives.h:30
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
Definition: MCDirectives.h:23
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,...