MipsAsmPrinter.cpp revision a4485c49641a492688276a061ddd0cb38d38e270
1972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//===-- MipsAsmPrinter.cpp - Mips LLVM assembly writer --------------------===//
2972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//
3972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//                     The LLVM Compiler Infrastructure
4972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//
8972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//===----------------------------------------------------------------------===//
9972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//
10972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes// This file contains a printer that converts from our internal representation
11972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes// of machine-dependent LLVM code to GAS-format MIPS assembly language.
12972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//
13972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//===----------------------------------------------------------------------===//
14972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
15972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#define DEBUG_TYPE "mips-asm-printer"
16972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "Mips.h"
1743d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes#include "MipsSubtarget.h"
18972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "MipsInstrInfo.h"
19972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "MipsTargetMachine.h"
20a4e8200366805c665bb1424d8af5550f5d3d6863Bruno Cardoso Lopes#include "MipsMachineFunction.h"
2146773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes#include "llvm/BasicBlock.h"
2246773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes#include "llvm/Instructions.h"
23972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "llvm/CodeGen/AsmPrinter.h"
24972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "llvm/CodeGen/MachineFunctionPass.h"
25972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "llvm/CodeGen/MachineConstantPool.h"
26a4e8200366805c665bb1424d8af5550f5d3d6863Bruno Cardoso Lopes#include "llvm/CodeGen/MachineFrameInfo.h"
27972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "llvm/CodeGen/MachineInstr.h"
286c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h"
29af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner#include "llvm/MC/MCAsmInfo.h"
30325d3dcfe4d5efc91db0f59b20a72a11dea024edChris Lattner#include "llvm/MC/MCSymbol.h"
31d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner#include "llvm/Target/Mangler.h"
32972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "llvm/Target/TargetData.h"
3381092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes#include "llvm/Target/TargetLoweringObjectFile.h"
34972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "llvm/Target/TargetMachine.h"
35753a98740bfe3164fd0961a1959306c46135cf19Bruno Cardoso Lopes#include "llvm/Target/TargetOptions.h"
3651b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar#include "llvm/Target/TargetRegistry.h"
377ad07c46362500f7291a92742569e94fd3538dfdChris Lattner#include "llvm/ADT/SmallString.h"
38972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "llvm/ADT/StringExtras.h"
39b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner#include "llvm/ADT/Twine.h"
40b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner#include "llvm/Support/raw_ostream.h"
41972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopesusing namespace llvm;
42972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
43972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopesnamespace {
446726b6d75a8b679068a58cb954ba97cf9d1690baNick Lewycky  class MipsAsmPrinter : public AsmPrinter {
4543d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes    const MipsSubtarget *Subtarget;
4657f0db833dc30404f1f5d28b23df326e520698ecBill Wendling  public:
47b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner    explicit MipsAsmPrinter(TargetMachine &TM,  MCStreamer &Streamer)
48b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner      : AsmPrinter(TM, Streamer) {
4943d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes      Subtarget = &TM.getSubtarget<MipsSubtarget>();
5043d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes    }
51972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
52972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes    virtual const char *getPassName() const {
53972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes      return "Mips Assembly Printer";
54972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes    }
55972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
5681092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes    bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
57c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                         unsigned AsmVariant, const char *ExtraCode,
58c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                         raw_ostream &O);
5935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
6035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printUnsignedImm(const MachineInstr *MI, int opNum, raw_ostream &O);
6181092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes    void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
62972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes                         const char *Modifier = 0);
6381092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes    void printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
64225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes                         const char *Modifier = 0);
6535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printSavedRegsBitmask(raw_ostream &O);
6635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printHex32(unsigned int Value, raw_ostream &O);
67dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes
689d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    const char *getCurrentABIString() const;
699d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    void emitFrameDirective();
70ae408e6f1e4e2e7658b76b8dec679aeae9a9df99Anton Korobeynikov
7135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printInstruction(const MachineInstr *MI, raw_ostream &O); // autogen'd.
72d1ff72b8a797304f146e4293db8c814231ea8cb3Chris Lattner    void EmitInstruction(const MachineInstr *MI) {
737ad07c46362500f7291a92742569e94fd3538dfdChris Lattner      SmallString<128> Str;
747ad07c46362500f7291a92742569e94fd3538dfdChris Lattner      raw_svector_ostream OS(Str);
757ad07c46362500f7291a92742569e94fd3538dfdChris Lattner      printInstruction(MI, OS);
767ad07c46362500f7291a92742569e94fd3538dfdChris Lattner      OutStreamer.EmitRawText(OS.str());
77d1ff72b8a797304f146e4293db8c814231ea8cb3Chris Lattner    }
78a34103f6fa6f21025518596efc73631eb899410bChris Lattner    virtual void EmitFunctionBodyStart();
79a34103f6fa6f21025518596efc73631eb899410bChris Lattner    virtual void EmitFunctionBodyEnd();
8046773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes    virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const;
81d95148f073c31924f275a34296da52a7cdefad91Chris Lattner    static const char *getRegisterName(unsigned RegNo);
8205af2616d0df19638e799d3e7afadea26d96a4baChris Lattner
835006071f7a75b81ea9b4cb18d8352e612bb787ecChris Lattner    virtual void EmitFunctionEntryLabel();
84812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson    void EmitStartOfAsmFile(Module &M);
85972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  };
86972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes} // end of anonymous namespace
87972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
88972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "MipsGenAsmWriter.inc"
89972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
90dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes//===----------------------------------------------------------------------===//
91dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes//
92dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes//  Mips Asm Directives
93dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes//
94dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes//  -- Frame directive "frame Stackpointer, Stacksize, RARegister"
95dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes//  Describe the stack frame.
96dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes//
9781092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes//  -- Mask directives "(f)mask  bitmask, offset"
98dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes//  Tells the assembler which registers are saved and where.
9981092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes//  bitmask - contain a little endian bitset indicating which registers are
10081092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes//            saved on function prologue (e.g. with a 0x80000000 mask, the
101dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes//            assembler knows the register 31 (RA) is saved at prologue.
10281092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes//  offset  - the position before stack pointer subtraction indicating where
103dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes//            the first saved register on prologue is located. (e.g. with a
104dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes//
105dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes//  Consider the following function prologue:
106dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes//
1076ef781f3ce0d0311004adba9d1e7dbd7950918ddBill Wendling//    .frame  $fp,48,$ra
1086ef781f3ce0d0311004adba9d1e7dbd7950918ddBill Wendling//    .mask   0xc0000000,-8
1096ef781f3ce0d0311004adba9d1e7dbd7950918ddBill Wendling//       addiu $sp, $sp, -48
1106ef781f3ce0d0311004adba9d1e7dbd7950918ddBill Wendling//       sw $ra, 40($sp)
1116ef781f3ce0d0311004adba9d1e7dbd7950918ddBill Wendling//       sw $fp, 36($sp)
112dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes//
11381092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes//    With a 0xc0000000 mask, the assembler knows the register 31 (RA) and
11481092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes//    30 (FP) are saved at prologue. As the save order on prologue is from
11581092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes//    left to right, RA is saved first. A -8 offset means that after the
116dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes//    stack pointer subtration, the first register in the mask (RA) will be
117dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes//    saved at address 48-8=40.
118dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes//
119dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes//===----------------------------------------------------------------------===//
120a4e8200366805c665bb1424d8af5550f5d3d6863Bruno Cardoso Lopes
12143d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes//===----------------------------------------------------------------------===//
12243d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes// Mask directives
12343d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes//===----------------------------------------------------------------------===//
12443d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes
12581092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes// Create a bitmask with all callee saved registers for CPU or Floating Point
126bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes// registers. For CPU registers consider RA, GP and FP for saving if necessary.
12735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid MipsAsmPrinter::printSavedRegsBitmask(raw_ostream &O) {
12816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = TM.getFrameLowering();
129d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  const TargetRegisterInfo *RI = TM.getRegisterInfo();
130a34103f6fa6f21025518596efc73631eb899410bChris Lattner  const MipsFunctionInfo *MipsFI = MF->getInfo<MipsFunctionInfo>();
131d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
132bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes  // CPU and FPU Saved Registers Bitmasks
133bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes  unsigned int CPUBitmask = 0;
134bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes  unsigned int FPUBitmask = 0;
135dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes
136bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes  // Set the CPU and FPU Bitmasks
137a34103f6fa6f21025518596efc73631eb899410bChris Lattner  const MachineFrameInfo *MFI = MF->getFrameInfo();
138dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
139bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
14042d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola    unsigned Reg = CSI[i].getReg();
14142d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola    unsigned RegNum = MipsRegisterInfo::getRegisterNumbering(Reg);
14242d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola    if (Mips::CPURegsRegisterClass->contains(Reg))
143bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes      CPUBitmask |= (1 << RegNum);
144bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes    else
145bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes      FPUBitmask |= (1 << RegNum);
146bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes  }
147dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes
148bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes  // Return Address and Frame registers must also be set in CPUBitmask.
14916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  // FIXME: Do we really need hasFP() call here? When no FP is present SP is
15016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  // just returned -- will it be ok?
151d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (TFI->hasFP(*MF))
152bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes    CPUBitmask |= (1 << MipsRegisterInfo::
153d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov                getRegisterNumbering(RI->getFrameRegister(*MF)));
154d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
155d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (MFI->adjustsStack())
156bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes    CPUBitmask |= (1 << MipsRegisterInfo::
157d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov                getRegisterNumbering(RI->getRARegister()));
158dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes
159bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes  // Print CPUBitmask
16035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  O << "\t.mask \t"; printHex32(CPUBitmask, O);
16135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  O << ',' << MipsFI->getCPUTopSavedRegOff() << '\n';
162bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes
163bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes  // Print FPUBitmask
16435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  O << "\t.fmask\t"; printHex32(FPUBitmask, O); O << ","
165bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes    << MipsFI->getFPUTopSavedRegOff() << '\n';
166dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes}
167dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes
168dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes// Print a 32 bit hex number with all numbers.
16935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid MipsAsmPrinter::printHex32(unsigned Value, raw_ostream &O) {
170cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson  O << "0x";
17181092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes  for (int i = 7; i >= 0; i--)
17235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    O << utohexstr((Value & (0xF << (i*4))) >> (i*4));
173a4e8200366805c665bb1424d8af5550f5d3d6863Bruno Cardoso Lopes}
174a4e8200366805c665bb1424d8af5550f5d3d6863Bruno Cardoso Lopes
17543d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes//===----------------------------------------------------------------------===//
17643d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes// Frame and Set directives
17743d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes//===----------------------------------------------------------------------===//
17843d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes
17943d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes/// Frame Directive
1809d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattnervoid MipsAsmPrinter::emitFrameDirective() {
18143d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes  const TargetRegisterInfo &RI = *TM.getRegisterInfo();
18243d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes
183a34103f6fa6f21025518596efc73631eb899410bChris Lattner  unsigned stackReg  = RI.getFrameRegister(*MF);
18443d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes  unsigned returnReg = RI.getRARegister();
185a34103f6fa6f21025518596efc73631eb899410bChris Lattner  unsigned stackSize = MF->getFrameInfo()->getStackSize();
18643d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes
1879d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  OutStreamer.EmitRawText("\t.frame\t$" +
1889d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                          Twine(LowercaseString(getRegisterName(stackReg))) +
1899d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                          "," + Twine(stackSize) + ",$" +
1909d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                          Twine(LowercaseString(getRegisterName(returnReg))));
19143d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes}
19243d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes
19343d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes/// Emit Set directives.
19481092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopesconst char *MipsAsmPrinter::getCurrentABIString() const {
1959d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  switch (Subtarget->getTargetABI()) {
19681092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes  case MipsSubtarget::O32:  return "abi32";
1979d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  case MipsSubtarget::O64:  return "abiO64";
1989d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  case MipsSubtarget::N32:  return "abiN32";
1999d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  case MipsSubtarget::N64:  return "abi64";
2009d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  case MipsSubtarget::EABI: return "eabi32"; // TODO: handle eabi64
2019d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  default: break;
20243d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes  }
20343d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes
204c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  llvm_unreachable("Unknown Mips ABI");
20543d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes  return NULL;
20681092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes}
20743d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes
2085006071f7a75b81ea9b4cb18d8352e612bb787ecChris Lattnervoid MipsAsmPrinter::EmitFunctionEntryLabel() {
2099d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  OutStreamer.EmitRawText("\t.ent\t" + Twine(CurrentFnSym->getName()));
2105006071f7a75b81ea9b4cb18d8352e612bb787ecChris Lattner  OutStreamer.EmitLabel(CurrentFnSym);
2115006071f7a75b81ea9b4cb18d8352e612bb787ecChris Lattner}
2125006071f7a75b81ea9b4cb18d8352e612bb787ecChris Lattner
213a34103f6fa6f21025518596efc73631eb899410bChris Lattner/// EmitFunctionBodyStart - Targets can override this to emit stuff before
214a34103f6fa6f21025518596efc73631eb899410bChris Lattner/// the first basic block in the function.
215a34103f6fa6f21025518596efc73631eb899410bChris Lattnervoid MipsAsmPrinter::EmitFunctionBodyStart() {
2169d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  emitFrameDirective();
21781092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes
2189d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  SmallString<128> Str;
2199d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  raw_svector_ostream OS(Str);
2209d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  printSavedRegsBitmask(OS);
2219d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  OutStreamer.EmitRawText(OS.str());
222a34103f6fa6f21025518596efc73631eb899410bChris Lattner}
223972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
224a34103f6fa6f21025518596efc73631eb899410bChris Lattner/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
225a34103f6fa6f21025518596efc73631eb899410bChris Lattner/// the last basic block in the function.
226a34103f6fa6f21025518596efc73631eb899410bChris Lattnervoid MipsAsmPrinter::EmitFunctionBodyEnd() {
227745ec06ad2fa533e9ef47ce572c3a03547376224Chris Lattner  // There are instruction for this macros, but they must
228745ec06ad2fa533e9ef47ce572c3a03547376224Chris Lattner  // always be at the function end, and we can't emit and
22981092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes  // break with BB logic.
2309d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  OutStreamer.EmitRawText(StringRef("\t.set\tmacro"));
2319d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  OutStreamer.EmitRawText(StringRef("\t.set\treorder"));
2329d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  OutStreamer.EmitRawText("\t.end\t" + Twine(CurrentFnSym->getName()));
233972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes}
234972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
235a34103f6fa6f21025518596efc73631eb899410bChris Lattner
23646773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes/// isBlockOnlyReachableByFallthough - Return true if the basic block has
23746773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes/// exactly one predecessor and the control transfer mechanism between
23846773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes/// the predecessor and this block is a fall-through.
23981092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopesbool MipsAsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB)
24046773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes    const {
24146773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes  // The predecessor has to be immediately before this block.
24246773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes  const MachineBasicBlock *Pred = *MBB->pred_begin();
24346773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes
24446773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes  // If the predecessor is a switch statement, assume a jump table
24546773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes  // implementation, so it is not a fall through.
24646773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes  if (const BasicBlock *bb = Pred->getBasicBlock())
24746773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes    if (isa<SwitchInst>(bb->getTerminator()))
24846773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes      return false;
24981092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes
250a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka  // If this is a landing pad, it isn't a fall through.  If it has no preds,
251a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka  // then nothing falls through to it.
252a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka  if (MBB->isLandingPad() || MBB->pred_empty())
253a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka    return false;
254a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka
255a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka  // If there isn't exactly one predecessor, it can't be a fall through.
256a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka  MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI;
257a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka  ++PI2;
258a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka
259a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka  if (PI2 != MBB->pred_end())
260a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka    return false;
261a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka
262a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka  // The predecessor has to be immediately before this block.
263a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka  if (!Pred->isLayoutSuccessor(MBB))
264a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka    return false;
265a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka
266a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka  // If the block is completely empty, then it definitely does fall through.
267a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka  if (Pred->empty())
268a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka    return true;
269a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka
270a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka  // Otherwise, check the last instruction.
271a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka  // Check if the last terminator is an unconditional branch.
272a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka  MachineBasicBlock::const_iterator I = Pred->end();
273a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka  while (I != Pred->begin() && !(--I)->getDesc().isTerminator());
274a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka
275a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka  return !I->getDesc().isBarrier();
27646773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes}
27746773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes
27891ef849e6cb01a019dc50ed4e95c058e01616062Bruno Cardoso Lopes// Print out an operand for an inline asm expression.
27981092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopesbool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
280c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                     unsigned AsmVariant,const char *ExtraCode,
281c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                     raw_ostream &O) {
28291ef849e6cb01a019dc50ed4e95c058e01616062Bruno Cardoso Lopes  // Does this asm operand have a single letter operand modifier?
28381092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes  if (ExtraCode && ExtraCode[0])
28491ef849e6cb01a019dc50ed4e95c058e01616062Bruno Cardoso Lopes    return true; // Unknown modifier.
28591ef849e6cb01a019dc50ed4e95c058e01616062Bruno Cardoso Lopes
28635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, OpNo, O);
28791ef849e6cb01a019dc50ed4e95c058e01616062Bruno Cardoso Lopes  return false;
28891ef849e6cb01a019dc50ed4e95c058e01616062Bruno Cardoso Lopes}
28991ef849e6cb01a019dc50ed4e95c058e01616062Bruno Cardoso Lopes
29035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
29135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                  raw_ostream &O) {
292972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  const MachineOperand &MO = MI->getOperand(opNum);
293c7db5618f9e5e708b87d9ae6595b3fd510a2a0c0Bruno Cardoso Lopes  bool closeP = false;
294c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes
295c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes  if (MO.getTargetFlags())
2960c80be59c7ccbd844b5dee71b038090052cac07bBruno Cardoso Lopes    closeP = true;
297c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes
298c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes  switch(MO.getTargetFlags()) {
299c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes  case MipsII::MO_GPREL:    O << "%gp_rel("; break;
300c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes  case MipsII::MO_GOT_CALL: O << "%call16("; break;
301ab8d53a56ae707db3f8490b7727eeb05140954c6Bruno Cardoso Lopes  case MipsII::MO_GOT: {
302ab8d53a56ae707db3f8490b7727eeb05140954c6Bruno Cardoso Lopes    const MachineOperand &LastMO = MI->getOperand(opNum-1);
303ab8d53a56ae707db3f8490b7727eeb05140954c6Bruno Cardoso Lopes    bool LastMOIsGP = LastMO.getType() == MachineOperand::MO_Register
304ab8d53a56ae707db3f8490b7727eeb05140954c6Bruno Cardoso Lopes                      && LastMO.getReg() == Mips::GP;
305ab8d53a56ae707db3f8490b7727eeb05140954c6Bruno Cardoso Lopes    if (MI->getOpcode() == Mips::LW || LastMOIsGP)
306c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes      O << "%got(";
307dcace5c6209bdcb66d6b030b461b07a15ee569c9Bruno Cardoso Lopes    else
3080c80be59c7ccbd844b5dee71b038090052cac07bBruno Cardoso Lopes      O << "%lo(";
309c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes    break;
310ab8d53a56ae707db3f8490b7727eeb05140954c6Bruno Cardoso Lopes  }
311c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes  case MipsII::MO_ABS_HILO:
312c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes    if (MI->getOpcode() == Mips::LUi)
313c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes      O << "%hi(";
314c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes    else
31581092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes      O << "%lo(";
316c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes    break;
317972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  }
318c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes
319762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  switch (MO.getType()) {
320972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes    case MachineOperand::MO_Register:
321762ccea600158bb317dcccdff3303e942426cb71Chris Lattner      O << '$' << LowercaseString(getRegisterName(MO.getReg()));
322972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes      break;
323972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
324972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes    case MachineOperand::MO_Immediate:
325739e441311410796d66e6d72426ef0344e0be98fBruno Cardoso Lopes      O << (short int)MO.getImm();
326972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes      break;
327972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
328972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes    case MachineOperand::MO_MachineBasicBlock:
3291b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner      O << *MO.getMBB()->getSymbol();
330972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes      return;
331972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
332972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes    case MachineOperand::MO_GlobalAddress:
333d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner      O << *Mang->getSymbol(MO.getGlobal());
334972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes      break;
335972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
336ca8a2aa921ec8966b1f0708d77e4dc0a6f1a32f8Bruno Cardoso Lopes    case MachineOperand::MO_BlockAddress: {
337ca8a2aa921ec8966b1f0708d77e4dc0a6f1a32f8Bruno Cardoso Lopes      MCSymbol* BA = GetBlockAddressSymbol(MO.getBlockAddress());
338ca8a2aa921ec8966b1f0708d77e4dc0a6f1a32f8Bruno Cardoso Lopes      O << BA->getName();
339ca8a2aa921ec8966b1f0708d77e4dc0a6f1a32f8Bruno Cardoso Lopes      break;
340ca8a2aa921ec8966b1f0708d77e4dc0a6f1a32f8Bruno Cardoso Lopes    }
341ca8a2aa921ec8966b1f0708d77e4dc0a6f1a32f8Bruno Cardoso Lopes
342972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes    case MachineOperand::MO_ExternalSymbol:
34310b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner      O << *GetExternalSymbolSymbol(MO.getSymbolName());
344972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes      break;
345972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
346753a98740bfe3164fd0961a1959306c46135cf19Bruno Cardoso Lopes    case MachineOperand::MO_JumpTableIndex:
34733adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner      O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
34812164414dd3daa6974985eeb2e89bfb93cf07641Chris Lattner        << '_' << MO.getIndex();
349753a98740bfe3164fd0961a1959306c46135cf19Bruno Cardoso Lopes      break;
350753a98740bfe3164fd0961a1959306c46135cf19Bruno Cardoso Lopes
351972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes    case MachineOperand::MO_ConstantPoolIndex:
35233adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner      O << MAI->getPrivateGlobalPrefix() << "CPI"
3538aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner        << getFunctionNumber() << "_" << MO.getIndex();
3542045c47affc0d1462a815175e420f9d6bd3f35c6Bruno Cardoso Lopes      if (MO.getOffset())
3552045c47affc0d1462a815175e420f9d6bd3f35c6Bruno Cardoso Lopes        O << "+" << MO.getOffset();
356972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes      break;
35781092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes
358972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes    default:
359c23197a26f34f559ea9797de51e187087c039c42Torok Edwin      llvm_unreachable("<unknown operand type>");
360972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  }
361972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
362972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  if (closeP) O << ")";
363972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes}
364972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
36535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid MipsAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum,
36635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                      raw_ostream &O) {
367739e441311410796d66e6d72426ef0344e0be98fBruno Cardoso Lopes  const MachineOperand &MO = MI->getOperand(opNum);
368a00adba6a7e9b0f6600cb6c8c627bb0c705d2f59Devang Patel  if (MO.isImm())
369739e441311410796d66e6d72426ef0344e0be98fBruno Cardoso Lopes    O << (unsigned short int)MO.getImm();
37081092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes  else
37135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, opNum, O);
372739e441311410796d66e6d72426ef0344e0be98fBruno Cardoso Lopes}
373739e441311410796d66e6d72426ef0344e0be98fBruno Cardoso Lopes
374739e441311410796d66e6d72426ef0344e0be98fBruno Cardoso Lopesvoid MipsAsmPrinter::
37535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerprintMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
37635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                const char *Modifier) {
377b42abebe36f1dfbd0c779fd1471618c42ed3fec5Bruno Cardoso Lopes  // when using stack locations for not load/store instructions
378b42abebe36f1dfbd0c779fd1471618c42ed3fec5Bruno Cardoso Lopes  // print the same way as all normal 3 operand instructions.
379b42abebe36f1dfbd0c779fd1471618c42ed3fec5Bruno Cardoso Lopes  if (Modifier && !strcmp(Modifier, "stackloc")) {
38035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, opNum+1, O);
381b42abebe36f1dfbd0c779fd1471618c42ed3fec5Bruno Cardoso Lopes    O << ", ";
38235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, opNum, O);
383b42abebe36f1dfbd0c779fd1471618c42ed3fec5Bruno Cardoso Lopes    return;
384b42abebe36f1dfbd0c779fd1471618c42ed3fec5Bruno Cardoso Lopes  }
385b42abebe36f1dfbd0c779fd1471618c42ed3fec5Bruno Cardoso Lopes
38681092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes  // Load/Store memory operands -- imm($reg)
38781092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes  // If PIC target the target is loaded as the
388c7db5618f9e5e708b87d9ae6595b3fd510a2a0c0Bruno Cardoso Lopes  // pattern lw $25,%call16($28)
38935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, opNum, O);
390972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  O << "(";
39135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, opNum+1, O);
392972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  O << ")";
393972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes}
394972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
395225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopesvoid MipsAsmPrinter::
39635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerprintFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
39735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                const char *Modifier) {
398225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes  const MachineOperand& MO = MI->getOperand(opNum);
39981092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes  O << Mips::MipsFCCToString((Mips::CondCode)MO.getImm());
400225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes}
401225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes
402812209a58c5520c604bc9279aa069e5ae066e860Bob Wilsonvoid MipsAsmPrinter::EmitStartOfAsmFile(Module &M) {
4036c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner  // FIXME: Use SwitchSection.
40481092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes
40543d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes  // Tell the assembler which ABI we are using
4069d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  OutStreamer.EmitRawText("\t.section .mdebug." + Twine(getCurrentABIString()));
40743d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes
40843d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes  // TODO: handle O64 ABI
40975e818ad2f6b809ff6644de2a7c2ec35d68c92eaBenjamin Kramer  if (Subtarget->isABI_EABI()) {
4109d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    if (Subtarget->isGP32bit())
4119d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText(StringRef("\t.section .gcc_compiled_long32"));
4129d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    else
4139d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText(StringRef("\t.section .gcc_compiled_long64"));
41475e818ad2f6b809ff6644de2a7c2ec35d68c92eaBenjamin Kramer  }
41543d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes
41643d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes  // return to previous section
41781092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes  OutStreamer.EmitRawText(StringRef("\t.previous"));
418972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes}
419972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
420a96751fc8ff1cc9a225ffbba73de53e2b9e1ae35Bob Wilson// Force static initialization.
42181092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopesextern "C" void LLVMInitializeMipsAsmPrinter() {
4220c795d61878156817cedbac51ec2921f2634c1a5Daniel Dunbar  RegisterAsmPrinter<MipsAsmPrinter> X(TheMipsTarget);
4230c795d61878156817cedbac51ec2921f2634c1a5Daniel Dunbar  RegisterAsmPrinter<MipsAsmPrinter> Y(TheMipselTarget);
42451b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar}
425