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 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 //===------------------------------------------------------------------===// 111 public: 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 117 private: 118 void EmitSled(const MachineInstr &MI, SledKind Kind); 119 120 // Helpers for emitStartOfAsmFile() and emitEndOfAsmFile() 121 void emitAttributes(); 122 123 void EmitUnwindingInstruction(const MachineInstr *MI); 124 125 // emitPseudoExpansionLowering - tblgen'erated. 126 bool emitPseudoExpansionLowering(MCStreamer &OutStreamer, 127 const MachineInstr *MI); 128 129 public: 130 unsigned getISAEncoding() override { 131 // ARM/Darwin adds ISA to the DWARF info for each function. 132 const Triple &TT = TM.getTargetTriple(); 133 if (!TT.isOSBinFormatMachO()) 134 return 0; 135 bool isThumb = TT.isThumb() || 136 TT.getSubArch() == Triple::ARMSubArch_v7m || 137 TT.getSubArch() == Triple::ARMSubArch_v6m; 138 return isThumb ? ARM::DW_ISA_ARM_thumb : ARM::DW_ISA_ARM_arm; 139 } 140 141 private: 142 MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol); 143 MCSymbol *GetARMJTIPICJumpTableLabel(unsigned uid) const; 144 145 MCSymbol *GetARMGVSymbol(const GlobalValue *GV, unsigned char TargetFlags); 146 147 public: 148 /// EmitMachineConstantPoolValue - Print a machine constantpool value to 149 /// the .s file. 150 void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override; 151 }; 152 } // end namespace llvm 153 154 #endif 155