10b57cec5SDimitry Andric //===- MipsAsmPrinter.h - Mips LLVM Assembly Printer -----------*- C++ -*--===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // Mips Assembly printer class. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_MIPS_MIPSASMPRINTER_H 140b57cec5SDimitry Andric #define LLVM_LIB_TARGET_MIPS_MIPSASMPRINTER_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "Mips16HardFloatInfo.h" 170b57cec5SDimitry Andric #include "MipsMCInstLower.h" 180b57cec5SDimitry Andric #include "MipsSubtarget.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h" 200b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 210b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 220b57cec5SDimitry Andric #include <algorithm> 230b57cec5SDimitry Andric #include <map> 240b57cec5SDimitry Andric #include <memory> 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric namespace llvm { 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric class MCOperand; 290b57cec5SDimitry Andric class MCSubtargetInfo; 300b57cec5SDimitry Andric class MCSymbol; 310b57cec5SDimitry Andric class MachineBasicBlock; 320b57cec5SDimitry Andric class MachineConstantPool; 330b57cec5SDimitry Andric class MachineFunction; 340b57cec5SDimitry Andric class MachineInstr; 350b57cec5SDimitry Andric class MachineOperand; 360b57cec5SDimitry Andric class MipsFunctionInfo; 370b57cec5SDimitry Andric class MipsTargetStreamer; 380b57cec5SDimitry Andric class Module; 390b57cec5SDimitry Andric class raw_ostream; 400b57cec5SDimitry Andric class TargetMachine; 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY MipsAsmPrinter : public AsmPrinter { 430b57cec5SDimitry Andric MipsTargetStreamer &getTargetStreamer() const; 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric void EmitInstrWithMacroNoAT(const MachineInstr *MI); 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric //===------------------------------------------------------------------===// 480b57cec5SDimitry Andric // XRay implementation 490b57cec5SDimitry Andric //===------------------------------------------------------------------===// 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric public: 520b57cec5SDimitry Andric // XRay-specific lowering for Mips. 530b57cec5SDimitry Andric void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI); 540b57cec5SDimitry Andric void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI); 550b57cec5SDimitry Andric void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI); 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric private: 580b57cec5SDimitry Andric /// MCP - Keep a pointer to constantpool entries of the current 590b57cec5SDimitry Andric /// MachineFunction. 600b57cec5SDimitry Andric const MachineConstantPool *MCP = nullptr; 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric /// InConstantPool - Maintain state when emitting a sequence of constant 630b57cec5SDimitry Andric /// pool entries so we can properly mark them as data regions. 640b57cec5SDimitry Andric bool InConstantPool = false; 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric std::map<const char *, const Mips16HardFloatInfo::FuncSignature *> 670b57cec5SDimitry Andric StubsNeeded; 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric void EmitSled(const MachineInstr &MI, SledKind Kind); 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric // tblgen'erated function. 720b57cec5SDimitry Andric bool emitPseudoExpansionLowering(MCStreamer &OutStreamer, 730b57cec5SDimitry Andric const MachineInstr *MI); 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric // Emit PseudoReturn, PseudoReturn64, PseudoIndirectBranch, 760b57cec5SDimitry Andric // and PseudoIndirectBranch64 as a JR, JR_MM, JALR, or JALR64 as appropriate 770b57cec5SDimitry Andric // for the target. 780b57cec5SDimitry Andric void emitPseudoIndirectBranch(MCStreamer &OutStreamer, 790b57cec5SDimitry Andric const MachineInstr *MI); 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric // lowerOperand - Convert a MachineOperand into the equivalent MCOperand. 820b57cec5SDimitry Andric bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp); 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric void emitInlineAsmStart() const override; 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, 870b57cec5SDimitry Andric const MCSubtargetInfo *EndInfo) const override; 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric void EmitJal(const MCSubtargetInfo &STI, MCSymbol *Symbol); 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric void EmitInstrReg(const MCSubtargetInfo &STI, unsigned Opcode, unsigned Reg); 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric void EmitInstrRegReg(const MCSubtargetInfo &STI, unsigned Opcode, 940b57cec5SDimitry Andric unsigned Reg1, unsigned Reg2); 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric void EmitInstrRegRegReg(const MCSubtargetInfo &STI, unsigned Opcode, 970b57cec5SDimitry Andric unsigned Reg1, unsigned Reg2, unsigned Reg3); 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric void EmitMovFPIntPair(const MCSubtargetInfo &STI, unsigned MovOpc, 1000b57cec5SDimitry Andric unsigned Reg1, unsigned Reg2, unsigned FPReg1, 1010b57cec5SDimitry Andric unsigned FPReg2, bool LE); 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric void EmitSwapFPIntParams(const MCSubtargetInfo &STI, 1040b57cec5SDimitry Andric Mips16HardFloatInfo::FPParamVariant, bool LE, 1050b57cec5SDimitry Andric bool ToFP); 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric void EmitSwapFPIntRetval(const MCSubtargetInfo &STI, 1080b57cec5SDimitry Andric Mips16HardFloatInfo::FPReturnVariant, bool LE); 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric void EmitFPCallStub(const char *, const Mips16HardFloatInfo::FuncSignature *); 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric void NaClAlignIndirectJumpTargets(MachineFunction &MF); 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric bool isLongBranchPseudo(int Opcode) const; 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric public: 1170b57cec5SDimitry Andric const MipsSubtarget *Subtarget; 1180b57cec5SDimitry Andric const MipsFunctionInfo *MipsFI; 1190b57cec5SDimitry Andric MipsMCInstLower MCInstLowering; 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric explicit MipsAsmPrinter(TargetMachine &TM, 1220b57cec5SDimitry Andric std::unique_ptr<MCStreamer> Streamer) 1230b57cec5SDimitry Andric : AsmPrinter(TM, std::move(Streamer)), MCInstLowering(*this) {} 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric StringRef getPassName() const override { return "Mips Assembly Printer"; } 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 1280b57cec5SDimitry Andric 129*5ffd83dbSDimitry Andric void emitConstantPool() override { 1300b57cec5SDimitry Andric bool UsingConstantPools = 1310b57cec5SDimitry Andric (Subtarget->inMips16Mode() && Subtarget->useConstantIslands()); 1320b57cec5SDimitry Andric if (!UsingConstantPools) 133*5ffd83dbSDimitry Andric AsmPrinter::emitConstantPool(); 1340b57cec5SDimitry Andric // we emit constant pools customly! 1350b57cec5SDimitry Andric } 1360b57cec5SDimitry Andric 137*5ffd83dbSDimitry Andric void emitInstruction(const MachineInstr *MI) override; 1380b57cec5SDimitry Andric void printSavedRegsBitmask(); 1390b57cec5SDimitry Andric void emitFrameDirective(); 1400b57cec5SDimitry Andric const char *getCurrentABIString() const; 141*5ffd83dbSDimitry Andric void emitFunctionEntryLabel() override; 142*5ffd83dbSDimitry Andric void emitFunctionBodyStart() override; 143*5ffd83dbSDimitry Andric void emitFunctionBodyEnd() override; 144*5ffd83dbSDimitry Andric void emitBasicBlockEnd(const MachineBasicBlock &MBB) override; 1450b57cec5SDimitry Andric bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 1460b57cec5SDimitry Andric const char *ExtraCode, raw_ostream &O) override; 1470b57cec5SDimitry Andric bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, 1480b57cec5SDimitry Andric const char *ExtraCode, raw_ostream &O) override; 1490b57cec5SDimitry Andric void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O); 1500b57cec5SDimitry Andric void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O); 1510b57cec5SDimitry Andric void printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O); 1520b57cec5SDimitry Andric void printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O, 1530b57cec5SDimitry Andric const char *Modifier = nullptr); 1540b57cec5SDimitry Andric void printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O); 155*5ffd83dbSDimitry Andric void emitStartOfAsmFile(Module &M) override; 156*5ffd83dbSDimitry Andric void emitEndOfAsmFile(Module &M) override; 1570b57cec5SDimitry Andric void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS); 158*5ffd83dbSDimitry Andric void emitDebugValue(const MCExpr *Value, unsigned Size) const override; 1590b57cec5SDimitry Andric }; 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric } // end namespace llvm 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_MIPS_MIPSASMPRINTER_H 164