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 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,
160 TargetMachine &TM,
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 (MCInst OutInst; lowerPseudoInstExpansion(&*I, OutInst)) {
258 EmitToStreamer(*OutStreamer, OutInst);
259 continue;
260 }
261
262 // Skip the BUNDLE pseudo instruction and lower the contents
263 if (I->isBundle())
264 continue;
265
266 if (I->getOpcode() == Mips::PseudoReturn ||
267 I->getOpcode() == Mips::PseudoReturn64 ||
268 I->getOpcode() == Mips::PseudoIndirectBranch ||
269 I->getOpcode() == Mips::PseudoIndirectBranch64 ||
270 I->getOpcode() == Mips::TAILCALLREG ||
271 I->getOpcode() == Mips::TAILCALLREG64) {
272 emitPseudoIndirectBranch(*OutStreamer, &*I);
273 continue;
274 }
275
276 // The inMips16Mode() test is not permanent.
277 // Some instructions are marked as pseudo right now which
278 // would make the test fail for the wrong reason but
279 // that will be fixed soon. We need this here because we are
280 // removing another test for this situation downstream in the
281 // callchain.
282 //
283 if (I->isPseudo() && !Subtarget->inMips16Mode()
284 && !isLongBranchPseudo(I->getOpcode()))
285 llvm_unreachable("Pseudo opcode found in emitInstruction()");
286
287 MCInst TmpInst0;
288 MCInstLowering.Lower(&*I, TmpInst0);
289 EmitToStreamer(*OutStreamer, TmpInst0);
290 } while ((++I != E) && I->isInsideBundle()); // Delay slot check
291}
292
293//===----------------------------------------------------------------------===//
294//
295// Mips Asm Directives
296//
297// -- Frame directive "frame Stackpointer, Stacksize, RARegister"
298// Describe the stack frame.
299//
300// -- Mask directives "(f)mask bitmask, offset"
301// Tells the assembler which registers are saved and where.
302// bitmask - contain a little endian bitset indicating which registers are
303// saved on function prologue (e.g. with a 0x80000000 mask, the
304// assembler knows the register 31 (RA) is saved at prologue.
305// offset - the position before stack pointer subtraction indicating where
306// the first saved register on prologue is located. (e.g. with a
307//
308// Consider the following function prologue:
309//
310// .frame $fp,48,$ra
311// .mask 0xc0000000,-8
312// addiu $sp, $sp, -48
313// sw $ra, 40($sp)
314// sw $fp, 36($sp)
315//
316// With a 0xc0000000 mask, the assembler knows the register 31 (RA) and
317// 30 (FP) are saved at prologue. As the save order on prologue is from
318// left to right, RA is saved first. A -8 offset means that after the
319// stack pointer subtration, the first register in the mask (RA) will be
320// saved at address 48-8=40.
321//
322//===----------------------------------------------------------------------===//
323
324//===----------------------------------------------------------------------===//
325// Mask directives
326//===----------------------------------------------------------------------===//
327
328// Create a bitmask with all callee saved registers for CPU or Floating Point
329// registers. For CPU registers consider RA, GP and FP for saving if necessary.
331 // CPU and FPU Saved Registers Bitmasks
332 unsigned CPUBitmask = 0, FPUBitmask = 0;
333 int CPUTopSavedRegOff, FPUTopSavedRegOff;
334
335 // Set the CPU and FPU Bitmasks
336 const MachineFrameInfo &MFI = MF->getFrameInfo();
338 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
339 // size of stack area to which FP callee-saved regs are saved.
340 unsigned CPURegSize = TRI->getRegSizeInBits(Mips::GPR32RegClass) / 8;
341 unsigned FGR32RegSize = TRI->getRegSizeInBits(Mips::FGR32RegClass) / 8;
342 unsigned AFGR64RegSize = TRI->getRegSizeInBits(Mips::AFGR64RegClass) / 8;
343 bool HasAFGR64Reg = false;
344 unsigned CSFPRegsSize = 0;
345
346 for (const auto &I : CSI) {
347 Register Reg = I.getReg();
348 unsigned RegNum = TRI->getEncodingValue(Reg);
349
350 // If it's a floating point register, set the FPU Bitmask.
351 // If it's a general purpose register, set the CPU Bitmask.
352 if (Mips::FGR32RegClass.contains(Reg)) {
353 FPUBitmask |= (1 << RegNum);
354 CSFPRegsSize += FGR32RegSize;
355 } else if (Mips::AFGR64RegClass.contains(Reg)) {
356 FPUBitmask |= (3 << RegNum);
357 CSFPRegsSize += AFGR64RegSize;
358 HasAFGR64Reg = true;
359 } else if (Mips::GPR32RegClass.contains(Reg))
360 CPUBitmask |= (1 << RegNum);
361 }
362
363 // FP Regs are saved right below where the virtual frame pointer points to.
364 FPUTopSavedRegOff = FPUBitmask ?
365 (HasAFGR64Reg ? -AFGR64RegSize : -FGR32RegSize) : 0;
366
367 // CPU Regs are saved below FP Regs.
368 CPUTopSavedRegOff = CPUBitmask ? -CSFPRegsSize - CPURegSize : 0;
369
370 MipsTargetStreamer &TS = getTargetStreamer();
371 // Print CPUBitmask
372 TS.emitMask(CPUBitmask, CPUTopSavedRegOff);
373
374 // Print FPUBitmask
375 TS.emitFMask(FPUBitmask, FPUTopSavedRegOff);
376}
377
378//===----------------------------------------------------------------------===//
379// Frame and Set directives
380//===----------------------------------------------------------------------===//
381
382/// Frame Directive
385
386 Register stackReg = RI.getFrameRegister(*MF);
387 unsigned returnReg = RI.getRARegister();
388 unsigned stackSize = MF->getFrameInfo().getStackSize();
389
390 getTargetStreamer().emitFrame(stackReg, stackSize, returnReg);
391}
392
393/// Emit Set directives.
395 switch (static_cast<MipsTargetMachine &>(TM).getABI().GetEnumValue()) {
396 case MipsABIInfo::ABI::O32: return "abi32";
397 case MipsABIInfo::ABI::N32: return "abiN32";
398 case MipsABIInfo::ABI::N64: return "abi64";
399 default: llvm_unreachable("Unknown Mips ABI");
400 }
401}
402
404 MipsTargetStreamer &TS = getTargetStreamer();
405
406 // NaCl sandboxing requires that indirect call instructions are masked.
407 // This means that function entry points should be bundle-aligned.
408 if (Subtarget->isTargetNaCl())
410
411 if (Subtarget->inMicroMipsMode()) {
413 TS.setUsesMicroMips();
415 } else
417
418 if (Subtarget->inMips16Mode())
420 else
422
424 OutStreamer->emitLabel(CurrentFnSym);
425}
426
427/// EmitFunctionBodyStart - Targets can override this to emit stuff before
428/// the first basic block in the function.
430 MipsTargetStreamer &TS = getTargetStreamer();
431
433
434 bool IsNakedFunction = MF->getFunction().hasFnAttribute(Attribute::Naked);
435 if (!IsNakedFunction)
437
438 if (!IsNakedFunction)
440
441 if (!Subtarget->inMips16Mode()) {
445 }
446}
447
448/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
449/// the last basic block in the function.
451 MipsTargetStreamer &TS = getTargetStreamer();
452
453 // There are instruction for this macros, but they must
454 // always be at the function end, and we can't emit and
455 // break with BB logic.
456 if (!Subtarget->inMips16Mode()) {
460 }
462 // Make sure to terminate any constant pools that were at the end
463 // of the function.
464 if (!InConstantPool)
465 return;
466 InConstantPool = false;
467 OutStreamer->emitDataRegion(MCDR_DataRegionEnd);
468}
469
472 MipsTargetStreamer &TS = getTargetStreamer();
473 if (MBB.empty())
475}
476
477// Print out an operand for an inline asm expression.
479 const char *ExtraCode, raw_ostream &O) {
480 // Does this asm operand have a single letter operand modifier?
481 if (ExtraCode && ExtraCode[0]) {
482 if (ExtraCode[1] != 0) return true; // Unknown modifier.
483
484 const MachineOperand &MO = MI->getOperand(OpNum);
485 switch (ExtraCode[0]) {
486 default:
487 // See if this is a generic print operand
488 return AsmPrinter::PrintAsmOperand(MI, OpNum, ExtraCode, O);
489 case 'X': // hex const int
490 if (!MO.isImm())
491 return true;
492 O << "0x" << Twine::utohexstr(MO.getImm());
493 return false;
494 case 'x': // hex const int (low 16 bits)
495 if (!MO.isImm())
496 return true;
497 O << "0x" << Twine::utohexstr(MO.getImm() & 0xffff);
498 return false;
499 case 'd': // decimal const int
500 if (!MO.isImm())
501 return true;
502 O << MO.getImm();
503 return false;
504 case 'm': // decimal const int minus 1
505 if (!MO.isImm())
506 return true;
507 O << MO.getImm() - 1;
508 return false;
509 case 'y': // exact log2
510 if (!MO.isImm())
511 return true;
512 if (!isPowerOf2_64(MO.getImm()))
513 return true;
514 O << Log2_64(MO.getImm());
515 return false;
516 case 'z':
517 // $0 if zero, regular printing otherwise
518 if (MO.isImm() && MO.getImm() == 0) {
519 O << "$0";
520 return false;
521 }
522 // If not, call printOperand as normal.
523 break;
524 case 'D': // Second part of a double word register operand
525 case 'L': // Low order register of a double word register operand
526 case 'M': // High order register of a double word register operand
527 {
528 if (OpNum == 0)
529 return true;
530 const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1);
531 if (!FlagsOP.isImm())
532 return true;
533 const InlineAsm::Flag Flags(FlagsOP.getImm());
534 const unsigned NumVals = Flags.getNumOperandRegisters();
535 // Number of registers represented by this operand. We are looking
536 // for 2 for 32 bit mode and 1 for 64 bit mode.
537 if (NumVals != 2) {
538 if (Subtarget->isGP64bit() && NumVals == 1 && MO.isReg()) {
539 Register Reg = MO.getReg();
540 O << '$' << MipsInstPrinter::getRegisterName(Reg);
541 return false;
542 }
543 return true;
544 }
545
546 unsigned RegOp = OpNum;
547 if (!Subtarget->isGP64bit()){
548 // Endianness reverses which register holds the high or low value
549 // between M and L.
550 switch(ExtraCode[0]) {
551 case 'M':
552 RegOp = (Subtarget->isLittle()) ? OpNum + 1 : OpNum;
553 break;
554 case 'L':
555 RegOp = (Subtarget->isLittle()) ? OpNum : OpNum + 1;
556 break;
557 case 'D': // Always the second part
558 RegOp = OpNum + 1;
559 }
560 if (RegOp >= MI->getNumOperands())
561 return true;
562 const MachineOperand &MO = MI->getOperand(RegOp);
563 if (!MO.isReg())
564 return true;
565 Register Reg = MO.getReg();
566 O << '$' << MipsInstPrinter::getRegisterName(Reg);
567 return false;
568 }
569 break;
570 }
571 case 'w': {
573 if (w != Mips::NoRegister) {
575 return false;
576 }
577 break;
578 }
579 }
580 }
581
582 printOperand(MI, OpNum, O);
583 return false;
584}
585
587 unsigned OpNum,
588 const char *ExtraCode,
589 raw_ostream &O) {
590 assert(OpNum + 1 < MI->getNumOperands() && "Insufficient operands");
591 const MachineOperand &BaseMO = MI->getOperand(OpNum);
592 const MachineOperand &OffsetMO = MI->getOperand(OpNum + 1);
593 assert(BaseMO.isReg() &&
594 "Unexpected base pointer for inline asm memory operand.");
595 assert(OffsetMO.isImm() &&
596 "Unexpected offset for inline asm memory operand.");
597 int Offset = OffsetMO.getImm();
598
599 // Currently we are expecting either no ExtraCode or 'D','M','L'.
600 if (ExtraCode) {
601 switch (ExtraCode[0]) {
602 case 'D':
603 Offset += 4;
604 break;
605 case 'M':
606 if (Subtarget->isLittle())
607 Offset += 4;
608 break;
609 case 'L':
610 if (!Subtarget->isLittle())
611 Offset += 4;
612 break;
613 default:
614 return true; // Unknown modifier.
615 }
616 }
617
618 O << Offset << "($" << MipsInstPrinter::getRegisterName(BaseMO.getReg())
619 << ")";
620
621 return false;
622}
623
625 raw_ostream &O) {
626 const MachineOperand &MO = MI->getOperand(opNum);
627 bool closeP = false;
628
629 if (MO.getTargetFlags())
630 closeP = true;
631
632 switch(MO.getTargetFlags()) {
633 case MipsII::MO_GPREL: O << "%gp_rel("; break;
634 case MipsII::MO_GOT_CALL: O << "%call16("; break;
635 case MipsII::MO_GOT: O << "%got("; break;
636 case MipsII::MO_ABS_HI: O << "%hi("; break;
637 case MipsII::MO_ABS_LO: O << "%lo("; break;
638 case MipsII::MO_HIGHER: O << "%higher("; break;
639 case MipsII::MO_HIGHEST: O << "%highest(("; break;
640 case MipsII::MO_TLSGD: O << "%tlsgd("; break;
641 case MipsII::MO_GOTTPREL: O << "%gottprel("; break;
642 case MipsII::MO_TPREL_HI: O << "%tprel_hi("; break;
643 case MipsII::MO_TPREL_LO: O << "%tprel_lo("; break;
644 case MipsII::MO_GPOFF_HI: O << "%hi(%neg(%gp_rel("; break;
645 case MipsII::MO_GPOFF_LO: O << "%lo(%neg(%gp_rel("; break;
646 case MipsII::MO_GOT_DISP: O << "%got_disp("; break;
647 case MipsII::MO_GOT_PAGE: O << "%got_page("; break;
648 case MipsII::MO_GOT_OFST: O << "%got_ofst("; break;
649 }
650
651 switch (MO.getType()) {
653 O << '$'
655 break;
656
658 O << MO.getImm();
659 break;
660
662 MO.getMBB()->getSymbol()->print(O, MAI);
663 return;
664
666 PrintSymbolOperand(MO, O);
667 break;
668
671 O << BA->getName();
672 break;
673 }
674
676 O << getDataLayout().getPrivateGlobalPrefix() << "CPI"
677 << getFunctionNumber() << "_" << MO.getIndex();
678 if (MO.getOffset())
679 O << "+" << MO.getOffset();
680 break;
681
682 default:
683 llvm_unreachable("<unknown operand type>");
684 }
685
686 if (closeP) O << ")";
687}
688
690printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O) {
691 // Load/Store memory operands -- imm($reg)
692 // If PIC target the target is loaded as the
693 // pattern lw $25,%call16($28)
694
695 // opNum can be invalid if instruction has reglist as operand.
696 // MemOperand is always last operand of instruction (base + offset).
697 switch (MI->getOpcode()) {
698 default:
699 break;
700 case Mips::SWM32_MM:
701 case Mips::LWM32_MM:
702 opNum = MI->getNumOperands() - 2;
703 break;
704 }
705
706 printOperand(MI, opNum+1, O);
707 O << "(";
708 printOperand(MI, opNum, O);
709 O << ")";
710}
711
713printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O) {
714 // when using stack locations for not load/store instructions
715 // print the same way as all normal 3 operand instructions.
716 printOperand(MI, opNum, O);
717 O << ", ";
718 printOperand(MI, opNum+1, O);
719}
720
722printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
723 const char *Modifier) {
724 const MachineOperand &MO = MI->getOperand(opNum);
726}
727
729printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O) {
730 for (int i = opNum, e = MI->getNumOperands(); i != e; ++i) {
731 if (i != opNum) O << ", ";
732 printOperand(MI, i, O);
733 }
734}
735
737 MipsTargetStreamer &TS = getTargetStreamer();
738
739 // MipsTargetStreamer has an initialization order problem when emitting an
740 // object file directly (see MipsTargetELFStreamer for full details). Work
741 // around it by re-initializing the PIC state here.
743
744 // Try to get target-features from the first function.
746 Module::iterator F = M.begin();
747 if (FS.empty() && M.size() && F->hasFnAttribute("target-features"))
748 FS = F->getFnAttribute("target-features").getValueAsString();
749
750 // Compute MIPS architecture attributes based on the default subtarget
751 // that we'd have constructed.
752 // FIXME: For ifunc related functions we could iterate over and look
753 // for a feature string that doesn't match the default one.
754 const Triple &TT = TM.getTargetTriple();
756 const MipsTargetMachine &MTM = static_cast<const MipsTargetMachine &>(TM);
757 const MipsSubtarget STI(TT, CPU, FS, MTM.isLittleEndian(), MTM, std::nullopt);
758
759 bool IsABICalls = STI.isABICalls();
760 const MipsABIInfo &ABI = MTM.getABI();
761 if (IsABICalls) {
763 // FIXME: This condition should be a lot more complicated that it is here.
764 // Ideally it should test for properties of the ABI and not the ABI
765 // itself.
766 // For the moment, I'm only correcting enough to make MIPS-IV work.
767 if (!isPositionIndependent() && STI.hasSym32())
769 }
770
771 // Tell the assembler which ABI we are using
772 std::string SectionName = std::string(".mdebug.") + getCurrentABIString();
773 OutStreamer->switchSection(
775
776 // NaN: At the moment we only support:
777 // 1. .nan legacy (default)
778 // 2. .nan 2008
781
782 // TODO: handle O64 ABI
783
784 TS.updateABIInfo(STI);
785
786 // We should always emit a '.module fp=...' but binutils 2.24 does not accept
787 // it. We therefore emit it when it contradicts the ABI defaults (-mfpxx or
788 // -mfp64) and omit it otherwise.
789 if ((ABI.IsO32() && (STI.isABI_FPXX() || STI.isFP64bit())) ||
790 STI.useSoftFloat())
792
793 // We should always emit a '.module [no]oddspreg' but binutils 2.24 does not
794 // accept it. We therefore emit it when it contradicts the default or an
795 // option has changed the default (i.e. FPXX) and omit it otherwise.
796 if (ABI.IsO32() && (!STI.useOddSPReg() || STI.isABI_FPXX()))
798
799 // Switch to the .text section.
800 OutStreamer->switchSection(getObjFileLowering().getTextSection());
801}
802
803void MipsAsmPrinter::emitInlineAsmStart() const {
804 MipsTargetStreamer &TS = getTargetStreamer();
805
806 // GCC's choice of assembler options for inline assembly code ('at', 'macro'
807 // and 'reorder') is different from LLVM's choice for generated code ('noat',
808 // 'nomacro' and 'noreorder').
809 // In order to maintain compatibility with inline assembly code which depends
810 // on GCC's assembler options being used, we have to switch to those options
811 // for the duration of the inline assembly block and then switch back.
816 OutStreamer->addBlankLine();
817}
818
819void MipsAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
820 const MCSubtargetInfo *EndInfo) const {
821 OutStreamer->addBlankLine();
822 getTargetStreamer().emitDirectiveSetPop();
823}
824
825void MipsAsmPrinter::EmitJal(const MCSubtargetInfo &STI, MCSymbol *Symbol) {
826 MCInst I;
827 I.setOpcode(Mips::JAL);
828 I.addOperand(
830 OutStreamer->emitInstruction(I, STI);
831}
832
833void MipsAsmPrinter::EmitInstrReg(const MCSubtargetInfo &STI, unsigned Opcode,
834 unsigned Reg) {
835 MCInst I;
836 I.setOpcode(Opcode);
837 I.addOperand(MCOperand::createReg(Reg));
838 OutStreamer->emitInstruction(I, STI);
839}
840
841void MipsAsmPrinter::EmitInstrRegReg(const MCSubtargetInfo &STI,
842 unsigned Opcode, unsigned Reg1,
843 unsigned Reg2) {
844 MCInst I;
845 //
846 // Because of the current td files for Mips32, the operands for MTC1
847 // appear backwards from their normal assembly order. It's not a trivial
848 // change to fix this in the td file so we adjust for it here.
849 //
850 if (Opcode == Mips::MTC1) {
851 unsigned Temp = Reg1;
852 Reg1 = Reg2;
853 Reg2 = Temp;
854 }
855 I.setOpcode(Opcode);
856 I.addOperand(MCOperand::createReg(Reg1));
857 I.addOperand(MCOperand::createReg(Reg2));
858 OutStreamer->emitInstruction(I, STI);
859}
860
861void MipsAsmPrinter::EmitInstrRegRegReg(const MCSubtargetInfo &STI,
862 unsigned Opcode, unsigned Reg1,
863 unsigned Reg2, unsigned Reg3) {
864 MCInst I;
865 I.setOpcode(Opcode);
866 I.addOperand(MCOperand::createReg(Reg1));
867 I.addOperand(MCOperand::createReg(Reg2));
868 I.addOperand(MCOperand::createReg(Reg3));
869 OutStreamer->emitInstruction(I, STI);
870}
871
872void MipsAsmPrinter::EmitMovFPIntPair(const MCSubtargetInfo &STI,
873 unsigned MovOpc, unsigned Reg1,
874 unsigned Reg2, unsigned FPReg1,
875 unsigned FPReg2, bool LE) {
876 if (!LE) {
877 unsigned temp = Reg1;
878 Reg1 = Reg2;
879 Reg2 = temp;
880 }
881 EmitInstrRegReg(STI, MovOpc, Reg1, FPReg1);
882 EmitInstrRegReg(STI, MovOpc, Reg2, FPReg2);
883}
884
885void MipsAsmPrinter::EmitSwapFPIntParams(const MCSubtargetInfo &STI,
887 bool LE, bool ToFP) {
888 using namespace Mips16HardFloatInfo;
889
890 unsigned MovOpc = ToFP ? Mips::MTC1 : Mips::MFC1;
891 switch (PV) {
892 case FSig:
893 EmitInstrRegReg(STI, MovOpc, Mips::A0, Mips::F12);
894 break;
895 case FFSig:
896 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F14, LE);
897 break;
898 case FDSig:
899 EmitInstrRegReg(STI, MovOpc, Mips::A0, Mips::F12);
900 EmitMovFPIntPair(STI, MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE);
901 break;
902 case DSig:
903 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
904 break;
905 case DDSig:
906 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
907 EmitMovFPIntPair(STI, MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE);
908 break;
909 case DFSig:
910 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
911 EmitInstrRegReg(STI, MovOpc, Mips::A2, Mips::F14);
912 break;
913 case NoSig:
914 return;
915 }
916}
917
918void MipsAsmPrinter::EmitSwapFPIntRetval(
920 bool LE) {
921 using namespace Mips16HardFloatInfo;
922
923 unsigned MovOpc = Mips::MFC1;
924 switch (RV) {
925 case FRet:
926 EmitInstrRegReg(STI, MovOpc, Mips::V0, Mips::F0);
927 break;
928 case DRet:
929 EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
930 break;
931 case CFRet:
932 EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
933 break;
934 case CDRet:
935 EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
936 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F2, Mips::F3, LE);
937 break;
938 case NoFPRet:
939 break;
940 }
941}
942
943void MipsAsmPrinter::EmitFPCallStub(
944 const char *Symbol, const Mips16HardFloatInfo::FuncSignature *Signature) {
945 using namespace Mips16HardFloatInfo;
946
949 // Construct a local MCSubtargetInfo here.
950 // This is because the MachineFunction won't exist (but have not yet been
951 // freed) and since we're at the global level we can use the default
952 // constructed subtarget.
953 std::unique_ptr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo(
956
957 //
958 // .global xxxx
959 //
960 OutStreamer->emitSymbolAttribute(MSymbol, MCSA_Global);
961 const char *RetType;
962 //
963 // make the comment field identifying the return and parameter
964 // types of the floating point stub
965 // # Stub function to call rettype xxxx (params)
966 //
967 switch (Signature->RetSig) {
968 case FRet:
969 RetType = "float";
970 break;
971 case DRet:
972 RetType = "double";
973 break;
974 case CFRet:
975 RetType = "complex";
976 break;
977 case CDRet:
978 RetType = "double complex";
979 break;
980 case NoFPRet:
981 RetType = "";
982 break;
983 }
984 const char *Parms;
985 switch (Signature->ParamSig) {
986 case FSig:
987 Parms = "float";
988 break;
989 case FFSig:
990 Parms = "float, float";
991 break;
992 case FDSig:
993 Parms = "float, double";
994 break;
995 case DSig:
996 Parms = "double";
997 break;
998 case DDSig:
999 Parms = "double, double";
1000 break;
1001 case DFSig:
1002 Parms = "double, float";
1003 break;
1004 case NoSig:
1005 Parms = "";
1006 break;
1007 }
1008 OutStreamer->AddComment("\t# Stub function to call " + Twine(RetType) + " " +
1009 Twine(Symbol) + " (" + Twine(Parms) + ")");
1010 //
1011 // probably not necessary but we save and restore the current section state
1012 //
1013 OutStreamer->pushSection();
1014 //
1015 // .section mips16.call.fpxxxx,"ax",@progbits
1016 //
1018 ".mips16.call.fp." + std::string(Symbol), ELF::SHT_PROGBITS,
1020 OutStreamer->switchSection(M);
1021 //
1022 // .align 2
1023 //
1024 OutStreamer->emitValueToAlignment(Align(4));
1025 MipsTargetStreamer &TS = getTargetStreamer();
1026 //
1027 // .set nomips16
1028 // .set nomicromips
1029 //
1032 //
1033 // .ent __call_stub_fp_xxxx
1034 // .type __call_stub_fp_xxxx,@function
1035 // __call_stub_fp_xxxx:
1036 //
1037 std::string x = "__call_stub_fp_" + std::string(Symbol);
1038 MCSymbolELF *Stub =
1039 cast<MCSymbolELF>(OutContext.getOrCreateSymbol(StringRef(x)));
1040 TS.emitDirectiveEnt(*Stub);
1041 MCSymbol *MType =
1042 OutContext.getOrCreateSymbol("__call_stub_fp_" + Twine(Symbol));
1043 OutStreamer->emitSymbolAttribute(MType, MCSA_ELF_TypeFunction);
1044 OutStreamer->emitLabel(Stub);
1045
1046 // Only handle non-pic for now.
1048 "should not be here if we are compiling pic");
1050 //
1051 // We need to add a MipsMCExpr class to MCTargetDesc to fully implement
1052 // stubs without raw text but this current patch is for compiler generated
1053 // functions and they all return some value.
1054 // The calling sequence for non pic is different in that case and we need
1055 // to implement %lo and %hi in order to handle the case of no return value
1056 // See the corresponding method in Mips16HardFloat for details.
1057 //
1058 // mov the return address to S2.
1059 // we have no stack space to store it and we are about to make another call.
1060 // We need to make sure that the enclosing function knows to save S2
1061 // This should have already been handled.
1062 //
1063 // Mov $18, $31
1064
1065 EmitInstrRegRegReg(*STI, Mips::OR, Mips::S2, Mips::RA, Mips::ZERO);
1066
1067 EmitSwapFPIntParams(*STI, Signature->ParamSig, LE, true);
1068
1069 // Jal xxxx
1070 //
1071 EmitJal(*STI, MSymbol);
1072
1073 // fix return values
1074 EmitSwapFPIntRetval(*STI, Signature->RetSig, LE);
1075 //
1076 // do the return
1077 // if (Signature->RetSig == NoFPRet)
1078 // llvm_unreachable("should not be any stubs here with no return value");
1079 // else
1080 EmitInstrReg(*STI, Mips::JR, Mips::S2);
1081
1083 OutStreamer->emitLabel(Tmp);
1086 const MCExpr *T_min_E = MCBinaryExpr::createSub(T, E, OutContext);
1087 OutStreamer->emitELFSize(Stub, T_min_E);
1088 TS.emitDirectiveEnd(x);
1089 OutStreamer->popSection();
1090}
1091
1093 // Emit needed stubs
1094 //
1095 for (std::map<
1096 const char *,
1098 it = StubsNeeded.begin();
1099 it != StubsNeeded.end(); ++it) {
1100 const char *Symbol = it->first;
1101 const Mips16HardFloatInfo::FuncSignature *Signature = it->second;
1102 EmitFPCallStub(Symbol, Signature);
1103 }
1104 // return to the text section
1106}
1107
1108void MipsAsmPrinter::EmitSled(const MachineInstr &MI, SledKind Kind) {
1109 const uint8_t NoopsInSledCount = Subtarget->isGP64bit() ? 15 : 11;
1110 // For mips32 we want to emit the following pattern:
1111 //
1112 // .Lxray_sled_N:
1113 // ALIGN
1114 // B .tmpN
1115 // 11 NOP instructions (44 bytes)
1116 // ADDIU T9, T9, 52
1117 // .tmpN
1118 //
1119 // We need the 44 bytes (11 instructions) because at runtime, we'd
1120 // be patching over the full 48 bytes (12 instructions) with the following
1121 // pattern:
1122 //
1123 // ADDIU SP, SP, -8
1124 // NOP
1125 // SW RA, 4(SP)
1126 // SW T9, 0(SP)
1127 // LUI T9, %hi(__xray_FunctionEntry/Exit)
1128 // ORI T9, T9, %lo(__xray_FunctionEntry/Exit)
1129 // LUI T0, %hi(function_id)
1130 // JALR T9
1131 // ORI T0, T0, %lo(function_id)
1132 // LW T9, 0(SP)
1133 // LW RA, 4(SP)
1134 // ADDIU SP, SP, 8
1135 //
1136 // We add 52 bytes to t9 because we want to adjust the function pointer to
1137 // the actual start of function i.e. the address just after the noop sled.
1138 // We do this because gp displacement relocation is emitted at the start of
1139 // of the function i.e after the nop sled and to correctly calculate the
1140 // global offset table address, t9 must hold the address of the instruction
1141 // containing the gp displacement relocation.
1142 // FIXME: Is this correct for the static relocation model?
1143 //
1144 // For mips64 we want to emit the following pattern:
1145 //
1146 // .Lxray_sled_N:
1147 // ALIGN
1148 // B .tmpN
1149 // 15 NOP instructions (60 bytes)
1150 // .tmpN
1151 //
1152 // We need the 60 bytes (15 instructions) because at runtime, we'd
1153 // be patching over the full 64 bytes (16 instructions) with the following
1154 // pattern:
1155 //
1156 // DADDIU SP, SP, -16
1157 // NOP
1158 // SD RA, 8(SP)
1159 // SD T9, 0(SP)
1160 // LUI T9, %highest(__xray_FunctionEntry/Exit)
1161 // ORI T9, T9, %higher(__xray_FunctionEntry/Exit)
1162 // DSLL T9, T9, 16
1163 // ORI T9, T9, %hi(__xray_FunctionEntry/Exit)
1164 // DSLL T9, T9, 16
1165 // ORI T9, T9, %lo(__xray_FunctionEntry/Exit)
1166 // LUI T0, %hi(function_id)
1167 // JALR T9
1168 // ADDIU T0, T0, %lo(function_id)
1169 // LD T9, 0(SP)
1170 // LD RA, 8(SP)
1171 // DADDIU SP, SP, 16
1172 //
1173 OutStreamer->emitCodeAlignment(Align(4), &getSubtargetInfo());
1174 auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
1175 OutStreamer->emitLabel(CurSled);
1177
1178 // Emit "B .tmpN" instruction, which jumps over the nop sled to the actual
1179 // start of function
1180 const MCExpr *TargetExpr = MCSymbolRefExpr::create(
1183 .addReg(Mips::ZERO)
1184 .addReg(Mips::ZERO)
1185 .addExpr(TargetExpr));
1186
1187 for (int8_t I = 0; I < NoopsInSledCount; I++)
1189 .addReg(Mips::ZERO)
1190 .addReg(Mips::ZERO)
1191 .addImm(0));
1192
1193 OutStreamer->emitLabel(Target);
1194
1195 if (!Subtarget->isGP64bit()) {
1197 MCInstBuilder(Mips::ADDiu)
1198 .addReg(Mips::T9)
1199 .addReg(Mips::T9)
1200 .addImm(0x34));
1201 }
1202
1203 recordSled(CurSled, MI, Kind, 2);
1204}
1205
1207 EmitSled(MI, SledKind::FUNCTION_ENTER);
1208}
1209
1211 EmitSled(MI, SledKind::FUNCTION_EXIT);
1212}
1213
1215 EmitSled(MI, SledKind::TAIL_CALL);
1216}
1217
1219 raw_ostream &OS) {
1220 // TODO: implement
1221}
1222
1223// Emit .dtprelword or .dtpreldword directive
1224// and value for debug thread local expression.
1225void MipsAsmPrinter::emitDebugValue(const MCExpr *Value, unsigned Size) const {
1226 if (auto *MipsExpr = dyn_cast<MipsMCExpr>(Value)) {
1227 if (MipsExpr && MipsExpr->getKind() == MipsMCExpr::MEK_DTPREL) {
1228 switch (Size) {
1229 case 4:
1230 OutStreamer->emitDTPRel32Value(MipsExpr->getSubExpr());
1231 break;
1232 case 8:
1233 OutStreamer->emitDTPRel64Value(MipsExpr->getSubExpr());
1234 break;
1235 default:
1236 llvm_unreachable("Unexpected size of expression value.");
1237 }
1238 return;
1239 }
1240 }
1242}
1243
1244// Align all targets of indirect branches on bundle size. Used only if target
1245// is NaCl.
1246void MipsAsmPrinter::NaClAlignIndirectJumpTargets(MachineFunction &MF) {
1247 // Align all blocks that are jumped to through jump table.
1248 if (MachineJumpTableInfo *JtInfo = MF.getJumpTableInfo()) {
1249 const std::vector<MachineJumpTableEntry> &JT = JtInfo->getJumpTables();
1250 for (const auto &I : JT) {
1251 const std::vector<MachineBasicBlock *> &MBBs = I.MBBs;
1252
1253 for (MachineBasicBlock *MBB : MBBs)
1255 }
1256 }
1257
1258 // If basic block address is taken, block can be target of indirect branch.
1259 for (auto &MBB : MF) {
1260 if (MBB.hasAddressTaken())
1262 }
1263}
1264
1265bool MipsAsmPrinter::isLongBranchPseudo(int Opcode) const {
1266 return (Opcode == Mips::LONG_BRANCH_LUi
1267 || Opcode == Mips::LONG_BRANCH_LUi2Op
1268 || Opcode == Mips::LONG_BRANCH_LUi2Op_64
1269 || Opcode == Mips::LONG_BRANCH_ADDiu
1270 || Opcode == Mips::LONG_BRANCH_ADDiu2Op
1271 || Opcode == Mips::LONG_BRANCH_DADDiu
1272 || Opcode == Mips::LONG_BRANCH_DADDiu2Op);
1273}
1274
1275// Force static initialization.
1281}
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")
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:383
virtual void emitDebugValue(const MCExpr *Value, unsigned Size) const
Emit the directive and value for debug thread local expression.
Definition: AsmPrinter.cpp:895
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
Definition: AsmPrinter.cpp:403
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:379
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:374
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:387
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
Definition: AsmPrinter.cpp:398
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:195
StringRef getPrivateGlobalPrefix() const
Definition: DataLayout.h:289
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:743
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:617
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:346
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:213
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: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:1063
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:414
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:188
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:393
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: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:1089
@ SHF_ALLOC
Definition: ELF.h:1186
@ SHF_EXECINSTR
Definition: ELF.h:1189
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,...