1*0b57cec5SDimitry Andric //===- MCAsmInfo.cpp - Asm Info -------------------------------------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file defines target asm properties related what form asm statements 10*0b57cec5SDimitry Andric // should take. 11*0b57cec5SDimitry Andric // 12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 15*0b57cec5SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h" 16*0b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 17*0b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h" 18*0b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 19*0b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 20*0b57cec5SDimitry Andric 21*0b57cec5SDimitry Andric using namespace llvm; 22*0b57cec5SDimitry Andric 23*0b57cec5SDimitry Andric enum DefaultOnOff { Default, Enable, Disable }; 24*0b57cec5SDimitry Andric static cl::opt<DefaultOnOff> DwarfExtendedLoc( 25*0b57cec5SDimitry Andric "dwarf-extended-loc", cl::Hidden, 26*0b57cec5SDimitry Andric cl::desc("Disable emission of the extended flags in .loc directives."), 27*0b57cec5SDimitry Andric cl::values(clEnumVal(Default, "Default for platform"), 28*0b57cec5SDimitry Andric clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")), 29*0b57cec5SDimitry Andric cl::init(Default)); 30*0b57cec5SDimitry Andric 31*0b57cec5SDimitry Andric MCAsmInfo::MCAsmInfo() { 32*0b57cec5SDimitry Andric SeparatorString = ";"; 33*0b57cec5SDimitry Andric CommentString = "#"; 34*0b57cec5SDimitry Andric LabelSuffix = ":"; 35*0b57cec5SDimitry Andric PrivateGlobalPrefix = "L"; 36*0b57cec5SDimitry Andric PrivateLabelPrefix = PrivateGlobalPrefix; 37*0b57cec5SDimitry Andric LinkerPrivateGlobalPrefix = ""; 38*0b57cec5SDimitry Andric InlineAsmStart = "APP"; 39*0b57cec5SDimitry Andric InlineAsmEnd = "NO_APP"; 40*0b57cec5SDimitry Andric Code16Directive = ".code16"; 41*0b57cec5SDimitry Andric Code32Directive = ".code32"; 42*0b57cec5SDimitry Andric Code64Directive = ".code64"; 43*0b57cec5SDimitry Andric ZeroDirective = "\t.zero\t"; 44*0b57cec5SDimitry Andric AsciiDirective = "\t.ascii\t"; 45*0b57cec5SDimitry Andric AscizDirective = "\t.asciz\t"; 46*0b57cec5SDimitry Andric Data8bitsDirective = "\t.byte\t"; 47*0b57cec5SDimitry Andric Data16bitsDirective = "\t.short\t"; 48*0b57cec5SDimitry Andric Data32bitsDirective = "\t.long\t"; 49*0b57cec5SDimitry Andric Data64bitsDirective = "\t.quad\t"; 50*0b57cec5SDimitry Andric GlobalDirective = "\t.globl\t"; 51*0b57cec5SDimitry Andric WeakDirective = "\t.weak\t"; 52*0b57cec5SDimitry Andric if (DwarfExtendedLoc != Default) 53*0b57cec5SDimitry Andric SupportsExtendedDwarfLocDirective = DwarfExtendedLoc == Enable; 54*0b57cec5SDimitry Andric 55*0b57cec5SDimitry Andric // FIXME: Clang's logic should be synced with the logic used to initialize 56*0b57cec5SDimitry Andric // this member and the two implementations should be merged. 57*0b57cec5SDimitry Andric // For reference: 58*0b57cec5SDimitry Andric // - Solaris always enables the integrated assembler by default 59*0b57cec5SDimitry Andric // - SparcELFMCAsmInfo and X86ELFMCAsmInfo are handling this case 60*0b57cec5SDimitry Andric // - Windows always enables the integrated assembler by default 61*0b57cec5SDimitry Andric // - MCAsmInfoCOFF is handling this case, should it be MCAsmInfoMicrosoft? 62*0b57cec5SDimitry Andric // - MachO targets always enables the integrated assembler by default 63*0b57cec5SDimitry Andric // - MCAsmInfoDarwin is handling this case 64*0b57cec5SDimitry Andric // - Generic_GCC toolchains enable the integrated assembler on a per 65*0b57cec5SDimitry Andric // architecture basis. 66*0b57cec5SDimitry Andric // - The target subclasses for AArch64, ARM, and X86 handle these cases 67*0b57cec5SDimitry Andric UseIntegratedAssembler = false; 68*0b57cec5SDimitry Andric PreserveAsmComments = true; 69*0b57cec5SDimitry Andric } 70*0b57cec5SDimitry Andric 71*0b57cec5SDimitry Andric MCAsmInfo::~MCAsmInfo() = default; 72*0b57cec5SDimitry Andric 73*0b57cec5SDimitry Andric void MCAsmInfo::addInitialFrameState(const MCCFIInstruction &Inst) { 74*0b57cec5SDimitry Andric InitialFrameState.push_back(Inst); 75*0b57cec5SDimitry Andric } 76*0b57cec5SDimitry Andric 77*0b57cec5SDimitry Andric bool MCAsmInfo::isSectionAtomizableBySymbols(const MCSection &Section) const { 78*0b57cec5SDimitry Andric return false; 79*0b57cec5SDimitry Andric } 80*0b57cec5SDimitry Andric 81*0b57cec5SDimitry Andric const MCExpr * 82*0b57cec5SDimitry Andric MCAsmInfo::getExprForPersonalitySymbol(const MCSymbol *Sym, 83*0b57cec5SDimitry Andric unsigned Encoding, 84*0b57cec5SDimitry Andric MCStreamer &Streamer) const { 85*0b57cec5SDimitry Andric return getExprForFDESymbol(Sym, Encoding, Streamer); 86*0b57cec5SDimitry Andric } 87*0b57cec5SDimitry Andric 88*0b57cec5SDimitry Andric const MCExpr * 89*0b57cec5SDimitry Andric MCAsmInfo::getExprForFDESymbol(const MCSymbol *Sym, 90*0b57cec5SDimitry Andric unsigned Encoding, 91*0b57cec5SDimitry Andric MCStreamer &Streamer) const { 92*0b57cec5SDimitry Andric if (!(Encoding & dwarf::DW_EH_PE_pcrel)) 93*0b57cec5SDimitry Andric return MCSymbolRefExpr::create(Sym, Streamer.getContext()); 94*0b57cec5SDimitry Andric 95*0b57cec5SDimitry Andric MCContext &Context = Streamer.getContext(); 96*0b57cec5SDimitry Andric const MCExpr *Res = MCSymbolRefExpr::create(Sym, Context); 97*0b57cec5SDimitry Andric MCSymbol *PCSym = Context.createTempSymbol(); 98*0b57cec5SDimitry Andric Streamer.EmitLabel(PCSym); 99*0b57cec5SDimitry Andric const MCExpr *PC = MCSymbolRefExpr::create(PCSym, Context); 100*0b57cec5SDimitry Andric return MCBinaryExpr::createSub(Res, PC, Context); 101*0b57cec5SDimitry Andric } 102*0b57cec5SDimitry Andric 103*0b57cec5SDimitry Andric static bool isAcceptableChar(char C) { 104*0b57cec5SDimitry Andric return (C >= 'a' && C <= 'z') || (C >= 'A' && C <= 'Z') || 105*0b57cec5SDimitry Andric (C >= '0' && C <= '9') || C == '_' || C == '$' || C == '.' || C == '@'; 106*0b57cec5SDimitry Andric } 107*0b57cec5SDimitry Andric 108*0b57cec5SDimitry Andric bool MCAsmInfo::isValidUnquotedName(StringRef Name) const { 109*0b57cec5SDimitry Andric if (Name.empty()) 110*0b57cec5SDimitry Andric return false; 111*0b57cec5SDimitry Andric 112*0b57cec5SDimitry Andric // If any of the characters in the string is an unacceptable character, force 113*0b57cec5SDimitry Andric // quotes. 114*0b57cec5SDimitry Andric for (char C : Name) { 115*0b57cec5SDimitry Andric if (!isAcceptableChar(C)) 116*0b57cec5SDimitry Andric return false; 117*0b57cec5SDimitry Andric } 118*0b57cec5SDimitry Andric 119*0b57cec5SDimitry Andric return true; 120*0b57cec5SDimitry Andric } 121*0b57cec5SDimitry Andric 122*0b57cec5SDimitry Andric bool MCAsmInfo::shouldOmitSectionDirective(StringRef SectionName) const { 123*0b57cec5SDimitry Andric // FIXME: Does .section .bss/.data/.text work everywhere?? 124*0b57cec5SDimitry Andric return SectionName == ".text" || SectionName == ".data" || 125*0b57cec5SDimitry Andric (SectionName == ".bss" && !usesELFSectionDirectiveForBSS()); 126*0b57cec5SDimitry Andric } 127