10b57cec5SDimitry Andric //===-- ARMAsmPrinter.h - ARM implementation of AsmPrinter ------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_ARM_ARMASMPRINTER_H 100b57cec5SDimitry Andric #define LLVM_LIB_TARGET_ARM_ARMASMPRINTER_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "ARMSubtarget.h" 130b57cec5SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h" 140b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric namespace llvm { 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric class ARMFunctionInfo; 190b57cec5SDimitry Andric class MCOperand; 200b57cec5SDimitry Andric class MachineConstantPool; 210b57cec5SDimitry Andric class MachineOperand; 220b57cec5SDimitry Andric class MCSymbol; 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric namespace ARM { 250b57cec5SDimitry Andric enum DW_ISA { 260b57cec5SDimitry Andric DW_ISA_ARM_thumb = 1, 270b57cec5SDimitry Andric DW_ISA_ARM_arm = 2 280b57cec5SDimitry Andric }; 290b57cec5SDimitry Andric } 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY ARMAsmPrinter : public AsmPrinter { 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can 340b57cec5SDimitry Andric /// make the right decision when printing asm code for different targets. 350b57cec5SDimitry Andric const ARMSubtarget *Subtarget; 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric /// AFI - Keep a pointer to ARMFunctionInfo for the current 380b57cec5SDimitry Andric /// MachineFunction. 390b57cec5SDimitry Andric ARMFunctionInfo *AFI; 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric /// MCP - Keep a pointer to constantpool entries of the current 420b57cec5SDimitry Andric /// MachineFunction. 430b57cec5SDimitry Andric const MachineConstantPool *MCP; 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric /// InConstantPool - Maintain state when emitting a sequence of constant 460b57cec5SDimitry Andric /// pool entries so we can properly mark them as data regions. 470b57cec5SDimitry Andric bool InConstantPool; 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric /// ThumbIndirectPads - These maintain a per-function list of jump pad 500b57cec5SDimitry Andric /// labels used for ARMv4t thumb code to make register indirect calls. 510b57cec5SDimitry Andric SmallVector<std::pair<unsigned, MCSymbol*>, 4> ThumbIndirectPads; 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric /// OptimizationGoals - Maintain a combined optimization goal for all 540b57cec5SDimitry Andric /// functions in a module: one of Tag_ABI_optimization_goals values, 550b57cec5SDimitry Andric /// -1 if uninitialized, 0 if conflicting goals 560b57cec5SDimitry Andric int OptimizationGoals; 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric /// List of globals that have had their storage promoted to a constant 590b57cec5SDimitry Andric /// pool. This lives between calls to runOnMachineFunction and collects 600b57cec5SDimitry Andric /// data from every MachineFunction. It is used during doFinalization 610b57cec5SDimitry Andric /// when all non-function globals are emitted. 620b57cec5SDimitry Andric SmallPtrSet<const GlobalVariable*,2> PromotedGlobals; 630b57cec5SDimitry Andric /// Set of globals in PromotedGlobals that we've emitted labels for. 640b57cec5SDimitry Andric /// We need to emit labels even for promoted globals so that DWARF 650b57cec5SDimitry Andric /// debug info can link properly. 660b57cec5SDimitry Andric SmallPtrSet<const GlobalVariable*,2> EmittedPromotedGlobalLabels; 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric public: 690b57cec5SDimitry Andric explicit ARMAsmPrinter(TargetMachine &TM, 700b57cec5SDimitry Andric std::unique_ptr<MCStreamer> Streamer); 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric StringRef getPassName() const override { 730b57cec5SDimitry Andric return "ARM Assembly Printer"; 740b57cec5SDimitry Andric } 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O); 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override; 790b57cec5SDimitry Andric bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 800b57cec5SDimitry Andric const char *ExtraCode, raw_ostream &O) override; 810b57cec5SDimitry Andric bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, 820b57cec5SDimitry Andric const char *ExtraCode, raw_ostream &O) override; 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, 850b57cec5SDimitry Andric const MCSubtargetInfo *EndInfo) const override; 860b57cec5SDimitry Andric 875ffd83dbSDimitry Andric void emitJumpTableAddrs(const MachineInstr *MI); 885ffd83dbSDimitry Andric void emitJumpTableInsts(const MachineInstr *MI); 895ffd83dbSDimitry Andric void emitJumpTableTBInst(const MachineInstr *MI, unsigned OffsetWidth); 905ffd83dbSDimitry Andric void emitInstruction(const MachineInstr *MI) override; 910b57cec5SDimitry Andric bool runOnMachineFunction(MachineFunction &F) override; 92*5f757f3fSDimitry Andric std::tuple<const MCSymbol *, uint64_t, const MCSymbol *, 93*5f757f3fSDimitry Andric codeview::JumpTableEntrySize> 94*5f757f3fSDimitry Andric getCodeViewJumpTableInfo(int JTI, const MachineInstr *BranchInstr, 95*5f757f3fSDimitry Andric const MCSymbol *BranchLabel) const override; 960b57cec5SDimitry Andric 975ffd83dbSDimitry Andric void emitConstantPool() override { 980b57cec5SDimitry Andric // we emit constant pools customly! 990b57cec5SDimitry Andric } 1005ffd83dbSDimitry Andric void emitFunctionBodyEnd() override; 1015ffd83dbSDimitry Andric void emitFunctionEntryLabel() override; 1025ffd83dbSDimitry Andric void emitStartOfAsmFile(Module &M) override; 1035ffd83dbSDimitry Andric void emitEndOfAsmFile(Module &M) override; 1045ffd83dbSDimitry Andric void emitXXStructor(const DataLayout &DL, const Constant *CV) override; 1055ffd83dbSDimitry Andric void emitGlobalVariable(const GlobalVariable *GV) override; 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric MCSymbol *GetCPISymbol(unsigned CPID) const override; 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric // lowerOperand - Convert a MachineOperand into the equivalent MCOperand. 1100b57cec5SDimitry Andric bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp); 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric //===------------------------------------------------------------------===// 1130b57cec5SDimitry Andric // XRay implementation 1140b57cec5SDimitry Andric //===------------------------------------------------------------------===// 1150b57cec5SDimitry Andric public: 1160b57cec5SDimitry Andric // XRay-specific lowering for ARM. 1170b57cec5SDimitry Andric void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI); 1180b57cec5SDimitry Andric void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI); 1190b57cec5SDimitry Andric void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI); 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric private: 1220b57cec5SDimitry Andric void EmitSled(const MachineInstr &MI, SledKind Kind); 1230b57cec5SDimitry Andric 1245ffd83dbSDimitry Andric // Helpers for emitStartOfAsmFile() and emitEndOfAsmFile() 1250b57cec5SDimitry Andric void emitAttributes(); 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric void EmitUnwindingInstruction(const MachineInstr *MI); 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric // emitPseudoExpansionLowering - tblgen'erated. 1300b57cec5SDimitry Andric bool emitPseudoExpansionLowering(MCStreamer &OutStreamer, 1310b57cec5SDimitry Andric const MachineInstr *MI); 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric public: 1340b57cec5SDimitry Andric unsigned getISAEncoding() override { 1350b57cec5SDimitry Andric // ARM/Darwin adds ISA to the DWARF info for each function. 1360b57cec5SDimitry Andric const Triple &TT = TM.getTargetTriple(); 1370b57cec5SDimitry Andric if (!TT.isOSBinFormatMachO()) 1380b57cec5SDimitry Andric return 0; 1390b57cec5SDimitry Andric bool isThumb = TT.isThumb() || 1400b57cec5SDimitry Andric TT.getSubArch() == Triple::ARMSubArch_v7m || 1410b57cec5SDimitry Andric TT.getSubArch() == Triple::ARMSubArch_v6m; 1420b57cec5SDimitry Andric return isThumb ? ARM::DW_ISA_ARM_thumb : ARM::DW_ISA_ARM_arm; 1430b57cec5SDimitry Andric } 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric private: 1460b57cec5SDimitry Andric MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol); 1470b57cec5SDimitry Andric MCSymbol *GetARMJTIPICJumpTableLabel(unsigned uid) const; 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric MCSymbol *GetARMGVSymbol(const GlobalValue *GV, unsigned char TargetFlags); 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric public: 1520b57cec5SDimitry Andric /// EmitMachineConstantPoolValue - Print a machine constantpool value to 1530b57cec5SDimitry Andric /// the .s file. 1545ffd83dbSDimitry Andric void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override; 1550b57cec5SDimitry Andric }; 1560b57cec5SDimitry Andric } // end namespace llvm 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric #endif 159