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" 24 using namespace llvm; 25 26 namespace { 27 28 class AArch64AsmBackend : public MCAsmBackend { 29 static const unsigned PCRelFlagVal = 30 MCFixupKindInfo::FKF_IsAlignedDownTo32Bits | MCFixupKindInfo::FKF_IsPCRel; 31 32 public: 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. 88 static 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 126 static unsigned AdrImmBits(unsigned Value) { 127 unsigned lo2 = Value & 0x3; 128 unsigned hi19 = (Value & 0x1ffffc) >> 2; 129 return (hi19 << 5) | (lo2 << 29); 130 } 131 132 static 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 204 void 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 226 bool AArch64AsmBackend::mayNeedRelaxation(const MCInst &Inst) const { 227 return false; 228 } 229 230 bool 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 241 void AArch64AsmBackend::relaxInstruction(const MCInst &Inst, 242 MCInst &Res) const { 243 llvm_unreachable("AArch64AsmBackend::relaxInstruction() unimplemented"); 244 } 245 246 bool 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 OW->WriteZeros(Count % 4); 251 252 // We are properly aligned, so write NOPs as requested. 253 Count /= 4; 254 for (uint64_t i = 0; i != Count; ++i) 255 OW->write32(0xd503201f); 256 return true; 257 } 258 259 namespace { 260 261 namespace CU { 262 263 /// \brief Compact unwind encoding values. 264 enum CompactUnwindEncodings { 265 /// \brief A "frameless" leaf function, where no non-volatile registers are 266 /// saved. The return remains in LR throughout the function. 267 UNWIND_AArch64_MODE_FRAMELESS = 0x02000000, 268 269 /// \brief No compact unwind encoding available. Instead the low 23-bits of 270 /// the compact unwind encoding is the offset of the DWARF FDE in the 271 /// __eh_frame section. This mode is never used in object files. It is only 272 /// generated by the linker in final linked images, which have only DWARF info 273 /// for a function. 274 UNWIND_AArch64_MODE_DWARF = 0x03000000, 275 276 /// \brief This is a standard arm64 prologue where FP/LR are immediately 277 /// pushed on the stack, then SP is copied to FP. If there are any 278 /// non-volatile register saved, they are copied into the stack fame in pairs 279 /// in a contiguous ranger right below the saved FP/LR pair. Any subset of the 280 /// five X pairs and four D pairs can be saved, but the memory layout must be 281 /// in register number order. 282 UNWIND_AArch64_MODE_FRAME = 0x04000000, 283 284 /// \brief Frame register pair encodings. 285 UNWIND_AArch64_FRAME_X19_X20_PAIR = 0x00000001, 286 UNWIND_AArch64_FRAME_X21_X22_PAIR = 0x00000002, 287 UNWIND_AArch64_FRAME_X23_X24_PAIR = 0x00000004, 288 UNWIND_AArch64_FRAME_X25_X26_PAIR = 0x00000008, 289 UNWIND_AArch64_FRAME_X27_X28_PAIR = 0x00000010, 290 UNWIND_AArch64_FRAME_D8_D9_PAIR = 0x00000100, 291 UNWIND_AArch64_FRAME_D10_D11_PAIR = 0x00000200, 292 UNWIND_AArch64_FRAME_D12_D13_PAIR = 0x00000400, 293 UNWIND_AArch64_FRAME_D14_D15_PAIR = 0x00000800 294 }; 295 296 } // end CU namespace 297 298 // FIXME: This should be in a separate file. 299 class DarwinAArch64AsmBackend : public AArch64AsmBackend { 300 const MCRegisterInfo &MRI; 301 302 /// \brief Encode compact unwind stack adjustment for frameless functions. 303 /// See UNWIND_AArch64_FRAMELESS_STACK_SIZE_MASK in compact_unwind_encoding.h. 304 /// The stack size always needs to be 16 byte aligned. 305 uint32_t encodeStackAdjustment(uint32_t StackSize) const { 306 return (StackSize / 16) << 12; 307 } 308 309 public: 310 DarwinAArch64AsmBackend(const Target &T, const MCRegisterInfo &MRI) 311 : AArch64AsmBackend(T), MRI(MRI) {} 312 313 MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override { 314 return createAArch64MachObjectWriter(OS, MachO::CPU_TYPE_ARM64, 315 MachO::CPU_SUBTYPE_ARM64_ALL); 316 } 317 318 /// \brief Generate the compact unwind encoding from the CFI directives. 319 uint32_t generateCompactUnwindEncoding( 320 ArrayRef<MCCFIInstruction> Instrs) const override { 321 if (Instrs.empty()) 322 return CU::UNWIND_AArch64_MODE_FRAMELESS; 323 324 bool HasFP = false; 325 unsigned StackSize = 0; 326 327 uint32_t CompactUnwindEncoding = 0; 328 for (size_t i = 0, e = Instrs.size(); i != e; ++i) { 329 const MCCFIInstruction &Inst = Instrs[i]; 330 331 switch (Inst.getOperation()) { 332 default: 333 // Cannot handle this directive: bail out. 334 return CU::UNWIND_AArch64_MODE_DWARF; 335 case MCCFIInstruction::OpDefCfa: { 336 // Defines a frame pointer. 337 assert(getXRegFromWReg(MRI.getLLVMRegNum(Inst.getRegister(), true)) == 338 AArch64::FP && 339 "Invalid frame pointer!"); 340 assert(i + 2 < e && "Insufficient CFI instructions to define a frame!"); 341 342 const MCCFIInstruction &LRPush = Instrs[++i]; 343 assert(LRPush.getOperation() == MCCFIInstruction::OpOffset && 344 "Link register not pushed!"); 345 const MCCFIInstruction &FPPush = Instrs[++i]; 346 assert(FPPush.getOperation() == MCCFIInstruction::OpOffset && 347 "Frame pointer not pushed!"); 348 349 unsigned LRReg = MRI.getLLVMRegNum(LRPush.getRegister(), true); 350 unsigned FPReg = MRI.getLLVMRegNum(FPPush.getRegister(), true); 351 352 LRReg = getXRegFromWReg(LRReg); 353 FPReg = getXRegFromWReg(FPReg); 354 355 assert(LRReg == AArch64::LR && FPReg == AArch64::FP && 356 "Pushing invalid registers for frame!"); 357 358 // Indicate that the function has a frame. 359 CompactUnwindEncoding |= CU::UNWIND_AArch64_MODE_FRAME; 360 HasFP = true; 361 break; 362 } 363 case MCCFIInstruction::OpDefCfaOffset: { 364 assert(StackSize == 0 && "We already have the CFA offset!"); 365 StackSize = std::abs(Inst.getOffset()); 366 break; 367 } 368 case MCCFIInstruction::OpOffset: { 369 // Registers are saved in pairs. We expect there to be two consecutive 370 // `.cfi_offset' instructions with the appropriate registers specified. 371 unsigned Reg1 = MRI.getLLVMRegNum(Inst.getRegister(), true); 372 if (i + 1 == e) 373 return CU::UNWIND_AArch64_MODE_DWARF; 374 375 const MCCFIInstruction &Inst2 = Instrs[++i]; 376 if (Inst2.getOperation() != MCCFIInstruction::OpOffset) 377 return CU::UNWIND_AArch64_MODE_DWARF; 378 unsigned Reg2 = MRI.getLLVMRegNum(Inst2.getRegister(), true); 379 380 // N.B. The encodings must be in register number order, and the X 381 // registers before the D registers. 382 383 // X19/X20 pair = 0x00000001, 384 // X21/X22 pair = 0x00000002, 385 // X23/X24 pair = 0x00000004, 386 // X25/X26 pair = 0x00000008, 387 // X27/X28 pair = 0x00000010 388 Reg1 = getXRegFromWReg(Reg1); 389 Reg2 = getXRegFromWReg(Reg2); 390 391 if (Reg1 == AArch64::X19 && Reg2 == AArch64::X20 && 392 (CompactUnwindEncoding & 0xF1E) == 0) 393 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X19_X20_PAIR; 394 else if (Reg1 == AArch64::X21 && Reg2 == AArch64::X22 && 395 (CompactUnwindEncoding & 0xF1C) == 0) 396 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X21_X22_PAIR; 397 else if (Reg1 == AArch64::X23 && Reg2 == AArch64::X24 && 398 (CompactUnwindEncoding & 0xF18) == 0) 399 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X23_X24_PAIR; 400 else if (Reg1 == AArch64::X25 && Reg2 == AArch64::X26 && 401 (CompactUnwindEncoding & 0xF10) == 0) 402 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X25_X26_PAIR; 403 else if (Reg1 == AArch64::X27 && Reg2 == AArch64::X28 && 404 (CompactUnwindEncoding & 0xF00) == 0) 405 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X27_X28_PAIR; 406 else { 407 Reg1 = getDRegFromBReg(Reg1); 408 Reg2 = getDRegFromBReg(Reg2); 409 410 // D8/D9 pair = 0x00000100, 411 // D10/D11 pair = 0x00000200, 412 // D12/D13 pair = 0x00000400, 413 // D14/D15 pair = 0x00000800 414 if (Reg1 == AArch64::D8 && Reg2 == AArch64::D9 && 415 (CompactUnwindEncoding & 0xE00) == 0) 416 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_D8_D9_PAIR; 417 else if (Reg1 == AArch64::D10 && Reg2 == AArch64::D11 && 418 (CompactUnwindEncoding & 0xC00) == 0) 419 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_D10_D11_PAIR; 420 else if (Reg1 == AArch64::D12 && Reg2 == AArch64::D13 && 421 (CompactUnwindEncoding & 0x800) == 0) 422 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_D12_D13_PAIR; 423 else if (Reg1 == AArch64::D14 && Reg2 == AArch64::D15) 424 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_D14_D15_PAIR; 425 else 426 // A pair was pushed which we cannot handle. 427 return CU::UNWIND_AArch64_MODE_DWARF; 428 } 429 430 break; 431 } 432 } 433 } 434 435 if (!HasFP) { 436 // With compact unwind info we can only represent stack adjustments of up 437 // to 65520 bytes. 438 if (StackSize > 65520) 439 return CU::UNWIND_AArch64_MODE_DWARF; 440 441 CompactUnwindEncoding |= CU::UNWIND_AArch64_MODE_FRAMELESS; 442 CompactUnwindEncoding |= encodeStackAdjustment(StackSize); 443 } 444 445 return CompactUnwindEncoding; 446 } 447 }; 448 449 } // end anonymous namespace 450 451 namespace { 452 453 class ELFAArch64AsmBackend : public AArch64AsmBackend { 454 public: 455 uint8_t OSABI; 456 bool IsLittleEndian; 457 458 ELFAArch64AsmBackend(const Target &T, uint8_t OSABI, bool IsLittleEndian) 459 : AArch64AsmBackend(T), OSABI(OSABI), IsLittleEndian(IsLittleEndian) {} 460 461 MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override { 462 return createAArch64ELFObjectWriter(OS, OSABI, IsLittleEndian); 463 } 464 465 void processFixupValue(const MCAssembler &Asm, const MCAsmLayout &Layout, 466 const MCFixup &Fixup, const MCFragment *DF, 467 const MCValue &Target, uint64_t &Value, 468 bool &IsResolved) override; 469 470 void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, 471 uint64_t Value, bool IsPCRel) const override; 472 }; 473 474 void ELFAArch64AsmBackend::processFixupValue( 475 const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFixup &Fixup, 476 const MCFragment *DF, const MCValue &Target, uint64_t &Value, 477 bool &IsResolved) { 478 // The ADRP instruction adds some multiple of 0x1000 to the current PC & 479 // ~0xfff. This means that the required offset to reach a symbol can vary by 480 // up to one step depending on where the ADRP is in memory. For example: 481 // 482 // ADRP x0, there 483 // there: 484 // 485 // If the ADRP occurs at address 0xffc then "there" will be at 0x1000 and 486 // we'll need that as an offset. At any other address "there" will be in the 487 // same page as the ADRP and the instruction should encode 0x0. Assuming the 488 // section isn't 0x1000-aligned, we therefore need to delegate this decision 489 // to the linker -- a relocation! 490 if ((uint32_t)Fixup.getKind() == AArch64::fixup_aarch64_pcrel_adrp_imm21) 491 IsResolved = false; 492 } 493 494 // Returns whether this fixup is based on an address in the .eh_frame section, 495 // and therefore should be byte swapped. 496 // FIXME: Should be replaced with something more principled. 497 static bool isByteSwappedFixup(const MCExpr *E) { 498 MCValue Val; 499 if (!E->evaluateAsRelocatable(Val, nullptr, nullptr)) 500 return false; 501 502 if (!Val.getSymA() || Val.getSymA()->getSymbol().isUndefined()) 503 return false; 504 505 const MCSectionELF *SecELF = 506 dyn_cast<MCSectionELF>(&Val.getSymA()->getSymbol().getSection()); 507 return SecELF->getSectionName() == ".eh_frame"; 508 } 509 510 void ELFAArch64AsmBackend::applyFixup(const MCFixup &Fixup, char *Data, 511 unsigned DataSize, uint64_t Value, 512 bool IsPCRel) const { 513 // store fixups in .eh_frame section in big endian order 514 if (!IsLittleEndian && Fixup.getKind() == FK_Data_4) { 515 if (isByteSwappedFixup(Fixup.getValue())) 516 Value = ByteSwap_32(unsigned(Value)); 517 } 518 AArch64AsmBackend::applyFixup (Fixup, Data, DataSize, Value, IsPCRel); 519 } 520 } 521 522 MCAsmBackend *llvm::createAArch64leAsmBackend(const Target &T, 523 const MCRegisterInfo &MRI, 524 const Triple &TheTriple, 525 StringRef CPU) { 526 if (TheTriple.isOSBinFormatMachO()) 527 return new DarwinAArch64AsmBackend(T, MRI); 528 529 assert(TheTriple.isOSBinFormatELF() && "Expect either MachO or ELF target"); 530 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); 531 return new ELFAArch64AsmBackend(T, OSABI, /*IsLittleEndian=*/true); 532 } 533 534 MCAsmBackend *llvm::createAArch64beAsmBackend(const Target &T, 535 const MCRegisterInfo &MRI, 536 const Triple &TheTriple, 537 StringRef CPU) { 538 assert(TheTriple.isOSBinFormatELF() && 539 "Big endian is only supported for ELF targets!"); 540 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); 541 return new ELFAArch64AsmBackend(T, OSABI, 542 /*IsLittleEndian=*/false); 543 } 544