1 //===-- AArch64TargetStreamer.h - AArch64 Target Streamer ------*- 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_AARCH64_MCTARGETDESC_AARCH64TARGETSTREAMER_H 10 #define LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64TARGETSTREAMER_H 11 12 #include "AArch64MCAsmInfo.h" 13 #include "llvm/ADT/StringRef.h" 14 #include "llvm/IR/Instructions.h" 15 #include "llvm/MC/MCELFStreamer.h" 16 #include "llvm/MC/MCStreamer.h" 17 #include "llvm/Support/AArch64BuildAttributes.h" 18 #include <cstdint> 19 20 namespace { 21 class AArch64ELFStreamer; 22 } 23 24 namespace llvm { 25 26 class AArch64TargetStreamer : public MCTargetStreamer { 27 public: 28 AArch64TargetStreamer(MCStreamer &S); 29 ~AArch64TargetStreamer() override; 30 31 void finish() override; 32 void emitConstantPools() override; 33 34 /// Callback used to implement the ldr= pseudo. 35 /// Add a new entry to the constant pool for the current section and return an 36 /// MCExpr that can be used to refer to the constant pool location. 37 const MCExpr *addConstantPoolEntry(const MCExpr *, unsigned Size, SMLoc Loc); 38 39 /// Callback used to implement the .ltorg directive. 40 /// Emit contents of constant pool for the current section. 41 void emitCurrentConstantPool(); 42 43 /// Callback used to implement the .note.gnu.property section. 44 void emitNoteSection(unsigned Flags, uint64_t PAuthABIPlatform = -1, 45 uint64_t PAuthABIVersion = -1); 46 47 /// Callback used to emit AUTH expressions (e.g. signed 48 /// personality function pointer). 49 void emitAuthValue(const MCExpr *Expr, uint16_t Discriminator, 50 AArch64PACKey::ID Key, bool HasAddressDiversity); 51 52 /// Callback used to implement the .inst directive. 53 virtual void emitInst(uint32_t Inst); 54 55 /// Callback used to implement the .variant_pcs directive. emitDirectiveVariantPCS(MCSymbol * Symbol)56 virtual void emitDirectiveVariantPCS(MCSymbol *Symbol) {}; 57 emitDirectiveArch(StringRef Name)58 virtual void emitDirectiveArch(StringRef Name) {}; emitDirectiveArchExtension(StringRef Name)59 virtual void emitDirectiveArchExtension(StringRef Name) {}; 60 emitARM64WinCFIAllocStack(unsigned Size)61 virtual void emitARM64WinCFIAllocStack(unsigned Size) {} emitARM64WinCFISaveR19R20X(int Offset)62 virtual void emitARM64WinCFISaveR19R20X(int Offset) {} emitARM64WinCFISaveFPLR(int Offset)63 virtual void emitARM64WinCFISaveFPLR(int Offset) {} emitARM64WinCFISaveFPLRX(int Offset)64 virtual void emitARM64WinCFISaveFPLRX(int Offset) {} emitARM64WinCFISaveReg(unsigned Reg,int Offset)65 virtual void emitARM64WinCFISaveReg(unsigned Reg, int Offset) {} emitARM64WinCFISaveRegX(unsigned Reg,int Offset)66 virtual void emitARM64WinCFISaveRegX(unsigned Reg, int Offset) {} emitARM64WinCFISaveRegP(unsigned Reg,int Offset)67 virtual void emitARM64WinCFISaveRegP(unsigned Reg, int Offset) {} emitARM64WinCFISaveRegPX(unsigned Reg,int Offset)68 virtual void emitARM64WinCFISaveRegPX(unsigned Reg, int Offset) {} emitARM64WinCFISaveLRPair(unsigned Reg,int Offset)69 virtual void emitARM64WinCFISaveLRPair(unsigned Reg, int Offset) {} emitARM64WinCFISaveFReg(unsigned Reg,int Offset)70 virtual void emitARM64WinCFISaveFReg(unsigned Reg, int Offset) {} emitARM64WinCFISaveFRegX(unsigned Reg,int Offset)71 virtual void emitARM64WinCFISaveFRegX(unsigned Reg, int Offset) {} emitARM64WinCFISaveFRegP(unsigned Reg,int Offset)72 virtual void emitARM64WinCFISaveFRegP(unsigned Reg, int Offset) {} emitARM64WinCFISaveFRegPX(unsigned Reg,int Offset)73 virtual void emitARM64WinCFISaveFRegPX(unsigned Reg, int Offset) {} emitARM64WinCFISetFP()74 virtual void emitARM64WinCFISetFP() {} emitARM64WinCFIAddFP(unsigned Size)75 virtual void emitARM64WinCFIAddFP(unsigned Size) {} emitARM64WinCFINop()76 virtual void emitARM64WinCFINop() {} emitARM64WinCFISaveNext()77 virtual void emitARM64WinCFISaveNext() {} emitARM64WinCFIPrologEnd()78 virtual void emitARM64WinCFIPrologEnd() {} emitARM64WinCFIEpilogStart()79 virtual void emitARM64WinCFIEpilogStart() {} emitARM64WinCFIEpilogEnd()80 virtual void emitARM64WinCFIEpilogEnd() {} emitARM64WinCFITrapFrame()81 virtual void emitARM64WinCFITrapFrame() {} emitARM64WinCFIMachineFrame()82 virtual void emitARM64WinCFIMachineFrame() {} emitARM64WinCFIContext()83 virtual void emitARM64WinCFIContext() {} emitARM64WinCFIECContext()84 virtual void emitARM64WinCFIECContext() {} emitARM64WinCFIClearUnwoundToCall()85 virtual void emitARM64WinCFIClearUnwoundToCall() {} emitARM64WinCFIPACSignLR()86 virtual void emitARM64WinCFIPACSignLR() {} emitARM64WinCFISaveAnyRegI(unsigned Reg,int Offset)87 virtual void emitARM64WinCFISaveAnyRegI(unsigned Reg, int Offset) {} emitARM64WinCFISaveAnyRegIP(unsigned Reg,int Offset)88 virtual void emitARM64WinCFISaveAnyRegIP(unsigned Reg, int Offset) {} emitARM64WinCFISaveAnyRegD(unsigned Reg,int Offset)89 virtual void emitARM64WinCFISaveAnyRegD(unsigned Reg, int Offset) {} emitARM64WinCFISaveAnyRegDP(unsigned Reg,int Offset)90 virtual void emitARM64WinCFISaveAnyRegDP(unsigned Reg, int Offset) {} emitARM64WinCFISaveAnyRegQ(unsigned Reg,int Offset)91 virtual void emitARM64WinCFISaveAnyRegQ(unsigned Reg, int Offset) {} emitARM64WinCFISaveAnyRegQP(unsigned Reg,int Offset)92 virtual void emitARM64WinCFISaveAnyRegQP(unsigned Reg, int Offset) {} emitARM64WinCFISaveAnyRegIX(unsigned Reg,int Offset)93 virtual void emitARM64WinCFISaveAnyRegIX(unsigned Reg, int Offset) {} emitARM64WinCFISaveAnyRegIPX(unsigned Reg,int Offset)94 virtual void emitARM64WinCFISaveAnyRegIPX(unsigned Reg, int Offset) {} emitARM64WinCFISaveAnyRegDX(unsigned Reg,int Offset)95 virtual void emitARM64WinCFISaveAnyRegDX(unsigned Reg, int Offset) {} emitARM64WinCFISaveAnyRegDPX(unsigned Reg,int Offset)96 virtual void emitARM64WinCFISaveAnyRegDPX(unsigned Reg, int Offset) {} emitARM64WinCFISaveAnyRegQX(unsigned Reg,int Offset)97 virtual void emitARM64WinCFISaveAnyRegQX(unsigned Reg, int Offset) {} emitARM64WinCFISaveAnyRegQPX(unsigned Reg,int Offset)98 virtual void emitARM64WinCFISaveAnyRegQPX(unsigned Reg, int Offset) {} emitARM64WinCFIAllocZ(int Offset)99 virtual void emitARM64WinCFIAllocZ(int Offset) {} emitARM64WinCFISaveZReg(unsigned Reg,int Offset)100 virtual void emitARM64WinCFISaveZReg(unsigned Reg, int Offset) {} emitARM64WinCFISavePReg(unsigned Reg,int Offset)101 virtual void emitARM64WinCFISavePReg(unsigned Reg, int Offset) {} 102 103 /// Build attributes implementation 104 virtual void 105 emitAttributesSubsection(StringRef VendorName, 106 AArch64BuildAttributes::SubsectionOptional IsOptional, 107 AArch64BuildAttributes::SubsectionType ParameterType); 108 virtual void emitAttribute(StringRef VendorName, unsigned Tag, unsigned Value, 109 std::string String); 110 void activateAttributesSubsection(StringRef VendorName); 111 std::unique_ptr<MCELFStreamer::AttributeSubSection> 112 getActiveAttributesSubsection(); 113 std::unique_ptr<MCELFStreamer::AttributeSubSection> 114 getAttributesSubsectionByName(StringRef Name); 115 void 116 insertAttributeInPlace(const MCELFStreamer::AttributeItem &Attr, 117 MCELFStreamer::AttributeSubSection &AttSubSection); 118 119 SmallVector<MCELFStreamer::AttributeSubSection, 64> AttributeSubSections; 120 121 private: 122 std::unique_ptr<AssemblerConstantPools> ConstantPools; 123 }; 124 125 class AArch64TargetELFStreamer : public AArch64TargetStreamer { 126 private: 127 AArch64ELFStreamer &getStreamer(); 128 129 MCSection *AttributeSection = nullptr; 130 131 /// Build attributes implementation 132 void emitAttributesSubsection( 133 StringRef VendorName, 134 AArch64BuildAttributes::SubsectionOptional IsOptional, 135 AArch64BuildAttributes::SubsectionType ParameterType) override; 136 void emitAttribute(StringRef VendorName, unsigned Tag, unsigned Value, 137 std::string String) override; 138 void emitInst(uint32_t Inst) override; 139 void emitDirectiveVariantPCS(MCSymbol *Symbol) override; 140 void finish() override; 141 142 public: AArch64TargetELFStreamer(MCStreamer & S)143 AArch64TargetELFStreamer(MCStreamer &S) : AArch64TargetStreamer(S) {} 144 }; 145 146 class AArch64TargetWinCOFFStreamer : public llvm::AArch64TargetStreamer { 147 public: AArch64TargetWinCOFFStreamer(llvm::MCStreamer & S)148 AArch64TargetWinCOFFStreamer(llvm::MCStreamer &S) 149 : AArch64TargetStreamer(S) {} 150 151 // The unwind codes on ARM64 Windows are documented at 152 // https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling 153 void emitARM64WinCFIAllocStack(unsigned Size) override; 154 void emitARM64WinCFISaveR19R20X(int Offset) override; 155 void emitARM64WinCFISaveFPLR(int Offset) override; 156 void emitARM64WinCFISaveFPLRX(int Offset) override; 157 void emitARM64WinCFISaveReg(unsigned Reg, int Offset) override; 158 void emitARM64WinCFISaveRegX(unsigned Reg, int Offset) override; 159 void emitARM64WinCFISaveRegP(unsigned Reg, int Offset) override; 160 void emitARM64WinCFISaveRegPX(unsigned Reg, int Offset) override; 161 void emitARM64WinCFISaveLRPair(unsigned Reg, int Offset) override; 162 void emitARM64WinCFISaveFReg(unsigned Reg, int Offset) override; 163 void emitARM64WinCFISaveFRegX(unsigned Reg, int Offset) override; 164 void emitARM64WinCFISaveFRegP(unsigned Reg, int Offset) override; 165 void emitARM64WinCFISaveFRegPX(unsigned Reg, int Offset) override; 166 void emitARM64WinCFISetFP() override; 167 void emitARM64WinCFIAddFP(unsigned Size) override; 168 void emitARM64WinCFINop() override; 169 void emitARM64WinCFISaveNext() override; 170 void emitARM64WinCFIPrologEnd() override; 171 void emitARM64WinCFIEpilogStart() override; 172 void emitARM64WinCFIEpilogEnd() override; 173 void emitARM64WinCFITrapFrame() override; 174 void emitARM64WinCFIMachineFrame() override; 175 void emitARM64WinCFIContext() override; 176 void emitARM64WinCFIECContext() override; 177 void emitARM64WinCFIClearUnwoundToCall() override; 178 void emitARM64WinCFIPACSignLR() override; 179 void emitARM64WinCFISaveAnyRegI(unsigned Reg, int Offset) override; 180 void emitARM64WinCFISaveAnyRegIP(unsigned Reg, int Offset) override; 181 void emitARM64WinCFISaveAnyRegD(unsigned Reg, int Offset) override; 182 void emitARM64WinCFISaveAnyRegDP(unsigned Reg, int Offset) override; 183 void emitARM64WinCFISaveAnyRegQ(unsigned Reg, int Offset) override; 184 void emitARM64WinCFISaveAnyRegQP(unsigned Reg, int Offset) override; 185 void emitARM64WinCFISaveAnyRegIX(unsigned Reg, int Offset) override; 186 void emitARM64WinCFISaveAnyRegIPX(unsigned Reg, int Offset) override; 187 void emitARM64WinCFISaveAnyRegDX(unsigned Reg, int Offset) override; 188 void emitARM64WinCFISaveAnyRegDPX(unsigned Reg, int Offset) override; 189 void emitARM64WinCFISaveAnyRegQX(unsigned Reg, int Offset) override; 190 void emitARM64WinCFISaveAnyRegQPX(unsigned Reg, int Offset) override; 191 void emitARM64WinCFIAllocZ(int Offset) override; 192 void emitARM64WinCFISaveZReg(unsigned Reg, int Offset) override; 193 void emitARM64WinCFISavePReg(unsigned Reg, int Offset) override; 194 195 private: 196 void emitARM64WinUnwindCode(unsigned UnwindCode, int Reg, int Offset); 197 }; 198 199 MCTargetStreamer * 200 createAArch64ObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI); 201 202 MCTargetStreamer *createAArch64NullTargetStreamer(MCStreamer &S); 203 204 } // end namespace llvm 205 206 #endif 207