181ad6265SDimitry Andric //===-- LoongArchAsmBackend.cpp - LoongArch Assembler Backend -*- C++ -*---===// 281ad6265SDimitry Andric // 381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 681ad6265SDimitry Andric // 781ad6265SDimitry Andric //===----------------------------------------------------------------------===// 881ad6265SDimitry Andric // 981ad6265SDimitry Andric // This file implements the LoongArchAsmBackend class. 1081ad6265SDimitry Andric // 1181ad6265SDimitry Andric //===----------------------------------------------------------------------===// 1281ad6265SDimitry Andric 1381ad6265SDimitry Andric #include "LoongArchAsmBackend.h" 14bdd1243dSDimitry Andric #include "LoongArchFixupKinds.h" 1581ad6265SDimitry Andric #include "llvm/MC/MCAsmLayout.h" 1681ad6265SDimitry Andric #include "llvm/MC/MCAssembler.h" 1781ad6265SDimitry Andric #include "llvm/MC/MCContext.h" 1881ad6265SDimitry Andric #include "llvm/MC/MCELFObjectWriter.h" 19bdd1243dSDimitry Andric #include "llvm/MC/MCValue.h" 2081ad6265SDimitry Andric #include "llvm/Support/EndianStream.h" 2181ad6265SDimitry Andric 2281ad6265SDimitry Andric #define DEBUG_TYPE "loongarch-asmbackend" 2381ad6265SDimitry Andric 2481ad6265SDimitry Andric using namespace llvm; 2581ad6265SDimitry Andric 26bdd1243dSDimitry Andric std::optional<MCFixupKind> 27bdd1243dSDimitry Andric LoongArchAsmBackend::getFixupKind(StringRef Name) const { 28bdd1243dSDimitry Andric if (STI.getTargetTriple().isOSBinFormatELF()) { 29bdd1243dSDimitry Andric auto Type = llvm::StringSwitch<unsigned>(Name) 30bdd1243dSDimitry Andric #define ELF_RELOC(X, Y) .Case(#X, Y) 31bdd1243dSDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/LoongArch.def" 32bdd1243dSDimitry Andric #undef ELF_RELOC 33bdd1243dSDimitry Andric .Case("BFD_RELOC_NONE", ELF::R_LARCH_NONE) 34bdd1243dSDimitry Andric .Case("BFD_RELOC_32", ELF::R_LARCH_32) 35bdd1243dSDimitry Andric .Case("BFD_RELOC_64", ELF::R_LARCH_64) 36bdd1243dSDimitry Andric .Default(-1u); 37bdd1243dSDimitry Andric if (Type != -1u) 38bdd1243dSDimitry Andric return static_cast<MCFixupKind>(FirstLiteralRelocationKind + Type); 39bdd1243dSDimitry Andric } 40bdd1243dSDimitry Andric return std::nullopt; 41bdd1243dSDimitry Andric } 42bdd1243dSDimitry Andric 43bdd1243dSDimitry Andric const MCFixupKindInfo & 44bdd1243dSDimitry Andric LoongArchAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { 45bdd1243dSDimitry Andric const static MCFixupKindInfo Infos[] = { 46bdd1243dSDimitry Andric // This table *must* be in the order that the fixup_* kinds are defined in 47bdd1243dSDimitry Andric // LoongArchFixupKinds.h. 48bdd1243dSDimitry Andric // 49bdd1243dSDimitry Andric // {name, offset, bits, flags} 50bdd1243dSDimitry Andric {"fixup_loongarch_b16", 10, 16, MCFixupKindInfo::FKF_IsPCRel}, 51bdd1243dSDimitry Andric {"fixup_loongarch_b21", 0, 26, MCFixupKindInfo::FKF_IsPCRel}, 52bdd1243dSDimitry Andric {"fixup_loongarch_b26", 0, 26, MCFixupKindInfo::FKF_IsPCRel}, 53bdd1243dSDimitry Andric {"fixup_loongarch_abs_hi20", 5, 20, 0}, 54bdd1243dSDimitry Andric {"fixup_loongarch_abs_lo12", 10, 12, 0}, 55bdd1243dSDimitry Andric {"fixup_loongarch_abs64_lo20", 5, 20, 0}, 56bdd1243dSDimitry Andric {"fixup_loongarch_abs64_hi12", 10, 12, 0}, 57bdd1243dSDimitry Andric {"fixup_loongarch_tls_le_hi20", 5, 20, 0}, 58bdd1243dSDimitry Andric {"fixup_loongarch_tls_le_lo12", 10, 12, 0}, 59bdd1243dSDimitry Andric {"fixup_loongarch_tls_le64_lo20", 5, 20, 0}, 60bdd1243dSDimitry Andric {"fixup_loongarch_tls_le64_hi12", 10, 12, 0}, 61bdd1243dSDimitry Andric // TODO: Add more fixup kinds. 62bdd1243dSDimitry Andric }; 63bdd1243dSDimitry Andric 64bdd1243dSDimitry Andric static_assert((std::size(Infos)) == LoongArch::NumTargetFixupKinds, 65bdd1243dSDimitry Andric "Not all fixup kinds added to Infos array"); 66bdd1243dSDimitry Andric 67bdd1243dSDimitry Andric // Fixup kinds from .reloc directive are like R_LARCH_NONE. They 68bdd1243dSDimitry Andric // do not require any extra processing. 69bdd1243dSDimitry Andric if (Kind >= FirstLiteralRelocationKind) 70bdd1243dSDimitry Andric return MCAsmBackend::getFixupKindInfo(FK_NONE); 71bdd1243dSDimitry Andric 72bdd1243dSDimitry Andric if (Kind < FirstTargetFixupKind) 73bdd1243dSDimitry Andric return MCAsmBackend::getFixupKindInfo(Kind); 74bdd1243dSDimitry Andric 75bdd1243dSDimitry Andric assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && 76bdd1243dSDimitry Andric "Invalid kind!"); 77bdd1243dSDimitry Andric return Infos[Kind - FirstTargetFixupKind]; 78bdd1243dSDimitry Andric } 79bdd1243dSDimitry Andric 80bdd1243dSDimitry Andric static void reportOutOfRangeError(MCContext &Ctx, SMLoc Loc, unsigned N) { 81bdd1243dSDimitry Andric Ctx.reportError(Loc, "fixup value out of range [" + Twine(llvm::minIntN(N)) + 82bdd1243dSDimitry Andric ", " + Twine(llvm::maxIntN(N)) + "]"); 83bdd1243dSDimitry Andric } 84bdd1243dSDimitry Andric 85bdd1243dSDimitry Andric static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value, 86bdd1243dSDimitry Andric MCContext &Ctx) { 87bdd1243dSDimitry Andric switch (Fixup.getTargetKind()) { 88bdd1243dSDimitry Andric default: 89bdd1243dSDimitry Andric llvm_unreachable("Unknown fixup kind"); 90bdd1243dSDimitry Andric case FK_Data_1: 91bdd1243dSDimitry Andric case FK_Data_2: 92bdd1243dSDimitry Andric case FK_Data_4: 93bdd1243dSDimitry Andric case FK_Data_8: 94*1db9f3b2SDimitry Andric case FK_Data_leb128: 95bdd1243dSDimitry Andric return Value; 96bdd1243dSDimitry Andric case LoongArch::fixup_loongarch_b16: { 97bdd1243dSDimitry Andric if (!isInt<18>(Value)) 98bdd1243dSDimitry Andric reportOutOfRangeError(Ctx, Fixup.getLoc(), 18); 99bdd1243dSDimitry Andric if (Value % 4) 100bdd1243dSDimitry Andric Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned"); 101bdd1243dSDimitry Andric return (Value >> 2) & 0xffff; 102bdd1243dSDimitry Andric } 103bdd1243dSDimitry Andric case LoongArch::fixup_loongarch_b21: { 104bdd1243dSDimitry Andric if (!isInt<23>(Value)) 105bdd1243dSDimitry Andric reportOutOfRangeError(Ctx, Fixup.getLoc(), 23); 106bdd1243dSDimitry Andric if (Value % 4) 107bdd1243dSDimitry Andric Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned"); 108bdd1243dSDimitry Andric return ((Value & 0x3fffc) << 8) | ((Value >> 18) & 0x1f); 109bdd1243dSDimitry Andric } 110bdd1243dSDimitry Andric case LoongArch::fixup_loongarch_b26: { 111bdd1243dSDimitry Andric if (!isInt<28>(Value)) 112bdd1243dSDimitry Andric reportOutOfRangeError(Ctx, Fixup.getLoc(), 28); 113bdd1243dSDimitry Andric if (Value % 4) 114bdd1243dSDimitry Andric Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned"); 115bdd1243dSDimitry Andric return ((Value & 0x3fffc) << 8) | ((Value >> 18) & 0x3ff); 116bdd1243dSDimitry Andric } 117bdd1243dSDimitry Andric case LoongArch::fixup_loongarch_abs_hi20: 118bdd1243dSDimitry Andric case LoongArch::fixup_loongarch_tls_le_hi20: 119bdd1243dSDimitry Andric return (Value >> 12) & 0xfffff; 120bdd1243dSDimitry Andric case LoongArch::fixup_loongarch_abs_lo12: 121bdd1243dSDimitry Andric case LoongArch::fixup_loongarch_tls_le_lo12: 122bdd1243dSDimitry Andric return Value & 0xfff; 123bdd1243dSDimitry Andric case LoongArch::fixup_loongarch_abs64_lo20: 124bdd1243dSDimitry Andric case LoongArch::fixup_loongarch_tls_le64_lo20: 125bdd1243dSDimitry Andric return (Value >> 32) & 0xfffff; 126bdd1243dSDimitry Andric case LoongArch::fixup_loongarch_abs64_hi12: 127bdd1243dSDimitry Andric case LoongArch::fixup_loongarch_tls_le64_hi12: 128bdd1243dSDimitry Andric return (Value >> 52) & 0xfff; 129bdd1243dSDimitry Andric } 130bdd1243dSDimitry Andric } 131bdd1243dSDimitry Andric 132*1db9f3b2SDimitry Andric static void fixupLeb128(MCContext &Ctx, const MCFixup &Fixup, 133*1db9f3b2SDimitry Andric MutableArrayRef<char> Data, uint64_t Value) { 134*1db9f3b2SDimitry Andric unsigned I; 135*1db9f3b2SDimitry Andric for (I = 0; I != Data.size() && Value; ++I, Value >>= 7) 136*1db9f3b2SDimitry Andric Data[I] |= uint8_t(Value & 0x7f); 137*1db9f3b2SDimitry Andric if (Value) 138*1db9f3b2SDimitry Andric Ctx.reportError(Fixup.getLoc(), "Invalid uleb128 value!"); 139*1db9f3b2SDimitry Andric } 140*1db9f3b2SDimitry Andric 14181ad6265SDimitry Andric void LoongArchAsmBackend::applyFixup(const MCAssembler &Asm, 14281ad6265SDimitry Andric const MCFixup &Fixup, 14381ad6265SDimitry Andric const MCValue &Target, 14481ad6265SDimitry Andric MutableArrayRef<char> Data, uint64_t Value, 14581ad6265SDimitry Andric bool IsResolved, 14681ad6265SDimitry Andric const MCSubtargetInfo *STI) const { 147bdd1243dSDimitry Andric if (!Value) 148bdd1243dSDimitry Andric return; // Doesn't change encoding. 149bdd1243dSDimitry Andric 150bdd1243dSDimitry Andric MCFixupKind Kind = Fixup.getKind(); 151bdd1243dSDimitry Andric if (Kind >= FirstLiteralRelocationKind) 15281ad6265SDimitry Andric return; 153bdd1243dSDimitry Andric MCFixupKindInfo Info = getFixupKindInfo(Kind); 154bdd1243dSDimitry Andric MCContext &Ctx = Asm.getContext(); 155bdd1243dSDimitry Andric 156*1db9f3b2SDimitry Andric // Fixup leb128 separately. 157*1db9f3b2SDimitry Andric if (Fixup.getTargetKind() == FK_Data_leb128) 158*1db9f3b2SDimitry Andric return fixupLeb128(Ctx, Fixup, Data, Value); 159*1db9f3b2SDimitry Andric 160bdd1243dSDimitry Andric // Apply any target-specific value adjustments. 161bdd1243dSDimitry Andric Value = adjustFixupValue(Fixup, Value, Ctx); 162bdd1243dSDimitry Andric 163bdd1243dSDimitry Andric // Shift the value into position. 164bdd1243dSDimitry Andric Value <<= Info.TargetOffset; 165bdd1243dSDimitry Andric 166bdd1243dSDimitry Andric unsigned Offset = Fixup.getOffset(); 167bdd1243dSDimitry Andric unsigned NumBytes = alignTo(Info.TargetSize + Info.TargetOffset, 8) / 8; 168bdd1243dSDimitry Andric 169bdd1243dSDimitry Andric assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!"); 170bdd1243dSDimitry Andric // For each byte of the fragment that the fixup touches, mask in the 171bdd1243dSDimitry Andric // bits from the fixup value. 172bdd1243dSDimitry Andric for (unsigned I = 0; I != NumBytes; ++I) { 173bdd1243dSDimitry Andric Data[Offset + I] |= uint8_t((Value >> (I * 8)) & 0xff); 174bdd1243dSDimitry Andric } 17581ad6265SDimitry Andric } 17681ad6265SDimitry Andric 17781ad6265SDimitry Andric bool LoongArchAsmBackend::shouldForceRelocation(const MCAssembler &Asm, 17881ad6265SDimitry Andric const MCFixup &Fixup, 1795f757f3fSDimitry Andric const MCValue &Target, 1805f757f3fSDimitry Andric const MCSubtargetInfo *STI) { 181bdd1243dSDimitry Andric if (Fixup.getKind() >= FirstLiteralRelocationKind) 182bdd1243dSDimitry Andric return true; 183bdd1243dSDimitry Andric switch (Fixup.getTargetKind()) { 184bdd1243dSDimitry Andric default: 1855f757f3fSDimitry Andric return STI->hasFeature(LoongArch::FeatureRelax); 186bdd1243dSDimitry Andric case FK_Data_1: 187bdd1243dSDimitry Andric case FK_Data_2: 188bdd1243dSDimitry Andric case FK_Data_4: 189bdd1243dSDimitry Andric case FK_Data_8: 190*1db9f3b2SDimitry Andric case FK_Data_leb128: 191bdd1243dSDimitry Andric return !Target.isAbsolute(); 192bdd1243dSDimitry Andric } 19381ad6265SDimitry Andric } 19481ad6265SDimitry Andric 195cb14a3feSDimitry Andric static inline std::pair<MCFixupKind, MCFixupKind> 196cb14a3feSDimitry Andric getRelocPairForSize(unsigned Size) { 197cb14a3feSDimitry Andric switch (Size) { 198cb14a3feSDimitry Andric default: 199cb14a3feSDimitry Andric llvm_unreachable("unsupported fixup size"); 200cb14a3feSDimitry Andric case 6: 201cb14a3feSDimitry Andric return std::make_pair( 202cb14a3feSDimitry Andric MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_ADD6), 203cb14a3feSDimitry Andric MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_SUB6)); 204cb14a3feSDimitry Andric case 8: 205cb14a3feSDimitry Andric return std::make_pair( 206cb14a3feSDimitry Andric MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_ADD8), 207cb14a3feSDimitry Andric MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_SUB8)); 208cb14a3feSDimitry Andric case 16: 209cb14a3feSDimitry Andric return std::make_pair( 210cb14a3feSDimitry Andric MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_ADD16), 211cb14a3feSDimitry Andric MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_SUB16)); 212cb14a3feSDimitry Andric case 32: 213cb14a3feSDimitry Andric return std::make_pair( 214cb14a3feSDimitry Andric MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_ADD32), 215cb14a3feSDimitry Andric MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_SUB32)); 216cb14a3feSDimitry Andric case 64: 217cb14a3feSDimitry Andric return std::make_pair( 218cb14a3feSDimitry Andric MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_ADD64), 219cb14a3feSDimitry Andric MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_SUB64)); 220*1db9f3b2SDimitry Andric case 128: 221*1db9f3b2SDimitry Andric return std::make_pair( 222*1db9f3b2SDimitry Andric MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_ADD_ULEB128), 223*1db9f3b2SDimitry Andric MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_SUB_ULEB128)); 224cb14a3feSDimitry Andric } 225cb14a3feSDimitry Andric } 226cb14a3feSDimitry Andric 227*1db9f3b2SDimitry Andric std::pair<bool, bool> LoongArchAsmBackend::relaxLEB128(MCLEBFragment &LF, 228*1db9f3b2SDimitry Andric MCAsmLayout &Layout, 229*1db9f3b2SDimitry Andric int64_t &Value) const { 230*1db9f3b2SDimitry Andric const MCExpr &Expr = LF.getValue(); 231*1db9f3b2SDimitry Andric if (LF.isSigned() || !Expr.evaluateKnownAbsolute(Value, Layout)) 232*1db9f3b2SDimitry Andric return std::make_pair(false, false); 233*1db9f3b2SDimitry Andric LF.getFixups().push_back( 234*1db9f3b2SDimitry Andric MCFixup::create(0, &Expr, FK_Data_leb128, Expr.getLoc())); 235*1db9f3b2SDimitry Andric return std::make_pair(true, true); 236*1db9f3b2SDimitry Andric } 237*1db9f3b2SDimitry Andric 23881ad6265SDimitry Andric bool LoongArchAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count, 23981ad6265SDimitry Andric const MCSubtargetInfo *STI) const { 240bdd1243dSDimitry Andric // We mostly follow binutils' convention here: align to 4-byte boundary with a 241bdd1243dSDimitry Andric // 0-fill padding. 242bdd1243dSDimitry Andric OS.write_zeros(Count % 4); 24381ad6265SDimitry Andric 244bdd1243dSDimitry Andric // The remainder is now padded with 4-byte nops. 245bdd1243dSDimitry Andric // nop: andi r0, r0, 0 24681ad6265SDimitry Andric for (; Count >= 4; Count -= 4) 247bdd1243dSDimitry Andric OS.write("\0\0\x40\x03", 4); 24881ad6265SDimitry Andric 24981ad6265SDimitry Andric return true; 25081ad6265SDimitry Andric } 25181ad6265SDimitry Andric 252cb14a3feSDimitry Andric bool LoongArchAsmBackend::handleAddSubRelocations(const MCAsmLayout &Layout, 253cb14a3feSDimitry Andric const MCFragment &F, 254cb14a3feSDimitry Andric const MCFixup &Fixup, 255cb14a3feSDimitry Andric const MCValue &Target, 256cb14a3feSDimitry Andric uint64_t &FixedValue) const { 257cb14a3feSDimitry Andric std::pair<MCFixupKind, MCFixupKind> FK; 258cb14a3feSDimitry Andric uint64_t FixedValueA, FixedValueB; 259*1db9f3b2SDimitry Andric const MCSymbol &SA = Target.getSymA()->getSymbol(); 260*1db9f3b2SDimitry Andric const MCSymbol &SB = Target.getSymB()->getSymbol(); 261*1db9f3b2SDimitry Andric 262*1db9f3b2SDimitry Andric bool force = !SA.isInSection() || !SB.isInSection(); 263*1db9f3b2SDimitry Andric if (!force) { 264*1db9f3b2SDimitry Andric const MCSection &SecA = SA.getSection(); 265*1db9f3b2SDimitry Andric const MCSection &SecB = SB.getSection(); 266cb14a3feSDimitry Andric 267cb14a3feSDimitry Andric // We need record relocation if SecA != SecB. Usually SecB is same as the 268cb14a3feSDimitry Andric // section of Fixup, which will be record the relocation as PCRel. If SecB 269cb14a3feSDimitry Andric // is not same as the section of Fixup, it will report error. Just return 270cb14a3feSDimitry Andric // false and then this work can be finished by handleFixup. 271cb14a3feSDimitry Andric if (&SecA != &SecB) 272cb14a3feSDimitry Andric return false; 273cb14a3feSDimitry Andric 274cb14a3feSDimitry Andric // In SecA == SecB case. If the linker relaxation is enabled, we need record 275*1db9f3b2SDimitry Andric // the ADD, SUB relocations. Otherwise the FixedValue has already been calc- 276*1db9f3b2SDimitry Andric // ulated out in evaluateFixup, return true and avoid record relocations. 277cb14a3feSDimitry Andric if (!STI.hasFeature(LoongArch::FeatureRelax)) 278cb14a3feSDimitry Andric return true; 279*1db9f3b2SDimitry Andric } 280cb14a3feSDimitry Andric 281cb14a3feSDimitry Andric switch (Fixup.getKind()) { 282cb14a3feSDimitry Andric case llvm::FK_Data_1: 283cb14a3feSDimitry Andric FK = getRelocPairForSize(8); 284cb14a3feSDimitry Andric break; 285cb14a3feSDimitry Andric case llvm::FK_Data_2: 286cb14a3feSDimitry Andric FK = getRelocPairForSize(16); 287cb14a3feSDimitry Andric break; 288cb14a3feSDimitry Andric case llvm::FK_Data_4: 289cb14a3feSDimitry Andric FK = getRelocPairForSize(32); 290cb14a3feSDimitry Andric break; 291cb14a3feSDimitry Andric case llvm::FK_Data_8: 292cb14a3feSDimitry Andric FK = getRelocPairForSize(64); 293cb14a3feSDimitry Andric break; 294*1db9f3b2SDimitry Andric case llvm::FK_Data_leb128: 295*1db9f3b2SDimitry Andric FK = getRelocPairForSize(128); 296*1db9f3b2SDimitry Andric break; 297cb14a3feSDimitry Andric default: 298cb14a3feSDimitry Andric llvm_unreachable("unsupported fixup size"); 299cb14a3feSDimitry Andric } 300cb14a3feSDimitry Andric MCValue A = MCValue::get(Target.getSymA(), nullptr, Target.getConstant()); 301cb14a3feSDimitry Andric MCValue B = MCValue::get(Target.getSymB()); 302cb14a3feSDimitry Andric auto FA = MCFixup::create(Fixup.getOffset(), nullptr, std::get<0>(FK)); 303cb14a3feSDimitry Andric auto FB = MCFixup::create(Fixup.getOffset(), nullptr, std::get<1>(FK)); 304cb14a3feSDimitry Andric auto &Asm = Layout.getAssembler(); 305cb14a3feSDimitry Andric Asm.getWriter().recordRelocation(Asm, Layout, &F, FA, A, FixedValueA); 306cb14a3feSDimitry Andric Asm.getWriter().recordRelocation(Asm, Layout, &F, FB, B, FixedValueB); 307cb14a3feSDimitry Andric FixedValue = FixedValueA - FixedValueB; 308cb14a3feSDimitry Andric return true; 309cb14a3feSDimitry Andric } 310cb14a3feSDimitry Andric 31181ad6265SDimitry Andric std::unique_ptr<MCObjectTargetWriter> 31281ad6265SDimitry Andric LoongArchAsmBackend::createObjectTargetWriter() const { 3135f757f3fSDimitry Andric return createLoongArchELFObjectWriter( 3145f757f3fSDimitry Andric OSABI, Is64Bit, STI.hasFeature(LoongArch::FeatureRelax)); 31581ad6265SDimitry Andric } 31681ad6265SDimitry Andric 31781ad6265SDimitry Andric MCAsmBackend *llvm::createLoongArchAsmBackend(const Target &T, 31881ad6265SDimitry Andric const MCSubtargetInfo &STI, 31981ad6265SDimitry Andric const MCRegisterInfo &MRI, 32081ad6265SDimitry Andric const MCTargetOptions &Options) { 32181ad6265SDimitry Andric const Triple &TT = STI.getTargetTriple(); 32281ad6265SDimitry Andric uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS()); 32306c3fb27SDimitry Andric return new LoongArchAsmBackend(STI, OSABI, TT.isArch64Bit(), Options); 32481ad6265SDimitry Andric } 325