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