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
18using namespace llvm;
19
20const 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
47void ARMMCAsmInfoDarwin::anchor() { }
48
49ARMMCAsmInfoDarwin::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
72void ARMELFMCAsmInfo::anchor() { }
73
74ARMELFMCAsmInfo::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
108void 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
118void ARMCOFFMCAsmInfoMicrosoft::anchor() { }
119
120ARMCOFFMCAsmInfoMicrosoft::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
135void ARMCOFFMCAsmInfoGNU::anchor() { }
136
137ARMCOFFMCAsmInfoGNU::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
160void 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
193const MCSpecifierExpr *ARM::createUpper16(const MCExpr *Expr, MCContext &Ctx) {
194 return MCSpecifierExpr::create(Expr, S: ARM::S_HI16, Ctx);
195}
196
197const MCSpecifierExpr *ARM::createLower16(const MCExpr *Expr, MCContext &Ctx) {
198 return MCSpecifierExpr::create(Expr, S: ARM::S_LO16, Ctx);
199}
200
201const MCSpecifierExpr *ARM::createUpper8_15(const MCExpr *Expr,
202 MCContext &Ctx) {
203 return MCSpecifierExpr::create(Expr, S: ARM::S_HI_8_15, Ctx);
204}
205
206const MCSpecifierExpr *ARM::createUpper0_7(const MCExpr *Expr, MCContext &Ctx) {
207 return MCSpecifierExpr::create(Expr, S: ARM::S_HI_0_7, Ctx);
208}
209
210const MCSpecifierExpr *ARM::createLower8_15(const MCExpr *Expr,
211 MCContext &Ctx) {
212 return MCSpecifierExpr::create(Expr, S: ARM::S_LO_8_15, Ctx);
213}
214
215const MCSpecifierExpr *ARM::createLower0_7(const MCExpr *Expr, MCContext &Ctx) {
216 return MCSpecifierExpr::create(Expr, S: ARM::S_LO_0_7, Ctx);
217}
218