| 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 | |