18f5e8c1cd69fa77bea20140a7132ee2dea166c6dJia Liu//===-- MipsAsmPrinter.h - Mips LLVM Assembly Printer ----------*- C++ -*--===//
2aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka//
3aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka//                     The LLVM Compiler Infrastructure
4aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka//
5aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka// This file is distributed under the University of Illinois Open Source
6aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka// License. See LICENSE.TXT for details.
7aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka//
8aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka//===----------------------------------------------------------------------===//
9aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka//
10aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka// Mips Assembly printer class.
11aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka//
12aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka//===----------------------------------------------------------------------===//
13aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka
1437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#ifndef LLVM_LIB_TARGET_MIPS_MIPSASMPRINTER_H
1537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#define LLVM_LIB_TARGET_MIPS_MIPSASMPRINTER_H
16aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka
1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "Mips16HardFloatInfo.h"
18f93b86306683f8e860c8824efb717995cb072a70Akira Hatanaka#include "MipsMCInstLower.h"
19a1514e24cc24b050f53a12650e047799358833a1Chandler Carruth#include "MipsMachineFunction.h"
20aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka#include "MipsSubtarget.h"
21aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka#include "llvm/CodeGen/AsmPrinter.h"
22aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka#include "llvm/Support/Compiler.h"
23aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka#include "llvm/Target/TargetMachine.h"
24aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka
25aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanakanamespace llvm {
26aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanakaclass MCStreamer;
27aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanakaclass MachineInstr;
28aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanakaclass MachineBasicBlock;
29320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolaclass MipsTargetStreamer;
30aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanakaclass Module;
3179aa3417eb6f58d668aadfedf075240a41d35a26Craig Topperclass raw_ostream;
32aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka
33aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanakaclass LLVM_LIBRARY_VISIBILITY MipsAsmPrinter : public AsmPrinter {
34ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  MipsTargetStreamer &getTargetStreamer() const;
35421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka
36f93b86306683f8e860c8824efb717995cb072a70Akira Hatanaka  void EmitInstrWithMacroNoAT(const MachineInstr *MI);
37f93b86306683f8e860c8824efb717995cb072a70Akira Hatanaka
38cc46fe591af10c193c17323547a3dd7cc00c925dAkira Hatanakaprivate:
39cc46fe591af10c193c17323547a3dd7cc00c925dAkira Hatanaka  // tblgen'erated function.
40cc46fe591af10c193c17323547a3dd7cc00c925dAkira Hatanaka  bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
41cc46fe591af10c193c17323547a3dd7cc00c925dAkira Hatanaka                                   const MachineInstr *MI);
42cc46fe591af10c193c17323547a3dd7cc00c925dAkira Hatanaka
43c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // Emit PseudoReturn, PseudoReturn64, PseudoIndirectBranch,
44c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // and PseudoIndirectBranch64 as a JR, JR_MM, JALR, or JALR64 as appropriate
45c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // for the target.
46c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  void emitPseudoIndirectBranch(MCStreamer &OutStreamer,
47c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                const MachineInstr *MI);
48c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
49cc46fe591af10c193c17323547a3dd7cc00c925dAkira Hatanaka  // lowerOperand - Convert a MachineOperand into the equivalent MCOperand.
50cc46fe591af10c193c17323547a3dd7cc00c925dAkira Hatanaka  bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp);
51cc46fe591af10c193c17323547a3dd7cc00c925dAkira Hatanaka
52cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler  /// MCP - Keep a pointer to constantpool entries of the current
53cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler  /// MachineFunction.
54cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler  const MachineConstantPool *MCP;
55cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler
56cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler  /// InConstantPool - Maintain state when emitting a sequence of constant
57cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler  /// pool entries so we can properly mark them as data regions.
58cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler  bool InConstantPool;
59cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler
6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::map<const char *, const llvm::Mips16HardFloatInfo::FuncSignature *>
6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  StubsNeeded;
6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
63ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void emitInlineAsmStart() const override;
6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
65ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
66ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                        const MCSubtargetInfo *EndInfo) const override;
6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
68ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void EmitJal(const MCSubtargetInfo &STI, MCSymbol *Symbol);
6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
70ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void EmitInstrReg(const MCSubtargetInfo &STI, unsigned Opcode, unsigned Reg);
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
72ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void EmitInstrRegReg(const MCSubtargetInfo &STI, unsigned Opcode,
73ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                       unsigned Reg1, unsigned Reg2);
7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
75ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void EmitInstrRegRegReg(const MCSubtargetInfo &STI, unsigned Opcode,
76ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                          unsigned Reg1, unsigned Reg2, unsigned Reg3);
77ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
78ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void EmitMovFPIntPair(const MCSubtargetInfo &STI, unsigned MovOpc,
79ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                        unsigned Reg1, unsigned Reg2, unsigned FPReg1,
80ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                        unsigned FPReg2, bool LE);
81ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
82ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void EmitSwapFPIntParams(const MCSubtargetInfo &STI,
83ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                           Mips16HardFloatInfo::FPParamVariant, bool LE,
8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                           bool ToFP);
8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
86ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void EmitSwapFPIntRetval(const MCSubtargetInfo &STI,
87ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                           Mips16HardFloatInfo::FPReturnVariant, bool LE);
8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitFPCallStub(const char *, const Mips16HardFloatInfo::FuncSignature *);
9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void NaClAlignIndirectJumpTargets(MachineFunction &MF);
92cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler
93dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isLongBranchPseudo(int Opcode) const;
94dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
95aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanakapublic:
96421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka
97421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka  const MipsSubtarget *Subtarget;
98f93b86306683f8e860c8824efb717995cb072a70Akira Hatanaka  const MipsFunctionInfo *MipsFI;
99f93b86306683f8e860c8824efb717995cb072a70Akira Hatanaka  MipsMCInstLower MCInstLowering;
100421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka
101ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  explicit MipsAsmPrinter(TargetMachine &TM,
102ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                          std::unique_ptr<MCStreamer> Streamer)
103ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      : AsmPrinter(TM, std::move(Streamer)), MCP(nullptr),
104ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        InConstantPool(false), MCInstLowering(*this) {}
105aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka
106dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const char *getPassName() const override {
107aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka    return "Mips Assembly Printer";
108aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka  }
109aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka
110dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool runOnMachineFunction(MachineFunction &MF) override;
111f93b86306683f8e860c8824efb717995cb072a70Akira Hatanaka
112dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void EmitConstantPool() override {
11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool UsingConstantPools =
11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      (Subtarget->inMips16Mode() && Subtarget->useConstantIslands());
115cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler    if (!UsingConstantPools)
116cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler      AsmPrinter::EmitConstantPool();
117cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler    // we emit constant pools customly!
118cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler  }
119cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler
120dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void EmitInstruction(const MachineInstr *MI) override;
12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void printSavedRegsBitmask();
122aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka  void emitFrameDirective();
123aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka  const char *getCurrentABIString() const;
124dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void EmitFunctionEntryLabel() override;
125dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void EmitFunctionBodyStart() override;
126dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void EmitFunctionBodyEnd() override;
127dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isBlockOnlyReachableByFallthrough(
128dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                   const MachineBasicBlock* MBB) const override;
129aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka  bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
130aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka                       unsigned AsmVariant, const char *ExtraCode,
131dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                       raw_ostream &O) override;
132aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka  bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
133aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka                             unsigned AsmVariant, const char *ExtraCode,
134dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                             raw_ostream &O) override;
135aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka  void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
136aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka  void printUnsignedImm(const MachineInstr *MI, int opNum, raw_ostream &O);
137bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders  void printUnsignedImm8(const MachineInstr *MI, int opNum, raw_ostream &O);
13803236be44af1d98eb8daa57e8eb8b7bdd7884523Akira Hatanaka  void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
13903236be44af1d98eb8daa57e8eb8b7bdd7884523Akira Hatanaka  void printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O);
140aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka  void printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
141dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                       const char *Modifier = nullptr);
14237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  void printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O);
143dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void EmitStartOfAsmFile(Module &M) override;
144dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void EmitEndOfAsmFile(Module &M) override;
145aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka  void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
146aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka};
147aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka}
148aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka
149aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka#endif
150aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka
151