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
16namespace llvm {
17
18class ARMFunctionInfo;
19class MCOperand;
20class MachineConstantPool;
21class MachineOperand;
22class MCSymbol;
23
24namespace ARM {
25  enum DW_ISA {
26    DW_ISA_ARM_thumb = 1,
27    DW_ISA_ARM_arm = 2
28  };
29}
30
31class 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
68public:
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 *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
93  void emitConstantPool() override {
94    // we emit constant pools customly!
95  }
96  void emitFunctionBodyEnd() override;
97  void emitFunctionEntryLabel() override;
98  void emitStartOfAsmFile(Module &M) override;
99  void emitEndOfAsmFile(Module &M) override;
100  void emitXXStructor(const DataLayout &DL, const Constant *CV) override;
101  void emitGlobalVariable(const GlobalVariable *GV) override;
102
103  MCSymbol *GetCPISymbol(unsigned CPID) const override;
104
105  // lowerOperand - Convert a MachineOperand into the equivalent MCOperand.
106  bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp);
107
108  //===------------------------------------------------------------------===//
109  // XRay implementation
110  //===------------------------------------------------------------------===//
111public:
112  // XRay-specific lowering for ARM.
113  void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI);
114  void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI);
115  void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI);
116
117private:
118  void EmitSled(const MachineInstr &MI, SledKind Kind);
119
120  // Helpers for emitStartOfAsmFile() and emitEndOfAsmFile()
121  void emitAttributes();
122
123  // Generic helper used to emit e.g. ARMv5 mul pseudos
124  void EmitPatchedInstruction(const MachineInstr *MI, unsigned TargetOpc);
125
126  void EmitUnwindingInstruction(const MachineInstr *MI);
127
128  // emitPseudoExpansionLowering - tblgen'erated.
129  bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
130                                   const MachineInstr *MI);
131
132public:
133  unsigned getISAEncoding() override {
134    // ARM/Darwin adds ISA to the DWARF info for each function.
135    const Triple &TT = TM.getTargetTriple();
136    if (!TT.isOSBinFormatMachO())
137      return 0;
138    bool isThumb = TT.isThumb() ||
139                   TT.getSubArch() == Triple::ARMSubArch_v7m ||
140                   TT.getSubArch() == Triple::ARMSubArch_v6m;
141    return isThumb ? ARM::DW_ISA_ARM_thumb : ARM::DW_ISA_ARM_arm;
142  }
143
144private:
145  MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol);
146  MCSymbol *GetARMJTIPICJumpTableLabel(unsigned uid) const;
147
148  MCSymbol *GetARMGVSymbol(const GlobalValue *GV, unsigned char TargetFlags);
149
150public:
151  /// EmitMachineConstantPoolValue - Print a machine constantpool value to
152  /// the .s file.
153  void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override;
154};
155} // end namespace llvm
156
157#endif
158