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 initializeAtSpecifiers(atSpecifiers);
100 // foo(plt) instead of foo@plt
101 UseAtForSpecifier = false;
102 UseParensForSpecifier = true;
103}
104
105void ARMELFMCAsmInfo::setUseIntegratedAssembler(bool Value) {
106 UseIntegratedAssembler = Value;
107 if (!UseIntegratedAssembler) {
108 // gas doesn't handle VFP register names in cfi directives,
109 // so don't use register names with external assembler.
110 // See https://sourceware.org/bugzilla/show_bug.cgi?id=16694
111 DwarfRegNumForCFI = true;
112 }
113}
114
115void ARMCOFFMCAsmInfoMicrosoft::anchor() { }
116
117ARMCOFFMCAsmInfoMicrosoft::ARMCOFFMCAsmInfoMicrosoft() {
118 AlignmentIsInBytes = false;
119 SupportsDebugInformation = true;
120 ExceptionsType = ExceptionHandling::WinEH;
121 WinEHEncodingType = WinEH::EncodingType::Itanium;
122 InternalSymbolPrefix = "$M";
123 PrivateLabelPrefix = "$M";
124 CommentString = "@";
125
126 // Conditional Thumb 4-byte instructions can have an implicit IT.
127 MaxInstLength = 6;
128
129 initializeAtSpecifiers(atSpecifiers);
130}
131
132void ARMCOFFMCAsmInfoGNU::anchor() { }
133
134ARMCOFFMCAsmInfoGNU::ARMCOFFMCAsmInfoGNU() {
135 AlignmentIsInBytes = false;
136 HasSingleParameterDotFile = true;
137
138 CommentString = "@";
139 InternalSymbolPrefix = ".L";
140 PrivateLabelPrefix = ".L";
141
142 SupportsDebugInformation = true;
143 ExceptionsType = ExceptionHandling::WinEH;
144 WinEHEncodingType = WinEH::EncodingType::Itanium;
145 DwarfRegNumForCFI = false;
146
147 // Conditional Thumb 4-byte instructions can have an implicit IT.
148 MaxInstLength = 6;
149
150 initializeAtSpecifiers(atSpecifiers);
151 UseAtForSpecifier = false;
152 UseParensForSpecifier = true;
153}
154
155void ARM::printSpecifierExpr(const MCAsmInfo &MAI, raw_ostream &OS,
156 const MCSpecifierExpr &Expr) {
157 switch (Expr.getSpecifier()) {
158 default:
159 llvm_unreachable("Invalid kind!");
160 case ARM::S_HI16:
161 OS << ":upper16:";
162 break;
163 case ARM::S_LO16:
164 OS << ":lower16:";
165 break;
166 case ARM::S_HI_8_15:
167 OS << ":upper8_15:";
168 break;
169 case ARM::S_HI_0_7:
170 OS << ":upper0_7:";
171 break;
172 case ARM::S_LO_8_15:
173 OS << ":lower8_15:";
174 break;
175 case ARM::S_LO_0_7:
176 OS << ":lower0_7:";
177 break;
178 }
179
180 const MCExpr *Sub = Expr.getSubExpr();
181 if (Sub->getKind() != MCExpr::SymbolRef)
182 OS << '(';
183 MAI.printExpr(OS, *Sub);
184 if (Sub->getKind() != MCExpr::SymbolRef)
185 OS << ')';
186}
187
188const MCSpecifierExpr *ARM::createUpper16(const MCExpr *Expr, MCContext &Ctx) {
189 return MCSpecifierExpr::create(Expr, S: ARM::S_HI16, Ctx);
190}
191
192const MCSpecifierExpr *ARM::createLower16(const MCExpr *Expr, MCContext &Ctx) {
193 return MCSpecifierExpr::create(Expr, S: ARM::S_LO16, Ctx);
194}
195
196const MCSpecifierExpr *ARM::createUpper8_15(const MCExpr *Expr,
197 MCContext &Ctx) {
198 return MCSpecifierExpr::create(Expr, S: ARM::S_HI_8_15, Ctx);
199}
200
201const MCSpecifierExpr *ARM::createUpper0_7(const MCExpr *Expr, MCContext &Ctx) {
202 return MCSpecifierExpr::create(Expr, S: ARM::S_HI_0_7, Ctx);
203}
204
205const MCSpecifierExpr *ARM::createLower8_15(const MCExpr *Expr,
206 MCContext &Ctx) {
207 return MCSpecifierExpr::create(Expr, S: ARM::S_LO_8_15, Ctx);
208}
209
210const MCSpecifierExpr *ARM::createLower0_7(const MCExpr *Expr, MCContext &Ctx) {
211 return MCSpecifierExpr::create(Expr, S: ARM::S_LO_0_7, Ctx);
212}
213