xref: /freebsd/contrib/llvm-project/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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