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 // 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 132 public: 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 144 private: 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 150 public: 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