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