10b57cec5SDimitry Andric //===- MCAsmInfo.cpp - Asm Info -------------------------------------------===// 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 // This file defines target asm properties related what form asm statements 100b57cec5SDimitry Andric // should take. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 150b57cec5SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h" 160b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 170b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h" 180b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 190b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric using namespace llvm; 220b57cec5SDimitry Andric 23*fe6060f1SDimitry Andric namespace { 240b57cec5SDimitry Andric enum DefaultOnOff { Default, Enable, Disable }; 25*fe6060f1SDimitry Andric } 260b57cec5SDimitry Andric static cl::opt<DefaultOnOff> DwarfExtendedLoc( 270b57cec5SDimitry Andric "dwarf-extended-loc", cl::Hidden, 280b57cec5SDimitry Andric cl::desc("Disable emission of the extended flags in .loc directives."), 290b57cec5SDimitry Andric cl::values(clEnumVal(Default, "Default for platform"), 300b57cec5SDimitry Andric clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")), 310b57cec5SDimitry Andric cl::init(Default)); 320b57cec5SDimitry Andric 33*fe6060f1SDimitry Andric namespace llvm { 34e8d8bef9SDimitry Andric cl::opt<cl::boolOrDefault> UseLEB128Directives( 35e8d8bef9SDimitry Andric "use-leb128-directives", cl::Hidden, 36e8d8bef9SDimitry Andric cl::desc( 37e8d8bef9SDimitry Andric "Disable the usage of LEB128 directives, and generate .byte instead."), 38e8d8bef9SDimitry Andric cl::init(cl::BOU_UNSET)); 39*fe6060f1SDimitry Andric } 40e8d8bef9SDimitry Andric 410b57cec5SDimitry Andric MCAsmInfo::MCAsmInfo() { 420b57cec5SDimitry Andric SeparatorString = ";"; 430b57cec5SDimitry Andric CommentString = "#"; 440b57cec5SDimitry Andric LabelSuffix = ":"; 450b57cec5SDimitry Andric PrivateGlobalPrefix = "L"; 460b57cec5SDimitry Andric PrivateLabelPrefix = PrivateGlobalPrefix; 470b57cec5SDimitry Andric LinkerPrivateGlobalPrefix = ""; 480b57cec5SDimitry Andric InlineAsmStart = "APP"; 490b57cec5SDimitry Andric InlineAsmEnd = "NO_APP"; 500b57cec5SDimitry Andric Code16Directive = ".code16"; 510b57cec5SDimitry Andric Code32Directive = ".code32"; 520b57cec5SDimitry Andric Code64Directive = ".code64"; 530b57cec5SDimitry Andric ZeroDirective = "\t.zero\t"; 540b57cec5SDimitry Andric AsciiDirective = "\t.ascii\t"; 550b57cec5SDimitry Andric AscizDirective = "\t.asciz\t"; 560b57cec5SDimitry Andric Data8bitsDirective = "\t.byte\t"; 570b57cec5SDimitry Andric Data16bitsDirective = "\t.short\t"; 580b57cec5SDimitry Andric Data32bitsDirective = "\t.long\t"; 590b57cec5SDimitry Andric Data64bitsDirective = "\t.quad\t"; 600b57cec5SDimitry Andric GlobalDirective = "\t.globl\t"; 610b57cec5SDimitry Andric WeakDirective = "\t.weak\t"; 620b57cec5SDimitry Andric if (DwarfExtendedLoc != Default) 630b57cec5SDimitry Andric SupportsExtendedDwarfLocDirective = DwarfExtendedLoc == Enable; 64e8d8bef9SDimitry Andric if (UseLEB128Directives != cl::BOU_UNSET) 65e8d8bef9SDimitry Andric HasLEB128Directives = UseLEB128Directives == cl::BOU_TRUE; 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric // FIXME: Clang's logic should be synced with the logic used to initialize 680b57cec5SDimitry Andric // this member and the two implementations should be merged. 690b57cec5SDimitry Andric // For reference: 700b57cec5SDimitry Andric // - Solaris always enables the integrated assembler by default 710b57cec5SDimitry Andric // - SparcELFMCAsmInfo and X86ELFMCAsmInfo are handling this case 720b57cec5SDimitry Andric // - Windows always enables the integrated assembler by default 730b57cec5SDimitry Andric // - MCAsmInfoCOFF is handling this case, should it be MCAsmInfoMicrosoft? 740b57cec5SDimitry Andric // - MachO targets always enables the integrated assembler by default 750b57cec5SDimitry Andric // - MCAsmInfoDarwin is handling this case 760b57cec5SDimitry Andric // - Generic_GCC toolchains enable the integrated assembler on a per 770b57cec5SDimitry Andric // architecture basis. 780b57cec5SDimitry Andric // - The target subclasses for AArch64, ARM, and X86 handle these cases 795ffd83dbSDimitry Andric UseIntegratedAssembler = true; 80*fe6060f1SDimitry Andric ParseInlineAsmUsingAsmParser = false; 810b57cec5SDimitry Andric PreserveAsmComments = true; 820b57cec5SDimitry Andric } 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric MCAsmInfo::~MCAsmInfo() = default; 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric void MCAsmInfo::addInitialFrameState(const MCCFIInstruction &Inst) { 870b57cec5SDimitry Andric InitialFrameState.push_back(Inst); 880b57cec5SDimitry Andric } 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric bool MCAsmInfo::isSectionAtomizableBySymbols(const MCSection &Section) const { 910b57cec5SDimitry Andric return false; 920b57cec5SDimitry Andric } 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric const MCExpr * 950b57cec5SDimitry Andric MCAsmInfo::getExprForPersonalitySymbol(const MCSymbol *Sym, 960b57cec5SDimitry Andric unsigned Encoding, 970b57cec5SDimitry Andric MCStreamer &Streamer) const { 980b57cec5SDimitry Andric return getExprForFDESymbol(Sym, Encoding, Streamer); 990b57cec5SDimitry Andric } 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric const MCExpr * 1020b57cec5SDimitry Andric MCAsmInfo::getExprForFDESymbol(const MCSymbol *Sym, 1030b57cec5SDimitry Andric unsigned Encoding, 1040b57cec5SDimitry Andric MCStreamer &Streamer) const { 1050b57cec5SDimitry Andric if (!(Encoding & dwarf::DW_EH_PE_pcrel)) 1060b57cec5SDimitry Andric return MCSymbolRefExpr::create(Sym, Streamer.getContext()); 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric MCContext &Context = Streamer.getContext(); 1090b57cec5SDimitry Andric const MCExpr *Res = MCSymbolRefExpr::create(Sym, Context); 1100b57cec5SDimitry Andric MCSymbol *PCSym = Context.createTempSymbol(); 1115ffd83dbSDimitry Andric Streamer.emitLabel(PCSym); 1120b57cec5SDimitry Andric const MCExpr *PC = MCSymbolRefExpr::create(PCSym, Context); 1130b57cec5SDimitry Andric return MCBinaryExpr::createSub(Res, PC, Context); 1140b57cec5SDimitry Andric } 1150b57cec5SDimitry Andric 116480093f4SDimitry Andric bool MCAsmInfo::isAcceptableChar(char C) const { 117e8d8bef9SDimitry Andric return isAlnum(C) || C == '_' || C == '$' || C == '.' || C == '@'; 1180b57cec5SDimitry Andric } 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric bool MCAsmInfo::isValidUnquotedName(StringRef Name) const { 1210b57cec5SDimitry Andric if (Name.empty()) 1220b57cec5SDimitry Andric return false; 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric // If any of the characters in the string is an unacceptable character, force 1250b57cec5SDimitry Andric // quotes. 1260b57cec5SDimitry Andric for (char C : Name) { 1270b57cec5SDimitry Andric if (!isAcceptableChar(C)) 1280b57cec5SDimitry Andric return false; 1290b57cec5SDimitry Andric } 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric return true; 1320b57cec5SDimitry Andric } 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric bool MCAsmInfo::shouldOmitSectionDirective(StringRef SectionName) const { 1350b57cec5SDimitry Andric // FIXME: Does .section .bss/.data/.text work everywhere?? 1360b57cec5SDimitry Andric return SectionName == ".text" || SectionName == ".data" || 1370b57cec5SDimitry Andric (SectionName == ".bss" && !usesELFSectionDirectiveForBSS()); 1380b57cec5SDimitry Andric } 139