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-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file defines target asm properties related what form asm statements |
10 | // 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 | |
24 | using namespace llvm; |
25 | |
26 | namespace { |
27 | enum DefaultOnOff { Default, Enable, Disable }; |
28 | } |
29 | static 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(Val: Default)); |
35 | |
36 | namespace llvm { |
37 | cl::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(Val: cl::BOU_UNSET)); |
42 | } |
43 | |
44 | MCAsmInfo::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 | |
72 | MCAsmInfo::~MCAsmInfo() = default; |
73 | |
74 | void MCAsmInfo::addInitialFrameState(const MCCFIInstruction &Inst) { |
75 | InitialFrameState.push_back(x: Inst); |
76 | } |
77 | |
78 | const MCExpr * |
79 | MCAsmInfo::getExprForPersonalitySymbol(const MCSymbol *Sym, |
80 | unsigned Encoding, |
81 | MCStreamer &Streamer) const { |
82 | return getExprForFDESymbol(Sym, Encoding, Streamer); |
83 | } |
84 | |
85 | const MCExpr * |
86 | MCAsmInfo::getExprForFDESymbol(const MCSymbol *Sym, |
87 | unsigned Encoding, |
88 | MCStreamer &Streamer) const { |
89 | if (!(Encoding & dwarf::DW_EH_PE_pcrel)) |
90 | return MCSymbolRefExpr::create(Symbol: Sym, Ctx&: Streamer.getContext()); |
91 | |
92 | MCContext &Context = Streamer.getContext(); |
93 | const MCExpr *Res = MCSymbolRefExpr::create(Symbol: Sym, Ctx&: Context); |
94 | MCSymbol *PCSym = Context.createTempSymbol(); |
95 | Streamer.emitLabel(Symbol: PCSym); |
96 | const MCExpr *PC = MCSymbolRefExpr::create(Symbol: PCSym, Ctx&: Context); |
97 | return MCBinaryExpr::createSub(LHS: Res, RHS: PC, Ctx&: Context); |
98 | } |
99 | |
100 | bool MCAsmInfo::isAcceptableChar(char C) const { |
101 | if (C == '@') |
102 | return doesAllowAtInName(); |
103 | |
104 | return isAlnum(C) || C == '_' || C == '$' || C == '.'; |
105 | } |
106 | |
107 | bool 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, force |
112 | // quotes. |
113 | for (char C : Name) { |
114 | if (!isAcceptableChar(C)) |
115 | return false; |
116 | } |
117 | |
118 | return true; |
119 | } |
120 | |
121 | bool 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 | |
127 | void 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(Key: Desc.Kind, Args&: Desc.Name); |
132 | assert(It.second && "duplicate Kind" ); |
133 | [[maybe_unused]] auto It2 = |
134 | NameToAtSpecifier.try_emplace(Key: Desc.Name.lower(), Args&: Desc.Kind); |
135 | assert(It2.second); |
136 | } |
137 | } |
138 | |
139 | StringRef MCAsmInfo::getSpecifierName(uint32_t S) const { |
140 | auto It = AtSpecifierToName.find(Val: S); |
141 | assert(It != AtSpecifierToName.end() && |
142 | "ensure the specifier is set in initializeVariantKinds" ); |
143 | return It->second; |
144 | } |
145 | |
146 | std::optional<uint32_t> MCAsmInfo::getSpecifierForName(StringRef Name) const { |
147 | auto It = NameToAtSpecifier.find(Key: Name.lower()); |
148 | if (It != NameToAtSpecifier.end()) |
149 | return It->second; |
150 | return {}; |
151 | } |
152 | |
153 | void MCAsmInfo::printExpr(raw_ostream &OS, const MCExpr &Expr) const { |
154 | if (auto *SE = dyn_cast<MCSpecifierExpr>(Val: &Expr)) |
155 | printSpecifierExpr(OS, *SE); |
156 | else |
157 | Expr.print(OS, MAI: this); |
158 | } |
159 | |
160 | bool 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 | |