1 //===-- SystemZAsmPrinter.h - SystemZ LLVM assembly printer ----*- C++ -*--===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZASMPRINTER_H
10 #define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZASMPRINTER_H
11 
12 #include "SystemZMCInstLower.h"
13 #include "SystemZTargetMachine.h"
14 #include "llvm/CodeGen/AsmPrinter.h"
15 #include "llvm/CodeGen/StackMaps.h"
16 #include "llvm/MC/MCInstBuilder.h"
17 #include "llvm/Support/Compiler.h"
18 
19 namespace llvm {
20 class MCStreamer;
21 class MachineBasicBlock;
22 class MachineInstr;
23 class Module;
24 class raw_ostream;
25 
26 class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter {
27 private:
28   StackMaps SM;
29 
30   typedef std::pair<MCInst, const MCSubtargetInfo *> MCInstSTIPair;
31   struct CmpMCInst {
operatorCmpMCInst32     bool operator()(const MCInstSTIPair &MCI_STI_A,
33                     const MCInstSTIPair &MCI_STI_B) const {
34       if (MCI_STI_A.second != MCI_STI_B.second)
35         return uintptr_t(MCI_STI_A.second) < uintptr_t(MCI_STI_B.second);
36       const MCInst &A = MCI_STI_A.first;
37       const MCInst &B = MCI_STI_B.first;
38       assert(A.getNumOperands() == B.getNumOperands() &&
39              A.getNumOperands() == 5 && A.getOperand(2).getImm() == 1 &&
40              B.getOperand(2).getImm() == 1 && "Unexpected EXRL target MCInst");
41       if (A.getOpcode() != B.getOpcode())
42         return A.getOpcode() < B.getOpcode();
43       if (A.getOperand(0).getReg() != B.getOperand(0).getReg())
44         return A.getOperand(0).getReg() < B.getOperand(0).getReg();
45       if (A.getOperand(1).getImm() != B.getOperand(1).getImm())
46         return A.getOperand(1).getImm() < B.getOperand(1).getImm();
47       if (A.getOperand(3).getReg() != B.getOperand(3).getReg())
48         return A.getOperand(3).getReg() < B.getOperand(3).getReg();
49       if (A.getOperand(4).getImm() != B.getOperand(4).getImm())
50         return A.getOperand(4).getImm() < B.getOperand(4).getImm();
51       return false;
52     }
53   };
54   typedef std::map<MCInstSTIPair, MCSymbol *, CmpMCInst> EXRLT2SymMap;
55   EXRLT2SymMap EXRLTargets2Sym;
56 
57 public:
SystemZAsmPrinter(TargetMachine & TM,std::unique_ptr<MCStreamer> Streamer)58   SystemZAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
59       : AsmPrinter(TM, std::move(Streamer)), SM(*this) {}
60 
61   // Override AsmPrinter.
getPassName()62   StringRef getPassName() const override { return "SystemZ Assembly Printer"; }
63   void emitInstruction(const MachineInstr *MI) override;
64   void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override;
65   void emitEndOfAsmFile(Module &M) override;
66   bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
67                        const char *ExtraCode, raw_ostream &OS) override;
68   bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
69                              const char *ExtraCode, raw_ostream &OS) override;
70 
doInitialization(Module & M)71   bool doInitialization(Module &M) override {
72     SM.reset();
73     return AsmPrinter::doInitialization(M);
74   }
75 
76 private:
77   void LowerFENTRY_CALL(const MachineInstr &MI, SystemZMCInstLower &MCIL);
78   void LowerSTACKMAP(const MachineInstr &MI);
79   void LowerPATCHPOINT(const MachineInstr &MI, SystemZMCInstLower &Lower);
80   void emitEXRLTargetInstructions();
81 };
82 } // end namespace llvm
83 
84 #endif
85