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 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
71void ARMELFMCAsmInfo::anchor() { }
72
73ARMELFMCAsmInfo::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
106void 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
116void ARMCOFFMCAsmInfoMicrosoft::anchor() { }
117
118ARMCOFFMCAsmInfoMicrosoft::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
133void ARMCOFFMCAsmInfoGNU::anchor() { }
134
135ARMCOFFMCAsmInfoGNU::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
157void 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
190const MCSpecifierExpr *ARM::createUpper16(const MCExpr *Expr, MCContext &Ctx) {
191 return MCSpecifierExpr::create(Expr, S: ARM::S_HI16, Ctx);
192}
193
194const MCSpecifierExpr *ARM::createLower16(const MCExpr *Expr, MCContext &Ctx) {
195 return MCSpecifierExpr::create(Expr, S: ARM::S_LO16, Ctx);
196}
197
198const MCSpecifierExpr *ARM::createUpper8_15(const MCExpr *Expr,
199 MCContext &Ctx) {
200 return MCSpecifierExpr::create(Expr, S: ARM::S_HI_8_15, Ctx);
201}
202
203const MCSpecifierExpr *ARM::createUpper0_7(const MCExpr *Expr, MCContext &Ctx) {
204 return MCSpecifierExpr::create(Expr, S: ARM::S_HI_0_7, Ctx);
205}
206
207const MCSpecifierExpr *ARM::createLower8_15(const MCExpr *Expr,
208 MCContext &Ctx) {
209 return MCSpecifierExpr::create(Expr, S: ARM::S_LO_8_15, Ctx);
210}
211
212const MCSpecifierExpr *ARM::createLower0_7(const MCExpr *Expr, MCContext &Ctx) {
213 return MCSpecifierExpr::create(Expr, S: ARM::S_LO_0_7, Ctx);
214}
215