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