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 
getPassName()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 *ExtraCode, raw_ostream &O) override;
81   bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
82                              const char *ExtraCode, 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 
emitConstantPool()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:
getISAEncoding()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