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