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