172062f5744557e270a38192554c3126ea5f97434Tim Northover//===-- AArch64AsmBackend.cpp - AArch64 Assembler Backend -----------------===//
272062f5744557e270a38192554c3126ea5f97434Tim Northover//
372062f5744557e270a38192554c3126ea5f97434Tim Northover//                     The LLVM Compiler Infrastructure
472062f5744557e270a38192554c3126ea5f97434Tim Northover//
572062f5744557e270a38192554c3126ea5f97434Tim Northover// This file is distributed under the University of Illinois Open Source
672062f5744557e270a38192554c3126ea5f97434Tim Northover// License. See LICENSE.TXT for details.
772062f5744557e270a38192554c3126ea5f97434Tim Northover//
872062f5744557e270a38192554c3126ea5f97434Tim Northover//===----------------------------------------------------------------------===//
972062f5744557e270a38192554c3126ea5f97434Tim Northover
10dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "AArch64.h"
11dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "AArch64RegisterInfo.h"
1272062f5744557e270a38192554c3126ea5f97434Tim Northover#include "MCTargetDesc/AArch64FixupKinds.h"
13dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/ADT/Triple.h"
1472062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCAsmBackend.h"
15dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCDirectives.h"
1637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/MC/MCELFObjectWriter.h"
17ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/MC/MCFixupKindInfo.h"
1872062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCObjectWriter.h"
19dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCSectionELF.h"
2037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/MC/MCSectionMachO.h"
214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/MC/MCValue.h"
2272062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Support/ErrorHandling.h"
23dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Support/MachO.h"
2472062f5744557e270a38192554c3126ea5f97434Tim Northoverusing namespace llvm;
2572062f5744557e270a38192554c3126ea5f97434Tim Northover
2672062f5744557e270a38192554c3126ea5f97434Tim Northovernamespace {
2772062f5744557e270a38192554c3126ea5f97434Tim Northover
28dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesclass AArch64AsmBackend : public MCAsmBackend {
29dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  static const unsigned PCRelFlagVal =
30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MCFixupKindInfo::FKF_IsAlignedDownTo32Bits | MCFixupKindInfo::FKF_IsPCRel;
3172062f5744557e270a38192554c3126ea5f97434Tim Northover
3236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic:
33dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  AArch64AsmBackend(const Target &T) : MCAsmBackend() {}
3472062f5744557e270a38192554c3126ea5f97434Tim Northover
35dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned getNumFixupKinds() const override {
3672062f5744557e270a38192554c3126ea5f97434Tim Northover    return AArch64::NumTargetFixupKinds;
3772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
3872062f5744557e270a38192554c3126ea5f97434Tim Northover
39dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
4072062f5744557e270a38192554c3126ea5f97434Tim Northover    const static MCFixupKindInfo Infos[AArch64::NumTargetFixupKinds] = {
41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // This table *must* be in the order that the fixup_* kinds are defined in
42dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // AArch64FixupKinds.h.
43dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      //
44dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // Name                           Offset (bits) Size (bits)     Flags
45dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      { "fixup_aarch64_pcrel_adr_imm21", 0, 32, PCRelFlagVal },
46dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      { "fixup_aarch64_pcrel_adrp_imm21", 0, 32, PCRelFlagVal },
47dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      { "fixup_aarch64_add_imm12", 10, 12, 0 },
48dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      { "fixup_aarch64_ldst_imm12_scale1", 10, 12, 0 },
49dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      { "fixup_aarch64_ldst_imm12_scale2", 10, 12, 0 },
50dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      { "fixup_aarch64_ldst_imm12_scale4", 10, 12, 0 },
51dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      { "fixup_aarch64_ldst_imm12_scale8", 10, 12, 0 },
52dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      { "fixup_aarch64_ldst_imm12_scale16", 10, 12, 0 },
53dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      { "fixup_aarch64_ldr_pcrel_imm19", 5, 19, PCRelFlagVal },
54dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      { "fixup_aarch64_movw", 5, 16, 0 },
55dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      { "fixup_aarch64_pcrel_branch14", 5, 14, PCRelFlagVal },
56dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      { "fixup_aarch64_pcrel_branch19", 5, 19, PCRelFlagVal },
57dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      { "fixup_aarch64_pcrel_branch26", 0, 26, PCRelFlagVal },
58dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      { "fixup_aarch64_pcrel_call26", 0, 26, PCRelFlagVal },
59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      { "fixup_aarch64_tlsdesc_call", 0, 0, 0 }
6072062f5744557e270a38192554c3126ea5f97434Tim Northover    };
61dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
6272062f5744557e270a38192554c3126ea5f97434Tim Northover    if (Kind < FirstTargetFixupKind)
6372062f5744557e270a38192554c3126ea5f97434Tim Northover      return MCAsmBackend::getFixupKindInfo(Kind);
6472062f5744557e270a38192554c3126ea5f97434Tim Northover
6572062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
6672062f5744557e270a38192554c3126ea5f97434Tim Northover           "Invalid kind!");
6772062f5744557e270a38192554c3126ea5f97434Tim Northover    return Infos[Kind - FirstTargetFixupKind];
6872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
6972062f5744557e270a38192554c3126ea5f97434Tim Northover
7072062f5744557e270a38192554c3126ea5f97434Tim Northover  void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
71dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  uint64_t Value, bool IsPCRel) const override;
7272062f5744557e270a38192554c3126ea5f97434Tim Northover
73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool mayNeedRelaxation(const MCInst &Inst) const override;
74dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
75dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                            const MCRelaxableFragment *DF,
76dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                            const MCAsmLayout &Layout) const override;
77dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void relaxInstruction(const MCInst &Inst, MCInst &Res) const override;
78dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
7972062f5744557e270a38192554c3126ea5f97434Tim Northover
80dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void HandleAssemblerFlag(MCAssemblerFlag Flag) {}
8172062f5744557e270a38192554c3126ea5f97434Tim Northover
82dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned getPointerSize() const { return 8; }
8372062f5744557e270a38192554c3126ea5f97434Tim Northover};
8472062f5744557e270a38192554c3126ea5f97434Tim Northover
8572062f5744557e270a38192554c3126ea5f97434Tim Northover} // end anonymous namespace
8672062f5744557e270a38192554c3126ea5f97434Tim Northover
87dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// \brief The number of bytes the fixup may change.
88dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic unsigned getFixupKindNumBytes(unsigned Kind) {
89dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (Kind) {
90dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
91c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    llvm_unreachable("Unknown fixup kind!");
9272062f5744557e270a38192554c3126ea5f97434Tim Northover
93dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_tlsdesc_call:
94dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 0;
9572062f5744557e270a38192554c3126ea5f97434Tim Northover
96dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case FK_Data_1:
97dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 1;
9872062f5744557e270a38192554c3126ea5f97434Tim Northover
99dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case FK_Data_2:
100dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_movw:
101dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 2;
102dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
103dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_pcrel_branch14:
104dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_add_imm12:
105dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_ldst_imm12_scale1:
106dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_ldst_imm12_scale2:
107dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_ldst_imm12_scale4:
108dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_ldst_imm12_scale8:
109dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_ldst_imm12_scale16:
110dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_ldr_pcrel_imm19:
111dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_pcrel_branch19:
112dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 3;
113dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
114dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_pcrel_adr_imm21:
115dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_pcrel_adrp_imm21:
116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_pcrel_branch26:
117dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_pcrel_call26:
118dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case FK_Data_4:
119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 4;
12072062f5744557e270a38192554c3126ea5f97434Tim Northover
121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case FK_Data_8:
122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 8;
123dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
12472062f5744557e270a38192554c3126ea5f97434Tim Northover}
12572062f5744557e270a38192554c3126ea5f97434Tim Northover
126dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic unsigned AdrImmBits(unsigned Value) {
12772062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned lo2 = Value & 0x3;
128dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned hi19 = (Value & 0x1ffffc) >> 2;
12972062f5744557e270a38192554c3126ea5f97434Tim Northover  return (hi19 << 5) | (lo2 << 29);
13072062f5744557e270a38192554c3126ea5f97434Tim Northover}
13172062f5744557e270a38192554c3126ea5f97434Tim Northover
13272062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic uint64_t adjustFixupValue(unsigned Kind, uint64_t Value) {
133dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int64_t SignedValue = static_cast<int64_t>(Value);
13472062f5744557e270a38192554c3126ea5f97434Tim Northover  switch (Kind) {
13572062f5744557e270a38192554c3126ea5f97434Tim Northover  default:
136ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    llvm_unreachable("Unknown fixup kind!");
137dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_pcrel_adr_imm21:
138dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (SignedValue > 2097151 || SignedValue < -2097152)
139dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      report_fatal_error("fixup value out of range");
140dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AdrImmBits(Value & 0x1fffffULL);
141dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_pcrel_adrp_imm21:
142dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AdrImmBits((Value & 0x1fffff000ULL) >> 12);
143dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_ldr_pcrel_imm19:
144dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_pcrel_branch19:
145dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Signed 21-bit immediate
146dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (SignedValue > 2097151 || SignedValue < -2097152)
147dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      report_fatal_error("fixup value out of range");
148dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Low two bits are not encoded.
149dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Value >> 2) & 0x7ffff;
150dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_add_imm12:
151dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_ldst_imm12_scale1:
152dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Unsigned 12-bit immediate
153dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Value >= 0x1000)
154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      report_fatal_error("invalid imm12 fixup value");
15572062f5744557e270a38192554c3126ea5f97434Tim Northover    return Value;
156dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_ldst_imm12_scale2:
157dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Unsigned 12-bit immediate which gets multiplied by 2
158dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Value & 1 || Value >= 0x2000)
159dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      report_fatal_error("invalid imm12 fixup value");
160dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Value >> 1;
161dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_ldst_imm12_scale4:
162dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Unsigned 12-bit immediate which gets multiplied by 4
163dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Value & 3 || Value >= 0x4000)
164dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      report_fatal_error("invalid imm12 fixup value");
165dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Value >> 2;
166dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_ldst_imm12_scale8:
167dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Unsigned 12-bit immediate which gets multiplied by 8
168dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Value & 7 || Value >= 0x8000)
169dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      report_fatal_error("invalid imm12 fixup value");
170dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Value >> 3;
171dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_ldst_imm12_scale16:
172dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Unsigned 12-bit immediate which gets multiplied by 16
173dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Value & 15 || Value >= 0x10000)
174dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      report_fatal_error("invalid imm12 fixup value");
175dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Value >> 4;
176dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_movw:
177dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    report_fatal_error("no resolvable MOVZ/MOVK fixups supported yet");
17872062f5744557e270a38192554c3126ea5f97434Tim Northover    return Value;
179dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_pcrel_branch14:
180dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Signed 16-bit immediate
181dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (SignedValue > 32767 || SignedValue < -32768)
182dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      report_fatal_error("fixup value out of range");
183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Low two bits are not encoded (4-byte alignment assumed).
184dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Value & 0x3)
185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      report_fatal_error("fixup not sufficiently aligned");
186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Value >> 2) & 0x3fff;
187dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_pcrel_branch26:
188dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64::fixup_aarch64_pcrel_call26:
189dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Signed 28-bit immediate
190dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (SignedValue > 134217727 || SignedValue < -134217728)
191dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      report_fatal_error("fixup value out of range");
192dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Low two bits are not encoded (4-byte alignment assumed).
193dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Value & 0x3)
194dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      report_fatal_error("fixup not sufficiently aligned");
195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (Value >> 2) & 0x3ffffff;
196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case FK_Data_1:
197dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case FK_Data_2:
198dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case FK_Data_4:
19972062f5744557e270a38192554c3126ea5f97434Tim Northover  case FK_Data_8:
20072062f5744557e270a38192554c3126ea5f97434Tim Northover    return Value;
201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
202dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
20372062f5744557e270a38192554c3126ea5f97434Tim Northover
204dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AArch64AsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                   unsigned DataSize, uint64_t Value,
206dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                   bool IsPCRel) const {
207dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
208dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!Value)
209dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return; // Doesn't change encoding.
210dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind());
211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Apply any target-specific value adjustments.
212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Value = adjustFixupValue(Fixup.getKind(), Value);
213dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
214dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Shift the value into position.
215dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Value <<= Info.TargetOffset;
216dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
217dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Offset = Fixup.getOffset();
218dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(Offset + NumBytes <= DataSize && "Invalid fixup offset!");
219dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
220dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // For each byte of the fragment that the fixup touches, mask in the
221dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // bits from the fixup value.
222dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (unsigned i = 0; i != NumBytes; ++i)
223dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
224dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
225dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
226dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64AsmBackend::mayNeedRelaxation(const MCInst &Inst) const {
227dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
228dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
229dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
230dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64AsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
231dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                             uint64_t Value,
232dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                             const MCRelaxableFragment *DF,
233dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                             const MCAsmLayout &Layout) const {
234dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // FIXME:  This isn't correct for AArch64. Just moving the "generic" logic
235dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // into the targets for now.
236dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //
237dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Relax if the value is too big for a (signed) i8.
238dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return int64_t(Value) != int64_t(int8_t(Value));
239dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
240dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
241dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AArch64AsmBackend::relaxInstruction(const MCInst &Inst,
242dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                         MCInst &Res) const {
243ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  llvm_unreachable("AArch64AsmBackend::relaxInstruction() unimplemented");
244dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
245dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
246dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
247dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // If the count is not 4-byte aligned, we must be writing data into the text
248dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // section (otherwise we have unaligned instructions, and thus have far
249dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // bigger problems), so just write zeros instead.
250dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if ((Count & 3) != 0) {
251dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (uint64_t i = 0, e = (Count & 3); i != e; ++i)
252dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      OW->Write8(0);
25372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
25472062f5744557e270a38192554c3126ea5f97434Tim Northover
255dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // We are properly aligned, so write NOPs as requested.
256dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Count /= 4;
257dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (uint64_t i = 0; i != Count; ++i)
258dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OW->Write32(0xd503201f);
259dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return true;
260dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
261dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
262dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesnamespace {
263dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
264dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesnamespace CU {
265dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
266dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// \brief Compact unwind encoding values.
267dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesenum CompactUnwindEncodings {
268dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// \brief A "frameless" leaf function, where no non-volatile registers are
269dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// saved. The return remains in LR throughout the function.
270dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  UNWIND_AArch64_MODE_FRAMELESS = 0x02000000,
271dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
272dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// \brief No compact unwind encoding available. Instead the low 23-bits of
273dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// the compact unwind encoding is the offset of the DWARF FDE in the
274dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// __eh_frame section. This mode is never used in object files. It is only
275dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// generated by the linker in final linked images, which have only DWARF info
276dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// for a function.
277dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  UNWIND_AArch64_MODE_DWARF = 0x03000000,
278dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
279dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// \brief This is a standard arm64 prologue where FP/LR are immediately
280dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// pushed on the stack, then SP is copied to FP. If there are any
281dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// non-volatile register saved, they are copied into the stack fame in pairs
282dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// in a contiguous ranger right below the saved FP/LR pair. Any subset of the
283dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// five X pairs and four D pairs can be saved, but the memory layout must be
284dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// in register number order.
285dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  UNWIND_AArch64_MODE_FRAME = 0x04000000,
286dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
287dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// \brief Frame register pair encodings.
288dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  UNWIND_AArch64_FRAME_X19_X20_PAIR = 0x00000001,
289dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  UNWIND_AArch64_FRAME_X21_X22_PAIR = 0x00000002,
290dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  UNWIND_AArch64_FRAME_X23_X24_PAIR = 0x00000004,
291dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  UNWIND_AArch64_FRAME_X25_X26_PAIR = 0x00000008,
292dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  UNWIND_AArch64_FRAME_X27_X28_PAIR = 0x00000010,
293dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  UNWIND_AArch64_FRAME_D8_D9_PAIR = 0x00000100,
294dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  UNWIND_AArch64_FRAME_D10_D11_PAIR = 0x00000200,
295dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  UNWIND_AArch64_FRAME_D12_D13_PAIR = 0x00000400,
296dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  UNWIND_AArch64_FRAME_D14_D15_PAIR = 0x00000800
297dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines};
298dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
299dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} // end CU namespace
300dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
301dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// FIXME: This should be in a separate file.
302dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesclass DarwinAArch64AsmBackend : public AArch64AsmBackend {
303dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCRegisterInfo &MRI;
304dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
305dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// \brief Encode compact unwind stack adjustment for frameless functions.
306dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// See UNWIND_AArch64_FRAMELESS_STACK_SIZE_MASK in compact_unwind_encoding.h.
307dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// The stack size always needs to be 16 byte aligned.
308dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint32_t encodeStackAdjustment(uint32_t StackSize) const {
309dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return (StackSize / 16) << 12;
310dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
311dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
312dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinespublic:
313dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  DarwinAArch64AsmBackend(const Target &T, const MCRegisterInfo &MRI)
314dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      : AArch64AsmBackend(T), MRI(MRI) {}
315dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3162c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override {
317dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return createAArch64MachObjectWriter(OS, MachO::CPU_TYPE_ARM64,
318dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                         MachO::CPU_SUBTYPE_ARM64_ALL);
319dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
320dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
321dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// \brief Generate the compact unwind encoding from the CFI directives.
322dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint32_t generateCompactUnwindEncoding(
323dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                             ArrayRef<MCCFIInstruction> Instrs) const override {
324dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Instrs.empty())
325dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return CU::UNWIND_AArch64_MODE_FRAMELESS;
326dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
327dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool HasFP = false;
328dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned StackSize = 0;
329dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
330dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint32_t CompactUnwindEncoding = 0;
331dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (size_t i = 0, e = Instrs.size(); i != e; ++i) {
332dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      const MCCFIInstruction &Inst = Instrs[i];
333dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
334dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      switch (Inst.getOperation()) {
335dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      default:
336dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // Cannot handle this directive:  bail out.
337dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return CU::UNWIND_AArch64_MODE_DWARF;
338dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case MCCFIInstruction::OpDefCfa: {
339dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // Defines a frame pointer.
340dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        assert(getXRegFromWReg(MRI.getLLVMRegNum(Inst.getRegister(), true)) ==
341dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                   AArch64::FP &&
342dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines               "Invalid frame pointer!");
343dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        assert(i + 2 < e && "Insufficient CFI instructions to define a frame!");
344dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
345dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        const MCCFIInstruction &LRPush = Instrs[++i];
346dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        assert(LRPush.getOperation() == MCCFIInstruction::OpOffset &&
347dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines               "Link register not pushed!");
348dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        const MCCFIInstruction &FPPush = Instrs[++i];
349dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        assert(FPPush.getOperation() == MCCFIInstruction::OpOffset &&
350dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines               "Frame pointer not pushed!");
351dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
352dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        unsigned LRReg = MRI.getLLVMRegNum(LRPush.getRegister(), true);
353dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        unsigned FPReg = MRI.getLLVMRegNum(FPPush.getRegister(), true);
354dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
355dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        LRReg = getXRegFromWReg(LRReg);
356dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        FPReg = getXRegFromWReg(FPReg);
357dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
358dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        assert(LRReg == AArch64::LR && FPReg == AArch64::FP &&
359dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines               "Pushing invalid registers for frame!");
360dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
361dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // Indicate that the function has a frame.
362dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        CompactUnwindEncoding |= CU::UNWIND_AArch64_MODE_FRAME;
363dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        HasFP = true;
364dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        break;
365dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
366dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case MCCFIInstruction::OpDefCfaOffset: {
367dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        assert(StackSize == 0 && "We already have the CFA offset!");
368dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        StackSize = std::abs(Inst.getOffset());
369dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        break;
370dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
371dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      case MCCFIInstruction::OpOffset: {
372dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // Registers are saved in pairs. We expect there to be two consecutive
373dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // `.cfi_offset' instructions with the appropriate registers specified.
374dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        unsigned Reg1 = MRI.getLLVMRegNum(Inst.getRegister(), true);
375dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        if (i + 1 == e)
376dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          return CU::UNWIND_AArch64_MODE_DWARF;
377dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
378dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        const MCCFIInstruction &Inst2 = Instrs[++i];
379dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        if (Inst2.getOperation() != MCCFIInstruction::OpOffset)
380dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          return CU::UNWIND_AArch64_MODE_DWARF;
381dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        unsigned Reg2 = MRI.getLLVMRegNum(Inst2.getRegister(), true);
382dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
383dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // N.B. The encodings must be in register number order, and the X
384dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // registers before the D registers.
385dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
386dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // X19/X20 pair = 0x00000001,
387dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // X21/X22 pair = 0x00000002,
388dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // X23/X24 pair = 0x00000004,
389dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // X25/X26 pair = 0x00000008,
390dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // X27/X28 pair = 0x00000010
391dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Reg1 = getXRegFromWReg(Reg1);
392dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Reg2 = getXRegFromWReg(Reg2);
393dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
394dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        if (Reg1 == AArch64::X19 && Reg2 == AArch64::X20 &&
395dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            (CompactUnwindEncoding & 0xF1E) == 0)
396dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X19_X20_PAIR;
397dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        else if (Reg1 == AArch64::X21 && Reg2 == AArch64::X22 &&
398dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 (CompactUnwindEncoding & 0xF1C) == 0)
399dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X21_X22_PAIR;
400dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        else if (Reg1 == AArch64::X23 && Reg2 == AArch64::X24 &&
401dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 (CompactUnwindEncoding & 0xF18) == 0)
402dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X23_X24_PAIR;
403dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        else if (Reg1 == AArch64::X25 && Reg2 == AArch64::X26 &&
404dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 (CompactUnwindEncoding & 0xF10) == 0)
405dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X25_X26_PAIR;
406dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        else if (Reg1 == AArch64::X27 && Reg2 == AArch64::X28 &&
407dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                 (CompactUnwindEncoding & 0xF00) == 0)
408dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X27_X28_PAIR;
409dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        else {
410dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          Reg1 = getDRegFromBReg(Reg1);
411dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          Reg2 = getDRegFromBReg(Reg2);
412dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
413dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          // D8/D9 pair   = 0x00000100,
414dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          // D10/D11 pair = 0x00000200,
415dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          // D12/D13 pair = 0x00000400,
416dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          // D14/D15 pair = 0x00000800
417dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          if (Reg1 == AArch64::D8 && Reg2 == AArch64::D9 &&
418dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines              (CompactUnwindEncoding & 0xE00) == 0)
419dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_D8_D9_PAIR;
420dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          else if (Reg1 == AArch64::D10 && Reg2 == AArch64::D11 &&
421dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                   (CompactUnwindEncoding & 0xC00) == 0)
422dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_D10_D11_PAIR;
423dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          else if (Reg1 == AArch64::D12 && Reg2 == AArch64::D13 &&
424dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                   (CompactUnwindEncoding & 0x800) == 0)
425dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_D12_D13_PAIR;
426dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          else if (Reg1 == AArch64::D14 && Reg2 == AArch64::D15)
427dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_D14_D15_PAIR;
428dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          else
429dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            // A pair was pushed which we cannot handle.
430dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            return CU::UNWIND_AArch64_MODE_DWARF;
431dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        }
432dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
433dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        break;
434dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
435dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
43672062f5744557e270a38192554c3126ea5f97434Tim Northover    }
437dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
438dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!HasFP) {
439dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // With compact unwind info we can only represent stack adjustments of up
440dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // to 65520 bytes.
441dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (StackSize > 65520)
442dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        return CU::UNWIND_AArch64_MODE_DWARF;
443dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
444dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CompactUnwindEncoding |= CU::UNWIND_AArch64_MODE_FRAMELESS;
445dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CompactUnwindEncoding |= encodeStackAdjustment(StackSize);
446dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
447dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
448dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return CompactUnwindEncoding;
44972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
450dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines};
45172062f5744557e270a38192554c3126ea5f97434Tim Northover
452dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} // end anonymous namespace
453dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
454dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesnamespace {
455dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
456dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesclass ELFAArch64AsmBackend : public AArch64AsmBackend {
457dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinespublic:
458dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint8_t OSABI;
459dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool IsLittleEndian;
460dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
461dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  ELFAArch64AsmBackend(const Target &T, uint8_t OSABI, bool IsLittleEndian)
462dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    : AArch64AsmBackend(T), OSABI(OSABI), IsLittleEndian(IsLittleEndian) {}
463dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
4642c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override {
465dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return createAArch64ELFObjectWriter(OS, OSABI, IsLittleEndian);
46672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
467dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
468dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void processFixupValue(const MCAssembler &Asm, const MCAsmLayout &Layout,
469dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                         const MCFixup &Fixup, const MCFragment *DF,
470dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                         const MCValue &Target, uint64_t &Value,
471dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                         bool &IsResolved) override;
472dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
473dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
474dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                  uint64_t Value, bool IsPCRel) const override;
475dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines};
476dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
477dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid ELFAArch64AsmBackend::processFixupValue(
478dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFixup &Fixup,
479dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCFragment *DF, const MCValue &Target, uint64_t &Value,
480dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool &IsResolved) {
481dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // The ADRP instruction adds some multiple of 0x1000 to the current PC &
482dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // ~0xfff. This means that the required offset to reach a symbol can vary by
483dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // up to one step depending on where the ADRP is in memory. For example:
484dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //
485dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //     ADRP x0, there
486dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //  there:
487dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //
488dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // If the ADRP occurs at address 0xffc then "there" will be at 0x1000 and
489dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // we'll need that as an offset. At any other address "there" will be in the
490dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // same page as the ADRP and the instruction should encode 0x0. Assuming the
491dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // section isn't 0x1000-aligned, we therefore need to delegate this decision
492dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // to the linker -- a relocation!
493dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if ((uint32_t)Fixup.getKind() == AArch64::fixup_aarch64_pcrel_adrp_imm21)
494dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    IsResolved = false;
495dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
496dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
4974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// Returns whether this fixup is based on an address in the .eh_frame section,
4984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// and therefore should be byte swapped.
4994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// FIXME: Should be replaced with something more principled.
5004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic bool isByteSwappedFixup(const MCExpr *E) {
5014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  MCValue Val;
5024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  if (!E->EvaluateAsRelocatable(Val, nullptr, nullptr))
5034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    return false;
5044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
5054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  if (!Val.getSymA() || Val.getSymA()->getSymbol().isUndefined())
5064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    return false;
5074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
5084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  const MCSectionELF *SecELF =
5094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      dyn_cast<MCSectionELF>(&Val.getSymA()->getSymbol().getSection());
5104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  return SecELF->getSectionName() == ".eh_frame";
5114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar}
5124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
513dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid ELFAArch64AsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
514dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      unsigned DataSize, uint64_t Value,
515dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      bool IsPCRel) const {
516dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // store fixups in .eh_frame section in big endian order
517dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!IsLittleEndian && Fixup.getKind() == FK_Data_4) {
5184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    if (isByteSwappedFixup(Fixup.getValue()))
519dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Value = ByteSwap_32(unsigned(Value));
520dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
521dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  AArch64AsmBackend::applyFixup (Fixup, Data, DataSize, Value, IsPCRel);
522dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
52372062f5744557e270a38192554c3126ea5f97434Tim Northover}
52472062f5744557e270a38192554c3126ea5f97434Tim Northover
525dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesMCAsmBackend *llvm::createAArch64leAsmBackend(const Target &T,
526dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                            const MCRegisterInfo &MRI,
527dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                            StringRef TT, StringRef CPU) {
52836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Triple TheTriple(TT);
529dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
530dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (TheTriple.isOSDarwin())
531dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return new DarwinAArch64AsmBackend(T, MRI);
532dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
533dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(TheTriple.isOSBinFormatELF() && "Expect either MachO or ELF target");
53437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
53537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return new ELFAArch64AsmBackend(T, OSABI, /*IsLittleEndian=*/true);
53636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
53736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
538dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesMCAsmBackend *llvm::createAArch64beAsmBackend(const Target &T,
539dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                            const MCRegisterInfo &MRI,
540dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                            StringRef TT, StringRef CPU) {
54172062f5744557e270a38192554c3126ea5f97434Tim Northover  Triple TheTriple(TT);
542dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
543dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(TheTriple.isOSBinFormatELF() &&
544dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         "Big endian is only supported for ELF targets!");
54537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
54637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return new ELFAArch64AsmBackend(T, OSABI,
547dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                  /*IsLittleEndian=*/false);
54872062f5744557e270a38192554c3126ea5f97434Tim Northover}
549