1 | //===-- ARMMCAsmInfo.cpp - ARM asm properties -----------------------------===// |
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 contains the declarations of the ARMMCAsmInfo properties. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "ARMMCAsmInfo.h" |
14 | #include "llvm/MC/MCExpr.h" |
15 | #include "llvm/Support/raw_ostream.h" |
16 | #include "llvm/TargetParser/Triple.h" |
17 | |
18 | using namespace llvm; |
19 | |
20 | const MCAsmInfo::AtSpecifier atSpecifiers[] = { |
21 | {.Kind: ARM::S_GOT_PREL, .Name: "GOT_PREL" }, |
22 | {.Kind: ARM::S_ARM_NONE, .Name: "none" }, |
23 | {.Kind: ARM::S_PREL31, .Name: "prel31" }, |
24 | {.Kind: ARM::S_SBREL, .Name: "sbrel" }, |
25 | {.Kind: ARM::S_TARGET1, .Name: "target1" }, |
26 | {.Kind: ARM::S_TARGET2, .Name: "target2" }, |
27 | {.Kind: ARM::S_TLSLDO, .Name: "TLSLDO" }, |
28 | {.Kind: MCSymbolRefExpr::VK_COFF_IMGREL32, .Name: "imgrel" }, |
29 | {.Kind: ARM::S_FUNCDESC, .Name: "FUNCDESC" }, |
30 | {.Kind: ARM::S_GOT, .Name: "GOT" }, |
31 | {.Kind: ARM::S_GOTFUNCDESC, .Name: "GOTFUNCDESC" }, |
32 | {.Kind: ARM::S_GOTOFF, .Name: "GOTOFF" }, |
33 | {.Kind: ARM::S_GOTOFFFUNCDESC, .Name: "GOTOFFFUNCDESC" }, |
34 | {.Kind: ARM::S_GOTTPOFF, .Name: "GOTTPOFF" }, |
35 | {.Kind: ARM::S_GOTTPOFF_FDPIC, .Name: "gottpoff_fdpic" }, |
36 | {.Kind: ARM::S_PLT, .Name: "PLT" }, |
37 | {.Kind: ARM::S_COFF_SECREL, .Name: "SECREL32" }, |
38 | {.Kind: ARM::S_TLSCALL, .Name: "tlscall" }, |
39 | {.Kind: ARM::S_TLSDESC, .Name: "tlsdesc" }, |
40 | {.Kind: ARM::S_TLSGD, .Name: "TLSGD" }, |
41 | {.Kind: ARM::S_TLSGD_FDPIC, .Name: "tlsgd_fdpic" }, |
42 | {.Kind: ARM::S_TLSLDM, .Name: "TLSLDM" }, |
43 | {.Kind: ARM::S_TLSLDM_FDPIC, .Name: "tlsldm_fdpic" }, |
44 | {.Kind: ARM::S_TPOFF, .Name: "TPOFF" }, |
45 | }; |
46 | |
47 | void ARMMCAsmInfoDarwin::anchor() { } |
48 | |
49 | ARMMCAsmInfoDarwin::ARMMCAsmInfoDarwin(const Triple &TheTriple) { |
50 | if ((TheTriple.getArch() == Triple::armeb) || |
51 | (TheTriple.getArch() == Triple::thumbeb)) |
52 | IsLittleEndian = false; |
53 | |
54 | Data64bitsDirective = nullptr; |
55 | CommentString = "@" ; |
56 | UseDataRegionDirectives = true; |
57 | |
58 | SupportsDebugInformation = true; |
59 | |
60 | // Conditional Thumb 4-byte instructions can have an implicit IT. |
61 | MaxInstLength = 6; |
62 | |
63 | // Exceptions handling |
64 | ExceptionsType = (TheTriple.isOSDarwin() && !TheTriple.isWatchABI()) |
65 | ? ExceptionHandling::SjLj |
66 | : ExceptionHandling::DwarfCFI; |
67 | |
68 | initializeAtSpecifiers(atSpecifiers); |
69 | } |
70 | |
71 | void ARMELFMCAsmInfo::anchor() { } |
72 | |
73 | ARMELFMCAsmInfo::ARMELFMCAsmInfo(const Triple &TheTriple) { |
74 | if ((TheTriple.getArch() == Triple::armeb) || |
75 | (TheTriple.getArch() == Triple::thumbeb)) |
76 | IsLittleEndian = false; |
77 | |
78 | // ".comm align is in bytes but .align is pow-2." |
79 | AlignmentIsInBytes = false; |
80 | |
81 | Data64bitsDirective = nullptr; |
82 | CommentString = "@" ; |
83 | |
84 | SupportsDebugInformation = true; |
85 | |
86 | // Conditional Thumb 4-byte instructions can have an implicit IT. |
87 | MaxInstLength = 6; |
88 | |
89 | // Exceptions handling |
90 | switch (TheTriple.getOS()) { |
91 | case Triple::NetBSD: |
92 | ExceptionsType = ExceptionHandling::DwarfCFI; |
93 | break; |
94 | default: |
95 | ExceptionsType = ExceptionHandling::ARM; |
96 | break; |
97 | } |
98 | |
99 | // foo(plt) instead of foo@plt |
100 | UseAtForSpecifier = false; |
101 | UseParensForSpecifier = true; |
102 | |
103 | initializeAtSpecifiers(atSpecifiers); |
104 | } |
105 | |
106 | void ARMELFMCAsmInfo::setUseIntegratedAssembler(bool Value) { |
107 | UseIntegratedAssembler = Value; |
108 | if (!UseIntegratedAssembler) { |
109 | // gas doesn't handle VFP register names in cfi directives, |
110 | // so don't use register names with external assembler. |
111 | // See https://sourceware.org/bugzilla/show_bug.cgi?id=16694 |
112 | DwarfRegNumForCFI = true; |
113 | } |
114 | } |
115 | |
116 | void ARMCOFFMCAsmInfoMicrosoft::anchor() { } |
117 | |
118 | ARMCOFFMCAsmInfoMicrosoft::ARMCOFFMCAsmInfoMicrosoft() { |
119 | AlignmentIsInBytes = false; |
120 | SupportsDebugInformation = true; |
121 | ExceptionsType = ExceptionHandling::WinEH; |
122 | WinEHEncodingType = WinEH::EncodingType::Itanium; |
123 | PrivateGlobalPrefix = "$M" ; |
124 | PrivateLabelPrefix = "$M" ; |
125 | CommentString = "@" ; |
126 | |
127 | // Conditional Thumb 4-byte instructions can have an implicit IT. |
128 | MaxInstLength = 6; |
129 | |
130 | initializeAtSpecifiers(atSpecifiers); |
131 | } |
132 | |
133 | void ARMCOFFMCAsmInfoGNU::anchor() { } |
134 | |
135 | ARMCOFFMCAsmInfoGNU::ARMCOFFMCAsmInfoGNU() { |
136 | AlignmentIsInBytes = false; |
137 | HasSingleParameterDotFile = true; |
138 | |
139 | CommentString = "@" ; |
140 | PrivateGlobalPrefix = ".L" ; |
141 | PrivateLabelPrefix = ".L" ; |
142 | |
143 | SupportsDebugInformation = true; |
144 | ExceptionsType = ExceptionHandling::WinEH; |
145 | WinEHEncodingType = WinEH::EncodingType::Itanium; |
146 | UseAtForSpecifier = false; |
147 | UseParensForSpecifier = true; |
148 | |
149 | DwarfRegNumForCFI = false; |
150 | |
151 | // Conditional Thumb 4-byte instructions can have an implicit IT. |
152 | MaxInstLength = 6; |
153 | |
154 | initializeAtSpecifiers(atSpecifiers); |
155 | } |
156 | |
157 | void ARM::printSpecifierExpr(const MCAsmInfo &MAI, raw_ostream &OS, |
158 | const MCSpecifierExpr &Expr) { |
159 | switch (Expr.getSpecifier()) { |
160 | default: |
161 | llvm_unreachable("Invalid kind!" ); |
162 | case ARM::S_HI16: |
163 | OS << ":upper16:" ; |
164 | break; |
165 | case ARM::S_LO16: |
166 | OS << ":lower16:" ; |
167 | break; |
168 | case ARM::S_HI_8_15: |
169 | OS << ":upper8_15:" ; |
170 | break; |
171 | case ARM::S_HI_0_7: |
172 | OS << ":upper0_7:" ; |
173 | break; |
174 | case ARM::S_LO_8_15: |
175 | OS << ":lower8_15:" ; |
176 | break; |
177 | case ARM::S_LO_0_7: |
178 | OS << ":lower0_7:" ; |
179 | break; |
180 | } |
181 | |
182 | const MCExpr *Sub = Expr.getSubExpr(); |
183 | if (Sub->getKind() != MCExpr::SymbolRef) |
184 | OS << '('; |
185 | MAI.printExpr(OS, *Sub); |
186 | if (Sub->getKind() != MCExpr::SymbolRef) |
187 | OS << ')'; |
188 | } |
189 | |
190 | const MCSpecifierExpr *ARM::createUpper16(const MCExpr *Expr, MCContext &Ctx) { |
191 | return MCSpecifierExpr::create(Expr, S: ARM::S_HI16, Ctx); |
192 | } |
193 | |
194 | const MCSpecifierExpr *ARM::createLower16(const MCExpr *Expr, MCContext &Ctx) { |
195 | return MCSpecifierExpr::create(Expr, S: ARM::S_LO16, Ctx); |
196 | } |
197 | |
198 | const MCSpecifierExpr *ARM::createUpper8_15(const MCExpr *Expr, |
199 | MCContext &Ctx) { |
200 | return MCSpecifierExpr::create(Expr, S: ARM::S_HI_8_15, Ctx); |
201 | } |
202 | |
203 | const MCSpecifierExpr *ARM::createUpper0_7(const MCExpr *Expr, MCContext &Ctx) { |
204 | return MCSpecifierExpr::create(Expr, S: ARM::S_HI_0_7, Ctx); |
205 | } |
206 | |
207 | const MCSpecifierExpr *ARM::createLower8_15(const MCExpr *Expr, |
208 | MCContext &Ctx) { |
209 | return MCSpecifierExpr::create(Expr, S: ARM::S_LO_8_15, Ctx); |
210 | } |
211 | |
212 | const MCSpecifierExpr *ARM::createLower0_7(const MCExpr *Expr, MCContext &Ctx) { |
213 | return MCSpecifierExpr::create(Expr, S: ARM::S_LO_0_7, Ctx); |
214 | } |
215 | |