xref: /freebsd/contrib/llvm-project/llvm/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp (revision 9c77fb6aaa366cbabc80ee1b834bcfe4df135491)
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 
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   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 
72 void ARMELFMCAsmInfo::anchor() { }
73 
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 
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 
118 void ARMCOFFMCAsmInfoMicrosoft::anchor() { }
119 
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 
135 void ARMCOFFMCAsmInfoGNU::anchor() { }
136 
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 
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 
193 const MCSpecifierExpr *ARM::createUpper16(const MCExpr *Expr, MCContext &Ctx) {
194   return MCSpecifierExpr::create(Expr, ARM::S_HI16, Ctx);
195 }
196 
197 const MCSpecifierExpr *ARM::createLower16(const MCExpr *Expr, MCContext &Ctx) {
198   return MCSpecifierExpr::create(Expr, ARM::S_LO16, Ctx);
199 }
200 
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 
206 const MCSpecifierExpr *ARM::createUpper0_7(const MCExpr *Expr, MCContext &Ctx) {
207   return MCSpecifierExpr::create(Expr, ARM::S_HI_0_7, Ctx);
208 }
209 
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 
215 const MCSpecifierExpr *ARM::createLower0_7(const MCExpr *Expr, MCContext &Ctx) {
216   return MCSpecifierExpr::create(Expr, ARM::S_LO_0_7, Ctx);
217 }
218