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