169 lines · cpp
1//===- MCAsmInfo.cpp - Asm Info -------------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines target asm properties related what form asm statements10// should take.11//12//===----------------------------------------------------------------------===//13 14#include "llvm/MC/MCAsmInfo.h"15#include "llvm/ADT/StringExtras.h"16#include "llvm/BinaryFormat/Dwarf.h"17#include "llvm/MC/MCContext.h"18#include "llvm/MC/MCExpr.h"19#include "llvm/MC/MCStreamer.h"20#include "llvm/MC/MCValue.h"21#include "llvm/Support/Casting.h"22#include "llvm/Support/CommandLine.h"23 24using namespace llvm;25 26namespace {27enum DefaultOnOff { Default, Enable, Disable };28}29static cl::opt<DefaultOnOff> DwarfExtendedLoc(30 "dwarf-extended-loc", cl::Hidden,31 cl::desc("Disable emission of the extended flags in .loc directives."),32 cl::values(clEnumVal(Default, "Default for platform"),33 clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")),34 cl::init(Default));35 36namespace llvm {37cl::opt<cl::boolOrDefault> UseLEB128Directives(38 "use-leb128-directives", cl::Hidden,39 cl::desc(40 "Disable the usage of LEB128 directives, and generate .byte instead."),41 cl::init(cl::BOU_UNSET));42}43 44MCAsmInfo::MCAsmInfo() {45 SeparatorString = ";";46 CommentString = "#";47 LabelSuffix = ":";48 PrivateGlobalPrefix = "L";49 PrivateLabelPrefix = PrivateGlobalPrefix;50 LinkerPrivateGlobalPrefix = "";51 InlineAsmStart = "APP";52 InlineAsmEnd = "NO_APP";53 ZeroDirective = "\t.zero\t";54 AsciiDirective = "\t.ascii\t";55 AscizDirective = "\t.asciz\t";56 Data8bitsDirective = "\t.byte\t";57 Data16bitsDirective = "\t.short\t";58 Data32bitsDirective = "\t.long\t";59 Data64bitsDirective = "\t.quad\t";60 GlobalDirective = "\t.globl\t";61 WeakDirective = "\t.weak\t";62 if (DwarfExtendedLoc != Default)63 SupportsExtendedDwarfLocDirective = DwarfExtendedLoc == Enable;64 if (UseLEB128Directives != cl::BOU_UNSET)65 HasLEB128Directives = UseLEB128Directives == cl::BOU_TRUE;66 UseIntegratedAssembler = true;67 ParseInlineAsmUsingAsmParser = false;68 PreserveAsmComments = true;69 PPCUseFullRegisterNames = false;70}71 72MCAsmInfo::~MCAsmInfo() = default;73 74void MCAsmInfo::addInitialFrameState(const MCCFIInstruction &Inst) {75 InitialFrameState.push_back(Inst);76}77 78const MCExpr *79MCAsmInfo::getExprForPersonalitySymbol(const MCSymbol *Sym,80 unsigned Encoding,81 MCStreamer &Streamer) const {82 return getExprForFDESymbol(Sym, Encoding, Streamer);83}84 85const MCExpr *86MCAsmInfo::getExprForFDESymbol(const MCSymbol *Sym,87 unsigned Encoding,88 MCStreamer &Streamer) const {89 if (!(Encoding & dwarf::DW_EH_PE_pcrel))90 return MCSymbolRefExpr::create(Sym, Streamer.getContext());91 92 MCContext &Context = Streamer.getContext();93 const MCExpr *Res = MCSymbolRefExpr::create(Sym, Context);94 MCSymbol *PCSym = Context.createTempSymbol();95 Streamer.emitLabel(PCSym);96 const MCExpr *PC = MCSymbolRefExpr::create(PCSym, Context);97 return MCBinaryExpr::createSub(Res, PC, Context);98}99 100bool MCAsmInfo::isAcceptableChar(char C) const {101 if (C == '@')102 return doesAllowAtInName();103 104 return isAlnum(C) || C == '_' || C == '$' || C == '.';105}106 107bool MCAsmInfo::isValidUnquotedName(StringRef Name) const {108 if (Name.empty())109 return false;110 111 // If any of the characters in the string is an unacceptable character, force112 // quotes.113 for (char C : Name) {114 if (!isAcceptableChar(C))115 return false;116 }117 118 return true;119}120 121bool MCAsmInfo::shouldOmitSectionDirective(StringRef SectionName) const {122 // FIXME: Does .section .bss/.data/.text work everywhere??123 return SectionName == ".text" || SectionName == ".data" ||124 (SectionName == ".bss" && !usesELFSectionDirectiveForBSS());125}126 127void MCAsmInfo::initializeAtSpecifiers(ArrayRef<AtSpecifier> Descs) {128 assert(AtSpecifierToName.empty() && "cannot initialize twice");129 for (auto Desc : Descs) {130 [[maybe_unused]] auto It =131 AtSpecifierToName.try_emplace(Desc.Kind, Desc.Name);132 assert(It.second && "duplicate Kind");133 [[maybe_unused]] auto It2 =134 NameToAtSpecifier.try_emplace(Desc.Name.lower(), Desc.Kind);135 assert(It2.second);136 }137}138 139StringRef MCAsmInfo::getSpecifierName(uint32_t S) const {140 auto It = AtSpecifierToName.find(S);141 assert(It != AtSpecifierToName.end() &&142 "ensure the specifier is set in initializeVariantKinds");143 return It->second;144}145 146std::optional<uint32_t> MCAsmInfo::getSpecifierForName(StringRef Name) const {147 auto It = NameToAtSpecifier.find(Name.lower());148 if (It != NameToAtSpecifier.end())149 return It->second;150 return {};151}152 153void MCAsmInfo::printExpr(raw_ostream &OS, const MCExpr &Expr) const {154 if (auto *SE = dyn_cast<MCSpecifierExpr>(&Expr))155 printSpecifierExpr(OS, *SE);156 else157 Expr.print(OS, this);158}159 160bool MCAsmInfo::evaluateAsRelocatableImpl(const MCSpecifierExpr &E,161 MCValue &Res,162 const MCAssembler *Asm) const {163 if (!E.getSubExpr()->evaluateAsRelocatable(Res, Asm))164 return false;165 166 Res.setSpecifier(E.getSpecifier());167 return !Res.getSubSym();168}169