Home | History | Annotate | Download | only in Mips
      1 //===-- MipsAsmPrinter.cpp - Mips LLVM Assembly Printer -------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file contains a printer that converts from our internal representation
     11 // of machine-dependent LLVM code to GAS-format MIPS assembly language.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "InstPrinter/MipsInstPrinter.h"
     16 #include "MCTargetDesc/MipsBaseInfo.h"
     17 #include "MCTargetDesc/MipsMCNaCl.h"
     18 #include "Mips.h"
     19 #include "MipsAsmPrinter.h"
     20 #include "MipsInstrInfo.h"
     21 #include "MipsMCInstLower.h"
     22 #include "MipsTargetMachine.h"
     23 #include "MipsTargetStreamer.h"
     24 #include "llvm/ADT/SmallString.h"
     25 #include "llvm/ADT/Twine.h"
     26 #include "llvm/CodeGen/MachineConstantPool.h"
     27 #include "llvm/CodeGen/MachineFrameInfo.h"
     28 #include "llvm/CodeGen/MachineFunctionPass.h"
     29 #include "llvm/CodeGen/MachineInstr.h"
     30 #include "llvm/CodeGen/MachineJumpTableInfo.h"
     31 #include "llvm/CodeGen/MachineMemOperand.h"
     32 #include "llvm/IR/BasicBlock.h"
     33 #include "llvm/IR/DataLayout.h"
     34 #include "llvm/IR/InlineAsm.h"
     35 #include "llvm/IR/Instructions.h"
     36 #include "llvm/IR/Mangler.h"
     37 #include "llvm/MC/MCAsmInfo.h"
     38 #include "llvm/MC/MCContext.h"
     39 #include "llvm/MC/MCELFStreamer.h"
     40 #include "llvm/MC/MCExpr.h"
     41 #include "llvm/MC/MCInst.h"
     42 #include "llvm/MC/MCSection.h"
     43 #include "llvm/MC/MCSectionELF.h"
     44 #include "llvm/MC/MCSymbolELF.h"
     45 #include "llvm/Support/ELF.h"
     46 #include "llvm/Support/TargetRegistry.h"
     47 #include "llvm/Support/raw_ostream.h"
     48 #include "llvm/Target/TargetLoweringObjectFile.h"
     49 #include "llvm/Target/TargetOptions.h"
     50 #include <string>
     51 
     52 using namespace llvm;
     53 
     54 #define DEBUG_TYPE "mips-asm-printer"
     55 
     56 MipsTargetStreamer &MipsAsmPrinter::getTargetStreamer() const {
     57   return static_cast<MipsTargetStreamer &>(*OutStreamer->getTargetStreamer());
     58 }
     59 
     60 bool MipsAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
     61   Subtarget = &MF.getSubtarget<MipsSubtarget>();
     62 
     63   // Initialize TargetLoweringObjectFile.
     64   const_cast<TargetLoweringObjectFile &>(getObjFileLowering())
     65       .Initialize(OutContext, TM);
     66 
     67   MipsFI = MF.getInfo<MipsFunctionInfo>();
     68   if (Subtarget->inMips16Mode())
     69     for (std::map<
     70              const char *,
     71              const llvm::Mips16HardFloatInfo::FuncSignature *>::const_iterator
     72              it = MipsFI->StubsNeeded.begin();
     73          it != MipsFI->StubsNeeded.end(); ++it) {
     74       const char *Symbol = it->first;
     75       const llvm::Mips16HardFloatInfo::FuncSignature *Signature = it->second;
     76       if (StubsNeeded.find(Symbol) == StubsNeeded.end())
     77         StubsNeeded[Symbol] = Signature;
     78     }
     79   MCP = MF.getConstantPool();
     80 
     81   // In NaCl, all indirect jump targets must be aligned to bundle size.
     82   if (Subtarget->isTargetNaCl())
     83     NaClAlignIndirectJumpTargets(MF);
     84 
     85   AsmPrinter::runOnMachineFunction(MF);
     86   return true;
     87 }
     88 
     89 bool MipsAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) {
     90   MCOp = MCInstLowering.LowerOperand(MO);
     91   return MCOp.isValid();
     92 }
     93 
     94 #include "MipsGenMCPseudoLowering.inc"
     95 
     96 // Lower PseudoReturn/PseudoIndirectBranch/PseudoIndirectBranch64 to JR, JR_MM,
     97 // JALR, or JALR64 as appropriate for the target
     98 void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer,
     99                                               const MachineInstr *MI) {
    100   bool HasLinkReg = false;
    101   MCInst TmpInst0;
    102 
    103   if (Subtarget->hasMips64r6()) {
    104     // MIPS64r6 should use (JALR64 ZERO_64, $rs)
    105     TmpInst0.setOpcode(Mips::JALR64);
    106     HasLinkReg = true;
    107   } else if (Subtarget->hasMips32r6()) {
    108     // MIPS32r6 should use (JALR ZERO, $rs)
    109     TmpInst0.setOpcode(Mips::JALR);
    110     HasLinkReg = true;
    111   } else if (Subtarget->inMicroMipsMode())
    112     // microMIPS should use (JR_MM $rs)
    113     TmpInst0.setOpcode(Mips::JR_MM);
    114   else {
    115     // Everything else should use (JR $rs)
    116     TmpInst0.setOpcode(Mips::JR);
    117   }
    118 
    119   MCOperand MCOp;
    120 
    121   if (HasLinkReg) {
    122     unsigned ZeroReg = Subtarget->isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
    123     TmpInst0.addOperand(MCOperand::createReg(ZeroReg));
    124   }
    125 
    126   lowerOperand(MI->getOperand(0), MCOp);
    127   TmpInst0.addOperand(MCOp);
    128 
    129   EmitToStreamer(OutStreamer, TmpInst0);
    130 }
    131 
    132 void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
    133   MipsTargetStreamer &TS = getTargetStreamer();
    134   TS.forbidModuleDirective();
    135 
    136   if (MI->isDebugValue()) {
    137     SmallString<128> Str;
    138     raw_svector_ostream OS(Str);
    139 
    140     PrintDebugValueComment(MI, OS);
    141     return;
    142   }
    143 
    144   // If we just ended a constant pool, mark it as such.
    145   if (InConstantPool && MI->getOpcode() != Mips::CONSTPOOL_ENTRY) {
    146     OutStreamer->EmitDataRegion(MCDR_DataRegionEnd);
    147     InConstantPool = false;
    148   }
    149   if (MI->getOpcode() == Mips::CONSTPOOL_ENTRY) {
    150     // CONSTPOOL_ENTRY - This instruction represents a floating
    151     //constant pool in the function.  The first operand is the ID#
    152     // for this instruction, the second is the index into the
    153     // MachineConstantPool that this is, the third is the size in
    154     // bytes of this constant pool entry.
    155     // The required alignment is specified on the basic block holding this MI.
    156     //
    157     unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
    158     unsigned CPIdx   = (unsigned)MI->getOperand(1).getIndex();
    159 
    160     // If this is the first entry of the pool, mark it.
    161     if (!InConstantPool) {
    162       OutStreamer->EmitDataRegion(MCDR_DataRegion);
    163       InConstantPool = true;
    164     }
    165 
    166     OutStreamer->EmitLabel(GetCPISymbol(LabelId));
    167 
    168     const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
    169     if (MCPE.isMachineConstantPoolEntry())
    170       EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
    171     else
    172       EmitGlobalConstant(MF->getDataLayout(), MCPE.Val.ConstVal);
    173     return;
    174   }
    175 
    176 
    177   MachineBasicBlock::const_instr_iterator I = MI->getIterator();
    178   MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();
    179 
    180   do {
    181     // Do any auto-generated pseudo lowerings.
    182     if (emitPseudoExpansionLowering(*OutStreamer, &*I))
    183       continue;
    184 
    185     if (I->getOpcode() == Mips::PseudoReturn ||
    186         I->getOpcode() == Mips::PseudoReturn64 ||
    187         I->getOpcode() == Mips::PseudoIndirectBranch ||
    188         I->getOpcode() == Mips::PseudoIndirectBranch64) {
    189       emitPseudoIndirectBranch(*OutStreamer, &*I);
    190       continue;
    191     }
    192 
    193     // The inMips16Mode() test is not permanent.
    194     // Some instructions are marked as pseudo right now which
    195     // would make the test fail for the wrong reason but
    196     // that will be fixed soon. We need this here because we are
    197     // removing another test for this situation downstream in the
    198     // callchain.
    199     //
    200     if (I->isPseudo() && !Subtarget->inMips16Mode()
    201         && !isLongBranchPseudo(I->getOpcode()))
    202       llvm_unreachable("Pseudo opcode found in EmitInstruction()");
    203 
    204     MCInst TmpInst0;
    205     MCInstLowering.Lower(&*I, TmpInst0);
    206     EmitToStreamer(*OutStreamer, TmpInst0);
    207   } while ((++I != E) && I->isInsideBundle()); // Delay slot check
    208 }
    209 
    210 //===----------------------------------------------------------------------===//
    211 //
    212 //  Mips Asm Directives
    213 //
    214 //  -- Frame directive "frame Stackpointer, Stacksize, RARegister"
    215 //  Describe the stack frame.
    216 //
    217 //  -- Mask directives "(f)mask  bitmask, offset"
    218 //  Tells the assembler which registers are saved and where.
    219 //  bitmask - contain a little endian bitset indicating which registers are
    220 //            saved on function prologue (e.g. with a 0x80000000 mask, the
    221 //            assembler knows the register 31 (RA) is saved at prologue.
    222 //  offset  - the position before stack pointer subtraction indicating where
    223 //            the first saved register on prologue is located. (e.g. with a
    224 //
    225 //  Consider the following function prologue:
    226 //
    227 //    .frame  $fp,48,$ra
    228 //    .mask   0xc0000000,-8
    229 //       addiu $sp, $sp, -48
    230 //       sw $ra, 40($sp)
    231 //       sw $fp, 36($sp)
    232 //
    233 //    With a 0xc0000000 mask, the assembler knows the register 31 (RA) and
    234 //    30 (FP) are saved at prologue. As the save order on prologue is from
    235 //    left to right, RA is saved first. A -8 offset means that after the
    236 //    stack pointer subtration, the first register in the mask (RA) will be
    237 //    saved at address 48-8=40.
    238 //
    239 //===----------------------------------------------------------------------===//
    240 
    241 //===----------------------------------------------------------------------===//
    242 // Mask directives
    243 //===----------------------------------------------------------------------===//
    244 
    245 // Create a bitmask with all callee saved registers for CPU or Floating Point
    246 // registers. For CPU registers consider RA, GP and FP for saving if necessary.
    247 void MipsAsmPrinter::printSavedRegsBitmask() {
    248   // CPU and FPU Saved Registers Bitmasks
    249   unsigned CPUBitmask = 0, FPUBitmask = 0;
    250   int CPUTopSavedRegOff, FPUTopSavedRegOff;
    251 
    252   // Set the CPU and FPU Bitmasks
    253   const MachineFrameInfo *MFI = MF->getFrameInfo();
    254   const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
    255   const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
    256   // size of stack area to which FP callee-saved regs are saved.
    257   unsigned CPURegSize = Mips::GPR32RegClass.getSize();
    258   unsigned FGR32RegSize = Mips::FGR32RegClass.getSize();
    259   unsigned AFGR64RegSize = Mips::AFGR64RegClass.getSize();
    260   bool HasAFGR64Reg = false;
    261   unsigned CSFPRegsSize = 0;
    262 
    263   for (const auto &I : CSI) {
    264     unsigned Reg = I.getReg();
    265     unsigned RegNum = TRI->getEncodingValue(Reg);
    266 
    267     // If it's a floating point register, set the FPU Bitmask.
    268     // If it's a general purpose register, set the CPU Bitmask.
    269     if (Mips::FGR32RegClass.contains(Reg)) {
    270       FPUBitmask |= (1 << RegNum);
    271       CSFPRegsSize += FGR32RegSize;
    272     } else if (Mips::AFGR64RegClass.contains(Reg)) {
    273       FPUBitmask |= (3 << RegNum);
    274       CSFPRegsSize += AFGR64RegSize;
    275       HasAFGR64Reg = true;
    276     } else if (Mips::GPR32RegClass.contains(Reg))
    277       CPUBitmask |= (1 << RegNum);
    278   }
    279 
    280   // FP Regs are saved right below where the virtual frame pointer points to.
    281   FPUTopSavedRegOff = FPUBitmask ?
    282     (HasAFGR64Reg ? -AFGR64RegSize : -FGR32RegSize) : 0;
    283 
    284   // CPU Regs are saved below FP Regs.
    285   CPUTopSavedRegOff = CPUBitmask ? -CSFPRegsSize - CPURegSize : 0;
    286 
    287   MipsTargetStreamer &TS = getTargetStreamer();
    288   // Print CPUBitmask
    289   TS.emitMask(CPUBitmask, CPUTopSavedRegOff);
    290 
    291   // Print FPUBitmask
    292   TS.emitFMask(FPUBitmask, FPUTopSavedRegOff);
    293 }
    294 
    295 //===----------------------------------------------------------------------===//
    296 // Frame and Set directives
    297 //===----------------------------------------------------------------------===//
    298 
    299 /// Frame Directive
    300 void MipsAsmPrinter::emitFrameDirective() {
    301   const TargetRegisterInfo &RI = *MF->getSubtarget().getRegisterInfo();
    302 
    303   unsigned stackReg  = RI.getFrameRegister(*MF);
    304   unsigned returnReg = RI.getRARegister();
    305   unsigned stackSize = MF->getFrameInfo()->getStackSize();
    306 
    307   getTargetStreamer().emitFrame(stackReg, stackSize, returnReg);
    308 }
    309 
    310 /// Emit Set directives.
    311 const char *MipsAsmPrinter::getCurrentABIString() const {
    312   switch (static_cast<MipsTargetMachine &>(TM).getABI().GetEnumValue()) {
    313   case MipsABIInfo::ABI::O32:  return "abi32";
    314   case MipsABIInfo::ABI::N32:  return "abiN32";
    315   case MipsABIInfo::ABI::N64:  return "abi64";
    316   case MipsABIInfo::ABI::EABI: return "eabi32"; // TODO: handle eabi64
    317   default: llvm_unreachable("Unknown Mips ABI");
    318   }
    319 }
    320 
    321 void MipsAsmPrinter::EmitFunctionEntryLabel() {
    322   MipsTargetStreamer &TS = getTargetStreamer();
    323 
    324   // NaCl sandboxing requires that indirect call instructions are masked.
    325   // This means that function entry points should be bundle-aligned.
    326   if (Subtarget->isTargetNaCl())
    327     EmitAlignment(std::max(MF->getAlignment(), MIPS_NACL_BUNDLE_ALIGN));
    328 
    329   if (Subtarget->inMicroMipsMode())
    330     TS.emitDirectiveSetMicroMips();
    331   else
    332     TS.emitDirectiveSetNoMicroMips();
    333 
    334   if (Subtarget->inMips16Mode())
    335     TS.emitDirectiveSetMips16();
    336   else
    337     TS.emitDirectiveSetNoMips16();
    338 
    339   TS.emitDirectiveEnt(*CurrentFnSym);
    340   OutStreamer->EmitLabel(CurrentFnSym);
    341 }
    342 
    343 /// EmitFunctionBodyStart - Targets can override this to emit stuff before
    344 /// the first basic block in the function.
    345 void MipsAsmPrinter::EmitFunctionBodyStart() {
    346   MipsTargetStreamer &TS = getTargetStreamer();
    347 
    348   MCInstLowering.Initialize(&MF->getContext());
    349 
    350   bool IsNakedFunction = MF->getFunction()->hasFnAttribute(Attribute::Naked);
    351   if (!IsNakedFunction)
    352     emitFrameDirective();
    353 
    354   if (!IsNakedFunction)
    355     printSavedRegsBitmask();
    356 
    357   if (!Subtarget->inMips16Mode()) {
    358     TS.emitDirectiveSetNoReorder();
    359     TS.emitDirectiveSetNoMacro();
    360     TS.emitDirectiveSetNoAt();
    361   }
    362 }
    363 
    364 /// EmitFunctionBodyEnd - Targets can override this to emit stuff after
    365 /// the last basic block in the function.
    366 void MipsAsmPrinter::EmitFunctionBodyEnd() {
    367   MipsTargetStreamer &TS = getTargetStreamer();
    368 
    369   // There are instruction for this macros, but they must
    370   // always be at the function end, and we can't emit and
    371   // break with BB logic.
    372   if (!Subtarget->inMips16Mode()) {
    373     TS.emitDirectiveSetAt();
    374     TS.emitDirectiveSetMacro();
    375     TS.emitDirectiveSetReorder();
    376   }
    377   TS.emitDirectiveEnd(CurrentFnSym->getName());
    378   // Make sure to terminate any constant pools that were at the end
    379   // of the function.
    380   if (!InConstantPool)
    381     return;
    382   InConstantPool = false;
    383   OutStreamer->EmitDataRegion(MCDR_DataRegionEnd);
    384 }
    385 
    386 void MipsAsmPrinter::EmitBasicBlockEnd(const MachineBasicBlock &MBB) {
    387   MipsTargetStreamer &TS = getTargetStreamer();
    388   if (MBB.size() == 0)
    389     TS.emitDirectiveInsn();
    390 }
    391 
    392 /// isBlockOnlyReachableByFallthough - Return true if the basic block has
    393 /// exactly one predecessor and the control transfer mechanism between
    394 /// the predecessor and this block is a fall-through.
    395 bool MipsAsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock*
    396                                                        MBB) const {
    397   // The predecessor has to be immediately before this block.
    398   const MachineBasicBlock *Pred = *MBB->pred_begin();
    399 
    400   // If the predecessor is a switch statement, assume a jump table
    401   // implementation, so it is not a fall through.
    402   if (const BasicBlock *bb = Pred->getBasicBlock())
    403     if (isa<SwitchInst>(bb->getTerminator()))
    404       return false;
    405 
    406   // If this is a landing pad, it isn't a fall through.  If it has no preds,
    407   // then nothing falls through to it.
    408   if (MBB->isEHPad() || MBB->pred_empty())
    409     return false;
    410 
    411   // If there isn't exactly one predecessor, it can't be a fall through.
    412   MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI;
    413   ++PI2;
    414 
    415   if (PI2 != MBB->pred_end())
    416     return false;
    417 
    418   // The predecessor has to be immediately before this block.
    419   if (!Pred->isLayoutSuccessor(MBB))
    420     return false;
    421 
    422   // If the block is completely empty, then it definitely does fall through.
    423   if (Pred->empty())
    424     return true;
    425 
    426   // Otherwise, check the last instruction.
    427   // Check if the last terminator is an unconditional branch.
    428   MachineBasicBlock::const_iterator I = Pred->end();
    429   while (I != Pred->begin() && !(--I)->isTerminator()) ;
    430 
    431   return !I->isBarrier();
    432 }
    433 
    434 // Print out an operand for an inline asm expression.
    435 bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
    436                                      unsigned AsmVariant, const char *ExtraCode,
    437                                      raw_ostream &O) {
    438   // Does this asm operand have a single letter operand modifier?
    439   if (ExtraCode && ExtraCode[0]) {
    440     if (ExtraCode[1] != 0) return true; // Unknown modifier.
    441 
    442     const MachineOperand &MO = MI->getOperand(OpNum);
    443     switch (ExtraCode[0]) {
    444     default:
    445       // See if this is a generic print operand
    446       return AsmPrinter::PrintAsmOperand(MI,OpNum,AsmVariant,ExtraCode,O);
    447     case 'X': // hex const int
    448       if ((MO.getType()) != MachineOperand::MO_Immediate)
    449         return true;
    450       O << "0x" << Twine::utohexstr(MO.getImm());
    451       return false;
    452     case 'x': // hex const int (low 16 bits)
    453       if ((MO.getType()) != MachineOperand::MO_Immediate)
    454         return true;
    455       O << "0x" << Twine::utohexstr(MO.getImm() & 0xffff);
    456       return false;
    457     case 'd': // decimal const int
    458       if ((MO.getType()) != MachineOperand::MO_Immediate)
    459         return true;
    460       O << MO.getImm();
    461       return false;
    462     case 'm': // decimal const int minus 1
    463       if ((MO.getType()) != MachineOperand::MO_Immediate)
    464         return true;
    465       O << MO.getImm() - 1;
    466       return false;
    467     case 'z': {
    468       // $0 if zero, regular printing otherwise
    469       if (MO.getType() == MachineOperand::MO_Immediate && MO.getImm() == 0) {
    470         O << "$0";
    471         return false;
    472       }
    473       // If not, call printOperand as normal.
    474       break;
    475     }
    476     case 'D': // Second part of a double word register operand
    477     case 'L': // Low order register of a double word register operand
    478     case 'M': // High order register of a double word register operand
    479     {
    480       if (OpNum == 0)
    481         return true;
    482       const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1);
    483       if (!FlagsOP.isImm())
    484         return true;
    485       unsigned Flags = FlagsOP.getImm();
    486       unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags);
    487       // Number of registers represented by this operand. We are looking
    488       // for 2 for 32 bit mode and 1 for 64 bit mode.
    489       if (NumVals != 2) {
    490         if (Subtarget->isGP64bit() && NumVals == 1 && MO.isReg()) {
    491           unsigned Reg = MO.getReg();
    492           O << '$' << MipsInstPrinter::getRegisterName(Reg);
    493           return false;
    494         }
    495         return true;
    496       }
    497 
    498       unsigned RegOp = OpNum;
    499       if (!Subtarget->isGP64bit()){
    500         // Endianess reverses which register holds the high or low value
    501         // between M and L.
    502         switch(ExtraCode[0]) {
    503         case 'M':
    504           RegOp = (Subtarget->isLittle()) ? OpNum + 1 : OpNum;
    505           break;
    506         case 'L':
    507           RegOp = (Subtarget->isLittle()) ? OpNum : OpNum + 1;
    508           break;
    509         case 'D': // Always the second part
    510           RegOp = OpNum + 1;
    511         }
    512         if (RegOp >= MI->getNumOperands())
    513           return true;
    514         const MachineOperand &MO = MI->getOperand(RegOp);
    515         if (!MO.isReg())
    516           return true;
    517         unsigned Reg = MO.getReg();
    518         O << '$' << MipsInstPrinter::getRegisterName(Reg);
    519         return false;
    520       }
    521     }
    522     case 'w':
    523       // Print MSA registers for the 'f' constraint
    524       // In LLVM, the 'w' modifier doesn't need to do anything.
    525       // We can just call printOperand as normal.
    526       break;
    527     }
    528   }
    529 
    530   printOperand(MI, OpNum, O);
    531   return false;
    532 }
    533 
    534 bool MipsAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
    535                                            unsigned OpNum, unsigned AsmVariant,
    536                                            const char *ExtraCode,
    537                                            raw_ostream &O) {
    538   assert(OpNum + 1 < MI->getNumOperands() && "Insufficient operands");
    539   const MachineOperand &BaseMO = MI->getOperand(OpNum);
    540   const MachineOperand &OffsetMO = MI->getOperand(OpNum + 1);
    541   assert(BaseMO.isReg() && "Unexpected base pointer for inline asm memory operand.");
    542   assert(OffsetMO.isImm() && "Unexpected offset for inline asm memory operand.");
    543   int Offset = OffsetMO.getImm();
    544 
    545   // Currently we are expecting either no ExtraCode or 'D'
    546   if (ExtraCode) {
    547     if (ExtraCode[0] == 'D')
    548       Offset += 4;
    549     else
    550       return true; // Unknown modifier.
    551     // FIXME: M = high order bits
    552     // FIXME: L = low order bits
    553   }
    554 
    555   O << Offset << "($" << MipsInstPrinter::getRegisterName(BaseMO.getReg()) << ")";
    556 
    557   return false;
    558 }
    559 
    560 void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
    561                                   raw_ostream &O) {
    562   const MachineOperand &MO = MI->getOperand(opNum);
    563   bool closeP = false;
    564 
    565   if (MO.getTargetFlags())
    566     closeP = true;
    567 
    568   switch(MO.getTargetFlags()) {
    569   case MipsII::MO_GPREL:    O << "%gp_rel("; break;
    570   case MipsII::MO_GOT_CALL: O << "%call16("; break;
    571   case MipsII::MO_GOT:      O << "%got(";    break;
    572   case MipsII::MO_ABS_HI:   O << "%hi(";     break;
    573   case MipsII::MO_ABS_LO:   O << "%lo(";     break;
    574   case MipsII::MO_TLSGD:    O << "%tlsgd(";  break;
    575   case MipsII::MO_GOTTPREL: O << "%gottprel("; break;
    576   case MipsII::MO_TPREL_HI: O << "%tprel_hi("; break;
    577   case MipsII::MO_TPREL_LO: O << "%tprel_lo("; break;
    578   case MipsII::MO_GPOFF_HI: O << "%hi(%neg(%gp_rel("; break;
    579   case MipsII::MO_GPOFF_LO: O << "%lo(%neg(%gp_rel("; break;
    580   case MipsII::MO_GOT_DISP: O << "%got_disp("; break;
    581   case MipsII::MO_GOT_PAGE: O << "%got_page("; break;
    582   case MipsII::MO_GOT_OFST: O << "%got_ofst("; break;
    583   }
    584 
    585   switch (MO.getType()) {
    586     case MachineOperand::MO_Register:
    587       O << '$'
    588         << StringRef(MipsInstPrinter::getRegisterName(MO.getReg())).lower();
    589       break;
    590 
    591     case MachineOperand::MO_Immediate:
    592       O << MO.getImm();
    593       break;
    594 
    595     case MachineOperand::MO_MachineBasicBlock:
    596       MO.getMBB()->getSymbol()->print(O, MAI);
    597       return;
    598 
    599     case MachineOperand::MO_GlobalAddress:
    600       getSymbol(MO.getGlobal())->print(O, MAI);
    601       break;
    602 
    603     case MachineOperand::MO_BlockAddress: {
    604       MCSymbol *BA = GetBlockAddressSymbol(MO.getBlockAddress());
    605       O << BA->getName();
    606       break;
    607     }
    608 
    609     case MachineOperand::MO_ConstantPoolIndex:
    610       O << getDataLayout().getPrivateGlobalPrefix() << "CPI"
    611         << getFunctionNumber() << "_" << MO.getIndex();
    612       if (MO.getOffset())
    613         O << "+" << MO.getOffset();
    614       break;
    615 
    616     default:
    617       llvm_unreachable("<unknown operand type>");
    618   }
    619 
    620   if (closeP) O << ")";
    621 }
    622 
    623 void MipsAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum,
    624                                       raw_ostream &O) {
    625   const MachineOperand &MO = MI->getOperand(opNum);
    626   if (MO.isImm())
    627     O << (unsigned short int)MO.getImm();
    628   else
    629     printOperand(MI, opNum, O);
    630 }
    631 
    632 void MipsAsmPrinter::printUnsignedImm8(const MachineInstr *MI, int opNum,
    633                                        raw_ostream &O) {
    634   const MachineOperand &MO = MI->getOperand(opNum);
    635   if (MO.isImm())
    636     O << (unsigned short int)(unsigned char)MO.getImm();
    637   else
    638     printOperand(MI, opNum, O);
    639 }
    640 
    641 void MipsAsmPrinter::
    642 printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O) {
    643   // Load/Store memory operands -- imm($reg)
    644   // If PIC target the target is loaded as the
    645   // pattern lw $25,%call16($28)
    646 
    647   // opNum can be invalid if instruction has reglist as operand.
    648   // MemOperand is always last operand of instruction (base + offset).
    649   switch (MI->getOpcode()) {
    650   default:
    651     break;
    652   case Mips::SWM32_MM:
    653   case Mips::LWM32_MM:
    654     opNum = MI->getNumOperands() - 2;
    655     break;
    656   }
    657 
    658   printOperand(MI, opNum+1, O);
    659   O << "(";
    660   printOperand(MI, opNum, O);
    661   O << ")";
    662 }
    663 
    664 void MipsAsmPrinter::
    665 printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O) {
    666   // when using stack locations for not load/store instructions
    667   // print the same way as all normal 3 operand instructions.
    668   printOperand(MI, opNum, O);
    669   O << ", ";
    670   printOperand(MI, opNum+1, O);
    671   return;
    672 }
    673 
    674 void MipsAsmPrinter::
    675 printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
    676                 const char *Modifier) {
    677   const MachineOperand &MO = MI->getOperand(opNum);
    678   O << Mips::MipsFCCToString((Mips::CondCode)MO.getImm());
    679 }
    680 
    681 void MipsAsmPrinter::
    682 printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O) {
    683   for (int i = opNum, e = MI->getNumOperands(); i != e; ++i) {
    684     if (i != opNum) O << ", ";
    685     printOperand(MI, i, O);
    686   }
    687 }
    688 
    689 void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) {
    690 
    691   // Compute MIPS architecture attributes based on the default subtarget
    692   // that we'd have constructed. Module level directives aren't LTO
    693   // clean anyhow.
    694   // FIXME: For ifunc related functions we could iterate over and look
    695   // for a feature string that doesn't match the default one.
    696   const Triple &TT = TM.getTargetTriple();
    697   StringRef CPU = MIPS_MC::selectMipsCPU(TT, TM.getTargetCPU());
    698   StringRef FS = TM.getTargetFeatureString();
    699   const MipsTargetMachine &MTM = static_cast<const MipsTargetMachine &>(TM);
    700   const MipsSubtarget STI(TT, CPU, FS, MTM.isLittleEndian(), MTM);
    701 
    702   bool IsABICalls = STI.isABICalls();
    703   const MipsABIInfo &ABI = MTM.getABI();
    704   if (IsABICalls) {
    705     getTargetStreamer().emitDirectiveAbiCalls();
    706     Reloc::Model RM = TM.getRelocationModel();
    707     // FIXME: This condition should be a lot more complicated that it is here.
    708     //        Ideally it should test for properties of the ABI and not the ABI
    709     //        itself.
    710     //        For the moment, I'm only correcting enough to make MIPS-IV work.
    711     if (RM == Reloc::Static && !ABI.IsN64())
    712       getTargetStreamer().emitDirectiveOptionPic0();
    713   }
    714 
    715   // Tell the assembler which ABI we are using
    716   std::string SectionName = std::string(".mdebug.") + getCurrentABIString();
    717   OutStreamer->SwitchSection(
    718       OutContext.getELFSection(SectionName, ELF::SHT_PROGBITS, 0));
    719 
    720   // NaN: At the moment we only support:
    721   // 1. .nan legacy (default)
    722   // 2. .nan 2008
    723   STI.isNaN2008() ? getTargetStreamer().emitDirectiveNaN2008()
    724                   : getTargetStreamer().emitDirectiveNaNLegacy();
    725 
    726   // TODO: handle O64 ABI
    727 
    728   if (ABI.IsEABI()) {
    729     if (STI.isGP32bit())
    730       OutStreamer->SwitchSection(OutContext.getELFSection(".gcc_compiled_long32",
    731                                                           ELF::SHT_PROGBITS, 0));
    732     else
    733       OutStreamer->SwitchSection(OutContext.getELFSection(".gcc_compiled_long64",
    734                                                           ELF::SHT_PROGBITS, 0));
    735   }
    736 
    737   getTargetStreamer().updateABIInfo(STI);
    738 
    739   // We should always emit a '.module fp=...' but binutils 2.24 does not accept
    740   // it. We therefore emit it when it contradicts the ABI defaults (-mfpxx or
    741   // -mfp64) and omit it otherwise.
    742   if (ABI.IsO32() && (STI.isABI_FPXX() || STI.isFP64bit()))
    743     getTargetStreamer().emitDirectiveModuleFP();
    744 
    745   // We should always emit a '.module [no]oddspreg' but binutils 2.24 does not
    746   // accept it. We therefore emit it when it contradicts the default or an
    747   // option has changed the default (i.e. FPXX) and omit it otherwise.
    748   if (ABI.IsO32() && (!STI.useOddSPReg() || STI.isABI_FPXX()))
    749     getTargetStreamer().emitDirectiveModuleOddSPReg();
    750 }
    751 
    752 void MipsAsmPrinter::emitInlineAsmStart() const {
    753   MipsTargetStreamer &TS = getTargetStreamer();
    754 
    755   // GCC's choice of assembler options for inline assembly code ('at', 'macro'
    756   // and 'reorder') is different from LLVM's choice for generated code ('noat',
    757   // 'nomacro' and 'noreorder').
    758   // In order to maintain compatibility with inline assembly code which depends
    759   // on GCC's assembler options being used, we have to switch to those options
    760   // for the duration of the inline assembly block and then switch back.
    761   TS.emitDirectiveSetPush();
    762   TS.emitDirectiveSetAt();
    763   TS.emitDirectiveSetMacro();
    764   TS.emitDirectiveSetReorder();
    765   OutStreamer->AddBlankLine();
    766 }
    767 
    768 void MipsAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
    769                                       const MCSubtargetInfo *EndInfo) const {
    770   OutStreamer->AddBlankLine();
    771   getTargetStreamer().emitDirectiveSetPop();
    772 }
    773 
    774 void MipsAsmPrinter::EmitJal(const MCSubtargetInfo &STI, MCSymbol *Symbol) {
    775   MCInst I;
    776   I.setOpcode(Mips::JAL);
    777   I.addOperand(
    778       MCOperand::createExpr(MCSymbolRefExpr::create(Symbol, OutContext)));
    779   OutStreamer->EmitInstruction(I, STI);
    780 }
    781 
    782 void MipsAsmPrinter::EmitInstrReg(const MCSubtargetInfo &STI, unsigned Opcode,
    783                                   unsigned Reg) {
    784   MCInst I;
    785   I.setOpcode(Opcode);
    786   I.addOperand(MCOperand::createReg(Reg));
    787   OutStreamer->EmitInstruction(I, STI);
    788 }
    789 
    790 void MipsAsmPrinter::EmitInstrRegReg(const MCSubtargetInfo &STI,
    791                                      unsigned Opcode, unsigned Reg1,
    792                                      unsigned Reg2) {
    793   MCInst I;
    794   //
    795   // Because of the current td files for Mips32, the operands for MTC1
    796   // appear backwards from their normal assembly order. It's not a trivial
    797   // change to fix this in the td file so we adjust for it here.
    798   //
    799   if (Opcode == Mips::MTC1) {
    800     unsigned Temp = Reg1;
    801     Reg1 = Reg2;
    802     Reg2 = Temp;
    803   }
    804   I.setOpcode(Opcode);
    805   I.addOperand(MCOperand::createReg(Reg1));
    806   I.addOperand(MCOperand::createReg(Reg2));
    807   OutStreamer->EmitInstruction(I, STI);
    808 }
    809 
    810 void MipsAsmPrinter::EmitInstrRegRegReg(const MCSubtargetInfo &STI,
    811                                         unsigned Opcode, unsigned Reg1,
    812                                         unsigned Reg2, unsigned Reg3) {
    813   MCInst I;
    814   I.setOpcode(Opcode);
    815   I.addOperand(MCOperand::createReg(Reg1));
    816   I.addOperand(MCOperand::createReg(Reg2));
    817   I.addOperand(MCOperand::createReg(Reg3));
    818   OutStreamer->EmitInstruction(I, STI);
    819 }
    820 
    821 void MipsAsmPrinter::EmitMovFPIntPair(const MCSubtargetInfo &STI,
    822                                       unsigned MovOpc, unsigned Reg1,
    823                                       unsigned Reg2, unsigned FPReg1,
    824                                       unsigned FPReg2, bool LE) {
    825   if (!LE) {
    826     unsigned temp = Reg1;
    827     Reg1 = Reg2;
    828     Reg2 = temp;
    829   }
    830   EmitInstrRegReg(STI, MovOpc, Reg1, FPReg1);
    831   EmitInstrRegReg(STI, MovOpc, Reg2, FPReg2);
    832 }
    833 
    834 void MipsAsmPrinter::EmitSwapFPIntParams(const MCSubtargetInfo &STI,
    835                                          Mips16HardFloatInfo::FPParamVariant PV,
    836                                          bool LE, bool ToFP) {
    837   using namespace Mips16HardFloatInfo;
    838   unsigned MovOpc = ToFP ? Mips::MTC1 : Mips::MFC1;
    839   switch (PV) {
    840   case FSig:
    841     EmitInstrRegReg(STI, MovOpc, Mips::A0, Mips::F12);
    842     break;
    843   case FFSig:
    844     EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F14, LE);
    845     break;
    846   case FDSig:
    847     EmitInstrRegReg(STI, MovOpc, Mips::A0, Mips::F12);
    848     EmitMovFPIntPair(STI, MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE);
    849     break;
    850   case DSig:
    851     EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
    852     break;
    853   case DDSig:
    854     EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
    855     EmitMovFPIntPair(STI, MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE);
    856     break;
    857   case DFSig:
    858     EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE);
    859     EmitInstrRegReg(STI, MovOpc, Mips::A2, Mips::F14);
    860     break;
    861   case NoSig:
    862     return;
    863   }
    864 }
    865 
    866 void MipsAsmPrinter::EmitSwapFPIntRetval(
    867     const MCSubtargetInfo &STI, Mips16HardFloatInfo::FPReturnVariant RV,
    868     bool LE) {
    869   using namespace Mips16HardFloatInfo;
    870   unsigned MovOpc = Mips::MFC1;
    871   switch (RV) {
    872   case FRet:
    873     EmitInstrRegReg(STI, MovOpc, Mips::V0, Mips::F0);
    874     break;
    875   case DRet:
    876     EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
    877     break;
    878   case CFRet:
    879     EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
    880     break;
    881   case CDRet:
    882     EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE);
    883     EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F2, Mips::F3, LE);
    884     break;
    885   case NoFPRet:
    886     break;
    887   }
    888 }
    889 
    890 void MipsAsmPrinter::EmitFPCallStub(
    891     const char *Symbol, const Mips16HardFloatInfo::FuncSignature *Signature) {
    892   MCSymbol *MSymbol = OutContext.getOrCreateSymbol(StringRef(Symbol));
    893   using namespace Mips16HardFloatInfo;
    894   bool LE = getDataLayout().isLittleEndian();
    895   // Construct a local MCSubtargetInfo here.
    896   // This is because the MachineFunction won't exist (but have not yet been
    897   // freed) and since we're at the global level we can use the default
    898   // constructed subtarget.
    899   std::unique_ptr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo(
    900       TM.getTargetTriple().str(), TM.getTargetCPU(),
    901       TM.getTargetFeatureString()));
    902 
    903   //
    904   // .global xxxx
    905   //
    906   OutStreamer->EmitSymbolAttribute(MSymbol, MCSA_Global);
    907   const char *RetType;
    908   //
    909   // make the comment field identifying the return and parameter
    910   // types of the floating point stub
    911   // # Stub function to call rettype xxxx (params)
    912   //
    913   switch (Signature->RetSig) {
    914   case FRet:
    915     RetType = "float";
    916     break;
    917   case DRet:
    918     RetType = "double";
    919     break;
    920   case CFRet:
    921     RetType = "complex";
    922     break;
    923   case CDRet:
    924     RetType = "double complex";
    925     break;
    926   case NoFPRet:
    927     RetType = "";
    928     break;
    929   }
    930   const char *Parms;
    931   switch (Signature->ParamSig) {
    932   case FSig:
    933     Parms = "float";
    934     break;
    935   case FFSig:
    936     Parms = "float, float";
    937     break;
    938   case FDSig:
    939     Parms = "float, double";
    940     break;
    941   case DSig:
    942     Parms = "double";
    943     break;
    944   case DDSig:
    945     Parms = "double, double";
    946     break;
    947   case DFSig:
    948     Parms = "double, float";
    949     break;
    950   case NoSig:
    951     Parms = "";
    952     break;
    953   }
    954   OutStreamer->AddComment("\t# Stub function to call " + Twine(RetType) + " " +
    955                           Twine(Symbol) + " (" + Twine(Parms) + ")");
    956   //
    957   // probably not necessary but we save and restore the current section state
    958   //
    959   OutStreamer->PushSection();
    960   //
    961   // .section mips16.call.fpxxxx,"ax",@progbits
    962   //
    963   MCSectionELF *M = OutContext.getELFSection(
    964       ".mips16.call.fp." + std::string(Symbol), ELF::SHT_PROGBITS,
    965       ELF::SHF_ALLOC | ELF::SHF_EXECINSTR);
    966   OutStreamer->SwitchSection(M, nullptr);
    967   //
    968   // .align 2
    969   //
    970   OutStreamer->EmitValueToAlignment(4);
    971   MipsTargetStreamer &TS = getTargetStreamer();
    972   //
    973   // .set nomips16
    974   // .set nomicromips
    975   //
    976   TS.emitDirectiveSetNoMips16();
    977   TS.emitDirectiveSetNoMicroMips();
    978   //
    979   // .ent __call_stub_fp_xxxx
    980   // .type  __call_stub_fp_xxxx,@function
    981   //  __call_stub_fp_xxxx:
    982   //
    983   std::string x = "__call_stub_fp_" + std::string(Symbol);
    984   MCSymbolELF *Stub =
    985       cast<MCSymbolELF>(OutContext.getOrCreateSymbol(StringRef(x)));
    986   TS.emitDirectiveEnt(*Stub);
    987   MCSymbol *MType =
    988       OutContext.getOrCreateSymbol("__call_stub_fp_" + Twine(Symbol));
    989   OutStreamer->EmitSymbolAttribute(MType, MCSA_ELF_TypeFunction);
    990   OutStreamer->EmitLabel(Stub);
    991 
    992   // Only handle non-pic for now.
    993   assert(TM.getRelocationModel() != Reloc::PIC_ &&
    994          "should not be here if we are compiling pic");
    995   TS.emitDirectiveSetReorder();
    996   //
    997   // We need to add a MipsMCExpr class to MCTargetDesc to fully implement
    998   // stubs without raw text but this current patch is for compiler generated
    999   // functions and they all return some value.
   1000   // The calling sequence for non pic is different in that case and we need
   1001   // to implement %lo and %hi in order to handle the case of no return value
   1002   // See the corresponding method in Mips16HardFloat for details.
   1003   //
   1004   // mov the return address to S2.
   1005   // we have no stack space to store it and we are about to make another call.
   1006   // We need to make sure that the enclosing function knows to save S2
   1007   // This should have already been handled.
   1008   //
   1009   // Mov $18, $31
   1010 
   1011   EmitInstrRegRegReg(*STI, Mips::OR, Mips::S2, Mips::RA, Mips::ZERO);
   1012 
   1013   EmitSwapFPIntParams(*STI, Signature->ParamSig, LE, true);
   1014 
   1015   // Jal xxxx
   1016   //
   1017   EmitJal(*STI, MSymbol);
   1018 
   1019   // fix return values
   1020   EmitSwapFPIntRetval(*STI, Signature->RetSig, LE);
   1021   //
   1022   // do the return
   1023   // if (Signature->RetSig == NoFPRet)
   1024   //  llvm_unreachable("should not be any stubs here with no return value");
   1025   // else
   1026   EmitInstrReg(*STI, Mips::JR, Mips::S2);
   1027 
   1028   MCSymbol *Tmp = OutContext.createTempSymbol();
   1029   OutStreamer->EmitLabel(Tmp);
   1030   const MCSymbolRefExpr *E = MCSymbolRefExpr::create(Stub, OutContext);
   1031   const MCSymbolRefExpr *T = MCSymbolRefExpr::create(Tmp, OutContext);
   1032   const MCExpr *T_min_E = MCBinaryExpr::createSub(T, E, OutContext);
   1033   OutStreamer->emitELFSize(Stub, T_min_E);
   1034   TS.emitDirectiveEnd(x);
   1035   OutStreamer->PopSection();
   1036 }
   1037 
   1038 void MipsAsmPrinter::EmitEndOfAsmFile(Module &M) {
   1039   // Emit needed stubs
   1040   //
   1041   for (std::map<
   1042            const char *,
   1043            const llvm::Mips16HardFloatInfo::FuncSignature *>::const_iterator
   1044            it = StubsNeeded.begin();
   1045        it != StubsNeeded.end(); ++it) {
   1046     const char *Symbol = it->first;
   1047     const llvm::Mips16HardFloatInfo::FuncSignature *Signature = it->second;
   1048     EmitFPCallStub(Symbol, Signature);
   1049   }
   1050   // return to the text section
   1051   OutStreamer->SwitchSection(OutContext.getObjectFileInfo()->getTextSection());
   1052 }
   1053 
   1054 void MipsAsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
   1055                                            raw_ostream &OS) {
   1056   // TODO: implement
   1057 }
   1058 
   1059 // Align all targets of indirect branches on bundle size.  Used only if target
   1060 // is NaCl.
   1061 void MipsAsmPrinter::NaClAlignIndirectJumpTargets(MachineFunction &MF) {
   1062   // Align all blocks that are jumped to through jump table.
   1063   if (MachineJumpTableInfo *JtInfo = MF.getJumpTableInfo()) {
   1064     const std::vector<MachineJumpTableEntry> &JT = JtInfo->getJumpTables();
   1065     for (unsigned I = 0; I < JT.size(); ++I) {
   1066       const std::vector<MachineBasicBlock*> &MBBs = JT[I].MBBs;
   1067 
   1068       for (unsigned J = 0; J < MBBs.size(); ++J)
   1069         MBBs[J]->setAlignment(MIPS_NACL_BUNDLE_ALIGN);
   1070     }
   1071   }
   1072 
   1073   // If basic block address is taken, block can be target of indirect branch.
   1074   for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
   1075                                  MBB != E; ++MBB) {
   1076     if (MBB->hasAddressTaken())
   1077       MBB->setAlignment(MIPS_NACL_BUNDLE_ALIGN);
   1078   }
   1079 }
   1080 
   1081 bool MipsAsmPrinter::isLongBranchPseudo(int Opcode) const {
   1082   return (Opcode == Mips::LONG_BRANCH_LUi
   1083           || Opcode == Mips::LONG_BRANCH_ADDiu
   1084           || Opcode == Mips::LONG_BRANCH_DADDiu);
   1085 }
   1086 
   1087 // Force static initialization.
   1088 extern "C" void LLVMInitializeMipsAsmPrinter() {
   1089   RegisterAsmPrinter<MipsAsmPrinter> X(TheMipsTarget);
   1090   RegisterAsmPrinter<MipsAsmPrinter> Y(TheMipselTarget);
   1091   RegisterAsmPrinter<MipsAsmPrinter> A(TheMips64Target);
   1092   RegisterAsmPrinter<MipsAsmPrinter> B(TheMips64elTarget);
   1093 }
   1094