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 #define DEBUG_TYPE "mips-asm-printer"
     16 #include "InstPrinter/MipsInstPrinter.h"
     17 #include "MCTargetDesc/MipsBaseInfo.h"
     18 #include "MCTargetDesc/MipsELFStreamer.h"
     19 #include "Mips.h"
     20 #include "MipsAsmPrinter.h"
     21 #include "MipsInstrInfo.h"
     22 #include "MipsMCInstLower.h"
     23 #include "llvm/ADT/SmallString.h"
     24 #include "llvm/ADT/StringExtras.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/MachineMemOperand.h"
     31 #include "llvm/IR/BasicBlock.h"
     32 #include "llvm/IR/DataLayout.h"
     33 #include "llvm/IR/InlineAsm.h"
     34 #include "llvm/IR/Instructions.h"
     35 #include "llvm/MC/MCAsmInfo.h"
     36 #include "llvm/MC/MCInst.h"
     37 #include "llvm/MC/MCStreamer.h"
     38 #include "llvm/MC/MCSymbol.h"
     39 #include "llvm/Support/ELF.h"
     40 #include "llvm/Support/TargetRegistry.h"
     41 #include "llvm/Support/raw_ostream.h"
     42 #include "llvm/Target/Mangler.h"
     43 #include "llvm/Target/TargetLoweringObjectFile.h"
     44 #include "llvm/Target/TargetOptions.h"
     45 
     46 using namespace llvm;
     47 
     48 bool MipsAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
     49   // Initialize TargetLoweringObjectFile.
     50   if (Subtarget->allowMixed16_32())
     51     const_cast<TargetLoweringObjectFile&>(getObjFileLowering())
     52       .Initialize(OutContext, TM);
     53   MipsFI = MF.getInfo<MipsFunctionInfo>();
     54   AsmPrinter::runOnMachineFunction(MF);
     55   return true;
     56 }
     57 
     58 bool MipsAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) {
     59   MCOp = MCInstLowering.LowerOperand(MO);
     60   return MCOp.isValid();
     61 }
     62 
     63 #include "MipsGenMCPseudoLowering.inc"
     64 
     65 void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
     66   if (MI->isDebugValue()) {
     67     SmallString<128> Str;
     68     raw_svector_ostream OS(Str);
     69 
     70     PrintDebugValueComment(MI, OS);
     71     return;
     72   }
     73 
     74   MachineBasicBlock::const_instr_iterator I = MI;
     75   MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();
     76 
     77   do {
     78     // Do any auto-generated pseudo lowerings.
     79     if (emitPseudoExpansionLowering(OutStreamer, &*I))
     80       continue;
     81 
     82     // The inMips16Mode() test is not permanent.
     83     // Some instructions are marked as pseudo right now which
     84     // would make the test fail for the wrong reason but
     85     // that will be fixed soon. We need this here because we are
     86     // removing another test for this situation downstream in the
     87     // callchain.
     88     //
     89     if (I->isPseudo() && !Subtarget->inMips16Mode())
     90       llvm_unreachable("Pseudo opcode found in EmitInstruction()");
     91 
     92     MCInst TmpInst0;
     93     MCInstLowering.Lower(I, TmpInst0);
     94     OutStreamer.EmitInstruction(TmpInst0);
     95   } while ((++I != E) && I->isInsideBundle()); // Delay slot check
     96 }
     97 
     98 //===----------------------------------------------------------------------===//
     99 //
    100 //  Mips Asm Directives
    101 //
    102 //  -- Frame directive "frame Stackpointer, Stacksize, RARegister"
    103 //  Describe the stack frame.
    104 //
    105 //  -- Mask directives "(f)mask  bitmask, offset"
    106 //  Tells the assembler which registers are saved and where.
    107 //  bitmask - contain a little endian bitset indicating which registers are
    108 //            saved on function prologue (e.g. with a 0x80000000 mask, the
    109 //            assembler knows the register 31 (RA) is saved at prologue.
    110 //  offset  - the position before stack pointer subtraction indicating where
    111 //            the first saved register on prologue is located. (e.g. with a
    112 //
    113 //  Consider the following function prologue:
    114 //
    115 //    .frame  $fp,48,$ra
    116 //    .mask   0xc0000000,-8
    117 //       addiu $sp, $sp, -48
    118 //       sw $ra, 40($sp)
    119 //       sw $fp, 36($sp)
    120 //
    121 //    With a 0xc0000000 mask, the assembler knows the register 31 (RA) and
    122 //    30 (FP) are saved at prologue. As the save order on prologue is from
    123 //    left to right, RA is saved first. A -8 offset means that after the
    124 //    stack pointer subtration, the first register in the mask (RA) will be
    125 //    saved at address 48-8=40.
    126 //
    127 //===----------------------------------------------------------------------===//
    128 
    129 //===----------------------------------------------------------------------===//
    130 // Mask directives
    131 //===----------------------------------------------------------------------===//
    132 
    133 // Create a bitmask with all callee saved registers for CPU or Floating Point
    134 // registers. For CPU registers consider RA, GP and FP for saving if necessary.
    135 void MipsAsmPrinter::printSavedRegsBitmask(raw_ostream &O) {
    136   // CPU and FPU Saved Registers Bitmasks
    137   unsigned CPUBitmask = 0, FPUBitmask = 0;
    138   int CPUTopSavedRegOff, FPUTopSavedRegOff;
    139 
    140   // Set the CPU and FPU Bitmasks
    141   const MachineFrameInfo *MFI = MF->getFrameInfo();
    142   const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
    143   // size of stack area to which FP callee-saved regs are saved.
    144   unsigned CPURegSize = Mips::GPR32RegClass.getSize();
    145   unsigned FGR32RegSize = Mips::FGR32RegClass.getSize();
    146   unsigned AFGR64RegSize = Mips::AFGR64RegClass.getSize();
    147   bool HasAFGR64Reg = false;
    148   unsigned CSFPRegsSize = 0;
    149   unsigned i, e = CSI.size();
    150 
    151   // Set FPU Bitmask.
    152   for (i = 0; i != e; ++i) {
    153     unsigned Reg = CSI[i].getReg();
    154     if (Mips::GPR32RegClass.contains(Reg))
    155       break;
    156 
    157     unsigned RegNum = TM.getRegisterInfo()->getEncodingValue(Reg);
    158     if (Mips::AFGR64RegClass.contains(Reg)) {
    159       FPUBitmask |= (3 << RegNum);
    160       CSFPRegsSize += AFGR64RegSize;
    161       HasAFGR64Reg = true;
    162       continue;
    163     }
    164 
    165     FPUBitmask |= (1 << RegNum);
    166     CSFPRegsSize += FGR32RegSize;
    167   }
    168 
    169   // Set CPU Bitmask.
    170   for (; i != e; ++i) {
    171     unsigned Reg = CSI[i].getReg();
    172     unsigned RegNum = TM.getRegisterInfo()->getEncodingValue(Reg);
    173     CPUBitmask |= (1 << RegNum);
    174   }
    175 
    176   // FP Regs are saved right below where the virtual frame pointer points to.
    177   FPUTopSavedRegOff = FPUBitmask ?
    178     (HasAFGR64Reg ? -AFGR64RegSize : -FGR32RegSize) : 0;
    179 
    180   // CPU Regs are saved below FP Regs.
    181   CPUTopSavedRegOff = CPUBitmask ? -CSFPRegsSize - CPURegSize : 0;
    182 
    183   // Print CPUBitmask
    184   O << "\t.mask \t"; printHex32(CPUBitmask, O);
    185   O << ',' << CPUTopSavedRegOff << '\n';
    186 
    187   // Print FPUBitmask
    188   O << "\t.fmask\t"; printHex32(FPUBitmask, O);
    189   O << "," << FPUTopSavedRegOff << '\n';
    190 }
    191 
    192 // Print a 32 bit hex number with all numbers.
    193 void MipsAsmPrinter::printHex32(unsigned Value, raw_ostream &O) {
    194   O << "0x";
    195   for (int i = 7; i >= 0; i--)
    196     O.write_hex((Value & (0xF << (i*4))) >> (i*4));
    197 }
    198 
    199 //===----------------------------------------------------------------------===//
    200 // Frame and Set directives
    201 //===----------------------------------------------------------------------===//
    202 
    203 /// Frame Directive
    204 void MipsAsmPrinter::emitFrameDirective() {
    205   const TargetRegisterInfo &RI = *TM.getRegisterInfo();
    206 
    207   unsigned stackReg  = RI.getFrameRegister(*MF);
    208   unsigned returnReg = RI.getRARegister();
    209   unsigned stackSize = MF->getFrameInfo()->getStackSize();
    210 
    211   if (OutStreamer.hasRawTextSupport())
    212     OutStreamer.EmitRawText("\t.frame\t$" +
    213            StringRef(MipsInstPrinter::getRegisterName(stackReg)).lower() +
    214            "," + Twine(stackSize) + ",$" +
    215            StringRef(MipsInstPrinter::getRegisterName(returnReg)).lower());
    216 }
    217 
    218 /// Emit Set directives.
    219 const char *MipsAsmPrinter::getCurrentABIString() const {
    220   switch (Subtarget->getTargetABI()) {
    221   case MipsSubtarget::O32:  return "abi32";
    222   case MipsSubtarget::N32:  return "abiN32";
    223   case MipsSubtarget::N64:  return "abi64";
    224   case MipsSubtarget::EABI: return "eabi32"; // TODO: handle eabi64
    225   default: llvm_unreachable("Unknown Mips ABI");
    226   }
    227 }
    228 
    229 void MipsAsmPrinter::EmitFunctionEntryLabel() {
    230   if (OutStreamer.hasRawTextSupport()) {
    231     if (Subtarget->inMips16Mode())
    232       OutStreamer.EmitRawText(StringRef("\t.set\tmips16"));
    233     else
    234       OutStreamer.EmitRawText(StringRef("\t.set\tnomips16"));
    235     // leave out until FSF available gas has micromips changes
    236     // OutStreamer.EmitRawText(StringRef("\t.set\tnomicromips"));
    237     OutStreamer.EmitRawText("\t.ent\t" + Twine(CurrentFnSym->getName()));
    238   }
    239 
    240   if (Subtarget->inMicroMipsMode())
    241     if (MipsELFStreamer *MES = dyn_cast<MipsELFStreamer>(&OutStreamer))
    242       MES->emitMipsSTOCG(*Subtarget, CurrentFnSym,
    243       (unsigned)ELF::STO_MIPS_MICROMIPS);
    244   OutStreamer.EmitLabel(CurrentFnSym);
    245 }
    246 
    247 /// EmitFunctionBodyStart - Targets can override this to emit stuff before
    248 /// the first basic block in the function.
    249 void MipsAsmPrinter::EmitFunctionBodyStart() {
    250   MCInstLowering.Initialize(Mang, &MF->getContext());
    251 
    252   bool IsNakedFunction =
    253     MF->getFunction()->
    254       getAttributes().hasAttribute(AttributeSet::FunctionIndex,
    255                                    Attribute::Naked);
    256   if (!IsNakedFunction)
    257     emitFrameDirective();
    258 
    259   if (OutStreamer.hasRawTextSupport()) {
    260     SmallString<128> Str;
    261     raw_svector_ostream OS(Str);
    262     if (!IsNakedFunction)
    263       printSavedRegsBitmask(OS);
    264     OutStreamer.EmitRawText(OS.str());
    265     if (!Subtarget->inMips16Mode()) {
    266       OutStreamer.EmitRawText(StringRef("\t.set\tnoreorder"));
    267       OutStreamer.EmitRawText(StringRef("\t.set\tnomacro"));
    268       OutStreamer.EmitRawText(StringRef("\t.set\tnoat"));
    269     }
    270   }
    271 }
    272 
    273 /// EmitFunctionBodyEnd - Targets can override this to emit stuff after
    274 /// the last basic block in the function.
    275 void MipsAsmPrinter::EmitFunctionBodyEnd() {
    276   // There are instruction for this macros, but they must
    277   // always be at the function end, and we can't emit and
    278   // break with BB logic.
    279   if (OutStreamer.hasRawTextSupport()) {
    280     if (!Subtarget->inMips16Mode()) {
    281       OutStreamer.EmitRawText(StringRef("\t.set\tat"));
    282       OutStreamer.EmitRawText(StringRef("\t.set\tmacro"));
    283       OutStreamer.EmitRawText(StringRef("\t.set\treorder"));
    284     }
    285     OutStreamer.EmitRawText("\t.end\t" + Twine(CurrentFnSym->getName()));
    286   }
    287 }
    288 
    289 /// isBlockOnlyReachableByFallthough - Return true if the basic block has
    290 /// exactly one predecessor and the control transfer mechanism between
    291 /// the predecessor and this block is a fall-through.
    292 bool MipsAsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock*
    293                                                        MBB) const {
    294   // The predecessor has to be immediately before this block.
    295   const MachineBasicBlock *Pred = *MBB->pred_begin();
    296 
    297   // If the predecessor is a switch statement, assume a jump table
    298   // implementation, so it is not a fall through.
    299   if (const BasicBlock *bb = Pred->getBasicBlock())
    300     if (isa<SwitchInst>(bb->getTerminator()))
    301       return false;
    302 
    303   // If this is a landing pad, it isn't a fall through.  If it has no preds,
    304   // then nothing falls through to it.
    305   if (MBB->isLandingPad() || MBB->pred_empty())
    306     return false;
    307 
    308   // If there isn't exactly one predecessor, it can't be a fall through.
    309   MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI;
    310   ++PI2;
    311 
    312   if (PI2 != MBB->pred_end())
    313     return false;
    314 
    315   // The predecessor has to be immediately before this block.
    316   if (!Pred->isLayoutSuccessor(MBB))
    317     return false;
    318 
    319   // If the block is completely empty, then it definitely does fall through.
    320   if (Pred->empty())
    321     return true;
    322 
    323   // Otherwise, check the last instruction.
    324   // Check if the last terminator is an unconditional branch.
    325   MachineBasicBlock::const_iterator I = Pred->end();
    326   while (I != Pred->begin() && !(--I)->isTerminator()) ;
    327 
    328   return !I->isBarrier();
    329 }
    330 
    331 // Print out an operand for an inline asm expression.
    332 bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
    333                                      unsigned AsmVariant,const char *ExtraCode,
    334                                      raw_ostream &O) {
    335   // Does this asm operand have a single letter operand modifier?
    336   if (ExtraCode && ExtraCode[0]) {
    337     if (ExtraCode[1] != 0) return true; // Unknown modifier.
    338 
    339     const MachineOperand &MO = MI->getOperand(OpNum);
    340     switch (ExtraCode[0]) {
    341     default:
    342       // See if this is a generic print operand
    343       return AsmPrinter::PrintAsmOperand(MI,OpNum,AsmVariant,ExtraCode,O);
    344     case 'X': // hex const int
    345       if ((MO.getType()) != MachineOperand::MO_Immediate)
    346         return true;
    347       O << "0x" << StringRef(utohexstr(MO.getImm())).lower();
    348       return false;
    349     case 'x': // hex const int (low 16 bits)
    350       if ((MO.getType()) != MachineOperand::MO_Immediate)
    351         return true;
    352       O << "0x" << StringRef(utohexstr(MO.getImm() & 0xffff)).lower();
    353       return false;
    354     case 'd': // decimal const int
    355       if ((MO.getType()) != MachineOperand::MO_Immediate)
    356         return true;
    357       O << MO.getImm();
    358       return false;
    359     case 'm': // decimal const int minus 1
    360       if ((MO.getType()) != MachineOperand::MO_Immediate)
    361         return true;
    362       O << MO.getImm() - 1;
    363       return false;
    364     case 'z': {
    365       // $0 if zero, regular printing otherwise
    366       if (MO.getType() != MachineOperand::MO_Immediate)
    367         return true;
    368       int64_t Val = MO.getImm();
    369       if (Val)
    370         O << Val;
    371       else
    372         O << "$0";
    373       return false;
    374     }
    375     case 'D': // Second part of a double word register operand
    376     case 'L': // Low order register of a double word register operand
    377     case 'M': // High order register of a double word register operand
    378     {
    379       if (OpNum == 0)
    380         return true;
    381       const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1);
    382       if (!FlagsOP.isImm())
    383         return true;
    384       unsigned Flags = FlagsOP.getImm();
    385       unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags);
    386       // Number of registers represented by this operand. We are looking
    387       // for 2 for 32 bit mode and 1 for 64 bit mode.
    388       if (NumVals != 2) {
    389         if (Subtarget->isGP64bit() && NumVals == 1 && MO.isReg()) {
    390           unsigned Reg = MO.getReg();
    391           O << '$' << MipsInstPrinter::getRegisterName(Reg);
    392           return false;
    393         }
    394         return true;
    395       }
    396 
    397       unsigned RegOp = OpNum;
    398       if (!Subtarget->isGP64bit()){
    399         // Endianess reverses which register holds the high or low value
    400         // between M and L.
    401         switch(ExtraCode[0]) {
    402         case 'M':
    403           RegOp = (Subtarget->isLittle()) ? OpNum + 1 : OpNum;
    404           break;
    405         case 'L':
    406           RegOp = (Subtarget->isLittle()) ? OpNum : OpNum + 1;
    407           break;
    408         case 'D': // Always the second part
    409           RegOp = OpNum + 1;
    410         }
    411         if (RegOp >= MI->getNumOperands())
    412           return true;
    413         const MachineOperand &MO = MI->getOperand(RegOp);
    414         if (!MO.isReg())
    415           return true;
    416         unsigned Reg = MO.getReg();
    417         O << '$' << MipsInstPrinter::getRegisterName(Reg);
    418         return false;
    419       }
    420     }
    421     }
    422   }
    423 
    424   printOperand(MI, OpNum, O);
    425   return false;
    426 }
    427 
    428 bool MipsAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
    429                                            unsigned OpNum, unsigned AsmVariant,
    430                                            const char *ExtraCode,
    431                                            raw_ostream &O) {
    432   int Offset = 0;
    433   // Currently we are expecting either no ExtraCode or 'D'
    434   if (ExtraCode) {
    435     if (ExtraCode[0] == 'D')
    436       Offset = 4;
    437     else
    438       return true; // Unknown modifier.
    439   }
    440 
    441   const MachineOperand &MO = MI->getOperand(OpNum);
    442   assert(MO.isReg() && "unexpected inline asm memory operand");
    443   O << Offset << "($" << MipsInstPrinter::getRegisterName(MO.getReg()) << ")";
    444 
    445   return false;
    446 }
    447 
    448 void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
    449                                   raw_ostream &O) {
    450   const MachineOperand &MO = MI->getOperand(opNum);
    451   bool closeP = false;
    452 
    453   if (MO.getTargetFlags())
    454     closeP = true;
    455 
    456   switch(MO.getTargetFlags()) {
    457   case MipsII::MO_GPREL:    O << "%gp_rel("; break;
    458   case MipsII::MO_GOT_CALL: O << "%call16("; break;
    459   case MipsII::MO_GOT:      O << "%got(";    break;
    460   case MipsII::MO_ABS_HI:   O << "%hi(";     break;
    461   case MipsII::MO_ABS_LO:   O << "%lo(";     break;
    462   case MipsII::MO_TLSGD:    O << "%tlsgd(";  break;
    463   case MipsII::MO_GOTTPREL: O << "%gottprel("; break;
    464   case MipsII::MO_TPREL_HI: O << "%tprel_hi("; break;
    465   case MipsII::MO_TPREL_LO: O << "%tprel_lo("; break;
    466   case MipsII::MO_GPOFF_HI: O << "%hi(%neg(%gp_rel("; break;
    467   case MipsII::MO_GPOFF_LO: O << "%lo(%neg(%gp_rel("; break;
    468   case MipsII::MO_GOT_DISP: O << "%got_disp("; break;
    469   case MipsII::MO_GOT_PAGE: O << "%got_page("; break;
    470   case MipsII::MO_GOT_OFST: O << "%got_ofst("; break;
    471   }
    472 
    473   switch (MO.getType()) {
    474     case MachineOperand::MO_Register:
    475       O << '$'
    476         << StringRef(MipsInstPrinter::getRegisterName(MO.getReg())).lower();
    477       break;
    478 
    479     case MachineOperand::MO_Immediate:
    480       O << MO.getImm();
    481       break;
    482 
    483     case MachineOperand::MO_MachineBasicBlock:
    484       O << *MO.getMBB()->getSymbol();
    485       return;
    486 
    487     case MachineOperand::MO_GlobalAddress:
    488       O << *Mang->getSymbol(MO.getGlobal());
    489       break;
    490 
    491     case MachineOperand::MO_BlockAddress: {
    492       MCSymbol *BA = GetBlockAddressSymbol(MO.getBlockAddress());
    493       O << BA->getName();
    494       break;
    495     }
    496 
    497     case MachineOperand::MO_ExternalSymbol:
    498       O << *GetExternalSymbolSymbol(MO.getSymbolName());
    499       break;
    500 
    501     case MachineOperand::MO_JumpTableIndex:
    502       O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
    503         << '_' << MO.getIndex();
    504       break;
    505 
    506     case MachineOperand::MO_ConstantPoolIndex:
    507       O << MAI->getPrivateGlobalPrefix() << "CPI"
    508         << getFunctionNumber() << "_" << MO.getIndex();
    509       if (MO.getOffset())
    510         O << "+" << MO.getOffset();
    511       break;
    512 
    513     default:
    514       llvm_unreachable("<unknown operand type>");
    515   }
    516 
    517   if (closeP) O << ")";
    518 }
    519 
    520 void MipsAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum,
    521                                       raw_ostream &O) {
    522   const MachineOperand &MO = MI->getOperand(opNum);
    523   if (MO.isImm())
    524     O << (unsigned short int)MO.getImm();
    525   else
    526     printOperand(MI, opNum, O);
    527 }
    528 
    529 void MipsAsmPrinter::
    530 printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O) {
    531   // Load/Store memory operands -- imm($reg)
    532   // If PIC target the target is loaded as the
    533   // pattern lw $25,%call16($28)
    534   printOperand(MI, opNum+1, O);
    535   O << "(";
    536   printOperand(MI, opNum, O);
    537   O << ")";
    538 }
    539 
    540 void MipsAsmPrinter::
    541 printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O) {
    542   // when using stack locations for not load/store instructions
    543   // print the same way as all normal 3 operand instructions.
    544   printOperand(MI, opNum, O);
    545   O << ", ";
    546   printOperand(MI, opNum+1, O);
    547   return;
    548 }
    549 
    550 void MipsAsmPrinter::
    551 printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
    552                 const char *Modifier) {
    553   const MachineOperand &MO = MI->getOperand(opNum);
    554   O << Mips::MipsFCCToString((Mips::CondCode)MO.getImm());
    555 }
    556 
    557 void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) {
    558   // FIXME: Use SwitchSection.
    559 
    560   // TODO: Need to add -mabicalls and -mno-abicalls flags.
    561   // Currently we assume that -mabicalls is the default.
    562   if (OutStreamer.hasRawTextSupport()) {
    563     OutStreamer.EmitRawText(StringRef("\t.abicalls"));
    564     Reloc::Model RM = Subtarget->getRelocationModel();
    565     if (RM == Reloc::Static && !Subtarget->hasMips64())
    566       OutStreamer.EmitRawText(StringRef("\t.option\tpic0"));
    567   }
    568 
    569   // Tell the assembler which ABI we are using
    570   if (OutStreamer.hasRawTextSupport())
    571     OutStreamer.EmitRawText("\t.section .mdebug." +
    572                             Twine(getCurrentABIString()));
    573 
    574   // TODO: handle O64 ABI
    575   if (OutStreamer.hasRawTextSupport()) {
    576     if (Subtarget->isABI_EABI()) {
    577       if (Subtarget->isGP32bit())
    578         OutStreamer.EmitRawText(StringRef("\t.section .gcc_compiled_long32"));
    579       else
    580         OutStreamer.EmitRawText(StringRef("\t.section .gcc_compiled_long64"));
    581     }
    582   }
    583 
    584   // return to previous section
    585   if (OutStreamer.hasRawTextSupport())
    586     OutStreamer.EmitRawText(StringRef("\t.previous"));
    587 
    588 }
    589 
    590 void MipsAsmPrinter::EmitEndOfAsmFile(Module &M) {
    591 
    592   if (OutStreamer.hasRawTextSupport()) return;
    593 
    594   // Emit Mips ELF register info
    595   Subtarget->getMReginfo().emitMipsReginfoSectionCG(
    596              OutStreamer, getObjFileLowering(), *Subtarget);
    597   if (MipsELFStreamer *MES = dyn_cast<MipsELFStreamer>(&OutStreamer))
    598     MES->emitELFHeaderFlagsCG(*Subtarget);
    599 }
    600 
    601 void MipsAsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
    602                                            raw_ostream &OS) {
    603   // TODO: implement
    604 }
    605 
    606 // Force static initialization.
    607 extern "C" void LLVMInitializeMipsAsmPrinter() {
    608   RegisterAsmPrinter<MipsAsmPrinter> X(TheMipsTarget);
    609   RegisterAsmPrinter<MipsAsmPrinter> Y(TheMipselTarget);
    610   RegisterAsmPrinter<MipsAsmPrinter> A(TheMips64Target);
    611   RegisterAsmPrinter<MipsAsmPrinter> B(TheMips64elTarget);
    612 }
    613