10b57cec5SDimitry Andric //===-- SystemZAsmPrinter.h - SystemZ 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 #ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZASMPRINTER_H 100b57cec5SDimitry Andric #define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZASMPRINTER_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "SystemZMCInstLower.h" 13fe6060f1SDimitry Andric #include "SystemZTargetMachine.h" 14349cc55cSDimitry Andric #include "SystemZTargetStreamer.h" 150b57cec5SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h" 160b57cec5SDimitry Andric #include "llvm/CodeGen/StackMaps.h" 17fe6060f1SDimitry Andric #include "llvm/MC/MCInstBuilder.h" 180b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric namespace llvm { 210b57cec5SDimitry Andric class MCStreamer; 220b57cec5SDimitry Andric class MachineInstr; 230b57cec5SDimitry Andric class Module; 240b57cec5SDimitry Andric class raw_ostream; 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter { 270b57cec5SDimitry Andric private: 2881ad6265SDimitry Andric MCSymbol *CurrentFnPPA1Sym; // PPA1 Symbol. 2981ad6265SDimitry Andric MCSymbol *CurrentFnEPMarkerSym; // Entry Point Marker. 30*5f757f3fSDimitry Andric MCSymbol *PPA2Sym; 310b57cec5SDimitry Andric 32349cc55cSDimitry Andric SystemZTargetStreamer *getTargetStreamer() { 33349cc55cSDimitry Andric MCTargetStreamer *TS = OutStreamer->getTargetStreamer(); 34349cc55cSDimitry Andric assert(TS && "do not have a target streamer"); 35349cc55cSDimitry Andric return static_cast<SystemZTargetStreamer *>(TS); 36fe6060f1SDimitry Andric } 37fe6060f1SDimitry Andric 3881ad6265SDimitry Andric /// Call type information for XPLINK. 3981ad6265SDimitry Andric enum class CallType { 4081ad6265SDimitry Andric BASR76 = 0, // b'x000' == BASR r7,r6 4181ad6265SDimitry Andric BRAS7 = 1, // b'x001' == BRAS r7,ep 4281ad6265SDimitry Andric RESVD_2 = 2, // b'x010' 4381ad6265SDimitry Andric BRASL7 = 3, // b'x011' == BRASL r7,ep 4481ad6265SDimitry Andric RESVD_4 = 4, // b'x100' 4581ad6265SDimitry Andric RESVD_5 = 5, // b'x101' 4681ad6265SDimitry Andric BALR1415 = 6, // b'x110' == BALR r14,r15 4781ad6265SDimitry Andric BASR33 = 7, // b'x111' == BASR r3,r3 4881ad6265SDimitry Andric }; 4981ad6265SDimitry Andric 5006c3fb27SDimitry Andric // The Associated Data Area (ADA) contains descriptors which help locating 5106c3fb27SDimitry Andric // external symbols. For each symbol and type, the displacement into the ADA 5206c3fb27SDimitry Andric // is stored. 5306c3fb27SDimitry Andric class AssociatedDataAreaTable { 5406c3fb27SDimitry Andric public: 5506c3fb27SDimitry Andric using DisplacementTable = 5606c3fb27SDimitry Andric MapVector<std::pair<const MCSymbol *, unsigned>, uint32_t>; 5706c3fb27SDimitry Andric 5806c3fb27SDimitry Andric private: 5906c3fb27SDimitry Andric const uint64_t PointerSize; 6006c3fb27SDimitry Andric 6106c3fb27SDimitry Andric /// The mapping of name/slot type pairs to displacements. 6206c3fb27SDimitry Andric DisplacementTable Displacements; 6306c3fb27SDimitry Andric 6406c3fb27SDimitry Andric /// The next available displacement value. Incremented when new entries into 6506c3fb27SDimitry Andric /// the ADA are created. 6606c3fb27SDimitry Andric uint32_t NextDisplacement = 0; 6706c3fb27SDimitry Andric 6806c3fb27SDimitry Andric public: 6906c3fb27SDimitry Andric AssociatedDataAreaTable(uint64_t PointerSize) : PointerSize(PointerSize) {} 7006c3fb27SDimitry Andric 7106c3fb27SDimitry Andric /// @brief Add a function descriptor to the ADA. 7206c3fb27SDimitry Andric /// @param MI Pointer to an ADA_ENTRY instruction. 7306c3fb27SDimitry Andric /// @return The displacement of the descriptor into the ADA. 7406c3fb27SDimitry Andric uint32_t insert(const MachineOperand MO); 7506c3fb27SDimitry Andric 7606c3fb27SDimitry Andric /// @brief Get the displacement into associated data area (ADA) for a name. 7706c3fb27SDimitry Andric /// If no displacement is already associated with the name, assign one and 7806c3fb27SDimitry Andric /// return it. 7906c3fb27SDimitry Andric /// @param Sym The symbol for which the displacement should be returned. 8006c3fb27SDimitry Andric /// @param SlotKind The ADA type. 8106c3fb27SDimitry Andric /// @return The displacement of the descriptor into the ADA. 8206c3fb27SDimitry Andric uint32_t insert(const MCSymbol *Sym, unsigned SlotKind); 8306c3fb27SDimitry Andric 8406c3fb27SDimitry Andric /// Get the table of GOFF displacements. This is 'const' since it should 8506c3fb27SDimitry Andric /// never be modified by anything except the APIs on this class. 8606c3fb27SDimitry Andric const DisplacementTable &getTable() const { return Displacements; } 8706c3fb27SDimitry Andric 8806c3fb27SDimitry Andric uint32_t getNextDisplacement() const { return NextDisplacement; } 8906c3fb27SDimitry Andric }; 9006c3fb27SDimitry Andric 9106c3fb27SDimitry Andric AssociatedDataAreaTable ADATable; 9206c3fb27SDimitry Andric 9381ad6265SDimitry Andric void emitPPA1(MCSymbol *FnEndSym); 94*5f757f3fSDimitry Andric void emitPPA2(Module &M); 9506c3fb27SDimitry Andric void emitADASection(); 96*5f757f3fSDimitry Andric void emitIDRLSection(Module &M); 9781ad6265SDimitry Andric 980b57cec5SDimitry Andric public: 990b57cec5SDimitry Andric SystemZAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer) 100bdd1243dSDimitry Andric : AsmPrinter(TM, std::move(Streamer)), CurrentFnPPA1Sym(nullptr), 101*5f757f3fSDimitry Andric CurrentFnEPMarkerSym(nullptr), PPA2Sym(nullptr), 102*5f757f3fSDimitry Andric ADATable(TM.getPointerSize(0)) {} 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric // Override AsmPrinter. 1050b57cec5SDimitry Andric StringRef getPassName() const override { return "SystemZ Assembly Printer"; } 1065ffd83dbSDimitry Andric void emitInstruction(const MachineInstr *MI) override; 1075ffd83dbSDimitry Andric void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override; 1085ffd83dbSDimitry Andric void emitEndOfAsmFile(Module &M) override; 1090b57cec5SDimitry Andric bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 1100b57cec5SDimitry Andric const char *ExtraCode, raw_ostream &OS) override; 1110b57cec5SDimitry Andric bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 1120b57cec5SDimitry Andric const char *ExtraCode, raw_ostream &OS) override; 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric bool doInitialization(Module &M) override { 1150b57cec5SDimitry Andric SM.reset(); 1160b57cec5SDimitry Andric return AsmPrinter::doInitialization(M); 1170b57cec5SDimitry Andric } 11804eeddc0SDimitry Andric void emitFunctionEntryLabel() override; 11981ad6265SDimitry Andric void emitFunctionBodyEnd() override; 120*5f757f3fSDimitry Andric void emitStartOfAsmFile(Module &M) override; 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric private: 12381ad6265SDimitry Andric void emitCallInformation(CallType CT); 1248bcb0991SDimitry Andric void LowerFENTRY_CALL(const MachineInstr &MI, SystemZMCInstLower &MCIL); 1250b57cec5SDimitry Andric void LowerSTACKMAP(const MachineInstr &MI); 1260b57cec5SDimitry Andric void LowerPATCHPOINT(const MachineInstr &MI, SystemZMCInstLower &Lower); 127bdd1243dSDimitry Andric void emitAttributes(Module &M); 1280b57cec5SDimitry Andric }; 1290b57cec5SDimitry Andric } // end namespace llvm 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric #endif 132