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