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': {
570 if (w != Mips::NoRegister) {
572 return false;
573 }
574 break;
575 }
576 }
577 }
578
579 printOperand(MI, OpNum, O);
580 return false;
581}
582
584 unsigned OpNum,
585 const char *ExtraCode,
586 raw_ostream &O) {
587 assert(OpNum + 1 < MI->getNumOperands() && "Insufficient operands");
588 const MachineOperand &BaseMO = MI->getOperand(OpNum);
589 const MachineOperand &OffsetMO = MI->getOperand(OpNum + 1);
590 assert(BaseMO.isReg() &&
591 "Unexpected base pointer for inline asm memory operand.");
592 assert(OffsetMO.isImm() &&
593 "Unexpected offset for inline asm memory operand.");
594 int Offset = OffsetMO.getImm();
595
596 // Currently we are expecting either no ExtraCode or 'D','M','L'.
597 if (ExtraCode) {
598 switch (ExtraCode[0]) {
599 case 'D':
600 Offset += 4;
601 break;
602 case 'M':
603 if (Subtarget->isLittle())
604 Offset += 4;
605 break;
606 case 'L':
607 if (!Subtarget->isLittle())
608 Offset += 4;
609 break;
610 default:
611 return true; // Unknown modifier.
612 }
613 }
614
615 O << Offset << "($" << MipsInstPrinter::getRegisterName(BaseMO.getReg())
616 << ")";
617
618 return false;
619}
620
622 raw_ostream &O) {
623 const MachineOperand &MO = MI->getOperand(opNum);
624 bool closeP = false;
625
626 if (MO.getTargetFlags())
627 closeP = true;
628
629 switch(MO.getTargetFlags()) {
630 case MipsII::MO_GPREL: O << "%gp_rel("; break;
631 case MipsII::MO_GOT_CALL: O << "%call16("; break;
632 case MipsII::MO_GOT: O << "%got("; break;
633 case MipsII::MO_ABS_HI: O << "%hi("; break;
634 case MipsII::MO_ABS_LO: O << "%lo("; break;
635 case MipsII::MO_HIGHER: O << "%higher("; break;
636 case MipsII::MO_HIGHEST: O << "%highest(("; break;
637 case MipsII::MO_TLSGD: O << "%tlsgd("; break;
638 case MipsII::MO_GOTTPREL: O << "%gottprel("; break;
639 case MipsII::MO_TPREL_HI: O << "%tprel_hi("; break;
640 case MipsII::MO_TPREL_LO: O << "%tprel_lo("; break;
641 case MipsII::MO_GPOFF_HI: O << "%hi(%neg(%gp_rel("; break;
642 case MipsII::MO_GPOFF_LO: O << "%lo(%neg(%gp_rel("; break;
643 case MipsII::MO_GOT_DISP: O << "%got_disp("; break;
644 case MipsII::MO_GOT_PAGE: O << "%got_page("; break;
645 case MipsII::MO_GOT_OFST: O << "%got_ofst("; break;
646 }
647
648 switch (MO.getType()) {
650 O << '$'
652 break;
653
655 O << MO.getImm();
656 break;
657
659 MO.getMBB()->getSymbol()->print(O, MAI);
660 return;
661
663 PrintSymbolOperand(MO, O);
664 break;
665
668 O << BA->getName();
669 break;
670 }
671
673 O << getDataLayout().getPrivateGlobalPrefix() << "CPI"
674 << getFunctionNumber() << "_" << MO.getIndex();
675 if (MO.getOffset())
676 O << "+" << MO.getOffset();
677 break;
678
679 default:
680 llvm_unreachable("<unknown operand type>");
681 }
682
683 if (closeP) O << ")";
684}
685
687printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O) {
688 // Load/Store memory operands -- imm($reg)
689 // If PIC target the target is loaded as the
690 // pattern lw $25,%call16($28)
691
692 // opNum can be invalid if instruction has reglist as operand.
693 // MemOperand is always last operand of instruction (base + offset).
694 switch (MI->getOpcode()) {
695 default:
696 break;
697 case Mips::SWM32_MM:
698 case Mips::LWM32_MM:
699 opNum = MI->getNumOperands() - 2;
700 break;
701 }
702
703 printOperand(MI, opNum+1, O);
704 O << "(";
705 printOperand(MI, opNum, O);
706 O << ")";
707}
708
710printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O) {
711 // when using stack locations for not load/store instructions
712 // print the same way as all normal 3 operand instructions.
713 printOperand(MI, opNum, O);
714 O << ", ";
715 printOperand(MI, opNum+1, O);
716}
717
719printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
720 const char *Modifier) {
721 const MachineOperand &MO = MI->getOperand(opNum);
723}
724
726printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O) {
727 for (int i = opNum, e = MI->getNumOperands(); i != e; ++i) {
728 if (i != opNum) O << ", ";
729 printOperand(MI, i, O);
730 }
731}
732
734 MipsTargetStreamer &TS = getTargetStreamer();
735
736 // MipsTargetStreamer has an initialization order problem when emitting an
737 // object file directly (see MipsTargetELFStreamer for full details). Work
738 // around it by re-initializing the PIC state here.
740
741 // Try to get target-features from the first function.
743 Module::iterator F = M.begin();
744 if (FS.empty() && M.size() && F->hasFnAttribute("target-features"))
745 FS = F->getFnAttribute("target-features").getValueAsString();
746
747 // Compute MIPS architecture attributes based on the default subtarget
748 // that we'd have constructed.
749 // FIXME: For ifunc related functions we could iterate over and look
750 // for a feature string that doesn't match the default one.
751 const Triple &TT = TM.getTargetTriple();
753 const MipsTargetMachine &MTM = static_cast<const MipsTargetMachine &>(TM);
754 const MipsSubtarget STI(TT, CPU, FS, MTM.isLittleEndian(), MTM, std::nullopt);
755
756 bool IsABICalls = STI.isABICalls();
757 const MipsABIInfo &ABI = MTM.getABI();
758 if (IsABICalls) {
760 // FIXME: This condition should be a lot more complicated that it is here.
761 // Ideally it should test for properties of the ABI and not the ABI
762 // itself.
763 // For the moment, I'm only correcting enough to make MIPS-IV work.
764 if (!isPositionIndependent() && STI.hasSym32())
766 }
767
768 // Tell the assembler which ABI we are using
769 std::string SectionName = std::string(".mdebug.") + getCurrentABIString();
770 OutStreamer->switchSection(
772
773 // NaN: At the moment we only support:
774 // 1. .nan legacy (default)
775 // 2. .nan 2008
778
779 // TODO: handle O64 ABI
780
781 TS.updateABIInfo(STI);
782
783 // We should always emit a '.module fp=...' but binutils 2.24 does not accept
784 // it. We therefore emit it when it contradicts the ABI defaults (-mfpxx or
785 // -mfp64) and omit it otherwise.
786 if ((ABI.IsO32() && (STI.isABI_FPXX() || STI.isFP64bit())) ||
787 STI.useSoftFloat())
789
790 // We should always emit a '.module [no]oddspreg' but binutils 2.24 does not
791 // accept it. We therefore emit it when it contradicts the default or an
792 // option has changed the default (i.e. FPXX) and omit it otherwise.
793 if (ABI.IsO32() && (!STI.useOddSPReg() || STI.isABI_FPXX()))
795
796 // Switch to the .text section.
797 OutStreamer->switchSection(getObjFileLowering().getTextSection());
798}
799
800void MipsAsmPrinter::emitInlineAsmStart() const {
801 MipsTargetStreamer &TS = getTargetStreamer();
802
803 // GCC's choice of assembler options for inline assembly code ('at', 'macro'
804 // and 'reorder') is different from LLVM's choice for generated code ('noat',
805 // 'nomacro' and 'noreorder').
806 // In order to maintain compatibility with inline assembly code which depends
807 // on GCC's assembler options being used, we have to switch to those options
808 // for the duration of the inline assembly block and then switch back.
813 OutStreamer->addBlankLine();
814}
815
816void MipsAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
817 const MCSubtargetInfo *EndInfo) const {
818 OutStreamer->addBlankLine();
819 getTargetStreamer().emitDirectiveSetPop();
820}
821
822void MipsAsmPrinter::EmitJal(const MCSubtargetInfo &STI, MCSymbol *Symbol) {
823 MCInst I;
824 I.setOpcode(Mips::JAL);
825 I.addOperand(
827 OutStreamer->emitInstruction(I, STI);
828}
829
830void MipsAsmPrinter::EmitInstrReg(const MCSubtargetInfo &STI, unsigned Opcode,
831 unsigned Reg) {
832 MCInst I;
833 I.setOpcode(Opcode);
834 I.addOperand(MCOperand::createReg(Reg));
835 OutStreamer->emitInstruction(I, STI);
836}
837
838void MipsAsmPrinter::EmitInstrRegReg(const MCSubtargetInfo &STI,
839 unsigned Opcode, unsigned Reg1,
840 unsigned Reg2) {
841 MCInst I;
842 //
843 // Because of the current td files for Mips32, the operands for MTC1
844 // appear backwards from their normal assembly order. It's not a trivial
845 // change to fix this in the td file so we adjust for it here.
846 //
847 if (Opcode == Mips::MTC1) {
848 unsigned Temp = Reg1;
849 Reg1 = Reg2;
850 Reg2 = Temp;
851 }
852 I.setOpcode(Opcode);
853 I.addOperand(MCOperand::createReg(Reg1));
854 I.addOperand(MCOperand::createReg(Reg2));
855 OutStreamer->emitInstruction(I, STI);
856}
857
858void MipsAsmPrinter::EmitInstrRegRegReg(const MCSubtargetInfo &STI,
859 unsigned Opcode, unsigned Reg1,
860 unsigned Reg2, unsigned Reg3) {
861 MCInst I;
862 I.setOpcode(Opcode);
863 I.addOperand(MCOperand::createReg(Reg1));
864 I.addOperand(MCOperand::createReg(Reg2));
865 I.addOperand(MCOperand::createReg(Reg3));
866 OutStreamer->emitInstruction(I, STI);
867}
868
869void MipsAsmPrinter::EmitMovFPIntPair(const MCSubtargetInfo &STI,
870 unsigned MovOpc, unsigned Reg1,
871 unsigned Reg2, unsigned FPReg1,
872 unsigned FPReg2, bool LE) {
873 if (!LE) {
874 unsigned temp = Reg1;
875 Reg1 = Reg2;
876 Reg2 = temp;
877 }
878 EmitInstrRegReg(STI, MovOpc, Reg1, FPReg1);
879 EmitInstrRegReg(STI, MovOpc, Reg2, FPReg2);
880}
881
882void MipsAsmPrinter::EmitSwapFPIntParams(const MCSubtargetInfo &STI,
884 bool LE, bool ToFP) {
885 using namespace Mips16HardFloatInfo;
886
887 unsigned MovOpc = ToFP ? Mips::MTC1 : Mips::MFC1;
888 switch (PV) {
889 case FSig:
890 EmitInstrRegReg(STI, MovOpc, Mips::A0, Mips::F12);
891 break;
892 case FFSig:
893 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F14, LE);
894 break;
895 case FDSig:
896 EmitInstrRegReg(STI, MovOpc, Mips::A0, Mips::F12);
897 EmitMovFPIntPair(STI, MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE);
898 break;
899 case DSig:
900 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
901 break;
902 case DDSig:
903 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
904 EmitMovFPIntPair(STI, MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE);
905 break;
906 case DFSig:
907 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
908 EmitInstrRegReg(STI, MovOpc, Mips::A2, Mips::F14);
909 break;
910 case NoSig:
911 return;
912 }
913}
914
915void MipsAsmPrinter::EmitSwapFPIntRetval(
917 bool LE) {
918 using namespace Mips16HardFloatInfo;
919
920 unsigned MovOpc = Mips::MFC1;
921 switch (RV) {
922 case FRet:
923 EmitInstrRegReg(STI, MovOpc, Mips::V0, Mips::F0);
924 break;
925 case DRet:
926 EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
927 break;
928 case CFRet:
929 EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
930 break;
931 case CDRet:
932 EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
933 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F2, Mips::F3, LE);
934 break;
935 case NoFPRet:
936 break;
937 }
938}
939
940void MipsAsmPrinter::EmitFPCallStub(
941 const char *Symbol, const Mips16HardFloatInfo::FuncSignature *Signature) {
942 using namespace Mips16HardFloatInfo;
943
946 // Construct a local MCSubtargetInfo here.
947 // This is because the MachineFunction won't exist (but have not yet been
948 // freed) and since we're at the global level we can use the default
949 // constructed subtarget.
950 std::unique_ptr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo(
953
954 //
955 // .global xxxx
956 //
957 OutStreamer->emitSymbolAttribute(MSymbol, MCSA_Global);
958 const char *RetType;
959 //
960 // make the comment field identifying the return and parameter
961 // types of the floating point stub
962 // # Stub function to call rettype xxxx (params)
963 //
964 switch (Signature->RetSig) {
965 case FRet:
966 RetType = "float";
967 break;
968 case DRet:
969 RetType = "double";
970 break;
971 case CFRet:
972 RetType = "complex";
973 break;
974 case CDRet:
975 RetType = "double complex";
976 break;
977 case NoFPRet:
978 RetType = "";
979 break;
980 }
981 const char *Parms;
982 switch (Signature->ParamSig) {
983 case FSig:
984 Parms = "float";
985 break;
986 case FFSig:
987 Parms = "float, float";
988 break;
989 case FDSig:
990 Parms = "float, double";
991 break;
992 case DSig:
993 Parms = "double";
994 break;
995 case DDSig:
996 Parms = "double, double";
997 break;
998 case DFSig:
999 Parms = "double, float";
1000 break;
1001 case NoSig:
1002 Parms = "";
1003 break;
1004 }
1005 OutStreamer->AddComment("\t# Stub function to call " + Twine(RetType) + " " +
1006 Twine(Symbol) + " (" + Twine(Parms) + ")");
1007 //
1008 // probably not necessary but we save and restore the current section state
1009 //
1010 OutStreamer->pushSection();
1011 //
1012 // .section mips16.call.fpxxxx,"ax",@progbits
1013 //
1015 ".mips16.call.fp." + std::string(Symbol), ELF::SHT_PROGBITS,
1017 OutStreamer->switchSection(M);
1018 //
1019 // .align 2
1020 //
1021 OutStreamer->emitValueToAlignment(Align(4));
1022 MipsTargetStreamer &TS = getTargetStreamer();
1023 //
1024 // .set nomips16
1025 // .set nomicromips
1026 //
1029 //
1030 // .ent __call_stub_fp_xxxx
1031 // .type __call_stub_fp_xxxx,@function
1032 // __call_stub_fp_xxxx:
1033 //
1034 std::string x = "__call_stub_fp_" + std::string(Symbol);
1035 MCSymbolELF *Stub =
1036 cast<MCSymbolELF>(OutContext.getOrCreateSymbol(StringRef(x)));
1037 TS.emitDirectiveEnt(*Stub);
1038 MCSymbol *MType =
1039 OutContext.getOrCreateSymbol("__call_stub_fp_" + Twine(Symbol));
1040 OutStreamer->emitSymbolAttribute(MType, MCSA_ELF_TypeFunction);
1041 OutStreamer->emitLabel(Stub);
1042
1043 // Only handle non-pic for now.
1045 "should not be here if we are compiling pic");
1047 //
1048 // We need to add a MipsMCExpr class to MCTargetDesc to fully implement
1049 // stubs without raw text but this current patch is for compiler generated
1050 // functions and they all return some value.
1051 // The calling sequence for non pic is different in that case and we need
1052 // to implement %lo and %hi in order to handle the case of no return value
1053 // See the corresponding method in Mips16HardFloat for details.
1054 //
1055 // mov the return address to S2.
1056 // we have no stack space to store it and we are about to make another call.
1057 // We need to make sure that the enclosing function knows to save S2
1058 // This should have already been handled.
1059 //
1060 // Mov $18, $31
1061
1062 EmitInstrRegRegReg(*STI, Mips::OR, Mips::S2, Mips::RA, Mips::ZERO);
1063
1064 EmitSwapFPIntParams(*STI, Signature->ParamSig, LE, true);
1065
1066 // Jal xxxx
1067 //
1068 EmitJal(*STI, MSymbol);
1069
1070 // fix return values
1071 EmitSwapFPIntRetval(*STI, Signature->RetSig, LE);
1072 //
1073 // do the return
1074 // if (Signature->RetSig == NoFPRet)
1075 // llvm_unreachable("should not be any stubs here with no return value");
1076 // else
1077 EmitInstrReg(*STI, Mips::JR, Mips::S2);
1078
1080 OutStreamer->emitLabel(Tmp);
1083 const MCExpr *T_min_E = MCBinaryExpr::createSub(T, E, OutContext);
1084 OutStreamer->emitELFSize(Stub, T_min_E);
1085 TS.emitDirectiveEnd(x);
1086 OutStreamer->popSection();
1087}
1088
1090 // Emit needed stubs
1091 //
1092 for (std::map<
1093 const char *,
1095 it = StubsNeeded.begin();
1096 it != StubsNeeded.end(); ++it) {
1097 const char *Symbol = it->first;
1098 const Mips16HardFloatInfo::FuncSignature *Signature = it->second;
1099 EmitFPCallStub(Symbol, Signature);
1100 }
1101 // return to the text section
1103}
1104
1105void MipsAsmPrinter::EmitSled(const MachineInstr &MI, SledKind Kind) {
1106 const uint8_t NoopsInSledCount = Subtarget->isGP64bit() ? 15 : 11;
1107 // For mips32 we want to emit the following pattern:
1108 //
1109 // .Lxray_sled_N:
1110 // ALIGN
1111 // B .tmpN
1112 // 11 NOP instructions (44 bytes)
1113 // ADDIU T9, T9, 52
1114 // .tmpN
1115 //
1116 // We need the 44 bytes (11 instructions) because at runtime, we'd
1117 // be patching over the full 48 bytes (12 instructions) with the following
1118 // pattern:
1119 //
1120 // ADDIU SP, SP, -8
1121 // NOP
1122 // SW RA, 4(SP)
1123 // SW T9, 0(SP)
1124 // LUI T9, %hi(__xray_FunctionEntry/Exit)
1125 // ORI T9, T9, %lo(__xray_FunctionEntry/Exit)
1126 // LUI T0, %hi(function_id)
1127 // JALR T9
1128 // ORI T0, T0, %lo(function_id)
1129 // LW T9, 0(SP)
1130 // LW RA, 4(SP)
1131 // ADDIU SP, SP, 8
1132 //
1133 // We add 52 bytes to t9 because we want to adjust the function pointer to
1134 // the actual start of function i.e. the address just after the noop sled.
1135 // We do this because gp displacement relocation is emitted at the start of
1136 // of the function i.e after the nop sled and to correctly calculate the
1137 // global offset table address, t9 must hold the address of the instruction
1138 // containing the gp displacement relocation.
1139 // FIXME: Is this correct for the static relocation model?
1140 //
1141 // For mips64 we want to emit the following pattern:
1142 //
1143 // .Lxray_sled_N:
1144 // ALIGN
1145 // B .tmpN
1146 // 15 NOP instructions (60 bytes)
1147 // .tmpN
1148 //
1149 // We need the 60 bytes (15 instructions) because at runtime, we'd
1150 // be patching over the full 64 bytes (16 instructions) with the following
1151 // pattern:
1152 //
1153 // DADDIU SP, SP, -16
1154 // NOP
1155 // SD RA, 8(SP)
1156 // SD T9, 0(SP)
1157 // LUI T9, %highest(__xray_FunctionEntry/Exit)
1158 // ORI T9, T9, %higher(__xray_FunctionEntry/Exit)
1159 // DSLL T9, T9, 16
1160 // ORI T9, T9, %hi(__xray_FunctionEntry/Exit)
1161 // DSLL T9, T9, 16
1162 // ORI T9, T9, %lo(__xray_FunctionEntry/Exit)
1163 // LUI T0, %hi(function_id)
1164 // JALR T9
1165 // ADDIU T0, T0, %lo(function_id)
1166 // LD T9, 0(SP)
1167 // LD RA, 8(SP)
1168 // DADDIU SP, SP, 16
1169 //
1170 OutStreamer->emitCodeAlignment(Align(4), &getSubtargetInfo());
1171 auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
1172 OutStreamer->emitLabel(CurSled);
1174
1175 // Emit "B .tmpN" instruction, which jumps over the nop sled to the actual
1176 // start of function
1177 const MCExpr *TargetExpr = MCSymbolRefExpr::create(
1180 .addReg(Mips::ZERO)
1181 .addReg(Mips::ZERO)
1182 .addExpr(TargetExpr));
1183
1184 for (int8_t I = 0; I < NoopsInSledCount; I++)
1186 .addReg(Mips::ZERO)
1187 .addReg(Mips::ZERO)
1188 .addImm(0));
1189
1190 OutStreamer->emitLabel(Target);
1191
1192 if (!Subtarget->isGP64bit()) {
1194 MCInstBuilder(Mips::ADDiu)
1195 .addReg(Mips::T9)
1196 .addReg(Mips::T9)
1197 .addImm(0x34));
1198 }
1199
1200 recordSled(CurSled, MI, Kind, 2);
1201}
1202
1204 EmitSled(MI, SledKind::FUNCTION_ENTER);
1205}
1206
1208 EmitSled(MI, SledKind::FUNCTION_EXIT);
1209}
1210
1212 EmitSled(MI, SledKind::TAIL_CALL);
1213}
1214
1216 raw_ostream &OS) {
1217 // TODO: implement
1218}
1219
1220// Emit .dtprelword or .dtpreldword directive
1221// and value for debug thread local expression.
1222void MipsAsmPrinter::emitDebugValue(const MCExpr *Value, unsigned Size) const {
1223 if (auto *MipsExpr = dyn_cast<MipsMCExpr>(Value)) {
1224 if (MipsExpr && MipsExpr->getKind() == MipsMCExpr::MEK_DTPREL) {
1225 switch (Size) {
1226 case 4:
1227 OutStreamer->emitDTPRel32Value(MipsExpr->getSubExpr());
1228 break;
1229 case 8:
1230 OutStreamer->emitDTPRel64Value(MipsExpr->getSubExpr());
1231 break;
1232 default:
1233 llvm_unreachable("Unexpected size of expression value.");
1234 }
1235 return;
1236 }
1237 }
1239}
1240
1241// Align all targets of indirect branches on bundle size. Used only if target
1242// is NaCl.
1243void MipsAsmPrinter::NaClAlignIndirectJumpTargets(MachineFunction &MF) {
1244 // Align all blocks that are jumped to through jump table.
1245 if (MachineJumpTableInfo *JtInfo = MF.getJumpTableInfo()) {
1246 const std::vector<MachineJumpTableEntry> &JT = JtInfo->getJumpTables();
1247 for (const auto &I : JT) {
1248 const std::vector<MachineBasicBlock *> &MBBs = I.MBBs;
1249
1250 for (MachineBasicBlock *MBB : MBBs)
1252 }
1253 }
1254
1255 // If basic block address is taken, block can be target of indirect branch.
1256 for (auto &MBB : MF) {
1257 if (MBB.hasAddressTaken())
1259 }
1260}
1261
1262bool MipsAsmPrinter::isLongBranchPseudo(int Opcode) const {
1263 return (Opcode == Mips::LONG_BRANCH_LUi
1264 || Opcode == Mips::LONG_BRANCH_LUi2Op
1265 || Opcode == Mips::LONG_BRANCH_LUi2Op_64
1266 || Opcode == Mips::LONG_BRANCH_ADDiu
1267 || Opcode == Mips::LONG_BRANCH_ADDiu2Op
1268 || Opcode == Mips::LONG_BRANCH_DADDiu
1269 || Opcode == Mips::LONG_BRANCH_DADDiu2Op);
1270}
1271
1272// Force static initialization.
1278}
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
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const char LLVMTargetMachineRef TM
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file defines the SmallString class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:469
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
Definition: AsmPrinter.cpp:399
virtual void emitDebugValue(const MCExpr *Value, unsigned Size) const
Emit the directive and value for debug thread local expression.
Definition: AsmPrinter.cpp:928
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
Definition: AsmPrinter.cpp:419
TargetMachine & TM
Target machine description.
Definition: AsmPrinter.h:88
void emitXRayTable()
Emit a table with all XRay instrumentation points.
virtual void emitBasicBlockEnd(const MachineBasicBlock &MBB)
Targets can override this to emit stuff at the end of a basic block.
virtual MCSymbol * GetCPISymbol(unsigned CPID) const
Return the symbol for the specified constant pool entry.
virtual void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS)
Print the MachineOperand as a symbol.
const MCAsmInfo * MAI
Target Asm Printer information.
Definition: AsmPrinter.h:91
MachineFunction * MF
The current machine function.
Definition: AsmPrinter.h:103
virtual void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV)
void recordSled(MCSymbol *Sled, const MachineInstr &MI, SledKind Kind, uint8_t Version=0)
unsigned getFunctionNumber() const
Return a unique ID for the current function.
Definition: AsmPrinter.cpp:395
void emitGlobalConstant(const DataLayout &DL, const Constant *CV, AliasMapTy *AliasList=nullptr)
EmitGlobalConstant - Print a general LLVM constant to the .s file.
MCSymbol * CurrentFnSym
The symbol for the current function.
Definition: AsmPrinter.h:122
void emitAlignment(Align Alignment, const GlobalObject *GV=nullptr, unsigned MaxBytesToEmit=0) const
Emit an alignment directive to the specified power of two boundary.
MCContext & OutContext
This is the context for the output file that we are streaming.
Definition: AsmPrinter.h:95
bool isPositionIndependent() const
Definition: AsmPrinter.cpp:390
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
Definition: AsmPrinter.h:396
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition: AsmPrinter.h:100
MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const
Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.
const DataLayout & getDataLayout() const
Return information about data layout.
Definition: AsmPrinter.cpp:403
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
Definition: AsmPrinter.cpp:414
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
bool isLittleEndian() const
Layout endianness...
Definition: DataLayout.h:238
StringRef getPrivateGlobalPrefix() const
Definition: DataLayout.h:332
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:680
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:621
Context object for machine code objects.
Definition: MCContext.h:83
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:413
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:345
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition: MCContext.h:544
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:212
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
void addOperand(const MCOperand Op)
Definition: MCInst.h:210
void setOpcode(unsigned Op)
Definition: MCInst.h:197
bool isPositionIndependent() const
MCSection * getTextSection() const
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:134
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:162
bool isValid() const
Definition: MCInst.h:60
MCRegister getRARegister() const
This method should return the register where the return address can be found.
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
This represents a section on linux, lots of unix variants and some bare metal systems.
Definition: MCSectionELF.h:27
Streaming machine code generation interface.
Definition: MCStreamer.h: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:1076
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:423
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:397
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition: MCSymbol.cpp:58
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:205
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
bool hasAddressTaken() const
Test whether this block is used as something other than the target of a terminator,...
void setAlignment(Align A)
Set alignment of the basic block.
Instructions::const_iterator const_instr_iterator
This class is a data container for one entry in a MachineConstantPool.
bool isMachineConstantPoolEntry() const
isMachineConstantPoolEntry - Return true if the MachineConstantPoolEntry is indeed a target specific ...
MachineConstantPoolValue * MachineCPVal
union llvm::MachineConstantPoolEntry::@198 Val
The constant itself.
const std::vector< MachineConstantPoolEntry > & getConstants() const
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Align getAlignment() const
getAlignment - Return the alignment of the function.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
Representation of each machine instruction.
Definition: MachineInstr.h:69
MachineOperand class - Representation of each machine instruction operand.
bool isMCSymbol() const
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
const BlockAddress * getBlockAddress() const
unsigned getTargetFlags() const
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Register getReg() const
getReg - Returns the register number.
MCSymbol * getMCSymbol() const
@ MO_Immediate
Immediate operand.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_GlobalAddress
Address of a global value.
@ MO_BlockAddress
Address of a basic block.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_Register
Register operand.
int64_t getOffset() const
Return the offset from the symbol in this operand.
void emitFunctionBodyStart() override
EmitFunctionBodyStart - Targets can override this to emit stuff before the first basic block in the f...
void emitDebugValue(const MCExpr *Value, unsigned Size) const override
Emit the directive and value for debug thread local expression.
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &O) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
void emitBasicBlockEnd(const MachineBasicBlock &MBB) override
Targets can override this to emit stuff at the end of a basic block.
void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI)
const char * getCurrentABIString() const
Emit Set directives.
void printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O)
void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS)
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
void emitFunctionBodyEnd() override
EmitFunctionBodyEnd - Targets can override this to emit stuff after the last basic block in the funct...
MipsMCInstLower MCInstLowering
void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O)
void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI)
void printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O, const char *Modifier=nullptr)
const MipsSubtarget * Subtarget
const MipsFunctionInfo * MipsFI
void emitEndOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the end of their file...
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, const char *ExtraCode, raw_ostream &O) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI)
void emitFrameDirective()
Frame Directive.
void emitStartOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the start of their fi...
void printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O)
void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O)
void emitFunctionEntryLabel() override
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
void emitInstruction(const MachineInstr *MI) override
Targets should implement this to emit instructions.
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
std::map< const char *, const Mips16HardFloatInfo::FuncSignature * > StubsNeeded
static const char * getRegisterName(MCRegister Reg)
void Lower(const MachineInstr *MI, MCInst &OutMI) const
MCOperand LowerOperand(const MachineOperand &MO, int64_t offset=0) const
void Initialize(MCContext *C)
bool hasMips32r6() const
bool isFP64bit() const
bool isLittle() const
bool inMicroMipsMode() const
bool useSoftFloat() const
bool hasMips64r6() const
bool isNaN2008() const
bool useOddSPReg() const
bool inMips16Mode() const
bool hasSym32() const
bool isABI_FPXX() const
bool isABICalls() const
bool isGP64bit() const
bool isTargetNaCl() const
const MipsABIInfo & getABI() const
virtual void emitDirectiveSetReorder()
virtual void emitDirectiveSetNoMicroMips()
virtual void emitDirectiveEnd(StringRef Name)
virtual void emitDirectiveSetMacro()
virtual void emitDirectiveEnt(const MCSymbol &Symbol)
virtual void emitDirectiveSetNoMips16()
virtual void setPic(bool Value)
virtual void emitFrame(unsigned StackReg, unsigned StackSize, unsigned ReturnReg)
void updateABIInfo(const PredicateLibrary &P)
virtual void emitDirectiveNaNLegacy()
virtual void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff)
virtual void emitDirectiveSetMicroMips()
virtual void emitDirectiveSetNoMacro()
virtual void emitDirectiveModuleOddSPReg()
virtual void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff)
virtual void emitDirectiveSetNoReorder()
virtual void emitDirectiveOptionPic0()
virtual void emitDirectiveSetMips16()
virtual void emitDirectiveAbiCalls()
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
FunctionListType::iterator iterator
The Function iterators.
Definition: Module.h:90
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
Represents a location in source code.
Definition: SMLoc.h:23
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::string lower() const
Definition: StringRef.cpp:111
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:77
const Triple & getTargetTriple() const
StringRef getTargetFeatureString() const
StringRef getTargetCPU() const
const Target & getTarget() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual Register getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Target - Wrapper for Target specific information.
MCSubtargetInfo * createMCSubtargetInfo(StringRef TheTriple, StringRef CPU, StringRef Features) const
createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
const std::string & str() const
Definition: Triple.h:440
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
static Twine utohexstr(const uint64_t &Val)
Definition: Twine.h:416
LLVM Value Representation.
Definition: Value.h:74
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:691
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ SHT_PROGBITS
Definition: ELF.h:1067
@ SHF_ALLOC
Definition: ELF.h:1161
@ SHF_EXECINSTR
Definition: ELF.h:1164
StringRef selectMipsCPU(const Triple &TT, StringRef CPU)
Select the Mips CPU for the given triple and cpu name.
@ MO_GOT_CALL
MO_GOT_CALL - Represents the offset into the global offset table at which the address of a call site ...
Definition: MipsBaseInfo.h:44
@ MO_TPREL_HI
MO_TPREL_HI/LO - Represents the hi and low part of the offset from.
Definition: MipsBaseInfo.h:73
@ MO_GOT
MO_GOT - Represents the offset into the global offset table at which the address the relocation entry...
Definition: MipsBaseInfo.h:38
@ MO_JALR
Helper operand used to generate R_MIPS_JALR.
Definition: MipsBaseInfo.h:95
@ MO_GOTTPREL
MO_GOTTPREL - Represents the offset from the thread pointer (Initial.
Definition: MipsBaseInfo.h:69
@ MO_ABS_HI
MO_ABS_HI/LO - Represents the hi or low part of an absolute symbol address.
Definition: MipsBaseInfo.h:52
@ MO_TLSGD
MO_TLSGD - Represents the offset into the global offset table at which.
Definition: MipsBaseInfo.h:58
@ MO_GPREL
MO_GPREL - Represents the offset from the current gp value to be used for the relocatable object file...
Definition: MipsBaseInfo.h:48
@ MO_HIGHER
MO_HIGHER/HIGHEST - Represents the highest or higher half word of a 64-bit symbol address.
Definition: MipsBaseInfo.h:85
const char * MipsFCCToString(Mips::CondCode CC)
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:329
@ Offset
Definition: DWP.cpp: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:280
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:330
@ MCDR_DataRegionEnd
.end_data_region
Definition: MCDirectives.h:66
@ MCDR_DataRegion
.data_region
Definition: MCDirectives.h:62
static MCRegister getMSARegFromFReg(MCRegister Reg)
Definition: MipsBaseInfo.h:139
Target & getTheMips64elTarget()
static const Align MIPS_NACL_BUNDLE_ALIGN
Definition: MipsMCNaCl.h:18
Target & getTheMipselTarget()
Target & getTheMipsTarget()
@ MCSA_Global
.type _foo, @gnu_unique_object
Definition: MCDirectives.h:30
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
Definition: MCDirectives.h:23
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...