1 | //===-- ARMAsmPrinter.h - ARM implementation of AsmPrinter ------*- 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_ARM_ARMASMPRINTER_H |
10 | #define LLVM_LIB_TARGET_ARM_ARMASMPRINTER_H |
11 | |
12 | #include "ARMSubtarget.h" |
13 | #include "llvm/CodeGen/AsmPrinter.h" |
14 | #include "llvm/Target/TargetMachine.h" |
15 | |
16 | namespace llvm { |
17 | |
18 | class ARMFunctionInfo; |
19 | class MCOperand; |
20 | class MachineConstantPool; |
21 | class MachineOperand; |
22 | class MCSymbol; |
23 | |
24 | namespace ARM { |
25 | enum DW_ISA { |
26 | DW_ISA_ARM_thumb = 1, |
27 | DW_ISA_ARM_arm = 2 |
28 | }; |
29 | } |
30 | |
31 | class LLVM_LIBRARY_VISIBILITY ARMAsmPrinter : public AsmPrinter { |
32 | public: |
33 | static char ID; |
34 | |
35 | private: |
36 | /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can |
37 | /// make the right decision when printing asm code for different targets. |
38 | const ARMSubtarget *Subtarget; |
39 | |
40 | /// AFI - Keep a pointer to ARMFunctionInfo for the current |
41 | /// MachineFunction. |
42 | ARMFunctionInfo *AFI; |
43 | |
44 | /// MCP - Keep a pointer to constantpool entries of the current |
45 | /// MachineFunction. |
46 | const MachineConstantPool *MCP; |
47 | |
48 | /// InConstantPool - Maintain state when emitting a sequence of constant |
49 | /// pool entries so we can properly mark them as data regions. |
50 | bool InConstantPool; |
51 | |
52 | /// ThumbIndirectPads - These maintain a per-function list of jump pad |
53 | /// labels used for ARMv4t thumb code to make register indirect calls. |
54 | SmallVector<std::pair<unsigned, MCSymbol*>, 4> ThumbIndirectPads; |
55 | |
56 | /// OptimizationGoals - Maintain a combined optimization goal for all |
57 | /// functions in a module: one of Tag_ABI_optimization_goals values, |
58 | /// -1 if uninitialized, 0 if conflicting goals |
59 | int OptimizationGoals; |
60 | |
61 | /// List of globals that have had their storage promoted to a constant |
62 | /// pool. This lives between calls to runOnMachineFunction and collects |
63 | /// data from every MachineFunction. It is used during doFinalization |
64 | /// when all non-function globals are emitted. |
65 | SmallPtrSet<const GlobalVariable*,2> PromotedGlobals; |
66 | /// Set of globals in PromotedGlobals that we've emitted labels for. |
67 | /// We need to emit labels even for promoted globals so that DWARF |
68 | /// debug info can link properly. |
69 | SmallPtrSet<const GlobalVariable*,2> EmittedPromotedGlobalLabels; |
70 | |
71 | public: |
72 | explicit ARMAsmPrinter(TargetMachine &TM, |
73 | std::unique_ptr<MCStreamer> Streamer); |
74 | |
75 | StringRef getPassName() const override { |
76 | return "ARM Assembly Printer" ; |
77 | } |
78 | |
79 | const ARMBaseTargetMachine &getTM() const; |
80 | |
81 | void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O); |
82 | |
83 | void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override; |
84 | bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, |
85 | const char *, raw_ostream &O) override; |
86 | bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, |
87 | const char *, raw_ostream &O) override; |
88 | |
89 | void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, |
90 | const MCSubtargetInfo *EndInfo) const override; |
91 | |
92 | void emitJumpTableAddrs(const MachineInstr *MI); |
93 | void emitJumpTableInsts(const MachineInstr *MI); |
94 | void emitJumpTableTBInst(const MachineInstr *MI, unsigned OffsetWidth); |
95 | void emitInstruction(const MachineInstr *MI) override; |
96 | bool runOnMachineFunction(MachineFunction &F) override; |
97 | std::tuple<const MCSymbol *, uint64_t, const MCSymbol *, |
98 | codeview::JumpTableEntrySize> |
99 | getCodeViewJumpTableInfo(int JTI, const MachineInstr *BranchInstr, |
100 | const MCSymbol *BranchLabel) const override; |
101 | |
102 | void emitConstantPool() override { |
103 | // we emit constant pools customly! |
104 | } |
105 | void emitFunctionBodyEnd() override; |
106 | void emitFunctionEntryLabel() override; |
107 | void emitStartOfAsmFile(Module &M) override; |
108 | void emitEndOfAsmFile(Module &M) override; |
109 | void emitXXStructor(const DataLayout &DL, const Constant *CV) override; |
110 | void emitGlobalVariable(const GlobalVariable *GV) override; |
111 | |
112 | MCSymbol *GetCPISymbol(unsigned CPID) const override; |
113 | |
114 | // lowerOperand - Convert a MachineOperand into the equivalent MCOperand. |
115 | bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp); |
116 | |
117 | //===------------------------------------------------------------------===// |
118 | // XRay implementation |
119 | //===------------------------------------------------------------------===// |
120 | public: |
121 | // XRay-specific lowering for ARM. |
122 | void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI); |
123 | void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI); |
124 | void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI); |
125 | |
126 | private: |
127 | void EmitSled(const MachineInstr &MI, SledKind Kind); |
128 | |
129 | // Helpers for emitStartOfAsmFile() and emitEndOfAsmFile() |
130 | void emitAttributes(); |
131 | |
132 | void EmitUnwindingInstruction(const MachineInstr *MI); |
133 | |
134 | // tblgen'erated. |
135 | bool lowerPseudoInstExpansion(const MachineInstr *MI, MCInst &Inst); |
136 | |
137 | public: |
138 | unsigned getISAEncoding() override { |
139 | // ARM/Darwin adds ISA to the DWARF info for each function. |
140 | const Triple &TT = TM.getTargetTriple(); |
141 | if (!TT.isOSBinFormatMachO()) |
142 | return 0; |
143 | bool isThumb = TT.isThumb() || |
144 | TT.getSubArch() == Triple::ARMSubArch_v7m || |
145 | TT.getSubArch() == Triple::ARMSubArch_v6m; |
146 | return isThumb ? ARM::DW_ISA_ARM_thumb : ARM::DW_ISA_ARM_arm; |
147 | } |
148 | |
149 | private: |
150 | MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol); |
151 | MCSymbol *GetARMJTIPICJumpTableLabel(unsigned uid) const; |
152 | |
153 | MCSymbol *GetARMGVSymbol(const GlobalValue *GV, unsigned char TargetFlags); |
154 | |
155 | public: |
156 | /// EmitMachineConstantPoolValue - Print a machine constantpool value to |
157 | /// the .s file. |
158 | void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override; |
159 | }; |
160 | |
161 | } // end namespace llvm |
162 | |
163 | #endif |
164 | |