blob: 4df8acbb66512f085a75b371d0482882684e4e63 [file] [log] [blame]
Tim Northover3b0846e2014-05-24 12:50:23 +00001//===-- AArch64AsmBackend.cpp - AArch64 Assembler Backend -----------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Tim Northover3b0846e2014-05-24 12:50:23 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "AArch64.h"
Tim Northover3b0846e2014-05-24 12:50:23 +000010#include "MCTargetDesc/AArch64FixupKinds.h"
David Green9dd1d452018-08-22 11:31:39 +000011#include "MCTargetDesc/AArch64MCExpr.h"
Daniel Sanders50f17232015-09-15 16:17:27 +000012#include "llvm/ADT/Triple.h"
Zachary Turner264b5d92017-06-07 03:48:56 +000013#include "llvm/BinaryFormat/MachO.h"
Tim Northover3b0846e2014-05-24 12:50:23 +000014#include "llvm/MC/MCAsmBackend.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000015#include "llvm/MC/MCAssembler.h"
Oliver Stannarda5520b02016-04-01 09:14:50 +000016#include "llvm/MC/MCContext.h"
Tim Northover3b0846e2014-05-24 12:50:23 +000017#include "llvm/MC/MCDirectives.h"
Chad Rosierafe7c932014-08-06 16:05:02 +000018#include "llvm/MC/MCELFObjectWriter.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000019#include "llvm/MC/MCFixupKindInfo.h"
Tim Northover3b0846e2014-05-24 12:50:23 +000020#include "llvm/MC/MCObjectWriter.h"
Benjamin Kramer27c769d2018-09-10 12:53:46 +000021#include "llvm/MC/MCRegisterInfo.h"
Tim Northover3b0846e2014-05-24 12:50:23 +000022#include "llvm/MC/MCSectionELF.h"
Benjamin Kramer1f8930e2014-07-25 11:42:14 +000023#include "llvm/MC/MCSectionMachO.h"
Peter Collingbournee8813e62015-03-24 21:47:03 +000024#include "llvm/MC/MCValue.h"
Tim Northover3b0846e2014-05-24 12:50:23 +000025#include "llvm/Support/ErrorHandling.h"
Tim Northover3b0846e2014-05-24 12:50:23 +000026using namespace llvm;
27
28namespace {
29
30class AArch64AsmBackend : public MCAsmBackend {
31 static const unsigned PCRelFlagVal =
32 MCFixupKindInfo::FKF_IsAlignedDownTo32Bits | MCFixupKindInfo::FKF_IsPCRel;
Martin Storsjo0b7bf7a2017-07-26 11:19:17 +000033 Triple TheTriple;
34
Keith Walker8c44bf12016-01-20 15:59:14 +000035public:
Martin Storsjo0b7bf7a2017-07-26 11:19:17 +000036 AArch64AsmBackend(const Target &T, const Triple &TT, bool IsLittleEndian)
Peter Collingbourne571a3302018-05-21 17:57:19 +000037 : MCAsmBackend(IsLittleEndian ? support::little : support::big),
38 TheTriple(TT) {}
Tim Northover3b0846e2014-05-24 12:50:23 +000039
40 unsigned getNumFixupKinds() const override {
41 return AArch64::NumTargetFixupKinds;
42 }
43
44 const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
45 const static MCFixupKindInfo Infos[AArch64::NumTargetFixupKinds] = {
Rafael Espindola3ac4c092017-06-20 22:53:29 +000046 // This table *must* be in the order that the fixup_* kinds are defined
47 // in AArch64FixupKinds.h.
48 //
49 // Name Offset (bits) Size (bits) Flags
50 {"fixup_aarch64_pcrel_adr_imm21", 0, 32, PCRelFlagVal},
51 {"fixup_aarch64_pcrel_adrp_imm21", 0, 32, PCRelFlagVal},
52 {"fixup_aarch64_add_imm12", 10, 12, 0},
53 {"fixup_aarch64_ldst_imm12_scale1", 10, 12, 0},
54 {"fixup_aarch64_ldst_imm12_scale2", 10, 12, 0},
55 {"fixup_aarch64_ldst_imm12_scale4", 10, 12, 0},
56 {"fixup_aarch64_ldst_imm12_scale8", 10, 12, 0},
57 {"fixup_aarch64_ldst_imm12_scale16", 10, 12, 0},
58 {"fixup_aarch64_ldr_pcrel_imm19", 5, 19, PCRelFlagVal},
59 {"fixup_aarch64_movw", 5, 16, 0},
60 {"fixup_aarch64_pcrel_branch14", 5, 14, PCRelFlagVal},
61 {"fixup_aarch64_pcrel_branch19", 5, 19, PCRelFlagVal},
62 {"fixup_aarch64_pcrel_branch26", 0, 26, PCRelFlagVal},
63 {"fixup_aarch64_pcrel_call26", 0, 26, PCRelFlagVal},
64 {"fixup_aarch64_tlsdesc_call", 0, 0, 0}};
Tim Northover3b0846e2014-05-24 12:50:23 +000065
66 if (Kind < FirstTargetFixupKind)
67 return MCAsmBackend::getFixupKindInfo(Kind);
68
69 assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
70 "Invalid kind!");
71 return Infos[Kind - FirstTargetFixupKind];
72 }
73
Rafael Espindola801b42d2017-06-23 22:52:36 +000074 void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
75 const MCValue &Target, MutableArrayRef<char> Data,
Peter Smith57f661b2018-06-06 09:40:06 +000076 uint64_t Value, bool IsResolved,
77 const MCSubtargetInfo *STI) const override;
Tim Northover3b0846e2014-05-24 12:50:23 +000078
Peter Smith57f661b2018-06-06 09:40:06 +000079 bool mayNeedRelaxation(const MCInst &Inst,
80 const MCSubtargetInfo &STI) const override;
Tim Northover3b0846e2014-05-24 12:50:23 +000081 bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
82 const MCRelaxableFragment *DF,
83 const MCAsmLayout &Layout) const override;
Nirav Dave86030622016-07-11 14:23:53 +000084 void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
85 MCInst &Res) const override;
Peter Collingbourne571a3302018-05-21 17:57:19 +000086 bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
Tim Northover3b0846e2014-05-24 12:50:23 +000087
88 void HandleAssemblerFlag(MCAssemblerFlag Flag) {}
89
90 unsigned getPointerSize() const { return 8; }
Keith Walker8c44bf12016-01-20 15:59:14 +000091
92 unsigned getFixupKindContainereSizeInBytes(unsigned Kind) const;
Martin Storsjob2e9fcf2017-07-19 20:14:32 +000093
94 bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
95 const MCValue &Target) override;
Tim Northover3b0846e2014-05-24 12:50:23 +000096};
97
98} // end anonymous namespace
99
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000100/// The number of bytes the fixup may change.
Tim Northover3b0846e2014-05-24 12:50:23 +0000101static unsigned getFixupKindNumBytes(unsigned Kind) {
102 switch (Kind) {
103 default:
Craig Topper2a30d782014-06-18 05:05:13 +0000104 llvm_unreachable("Unknown fixup kind!");
Tim Northover3b0846e2014-05-24 12:50:23 +0000105
106 case AArch64::fixup_aarch64_tlsdesc_call:
107 return 0;
108
109 case FK_Data_1:
110 return 1;
111
Mandeep Singh Granga210f1d2017-07-17 00:05:32 +0000112 case FK_Data_2:
113 case FK_SecRel_2:
Tim Northover3b0846e2014-05-24 12:50:23 +0000114 return 2;
115
Eli Friedman46482092018-12-20 19:38:07 +0000116 case AArch64::fixup_aarch64_movw:
Tim Northover3b0846e2014-05-24 12:50:23 +0000117 case AArch64::fixup_aarch64_pcrel_branch14:
118 case AArch64::fixup_aarch64_add_imm12:
119 case AArch64::fixup_aarch64_ldst_imm12_scale1:
120 case AArch64::fixup_aarch64_ldst_imm12_scale2:
121 case AArch64::fixup_aarch64_ldst_imm12_scale4:
122 case AArch64::fixup_aarch64_ldst_imm12_scale8:
123 case AArch64::fixup_aarch64_ldst_imm12_scale16:
124 case AArch64::fixup_aarch64_ldr_pcrel_imm19:
125 case AArch64::fixup_aarch64_pcrel_branch19:
126 return 3;
127
128 case AArch64::fixup_aarch64_pcrel_adr_imm21:
129 case AArch64::fixup_aarch64_pcrel_adrp_imm21:
130 case AArch64::fixup_aarch64_pcrel_branch26:
131 case AArch64::fixup_aarch64_pcrel_call26:
132 case FK_Data_4:
Mandeep Singh Granga210f1d2017-07-17 00:05:32 +0000133 case FK_SecRel_4:
Tim Northover3b0846e2014-05-24 12:50:23 +0000134 return 4;
135
136 case FK_Data_8:
137 return 8;
138 }
139}
140
141static unsigned AdrImmBits(unsigned Value) {
142 unsigned lo2 = Value & 0x3;
143 unsigned hi19 = (Value & 0x1ffffc) >> 2;
144 return (hi19 << 5) | (lo2 << 29);
145}
146
Eli Friedman46482092018-12-20 19:38:07 +0000147static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target,
148 uint64_t Value, MCContext &Ctx,
149 const Triple &TheTriple, bool IsResolved) {
Oliver Stannarda5520b02016-04-01 09:14:50 +0000150 unsigned Kind = Fixup.getKind();
Tim Northover3b0846e2014-05-24 12:50:23 +0000151 int64_t SignedValue = static_cast<int64_t>(Value);
152 switch (Kind) {
153 default:
Craig Topperd3c02f12015-01-05 10:15:49 +0000154 llvm_unreachable("Unknown fixup kind!");
Tim Northover3b0846e2014-05-24 12:50:23 +0000155 case AArch64::fixup_aarch64_pcrel_adr_imm21:
Alex Bradbury866113c2017-04-05 10:16:14 +0000156 if (SignedValue > 2097151 || SignedValue < -2097152)
157 Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
Tim Northover3b0846e2014-05-24 12:50:23 +0000158 return AdrImmBits(Value & 0x1fffffULL);
159 case AArch64::fixup_aarch64_pcrel_adrp_imm21:
Martin Storsjo0b7bf7a2017-07-26 11:19:17 +0000160 assert(!IsResolved);
161 if (TheTriple.isOSBinFormatCOFF())
162 return AdrImmBits(Value & 0x1fffffULL);
Tim Northover3b0846e2014-05-24 12:50:23 +0000163 return AdrImmBits((Value & 0x1fffff000ULL) >> 12);
164 case AArch64::fixup_aarch64_ldr_pcrel_imm19:
165 case AArch64::fixup_aarch64_pcrel_branch19:
166 // Signed 21-bit immediate
167 if (SignedValue > 2097151 || SignedValue < -2097152)
Alex Bradbury866113c2017-04-05 10:16:14 +0000168 Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
169 if (Value & 0x3)
170 Ctx.reportError(Fixup.getLoc(), "fixup not sufficiently aligned");
Tim Northover3b0846e2014-05-24 12:50:23 +0000171 // Low two bits are not encoded.
172 return (Value >> 2) & 0x7ffff;
173 case AArch64::fixup_aarch64_add_imm12:
174 case AArch64::fixup_aarch64_ldst_imm12_scale1:
Martin Storsjo0b7bf7a2017-07-26 11:19:17 +0000175 if (TheTriple.isOSBinFormatCOFF() && !IsResolved)
176 Value &= 0xfff;
Tim Northover3b0846e2014-05-24 12:50:23 +0000177 // Unsigned 12-bit immediate
Alex Bradbury866113c2017-04-05 10:16:14 +0000178 if (Value >= 0x1000)
179 Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
Tim Northover3b0846e2014-05-24 12:50:23 +0000180 return Value;
181 case AArch64::fixup_aarch64_ldst_imm12_scale2:
Martin Storsjo0b7bf7a2017-07-26 11:19:17 +0000182 if (TheTriple.isOSBinFormatCOFF() && !IsResolved)
183 Value &= 0xfff;
Tim Northover3b0846e2014-05-24 12:50:23 +0000184 // Unsigned 12-bit immediate which gets multiplied by 2
Alex Bradbury866113c2017-04-05 10:16:14 +0000185 if (Value >= 0x2000)
186 Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
187 if (Value & 0x1)
188 Ctx.reportError(Fixup.getLoc(), "fixup must be 2-byte aligned");
Tim Northover3b0846e2014-05-24 12:50:23 +0000189 return Value >> 1;
190 case AArch64::fixup_aarch64_ldst_imm12_scale4:
Martin Storsjo0b7bf7a2017-07-26 11:19:17 +0000191 if (TheTriple.isOSBinFormatCOFF() && !IsResolved)
192 Value &= 0xfff;
Tim Northover3b0846e2014-05-24 12:50:23 +0000193 // Unsigned 12-bit immediate which gets multiplied by 4
Alex Bradbury866113c2017-04-05 10:16:14 +0000194 if (Value >= 0x4000)
195 Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
196 if (Value & 0x3)
197 Ctx.reportError(Fixup.getLoc(), "fixup must be 4-byte aligned");
Tim Northover3b0846e2014-05-24 12:50:23 +0000198 return Value >> 2;
199 case AArch64::fixup_aarch64_ldst_imm12_scale8:
Martin Storsjo0b7bf7a2017-07-26 11:19:17 +0000200 if (TheTriple.isOSBinFormatCOFF() && !IsResolved)
201 Value &= 0xfff;
Tim Northover3b0846e2014-05-24 12:50:23 +0000202 // Unsigned 12-bit immediate which gets multiplied by 8
Alex Bradbury866113c2017-04-05 10:16:14 +0000203 if (Value >= 0x8000)
204 Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
205 if (Value & 0x7)
206 Ctx.reportError(Fixup.getLoc(), "fixup must be 8-byte aligned");
Tim Northover3b0846e2014-05-24 12:50:23 +0000207 return Value >> 3;
208 case AArch64::fixup_aarch64_ldst_imm12_scale16:
Martin Storsjo0b7bf7a2017-07-26 11:19:17 +0000209 if (TheTriple.isOSBinFormatCOFF() && !IsResolved)
210 Value &= 0xfff;
Tim Northover3b0846e2014-05-24 12:50:23 +0000211 // Unsigned 12-bit immediate which gets multiplied by 16
Alex Bradbury866113c2017-04-05 10:16:14 +0000212 if (Value >= 0x10000)
213 Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
214 if (Value & 0xf)
215 Ctx.reportError(Fixup.getLoc(), "fixup must be 16-byte aligned");
Tim Northover3b0846e2014-05-24 12:50:23 +0000216 return Value >> 4;
Eli Friedman46482092018-12-20 19:38:07 +0000217 case AArch64::fixup_aarch64_movw: {
218 AArch64MCExpr::VariantKind RefKind =
219 static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind());
Mandeep Singh Grangf286bee2019-01-08 04:48:00 +0000220 if (AArch64MCExpr::getSymbolLoc(RefKind) != AArch64MCExpr::VK_ABS &&
221 AArch64MCExpr::getSymbolLoc(RefKind) != AArch64MCExpr::VK_SABS) {
222 // VK_GOTTPREL, VK_TPREL, VK_DTPREL are movw fixups, but they can't
223 // ever be resolved in the assembler.
Eli Friedman46482092018-12-20 19:38:07 +0000224 Ctx.reportError(Fixup.getLoc(),
Mandeep Singh Grangf286bee2019-01-08 04:48:00 +0000225 "relocation for a thread-local variable points to an "
226 "absolute symbol");
Eli Friedman46482092018-12-20 19:38:07 +0000227 return Value;
228 }
Mandeep Singh Grangf286bee2019-01-08 04:48:00 +0000229
Eli Friedman46482092018-12-20 19:38:07 +0000230 if (!IsResolved) {
231 // FIXME: Figure out when this can actually happen, and verify our
232 // behavior.
233 Ctx.reportError(Fixup.getLoc(), "unresolved movw fixup not yet "
234 "implemented");
235 return Value;
236 }
Mandeep Singh Grangf286bee2019-01-08 04:48:00 +0000237
238 if (AArch64MCExpr::getSymbolLoc(RefKind) == AArch64MCExpr::VK_SABS) {
239 switch (AArch64MCExpr::getAddressFrag(RefKind)) {
240 case AArch64MCExpr::VK_G0:
241 break;
242 case AArch64MCExpr::VK_G1:
243 SignedValue = SignedValue >> 16;
244 break;
245 case AArch64MCExpr::VK_G2:
246 SignedValue = SignedValue >> 32;
247 break;
248 case AArch64MCExpr::VK_G3:
249 SignedValue = SignedValue >> 48;
250 break;
251 default:
252 llvm_unreachable("Variant kind doesn't correspond to fixup");
253 }
254
255 } else {
256 switch (AArch64MCExpr::getAddressFrag(RefKind)) {
257 case AArch64MCExpr::VK_G0:
258 break;
259 case AArch64MCExpr::VK_G1:
260 Value = Value >> 16;
261 break;
262 case AArch64MCExpr::VK_G2:
263 Value = Value >> 32;
264 break;
265 case AArch64MCExpr::VK_G3:
266 Value = Value >> 48;
267 break;
268 default:
269 llvm_unreachable("Variant kind doesn't correspond to fixup");
270 }
Eli Friedman46482092018-12-20 19:38:07 +0000271 }
Mandeep Singh Grangf286bee2019-01-08 04:48:00 +0000272
273 if (RefKind & AArch64MCExpr::VK_NC) {
Eli Friedman46482092018-12-20 19:38:07 +0000274 Value &= 0xFFFF;
Mandeep Singh Grangf286bee2019-01-08 04:48:00 +0000275 }
276 else if (RefKind & AArch64MCExpr::VK_SABS) {
277 if (SignedValue > 0xFFFF || SignedValue < -0xFFFF)
278 Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
279
280 // Invert the negative immediate because it will feed into a MOVN.
281 if (SignedValue < 0)
282 SignedValue = ~SignedValue;
283 Value = static_cast<uint64_t>(SignedValue);
284 }
285 else if (Value > 0xFFFF) {
Eli Friedman46482092018-12-20 19:38:07 +0000286 Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
Mandeep Singh Grangf286bee2019-01-08 04:48:00 +0000287 }
Tim Northover3b0846e2014-05-24 12:50:23 +0000288 return Value;
Eli Friedman46482092018-12-20 19:38:07 +0000289 }
Tim Northover3b0846e2014-05-24 12:50:23 +0000290 case AArch64::fixup_aarch64_pcrel_branch14:
291 // Signed 16-bit immediate
Alex Bradbury866113c2017-04-05 10:16:14 +0000292 if (SignedValue > 32767 || SignedValue < -32768)
293 Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
Tim Northover3b0846e2014-05-24 12:50:23 +0000294 // Low two bits are not encoded (4-byte alignment assumed).
Alex Bradbury866113c2017-04-05 10:16:14 +0000295 if (Value & 0x3)
296 Ctx.reportError(Fixup.getLoc(), "fixup not sufficiently aligned");
Tim Northover3b0846e2014-05-24 12:50:23 +0000297 return (Value >> 2) & 0x3fff;
298 case AArch64::fixup_aarch64_pcrel_branch26:
299 case AArch64::fixup_aarch64_pcrel_call26:
300 // Signed 28-bit immediate
Alex Bradbury866113c2017-04-05 10:16:14 +0000301 if (SignedValue > 134217727 || SignedValue < -134217728)
302 Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
Tim Northover3b0846e2014-05-24 12:50:23 +0000303 // Low two bits are not encoded (4-byte alignment assumed).
Alex Bradbury866113c2017-04-05 10:16:14 +0000304 if (Value & 0x3)
305 Ctx.reportError(Fixup.getLoc(), "fixup not sufficiently aligned");
Tim Northover3b0846e2014-05-24 12:50:23 +0000306 return (Value >> 2) & 0x3ffffff;
307 case FK_Data_1:
308 case FK_Data_2:
309 case FK_Data_4:
310 case FK_Data_8:
Mandeep Singh Granga210f1d2017-07-17 00:05:32 +0000311 case FK_SecRel_2:
312 case FK_SecRel_4:
Tim Northover3b0846e2014-05-24 12:50:23 +0000313 return Value;
314 }
315}
316
Keith Walker8c44bf12016-01-20 15:59:14 +0000317/// getFixupKindContainereSizeInBytes - The number of bytes of the
318/// container involved in big endian or 0 if the item is little endian
319unsigned AArch64AsmBackend::getFixupKindContainereSizeInBytes(unsigned Kind) const {
Peter Collingbourne571a3302018-05-21 17:57:19 +0000320 if (Endian == support::little)
Keith Walker8c44bf12016-01-20 15:59:14 +0000321 return 0;
322
323 switch (Kind) {
324 default:
325 llvm_unreachable("Unknown fixup kind!");
326
327 case FK_Data_1:
328 return 1;
329 case FK_Data_2:
330 return 2;
331 case FK_Data_4:
332 return 4;
333 case FK_Data_8:
334 return 8;
335
336 case AArch64::fixup_aarch64_tlsdesc_call:
337 case AArch64::fixup_aarch64_movw:
338 case AArch64::fixup_aarch64_pcrel_branch14:
339 case AArch64::fixup_aarch64_add_imm12:
340 case AArch64::fixup_aarch64_ldst_imm12_scale1:
341 case AArch64::fixup_aarch64_ldst_imm12_scale2:
342 case AArch64::fixup_aarch64_ldst_imm12_scale4:
343 case AArch64::fixup_aarch64_ldst_imm12_scale8:
344 case AArch64::fixup_aarch64_ldst_imm12_scale16:
345 case AArch64::fixup_aarch64_ldr_pcrel_imm19:
346 case AArch64::fixup_aarch64_pcrel_branch19:
347 case AArch64::fixup_aarch64_pcrel_adr_imm21:
348 case AArch64::fixup_aarch64_pcrel_adrp_imm21:
349 case AArch64::fixup_aarch64_pcrel_branch26:
350 case AArch64::fixup_aarch64_pcrel_call26:
351 // Instructions are always little endian
352 return 0;
353 }
354}
355
Rafael Espindola801b42d2017-06-23 22:52:36 +0000356void AArch64AsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
357 const MCValue &Target,
Rafael Espindola88d9e372017-06-21 23:06:53 +0000358 MutableArrayRef<char> Data, uint64_t Value,
Peter Smith57f661b2018-06-06 09:40:06 +0000359 bool IsResolved,
360 const MCSubtargetInfo *STI) const {
Tim Northover3b0846e2014-05-24 12:50:23 +0000361 unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
362 if (!Value)
363 return; // Doesn't change encoding.
364 MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind());
Rafael Espindolaf3512922017-06-24 00:26:57 +0000365 MCContext &Ctx = Asm.getContext();
Mandeep Singh Grangf286bee2019-01-08 04:48:00 +0000366 int64_t SignedValue = static_cast<int64_t>(Value);
Tim Northover3b0846e2014-05-24 12:50:23 +0000367 // Apply any target-specific value adjustments.
Eli Friedman46482092018-12-20 19:38:07 +0000368 Value = adjustFixupValue(Fixup, Target, Value, Ctx, TheTriple, IsResolved);
Tim Northover3b0846e2014-05-24 12:50:23 +0000369
370 // Shift the value into position.
371 Value <<= Info.TargetOffset;
372
373 unsigned Offset = Fixup.getOffset();
Rafael Espindola88d9e372017-06-21 23:06:53 +0000374 assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");
Tim Northover3b0846e2014-05-24 12:50:23 +0000375
Keith Walker8c44bf12016-01-20 15:59:14 +0000376 // Used to point to big endian bytes.
377 unsigned FulleSizeInBytes = getFixupKindContainereSizeInBytes(Fixup.getKind());
378
Tim Northover3b0846e2014-05-24 12:50:23 +0000379 // For each byte of the fragment that the fixup touches, mask in the
380 // bits from the fixup value.
Keith Walker8c44bf12016-01-20 15:59:14 +0000381 if (FulleSizeInBytes == 0) {
382 // Handle as little-endian
383 for (unsigned i = 0; i != NumBytes; ++i) {
384 Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
385 }
386 } else {
387 // Handle as big-endian
Rafael Espindola88d9e372017-06-21 23:06:53 +0000388 assert((Offset + FulleSizeInBytes) <= Data.size() && "Invalid fixup size!");
Keith Walker8c44bf12016-01-20 15:59:14 +0000389 assert(NumBytes <= FulleSizeInBytes && "Invalid fixup size!");
390 for (unsigned i = 0; i != NumBytes; ++i) {
391 unsigned Idx = FulleSizeInBytes - 1 - i;
392 Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
393 }
394 }
Mandeep Singh Grangf286bee2019-01-08 04:48:00 +0000395
396 // FIXME: getFixupKindInfo() and getFixupKindNumBytes() could be fixed to
397 // handle this more cleanly. This may affect the output of -show-mc-encoding.
398 AArch64MCExpr::VariantKind RefKind =
399 static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind());
400 if (RefKind & AArch64MCExpr::VK_SABS) {
401 // If the immediate is negative, generate MOVN else MOVZ.
402 // (Bit 30 = 0) ==> MOVN, (Bit 30 = 1) ==> MOVZ.
403 if (SignedValue < 0)
404 Data[Offset + 3] &= ~(1 << 6);
405 else
406 Data[Offset + 3] |= (1 << 6);
407 }
Tim Northover3b0846e2014-05-24 12:50:23 +0000408}
409
Peter Smith57f661b2018-06-06 09:40:06 +0000410bool AArch64AsmBackend::mayNeedRelaxation(const MCInst &Inst,
411 const MCSubtargetInfo &STI) const {
Tim Northover3b0846e2014-05-24 12:50:23 +0000412 return false;
413}
414
415bool AArch64AsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
416 uint64_t Value,
417 const MCRelaxableFragment *DF,
418 const MCAsmLayout &Layout) const {
419 // FIXME: This isn't correct for AArch64. Just moving the "generic" logic
420 // into the targets for now.
421 //
422 // Relax if the value is too big for a (signed) i8.
423 return int64_t(Value) != int64_t(int8_t(Value));
424}
425
426void AArch64AsmBackend::relaxInstruction(const MCInst &Inst,
Nirav Dave86030622016-07-11 14:23:53 +0000427 const MCSubtargetInfo &STI,
Tim Northover3b0846e2014-05-24 12:50:23 +0000428 MCInst &Res) const {
Craig Topperd3c02f12015-01-05 10:15:49 +0000429 llvm_unreachable("AArch64AsmBackend::relaxInstruction() unimplemented");
Tim Northover3b0846e2014-05-24 12:50:23 +0000430}
431
Peter Collingbourne571a3302018-05-21 17:57:19 +0000432bool AArch64AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
Tim Northover3b0846e2014-05-24 12:50:23 +0000433 // If the count is not 4-byte aligned, we must be writing data into the text
434 // section (otherwise we have unaligned instructions, and thus have far
435 // bigger problems), so just write zeros instead.
Peter Collingbourne571a3302018-05-21 17:57:19 +0000436 OS.write_zeros(Count % 4);
Tim Northover3b0846e2014-05-24 12:50:23 +0000437
438 // We are properly aligned, so write NOPs as requested.
439 Count /= 4;
440 for (uint64_t i = 0; i != Count; ++i)
Peter Collingbourne571a3302018-05-21 17:57:19 +0000441 support::endian::write<uint32_t>(OS, 0xd503201f, Endian);
Tim Northover3b0846e2014-05-24 12:50:23 +0000442 return true;
443}
444
Martin Storsjob2e9fcf2017-07-19 20:14:32 +0000445bool AArch64AsmBackend::shouldForceRelocation(const MCAssembler &Asm,
446 const MCFixup &Fixup,
447 const MCValue &Target) {
448 // The ADRP instruction adds some multiple of 0x1000 to the current PC &
449 // ~0xfff. This means that the required offset to reach a symbol can vary by
450 // up to one step depending on where the ADRP is in memory. For example:
451 //
452 // ADRP x0, there
453 // there:
454 //
455 // If the ADRP occurs at address 0xffc then "there" will be at 0x1000 and
456 // we'll need that as an offset. At any other address "there" will be in the
457 // same page as the ADRP and the instruction should encode 0x0. Assuming the
458 // section isn't 0x1000-aligned, we therefore need to delegate this decision
459 // to the linker -- a relocation!
460 if ((uint32_t)Fixup.getKind() == AArch64::fixup_aarch64_pcrel_adrp_imm21)
461 return true;
David Green9dd1d452018-08-22 11:31:39 +0000462
463 AArch64MCExpr::VariantKind RefKind =
464 static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind());
465 AArch64MCExpr::VariantKind SymLoc = AArch64MCExpr::getSymbolLoc(RefKind);
466 // LDR GOT relocations need a relocation
467 if ((uint32_t)Fixup.getKind() == AArch64::fixup_aarch64_ldr_pcrel_imm19 &&
468 SymLoc == AArch64MCExpr::VK_GOT)
469 return true;
Martin Storsjob2e9fcf2017-07-19 20:14:32 +0000470 return false;
471}
472
Tim Northover3b0846e2014-05-24 12:50:23 +0000473namespace {
474
475namespace CU {
476
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000477/// Compact unwind encoding values.
Tim Northover3b0846e2014-05-24 12:50:23 +0000478enum CompactUnwindEncodings {
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000479 /// A "frameless" leaf function, where no non-volatile registers are
Tim Northover3b0846e2014-05-24 12:50:23 +0000480 /// saved. The return remains in LR throughout the function.
Tim Northover87442c12016-02-23 21:49:05 +0000481 UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
Tim Northover3b0846e2014-05-24 12:50:23 +0000482
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000483 /// No compact unwind encoding available. Instead the low 23-bits of
Tim Northover3b0846e2014-05-24 12:50:23 +0000484 /// the compact unwind encoding is the offset of the DWARF FDE in the
485 /// __eh_frame section. This mode is never used in object files. It is only
486 /// generated by the linker in final linked images, which have only DWARF info
487 /// for a function.
Tim Northover87442c12016-02-23 21:49:05 +0000488 UNWIND_ARM64_MODE_DWARF = 0x03000000,
Tim Northover3b0846e2014-05-24 12:50:23 +0000489
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000490 /// This is a standard arm64 prologue where FP/LR are immediately
Tim Northover3b0846e2014-05-24 12:50:23 +0000491 /// pushed on the stack, then SP is copied to FP. If there are any
492 /// non-volatile register saved, they are copied into the stack fame in pairs
493 /// in a contiguous ranger right below the saved FP/LR pair. Any subset of the
494 /// five X pairs and four D pairs can be saved, but the memory layout must be
495 /// in register number order.
Tim Northover87442c12016-02-23 21:49:05 +0000496 UNWIND_ARM64_MODE_FRAME = 0x04000000,
Tim Northover3b0846e2014-05-24 12:50:23 +0000497
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000498 /// Frame register pair encodings.
Tim Northover87442c12016-02-23 21:49:05 +0000499 UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
500 UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
501 UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
502 UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
503 UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
504 UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
505 UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
506 UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
507 UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800
Tim Northover3b0846e2014-05-24 12:50:23 +0000508};
509
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000510} // end CU namespace
Tim Northover3b0846e2014-05-24 12:50:23 +0000511
512// FIXME: This should be in a separate file.
513class DarwinAArch64AsmBackend : public AArch64AsmBackend {
514 const MCRegisterInfo &MRI;
515
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000516 /// Encode compact unwind stack adjustment for frameless functions.
Tim Northover87442c12016-02-23 21:49:05 +0000517 /// See UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK in compact_unwind_encoding.h.
Tim Northover3b0846e2014-05-24 12:50:23 +0000518 /// The stack size always needs to be 16 byte aligned.
519 uint32_t encodeStackAdjustment(uint32_t StackSize) const {
520 return (StackSize / 16) << 12;
521 }
522
523public:
Martin Storsjo0b7bf7a2017-07-26 11:19:17 +0000524 DarwinAArch64AsmBackend(const Target &T, const Triple &TT,
525 const MCRegisterInfo &MRI)
526 : AArch64AsmBackend(T, TT, /*IsLittleEndian*/ true), MRI(MRI) {}
Tim Northover3b0846e2014-05-24 12:50:23 +0000527
Peter Collingbournedcd7d6c2018-05-21 19:20:29 +0000528 std::unique_ptr<MCObjectTargetWriter>
529 createObjectTargetWriter() const override {
530 return createAArch64MachObjectWriter(MachO::CPU_TYPE_ARM64,
Tim Northover3b0846e2014-05-24 12:50:23 +0000531 MachO::CPU_SUBTYPE_ARM64_ALL);
532 }
533
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000534 /// Generate the compact unwind encoding from the CFI directives.
Tim Northover3b0846e2014-05-24 12:50:23 +0000535 uint32_t generateCompactUnwindEncoding(
536 ArrayRef<MCCFIInstruction> Instrs) const override {
537 if (Instrs.empty())
Tim Northover87442c12016-02-23 21:49:05 +0000538 return CU::UNWIND_ARM64_MODE_FRAMELESS;
Tim Northover3b0846e2014-05-24 12:50:23 +0000539
540 bool HasFP = false;
541 unsigned StackSize = 0;
542
543 uint32_t CompactUnwindEncoding = 0;
544 for (size_t i = 0, e = Instrs.size(); i != e; ++i) {
545 const MCCFIInstruction &Inst = Instrs[i];
546
547 switch (Inst.getOperation()) {
548 default:
549 // Cannot handle this directive: bail out.
Tim Northover87442c12016-02-23 21:49:05 +0000550 return CU::UNWIND_ARM64_MODE_DWARF;
Tim Northover3b0846e2014-05-24 12:50:23 +0000551 case MCCFIInstruction::OpDefCfa: {
552 // Defines a frame pointer.
Francis Visoiu Mistrih90aba022018-05-31 16:33:26 +0000553 unsigned XReg =
554 getXRegFromWReg(MRI.getLLVMRegNum(Inst.getRegister(), true));
555
556 // Other CFA registers than FP are not supported by compact unwind.
557 // Fallback on DWARF.
558 // FIXME: When opt-remarks are supported in MC, add a remark to notify
559 // the user.
560 if (XReg != AArch64::FP)
561 return CU::UNWIND_ARM64_MODE_DWARF;
562
563 assert(XReg == AArch64::FP && "Invalid frame pointer!");
Tim Northover3b0846e2014-05-24 12:50:23 +0000564 assert(i + 2 < e && "Insufficient CFI instructions to define a frame!");
565
566 const MCCFIInstruction &LRPush = Instrs[++i];
567 assert(LRPush.getOperation() == MCCFIInstruction::OpOffset &&
568 "Link register not pushed!");
569 const MCCFIInstruction &FPPush = Instrs[++i];
570 assert(FPPush.getOperation() == MCCFIInstruction::OpOffset &&
571 "Frame pointer not pushed!");
572
573 unsigned LRReg = MRI.getLLVMRegNum(LRPush.getRegister(), true);
574 unsigned FPReg = MRI.getLLVMRegNum(FPPush.getRegister(), true);
575
576 LRReg = getXRegFromWReg(LRReg);
577 FPReg = getXRegFromWReg(FPReg);
578
579 assert(LRReg == AArch64::LR && FPReg == AArch64::FP &&
580 "Pushing invalid registers for frame!");
581
582 // Indicate that the function has a frame.
Tim Northover87442c12016-02-23 21:49:05 +0000583 CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAME;
Tim Northover3b0846e2014-05-24 12:50:23 +0000584 HasFP = true;
585 break;
586 }
587 case MCCFIInstruction::OpDefCfaOffset: {
588 assert(StackSize == 0 && "We already have the CFA offset!");
589 StackSize = std::abs(Inst.getOffset());
590 break;
591 }
592 case MCCFIInstruction::OpOffset: {
593 // Registers are saved in pairs. We expect there to be two consecutive
594 // `.cfi_offset' instructions with the appropriate registers specified.
595 unsigned Reg1 = MRI.getLLVMRegNum(Inst.getRegister(), true);
596 if (i + 1 == e)
Tim Northover87442c12016-02-23 21:49:05 +0000597 return CU::UNWIND_ARM64_MODE_DWARF;
Tim Northover3b0846e2014-05-24 12:50:23 +0000598
599 const MCCFIInstruction &Inst2 = Instrs[++i];
600 if (Inst2.getOperation() != MCCFIInstruction::OpOffset)
Tim Northover87442c12016-02-23 21:49:05 +0000601 return CU::UNWIND_ARM64_MODE_DWARF;
Tim Northover3b0846e2014-05-24 12:50:23 +0000602 unsigned Reg2 = MRI.getLLVMRegNum(Inst2.getRegister(), true);
603
604 // N.B. The encodings must be in register number order, and the X
605 // registers before the D registers.
606
607 // X19/X20 pair = 0x00000001,
608 // X21/X22 pair = 0x00000002,
609 // X23/X24 pair = 0x00000004,
610 // X25/X26 pair = 0x00000008,
611 // X27/X28 pair = 0x00000010
612 Reg1 = getXRegFromWReg(Reg1);
613 Reg2 = getXRegFromWReg(Reg2);
614
615 if (Reg1 == AArch64::X19 && Reg2 == AArch64::X20 &&
616 (CompactUnwindEncoding & 0xF1E) == 0)
Tim Northover87442c12016-02-23 21:49:05 +0000617 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X19_X20_PAIR;
Tim Northover3b0846e2014-05-24 12:50:23 +0000618 else if (Reg1 == AArch64::X21 && Reg2 == AArch64::X22 &&
619 (CompactUnwindEncoding & 0xF1C) == 0)
Tim Northover87442c12016-02-23 21:49:05 +0000620 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X21_X22_PAIR;
Tim Northover3b0846e2014-05-24 12:50:23 +0000621 else if (Reg1 == AArch64::X23 && Reg2 == AArch64::X24 &&
622 (CompactUnwindEncoding & 0xF18) == 0)
Tim Northover87442c12016-02-23 21:49:05 +0000623 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X23_X24_PAIR;
Tim Northover3b0846e2014-05-24 12:50:23 +0000624 else if (Reg1 == AArch64::X25 && Reg2 == AArch64::X26 &&
625 (CompactUnwindEncoding & 0xF10) == 0)
Tim Northover87442c12016-02-23 21:49:05 +0000626 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X25_X26_PAIR;
Tim Northover3b0846e2014-05-24 12:50:23 +0000627 else if (Reg1 == AArch64::X27 && Reg2 == AArch64::X28 &&
628 (CompactUnwindEncoding & 0xF00) == 0)
Tim Northover87442c12016-02-23 21:49:05 +0000629 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X27_X28_PAIR;
Tim Northover3b0846e2014-05-24 12:50:23 +0000630 else {
631 Reg1 = getDRegFromBReg(Reg1);
632 Reg2 = getDRegFromBReg(Reg2);
633
634 // D8/D9 pair = 0x00000100,
635 // D10/D11 pair = 0x00000200,
636 // D12/D13 pair = 0x00000400,
637 // D14/D15 pair = 0x00000800
638 if (Reg1 == AArch64::D8 && Reg2 == AArch64::D9 &&
639 (CompactUnwindEncoding & 0xE00) == 0)
Tim Northover87442c12016-02-23 21:49:05 +0000640 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D8_D9_PAIR;
Tim Northover3b0846e2014-05-24 12:50:23 +0000641 else if (Reg1 == AArch64::D10 && Reg2 == AArch64::D11 &&
642 (CompactUnwindEncoding & 0xC00) == 0)
Tim Northover87442c12016-02-23 21:49:05 +0000643 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D10_D11_PAIR;
Tim Northover3b0846e2014-05-24 12:50:23 +0000644 else if (Reg1 == AArch64::D12 && Reg2 == AArch64::D13 &&
645 (CompactUnwindEncoding & 0x800) == 0)
Tim Northover87442c12016-02-23 21:49:05 +0000646 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D12_D13_PAIR;
Tim Northover3b0846e2014-05-24 12:50:23 +0000647 else if (Reg1 == AArch64::D14 && Reg2 == AArch64::D15)
Tim Northover87442c12016-02-23 21:49:05 +0000648 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D14_D15_PAIR;
Tim Northover3b0846e2014-05-24 12:50:23 +0000649 else
650 // A pair was pushed which we cannot handle.
Tim Northover87442c12016-02-23 21:49:05 +0000651 return CU::UNWIND_ARM64_MODE_DWARF;
Tim Northover3b0846e2014-05-24 12:50:23 +0000652 }
653
654 break;
655 }
656 }
657 }
658
659 if (!HasFP) {
660 // With compact unwind info we can only represent stack adjustments of up
661 // to 65520 bytes.
662 if (StackSize > 65520)
Tim Northover87442c12016-02-23 21:49:05 +0000663 return CU::UNWIND_ARM64_MODE_DWARF;
Tim Northover3b0846e2014-05-24 12:50:23 +0000664
Tim Northover87442c12016-02-23 21:49:05 +0000665 CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAMELESS;
Tim Northover3b0846e2014-05-24 12:50:23 +0000666 CompactUnwindEncoding |= encodeStackAdjustment(StackSize);
667 }
668
669 return CompactUnwindEncoding;
670 }
671};
672
673} // end anonymous namespace
674
675namespace {
676
677class ELFAArch64AsmBackend : public AArch64AsmBackend {
678public:
679 uint8_t OSABI;
Joel Jones504bf332016-10-24 13:37:13 +0000680 bool IsILP32;
Tim Northover3b0846e2014-05-24 12:50:23 +0000681
Martin Storsjo0b7bf7a2017-07-26 11:19:17 +0000682 ELFAArch64AsmBackend(const Target &T, const Triple &TT, uint8_t OSABI,
683 bool IsLittleEndian, bool IsILP32)
684 : AArch64AsmBackend(T, TT, IsLittleEndian), OSABI(OSABI),
685 IsILP32(IsILP32) {}
Tim Northover3b0846e2014-05-24 12:50:23 +0000686
Peter Collingbournedcd7d6c2018-05-21 19:20:29 +0000687 std::unique_ptr<MCObjectTargetWriter>
688 createObjectTargetWriter() const override {
689 return createAArch64ELFObjectWriter(OSABI, IsILP32);
Tim Northover3b0846e2014-05-24 12:50:23 +0000690 }
Tim Northover3b0846e2014-05-24 12:50:23 +0000691};
692
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000693}
Tim Northover3b0846e2014-05-24 12:50:23 +0000694
Mandeep Singh Grang0c721722017-06-27 23:58:19 +0000695namespace {
696class COFFAArch64AsmBackend : public AArch64AsmBackend {
697public:
698 COFFAArch64AsmBackend(const Target &T, const Triple &TheTriple)
Martin Storsjo0b7bf7a2017-07-26 11:19:17 +0000699 : AArch64AsmBackend(T, TheTriple, /*IsLittleEndian*/ true) {}
Mandeep Singh Grang0c721722017-06-27 23:58:19 +0000700
Peter Collingbournedcd7d6c2018-05-21 19:20:29 +0000701 std::unique_ptr<MCObjectTargetWriter>
702 createObjectTargetWriter() const override {
703 return createAArch64WinCOFFObjectWriter();
Mandeep Singh Grang0c721722017-06-27 23:58:19 +0000704 }
705};
706}
707
Tim Northover3b0846e2014-05-24 12:50:23 +0000708MCAsmBackend *llvm::createAArch64leAsmBackend(const Target &T,
Alex Bradburyb22f7512018-01-03 08:53:05 +0000709 const MCSubtargetInfo &STI,
Daniel Sanders418caf52015-06-10 10:35:34 +0000710 const MCRegisterInfo &MRI,
Joel Jones373d7d32016-07-25 17:18:28 +0000711 const MCTargetOptions &Options) {
Alex Bradburyb22f7512018-01-03 08:53:05 +0000712 const Triple &TheTriple = STI.getTargetTriple();
Daniel Sanders50f17232015-09-15 16:17:27 +0000713 if (TheTriple.isOSBinFormatMachO())
Martin Storsjo0b7bf7a2017-07-26 11:19:17 +0000714 return new DarwinAArch64AsmBackend(T, TheTriple, MRI);
Tim Northover3b0846e2014-05-24 12:50:23 +0000715
Mandeep Singh Grang0c721722017-06-27 23:58:19 +0000716 if (TheTriple.isOSBinFormatCOFF())
717 return new COFFAArch64AsmBackend(T, TheTriple);
718
Mandeep Singh Grang6f61e232017-06-28 19:37:38 +0000719 assert(TheTriple.isOSBinFormatELF() && "Invalid target");
Mandeep Singh Grang0c721722017-06-27 23:58:19 +0000720
Daniel Sanders50f17232015-09-15 16:17:27 +0000721 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
Joel Jones504bf332016-10-24 13:37:13 +0000722 bool IsILP32 = Options.getABIName() == "ilp32";
Martin Storsjo0b7bf7a2017-07-26 11:19:17 +0000723 return new ELFAArch64AsmBackend(T, TheTriple, OSABI, /*IsLittleEndian=*/true,
724 IsILP32);
Tim Northover3b0846e2014-05-24 12:50:23 +0000725}
726
727MCAsmBackend *llvm::createAArch64beAsmBackend(const Target &T,
Alex Bradburyb22f7512018-01-03 08:53:05 +0000728 const MCSubtargetInfo &STI,
Daniel Sanders418caf52015-06-10 10:35:34 +0000729 const MCRegisterInfo &MRI,
Joel Jones373d7d32016-07-25 17:18:28 +0000730 const MCTargetOptions &Options) {
Alex Bradburyb22f7512018-01-03 08:53:05 +0000731 const Triple &TheTriple = STI.getTargetTriple();
Daniel Sanders50f17232015-09-15 16:17:27 +0000732 assert(TheTriple.isOSBinFormatELF() &&
Tim Northover3b0846e2014-05-24 12:50:23 +0000733 "Big endian is only supported for ELF targets!");
Daniel Sanders50f17232015-09-15 16:17:27 +0000734 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
Joel Jones504bf332016-10-24 13:37:13 +0000735 bool IsILP32 = Options.getABIName() == "ilp32";
Martin Storsjo0b7bf7a2017-07-26 11:19:17 +0000736 return new ELFAArch64AsmBackend(T, TheTriple, OSABI, /*IsLittleEndian=*/false,
737 IsILP32);
Tim Northover3b0846e2014-05-24 12:50:23 +0000738}