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