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