LLVM  9.0.0svn
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"
26 #include "llvm/ADT/SmallString.h"
27 #include "llvm/ADT/StringRef.h"
28 #include "llvm/ADT/Triple.h"
29 #include "llvm/ADT/Twine.h"
30 #include "llvm/BinaryFormat/ELF.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"
45 #include "llvm/IR/Instructions.h"
46 #include "llvm/MC/MCContext.h"
47 #include "llvm/MC/MCExpr.h"
48 #include "llvm/MC/MCInst.h"
49 #include "llvm/MC/MCInstBuilder.h"
51 #include "llvm/MC/MCSectionELF.h"
52 #include "llvm/MC/MCSymbol.h"
53 #include "llvm/MC/MCSymbolELF.h"
54 #include "llvm/Support/Casting.h"
59 #include <cassert>
60 #include <cstdint>
61 #include <map>
62 #include <memory>
63 #include <string>
64 #include <vector>
65 
66 using namespace llvm;
67 
68 #define DEBUG_TYPE "mips-asm-printer"
69 
71 
72 MipsTargetStreamer &MipsAsmPrinter::getTargetStreamer() const {
73  return static_cast<MipsTargetStreamer &>(*OutStreamer->getTargetStreamer());
74 }
75 
78 
80  if (Subtarget->inMips16Mode())
81  for (std::map<
82  const char *,
83  const Mips16HardFloatInfo::FuncSignature *>::const_iterator
84  it = MipsFI->StubsNeeded.begin();
85  it != MipsFI->StubsNeeded.end(); ++it) {
86  const char *Symbol = it->first;
87  const Mips16HardFloatInfo::FuncSignature *Signature = it->second;
88  if (StubsNeeded.find(Symbol) == StubsNeeded.end())
89  StubsNeeded[Symbol] = Signature;
90  }
91  MCP = MF.getConstantPool();
92 
93  // In NaCl, all indirect jump targets must be aligned to bundle size.
94  if (Subtarget->isTargetNaCl())
95  NaClAlignIndirectJumpTargets(MF);
96 
98 
99  emitXRayTable();
100 
101  return true;
102 }
103 
104 bool MipsAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) {
105  MCOp = MCInstLowering.LowerOperand(MO);
106  return MCOp.isValid();
107 }
108 
109 #include "MipsGenMCPseudoLowering.inc"
110 
111 // Lower PseudoReturn/PseudoIndirectBranch/PseudoIndirectBranch64 to JR, JR_MM,
112 // JALR, or JALR64 as appropriate for the target.
113 void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer,
114  const MachineInstr *MI) {
115  bool HasLinkReg = false;
116  bool InMicroMipsMode = Subtarget->inMicroMipsMode();
117  MCInst TmpInst0;
118 
119  if (Subtarget->hasMips64r6()) {
120  // MIPS64r6 should use (JALR64 ZERO_64, $rs)
121  TmpInst0.setOpcode(Mips::JALR64);
122  HasLinkReg = true;
123  } else if (Subtarget->hasMips32r6()) {
124  // MIPS32r6 should use (JALR ZERO, $rs)
125  if (InMicroMipsMode)
126  TmpInst0.setOpcode(Mips::JRC16_MMR6);
127  else {
128  TmpInst0.setOpcode(Mips::JALR);
129  HasLinkReg = true;
130  }
131  } else if (Subtarget->inMicroMipsMode())
132  // microMIPS should use (JR_MM $rs)
133  TmpInst0.setOpcode(Mips::JR_MM);
134  else {
135  // Everything else should use (JR $rs)
136  TmpInst0.setOpcode(Mips::JR);
137  }
138 
139  MCOperand MCOp;
140 
141  if (HasLinkReg) {
142  unsigned ZeroReg = Subtarget->isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
143  TmpInst0.addOperand(MCOperand::createReg(ZeroReg));
144  }
145 
146  lowerOperand(MI->getOperand(0), MCOp);
147  TmpInst0.addOperand(MCOp);
148 
149  EmitToStreamer(OutStreamer, TmpInst0);
150 }
151 
152 // If there is an MO_JALR operand, insert:
153 //
154 // .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
155 // tmplabel:
156 //
157 // This is an optimization hint for the linker which may then replace
158 // an indirect call with a direct branch.
159 static void emitDirectiveRelocJalr(const MachineInstr &MI,
161  TargetMachine &TM,
162  MCStreamer &OutStreamer,
163  const MipsSubtarget &Subtarget) {
164  for (unsigned int I = MI.getDesc().getNumOperands(), E = MI.getNumOperands();
165  I < E; ++I) {
166  MachineOperand MO = MI.getOperand(I);
167  if (MO.isMCSymbol() && (MO.getTargetFlags() & MipsII::MO_JALR)) {
168  MCSymbol *Callee = MO.getMCSymbol();
169  if (Callee && !Callee->getName().empty()) {
170  MCSymbol *OffsetLabel = OutContext.createTempSymbol();
171  const MCExpr *OffsetExpr =
172  MCSymbolRefExpr::create(OffsetLabel, OutContext);
173  const MCExpr *CaleeExpr =
174  MCSymbolRefExpr::create(Callee, OutContext);
175  OutStreamer.EmitRelocDirective
176  (*OffsetExpr,
177  Subtarget.inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
178  CaleeExpr, SMLoc(), *TM.getMCSubtargetInfo());
179  OutStreamer.EmitLabel(OffsetLabel);
180  return;
181  }
182  }
183  }
184 }
185 
187  MipsTargetStreamer &TS = getTargetStreamer();
188  unsigned Opc = MI->getOpcode();
190 
191  if (MI->isDebugValue()) {
192  SmallString<128> Str;
193  raw_svector_ostream OS(Str);
194 
195  PrintDebugValueComment(MI, OS);
196  return;
197  }
198  if (MI->isDebugLabel())
199  return;
200 
201  // If we just ended a constant pool, mark it as such.
202  if (InConstantPool && Opc != Mips::CONSTPOOL_ENTRY) {
203  OutStreamer->EmitDataRegion(MCDR_DataRegionEnd);
204  InConstantPool = false;
205  }
206  if (Opc == Mips::CONSTPOOL_ENTRY) {
207  // CONSTPOOL_ENTRY - This instruction represents a floating
208  // constant pool in the function. The first operand is the ID#
209  // for this instruction, the second is the index into the
210  // MachineConstantPool that this is, the third is the size in
211  // bytes of this constant pool entry.
212  // The required alignment is specified on the basic block holding this MI.
213  //
214  unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
215  unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex();
216 
217  // If this is the first entry of the pool, mark it.
218  if (!InConstantPool) {
219  OutStreamer->EmitDataRegion(MCDR_DataRegion);
220  InConstantPool = true;
221  }
222 
223  OutStreamer->EmitLabel(GetCPISymbol(LabelId));
224 
225  const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
226  if (MCPE.isMachineConstantPoolEntry())
228  else
230  return;
231  }
232 
233  switch (Opc) {
234  case Mips::PATCHABLE_FUNCTION_ENTER:
236  return;
237  case Mips::PATCHABLE_FUNCTION_EXIT:
239  return;
240  case Mips::PATCHABLE_TAIL_CALL:
242  return;
243  }
244 
245  if (EmitJalrReloc &&
246  (MI->isReturn() || MI->isCall() || MI->isIndirectBranch())) {
247  emitDirectiveRelocJalr(*MI, OutContext, TM, *OutStreamer, *Subtarget);
248  }
249 
252 
253  do {
254  // Do any auto-generated pseudo lowerings.
255  if (emitPseudoExpansionLowering(*OutStreamer, &*I))
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  unsigned 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  unsigned stackReg = RI.getFrameRegister(*MF);
379  unsigned 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  // NaCl sandboxing requires that indirect call instructions are masked.
399  // This means that function entry points should be bundle-aligned.
400  if (Subtarget->isTargetNaCl())
402 
403  if (Subtarget->inMicroMipsMode()) {
405  TS.setUsesMicroMips();
407  } else
409 
410  if (Subtarget->inMips16Mode())
412  else
414 
416  OutStreamer->EmitLabel(CurrentFnSym);
417 }
418 
419 /// EmitFunctionBodyStart - Targets can override this to emit stuff before
420 /// the first basic block in the function.
422  MipsTargetStreamer &TS = getTargetStreamer();
423 
425 
426  bool IsNakedFunction = MF->getFunction().hasFnAttribute(Attribute::Naked);
427  if (!IsNakedFunction)
429 
430  if (!IsNakedFunction)
432 
433  if (!Subtarget->inMips16Mode()) {
437  }
438 }
439 
440 /// EmitFunctionBodyEnd - Targets can override this to emit stuff after
441 /// the last basic block in the function.
443  MipsTargetStreamer &TS = getTargetStreamer();
444 
445  // There are instruction for this macros, but they must
446  // always be at the function end, and we can't emit and
447  // break with BB logic.
448  if (!Subtarget->inMips16Mode()) {
449  TS.emitDirectiveSetAt();
452  }
454  // Make sure to terminate any constant pools that were at the end
455  // of the function.
456  if (!InConstantPool)
457  return;
458  InConstantPool = false;
459  OutStreamer->EmitDataRegion(MCDR_DataRegionEnd);
460 }
461 
464  MipsTargetStreamer &TS = getTargetStreamer();
465  if (MBB.empty())
466  TS.emitDirectiveInsn();
467 }
468 
469 /// isBlockOnlyReachableByFallthough - Return true if the basic block has
470 /// exactly one predecessor and the control transfer mechanism between
471 /// the predecessor and this block is a fall-through.
473  MBB) const {
474  // The predecessor has to be immediately before this block.
475  const MachineBasicBlock *Pred = *MBB->pred_begin();
476 
477  // If the predecessor is a switch statement, assume a jump table
478  // implementation, so it is not a fall through.
479  if (const BasicBlock *bb = Pred->getBasicBlock())
480  if (isa<SwitchInst>(bb->getTerminator()))
481  return false;
482 
483  // If this is a landing pad, it isn't a fall through. If it has no preds,
484  // then nothing falls through to it.
485  if (MBB->isEHPad() || MBB->pred_empty())
486  return false;
487 
488  // If there isn't exactly one predecessor, it can't be a fall through.
490  ++PI2;
491 
492  if (PI2 != MBB->pred_end())
493  return false;
494 
495  // The predecessor has to be immediately before this block.
496  if (!Pred->isLayoutSuccessor(MBB))
497  return false;
498 
499  // If the block is completely empty, then it definitely does fall through.
500  if (Pred->empty())
501  return true;
502 
503  // Otherwise, check the last instruction.
504  // Check if the last terminator is an unconditional branch.
506  while (I != Pred->begin() && !(--I)->isTerminator()) ;
507 
508  return !I->isBarrier();
509 }
510 
511 // Print out an operand for an inline asm expression.
512 bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
513  unsigned AsmVariant, const char *ExtraCode,
514  raw_ostream &O) {
515  // Does this asm operand have a single letter operand modifier?
516  if (ExtraCode && ExtraCode[0]) {
517  if (ExtraCode[1] != 0) return true; // Unknown modifier.
518 
519  const MachineOperand &MO = MI->getOperand(OpNum);
520  switch (ExtraCode[0]) {
521  default:
522  // See if this is a generic print operand
523  return AsmPrinter::PrintAsmOperand(MI,OpNum,AsmVariant,ExtraCode,O);
524  case 'X': // hex const int
526  return true;
527  O << "0x" << Twine::utohexstr(MO.getImm());
528  return false;
529  case 'x': // hex const int (low 16 bits)
531  return true;
532  O << "0x" << Twine::utohexstr(MO.getImm() & 0xffff);
533  return false;
534  case 'd': // decimal const int
536  return true;
537  O << MO.getImm();
538  return false;
539  case 'm': // decimal const int minus 1
541  return true;
542  O << MO.getImm() - 1;
543  return false;
544  case 'y': // exact log2
546  return true;
547  if (!isPowerOf2_64(MO.getImm()))
548  return true;
549  O << Log2_64(MO.getImm());
550  return false;
551  case 'z':
552  // $0 if zero, regular printing otherwise
553  if (MO.getType() == MachineOperand::MO_Immediate && MO.getImm() == 0) {
554  O << "$0";
555  return false;
556  }
557  // If not, call printOperand as normal.
558  break;
559  case 'D': // Second part of a double word register operand
560  case 'L': // Low order register of a double word register operand
561  case 'M': // High order register of a double word register operand
562  {
563  if (OpNum == 0)
564  return true;
565  const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1);
566  if (!FlagsOP.isImm())
567  return true;
568  unsigned Flags = FlagsOP.getImm();
569  unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags);
570  // Number of registers represented by this operand. We are looking
571  // for 2 for 32 bit mode and 1 for 64 bit mode.
572  if (NumVals != 2) {
573  if (Subtarget->isGP64bit() && NumVals == 1 && MO.isReg()) {
574  unsigned Reg = MO.getReg();
575  O << '$' << MipsInstPrinter::getRegisterName(Reg);
576  return false;
577  }
578  return true;
579  }
580 
581  unsigned RegOp = OpNum;
582  if (!Subtarget->isGP64bit()){
583  // Endianness reverses which register holds the high or low value
584  // between M and L.
585  switch(ExtraCode[0]) {
586  case 'M':
587  RegOp = (Subtarget->isLittle()) ? OpNum + 1 : OpNum;
588  break;
589  case 'L':
590  RegOp = (Subtarget->isLittle()) ? OpNum : OpNum + 1;
591  break;
592  case 'D': // Always the second part
593  RegOp = OpNum + 1;
594  }
595  if (RegOp >= MI->getNumOperands())
596  return true;
597  const MachineOperand &MO = MI->getOperand(RegOp);
598  if (!MO.isReg())
599  return true;
600  unsigned Reg = MO.getReg();
601  O << '$' << MipsInstPrinter::getRegisterName(Reg);
602  return false;
603  }
604  break;
605  }
606  case 'w':
607  // Print MSA registers for the 'f' constraint
608  // In LLVM, the 'w' modifier doesn't need to do anything.
609  // We can just call printOperand as normal.
610  break;
611  }
612  }
613 
614  printOperand(MI, OpNum, O);
615  return false;
616 }
617 
619  unsigned OpNum, unsigned AsmVariant,
620  const char *ExtraCode,
621  raw_ostream &O) {
622  assert(OpNum + 1 < MI->getNumOperands() && "Insufficient operands");
623  const MachineOperand &BaseMO = MI->getOperand(OpNum);
624  const MachineOperand &OffsetMO = MI->getOperand(OpNum + 1);
625  assert(BaseMO.isReg() && "Unexpected base pointer for inline asm memory operand.");
626  assert(OffsetMO.isImm() && "Unexpected offset for inline asm memory operand.");
627  int Offset = OffsetMO.getImm();
628 
629  // Currently we are expecting either no ExtraCode or 'D','M','L'.
630  if (ExtraCode) {
631  switch (ExtraCode[0]) {
632  case 'D':
633  Offset += 4;
634  break;
635  case 'M':
636  if (Subtarget->isLittle())
637  Offset += 4;
638  break;
639  case 'L':
640  if (!Subtarget->isLittle())
641  Offset += 4;
642  break;
643  default:
644  return true; // Unknown modifier.
645  }
646  }
647 
648  O << Offset << "($" << MipsInstPrinter::getRegisterName(BaseMO.getReg())
649  << ")";
650 
651  return false;
652 }
653 
654 void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
655  raw_ostream &O) {
656  const MachineOperand &MO = MI->getOperand(opNum);
657  bool closeP = false;
658 
659  if (MO.getTargetFlags())
660  closeP = true;
661 
662  switch(MO.getTargetFlags()) {
663  case MipsII::MO_GPREL: O << "%gp_rel("; break;
664  case MipsII::MO_GOT_CALL: O << "%call16("; break;
665  case MipsII::MO_GOT: O << "%got("; break;
666  case MipsII::MO_ABS_HI: O << "%hi("; break;
667  case MipsII::MO_ABS_LO: O << "%lo("; break;
668  case MipsII::MO_HIGHER: O << "%higher("; break;
669  case MipsII::MO_HIGHEST: O << "%highest(("; break;
670  case MipsII::MO_TLSGD: O << "%tlsgd("; break;
671  case MipsII::MO_GOTTPREL: O << "%gottprel("; break;
672  case MipsII::MO_TPREL_HI: O << "%tprel_hi("; break;
673  case MipsII::MO_TPREL_LO: O << "%tprel_lo("; break;
674  case MipsII::MO_GPOFF_HI: O << "%hi(%neg(%gp_rel("; break;
675  case MipsII::MO_GPOFF_LO: O << "%lo(%neg(%gp_rel("; break;
676  case MipsII::MO_GOT_DISP: O << "%got_disp("; break;
677  case MipsII::MO_GOT_PAGE: O << "%got_page("; break;
678  case MipsII::MO_GOT_OFST: O << "%got_ofst("; break;
679  }
680 
681  switch (MO.getType()) {
683  O << '$'
685  break;
686 
688  O << MO.getImm();
689  break;
690 
692  MO.getMBB()->getSymbol()->print(O, MAI);
693  return;
694 
696  getSymbol(MO.getGlobal())->print(O, MAI);
697  break;
698 
701  O << BA->getName();
702  break;
703  }
704 
706  O << getDataLayout().getPrivateGlobalPrefix() << "CPI"
707  << getFunctionNumber() << "_" << MO.getIndex();
708  if (MO.getOffset())
709  O << "+" << MO.getOffset();
710  break;
711 
712  default:
713  llvm_unreachable("<unknown operand type>");
714  }
715 
716  if (closeP) O << ")";
717 }
718 
719 void MipsAsmPrinter::
720 printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O) {
721  // Load/Store memory operands -- imm($reg)
722  // If PIC target the target is loaded as the
723  // pattern lw $25,%call16($28)
724 
725  // opNum can be invalid if instruction has reglist as operand.
726  // MemOperand is always last operand of instruction (base + offset).
727  switch (MI->getOpcode()) {
728  default:
729  break;
730  case Mips::SWM32_MM:
731  case Mips::LWM32_MM:
732  opNum = MI->getNumOperands() - 2;
733  break;
734  }
735 
736  printOperand(MI, opNum+1, O);
737  O << "(";
738  printOperand(MI, opNum, O);
739  O << ")";
740 }
741 
742 void MipsAsmPrinter::
743 printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O) {
744  // when using stack locations for not load/store instructions
745  // print the same way as all normal 3 operand instructions.
746  printOperand(MI, opNum, O);
747  O << ", ";
748  printOperand(MI, opNum+1, O);
749 }
750 
751 void MipsAsmPrinter::
752 printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
753  const char *Modifier) {
754  const MachineOperand &MO = MI->getOperand(opNum);
756 }
757 
758 void MipsAsmPrinter::
759 printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O) {
760  for (int i = opNum, e = MI->getNumOperands(); i != e; ++i) {
761  if (i != opNum) O << ", ";
762  printOperand(MI, i, O);
763  }
764 }
765 
767  MipsTargetStreamer &TS = getTargetStreamer();
768 
769  // MipsTargetStreamer has an initialization order problem when emitting an
770  // object file directly (see MipsTargetELFStreamer for full details). Work
771  // around it by re-initializing the PIC state here.
773 
774  // Compute MIPS architecture attributes based on the default subtarget
775  // that we'd have constructed. Module level directives aren't LTO
776  // clean anyhow.
777  // FIXME: For ifunc related functions we could iterate over and look
778  // for a feature string that doesn't match the default one.
779  const Triple &TT = TM.getTargetTriple();
782  const MipsTargetMachine &MTM = static_cast<const MipsTargetMachine &>(TM);
783  const MipsSubtarget STI(TT, CPU, FS, MTM.isLittleEndian(), MTM, 0);
784 
785  bool IsABICalls = STI.isABICalls();
786  const MipsABIInfo &ABI = MTM.getABI();
787  if (IsABICalls) {
789  // FIXME: This condition should be a lot more complicated that it is here.
790  // Ideally it should test for properties of the ABI and not the ABI
791  // itself.
792  // For the moment, I'm only correcting enough to make MIPS-IV work.
793  if (!isPositionIndependent() && STI.hasSym32())
795  }
796 
797  // Tell the assembler which ABI we are using
798  std::string SectionName = std::string(".mdebug.") + getCurrentABIString();
799  OutStreamer->SwitchSection(
800  OutContext.getELFSection(SectionName, ELF::SHT_PROGBITS, 0));
801 
802  // NaN: At the moment we only support:
803  // 1. .nan legacy (default)
804  // 2. .nan 2008
805  STI.isNaN2008() ? TS.emitDirectiveNaN2008()
806  : TS.emitDirectiveNaNLegacy();
807 
808  // TODO: handle O64 ABI
809 
810  TS.updateABIInfo(STI);
811 
812  // We should always emit a '.module fp=...' but binutils 2.24 does not accept
813  // it. We therefore emit it when it contradicts the ABI defaults (-mfpxx or
814  // -mfp64) and omit it otherwise.
815  if (ABI.IsO32() && (STI.isABI_FPXX() || STI.isFP64bit()))
817 
818  // We should always emit a '.module [no]oddspreg' but binutils 2.24 does not
819  // accept it. We therefore emit it when it contradicts the default or an
820  // option has changed the default (i.e. FPXX) and omit it otherwise.
821  if (ABI.IsO32() && (!STI.useOddSPReg() || STI.isABI_FPXX()))
823 }
824 
825 void MipsAsmPrinter::emitInlineAsmStart() const {
826  MipsTargetStreamer &TS = getTargetStreamer();
827 
828  // GCC's choice of assembler options for inline assembly code ('at', 'macro'
829  // and 'reorder') is different from LLVM's choice for generated code ('noat',
830  // 'nomacro' and 'noreorder').
831  // In order to maintain compatibility with inline assembly code which depends
832  // on GCC's assembler options being used, we have to switch to those options
833  // for the duration of the inline assembly block and then switch back.
835  TS.emitDirectiveSetAt();
838  OutStreamer->AddBlankLine();
839 }
840 
841 void MipsAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
842  const MCSubtargetInfo *EndInfo) const {
843  OutStreamer->AddBlankLine();
844  getTargetStreamer().emitDirectiveSetPop();
845 }
846 
847 void MipsAsmPrinter::EmitJal(const MCSubtargetInfo &STI, MCSymbol *Symbol) {
848  MCInst I;
849  I.setOpcode(Mips::JAL);
850  I.addOperand(
852  OutStreamer->EmitInstruction(I, STI);
853 }
854 
855 void MipsAsmPrinter::EmitInstrReg(const MCSubtargetInfo &STI, unsigned Opcode,
856  unsigned Reg) {
857  MCInst I;
858  I.setOpcode(Opcode);
860  OutStreamer->EmitInstruction(I, STI);
861 }
862 
863 void MipsAsmPrinter::EmitInstrRegReg(const MCSubtargetInfo &STI,
864  unsigned Opcode, unsigned Reg1,
865  unsigned Reg2) {
866  MCInst I;
867  //
868  // Because of the current td files for Mips32, the operands for MTC1
869  // appear backwards from their normal assembly order. It's not a trivial
870  // change to fix this in the td file so we adjust for it here.
871  //
872  if (Opcode == Mips::MTC1) {
873  unsigned Temp = Reg1;
874  Reg1 = Reg2;
875  Reg2 = Temp;
876  }
877  I.setOpcode(Opcode);
880  OutStreamer->EmitInstruction(I, STI);
881 }
882 
883 void MipsAsmPrinter::EmitInstrRegRegReg(const MCSubtargetInfo &STI,
884  unsigned Opcode, unsigned Reg1,
885  unsigned Reg2, unsigned Reg3) {
886  MCInst I;
887  I.setOpcode(Opcode);
891  OutStreamer->EmitInstruction(I, STI);
892 }
893 
894 void MipsAsmPrinter::EmitMovFPIntPair(const MCSubtargetInfo &STI,
895  unsigned MovOpc, unsigned Reg1,
896  unsigned Reg2, unsigned FPReg1,
897  unsigned FPReg2, bool LE) {
898  if (!LE) {
899  unsigned temp = Reg1;
900  Reg1 = Reg2;
901  Reg2 = temp;
902  }
903  EmitInstrRegReg(STI, MovOpc, Reg1, FPReg1);
904  EmitInstrRegReg(STI, MovOpc, Reg2, FPReg2);
905 }
906 
907 void MipsAsmPrinter::EmitSwapFPIntParams(const MCSubtargetInfo &STI,
909  bool LE, bool ToFP) {
910  using namespace Mips16HardFloatInfo;
911 
912  unsigned MovOpc = ToFP ? Mips::MTC1 : Mips::MFC1;
913  switch (PV) {
914  case FSig:
915  EmitInstrRegReg(STI, MovOpc, Mips::A0, Mips::F12);
916  break;
917  case FFSig:
918  EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F14, LE);
919  break;
920  case FDSig:
921  EmitInstrRegReg(STI, MovOpc, Mips::A0, Mips::F12);
922  EmitMovFPIntPair(STI, MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE);
923  break;
924  case DSig:
925  EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
926  break;
927  case DDSig:
928  EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
929  EmitMovFPIntPair(STI, MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE);
930  break;
931  case DFSig:
932  EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
933  EmitInstrRegReg(STI, MovOpc, Mips::A2, Mips::F14);
934  break;
935  case NoSig:
936  return;
937  }
938 }
939 
940 void MipsAsmPrinter::EmitSwapFPIntRetval(
942  bool LE) {
943  using namespace Mips16HardFloatInfo;
944 
945  unsigned MovOpc = Mips::MFC1;
946  switch (RV) {
947  case FRet:
948  EmitInstrRegReg(STI, MovOpc, Mips::V0, Mips::F0);
949  break;
950  case DRet:
951  EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
952  break;
953  case CFRet:
954  EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
955  break;
956  case CDRet:
957  EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
958  EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F2, Mips::F3, LE);
959  break;
960  case NoFPRet:
961  break;
962  }
963 }
964 
965 void MipsAsmPrinter::EmitFPCallStub(
966  const char *Symbol, const Mips16HardFloatInfo::FuncSignature *Signature) {
967  using namespace Mips16HardFloatInfo;
968 
969  MCSymbol *MSymbol = OutContext.getOrCreateSymbol(StringRef(Symbol));
970  bool LE = getDataLayout().isLittleEndian();
971  // Construct a local MCSubtargetInfo here.
972  // This is because the MachineFunction won't exist (but have not yet been
973  // freed) and since we're at the global level we can use the default
974  // constructed subtarget.
975  std::unique_ptr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo(
978 
979  //
980  // .global xxxx
981  //
982  OutStreamer->EmitSymbolAttribute(MSymbol, MCSA_Global);
983  const char *RetType;
984  //
985  // make the comment field identifying the return and parameter
986  // types of the floating point stub
987  // # Stub function to call rettype xxxx (params)
988  //
989  switch (Signature->RetSig) {
990  case FRet:
991  RetType = "float";
992  break;
993  case DRet:
994  RetType = "double";
995  break;
996  case CFRet:
997  RetType = "complex";
998  break;
999  case CDRet:
1000  RetType = "double complex";
1001  break;
1002  case NoFPRet:
1003  RetType = "";
1004  break;
1005  }
1006  const char *Parms;
1007  switch (Signature->ParamSig) {
1008  case FSig:
1009  Parms = "float";
1010  break;
1011  case FFSig:
1012  Parms = "float, float";
1013  break;
1014  case FDSig:
1015  Parms = "float, double";
1016  break;
1017  case DSig:
1018  Parms = "double";
1019  break;
1020  case DDSig:
1021  Parms = "double, double";
1022  break;
1023  case DFSig:
1024  Parms = "double, float";
1025  break;
1026  case NoSig:
1027  Parms = "";
1028  break;
1029  }
1030  OutStreamer->AddComment("\t# Stub function to call " + Twine(RetType) + " " +
1031  Twine(Symbol) + " (" + Twine(Parms) + ")");
1032  //
1033  // probably not necessary but we save and restore the current section state
1034  //
1035  OutStreamer->PushSection();
1036  //
1037  // .section mips16.call.fpxxxx,"ax",@progbits
1038  //
1040  ".mips16.call.fp." + std::string(Symbol), ELF::SHT_PROGBITS,
1042  OutStreamer->SwitchSection(M, nullptr);
1043  //
1044  // .align 2
1045  //
1046  OutStreamer->EmitValueToAlignment(4);
1047  MipsTargetStreamer &TS = getTargetStreamer();
1048  //
1049  // .set nomips16
1050  // .set nomicromips
1051  //
1054  //
1055  // .ent __call_stub_fp_xxxx
1056  // .type __call_stub_fp_xxxx,@function
1057  // __call_stub_fp_xxxx:
1058  //
1059  std::string x = "__call_stub_fp_" + std::string(Symbol);
1060  MCSymbolELF *Stub =
1061  cast<MCSymbolELF>(OutContext.getOrCreateSymbol(StringRef(x)));
1062  TS.emitDirectiveEnt(*Stub);
1063  MCSymbol *MType =
1064  OutContext.getOrCreateSymbol("__call_stub_fp_" + Twine(Symbol));
1065  OutStreamer->EmitSymbolAttribute(MType, MCSA_ELF_TypeFunction);
1066  OutStreamer->EmitLabel(Stub);
1067 
1068  // Only handle non-pic for now.
1070  "should not be here if we are compiling pic");
1072  //
1073  // We need to add a MipsMCExpr class to MCTargetDesc to fully implement
1074  // stubs without raw text but this current patch is for compiler generated
1075  // functions and they all return some value.
1076  // The calling sequence for non pic is different in that case and we need
1077  // to implement %lo and %hi in order to handle the case of no return value
1078  // See the corresponding method in Mips16HardFloat for details.
1079  //
1080  // mov the return address to S2.
1081  // we have no stack space to store it and we are about to make another call.
1082  // We need to make sure that the enclosing function knows to save S2
1083  // This should have already been handled.
1084  //
1085  // Mov $18, $31
1086 
1087  EmitInstrRegRegReg(*STI, Mips::OR, Mips::S2, Mips::RA, Mips::ZERO);
1088 
1089  EmitSwapFPIntParams(*STI, Signature->ParamSig, LE, true);
1090 
1091  // Jal xxxx
1092  //
1093  EmitJal(*STI, MSymbol);
1094 
1095  // fix return values
1096  EmitSwapFPIntRetval(*STI, Signature->RetSig, LE);
1097  //
1098  // do the return
1099  // if (Signature->RetSig == NoFPRet)
1100  // llvm_unreachable("should not be any stubs here with no return value");
1101  // else
1102  EmitInstrReg(*STI, Mips::JR, Mips::S2);
1103 
1105  OutStreamer->EmitLabel(Tmp);
1108  const MCExpr *T_min_E = MCBinaryExpr::createSub(T, E, OutContext);
1109  OutStreamer->emitELFSize(Stub, T_min_E);
1110  TS.emitDirectiveEnd(x);
1111  OutStreamer->PopSection();
1112 }
1113 
1115  // Emit needed stubs
1116  //
1117  for (std::map<
1118  const char *,
1119  const Mips16HardFloatInfo::FuncSignature *>::const_iterator
1120  it = StubsNeeded.begin();
1121  it != StubsNeeded.end(); ++it) {
1122  const char *Symbol = it->first;
1123  const Mips16HardFloatInfo::FuncSignature *Signature = it->second;
1124  EmitFPCallStub(Symbol, Signature);
1125  }
1126  // return to the text section
1128 }
1129 
1130 void MipsAsmPrinter::EmitSled(const MachineInstr &MI, SledKind Kind) {
1131  const uint8_t NoopsInSledCount = Subtarget->isGP64bit() ? 15 : 11;
1132  // For mips32 we want to emit the following pattern:
1133  //
1134  // .Lxray_sled_N:
1135  // ALIGN
1136  // B .tmpN
1137  // 11 NOP instructions (44 bytes)
1138  // ADDIU T9, T9, 52
1139  // .tmpN
1140  //
1141  // We need the 44 bytes (11 instructions) because at runtime, we'd
1142  // be patching over the full 48 bytes (12 instructions) with the following
1143  // pattern:
1144  //
1145  // ADDIU SP, SP, -8
1146  // NOP
1147  // SW RA, 4(SP)
1148  // SW T9, 0(SP)
1149  // LUI T9, %hi(__xray_FunctionEntry/Exit)
1150  // ORI T9, T9, %lo(__xray_FunctionEntry/Exit)
1151  // LUI T0, %hi(function_id)
1152  // JALR T9
1153  // ORI T0, T0, %lo(function_id)
1154  // LW T9, 0(SP)
1155  // LW RA, 4(SP)
1156  // ADDIU SP, SP, 8
1157  //
1158  // We add 52 bytes to t9 because we want to adjust the function pointer to
1159  // the actual start of function i.e. the address just after the noop sled.
1160  // We do this because gp displacement relocation is emitted at the start of
1161  // of the function i.e after the nop sled and to correctly calculate the
1162  // global offset table address, t9 must hold the address of the instruction
1163  // containing the gp displacement relocation.
1164  // FIXME: Is this correct for the static relocation model?
1165  //
1166  // For mips64 we want to emit the following pattern:
1167  //
1168  // .Lxray_sled_N:
1169  // ALIGN
1170  // B .tmpN
1171  // 15 NOP instructions (60 bytes)
1172  // .tmpN
1173  //
1174  // We need the 60 bytes (15 instructions) because at runtime, we'd
1175  // be patching over the full 64 bytes (16 instructions) with the following
1176  // pattern:
1177  //
1178  // DADDIU SP, SP, -16
1179  // NOP
1180  // SD RA, 8(SP)
1181  // SD T9, 0(SP)
1182  // LUI T9, %highest(__xray_FunctionEntry/Exit)
1183  // ORI T9, T9, %higher(__xray_FunctionEntry/Exit)
1184  // DSLL T9, T9, 16
1185  // ORI T9, T9, %hi(__xray_FunctionEntry/Exit)
1186  // DSLL T9, T9, 16
1187  // ORI T9, T9, %lo(__xray_FunctionEntry/Exit)
1188  // LUI T0, %hi(function_id)
1189  // JALR T9
1190  // ADDIU T0, T0, %lo(function_id)
1191  // LD T9, 0(SP)
1192  // LD RA, 8(SP)
1193  // DADDIU SP, SP, 16
1194  //
1195  OutStreamer->EmitCodeAlignment(4);
1196  auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
1197  OutStreamer->EmitLabel(CurSled);
1199 
1200  // Emit "B .tmpN" instruction, which jumps over the nop sled to the actual
1201  // start of function
1202  const MCExpr *TargetExpr = MCSymbolRefExpr::create(
1203  Target, MCSymbolRefExpr::VariantKind::VK_None, OutContext);
1204  EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::BEQ)
1205  .addReg(Mips::ZERO)
1206  .addReg(Mips::ZERO)
1207  .addExpr(TargetExpr));
1208 
1209  for (int8_t I = 0; I < NoopsInSledCount; I++)
1210  EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::SLL)
1211  .addReg(Mips::ZERO)
1212  .addReg(Mips::ZERO)
1213  .addImm(0));
1214 
1215  OutStreamer->EmitLabel(Target);
1216 
1217  if (!Subtarget->isGP64bit()) {
1218  EmitToStreamer(*OutStreamer,
1219  MCInstBuilder(Mips::ADDiu)
1220  .addReg(Mips::T9)
1221  .addReg(Mips::T9)
1222  .addImm(0x34));
1223  }
1224 
1225  recordSled(CurSled, MI, Kind);
1226 }
1227 
1229  EmitSled(MI, SledKind::FUNCTION_ENTER);
1230 }
1231 
1233  EmitSled(MI, SledKind::FUNCTION_EXIT);
1234 }
1235 
1237  EmitSled(MI, SledKind::TAIL_CALL);
1238 }
1239 
1241  raw_ostream &OS) {
1242  // TODO: implement
1243 }
1244 
1245 // Emit .dtprelword or .dtpreldword directive
1246 // and value for debug thread local expression.
1247 void MipsAsmPrinter::EmitDebugValue(const MCExpr *Value, unsigned Size) const {
1248  if (auto *MipsExpr = dyn_cast<MipsMCExpr>(Value)) {
1249  if (MipsExpr && MipsExpr->getKind() == MipsMCExpr::MEK_DTPREL) {
1250  switch (Size) {
1251  case 4:
1252  OutStreamer->EmitDTPRel32Value(MipsExpr->getSubExpr());
1253  break;
1254  case 8:
1255  OutStreamer->EmitDTPRel64Value(MipsExpr->getSubExpr());
1256  break;
1257  default:
1258  llvm_unreachable("Unexpected size of expression value.");
1259  }
1260  return;
1261  }
1262  }
1263  AsmPrinter::EmitDebugValue(Value, Size);
1264 }
1265 
1266 // Align all targets of indirect branches on bundle size. Used only if target
1267 // is NaCl.
1268 void MipsAsmPrinter::NaClAlignIndirectJumpTargets(MachineFunction &MF) {
1269  // Align all blocks that are jumped to through jump table.
1270  if (MachineJumpTableInfo *JtInfo = MF.getJumpTableInfo()) {
1271  const std::vector<MachineJumpTableEntry> &JT = JtInfo->getJumpTables();
1272  for (unsigned I = 0; I < JT.size(); ++I) {
1273  const std::vector<MachineBasicBlock*> &MBBs = JT[I].MBBs;
1274 
1275  for (unsigned J = 0; J < MBBs.size(); ++J)
1276  MBBs[J]->setAlignment(MIPS_NACL_BUNDLE_ALIGN);
1277  }
1278  }
1279 
1280  // If basic block address is taken, block can be target of indirect branch.
1281  for (auto &MBB : MF) {
1282  if (MBB.hasAddressTaken())
1283  MBB.setAlignment(MIPS_NACL_BUNDLE_ALIGN);
1284  }
1285 }
1286 
1287 bool MipsAsmPrinter::isLongBranchPseudo(int Opcode) const {
1288  return (Opcode == Mips::LONG_BRANCH_LUi
1289  || Opcode == Mips::LONG_BRANCH_LUi2Op
1290  || Opcode == Mips::LONG_BRANCH_LUi2Op_64
1291  || Opcode == Mips::LONG_BRANCH_ADDiu
1292  || Opcode == Mips::LONG_BRANCH_ADDiu2Op
1293  || Opcode == Mips::LONG_BRANCH_DADDiu
1294  || Opcode == Mips::LONG_BRANCH_DADDiu2Op);
1295 }
1296 
1297 // Force static initialization.
1298 extern "C" void LLVMInitializeMipsAsmPrinter() {
1303 }
unsigned getTargetFlags() const
MachineConstantPoolValue * MachineCPVal
virtual void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff)
bool isABICalls() const
StringRef getTargetFeatureString() const
bool isDebugLabel() const
Definition: MachineInstr.h:997
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
bool isCall(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:632
instr_iterator instr_end()
MachineBasicBlock * getMBB() const
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition: AsmPrinter.h:93
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:322
This class represents lattice values for constants.
Definition: AllocatorList.h:23
StringRef getPrivateGlobalPrefix() const
Definition: DataLayout.h:293
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:64
bool inMips16Mode() const
virtual void AddBlankLine()
AddBlankLine - Emit a blank line to a .s file to pretty it up.
Definition: MCStreamer.h:332
MO_HIGHER/HIGHEST - Represents the highest or higher half word of a 64-bit symbol address...
Definition: MipsBaseInfo.h:84
MCContext & OutContext
This is the context for the output file that we are streaming.
Definition: AsmPrinter.h:88
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:136
void EmitFunctionBodyEnd() override
EmitFunctionBodyEnd - Targets can override this to emit stuff after the last basic block in the funct...
MO_TLSGD - Represents the offset into the global offset table at which.
Definition: MipsBaseInfo.h:57
void EmitDebugValue(const MCExpr *Value, unsigned Size) const override
Emit the directive and value for debug thread local expression.
unsigned getReg() const
getReg - Returns the register number.
unsigned Reg
Target & getTheMipselTarget()
virtual void EmitDTPRel64Value(const MCExpr *Value)
Emit the expression Value into the output as a dtprel (64-bit DTP relative) value.
Definition: MCStreamer.cpp:169
virtual void emitDirectiveSetNoReorder()
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.h:320
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:509
bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const override
isBlockOnlyReachableByFallthough - Return true if the basic block has exactly one predecessor and the...
void PushSection()
Save the current and previous section on the section stack.
Definition: MCStreamer.h:367
MachineBasicBlock reference.
unsigned const TargetRegisterInfo * TRI
MachineFunction * MF
The current machine function.
Definition: AsmPrinter.h:96
void Initialize(MCContext *C)
std::vector< MachineBasicBlock * >::const_iterator const_pred_iterator
void EmitFunctionBodyStart() override
EmitFunctionBodyStart - Targets can override this to emit stuff before the first basic block in the f...
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
virtual void EmitDebugValue(const MCExpr *Value, unsigned Size) const
Emit the directive and value for debug thread local expression.
Definition: AsmPrinter.cpp:633
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Definition: MCStreamer.cpp:955
void EmitFunctionEntryLabel() override
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
union llvm::MachineConstantPoolEntry::@163 Val
The constant itself.
return AArch64::GPR64RegClass contains(Reg)
SI optimize exec mask operations pre RA
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
virtual void emitDirectiveSetMicroMips()
void recordSled(MCSymbol *Sled, const MachineInstr &MI, SledKind Kind, uint8_t Version=0)
bool isMachineConstantPoolEntry() const
isMachineConstantPoolEntry - Return true if the MachineConstantPoolEntry is indeed a target specific ...
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:115
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
Definition: MCInstrDesc.h:210
virtual void emitFrame(unsigned StackReg, unsigned StackSize, unsigned ReturnReg)
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:411
static void emitDirectiveRelocJalr(const MachineInstr &MI, MCContext &OutContext, TargetMachine &TM, MCStreamer &OutStreamer, const MipsSubtarget &Subtarget)
bool inMicroMipsMode() const
void LLVMInitializeMipsAsmPrinter()
virtual void emitDirectiveSetNoMacro()
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
virtual void emitDirectiveEnd(StringRef Name)
bool isGP64bit() const
This file contains the simple types necessary to represent the attributes associated with functions a...
unsigned getAlignment() const
getAlignment - Return the alignment (log2, not bytes) of the function.
bool hasMips32r6() const
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:165
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:408
virtual unsigned getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:126
MO_ABS_HI/LO - Represents the hi or low part of an absolute symbol address.
Definition: MipsBaseInfo.h:51
const MipsABIInfo & getABI() const
void emitXRayTable()
Emit a table with all XRay instrumentation points.
virtual void emitDirectiveModuleOddSPReg()
Context object for machine code objects.
Definition: MCContext.h:62
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
Definition: MCStreamer.h:311
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition: MachineInstr.h:405
bool isIndirectBranch(QueryType Type=AnyInBundle) const
Return true if this is an indirect branch, such as a branch through a register.
Definition: MachineInstr.h:662
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
Definition: AsmPrinter.h:295
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:545
bool isPositionIndependent() const
Definition: AsmPrinter.cpp:197
virtual void EmitBasicBlockEnd(const MachineBasicBlock &MBB)
Targets can override this to emit stuff at the end of a basic block.
Target & getTheMips64Target()
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &O) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant...
void printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O)
bool isLittleEndian() const
Layout endianness...
Definition: DataLayout.h:220
RegisterAsmPrinter - Helper template for registering a target specific assembly printer, for use in the target machine initialization function.
This class is a data container for one entry in a MachineConstantPool.
StringRef getTargetCPU() const
void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS)
void EmitEndOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the end of their file...
const std::string & str() const
Definition: Triple.h:358
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:158
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
bool isTargetNaCl() const
MO_GPREL - Represents the offset from the current gp value to be used for the relocatable object file...
Definition: MipsBaseInfo.h:47
bool isReturn(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:622
MCContext & getContext() const
Address of a global value.
Streaming machine code generation interface.
Definition: MCStreamer.h:188
MO_GOT_CALL - Represents the offset into the global offset table at which the address of a call site ...
Definition: MipsBaseInfo.h:43
MCSymbol * createTempSymbol(bool CanBeUnnamed=true)
Create and return a new assembler temporary symbol with a unique but unspecified name.
Definition: MCContext.cpp:216
Target & getTheMips64elTarget()
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
MCSymbol * CurrentFnSym
The symbol for the current function.
Definition: AsmPrinter.h:112
LLVM Basic Block Representation.
Definition: BasicBlock.h:57
const MCAsmInfo * MAI
Target Asm Printer information.
Definition: AsmPrinter.h:84
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
virtual void emitDirectiveSetNoMicroMips()
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
virtual void emitDirectiveSetMips16()
virtual void SwitchSection(MCSection *Section, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
const GlobalValue * getGlobal() const
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant...
void EmitInstruction(const MachineInstr *MI) override
Targets should implement this to emit instructions.
static ManagedStatic< OptionRegistry > OR
Definition: Options.cpp:30
virtual void emitDirectiveSetMacro()
void EmitAlignment(unsigned NumBits, const GlobalObject *GV=nullptr) const
Emit an alignment directive to the specified power of two boundary.
TargetMachine & TM
Target machine description.
Definition: AsmPrinter.h:81
static unsigned getNumOperandRegisters(unsigned Flag)
getNumOperandRegisters - Extract the number of registers field from the inline asm operand flag...
Definition: InlineAsm.h:335
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition: MathExtras.h:433
void Lower(const MachineInstr *MI, MCInst &OutMI) const
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value=0, unsigned ValueSize=1, unsigned MaxBytesToEmit=0)
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute)=0
Add the given Attribute to Symbol.
Address of a basic block.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:296
const Triple & getTargetTriple() const
StringRef selectMipsCPU(const Triple &TT, StringRef CPU)
Select the Mips CPU for the given triple and cpu name.
bool IsO32() const
Definition: MipsABIInfo.h:41
self_iterator getIterator()
Definition: ilist_node.h:81
virtual void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff)
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
const Target & getTarget() const
MipsMCInstLower MCInstLowering
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual MCSymbol * GetCPISymbol(unsigned CPID) const
Return the symbol for the specified constant pool entry.
bool hasMips64r6() const
bool isMCSymbol() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
MO_GOTTPREL - Represents the offset from the thread pointer (Initial.
Definition: MipsBaseInfo.h:68
virtual void EmitDataRegion(MCDataRegionType Kind)
Note in the output the specified region Kind.
Definition: MCStreamer.h:451
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:43
const std::vector< MachineConstantPoolEntry > & getConstants() const
cl::opt< bool > EmitJalrReloc
unsigned getFunctionNumber() const
Return a unique ID for the current function.
Definition: AsmPrinter.cpp:202
virtual void emitDirectiveAbiCalls()
MO_GOT - Represents the offset into the global offset table at which the address the relocation entry...
Definition: MipsBaseInfo.h:37
Iterator for intrusive lists based on ilist_node.
void setOpcode(unsigned Op)
Definition: MCInst.h:170
MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const
Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.
bool isLittle() const
virtual void emitDirectiveOptionPic0()
MCSymbol * getSymbol(const GlobalValue *GV) const
Definition: AsmPrinter.cpp:430
bool isDebugValue() const
Definition: MachineInstr.h:996
MachineOperand class - Representation of each machine instruction operand.
virtual void EmitCodeAlignment(unsigned ByteAlignment, unsigned MaxBytesToEmit=0)
Emit nops until the byte alignment ByteAlignment is reached.
virtual bool EmitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, SMLoc Loc, const MCSubtargetInfo &STI)
Emit a .reloc directive.
Definition: MCStreamer.h:945
const MCSubtargetInfo * getMCSubtargetInfo() const
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
Definition: AsmPrinter.cpp:225
static Twine utohexstr(const uint64_t &Val)
Definition: Twine.h:387
virtual void emitDirectiveSetNoMips16()
int64_t getImm() const
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
const Function & getFunction() const
Return the LLVM function that this machine code represents.
void printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O, const char *Modifier=nullptr)
void EmitStartOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the start of their fi...
const char * MipsFCCToString(Mips::CondCode CC)
Target - Wrapper for Target specific information.
amdgpu Simplify well known AMD library false FunctionCallee Callee
Target & getTheMipsTarget()
MCSubtargetInfo * createMCSubtargetInfo(StringRef TheTriple, StringRef CPU, StringRef Features) const
createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
MO_TPREL_HI/LO - Represents the hi and low part of the offset from.
Definition: MipsBaseInfo.h:72
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:253
static const unsigned MIPS_NACL_BUNDLE_ALIGN
Definition: MipsMCNaCl.h:17
virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV)
const char * getCurrentABIString() const
Emit Set directives.
virtual void setPic(bool Value)
void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O)
Representation of each machine instruction.
Definition: MachineInstr.h:63
void updateABIInfo(const PredicateLibrary &P)
virtual void emitDirectiveEnt(const MCSymbol &Symbol)
uint16_t getEncodingValue(unsigned RegNo) const
Returns the encoding for RegNo.
const MipsSubtarget * Subtarget
.type _foo,
Definition: MCDirectives.h:30
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:122
bool isEHPad() const
Returns true if the block is a landing pad.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
.type _foo, STT_FUNC # aka
Definition: MCDirectives.h:23
int64_t getOffset() const
Return the offset from the symbol in this operand.
const BlockAddress * getBlockAddress() const
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
#define I(x, y, z)
Definition: MD5.cpp:58
virtual void EmitDTPRel32Value(const MCExpr *Value)
Emit the expression Value into the output as a dtprel (32-bit DTP relative) value.
Definition: MCStreamer.cpp:173
Generic base class for all target subtargets.
void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O)
virtual void emitELFSize(MCSymbol *Symbol, const MCExpr *Value)
Emit an ELF .size directive.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI)
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
virtual void print(raw_ostream &OS, const Module *M) const
print - Print out the internal state of the pass.
Definition: Pass.cpp:123
This represents a section on linux, lots of unix variants and some bare metal systems.
Definition: MCSectionELF.h:27
uint32_t Size
Definition: Profile.cpp:46
MCOperand LowerOperand(const MachineOperand &MO, unsigned offset=0) const
unsigned getRARegister() const
This method should return the register where the return address can be found.
void printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:202
LLVM_NODISCARD std::string lower() const
Definition: StringRef.cpp:107
MCSection * getTextSection() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool PopSection()
Restore the current and previous section from the section stack.
Definition: MCStreamer.h:376
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition: MCContext.h:388
virtual void emitDirectiveSetReorder()
static const char * getRegisterName(unsigned RegNo)
MCSymbol * getMCSymbol() const
void EmitGlobalConstant(const DataLayout &DL, const Constant *CV)
Print a general LLVM constant to the .s file.
LLVM Value Representation.
Definition: Value.h:72
virtual void emitDirectiveNaNLegacy()
virtual void EmitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:346
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:58
const DataLayout & getDataLayout() const
Return information about data layout.
Definition: AsmPrinter.cpp:210
const MipsFunctionInfo * MipsFI
IRTranslator LLVM IR MI
void emitFrameDirective()
Frame Directive.
void addOperand(const MCOperand &Op)
Definition: MCInst.h:183
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
bool isValid() const
Definition: MCInst.h:56
void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI)
Address of indexed Constant in Constant Pool.
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, unsigned AsmVariant, const char *ExtraCode, raw_ostream &O) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
bool isPositionIndependent() const
unsigned getRegSizeInBits(const TargetRegisterClass &RC) const
Return the size in bits of a register from class RC.
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)
Represents a location in source code.
Definition: SMLoc.h:23
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:413
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:34
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
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:544
.end_data_region
Definition: MCDirectives.h:61
Helper operand used to generate R_MIPS_JALR.
Definition: MipsBaseInfo.h:94
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition: MCSymbol.cpp:59