1*0b57cec5SDimitry Andric //===- MipsAsmPrinter.h - Mips LLVM Assembly Printer -----------*- C++ -*--===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // Mips Assembly printer class. 10*0b57cec5SDimitry Andric // 11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_MIPS_MIPSASMPRINTER_H 14*0b57cec5SDimitry Andric #define LLVM_LIB_TARGET_MIPS_MIPSASMPRINTER_H 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric #include "Mips16HardFloatInfo.h" 17*0b57cec5SDimitry Andric #include "MipsMCInstLower.h" 18*0b57cec5SDimitry Andric #include "MipsSubtarget.h" 19*0b57cec5SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h" 20*0b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 21*0b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 22*0b57cec5SDimitry Andric #include <algorithm> 23*0b57cec5SDimitry Andric #include <map> 24*0b57cec5SDimitry Andric #include <memory> 25*0b57cec5SDimitry Andric 26*0b57cec5SDimitry Andric namespace llvm { 27*0b57cec5SDimitry Andric 28*0b57cec5SDimitry Andric class MCOperand; 29*0b57cec5SDimitry Andric class MCSubtargetInfo; 30*0b57cec5SDimitry Andric class MCSymbol; 31*0b57cec5SDimitry Andric class MachineBasicBlock; 32*0b57cec5SDimitry Andric class MachineConstantPool; 33*0b57cec5SDimitry Andric class MachineFunction; 34*0b57cec5SDimitry Andric class MachineInstr; 35*0b57cec5SDimitry Andric class MachineOperand; 36*0b57cec5SDimitry Andric class MipsFunctionInfo; 37*0b57cec5SDimitry Andric class MipsTargetStreamer; 38*0b57cec5SDimitry Andric class Module; 39*0b57cec5SDimitry Andric class raw_ostream; 40*0b57cec5SDimitry Andric class TargetMachine; 41*0b57cec5SDimitry Andric 42*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY MipsAsmPrinter : public AsmPrinter { 43*0b57cec5SDimitry Andric MipsTargetStreamer &getTargetStreamer() const; 44*0b57cec5SDimitry Andric 45*0b57cec5SDimitry Andric void EmitInstrWithMacroNoAT(const MachineInstr *MI); 46*0b57cec5SDimitry Andric 47*0b57cec5SDimitry Andric //===------------------------------------------------------------------===// 48*0b57cec5SDimitry Andric // XRay implementation 49*0b57cec5SDimitry Andric //===------------------------------------------------------------------===// 50*0b57cec5SDimitry Andric 51*0b57cec5SDimitry Andric public: 52*0b57cec5SDimitry Andric // XRay-specific lowering for Mips. 53*0b57cec5SDimitry Andric void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI); 54*0b57cec5SDimitry Andric void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI); 55*0b57cec5SDimitry Andric void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI); 56*0b57cec5SDimitry Andric 57*0b57cec5SDimitry Andric private: 58*0b57cec5SDimitry Andric /// MCP - Keep a pointer to constantpool entries of the current 59*0b57cec5SDimitry Andric /// MachineFunction. 60*0b57cec5SDimitry Andric const MachineConstantPool *MCP = nullptr; 61*0b57cec5SDimitry Andric 62*0b57cec5SDimitry Andric /// InConstantPool - Maintain state when emitting a sequence of constant 63*0b57cec5SDimitry Andric /// pool entries so we can properly mark them as data regions. 64*0b57cec5SDimitry Andric bool InConstantPool = false; 65*0b57cec5SDimitry Andric 66*0b57cec5SDimitry Andric std::map<const char *, const Mips16HardFloatInfo::FuncSignature *> 67*0b57cec5SDimitry Andric StubsNeeded; 68*0b57cec5SDimitry Andric 69*0b57cec5SDimitry Andric void EmitSled(const MachineInstr &MI, SledKind Kind); 70*0b57cec5SDimitry Andric 71*0b57cec5SDimitry Andric // tblgen'erated function. 72*0b57cec5SDimitry Andric bool emitPseudoExpansionLowering(MCStreamer &OutStreamer, 73*0b57cec5SDimitry Andric const MachineInstr *MI); 74*0b57cec5SDimitry Andric 75*0b57cec5SDimitry Andric // Emit PseudoReturn, PseudoReturn64, PseudoIndirectBranch, 76*0b57cec5SDimitry Andric // and PseudoIndirectBranch64 as a JR, JR_MM, JALR, or JALR64 as appropriate 77*0b57cec5SDimitry Andric // for the target. 78*0b57cec5SDimitry Andric void emitPseudoIndirectBranch(MCStreamer &OutStreamer, 79*0b57cec5SDimitry Andric const MachineInstr *MI); 80*0b57cec5SDimitry Andric 81*0b57cec5SDimitry Andric // lowerOperand - Convert a MachineOperand into the equivalent MCOperand. 82*0b57cec5SDimitry Andric bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp); 83*0b57cec5SDimitry Andric 84*0b57cec5SDimitry Andric void emitInlineAsmStart() const override; 85*0b57cec5SDimitry Andric 86*0b57cec5SDimitry Andric void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, 87*0b57cec5SDimitry Andric const MCSubtargetInfo *EndInfo) const override; 88*0b57cec5SDimitry Andric 89*0b57cec5SDimitry Andric void EmitJal(const MCSubtargetInfo &STI, MCSymbol *Symbol); 90*0b57cec5SDimitry Andric 91*0b57cec5SDimitry Andric void EmitInstrReg(const MCSubtargetInfo &STI, unsigned Opcode, unsigned Reg); 92*0b57cec5SDimitry Andric 93*0b57cec5SDimitry Andric void EmitInstrRegReg(const MCSubtargetInfo &STI, unsigned Opcode, 94*0b57cec5SDimitry Andric unsigned Reg1, unsigned Reg2); 95*0b57cec5SDimitry Andric 96*0b57cec5SDimitry Andric void EmitInstrRegRegReg(const MCSubtargetInfo &STI, unsigned Opcode, 97*0b57cec5SDimitry Andric unsigned Reg1, unsigned Reg2, unsigned Reg3); 98*0b57cec5SDimitry Andric 99*0b57cec5SDimitry Andric void EmitMovFPIntPair(const MCSubtargetInfo &STI, unsigned MovOpc, 100*0b57cec5SDimitry Andric unsigned Reg1, unsigned Reg2, unsigned FPReg1, 101*0b57cec5SDimitry Andric unsigned FPReg2, bool LE); 102*0b57cec5SDimitry Andric 103*0b57cec5SDimitry Andric void EmitSwapFPIntParams(const MCSubtargetInfo &STI, 104*0b57cec5SDimitry Andric Mips16HardFloatInfo::FPParamVariant, bool LE, 105*0b57cec5SDimitry Andric bool ToFP); 106*0b57cec5SDimitry Andric 107*0b57cec5SDimitry Andric void EmitSwapFPIntRetval(const MCSubtargetInfo &STI, 108*0b57cec5SDimitry Andric Mips16HardFloatInfo::FPReturnVariant, bool LE); 109*0b57cec5SDimitry Andric 110*0b57cec5SDimitry Andric void EmitFPCallStub(const char *, const Mips16HardFloatInfo::FuncSignature *); 111*0b57cec5SDimitry Andric 112*0b57cec5SDimitry Andric void NaClAlignIndirectJumpTargets(MachineFunction &MF); 113*0b57cec5SDimitry Andric 114*0b57cec5SDimitry Andric bool isLongBranchPseudo(int Opcode) const; 115*0b57cec5SDimitry Andric 116*0b57cec5SDimitry Andric public: 117*0b57cec5SDimitry Andric const MipsSubtarget *Subtarget; 118*0b57cec5SDimitry Andric const MipsFunctionInfo *MipsFI; 119*0b57cec5SDimitry Andric MipsMCInstLower MCInstLowering; 120*0b57cec5SDimitry Andric 121*0b57cec5SDimitry Andric explicit MipsAsmPrinter(TargetMachine &TM, 122*0b57cec5SDimitry Andric std::unique_ptr<MCStreamer> Streamer) 123*0b57cec5SDimitry Andric : AsmPrinter(TM, std::move(Streamer)), MCInstLowering(*this) {} 124*0b57cec5SDimitry Andric 125*0b57cec5SDimitry Andric StringRef getPassName() const override { return "Mips Assembly Printer"; } 126*0b57cec5SDimitry Andric 127*0b57cec5SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 128*0b57cec5SDimitry Andric 129*0b57cec5SDimitry Andric void EmitConstantPool() override { 130*0b57cec5SDimitry Andric bool UsingConstantPools = 131*0b57cec5SDimitry Andric (Subtarget->inMips16Mode() && Subtarget->useConstantIslands()); 132*0b57cec5SDimitry Andric if (!UsingConstantPools) 133*0b57cec5SDimitry Andric AsmPrinter::EmitConstantPool(); 134*0b57cec5SDimitry Andric // we emit constant pools customly! 135*0b57cec5SDimitry Andric } 136*0b57cec5SDimitry Andric 137*0b57cec5SDimitry Andric void EmitInstruction(const MachineInstr *MI) override; 138*0b57cec5SDimitry Andric void printSavedRegsBitmask(); 139*0b57cec5SDimitry Andric void emitFrameDirective(); 140*0b57cec5SDimitry Andric const char *getCurrentABIString() const; 141*0b57cec5SDimitry Andric void EmitFunctionEntryLabel() override; 142*0b57cec5SDimitry Andric void EmitFunctionBodyStart() override; 143*0b57cec5SDimitry Andric void EmitFunctionBodyEnd() override; 144*0b57cec5SDimitry Andric void EmitBasicBlockEnd(const MachineBasicBlock &MBB) override; 145*0b57cec5SDimitry Andric bool isBlockOnlyReachableByFallthrough( 146*0b57cec5SDimitry Andric const MachineBasicBlock* MBB) const override; 147*0b57cec5SDimitry Andric bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 148*0b57cec5SDimitry Andric const char *ExtraCode, raw_ostream &O) override; 149*0b57cec5SDimitry Andric bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, 150*0b57cec5SDimitry Andric const char *ExtraCode, raw_ostream &O) override; 151*0b57cec5SDimitry Andric void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O); 152*0b57cec5SDimitry Andric void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O); 153*0b57cec5SDimitry Andric void printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O); 154*0b57cec5SDimitry Andric void printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O, 155*0b57cec5SDimitry Andric const char *Modifier = nullptr); 156*0b57cec5SDimitry Andric void printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O); 157*0b57cec5SDimitry Andric void EmitStartOfAsmFile(Module &M) override; 158*0b57cec5SDimitry Andric void EmitEndOfAsmFile(Module &M) override; 159*0b57cec5SDimitry Andric void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS); 160*0b57cec5SDimitry Andric void EmitDebugValue(const MCExpr *Value, unsigned Size) const override; 161*0b57cec5SDimitry Andric }; 162*0b57cec5SDimitry Andric 163*0b57cec5SDimitry Andric } // end namespace llvm 164*0b57cec5SDimitry Andric 165*0b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_MIPS_MIPSASMPRINTER_H 166