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