LLVM 19.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/IR/Module.h"
47#include "llvm/MC/MCContext.h"
48#include "llvm/MC/MCExpr.h"
49#include "llvm/MC/MCInst.h"
53#include "llvm/MC/MCSymbol.h"
54#include "llvm/MC/MCSymbolELF.h"
62#include <cassert>
63#include <cstdint>
64#include <map>
65#include <memory>
66#include <string>
67#include <vector>
68
69using namespace llvm;
70
71#define DEBUG_TYPE "mips-asm-printer"
72
74
75MipsTargetStreamer &MipsAsmPrinter::getTargetStreamer() const {
76 return static_cast<MipsTargetStreamer &>(*OutStreamer->getTargetStreamer());
77}
78
81
84 for (const auto &I : MipsFI->StubsNeeded) {
85 const char *Symbol = I.first;
86 const Mips16HardFloatInfo::FuncSignature *Signature = I.second;
87 if (StubsNeeded.find(Symbol) == StubsNeeded.end())
88 StubsNeeded[Symbol] = Signature;
89 }
90 MCP = MF.getConstantPool();
91
92 // In NaCl, all indirect jump targets must be aligned to bundle size.
94 NaClAlignIndirectJumpTargets(MF);
95
97
99
100 return true;
101}
102
103bool MipsAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) {
104 MCOp = MCInstLowering.LowerOperand(MO);
105 return MCOp.isValid();
106}
107
108#include "MipsGenMCPseudoLowering.inc"
109
110// Lower PseudoReturn/PseudoIndirectBranch/PseudoIndirectBranch64 to JR, JR_MM,
111// JALR, or JALR64 as appropriate for the target.
112void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer,
113 const MachineInstr *MI) {
114 bool HasLinkReg = false;
115 bool InMicroMipsMode = Subtarget->inMicroMipsMode();
116 MCInst TmpInst0;
117
118 if (Subtarget->hasMips64r6()) {
119 // MIPS64r6 should use (JALR64 ZERO_64, $rs)
120 TmpInst0.setOpcode(Mips::JALR64);
121 HasLinkReg = true;
122 } else if (Subtarget->hasMips32r6()) {
123 // MIPS32r6 should use (JALR ZERO, $rs)
124 if (InMicroMipsMode)
125 TmpInst0.setOpcode(Mips::JRC16_MMR6);
126 else {
127 TmpInst0.setOpcode(Mips::JALR);
128 HasLinkReg = true;
129 }
130 } else if (Subtarget->inMicroMipsMode())
131 // microMIPS should use (JR_MM $rs)
132 TmpInst0.setOpcode(Mips::JR_MM);
133 else {
134 // Everything else should use (JR $rs)
135 TmpInst0.setOpcode(Mips::JR);
136 }
137
138 MCOperand MCOp;
139
140 if (HasLinkReg) {
141 unsigned ZeroReg = Subtarget->isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
142 TmpInst0.addOperand(MCOperand::createReg(ZeroReg));
143 }
144
145 lowerOperand(MI->getOperand(0), MCOp);
146 TmpInst0.addOperand(MCOp);
147
148 EmitToStreamer(OutStreamer, TmpInst0);
149}
150
151// If there is an MO_JALR operand, insert:
152//
153// .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
154// tmplabel:
155//
156// This is an optimization hint for the linker which may then replace
157// an indirect call with a direct branch.
159 MCContext &OutContext,
161 MCStreamer &OutStreamer,
162 const MipsSubtarget &Subtarget) {
163 for (const MachineOperand &MO :
164 llvm::drop_begin(MI.operands(), MI.getDesc().getNumOperands())) {
165 if (MO.isMCSymbol() && (MO.getTargetFlags() & MipsII::MO_JALR)) {
166 MCSymbol *Callee = MO.getMCSymbol();
167 if (Callee && !Callee->getName().empty()) {
168 MCSymbol *OffsetLabel = OutContext.createTempSymbol();
169 const MCExpr *OffsetExpr =
170 MCSymbolRefExpr::create(OffsetLabel, OutContext);
171 const MCExpr *CaleeExpr =
172 MCSymbolRefExpr::create(Callee, OutContext);
173 OutStreamer.emitRelocDirective(
174 *OffsetExpr,
175 Subtarget.inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
176 CaleeExpr, SMLoc(), *TM.getMCSubtargetInfo());
177 OutStreamer.emitLabel(OffsetLabel);
178 return;
179 }
180 }
181 }
182}
183
185 // FIXME: Enable feature predicate checks once all the test pass.
186 // Mips_MC::verifyInstructionPredicates(MI->getOpcode(),
187 // getSubtargetInfo().getFeatureBits());
188
189 MipsTargetStreamer &TS = getTargetStreamer();
190 unsigned Opc = MI->getOpcode();
192
193 if (MI->isDebugValue()) {
196
198 return;
199 }
200 if (MI->isDebugLabel())
201 return;
202
203 // If we just ended a constant pool, mark it as such.
204 if (InConstantPool && Opc != Mips::CONSTPOOL_ENTRY) {
205 OutStreamer->emitDataRegion(MCDR_DataRegionEnd);
206 InConstantPool = false;
207 }
208 if (Opc == Mips::CONSTPOOL_ENTRY) {
209 // CONSTPOOL_ENTRY - This instruction represents a floating
210 // constant pool in the function. The first operand is the ID#
211 // for this instruction, the second is the index into the
212 // MachineConstantPool that this is, the third is the size in
213 // bytes of this constant pool entry.
214 // The required alignment is specified on the basic block holding this MI.
215 //
216 unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
217 unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex();
218
219 // If this is the first entry of the pool, mark it.
220 if (!InConstantPool) {
221 OutStreamer->emitDataRegion(MCDR_DataRegion);
222 InConstantPool = true;
223 }
224
225 OutStreamer->emitLabel(GetCPISymbol(LabelId));
226
227 const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
230 else
232 return;
233 }
234
235 switch (Opc) {
236 case Mips::PATCHABLE_FUNCTION_ENTER:
238 return;
239 case Mips::PATCHABLE_FUNCTION_EXIT:
241 return;
242 case Mips::PATCHABLE_TAIL_CALL:
244 return;
245 }
246
247 if (EmitJalrReloc &&
248 (MI->isReturn() || MI->isCall() || MI->isIndirectBranch())) {
250 }
251
253 MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();
254
255 do {
256 // Do any auto-generated pseudo lowerings.
257 if (emitPseudoExpansionLowering(*OutStreamer, &*I))
258 continue;
259
260 // Skip the BUNDLE pseudo instruction and lower the contents
261 if (I->isBundle())
262 continue;
263
264 if (I->getOpcode() == Mips::PseudoReturn ||
265 I->getOpcode() == Mips::PseudoReturn64 ||
266 I->getOpcode() == Mips::PseudoIndirectBranch ||
267 I->getOpcode() == Mips::PseudoIndirectBranch64 ||
268 I->getOpcode() == Mips::TAILCALLREG ||
269 I->getOpcode() == Mips::TAILCALLREG64) {
270 emitPseudoIndirectBranch(*OutStreamer, &*I);
271 continue;
272 }
273
274 // The inMips16Mode() test is not permanent.
275 // Some instructions are marked as pseudo right now which
276 // would make the test fail for the wrong reason but
277 // that will be fixed soon. We need this here because we are
278 // removing another test for this situation downstream in the
279 // callchain.
280 //
281 if (I->isPseudo() && !Subtarget->inMips16Mode()
282 && !isLongBranchPseudo(I->getOpcode()))
283 llvm_unreachable("Pseudo opcode found in emitInstruction()");
284
285 MCInst TmpInst0;
286 MCInstLowering.Lower(&*I, TmpInst0);
287 EmitToStreamer(*OutStreamer, TmpInst0);
288 } while ((++I != E) && I->isInsideBundle()); // Delay slot check
289}
290
291//===----------------------------------------------------------------------===//
292//
293// Mips Asm Directives
294//
295// -- Frame directive "frame Stackpointer, Stacksize, RARegister"
296// Describe the stack frame.
297//
298// -- Mask directives "(f)mask bitmask, offset"
299// Tells the assembler which registers are saved and where.
300// bitmask - contain a little endian bitset indicating which registers are
301// saved on function prologue (e.g. with a 0x80000000 mask, the
302// assembler knows the register 31 (RA) is saved at prologue.
303// offset - the position before stack pointer subtraction indicating where
304// the first saved register on prologue is located. (e.g. with a
305//
306// Consider the following function prologue:
307//
308// .frame $fp,48,$ra
309// .mask 0xc0000000,-8
310// addiu $sp, $sp, -48
311// sw $ra, 40($sp)
312// sw $fp, 36($sp)
313//
314// With a 0xc0000000 mask, the assembler knows the register 31 (RA) and
315// 30 (FP) are saved at prologue. As the save order on prologue is from
316// left to right, RA is saved first. A -8 offset means that after the
317// stack pointer subtration, the first register in the mask (RA) will be
318// saved at address 48-8=40.
319//
320//===----------------------------------------------------------------------===//
321
322//===----------------------------------------------------------------------===//
323// Mask directives
324//===----------------------------------------------------------------------===//
325
326// Create a bitmask with all callee saved registers for CPU or Floating Point
327// registers. For CPU registers consider RA, GP and FP for saving if necessary.
329 // CPU and FPU Saved Registers Bitmasks
330 unsigned CPUBitmask = 0, FPUBitmask = 0;
331 int CPUTopSavedRegOff, FPUTopSavedRegOff;
332
333 // Set the CPU and FPU Bitmasks
334 const MachineFrameInfo &MFI = MF->getFrameInfo();
336 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
337 // size of stack area to which FP callee-saved regs are saved.
338 unsigned CPURegSize = TRI->getRegSizeInBits(Mips::GPR32RegClass) / 8;
339 unsigned FGR32RegSize = TRI->getRegSizeInBits(Mips::FGR32RegClass) / 8;
340 unsigned AFGR64RegSize = TRI->getRegSizeInBits(Mips::AFGR64RegClass) / 8;
341 bool HasAFGR64Reg = false;
342 unsigned CSFPRegsSize = 0;
343
344 for (const auto &I : CSI) {
345 Register Reg = I.getReg();
346 unsigned RegNum = TRI->getEncodingValue(Reg);
347
348 // If it's a floating point register, set the FPU Bitmask.
349 // If it's a general purpose register, set the CPU Bitmask.
350 if (Mips::FGR32RegClass.contains(Reg)) {
351 FPUBitmask |= (1 << RegNum);
352 CSFPRegsSize += FGR32RegSize;
353 } else if (Mips::AFGR64RegClass.contains(Reg)) {
354 FPUBitmask |= (3 << RegNum);
355 CSFPRegsSize += AFGR64RegSize;
356 HasAFGR64Reg = true;
357 } else if (Mips::GPR32RegClass.contains(Reg))
358 CPUBitmask |= (1 << RegNum);
359 }
360
361 // FP Regs are saved right below where the virtual frame pointer points to.
362 FPUTopSavedRegOff = FPUBitmask ?
363 (HasAFGR64Reg ? -AFGR64RegSize : -FGR32RegSize) : 0;
364
365 // CPU Regs are saved below FP Regs.
366 CPUTopSavedRegOff = CPUBitmask ? -CSFPRegsSize - CPURegSize : 0;
367
368 MipsTargetStreamer &TS = getTargetStreamer();
369 // Print CPUBitmask
370 TS.emitMask(CPUBitmask, CPUTopSavedRegOff);
371
372 // Print FPUBitmask
373 TS.emitFMask(FPUBitmask, FPUTopSavedRegOff);
374}
375
376//===----------------------------------------------------------------------===//
377// Frame and Set directives
378//===----------------------------------------------------------------------===//
379
380/// Frame Directive
383
384 Register stackReg = RI.getFrameRegister(*MF);
385 unsigned returnReg = RI.getRARegister();
386 unsigned stackSize = MF->getFrameInfo().getStackSize();
387
388 getTargetStreamer().emitFrame(stackReg, stackSize, returnReg);
389}
390
391/// Emit Set directives.
393 switch (static_cast<MipsTargetMachine &>(TM).getABI().GetEnumValue()) {
394 case MipsABIInfo::ABI::O32: return "abi32";
395 case MipsABIInfo::ABI::N32: return "abiN32";
396 case MipsABIInfo::ABI::N64: return "abi64";
397 default: llvm_unreachable("Unknown Mips ABI");
398 }
399}
400
402 MipsTargetStreamer &TS = getTargetStreamer();
403
404 // NaCl sandboxing requires that indirect call instructions are masked.
405 // This means that function entry points should be bundle-aligned.
406 if (Subtarget->isTargetNaCl())
408
409 if (Subtarget->inMicroMipsMode()) {
411 TS.setUsesMicroMips();
413 } else
415
416 if (Subtarget->inMips16Mode())
418 else
420
422 OutStreamer->emitLabel(CurrentFnSym);
423}
424
425/// EmitFunctionBodyStart - Targets can override this to emit stuff before
426/// the first basic block in the function.
428 MipsTargetStreamer &TS = getTargetStreamer();
429
431
432 bool IsNakedFunction = MF->getFunction().hasFnAttribute(Attribute::Naked);
433 if (!IsNakedFunction)
435
436 if (!IsNakedFunction)
438
439 if (!Subtarget->inMips16Mode()) {
443 }
444}
445
446/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
447/// the last basic block in the function.
449 MipsTargetStreamer &TS = getTargetStreamer();
450
451 // There are instruction for this macros, but they must
452 // always be at the function end, and we can't emit and
453 // break with BB logic.
454 if (!Subtarget->inMips16Mode()) {
458 }
460 // Make sure to terminate any constant pools that were at the end
461 // of the function.
462 if (!InConstantPool)
463 return;
464 InConstantPool = false;
465 OutStreamer->emitDataRegion(MCDR_DataRegionEnd);
466}
467
470 MipsTargetStreamer &TS = getTargetStreamer();
471 if (MBB.empty())
473}
474
475// Print out an operand for an inline asm expression.
477 const char *ExtraCode, raw_ostream &O) {
478 // Does this asm operand have a single letter operand modifier?
479 if (ExtraCode && ExtraCode[0]) {
480 if (ExtraCode[1] != 0) return true; // Unknown modifier.
481
482 const MachineOperand &MO = MI->getOperand(OpNum);
483 switch (ExtraCode[0]) {
484 default:
485 // See if this is a generic print operand
486 return AsmPrinter::PrintAsmOperand(MI, OpNum, ExtraCode, O);
487 case 'X': // hex const int
488 if (!MO.isImm())
489 return true;
490 O << "0x" << Twine::utohexstr(MO.getImm());
491 return false;
492 case 'x': // hex const int (low 16 bits)
493 if (!MO.isImm())
494 return true;
495 O << "0x" << Twine::utohexstr(MO.getImm() & 0xffff);
496 return false;
497 case 'd': // decimal const int
498 if (!MO.isImm())
499 return true;
500 O << MO.getImm();
501 return false;
502 case 'm': // decimal const int minus 1
503 if (!MO.isImm())
504 return true;
505 O << MO.getImm() - 1;
506 return false;
507 case 'y': // exact log2
508 if (!MO.isImm())
509 return true;
510 if (!isPowerOf2_64(MO.getImm()))
511 return true;
512 O << Log2_64(MO.getImm());
513 return false;
514 case 'z':
515 // $0 if zero, regular printing otherwise
516 if (MO.isImm() && MO.getImm() == 0) {
517 O << "$0";
518 return false;
519 }
520 // If not, call printOperand as normal.
521 break;
522 case 'D': // Second part of a double word register operand
523 case 'L': // Low order register of a double word register operand
524 case 'M': // High order register of a double word register operand
525 {
526 if (OpNum == 0)
527 return true;
528 const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1);
529 if (!FlagsOP.isImm())
530 return true;
531 const InlineAsm::Flag Flags(FlagsOP.getImm());
532 const unsigned NumVals = Flags.getNumOperandRegisters();
533 // Number of registers represented by this operand. We are looking
534 // for 2 for 32 bit mode and 1 for 64 bit mode.
535 if (NumVals != 2) {
536 if (Subtarget->isGP64bit() && NumVals == 1 && MO.isReg()) {
537 Register Reg = MO.getReg();
538 O << '$' << MipsInstPrinter::getRegisterName(Reg);
539 return false;
540 }
541 return true;
542 }
543
544 unsigned RegOp = OpNum;
545 if (!Subtarget->isGP64bit()){
546 // Endianness reverses which register holds the high or low value
547 // between M and L.
548 switch(ExtraCode[0]) {
549 case 'M':
550 RegOp = (Subtarget->isLittle()) ? OpNum + 1 : OpNum;
551 break;
552 case 'L':
553 RegOp = (Subtarget->isLittle()) ? OpNum : OpNum + 1;
554 break;
555 case 'D': // Always the second part
556 RegOp = OpNum + 1;
557 }
558 if (RegOp >= MI->getNumOperands())
559 return true;
560 const MachineOperand &MO = MI->getOperand(RegOp);
561 if (!MO.isReg())
562 return true;
563 Register Reg = MO.getReg();
564 O << '$' << MipsInstPrinter::getRegisterName(Reg);
565 return false;
566 }
567 break;
568 }
569 case 'w': {
571 if (w != Mips::NoRegister) {
573 return false;
574 }
575 break;
576 }
577 }
578 }
579
580 printOperand(MI, OpNum, O);
581 return false;
582}
583
585 unsigned OpNum,
586 const char *ExtraCode,
587 raw_ostream &O) {
588 assert(OpNum + 1 < MI->getNumOperands() && "Insufficient operands");
589 const MachineOperand &BaseMO = MI->getOperand(OpNum);
590 const MachineOperand &OffsetMO = MI->getOperand(OpNum + 1);
591 assert(BaseMO.isReg() &&
592 "Unexpected base pointer for inline asm memory operand.");
593 assert(OffsetMO.isImm() &&
594 "Unexpected offset for inline asm memory operand.");
595 int Offset = OffsetMO.getImm();
596
597 // Currently we are expecting either no ExtraCode or 'D','M','L'.
598 if (ExtraCode) {
599 switch (ExtraCode[0]) {
600 case 'D':
601 Offset += 4;
602 break;
603 case 'M':
604 if (Subtarget->isLittle())
605 Offset += 4;
606 break;
607 case 'L':
608 if (!Subtarget->isLittle())
609 Offset += 4;
610 break;
611 default:
612 return true; // Unknown modifier.
613 }
614 }
615
616 O << Offset << "($" << MipsInstPrinter::getRegisterName(BaseMO.getReg())
617 << ")";
618
619 return false;
620}
621
623 raw_ostream &O) {
624 const MachineOperand &MO = MI->getOperand(opNum);
625 bool closeP = false;
626
627 if (MO.getTargetFlags())
628 closeP = true;
629
630 switch(MO.getTargetFlags()) {
631 case MipsII::MO_GPREL: O << "%gp_rel("; break;
632 case MipsII::MO_GOT_CALL: O << "%call16("; break;
633 case MipsII::MO_GOT: O << "%got("; break;
634 case MipsII::MO_ABS_HI: O << "%hi("; break;
635 case MipsII::MO_ABS_LO: O << "%lo("; break;
636 case MipsII::MO_HIGHER: O << "%higher("; break;
637 case MipsII::MO_HIGHEST: O << "%highest(("; break;
638 case MipsII::MO_TLSGD: O << "%tlsgd("; break;
639 case MipsII::MO_GOTTPREL: O << "%gottprel("; break;
640 case MipsII::MO_TPREL_HI: O << "%tprel_hi("; break;
641 case MipsII::MO_TPREL_LO: O << "%tprel_lo("; break;
642 case MipsII::MO_GPOFF_HI: O << "%hi(%neg(%gp_rel("; break;
643 case MipsII::MO_GPOFF_LO: O << "%lo(%neg(%gp_rel("; break;
644 case MipsII::MO_GOT_DISP: O << "%got_disp("; break;
645 case MipsII::MO_GOT_PAGE: O << "%got_page("; break;
646 case MipsII::MO_GOT_OFST: O << "%got_ofst("; break;
647 }
648
649 switch (MO.getType()) {
651 O << '$'
653 break;
654
656 O << MO.getImm();
657 break;
658
660 MO.getMBB()->getSymbol()->print(O, MAI);
661 return;
662
664 PrintSymbolOperand(MO, O);
665 break;
666
669 O << BA->getName();
670 break;
671 }
672
674 O << getDataLayout().getPrivateGlobalPrefix() << "CPI"
675 << getFunctionNumber() << "_" << MO.getIndex();
676 if (MO.getOffset())
677 O << "+" << MO.getOffset();
678 break;
679
680 default:
681 llvm_unreachable("<unknown operand type>");
682 }
683
684 if (closeP) O << ")";
685}
686
688printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O) {
689 // Load/Store memory operands -- imm($reg)
690 // If PIC target the target is loaded as the
691 // pattern lw $25,%call16($28)
692
693 // opNum can be invalid if instruction has reglist as operand.
694 // MemOperand is always last operand of instruction (base + offset).
695 switch (MI->getOpcode()) {
696 default:
697 break;
698 case Mips::SWM32_MM:
699 case Mips::LWM32_MM:
700 opNum = MI->getNumOperands() - 2;
701 break;
702 }
703
704 printOperand(MI, opNum+1, O);
705 O << "(";
706 printOperand(MI, opNum, O);
707 O << ")";
708}
709
711printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O) {
712 // when using stack locations for not load/store instructions
713 // print the same way as all normal 3 operand instructions.
714 printOperand(MI, opNum, O);
715 O << ", ";
716 printOperand(MI, opNum+1, O);
717}
718
720printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
721 const char *Modifier) {
722 const MachineOperand &MO = MI->getOperand(opNum);
724}
725
727printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O) {
728 for (int i = opNum, e = MI->getNumOperands(); i != e; ++i) {
729 if (i != opNum) O << ", ";
730 printOperand(MI, i, O);
731 }
732}
733
735 MipsTargetStreamer &TS = getTargetStreamer();
736
737 // MipsTargetStreamer has an initialization order problem when emitting an
738 // object file directly (see MipsTargetELFStreamer for full details). Work
739 // around it by re-initializing the PIC state here.
741
742 // Try to get target-features from the first function.
744 Module::iterator F = M.begin();
745 if (FS.empty() && M.size() && F->hasFnAttribute("target-features"))
746 FS = F->getFnAttribute("target-features").getValueAsString();
747
748 // Compute MIPS architecture attributes based on the default subtarget
749 // that we'd have constructed.
750 // FIXME: For ifunc related functions we could iterate over and look
751 // for a feature string that doesn't match the default one.
752 const Triple &TT = TM.getTargetTriple();
754 const MipsTargetMachine &MTM = static_cast<const MipsTargetMachine &>(TM);
755 const MipsSubtarget STI(TT, CPU, FS, MTM.isLittleEndian(), MTM, std::nullopt);
756
757 bool IsABICalls = STI.isABICalls();
758 const MipsABIInfo &ABI = MTM.getABI();
759 if (IsABICalls) {
761 // FIXME: This condition should be a lot more complicated that it is here.
762 // Ideally it should test for properties of the ABI and not the ABI
763 // itself.
764 // For the moment, I'm only correcting enough to make MIPS-IV work.
765 if (!isPositionIndependent() && STI.hasSym32())
767 }
768
769 // Tell the assembler which ABI we are using
770 std::string SectionName = std::string(".mdebug.") + getCurrentABIString();
771 OutStreamer->switchSection(
773
774 // NaN: At the moment we only support:
775 // 1. .nan legacy (default)
776 // 2. .nan 2008
779
780 // TODO: handle O64 ABI
781
782 TS.updateABIInfo(STI);
783
784 // We should always emit a '.module fp=...' but binutils 2.24 does not accept
785 // it. We therefore emit it when it contradicts the ABI defaults (-mfpxx or
786 // -mfp64) and omit it otherwise.
787 if ((ABI.IsO32() && (STI.isABI_FPXX() || STI.isFP64bit())) ||
788 STI.useSoftFloat())
790
791 // We should always emit a '.module [no]oddspreg' but binutils 2.24 does not
792 // accept it. We therefore emit it when it contradicts the default or an
793 // option has changed the default (i.e. FPXX) and omit it otherwise.
794 if (ABI.IsO32() && (!STI.useOddSPReg() || STI.isABI_FPXX()))
796
797 // Switch to the .text section.
798 OutStreamer->switchSection(getObjFileLowering().getTextSection());
799}
800
801void MipsAsmPrinter::emitInlineAsmStart() const {
802 MipsTargetStreamer &TS = getTargetStreamer();
803
804 // GCC's choice of assembler options for inline assembly code ('at', 'macro'
805 // and 'reorder') is different from LLVM's choice for generated code ('noat',
806 // 'nomacro' and 'noreorder').
807 // In order to maintain compatibility with inline assembly code which depends
808 // on GCC's assembler options being used, we have to switch to those options
809 // for the duration of the inline assembly block and then switch back.
814 OutStreamer->addBlankLine();
815}
816
817void MipsAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
818 const MCSubtargetInfo *EndInfo) const {
819 OutStreamer->addBlankLine();
820 getTargetStreamer().emitDirectiveSetPop();
821}
822
823void MipsAsmPrinter::EmitJal(const MCSubtargetInfo &STI, MCSymbol *Symbol) {
824 MCInst I;
825 I.setOpcode(Mips::JAL);
826 I.addOperand(
828 OutStreamer->emitInstruction(I, STI);
829}
830
831void MipsAsmPrinter::EmitInstrReg(const MCSubtargetInfo &STI, unsigned Opcode,
832 unsigned Reg) {
833 MCInst I;
834 I.setOpcode(Opcode);
835 I.addOperand(MCOperand::createReg(Reg));
836 OutStreamer->emitInstruction(I, STI);
837}
838
839void MipsAsmPrinter::EmitInstrRegReg(const MCSubtargetInfo &STI,
840 unsigned Opcode, unsigned Reg1,
841 unsigned Reg2) {
842 MCInst I;
843 //
844 // Because of the current td files for Mips32, the operands for MTC1
845 // appear backwards from their normal assembly order. It's not a trivial
846 // change to fix this in the td file so we adjust for it here.
847 //
848 if (Opcode == Mips::MTC1) {
849 unsigned Temp = Reg1;
850 Reg1 = Reg2;
851 Reg2 = Temp;
852 }
853 I.setOpcode(Opcode);
854 I.addOperand(MCOperand::createReg(Reg1));
855 I.addOperand(MCOperand::createReg(Reg2));
856 OutStreamer->emitInstruction(I, STI);
857}
858
859void MipsAsmPrinter::EmitInstrRegRegReg(const MCSubtargetInfo &STI,
860 unsigned Opcode, unsigned Reg1,
861 unsigned Reg2, unsigned Reg3) {
862 MCInst I;
863 I.setOpcode(Opcode);
864 I.addOperand(MCOperand::createReg(Reg1));
865 I.addOperand(MCOperand::createReg(Reg2));
866 I.addOperand(MCOperand::createReg(Reg3));
867 OutStreamer->emitInstruction(I, STI);
868}
869
870void MipsAsmPrinter::EmitMovFPIntPair(const MCSubtargetInfo &STI,
871 unsigned MovOpc, unsigned Reg1,
872 unsigned Reg2, unsigned FPReg1,
873 unsigned FPReg2, bool LE) {
874 if (!LE) {
875 unsigned temp = Reg1;
876 Reg1 = Reg2;
877 Reg2 = temp;
878 }
879 EmitInstrRegReg(STI, MovOpc, Reg1, FPReg1);
880 EmitInstrRegReg(STI, MovOpc, Reg2, FPReg2);
881}
882
883void MipsAsmPrinter::EmitSwapFPIntParams(const MCSubtargetInfo &STI,
885 bool LE, bool ToFP) {
886 using namespace Mips16HardFloatInfo;
887
888 unsigned MovOpc = ToFP ? Mips::MTC1 : Mips::MFC1;
889 switch (PV) {
890 case FSig:
891 EmitInstrRegReg(STI, MovOpc, Mips::A0, Mips::F12);
892 break;
893 case FFSig:
894 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F14, LE);
895 break;
896 case FDSig:
897 EmitInstrRegReg(STI, MovOpc, Mips::A0, Mips::F12);
898 EmitMovFPIntPair(STI, MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE);
899 break;
900 case DSig:
901 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
902 break;
903 case DDSig:
904 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
905 EmitMovFPIntPair(STI, MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE);
906 break;
907 case DFSig:
908 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
909 EmitInstrRegReg(STI, MovOpc, Mips::A2, Mips::F14);
910 break;
911 case NoSig:
912 return;
913 }
914}
915
916void MipsAsmPrinter::EmitSwapFPIntRetval(
918 bool LE) {
919 using namespace Mips16HardFloatInfo;
920
921 unsigned MovOpc = Mips::MFC1;
922 switch (RV) {
923 case FRet:
924 EmitInstrRegReg(STI, MovOpc, Mips::V0, Mips::F0);
925 break;
926 case DRet:
927 EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
928 break;
929 case CFRet:
930 EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
931 break;
932 case CDRet:
933 EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
934 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F2, Mips::F3, LE);
935 break;
936 case NoFPRet:
937 break;
938 }
939}
940
941void MipsAsmPrinter::EmitFPCallStub(
942 const char *Symbol, const Mips16HardFloatInfo::FuncSignature *Signature) {
943 using namespace Mips16HardFloatInfo;
944
947 // Construct a local MCSubtargetInfo here.
948 // This is because the MachineFunction won't exist (but have not yet been
949 // freed) and since we're at the global level we can use the default
950 // constructed subtarget.
951 std::unique_ptr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo(
954
955 //
956 // .global xxxx
957 //
958 OutStreamer->emitSymbolAttribute(MSymbol, MCSA_Global);
959 const char *RetType;
960 //
961 // make the comment field identifying the return and parameter
962 // types of the floating point stub
963 // # Stub function to call rettype xxxx (params)
964 //
965 switch (Signature->RetSig) {
966 case FRet:
967 RetType = "float";
968 break;
969 case DRet:
970 RetType = "double";
971 break;
972 case CFRet:
973 RetType = "complex";
974 break;
975 case CDRet:
976 RetType = "double complex";
977 break;
978 case NoFPRet:
979 RetType = "";
980 break;
981 }
982 const char *Parms;
983 switch (Signature->ParamSig) {
984 case FSig:
985 Parms = "float";
986 break;
987 case FFSig:
988 Parms = "float, float";
989 break;
990 case FDSig:
991 Parms = "float, double";
992 break;
993 case DSig:
994 Parms = "double";
995 break;
996 case DDSig:
997 Parms = "double, double";
998 break;
999 case DFSig:
1000 Parms = "double, float";
1001 break;
1002 case NoSig:
1003 Parms = "";
1004 break;
1005 }
1006 OutStreamer->AddComment("\t# Stub function to call " + Twine(RetType) + " " +
1007 Twine(Symbol) + " (" + Twine(Parms) + ")");
1008 //
1009 // probably not necessary but we save and restore the current section state
1010 //
1011 OutStreamer->pushSection();
1012 //
1013 // .section mips16.call.fpxxxx,"ax",@progbits
1014 //
1016 ".mips16.call.fp." + std::string(Symbol), ELF::SHT_PROGBITS,
1018 OutStreamer->switchSection(M);
1019 //
1020 // .align 2
1021 //
1022 OutStreamer->emitValueToAlignment(Align(4));
1023 MipsTargetStreamer &TS = getTargetStreamer();
1024 //
1025 // .set nomips16
1026 // .set nomicromips
1027 //
1030 //
1031 // .ent __call_stub_fp_xxxx
1032 // .type __call_stub_fp_xxxx,@function
1033 // __call_stub_fp_xxxx:
1034 //
1035 std::string x = "__call_stub_fp_" + std::string(Symbol);
1036 MCSymbolELF *Stub =
1037 cast<MCSymbolELF>(OutContext.getOrCreateSymbol(StringRef(x)));
1038 TS.emitDirectiveEnt(*Stub);
1039 MCSymbol *MType =
1040 OutContext.getOrCreateSymbol("__call_stub_fp_" + Twine(Symbol));
1041 OutStreamer->emitSymbolAttribute(MType, MCSA_ELF_TypeFunction);
1042 OutStreamer->emitLabel(Stub);
1043
1044 // Only handle non-pic for now.
1046 "should not be here if we are compiling pic");
1048 //
1049 // We need to add a MipsMCExpr class to MCTargetDesc to fully implement
1050 // stubs without raw text but this current patch is for compiler generated
1051 // functions and they all return some value.
1052 // The calling sequence for non pic is different in that case and we need
1053 // to implement %lo and %hi in order to handle the case of no return value
1054 // See the corresponding method in Mips16HardFloat for details.
1055 //
1056 // mov the return address to S2.
1057 // we have no stack space to store it and we are about to make another call.
1058 // We need to make sure that the enclosing function knows to save S2
1059 // This should have already been handled.
1060 //
1061 // Mov $18, $31
1062
1063 EmitInstrRegRegReg(*STI, Mips::OR, Mips::S2, Mips::RA, Mips::ZERO);
1064
1065 EmitSwapFPIntParams(*STI, Signature->ParamSig, LE, true);
1066
1067 // Jal xxxx
1068 //
1069 EmitJal(*STI, MSymbol);
1070
1071 // fix return values
1072 EmitSwapFPIntRetval(*STI, Signature->RetSig, LE);
1073 //
1074 // do the return
1075 // if (Signature->RetSig == NoFPRet)
1076 // llvm_unreachable("should not be any stubs here with no return value");
1077 // else
1078 EmitInstrReg(*STI, Mips::JR, Mips::S2);
1079
1081 OutStreamer->emitLabel(Tmp);
1084 const MCExpr *T_min_E = MCBinaryExpr::createSub(T, E, OutContext);
1085 OutStreamer->emitELFSize(Stub, T_min_E);
1086 TS.emitDirectiveEnd(x);
1087 OutStreamer->popSection();
1088}
1089
1091 // Emit needed stubs
1092 //
1093 for (std::map<
1094 const char *,
1096 it = StubsNeeded.begin();
1097 it != StubsNeeded.end(); ++it) {
1098 const char *Symbol = it->first;
1099 const Mips16HardFloatInfo::FuncSignature *Signature = it->second;
1100 EmitFPCallStub(Symbol, Signature);
1101 }
1102 // return to the text section
1104}
1105
1106void MipsAsmPrinter::EmitSled(const MachineInstr &MI, SledKind Kind) {
1107 const uint8_t NoopsInSledCount = Subtarget->isGP64bit() ? 15 : 11;
1108 // For mips32 we want to emit the following pattern:
1109 //
1110 // .Lxray_sled_N:
1111 // ALIGN
1112 // B .tmpN
1113 // 11 NOP instructions (44 bytes)
1114 // ADDIU T9, T9, 52
1115 // .tmpN
1116 //
1117 // We need the 44 bytes (11 instructions) because at runtime, we'd
1118 // be patching over the full 48 bytes (12 instructions) with the following
1119 // pattern:
1120 //
1121 // ADDIU SP, SP, -8
1122 // NOP
1123 // SW RA, 4(SP)
1124 // SW T9, 0(SP)
1125 // LUI T9, %hi(__xray_FunctionEntry/Exit)
1126 // ORI T9, T9, %lo(__xray_FunctionEntry/Exit)
1127 // LUI T0, %hi(function_id)
1128 // JALR T9
1129 // ORI T0, T0, %lo(function_id)
1130 // LW T9, 0(SP)
1131 // LW RA, 4(SP)
1132 // ADDIU SP, SP, 8
1133 //
1134 // We add 52 bytes to t9 because we want to adjust the function pointer to
1135 // the actual start of function i.e. the address just after the noop sled.
1136 // We do this because gp displacement relocation is emitted at the start of
1137 // of the function i.e after the nop sled and to correctly calculate the
1138 // global offset table address, t9 must hold the address of the instruction
1139 // containing the gp displacement relocation.
1140 // FIXME: Is this correct for the static relocation model?
1141 //
1142 // For mips64 we want to emit the following pattern:
1143 //
1144 // .Lxray_sled_N:
1145 // ALIGN
1146 // B .tmpN
1147 // 15 NOP instructions (60 bytes)
1148 // .tmpN
1149 //
1150 // We need the 60 bytes (15 instructions) because at runtime, we'd
1151 // be patching over the full 64 bytes (16 instructions) with the following
1152 // pattern:
1153 //
1154 // DADDIU SP, SP, -16
1155 // NOP
1156 // SD RA, 8(SP)
1157 // SD T9, 0(SP)
1158 // LUI T9, %highest(__xray_FunctionEntry/Exit)
1159 // ORI T9, T9, %higher(__xray_FunctionEntry/Exit)
1160 // DSLL T9, T9, 16
1161 // ORI T9, T9, %hi(__xray_FunctionEntry/Exit)
1162 // DSLL T9, T9, 16
1163 // ORI T9, T9, %lo(__xray_FunctionEntry/Exit)
1164 // LUI T0, %hi(function_id)
1165 // JALR T9
1166 // ADDIU T0, T0, %lo(function_id)
1167 // LD T9, 0(SP)
1168 // LD RA, 8(SP)
1169 // DADDIU SP, SP, 16
1170 //
1171 OutStreamer->emitCodeAlignment(Align(4), &getSubtargetInfo());
1172 auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
1173 OutStreamer->emitLabel(CurSled);
1175
1176 // Emit "B .tmpN" instruction, which jumps over the nop sled to the actual
1177 // start of function
1178 const MCExpr *TargetExpr = MCSymbolRefExpr::create(
1181 .addReg(Mips::ZERO)
1182 .addReg(Mips::ZERO)
1183 .addExpr(TargetExpr));
1184
1185 for (int8_t I = 0; I < NoopsInSledCount; I++)
1187 .addReg(Mips::ZERO)
1188 .addReg(Mips::ZERO)
1189 .addImm(0));
1190
1191 OutStreamer->emitLabel(Target);
1192
1193 if (!Subtarget->isGP64bit()) {
1195 MCInstBuilder(Mips::ADDiu)
1196 .addReg(Mips::T9)
1197 .addReg(Mips::T9)
1198 .addImm(0x34));
1199 }
1200
1201 recordSled(CurSled, MI, Kind, 2);
1202}
1203
1205 EmitSled(MI, SledKind::FUNCTION_ENTER);
1206}
1207
1209 EmitSled(MI, SledKind::FUNCTION_EXIT);
1210}
1211
1213 EmitSled(MI, SledKind::TAIL_CALL);
1214}
1215
1217 raw_ostream &OS) {
1218 // TODO: implement
1219}
1220
1221// Emit .dtprelword or .dtpreldword directive
1222// and value for debug thread local expression.
1223void MipsAsmPrinter::emitDebugValue(const MCExpr *Value, unsigned Size) const {
1224 if (auto *MipsExpr = dyn_cast<MipsMCExpr>(Value)) {
1225 if (MipsExpr && MipsExpr->getKind() == MipsMCExpr::MEK_DTPREL) {
1226 switch (Size) {
1227 case 4:
1228 OutStreamer->emitDTPRel32Value(MipsExpr->getSubExpr());
1229 break;
1230 case 8:
1231 OutStreamer->emitDTPRel64Value(MipsExpr->getSubExpr());
1232 break;
1233 default:
1234 llvm_unreachable("Unexpected size of expression value.");
1235 }
1236 return;
1237 }
1238 }
1240}
1241
1242// Align all targets of indirect branches on bundle size. Used only if target
1243// is NaCl.
1244void MipsAsmPrinter::NaClAlignIndirectJumpTargets(MachineFunction &MF) {
1245 // Align all blocks that are jumped to through jump table.
1246 if (MachineJumpTableInfo *JtInfo = MF.getJumpTableInfo()) {
1247 const std::vector<MachineJumpTableEntry> &JT = JtInfo->getJumpTables();
1248 for (const auto &I : JT) {
1249 const std::vector<MachineBasicBlock *> &MBBs = I.MBBs;
1250
1251 for (MachineBasicBlock *MBB : MBBs)
1253 }
1254 }
1255
1256 // If basic block address is taken, block can be target of indirect branch.
1257 for (auto &MBB : MF) {
1258 if (MBB.hasAddressTaken())
1260 }
1261}
1262
1263bool MipsAsmPrinter::isLongBranchPseudo(int Opcode) const {
1264 return (Opcode == Mips::LONG_BRANCH_LUi
1265 || Opcode == Mips::LONG_BRANCH_LUi2Op
1266 || Opcode == Mips::LONG_BRANCH_LUi2Op_64
1267 || Opcode == Mips::LONG_BRANCH_ADDiu
1268 || Opcode == Mips::LONG_BRANCH_ADDiu2Op
1269 || Opcode == Mips::LONG_BRANCH_DADDiu
1270 || Opcode == Mips::LONG_BRANCH_DADDiu2Op);
1271}
1272
1273// Force static initialization.
1279}
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")
#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
Module.h This file contains the declarations for the Module class.
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:469
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
Definition: AsmPrinter.cpp:399
virtual void emitDebugValue(const MCExpr *Value, unsigned Size) const
Emit the directive and value for debug thread local expression.
Definition: AsmPrinter.cpp:930
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
Definition: AsmPrinter.cpp:419
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:395
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:390
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
Definition: AsmPrinter.h:396
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:403
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
Definition: AsmPrinter.cpp:414
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.
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:690
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:621
Context object for machine code objects.
Definition: MCContext.h:83
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:416
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:345
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition: MCContext.h:547
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:212
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.
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
This represents a section on linux, lots of unix variants and some bare metal systems.
Definition: MCSectionELF.h:27
Streaming machine code generation interface.
Definition: MCStreamer.h:213
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:1078
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:397
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:205
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
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.
Instructions::const_iterator const_instr_iterator
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::@198 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:69
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 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:77
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:440
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
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:691
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ SHT_PROGBITS
Definition: ELF.h:1067
@ SHF_ALLOC
Definition: ELF.h:1161
@ SHF_EXECINSTR
Definition: ELF.h:1164
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:329
@ Offset
Definition: DWP.cpp:480
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:280
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:330
@ MCDR_DataRegionEnd
.end_data_region
Definition: MCDirectives.h:66
@ MCDR_DataRegion
.data_region
Definition: MCDirectives.h:62
static MCRegister getMSARegFromFReg(MCRegister Reg)
Definition: MipsBaseInfo.h:139
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,...