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"
61 #include <cassert>
62 #include <cstdint>
63 #include <map>
64 #include <memory>
65 #include <string>
66 #include <vector>
67 
68 using namespace llvm;
69 
70 #define DEBUG_TYPE "mips-asm-printer"
71 
73 
74 MipsTargetStreamer &MipsAsmPrinter::getTargetStreamer() const {
75  return static_cast<MipsTargetStreamer &>(*OutStreamer->getTargetStreamer());
76 }
77 
80 
82  if (Subtarget->inMips16Mode())
83  for (std::map<
84  const char *,
85  const Mips16HardFloatInfo::FuncSignature *>::const_iterator
86  it = MipsFI->StubsNeeded.begin();
87  it != MipsFI->StubsNeeded.end(); ++it) {
88  const char *Symbol = it->first;
89  const Mips16HardFloatInfo::FuncSignature *Signature = it->second;
90  if (StubsNeeded.find(Symbol) == StubsNeeded.end())
91  StubsNeeded[Symbol] = Signature;
92  }
93  MCP = MF.getConstantPool();
94 
95  // In NaCl, all indirect jump targets must be aligned to bundle size.
96  if (Subtarget->isTargetNaCl())
97  NaClAlignIndirectJumpTargets(MF);
98 
100 
101  emitXRayTable();
102 
103  return true;
104 }
105 
106 bool MipsAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) {
107  MCOp = MCInstLowering.LowerOperand(MO);
108  return MCOp.isValid();
109 }
110 
111 #include "MipsGenMCPseudoLowering.inc"
112 
113 // Lower PseudoReturn/PseudoIndirectBranch/PseudoIndirectBranch64 to JR, JR_MM,
114 // JALR, or JALR64 as appropriate for the target.
115 void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer,
116  const MachineInstr *MI) {
117  bool HasLinkReg = false;
118  bool InMicroMipsMode = Subtarget->inMicroMipsMode();
119  MCInst TmpInst0;
120 
121  if (Subtarget->hasMips64r6()) {
122  // MIPS64r6 should use (JALR64 ZERO_64, $rs)
123  TmpInst0.setOpcode(Mips::JALR64);
124  HasLinkReg = true;
125  } else if (Subtarget->hasMips32r6()) {
126  // MIPS32r6 should use (JALR ZERO, $rs)
127  if (InMicroMipsMode)
128  TmpInst0.setOpcode(Mips::JRC16_MMR6);
129  else {
130  TmpInst0.setOpcode(Mips::JALR);
131  HasLinkReg = true;
132  }
133  } else if (Subtarget->inMicroMipsMode())
134  // microMIPS should use (JR_MM $rs)
135  TmpInst0.setOpcode(Mips::JR_MM);
136  else {
137  // Everything else should use (JR $rs)
138  TmpInst0.setOpcode(Mips::JR);
139  }
140 
141  MCOperand MCOp;
142 
143  if (HasLinkReg) {
144  unsigned ZeroReg = Subtarget->isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
145  TmpInst0.addOperand(MCOperand::createReg(ZeroReg));
146  }
147 
148  lowerOperand(MI->getOperand(0), MCOp);
149  TmpInst0.addOperand(MCOp);
150 
151  EmitToStreamer(OutStreamer, TmpInst0);
152 }
153 
154 // If there is an MO_JALR operand, insert:
155 //
156 // .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
157 // tmplabel:
158 //
159 // This is an optimization hint for the linker which may then replace
160 // an indirect call with a direct branch.
161 static void emitDirectiveRelocJalr(const MachineInstr &MI,
163  TargetMachine &TM,
164  MCStreamer &OutStreamer,
165  const MipsSubtarget &Subtarget) {
166  for (unsigned int I = MI.getDesc().getNumOperands(), E = MI.getNumOperands();
167  I < E; ++I) {
168  MachineOperand MO = MI.getOperand(I);
169  if (MO.isMCSymbol() && (MO.getTargetFlags() & MipsII::MO_JALR)) {
170  MCSymbol *Callee = MO.getMCSymbol();
171  if (Callee && !Callee->getName().empty()) {
172  MCSymbol *OffsetLabel = OutContext.createTempSymbol();
173  const MCExpr *OffsetExpr =
174  MCSymbolRefExpr::create(OffsetLabel, OutContext);
175  const MCExpr *CaleeExpr =
176  MCSymbolRefExpr::create(Callee, OutContext);
177  OutStreamer.EmitRelocDirective
178  (*OffsetExpr,
179  Subtarget.inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
180  CaleeExpr, SMLoc(), *TM.getMCSubtargetInfo());
181  OutStreamer.EmitLabel(OffsetLabel);
182  return;
183  }
184  }
185  }
186 }
187 
189  MipsTargetStreamer &TS = getTargetStreamer();
190  unsigned Opc = MI->getOpcode();
192 
193  if (MI->isDebugValue()) {
194  SmallString<128> Str;
195  raw_svector_ostream OS(Str);
196 
197  PrintDebugValueComment(MI, OS);
198  return;
199  }
200  if (MI->isDebugLabel())
201  return;
202 
203  // If we just ended a constant pool, mark it as such.
204  if (InConstantPool && Opc != Mips::CONSTPOOL_ENTRY) {
205  OutStreamer->EmitDataRegion(MCDR_DataRegionEnd);
206  InConstantPool = false;
207  }
208  if (Opc == Mips::CONSTPOOL_ENTRY) {
209  // CONSTPOOL_ENTRY - This instruction represents a floating
210  // constant pool in the function. The first operand is the ID#
211  // for this instruction, the second is the index into the
212  // MachineConstantPool that this is, the third is the size in
213  // bytes of this constant pool entry.
214  // The required alignment is specified on the basic block holding this MI.
215  //
216  unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
217  unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex();
218 
219  // If this is the first entry of the pool, mark it.
220  if (!InConstantPool) {
221  OutStreamer->EmitDataRegion(MCDR_DataRegion);
222  InConstantPool = true;
223  }
224 
225  OutStreamer->EmitLabel(GetCPISymbol(LabelId));
226 
227  const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
228  if (MCPE.isMachineConstantPoolEntry())
230  else
232  return;
233  }
234 
235  switch (Opc) {
236  case Mips::PATCHABLE_FUNCTION_ENTER:
238  return;
239  case Mips::PATCHABLE_FUNCTION_EXIT:
241  return;
242  case Mips::PATCHABLE_TAIL_CALL:
244  return;
245  }
246 
247  if (EmitJalrReloc &&
248  (MI->isReturn() || MI->isCall() || MI->isIndirectBranch())) {
249  emitDirectiveRelocJalr(*MI, OutContext, TM, *OutStreamer, *Subtarget);
250  }
251 
254 
255  do {
256  // Do any auto-generated pseudo lowerings.
257  if (emitPseudoExpansionLowering(*OutStreamer, &*I))
258  continue;
259 
260  if (I->getOpcode() == Mips::PseudoReturn ||
261  I->getOpcode() == Mips::PseudoReturn64 ||
262  I->getOpcode() == Mips::PseudoIndirectBranch ||
263  I->getOpcode() == Mips::PseudoIndirectBranch64 ||
264  I->getOpcode() == Mips::TAILCALLREG ||
265  I->getOpcode() == Mips::TAILCALLREG64) {
266  emitPseudoIndirectBranch(*OutStreamer, &*I);
267  continue;
268  }
269 
270  // The inMips16Mode() test is not permanent.
271  // Some instructions are marked as pseudo right now which
272  // would make the test fail for the wrong reason but
273  // that will be fixed soon. We need this here because we are
274  // removing another test for this situation downstream in the
275  // callchain.
276  //
277  if (I->isPseudo() && !Subtarget->inMips16Mode()
278  && !isLongBranchPseudo(I->getOpcode()))
279  llvm_unreachable("Pseudo opcode found in EmitInstruction()");
280 
281  MCInst TmpInst0;
282  MCInstLowering.Lower(&*I, TmpInst0);
283  EmitToStreamer(*OutStreamer, TmpInst0);
284  } while ((++I != E) && I->isInsideBundle()); // Delay slot check
285 }
286 
287 //===----------------------------------------------------------------------===//
288 //
289 // Mips Asm Directives
290 //
291 // -- Frame directive "frame Stackpointer, Stacksize, RARegister"
292 // Describe the stack frame.
293 //
294 // -- Mask directives "(f)mask bitmask, offset"
295 // Tells the assembler which registers are saved and where.
296 // bitmask - contain a little endian bitset indicating which registers are
297 // saved on function prologue (e.g. with a 0x80000000 mask, the
298 // assembler knows the register 31 (RA) is saved at prologue.
299 // offset - the position before stack pointer subtraction indicating where
300 // the first saved register on prologue is located. (e.g. with a
301 //
302 // Consider the following function prologue:
303 //
304 // .frame $fp,48,$ra
305 // .mask 0xc0000000,-8
306 // addiu $sp, $sp, -48
307 // sw $ra, 40($sp)
308 // sw $fp, 36($sp)
309 //
310 // With a 0xc0000000 mask, the assembler knows the register 31 (RA) and
311 // 30 (FP) are saved at prologue. As the save order on prologue is from
312 // left to right, RA is saved first. A -8 offset means that after the
313 // stack pointer subtration, the first register in the mask (RA) will be
314 // saved at address 48-8=40.
315 //
316 //===----------------------------------------------------------------------===//
317 
318 //===----------------------------------------------------------------------===//
319 // Mask directives
320 //===----------------------------------------------------------------------===//
321 
322 // Create a bitmask with all callee saved registers for CPU or Floating Point
323 // registers. For CPU registers consider RA, GP and FP for saving if necessary.
325  // CPU and FPU Saved Registers Bitmasks
326  unsigned CPUBitmask = 0, FPUBitmask = 0;
327  int CPUTopSavedRegOff, FPUTopSavedRegOff;
328 
329  // Set the CPU and FPU Bitmasks
330  const MachineFrameInfo &MFI = MF->getFrameInfo();
332  const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
333  // size of stack area to which FP callee-saved regs are saved.
334  unsigned CPURegSize = TRI->getRegSizeInBits(Mips::GPR32RegClass) / 8;
335  unsigned FGR32RegSize = TRI->getRegSizeInBits(Mips::FGR32RegClass) / 8;
336  unsigned AFGR64RegSize = TRI->getRegSizeInBits(Mips::AFGR64RegClass) / 8;
337  bool HasAFGR64Reg = false;
338  unsigned CSFPRegsSize = 0;
339 
340  for (const auto &I : CSI) {
341  unsigned Reg = I.getReg();
342  unsigned RegNum = TRI->getEncodingValue(Reg);
343 
344  // If it's a floating point register, set the FPU Bitmask.
345  // If it's a general purpose register, set the CPU Bitmask.
346  if (Mips::FGR32RegClass.contains(Reg)) {
347  FPUBitmask |= (1 << RegNum);
348  CSFPRegsSize += FGR32RegSize;
349  } else if (Mips::AFGR64RegClass.contains(Reg)) {
350  FPUBitmask |= (3 << RegNum);
351  CSFPRegsSize += AFGR64RegSize;
352  HasAFGR64Reg = true;
353  } else if (Mips::GPR32RegClass.contains(Reg))
354  CPUBitmask |= (1 << RegNum);
355  }
356 
357  // FP Regs are saved right below where the virtual frame pointer points to.
358  FPUTopSavedRegOff = FPUBitmask ?
359  (HasAFGR64Reg ? -AFGR64RegSize : -FGR32RegSize) : 0;
360 
361  // CPU Regs are saved below FP Regs.
362  CPUTopSavedRegOff = CPUBitmask ? -CSFPRegsSize - CPURegSize : 0;
363 
364  MipsTargetStreamer &TS = getTargetStreamer();
365  // Print CPUBitmask
366  TS.emitMask(CPUBitmask, CPUTopSavedRegOff);
367 
368  // Print FPUBitmask
369  TS.emitFMask(FPUBitmask, FPUTopSavedRegOff);
370 }
371 
372 //===----------------------------------------------------------------------===//
373 // Frame and Set directives
374 //===----------------------------------------------------------------------===//
375 
376 /// Frame Directive
379 
380  Register stackReg = RI.getFrameRegister(*MF);
381  unsigned returnReg = RI.getRARegister();
382  unsigned stackSize = MF->getFrameInfo().getStackSize();
383 
384  getTargetStreamer().emitFrame(stackReg, stackSize, returnReg);
385 }
386 
387 /// Emit Set directives.
389  switch (static_cast<MipsTargetMachine &>(TM).getABI().GetEnumValue()) {
390  case MipsABIInfo::ABI::O32: return "abi32";
391  case MipsABIInfo::ABI::N32: return "abiN32";
392  case MipsABIInfo::ABI::N64: return "abi64";
393  default: llvm_unreachable("Unknown Mips ABI");
394  }
395 }
396 
398  MipsTargetStreamer &TS = getTargetStreamer();
399 
400  // NaCl sandboxing requires that indirect call instructions are masked.
401  // This means that function entry points should be bundle-aligned.
402  if (Subtarget->isTargetNaCl())
404 
405  if (Subtarget->inMicroMipsMode()) {
407  TS.setUsesMicroMips();
409  } else
411 
412  if (Subtarget->inMips16Mode())
414  else
416 
418  OutStreamer->EmitLabel(CurrentFnSym);
419 }
420 
421 /// EmitFunctionBodyStart - Targets can override this to emit stuff before
422 /// the first basic block in the function.
424  MipsTargetStreamer &TS = getTargetStreamer();
425 
427 
428  bool IsNakedFunction = MF->getFunction().hasFnAttribute(Attribute::Naked);
429  if (!IsNakedFunction)
431 
432  if (!IsNakedFunction)
434 
435  if (!Subtarget->inMips16Mode()) {
439  }
440 }
441 
442 /// EmitFunctionBodyEnd - Targets can override this to emit stuff after
443 /// the last basic block in the function.
445  MipsTargetStreamer &TS = getTargetStreamer();
446 
447  // There are instruction for this macros, but they must
448  // always be at the function end, and we can't emit and
449  // break with BB logic.
450  if (!Subtarget->inMips16Mode()) {
451  TS.emitDirectiveSetAt();
454  }
456  // Make sure to terminate any constant pools that were at the end
457  // of the function.
458  if (!InConstantPool)
459  return;
460  InConstantPool = false;
461  OutStreamer->EmitDataRegion(MCDR_DataRegionEnd);
462 }
463 
466  MipsTargetStreamer &TS = getTargetStreamer();
467  if (MBB.empty())
468  TS.emitDirectiveInsn();
469 }
470 
471 /// isBlockOnlyReachableByFallthough - Return true if the basic block has
472 /// exactly one predecessor and the control transfer mechanism between
473 /// the predecessor and this block is a fall-through.
475  MBB) const {
476  // The predecessor has to be immediately before this block.
477  const MachineBasicBlock *Pred = *MBB->pred_begin();
478 
479  // If the predecessor is a switch statement, assume a jump table
480  // implementation, so it is not a fall through.
481  if (const BasicBlock *bb = Pred->getBasicBlock())
482  if (isa<SwitchInst>(bb->getTerminator()))
483  return false;
484 
485  // If this is a landing pad, it isn't a fall through. If it has no preds,
486  // then nothing falls through to it.
487  if (MBB->isEHPad() || MBB->pred_empty())
488  return false;
489 
490  // If there isn't exactly one predecessor, it can't be a fall through.
492  ++PI2;
493 
494  if (PI2 != MBB->pred_end())
495  return false;
496 
497  // The predecessor has to be immediately before this block.
498  if (!Pred->isLayoutSuccessor(MBB))
499  return false;
500 
501  // If the block is completely empty, then it definitely does fall through.
502  if (Pred->empty())
503  return true;
504 
505  // Otherwise, check the last instruction.
506  // Check if the last terminator is an unconditional branch.
508  while (I != Pred->begin() && !(--I)->isTerminator()) ;
509 
510  return !I->isBarrier();
511 }
512 
513 // Print out an operand for an inline asm expression.
514 bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
515  const char *ExtraCode, raw_ostream &O) {
516  // Does this asm operand have a single letter operand modifier?
517  if (ExtraCode && ExtraCode[0]) {
518  if (ExtraCode[1] != 0) return true; // Unknown modifier.
519 
520  const MachineOperand &MO = MI->getOperand(OpNum);
521  switch (ExtraCode[0]) {
522  default:
523  // See if this is a generic print operand
524  return AsmPrinter::PrintAsmOperand(MI, OpNum, ExtraCode, O);
525  case 'X': // hex const int
527  return true;
528  O << "0x" << Twine::utohexstr(MO.getImm());
529  return false;
530  case 'x': // hex const int (low 16 bits)
532  return true;
533  O << "0x" << Twine::utohexstr(MO.getImm() & 0xffff);
534  return false;
535  case 'd': // decimal const int
537  return true;
538  O << MO.getImm();
539  return false;
540  case 'm': // decimal const int minus 1
542  return true;
543  O << MO.getImm() - 1;
544  return false;
545  case 'y': // exact log2
547  return true;
548  if (!isPowerOf2_64(MO.getImm()))
549  return true;
550  O << Log2_64(MO.getImm());
551  return false;
552  case 'z':
553  // $0 if zero, regular printing otherwise
554  if (MO.getType() == MachineOperand::MO_Immediate && MO.getImm() == 0) {
555  O << "$0";
556  return false;
557  }
558  // If not, call printOperand as normal.
559  break;
560  case 'D': // Second part of a double word register operand
561  case 'L': // Low order register of a double word register operand
562  case 'M': // High order register of a double word register operand
563  {
564  if (OpNum == 0)
565  return true;
566  const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1);
567  if (!FlagsOP.isImm())
568  return true;
569  unsigned Flags = FlagsOP.getImm();
570  unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags);
571  // Number of registers represented by this operand. We are looking
572  // for 2 for 32 bit mode and 1 for 64 bit mode.
573  if (NumVals != 2) {
574  if (Subtarget->isGP64bit() && NumVals == 1 && MO.isReg()) {
575  Register Reg = MO.getReg();
576  O << '$' << MipsInstPrinter::getRegisterName(Reg);
577  return false;
578  }
579  return true;
580  }
581 
582  unsigned RegOp = OpNum;
583  if (!Subtarget->isGP64bit()){
584  // Endianness reverses which register holds the high or low value
585  // between M and L.
586  switch(ExtraCode[0]) {
587  case 'M':
588  RegOp = (Subtarget->isLittle()) ? OpNum + 1 : OpNum;
589  break;
590  case 'L':
591  RegOp = (Subtarget->isLittle()) ? OpNum : OpNum + 1;
592  break;
593  case 'D': // Always the second part
594  RegOp = OpNum + 1;
595  }
596  if (RegOp >= MI->getNumOperands())
597  return true;
598  const MachineOperand &MO = MI->getOperand(RegOp);
599  if (!MO.isReg())
600  return true;
601  Register Reg = MO.getReg();
602  O << '$' << MipsInstPrinter::getRegisterName(Reg);
603  return false;
604  }
605  break;
606  }
607  case 'w':
608  // Print MSA registers for the 'f' constraint
609  // In LLVM, the 'w' modifier doesn't need to do anything.
610  // We can just call printOperand as normal.
611  break;
612  }
613  }
614 
615  printOperand(MI, OpNum, O);
616  return false;
617 }
618 
620  unsigned OpNum,
621  const char *ExtraCode,
622  raw_ostream &O) {
623  assert(OpNum + 1 < MI->getNumOperands() && "Insufficient operands");
624  const MachineOperand &BaseMO = MI->getOperand(OpNum);
625  const MachineOperand &OffsetMO = MI->getOperand(OpNum + 1);
626  assert(BaseMO.isReg() && "Unexpected base pointer for inline asm memory operand.");
627  assert(OffsetMO.isImm() && "Unexpected offset for inline asm memory operand.");
628  int Offset = OffsetMO.getImm();
629 
630  // Currently we are expecting either no ExtraCode or 'D','M','L'.
631  if (ExtraCode) {
632  switch (ExtraCode[0]) {
633  case 'D':
634  Offset += 4;
635  break;
636  case 'M':
637  if (Subtarget->isLittle())
638  Offset += 4;
639  break;
640  case 'L':
641  if (!Subtarget->isLittle())
642  Offset += 4;
643  break;
644  default:
645  return true; // Unknown modifier.
646  }
647  }
648 
649  O << Offset << "($" << MipsInstPrinter::getRegisterName(BaseMO.getReg())
650  << ")";
651 
652  return false;
653 }
654 
655 void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
656  raw_ostream &O) {
657  const MachineOperand &MO = MI->getOperand(opNum);
658  bool closeP = false;
659 
660  if (MO.getTargetFlags())
661  closeP = true;
662 
663  switch(MO.getTargetFlags()) {
664  case MipsII::MO_GPREL: O << "%gp_rel("; break;
665  case MipsII::MO_GOT_CALL: O << "%call16("; break;
666  case MipsII::MO_GOT: O << "%got("; break;
667  case MipsII::MO_ABS_HI: O << "%hi("; break;
668  case MipsII::MO_ABS_LO: O << "%lo("; break;
669  case MipsII::MO_HIGHER: O << "%higher("; break;
670  case MipsII::MO_HIGHEST: O << "%highest(("; break;
671  case MipsII::MO_TLSGD: O << "%tlsgd("; break;
672  case MipsII::MO_GOTTPREL: O << "%gottprel("; break;
673  case MipsII::MO_TPREL_HI: O << "%tprel_hi("; break;
674  case MipsII::MO_TPREL_LO: O << "%tprel_lo("; break;
675  case MipsII::MO_GPOFF_HI: O << "%hi(%neg(%gp_rel("; break;
676  case MipsII::MO_GPOFF_LO: O << "%lo(%neg(%gp_rel("; break;
677  case MipsII::MO_GOT_DISP: O << "%got_disp("; break;
678  case MipsII::MO_GOT_PAGE: O << "%got_page("; break;
679  case MipsII::MO_GOT_OFST: O << "%got_ofst("; break;
680  }
681 
682  switch (MO.getType()) {
684  O << '$'
686  break;
687 
689  O << MO.getImm();
690  break;
691 
693  MO.getMBB()->getSymbol()->print(O, MAI);
694  return;
695 
697  PrintSymbolOperand(MO, O);
698  break;
699 
702  O << BA->getName();
703  break;
704  }
705 
707  O << getDataLayout().getPrivateGlobalPrefix() << "CPI"
708  << getFunctionNumber() << "_" << MO.getIndex();
709  if (MO.getOffset())
710  O << "+" << MO.getOffset();
711  break;
712 
713  default:
714  llvm_unreachable("<unknown operand type>");
715  }
716 
717  if (closeP) O << ")";
718 }
719 
720 void MipsAsmPrinter::
721 printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O) {
722  // Load/Store memory operands -- imm($reg)
723  // If PIC target the target is loaded as the
724  // pattern lw $25,%call16($28)
725 
726  // opNum can be invalid if instruction has reglist as operand.
727  // MemOperand is always last operand of instruction (base + offset).
728  switch (MI->getOpcode()) {
729  default:
730  break;
731  case Mips::SWM32_MM:
732  case Mips::LWM32_MM:
733  opNum = MI->getNumOperands() - 2;
734  break;
735  }
736 
737  printOperand(MI, opNum+1, O);
738  O << "(";
739  printOperand(MI, opNum, O);
740  O << ")";
741 }
742 
743 void MipsAsmPrinter::
744 printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O) {
745  // when using stack locations for not load/store instructions
746  // print the same way as all normal 3 operand instructions.
747  printOperand(MI, opNum, O);
748  O << ", ";
749  printOperand(MI, opNum+1, O);
750 }
751 
752 void MipsAsmPrinter::
753 printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
754  const char *Modifier) {
755  const MachineOperand &MO = MI->getOperand(opNum);
757 }
758 
759 void MipsAsmPrinter::
760 printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O) {
761  for (int i = opNum, e = MI->getNumOperands(); i != e; ++i) {
762  if (i != opNum) O << ", ";
763  printOperand(MI, i, O);
764  }
765 }
766 
768  MipsTargetStreamer &TS = getTargetStreamer();
769 
770  // MipsTargetStreamer has an initialization order problem when emitting an
771  // object file directly (see MipsTargetELFStreamer for full details). Work
772  // around it by re-initializing the PIC state here.
774 
775  // Compute MIPS architecture attributes based on the default subtarget
776  // that we'd have constructed. Module level directives aren't LTO
777  // clean anyhow.
778  // FIXME: For ifunc related functions we could iterate over and look
779  // for a feature string that doesn't match the default one.
780  const Triple &TT = TM.getTargetTriple();
783  const MipsTargetMachine &MTM = static_cast<const MipsTargetMachine &>(TM);
784  const MipsSubtarget STI(TT, CPU, FS, MTM.isLittleEndian(), MTM, None);
785 
786  bool IsABICalls = STI.isABICalls();
787  const MipsABIInfo &ABI = MTM.getABI();
788  if (IsABICalls) {
790  // FIXME: This condition should be a lot more complicated that it is here.
791  // Ideally it should test for properties of the ABI and not the ABI
792  // itself.
793  // For the moment, I'm only correcting enough to make MIPS-IV work.
794  if (!isPositionIndependent() && STI.hasSym32())
796  }
797 
798  // Tell the assembler which ABI we are using
799  std::string SectionName = std::string(".mdebug.") + getCurrentABIString();
800  OutStreamer->SwitchSection(
801  OutContext.getELFSection(SectionName, ELF::SHT_PROGBITS, 0));
802 
803  // NaN: At the moment we only support:
804  // 1. .nan legacy (default)
805  // 2. .nan 2008
806  STI.isNaN2008() ? TS.emitDirectiveNaN2008()
807  : TS.emitDirectiveNaNLegacy();
808 
809  // TODO: handle O64 ABI
810 
811  TS.updateABIInfo(STI);
812 
813  // We should always emit a '.module fp=...' but binutils 2.24 does not accept
814  // it. We therefore emit it when it contradicts the ABI defaults (-mfpxx or
815  // -mfp64) and omit it otherwise.
816  if ((ABI.IsO32() && (STI.isABI_FPXX() || STI.isFP64bit())) ||
817  STI.useSoftFloat())
819 
820  // We should always emit a '.module [no]oddspreg' but binutils 2.24 does not
821  // accept it. We therefore emit it when it contradicts the default or an
822  // option has changed the default (i.e. FPXX) and omit it otherwise.
823  if (ABI.IsO32() && (!STI.useOddSPReg() || STI.isABI_FPXX()))
825 
826  // Switch to the .text section.
827  OutStreamer->SwitchSection(getObjFileLowering().getTextSection());
828 }
829 
830 void MipsAsmPrinter::emitInlineAsmStart() const {
831  MipsTargetStreamer &TS = getTargetStreamer();
832 
833  // GCC's choice of assembler options for inline assembly code ('at', 'macro'
834  // and 'reorder') is different from LLVM's choice for generated code ('noat',
835  // 'nomacro' and 'noreorder').
836  // In order to maintain compatibility with inline assembly code which depends
837  // on GCC's assembler options being used, we have to switch to those options
838  // for the duration of the inline assembly block and then switch back.
840  TS.emitDirectiveSetAt();
843  OutStreamer->AddBlankLine();
844 }
845 
846 void MipsAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
847  const MCSubtargetInfo *EndInfo) const {
848  OutStreamer->AddBlankLine();
849  getTargetStreamer().emitDirectiveSetPop();
850 }
851 
852 void MipsAsmPrinter::EmitJal(const MCSubtargetInfo &STI, MCSymbol *Symbol) {
853  MCInst I;
854  I.setOpcode(Mips::JAL);
855  I.addOperand(
857  OutStreamer->EmitInstruction(I, STI);
858 }
859 
860 void MipsAsmPrinter::EmitInstrReg(const MCSubtargetInfo &STI, unsigned Opcode,
861  unsigned Reg) {
862  MCInst I;
863  I.setOpcode(Opcode);
865  OutStreamer->EmitInstruction(I, STI);
866 }
867 
868 void MipsAsmPrinter::EmitInstrRegReg(const MCSubtargetInfo &STI,
869  unsigned Opcode, unsigned Reg1,
870  unsigned Reg2) {
871  MCInst I;
872  //
873  // Because of the current td files for Mips32, the operands for MTC1
874  // appear backwards from their normal assembly order. It's not a trivial
875  // change to fix this in the td file so we adjust for it here.
876  //
877  if (Opcode == Mips::MTC1) {
878  unsigned Temp = Reg1;
879  Reg1 = Reg2;
880  Reg2 = Temp;
881  }
882  I.setOpcode(Opcode);
885  OutStreamer->EmitInstruction(I, STI);
886 }
887 
888 void MipsAsmPrinter::EmitInstrRegRegReg(const MCSubtargetInfo &STI,
889  unsigned Opcode, unsigned Reg1,
890  unsigned Reg2, unsigned Reg3) {
891  MCInst I;
892  I.setOpcode(Opcode);
896  OutStreamer->EmitInstruction(I, STI);
897 }
898 
899 void MipsAsmPrinter::EmitMovFPIntPair(const MCSubtargetInfo &STI,
900  unsigned MovOpc, unsigned Reg1,
901  unsigned Reg2, unsigned FPReg1,
902  unsigned FPReg2, bool LE) {
903  if (!LE) {
904  unsigned temp = Reg1;
905  Reg1 = Reg2;
906  Reg2 = temp;
907  }
908  EmitInstrRegReg(STI, MovOpc, Reg1, FPReg1);
909  EmitInstrRegReg(STI, MovOpc, Reg2, FPReg2);
910 }
911 
912 void MipsAsmPrinter::EmitSwapFPIntParams(const MCSubtargetInfo &STI,
914  bool LE, bool ToFP) {
915  using namespace Mips16HardFloatInfo;
916 
917  unsigned MovOpc = ToFP ? Mips::MTC1 : Mips::MFC1;
918  switch (PV) {
919  case FSig:
920  EmitInstrRegReg(STI, MovOpc, Mips::A0, Mips::F12);
921  break;
922  case FFSig:
923  EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F14, LE);
924  break;
925  case FDSig:
926  EmitInstrRegReg(STI, MovOpc, Mips::A0, Mips::F12);
927  EmitMovFPIntPair(STI, MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE);
928  break;
929  case DSig:
930  EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
931  break;
932  case DDSig:
933  EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
934  EmitMovFPIntPair(STI, MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE);
935  break;
936  case DFSig:
937  EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
938  EmitInstrRegReg(STI, MovOpc, Mips::A2, Mips::F14);
939  break;
940  case NoSig:
941  return;
942  }
943 }
944 
945 void MipsAsmPrinter::EmitSwapFPIntRetval(
947  bool LE) {
948  using namespace Mips16HardFloatInfo;
949 
950  unsigned MovOpc = Mips::MFC1;
951  switch (RV) {
952  case FRet:
953  EmitInstrRegReg(STI, MovOpc, Mips::V0, Mips::F0);
954  break;
955  case DRet:
956  EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
957  break;
958  case CFRet:
959  EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
960  break;
961  case CDRet:
962  EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
963  EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F2, Mips::F3, LE);
964  break;
965  case NoFPRet:
966  break;
967  }
968 }
969 
970 void MipsAsmPrinter::EmitFPCallStub(
971  const char *Symbol, const Mips16HardFloatInfo::FuncSignature *Signature) {
972  using namespace Mips16HardFloatInfo;
973 
974  MCSymbol *MSymbol = OutContext.getOrCreateSymbol(StringRef(Symbol));
975  bool LE = getDataLayout().isLittleEndian();
976  // Construct a local MCSubtargetInfo here.
977  // This is because the MachineFunction won't exist (but have not yet been
978  // freed) and since we're at the global level we can use the default
979  // constructed subtarget.
980  std::unique_ptr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo(
983 
984  //
985  // .global xxxx
986  //
987  OutStreamer->EmitSymbolAttribute(MSymbol, MCSA_Global);
988  const char *RetType;
989  //
990  // make the comment field identifying the return and parameter
991  // types of the floating point stub
992  // # Stub function to call rettype xxxx (params)
993  //
994  switch (Signature->RetSig) {
995  case FRet:
996  RetType = "float";
997  break;
998  case DRet:
999  RetType = "double";
1000  break;
1001  case CFRet:
1002  RetType = "complex";
1003  break;
1004  case CDRet:
1005  RetType = "double complex";
1006  break;
1007  case NoFPRet:
1008  RetType = "";
1009  break;
1010  }
1011  const char *Parms;
1012  switch (Signature->ParamSig) {
1013  case FSig:
1014  Parms = "float";
1015  break;
1016  case FFSig:
1017  Parms = "float, float";
1018  break;
1019  case FDSig:
1020  Parms = "float, double";
1021  break;
1022  case DSig:
1023  Parms = "double";
1024  break;
1025  case DDSig:
1026  Parms = "double, double";
1027  break;
1028  case DFSig:
1029  Parms = "double, float";
1030  break;
1031  case NoSig:
1032  Parms = "";
1033  break;
1034  }
1035  OutStreamer->AddComment("\t# Stub function to call " + Twine(RetType) + " " +
1036  Twine(Symbol) + " (" + Twine(Parms) + ")");
1037  //
1038  // probably not necessary but we save and restore the current section state
1039  //
1040  OutStreamer->PushSection();
1041  //
1042  // .section mips16.call.fpxxxx,"ax",@progbits
1043  //
1045  ".mips16.call.fp." + std::string(Symbol), ELF::SHT_PROGBITS,
1047  OutStreamer->SwitchSection(M, nullptr);
1048  //
1049  // .align 2
1050  //
1051  OutStreamer->EmitValueToAlignment(4);
1052  MipsTargetStreamer &TS = getTargetStreamer();
1053  //
1054  // .set nomips16
1055  // .set nomicromips
1056  //
1059  //
1060  // .ent __call_stub_fp_xxxx
1061  // .type __call_stub_fp_xxxx,@function
1062  // __call_stub_fp_xxxx:
1063  //
1064  std::string x = "__call_stub_fp_" + std::string(Symbol);
1065  MCSymbolELF *Stub =
1066  cast<MCSymbolELF>(OutContext.getOrCreateSymbol(StringRef(x)));
1067  TS.emitDirectiveEnt(*Stub);
1068  MCSymbol *MType =
1069  OutContext.getOrCreateSymbol("__call_stub_fp_" + Twine(Symbol));
1070  OutStreamer->EmitSymbolAttribute(MType, MCSA_ELF_TypeFunction);
1071  OutStreamer->EmitLabel(Stub);
1072 
1073  // Only handle non-pic for now.
1075  "should not be here if we are compiling pic");
1077  //
1078  // We need to add a MipsMCExpr class to MCTargetDesc to fully implement
1079  // stubs without raw text but this current patch is for compiler generated
1080  // functions and they all return some value.
1081  // The calling sequence for non pic is different in that case and we need
1082  // to implement %lo and %hi in order to handle the case of no return value
1083  // See the corresponding method in Mips16HardFloat for details.
1084  //
1085  // mov the return address to S2.
1086  // we have no stack space to store it and we are about to make another call.
1087  // We need to make sure that the enclosing function knows to save S2
1088  // This should have already been handled.
1089  //
1090  // Mov $18, $31
1091 
1092  EmitInstrRegRegReg(*STI, Mips::OR, Mips::S2, Mips::RA, Mips::ZERO);
1093 
1094  EmitSwapFPIntParams(*STI, Signature->ParamSig, LE, true);
1095 
1096  // Jal xxxx
1097  //
1098  EmitJal(*STI, MSymbol);
1099 
1100  // fix return values
1101  EmitSwapFPIntRetval(*STI, Signature->RetSig, LE);
1102  //
1103  // do the return
1104  // if (Signature->RetSig == NoFPRet)
1105  // llvm_unreachable("should not be any stubs here with no return value");
1106  // else
1107  EmitInstrReg(*STI, Mips::JR, Mips::S2);
1108 
1110  OutStreamer->EmitLabel(Tmp);
1113  const MCExpr *T_min_E = MCBinaryExpr::createSub(T, E, OutContext);
1114  OutStreamer->emitELFSize(Stub, T_min_E);
1115  TS.emitDirectiveEnd(x);
1116  OutStreamer->PopSection();
1117 }
1118 
1120  // Emit needed stubs
1121  //
1122  for (std::map<
1123  const char *,
1124  const Mips16HardFloatInfo::FuncSignature *>::const_iterator
1125  it = StubsNeeded.begin();
1126  it != StubsNeeded.end(); ++it) {
1127  const char *Symbol = it->first;
1128  const Mips16HardFloatInfo::FuncSignature *Signature = it->second;
1129  EmitFPCallStub(Symbol, Signature);
1130  }
1131  // return to the text section
1133 }
1134 
1135 void MipsAsmPrinter::EmitSled(const MachineInstr &MI, SledKind Kind) {
1136  const uint8_t NoopsInSledCount = Subtarget->isGP64bit() ? 15 : 11;
1137  // For mips32 we want to emit the following pattern:
1138  //
1139  // .Lxray_sled_N:
1140  // ALIGN
1141  // B .tmpN
1142  // 11 NOP instructions (44 bytes)
1143  // ADDIU T9, T9, 52
1144  // .tmpN
1145  //
1146  // We need the 44 bytes (11 instructions) because at runtime, we'd
1147  // be patching over the full 48 bytes (12 instructions) with the following
1148  // pattern:
1149  //
1150  // ADDIU SP, SP, -8
1151  // NOP
1152  // SW RA, 4(SP)
1153  // SW T9, 0(SP)
1154  // LUI T9, %hi(__xray_FunctionEntry/Exit)
1155  // ORI T9, T9, %lo(__xray_FunctionEntry/Exit)
1156  // LUI T0, %hi(function_id)
1157  // JALR T9
1158  // ORI T0, T0, %lo(function_id)
1159  // LW T9, 0(SP)
1160  // LW RA, 4(SP)
1161  // ADDIU SP, SP, 8
1162  //
1163  // We add 52 bytes to t9 because we want to adjust the function pointer to
1164  // the actual start of function i.e. the address just after the noop sled.
1165  // We do this because gp displacement relocation is emitted at the start of
1166  // of the function i.e after the nop sled and to correctly calculate the
1167  // global offset table address, t9 must hold the address of the instruction
1168  // containing the gp displacement relocation.
1169  // FIXME: Is this correct for the static relocation model?
1170  //
1171  // For mips64 we want to emit the following pattern:
1172  //
1173  // .Lxray_sled_N:
1174  // ALIGN
1175  // B .tmpN
1176  // 15 NOP instructions (60 bytes)
1177  // .tmpN
1178  //
1179  // We need the 60 bytes (15 instructions) because at runtime, we'd
1180  // be patching over the full 64 bytes (16 instructions) with the following
1181  // pattern:
1182  //
1183  // DADDIU SP, SP, -16
1184  // NOP
1185  // SD RA, 8(SP)
1186  // SD T9, 0(SP)
1187  // LUI T9, %highest(__xray_FunctionEntry/Exit)
1188  // ORI T9, T9, %higher(__xray_FunctionEntry/Exit)
1189  // DSLL T9, T9, 16
1190  // ORI T9, T9, %hi(__xray_FunctionEntry/Exit)
1191  // DSLL T9, T9, 16
1192  // ORI T9, T9, %lo(__xray_FunctionEntry/Exit)
1193  // LUI T0, %hi(function_id)
1194  // JALR T9
1195  // ADDIU T0, T0, %lo(function_id)
1196  // LD T9, 0(SP)
1197  // LD RA, 8(SP)
1198  // DADDIU SP, SP, 16
1199  //
1200  OutStreamer->EmitCodeAlignment(4);
1201  auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
1202  OutStreamer->EmitLabel(CurSled);
1204 
1205  // Emit "B .tmpN" instruction, which jumps over the nop sled to the actual
1206  // start of function
1207  const MCExpr *TargetExpr = MCSymbolRefExpr::create(
1208  Target, MCSymbolRefExpr::VariantKind::VK_None, OutContext);
1209  EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::BEQ)
1210  .addReg(Mips::ZERO)
1211  .addReg(Mips::ZERO)
1212  .addExpr(TargetExpr));
1213 
1214  for (int8_t I = 0; I < NoopsInSledCount; I++)
1215  EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::SLL)
1216  .addReg(Mips::ZERO)
1217  .addReg(Mips::ZERO)
1218  .addImm(0));
1219 
1220  OutStreamer->EmitLabel(Target);
1221 
1222  if (!Subtarget->isGP64bit()) {
1223  EmitToStreamer(*OutStreamer,
1224  MCInstBuilder(Mips::ADDiu)
1225  .addReg(Mips::T9)
1226  .addReg(Mips::T9)
1227  .addImm(0x34));
1228  }
1229 
1230  recordSled(CurSled, MI, Kind);
1231 }
1232 
1234  EmitSled(MI, SledKind::FUNCTION_ENTER);
1235 }
1236 
1238  EmitSled(MI, SledKind::FUNCTION_EXIT);
1239 }
1240 
1242  EmitSled(MI, SledKind::TAIL_CALL);
1243 }
1244 
1246  raw_ostream &OS) {
1247  // TODO: implement
1248 }
1249 
1250 // Emit .dtprelword or .dtpreldword directive
1251 // and value for debug thread local expression.
1252 void MipsAsmPrinter::EmitDebugValue(const MCExpr *Value, unsigned Size) const {
1253  if (auto *MipsExpr = dyn_cast<MipsMCExpr>(Value)) {
1254  if (MipsExpr && MipsExpr->getKind() == MipsMCExpr::MEK_DTPREL) {
1255  switch (Size) {
1256  case 4:
1257  OutStreamer->EmitDTPRel32Value(MipsExpr->getSubExpr());
1258  break;
1259  case 8:
1260  OutStreamer->EmitDTPRel64Value(MipsExpr->getSubExpr());
1261  break;
1262  default:
1263  llvm_unreachable("Unexpected size of expression value.");
1264  }
1265  return;
1266  }
1267  }
1268  AsmPrinter::EmitDebugValue(Value, Size);
1269 }
1270 
1271 // Align all targets of indirect branches on bundle size. Used only if target
1272 // is NaCl.
1273 void MipsAsmPrinter::NaClAlignIndirectJumpTargets(MachineFunction &MF) {
1274  // Align all blocks that are jumped to through jump table.
1275  if (MachineJumpTableInfo *JtInfo = MF.getJumpTableInfo()) {
1276  const std::vector<MachineJumpTableEntry> &JT = JtInfo->getJumpTables();
1277  for (unsigned I = 0; I < JT.size(); ++I) {
1278  const std::vector<MachineBasicBlock*> &MBBs = JT[I].MBBs;
1279 
1280  for (unsigned J = 0; J < MBBs.size(); ++J)
1281  MBBs[J]->setAlignment(MIPS_NACL_BUNDLE_ALIGN);
1282  }
1283  }
1284 
1285  // If basic block address is taken, block can be target of indirect branch.
1286  for (auto &MBB : MF) {
1287  if (MBB.hasAddressTaken())
1288  MBB.setAlignment(MIPS_NACL_BUNDLE_ALIGN);
1289  }
1290 }
1291 
1292 bool MipsAsmPrinter::isLongBranchPseudo(int Opcode) const {
1293  return (Opcode == Mips::LONG_BRANCH_LUi
1294  || Opcode == Mips::LONG_BRANCH_LUi2Op
1295  || Opcode == Mips::LONG_BRANCH_LUi2Op_64
1296  || Opcode == Mips::LONG_BRANCH_ADDiu
1297  || Opcode == Mips::LONG_BRANCH_ADDiu2Op
1298  || Opcode == Mips::LONG_BRANCH_DADDiu
1299  || Opcode == Mips::LONG_BRANCH_DADDiu2Op);
1300 }
1301 
1302 // Force static initialization.
1303 extern "C" void LLVMInitializeMipsAsmPrinter() {
1308 }
unsigned getTargetFlags() const
MachineConstantPoolValue * MachineCPVal
virtual void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff)
bool isABICalls() const
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
Definition: AsmPrinter.cpp:216
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...
static const Align MIPS_NACL_BUNDLE_ALIGN
Definition: MipsMCNaCl.h:18
bool isDebugLabel() const
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
union llvm::MachineConstantPoolEntry::@168 Val
The constant itself.
bool isCall(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:657
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:329
This class represents lattice values for constants.
Definition: AllocatorList.h:23
StringRef getPrivateGlobalPrefix() const
Definition: DataLayout.h:321
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
Align getAlignment() const
getAlignment - Return the alignment of the function.
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: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 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:176
virtual void emitDirectiveSetNoReorder()
void EmitAlignment(Align Alignment, const GlobalObject *GV=nullptr) const
Emit an alignment directive to the specified power of two boundary.
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: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:649
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:226
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...
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:140
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:311
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:687
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
Definition: AsmPrinter.h:299
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:552
bool isPositionIndependent() const
Definition: AsmPrinter.cpp:207
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:647
MCContext & getContext() const
Address of a global value.
Streaming machine code generation interface.
Definition: MCStreamer.h:190
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()
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:470
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.
constexpr double e
Definition: MathExtras.h:57
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: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:212
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
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:390
virtual void emitDirectiveOptionPic0()
bool isDebugValue() const
MachineOperand class - Representation of each machine instruction operand.
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:977
const MCSubtargetInfo * getMCSubtargetInfo() const
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
Definition: AsmPrinter.cpp:235
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
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:180
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:376
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:74
virtual void emitDirectiveNaNLegacy()
virtual void EmitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:399
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:220
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:591
.end_data_region
Definition: MCDirectives.h:62
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