LLVM  10.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"
27 #include "llvm/ADT/SmallString.h"
28 #include "llvm/ADT/StringRef.h"
29 #include "llvm/ADT/Triple.h"
30 #include "llvm/ADT/Twine.h"
31 #include "llvm/BinaryFormat/ELF.h"
41 #include "llvm/IR/Attributes.h"
42 #include "llvm/IR/BasicBlock.h"
43 #include "llvm/IR/DataLayout.h"
44 #include "llvm/IR/Function.h"
45 #include "llvm/IR/InlineAsm.h"
46 #include "llvm/IR/Instructions.h"
47 #include "llvm/MC/MCContext.h"
48 #include "llvm/MC/MCExpr.h"
49 #include "llvm/MC/MCInst.h"
50 #include "llvm/MC/MCInstBuilder.h"
52 #include "llvm/MC/MCSectionELF.h"
53 #include "llvm/MC/MCSymbol.h"
54 #include "llvm/MC/MCSymbolELF.h"
55 #include "llvm/Support/Casting.h"
60 #include <cassert>
61 #include <cstdint>
62 #include <map>
63 #include <memory>
64 #include <string>
65 #include <vector>
66 
67 using namespace llvm;
68 
69 #define DEBUG_TYPE "mips-asm-printer"
70 
72 
73 MipsTargetStreamer &MipsAsmPrinter::getTargetStreamer() const {
74  return static_cast<MipsTargetStreamer &>(*OutStreamer->getTargetStreamer());
75 }
76 
79 
81  if (Subtarget->inMips16Mode())
82  for (std::map<
83  const char *,
84  const Mips16HardFloatInfo::FuncSignature *>::const_iterator
85  it = MipsFI->StubsNeeded.begin();
86  it != MipsFI->StubsNeeded.end(); ++it) {
87  const char *Symbol = it->first;
88  const Mips16HardFloatInfo::FuncSignature *Signature = it->second;
89  if (StubsNeeded.find(Symbol) == StubsNeeded.end())
90  StubsNeeded[Symbol] = Signature;
91  }
92  MCP = MF.getConstantPool();
93 
94  // In NaCl, all indirect jump targets must be aligned to bundle size.
95  if (Subtarget->isTargetNaCl())
96  NaClAlignIndirectJumpTargets(MF);
97 
99 
100  emitXRayTable();
101 
102  return true;
103 }
104 
105 bool MipsAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) {
106  MCOp = MCInstLowering.LowerOperand(MO);
107  return MCOp.isValid();
108 }
109 
110 #include "MipsGenMCPseudoLowering.inc"
111 
112 // Lower PseudoReturn/PseudoIndirectBranch/PseudoIndirectBranch64 to JR, JR_MM,
113 // JALR, or JALR64 as appropriate for the target.
114 void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer,
115  const MachineInstr *MI) {
116  bool HasLinkReg = false;
117  bool InMicroMipsMode = Subtarget->inMicroMipsMode();
118  MCInst TmpInst0;
119 
120  if (Subtarget->hasMips64r6()) {
121  // MIPS64r6 should use (JALR64 ZERO_64, $rs)
122  TmpInst0.setOpcode(Mips::JALR64);
123  HasLinkReg = true;
124  } else if (Subtarget->hasMips32r6()) {
125  // MIPS32r6 should use (JALR ZERO, $rs)
126  if (InMicroMipsMode)
127  TmpInst0.setOpcode(Mips::JRC16_MMR6);
128  else {
129  TmpInst0.setOpcode(Mips::JALR);
130  HasLinkReg = true;
131  }
132  } else if (Subtarget->inMicroMipsMode())
133  // microMIPS should use (JR_MM $rs)
134  TmpInst0.setOpcode(Mips::JR_MM);
135  else {
136  // Everything else should use (JR $rs)
137  TmpInst0.setOpcode(Mips::JR);
138  }
139 
140  MCOperand MCOp;
141 
142  if (HasLinkReg) {
143  unsigned ZeroReg = Subtarget->isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
144  TmpInst0.addOperand(MCOperand::createReg(ZeroReg));
145  }
146 
147  lowerOperand(MI->getOperand(0), MCOp);
148  TmpInst0.addOperand(MCOp);
149 
150  EmitToStreamer(OutStreamer, TmpInst0);
151 }
152 
153 // If there is an MO_JALR operand, insert:
154 //
155 // .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
156 // tmplabel:
157 //
158 // This is an optimization hint for the linker which may then replace
159 // an indirect call with a direct branch.
160 static void emitDirectiveRelocJalr(const MachineInstr &MI,
162  TargetMachine &TM,
163  MCStreamer &OutStreamer,
164  const MipsSubtarget &Subtarget) {
165  for (unsigned int I = MI.getDesc().getNumOperands(), E = MI.getNumOperands();
166  I < E; ++I) {
167  MachineOperand MO = MI.getOperand(I);
168  if (MO.isMCSymbol() && (MO.getTargetFlags() & MipsII::MO_JALR)) {
169  MCSymbol *Callee = MO.getMCSymbol();
170  if (Callee && !Callee->getName().empty()) {
171  MCSymbol *OffsetLabel = OutContext.createTempSymbol();
172  const MCExpr *OffsetExpr =
173  MCSymbolRefExpr::create(OffsetLabel, OutContext);
174  const MCExpr *CaleeExpr =
175  MCSymbolRefExpr::create(Callee, OutContext);
176  OutStreamer.EmitRelocDirective
177  (*OffsetExpr,
178  Subtarget.inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
179  CaleeExpr, SMLoc(), *TM.getMCSubtargetInfo());
180  OutStreamer.EmitLabel(OffsetLabel);
181  return;
182  }
183  }
184  }
185 }
186 
188  MipsTargetStreamer &TS = getTargetStreamer();
189  unsigned Opc = MI->getOpcode();
191 
192  if (MI->isDebugValue()) {
193  SmallString<128> Str;
194  raw_svector_ostream OS(Str);
195 
196  PrintDebugValueComment(MI, OS);
197  return;
198  }
199  if (MI->isDebugLabel())
200  return;
201 
202  // If we just ended a constant pool, mark it as such.
203  if (InConstantPool && Opc != Mips::CONSTPOOL_ENTRY) {
204  OutStreamer->EmitDataRegion(MCDR_DataRegionEnd);
205  InConstantPool = false;
206  }
207  if (Opc == Mips::CONSTPOOL_ENTRY) {
208  // CONSTPOOL_ENTRY - This instruction represents a floating
209  // constant pool in the function. The first operand is the ID#
210  // for this instruction, the second is the index into the
211  // MachineConstantPool that this is, the third is the size in
212  // bytes of this constant pool entry.
213  // The required alignment is specified on the basic block holding this MI.
214  //
215  unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
216  unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex();
217 
218  // If this is the first entry of the pool, mark it.
219  if (!InConstantPool) {
220  OutStreamer->EmitDataRegion(MCDR_DataRegion);
221  InConstantPool = true;
222  }
223 
224  OutStreamer->EmitLabel(GetCPISymbol(LabelId));
225 
226  const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
227  if (MCPE.isMachineConstantPoolEntry())
229  else
231  return;
232  }
233 
234  switch (Opc) {
235  case Mips::PATCHABLE_FUNCTION_ENTER:
237  return;
238  case Mips::PATCHABLE_FUNCTION_EXIT:
240  return;
241  case Mips::PATCHABLE_TAIL_CALL:
243  return;
244  }
245 
246  if (EmitJalrReloc &&
247  (MI->isReturn() || MI->isCall() || MI->isIndirectBranch())) {
248  emitDirectiveRelocJalr(*MI, OutContext, TM, *OutStreamer, *Subtarget);
249  }
250 
253 
254  do {
255  // Do any auto-generated pseudo lowerings.
256  if (emitPseudoExpansionLowering(*OutStreamer, &*I))
257  continue;
258 
259  if (I->getOpcode() == Mips::PseudoReturn ||
260  I->getOpcode() == Mips::PseudoReturn64 ||
261  I->getOpcode() == Mips::PseudoIndirectBranch ||
262  I->getOpcode() == Mips::PseudoIndirectBranch64 ||
263  I->getOpcode() == Mips::TAILCALLREG ||
264  I->getOpcode() == Mips::TAILCALLREG64) {
265  emitPseudoIndirectBranch(*OutStreamer, &*I);
266  continue;
267  }
268 
269  // The inMips16Mode() test is not permanent.
270  // Some instructions are marked as pseudo right now which
271  // would make the test fail for the wrong reason but
272  // that will be fixed soon. We need this here because we are
273  // removing another test for this situation downstream in the
274  // callchain.
275  //
276  if (I->isPseudo() && !Subtarget->inMips16Mode()
277  && !isLongBranchPseudo(I->getOpcode()))
278  llvm_unreachable("Pseudo opcode found in EmitInstruction()");
279 
280  MCInst TmpInst0;
281  MCInstLowering.Lower(&*I, TmpInst0);
282  EmitToStreamer(*OutStreamer, TmpInst0);
283  } while ((++I != E) && I->isInsideBundle()); // Delay slot check
284 }
285 
286 //===----------------------------------------------------------------------===//
287 //
288 // Mips Asm Directives
289 //
290 // -- Frame directive "frame Stackpointer, Stacksize, RARegister"
291 // Describe the stack frame.
292 //
293 // -- Mask directives "(f)mask bitmask, offset"
294 // Tells the assembler which registers are saved and where.
295 // bitmask - contain a little endian bitset indicating which registers are
296 // saved on function prologue (e.g. with a 0x80000000 mask, the
297 // assembler knows the register 31 (RA) is saved at prologue.
298 // offset - the position before stack pointer subtraction indicating where
299 // the first saved register on prologue is located. (e.g. with a
300 //
301 // Consider the following function prologue:
302 //
303 // .frame $fp,48,$ra
304 // .mask 0xc0000000,-8
305 // addiu $sp, $sp, -48
306 // sw $ra, 40($sp)
307 // sw $fp, 36($sp)
308 //
309 // With a 0xc0000000 mask, the assembler knows the register 31 (RA) and
310 // 30 (FP) are saved at prologue. As the save order on prologue is from
311 // left to right, RA is saved first. A -8 offset means that after the
312 // stack pointer subtration, the first register in the mask (RA) will be
313 // saved at address 48-8=40.
314 //
315 //===----------------------------------------------------------------------===//
316 
317 //===----------------------------------------------------------------------===//
318 // Mask directives
319 //===----------------------------------------------------------------------===//
320 
321 // Create a bitmask with all callee saved registers for CPU or Floating Point
322 // registers. For CPU registers consider RA, GP and FP for saving if necessary.
324  // CPU and FPU Saved Registers Bitmasks
325  unsigned CPUBitmask = 0, FPUBitmask = 0;
326  int CPUTopSavedRegOff, FPUTopSavedRegOff;
327 
328  // Set the CPU and FPU Bitmasks
329  const MachineFrameInfo &MFI = MF->getFrameInfo();
331  const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
332  // size of stack area to which FP callee-saved regs are saved.
333  unsigned CPURegSize = TRI->getRegSizeInBits(Mips::GPR32RegClass) / 8;
334  unsigned FGR32RegSize = TRI->getRegSizeInBits(Mips::FGR32RegClass) / 8;
335  unsigned AFGR64RegSize = TRI->getRegSizeInBits(Mips::AFGR64RegClass) / 8;
336  bool HasAFGR64Reg = false;
337  unsigned CSFPRegsSize = 0;
338 
339  for (const auto &I : CSI) {
340  unsigned Reg = I.getReg();
341  unsigned RegNum = TRI->getEncodingValue(Reg);
342 
343  // If it's a floating point register, set the FPU Bitmask.
344  // If it's a general purpose register, set the CPU Bitmask.
345  if (Mips::FGR32RegClass.contains(Reg)) {
346  FPUBitmask |= (1 << RegNum);
347  CSFPRegsSize += FGR32RegSize;
348  } else if (Mips::AFGR64RegClass.contains(Reg)) {
349  FPUBitmask |= (3 << RegNum);
350  CSFPRegsSize += AFGR64RegSize;
351  HasAFGR64Reg = true;
352  } else if (Mips::GPR32RegClass.contains(Reg))
353  CPUBitmask |= (1 << RegNum);
354  }
355 
356  // FP Regs are saved right below where the virtual frame pointer points to.
357  FPUTopSavedRegOff = FPUBitmask ?
358  (HasAFGR64Reg ? -AFGR64RegSize : -FGR32RegSize) : 0;
359 
360  // CPU Regs are saved below FP Regs.
361  CPUTopSavedRegOff = CPUBitmask ? -CSFPRegsSize - CPURegSize : 0;
362 
363  MipsTargetStreamer &TS = getTargetStreamer();
364  // Print CPUBitmask
365  TS.emitMask(CPUBitmask, CPUTopSavedRegOff);
366 
367  // Print FPUBitmask
368  TS.emitFMask(FPUBitmask, FPUTopSavedRegOff);
369 }
370 
371 //===----------------------------------------------------------------------===//
372 // Frame and Set directives
373 //===----------------------------------------------------------------------===//
374 
375 /// Frame Directive
378 
379  Register stackReg = RI.getFrameRegister(*MF);
380  unsigned returnReg = RI.getRARegister();
381  unsigned stackSize = MF->getFrameInfo().getStackSize();
382 
383  getTargetStreamer().emitFrame(stackReg, stackSize, returnReg);
384 }
385 
386 /// Emit Set directives.
388  switch (static_cast<MipsTargetMachine &>(TM).getABI().GetEnumValue()) {
389  case MipsABIInfo::ABI::O32: return "abi32";
390  case MipsABIInfo::ABI::N32: return "abiN32";
391  case MipsABIInfo::ABI::N64: return "abi64";
392  default: llvm_unreachable("Unknown Mips ABI");
393  }
394 }
395 
397  MipsTargetStreamer &TS = getTargetStreamer();
398 
399  // NaCl sandboxing requires that indirect call instructions are masked.
400  // This means that function entry points should be bundle-aligned.
401  if (Subtarget->isTargetNaCl())
403 
404  if (Subtarget->inMicroMipsMode()) {
406  TS.setUsesMicroMips();
408  } else
410 
411  if (Subtarget->inMips16Mode())
413  else
415 
417  OutStreamer->EmitLabel(CurrentFnSym);
418 }
419 
420 /// EmitFunctionBodyStart - Targets can override this to emit stuff before
421 /// the first basic block in the function.
423  MipsTargetStreamer &TS = getTargetStreamer();
424 
426 
427  bool IsNakedFunction = MF->getFunction().hasFnAttribute(Attribute::Naked);
428  if (!IsNakedFunction)
430 
431  if (!IsNakedFunction)
433 
434  if (!Subtarget->inMips16Mode()) {
438  }
439 }
440 
441 /// EmitFunctionBodyEnd - Targets can override this to emit stuff after
442 /// the last basic block in the function.
444  MipsTargetStreamer &TS = getTargetStreamer();
445 
446  // There are instruction for this macros, but they must
447  // always be at the function end, and we can't emit and
448  // break with BB logic.
449  if (!Subtarget->inMips16Mode()) {
450  TS.emitDirectiveSetAt();
453  }
455  // Make sure to terminate any constant pools that were at the end
456  // of the function.
457  if (!InConstantPool)
458  return;
459  InConstantPool = false;
460  OutStreamer->EmitDataRegion(MCDR_DataRegionEnd);
461 }
462 
465  MipsTargetStreamer &TS = getTargetStreamer();
466  if (MBB.empty())
467  TS.emitDirectiveInsn();
468 }
469 
470 /// isBlockOnlyReachableByFallthough - Return true if the basic block has
471 /// exactly one predecessor and the control transfer mechanism between
472 /// the predecessor and this block is a fall-through.
474  MBB) const {
475  // The predecessor has to be immediately before this block.
476  const MachineBasicBlock *Pred = *MBB->pred_begin();
477 
478  // If the predecessor is a switch statement, assume a jump table
479  // implementation, so it is not a fall through.
480  if (const BasicBlock *bb = Pred->getBasicBlock())
481  if (isa<SwitchInst>(bb->getTerminator()))
482  return false;
483 
484  // If this is a landing pad, it isn't a fall through. If it has no preds,
485  // then nothing falls through to it.
486  if (MBB->isEHPad() || MBB->pred_empty())
487  return false;
488 
489  // If there isn't exactly one predecessor, it can't be a fall through.
491  ++PI2;
492 
493  if (PI2 != MBB->pred_end())
494  return false;
495 
496  // The predecessor has to be immediately before this block.
497  if (!Pred->isLayoutSuccessor(MBB))
498  return false;
499 
500  // If the block is completely empty, then it definitely does fall through.
501  if (Pred->empty())
502  return true;
503 
504  // Otherwise, check the last instruction.
505  // Check if the last terminator is an unconditional branch.
507  while (I != Pred->begin() && !(--I)->isTerminator()) ;
508 
509  return !I->isBarrier();
510 }
511 
512 // Print out an operand for an inline asm expression.
513 bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
514  const char *ExtraCode, 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, 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  Register 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  Register 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,
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  PrintSymbolOperand(MO, O);
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())) ||
816  STI.useSoftFloat())
818 
819  // We should always emit a '.module [no]oddspreg' but binutils 2.24 does not
820  // accept it. We therefore emit it when it contradicts the default or an
821  // option has changed the default (i.e. FPXX) and omit it otherwise.
822  if (ABI.IsO32() && (!STI.useOddSPReg() || STI.isABI_FPXX()))
824 }
825 
826 void MipsAsmPrinter::emitInlineAsmStart() const {
827  MipsTargetStreamer &TS = getTargetStreamer();
828 
829  // GCC's choice of assembler options for inline assembly code ('at', 'macro'
830  // and 'reorder') is different from LLVM's choice for generated code ('noat',
831  // 'nomacro' and 'noreorder').
832  // In order to maintain compatibility with inline assembly code which depends
833  // on GCC's assembler options being used, we have to switch to those options
834  // for the duration of the inline assembly block and then switch back.
836  TS.emitDirectiveSetAt();
839  OutStreamer->AddBlankLine();
840 }
841 
842 void MipsAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
843  const MCSubtargetInfo *EndInfo) const {
844  OutStreamer->AddBlankLine();
845  getTargetStreamer().emitDirectiveSetPop();
846 }
847 
848 void MipsAsmPrinter::EmitJal(const MCSubtargetInfo &STI, MCSymbol *Symbol) {
849  MCInst I;
850  I.setOpcode(Mips::JAL);
851  I.addOperand(
853  OutStreamer->EmitInstruction(I, STI);
854 }
855 
856 void MipsAsmPrinter::EmitInstrReg(const MCSubtargetInfo &STI, unsigned Opcode,
857  unsigned Reg) {
858  MCInst I;
859  I.setOpcode(Opcode);
861  OutStreamer->EmitInstruction(I, STI);
862 }
863 
864 void MipsAsmPrinter::EmitInstrRegReg(const MCSubtargetInfo &STI,
865  unsigned Opcode, unsigned Reg1,
866  unsigned Reg2) {
867  MCInst I;
868  //
869  // Because of the current td files for Mips32, the operands for MTC1
870  // appear backwards from their normal assembly order. It's not a trivial
871  // change to fix this in the td file so we adjust for it here.
872  //
873  if (Opcode == Mips::MTC1) {
874  unsigned Temp = Reg1;
875  Reg1 = Reg2;
876  Reg2 = Temp;
877  }
878  I.setOpcode(Opcode);
881  OutStreamer->EmitInstruction(I, STI);
882 }
883 
884 void MipsAsmPrinter::EmitInstrRegRegReg(const MCSubtargetInfo &STI,
885  unsigned Opcode, unsigned Reg1,
886  unsigned Reg2, unsigned Reg3) {
887  MCInst I;
888  I.setOpcode(Opcode);
892  OutStreamer->EmitInstruction(I, STI);
893 }
894 
895 void MipsAsmPrinter::EmitMovFPIntPair(const MCSubtargetInfo &STI,
896  unsigned MovOpc, unsigned Reg1,
897  unsigned Reg2, unsigned FPReg1,
898  unsigned FPReg2, bool LE) {
899  if (!LE) {
900  unsigned temp = Reg1;
901  Reg1 = Reg2;
902  Reg2 = temp;
903  }
904  EmitInstrRegReg(STI, MovOpc, Reg1, FPReg1);
905  EmitInstrRegReg(STI, MovOpc, Reg2, FPReg2);
906 }
907 
908 void MipsAsmPrinter::EmitSwapFPIntParams(const MCSubtargetInfo &STI,
910  bool LE, bool ToFP) {
911  using namespace Mips16HardFloatInfo;
912 
913  unsigned MovOpc = ToFP ? Mips::MTC1 : Mips::MFC1;
914  switch (PV) {
915  case FSig:
916  EmitInstrRegReg(STI, MovOpc, Mips::A0, Mips::F12);
917  break;
918  case FFSig:
919  EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F14, LE);
920  break;
921  case FDSig:
922  EmitInstrRegReg(STI, MovOpc, Mips::A0, Mips::F12);
923  EmitMovFPIntPair(STI, MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE);
924  break;
925  case DSig:
926  EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
927  break;
928  case DDSig:
929  EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
930  EmitMovFPIntPair(STI, MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE);
931  break;
932  case DFSig:
933  EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
934  EmitInstrRegReg(STI, MovOpc, Mips::A2, Mips::F14);
935  break;
936  case NoSig:
937  return;
938  }
939 }
940 
941 void MipsAsmPrinter::EmitSwapFPIntRetval(
943  bool LE) {
944  using namespace Mips16HardFloatInfo;
945 
946  unsigned MovOpc = Mips::MFC1;
947  switch (RV) {
948  case FRet:
949  EmitInstrRegReg(STI, MovOpc, Mips::V0, Mips::F0);
950  break;
951  case DRet:
952  EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
953  break;
954  case CFRet:
955  EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
956  break;
957  case CDRet:
958  EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
959  EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F2, Mips::F3, LE);
960  break;
961  case NoFPRet:
962  break;
963  }
964 }
965 
966 void MipsAsmPrinter::EmitFPCallStub(
967  const char *Symbol, const Mips16HardFloatInfo::FuncSignature *Signature) {
968  using namespace Mips16HardFloatInfo;
969 
970  MCSymbol *MSymbol = OutContext.getOrCreateSymbol(StringRef(Symbol));
971  bool LE = getDataLayout().isLittleEndian();
972  // Construct a local MCSubtargetInfo here.
973  // This is because the MachineFunction won't exist (but have not yet been
974  // freed) and since we're at the global level we can use the default
975  // constructed subtarget.
976  std::unique_ptr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo(
979 
980  //
981  // .global xxxx
982  //
983  OutStreamer->EmitSymbolAttribute(MSymbol, MCSA_Global);
984  const char *RetType;
985  //
986  // make the comment field identifying the return and parameter
987  // types of the floating point stub
988  // # Stub function to call rettype xxxx (params)
989  //
990  switch (Signature->RetSig) {
991  case FRet:
992  RetType = "float";
993  break;
994  case DRet:
995  RetType = "double";
996  break;
997  case CFRet:
998  RetType = "complex";
999  break;
1000  case CDRet:
1001  RetType = "double complex";
1002  break;
1003  case NoFPRet:
1004  RetType = "";
1005  break;
1006  }
1007  const char *Parms;
1008  switch (Signature->ParamSig) {
1009  case FSig:
1010  Parms = "float";
1011  break;
1012  case FFSig:
1013  Parms = "float, float";
1014  break;
1015  case FDSig:
1016  Parms = "float, double";
1017  break;
1018  case DSig:
1019  Parms = "double";
1020  break;
1021  case DDSig:
1022  Parms = "double, double";
1023  break;
1024  case DFSig:
1025  Parms = "double, float";
1026  break;
1027  case NoSig:
1028  Parms = "";
1029  break;
1030  }
1031  OutStreamer->AddComment("\t# Stub function to call " + Twine(RetType) + " " +
1032  Twine(Symbol) + " (" + Twine(Parms) + ")");
1033  //
1034  // probably not necessary but we save and restore the current section state
1035  //
1036  OutStreamer->PushSection();
1037  //
1038  // .section mips16.call.fpxxxx,"ax",@progbits
1039  //
1041  ".mips16.call.fp." + std::string(Symbol), ELF::SHT_PROGBITS,
1043  OutStreamer->SwitchSection(M, nullptr);
1044  //
1045  // .align 2
1046  //
1047  OutStreamer->EmitValueToAlignment(4);
1048  MipsTargetStreamer &TS = getTargetStreamer();
1049  //
1050  // .set nomips16
1051  // .set nomicromips
1052  //
1055  //
1056  // .ent __call_stub_fp_xxxx
1057  // .type __call_stub_fp_xxxx,@function
1058  // __call_stub_fp_xxxx:
1059  //
1060  std::string x = "__call_stub_fp_" + std::string(Symbol);
1061  MCSymbolELF *Stub =
1062  cast<MCSymbolELF>(OutContext.getOrCreateSymbol(StringRef(x)));
1063  TS.emitDirectiveEnt(*Stub);
1064  MCSymbol *MType =
1065  OutContext.getOrCreateSymbol("__call_stub_fp_" + Twine(Symbol));
1066  OutStreamer->EmitSymbolAttribute(MType, MCSA_ELF_TypeFunction);
1067  OutStreamer->EmitLabel(Stub);
1068 
1069  // Only handle non-pic for now.
1071  "should not be here if we are compiling pic");
1073  //
1074  // We need to add a MipsMCExpr class to MCTargetDesc to fully implement
1075  // stubs without raw text but this current patch is for compiler generated
1076  // functions and they all return some value.
1077  // The calling sequence for non pic is different in that case and we need
1078  // to implement %lo and %hi in order to handle the case of no return value
1079  // See the corresponding method in Mips16HardFloat for details.
1080  //
1081  // mov the return address to S2.
1082  // we have no stack space to store it and we are about to make another call.
1083  // We need to make sure that the enclosing function knows to save S2
1084  // This should have already been handled.
1085  //
1086  // Mov $18, $31
1087 
1088  EmitInstrRegRegReg(*STI, Mips::OR, Mips::S2, Mips::RA, Mips::ZERO);
1089 
1090  EmitSwapFPIntParams(*STI, Signature->ParamSig, LE, true);
1091 
1092  // Jal xxxx
1093  //
1094  EmitJal(*STI, MSymbol);
1095 
1096  // fix return values
1097  EmitSwapFPIntRetval(*STI, Signature->RetSig, LE);
1098  //
1099  // do the return
1100  // if (Signature->RetSig == NoFPRet)
1101  // llvm_unreachable("should not be any stubs here with no return value");
1102  // else
1103  EmitInstrReg(*STI, Mips::JR, Mips::S2);
1104 
1106  OutStreamer->EmitLabel(Tmp);
1109  const MCExpr *T_min_E = MCBinaryExpr::createSub(T, E, OutContext);
1110  OutStreamer->emitELFSize(Stub, T_min_E);
1111  TS.emitDirectiveEnd(x);
1112  OutStreamer->PopSection();
1113 }
1114 
1116  // Emit needed stubs
1117  //
1118  for (std::map<
1119  const char *,
1120  const Mips16HardFloatInfo::FuncSignature *>::const_iterator
1121  it = StubsNeeded.begin();
1122  it != StubsNeeded.end(); ++it) {
1123  const char *Symbol = it->first;
1124  const Mips16HardFloatInfo::FuncSignature *Signature = it->second;
1125  EmitFPCallStub(Symbol, Signature);
1126  }
1127  // return to the text section
1129 }
1130 
1131 void MipsAsmPrinter::EmitSled(const MachineInstr &MI, SledKind Kind) {
1132  const uint8_t NoopsInSledCount = Subtarget->isGP64bit() ? 15 : 11;
1133  // For mips32 we want to emit the following pattern:
1134  //
1135  // .Lxray_sled_N:
1136  // ALIGN
1137  // B .tmpN
1138  // 11 NOP instructions (44 bytes)
1139  // ADDIU T9, T9, 52
1140  // .tmpN
1141  //
1142  // We need the 44 bytes (11 instructions) because at runtime, we'd
1143  // be patching over the full 48 bytes (12 instructions) with the following
1144  // pattern:
1145  //
1146  // ADDIU SP, SP, -8
1147  // NOP
1148  // SW RA, 4(SP)
1149  // SW T9, 0(SP)
1150  // LUI T9, %hi(__xray_FunctionEntry/Exit)
1151  // ORI T9, T9, %lo(__xray_FunctionEntry/Exit)
1152  // LUI T0, %hi(function_id)
1153  // JALR T9
1154  // ORI T0, T0, %lo(function_id)
1155  // LW T9, 0(SP)
1156  // LW RA, 4(SP)
1157  // ADDIU SP, SP, 8
1158  //
1159  // We add 52 bytes to t9 because we want to adjust the function pointer to
1160  // the actual start of function i.e. the address just after the noop sled.
1161  // We do this because gp displacement relocation is emitted at the start of
1162  // of the function i.e after the nop sled and to correctly calculate the
1163  // global offset table address, t9 must hold the address of the instruction
1164  // containing the gp displacement relocation.
1165  // FIXME: Is this correct for the static relocation model?
1166  //
1167  // For mips64 we want to emit the following pattern:
1168  //
1169  // .Lxray_sled_N:
1170  // ALIGN
1171  // B .tmpN
1172  // 15 NOP instructions (60 bytes)
1173  // .tmpN
1174  //
1175  // We need the 60 bytes (15 instructions) because at runtime, we'd
1176  // be patching over the full 64 bytes (16 instructions) with the following
1177  // pattern:
1178  //
1179  // DADDIU SP, SP, -16
1180  // NOP
1181  // SD RA, 8(SP)
1182  // SD T9, 0(SP)
1183  // LUI T9, %highest(__xray_FunctionEntry/Exit)
1184  // ORI T9, T9, %higher(__xray_FunctionEntry/Exit)
1185  // DSLL T9, T9, 16
1186  // ORI T9, T9, %hi(__xray_FunctionEntry/Exit)
1187  // DSLL T9, T9, 16
1188  // ORI T9, T9, %lo(__xray_FunctionEntry/Exit)
1189  // LUI T0, %hi(function_id)
1190  // JALR T9
1191  // ADDIU T0, T0, %lo(function_id)
1192  // LD T9, 0(SP)
1193  // LD RA, 8(SP)
1194  // DADDIU SP, SP, 16
1195  //
1196  OutStreamer->EmitCodeAlignment(4);
1197  auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
1198  OutStreamer->EmitLabel(CurSled);
1200 
1201  // Emit "B .tmpN" instruction, which jumps over the nop sled to the actual
1202  // start of function
1203  const MCExpr *TargetExpr = MCSymbolRefExpr::create(
1204  Target, MCSymbolRefExpr::VariantKind::VK_None, OutContext);
1205  EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::BEQ)
1206  .addReg(Mips::ZERO)
1207  .addReg(Mips::ZERO)
1208  .addExpr(TargetExpr));
1209 
1210  for (int8_t I = 0; I < NoopsInSledCount; I++)
1211  EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::SLL)
1212  .addReg(Mips::ZERO)
1213  .addReg(Mips::ZERO)
1214  .addImm(0));
1215 
1216  OutStreamer->EmitLabel(Target);
1217 
1218  if (!Subtarget->isGP64bit()) {
1219  EmitToStreamer(*OutStreamer,
1220  MCInstBuilder(Mips::ADDiu)
1221  .addReg(Mips::T9)
1222  .addReg(Mips::T9)
1223  .addImm(0x34));
1224  }
1225 
1226  recordSled(CurSled, MI, Kind);
1227 }
1228 
1230  EmitSled(MI, SledKind::FUNCTION_ENTER);
1231 }
1232 
1234  EmitSled(MI, SledKind::FUNCTION_EXIT);
1235 }
1236 
1238  EmitSled(MI, SledKind::TAIL_CALL);
1239 }
1240 
1242  raw_ostream &OS) {
1243  // TODO: implement
1244 }
1245 
1246 // Emit .dtprelword or .dtpreldword directive
1247 // and value for debug thread local expression.
1248 void MipsAsmPrinter::EmitDebugValue(const MCExpr *Value, unsigned Size) const {
1249  if (auto *MipsExpr = dyn_cast<MipsMCExpr>(Value)) {
1250  if (MipsExpr && MipsExpr->getKind() == MipsMCExpr::MEK_DTPREL) {
1251  switch (Size) {
1252  case 4:
1253  OutStreamer->EmitDTPRel32Value(MipsExpr->getSubExpr());
1254  break;
1255  case 8:
1256  OutStreamer->EmitDTPRel64Value(MipsExpr->getSubExpr());
1257  break;
1258  default:
1259  llvm_unreachable("Unexpected size of expression value.");
1260  }
1261  return;
1262  }
1263  }
1264  AsmPrinter::EmitDebugValue(Value, Size);
1265 }
1266 
1267 // Align all targets of indirect branches on bundle size. Used only if target
1268 // is NaCl.
1269 void MipsAsmPrinter::NaClAlignIndirectJumpTargets(MachineFunction &MF) {
1270  // Align all blocks that are jumped to through jump table.
1271  if (MachineJumpTableInfo *JtInfo = MF.getJumpTableInfo()) {
1272  const std::vector<MachineJumpTableEntry> &JT = JtInfo->getJumpTables();
1273  for (unsigned I = 0; I < JT.size(); ++I) {
1274  const std::vector<MachineBasicBlock*> &MBBs = JT[I].MBBs;
1275 
1276  for (unsigned J = 0; J < MBBs.size(); ++J)
1277  MBBs[J]->setAlignment(MIPS_NACL_BUNDLE_ALIGN);
1278  }
1279  }
1280 
1281  // If basic block address is taken, block can be target of indirect branch.
1282  for (auto &MBB : MF) {
1283  if (MBB.hasAddressTaken())
1284  MBB.setAlignment(MIPS_NACL_BUNDLE_ALIGN);
1285  }
1286 }
1287 
1288 bool MipsAsmPrinter::isLongBranchPseudo(int Opcode) const {
1289  return (Opcode == Mips::LONG_BRANCH_LUi
1290  || Opcode == Mips::LONG_BRANCH_LUi2Op
1291  || Opcode == Mips::LONG_BRANCH_LUi2Op_64
1292  || Opcode == Mips::LONG_BRANCH_ADDiu
1293  || Opcode == Mips::LONG_BRANCH_ADDiu2Op
1294  || Opcode == Mips::LONG_BRANCH_DADDiu
1295  || Opcode == Mips::LONG_BRANCH_DADDiu2Op);
1296 }
1297 
1298 // Force static initialization.
1299 extern "C" void LLVMInitializeMipsAsmPrinter() {
1304 }
unsigned getTargetFlags() const
MachineConstantPoolValue * MachineCPVal
virtual void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff)
bool isABICalls() const
StringRef getTargetFeatureString() const
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...
bool isDebugLabel() const
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:651
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:327
This class represents lattice values for constants.
Definition: AllocatorList.h:23
StringRef getPrivateGlobalPrefix() const
Definition: DataLayout.h:317
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:65
bool inMips16Mode() const
virtual void AddBlankLine()
AddBlankLine - Emit a blank line to a .s file to pretty it up.
Definition: MCStreamer.h:331
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 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:174
virtual void emitDirectiveSetNoReorder()
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.h:323
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:530
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:366
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:646
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
void EmitFunctionEntryLabel() override
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
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:225
virtual void emitFrame(unsigned StackReg, unsigned StackSize, unsigned ReturnReg)
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:414
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:169
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:411
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:65
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
Definition: MCStreamer.h:310
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition: MachineInstr.h:408
bool isIndirectBranch(QueryType Type=AnyInBundle) const
Return true if this is an indirect branch, such as a branch through a register.
Definition: MachineInstr.h:681
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:550
bool isPositionIndependent() const
Definition: AsmPrinter.cpp:205
virtual void EmitBasicBlockEnd(const MachineBasicBlock &MBB)
Targets can override this to emit stuff at the end of a basic block.
Target & getTheMips64Target()
void printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O)
bool isLittleEndian() const
Layout endianness...
Definition: DataLayout.h:233
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:365
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:641
MCContext & getContext() const
Address of a global value.
Streaming machine code generation interface.
Definition: MCStreamer.h:189
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:225
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.
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:336
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:322
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.
uint16_t getEncodingValue(MCRegister RegNo) const
Returns the encoding for RegNo.
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:450
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:210
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()
bool isDebugValue() const
MachineOperand class - Representation of each machine instruction operand.
union llvm::MachineConstantPoolEntry::@167 Val
The constant itself.
virtual Register getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
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:976
const MCSubtargetInfo * getMCSubtargetInfo() const
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
Definition: AsmPrinter.cpp:233
static Twine utohexstr(const uint64_t &Val)
Definition: Twine.h:387
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...
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:256
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:64
void updateABIInfo(const PredicateLibrary &P)
virtual void emitDirectiveEnt(const MCSymbol &Symbol)
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:129
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
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...
virtual void EmitDTPRel32Value(const MCExpr *Value)
Emit the expression Value into the output as a dtprel (32-bit DTP relative) value.
Definition: MCStreamer.cpp:178
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...
This represents a section on linux, lots of unix variants and some bare metal systems.
Definition: MCSectionELF.h:27
virtual void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS)
Print the MachineOperand as a symbol.
uint32_t Size
Definition: Profile.cpp:46
MCOperand LowerOperand(const MachineOperand &MO, unsigned offset=0) const
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:204
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:375
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition: MCContext.h:424
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:73
virtual void emitDirectiveNaNLegacy()
virtual void EmitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:397
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:65
const DataLayout & getDataLayout() const
Return information about data layout.
Definition: AsmPrinter.cpp:218
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 isPositionIndependent() const
unsigned getRegSizeInBits(const TargetRegisterClass &RC) const
Return the size in bits of a register from class RC.
Register getReg() const
getReg - Returns the register number.
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:416
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...
MCRegister getRARegister() const
This method should return the register where the return address can be found.
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
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
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