diff --git a/0002-Support-LoongArch.patch b/0002-Support-LoongArch.patch new file mode 100644 index 0000000000000000000000000000000000000000..08ff01504e4744499032c96d926c03370025b00d --- /dev/null +++ b/0002-Support-LoongArch.patch @@ -0,0 +1,219713 @@ +diff --git a/llvm/docs/CompilerWriterInfo.rst b/llvm/docs/CompilerWriterInfo.rst +index 8b70dcb8b..6850387ef 100644 +--- a/llvm/docs/CompilerWriterInfo.rst ++++ b/llvm/docs/CompilerWriterInfo.rst +@@ -107,11 +107,6 @@ C-SKY + * `C-SKY Architecture User Guide `_ + * `C-SKY V2 ABI `_ + +-LoongArch +---------- +-* `LoongArch Reference Manual - Volume 1: Basic Architecture `_ +-* `LoongArch ELF ABI specification `_ +- + SPARC + ----- + +diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst +index ff929b0bc..4d8a1f843 100644 +--- a/llvm/docs/ReleaseNotes.rst ++++ b/llvm/docs/ReleaseNotes.rst +@@ -140,24 +140,6 @@ Changes to the DirectX Backend + Changes to the Hexagon Backend + ------------------------------ + +-Changes to the LoongArch Backend +--------------------------------- +- +-* Added intrinsics support for all LSX (128-bits SIMD) and LASX (256-bits SIMD) +- instructions. +-* Added definition and intrinsics support for new instructions that were +- introduced in LoongArch Reference Manual V1.10. +-* Emitted adjacent ``pcaddu18i+jirl`` instrunction sequence with one relocation +- ``R_LARCH_CALL36`` instead of ``pcalau12i+jirl`` with two relocations +- ``R_LARCH_PCALA_{HI20,LO12}`` for function call in medium code model. +-* The code model of global variables can now be overridden by means of the newly +- added LLVM IR attribute, ``code_model``. +-* Added support for the ``llvm.is.fpclass`` intrinsic. +-* ``mulodi4`` and ``muloti4`` libcalls were disabled due to absence in libgcc. +-* Added initial support for auto vectorization. +-* Added initial support for linker relaxation. +-* Assorted codegen improvements. +- + Changes to the MIPS Backend + --------------------------- + +diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h +index f17ba75e3..97d37937c 100644 +--- a/llvm/include/llvm/BinaryFormat/ELF.h ++++ b/llvm/include/llvm/BinaryFormat/ELF.h +@@ -964,20 +964,13 @@ enum { + + // LoongArch Specific e_flags + enum : unsigned { +- // Definitions from LoongArch ELF psABI v2.01. +- // Reference: https://github.com/loongson/LoongArch-Documentation +- // (commit hash 296de4def055c871809068e0816325a4ac04eb12) +- +- // Base ABI Modifiers +- EF_LOONGARCH_ABI_SOFT_FLOAT = 0x1, +- EF_LOONGARCH_ABI_SINGLE_FLOAT = 0x2, +- EF_LOONGARCH_ABI_DOUBLE_FLOAT = 0x3, +- EF_LOONGARCH_ABI_MODIFIER_MASK = 0x7, +- +- // Object file ABI versions +- EF_LOONGARCH_OBJABI_V0 = 0x0, +- EF_LOONGARCH_OBJABI_V1 = 0x40, +- EF_LOONGARCH_OBJABI_MASK = 0xC0, ++ // FIXME: Change these when all ABIs definition were finalized. ++ // See current definitions: ++ // https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html#_e_flags_identifies_abi_type_and_version ++ EF_LARCH_ABI = 0x0003, ++ EF_LARCH_ABI_LP32 = 0x0001, ++ EF_LARCH_ABI_LPX32 = 0x0002, ++ EF_LARCH_ABI_LP64 = 0x0003, + }; + + // ELF Relocation types for LoongArch +diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/LoongArch.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/LoongArch.def +index 4859057ab..8cbfe2fe4 100644 +--- a/llvm/include/llvm/BinaryFormat/ELFRelocs/LoongArch.def ++++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/LoongArch.def +@@ -60,92 +60,3 @@ ELF_RELOC(R_LARCH_SUB32, 55) + ELF_RELOC(R_LARCH_SUB64, 56) + ELF_RELOC(R_LARCH_GNU_VTINHERIT, 57) + ELF_RELOC(R_LARCH_GNU_VTENTRY, 58) +- +-// Relocs whose processing do not require a stack machine. +-// +-// Spec addition: https://github.com/loongson/LoongArch-Documentation/pull/57 +-// Binutils commit 6d13722a97cee3fd397e116bde3bcedbb1e220be +-// and commit 9801120721c3a702ce3bd50433ef920f92a83502 +-ELF_RELOC(R_LARCH_B16, 64) +-ELF_RELOC(R_LARCH_B21, 65) +-ELF_RELOC(R_LARCH_B26, 66) +-ELF_RELOC(R_LARCH_ABS_HI20, 67) +-ELF_RELOC(R_LARCH_ABS_LO12, 68) +-ELF_RELOC(R_LARCH_ABS64_LO20, 69) +-ELF_RELOC(R_LARCH_ABS64_HI12, 70) +-ELF_RELOC(R_LARCH_PCALA_HI20, 71) +-ELF_RELOC(R_LARCH_PCALA_LO12, 72) +-ELF_RELOC(R_LARCH_PCALA64_LO20, 73) +-ELF_RELOC(R_LARCH_PCALA64_HI12, 74) +-ELF_RELOC(R_LARCH_GOT_PC_HI20, 75) +-ELF_RELOC(R_LARCH_GOT_PC_LO12, 76) +-ELF_RELOC(R_LARCH_GOT64_PC_LO20, 77) +-ELF_RELOC(R_LARCH_GOT64_PC_HI12, 78) +-ELF_RELOC(R_LARCH_GOT_HI20, 79) +-ELF_RELOC(R_LARCH_GOT_LO12, 80) +-ELF_RELOC(R_LARCH_GOT64_LO20, 81) +-ELF_RELOC(R_LARCH_GOT64_HI12, 82) +-ELF_RELOC(R_LARCH_TLS_LE_HI20, 83) +-ELF_RELOC(R_LARCH_TLS_LE_LO12, 84) +-ELF_RELOC(R_LARCH_TLS_LE64_LO20, 85) +-ELF_RELOC(R_LARCH_TLS_LE64_HI12, 86) +-ELF_RELOC(R_LARCH_TLS_IE_PC_HI20, 87) +-ELF_RELOC(R_LARCH_TLS_IE_PC_LO12, 88) +-ELF_RELOC(R_LARCH_TLS_IE64_PC_LO20, 89) +-ELF_RELOC(R_LARCH_TLS_IE64_PC_HI12, 90) +-ELF_RELOC(R_LARCH_TLS_IE_HI20, 91) +-ELF_RELOC(R_LARCH_TLS_IE_LO12, 92) +-ELF_RELOC(R_LARCH_TLS_IE64_LO20, 93) +-ELF_RELOC(R_LARCH_TLS_IE64_HI12, 94) +-ELF_RELOC(R_LARCH_TLS_LD_PC_HI20, 95) +-ELF_RELOC(R_LARCH_TLS_LD_HI20, 96) +-ELF_RELOC(R_LARCH_TLS_GD_PC_HI20, 97) +-ELF_RELOC(R_LARCH_TLS_GD_HI20, 98) +-ELF_RELOC(R_LARCH_32_PCREL, 99) +-ELF_RELOC(R_LARCH_RELAX, 100) +- +-// Relocs added in ELF for the LoongArchâ„¢ Architecture v20230519, part of the +-// v2.10 LoongArch ABI specs. +-// +-// Spec addition: https://github.com/loongson/la-abi-specs/pull/1 +-// Binutils commit 57a930e3bfe4b2c7fd6463ed39311e1938513138 +-// Note that the 101 and 104 relocation numbers are defined as R_LARCH_DELETE +-// and R_LARCH_CFA respectively in psABI 2.10. But they are marked as reserved +-// in psABI v2.20 because they were proved not necessary to be exposed outside +-// of the linker. +-ELF_RELOC(R_LARCH_ALIGN, 102) +-ELF_RELOC(R_LARCH_PCREL20_S2, 103) +-ELF_RELOC(R_LARCH_ADD6, 105) +-ELF_RELOC(R_LARCH_SUB6, 106) +-ELF_RELOC(R_LARCH_ADD_ULEB128, 107) +-ELF_RELOC(R_LARCH_SUB_ULEB128, 108) +-ELF_RELOC(R_LARCH_64_PCREL, 109) +- +-// Relocs added in ELF for the LoongArchâ„¢ Architecture v20231102, part of the +-// v2.20 LoongArch ABI specs. +-// +-// Spec addition: https://github.com/loongson/la-abi-specs/pull/4 +-ELF_RELOC(R_LARCH_CALL36, 110) +- +-// Relocs added in ELF for the LoongArchâ„¢ Architecture v20231219, part of the +-// v2.30 LoongArch ABI specs. +-// +-// Spec addition: https://github.com/loongson/la-abi-specs/pull/5 +-ELF_RELOC(R_LARCH_TLS_DESC32, 13) +-ELF_RELOC(R_LARCH_TLS_DESC64, 14) +-ELF_RELOC(R_LARCH_TLS_DESC_PC_HI20, 111) +-ELF_RELOC(R_LARCH_TLS_DESC_PC_LO12, 112) +-ELF_RELOC(R_LARCH_TLS_DESC64_PC_LO20, 113) +-ELF_RELOC(R_LARCH_TLS_DESC64_PC_HI12, 114) +-ELF_RELOC(R_LARCH_TLS_DESC_HI20, 115) +-ELF_RELOC(R_LARCH_TLS_DESC_LO12, 116) +-ELF_RELOC(R_LARCH_TLS_DESC64_LO20, 117) +-ELF_RELOC(R_LARCH_TLS_DESC64_HI12, 118) +-ELF_RELOC(R_LARCH_TLS_DESC_LD, 119) +-ELF_RELOC(R_LARCH_TLS_DESC_CALL, 120) +-ELF_RELOC(R_LARCH_TLS_LE_HI20_R, 121) +-ELF_RELOC(R_LARCH_TLS_LE_ADD_R, 122) +-ELF_RELOC(R_LARCH_TLS_LE_LO12_R, 123) +-ELF_RELOC(R_LARCH_TLS_LD_PCREL20_S2, 124) +-ELF_RELOC(R_LARCH_TLS_GD_PCREL20_S2, 125) +-ELF_RELOC(R_LARCH_TLS_DESC_PCREL20_S2, 126) +diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/ELF_loongarch.h b/llvm/include/llvm/ExecutionEngine/JITLink/ELF_loongarch.h +deleted file mode 100644 +index 4d7655c4b..000000000 +--- a/llvm/include/llvm/ExecutionEngine/JITLink/ELF_loongarch.h ++++ /dev/null +@@ -1,39 +0,0 @@ +-//===-- ELF_loongarch.h - JIT link functions for ELF/loongarch -*- C++ -*--===// +-// +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +-// +-//===----------------------------------------------------------------------===// +-// +-//===----------------------------------------------------------------------===// +-// +-// jit-link functions for ELF/loongarch. +-// +-//===----------------------------------------------------------------------===// +- +-#ifndef LLVM_EXECUTIONENGINE_JITLINK_ELF_LOONGARCH_H +-#define LLVM_EXECUTIONENGINE_JITLINK_ELF_LOONGARCH_H +- +-#include "llvm/ExecutionEngine/JITLink/JITLink.h" +- +-namespace llvm { +-namespace jitlink { +- +-/// Create a LinkGraph from an ELF/loongarch relocatable object +-/// +-/// Note: The graph does not take ownership of the underlying buffer, nor copy +-/// its contents. The caller is responsible for ensuring that the object buffer +-/// outlives the graph. +-Expected> +-createLinkGraphFromELFObject_loongarch(MemoryBufferRef ObjectBuffer); +- +-/// jit-link the given object buffer, which must be an ELF loongarch object +-/// file. +-void link_ELF_loongarch(std::unique_ptr G, +- std::unique_ptr Ctx); +- +-} // end namespace jitlink +-} // end namespace llvm +- +-#endif // LLVM_EXECUTIONENGINE_JITLINK_ELF_LOONGARCH_H +diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h b/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h +deleted file mode 100644 +index 26351ed99..000000000 +--- a/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h ++++ /dev/null +@@ -1,399 +0,0 @@ +-//= loongarch.h - Generic JITLink loongarch edge kinds, utilities -*- C++ -*-=// +-// +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +-// +-//===----------------------------------------------------------------------===// +-// +-// Generic utilities for graphs representing loongarch objects. +-// +-//===----------------------------------------------------------------------===// +- +-#ifndef LLVM_EXECUTIONENGINE_JITLINK_LOONGARCH_H +-#define LLVM_EXECUTIONENGINE_JITLINK_LOONGARCH_H +- +-#include "TableManager.h" +-#include "llvm/ExecutionEngine/JITLink/JITLink.h" +-#include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h" +- +-namespace llvm { +-namespace jitlink { +-namespace loongarch { +- +-/// Represents loongarch fixups. +-enum EdgeKind_loongarch : Edge::Kind { +- /// A plain 64-bit pointer value relocation. +- /// +- /// Fixup expression: +- /// Fixup <- Target + Addend : uint64 +- /// +- Pointer64 = Edge::FirstRelocation, +- +- /// A plain 32-bit pointer value relocation. +- /// +- /// Fixup expression: +- /// Fixup <- Target + Addend : uint32 +- /// +- /// Errors: +- /// - The target must reside in the low 32-bits of the address space, +- /// otherwise an out-of-range error will be returned. +- /// +- Pointer32, +- +- /// A 26-bit PC-relative branch. +- /// +- /// Represents a PC-relative call or branch to a target within +/-128Mb. The +- /// target must be 4-byte aligned. +- /// +- /// Fixup expression: +- /// Fixup <- (Target - Fixup + Addend) >> 2 : int26 +- /// +- /// Notes: +- /// The '26' in the name refers to the number operand bits and follows the +- /// naming convention used by the corresponding ELF relocations. Since the low +- /// two bits must be zero (because of the 4-byte alignment of the target) the +- /// operand is effectively a signed 28-bit number. +- /// +- /// Errors: +- /// - The result of the unshifted part of the fixup expression must be +- /// 4-byte aligned otherwise an alignment error will be returned. +- /// - The result of the fixup expression must fit into an int26 otherwise an +- /// out-of-range error will be returned. +- /// +- Branch26PCRel, +- +- /// A 32-bit delta. +- /// +- /// Delta from the fixup to the target. +- /// +- /// Fixup expression: +- /// Fixup <- Target - Fixup + Addend : int32 +- /// +- /// Errors: +- /// - The result of the fixup expression must fit into an int32, otherwise +- /// an out-of-range error will be returned. +- /// +- Delta32, +- +- /// A 32-bit negative delta. +- /// +- /// Delta from the target back to the fixup. +- /// +- /// Fixup expression: +- /// Fixup <- Fixup - Target + Addend : int32 +- /// +- /// Errors: +- /// - The result of the fixup expression must fit into an int32, otherwise +- /// an out-of-range error will be returned. +- /// +- NegDelta32, +- +- /// A 64-bit delta. +- /// +- /// Delta from the fixup to the target. +- /// +- /// Fixup expression: +- /// Fixup <- Target - Fixup + Addend : int64 +- /// +- Delta64, +- +- /// The signed 20-bit delta from the fixup page to the page containing the +- /// target. +- /// +- /// Fixup expression: +- /// Fixup <- (((Target + Addend + ((Target + Addend) & 0x800)) & ~0xfff) +- // - (Fixup & ~0xfff)) >> 12 : int20 +- /// +- /// Notes: +- /// For PCALAU12I fixups. +- /// +- /// Errors: +- /// - The result of the fixup expression must fit into an int20 otherwise an +- /// out-of-range error will be returned. +- /// +- Page20, +- +- /// The 12-bit offset of the target within its page. +- /// +- /// Typically used to fix up ADDI/LD_W/LD_D immediates. +- /// +- /// Fixup expression: +- /// Fixup <- ((Target + Addend) >> Shift) & 0xfff : int12 +- /// +- PageOffset12, +- +- /// A GOT entry getter/constructor, transformed to Page20 pointing at the GOT +- /// entry for the original target. +- /// +- /// Indicates that this edge should be transformed into a Page20 targeting +- /// the GOT entry for the edge's current target, maintaining the same addend. +- /// A GOT entry for the target should be created if one does not already +- /// exist. +- /// +- /// Edges of this kind are usually handled by a GOT/PLT builder pass inserted +- /// by default. +- /// +- /// Fixup expression: +- /// NONE +- /// +- /// Errors: +- /// - *ASSERTION* Failure to handle edges of this kind prior to the fixup +- /// phase will result in an assert/unreachable during the fixup phase. +- /// +- RequestGOTAndTransformToPage20, +- +- /// A GOT entry getter/constructor, transformed to Pageoffset12 pointing at +- /// the GOT entry for the original target. +- /// +- /// Indicates that this edge should be transformed into a PageOffset12 +- /// targeting the GOT entry for the edge's current target, maintaining the +- /// same addend. A GOT entry for the target should be created if one does not +- /// already exist. +- /// +- /// Edges of this kind are usually handled by a GOT/PLT builder pass inserted +- /// by default. +- /// +- /// Fixup expression: +- /// NONE +- /// +- RequestGOTAndTransformToPageOffset12, +-}; +- +-/// Returns a string name for the given loongarch edge. For debugging purposes +-/// only. +-const char *getEdgeKindName(Edge::Kind K); +- +-// Returns extract bits Val[Hi:Lo]. +-inline uint32_t extractBits(uint32_t Val, unsigned Hi, unsigned Lo) { +- return (Val & (((1UL << (Hi + 1)) - 1))) >> Lo; +-} +- +-/// Apply fixup expression for edge to block content. +-inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E) { +- using namespace support; +- +- char *BlockWorkingMem = B.getAlreadyMutableContent().data(); +- char *FixupPtr = BlockWorkingMem + E.getOffset(); +- uint64_t FixupAddress = (B.getAddress() + E.getOffset()).getValue(); +- uint64_t TargetAddress = E.getTarget().getAddress().getValue(); +- int64_t Addend = E.getAddend(); +- +- switch (E.getKind()) { +- case Pointer64: +- *(ulittle64_t *)FixupPtr = TargetAddress + Addend; +- break; +- case Pointer32: { +- uint64_t Value = TargetAddress + Addend; +- if (Value > std::numeric_limits::max()) +- return makeTargetOutOfRangeError(G, B, E); +- *(ulittle32_t *)FixupPtr = Value; +- break; +- } +- case Branch26PCRel: { +- int64_t Value = TargetAddress - FixupAddress + Addend; +- +- if (!isInt<28>(Value)) +- return makeTargetOutOfRangeError(G, B, E); +- +- if (!isShiftedInt<26, 2>(Value)) +- return makeAlignmentError(orc::ExecutorAddr(FixupAddress), Value, 4, E); +- +- uint32_t RawInstr = *(little32_t *)FixupPtr; +- uint32_t Imm = static_cast(Value >> 2); +- uint32_t Imm15_0 = extractBits(Imm, /*Hi=*/15, /*Lo=*/0) << 10; +- uint32_t Imm25_16 = extractBits(Imm, /*Hi=*/25, /*Lo=*/16); +- *(little32_t *)FixupPtr = RawInstr | Imm15_0 | Imm25_16; +- break; +- } +- case Delta32: { +- int64_t Value = TargetAddress - FixupAddress + Addend; +- +- if (!isInt<32>(Value)) +- return makeTargetOutOfRangeError(G, B, E); +- *(little32_t *)FixupPtr = Value; +- break; +- } +- case NegDelta32: { +- int64_t Value = FixupAddress - TargetAddress + Addend; +- if (!isInt<32>(Value)) +- return makeTargetOutOfRangeError(G, B, E); +- *(little32_t *)FixupPtr = Value; +- break; +- } +- case Delta64: +- *(little64_t *)FixupPtr = TargetAddress - FixupAddress + Addend; +- break; +- case Page20: { +- uint64_t Target = TargetAddress + Addend; +- uint64_t TargetPage = +- (Target + (Target & 0x800)) & ~static_cast(0xfff); +- uint64_t PCPage = FixupAddress & ~static_cast(0xfff); +- +- int64_t PageDelta = TargetPage - PCPage; +- if (!isInt<32>(PageDelta)) +- return makeTargetOutOfRangeError(G, B, E); +- +- uint32_t RawInstr = *(little32_t *)FixupPtr; +- uint32_t Imm31_12 = extractBits(PageDelta, /*Hi=*/31, /*Lo=*/12) << 5; +- *(little32_t *)FixupPtr = RawInstr | Imm31_12; +- break; +- } +- case PageOffset12: { +- uint64_t TargetOffset = (TargetAddress + Addend) & 0xfff; +- +- uint32_t RawInstr = *(ulittle32_t *)FixupPtr; +- uint32_t Imm11_0 = TargetOffset << 10; +- *(ulittle32_t *)FixupPtr = RawInstr | Imm11_0; +- break; +- } +- default: +- return make_error( +- "In graph " + G.getName() + ", section " + B.getSection().getName() + +- " unsupported edge kind " + getEdgeKindName(E.getKind())); +- } +- +- return Error::success(); +-} +- +-/// loongarch null pointer content. +-extern const char NullPointerContent[8]; +-inline ArrayRef getGOTEntryBlockContent(LinkGraph &G) { +- return {reinterpret_cast(NullPointerContent), +- G.getPointerSize()}; +-} +- +-/// loongarch stub content. +-/// +-/// Contains the instruction sequence for an indirect jump via an in-memory +-/// pointer: +-/// pcalau12i $t8, %page20(ptr) +-/// ld.[w/d] $t8, %pageoff12(ptr) +-/// jr $t8 +-constexpr size_t StubEntrySize = 12; +-extern const uint8_t LA64StubContent[StubEntrySize]; +-extern const uint8_t LA32StubContent[StubEntrySize]; +-inline ArrayRef getStubBlockContent(LinkGraph &G) { +- auto StubContent = +- G.getPointerSize() == 8 ? LA64StubContent : LA32StubContent; +- return {reinterpret_cast(StubContent), StubEntrySize}; +-} +- +-/// Creates a new pointer block in the given section and returns an +-/// Anonymous symbol pointing to it. +-/// +-/// If InitialTarget is given then an Pointer64 relocation will be added to the +-/// block pointing at InitialTarget. +-/// +-/// The pointer block will have the following default values: +-/// alignment: PointerSize +-/// alignment-offset: 0 +-inline Symbol &createAnonymousPointer(LinkGraph &G, Section &PointerSection, +- Symbol *InitialTarget = nullptr, +- uint64_t InitialAddend = 0) { +- auto &B = G.createContentBlock(PointerSection, getGOTEntryBlockContent(G), +- orc::ExecutorAddr(), G.getPointerSize(), 0); +- if (InitialTarget) +- B.addEdge(G.getPointerSize() == 8 ? Pointer64 : Pointer32, 0, +- *InitialTarget, InitialAddend); +- return G.addAnonymousSymbol(B, 0, G.getPointerSize(), false, false); +-} +- +-/// Create a jump stub that jumps via the pointer at the given symbol and +-/// an anonymous symbol pointing to it. Return the anonymous symbol. +-inline Symbol &createAnonymousPointerJumpStub(LinkGraph &G, +- Section &StubSection, +- Symbol &PointerSymbol) { +- Block &StubContentBlock = G.createContentBlock( +- StubSection, getStubBlockContent(G), orc::ExecutorAddr(), 4, 0); +- StubContentBlock.addEdge(Page20, 0, PointerSymbol, 0); +- StubContentBlock.addEdge(PageOffset12, 4, PointerSymbol, 0); +- return G.addAnonymousSymbol(StubContentBlock, 0, StubEntrySize, true, false); +-} +- +-/// Global Offset Table Builder. +-class GOTTableManager : public TableManager { +-public: +- static StringRef getSectionName() { return "$__GOT"; } +- +- bool visitEdge(LinkGraph &G, Block *B, Edge &E) { +- Edge::Kind KindToSet = Edge::Invalid; +- switch (E.getKind()) { +- case RequestGOTAndTransformToPage20: +- KindToSet = Page20; +- break; +- case RequestGOTAndTransformToPageOffset12: +- KindToSet = PageOffset12; +- break; +- default: +- return false; +- } +- assert(KindToSet != Edge::Invalid && +- "Fell through switch, but no new kind to set"); +- DEBUG_WITH_TYPE("jitlink", { +- dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at " +- << B->getFixupAddress(E) << " (" << B->getAddress() << " + " +- << formatv("{0:x}", E.getOffset()) << ")\n"; +- }); +- E.setKind(KindToSet); +- E.setTarget(getEntryForTarget(G, E.getTarget())); +- return true; +- } +- +- Symbol &createEntry(LinkGraph &G, Symbol &Target) { +- return createAnonymousPointer(G, getGOTSection(G), &Target); +- } +- +-private: +- Section &getGOTSection(LinkGraph &G) { +- if (!GOTSection) +- GOTSection = &G.createSection(getSectionName(), +- orc::MemProt::Read | orc::MemProt::Exec); +- return *GOTSection; +- } +- +- Section *GOTSection = nullptr; +-}; +- +-/// Procedure Linkage Table Builder. +-class PLTTableManager : public TableManager { +-public: +- PLTTableManager(GOTTableManager &GOT) : GOT(GOT) {} +- +- static StringRef getSectionName() { return "$__STUBS"; } +- +- bool visitEdge(LinkGraph &G, Block *B, Edge &E) { +- if (E.getKind() == Branch26PCRel && !E.getTarget().isDefined()) { +- DEBUG_WITH_TYPE("jitlink", { +- dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at " +- << B->getFixupAddress(E) << " (" << B->getAddress() << " + " +- << formatv("{0:x}", E.getOffset()) << ")\n"; +- }); +- E.setTarget(getEntryForTarget(G, E.getTarget())); +- return true; +- } +- return false; +- } +- +- Symbol &createEntry(LinkGraph &G, Symbol &Target) { +- return createAnonymousPointerJumpStub(G, getStubsSection(G), +- GOT.getEntryForTarget(G, Target)); +- } +- +-public: +- Section &getStubsSection(LinkGraph &G) { +- if (!StubsSection) +- StubsSection = &G.createSection(getSectionName(), +- orc::MemProt::Read | orc::MemProt::Exec); +- return *StubsSection; +- } +- +- GOTTableManager &GOT; +- Section *StubsSection = nullptr; +-}; +- +-} // namespace loongarch +-} // namespace jitlink +-} // namespace llvm +- +-#endif +diff --git a/llvm/include/llvm/ExecutionEngine/Orc/OrcABISupport.h b/llvm/include/llvm/ExecutionEngine/Orc/OrcABISupport.h +index 5d25a3e85..e5e5cb989 100644 +--- a/llvm/include/llvm/ExecutionEngine/Orc/OrcABISupport.h ++++ b/llvm/include/llvm/ExecutionEngine/Orc/OrcABISupport.h +@@ -335,17 +335,14 @@ public: + unsigned NumStubs); + }; + +-// @brief riscv64 support. +-// +-// RISC-V 64 supports lazy JITing. +-class OrcRiscv64 { ++// @brief LoongArch64 support. ++class OrcLoongArch64 { + public: + static constexpr unsigned PointerSize = 8; +- static constexpr unsigned TrampolineSize = 16; +- static constexpr unsigned StubSize = 16; ++ static constexpr unsigned TrampolineSize = 40; ++ static constexpr unsigned StubSize = 32; + static constexpr unsigned StubToPointerMaxDisplacement = 1 << 31; +- static constexpr unsigned ResolverCodeSize = 0x148; +- ++ static constexpr unsigned ResolverCodeSize = 0x120; + /// Write the resolver code into the given memory. The user is + /// responsible for allocating the memory and setting permissions. + /// +@@ -369,22 +366,22 @@ public: + /// Stubs will be written as if linked at StubsBlockTargetAddress, with the + /// Nth stub using the Nth pointer in memory starting at + /// PointersBlockTargetAddress. +- static void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ++ static void writeIndirectStubsBlock(char *StubsBlockWorkingMem, + ExecutorAddr StubsBlockTargetAddress, + ExecutorAddr PointersBlockTargetAddress, + unsigned NumStubs); + }; + +-// @brief loongarch64 support. ++// @brief riscv64 support. + // +-// LoongArch 64 supports lazy JITing. +-class OrcLoongArch64 { ++// RISC-V 64 supports lazy JITing. ++class OrcRiscv64 { + public: + static constexpr unsigned PointerSize = 8; + static constexpr unsigned TrampolineSize = 16; + static constexpr unsigned StubSize = 16; + static constexpr unsigned StubToPointerMaxDisplacement = 1 << 31; +- static constexpr unsigned ResolverCodeSize = 0xc8; ++ static constexpr unsigned ResolverCodeSize = 0x148; + + /// Write the resolver code into the given memory. The user is + /// responsible for allocating the memory and setting permissions. +@@ -405,7 +402,6 @@ public: + ExecutorAddr TrampolineBlockTargetAddress, + ExecutorAddr ResolverFnAddr, + unsigned NumTrampolines); +- + /// Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem. + /// Stubs will be written as if linked at StubsBlockTargetAddress, with the + /// Nth stub using the Nth pointer in memory starting at +diff --git a/llvm/include/llvm/IR/IntrinsicsLoongArch.td b/llvm/include/llvm/IR/IntrinsicsLoongArch.td +index 9002076e7..f680d7cbd 100644 +--- a/llvm/include/llvm/IR/IntrinsicsLoongArch.td ++++ b/llvm/include/llvm/IR/IntrinsicsLoongArch.td +@@ -1,8 +1,9 @@ +-//===- IntrinsicsLoongArch.td - Defines LoongArch intrinsics *- tablegen -*===// ++//===- IntrinsicsLoongArch.td - Defines LoongArch intrinsics ---------*- tablegen -*-===// + // +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// The LLVM Compiler Infrastructure ++// ++// This file is distributed under the University of Illinois Open Source ++// License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // +@@ -10,1176 +11,3679 @@ + // + //===----------------------------------------------------------------------===// + +-let TargetPrefix = "loongarch" in { ++let TargetPrefix = "loongarch" in { // All intrinsics start with "llvm.loongarch.". + + //===----------------------------------------------------------------------===// +-// Atomics +- +-// T @llvm..T.

(any*, T, T, T imm); +-class MaskedAtomicRMW +- : Intrinsic<[itype], [llvm_anyptr_ty, itype, itype, itype], +- [IntrArgMemOnly, NoCapture>, ImmArg>]>; +- +-// We define 32-bit and 64-bit variants of the above, where T stands for i32 +-// or i64 respectively: +-multiclass MaskedAtomicRMWIntrinsics { +- // i32 @llvm..i32.

(any*, i32, i32, i32 imm); +- def _i32 : MaskedAtomicRMW; +- // i64 @llvm..i32.

(any*, i64, i64, i64 imm); +- def _i64 : MaskedAtomicRMW; +-} +- +-multiclass MaskedAtomicRMWFiveOpIntrinsics { +- // TODO: Support cmpxchg on LA32. +- // i64 @llvm..i64.

(any*, i64, i64, i64, i64 imm); +- def _i64 : MaskedAtomicRMWFiveArg; +-} +- +-defm int_loongarch_masked_atomicrmw_xchg : MaskedAtomicRMWIntrinsics; +-defm int_loongarch_masked_atomicrmw_add : MaskedAtomicRMWIntrinsics; +-defm int_loongarch_masked_atomicrmw_sub : MaskedAtomicRMWIntrinsics; +-defm int_loongarch_masked_atomicrmw_nand : MaskedAtomicRMWIntrinsics; +-defm int_loongarch_masked_atomicrmw_umax : MaskedAtomicRMWIntrinsics; +-defm int_loongarch_masked_atomicrmw_umin : MaskedAtomicRMWIntrinsics; +-defm int_loongarch_masked_atomicrmw_max : MaskedAtomicRMWFiveOpIntrinsics; +-defm int_loongarch_masked_atomicrmw_min : MaskedAtomicRMWFiveOpIntrinsics; ++// LoongArch LSX ++ ++def int_loongarch_lsx_vclo_b : ClangBuiltin<"__builtin_lsx_vclo_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vclo_h : ClangBuiltin<"__builtin_lsx_vclo_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vclo_w : ClangBuiltin<"__builtin_lsx_vclo_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vclo_d : ClangBuiltin<"__builtin_lsx_vclo_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vflogb_s : ClangBuiltin<"__builtin_lsx_vflogb_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vflogb_d : ClangBuiltin<"__builtin_lsx_vflogb_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vpickve2gr_b : ClangBuiltin<"__builtin_lsx_vpickve2gr_b">, ++ Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vpickve2gr_h : ClangBuiltin<"__builtin_lsx_vpickve2gr_h">, ++ Intrinsic<[llvm_i32_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vpickve2gr_w : ClangBuiltin<"__builtin_lsx_vpickve2gr_w">, ++ Intrinsic<[llvm_i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vpickve2gr_d : ClangBuiltin<"__builtin_lsx_vpickve2gr_d">, ++ Intrinsic<[llvm_i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vpickve2gr_bu : ClangBuiltin<"__builtin_lsx_vpickve2gr_bu">, ++ Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vpickve2gr_hu : ClangBuiltin<"__builtin_lsx_vpickve2gr_hu">, ++ Intrinsic<[llvm_i32_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vpickve2gr_wu : ClangBuiltin<"__builtin_lsx_vpickve2gr_wu">, ++ Intrinsic<[llvm_i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vpickve2gr_du : ClangBuiltin<"__builtin_lsx_vpickve2gr_du">, ++ Intrinsic<[llvm_i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vreplvei_b : ClangBuiltin<"__builtin_lsx_vreplvei_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vreplvei_h : ClangBuiltin<"__builtin_lsx_vreplvei_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vreplvei_w : ClangBuiltin<"__builtin_lsx_vreplvei_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vreplvei_d : ClangBuiltin<"__builtin_lsx_vreplvei_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmskltz_b : ClangBuiltin<"__builtin_lsx_vmskltz_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmskltz_h : ClangBuiltin<"__builtin_lsx_vmskltz_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmskltz_w : ClangBuiltin<"__builtin_lsx_vmskltz_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmskltz_d : ClangBuiltin<"__builtin_lsx_vmskltz_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfmadd_s : ClangBuiltin<"__builtin_lsx_vfmadd_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfmadd_d : ClangBuiltin<"__builtin_lsx_vfmadd_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfmsub_s : ClangBuiltin<"__builtin_lsx_vfmsub_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfmsub_d : ClangBuiltin<"__builtin_lsx_vfmsub_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfnmadd_s : ClangBuiltin<"__builtin_lsx_vfnmadd_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfnmadd_d : ClangBuiltin<"__builtin_lsx_vfnmadd_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfnmsub_s : ClangBuiltin<"__builtin_lsx_vfnmsub_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfnmsub_d : ClangBuiltin<"__builtin_lsx_vfnmsub_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcmp_caf_s : ClangBuiltin<"__builtin_lsx_vfcmp_caf_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcmp_caf_d : ClangBuiltin<"__builtin_lsx_vfcmp_caf_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcmp_cor_s : ClangBuiltin<"__builtin_lsx_vfcmp_cor_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcmp_cor_d : ClangBuiltin<"__builtin_lsx_vfcmp_cor_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcmp_cun_s : ClangBuiltin<"__builtin_lsx_vfcmp_cun_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcmp_cun_d : ClangBuiltin<"__builtin_lsx_vfcmp_cun_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcmp_cune_s : ClangBuiltin<"__builtin_lsx_vfcmp_cune_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcmp_cune_d : ClangBuiltin<"__builtin_lsx_vfcmp_cune_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcmp_cueq_s : ClangBuiltin<"__builtin_lsx_vfcmp_cueq_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcmp_cueq_d : ClangBuiltin<"__builtin_lsx_vfcmp_cueq_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcmp_ceq_s : ClangBuiltin<"__builtin_lsx_vfcmp_ceq_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcmp_ceq_d : ClangBuiltin<"__builtin_lsx_vfcmp_ceq_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcmp_cne_s : ClangBuiltin<"__builtin_lsx_vfcmp_cne_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcmp_cne_d : ClangBuiltin<"__builtin_lsx_vfcmp_cne_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcmp_clt_s : ClangBuiltin<"__builtin_lsx_vfcmp_clt_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcmp_clt_d : ClangBuiltin<"__builtin_lsx_vfcmp_clt_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcmp_cult_s : ClangBuiltin<"__builtin_lsx_vfcmp_cult_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcmp_cult_d : ClangBuiltin<"__builtin_lsx_vfcmp_cult_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcmp_cle_s : ClangBuiltin<"__builtin_lsx_vfcmp_cle_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcmp_cle_d : ClangBuiltin<"__builtin_lsx_vfcmp_cle_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcmp_cule_s : ClangBuiltin<"__builtin_lsx_vfcmp_cule_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcmp_cule_d : ClangBuiltin<"__builtin_lsx_vfcmp_cule_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcmp_saf_s : ClangBuiltin<"__builtin_lsx_vfcmp_saf_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcmp_saf_d : ClangBuiltin<"__builtin_lsx_vfcmp_saf_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcmp_sor_s : ClangBuiltin<"__builtin_lsx_vfcmp_sor_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcmp_sor_d : ClangBuiltin<"__builtin_lsx_vfcmp_sor_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcmp_sun_s : ClangBuiltin<"__builtin_lsx_vfcmp_sun_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcmp_sun_d : ClangBuiltin<"__builtin_lsx_vfcmp_sun_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcmp_sune_s : ClangBuiltin<"__builtin_lsx_vfcmp_sune_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcmp_sune_d : ClangBuiltin<"__builtin_lsx_vfcmp_sune_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcmp_sueq_s : ClangBuiltin<"__builtin_lsx_vfcmp_sueq_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcmp_sueq_d : ClangBuiltin<"__builtin_lsx_vfcmp_sueq_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcmp_seq_s : ClangBuiltin<"__builtin_lsx_vfcmp_seq_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcmp_seq_d : ClangBuiltin<"__builtin_lsx_vfcmp_seq_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcmp_sne_s : ClangBuiltin<"__builtin_lsx_vfcmp_sne_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcmp_sne_d : ClangBuiltin<"__builtin_lsx_vfcmp_sne_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcmp_slt_s : ClangBuiltin<"__builtin_lsx_vfcmp_slt_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcmp_slt_d : ClangBuiltin<"__builtin_lsx_vfcmp_slt_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcmp_sult_s : ClangBuiltin<"__builtin_lsx_vfcmp_sult_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcmp_sult_d : ClangBuiltin<"__builtin_lsx_vfcmp_sult_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcmp_sle_s : ClangBuiltin<"__builtin_lsx_vfcmp_sle_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcmp_sle_d : ClangBuiltin<"__builtin_lsx_vfcmp_sle_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcmp_sule_s : ClangBuiltin<"__builtin_lsx_vfcmp_sule_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcmp_sule_d : ClangBuiltin<"__builtin_lsx_vfcmp_sule_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vbitsel_v : ClangBuiltin<"__builtin_lsx_vbitsel_v">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vshuf_b : ClangBuiltin<"__builtin_lsx_vshuf_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vldrepl_b : ClangBuiltin<"__builtin_lsx_vldrepl_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty, llvm_i32_ty], [IntrReadMem, IntrArgMemOnly]>; ++def int_loongarch_lsx_vldrepl_h : ClangBuiltin<"__builtin_lsx_vldrepl_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_ptr_ty, llvm_i32_ty], [IntrReadMem, IntrArgMemOnly]>; ++def int_loongarch_lsx_vldrepl_w : ClangBuiltin<"__builtin_lsx_vldrepl_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty, llvm_i32_ty], [IntrReadMem, IntrArgMemOnly]>; ++def int_loongarch_lsx_vldrepl_d : ClangBuiltin<"__builtin_lsx_vldrepl_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_ptr_ty, llvm_i32_ty], [IntrReadMem, IntrArgMemOnly]>; ++ ++def int_loongarch_lsx_vstelm_b : ClangBuiltin<"__builtin_lsx_vstelm_b">, ++ Intrinsic<[], [llvm_v16i8_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; ++def int_loongarch_lsx_vstelm_h : ClangBuiltin<"__builtin_lsx_vstelm_h">, ++ Intrinsic<[], [llvm_v8i16_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; ++def int_loongarch_lsx_vstelm_w : ClangBuiltin<"__builtin_lsx_vstelm_w">, ++ Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; ++def int_loongarch_lsx_vstelm_d : ClangBuiltin<"__builtin_lsx_vstelm_d">, ++ Intrinsic<[], [llvm_v2i64_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; ++ ++def int_loongarch_lsx_vldx : ClangBuiltin<"__builtin_lsx_vldx">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty, llvm_i64_ty], ++ [IntrReadMem, IntrArgMemOnly]>; ++ ++def int_loongarch_lsx_vstx : ClangBuiltin<"__builtin_lsx_vstx">, ++ Intrinsic<[], [llvm_v16i8_ty, llvm_ptr_ty, llvm_i64_ty], ++ [IntrArgMemOnly]>; ++ ++def int_loongarch_lsx_vaddwev_d_w : ClangBuiltin<"__builtin_lsx_vaddwev_d_w">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vaddwev_w_h : ClangBuiltin<"__builtin_lsx_vaddwev_w_h">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vaddwev_h_b : ClangBuiltin<"__builtin_lsx_vaddwev_h_b">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vaddwev_q_d : ClangBuiltin<"__builtin_lsx_vaddwev_q_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsubwev_d_w : ClangBuiltin<"__builtin_lsx_vsubwev_d_w">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsubwev_w_h : ClangBuiltin<"__builtin_lsx_vsubwev_w_h">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsubwev_h_b : ClangBuiltin<"__builtin_lsx_vsubwev_h_b">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsubwev_q_d : ClangBuiltin<"__builtin_lsx_vsubwev_q_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++ ++def int_loongarch_lsx_vaddwod_d_w : ClangBuiltin<"__builtin_lsx_vaddwod_d_w">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vaddwod_w_h : ClangBuiltin<"__builtin_lsx_vaddwod_w_h">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vaddwod_h_b : ClangBuiltin<"__builtin_lsx_vaddwod_h_b">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vaddwod_q_d : ClangBuiltin<"__builtin_lsx_vaddwod_q_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsubwod_d_w : ClangBuiltin<"__builtin_lsx_vsubwod_d_w">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsubwod_w_h : ClangBuiltin<"__builtin_lsx_vsubwod_w_h">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsubwod_h_b : ClangBuiltin<"__builtin_lsx_vsubwod_h_b">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsubwod_q_d : ClangBuiltin<"__builtin_lsx_vsubwod_q_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vaddwev_d_wu : ClangBuiltin<"__builtin_lsx_vaddwev_d_wu">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vaddwev_w_hu : ClangBuiltin<"__builtin_lsx_vaddwev_w_hu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vaddwev_h_bu : ClangBuiltin<"__builtin_lsx_vaddwev_h_bu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vaddwev_q_du : ClangBuiltin<"__builtin_lsx_vaddwev_q_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsubwev_d_wu : ClangBuiltin<"__builtin_lsx_vsubwev_d_wu">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsubwev_w_hu : ClangBuiltin<"__builtin_lsx_vsubwev_w_hu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsubwev_h_bu : ClangBuiltin<"__builtin_lsx_vsubwev_h_bu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsubwev_q_du : ClangBuiltin<"__builtin_lsx_vsubwev_q_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vaddwod_d_wu : ClangBuiltin<"__builtin_lsx_vaddwod_d_wu">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vaddwod_w_hu : ClangBuiltin<"__builtin_lsx_vaddwod_w_hu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vaddwod_h_bu : ClangBuiltin<"__builtin_lsx_vaddwod_h_bu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vaddwod_q_du : ClangBuiltin<"__builtin_lsx_vaddwod_q_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsubwod_d_wu : ClangBuiltin<"__builtin_lsx_vsubwod_d_wu">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsubwod_w_hu : ClangBuiltin<"__builtin_lsx_vsubwod_w_hu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsubwod_h_bu : ClangBuiltin<"__builtin_lsx_vsubwod_h_bu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsubwod_q_du : ClangBuiltin<"__builtin_lsx_vsubwod_q_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vaddwev_d_wu_w : ClangBuiltin<"__builtin_lsx_vaddwev_d_wu_w">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vaddwev_w_hu_h : ClangBuiltin<"__builtin_lsx_vaddwev_w_hu_h">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vaddwev_h_bu_b : ClangBuiltin<"__builtin_lsx_vaddwev_h_bu_b">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vaddwev_q_du_d : ClangBuiltin<"__builtin_lsx_vaddwev_q_du_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vaddwod_d_wu_w : ClangBuiltin<"__builtin_lsx_vaddwod_d_wu_w">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vaddwod_w_hu_h : ClangBuiltin<"__builtin_lsx_vaddwod_w_hu_h">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vaddwod_h_bu_b : ClangBuiltin<"__builtin_lsx_vaddwod_h_bu_b">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vaddwod_q_du_d : ClangBuiltin<"__builtin_lsx_vaddwod_q_du_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vhaddw_qu_du : ClangBuiltin<"__builtin_lsx_vhaddw_qu_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vhsubw_qu_du : ClangBuiltin<"__builtin_lsx_vhsubw_qu_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vhaddw_q_d : ClangBuiltin<"__builtin_lsx_vhaddw_q_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vhsubw_q_d : ClangBuiltin<"__builtin_lsx_vhsubw_q_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmuh_b : ClangBuiltin<"__builtin_lsx_vmuh_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmuh_h : ClangBuiltin<"__builtin_lsx_vmuh_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmuh_w : ClangBuiltin<"__builtin_lsx_vmuh_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmuh_d : ClangBuiltin<"__builtin_lsx_vmuh_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmuh_bu : ClangBuiltin<"__builtin_lsx_vmuh_bu">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmuh_hu : ClangBuiltin<"__builtin_lsx_vmuh_hu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmuh_wu : ClangBuiltin<"__builtin_lsx_vmuh_wu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmuh_du : ClangBuiltin<"__builtin_lsx_vmuh_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmulwev_d_w : ClangBuiltin<"__builtin_lsx_vmulwev_d_w">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmulwev_w_h : ClangBuiltin<"__builtin_lsx_vmulwev_w_h">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmulwev_h_b : ClangBuiltin<"__builtin_lsx_vmulwev_h_b">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmulwev_q_d : ClangBuiltin<"__builtin_lsx_vmulwev_q_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmulwod_d_w : ClangBuiltin<"__builtin_lsx_vmulwod_d_w">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmulwod_w_h : ClangBuiltin<"__builtin_lsx_vmulwod_w_h">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmulwod_h_b : ClangBuiltin<"__builtin_lsx_vmulwod_h_b">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmulwod_q_d : ClangBuiltin<"__builtin_lsx_vmulwod_q_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmulwev_d_wu : ClangBuiltin<"__builtin_lsx_vmulwev_d_wu">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmulwev_w_hu : ClangBuiltin<"__builtin_lsx_vmulwev_w_hu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmulwev_h_bu : ClangBuiltin<"__builtin_lsx_vmulwev_h_bu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmulwev_q_du : ClangBuiltin<"__builtin_lsx_vmulwev_q_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmulwod_d_wu : ClangBuiltin<"__builtin_lsx_vmulwod_d_wu">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmulwod_w_hu : ClangBuiltin<"__builtin_lsx_vmulwod_w_hu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmulwod_h_bu : ClangBuiltin<"__builtin_lsx_vmulwod_h_bu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmulwod_q_du : ClangBuiltin<"__builtin_lsx_vmulwod_q_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmulwev_d_wu_w : ClangBuiltin<"__builtin_lsx_vmulwev_d_wu_w">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmulwev_w_hu_h : ClangBuiltin<"__builtin_lsx_vmulwev_w_hu_h">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmulwev_h_bu_b : ClangBuiltin<"__builtin_lsx_vmulwev_h_bu_b">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmulwev_q_du_d : ClangBuiltin<"__builtin_lsx_vmulwev_q_du_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmulwod_d_wu_w : ClangBuiltin<"__builtin_lsx_vmulwod_d_wu_w">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmulwod_w_hu_h : ClangBuiltin<"__builtin_lsx_vmulwod_w_hu_h">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmulwod_h_bu_b : ClangBuiltin<"__builtin_lsx_vmulwod_h_bu_b">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmulwod_q_du_d : ClangBuiltin<"__builtin_lsx_vmulwod_q_du_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmaddwev_d_w : ClangBuiltin<"__builtin_lsx_vmaddwev_d_w">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaddwev_w_h : ClangBuiltin<"__builtin_lsx_vmaddwev_w_h">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaddwev_h_b : ClangBuiltin<"__builtin_lsx_vmaddwev_h_b">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaddwev_q_d : ClangBuiltin<"__builtin_lsx_vmaddwev_q_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmaddwod_d_w : ClangBuiltin<"__builtin_lsx_vmaddwod_d_w">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaddwod_w_h : ClangBuiltin<"__builtin_lsx_vmaddwod_w_h">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaddwod_h_b : ClangBuiltin<"__builtin_lsx_vmaddwod_h_b">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaddwod_q_d : ClangBuiltin<"__builtin_lsx_vmaddwod_q_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmaddwev_d_wu : ClangBuiltin<"__builtin_lsx_vmaddwev_d_wu">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaddwev_w_hu : ClangBuiltin<"__builtin_lsx_vmaddwev_w_hu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaddwev_h_bu : ClangBuiltin<"__builtin_lsx_vmaddwev_h_bu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaddwev_q_du : ClangBuiltin<"__builtin_lsx_vmaddwev_q_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmaddwod_d_wu : ClangBuiltin<"__builtin_lsx_vmaddwod_d_wu">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaddwod_w_hu : ClangBuiltin<"__builtin_lsx_vmaddwod_w_hu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaddwod_h_bu : ClangBuiltin<"__builtin_lsx_vmaddwod_h_bu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaddwod_q_du : ClangBuiltin<"__builtin_lsx_vmaddwod_q_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmaddwev_d_wu_w : ClangBuiltin<"__builtin_lsx_vmaddwev_d_wu_w">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaddwev_w_hu_h : ClangBuiltin<"__builtin_lsx_vmaddwev_w_hu_h">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaddwev_h_bu_b : ClangBuiltin<"__builtin_lsx_vmaddwev_h_bu_b">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaddwev_q_du_d : ClangBuiltin<"__builtin_lsx_vmaddwev_q_du_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmaddwod_d_wu_w : ClangBuiltin<"__builtin_lsx_vmaddwod_d_wu_w">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaddwod_w_hu_h : ClangBuiltin<"__builtin_lsx_vmaddwod_w_hu_h">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaddwod_h_bu_b : ClangBuiltin<"__builtin_lsx_vmaddwod_h_bu_b">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaddwod_q_du_d : ClangBuiltin<"__builtin_lsx_vmaddwod_q_du_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsrln_b_h : ClangBuiltin<"__builtin_lsx_vsrln_b_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrln_h_w : ClangBuiltin<"__builtin_lsx_vsrln_h_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrln_w_d : ClangBuiltin<"__builtin_lsx_vsrln_w_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsran_b_h : ClangBuiltin<"__builtin_lsx_vsran_b_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsran_h_w : ClangBuiltin<"__builtin_lsx_vsran_h_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsran_w_d : ClangBuiltin<"__builtin_lsx_vsran_w_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsrlrn_b_h : ClangBuiltin<"__builtin_lsx_vsrlrn_b_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrlrn_h_w : ClangBuiltin<"__builtin_lsx_vsrlrn_h_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrlrn_w_d : ClangBuiltin<"__builtin_lsx_vsrlrn_w_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsrarn_b_h : ClangBuiltin<"__builtin_lsx_vsrarn_b_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrarn_h_w : ClangBuiltin<"__builtin_lsx_vsrarn_h_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrarn_w_d : ClangBuiltin<"__builtin_lsx_vsrarn_w_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vssrln_b_h : ClangBuiltin<"__builtin_lsx_vssrln_b_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrln_h_w : ClangBuiltin<"__builtin_lsx_vssrln_h_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrln_w_d : ClangBuiltin<"__builtin_lsx_vssrln_w_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vssran_b_h : ClangBuiltin<"__builtin_lsx_vssran_b_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssran_h_w : ClangBuiltin<"__builtin_lsx_vssran_h_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssran_w_d : ClangBuiltin<"__builtin_lsx_vssran_w_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vssrlrn_b_h : ClangBuiltin<"__builtin_lsx_vssrlrn_b_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrlrn_h_w : ClangBuiltin<"__builtin_lsx_vssrlrn_h_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrlrn_w_d : ClangBuiltin<"__builtin_lsx_vssrlrn_w_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vssrarn_b_h : ClangBuiltin<"__builtin_lsx_vssrarn_b_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrarn_h_w : ClangBuiltin<"__builtin_lsx_vssrarn_h_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrarn_w_d : ClangBuiltin<"__builtin_lsx_vssrarn_w_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vssrln_bu_h : ClangBuiltin<"__builtin_lsx_vssrln_bu_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrln_hu_w : ClangBuiltin<"__builtin_lsx_vssrln_hu_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrln_wu_d : ClangBuiltin<"__builtin_lsx_vssrln_wu_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vssran_bu_h : ClangBuiltin<"__builtin_lsx_vssran_bu_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssran_hu_w : ClangBuiltin<"__builtin_lsx_vssran_hu_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssran_wu_d : ClangBuiltin<"__builtin_lsx_vssran_wu_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vssrlrn_bu_h : ClangBuiltin<"__builtin_lsx_vssrlrn_bu_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrlrn_hu_w : ClangBuiltin<"__builtin_lsx_vssrlrn_hu_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrlrn_wu_d : ClangBuiltin<"__builtin_lsx_vssrlrn_wu_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vssrarn_bu_h : ClangBuiltin<"__builtin_lsx_vssrarn_bu_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrarn_hu_w : ClangBuiltin<"__builtin_lsx_vssrarn_hu_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrarn_wu_d : ClangBuiltin<"__builtin_lsx_vssrarn_wu_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vandn_v : ClangBuiltin<"__builtin_lsx_vandn_v">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vorn_v : ClangBuiltin<"__builtin_lsx_vorn_v">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfrstp_b : ClangBuiltin<"__builtin_lsx_vfrstp_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty], ++ [IntrNoMem]>; ++def int_loongarch_lsx_vfrstp_h : ClangBuiltin<"__builtin_lsx_vfrstp_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty], ++ [IntrNoMem]>; ++ ++def int_loongarch_lsx_vadd_q : ClangBuiltin<"__builtin_lsx_vadd_q">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsub_q : ClangBuiltin<"__builtin_lsx_vsub_q">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsigncov_b : ClangBuiltin<"__builtin_lsx_vsigncov_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], ++ [IntrNoMem]>; ++def int_loongarch_lsx_vsigncov_h : ClangBuiltin<"__builtin_lsx_vsigncov_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], ++ [IntrNoMem]>; ++def int_loongarch_lsx_vsigncov_w : ClangBuiltin<"__builtin_lsx_vsigncov_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], ++ [IntrNoMem]>; ++def int_loongarch_lsx_vsigncov_d : ClangBuiltin<"__builtin_lsx_vsigncov_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], ++ [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcvt_h_s : ClangBuiltin<"__builtin_lsx_vfcvt_h_s">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcvt_s_d : ClangBuiltin<"__builtin_lsx_vfcvt_s_d">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vffint_s_l : ClangBuiltin<"__builtin_lsx_vffint_s_l">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vftint_w_d : ClangBuiltin<"__builtin_lsx_vftint_w_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vftintrz_w_d : ClangBuiltin<"__builtin_lsx_vftintrz_w_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vftintrp_w_d : ClangBuiltin<"__builtin_lsx_vftintrp_w_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vftintrm_w_d : ClangBuiltin<"__builtin_lsx_vftintrm_w_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vftintrne_w_d : ClangBuiltin<"__builtin_lsx_vftintrne_w_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vbsrl_v : ClangBuiltin<"__builtin_lsx_vbsrl_v">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vbsll_v : ClangBuiltin<"__builtin_lsx_vbsll_v">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfrstpi_b : ClangBuiltin<"__builtin_lsx_vfrstpi_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfrstpi_h : ClangBuiltin<"__builtin_lsx_vfrstpi_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vneg_b : ClangBuiltin<"__builtin_lsx_vneg_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vneg_h : ClangBuiltin<"__builtin_lsx_vneg_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vneg_w : ClangBuiltin<"__builtin_lsx_vneg_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vneg_d : ClangBuiltin<"__builtin_lsx_vneg_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmskgez_b : ClangBuiltin<"__builtin_lsx_vmskgez_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmsknz_b : ClangBuiltin<"__builtin_lsx_vmsknz_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfrintrm_s : ClangBuiltin<"__builtin_lsx_vfrintrm_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfrintrm_d : ClangBuiltin<"__builtin_lsx_vfrintrm_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfrintrp_s : ClangBuiltin<"__builtin_lsx_vfrintrp_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfrintrp_d : ClangBuiltin<"__builtin_lsx_vfrintrp_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfrintrz_s : ClangBuiltin<"__builtin_lsx_vfrintrz_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfrintrz_d : ClangBuiltin<"__builtin_lsx_vfrintrz_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfrintrne_s : ClangBuiltin<"__builtin_lsx_vfrintrne_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfrintrne_d : ClangBuiltin<"__builtin_lsx_vfrintrne_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vffinth_d_w : ClangBuiltin<"__builtin_lsx_vffinth_d_w">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vffintl_d_w : ClangBuiltin<"__builtin_lsx_vffintl_d_w">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v4i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vftintrm_w_s : ClangBuiltin<"__builtin_lsx_vftintrm_w_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vftintrm_l_d : ClangBuiltin<"__builtin_lsx_vftintrm_l_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vftintrp_w_s : ClangBuiltin<"__builtin_lsx_vftintrp_w_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vftintrp_l_d : ClangBuiltin<"__builtin_lsx_vftintrp_l_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vftintrz_w_s : ClangBuiltin<"__builtin_lsx_vftintrz_w_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vftintrz_l_d : ClangBuiltin<"__builtin_lsx_vftintrz_l_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vftintrne_w_s : ClangBuiltin<"__builtin_lsx_vftintrne_w_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vftintrne_l_d : ClangBuiltin<"__builtin_lsx_vftintrne_l_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vftinth_l_s : ClangBuiltin<"__builtin_lsx_vftinth_l_s">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vftintl_l_s : ClangBuiltin<"__builtin_lsx_vftintl_l_s">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vftintrmh_l_s : ClangBuiltin<"__builtin_lsx_vftintrmh_l_s">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vftintrml_l_s : ClangBuiltin<"__builtin_lsx_vftintrml_l_s">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vftintrph_l_s : ClangBuiltin<"__builtin_lsx_vftintrph_l_s">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vftintrpl_l_s : ClangBuiltin<"__builtin_lsx_vftintrpl_l_s">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vftintrzh_l_s : ClangBuiltin<"__builtin_lsx_vftintrzh_l_s">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vftintrzl_l_s : ClangBuiltin<"__builtin_lsx_vftintrzl_l_s">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vftintrneh_l_s : ClangBuiltin<"__builtin_lsx_vftintrneh_l_s">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vftintrnel_l_s : ClangBuiltin<"__builtin_lsx_vftintrnel_l_s">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vexth_d_w : ClangBuiltin<"__builtin_lsx_vexth_d_w">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vexth_w_h : ClangBuiltin<"__builtin_lsx_vexth_w_h">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vexth_h_b : ClangBuiltin<"__builtin_lsx_vexth_h_b">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vexth_q_d : ClangBuiltin<"__builtin_lsx_vexth_q_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vexth_du_wu : ClangBuiltin<"__builtin_lsx_vexth_du_wu">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vexth_wu_hu : ClangBuiltin<"__builtin_lsx_vexth_wu_hu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vexth_hu_bu : ClangBuiltin<"__builtin_lsx_vexth_hu_bu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vexth_qu_du : ClangBuiltin<"__builtin_lsx_vexth_qu_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvexth_du_wu : ClangBuiltin<"__builtin_lasx_xvexth_du_wu">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvexth_wu_hu : ClangBuiltin<"__builtin_lasx_xvexth_wu_hu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvexth_hu_bu : ClangBuiltin<"__builtin_lasx_xvexth_hu_bu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvexth_qu_du : ClangBuiltin<"__builtin_lasx_xvexth_qu_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsllwil_d_w : ClangBuiltin<"__builtin_lsx_vsllwil_d_w">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsllwil_w_h : ClangBuiltin<"__builtin_lsx_vsllwil_w_h">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsllwil_h_b : ClangBuiltin<"__builtin_lsx_vsllwil_h_b">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vextl_q_d : ClangBuiltin<"__builtin_lsx_vextl_q_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsllwil_du_wu : ClangBuiltin<"__builtin_lsx_vsllwil_du_wu">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsllwil_wu_hu : ClangBuiltin<"__builtin_lsx_vsllwil_wu_hu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsllwil_hu_bu : ClangBuiltin<"__builtin_lsx_vsllwil_hu_bu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vextl_qu_du : ClangBuiltin<"__builtin_lsx_vextl_qu_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vbitclri_b : ClangBuiltin<"__builtin_lsx_vbitclri_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vbitclri_h : ClangBuiltin<"__builtin_lsx_vbitclri_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vbitclri_w : ClangBuiltin<"__builtin_lsx_vbitclri_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vbitclri_d : ClangBuiltin<"__builtin_lsx_vbitclri_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vbitseti_b : ClangBuiltin<"__builtin_lsx_vbitseti_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vbitseti_h : ClangBuiltin<"__builtin_lsx_vbitseti_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vbitseti_w : ClangBuiltin<"__builtin_lsx_vbitseti_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vbitseti_d : ClangBuiltin<"__builtin_lsx_vbitseti_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vbitrevi_b : ClangBuiltin<"__builtin_lsx_vbitrevi_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vbitrevi_h : ClangBuiltin<"__builtin_lsx_vbitrevi_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vbitrevi_w : ClangBuiltin<"__builtin_lsx_vbitrevi_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vbitrevi_d : ClangBuiltin<"__builtin_lsx_vbitrevi_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vssrlrni_b_h : ClangBuiltin<"__builtin_lsx_vssrlrni_b_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrlrni_h_w : ClangBuiltin<"__builtin_lsx_vssrlrni_h_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrlrni_w_d : ClangBuiltin<"__builtin_lsx_vssrlrni_w_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrlrni_d_q : ClangBuiltin<"__builtin_lsx_vssrlrni_d_q">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsrani_b_h : ClangBuiltin<"__builtin_lsx_vsrani_b_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrani_h_w : ClangBuiltin<"__builtin_lsx_vsrani_h_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrani_w_d : ClangBuiltin<"__builtin_lsx_vsrani_w_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrani_d_q : ClangBuiltin<"__builtin_lsx_vsrani_d_q">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vextrins_b : ClangBuiltin<"__builtin_lsx_vextrins_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vextrins_h : ClangBuiltin<"__builtin_lsx_vextrins_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vextrins_w : ClangBuiltin<"__builtin_lsx_vextrins_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vextrins_d : ClangBuiltin<"__builtin_lsx_vextrins_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vbitseli_b : ClangBuiltin<"__builtin_lsx_vbitseli_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vandi_b : ClangBuiltin<"__builtin_lsx_vandi_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vori_b : ClangBuiltin<"__builtin_lsx_vori_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vxori_b : ClangBuiltin<"__builtin_lsx_vxori_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vnori_b : ClangBuiltin<"__builtin_lsx_vnori_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vldi : ClangBuiltin<"__builtin_lsx_vldi">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vrepli_b : ClangBuiltin<"__builtin_lsx_vrepli_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vrepli_h : ClangBuiltin<"__builtin_lsx_vrepli_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vrepli_w : ClangBuiltin<"__builtin_lsx_vrepli_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vrepli_d : ClangBuiltin<"__builtin_lsx_vrepli_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vpermi_w : ClangBuiltin<"__builtin_lsx_vpermi_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsadd_b : ClangBuiltin<"__builtin_lsx_vsadd_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vsadd_h : ClangBuiltin<"__builtin_lsx_vsadd_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vsadd_w : ClangBuiltin<"__builtin_lsx_vsadd_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vsadd_d : ClangBuiltin<"__builtin_lsx_vsadd_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], ++ [Commutative, IntrNoMem]>; ++ ++def int_loongarch_lsx_vssub_b : ClangBuiltin<"__builtin_lsx_vssub_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssub_h : ClangBuiltin<"__builtin_lsx_vssub_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssub_w : ClangBuiltin<"__builtin_lsx_vssub_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssub_d : ClangBuiltin<"__builtin_lsx_vssub_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsadd_bu : ClangBuiltin<"__builtin_lsx_vsadd_bu">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vsadd_hu : ClangBuiltin<"__builtin_lsx_vsadd_hu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vsadd_wu : ClangBuiltin<"__builtin_lsx_vsadd_wu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vsadd_du : ClangBuiltin<"__builtin_lsx_vsadd_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], ++ [Commutative, IntrNoMem]>; ++ ++def int_loongarch_lsx_vssub_bu : ClangBuiltin<"__builtin_lsx_vssub_bu">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssub_hu : ClangBuiltin<"__builtin_lsx_vssub_hu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssub_wu : ClangBuiltin<"__builtin_lsx_vssub_wu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssub_du : ClangBuiltin<"__builtin_lsx_vssub_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vhaddw_h_b : ClangBuiltin<"__builtin_lsx_vhaddw_h_b">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vhaddw_w_h : ClangBuiltin<"__builtin_lsx_vhaddw_w_h">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vhaddw_d_w : ClangBuiltin<"__builtin_lsx_vhaddw_d_w">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vhsubw_h_b : ClangBuiltin<"__builtin_lsx_vhsubw_h_b">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vhsubw_w_h : ClangBuiltin<"__builtin_lsx_vhsubw_w_h">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vhsubw_d_w : ClangBuiltin<"__builtin_lsx_vhsubw_d_w">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vhaddw_hu_bu : ClangBuiltin<"__builtin_lsx_vhaddw_hu_bu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vhaddw_wu_hu : ClangBuiltin<"__builtin_lsx_vhaddw_wu_hu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vhaddw_du_wu : ClangBuiltin<"__builtin_lsx_vhaddw_du_wu">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vhsubw_hu_bu : ClangBuiltin<"__builtin_lsx_vhsubw_hu_bu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vhsubw_wu_hu : ClangBuiltin<"__builtin_lsx_vhsubw_wu_hu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vhsubw_du_wu : ClangBuiltin<"__builtin_lsx_vhsubw_du_wu">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vadda_b : ClangBuiltin<"__builtin_lsx_vadda_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vadda_h : ClangBuiltin<"__builtin_lsx_vadda_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vadda_w : ClangBuiltin<"__builtin_lsx_vadda_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vadda_d : ClangBuiltin<"__builtin_lsx_vadda_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], ++ [Commutative, IntrNoMem]>; ++ ++def int_loongarch_lsx_vabsd_b : ClangBuiltin<"__builtin_lsx_vabsd_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vabsd_h : ClangBuiltin<"__builtin_lsx_vabsd_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vabsd_w : ClangBuiltin<"__builtin_lsx_vabsd_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vabsd_d : ClangBuiltin<"__builtin_lsx_vabsd_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vabsd_bu : ClangBuiltin<"__builtin_lsx_vabsd_bu">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vabsd_hu : ClangBuiltin<"__builtin_lsx_vabsd_hu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vabsd_wu : ClangBuiltin<"__builtin_lsx_vabsd_wu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vabsd_du : ClangBuiltin<"__builtin_lsx_vabsd_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vavg_b : ClangBuiltin<"__builtin_lsx_vavg_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vavg_h : ClangBuiltin<"__builtin_lsx_vavg_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vavg_w : ClangBuiltin<"__builtin_lsx_vavg_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vavg_d : ClangBuiltin<"__builtin_lsx_vavg_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], ++ [Commutative, IntrNoMem]>; ++ ++def int_loongarch_lsx_vavg_bu : ClangBuiltin<"__builtin_lsx_vavg_bu">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vavg_hu : ClangBuiltin<"__builtin_lsx_vavg_hu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vavg_wu : ClangBuiltin<"__builtin_lsx_vavg_wu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vavg_du : ClangBuiltin<"__builtin_lsx_vavg_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], ++ [Commutative, IntrNoMem]>; ++ ++def int_loongarch_lsx_vavgr_b : ClangBuiltin<"__builtin_lsx_vavgr_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vavgr_h : ClangBuiltin<"__builtin_lsx_vavgr_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vavgr_w : ClangBuiltin<"__builtin_lsx_vavgr_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vavgr_d : ClangBuiltin<"__builtin_lsx_vavgr_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], ++ [Commutative, IntrNoMem]>; ++ ++def int_loongarch_lsx_vavgr_bu : ClangBuiltin<"__builtin_lsx_vavgr_bu">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vavgr_hu : ClangBuiltin<"__builtin_lsx_vavgr_hu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vavgr_wu : ClangBuiltin<"__builtin_lsx_vavgr_wu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vavgr_du : ClangBuiltin<"__builtin_lsx_vavgr_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], ++ [Commutative, IntrNoMem]>; ++ ++def int_loongarch_lsx_vsrlr_b : ClangBuiltin<"__builtin_lsx_vsrlr_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrlr_h : ClangBuiltin<"__builtin_lsx_vsrlr_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrlr_w : ClangBuiltin<"__builtin_lsx_vsrlr_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrlr_d : ClangBuiltin<"__builtin_lsx_vsrlr_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsrar_b : ClangBuiltin<"__builtin_lsx_vsrar_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrar_h : ClangBuiltin<"__builtin_lsx_vsrar_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrar_w : ClangBuiltin<"__builtin_lsx_vsrar_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrar_d : ClangBuiltin<"__builtin_lsx_vsrar_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfmax_s : ClangBuiltin<"__builtin_lsx_vfmax_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfmax_d : ClangBuiltin<"__builtin_lsx_vfmax_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfmin_s : ClangBuiltin<"__builtin_lsx_vfmin_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfmin_d : ClangBuiltin<"__builtin_lsx_vfmin_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfmaxa_s : ClangBuiltin<"__builtin_lsx_vfmaxa_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfmaxa_d : ClangBuiltin<"__builtin_lsx_vfmaxa_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfmina_s : ClangBuiltin<"__builtin_lsx_vfmina_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfmina_d : ClangBuiltin<"__builtin_lsx_vfmina_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfclass_s : ClangBuiltin<"__builtin_lsx_vfclass_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfclass_d : ClangBuiltin<"__builtin_lsx_vfclass_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfrecip_s : ClangBuiltin<"__builtin_lsx_vfrecip_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfrecip_d : ClangBuiltin<"__builtin_lsx_vfrecip_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfrecipe_s : ClangBuiltin<"__builtin_lsx_vfrecipe_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfrecipe_d : ClangBuiltin<"__builtin_lsx_vfrecipe_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfrsqrt_s : ClangBuiltin<"__builtin_lsx_vfrsqrt_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfrsqrt_d : ClangBuiltin<"__builtin_lsx_vfrsqrt_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfrsqrte_s : ClangBuiltin<"__builtin_lsx_vfrsqrte_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfrsqrte_d : ClangBuiltin<"__builtin_lsx_vfrsqrte_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcvtl_s_h : ClangBuiltin<"__builtin_lsx_vfcvtl_s_h">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcvtl_d_s : ClangBuiltin<"__builtin_lsx_vfcvtl_d_s">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfcvth_s_h : ClangBuiltin<"__builtin_lsx_vfcvth_s_h">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfcvth_d_s : ClangBuiltin<"__builtin_lsx_vfcvth_d_s">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vftint_w_s : ClangBuiltin<"__builtin_lsx_vftint_w_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vftint_l_d : ClangBuiltin<"__builtin_lsx_vftint_l_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vftint_wu_s : ClangBuiltin<"__builtin_lsx_vftint_wu_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vftint_lu_d : ClangBuiltin<"__builtin_lsx_vftint_lu_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsrlri_b : ClangBuiltin<"__builtin_lsx_vsrlri_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrlri_h : ClangBuiltin<"__builtin_lsx_vsrlri_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrlri_w : ClangBuiltin<"__builtin_lsx_vsrlri_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrlri_d : ClangBuiltin<"__builtin_lsx_vsrlri_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsrari_b : ClangBuiltin<"__builtin_lsx_vsrari_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrari_h : ClangBuiltin<"__builtin_lsx_vsrari_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrari_w : ClangBuiltin<"__builtin_lsx_vsrari_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrari_d : ClangBuiltin<"__builtin_lsx_vsrari_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsat_b : ClangBuiltin<"__builtin_lsx_vsat_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsat_h : ClangBuiltin<"__builtin_lsx_vsat_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsat_w : ClangBuiltin<"__builtin_lsx_vsat_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsat_d : ClangBuiltin<"__builtin_lsx_vsat_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsat_bu : ClangBuiltin<"__builtin_lsx_vsat_bu">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsat_hu : ClangBuiltin<"__builtin_lsx_vsat_hu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsat_wu : ClangBuiltin<"__builtin_lsx_vsat_wu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsat_du : ClangBuiltin<"__builtin_lsx_vsat_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsrlni_b_h : ClangBuiltin<"__builtin_lsx_vsrlni_b_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrlni_h_w : ClangBuiltin<"__builtin_lsx_vsrlni_h_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrlni_w_d : ClangBuiltin<"__builtin_lsx_vsrlni_w_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrlni_d_q : ClangBuiltin<"__builtin_lsx_vsrlni_d_q">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsrlrni_b_h : ClangBuiltin<"__builtin_lsx_vsrlrni_b_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrlrni_h_w : ClangBuiltin<"__builtin_lsx_vsrlrni_h_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrlrni_w_d : ClangBuiltin<"__builtin_lsx_vsrlrni_w_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrlrni_d_q : ClangBuiltin<"__builtin_lsx_vsrlrni_d_q">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vssrlni_b_h : ClangBuiltin<"__builtin_lsx_vssrlni_b_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrlni_h_w : ClangBuiltin<"__builtin_lsx_vssrlni_h_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrlni_w_d : ClangBuiltin<"__builtin_lsx_vssrlni_w_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrlni_d_q : ClangBuiltin<"__builtin_lsx_vssrlni_d_q">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vssrlrni_bu_h : ClangBuiltin<"__builtin_lsx_vssrlrni_bu_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrlrni_hu_w : ClangBuiltin<"__builtin_lsx_vssrlrni_hu_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrlrni_wu_d : ClangBuiltin<"__builtin_lsx_vssrlrni_wu_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrlrni_du_q : ClangBuiltin<"__builtin_lsx_vssrlrni_du_q">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsrarni_b_h : ClangBuiltin<"__builtin_lsx_vsrarni_b_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrarni_h_w : ClangBuiltin<"__builtin_lsx_vsrarni_h_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrarni_w_d : ClangBuiltin<"__builtin_lsx_vsrarni_w_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrarni_d_q : ClangBuiltin<"__builtin_lsx_vsrarni_d_q">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vssrani_b_h : ClangBuiltin<"__builtin_lsx_vssrani_b_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrani_h_w : ClangBuiltin<"__builtin_lsx_vssrani_h_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrani_w_d : ClangBuiltin<"__builtin_lsx_vssrani_w_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrani_d_q : ClangBuiltin<"__builtin_lsx_vssrani_d_q">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vssrani_bu_h : ClangBuiltin<"__builtin_lsx_vssrani_bu_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrani_hu_w : ClangBuiltin<"__builtin_lsx_vssrani_hu_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrani_wu_d : ClangBuiltin<"__builtin_lsx_vssrani_wu_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrani_du_q : ClangBuiltin<"__builtin_lsx_vssrani_du_q">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vssrarni_b_h : ClangBuiltin<"__builtin_lsx_vssrarni_b_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrarni_h_w : ClangBuiltin<"__builtin_lsx_vssrarni_h_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrarni_w_d : ClangBuiltin<"__builtin_lsx_vssrarni_w_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrarni_d_q : ClangBuiltin<"__builtin_lsx_vssrarni_d_q">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vssrarni_bu_h : ClangBuiltin<"__builtin_lsx_vssrarni_bu_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrarni_hu_w : ClangBuiltin<"__builtin_lsx_vssrarni_hu_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrarni_wu_d : ClangBuiltin<"__builtin_lsx_vssrarni_wu_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrarni_du_q : ClangBuiltin<"__builtin_lsx_vssrarni_du_q">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vssrlni_bu_h : ClangBuiltin<"__builtin_lsx_vssrlni_bu_h">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrlni_hu_w : ClangBuiltin<"__builtin_lsx_vssrlni_hu_w">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrlni_wu_d : ClangBuiltin<"__builtin_lsx_vssrlni_wu_d">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vssrlni_du_q : ClangBuiltin<"__builtin_lsx_vssrlni_du_q">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vseq_b : ClangBuiltin<"__builtin_lsx_vseq_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vseq_h : ClangBuiltin<"__builtin_lsx_vseq_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vseq_w : ClangBuiltin<"__builtin_lsx_vseq_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vseq_d : ClangBuiltin<"__builtin_lsx_vseq_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsle_b : ClangBuiltin<"__builtin_lsx_vsle_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsle_h : ClangBuiltin<"__builtin_lsx_vsle_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsle_w : ClangBuiltin<"__builtin_lsx_vsle_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsle_d : ClangBuiltin<"__builtin_lsx_vsle_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsle_bu : ClangBuiltin<"__builtin_lsx_vsle_bu">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsle_hu : ClangBuiltin<"__builtin_lsx_vsle_hu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsle_wu : ClangBuiltin<"__builtin_lsx_vsle_wu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsle_du : ClangBuiltin<"__builtin_lsx_vsle_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vslt_b : ClangBuiltin<"__builtin_lsx_vslt_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vslt_h : ClangBuiltin<"__builtin_lsx_vslt_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vslt_w : ClangBuiltin<"__builtin_lsx_vslt_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vslt_d : ClangBuiltin<"__builtin_lsx_vslt_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vslt_bu : ClangBuiltin<"__builtin_lsx_vslt_bu">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vslt_hu : ClangBuiltin<"__builtin_lsx_vslt_hu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vslt_wu : ClangBuiltin<"__builtin_lsx_vslt_wu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vslt_du : ClangBuiltin<"__builtin_lsx_vslt_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vadd_b : ClangBuiltin<"__builtin_lsx_vadd_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vadd_h : ClangBuiltin<"__builtin_lsx_vadd_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vadd_w : ClangBuiltin<"__builtin_lsx_vadd_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vadd_d : ClangBuiltin<"__builtin_lsx_vadd_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], ++ [Commutative, IntrNoMem]>; ++ ++def int_loongarch_lsx_vsub_b : ClangBuiltin<"__builtin_lsx_vsub_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsub_h : ClangBuiltin<"__builtin_lsx_vsub_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsub_w : ClangBuiltin<"__builtin_lsx_vsub_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsub_d : ClangBuiltin<"__builtin_lsx_vsub_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmax_b : ClangBuiltin<"__builtin_lsx_vmax_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmax_h : ClangBuiltin<"__builtin_lsx_vmax_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmax_w : ClangBuiltin<"__builtin_lsx_vmax_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmax_d : ClangBuiltin<"__builtin_lsx_vmax_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmin_b : ClangBuiltin<"__builtin_lsx_vmin_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmin_h : ClangBuiltin<"__builtin_lsx_vmin_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmin_w : ClangBuiltin<"__builtin_lsx_vmin_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmin_d : ClangBuiltin<"__builtin_lsx_vmin_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmax_bu : ClangBuiltin<"__builtin_lsx_vmax_bu">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmax_hu : ClangBuiltin<"__builtin_lsx_vmax_hu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmax_wu : ClangBuiltin<"__builtin_lsx_vmax_wu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmax_du : ClangBuiltin<"__builtin_lsx_vmax_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmin_bu : ClangBuiltin<"__builtin_lsx_vmin_bu">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmin_hu : ClangBuiltin<"__builtin_lsx_vmin_hu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmin_wu : ClangBuiltin<"__builtin_lsx_vmin_wu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmin_du : ClangBuiltin<"__builtin_lsx_vmin_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmul_b : ClangBuiltin<"__builtin_lsx_vmul_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmul_h : ClangBuiltin<"__builtin_lsx_vmul_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmul_w : ClangBuiltin<"__builtin_lsx_vmul_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmul_d : ClangBuiltin<"__builtin_lsx_vmul_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmadd_b : ClangBuiltin<"__builtin_lsx_vmadd_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty], ++ [IntrNoMem]>; ++def int_loongarch_lsx_vmadd_h : ClangBuiltin<"__builtin_lsx_vmadd_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty], ++ [IntrNoMem]>; ++def int_loongarch_lsx_vmadd_w : ClangBuiltin<"__builtin_lsx_vmadd_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty], ++ [IntrNoMem]>; ++def int_loongarch_lsx_vmadd_d : ClangBuiltin<"__builtin_lsx_vmadd_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty], ++ [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmsub_b : ClangBuiltin<"__builtin_lsx_vmsub_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty], ++ [IntrNoMem]>; ++def int_loongarch_lsx_vmsub_h : ClangBuiltin<"__builtin_lsx_vmsub_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty], ++ [IntrNoMem]>; ++def int_loongarch_lsx_vmsub_w : ClangBuiltin<"__builtin_lsx_vmsub_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty], ++ [IntrNoMem]>; ++def int_loongarch_lsx_vmsub_d : ClangBuiltin<"__builtin_lsx_vmsub_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty], ++ [IntrNoMem]>; ++ ++def int_loongarch_lsx_vdiv_b : ClangBuiltin<"__builtin_lsx_vdiv_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vdiv_h : ClangBuiltin<"__builtin_lsx_vdiv_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vdiv_w : ClangBuiltin<"__builtin_lsx_vdiv_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vdiv_d : ClangBuiltin<"__builtin_lsx_vdiv_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmod_b : ClangBuiltin<"__builtin_lsx_vmod_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmod_h : ClangBuiltin<"__builtin_lsx_vmod_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmod_w : ClangBuiltin<"__builtin_lsx_vmod_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmod_d : ClangBuiltin<"__builtin_lsx_vmod_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vdiv_bu : ClangBuiltin<"__builtin_lsx_vdiv_bu">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vdiv_hu : ClangBuiltin<"__builtin_lsx_vdiv_hu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vdiv_wu : ClangBuiltin<"__builtin_lsx_vdiv_wu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vdiv_du : ClangBuiltin<"__builtin_lsx_vdiv_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsll_b : ClangBuiltin<"__builtin_lsx_vsll_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsll_h : ClangBuiltin<"__builtin_lsx_vsll_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsll_w : ClangBuiltin<"__builtin_lsx_vsll_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsll_d : ClangBuiltin<"__builtin_lsx_vsll_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsrl_b : ClangBuiltin<"__builtin_lsx_vsrl_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrl_h : ClangBuiltin<"__builtin_lsx_vsrl_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrl_w : ClangBuiltin<"__builtin_lsx_vsrl_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrl_d : ClangBuiltin<"__builtin_lsx_vsrl_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vbitclr_b : ClangBuiltin<"__builtin_lsx_vbitclr_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vbitclr_h : ClangBuiltin<"__builtin_lsx_vbitclr_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vbitclr_w : ClangBuiltin<"__builtin_lsx_vbitclr_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vbitclr_d : ClangBuiltin<"__builtin_lsx_vbitclr_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vbitset_b : ClangBuiltin<"__builtin_lsx_vbitset_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vbitset_h : ClangBuiltin<"__builtin_lsx_vbitset_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vbitset_w : ClangBuiltin<"__builtin_lsx_vbitset_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vbitset_d : ClangBuiltin<"__builtin_lsx_vbitset_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vpackev_b : ClangBuiltin<"__builtin_lsx_vpackev_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vpackev_h : ClangBuiltin<"__builtin_lsx_vpackev_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vpackev_w : ClangBuiltin<"__builtin_lsx_vpackev_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vpackev_d : ClangBuiltin<"__builtin_lsx_vpackev_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vpackod_b : ClangBuiltin<"__builtin_lsx_vpackod_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vpackod_h : ClangBuiltin<"__builtin_lsx_vpackod_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vpackod_w : ClangBuiltin<"__builtin_lsx_vpackod_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vpackod_d : ClangBuiltin<"__builtin_lsx_vpackod_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vilvl_b : ClangBuiltin<"__builtin_lsx_vilvl_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vilvl_h : ClangBuiltin<"__builtin_lsx_vilvl_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vilvl_w : ClangBuiltin<"__builtin_lsx_vilvl_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vilvl_d : ClangBuiltin<"__builtin_lsx_vilvl_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vilvh_b : ClangBuiltin<"__builtin_lsx_vilvh_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vilvh_h : ClangBuiltin<"__builtin_lsx_vilvh_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vilvh_w : ClangBuiltin<"__builtin_lsx_vilvh_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vilvh_d : ClangBuiltin<"__builtin_lsx_vilvh_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vpickev_b : ClangBuiltin<"__builtin_lsx_vpickev_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vpickev_h : ClangBuiltin<"__builtin_lsx_vpickev_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vpickev_w : ClangBuiltin<"__builtin_lsx_vpickev_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vpickev_d : ClangBuiltin<"__builtin_lsx_vpickev_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vand_v : ClangBuiltin<"__builtin_lsx_vand_v">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vor_v : ClangBuiltin<"__builtin_lsx_vor_v">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vbitrev_b : ClangBuiltin<"__builtin_lsx_vbitrev_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vbitrev_h : ClangBuiltin<"__builtin_lsx_vbitrev_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vbitrev_w : ClangBuiltin<"__builtin_lsx_vbitrev_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vbitrev_d : ClangBuiltin<"__builtin_lsx_vbitrev_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmod_bu : ClangBuiltin<"__builtin_lsx_vmod_bu">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmod_hu : ClangBuiltin<"__builtin_lsx_vmod_hu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmod_wu : ClangBuiltin<"__builtin_lsx_vmod_wu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmod_du : ClangBuiltin<"__builtin_lsx_vmod_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vpickod_b : ClangBuiltin<"__builtin_lsx_vpickod_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vpickod_h : ClangBuiltin<"__builtin_lsx_vpickod_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vpickod_w : ClangBuiltin<"__builtin_lsx_vpickod_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vpickod_d : ClangBuiltin<"__builtin_lsx_vpickod_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vreplve_b : ClangBuiltin<"__builtin_lsx_vreplve_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vreplve_h : ClangBuiltin<"__builtin_lsx_vreplve_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vreplve_w : ClangBuiltin<"__builtin_lsx_vreplve_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vreplve_d : ClangBuiltin<"__builtin_lsx_vreplve_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsra_b : ClangBuiltin<"__builtin_lsx_vsra_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsra_h : ClangBuiltin<"__builtin_lsx_vsra_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsra_w : ClangBuiltin<"__builtin_lsx_vsra_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsra_d : ClangBuiltin<"__builtin_lsx_vsra_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vxor_v : ClangBuiltin<"__builtin_lsx_vxor_v">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vnor_v : ClangBuiltin<"__builtin_lsx_vnor_v">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfadd_s : ClangBuiltin<"__builtin_lsx_vfadd_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfadd_d : ClangBuiltin<"__builtin_lsx_vfadd_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfsub_s : ClangBuiltin<"__builtin_lsx_vfsub_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfsub_d : ClangBuiltin<"__builtin_lsx_vfsub_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfmul_s : ClangBuiltin<"__builtin_lsx_vfmul_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfmul_d : ClangBuiltin<"__builtin_lsx_vfmul_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vshuf_h : ClangBuiltin<"__builtin_lsx_vshuf_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty], ++ [IntrNoMem]>; ++def int_loongarch_lsx_vshuf_w : ClangBuiltin<"__builtin_lsx_vshuf_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty], ++ [IntrNoMem]>; ++def int_loongarch_lsx_vshuf_d : ClangBuiltin<"__builtin_lsx_vshuf_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty], ++ [IntrNoMem]>; ++ ++def int_loongarch_lsx_vseqi_b : ClangBuiltin<"__builtin_lsx_vseqi_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vseqi_h : ClangBuiltin<"__builtin_lsx_vseqi_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vseqi_w : ClangBuiltin<"__builtin_lsx_vseqi_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vseqi_d : ClangBuiltin<"__builtin_lsx_vseqi_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vslei_b : ClangBuiltin<"__builtin_lsx_vslei_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vslei_h : ClangBuiltin<"__builtin_lsx_vslei_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vslei_w : ClangBuiltin<"__builtin_lsx_vslei_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vslei_d : ClangBuiltin<"__builtin_lsx_vslei_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vslei_bu : ClangBuiltin<"__builtin_lsx_vslei_bu">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vslei_hu : ClangBuiltin<"__builtin_lsx_vslei_hu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vslei_wu : ClangBuiltin<"__builtin_lsx_vslei_wu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vslei_du : ClangBuiltin<"__builtin_lsx_vslei_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vslti_b : ClangBuiltin<"__builtin_lsx_vslti_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vslti_h : ClangBuiltin<"__builtin_lsx_vslti_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vslti_w : ClangBuiltin<"__builtin_lsx_vslti_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vslti_d : ClangBuiltin<"__builtin_lsx_vslti_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vslti_bu : ClangBuiltin<"__builtin_lsx_vslti_bu">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vslti_hu : ClangBuiltin<"__builtin_lsx_vslti_hu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vslti_wu : ClangBuiltin<"__builtin_lsx_vslti_wu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vslti_du : ClangBuiltin<"__builtin_lsx_vslti_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vaddi_bu : ClangBuiltin<"__builtin_lsx_vaddi_bu">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vaddi_hu : ClangBuiltin<"__builtin_lsx_vaddi_hu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vaddi_wu : ClangBuiltin<"__builtin_lsx_vaddi_wu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lsx_vaddi_du : ClangBuiltin<"__builtin_lsx_vaddi_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], ++ [Commutative, IntrNoMem]>; ++ ++def int_loongarch_lsx_vsubi_bu : ClangBuiltin<"__builtin_lsx_vsubi_bu">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsubi_hu : ClangBuiltin<"__builtin_lsx_vsubi_hu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsubi_wu : ClangBuiltin<"__builtin_lsx_vsubi_wu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsubi_du : ClangBuiltin<"__builtin_lsx_vsubi_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmaxi_b : ClangBuiltin<"__builtin_lsx_vmaxi_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaxi_h : ClangBuiltin<"__builtin_lsx_vmaxi_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaxi_w : ClangBuiltin<"__builtin_lsx_vmaxi_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaxi_d : ClangBuiltin<"__builtin_lsx_vmaxi_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmini_b : ClangBuiltin<"__builtin_lsx_vmini_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmini_h : ClangBuiltin<"__builtin_lsx_vmini_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmini_w : ClangBuiltin<"__builtin_lsx_vmini_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmini_d : ClangBuiltin<"__builtin_lsx_vmini_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmaxi_bu : ClangBuiltin<"__builtin_lsx_vmaxi_bu">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaxi_hu : ClangBuiltin<"__builtin_lsx_vmaxi_hu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaxi_wu : ClangBuiltin<"__builtin_lsx_vmaxi_wu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmaxi_du : ClangBuiltin<"__builtin_lsx_vmaxi_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vmini_bu : ClangBuiltin<"__builtin_lsx_vmini_bu">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmini_hu : ClangBuiltin<"__builtin_lsx_vmini_hu">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmini_wu : ClangBuiltin<"__builtin_lsx_vmini_wu">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vmini_du : ClangBuiltin<"__builtin_lsx_vmini_du">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vclz_b : ClangBuiltin<"__builtin_lsx_vclz_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vclz_h : ClangBuiltin<"__builtin_lsx_vclz_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vclz_w : ClangBuiltin<"__builtin_lsx_vclz_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vclz_d : ClangBuiltin<"__builtin_lsx_vclz_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vpcnt_b : ClangBuiltin<"__builtin_lsx_vpcnt_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vpcnt_h : ClangBuiltin<"__builtin_lsx_vpcnt_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vpcnt_w : ClangBuiltin<"__builtin_lsx_vpcnt_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vpcnt_d : ClangBuiltin<"__builtin_lsx_vpcnt_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfsqrt_s : ClangBuiltin<"__builtin_lsx_vfsqrt_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfsqrt_d : ClangBuiltin<"__builtin_lsx_vfsqrt_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfrint_s : ClangBuiltin<"__builtin_lsx_vfrint_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfrint_d : ClangBuiltin<"__builtin_lsx_vfrint_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vffint_s_w : ClangBuiltin<"__builtin_lsx_vffint_s_w">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vffint_d_l : ClangBuiltin<"__builtin_lsx_vffint_d_l">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vffint_s_wu : ClangBuiltin<"__builtin_lsx_vffint_s_wu">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vffint_d_lu : ClangBuiltin<"__builtin_lsx_vffint_d_lu">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vftintrz_wu_s : ClangBuiltin<"__builtin_lsx_vftintrz_wu_s">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vftintrz_lu_d : ClangBuiltin<"__builtin_lsx_vftintrz_lu_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vreplgr2vr_b : ClangBuiltin<"__builtin_lsx_vreplgr2vr_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vreplgr2vr_h : ClangBuiltin<"__builtin_lsx_vreplgr2vr_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vreplgr2vr_w : ClangBuiltin<"__builtin_lsx_vreplgr2vr_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vreplgr2vr_d : ClangBuiltin<"__builtin_lsx_vreplgr2vr_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vinsgr2vr_b : ClangBuiltin<"__builtin_lsx_vinsgr2vr_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty, llvm_i32_ty], ++ [IntrNoMem]>; ++def int_loongarch_lsx_vinsgr2vr_h : ClangBuiltin<"__builtin_lsx_vinsgr2vr_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty, llvm_i32_ty], ++ [IntrNoMem]>; ++def int_loongarch_lsx_vinsgr2vr_w : ClangBuiltin<"__builtin_lsx_vinsgr2vr_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty, llvm_i32_ty], ++ [IntrNoMem]>; ++def int_loongarch_lsx_vinsgr2vr_d : ClangBuiltin<"__builtin_lsx_vinsgr2vr_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i64_ty, llvm_i32_ty], ++ [IntrNoMem]>; ++ ++def int_loongarch_lsx_vfdiv_s : ClangBuiltin<"__builtin_lsx_vfdiv_s">, ++ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vfdiv_d : ClangBuiltin<"__builtin_lsx_vfdiv_d">, ++ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vslli_b : ClangBuiltin<"__builtin_lsx_vslli_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vslli_h : ClangBuiltin<"__builtin_lsx_vslli_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vslli_w : ClangBuiltin<"__builtin_lsx_vslli_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vslli_d : ClangBuiltin<"__builtin_lsx_vslli_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsrli_b : ClangBuiltin<"__builtin_lsx_vsrli_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrli_h : ClangBuiltin<"__builtin_lsx_vsrli_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrli_w : ClangBuiltin<"__builtin_lsx_vsrli_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrli_d : ClangBuiltin<"__builtin_lsx_vsrli_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vsrai_b : ClangBuiltin<"__builtin_lsx_vsrai_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrai_h : ClangBuiltin<"__builtin_lsx_vsrai_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrai_w : ClangBuiltin<"__builtin_lsx_vsrai_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vsrai_d : ClangBuiltin<"__builtin_lsx_vsrai_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vshuf4i_b : ClangBuiltin<"__builtin_lsx_vshuf4i_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vshuf4i_h : ClangBuiltin<"__builtin_lsx_vshuf4i_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vshuf4i_w : ClangBuiltin<"__builtin_lsx_vshuf4i_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vshuf4i_d : ClangBuiltin<"__builtin_lsx_vshuf4i_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vrotr_b : ClangBuiltin<"__builtin_lsx_vrotr_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vrotr_h : ClangBuiltin<"__builtin_lsx_vrotr_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vrotr_w : ClangBuiltin<"__builtin_lsx_vrotr_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vrotr_d : ClangBuiltin<"__builtin_lsx_vrotr_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vrotri_b : ClangBuiltin<"__builtin_lsx_vrotri_b">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vrotri_h : ClangBuiltin<"__builtin_lsx_vrotri_h">, ++ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vrotri_w : ClangBuiltin<"__builtin_lsx_vrotri_w">, ++ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_vrotri_d : ClangBuiltin<"__builtin_lsx_vrotri_d">, ++ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_vld : ClangBuiltin<"__builtin_lsx_vld">, ++ Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty, llvm_i32_ty], ++ [IntrReadMem, IntrArgMemOnly]>; ++ ++def int_loongarch_lsx_vst : ClangBuiltin<"__builtin_lsx_vst">, ++ Intrinsic<[], [llvm_v16i8_ty, llvm_ptr_ty, llvm_i32_ty], ++ [IntrArgMemOnly]>; ++ ++def int_loongarch_lsx_bz_v : ClangBuiltin<"__builtin_lsx_bz_v">, ++ Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_bnz_v : ClangBuiltin<"__builtin_lsx_bnz_v">, ++ Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_bz_b : ClangBuiltin<"__builtin_lsx_bz_b">, ++ Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_bz_h : ClangBuiltin<"__builtin_lsx_bz_h">, ++ Intrinsic<[llvm_i32_ty], [llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_bz_w : ClangBuiltin<"__builtin_lsx_bz_w">, ++ Intrinsic<[llvm_i32_ty], [llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_bz_d : ClangBuiltin<"__builtin_lsx_bz_d">, ++ Intrinsic<[llvm_i32_ty], [llvm_v2i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lsx_bnz_b : ClangBuiltin<"__builtin_lsx_bnz_b">, ++ Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty], [IntrNoMem]>; ++def int_loongarch_lsx_bnz_h : ClangBuiltin<"__builtin_lsx_bnz_h">, ++ Intrinsic<[llvm_i32_ty], [llvm_v8i16_ty], [IntrNoMem]>; ++def int_loongarch_lsx_bnz_w : ClangBuiltin<"__builtin_lsx_bnz_w">, ++ Intrinsic<[llvm_i32_ty], [llvm_v4i32_ty], [IntrNoMem]>; ++def int_loongarch_lsx_bnz_d : ClangBuiltin<"__builtin_lsx_bnz_d">, ++ Intrinsic<[llvm_i32_ty], [llvm_v2i64_ty], [IntrNoMem]>; + +-// @llvm.loongarch.masked.cmpxchg.i64.

( +-// ptr addr, grlen cmpval, grlen newval, grlen mask, grlenimm ordering) +-defm int_loongarch_masked_cmpxchg : MaskedAtomicRMWFiveOpIntrinsics; ++//===----------------------------------------------------------------------===// ++//LoongArch LASX ++ ++def int_loongarch_lasx_xvfmadd_s : ClangBuiltin<"__builtin_lasx_xvfmadd_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty], ++ [IntrNoMem]>; ++def int_loongarch_lasx_xvfmadd_d : ClangBuiltin<"__builtin_lasx_xvfmadd_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty], ++ [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfmsub_s : ClangBuiltin<"__builtin_lasx_xvfmsub_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty], ++ [IntrNoMem]>; ++def int_loongarch_lasx_xvfmsub_d : ClangBuiltin<"__builtin_lasx_xvfmsub_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty], ++ [IntrNoMem]>; ++ ++ ++def int_loongarch_lasx_xvfnmadd_s : ClangBuiltin<"__builtin_lasx_xvfnmadd_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty], ++ [IntrNoMem]>; ++def int_loongarch_lasx_xvfnmadd_d : ClangBuiltin<"__builtin_lasx_xvfnmadd_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty], ++ [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfnmsub_s : ClangBuiltin<"__builtin_lasx_xvfnmsub_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty], ++ [IntrNoMem]>; ++def int_loongarch_lasx_xvfnmsub_d : ClangBuiltin<"__builtin_lasx_xvfnmsub_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty], ++ [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvclo_b : ClangBuiltin<"__builtin_lasx_xvclo_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvclo_h : ClangBuiltin<"__builtin_lasx_xvclo_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvclo_w : ClangBuiltin<"__builtin_lasx_xvclo_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvclo_d : ClangBuiltin<"__builtin_lasx_xvclo_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvflogb_s : ClangBuiltin<"__builtin_lasx_xvflogb_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvflogb_d : ClangBuiltin<"__builtin_lasx_xvflogb_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvpickve2gr_w : ClangBuiltin<"__builtin_lasx_xvpickve2gr_w">, ++ Intrinsic<[llvm_i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvpickve2gr_d : ClangBuiltin<"__builtin_lasx_xvpickve2gr_d">, ++ Intrinsic<[llvm_i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvpickve2gr_wu : ClangBuiltin<"__builtin_lasx_xvpickve2gr_wu">, ++ Intrinsic<[llvm_i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvpickve2gr_du : ClangBuiltin<"__builtin_lasx_xvpickve2gr_du">, ++ Intrinsic<[llvm_i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmskltz_b : ClangBuiltin<"__builtin_lasx_xvmskltz_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmskltz_h : ClangBuiltin<"__builtin_lasx_xvmskltz_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmskltz_w : ClangBuiltin<"__builtin_lasx_xvmskltz_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmskltz_d : ClangBuiltin<"__builtin_lasx_xvmskltz_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcmp_caf_s : ClangBuiltin<"__builtin_lasx_xvfcmp_caf_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcmp_caf_d : ClangBuiltin<"__builtin_lasx_xvfcmp_caf_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcmp_cor_s : ClangBuiltin<"__builtin_lasx_xvfcmp_cor_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcmp_cor_d : ClangBuiltin<"__builtin_lasx_xvfcmp_cor_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcmp_cun_s : ClangBuiltin<"__builtin_lasx_xvfcmp_cun_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcmp_cun_d : ClangBuiltin<"__builtin_lasx_xvfcmp_cun_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcmp_cune_s : ClangBuiltin<"__builtin_lasx_xvfcmp_cune_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcmp_cune_d : ClangBuiltin<"__builtin_lasx_xvfcmp_cune_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcmp_cueq_s : ClangBuiltin<"__builtin_lasx_xvfcmp_cueq_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcmp_cueq_d : ClangBuiltin<"__builtin_lasx_xvfcmp_cueq_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcmp_ceq_s : ClangBuiltin<"__builtin_lasx_xvfcmp_ceq_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcmp_ceq_d : ClangBuiltin<"__builtin_lasx_xvfcmp_ceq_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcmp_cne_s : ClangBuiltin<"__builtin_lasx_xvfcmp_cne_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcmp_cne_d : ClangBuiltin<"__builtin_lasx_xvfcmp_cne_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcmp_clt_s : ClangBuiltin<"__builtin_lasx_xvfcmp_clt_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcmp_clt_d : ClangBuiltin<"__builtin_lasx_xvfcmp_clt_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcmp_cult_s : ClangBuiltin<"__builtin_lasx_xvfcmp_cult_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcmp_cult_d : ClangBuiltin<"__builtin_lasx_xvfcmp_cult_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcmp_cle_s : ClangBuiltin<"__builtin_lasx_xvfcmp_cle_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcmp_cle_d : ClangBuiltin<"__builtin_lasx_xvfcmp_cle_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcmp_cule_s : ClangBuiltin<"__builtin_lasx_xvfcmp_cule_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcmp_cule_d : ClangBuiltin<"__builtin_lasx_xvfcmp_cule_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcmp_saf_s : ClangBuiltin<"__builtin_lasx_xvfcmp_saf_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcmp_saf_d : ClangBuiltin<"__builtin_lasx_xvfcmp_saf_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcmp_sor_s : ClangBuiltin<"__builtin_lasx_xvfcmp_sor_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcmp_sor_d : ClangBuiltin<"__builtin_lasx_xvfcmp_sor_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcmp_sun_s : ClangBuiltin<"__builtin_lasx_xvfcmp_sun_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcmp_sun_d : ClangBuiltin<"__builtin_lasx_xvfcmp_sun_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcmp_sune_s : ClangBuiltin<"__builtin_lasx_xvfcmp_sune_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcmp_sune_d : ClangBuiltin<"__builtin_lasx_xvfcmp_sune_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcmp_sueq_s : ClangBuiltin<"__builtin_lasx_xvfcmp_sueq_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcmp_sueq_d : ClangBuiltin<"__builtin_lasx_xvfcmp_sueq_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcmp_seq_s : ClangBuiltin<"__builtin_lasx_xvfcmp_seq_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcmp_seq_d : ClangBuiltin<"__builtin_lasx_xvfcmp_seq_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcmp_sne_s : ClangBuiltin<"__builtin_lasx_xvfcmp_sne_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcmp_sne_d : ClangBuiltin<"__builtin_lasx_xvfcmp_sne_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcmp_slt_s : ClangBuiltin<"__builtin_lasx_xvfcmp_slt_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcmp_slt_d : ClangBuiltin<"__builtin_lasx_xvfcmp_slt_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcmp_sult_s : ClangBuiltin<"__builtin_lasx_xvfcmp_sult_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcmp_sult_d : ClangBuiltin<"__builtin_lasx_xvfcmp_sult_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcmp_sle_s : ClangBuiltin<"__builtin_lasx_xvfcmp_sle_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcmp_sle_d : ClangBuiltin<"__builtin_lasx_xvfcmp_sle_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcmp_sule_s : ClangBuiltin<"__builtin_lasx_xvfcmp_sule_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcmp_sule_d : ClangBuiltin<"__builtin_lasx_xvfcmp_sule_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvbitsel_v : ClangBuiltin<"__builtin_lasx_xvbitsel_v">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvshuf_b : ClangBuiltin<"__builtin_lasx_xvshuf_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvldrepl_b : ClangBuiltin<"__builtin_lasx_xvldrepl_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_ptr_ty, llvm_i32_ty], [IntrReadMem, IntrArgMemOnly]>; ++def int_loongarch_lasx_xvldrepl_h : ClangBuiltin<"__builtin_lasx_xvldrepl_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_ptr_ty, llvm_i32_ty], [IntrReadMem, IntrArgMemOnly]>; ++def int_loongarch_lasx_xvldrepl_w : ClangBuiltin<"__builtin_lasx_xvldrepl_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_ptr_ty, llvm_i32_ty], [IntrReadMem, IntrArgMemOnly]>; ++def int_loongarch_lasx_xvldrepl_d : ClangBuiltin<"__builtin_lasx_xvldrepl_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_ptr_ty, llvm_i32_ty], [IntrReadMem, IntrArgMemOnly]>; ++ ++def int_loongarch_lasx_xvstelm_b : ClangBuiltin<"__builtin_lasx_xvstelm_b">, ++ Intrinsic<[], [llvm_v32i8_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; ++def int_loongarch_lasx_xvstelm_h : ClangBuiltin<"__builtin_lasx_xvstelm_h">, ++ Intrinsic<[], [llvm_v16i16_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; ++def int_loongarch_lasx_xvstelm_w : ClangBuiltin<"__builtin_lasx_xvstelm_w">, ++ Intrinsic<[], [llvm_v8i32_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; ++def int_loongarch_lasx_xvstelm_d : ClangBuiltin<"__builtin_lasx_xvstelm_d">, ++ Intrinsic<[], [llvm_v4i64_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; ++ ++def int_loongarch_lasx_xvldx : ClangBuiltin<"__builtin_lasx_xvldx">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_ptr_ty, llvm_i64_ty], ++ [IntrReadMem, IntrArgMemOnly]>; ++ ++def int_loongarch_lasx_xvstx : ClangBuiltin<"__builtin_lasx_xvstx">, ++ Intrinsic<[], [llvm_v32i8_ty, llvm_ptr_ty, llvm_i64_ty], ++ [IntrArgMemOnly]>; ++ ++def int_loongarch_lasx_xvaddwev_d_w : ClangBuiltin<"__builtin_lasx_xvaddwev_d_w">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvaddwev_w_h : ClangBuiltin<"__builtin_lasx_xvaddwev_w_h">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvaddwev_h_b : ClangBuiltin<"__builtin_lasx_xvaddwev_h_b">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvaddwev_q_d : ClangBuiltin<"__builtin_lasx_xvaddwev_q_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsubwev_d_w : ClangBuiltin<"__builtin_lasx_xvsubwev_d_w">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsubwev_w_h : ClangBuiltin<"__builtin_lasx_xvsubwev_w_h">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsubwev_h_b : ClangBuiltin<"__builtin_lasx_xvsubwev_h_b">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsubwev_q_d : ClangBuiltin<"__builtin_lasx_xvsubwev_q_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvaddwod_d_w : ClangBuiltin<"__builtin_lasx_xvaddwod_d_w">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvaddwod_w_h : ClangBuiltin<"__builtin_lasx_xvaddwod_w_h">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvaddwod_h_b : ClangBuiltin<"__builtin_lasx_xvaddwod_h_b">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvaddwod_q_d : ClangBuiltin<"__builtin_lasx_xvaddwod_q_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsubwod_d_w : ClangBuiltin<"__builtin_lasx_xvsubwod_d_w">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsubwod_w_h : ClangBuiltin<"__builtin_lasx_xvsubwod_w_h">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsubwod_h_b : ClangBuiltin<"__builtin_lasx_xvsubwod_h_b">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsubwod_q_d : ClangBuiltin<"__builtin_lasx_xvsubwod_q_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvaddwev_d_wu : ClangBuiltin<"__builtin_lasx_xvaddwev_d_wu">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvaddwev_w_hu : ClangBuiltin<"__builtin_lasx_xvaddwev_w_hu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvaddwev_h_bu : ClangBuiltin<"__builtin_lasx_xvaddwev_h_bu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvaddwev_q_du : ClangBuiltin<"__builtin_lasx_xvaddwev_q_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsubwev_d_wu : ClangBuiltin<"__builtin_lasx_xvsubwev_d_wu">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsubwev_w_hu : ClangBuiltin<"__builtin_lasx_xvsubwev_w_hu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsubwev_h_bu : ClangBuiltin<"__builtin_lasx_xvsubwev_h_bu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsubwev_q_du : ClangBuiltin<"__builtin_lasx_xvsubwev_q_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvaddwod_d_wu : ClangBuiltin<"__builtin_lasx_xvaddwod_d_wu">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvaddwod_w_hu : ClangBuiltin<"__builtin_lasx_xvaddwod_w_hu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvaddwod_h_bu : ClangBuiltin<"__builtin_lasx_xvaddwod_h_bu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvaddwod_q_du : ClangBuiltin<"__builtin_lasx_xvaddwod_q_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsubwod_d_wu : ClangBuiltin<"__builtin_lasx_xvsubwod_d_wu">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsubwod_w_hu : ClangBuiltin<"__builtin_lasx_xvsubwod_w_hu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsubwod_h_bu : ClangBuiltin<"__builtin_lasx_xvsubwod_h_bu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsubwod_q_du : ClangBuiltin<"__builtin_lasx_xvsubwod_q_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvaddwev_d_wu_w : ClangBuiltin<"__builtin_lasx_xvaddwev_d_wu_w">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvaddwev_w_hu_h : ClangBuiltin<"__builtin_lasx_xvaddwev_w_hu_h">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvaddwev_h_bu_b : ClangBuiltin<"__builtin_lasx_xvaddwev_h_bu_b">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvaddwev_q_du_d : ClangBuiltin<"__builtin_lasx_xvaddwev_q_du_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvaddwod_d_wu_w : ClangBuiltin<"__builtin_lasx_xvaddwod_d_wu_w">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvaddwod_w_hu_h : ClangBuiltin<"__builtin_lasx_xvaddwod_w_hu_h">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvaddwod_h_bu_b : ClangBuiltin<"__builtin_lasx_xvaddwod_h_bu_b">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvaddwod_q_du_d : ClangBuiltin<"__builtin_lasx_xvaddwod_q_du_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvhaddw_qu_du : ClangBuiltin<"__builtin_lasx_xvhaddw_qu_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvhsubw_qu_du : ClangBuiltin<"__builtin_lasx_xvhsubw_qu_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvhaddw_q_d : ClangBuiltin<"__builtin_lasx_xvhaddw_q_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvhsubw_q_d : ClangBuiltin<"__builtin_lasx_xvhsubw_q_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmuh_b : ClangBuiltin<"__builtin_lasx_xvmuh_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmuh_h : ClangBuiltin<"__builtin_lasx_xvmuh_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmuh_w : ClangBuiltin<"__builtin_lasx_xvmuh_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmuh_d : ClangBuiltin<"__builtin_lasx_xvmuh_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmuh_bu : ClangBuiltin<"__builtin_lasx_xvmuh_bu">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmuh_hu : ClangBuiltin<"__builtin_lasx_xvmuh_hu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmuh_wu : ClangBuiltin<"__builtin_lasx_xvmuh_wu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmuh_du : ClangBuiltin<"__builtin_lasx_xvmuh_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmulwev_d_w : ClangBuiltin<"__builtin_lasx_xvmulwev_d_w">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmulwev_w_h : ClangBuiltin<"__builtin_lasx_xvmulwev_w_h">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmulwev_h_b : ClangBuiltin<"__builtin_lasx_xvmulwev_h_b">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmulwev_q_d : ClangBuiltin<"__builtin_lasx_xvmulwev_q_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmulwod_d_w : ClangBuiltin<"__builtin_lasx_xvmulwod_d_w">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmulwod_w_h : ClangBuiltin<"__builtin_lasx_xvmulwod_w_h">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmulwod_h_b : ClangBuiltin<"__builtin_lasx_xvmulwod_h_b">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmulwod_q_d : ClangBuiltin<"__builtin_lasx_xvmulwod_q_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmulwev_d_wu : ClangBuiltin<"__builtin_lasx_xvmulwev_d_wu">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmulwev_w_hu : ClangBuiltin<"__builtin_lasx_xvmulwev_w_hu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmulwev_h_bu : ClangBuiltin<"__builtin_lasx_xvmulwev_h_bu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmulwev_q_du : ClangBuiltin<"__builtin_lasx_xvmulwev_q_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmulwod_d_wu : ClangBuiltin<"__builtin_lasx_xvmulwod_d_wu">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmulwod_w_hu : ClangBuiltin<"__builtin_lasx_xvmulwod_w_hu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmulwod_h_bu : ClangBuiltin<"__builtin_lasx_xvmulwod_h_bu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmulwod_q_du : ClangBuiltin<"__builtin_lasx_xvmulwod_q_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmulwev_d_wu_w : ClangBuiltin<"__builtin_lasx_xvmulwev_d_wu_w">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmulwev_w_hu_h : ClangBuiltin<"__builtin_lasx_xvmulwev_w_hu_h">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmulwev_h_bu_b : ClangBuiltin<"__builtin_lasx_xvmulwev_h_bu_b">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmulwev_q_du_d : ClangBuiltin<"__builtin_lasx_xvmulwev_q_du_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmulwod_d_wu_w : ClangBuiltin<"__builtin_lasx_xvmulwod_d_wu_w">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmulwod_w_hu_h : ClangBuiltin<"__builtin_lasx_xvmulwod_w_hu_h">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmulwod_h_bu_b : ClangBuiltin<"__builtin_lasx_xvmulwod_h_bu_b">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmulwod_q_du_d : ClangBuiltin<"__builtin_lasx_xvmulwod_q_du_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmaddwev_d_w : ClangBuiltin<"__builtin_lasx_xvmaddwev_d_w">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaddwev_w_h : ClangBuiltin<"__builtin_lasx_xvmaddwev_w_h">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaddwev_h_b : ClangBuiltin<"__builtin_lasx_xvmaddwev_h_b">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaddwev_q_d : ClangBuiltin<"__builtin_lasx_xvmaddwev_q_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmaddwod_d_w : ClangBuiltin<"__builtin_lasx_xvmaddwod_d_w">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaddwod_w_h : ClangBuiltin<"__builtin_lasx_xvmaddwod_w_h">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaddwod_h_b : ClangBuiltin<"__builtin_lasx_xvmaddwod_h_b">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaddwod_q_d : ClangBuiltin<"__builtin_lasx_xvmaddwod_q_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmaddwev_d_wu : ClangBuiltin<"__builtin_lasx_xvmaddwev_d_wu">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaddwev_w_hu : ClangBuiltin<"__builtin_lasx_xvmaddwev_w_hu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaddwev_h_bu : ClangBuiltin<"__builtin_lasx_xvmaddwev_h_bu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaddwev_q_du : ClangBuiltin<"__builtin_lasx_xvmaddwev_q_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmaddwod_d_wu : ClangBuiltin<"__builtin_lasx_xvmaddwod_d_wu">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaddwod_w_hu : ClangBuiltin<"__builtin_lasx_xvmaddwod_w_hu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaddwod_h_bu : ClangBuiltin<"__builtin_lasx_xvmaddwod_h_bu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaddwod_q_du : ClangBuiltin<"__builtin_lasx_xvmaddwod_q_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmaddwev_d_wu_w : ClangBuiltin<"__builtin_lasx_xvmaddwev_d_wu_w">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaddwev_w_hu_h : ClangBuiltin<"__builtin_lasx_xvmaddwev_w_hu_h">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaddwev_h_bu_b : ClangBuiltin<"__builtin_lasx_xvmaddwev_h_bu_b">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaddwev_q_du_d : ClangBuiltin<"__builtin_lasx_xvmaddwev_q_du_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmaddwod_d_wu_w : ClangBuiltin<"__builtin_lasx_xvmaddwod_d_wu_w">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaddwod_w_hu_h : ClangBuiltin<"__builtin_lasx_xvmaddwod_w_hu_h">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaddwod_h_bu_b : ClangBuiltin<"__builtin_lasx_xvmaddwod_h_bu_b">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaddwod_q_du_d : ClangBuiltin<"__builtin_lasx_xvmaddwod_q_du_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsrln_b_h : ClangBuiltin<"__builtin_lasx_xvsrln_b_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrln_h_w : ClangBuiltin<"__builtin_lasx_xvsrln_h_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrln_w_d : ClangBuiltin<"__builtin_lasx_xvsrln_w_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsran_b_h : ClangBuiltin<"__builtin_lasx_xvsran_b_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsran_h_w : ClangBuiltin<"__builtin_lasx_xvsran_h_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsran_w_d : ClangBuiltin<"__builtin_lasx_xvsran_w_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsrlrn_b_h : ClangBuiltin<"__builtin_lasx_xvsrlrn_b_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrlrn_h_w : ClangBuiltin<"__builtin_lasx_xvsrlrn_h_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrlrn_w_d : ClangBuiltin<"__builtin_lasx_xvsrlrn_w_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsrarn_b_h : ClangBuiltin<"__builtin_lasx_xvsrarn_b_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrarn_h_w : ClangBuiltin<"__builtin_lasx_xvsrarn_h_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrarn_w_d : ClangBuiltin<"__builtin_lasx_xvsrarn_w_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvssrln_b_h : ClangBuiltin<"__builtin_lasx_xvssrln_b_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrln_h_w : ClangBuiltin<"__builtin_lasx_xvssrln_h_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrln_w_d : ClangBuiltin<"__builtin_lasx_xvssrln_w_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvssran_b_h : ClangBuiltin<"__builtin_lasx_xvssran_b_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssran_h_w : ClangBuiltin<"__builtin_lasx_xvssran_h_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssran_w_d : ClangBuiltin<"__builtin_lasx_xvssran_w_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvssrlrn_b_h : ClangBuiltin<"__builtin_lasx_xvssrlrn_b_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrlrn_h_w : ClangBuiltin<"__builtin_lasx_xvssrlrn_h_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrlrn_w_d : ClangBuiltin<"__builtin_lasx_xvssrlrn_w_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvssrarn_b_h : ClangBuiltin<"__builtin_lasx_xvssrarn_b_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrarn_h_w : ClangBuiltin<"__builtin_lasx_xvssrarn_h_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrarn_w_d : ClangBuiltin<"__builtin_lasx_xvssrarn_w_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvssrln_bu_h : ClangBuiltin<"__builtin_lasx_xvssrln_bu_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrln_hu_w : ClangBuiltin<"__builtin_lasx_xvssrln_hu_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrln_wu_d : ClangBuiltin<"__builtin_lasx_xvssrln_wu_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvssran_bu_h : ClangBuiltin<"__builtin_lasx_xvssran_bu_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssran_hu_w : ClangBuiltin<"__builtin_lasx_xvssran_hu_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssran_wu_d : ClangBuiltin<"__builtin_lasx_xvssran_wu_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvssrlrn_bu_h : ClangBuiltin<"__builtin_lasx_xvssrlrn_bu_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrlrn_hu_w : ClangBuiltin<"__builtin_lasx_xvssrlrn_hu_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrlrn_wu_d : ClangBuiltin<"__builtin_lasx_xvssrlrn_wu_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvssrarn_bu_h : ClangBuiltin<"__builtin_lasx_xvssrarn_bu_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrarn_hu_w : ClangBuiltin<"__builtin_lasx_xvssrarn_hu_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrarn_wu_d : ClangBuiltin<"__builtin_lasx_xvssrarn_wu_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvandn_v : ClangBuiltin<"__builtin_lasx_xvandn_v">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvorn_v : ClangBuiltin<"__builtin_lasx_xvorn_v">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfrstp_b : ClangBuiltin<"__builtin_lasx_xvfrstp_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_v32i8_ty], ++ [IntrNoMem]>; ++def int_loongarch_lasx_xvfrstp_h : ClangBuiltin<"__builtin_lasx_xvfrstp_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_v16i16_ty], ++ [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvadd_q : ClangBuiltin<"__builtin_lasx_xvadd_q">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsub_q : ClangBuiltin<"__builtin_lasx_xvsub_q">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsigncov_b : ClangBuiltin<"__builtin_lasx_xvsigncov_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], ++ [IntrNoMem]>; ++def int_loongarch_lasx_xvsigncov_h : ClangBuiltin<"__builtin_lasx_xvsigncov_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], ++ [IntrNoMem]>; ++def int_loongarch_lasx_xvsigncov_w : ClangBuiltin<"__builtin_lasx_xvsigncov_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], ++ [IntrNoMem]>; ++def int_loongarch_lasx_xvsigncov_d : ClangBuiltin<"__builtin_lasx_xvsigncov_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], ++ [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcvt_h_s : ClangBuiltin<"__builtin_lasx_xvfcvt_h_s">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcvt_s_d : ClangBuiltin<"__builtin_lasx_xvfcvt_s_d">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvffint_s_l : ClangBuiltin<"__builtin_lasx_xvffint_s_l">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvftint_w_d : ClangBuiltin<"__builtin_lasx_xvftint_w_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvftintrz_w_d : ClangBuiltin<"__builtin_lasx_xvftintrz_w_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvftintrp_w_d : ClangBuiltin<"__builtin_lasx_xvftintrp_w_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvftintrm_w_d : ClangBuiltin<"__builtin_lasx_xvftintrm_w_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvftintrne_w_d : ClangBuiltin<"__builtin_lasx_xvftintrne_w_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvbsrl_v : ClangBuiltin<"__builtin_lasx_xvbsrl_v">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvbsll_v : ClangBuiltin<"__builtin_lasx_xvbsll_v">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfrstpi_b : ClangBuiltin<"__builtin_lasx_xvfrstpi_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfrstpi_h : ClangBuiltin<"__builtin_lasx_xvfrstpi_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvneg_b : ClangBuiltin<"__builtin_lasx_xvneg_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvneg_h : ClangBuiltin<"__builtin_lasx_xvneg_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvneg_w : ClangBuiltin<"__builtin_lasx_xvneg_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvneg_d : ClangBuiltin<"__builtin_lasx_xvneg_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmskgez_b : ClangBuiltin<"__builtin_lasx_xvmskgez_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmsknz_b : ClangBuiltin<"__builtin_lasx_xvmsknz_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfrintrm_s : ClangBuiltin<"__builtin_lasx_xvfrintrm_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfrintrm_d : ClangBuiltin<"__builtin_lasx_xvfrintrm_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfrintrp_s : ClangBuiltin<"__builtin_lasx_xvfrintrp_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfrintrp_d : ClangBuiltin<"__builtin_lasx_xvfrintrp_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfrintrz_s : ClangBuiltin<"__builtin_lasx_xvfrintrz_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfrintrz_d : ClangBuiltin<"__builtin_lasx_xvfrintrz_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfrintrne_s : ClangBuiltin<"__builtin_lasx_xvfrintrne_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfrintrne_d : ClangBuiltin<"__builtin_lasx_xvfrintrne_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvffinth_d_w : ClangBuiltin<"__builtin_lasx_xvffinth_d_w">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvffintl_d_w : ClangBuiltin<"__builtin_lasx_xvffintl_d_w">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v8i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvftintrm_w_s : ClangBuiltin<"__builtin_lasx_xvftintrm_w_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvftintrm_l_d : ClangBuiltin<"__builtin_lasx_xvftintrm_l_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvftintrp_w_s : ClangBuiltin<"__builtin_lasx_xvftintrp_w_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvftintrp_l_d : ClangBuiltin<"__builtin_lasx_xvftintrp_l_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvftintrz_w_s : ClangBuiltin<"__builtin_lasx_xvftintrz_w_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvftintrz_l_d : ClangBuiltin<"__builtin_lasx_xvftintrz_l_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvftintrne_w_s : ClangBuiltin<"__builtin_lasx_xvftintrne_w_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvftintrne_l_d : ClangBuiltin<"__builtin_lasx_xvftintrne_l_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvftinth_l_s : ClangBuiltin<"__builtin_lasx_xvftinth_l_s">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvftintl_l_s : ClangBuiltin<"__builtin_lasx_xvftintl_l_s">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvftintrmh_l_s : ClangBuiltin<"__builtin_lasx_xvftintrmh_l_s">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvftintrml_l_s : ClangBuiltin<"__builtin_lasx_xvftintrml_l_s">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvftintrph_l_s : ClangBuiltin<"__builtin_lasx_xvftintrph_l_s">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvftintrpl_l_s : ClangBuiltin<"__builtin_lasx_xvftintrpl_l_s">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvftintrzh_l_s : ClangBuiltin<"__builtin_lasx_xvftintrzh_l_s">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvftintrzl_l_s : ClangBuiltin<"__builtin_lasx_xvftintrzl_l_s">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvftintrneh_l_s : ClangBuiltin<"__builtin_lasx_xvftintrneh_l_s">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvftintrnel_l_s : ClangBuiltin<"__builtin_lasx_xvftintrnel_l_s">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvexth_d_w : ClangBuiltin<"__builtin_lasx_xvexth_d_w">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvexth_w_h : ClangBuiltin<"__builtin_lasx_xvexth_w_h">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvexth_h_b : ClangBuiltin<"__builtin_lasx_xvexth_h_b">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvexth_q_d : ClangBuiltin<"__builtin_lasx_xvexth_q_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsllwil_d_w : ClangBuiltin<"__builtin_lasx_xvsllwil_d_w">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsllwil_w_h : ClangBuiltin<"__builtin_lasx_xvsllwil_w_h">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsllwil_h_b : ClangBuiltin<"__builtin_lasx_xvsllwil_h_b">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsllwil_du_wu : ClangBuiltin<"__builtin_lasx_xvsllwil_du_wu">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsllwil_wu_hu : ClangBuiltin<"__builtin_lasx_xvsllwil_wu_hu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsllwil_hu_bu : ClangBuiltin<"__builtin_lasx_xvsllwil_hu_bu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvbitclri_b : ClangBuiltin<"__builtin_lasx_xvbitclri_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvbitclri_h : ClangBuiltin<"__builtin_lasx_xvbitclri_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvbitclri_w : ClangBuiltin<"__builtin_lasx_xvbitclri_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvbitclri_d : ClangBuiltin<"__builtin_lasx_xvbitclri_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvbitseti_b : ClangBuiltin<"__builtin_lasx_xvbitseti_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvbitseti_h : ClangBuiltin<"__builtin_lasx_xvbitseti_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvbitseti_w : ClangBuiltin<"__builtin_lasx_xvbitseti_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvbitseti_d : ClangBuiltin<"__builtin_lasx_xvbitseti_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvbitrevi_b : ClangBuiltin<"__builtin_lasx_xvbitrevi_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvbitrevi_h : ClangBuiltin<"__builtin_lasx_xvbitrevi_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvbitrevi_w : ClangBuiltin<"__builtin_lasx_xvbitrevi_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvbitrevi_d : ClangBuiltin<"__builtin_lasx_xvbitrevi_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvssrlrni_b_h : ClangBuiltin<"__builtin_lasx_xvssrlrni_b_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrlrni_h_w : ClangBuiltin<"__builtin_lasx_xvssrlrni_h_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrlrni_w_d : ClangBuiltin<"__builtin_lasx_xvssrlrni_w_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrlrni_d_q : ClangBuiltin<"__builtin_lasx_xvssrlrni_d_q">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsrani_b_h : ClangBuiltin<"__builtin_lasx_xvsrani_b_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrani_h_w : ClangBuiltin<"__builtin_lasx_xvsrani_h_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrani_w_d : ClangBuiltin<"__builtin_lasx_xvsrani_w_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrani_d_q : ClangBuiltin<"__builtin_lasx_xvsrani_d_q">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvextrins_b : ClangBuiltin<"__builtin_lasx_xvextrins_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvextrins_h : ClangBuiltin<"__builtin_lasx_xvextrins_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvextrins_w : ClangBuiltin<"__builtin_lasx_xvextrins_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvextrins_d : ClangBuiltin<"__builtin_lasx_xvextrins_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvbitseli_b : ClangBuiltin<"__builtin_lasx_xvbitseli_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvandi_b : ClangBuiltin<"__builtin_lasx_xvandi_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvori_b : ClangBuiltin<"__builtin_lasx_xvori_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvxori_b : ClangBuiltin<"__builtin_lasx_xvxori_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvnori_b : ClangBuiltin<"__builtin_lasx_xvnori_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvldi : ClangBuiltin<"__builtin_lasx_xvldi">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvrepli_b : ClangBuiltin<"__builtin_lasx_xvrepli_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvrepli_h : ClangBuiltin<"__builtin_lasx_xvrepli_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvrepli_w : ClangBuiltin<"__builtin_lasx_xvrepli_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvrepli_d : ClangBuiltin<"__builtin_lasx_xvrepli_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvpermi_w : ClangBuiltin<"__builtin_lasx_xvpermi_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsadd_b : ClangBuiltin<"__builtin_lasx_xvsadd_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvsadd_h : ClangBuiltin<"__builtin_lasx_xvsadd_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvsadd_w : ClangBuiltin<"__builtin_lasx_xvsadd_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvsadd_d : ClangBuiltin<"__builtin_lasx_xvsadd_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], ++ [Commutative, IntrNoMem]>; ++ ++def int_loongarch_lasx_xvssub_b : ClangBuiltin<"__builtin_lasx_xvssub_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssub_h : ClangBuiltin<"__builtin_lasx_xvssub_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssub_w : ClangBuiltin<"__builtin_lasx_xvssub_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssub_d : ClangBuiltin<"__builtin_lasx_xvssub_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsadd_bu : ClangBuiltin<"__builtin_lasx_xvsadd_bu">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvsadd_hu : ClangBuiltin<"__builtin_lasx_xvsadd_hu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvsadd_wu : ClangBuiltin<"__builtin_lasx_xvsadd_wu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvsadd_du : ClangBuiltin<"__builtin_lasx_xvsadd_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], ++ [Commutative, IntrNoMem]>; ++ ++def int_loongarch_lasx_xvssub_bu : ClangBuiltin<"__builtin_lasx_xvssub_bu">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssub_hu : ClangBuiltin<"__builtin_lasx_xvssub_hu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssub_wu : ClangBuiltin<"__builtin_lasx_xvssub_wu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssub_du : ClangBuiltin<"__builtin_lasx_xvssub_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvhaddw_h_b : ClangBuiltin<"__builtin_lasx_xvhaddw_h_b">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvhaddw_w_h : ClangBuiltin<"__builtin_lasx_xvhaddw_w_h">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvhaddw_d_w : ClangBuiltin<"__builtin_lasx_xvhaddw_d_w">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvhsubw_h_b : ClangBuiltin<"__builtin_lasx_xvhsubw_h_b">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvhsubw_w_h : ClangBuiltin<"__builtin_lasx_xvhsubw_w_h">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvhsubw_d_w : ClangBuiltin<"__builtin_lasx_xvhsubw_d_w">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvhaddw_hu_bu : ClangBuiltin<"__builtin_lasx_xvhaddw_hu_bu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvhaddw_wu_hu : ClangBuiltin<"__builtin_lasx_xvhaddw_wu_hu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvhaddw_du_wu : ClangBuiltin<"__builtin_lasx_xvhaddw_du_wu">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvhsubw_hu_bu : ClangBuiltin<"__builtin_lasx_xvhsubw_hu_bu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvhsubw_wu_hu : ClangBuiltin<"__builtin_lasx_xvhsubw_wu_hu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvhsubw_du_wu : ClangBuiltin<"__builtin_lasx_xvhsubw_du_wu">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvadda_b : ClangBuiltin<"__builtin_lasx_xvadda_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvadda_h : ClangBuiltin<"__builtin_lasx_xvadda_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvadda_w : ClangBuiltin<"__builtin_lasx_xvadda_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvadda_d : ClangBuiltin<"__builtin_lasx_xvadda_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], ++ [Commutative, IntrNoMem]>; ++ ++def int_loongarch_lasx_xvabsd_b : ClangBuiltin<"__builtin_lasx_xvabsd_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvabsd_h : ClangBuiltin<"__builtin_lasx_xvabsd_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvabsd_w : ClangBuiltin<"__builtin_lasx_xvabsd_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvabsd_d : ClangBuiltin<"__builtin_lasx_xvabsd_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvabsd_bu : ClangBuiltin<"__builtin_lasx_xvabsd_bu">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvabsd_hu : ClangBuiltin<"__builtin_lasx_xvabsd_hu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvabsd_wu : ClangBuiltin<"__builtin_lasx_xvabsd_wu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvabsd_du : ClangBuiltin<"__builtin_lasx_xvabsd_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvavg_b : ClangBuiltin<"__builtin_lasx_xvavg_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvavg_h : ClangBuiltin<"__builtin_lasx_xvavg_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvavg_w : ClangBuiltin<"__builtin_lasx_xvavg_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvavg_d : ClangBuiltin<"__builtin_lasx_xvavg_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], ++ [Commutative, IntrNoMem]>; ++ ++def int_loongarch_lasx_xvavg_bu : ClangBuiltin<"__builtin_lasx_xvavg_bu">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvavg_hu : ClangBuiltin<"__builtin_lasx_xvavg_hu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvavg_wu : ClangBuiltin<"__builtin_lasx_xvavg_wu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvavg_du : ClangBuiltin<"__builtin_lasx_xvavg_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], ++ [Commutative, IntrNoMem]>; ++ ++def int_loongarch_lasx_xvavgr_b : ClangBuiltin<"__builtin_lasx_xvavgr_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvavgr_h : ClangBuiltin<"__builtin_lasx_xvavgr_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvavgr_w : ClangBuiltin<"__builtin_lasx_xvavgr_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvavgr_d : ClangBuiltin<"__builtin_lasx_xvavgr_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], ++ [Commutative, IntrNoMem]>; ++ ++def int_loongarch_lasx_xvavgr_bu : ClangBuiltin<"__builtin_lasx_xvavgr_bu">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvavgr_hu : ClangBuiltin<"__builtin_lasx_xvavgr_hu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvavgr_wu : ClangBuiltin<"__builtin_lasx_xvavgr_wu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvavgr_du : ClangBuiltin<"__builtin_lasx_xvavgr_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], ++ [Commutative, IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsrlr_b : ClangBuiltin<"__builtin_lasx_xvsrlr_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrlr_h : ClangBuiltin<"__builtin_lasx_xvsrlr_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrlr_w : ClangBuiltin<"__builtin_lasx_xvsrlr_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrlr_d : ClangBuiltin<"__builtin_lasx_xvsrlr_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsrar_b : ClangBuiltin<"__builtin_lasx_xvsrar_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrar_h : ClangBuiltin<"__builtin_lasx_xvsrar_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrar_w : ClangBuiltin<"__builtin_lasx_xvsrar_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrar_d : ClangBuiltin<"__builtin_lasx_xvsrar_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfmax_s : ClangBuiltin<"__builtin_lasx_xvfmax_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfmax_d : ClangBuiltin<"__builtin_lasx_xvfmax_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfmin_s : ClangBuiltin<"__builtin_lasx_xvfmin_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfmin_d : ClangBuiltin<"__builtin_lasx_xvfmin_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfmaxa_s : ClangBuiltin<"__builtin_lasx_xvfmaxa_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfmaxa_d : ClangBuiltin<"__builtin_lasx_xvfmaxa_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfmina_s : ClangBuiltin<"__builtin_lasx_xvfmina_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfmina_d : ClangBuiltin<"__builtin_lasx_xvfmina_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfclass_s : ClangBuiltin<"__builtin_lasx_xvfclass_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfclass_d : ClangBuiltin<"__builtin_lasx_xvfclass_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfrecip_s : ClangBuiltin<"__builtin_lasx_xvfrecip_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfrecip_d : ClangBuiltin<"__builtin_lasx_xvfrecip_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfrecipe_s : ClangBuiltin<"__builtin_lasx_xvfrecipe_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfrecipe_d : ClangBuiltin<"__builtin_lasx_xvfrecipe_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfrsqrt_s : ClangBuiltin<"__builtin_lasx_xvfrsqrt_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfrsqrt_d : ClangBuiltin<"__builtin_lasx_xvfrsqrt_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfrsqrte_s : ClangBuiltin<"__builtin_lasx_xvfrsqrte_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfrsqrte_d : ClangBuiltin<"__builtin_lasx_xvfrsqrte_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcvtl_s_h : ClangBuiltin<"__builtin_lasx_xvfcvtl_s_h">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcvtl_d_s : ClangBuiltin<"__builtin_lasx_xvfcvtl_d_s">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfcvth_s_h : ClangBuiltin<"__builtin_lasx_xvfcvth_s_h">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfcvth_d_s : ClangBuiltin<"__builtin_lasx_xvfcvth_d_s">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvftint_w_s : ClangBuiltin<"__builtin_lasx_xvftint_w_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvftint_l_d : ClangBuiltin<"__builtin_lasx_xvftint_l_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvftint_wu_s : ClangBuiltin<"__builtin_lasx_xvftint_wu_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvftint_lu_d : ClangBuiltin<"__builtin_lasx_xvftint_lu_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsrlri_b : ClangBuiltin<"__builtin_lasx_xvsrlri_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrlri_h : ClangBuiltin<"__builtin_lasx_xvsrlri_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrlri_w : ClangBuiltin<"__builtin_lasx_xvsrlri_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrlri_d : ClangBuiltin<"__builtin_lasx_xvsrlri_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsrari_b : ClangBuiltin<"__builtin_lasx_xvsrari_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrari_h : ClangBuiltin<"__builtin_lasx_xvsrari_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrari_w : ClangBuiltin<"__builtin_lasx_xvsrari_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrari_d : ClangBuiltin<"__builtin_lasx_xvsrari_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsat_b : ClangBuiltin<"__builtin_lasx_xvsat_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsat_h : ClangBuiltin<"__builtin_lasx_xvsat_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsat_w : ClangBuiltin<"__builtin_lasx_xvsat_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsat_d : ClangBuiltin<"__builtin_lasx_xvsat_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsat_bu : ClangBuiltin<"__builtin_lasx_xvsat_bu">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsat_hu : ClangBuiltin<"__builtin_lasx_xvsat_hu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsat_wu : ClangBuiltin<"__builtin_lasx_xvsat_wu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsat_du : ClangBuiltin<"__builtin_lasx_xvsat_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsrlni_b_h : ClangBuiltin<"__builtin_lasx_xvsrlni_b_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrlni_h_w : ClangBuiltin<"__builtin_lasx_xvsrlni_h_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrlni_w_d : ClangBuiltin<"__builtin_lasx_xvsrlni_w_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrlni_d_q : ClangBuiltin<"__builtin_lasx_xvsrlni_d_q">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvssrlni_b_h : ClangBuiltin<"__builtin_lasx_xvssrlni_b_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrlni_h_w : ClangBuiltin<"__builtin_lasx_xvssrlni_h_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrlni_w_d : ClangBuiltin<"__builtin_lasx_xvssrlni_w_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrlni_d_q : ClangBuiltin<"__builtin_lasx_xvssrlni_d_q">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvssrlrni_bu_h : ClangBuiltin<"__builtin_lasx_xvssrlrni_bu_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrlrni_hu_w : ClangBuiltin<"__builtin_lasx_xvssrlrni_hu_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrlrni_wu_d : ClangBuiltin<"__builtin_lasx_xvssrlrni_wu_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrlrni_du_q : ClangBuiltin<"__builtin_lasx_xvssrlrni_du_q">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsrarni_b_h : ClangBuiltin<"__builtin_lasx_xvsrarni_b_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrarni_h_w : ClangBuiltin<"__builtin_lasx_xvsrarni_h_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrarni_w_d : ClangBuiltin<"__builtin_lasx_xvsrarni_w_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrarni_d_q : ClangBuiltin<"__builtin_lasx_xvsrarni_d_q">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvssrani_b_h : ClangBuiltin<"__builtin_lasx_xvssrani_b_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrani_h_w : ClangBuiltin<"__builtin_lasx_xvssrani_h_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrani_w_d : ClangBuiltin<"__builtin_lasx_xvssrani_w_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrani_d_q : ClangBuiltin<"__builtin_lasx_xvssrani_d_q">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvssrani_bu_h : ClangBuiltin<"__builtin_lasx_xvssrani_bu_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrani_hu_w : ClangBuiltin<"__builtin_lasx_xvssrani_hu_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrani_wu_d : ClangBuiltin<"__builtin_lasx_xvssrani_wu_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrani_du_q : ClangBuiltin<"__builtin_lasx_xvssrani_du_q">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvssrarni_b_h : ClangBuiltin<"__builtin_lasx_xvssrarni_b_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrarni_h_w : ClangBuiltin<"__builtin_lasx_xvssrarni_h_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrarni_w_d : ClangBuiltin<"__builtin_lasx_xvssrarni_w_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrarni_d_q : ClangBuiltin<"__builtin_lasx_xvssrarni_d_q">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvssrarni_bu_h : ClangBuiltin<"__builtin_lasx_xvssrarni_bu_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrarni_hu_w : ClangBuiltin<"__builtin_lasx_xvssrarni_hu_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrarni_wu_d : ClangBuiltin<"__builtin_lasx_xvssrarni_wu_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrarni_du_q : ClangBuiltin<"__builtin_lasx_xvssrarni_du_q">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvssrlni_bu_h : ClangBuiltin<"__builtin_lasx_xvssrlni_bu_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrlni_hu_w : ClangBuiltin<"__builtin_lasx_xvssrlni_hu_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrlni_wu_d : ClangBuiltin<"__builtin_lasx_xvssrlni_wu_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvssrlni_du_q : ClangBuiltin<"__builtin_lasx_xvssrlni_du_q">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvseq_b : ClangBuiltin<"__builtin_lasx_xvseq_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvseq_h : ClangBuiltin<"__builtin_lasx_xvseq_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvseq_w : ClangBuiltin<"__builtin_lasx_xvseq_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvseq_d : ClangBuiltin<"__builtin_lasx_xvseq_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsle_b : ClangBuiltin<"__builtin_lasx_xvsle_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsle_h : ClangBuiltin<"__builtin_lasx_xvsle_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsle_w : ClangBuiltin<"__builtin_lasx_xvsle_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsle_d : ClangBuiltin<"__builtin_lasx_xvsle_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsle_bu : ClangBuiltin<"__builtin_lasx_xvsle_bu">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsle_hu : ClangBuiltin<"__builtin_lasx_xvsle_hu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsle_wu : ClangBuiltin<"__builtin_lasx_xvsle_wu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsle_du : ClangBuiltin<"__builtin_lasx_xvsle_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvslt_b : ClangBuiltin<"__builtin_lasx_xvslt_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvslt_h : ClangBuiltin<"__builtin_lasx_xvslt_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvslt_w : ClangBuiltin<"__builtin_lasx_xvslt_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvslt_d : ClangBuiltin<"__builtin_lasx_xvslt_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvslt_bu : ClangBuiltin<"__builtin_lasx_xvslt_bu">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvslt_hu : ClangBuiltin<"__builtin_lasx_xvslt_hu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvslt_wu : ClangBuiltin<"__builtin_lasx_xvslt_wu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvslt_du : ClangBuiltin<"__builtin_lasx_xvslt_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvadd_b : ClangBuiltin<"__builtin_lasx_xvadd_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvadd_h : ClangBuiltin<"__builtin_lasx_xvadd_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvadd_w : ClangBuiltin<"__builtin_lasx_xvadd_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvadd_d : ClangBuiltin<"__builtin_lasx_xvadd_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], ++ [Commutative, IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsub_b : ClangBuiltin<"__builtin_lasx_xvsub_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsub_h : ClangBuiltin<"__builtin_lasx_xvsub_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsub_w : ClangBuiltin<"__builtin_lasx_xvsub_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsub_d : ClangBuiltin<"__builtin_lasx_xvsub_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmax_b : ClangBuiltin<"__builtin_lasx_xvmax_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmax_h : ClangBuiltin<"__builtin_lasx_xvmax_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmax_w : ClangBuiltin<"__builtin_lasx_xvmax_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmax_d : ClangBuiltin<"__builtin_lasx_xvmax_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmin_b : ClangBuiltin<"__builtin_lasx_xvmin_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmin_h : ClangBuiltin<"__builtin_lasx_xvmin_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmin_w : ClangBuiltin<"__builtin_lasx_xvmin_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmin_d : ClangBuiltin<"__builtin_lasx_xvmin_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmax_bu : ClangBuiltin<"__builtin_lasx_xvmax_bu">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmax_hu : ClangBuiltin<"__builtin_lasx_xvmax_hu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmax_wu : ClangBuiltin<"__builtin_lasx_xvmax_wu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmax_du : ClangBuiltin<"__builtin_lasx_xvmax_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmin_bu : ClangBuiltin<"__builtin_lasx_xvmin_bu">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmin_hu : ClangBuiltin<"__builtin_lasx_xvmin_hu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmin_wu : ClangBuiltin<"__builtin_lasx_xvmin_wu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmin_du : ClangBuiltin<"__builtin_lasx_xvmin_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmul_b : ClangBuiltin<"__builtin_lasx_xvmul_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmul_h : ClangBuiltin<"__builtin_lasx_xvmul_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmul_w : ClangBuiltin<"__builtin_lasx_xvmul_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmul_d : ClangBuiltin<"__builtin_lasx_xvmul_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmadd_b : ClangBuiltin<"__builtin_lasx_xvmadd_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_v32i8_ty], ++ [IntrNoMem]>; ++def int_loongarch_lasx_xvmadd_h : ClangBuiltin<"__builtin_lasx_xvmadd_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_v16i16_ty], ++ [IntrNoMem]>; ++def int_loongarch_lasx_xvmadd_w : ClangBuiltin<"__builtin_lasx_xvmadd_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_v8i32_ty], ++ [IntrNoMem]>; ++def int_loongarch_lasx_xvmadd_d : ClangBuiltin<"__builtin_lasx_xvmadd_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty], ++ [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmsub_b : ClangBuiltin<"__builtin_lasx_xvmsub_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_v32i8_ty], ++ [IntrNoMem]>; ++def int_loongarch_lasx_xvmsub_h : ClangBuiltin<"__builtin_lasx_xvmsub_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_v16i16_ty], ++ [IntrNoMem]>; ++def int_loongarch_lasx_xvmsub_w : ClangBuiltin<"__builtin_lasx_xvmsub_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_v8i32_ty], ++ [IntrNoMem]>; ++def int_loongarch_lasx_xvmsub_d : ClangBuiltin<"__builtin_lasx_xvmsub_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty], ++ [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvdiv_b : ClangBuiltin<"__builtin_lasx_xvdiv_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvdiv_h : ClangBuiltin<"__builtin_lasx_xvdiv_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvdiv_w : ClangBuiltin<"__builtin_lasx_xvdiv_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvdiv_d : ClangBuiltin<"__builtin_lasx_xvdiv_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmod_b : ClangBuiltin<"__builtin_lasx_xvmod_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmod_h : ClangBuiltin<"__builtin_lasx_xvmod_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmod_w : ClangBuiltin<"__builtin_lasx_xvmod_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmod_d : ClangBuiltin<"__builtin_lasx_xvmod_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvdiv_bu : ClangBuiltin<"__builtin_lasx_xvdiv_bu">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvdiv_hu : ClangBuiltin<"__builtin_lasx_xvdiv_hu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvdiv_wu : ClangBuiltin<"__builtin_lasx_xvdiv_wu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvdiv_du : ClangBuiltin<"__builtin_lasx_xvdiv_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsll_b : ClangBuiltin<"__builtin_lasx_xvsll_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsll_h : ClangBuiltin<"__builtin_lasx_xvsll_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsll_w : ClangBuiltin<"__builtin_lasx_xvsll_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsll_d : ClangBuiltin<"__builtin_lasx_xvsll_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsrl_b : ClangBuiltin<"__builtin_lasx_xvsrl_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrl_h : ClangBuiltin<"__builtin_lasx_xvsrl_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrl_w : ClangBuiltin<"__builtin_lasx_xvsrl_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrl_d : ClangBuiltin<"__builtin_lasx_xvsrl_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvbitclr_b : ClangBuiltin<"__builtin_lasx_xvbitclr_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvbitclr_h : ClangBuiltin<"__builtin_lasx_xvbitclr_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvbitclr_w : ClangBuiltin<"__builtin_lasx_xvbitclr_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvbitclr_d : ClangBuiltin<"__builtin_lasx_xvbitclr_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvbitset_b : ClangBuiltin<"__builtin_lasx_xvbitset_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvbitset_h : ClangBuiltin<"__builtin_lasx_xvbitset_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvbitset_w : ClangBuiltin<"__builtin_lasx_xvbitset_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvbitset_d : ClangBuiltin<"__builtin_lasx_xvbitset_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvpackev_b : ClangBuiltin<"__builtin_lasx_xvpackev_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvpackev_h : ClangBuiltin<"__builtin_lasx_xvpackev_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvpackev_w : ClangBuiltin<"__builtin_lasx_xvpackev_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvpackev_d : ClangBuiltin<"__builtin_lasx_xvpackev_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvpackod_b : ClangBuiltin<"__builtin_lasx_xvpackod_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvpackod_h : ClangBuiltin<"__builtin_lasx_xvpackod_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvpackod_w : ClangBuiltin<"__builtin_lasx_xvpackod_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvpackod_d : ClangBuiltin<"__builtin_lasx_xvpackod_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvilvl_b : ClangBuiltin<"__builtin_lasx_xvilvl_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvilvl_h : ClangBuiltin<"__builtin_lasx_xvilvl_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvilvl_w : ClangBuiltin<"__builtin_lasx_xvilvl_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvilvl_d : ClangBuiltin<"__builtin_lasx_xvilvl_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvilvh_b : ClangBuiltin<"__builtin_lasx_xvilvh_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvilvh_h : ClangBuiltin<"__builtin_lasx_xvilvh_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvilvh_w : ClangBuiltin<"__builtin_lasx_xvilvh_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvilvh_d : ClangBuiltin<"__builtin_lasx_xvilvh_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvpickev_b : ClangBuiltin<"__builtin_lasx_xvpickev_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvpickev_h : ClangBuiltin<"__builtin_lasx_xvpickev_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvpickev_w : ClangBuiltin<"__builtin_lasx_xvpickev_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvpickev_d : ClangBuiltin<"__builtin_lasx_xvpickev_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvand_v : ClangBuiltin<"__builtin_lasx_xvand_v">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvor_v : ClangBuiltin<"__builtin_lasx_xvor_v">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvbitrev_b : ClangBuiltin<"__builtin_lasx_xvbitrev_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvbitrev_h : ClangBuiltin<"__builtin_lasx_xvbitrev_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvbitrev_w : ClangBuiltin<"__builtin_lasx_xvbitrev_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvbitrev_d : ClangBuiltin<"__builtin_lasx_xvbitrev_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmod_bu : ClangBuiltin<"__builtin_lasx_xvmod_bu">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmod_hu : ClangBuiltin<"__builtin_lasx_xvmod_hu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmod_wu : ClangBuiltin<"__builtin_lasx_xvmod_wu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmod_du : ClangBuiltin<"__builtin_lasx_xvmod_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvpickod_b : ClangBuiltin<"__builtin_lasx_xvpickod_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvpickod_h : ClangBuiltin<"__builtin_lasx_xvpickod_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvpickod_w : ClangBuiltin<"__builtin_lasx_xvpickod_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvpickod_d : ClangBuiltin<"__builtin_lasx_xvpickod_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvreplve_b : ClangBuiltin<"__builtin_lasx_xvreplve_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvreplve_h : ClangBuiltin<"__builtin_lasx_xvreplve_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvreplve_w : ClangBuiltin<"__builtin_lasx_xvreplve_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvreplve_d : ClangBuiltin<"__builtin_lasx_xvreplve_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsra_b : ClangBuiltin<"__builtin_lasx_xvsra_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsra_h : ClangBuiltin<"__builtin_lasx_xvsra_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsra_w : ClangBuiltin<"__builtin_lasx_xvsra_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsra_d : ClangBuiltin<"__builtin_lasx_xvsra_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvxor_v : ClangBuiltin<"__builtin_lasx_xvxor_v">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvnor_v : ClangBuiltin<"__builtin_lasx_xvnor_v">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfadd_s : ClangBuiltin<"__builtin_lasx_xvfadd_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfadd_d : ClangBuiltin<"__builtin_lasx_xvfadd_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfsub_s : ClangBuiltin<"__builtin_lasx_xvfsub_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfsub_d : ClangBuiltin<"__builtin_lasx_xvfsub_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfmul_s : ClangBuiltin<"__builtin_lasx_xvfmul_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfmul_d : ClangBuiltin<"__builtin_lasx_xvfmul_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvshuf_h : ClangBuiltin<"__builtin_lasx_xvshuf_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_v16i16_ty], ++ [IntrNoMem]>; ++def int_loongarch_lasx_xvshuf_w : ClangBuiltin<"__builtin_lasx_xvshuf_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_v8i32_ty], ++ [IntrNoMem]>; ++def int_loongarch_lasx_xvshuf_d : ClangBuiltin<"__builtin_lasx_xvshuf_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty], ++ [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvseqi_b : ClangBuiltin<"__builtin_lasx_xvseqi_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvseqi_h : ClangBuiltin<"__builtin_lasx_xvseqi_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvseqi_w : ClangBuiltin<"__builtin_lasx_xvseqi_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvseqi_d : ClangBuiltin<"__builtin_lasx_xvseqi_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvslei_b : ClangBuiltin<"__builtin_lasx_xvslei_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvslei_h : ClangBuiltin<"__builtin_lasx_xvslei_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvslei_w : ClangBuiltin<"__builtin_lasx_xvslei_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvslei_d : ClangBuiltin<"__builtin_lasx_xvslei_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvslei_bu : ClangBuiltin<"__builtin_lasx_xvslei_bu">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvslei_hu : ClangBuiltin<"__builtin_lasx_xvslei_hu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvslei_wu : ClangBuiltin<"__builtin_lasx_xvslei_wu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvslei_du : ClangBuiltin<"__builtin_lasx_xvslei_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvslti_b : ClangBuiltin<"__builtin_lasx_xvslti_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvslti_h : ClangBuiltin<"__builtin_lasx_xvslti_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvslti_w : ClangBuiltin<"__builtin_lasx_xvslti_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvslti_d : ClangBuiltin<"__builtin_lasx_xvslti_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvslti_bu : ClangBuiltin<"__builtin_lasx_xvslti_bu">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvslti_hu : ClangBuiltin<"__builtin_lasx_xvslti_hu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvslti_wu : ClangBuiltin<"__builtin_lasx_xvslti_wu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvslti_du : ClangBuiltin<"__builtin_lasx_xvslti_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvaddi_bu : ClangBuiltin<"__builtin_lasx_xvaddi_bu">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvaddi_hu : ClangBuiltin<"__builtin_lasx_xvaddi_hu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvaddi_wu : ClangBuiltin<"__builtin_lasx_xvaddi_wu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], ++ [Commutative, IntrNoMem]>; ++def int_loongarch_lasx_xvaddi_du : ClangBuiltin<"__builtin_lasx_xvaddi_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], ++ [Commutative, IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsubi_bu : ClangBuiltin<"__builtin_lasx_xvsubi_bu">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsubi_hu : ClangBuiltin<"__builtin_lasx_xvsubi_hu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsubi_wu : ClangBuiltin<"__builtin_lasx_xvsubi_wu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsubi_du : ClangBuiltin<"__builtin_lasx_xvsubi_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmaxi_b : ClangBuiltin<"__builtin_lasx_xvmaxi_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaxi_h : ClangBuiltin<"__builtin_lasx_xvmaxi_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaxi_w : ClangBuiltin<"__builtin_lasx_xvmaxi_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaxi_d : ClangBuiltin<"__builtin_lasx_xvmaxi_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmini_b : ClangBuiltin<"__builtin_lasx_xvmini_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmini_h : ClangBuiltin<"__builtin_lasx_xvmini_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmini_w : ClangBuiltin<"__builtin_lasx_xvmini_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmini_d : ClangBuiltin<"__builtin_lasx_xvmini_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmaxi_bu : ClangBuiltin<"__builtin_lasx_xvmaxi_bu">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaxi_hu : ClangBuiltin<"__builtin_lasx_xvmaxi_hu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaxi_wu : ClangBuiltin<"__builtin_lasx_xvmaxi_wu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmaxi_du : ClangBuiltin<"__builtin_lasx_xvmaxi_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvmini_bu : ClangBuiltin<"__builtin_lasx_xvmini_bu">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmini_hu : ClangBuiltin<"__builtin_lasx_xvmini_hu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmini_wu : ClangBuiltin<"__builtin_lasx_xvmini_wu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvmini_du : ClangBuiltin<"__builtin_lasx_xvmini_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvclz_b : ClangBuiltin<"__builtin_lasx_xvclz_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvclz_h : ClangBuiltin<"__builtin_lasx_xvclz_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvclz_w : ClangBuiltin<"__builtin_lasx_xvclz_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvclz_d : ClangBuiltin<"__builtin_lasx_xvclz_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvpcnt_b : ClangBuiltin<"__builtin_lasx_xvpcnt_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvpcnt_h : ClangBuiltin<"__builtin_lasx_xvpcnt_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvpcnt_w : ClangBuiltin<"__builtin_lasx_xvpcnt_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvpcnt_d : ClangBuiltin<"__builtin_lasx_xvpcnt_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfsqrt_s : ClangBuiltin<"__builtin_lasx_xvfsqrt_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfsqrt_d : ClangBuiltin<"__builtin_lasx_xvfsqrt_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfrint_s : ClangBuiltin<"__builtin_lasx_xvfrint_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfrint_d : ClangBuiltin<"__builtin_lasx_xvfrint_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvffint_s_w : ClangBuiltin<"__builtin_lasx_xvffint_s_w">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvffint_d_l : ClangBuiltin<"__builtin_lasx_xvffint_d_l">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvffint_s_wu : ClangBuiltin<"__builtin_lasx_xvffint_s_wu">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvffint_d_lu : ClangBuiltin<"__builtin_lasx_xvffint_d_lu">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvftintrz_wu_s : ClangBuiltin<"__builtin_lasx_xvftintrz_wu_s">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvftintrz_lu_d : ClangBuiltin<"__builtin_lasx_xvftintrz_lu_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvreplgr2vr_b : ClangBuiltin<"__builtin_lasx_xvreplgr2vr_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvreplgr2vr_h : ClangBuiltin<"__builtin_lasx_xvreplgr2vr_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvreplgr2vr_w : ClangBuiltin<"__builtin_lasx_xvreplgr2vr_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvreplgr2vr_d : ClangBuiltin<"__builtin_lasx_xvreplgr2vr_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvinsgr2vr_w : ClangBuiltin<"__builtin_lasx_xvinsgr2vr_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty, llvm_i32_ty], ++ [IntrNoMem]>; ++def int_loongarch_lasx_xvinsgr2vr_d : ClangBuiltin<"__builtin_lasx_xvinsgr2vr_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i64_ty, llvm_i32_ty], ++ [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvfdiv_s : ClangBuiltin<"__builtin_lasx_xvfdiv_s">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvfdiv_d : ClangBuiltin<"__builtin_lasx_xvfdiv_d">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvslli_b : ClangBuiltin<"__builtin_lasx_xvslli_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvslli_h : ClangBuiltin<"__builtin_lasx_xvslli_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvslli_w : ClangBuiltin<"__builtin_lasx_xvslli_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvslli_d : ClangBuiltin<"__builtin_lasx_xvslli_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsrli_b : ClangBuiltin<"__builtin_lasx_xvsrli_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrli_h : ClangBuiltin<"__builtin_lasx_xvsrli_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrli_w : ClangBuiltin<"__builtin_lasx_xvsrli_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrli_d : ClangBuiltin<"__builtin_lasx_xvsrli_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsrai_b : ClangBuiltin<"__builtin_lasx_xvsrai_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrai_h : ClangBuiltin<"__builtin_lasx_xvsrai_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrai_w : ClangBuiltin<"__builtin_lasx_xvsrai_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrai_d : ClangBuiltin<"__builtin_lasx_xvsrai_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvshuf4i_b : ClangBuiltin<"__builtin_lasx_xvshuf4i_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvshuf4i_h : ClangBuiltin<"__builtin_lasx_xvshuf4i_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvshuf4i_w : ClangBuiltin<"__builtin_lasx_xvshuf4i_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvshuf4i_d : ClangBuiltin<"__builtin_lasx_xvshuf4i_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvrotr_b : ClangBuiltin<"__builtin_lasx_xvrotr_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvrotr_h : ClangBuiltin<"__builtin_lasx_xvrotr_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvrotr_w : ClangBuiltin<"__builtin_lasx_xvrotr_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvrotr_d : ClangBuiltin<"__builtin_lasx_xvrotr_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvrotri_b : ClangBuiltin<"__builtin_lasx_xvrotri_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvrotri_h : ClangBuiltin<"__builtin_lasx_xvrotri_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvrotri_w : ClangBuiltin<"__builtin_lasx_xvrotri_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvrotri_d : ClangBuiltin<"__builtin_lasx_xvrotri_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvld : ClangBuiltin<"__builtin_lasx_xvld">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_ptr_ty, llvm_i32_ty], ++ [IntrReadMem, IntrArgMemOnly]>; ++ ++def int_loongarch_lasx_xvst : ClangBuiltin<"__builtin_lasx_xvst">, ++ Intrinsic<[], [llvm_v32i8_ty, llvm_ptr_ty, llvm_i32_ty], ++ [IntrArgMemOnly]>; ++ ++def int_loongarch_lasx_xvrepl128vei_b : ClangBuiltin<"__builtin_lasx_xvrepl128vei_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvrepl128vei_h : ClangBuiltin<"__builtin_lasx_xvrepl128vei_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvrepl128vei_w : ClangBuiltin<"__builtin_lasx_xvrepl128vei_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvrepl128vei_d : ClangBuiltin<"__builtin_lasx_xvrepl128vei_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvinsve0_w : ClangBuiltin<"__builtin_lasx_xvinsve0_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvinsve0_d : ClangBuiltin<"__builtin_lasx_xvinsve0_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvpickve_w : ClangBuiltin<"__builtin_lasx_xvpickve_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvpickve_d : ClangBuiltin<"__builtin_lasx_xvpickve_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvpickve_w_f : ClangBuiltin<"__builtin_lasx_xvpickve_w_f">, ++ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvpickve_d_f : ClangBuiltin<"__builtin_lasx_xvpickve_d_f">, ++ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvreplve0_b : ClangBuiltin<"__builtin_lasx_xvreplve0_b">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvreplve0_h : ClangBuiltin<"__builtin_lasx_xvreplve0_h">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvreplve0_w : ClangBuiltin<"__builtin_lasx_xvreplve0_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvreplve0_d : ClangBuiltin<"__builtin_lasx_xvreplve0_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvreplve0_q : ClangBuiltin<"__builtin_lasx_xvreplve0_q">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_vext2xv_d_w : ClangBuiltin<"__builtin_lasx_vext2xv_d_w">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_vext2xv_w_h : ClangBuiltin<"__builtin_lasx_vext2xv_w_h">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_vext2xv_h_b : ClangBuiltin<"__builtin_lasx_vext2xv_h_b">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_vext2xv_d_h : ClangBuiltin<"__builtin_lasx_vext2xv_d_h">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_vext2xv_w_b : ClangBuiltin<"__builtin_lasx_vext2xv_w_b">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_vext2xv_d_b : ClangBuiltin<"__builtin_lasx_vext2xv_d_b">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v32i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_vext2xv_du_wu : ClangBuiltin<"__builtin_lasx_vext2xv_du_wu">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_vext2xv_wu_hu : ClangBuiltin<"__builtin_lasx_vext2xv_wu_hu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_vext2xv_hu_bu : ClangBuiltin<"__builtin_lasx_vext2xv_hu_bu">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_vext2xv_du_hu : ClangBuiltin<"__builtin_lasx_vext2xv_du_hu">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_vext2xv_wu_bu : ClangBuiltin<"__builtin_lasx_vext2xv_wu_bu">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_vext2xv_du_bu : ClangBuiltin<"__builtin_lasx_vext2xv_du_bu">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v32i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvpermi_q : ClangBuiltin<"__builtin_lasx_xvpermi_q">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvpermi_d : ClangBuiltin<"__builtin_lasx_xvpermi_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvperm_w : ClangBuiltin<"__builtin_lasx_xvperm_w">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvsrlrni_b_h : ClangBuiltin<"__builtin_lasx_xvsrlrni_b_h">, ++ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrlrni_h_w : ClangBuiltin<"__builtin_lasx_xvsrlrni_h_w">, ++ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrlrni_w_d : ClangBuiltin<"__builtin_lasx_xvsrlrni_w_d">, ++ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvsrlrni_d_q : ClangBuiltin<"__builtin_lasx_xvsrlrni_d_q">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xbz_v : ClangBuiltin<"__builtin_lasx_xbz_v">, ++ Intrinsic<[llvm_i32_ty], [llvm_v32i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xbnz_v : ClangBuiltin<"__builtin_lasx_xbnz_v">, ++ Intrinsic<[llvm_i32_ty], [llvm_v32i8_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xbz_b : ClangBuiltin<"__builtin_lasx_xbz_b">, ++ Intrinsic<[llvm_i32_ty], [llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xbz_h : ClangBuiltin<"__builtin_lasx_xbz_h">, ++ Intrinsic<[llvm_i32_ty], [llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xbz_w : ClangBuiltin<"__builtin_lasx_xbz_w">, ++ Intrinsic<[llvm_i32_ty], [llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xbz_d : ClangBuiltin<"__builtin_lasx_xbz_d">, ++ Intrinsic<[llvm_i32_ty], [llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xbnz_b : ClangBuiltin<"__builtin_lasx_xbnz_b">, ++ Intrinsic<[llvm_i32_ty], [llvm_v32i8_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xbnz_h : ClangBuiltin<"__builtin_lasx_xbnz_h">, ++ Intrinsic<[llvm_i32_ty], [llvm_v16i16_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xbnz_w : ClangBuiltin<"__builtin_lasx_xbnz_w">, ++ Intrinsic<[llvm_i32_ty], [llvm_v8i32_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xbnz_d : ClangBuiltin<"__builtin_lasx_xbnz_d">, ++ Intrinsic<[llvm_i32_ty], [llvm_v4i64_ty], [IntrNoMem]>; ++ ++def int_loongarch_lasx_xvextl_q_d : ClangBuiltin<"__builtin_lasx_xvextl_q_d">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty], [IntrNoMem]>; ++def int_loongarch_lasx_xvextl_qu_du : ClangBuiltin<"__builtin_lasx_xvextl_qu_du">, ++ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty], [IntrNoMem]>; + + //===----------------------------------------------------------------------===// + // LoongArch BASE + +-class BaseInt ret_types, list param_types, +- list intr_properties = []> +- : Intrinsic, +- ClangBuiltin; +- +-def int_loongarch_break : BaseInt<[], [llvm_i32_ty], [ImmArg>]>; +-def int_loongarch_cacop_d : BaseInt<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], +- [ImmArg>, ImmArg>]>; +-def int_loongarch_cacop_w : BaseInt<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], +- [ImmArg>, ImmArg>]>; +-def int_loongarch_dbar : BaseInt<[], [llvm_i32_ty], [ImmArg>]>; +- +-def int_loongarch_ibar : BaseInt<[], [llvm_i32_ty], [ImmArg>]>; +-def int_loongarch_movfcsr2gr : BaseInt<[llvm_i32_ty], [llvm_i32_ty], +- [ImmArg>]>; +-def int_loongarch_movgr2fcsr : BaseInt<[], [llvm_i32_ty, llvm_i32_ty], +- [ImmArg>]>; +-def int_loongarch_syscall : BaseInt<[], [llvm_i32_ty], [ImmArg>]>; +- +-def int_loongarch_crc_w_b_w : BaseInt<[llvm_i32_ty], +- [llvm_i32_ty, llvm_i32_ty]>; +-def int_loongarch_crc_w_h_w : BaseInt<[llvm_i32_ty], +- [llvm_i32_ty, llvm_i32_ty]>; +-def int_loongarch_crc_w_w_w : BaseInt<[llvm_i32_ty], +- [llvm_i32_ty, llvm_i32_ty]>; +-def int_loongarch_crc_w_d_w : BaseInt<[llvm_i32_ty], +- [llvm_i64_ty, llvm_i32_ty]>; +- +-def int_loongarch_crcc_w_b_w : BaseInt<[llvm_i32_ty], +- [llvm_i32_ty, llvm_i32_ty]>; +-def int_loongarch_crcc_w_h_w : BaseInt<[llvm_i32_ty], +- [llvm_i32_ty, llvm_i32_ty]>; +-def int_loongarch_crcc_w_w_w : BaseInt<[llvm_i32_ty], +- [llvm_i32_ty, llvm_i32_ty]>; +-def int_loongarch_crcc_w_d_w : BaseInt<[llvm_i32_ty], +- [llvm_i64_ty, llvm_i32_ty]>; +- +-def int_loongarch_csrrd_w : BaseInt<[llvm_i32_ty], [llvm_i32_ty], +- [ImmArg>]>; +-def int_loongarch_csrrd_d : BaseInt<[llvm_i64_ty], [llvm_i32_ty], +- [ImmArg>]>; +-def int_loongarch_csrwr_w : BaseInt<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], +- [ImmArg>]>; +-def int_loongarch_csrwr_d : BaseInt<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty], +- [ImmArg>]>; +-def int_loongarch_csrxchg_w : BaseInt<[llvm_i32_ty], +- [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], +- [ImmArg>]>; +-def int_loongarch_csrxchg_d : BaseInt<[llvm_i64_ty], +- [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty], +- [ImmArg>]>; +- +-def int_loongarch_iocsrrd_b : BaseInt<[llvm_i32_ty], [llvm_i32_ty]>; +-def int_loongarch_iocsrrd_h : BaseInt<[llvm_i32_ty], [llvm_i32_ty]>; +-def int_loongarch_iocsrrd_w : BaseInt<[llvm_i32_ty], [llvm_i32_ty]>; +-def int_loongarch_iocsrrd_d : BaseInt<[llvm_i64_ty], [llvm_i32_ty]>; +- +-def int_loongarch_iocsrwr_b : BaseInt<[], [llvm_i32_ty, llvm_i32_ty]>; +-def int_loongarch_iocsrwr_h : BaseInt<[], [llvm_i32_ty, llvm_i32_ty]>; +-def int_loongarch_iocsrwr_w : BaseInt<[], [llvm_i32_ty, llvm_i32_ty]>; +-def int_loongarch_iocsrwr_d : BaseInt<[], [llvm_i64_ty, llvm_i32_ty]>; +- +-def int_loongarch_cpucfg : BaseInt<[llvm_i32_ty], [llvm_i32_ty]>; +- +-def int_loongarch_asrtle_d : BaseInt<[], [llvm_i64_ty, llvm_i64_ty]>; +-def int_loongarch_asrtgt_d : BaseInt<[], [llvm_i64_ty, llvm_i64_ty]>; +- +-def int_loongarch_lddir_d : BaseInt<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], +- [ImmArg>]>; +-def int_loongarch_ldpte_d : BaseInt<[], [llvm_i64_ty, llvm_i64_ty], +- [ImmArg>]>; +- +-def int_loongarch_frecipe_s : BaseInt<[llvm_float_ty], [llvm_float_ty], +- [IntrNoMem]>; +-def int_loongarch_frecipe_d : BaseInt<[llvm_double_ty], [llvm_double_ty], +- [IntrNoMem]>; +-def int_loongarch_frsqrte_s : BaseInt<[llvm_float_ty], [llvm_float_ty], +- [IntrNoMem]>; +-def int_loongarch_frsqrte_d : BaseInt<[llvm_double_ty], [llvm_double_ty], +- [IntrNoMem]>; +-} // TargetPrefix = "loongarch" +- +-/// Vector intrinsic +- +-class VecInt ret_types, list param_types, +- list intr_properties = []> +- : Intrinsic, +- ClangBuiltin; ++def int_loongarch_cpucfg : ClangBuiltin<"__builtin_loongarch_cpucfg">, ++ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>; + +-//===----------------------------------------------------------------------===// +-// LSX +- +-let TargetPrefix = "loongarch" in { +- +-foreach inst = ["vadd_b", "vsub_b", +- "vsadd_b", "vsadd_bu", "vssub_b", "vssub_bu", +- "vavg_b", "vavg_bu", "vavgr_b", "vavgr_bu", +- "vabsd_b", "vabsd_bu", "vadda_b", +- "vmax_b", "vmax_bu", "vmin_b", "vmin_bu", +- "vmul_b", "vmuh_b", "vmuh_bu", +- "vdiv_b", "vdiv_bu", "vmod_b", "vmod_bu", "vsigncov_b", +- "vand_v", "vor_v", "vxor_v", "vnor_v", "vandn_v", "vorn_v", +- "vsll_b", "vsrl_b", "vsra_b", "vrotr_b", "vsrlr_b", "vsrar_b", +- "vbitclr_b", "vbitset_b", "vbitrev_b", +- "vseq_b", "vsle_b", "vsle_bu", "vslt_b", "vslt_bu", +- "vpackev_b", "vpackod_b", "vpickev_b", "vpickod_b", +- "vilvl_b", "vilvh_b"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v16i8_ty], +- [llvm_v16i8_ty, llvm_v16i8_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vadd_h", "vsub_h", +- "vsadd_h", "vsadd_hu", "vssub_h", "vssub_hu", +- "vavg_h", "vavg_hu", "vavgr_h", "vavgr_hu", +- "vabsd_h", "vabsd_hu", "vadda_h", +- "vmax_h", "vmax_hu", "vmin_h", "vmin_hu", +- "vmul_h", "vmuh_h", "vmuh_hu", +- "vdiv_h", "vdiv_hu", "vmod_h", "vmod_hu", "vsigncov_h", +- "vsll_h", "vsrl_h", "vsra_h", "vrotr_h", "vsrlr_h", "vsrar_h", +- "vbitclr_h", "vbitset_h", "vbitrev_h", +- "vseq_h", "vsle_h", "vsle_hu", "vslt_h", "vslt_hu", +- "vpackev_h", "vpackod_h", "vpickev_h", "vpickod_h", +- "vilvl_h", "vilvh_h"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v8i16_ty], +- [llvm_v8i16_ty, llvm_v8i16_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vadd_w", "vsub_w", +- "vsadd_w", "vsadd_wu", "vssub_w", "vssub_wu", +- "vavg_w", "vavg_wu", "vavgr_w", "vavgr_wu", +- "vabsd_w", "vabsd_wu", "vadda_w", +- "vmax_w", "vmax_wu", "vmin_w", "vmin_wu", +- "vmul_w", "vmuh_w", "vmuh_wu", +- "vdiv_w", "vdiv_wu", "vmod_w", "vmod_wu", "vsigncov_w", +- "vsll_w", "vsrl_w", "vsra_w", "vrotr_w", "vsrlr_w", "vsrar_w", +- "vbitclr_w", "vbitset_w", "vbitrev_w", +- "vseq_w", "vsle_w", "vsle_wu", "vslt_w", "vslt_wu", +- "vpackev_w", "vpackod_w", "vpickev_w", "vpickod_w", +- "vilvl_w", "vilvh_w"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v4i32_ty], +- [llvm_v4i32_ty, llvm_v4i32_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vadd_d", "vadd_q", "vsub_d", "vsub_q", +- "vsadd_d", "vsadd_du", "vssub_d", "vssub_du", +- "vhaddw_q_d", "vhaddw_qu_du", "vhsubw_q_d", "vhsubw_qu_du", +- "vaddwev_q_d", "vaddwod_q_d", "vsubwev_q_d", "vsubwod_q_d", +- "vaddwev_q_du", "vaddwod_q_du", "vsubwev_q_du", "vsubwod_q_du", +- "vaddwev_q_du_d", "vaddwod_q_du_d", +- "vavg_d", "vavg_du", "vavgr_d", "vavgr_du", +- "vabsd_d", "vabsd_du", "vadda_d", +- "vmax_d", "vmax_du", "vmin_d", "vmin_du", +- "vmul_d", "vmuh_d", "vmuh_du", +- "vmulwev_q_d", "vmulwod_q_d", "vmulwev_q_du", "vmulwod_q_du", +- "vmulwev_q_du_d", "vmulwod_q_du_d", +- "vdiv_d", "vdiv_du", "vmod_d", "vmod_du", "vsigncov_d", +- "vsll_d", "vsrl_d", "vsra_d", "vrotr_d", "vsrlr_d", "vsrar_d", +- "vbitclr_d", "vbitset_d", "vbitrev_d", +- "vseq_d", "vsle_d", "vsle_du", "vslt_d", "vslt_du", +- "vpackev_d", "vpackod_d", "vpickev_d", "vpickod_d", +- "vilvl_d", "vilvh_d"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v2i64_ty], +- [llvm_v2i64_ty, llvm_v2i64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vaddi_bu", "vsubi_bu", +- "vmaxi_b", "vmaxi_bu", "vmini_b", "vmini_bu", +- "vsat_b", "vsat_bu", +- "vandi_b", "vori_b", "vxori_b", "vnori_b", +- "vslli_b", "vsrli_b", "vsrai_b", "vrotri_b", +- "vsrlri_b", "vsrari_b", +- "vbitclri_b", "vbitseti_b", "vbitrevi_b", +- "vseqi_b", "vslei_b", "vslei_bu", "vslti_b", "vslti_bu", +- "vreplvei_b", "vbsll_v", "vbsrl_v", "vshuf4i_b"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v16i8_ty], +- [llvm_v16i8_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-foreach inst = ["vaddi_hu", "vsubi_hu", +- "vmaxi_h", "vmaxi_hu", "vmini_h", "vmini_hu", +- "vsat_h", "vsat_hu", +- "vslli_h", "vsrli_h", "vsrai_h", "vrotri_h", +- "vsrlri_h", "vsrari_h", +- "vbitclri_h", "vbitseti_h", "vbitrevi_h", +- "vseqi_h", "vslei_h", "vslei_hu", "vslti_h", "vslti_hu", +- "vreplvei_h", "vshuf4i_h"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v8i16_ty], +- [llvm_v8i16_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-foreach inst = ["vaddi_wu", "vsubi_wu", +- "vmaxi_w", "vmaxi_wu", "vmini_w", "vmini_wu", +- "vsat_w", "vsat_wu", +- "vslli_w", "vsrli_w", "vsrai_w", "vrotri_w", +- "vsrlri_w", "vsrari_w", +- "vbitclri_w", "vbitseti_w", "vbitrevi_w", +- "vseqi_w", "vslei_w", "vslei_wu", "vslti_w", "vslti_wu", +- "vreplvei_w", "vshuf4i_w"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v4i32_ty], +- [llvm_v4i32_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-foreach inst = ["vaddi_du", "vsubi_du", +- "vmaxi_d", "vmaxi_du", "vmini_d", "vmini_du", +- "vsat_d", "vsat_du", +- "vslli_d", "vsrli_d", "vsrai_d", "vrotri_d", +- "vsrlri_d", "vsrari_d", +- "vbitclri_d", "vbitseti_d", "vbitrevi_d", +- "vseqi_d", "vslei_d", "vslei_du", "vslti_d", "vslti_du", +- "vreplvei_d"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v2i64_ty], +- [llvm_v2i64_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +- +-foreach inst = ["vhaddw_h_b", "vhaddw_hu_bu", "vhsubw_h_b", "vhsubw_hu_bu", +- "vaddwev_h_b", "vaddwod_h_b", "vsubwev_h_b", "vsubwod_h_b", +- "vaddwev_h_bu", "vaddwod_h_bu", "vsubwev_h_bu", "vsubwod_h_bu", +- "vaddwev_h_bu_b", "vaddwod_h_bu_b", +- "vmulwev_h_b", "vmulwod_h_b", "vmulwev_h_bu", "vmulwod_h_bu", +- "vmulwev_h_bu_b", "vmulwod_h_bu_b"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v8i16_ty], +- [llvm_v16i8_ty, llvm_v16i8_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vhaddw_w_h", "vhaddw_wu_hu", "vhsubw_w_h", "vhsubw_wu_hu", +- "vaddwev_w_h", "vaddwod_w_h", "vsubwev_w_h", "vsubwod_w_h", +- "vaddwev_w_hu", "vaddwod_w_hu", "vsubwev_w_hu", "vsubwod_w_hu", +- "vaddwev_w_hu_h", "vaddwod_w_hu_h", +- "vmulwev_w_h", "vmulwod_w_h", "vmulwev_w_hu", "vmulwod_w_hu", +- "vmulwev_w_hu_h", "vmulwod_w_hu_h"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v4i32_ty], +- [llvm_v8i16_ty, llvm_v8i16_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vhaddw_d_w", "vhaddw_du_wu", "vhsubw_d_w", "vhsubw_du_wu", +- "vaddwev_d_w", "vaddwod_d_w", "vsubwev_d_w", "vsubwod_d_w", +- "vaddwev_d_wu", "vaddwod_d_wu", "vsubwev_d_wu", "vsubwod_d_wu", +- "vaddwev_d_wu_w", "vaddwod_d_wu_w", +- "vmulwev_d_w", "vmulwod_d_w", "vmulwev_d_wu", "vmulwod_d_wu", +- "vmulwev_d_wu_w", "vmulwod_d_wu_w"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v2i64_ty], +- [llvm_v4i32_ty, llvm_v4i32_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vsrln_b_h", "vsran_b_h", "vsrlrn_b_h", "vsrarn_b_h", +- "vssrln_b_h", "vssran_b_h", "vssrln_bu_h", "vssran_bu_h", +- "vssrlrn_b_h", "vssrarn_b_h", "vssrlrn_bu_h", "vssrarn_bu_h"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v16i8_ty], +- [llvm_v8i16_ty, llvm_v8i16_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vsrln_h_w", "vsran_h_w", "vsrlrn_h_w", "vsrarn_h_w", +- "vssrln_h_w", "vssran_h_w", "vssrln_hu_w", "vssran_hu_w", +- "vssrlrn_h_w", "vssrarn_h_w", "vssrlrn_hu_w", "vssrarn_hu_w"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v8i16_ty], +- [llvm_v4i32_ty, llvm_v4i32_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vsrln_w_d", "vsran_w_d", "vsrlrn_w_d", "vsrarn_w_d", +- "vssrln_w_d", "vssran_w_d", "vssrln_wu_d", "vssran_wu_d", +- "vssrlrn_w_d", "vssrarn_w_d", "vssrlrn_wu_d", "vssrarn_wu_d"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v4i32_ty], +- [llvm_v2i64_ty, llvm_v2i64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vmadd_b", "vmsub_b", "vfrstp_b", "vbitsel_v", "vshuf_b"] in +- def int_loongarch_lsx_#inst +- : VecInt<[llvm_v16i8_ty], +- [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty], +- [IntrNoMem]>; +-foreach inst = ["vmadd_h", "vmsub_h", "vfrstp_h", "vshuf_h"] in +- def int_loongarch_lsx_#inst +- : VecInt<[llvm_v8i16_ty], +- [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty], +- [IntrNoMem]>; +-foreach inst = ["vmadd_w", "vmsub_w", "vshuf_w"] in +- def int_loongarch_lsx_#inst +- : VecInt<[llvm_v4i32_ty], +- [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty], +- [IntrNoMem]>; +-foreach inst = ["vmadd_d", "vmsub_d", "vshuf_d"] in +- def int_loongarch_lsx_#inst +- : VecInt<[llvm_v2i64_ty], +- [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vsrlni_b_h", "vsrani_b_h", "vsrlrni_b_h", "vsrarni_b_h", +- "vssrlni_b_h", "vssrani_b_h", "vssrlni_bu_h", "vssrani_bu_h", +- "vssrlrni_b_h", "vssrarni_b_h", "vssrlrni_bu_h", "vssrarni_bu_h", +- "vfrstpi_b", "vbitseli_b", "vextrins_b"] in +- def int_loongarch_lsx_#inst +- : VecInt<[llvm_v16i8_ty], +- [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-foreach inst = ["vsrlni_h_w", "vsrani_h_w", "vsrlrni_h_w", "vsrarni_h_w", +- "vssrlni_h_w", "vssrani_h_w", "vssrlni_hu_w", "vssrani_hu_w", +- "vssrlrni_h_w", "vssrarni_h_w", "vssrlrni_hu_w", "vssrarni_hu_w", +- "vfrstpi_h", "vextrins_h"] in +- def int_loongarch_lsx_#inst +- : VecInt<[llvm_v8i16_ty], +- [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-foreach inst = ["vsrlni_w_d", "vsrani_w_d", "vsrlrni_w_d", "vsrarni_w_d", +- "vssrlni_w_d", "vssrani_w_d", "vssrlni_wu_d", "vssrani_wu_d", +- "vssrlrni_w_d", "vssrarni_w_d", "vssrlrni_wu_d", "vssrarni_wu_d", +- "vpermi_w", "vextrins_w"] in +- def int_loongarch_lsx_#inst +- : VecInt<[llvm_v4i32_ty], +- [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-foreach inst = ["vsrlni_d_q", "vsrani_d_q", "vsrlrni_d_q", "vsrarni_d_q", +- "vssrlni_d_q", "vssrani_d_q", "vssrlni_du_q", "vssrani_du_q", +- "vssrlrni_d_q", "vssrarni_d_q", "vssrlrni_du_q", "vssrarni_du_q", +- "vshuf4i_d", "vextrins_d"] in +- def int_loongarch_lsx_#inst +- : VecInt<[llvm_v2i64_ty], +- [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +- +-foreach inst = ["vmaddwev_h_b", "vmaddwod_h_b", "vmaddwev_h_bu", +- "vmaddwod_h_bu", "vmaddwev_h_bu_b", "vmaddwod_h_bu_b"] in +- def int_loongarch_lsx_#inst +- : VecInt<[llvm_v8i16_ty], +- [llvm_v8i16_ty, llvm_v16i8_ty, llvm_v16i8_ty], +- [IntrNoMem]>; +-foreach inst = ["vmaddwev_w_h", "vmaddwod_w_h", "vmaddwev_w_hu", +- "vmaddwod_w_hu", "vmaddwev_w_hu_h", "vmaddwod_w_hu_h"] in +- def int_loongarch_lsx_#inst +- : VecInt<[llvm_v4i32_ty], +- [llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty], +- [IntrNoMem]>; +-foreach inst = ["vmaddwev_d_w", "vmaddwod_d_w", "vmaddwev_d_wu", +- "vmaddwod_d_wu", "vmaddwev_d_wu_w", "vmaddwod_d_wu_w"] in +- def int_loongarch_lsx_#inst +- : VecInt<[llvm_v2i64_ty], +- [llvm_v2i64_ty, llvm_v4i32_ty, llvm_v4i32_ty], +- [IntrNoMem]>; +-foreach inst = ["vmaddwev_q_d", "vmaddwod_q_d", "vmaddwev_q_du", +- "vmaddwod_q_du", "vmaddwev_q_du_d", "vmaddwod_q_du_d"] in +- def int_loongarch_lsx_#inst +- : VecInt<[llvm_v2i64_ty], +- [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vsllwil_h_b", "vsllwil_hu_bu"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v8i16_ty], +- [llvm_v16i8_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-foreach inst = ["vsllwil_w_h", "vsllwil_wu_hu"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v4i32_ty], +- [llvm_v8i16_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-foreach inst = ["vsllwil_d_w", "vsllwil_du_wu"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v2i64_ty], +- [llvm_v4i32_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +- +-foreach inst = ["vneg_b", "vmskltz_b", "vmskgez_b", "vmsknz_b", +- "vclo_b", "vclz_b", "vpcnt_b"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v16i8_ty], [llvm_v16i8_ty], +- [IntrNoMem]>; +-foreach inst = ["vneg_h", "vmskltz_h", "vclo_h", "vclz_h", "vpcnt_h"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v8i16_ty], [llvm_v8i16_ty], +- [IntrNoMem]>; +-foreach inst = ["vneg_w", "vmskltz_w", "vclo_w", "vclz_w", "vpcnt_w"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v4i32_ty], [llvm_v4i32_ty], +- [IntrNoMem]>; +-foreach inst = ["vneg_d", "vexth_q_d", "vexth_qu_du", "vmskltz_d", +- "vextl_q_d", "vextl_qu_du", "vclo_d", "vclz_d", "vpcnt_d"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v2i64_ty], [llvm_v2i64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vexth_h_b", "vexth_hu_bu"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v8i16_ty], [llvm_v16i8_ty], +- [IntrNoMem]>; +-foreach inst = ["vexth_w_h", "vexth_wu_hu"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v4i32_ty], [llvm_v8i16_ty], +- [IntrNoMem]>; +-foreach inst = ["vexth_d_w", "vexth_du_wu"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v2i64_ty], [llvm_v4i32_ty], +- [IntrNoMem]>; +- +-def int_loongarch_lsx_vldi : VecInt<[llvm_v2i64_ty], [llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-def int_loongarch_lsx_vrepli_b : VecInt<[llvm_v16i8_ty], [llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-def int_loongarch_lsx_vrepli_h : VecInt<[llvm_v8i16_ty], [llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-def int_loongarch_lsx_vrepli_w : VecInt<[llvm_v4i32_ty], [llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-def int_loongarch_lsx_vrepli_d : VecInt<[llvm_v2i64_ty], [llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +- +-def int_loongarch_lsx_vreplgr2vr_b : VecInt<[llvm_v16i8_ty], [llvm_i32_ty], +- [IntrNoMem]>; +-def int_loongarch_lsx_vreplgr2vr_h : VecInt<[llvm_v8i16_ty], [llvm_i32_ty], +- [IntrNoMem]>; +-def int_loongarch_lsx_vreplgr2vr_w : VecInt<[llvm_v4i32_ty], [llvm_i32_ty], +- [IntrNoMem]>; +-def int_loongarch_lsx_vreplgr2vr_d : VecInt<[llvm_v2i64_ty], [llvm_i64_ty], +- [IntrNoMem]>; +- +-def int_loongarch_lsx_vinsgr2vr_b +- : VecInt<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-def int_loongarch_lsx_vinsgr2vr_h +- : VecInt<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-def int_loongarch_lsx_vinsgr2vr_w +- : VecInt<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-def int_loongarch_lsx_vinsgr2vr_d +- : VecInt<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i64_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +- +-def int_loongarch_lsx_vreplve_b +- : VecInt<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>; +-def int_loongarch_lsx_vreplve_h +- : VecInt<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>; +-def int_loongarch_lsx_vreplve_w +- : VecInt<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>; +-def int_loongarch_lsx_vreplve_d +- : VecInt<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>; +- +-foreach inst = ["vpickve2gr_b", "vpickve2gr_bu" ] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_i32_ty], +- [llvm_v16i8_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-foreach inst = ["vpickve2gr_h", "vpickve2gr_hu" ] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_i32_ty], +- [llvm_v8i16_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-foreach inst = ["vpickve2gr_w", "vpickve2gr_wu" ] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_i32_ty], +- [llvm_v4i32_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-foreach inst = ["vpickve2gr_d", "vpickve2gr_du" ] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_i64_ty], +- [llvm_v2i64_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +- +-def int_loongarch_lsx_bz_b : VecInt<[llvm_i32_ty], [llvm_v16i8_ty], +- [IntrNoMem]>; +-def int_loongarch_lsx_bz_h : VecInt<[llvm_i32_ty], [llvm_v8i16_ty], +- [IntrNoMem]>; +-def int_loongarch_lsx_bz_w : VecInt<[llvm_i32_ty], [llvm_v4i32_ty], +- [IntrNoMem]>; +-def int_loongarch_lsx_bz_d : VecInt<[llvm_i32_ty], [llvm_v2i64_ty], +- [IntrNoMem]>; +-def int_loongarch_lsx_bz_v : VecInt<[llvm_i32_ty], [llvm_v16i8_ty], +- [IntrNoMem]>; +- +-def int_loongarch_lsx_bnz_v : VecInt<[llvm_i32_ty], [llvm_v16i8_ty], +- [IntrNoMem]>; +-def int_loongarch_lsx_bnz_b : VecInt<[llvm_i32_ty], [llvm_v16i8_ty], +- [IntrNoMem]>; +-def int_loongarch_lsx_bnz_h : VecInt<[llvm_i32_ty], [llvm_v8i16_ty], +- [IntrNoMem]>; +-def int_loongarch_lsx_bnz_w : VecInt<[llvm_i32_ty], [llvm_v4i32_ty], +- [IntrNoMem]>; +-def int_loongarch_lsx_bnz_d : VecInt<[llvm_i32_ty], [llvm_v2i64_ty], +- [IntrNoMem]>; +- +-// LSX Float +- +-foreach inst = ["vfadd_s", "vfsub_s", "vfmul_s", "vfdiv_s", +- "vfmax_s", "vfmin_s", "vfmaxa_s", "vfmina_s"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v4f32_ty], +- [llvm_v4f32_ty, llvm_v4f32_ty], +- [IntrNoMem]>; +-foreach inst = ["vfadd_d", "vfsub_d", "vfmul_d", "vfdiv_d", +- "vfmax_d", "vfmin_d", "vfmaxa_d", "vfmina_d"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v2f64_ty], +- [llvm_v2f64_ty, llvm_v2f64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vfmadd_s", "vfmsub_s", "vfnmadd_s", "vfnmsub_s"] in +- def int_loongarch_lsx_#inst +- : VecInt<[llvm_v4f32_ty], +- [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], +- [IntrNoMem]>; +-foreach inst = ["vfmadd_d", "vfmsub_d", "vfnmadd_d", "vfnmsub_d"] in +- def int_loongarch_lsx_#inst +- : VecInt<[llvm_v2f64_ty], +- [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vflogb_s", "vfsqrt_s", "vfrecip_s", "vfrsqrt_s", "vfrint_s", +- "vfrecipe_s", "vfrsqrte_s", +- "vfrintrne_s", "vfrintrz_s", "vfrintrp_s", "vfrintrm_s"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v4f32_ty], [llvm_v4f32_ty], +- [IntrNoMem]>; +-foreach inst = ["vflogb_d", "vfsqrt_d", "vfrecip_d", "vfrsqrt_d", "vfrint_d", +- "vfrecipe_d", "vfrsqrte_d", +- "vfrintrne_d", "vfrintrz_d", "vfrintrp_d", "vfrintrm_d"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v2f64_ty], [llvm_v2f64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vfcvtl_s_h", "vfcvth_s_h"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v4f32_ty], [llvm_v8i16_ty], +- [IntrNoMem]>; +-foreach inst = ["vfcvtl_d_s", "vfcvth_d_s"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v2f64_ty], [llvm_v4f32_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vftintrne_w_s", "vftintrz_w_s", "vftintrp_w_s", "vftintrm_w_s", +- "vftint_w_s", "vftintrz_wu_s", "vftint_wu_s", "vfclass_s"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v4i32_ty], [llvm_v4f32_ty], +- [IntrNoMem]>; +-foreach inst = ["vftintrne_l_d", "vftintrz_l_d", "vftintrp_l_d", "vftintrm_l_d", +- "vftint_l_d", "vftintrz_lu_d", "vftint_lu_d", "vfclass_d"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v2i64_ty], [llvm_v2f64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vftintrnel_l_s", "vftintrneh_l_s", "vftintrzl_l_s", +- "vftintrzh_l_s", "vftintrpl_l_s", "vftintrph_l_s", +- "vftintrml_l_s", "vftintrmh_l_s", "vftintl_l_s", +- "vftinth_l_s"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v2i64_ty], [llvm_v4f32_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vffint_s_w", "vffint_s_wu"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v4f32_ty], [llvm_v4i32_ty], +- [IntrNoMem]>; +-foreach inst = ["vffint_d_l", "vffint_d_lu"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v2f64_ty], [llvm_v2i64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vffintl_d_w", "vffinth_d_w"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v2f64_ty], [llvm_v4i32_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vffint_s_l"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v4f32_ty], +- [llvm_v2i64_ty, llvm_v2i64_ty], +- [IntrNoMem]>; +-foreach inst = ["vftintrne_w_d", "vftintrz_w_d", "vftintrp_w_d", "vftintrm_w_d", +- "vftint_w_d"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v4i32_ty], +- [llvm_v2f64_ty, llvm_v2f64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vfcvt_h_s"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v8i16_ty], +- [llvm_v4f32_ty, llvm_v4f32_ty], +- [IntrNoMem]>; +-foreach inst = ["vfcvt_s_d"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v4f32_ty], +- [llvm_v2f64_ty, llvm_v2f64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vfcmp_caf_s", "vfcmp_cun_s", "vfcmp_ceq_s", "vfcmp_cueq_s", +- "vfcmp_clt_s", "vfcmp_cult_s", "vfcmp_cle_s", "vfcmp_cule_s", +- "vfcmp_cne_s", "vfcmp_cor_s", "vfcmp_cune_s", +- "vfcmp_saf_s", "vfcmp_sun_s", "vfcmp_seq_s", "vfcmp_sueq_s", +- "vfcmp_slt_s", "vfcmp_sult_s", "vfcmp_sle_s", "vfcmp_sule_s", +- "vfcmp_sne_s", "vfcmp_sor_s", "vfcmp_sune_s"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v4i32_ty], +- [llvm_v4f32_ty, llvm_v4f32_ty], +- [IntrNoMem]>; +-foreach inst = ["vfcmp_caf_d", "vfcmp_cun_d", "vfcmp_ceq_d", "vfcmp_cueq_d", +- "vfcmp_clt_d", "vfcmp_cult_d", "vfcmp_cle_d", "vfcmp_cule_d", +- "vfcmp_cne_d", "vfcmp_cor_d", "vfcmp_cune_d", +- "vfcmp_saf_d", "vfcmp_sun_d", "vfcmp_seq_d", "vfcmp_sueq_d", +- "vfcmp_slt_d", "vfcmp_sult_d", "vfcmp_sle_d", "vfcmp_sule_d", +- "vfcmp_sne_d", "vfcmp_sor_d", "vfcmp_sune_d"] in +- def int_loongarch_lsx_#inst : VecInt<[llvm_v2i64_ty], +- [llvm_v2f64_ty, llvm_v2f64_ty], +- [IntrNoMem]>; +- +-// LSX load/store +-def int_loongarch_lsx_vld +- : VecInt<[llvm_v16i8_ty], [llvm_ptr_ty, llvm_i32_ty], +- [IntrReadMem, IntrArgMemOnly, ImmArg>]>; +-def int_loongarch_lsx_vldx +- : VecInt<[llvm_v16i8_ty], [llvm_ptr_ty, llvm_i64_ty], +- [IntrReadMem, IntrArgMemOnly]>; +-def int_loongarch_lsx_vldrepl_b +- : VecInt<[llvm_v16i8_ty], [llvm_ptr_ty, llvm_i32_ty], +- [IntrReadMem, IntrArgMemOnly, ImmArg>]>; +-def int_loongarch_lsx_vldrepl_h +- : VecInt<[llvm_v8i16_ty], [llvm_ptr_ty, llvm_i32_ty], +- [IntrReadMem, IntrArgMemOnly, ImmArg>]>; +-def int_loongarch_lsx_vldrepl_w +- : VecInt<[llvm_v4i32_ty], [llvm_ptr_ty, llvm_i32_ty], +- [IntrReadMem, IntrArgMemOnly, ImmArg>]>; +-def int_loongarch_lsx_vldrepl_d +- : VecInt<[llvm_v2i64_ty], [llvm_ptr_ty, llvm_i32_ty], +- [IntrReadMem, IntrArgMemOnly, ImmArg>]>; +- +-def int_loongarch_lsx_vst +- : VecInt<[], [llvm_v16i8_ty, llvm_ptr_ty, llvm_i32_ty], +- [IntrWriteMem, IntrArgMemOnly, ImmArg>]>; +-def int_loongarch_lsx_vstx +- : VecInt<[], [llvm_v16i8_ty, llvm_ptr_ty, llvm_i64_ty], +- [IntrWriteMem, IntrArgMemOnly]>; +-def int_loongarch_lsx_vstelm_b +- : VecInt<[], [llvm_v16i8_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], +- [IntrWriteMem, IntrArgMemOnly, ImmArg>, ImmArg>]>; +-def int_loongarch_lsx_vstelm_h +- : VecInt<[], [llvm_v8i16_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], +- [IntrWriteMem, IntrArgMemOnly, ImmArg>, ImmArg>]>; +-def int_loongarch_lsx_vstelm_w +- : VecInt<[], [llvm_v4i32_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], +- [IntrWriteMem, IntrArgMemOnly, ImmArg>, ImmArg>]>; +-def int_loongarch_lsx_vstelm_d +- : VecInt<[], [llvm_v2i64_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], +- [IntrWriteMem, IntrArgMemOnly, ImmArg>, ImmArg>]>; +- +-} // TargetPrefix = "loongarch" ++def int_loongarch_csrrd_w : ClangBuiltin<"__builtin_loongarch_csrrd_w">, ++ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>; + +-//===----------------------------------------------------------------------===// +-// LASX +- +-let TargetPrefix = "loongarch" in { +-foreach inst = ["xvadd_b", "xvsub_b", +- "xvsadd_b", "xvsadd_bu", "xvssub_b", "xvssub_bu", +- "xvavg_b", "xvavg_bu", "xvavgr_b", "xvavgr_bu", +- "xvabsd_b", "xvabsd_bu", "xvadda_b", +- "xvmax_b", "xvmax_bu", "xvmin_b", "xvmin_bu", +- "xvmul_b", "xvmuh_b", "xvmuh_bu", +- "xvdiv_b", "xvdiv_bu", "xvmod_b", "xvmod_bu", "xvsigncov_b", +- "xvand_v", "xvor_v", "xvxor_v", "xvnor_v", "xvandn_v", "xvorn_v", +- "xvsll_b", "xvsrl_b", "xvsra_b", "xvrotr_b", "xvsrlr_b", "xvsrar_b", +- "xvbitclr_b", "xvbitset_b", "xvbitrev_b", +- "xvseq_b", "xvsle_b", "xvsle_bu", "xvslt_b", "xvslt_bu", +- "xvpackev_b", "xvpackod_b", "xvpickev_b", "xvpickod_b", +- "xvilvl_b", "xvilvh_b"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v32i8_ty], +- [llvm_v32i8_ty, llvm_v32i8_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvadd_h", "xvsub_h", +- "xvsadd_h", "xvsadd_hu", "xvssub_h", "xvssub_hu", +- "xvavg_h", "xvavg_hu", "xvavgr_h", "xvavgr_hu", +- "xvabsd_h", "xvabsd_hu", "xvadda_h", +- "xvmax_h", "xvmax_hu", "xvmin_h", "xvmin_hu", +- "xvmul_h", "xvmuh_h", "xvmuh_hu", +- "xvdiv_h", "xvdiv_hu", "xvmod_h", "xvmod_hu", "xvsigncov_h", +- "xvsll_h", "xvsrl_h", "xvsra_h", "xvrotr_h", "xvsrlr_h", "xvsrar_h", +- "xvbitclr_h", "xvbitset_h", "xvbitrev_h", +- "xvseq_h", "xvsle_h", "xvsle_hu", "xvslt_h", "xvslt_hu", +- "xvpackev_h", "xvpackod_h", "xvpickev_h", "xvpickod_h", +- "xvilvl_h", "xvilvh_h"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v16i16_ty], +- [llvm_v16i16_ty, llvm_v16i16_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvadd_w", "xvsub_w", +- "xvsadd_w", "xvsadd_wu", "xvssub_w", "xvssub_wu", +- "xvavg_w", "xvavg_wu", "xvavgr_w", "xvavgr_wu", +- "xvabsd_w", "xvabsd_wu", "xvadda_w", +- "xvmax_w", "xvmax_wu", "xvmin_w", "xvmin_wu", +- "xvmul_w", "xvmuh_w", "xvmuh_wu", +- "xvdiv_w", "xvdiv_wu", "xvmod_w", "xvmod_wu", "xvsigncov_w", +- "xvsll_w", "xvsrl_w", "xvsra_w", "xvrotr_w", "xvsrlr_w", "xvsrar_w", +- "xvbitclr_w", "xvbitset_w", "xvbitrev_w", +- "xvseq_w", "xvsle_w", "xvsle_wu", "xvslt_w", "xvslt_wu", +- "xvpackev_w", "xvpackod_w", "xvpickev_w", "xvpickod_w", +- "xvilvl_w", "xvilvh_w", "xvperm_w"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v8i32_ty], +- [llvm_v8i32_ty, llvm_v8i32_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvadd_d", "xvadd_q", "xvsub_d", "xvsub_q", +- "xvsadd_d", "xvsadd_du", "xvssub_d", "xvssub_du", +- "xvhaddw_q_d", "xvhaddw_qu_du", "xvhsubw_q_d", "xvhsubw_qu_du", +- "xvaddwev_q_d", "xvaddwod_q_d", "xvsubwev_q_d", "xvsubwod_q_d", +- "xvaddwev_q_du", "xvaddwod_q_du", "xvsubwev_q_du", "xvsubwod_q_du", +- "xvaddwev_q_du_d", "xvaddwod_q_du_d", +- "xvavg_d", "xvavg_du", "xvavgr_d", "xvavgr_du", +- "xvabsd_d", "xvabsd_du", "xvadda_d", +- "xvmax_d", "xvmax_du", "xvmin_d", "xvmin_du", +- "xvmul_d", "xvmuh_d", "xvmuh_du", +- "xvmulwev_q_d", "xvmulwod_q_d", "xvmulwev_q_du", "xvmulwod_q_du", +- "xvmulwev_q_du_d", "xvmulwod_q_du_d", +- "xvdiv_d", "xvdiv_du", "xvmod_d", "xvmod_du", "xvsigncov_d", +- "xvsll_d", "xvsrl_d", "xvsra_d", "xvrotr_d", "xvsrlr_d", "xvsrar_d", +- "xvbitclr_d", "xvbitset_d", "xvbitrev_d", +- "xvseq_d", "xvsle_d", "xvsle_du", "xvslt_d", "xvslt_du", +- "xvpackev_d", "xvpackod_d", "xvpickev_d", "xvpickod_d", +- "xvilvl_d", "xvilvh_d"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v4i64_ty], +- [llvm_v4i64_ty, llvm_v4i64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvaddi_bu", "xvsubi_bu", +- "xvmaxi_b", "xvmaxi_bu", "xvmini_b", "xvmini_bu", +- "xvsat_b", "xvsat_bu", +- "xvandi_b", "xvori_b", "xvxori_b", "xvnori_b", +- "xvslli_b", "xvsrli_b", "xvsrai_b", "xvrotri_b", +- "xvsrlri_b", "xvsrari_b", +- "xvbitclri_b", "xvbitseti_b", "xvbitrevi_b", +- "xvseqi_b", "xvslei_b", "xvslei_bu", "xvslti_b", "xvslti_bu", +- "xvrepl128vei_b", "xvbsll_v", "xvbsrl_v", "xvshuf4i_b"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v32i8_ty], +- [llvm_v32i8_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-foreach inst = ["xvaddi_hu", "xvsubi_hu", +- "xvmaxi_h", "xvmaxi_hu", "xvmini_h", "xvmini_hu", +- "xvsat_h", "xvsat_hu", +- "xvslli_h", "xvsrli_h", "xvsrai_h", "xvrotri_h", +- "xvsrlri_h", "xvsrari_h", +- "xvbitclri_h", "xvbitseti_h", "xvbitrevi_h", +- "xvseqi_h", "xvslei_h", "xvslei_hu", "xvslti_h", "xvslti_hu", +- "xvrepl128vei_h", "xvshuf4i_h"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v16i16_ty], +- [llvm_v16i16_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-foreach inst = ["xvaddi_wu", "xvsubi_wu", +- "xvmaxi_w", "xvmaxi_wu", "xvmini_w", "xvmini_wu", +- "xvsat_w", "xvsat_wu", +- "xvslli_w", "xvsrli_w", "xvsrai_w", "xvrotri_w", +- "xvsrlri_w", "xvsrari_w", +- "xvbitclri_w", "xvbitseti_w", "xvbitrevi_w", +- "xvseqi_w", "xvslei_w", "xvslei_wu", "xvslti_w", "xvslti_wu", +- "xvrepl128vei_w", "xvshuf4i_w", "xvpickve_w"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v8i32_ty], +- [llvm_v8i32_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-foreach inst = ["xvaddi_du", "xvsubi_du", +- "xvmaxi_d", "xvmaxi_du", "xvmini_d", "xvmini_du", +- "xvsat_d", "xvsat_du", +- "xvslli_d", "xvsrli_d", "xvsrai_d", "xvrotri_d", +- "xvsrlri_d", "xvsrari_d", +- "xvbitclri_d", "xvbitseti_d", "xvbitrevi_d", +- "xvseqi_d", "xvslei_d", "xvslei_du", "xvslti_d", "xvslti_du", +- "xvrepl128vei_d", "xvpermi_d", "xvpickve_d"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v4i64_ty], +- [llvm_v4i64_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +- +-foreach inst = ["xvhaddw_h_b", "xvhaddw_hu_bu", "xvhsubw_h_b", "xvhsubw_hu_bu", +- "xvaddwev_h_b", "xvaddwod_h_b", "xvsubwev_h_b", "xvsubwod_h_b", +- "xvaddwev_h_bu", "xvaddwod_h_bu", "xvsubwev_h_bu", "xvsubwod_h_bu", +- "xvaddwev_h_bu_b", "xvaddwod_h_bu_b", +- "xvmulwev_h_b", "xvmulwod_h_b", "xvmulwev_h_bu", "xvmulwod_h_bu", +- "xvmulwev_h_bu_b", "xvmulwod_h_bu_b"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v16i16_ty], +- [llvm_v32i8_ty, llvm_v32i8_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvhaddw_w_h", "xvhaddw_wu_hu", "xvhsubw_w_h", "xvhsubw_wu_hu", +- "xvaddwev_w_h", "xvaddwod_w_h", "xvsubwev_w_h", "xvsubwod_w_h", +- "xvaddwev_w_hu", "xvaddwod_w_hu", "xvsubwev_w_hu", "xvsubwod_w_hu", +- "xvaddwev_w_hu_h", "xvaddwod_w_hu_h", +- "xvmulwev_w_h", "xvmulwod_w_h", "xvmulwev_w_hu", "xvmulwod_w_hu", +- "xvmulwev_w_hu_h", "xvmulwod_w_hu_h"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v8i32_ty], +- [llvm_v16i16_ty, llvm_v16i16_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvhaddw_d_w", "xvhaddw_du_wu", "xvhsubw_d_w", "xvhsubw_du_wu", +- "xvaddwev_d_w", "xvaddwod_d_w", "xvsubwev_d_w", "xvsubwod_d_w", +- "xvaddwev_d_wu", "xvaddwod_d_wu", "xvsubwev_d_wu", "xvsubwod_d_wu", +- "xvaddwev_d_wu_w", "xvaddwod_d_wu_w", +- "xvmulwev_d_w", "xvmulwod_d_w", "xvmulwev_d_wu", "xvmulwod_d_wu", +- "xvmulwev_d_wu_w", "xvmulwod_d_wu_w"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v4i64_ty], +- [llvm_v8i32_ty, llvm_v8i32_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvsrln_b_h", "xvsran_b_h", "xvsrlrn_b_h", "xvsrarn_b_h", +- "xvssrln_b_h", "xvssran_b_h", "xvssrln_bu_h", "xvssran_bu_h", +- "xvssrlrn_b_h", "xvssrarn_b_h", "xvssrlrn_bu_h", "xvssrarn_bu_h"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v32i8_ty], +- [llvm_v16i16_ty, llvm_v16i16_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvsrln_h_w", "xvsran_h_w", "xvsrlrn_h_w", "xvsrarn_h_w", +- "xvssrln_h_w", "xvssran_h_w", "xvssrln_hu_w", "xvssran_hu_w", +- "xvssrlrn_h_w", "xvssrarn_h_w", "xvssrlrn_hu_w", "xvssrarn_hu_w"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v16i16_ty], +- [llvm_v8i32_ty, llvm_v8i32_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvsrln_w_d", "xvsran_w_d", "xvsrlrn_w_d", "xvsrarn_w_d", +- "xvssrln_w_d", "xvssran_w_d", "xvssrln_wu_d", "xvssran_wu_d", +- "xvssrlrn_w_d", "xvssrarn_w_d", "xvssrlrn_wu_d", "xvssrarn_wu_d"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v8i32_ty], +- [llvm_v4i64_ty, llvm_v4i64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvmadd_b", "xvmsub_b", "xvfrstp_b", "xvbitsel_v", "xvshuf_b"] in +- def int_loongarch_lasx_#inst +- : VecInt<[llvm_v32i8_ty], +- [llvm_v32i8_ty, llvm_v32i8_ty, llvm_v32i8_ty], +- [IntrNoMem]>; +-foreach inst = ["xvmadd_h", "xvmsub_h", "xvfrstp_h", "xvshuf_h"] in +- def int_loongarch_lasx_#inst +- : VecInt<[llvm_v16i16_ty], +- [llvm_v16i16_ty, llvm_v16i16_ty, llvm_v16i16_ty], +- [IntrNoMem]>; +-foreach inst = ["xvmadd_w", "xvmsub_w", "xvshuf_w"] in +- def int_loongarch_lasx_#inst +- : VecInt<[llvm_v8i32_ty], +- [llvm_v8i32_ty, llvm_v8i32_ty, llvm_v8i32_ty], +- [IntrNoMem]>; +-foreach inst = ["xvmadd_d", "xvmsub_d", "xvshuf_d"] in +- def int_loongarch_lasx_#inst +- : VecInt<[llvm_v4i64_ty], +- [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvsrlni_b_h", "xvsrani_b_h", "xvsrlrni_b_h", "xvsrarni_b_h", +- "xvssrlni_b_h", "xvssrani_b_h", "xvssrlni_bu_h", "xvssrani_bu_h", +- "xvssrlrni_b_h", "xvssrarni_b_h", "xvssrlrni_bu_h", "xvssrarni_bu_h", +- "xvfrstpi_b", "xvbitseli_b", "xvextrins_b", "xvpermi_q"] in +- def int_loongarch_lasx_#inst +- : VecInt<[llvm_v32i8_ty], +- [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-foreach inst = ["xvsrlni_h_w", "xvsrani_h_w", "xvsrlrni_h_w", "xvsrarni_h_w", +- "xvssrlni_h_w", "xvssrani_h_w", "xvssrlni_hu_w", "xvssrani_hu_w", +- "xvssrlrni_h_w", "xvssrarni_h_w", "xvssrlrni_hu_w", "xvssrarni_hu_w", +- "xvfrstpi_h", "xvextrins_h"] in +- def int_loongarch_lasx_#inst +- : VecInt<[llvm_v16i16_ty], +- [llvm_v16i16_ty, llvm_v16i16_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-foreach inst = ["xvsrlni_w_d", "xvsrani_w_d", "xvsrlrni_w_d", "xvsrarni_w_d", +- "xvssrlni_w_d", "xvssrani_w_d", "xvssrlni_wu_d", "xvssrani_wu_d", +- "xvssrlrni_w_d", "xvssrarni_w_d", "xvssrlrni_wu_d", "xvssrarni_wu_d", +- "xvpermi_w", "xvextrins_w", "xvinsve0_w"] in +- def int_loongarch_lasx_#inst +- : VecInt<[llvm_v8i32_ty], +- [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-foreach inst = ["xvsrlni_d_q", "xvsrani_d_q", "xvsrlrni_d_q", "xvsrarni_d_q", +- "xvssrlni_d_q", "xvssrani_d_q", "xvssrlni_du_q", "xvssrani_du_q", +- "xvssrlrni_d_q", "xvssrarni_d_q", "xvssrlrni_du_q", "xvssrarni_du_q", +- "xvshuf4i_d", "xvextrins_d", "xvinsve0_d"] in +- def int_loongarch_lasx_#inst +- : VecInt<[llvm_v4i64_ty], +- [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +- +-foreach inst = ["xvmaddwev_h_b", "xvmaddwod_h_b", "xvmaddwev_h_bu", +- "xvmaddwod_h_bu", "xvmaddwev_h_bu_b", "xvmaddwod_h_bu_b"] in +- def int_loongarch_lasx_#inst +- : VecInt<[llvm_v16i16_ty], +- [llvm_v16i16_ty, llvm_v32i8_ty, llvm_v32i8_ty], +- [IntrNoMem]>; +-foreach inst = ["xvmaddwev_w_h", "xvmaddwod_w_h", "xvmaddwev_w_hu", +- "xvmaddwod_w_hu", "xvmaddwev_w_hu_h", "xvmaddwod_w_hu_h"] in +- def int_loongarch_lasx_#inst +- : VecInt<[llvm_v8i32_ty], +- [llvm_v8i32_ty, llvm_v16i16_ty, llvm_v16i16_ty], +- [IntrNoMem]>; +-foreach inst = ["xvmaddwev_d_w", "xvmaddwod_d_w", "xvmaddwev_d_wu", +- "xvmaddwod_d_wu", "xvmaddwev_d_wu_w", "xvmaddwod_d_wu_w"] in +- def int_loongarch_lasx_#inst +- : VecInt<[llvm_v4i64_ty], +- [llvm_v4i64_ty, llvm_v8i32_ty, llvm_v8i32_ty], +- [IntrNoMem]>; +-foreach inst = ["xvmaddwev_q_d", "xvmaddwod_q_d", "xvmaddwev_q_du", +- "xvmaddwod_q_du", "xvmaddwev_q_du_d", "xvmaddwod_q_du_d"] in +- def int_loongarch_lasx_#inst +- : VecInt<[llvm_v4i64_ty], +- [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvsllwil_h_b", "xvsllwil_hu_bu"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v16i16_ty], +- [llvm_v32i8_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-foreach inst = ["xvsllwil_w_h", "xvsllwil_wu_hu"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v8i32_ty], +- [llvm_v16i16_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-foreach inst = ["xvsllwil_d_w", "xvsllwil_du_wu"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v4i64_ty], +- [llvm_v8i32_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +- +-foreach inst = ["xvneg_b", "xvmskltz_b", "xvmskgez_b", "xvmsknz_b", +- "xvclo_b", "xvclz_b", "xvpcnt_b", +- "xvreplve0_b", "xvreplve0_q"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v32i8_ty], [llvm_v32i8_ty], +- [IntrNoMem]>; +-foreach inst = ["xvneg_h", "xvmskltz_h", "xvclo_h", "xvclz_h", "xvpcnt_h", +- "xvreplve0_h"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v16i16_ty], [llvm_v16i16_ty], +- [IntrNoMem]>; +-foreach inst = ["xvneg_w", "xvmskltz_w", "xvclo_w", "xvclz_w", "xvpcnt_w", +- "xvreplve0_w"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v8i32_ty], [llvm_v8i32_ty], +- [IntrNoMem]>; +-foreach inst = ["xvneg_d", "xvexth_q_d", "xvexth_qu_du", "xvmskltz_d", +- "xvextl_q_d", "xvextl_qu_du", "xvclo_d", "xvclz_d", "xvpcnt_d", +- "xvreplve0_d"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v4i64_ty], [llvm_v4i64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvexth_h_b", "xvexth_hu_bu", "vext2xv_h_b", "vext2xv_hu_bu"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v16i16_ty], [llvm_v32i8_ty], +- [IntrNoMem]>; +-foreach inst = ["xvexth_w_h", "xvexth_wu_hu", "vext2xv_w_h", "vext2xv_wu_hu"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v8i32_ty], [llvm_v16i16_ty], +- [IntrNoMem]>; +-foreach inst = ["xvexth_d_w", "xvexth_du_wu", "vext2xv_d_w", "vext2xv_du_wu"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v4i64_ty], [llvm_v8i32_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vext2xv_w_b", "vext2xv_wu_bu"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v8i32_ty], [llvm_v32i8_ty], +- [IntrNoMem]>; +-foreach inst = ["vext2xv_d_h", "vext2xv_du_hu"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v4i64_ty], [llvm_v16i16_ty], +- [IntrNoMem]>; +- +-foreach inst = ["vext2xv_d_b", "vext2xv_du_bu"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v4i64_ty], [llvm_v32i8_ty], +- [IntrNoMem]>; +- +-def int_loongarch_lasx_xvldi : VecInt<[llvm_v4i64_ty], [llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-def int_loongarch_lasx_xvrepli_b : VecInt<[llvm_v32i8_ty], [llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-def int_loongarch_lasx_xvrepli_h : VecInt<[llvm_v16i16_ty], [llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-def int_loongarch_lasx_xvrepli_w : VecInt<[llvm_v8i32_ty], [llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-def int_loongarch_lasx_xvrepli_d : VecInt<[llvm_v4i64_ty], [llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +- +-def int_loongarch_lasx_xvreplgr2vr_b : VecInt<[llvm_v32i8_ty], [llvm_i32_ty], +- [IntrNoMem]>; +-def int_loongarch_lasx_xvreplgr2vr_h : VecInt<[llvm_v16i16_ty], [llvm_i32_ty], +- [IntrNoMem]>; +-def int_loongarch_lasx_xvreplgr2vr_w : VecInt<[llvm_v8i32_ty], [llvm_i32_ty], +- [IntrNoMem]>; +-def int_loongarch_lasx_xvreplgr2vr_d : VecInt<[llvm_v4i64_ty], [llvm_i64_ty], +- [IntrNoMem]>; +- +-def int_loongarch_lasx_xvinsgr2vr_w +- : VecInt<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-def int_loongarch_lasx_xvinsgr2vr_d +- : VecInt<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i64_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +- +-def int_loongarch_lasx_xvreplve_b +- : VecInt<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; +-def int_loongarch_lasx_xvreplve_h +- : VecInt<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_i32_ty], [IntrNoMem]>; +-def int_loongarch_lasx_xvreplve_w +- : VecInt<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i32_ty], [IntrNoMem]>; +-def int_loongarch_lasx_xvreplve_d +- : VecInt<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i32_ty], [IntrNoMem]>; +- +-foreach inst = ["xvpickve2gr_w", "xvpickve2gr_wu" ] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_i32_ty], +- [llvm_v8i32_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-foreach inst = ["xvpickve2gr_d", "xvpickve2gr_du" ] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_i64_ty], +- [llvm_v4i64_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +- +-def int_loongarch_lasx_xbz_b : VecInt<[llvm_i32_ty], [llvm_v32i8_ty], +- [IntrNoMem]>; +-def int_loongarch_lasx_xbz_h : VecInt<[llvm_i32_ty], [llvm_v16i16_ty], +- [IntrNoMem]>; +-def int_loongarch_lasx_xbz_w : VecInt<[llvm_i32_ty], [llvm_v8i32_ty], +- [IntrNoMem]>; +-def int_loongarch_lasx_xbz_d : VecInt<[llvm_i32_ty], [llvm_v4i64_ty], +- [IntrNoMem]>; +-def int_loongarch_lasx_xbz_v : VecInt<[llvm_i32_ty], [llvm_v32i8_ty], +- [IntrNoMem]>; +- +-def int_loongarch_lasx_xbnz_v : VecInt<[llvm_i32_ty], [llvm_v32i8_ty], +- [IntrNoMem]>; +-def int_loongarch_lasx_xbnz_b : VecInt<[llvm_i32_ty], [llvm_v32i8_ty], +- [IntrNoMem]>; +-def int_loongarch_lasx_xbnz_h : VecInt<[llvm_i32_ty], [llvm_v16i16_ty], +- [IntrNoMem]>; +-def int_loongarch_lasx_xbnz_w : VecInt<[llvm_i32_ty], [llvm_v8i32_ty], +- [IntrNoMem]>; +-def int_loongarch_lasx_xbnz_d : VecInt<[llvm_i32_ty], [llvm_v4i64_ty], +- [IntrNoMem]>; +- +-// LASX Float +- +-foreach inst = ["xvfadd_s", "xvfsub_s", "xvfmul_s", "xvfdiv_s", +- "xvfmax_s", "xvfmin_s", "xvfmaxa_s", "xvfmina_s"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v8f32_ty], +- [llvm_v8f32_ty, llvm_v8f32_ty], +- [IntrNoMem]>; +-foreach inst = ["xvfadd_d", "xvfsub_d", "xvfmul_d", "xvfdiv_d", +- "xvfmax_d", "xvfmin_d", "xvfmaxa_d", "xvfmina_d"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v4f64_ty], +- [llvm_v4f64_ty, llvm_v4f64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvfmadd_s", "xvfmsub_s", "xvfnmadd_s", "xvfnmsub_s"] in +- def int_loongarch_lasx_#inst +- : VecInt<[llvm_v8f32_ty], +- [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty], +- [IntrNoMem]>; +-foreach inst = ["xvfmadd_d", "xvfmsub_d", "xvfnmadd_d", "xvfnmsub_d"] in +- def int_loongarch_lasx_#inst +- : VecInt<[llvm_v4f64_ty], +- [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvflogb_s", "xvfsqrt_s", "xvfrecip_s", "xvfrsqrt_s", "xvfrint_s", +- "xvfrecipe_s", "xvfrsqrte_s", +- "xvfrintrne_s", "xvfrintrz_s", "xvfrintrp_s", "xvfrintrm_s"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v8f32_ty], [llvm_v8f32_ty], +- [IntrNoMem]>; +-foreach inst = ["xvflogb_d", "xvfsqrt_d", "xvfrecip_d", "xvfrsqrt_d", "xvfrint_d", +- "xvfrecipe_d", "xvfrsqrte_d", +- "xvfrintrne_d", "xvfrintrz_d", "xvfrintrp_d", "xvfrintrm_d"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v4f64_ty], [llvm_v4f64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvfcvtl_s_h", "xvfcvth_s_h"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v8f32_ty], [llvm_v16i16_ty], +- [IntrNoMem]>; +-foreach inst = ["xvfcvtl_d_s", "xvfcvth_d_s"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v4f64_ty], [llvm_v8f32_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvftintrne_w_s", "xvftintrz_w_s", "xvftintrp_w_s", "xvftintrm_w_s", +- "xvftint_w_s", "xvftintrz_wu_s", "xvftint_wu_s", "xvfclass_s"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v8i32_ty], [llvm_v8f32_ty], +- [IntrNoMem]>; +-foreach inst = ["xvftintrne_l_d", "xvftintrz_l_d", "xvftintrp_l_d", "xvftintrm_l_d", +- "xvftint_l_d", "xvftintrz_lu_d", "xvftint_lu_d", "xvfclass_d"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v4i64_ty], [llvm_v4f64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvftintrnel_l_s", "xvftintrneh_l_s", "xvftintrzl_l_s", +- "xvftintrzh_l_s", "xvftintrpl_l_s", "xvftintrph_l_s", +- "xvftintrml_l_s", "xvftintrmh_l_s", "xvftintl_l_s", +- "xvftinth_l_s"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v4i64_ty], [llvm_v8f32_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvffint_s_w", "xvffint_s_wu"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v8f32_ty], [llvm_v8i32_ty], +- [IntrNoMem]>; +-foreach inst = ["xvffint_d_l", "xvffint_d_lu"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v4f64_ty], [llvm_v4i64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvffintl_d_w", "xvffinth_d_w"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v4f64_ty], [llvm_v8i32_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvffint_s_l"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v8f32_ty], +- [llvm_v4i64_ty, llvm_v4i64_ty], +- [IntrNoMem]>; +-foreach inst = ["xvftintrne_w_d", "xvftintrz_w_d", "xvftintrp_w_d", "xvftintrm_w_d", +- "xvftint_w_d"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v8i32_ty], +- [llvm_v4f64_ty, llvm_v4f64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvfcvt_h_s"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v16i16_ty], +- [llvm_v8f32_ty, llvm_v8f32_ty], +- [IntrNoMem]>; +-foreach inst = ["xvfcvt_s_d"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v8f32_ty], +- [llvm_v4f64_ty, llvm_v4f64_ty], +- [IntrNoMem]>; +- +-foreach inst = ["xvfcmp_caf_s", "xvfcmp_cun_s", "xvfcmp_ceq_s", "xvfcmp_cueq_s", +- "xvfcmp_clt_s", "xvfcmp_cult_s", "xvfcmp_cle_s", "xvfcmp_cule_s", +- "xvfcmp_cne_s", "xvfcmp_cor_s", "xvfcmp_cune_s", +- "xvfcmp_saf_s", "xvfcmp_sun_s", "xvfcmp_seq_s", "xvfcmp_sueq_s", +- "xvfcmp_slt_s", "xvfcmp_sult_s", "xvfcmp_sle_s", "xvfcmp_sule_s", +- "xvfcmp_sne_s", "xvfcmp_sor_s", "xvfcmp_sune_s"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v8i32_ty], +- [llvm_v8f32_ty, llvm_v8f32_ty], +- [IntrNoMem]>; +-foreach inst = ["xvfcmp_caf_d", "xvfcmp_cun_d", "xvfcmp_ceq_d", "xvfcmp_cueq_d", +- "xvfcmp_clt_d", "xvfcmp_cult_d", "xvfcmp_cle_d", "xvfcmp_cule_d", +- "xvfcmp_cne_d", "xvfcmp_cor_d", "xvfcmp_cune_d", +- "xvfcmp_saf_d", "xvfcmp_sun_d", "xvfcmp_seq_d", "xvfcmp_sueq_d", +- "xvfcmp_slt_d", "xvfcmp_sult_d", "xvfcmp_sle_d", "xvfcmp_sule_d", +- "xvfcmp_sne_d", "xvfcmp_sor_d", "xvfcmp_sune_d"] in +- def int_loongarch_lasx_#inst : VecInt<[llvm_v4i64_ty], +- [llvm_v4f64_ty, llvm_v4f64_ty], +- [IntrNoMem]>; +- +-def int_loongarch_lasx_xvpickve_w_f +- : VecInt<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +-def int_loongarch_lasx_xvpickve_d_f +- : VecInt<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_i32_ty], +- [IntrNoMem, ImmArg>]>; +- +-// LASX load/store +-def int_loongarch_lasx_xvld +- : VecInt<[llvm_v32i8_ty], [llvm_ptr_ty, llvm_i32_ty], +- [IntrReadMem, IntrArgMemOnly, ImmArg>]>; +-def int_loongarch_lasx_xvldx +- : VecInt<[llvm_v32i8_ty], [llvm_ptr_ty, llvm_i64_ty], +- [IntrReadMem, IntrArgMemOnly]>; +-def int_loongarch_lasx_xvldrepl_b +- : VecInt<[llvm_v32i8_ty], [llvm_ptr_ty, llvm_i32_ty], +- [IntrReadMem, IntrArgMemOnly, ImmArg>]>; +-def int_loongarch_lasx_xvldrepl_h +- : VecInt<[llvm_v16i16_ty], [llvm_ptr_ty, llvm_i32_ty], +- [IntrReadMem, IntrArgMemOnly, ImmArg>]>; +-def int_loongarch_lasx_xvldrepl_w +- : VecInt<[llvm_v8i32_ty], [llvm_ptr_ty, llvm_i32_ty], +- [IntrReadMem, IntrArgMemOnly, ImmArg>]>; +-def int_loongarch_lasx_xvldrepl_d +- : VecInt<[llvm_v4i64_ty], [llvm_ptr_ty, llvm_i32_ty], +- [IntrReadMem, IntrArgMemOnly, ImmArg>]>; +- +-def int_loongarch_lasx_xvst +- : VecInt<[], [llvm_v32i8_ty, llvm_ptr_ty, llvm_i32_ty], +- [IntrWriteMem, IntrArgMemOnly, ImmArg>]>; +-def int_loongarch_lasx_xvstx +- : VecInt<[], [llvm_v32i8_ty, llvm_ptr_ty, llvm_i64_ty], +- [IntrWriteMem, IntrArgMemOnly]>; +-def int_loongarch_lasx_xvstelm_b +- : VecInt<[], [llvm_v32i8_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], +- [IntrWriteMem, IntrArgMemOnly, ImmArg>, ImmArg>]>; +-def int_loongarch_lasx_xvstelm_h +- : VecInt<[], [llvm_v16i16_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], +- [IntrWriteMem, IntrArgMemOnly, ImmArg>, ImmArg>]>; +-def int_loongarch_lasx_xvstelm_w +- : VecInt<[], [llvm_v8i32_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], +- [IntrWriteMem, IntrArgMemOnly, ImmArg>, ImmArg>]>; +-def int_loongarch_lasx_xvstelm_d +- : VecInt<[], [llvm_v4i64_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], +- [IntrWriteMem, IntrArgMemOnly, ImmArg>, ImmArg>]>; +-} // TargetPrefix = "loongarch" ++def int_loongarch_csrrd_d : ClangBuiltin<"__builtin_loongarch_csrrd_d">, ++ Intrinsic<[llvm_i64_ty], [llvm_i64_ty], []>; ++ ++def int_loongarch_csrwr_w : ClangBuiltin<"__builtin_loongarch_csrwr_w">, ++ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>; ++ ++def int_loongarch_csrwr_d : ClangBuiltin<"__builtin_loongarch_csrwr_d">, ++ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], []>; ++ ++def int_loongarch_csrxchg_w : ClangBuiltin<"__builtin_loongarch_csrxchg_w">, ++ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; ++ ++def int_loongarch_csrxchg_d : ClangBuiltin<"__builtin_loongarch_csrxchg_d">, ++ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], []>; ++ ++def int_loongarch_iocsrrd_b : ClangBuiltin<"__builtin_loongarch_iocsrrd_b">, ++ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>; ++ ++def int_loongarch_iocsrrd_h : ClangBuiltin<"__builtin_loongarch_iocsrrd_h">, ++ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>; ++ ++def int_loongarch_iocsrrd_w : ClangBuiltin<"__builtin_loongarch_iocsrrd_w">, ++ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>; ++ ++def int_loongarch_iocsrrd_d : ClangBuiltin<"__builtin_loongarch_iocsrrd_d">, ++ Intrinsic<[llvm_i64_ty], [llvm_i32_ty], []>; ++ ++def int_loongarch_iocsrwr_b : ClangBuiltin<"__builtin_loongarch_iocsrwr_b">, ++ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty], []>; ++ ++def int_loongarch_iocsrwr_h : ClangBuiltin<"__builtin_loongarch_iocsrwr_h">, ++ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty], []>; ++ ++def int_loongarch_iocsrwr_w : ClangBuiltin<"__builtin_loongarch_iocsrwr_w">, ++ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty], []>; ++ ++def int_loongarch_iocsrwr_d : ClangBuiltin<"__builtin_loongarch_iocsrwr_d">, ++ Intrinsic<[], [llvm_i64_ty, llvm_i32_ty], []>; ++ ++def int_loongarch_cacop_w : ClangBuiltin<"__builtin_loongarch_cacop_w">, ++ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; ++ ++def int_loongarch_cacop_d : ClangBuiltin<"__builtin_loongarch_cacop_d">, ++ Intrinsic<[], [llvm_i32_ty, llvm_i64_ty, llvm_i64_ty], []>; ++ ++def int_loongarch_crc_w_b_w : ClangBuiltin<"__builtin_loongarch_crc_w_b_w">, ++ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>; ++ ++def int_loongarch_crc_w_h_w : ClangBuiltin<"__builtin_loongarch_crc_w_h_w">, ++ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>; ++ ++def int_loongarch_crc_w_w_w : ClangBuiltin<"__builtin_loongarch_crc_w_w_w">, ++ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>; ++ ++def int_loongarch_crc_w_d_w : ClangBuiltin<"__builtin_loongarch_crc_w_d_w">, ++ Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty], []>; ++ ++def int_loongarch_crcc_w_b_w : ClangBuiltin<"__builtin_loongarch_crcc_w_b_w">, ++ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>; ++ ++def int_loongarch_crcc_w_h_w : ClangBuiltin<"__builtin_loongarch_crcc_w_h_w">, ++ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>; ++ ++def int_loongarch_crcc_w_w_w : ClangBuiltin<"__builtin_loongarch_crcc_w_w_w">, ++ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>; ++ ++def int_loongarch_crcc_w_d_w : ClangBuiltin<"__builtin_loongarch_crcc_w_d_w">, ++ Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty], []>; ++ ++def int_loongarch_tlbclr : ClangBuiltin<"__builtin_loongarch_tlbclr">, ++ Intrinsic<[], [], []>; ++ ++def int_loongarch_tlbflush : ClangBuiltin<"__builtin_loongarch_tlbflush">, ++ Intrinsic<[], [], []>; ++ ++def int_loongarch_tlbfill : ClangBuiltin<"__builtin_loongarch_tlbfill">, ++ Intrinsic<[], [], []>; ++ ++def int_loongarch_tlbrd : ClangBuiltin<"__builtin_loongarch_tlbrd">, ++ Intrinsic<[], [], []>; ++ ++def int_loongarch_tlbwr : ClangBuiltin<"__builtin_loongarch_tlbwr">, ++ Intrinsic<[], [], []>; ++ ++def int_loongarch_tlbsrch : ClangBuiltin<"__builtin_loongarch_tlbsrch">, ++ Intrinsic<[], [], []>; ++ ++def int_loongarch_syscall : ClangBuiltin<"__builtin_loongarch_syscall">, ++ Intrinsic<[], [llvm_i64_ty], []>; ++ ++def int_loongarch_break : ClangBuiltin<"__builtin_loongarch_break">, ++ Intrinsic<[], [llvm_i64_ty], []>; ++ ++def int_loongarch_asrtle_d : ClangBuiltin<"__builtin_loongarch_asrtle_d">, ++ Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], []>; ++ ++def int_loongarch_asrtgt_d : ClangBuiltin<"__builtin_loongarch_asrtgt_d">, ++ Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], []>; ++ ++def int_loongarch_dbar : ClangBuiltin<"__builtin_loongarch_dbar">, ++ Intrinsic<[], [llvm_i64_ty], []>; ++ ++def int_loongarch_ibar : ClangBuiltin<"__builtin_loongarch_ibar">, ++ Intrinsic<[], [llvm_i64_ty], []>; ++ ++def int_loongarch_frecipe_s : ClangBuiltin<"__builtin_loongarch_frecipe_s">, ++ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>; ++ ++def int_loongarch_frecipe_d : ClangBuiltin<"__builtin_loongarch_frecipe_d">, ++ Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>; ++ ++def int_loongarch_frsqrte_s : ClangBuiltin<"__builtin_loongarch_frsqrte_s">, ++ Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>; ++ ++def int_loongarch_frsqrte_d : ClangBuiltin<"__builtin_loongarch_frsqrte_d">, ++ Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>; ++ ++} +diff --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h +index 01a64fb42..8931e8cab 100644 +--- a/llvm/include/llvm/MC/MCAsmBackend.h ++++ b/llvm/include/llvm/MC/MCAsmBackend.h +@@ -198,9 +198,9 @@ public: + + // Defined by linker relaxation targets to possibly emit LEB128 relocations + // and set Value at the relocated location. +- virtual std::pair +- relaxLEB128(MCLEBFragment &LF, MCAsmLayout &Layout, int64_t &Value) const { +- return std::make_pair(false, false); ++ virtual bool relaxLEB128(MCLEBFragment &LF, MCAsmLayout &Layout, ++ int64_t &Value) const { ++ return false; + } + + /// @} +diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h +index 7124df50b..cd79caab7 100644 +--- a/llvm/include/llvm/Object/ELFObjectFile.h ++++ b/llvm/include/llvm/Object/ELFObjectFile.h +@@ -61,7 +61,6 @@ class ELFObjectFileBase : public ObjectFile { + SubtargetFeatures getMIPSFeatures() const; + SubtargetFeatures getARMFeatures() const; + Expected getRISCVFeatures() const; +- SubtargetFeatures getLoongArchFeatures() const; + + StringRef getAMDGPUCPUName() const; + StringRef getNVPTXCPUName() const; +@@ -777,6 +776,16 @@ Expected ELFObjectFile::getSymbolFlags(DataRefImpl Sym) const { + // TODO: Actually report errors helpfully. + consumeError(NameOrErr.takeError()); + } ++ } else if (EF.getHeader().e_machine == ELF::EM_LOONGARCH) { ++ if (Expected NameOrErr = getSymbolName(Sym)) { ++ StringRef Name = *NameOrErr; ++ // Mark empty name symbols (used for label differences). ++ if (Name.empty()) ++ Result |= SymbolRef::SF_FormatSpecific; ++ } else { ++ // TODO: Actually report errors helpfully. ++ consumeError(NameOrErr.takeError()); ++ } + } else if (EF.getHeader().e_machine == ELF::EM_RISCV) { + if (Expected NameOrErr = getSymbolName(Sym)) { + StringRef Name = *NameOrErr; +diff --git a/llvm/include/llvm/TargetParser/LoongArchTargetParser.def b/llvm/include/llvm/TargetParser/LoongArchTargetParser.def +deleted file mode 100644 +index b20d12495..000000000 +--- a/llvm/include/llvm/TargetParser/LoongArchTargetParser.def ++++ /dev/null +@@ -1,23 +0,0 @@ +-#ifndef LOONGARCH_FEATURE +-#define LOONGARCH_FEATURE(NAME, KIND) +-#endif +- +-LOONGARCH_FEATURE("+64bit", FK_64BIT) +-LOONGARCH_FEATURE("+f", FK_FP32) +-LOONGARCH_FEATURE("+d", FK_FP64) +-LOONGARCH_FEATURE("+lsx", FK_LSX) +-LOONGARCH_FEATURE("+lasx", FK_LASX) +-LOONGARCH_FEATURE("+lbt", FK_LBT) +-LOONGARCH_FEATURE("+lvz", FK_LVZ) +-LOONGARCH_FEATURE("+ual", FK_UAL) +- +-#undef LOONGARCH_FEATURE +- +-#ifndef LOONGARCH_ARCH +-#define LOONGARCH_ARCH(NAME, KIND, FEATURES) +-#endif +- +-LOONGARCH_ARCH("loongarch64", AK_LOONGARCH64, FK_64BIT | FK_FP32 | FK_FP64 | FK_UAL) +-LOONGARCH_ARCH("la464", AK_LA464, FK_64BIT | FK_FP32 | FK_FP64 | FK_LSX | FK_LASX | FK_UAL) +- +-#undef LOONGARCH_ARCH +diff --git a/llvm/include/llvm/TargetParser/LoongArchTargetParser.h b/llvm/include/llvm/TargetParser/LoongArchTargetParser.h +deleted file mode 100644 +index 028844187..000000000 +--- a/llvm/include/llvm/TargetParser/LoongArchTargetParser.h ++++ /dev/null +@@ -1,77 +0,0 @@ +-//==-- LoongArch64TargetParser - Parser for LoongArch64 features --*- C++ -*-=// +-// +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +-// +-//===----------------------------------------------------------------------===// +-// +-// This file implements a target parser to recognise LoongArch hardware features +-// such as CPU/ARCH and extension names. +-// +-//===----------------------------------------------------------------------===// +- +-#ifndef LLVM_TARGETPARSER_LOONGARCHTARGETPARSER_H +-#define LLVM_TARGETPARSER_LOONGARCHTARGETPARSER_H +- +-#include "llvm/TargetParser/Triple.h" +-#include +- +-namespace llvm { +-class StringRef; +- +-namespace LoongArch { +- +-enum FeatureKind : uint32_t { +- // 64-bit ISA is available. +- FK_64BIT = 1 << 1, +- +- // Single-precision floating-point instructions are available. +- FK_FP32 = 1 << 2, +- +- // Double-precision floating-point instructions are available. +- FK_FP64 = 1 << 3, +- +- // Loongson SIMD Extension is available. +- FK_LSX = 1 << 4, +- +- // Loongson Advanced SIMD Extension is available. +- FK_LASX = 1 << 5, +- +- // Loongson Binary Translation Extension is available. +- FK_LBT = 1 << 6, +- +- // Loongson Virtualization Extension is available. +- FK_LVZ = 1 << 7, +- +- // Allow memory accesses to be unaligned. +- FK_UAL = 1 << 8, +-}; +- +-struct FeatureInfo { +- StringRef Name; +- FeatureKind Kind; +-}; +- +-enum class ArchKind { +-#define LOONGARCH_ARCH(NAME, KIND, FEATURES) KIND, +-#include "LoongArchTargetParser.def" +-}; +- +-struct ArchInfo { +- StringRef Name; +- ArchKind Kind; +- uint32_t Features; +-}; +- +-bool isValidArchName(StringRef Arch); +-bool getArchFeatures(StringRef Arch, std::vector &Features); +-bool isValidCPUName(StringRef TuneCPU); +-void fillValidCPUList(SmallVectorImpl &Values); +-StringRef getDefaultArch(bool Is64Bit); +- +-} // namespace LoongArch +- +-} // namespace llvm +- +-#endif // LLVM_TARGETPARSER_LOONGARCHTARGETPARSER_H +diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h +index 49ec8de9c..5b9bf8080 100644 +--- a/llvm/include/llvm/TargetParser/Triple.h ++++ b/llvm/include/llvm/TargetParser/Triple.h +@@ -236,12 +236,10 @@ public: + GNUABI64, + GNUEABI, + GNUEABIHF, +- GNUF32, +- GNUF64, +- GNUSF, + GNUX32, + GNUILP32, + CODE16, ++ GNUABILPX32, + EABI, + EABIHF, + Android, +@@ -580,9 +578,7 @@ public: + EnvironmentType Env = getEnvironment(); + return Env == Triple::GNU || Env == Triple::GNUABIN32 || + Env == Triple::GNUABI64 || Env == Triple::GNUEABI || +- Env == Triple::GNUEABIHF || Env == Triple::GNUF32 || +- Env == Triple::GNUF64 || Env == Triple::GNUSF || +- Env == Triple::GNUX32; ++ Env == Triple::GNUEABIHF || Env == Triple::GNUX32; + } + + /// Tests whether the OS is Haiku. +@@ -900,14 +896,20 @@ public: + : PointerWidth == 64; + } + +- /// Tests whether the target is 32-bit LoongArch. +- bool isLoongArch32() const { return getArch() == Triple::loongarch32; } ++ /// Tests whether the target is LoongArch 32-bit ++ bool isLoongArch32() const { ++ return getArch() == Triple::loongarch32; ++ } + +- /// Tests whether the target is 64-bit LoongArch. +- bool isLoongArch64() const { return getArch() == Triple::loongarch64; } ++ /// Tests whether the target is LoongArch 64-bit. ++ bool isLoongArch64() const { ++ return getArch() == Triple::loongarch64; ++ } + + /// Tests whether the target is LoongArch (32- and 64-bit). +- bool isLoongArch() const { return isLoongArch32() || isLoongArch64(); } ++ bool isLoongArch() const { ++ return getArch() == Triple::loongarch32 || getArch() == Triple::loongarch64; ++ } + + /// Tests whether the target is MIPS 32-bit (little and big endian). + bool isMIPS32() const { +diff --git a/llvm/include/module.modulemap b/llvm/include/module.modulemap +index 8930fa8c0..d77677c80 100644 +--- a/llvm/include/module.modulemap ++++ b/llvm/include/module.modulemap +@@ -400,7 +400,6 @@ module LLVM_Utils { + textual header "llvm/TargetParser/ARMTargetParser.def" + textual header "llvm/TargetParser/CSKYTargetParser.def" + textual header "llvm/TargetParser/X86TargetParser.def" +- textual header "llvm/TargetParser/LoongArchTargetParser.def" + } + + // This part of the module is usable from both C and C++ code. +diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +index a69b71451..2f90f1d00 100644 +--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp ++++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +@@ -200,6 +200,16 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx, + PersonalityEncoding = dwarf::DW_EH_PE_absptr; + TTypeEncoding = dwarf::DW_EH_PE_absptr; + break; ++ case Triple::loongarch32: ++ case Triple::loongarch64: ++ PersonalityEncoding = dwarf::DW_EH_PE_indirect; ++ ++ // Note: gas does not support pc-relative LSDA references. ++ LSDAEncoding = dwarf::DW_EH_PE_absptr; ++ ++ TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | ++ dwarf::DW_EH_PE_sdata4; ++ break; + case Triple::mips: + case Triple::mipsel: + case Triple::mips64: +@@ -282,14 +292,6 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx, + TTypeEncoding = dwarf::DW_EH_PE_absptr; + } + break; +- case Triple::loongarch32: +- case Triple::loongarch64: +- LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; +- PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | +- dwarf::DW_EH_PE_sdata4; +- TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | +- dwarf::DW_EH_PE_sdata4; +- break; + default: + break; + } +diff --git a/llvm/lib/CodeGen/XRayInstrumentation.cpp b/llvm/lib/CodeGen/XRayInstrumentation.cpp +index d40725838..6f97ac2e0 100644 +--- a/llvm/lib/CodeGen/XRayInstrumentation.cpp ++++ b/llvm/lib/CodeGen/XRayInstrumentation.cpp +@@ -226,7 +226,6 @@ bool XRayInstrumentation::runOnMachineFunction(MachineFunction &MF) { + case Triple::ArchType::thumb: + case Triple::ArchType::aarch64: + case Triple::ArchType::hexagon: +- case Triple::ArchType::loongarch64: + case Triple::ArchType::mips: + case Triple::ArchType::mipsel: + case Triple::ArchType::mips64: +diff --git a/llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt b/llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt +index e5f5a99c3..72a692977 100644 +--- a/llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt ++++ b/llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt +@@ -23,7 +23,6 @@ add_llvm_component_library(LLVMJITLink + ELF_aarch32.cpp + ELF_aarch64.cpp + ELF_i386.cpp +- ELF_loongarch.cpp + ELF_ppc64.cpp + ELF_riscv.cpp + ELF_x86_64.cpp +@@ -38,7 +37,6 @@ add_llvm_component_library(LLVMJITLink + aarch32.cpp + aarch64.cpp + i386.cpp +- loongarch.cpp + ppc64.cpp + riscv.cpp + x86_64.cpp +diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF.cpp +index fdcce20cd..f3fb2930c 100644 +--- a/llvm/lib/ExecutionEngine/JITLink/ELF.cpp ++++ b/llvm/lib/ExecutionEngine/JITLink/ELF.cpp +@@ -16,7 +16,6 @@ + #include "llvm/ExecutionEngine/JITLink/ELF_aarch32.h" + #include "llvm/ExecutionEngine/JITLink/ELF_aarch64.h" + #include "llvm/ExecutionEngine/JITLink/ELF_i386.h" +-#include "llvm/ExecutionEngine/JITLink/ELF_loongarch.h" + #include "llvm/ExecutionEngine/JITLink/ELF_ppc64.h" + #include "llvm/ExecutionEngine/JITLink/ELF_riscv.h" + #include "llvm/ExecutionEngine/JITLink/ELF_x86_64.h" +@@ -89,8 +88,6 @@ createLinkGraphFromELFObject(MemoryBufferRef ObjectBuffer) { + return createLinkGraphFromELFObject_aarch64(ObjectBuffer); + case ELF::EM_ARM: + return createLinkGraphFromELFObject_aarch32(ObjectBuffer); +- case ELF::EM_LOONGARCH: +- return createLinkGraphFromELFObject_loongarch(ObjectBuffer); + case ELF::EM_PPC64: { + if (DataEncoding == ELF::ELFDATA2LSB) + return createLinkGraphFromELFObject_ppc64le(ObjectBuffer); +@@ -122,10 +119,6 @@ void link_ELF(std::unique_ptr G, + case Triple::thumbeb: + link_ELF_aarch32(std::move(G), std::move(Ctx)); + return; +- case Triple::loongarch32: +- case Triple::loongarch64: +- link_ELF_loongarch(std::move(G), std::move(Ctx)); +- return; + case Triple::ppc64: + link_ELF_ppc64(std::move(G), std::move(Ctx)); + return; +diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp +deleted file mode 100644 +index aa9385fcb..000000000 +--- a/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp ++++ /dev/null +@@ -1,213 +0,0 @@ +-//===--- ELF_loongarch.cpp - JIT linker implementation for ELF/loongarch --===// +-// +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +-// +-//===----------------------------------------------------------------------===// +-// +-// ELF/loongarch jit-link implementation. +-// +-//===----------------------------------------------------------------------===// +- +-#include "llvm/ExecutionEngine/JITLink/ELF_loongarch.h" +-#include "llvm/BinaryFormat/ELF.h" +-#include "llvm/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.h" +-#include "llvm/ExecutionEngine/JITLink/JITLink.h" +-#include "llvm/ExecutionEngine/JITLink/loongarch.h" +-#include "llvm/Object/ELF.h" +-#include "llvm/Object/ELFObjectFile.h" +- +-#include "EHFrameSupportImpl.h" +-#include "ELFLinkGraphBuilder.h" +-#include "JITLinkGeneric.h" +- +-#define DEBUG_TYPE "jitlink" +- +-using namespace llvm; +-using namespace llvm::jitlink; +-using namespace llvm::jitlink::loongarch; +- +-namespace { +- +-class ELFJITLinker_loongarch : public JITLinker { +- friend class JITLinker; +- +-public: +- ELFJITLinker_loongarch(std::unique_ptr Ctx, +- std::unique_ptr G, +- PassConfiguration PassConfig) +- : JITLinker(std::move(Ctx), std::move(G), std::move(PassConfig)) {} +- +-private: +- Error applyFixup(LinkGraph &G, Block &B, const Edge &E) const { +- return loongarch::applyFixup(G, B, E); +- } +-}; +- +-template +-class ELFLinkGraphBuilder_loongarch : public ELFLinkGraphBuilder { +-private: +- static Expected +- getRelocationKind(const uint32_t Type) { +- using namespace loongarch; +- switch (Type) { +- case ELF::R_LARCH_64: +- return Pointer64; +- case ELF::R_LARCH_32: +- return Pointer32; +- case ELF::R_LARCH_32_PCREL: +- return Delta32; +- case ELF::R_LARCH_B26: +- return Branch26PCRel; +- case ELF::R_LARCH_PCALA_HI20: +- return Page20; +- case ELF::R_LARCH_PCALA_LO12: +- return PageOffset12; +- case ELF::R_LARCH_GOT_PC_HI20: +- return RequestGOTAndTransformToPage20; +- case ELF::R_LARCH_GOT_PC_LO12: +- return RequestGOTAndTransformToPageOffset12; +- } +- +- return make_error( +- "Unsupported loongarch relocation:" + formatv("{0:d}: ", Type) + +- object::getELFRelocationTypeName(ELF::EM_LOONGARCH, Type)); +- } +- +- Error addRelocations() override { +- LLVM_DEBUG(dbgs() << "Processing relocations:\n"); +- +- using Base = ELFLinkGraphBuilder; +- using Self = ELFLinkGraphBuilder_loongarch; +- for (const auto &RelSect : Base::Sections) +- if (Error Err = Base::forEachRelaRelocation(RelSect, this, +- &Self::addSingleRelocation)) +- return Err; +- +- return Error::success(); +- } +- +- Error addSingleRelocation(const typename ELFT::Rela &Rel, +- const typename ELFT::Shdr &FixupSect, +- Block &BlockToFix) { +- using Base = ELFLinkGraphBuilder; +- +- uint32_t SymbolIndex = Rel.getSymbol(false); +- auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec); +- if (!ObjSymbol) +- return ObjSymbol.takeError(); +- +- Symbol *GraphSymbol = Base::getGraphSymbol(SymbolIndex); +- if (!GraphSymbol) +- return make_error( +- formatv("Could not find symbol at given index, did you add it to " +- "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}", +- SymbolIndex, (*ObjSymbol)->st_shndx, +- Base::GraphSymbols.size()), +- inconvertibleErrorCode()); +- +- uint32_t Type = Rel.getType(false); +- Expected Kind = getRelocationKind(Type); +- if (!Kind) +- return Kind.takeError(); +- +- int64_t Addend = Rel.r_addend; +- auto FixupAddress = orc::ExecutorAddr(FixupSect.sh_addr) + Rel.r_offset; +- Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress(); +- Edge GE(*Kind, Offset, *GraphSymbol, Addend); +- LLVM_DEBUG({ +- dbgs() << " "; +- printEdge(dbgs(), BlockToFix, GE, loongarch::getEdgeKindName(*Kind)); +- dbgs() << "\n"; +- }); +- +- BlockToFix.addEdge(std::move(GE)); +- +- return Error::success(); +- } +- +-public: +- ELFLinkGraphBuilder_loongarch(StringRef FileName, +- const object::ELFFile &Obj, Triple TT, +- SubtargetFeatures Features) +- : ELFLinkGraphBuilder(Obj, std::move(TT), std::move(Features), +- FileName, loongarch::getEdgeKindName) {} +-}; +- +-Error buildTables_ELF_loongarch(LinkGraph &G) { +- LLVM_DEBUG(dbgs() << "Visiting edges in graph:\n"); +- +- GOTTableManager GOT; +- PLTTableManager PLT(GOT); +- visitExistingEdges(G, GOT, PLT); +- return Error::success(); +-} +- +-} // namespace +- +-namespace llvm { +-namespace jitlink { +- +-Expected> +-createLinkGraphFromELFObject_loongarch(MemoryBufferRef ObjectBuffer) { +- LLVM_DEBUG({ +- dbgs() << "Building jitlink graph for new input " +- << ObjectBuffer.getBufferIdentifier() << "...\n"; +- }); +- +- auto ELFObj = object::ObjectFile::createELFObjectFile(ObjectBuffer); +- if (!ELFObj) +- return ELFObj.takeError(); +- +- auto Features = (*ELFObj)->getFeatures(); +- if (!Features) +- return Features.takeError(); +- +- if ((*ELFObj)->getArch() == Triple::loongarch64) { +- auto &ELFObjFile = cast>(**ELFObj); +- return ELFLinkGraphBuilder_loongarch( +- (*ELFObj)->getFileName(), ELFObjFile.getELFFile(), +- (*ELFObj)->makeTriple(), std::move(*Features)) +- .buildGraph(); +- } +- +- assert((*ELFObj)->getArch() == Triple::loongarch32 && +- "Invalid triple for LoongArch ELF object file"); +- auto &ELFObjFile = cast>(**ELFObj); +- return ELFLinkGraphBuilder_loongarch( +- (*ELFObj)->getFileName(), ELFObjFile.getELFFile(), +- (*ELFObj)->makeTriple(), std::move(*Features)) +- .buildGraph(); +-} +- +-void link_ELF_loongarch(std::unique_ptr G, +- std::unique_ptr Ctx) { +- PassConfiguration Config; +- const Triple &TT = G->getTargetTriple(); +- if (Ctx->shouldAddDefaultTargetPasses(TT)) { +- // Add eh-frame passes. +- Config.PrePrunePasses.push_back(DWARFRecordSectionSplitter(".eh_frame")); +- Config.PrePrunePasses.push_back( +- EHFrameEdgeFixer(".eh_frame", G->getPointerSize(), Pointer32, Pointer64, +- Delta32, Delta64, NegDelta32)); +- Config.PrePrunePasses.push_back(EHFrameNullTerminator(".eh_frame")); +- +- // Add a mark-live pass. +- if (auto MarkLive = Ctx->getMarkLivePass(TT)) +- Config.PrePrunePasses.push_back(std::move(MarkLive)); +- else +- Config.PrePrunePasses.push_back(markAllSymbolsLive); +- +- // Add an in-place GOT/PLTStubs build pass. +- Config.PostPrunePasses.push_back(buildTables_ELF_loongarch); +- } +- +- if (auto Err = Ctx->modifyPassConfig(*G, Config)) +- return Ctx->notifyFailed(std::move(Err)); +- +- ELFJITLinker_loongarch::link(std::move(Ctx), std::move(G), std::move(Config)); +-} +- +-} // namespace jitlink +-} // namespace llvm +diff --git a/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp b/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp +index 7f743dba6..16cacafb6 100644 +--- a/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp ++++ b/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp +@@ -15,7 +15,6 @@ + #include "llvm/ExecutionEngine/JITLink/MachO.h" + #include "llvm/ExecutionEngine/JITLink/aarch64.h" + #include "llvm/ExecutionEngine/JITLink/i386.h" +-#include "llvm/ExecutionEngine/JITLink/loongarch.h" + #include "llvm/ExecutionEngine/JITLink/x86_64.h" + #include "llvm/Support/Format.h" + #include "llvm/Support/MemoryBuffer.h" +@@ -429,9 +428,6 @@ AnonymousPointerCreator getAnonymousPointerCreator(const Triple &TT) { + return x86_64::createAnonymousPointer; + case Triple::x86: + return i386::createAnonymousPointer; +- case Triple::loongarch32: +- case Triple::loongarch64: +- return loongarch::createAnonymousPointer; + default: + return nullptr; + } +@@ -445,9 +441,6 @@ PointerJumpStubCreator getPointerJumpStubCreator(const Triple &TT) { + return x86_64::createAnonymousPointerJumpStub; + case Triple::x86: + return i386::createAnonymousPointerJumpStub; +- case Triple::loongarch32: +- case Triple::loongarch64: +- return loongarch::createAnonymousPointerJumpStub; + default: + return nullptr; + } +diff --git a/llvm/lib/ExecutionEngine/JITLink/loongarch.cpp b/llvm/lib/ExecutionEngine/JITLink/loongarch.cpp +deleted file mode 100644 +index d1e44ec18..000000000 +--- a/llvm/lib/ExecutionEngine/JITLink/loongarch.cpp ++++ /dev/null +@@ -1,60 +0,0 @@ +-//===--- loongarch.cpp - Generic JITLink loongarch edge kinds, utilities --===// +-// +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +-// +-//===----------------------------------------------------------------------===// +-// +-// Generic utilities for graphs representing loongarch objects. +-// +-//===----------------------------------------------------------------------===// +- +-#include "llvm/ExecutionEngine/JITLink/loongarch.h" +- +-#define DEBUG_TYPE "jitlink" +- +-namespace llvm { +-namespace jitlink { +-namespace loongarch { +- +-const char NullPointerContent[8] = {0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00}; +- +-const uint8_t LA64StubContent[StubEntrySize] = { +- 0x14, 0x00, 0x00, 0x1a, // pcalau12i $t8, %page20(imm) +- 0x94, 0x02, 0xc0, 0x28, // ld.d $t8, $t8, %pageoff12(imm) +- 0x80, 0x02, 0x00, 0x4c // jr $t8 +-}; +- +-const uint8_t LA32StubContent[StubEntrySize] = { +- 0x14, 0x00, 0x00, 0x1a, // pcalau12i $t8, %page20(imm) +- 0x94, 0x02, 0x80, 0x28, // ld.w $t8, $t8, %pageoff12(imm) +- 0x80, 0x02, 0x00, 0x4c // jr $t8 +-}; +- +-const char *getEdgeKindName(Edge::Kind K) { +-#define KIND_NAME_CASE(K) \ +- case K: \ +- return #K; +- +- switch (K) { +- KIND_NAME_CASE(Pointer64) +- KIND_NAME_CASE(Pointer32) +- KIND_NAME_CASE(Delta32) +- KIND_NAME_CASE(NegDelta32) +- KIND_NAME_CASE(Delta64) +- KIND_NAME_CASE(Branch26PCRel) +- KIND_NAME_CASE(Page20) +- KIND_NAME_CASE(PageOffset12) +- KIND_NAME_CASE(RequestGOTAndTransformToPage20) +- KIND_NAME_CASE(RequestGOTAndTransformToPageOffset12) +- default: +- return getGenericEdgeKindName(K); +- } +-#undef KIND_NAME_CASE +-} +- +-} // namespace loongarch +-} // namespace jitlink +-} // namespace llvm +diff --git a/llvm/lib/ExecutionEngine/Orc/EPCIndirectionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/EPCIndirectionUtils.cpp +index 833be826f..ae1c66146 100644 +--- a/llvm/lib/ExecutionEngine/Orc/EPCIndirectionUtils.cpp ++++ b/llvm/lib/ExecutionEngine/Orc/EPCIndirectionUtils.cpp +@@ -246,9 +246,6 @@ EPCIndirectionUtils::Create(ExecutorProcessControl &EPC) { + case Triple::x86: + return CreateWithABI(EPC); + +- case Triple::loongarch64: +- return CreateWithABI(EPC); +- + case Triple::mips: + return CreateWithABI(EPC); + +@@ -262,6 +259,9 @@ EPCIndirectionUtils::Create(ExecutorProcessControl &EPC) { + case Triple::riscv64: + return CreateWithABI(EPC); + ++ case Triple::loongarch64: ++ return CreateWithABI(EPC); ++ + case Triple::x86_64: + if (TT.getOS() == Triple::OSType::Win32) + return CreateWithABI(EPC); +diff --git a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp +index f9efff148..01afc648f 100644 +--- a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp ++++ b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp +@@ -193,12 +193,6 @@ createLocalIndirectStubsManagerBuilder(const Triple &T) { + orc::LocalIndirectStubsManager>(); + }; + +- case Triple::loongarch64: +- return []() { +- return std::make_unique< +- orc::LocalIndirectStubsManager>(); +- }; +- + case Triple::mips: + return [](){ + return std::make_unique< +diff --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp +index 833dcb9d5..e5fdad732 100644 +--- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp ++++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp +@@ -728,7 +728,6 @@ Error LLJITBuilderState::prepareForConstruction() { + bool UseJITLink = false; + switch (TT.getArch()) { + case Triple::riscv64: +- case Triple::loongarch64: + UseJITLink = true; + break; + case Triple::aarch64: +@@ -899,7 +898,8 @@ LLJIT::createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES) { + + if (S.JTMB->getTargetTriple().isOSBinFormatELF() && + (S.JTMB->getTargetTriple().getArch() == Triple::ArchType::ppc64 || +- S.JTMB->getTargetTriple().getArch() == Triple::ArchType::ppc64le)) ++ S.JTMB->getTargetTriple().getArch() == Triple::ArchType::ppc64le || ++ S.JTMB->getTargetTriple().getArch() == Triple::ArchType::loongarch64)) + Layer->setAutoClaimResponsibilityForObjectSymbols(true); + + // FIXME: Explicit conversion to std::unique_ptr added to silence +diff --git a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp +index d95a64293..f52c548d8 100644 +--- a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp ++++ b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp +@@ -120,10 +120,6 @@ createLocalLazyCallThroughManager(const Triple &T, ExecutionSession &ES, + case Triple::x86: + return LocalLazyCallThroughManager::Create(ES, ErrorHandlerAddr); + +- case Triple::loongarch64: +- return LocalLazyCallThroughManager::Create( +- ES, ErrorHandlerAddr); +- + case Triple::mips: + return LocalLazyCallThroughManager::Create(ES, + ErrorHandlerAddr); +@@ -140,6 +136,10 @@ createLocalLazyCallThroughManager(const Triple &T, ExecutionSession &ES, + return LocalLazyCallThroughManager::Create(ES, + ErrorHandlerAddr); + ++ case Triple::loongarch64: ++ return LocalLazyCallThroughManager::Create( ++ ES, ErrorHandlerAddr); ++ + case Triple::x86_64: + if (T.getOS() == Triple::OSType::Win32) + return LocalLazyCallThroughManager::Create( +diff --git a/llvm/lib/ExecutionEngine/Orc/OrcABISupport.cpp b/llvm/lib/ExecutionEngine/Orc/OrcABISupport.cpp +index 6d5681993..57e9a9414 100644 +--- a/llvm/lib/ExecutionEngine/Orc/OrcABISupport.cpp ++++ b/llvm/lib/ExecutionEngine/Orc/OrcABISupport.cpp +@@ -1090,151 +1090,199 @@ void OrcLoongArch64::writeResolverCode(char *ResolverWorkingMem, + ExecutorAddr ReentryFnAddr, + ExecutorAddr ReentryCtxAddr) { + +- LLVM_DEBUG({ +- dbgs() << "Writing resolver code to " +- << formatv("{0:x16}", ResolverTargetAddress) << "\n"; +- }); +- + const uint32_t ResolverCode[] = { +- 0x02fde063, // 0x0: addi.d $sp, $sp, -136(0xf78) +- 0x29c00061, // 0x4: st.d $ra, $sp, 0 +- 0x29c02064, // 0x8: st.d $a0, $sp, 8(0x8) +- 0x29c04065, // 0xc: st.d $a1, $sp, 16(0x10) +- 0x29c06066, // 0x10: st.d $a2, $sp, 24(0x18) +- 0x29c08067, // 0x14: st.d $a3, $sp, 32(0x20) +- 0x29c0a068, // 0x18: st.d $a4, $sp, 40(0x28) +- 0x29c0c069, // 0x1c: st.d $a5, $sp, 48(0x30) +- 0x29c0e06a, // 0x20: st.d $a6, $sp, 56(0x38) +- 0x29c1006b, // 0x24: st.d $a7, $sp, 64(0x40) +- 0x2bc12060, // 0x28: fst.d $fa0, $sp, 72(0x48) +- 0x2bc14061, // 0x2c: fst.d $fa1, $sp, 80(0x50) +- 0x2bc16062, // 0x30: fst.d $fa2, $sp, 88(0x58) +- 0x2bc18063, // 0x34: fst.d $fa3, $sp, 96(0x60) +- 0x2bc1a064, // 0x38: fst.d $fa4, $sp, 104(0x68) +- 0x2bc1c065, // 0x3c: fst.d $fa5, $sp, 112(0x70) +- 0x2bc1e066, // 0x40: fst.d $fa6, $sp, 120(0x78) +- 0x2bc20067, // 0x44: fst.d $fa7, $sp, 128(0x80) +- 0x1c000004, // 0x48: pcaddu12i $a0, 0 +- 0x28c1c084, // 0x4c: ld.d $a0, $a0, 112(0x70) +- 0x001501a5, // 0x50: move $a1, $t1 +- 0x02ffd0a5, // 0x54: addi.d $a1, $a1, -12(0xff4) +- 0x1c000006, // 0x58: pcaddu12i $a2, 0 +- 0x28c1a0c6, // 0x5c: ld.d $a2, $a2, 104(0x68) +- 0x4c0000c1, // 0x60: jirl $ra, $a2, 0 +- 0x0015008c, // 0x64: move $t0, $a0 +- 0x2b820067, // 0x68: fld.d $fa7, $sp, 128(0x80) +- 0x2b81e066, // 0x6c: fld.d $fa6, $sp, 120(0x78) +- 0x2b81c065, // 0x70: fld.d $fa5, $sp, 112(0x70) +- 0x2b81a064, // 0x74: fld.d $fa4, $sp, 104(0x68) +- 0x2b818063, // 0x78: fld.d $fa3, $sp, 96(0x60) +- 0x2b816062, // 0x7c: fld.d $fa2, $sp, 88(0x58) +- 0x2b814061, // 0x80: fld.d $fa1, $sp, 80(0x50) +- 0x2b812060, // 0x84: fld.d $fa0, $sp, 72(0x48) +- 0x28c1006b, // 0x88: ld.d $a7, $sp, 64(0x40) +- 0x28c0e06a, // 0x8c: ld.d $a6, $sp, 56(0x38) +- 0x28c0c069, // 0x90: ld.d $a5, $sp, 48(0x30) +- 0x28c0a068, // 0x94: ld.d $a4, $sp, 40(0x28) +- 0x28c08067, // 0x98: ld.d $a3, $sp, 32(0x20) +- 0x28c06066, // 0x9c: ld.d $a2, $sp, 24(0x18) +- 0x28c04065, // 0xa0: ld.d $a1, $sp, 16(0x10) +- 0x28c02064, // 0xa4: ld.d $a0, $sp, 8(0x8) +- 0x28c00061, // 0xa8: ld.d $ra, $sp, 0 +- 0x02c22063, // 0xac: addi.d $sp, $sp, 136(0x88) +- 0x4c000180, // 0xb0: jr $t0 +- 0x00000000, // 0xb4: padding to align at 8 bytes +- 0x01234567, // 0xb8: Lreentry_ctx_ptr: +- 0xdeedbeef, // 0xbc: .dword 0 +- 0x98765432, // 0xc0: Lreentry_fn_ptr: +- 0xcafef00d, // 0xc4: .dword 0 ++ // resolver_entry: ++ 0x02fc8063, // 0x0: addi.d $r3,$r3,-224(0xf20) ++ 0x29c00064, // 0x4: st.d $r4,$r3,0 ++ 0x29c02065, // 0x8: st.d $r5,$r3,8(0x8) ++ 0x29c04066, // 0xc: st.d $r6,$r3,16(0x10) ++ 0x29c06067, // 0x10: st.d $r7,$r3,24(0x18) ++ 0x29c08068, // 0x14: st.d $r8,$r3,32(0x20) ++ 0x29c0a069, // 0x18: st.d $r9,$r3,40(0x28) ++ 0x29c0c06a, // 0x1c: st.d $r10,$r3,48(0x30) ++ 0x29c0e06b, // 0x20: st.d $r11,$r3,56(0x38) ++ 0x29c1006c, // 0x24: st.d $r12,$r3,64(0x40) ++ 0x29c1206d, // 0x28: st.d $r13,$r3,72(0x48) ++ 0x29c1406e, // 0x2c: st.d $r14,$r3,80(0x50) ++ 0x29c1606f, // 0x30: st.d $r15,$r3,88(0x58) ++ 0x29c18070, // 0x34: st.d $r16,$r3,96(0x60) ++ 0x29c1a071, // 0x38: st.d $r17,$r3,104(0x68) ++ 0x29c1c072, // 0x3c: st.d $r18,$r3,112(0x70) ++ 0x29c1e073, // 0x40: st.d $r19,$r3,120(0x78) ++ 0x29c20074, // 0x44: st.d $r20,$r3,128(0x80) ++ 0x29c22076, // 0x48: st.d $r22,$r3,136(0x88) ++ 0x29c24077, // 0x4c: st.d $r23,$r3,144(0x90) ++ 0x29c26078, // 0x50: st.d $r24,$r3,152(0x98) ++ 0x29c28079, // 0x54: st.d $r25,$r3,160(0xa0) ++ 0x29c2a07a, // 0x58: st.d $r26,$r3,168(0xa8) ++ 0x29c2c07b, // 0x5c: st.d $r27,$r3,176(0xb0) ++ 0x29c2e07c, // 0x60: st.d $r28,$r3,184(0xb8) ++ 0x29c3007d, // 0x64: st.d $r29,$r3,192(0xc0) ++ 0x29c3207e, // 0x68: st.d $r30,$r3,200(0xc8) ++ 0x29c3407f, // 0x6c: st.d $r31,$r3,208(0xd0) ++ 0x29c36061, // 0x70: st.d $r1,$r3,216(0xd8) ++ // JIT re-entry ctx addr. ++ 0x00000000, // 0x74: lu12i.w $a0,hi(ctx) ++ 0x00000000, // 0x78: ori $a0,$a0,lo(ctx) ++ 0x00000000, // 0x7c: lu32i.d $a0,higher(ctx) ++ 0x00000000, // 0x80: lu52i.d $a0,$a0,highest(ctx) ++ ++ 0x00150025, // 0x84: move $r5,$r1 ++ 0x02ffa0a5, // 0x88: addi.d $r5,$r5,-24(0xfe8) ++ ++ // JIT re-entry fn addr: ++ 0x00000000, // 0x8c: lu12i.w $t0,hi(reentry) ++ 0x00000000, // 0x90: ori $t0,$t0,lo(reentry) ++ 0x00000000, // 0x94: lu32i.d $t0,higher(reentry) ++ 0x00000000, // 0x98: lu52i.d $t0,$t0,highest(reentry) ++ 0x4c0002a1, // 0x9c: jirl $r1,$r21,0 ++ 0x00150095, // 0xa0: move $r21,$r4 ++ 0x28c36061, // 0xa4: ld.d $r1,$r3,216(0xd8) ++ 0x28c3407f, // 0xa8: ld.d $r31,$r3,208(0xd0) ++ 0x28c3207e, // 0xac: ld.d $r30,$r3,200(0xc8) ++ 0x28c3007d, // 0xb0: ld.d $r29,$r3,192(0xc0) ++ 0x28c2e07c, // 0xb4: ld.d $r28,$r3,184(0xb8) ++ 0x28c2c07b, // 0xb8: ld.d $r27,$r3,176(0xb0) ++ 0x28c2a07a, // 0xbc: ld.d $r26,$r3,168(0xa8) ++ 0x28c28079, // 0xc0: ld.d $r25,$r3,160(0xa0) ++ 0x28c26078, // 0xc4: ld.d $r24,$r3,152(0x98) ++ 0x28c24077, // 0xc8: ld.d $r23,$r3,144(0x90) ++ 0x28c22076, // 0xcc: ld.d $r22,$r3,136(0x88) ++ 0x28c20074, // 0xd0: ld.d $r20,$r3,128(0x80) ++ 0x28c1e073, // 0xd4: ld.d $r19,$r3,120(0x78) ++ 0x28c1c072, // 0xd8: ld.d $r18,$r3,112(0x70) ++ 0x28c1a071, // 0xdc: ld.d $r17,$r3,104(0x68) ++ 0x28c18070, // 0xe0: ld.d $r16,$r3,96(0x60) ++ 0x28c1606f, // 0xe4: ld.d $r15,$r3,88(0x58) ++ 0x28c1406e, // 0xe8: ld.d $r14,$r3,80(0x50) ++ 0x28c1206d, // 0xec: ld.d $r13,$r3,72(0x48) ++ 0x28c1006c, // 0xf0: ld.d $r12,$r3,64(0x40) ++ 0x28c0e06b, // 0xf4: ld.d $r11,$r3,56(0x38) ++ 0x28c0c06a, // 0xf8: ld.d $r10,$r3,48(0x30) ++ 0x28c0a069, // 0xfc: ld.d $r9,$r3,40(0x28) ++ 0x28c08068, // 0x100: ld.d $r8,$r3,32(0x20) ++ 0x28c06067, // 0x104: ld.d $r7,$r3,24(0x18) ++ 0x28c04066, // 0x108: ld.d $r6,$r3,16(0x10) ++ 0x28c02065, // 0x10c: ld.d $r5,$r3,8(0x8) ++ 0x28c00064, // 0x110: ld.d $r4,$r3,0 ++ 0x02c38063, // 0x114: addi.d $r3,$r3,224(0xe0) ++ 0x00150281, // 0x118: move $r1,$r20 ++ 0x4c0002a0, // 0x11c: jirl $r0,$r21,0 + }; + +- const unsigned ReentryCtxAddrOffset = 0xb8; +- const unsigned ReentryFnAddrOffset = 0xc0; ++ const unsigned ReentryFnAddrOffset = 0x8c; // JIT re-entry fn addr lu12i.w ++ const unsigned ReentryCtxAddrOffset = 0x74; // JIT re-entry ctx addr lu12i.w + + memcpy(ResolverWorkingMem, ResolverCode, sizeof(ResolverCode)); +- memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnAddr, +- sizeof(uint64_t)); +- memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxAddr, +- sizeof(uint64_t)); ++ ++ uint32_t ReentryCtxLU12i = 0x14000004 | ((ReentryCtxAddr.getValue() << 32 >> 44) << 5); ++ uint32_t ReentryCtxORi = 0x03800084 | ((ReentryCtxAddr.getValue() & 0xFFF) << 10); ++ uint32_t ReentryCtxLU32i = 0x16000004 | ((ReentryCtxAddr.getValue() << 12 >> 44) << 5); ++ uint32_t ReentryCtxLU52i = 0x03000084 | ((ReentryCtxAddr.getValue() >> 52) << 10); ++ ++ memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxLU12i, ++ sizeof(ReentryCtxLU12i)); ++ memcpy(ResolverWorkingMem + (ReentryCtxAddrOffset + 4), &ReentryCtxORi, ++ sizeof(ReentryCtxORi)); ++ memcpy(ResolverWorkingMem + (ReentryCtxAddrOffset + 8), &ReentryCtxLU32i, ++ sizeof(ReentryCtxLU32i)); ++ memcpy(ResolverWorkingMem + (ReentryCtxAddrOffset + 12), &ReentryCtxLU52i, ++ sizeof(ReentryCtxLU52i)); ++ ++ uint32_t ReentryLU12i = 0x14000015 | ((ReentryFnAddr.getValue() << 32 >> 44) << 5); ++ uint32_t ReentryORi = 0x038002b5 | ((ReentryFnAddr.getValue() & 0xFFF) << 10); ++ uint32_t ReentryLU32i = 0x16000015 | ((ReentryFnAddr.getValue() << 12 >> 44) << 5); ++ uint32_t ReentryLU52i = 0x030002b5 | ((ReentryFnAddr.getValue() >> 52) << 10); ++ ++ memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryLU12i, ++ sizeof(ReentryLU12i)); ++ memcpy(ResolverWorkingMem + (ReentryFnAddrOffset + 4), &ReentryORi, ++ sizeof(ReentryORi)); ++ memcpy(ResolverWorkingMem + (ReentryFnAddrOffset + 8), &ReentryLU32i, ++ sizeof(ReentryLU32i)); ++ memcpy(ResolverWorkingMem + (ReentryFnAddrOffset + 12), &ReentryLU52i, ++ sizeof(ReentryLU52i)); + } + + void OrcLoongArch64::writeTrampolines(char *TrampolineBlockWorkingMem, + ExecutorAddr TrampolineBlockTargetAddress, +- ExecutorAddr ResolverAddr, ++ ExecutorAddr ResolverFnAddr, + unsigned NumTrampolines) { + +- LLVM_DEBUG({ +- dbgs() << "Writing trampoline code to " +- << formatv("{0:x16}", TrampolineBlockTargetAddress) << "\n"; +- }); +- +- unsigned OffsetToPtr = alignTo(NumTrampolines * TrampolineSize, 8); +- +- memcpy(TrampolineBlockWorkingMem + OffsetToPtr, &ResolverAddr, +- sizeof(uint64_t)); +- + uint32_t *Trampolines = + reinterpret_cast(TrampolineBlockWorkingMem); +- for (unsigned I = 0; I < NumTrampolines; ++I, OffsetToPtr -= TrampolineSize) { +- uint32_t Hi20 = (OffsetToPtr + 0x800) & 0xfffff000; +- uint32_t Lo12 = OffsetToPtr - Hi20; +- Trampolines[4 * I + 0] = +- 0x1c00000c | +- (((Hi20 >> 12) & 0xfffff) << 5); // pcaddu12i $t0, %pc_hi20(Lptr) +- Trampolines[4 * I + 1] = +- 0x28c0018c | ((Lo12 & 0xfff) << 10); // ld.d $t0, $t0, %pc_lo12(Lptr) +- Trampolines[4 * I + 2] = 0x4c00018d; // jirl $t1, $t0, 0 +- Trampolines[4 * I + 3] = 0x0; // padding ++ ++ uint64_t HiBits = ((ResolverFnAddr.getValue() << 32 >> 44) << 5); ++ uint64_t LoBits = ((ResolverFnAddr.getValue() & 0xFFF) << 10); ++ uint64_t HigherBits = ((ResolverFnAddr.getValue() << 12 >> 44) << 5); ++ uint64_t HighestBits = ((ResolverFnAddr.getValue() >> 52) << 10); ++ ++ for (unsigned I = 0; I < NumTrampolines; ++I) { ++ Trampolines[10 * I + 0] = 0x00150034; // move $t8,$ra ++ Trampolines[10 * I + 1] = ++ 0x14000015 | HiBits; // lu12i.w $r21,hi(ResolveAddr) ++ Trampolines[10 * I + 2] = ++ 0x038002b5 | LoBits; // ori $r21,$r21,lo(ResolveAddr) ++ Trampolines[10 * I + 3] = ++ 0x16000015 | HigherBits; // lu32i $r21,higher(ResolveAddr) ++ Trampolines[10 * I + 4] = ++ 0x030002b5 | HighestBits; // lu52i $r21,$r21,highest(ResolveAddr) ++ Trampolines[10 * I + 5] = 0x4c0002a1; // jirl $ra, $r21, 0 + } + } + +-void OrcLoongArch64::writeIndirectStubsBlock( +- char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, +- ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs) { ++void OrcLoongArch64::writeIndirectStubsBlock(char *StubsBlockWorkingMem, ++ ExecutorAddr StubsBlockTargetAddress, ++ ExecutorAddr PointersBlockTargetAddress, ++ unsigned NumStubs) { + // Stub format is: + // + // .section __orc_stubs + // stub1: +- // pcaddu12i $t0, %pc_hi20(ptr1) ; PC-rel load of ptr1 +- // ld.d $t0, $t0, %pc_lo12(ptr1) +- // jr $t0 ; Jump to resolver +- // .dword 0 ; Pad to 16 bytes ++ // lu12i.w $r21, %abs(ptr1)<<32>>44 ++ // ori $r21, $r21, %abs(ptr1)&0xfff ++ // lu32i.d $r21, %abs(ptr1)<<12>>44 ++ // lu52i.d $r21, $r21, %abs(ptr1)>>52 ++ // ld.d $r21, $r21, 0 ++ // jirl $r0, $r21, 0 + // stub2: +- // pcaddu12i $t0, %pc_hi20(ptr2) ; PC-rel load of ptr2 +- // ld.d $t0, $t0, %pc_lo12(ptr2) +- // jr $t0 ; Jump to resolver +- // .dword 0 ; Pad to 16 bytes ++ // lu12i.w $r21, %abs(ptr2)<<32>>44 ++ // ori $r21, $r21, %abs(ptr2)&0xfff ++ // lu32i.d $r21, %abs(ptr2)<<12>>44 ++ // lu52i.d $r21, $r21, %abs(ptr2)>>52 ++ // ld.d $r21, $r21, 0 ++ // jirl $r0, $r21, 0 ++ // + // ... + // + // .section __orc_ptrs + // ptr1: +- // .dword 0x0 ++ // .dword 0x0 + // ptr2: +- // .dword 0x0 ++ // .dword 0x0 ++ // + // ... +- LLVM_DEBUG({ +- dbgs() << "Writing stubs code to " +- << formatv("{0:x16}", StubsBlockTargetAddress) << "\n"; +- }); ++ + assert(stubAndPointerRangesOk( + StubsBlockTargetAddress, PointersBlockTargetAddress, NumStubs) && + "PointersBlock is out of range"); + ++ // Populate the stubs page stubs and mark it executable. + uint32_t *Stub = reinterpret_cast(StubsBlockWorkingMem); ++ uint64_t PtrAddr = PointersBlockTargetAddress.getValue(); + +- for (unsigned I = 0; I < NumStubs; ++I) { +- uint64_t PtrDisplacement = +- PointersBlockTargetAddress - StubsBlockTargetAddress; +- uint32_t Hi20 = (PtrDisplacement + 0x800) & 0xfffff000; +- uint32_t Lo12 = PtrDisplacement - Hi20; +- Stub[4 * I + 0] = 0x1c00000c | (((Hi20 >> 12) & 0xfffff) +- << 5); // pcaddu12i $t0, %pc_hi20(Lptr) +- Stub[4 * I + 1] = +- 0x28c0018c | ((Lo12 & 0xfff) << 10); // ld.d $t0, $t0, %pc_lo12(Lptr) +- Stub[4 * I + 2] = 0x4c000180; // jr $t0 +- Stub[4 * I + 3] = 0x0; // padding +- PointersBlockTargetAddress += PointerSize; +- StubsBlockTargetAddress += StubSize; ++ for (unsigned I = 0; I < NumStubs; ++I, PtrAddr += 8) { ++ uint64_t HiBits = ((PtrAddr << 32 >> 44) << 5); ++ uint64_t LoBits = ((PtrAddr & 0xFFF) << 10); ++ uint64_t HigherBits = ((PtrAddr << 12 >> 44) << 5); ++ uint64_t HighestBits = ((PtrAddr >> 52) << 10); ++ Stub[8 * I + 0] = 0x14000015 | HiBits; // lu12i.w $r21, hi(PtrAddr) ++ Stub[8 * I + 1] = 0x038002b5 | LoBits; // ori $r21, $r21, lo(PtrAddr) ++ Stub[8 * I + 2] = 0x16000015 | HigherBits; // lu32i.d $r21, higher(PtrAddr) ++ Stub[8 * I + 3] = ++ 0x030002b5 | HighestBits; // lu52i.d $r21, $r21, highest(PtrAddr) ++ Stub[8 * I + 4] = 0x28c002b5; // ld.d $r21, $r21, 0 ++ Stub[8 * I + 5] = 0x4c0002a0; // jirl $r0, $r21, 0 + } + } + +diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +index 9fdabf310..2fc2f01a0 100644 +--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp ++++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +@@ -646,6 +646,191 @@ void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section, + } + } + ++void RuntimeDyldELF::resolveLoongArch64Relocation(const SectionEntry &Section, ++ uint64_t Offset, ++ uint64_t Value, uint32_t Type, ++ int64_t Addend) { ++ uint32_t *TargetPtr = ++ reinterpret_cast(Section.getAddressWithOffset(Offset)); ++ uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); ++ uint64_t tmp1, tmp2, tmp3; ++ ++ LLVM_DEBUG(dbgs() << "[XXX] resolveLoongArch64Relocation, LocalAddress: 0x" ++ << format("%llx", Section.getAddressWithOffset(Offset)) ++ << " FinalAddress: 0x" << format("%llx", FinalAddress) ++ << " Value: 0x" << format("%llx", Value) << " Type: 0x" ++ << format("%x", Type) << " Addend: 0x" ++ << format("%llx", Addend) << "\n"); ++ ++ switch (Type) { ++ case ELF::R_LARCH_SOP_PUSH_GPREL: ++ case ELF::R_LARCH_SOP_PUSH_TLS_TPREL: ++ case ELF::R_LARCH_SOP_PUSH_TLS_GOT: ++ case ELF::R_LARCH_SOP_PUSH_TLS_GD: ++ default: ++ llvm_unreachable("Relocation type not implemented yet!"); ++ break; ++ case ELF::R_LARCH_MARK_LA: ++ // mark la ++ MarkLA = true; ++ break; ++ case ELF::R_LARCH_SOP_PUSH_ABSOLUTE: ++ if (MarkLA && !Addend) ++ // push(value) ++ ValuesStack.push_back(Value); ++ else ++ // push(addend) ++ ValuesStack.push_back(Addend); ++ break; ++ case ELF::R_LARCH_SOP_PUSH_PLT_PCREL: ++ case ELF::R_LARCH_SOP_PUSH_PCREL: ++ MarkLA = false; ++ // push(value -pc + addend) ++ ValuesStack.push_back(Value - FinalAddress + Addend); ++ break; ++ case ELF::R_LARCH_SOP_NOT: ++ // pop(tmp1) ++ // push(!tmp1) ++ tmp1 = ValuesStack.pop_back_val(); ++ ValuesStack.push_back(!tmp1); ++ break; ++ case ELF::R_LARCH_SOP_AND: ++ // pop(tmp2) ++ // pop(tmp1) ++ // push(tmp1 & tmp2) ++ tmp2 = ValuesStack.pop_back_val(); ++ tmp1 = ValuesStack.pop_back_val(); ++ ValuesStack.push_back(tmp1 & tmp2); ++ break; ++ case ELF::R_LARCH_SOP_IF_ELSE: ++ // pop(tmp3) ++ // pop(tmp2) ++ // pop(tmp1) ++ // push(tmp1 ? tmp2 : tmp3) ++ tmp3 = ValuesStack.pop_back_val(); ++ tmp2 = ValuesStack.pop_back_val(); ++ tmp1 = ValuesStack.pop_back_val(); ++ ValuesStack.push_back(tmp1 ? tmp2 : tmp3); ++ break; ++ case ELF::R_LARCH_SOP_ADD: ++ // pop(tmp2) ++ // pop(tmp1) ++ // push(tmp1 + tmp2) ++ tmp2 = ValuesStack.pop_back_val(); ++ tmp1 = ValuesStack.pop_back_val(); ++ ValuesStack.push_back(tmp1 + tmp2); ++ break; ++ case ELF::R_LARCH_SOP_SUB: ++ // pop(tmp2) ++ // pop(tmp1) ++ // push(tmp1 - tmp2) ++ tmp2 = ValuesStack.pop_back_val(); ++ tmp1 = ValuesStack.pop_back_val(); ++ ValuesStack.push_back(tmp1 - tmp2); ++ break; ++ case ELF::R_LARCH_SOP_SR: ++ // pop(tmp2) ++ // pop(tmp1) ++ // push(tmp1 >> tmp2) ++ tmp2 = ValuesStack.pop_back_val(); ++ tmp1 = ValuesStack.pop_back_val(); ++ ValuesStack.push_back(tmp1 >> tmp2); ++ break; ++ case ELF::R_LARCH_SOP_SL: ++ // pop(tmp2) ++ // pop(tmp1) ++ // push(tmp1 << tmp2) ++ tmp2 = ValuesStack.pop_back_val(); ++ tmp1 = ValuesStack.pop_back_val(); ++ ValuesStack.push_back(tmp1 << tmp2); ++ break; ++ case ELF::R_LARCH_32: ++ support::ulittle32_t::ref{TargetPtr} = ++ static_cast(Value + Addend); ++ break; ++ case ELF::R_LARCH_64: ++ support::ulittle64_t::ref{TargetPtr} = Value + Addend; ++ break; ++ case ELF::R_LARCH_SOP_POP_32_U_10_12: ++ case ELF::R_LARCH_SOP_POP_32_S_10_12: ++ // pop(tmp1) ++ // get(inst) ++ // inst=(inst & 0xffc003ff)|((tmp1 & 0xfff) << 10) ++ // write(inst) ++ tmp1 = ValuesStack.pop_back_val(); ++ support::ulittle32_t::ref{TargetPtr} = ++ (support::ulittle32_t::ref{TargetPtr} & 0xffc003ff) | ++ static_cast((tmp1 & 0xfff) << 10); ++ break; ++ case ELF::R_LARCH_SOP_POP_32_S_5_20: ++ // pop(tmp1) ++ // get(inst) ++ // inst=(inst & 0xfe00001f)|((tmp1 & 0xfffff) << 5) ++ // write(inst) ++ tmp1 = ValuesStack.pop_back_val(); ++ support::ulittle32_t::ref{TargetPtr} = ++ (support::ulittle32_t::ref{TargetPtr} & 0xfe00001f) | ++ static_cast((tmp1 & 0xfffff) << 5); ++ break; ++ case ELF::R_LARCH_SOP_POP_32_S_10_16_S2: ++ // pop(tmp1) ++ // tmp1 >>=2 ++ // get(inst) ++ // inst=(inst & 0xfc0003ff)|((tmp1 & 0xffff) << 10) ++ // write(inst) ++ tmp1 = ValuesStack.pop_back_val(); ++ tmp1 >>= 2; ++ support::ulittle32_t::ref{TargetPtr} = ++ (support::ulittle32_t::ref{TargetPtr} & 0xfc0003ff) | ++ static_cast((tmp1 & 0xffff) << 10); ++ break; ++ case ELF::R_LARCH_SOP_POP_32_S_0_5_10_16_S2: ++ // pop(tmp1) ++ // tmp1 >>= 2 ++ // get(inst) ++ // inst=(inst & 0xfc0003e0)|((tmp1 & 0xffff) << 10)|((tmp1 & 0x1f0000) >> ++ // 16) write(inst) ++ tmp1 = ValuesStack.pop_back_val(); ++ tmp1 >>= 2; ++ support::ulittle32_t::ref{TargetPtr} = ++ (support::ulittle32_t::ref{TargetPtr} & 0xfc0003e0) | ++ static_cast((tmp1 & 0xffff) << 10) | ++ static_cast((tmp1 & 0x1f0000) >> 16); ++ break; ++ case ELF::R_LARCH_SOP_POP_32_S_0_10_10_16_S2: ++ // pop(tmp1) ++ // tmp1 >>= 2 ++ // get(inst) ++ // inst=(inst & 0xfc000000)|((tmp1 & 0xffff) << 10)|((tmp1 & 0x3ff0000) >> ++ // 16) write(inst) ++ tmp1 = ValuesStack.pop_back_val(); ++ tmp1 >>= 2; ++ support::ulittle32_t::ref{TargetPtr} = ++ (support::ulittle32_t::ref{TargetPtr} & 0xfc000000) | ++ static_cast((tmp1 & 0xffff) << 10) | ++ static_cast((tmp1 & 0x3ff0000) >> 16); ++ break; ++ case ELF::R_LARCH_ADD32: ++ support::ulittle32_t::ref{TargetPtr} = ++ (support::ulittle32_t::ref{TargetPtr} + ++ static_cast(Value + Addend)); ++ break; ++ case ELF::R_LARCH_SUB32: ++ support::ulittle32_t::ref{TargetPtr} = ++ (support::ulittle32_t::ref{TargetPtr} - ++ static_cast(Value + Addend)); ++ break; ++ case ELF::R_LARCH_ADD64: ++ support::ulittle64_t::ref{TargetPtr} = ++ (support::ulittle64_t::ref{TargetPtr} + Value + Addend); ++ break; ++ case ELF::R_LARCH_SUB64: ++ support::ulittle64_t::ref{TargetPtr} = ++ (support::ulittle64_t::ref{TargetPtr} - Value - Addend); ++ break; ++ } ++} ++ + void RuntimeDyldELF::setMipsABI(const ObjectFile &Obj) { + if (Arch == Triple::UnknownArch || + !StringRef(Triple::getArchTypePrefix(Arch)).equals("mips")) { +@@ -1062,6 +1247,9 @@ void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section, + resolveARMRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), Type, + (uint32_t)(Addend & 0xffffffffL)); + break; ++ case Triple::loongarch64: ++ resolveLoongArch64Relocation(Section, Offset, Value, Type, Addend); ++ break; + case Triple::ppc: // Fall through. + case Triple::ppcle: + resolvePPC32Relocation(Section, Offset, Value, Type, Addend); +@@ -1375,6 +1563,58 @@ RuntimeDyldELF::processRelocationRef( + } + processSimpleRelocation(SectionID, Offset, RelType, Value); + } ++ } else if (Arch == Triple::loongarch64) { ++ if (RelType == ELF::R_LARCH_32 || RelType == ELF::R_LARCH_64 || ++ (RelType >= ELF::R_LARCH_ADD8 && RelType <= ELF::R_LARCH_SUB64)) { ++ if (TargetName.size() == 0 && ++ Sections[SectionID].getAddress() != nullptr) { ++ uint64_t SymOffset = 0; ++ unsigned SID = 0; ++ auto SectionOrErr = Symbol->getSection(); ++ if (!SectionOrErr) { ++ std::string Buf; ++ raw_string_ostream OS(Buf); ++ logAllUnhandledErrors(SectionOrErr.takeError(), OS); ++ report_fatal_error(Twine(OS.str())); ++ } ++ section_iterator si = *SectionOrErr; ++ if (si == Obj.section_end()) ++ llvm_unreachable("Symbol section not found!"); ++ bool isCode = si->isText(); ++ if (auto SectionIDOrErr = ++ findOrEmitSection(Obj, (*si), isCode, ObjSectionToID)) { ++ SID = *SectionIDOrErr; ++ } else ++ return SectionIDOrErr.takeError(); ++ auto OffsetOrErr = Symbol->getAddress(); ++ if (OffsetOrErr) ++ SymOffset = *OffsetOrErr; ++ uint64_t Target = Sections[SID].getLoadAddress() + SymOffset; ++ resolveRelocation(Sections[SectionID], Offset, Target, RelType, Addend); ++ } else { ++ processSimpleRelocation(SectionID, Offset, RelType, Value); ++ } ++ } else { ++ RTDyldSymbolTable::const_iterator Loc = ++ GlobalSymbolTable.find(TargetName); ++ if (!TargetName.empty()) { ++ if (Loc == GlobalSymbolTable.end()) { ++ IsSaved = true; ++ SavedSymbol = TargetName; ++ } else { ++ IsSaved = false; ++ } ++ } ++ if (IsSaved == true) { ++ Value.SymbolName = SavedSymbol.data(); ++ processSimpleRelocation(SectionID, Offset, RelType, Value); ++ } else { ++ uint8_t *TargetAddr = getSymbolLocalAddress(TargetName); ++ resolveRelocation(Sections[SectionID], Offset, ++ reinterpret_cast(TargetAddr), RelType, ++ Addend); ++ } ++ } + } else if (IsMipsO32ABI) { + uint8_t *Placeholder = reinterpret_cast( + computePlaceholderAddress(SectionID, Offset)); +@@ -2220,6 +2460,7 @@ size_t RuntimeDyldELF::getGOTEntrySize() { + case Triple::x86_64: + case Triple::aarch64: + case Triple::aarch64_be: ++ case Triple::loongarch64: + case Triple::ppc64: + case Triple::ppc64le: + case Triple::systemz: +diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +index b73d2af8c..b5bde4fe3 100644 +--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h ++++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +@@ -48,6 +48,10 @@ class RuntimeDyldELF : public RuntimeDyldImpl { + void resolveARMRelocation(const SectionEntry &Section, uint64_t Offset, + uint32_t Value, uint32_t Type, int32_t Addend); + ++ void resolveLoongArch64Relocation(const SectionEntry &Section, ++ uint64_t Offset, uint64_t Value, ++ uint32_t Type, int64_t Addend); ++ + void resolvePPC32Relocation(const SectionEntry &Section, uint64_t Offset, + uint64_t Value, uint32_t Type, int64_t Addend); + +@@ -155,6 +159,12 @@ private: + // EH frame sections with the memory manager. + SmallVector UnregisteredEHFrameSections; + ++ // For loongarch evaluteRelocation ++ SmallVector ValuesStack; ++ bool IsSaved; ++ bool MarkLA; ++ StringRef SavedSymbol; ++ + // Map between GOT relocation value and corresponding GOT offset + std::map GOTOffsetMap; + +diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp +index ad30b5ce9..def13044d 100644 +--- a/llvm/lib/MC/MCAssembler.cpp ++++ b/llvm/lib/MC/MCAssembler.cpp +@@ -1026,9 +1026,7 @@ bool MCAssembler::relaxLEB(MCAsmLayout &Layout, MCLEBFragment &LF) { + ? LF.getValue().evaluateKnownAbsolute(Value, Layout) + : LF.getValue().evaluateAsAbsolute(Value, Layout); + if (!Abs) { +- bool Relaxed, UseZeroPad; +- std::tie(Relaxed, UseZeroPad) = getBackend().relaxLEB128(LF, Layout, Value); +- if (!Relaxed) { ++ if (!getBackend().relaxLEB128(LF, Layout, Value)) { + getContext().reportError(LF.getValue().getLoc(), + Twine(LF.isSigned() ? ".s" : ".u") + + "leb128 expression is not absolute"); +@@ -1036,8 +1034,6 @@ bool MCAssembler::relaxLEB(MCAsmLayout &Layout, MCLEBFragment &LF) { + } + uint8_t Tmp[10]; // maximum size: ceil(64/7) + PadTo = std::max(PadTo, encodeULEB128(uint64_t(Value), Tmp)); +- if (UseZeroPad) +- Value = 0; + } + Data.clear(); + raw_svector_ostream OSE(Data); +diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp +index 80def6dfc..4bed3d2d7 100644 +--- a/llvm/lib/MC/MCExpr.cpp ++++ b/llvm/lib/MC/MCExpr.cpp +@@ -632,8 +632,7 @@ static void AttemptToFoldSymbolOffsetDifference( + // instructions and InSet is false (not expressions in directive like + // .size/.fill), disable the fast path. + if (Layout && (InSet || !SecA.hasInstructions() || +- !(Asm->getContext().getTargetTriple().isRISCV() || +- Asm->getContext().getTargetTriple().isLoongArch()))) { ++ !Asm->getContext().getTargetTriple().isRISCV())) { + // If both symbols are in the same fragment, return the difference of their + // offsets. canGetFragmentOffset(FA) may be false. + if (FA == FB && !SA.isVariable() && !SB.isVariable()) { +@@ -704,14 +703,8 @@ static void AttemptToFoldSymbolOffsetDifference( + } + + int64_t Num; +- unsigned Count; + if (DF) { + Displacement += DF->getContents().size(); +- } else if (auto *AF = dyn_cast(FI); +- AF && Layout && AF->hasEmitNops() && +- !Asm->getBackend().shouldInsertExtraNopBytesForCodeAlign( +- *AF, Count)) { +- Displacement += Asm->computeFragmentSize(*Layout, *AF); + } else if (auto *FF = dyn_cast(FI); + FF && FF->getNumValues().evaluateAsAbsolute(Num)) { + Displacement += Num * FF->getValueSize(); +diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp +index 7b382c131..e7999f6ab 100644 +--- a/llvm/lib/MC/MCObjectFileInfo.cpp ++++ b/llvm/lib/MC/MCObjectFileInfo.cpp +@@ -337,6 +337,12 @@ void MCObjectFileInfo::initMachOMCObjectFileInfo(const Triple &T) { + + void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) { + switch (T.getArch()) { ++ case Triple::loongarch32: ++ case Triple::loongarch64: ++ FDECFIEncoding = Ctx->getAsmInfo()->getCodePointerSize() == 4 ++ ? dwarf::DW_EH_PE_sdata4 ++ : dwarf::DW_EH_PE_sdata8; ++ break; + case Triple::mips: + case Triple::mipsel: + case Triple::mips64: +diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp +index f24395b02..caea29824 100644 +--- a/llvm/lib/Object/ELF.cpp ++++ b/llvm/lib/Object/ELF.cpp +@@ -231,8 +231,6 @@ uint32_t llvm::object::getELFRelativeRelocationType(uint32_t Machine) { + break; + case ELF::EM_BPF: + break; +- case ELF::EM_LOONGARCH: +- return ELF::R_LARCH_RELATIVE; + default: + break; + } +diff --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp +index 28b96c341..3f7f99b39 100644 +--- a/llvm/lib/Object/ELFObjectFile.cpp ++++ b/llvm/lib/Object/ELFObjectFile.cpp +@@ -321,24 +321,6 @@ Expected ELFObjectFileBase::getRISCVFeatures() const { + return Features; + } + +-SubtargetFeatures ELFObjectFileBase::getLoongArchFeatures() const { +- SubtargetFeatures Features; +- +- switch (getPlatformFlags() & ELF::EF_LOONGARCH_ABI_MODIFIER_MASK) { +- case ELF::EF_LOONGARCH_ABI_SOFT_FLOAT: +- break; +- case ELF::EF_LOONGARCH_ABI_DOUBLE_FLOAT: +- Features.AddFeature("d"); +- // D implies F according to LoongArch ISA spec. +- [[fallthrough]]; +- case ELF::EF_LOONGARCH_ABI_SINGLE_FLOAT: +- Features.AddFeature("f"); +- break; +- } +- +- return Features; +-} +- + Expected ELFObjectFileBase::getFeatures() const { + switch (getEMachine()) { + case ELF::EM_MIPS: +@@ -347,8 +329,6 @@ Expected ELFObjectFileBase::getFeatures() const { + return getARMFeatures(); + case ELF::EM_RISCV: + return getRISCVFeatures(); +- case ELF::EM_LOONGARCH: +- return getLoongArchFeatures(); + default: + return SubtargetFeatures(); + } +diff --git a/llvm/lib/Object/RelocationResolver.cpp b/llvm/lib/Object/RelocationResolver.cpp +index 564d9da78..39012174a 100644 +--- a/llvm/lib/Object/RelocationResolver.cpp ++++ b/llvm/lib/Object/RelocationResolver.cpp +@@ -534,20 +534,8 @@ static uint64_t resolveCSKY(uint64_t Type, uint64_t Offset, uint64_t S, + + static bool supportsLoongArch(uint64_t Type) { + switch (Type) { +- case ELF::R_LARCH_NONE: + case ELF::R_LARCH_32: +- case ELF::R_LARCH_32_PCREL: + case ELF::R_LARCH_64: +- case ELF::R_LARCH_ADD6: +- case ELF::R_LARCH_SUB6: +- case ELF::R_LARCH_ADD8: +- case ELF::R_LARCH_SUB8: +- case ELF::R_LARCH_ADD16: +- case ELF::R_LARCH_SUB16: +- case ELF::R_LARCH_ADD32: +- case ELF::R_LARCH_SUB32: +- case ELF::R_LARCH_ADD64: +- case ELF::R_LARCH_SUB64: + return true; + default: + return false; +@@ -557,34 +545,10 @@ static bool supportsLoongArch(uint64_t Type) { + static uint64_t resolveLoongArch(uint64_t Type, uint64_t Offset, uint64_t S, + uint64_t LocData, int64_t Addend) { + switch (Type) { +- case ELF::R_LARCH_NONE: +- return LocData; + case ELF::R_LARCH_32: + return (S + Addend) & 0xFFFFFFFF; +- case ELF::R_LARCH_32_PCREL: +- return (S + Addend - Offset) & 0xFFFFFFFF; + case ELF::R_LARCH_64: + return S + Addend; +- case ELF::R_LARCH_ADD6: +- return (LocData & 0xC0) | ((LocData + S + Addend) & 0x3F); +- case ELF::R_LARCH_SUB6: +- return (LocData & 0xC0) | ((LocData - (S + Addend)) & 0x3F); +- case ELF::R_LARCH_ADD8: +- return (LocData + (S + Addend)) & 0xFF; +- case ELF::R_LARCH_SUB8: +- return (LocData - (S + Addend)) & 0xFF; +- case ELF::R_LARCH_ADD16: +- return (LocData + (S + Addend)) & 0xFFFF; +- case ELF::R_LARCH_SUB16: +- return (LocData - (S + Addend)) & 0xFFFF; +- case ELF::R_LARCH_ADD32: +- return (LocData + (S + Addend)) & 0xFFFFFFFF; +- case ELF::R_LARCH_SUB32: +- return (LocData - (S + Addend)) & 0xFFFFFFFF; +- case ELF::R_LARCH_ADD64: +- return (LocData + (S + Addend)); +- case ELF::R_LARCH_SUB64: +- return (LocData - (S + Addend)); + default: + llvm_unreachable("Invalid relocation type"); + } +@@ -885,10 +849,8 @@ uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R, + + if (GetRelSectionType() == ELF::SHT_RELA) { + Addend = getELFAddend(R); +- // LoongArch and RISCV relocations use both LocData and Addend. +- if (Obj->getArch() != Triple::loongarch32 && +- Obj->getArch() != Triple::loongarch64 && +- Obj->getArch() != Triple::riscv32 && ++ // RISCV relocations use both LocData and Addend. ++ if (Obj->getArch() != Triple::riscv32 && + Obj->getArch() != Triple::riscv64) + LocData = 0; + } +diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp +index 6ad4a0674..c5bb2bce7 100644 +--- a/llvm/lib/ObjectYAML/ELFYAML.cpp ++++ b/llvm/lib/ObjectYAML/ELFYAML.cpp +@@ -529,13 +529,6 @@ void ScalarBitSetTraits::bitset(IO &IO, + BCaseMask(EF_AVR_ARCH_XMEGA7, EF_AVR_ARCH_MASK); + BCase(EF_AVR_LINKRELAX_PREPARED); + break; +- case ELF::EM_LOONGARCH: +- BCaseMask(EF_LOONGARCH_ABI_SOFT_FLOAT, EF_LOONGARCH_ABI_MODIFIER_MASK); +- BCaseMask(EF_LOONGARCH_ABI_SINGLE_FLOAT, EF_LOONGARCH_ABI_MODIFIER_MASK); +- BCaseMask(EF_LOONGARCH_ABI_DOUBLE_FLOAT, EF_LOONGARCH_ABI_MODIFIER_MASK); +- BCaseMask(EF_LOONGARCH_OBJABI_V0, EF_LOONGARCH_OBJABI_MASK); +- BCaseMask(EF_LOONGARCH_OBJABI_V1, EF_LOONGARCH_OBJABI_MASK); +- break; + case ELF::EM_RISCV: + BCase(EF_RISCV_RVC); + BCaseMask(EF_RISCV_FLOAT_ABI_SOFT, EF_RISCV_FLOAT_ABI); +@@ -641,6 +634,11 @@ void ScalarBitSetTraits::bitset(IO &IO, + break; + } + break; ++ case ELF::EM_LOONGARCH: ++ BCaseMask(EF_LARCH_ABI_LP32, EF_LARCH_ABI); ++ BCaseMask(EF_LARCH_ABI_LPX32, EF_LARCH_ABI); ++ BCaseMask(EF_LARCH_ABI_LP64, EF_LARCH_ABI); ++ break; + default: + break; + } +diff --git a/llvm/lib/Target/LoongArch/AsmParser/CMakeLists.txt b/llvm/lib/Target/LoongArch/AsmParser/CMakeLists.txt +index 296160531..cb8b768d5 100644 +--- a/llvm/lib/Target/LoongArch/AsmParser/CMakeLists.txt ++++ b/llvm/lib/Target/LoongArch/AsmParser/CMakeLists.txt +@@ -2,10 +2,10 @@ add_llvm_component_library(LLVMLoongArchAsmParser + LoongArchAsmParser.cpp + + LINK_COMPONENTS +- LoongArchDesc +- LoongArchInfo + MC + MCParser ++ LoongArchDesc ++ LoongArchInfo + Support + + ADD_TO_COMPONENT +diff --git a/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp b/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp +index 46f63a410..2c3a9c3e8 100644 +--- a/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp ++++ b/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp +@@ -1,4 +1,4 @@ +-// LoongArchAsmParser.cpp - Parse LoongArch assembly to MCInst instructions -=// ++//===-- LoongArchAsmParser.cpp - Parse LoongArch assembly to MCInst instructions ----===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -6,1294 +6,1470 @@ + // + //===----------------------------------------------------------------------===// + +-#include "MCTargetDesc/LoongArchInstPrinter.h" ++#include "LoongArchTargetStreamer.h" ++#include "MCTargetDesc/LoongArchABIInfo.h" ++#include "MCTargetDesc/LoongArchAnalyzeImmediate.h" ++#include "MCTargetDesc/LoongArchBaseInfo.h" + #include "MCTargetDesc/LoongArchMCExpr.h" + #include "MCTargetDesc/LoongArchMCTargetDesc.h" +-#include "MCTargetDesc/LoongArchMatInt.h" + #include "TargetInfo/LoongArchTargetInfo.h" ++#include "llvm/ADT/APFloat.h" ++#include "llvm/ADT/STLExtras.h" ++#include "llvm/ADT/SmallVector.h" ++#include "llvm/ADT/StringRef.h" ++#include "llvm/ADT/StringSwitch.h" ++#include "llvm/ADT/Twine.h" ++#include "llvm/BinaryFormat/ELF.h" + #include "llvm/MC/MCContext.h" +-#include "llvm/MC/MCInstBuilder.h" ++#include "llvm/MC/MCExpr.h" ++#include "llvm/MC/MCInst.h" ++#include "llvm/MC/MCInstrDesc.h" + #include "llvm/MC/MCInstrInfo.h" ++#include "llvm/MC/MCObjectFileInfo.h" + #include "llvm/MC/MCParser/MCAsmLexer.h" ++#include "llvm/MC/MCParser/MCAsmParser.h" ++#include "llvm/MC/MCParser/MCAsmParserExtension.h" + #include "llvm/MC/MCParser/MCParsedAsmOperand.h" + #include "llvm/MC/MCParser/MCTargetAsmParser.h" +-#include "llvm/MC/MCRegisterInfo.h" ++#include "llvm/MC/MCSectionELF.h" + #include "llvm/MC/MCStreamer.h" + #include "llvm/MC/MCSubtargetInfo.h" ++#include "llvm/MC/MCSymbol.h" ++#include "llvm/MC/MCSymbolELF.h" + #include "llvm/MC/MCValue.h" + #include "llvm/MC/TargetRegistry.h" + #include "llvm/Support/Casting.h" ++#include "llvm/Support/CommandLine.h" ++#include "llvm/Support/Compiler.h" ++#include "llvm/Support/Debug.h" ++#include "llvm/Support/ErrorHandling.h" ++#include "llvm/Support/MathExtras.h" ++#include "llvm/Support/SMLoc.h" ++#include "llvm/Support/SourceMgr.h" ++#include "llvm/Support/raw_ostream.h" ++#include "llvm/TargetParser/Triple.h" ++#include ++#include ++#include ++#include ++#include ++#include + + using namespace llvm; + + #define DEBUG_TYPE "loongarch-asm-parser" + ++namespace llvm { ++ ++class MCInstrInfo; ++ ++} // end namespace llvm ++ ++namespace { ++ ++class LoongArchAssemblerOptions { ++public: ++ LoongArchAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {} ++ ++ LoongArchAssemblerOptions(const LoongArchAssemblerOptions *Opts) { ++ Features = Opts->getFeatures(); ++ } ++ ++ const FeatureBitset &getFeatures() const { return Features; } ++ void setFeatures(const FeatureBitset &Features_) { Features = Features_; } ++ ++private: ++ FeatureBitset Features; ++}; ++ ++} // end anonymous namespace ++ + namespace { ++ + class LoongArchAsmParser : public MCTargetAsmParser { +- SMLoc getLoc() const { return getParser().getTok().getLoc(); } +- bool is64Bit() const { return getSTI().hasFeature(LoongArch::Feature64Bit); } +- +- struct Inst { +- unsigned Opc; +- LoongArchMCExpr::VariantKind VK; +- Inst(unsigned Opc, +- LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None) +- : Opc(Opc), VK(VK) {} +- }; +- using InstSeq = SmallVector; ++ LoongArchTargetStreamer &getTargetStreamer() { ++ MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); ++ return static_cast(TS); ++ } + +- /// Parse a register as used in CFI directives. ++ LoongArchABIInfo ABI; ++ SmallVector, 2> AssemblerOptions; ++ MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a ++ // nullptr, which indicates that no function is currently ++ // selected. This usually happens after an '.end' ++ // directive. ++ bool IsPicEnabled; ++ ++ // Map of register aliases created via the .set directive. ++ StringMap RegisterSets; ++ ++#define GET_ASSEMBLER_HEADER ++#include "LoongArchGenAsmMatcher.inc" ++ ++ unsigned checkTargetMatchPredicate(MCInst &Inst) override; ++ ++ bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, ++ OperandVector &Operands, MCStreamer &Out, ++ uint64_t &ErrorInfo, ++ bool MatchingInlineAsm) override; ++ ++ /// Parse a register as used in CFI directives + bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override; + ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, + SMLoc &EndLoc) override; + ++ bool mnemonicIsValid(StringRef Mnemonic); ++ + bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, + SMLoc NameLoc, OperandVector &Operands) override; + +- bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, +- OperandVector &Operands, MCStreamer &Out, +- uint64_t &ErrorInfo, +- bool MatchingInlineAsm) override; ++ bool ParseDirective(AsmToken DirectiveID) override; ++ ++ OperandMatchResultTy parseMemOperand(OperandVector &Operands); ++ OperandMatchResultTy parseAMemOperand(OperandVector &Operands); ++ OperandMatchResultTy ++ matchAnyRegisterNameWithoutDollar(OperandVector &Operands, ++ StringRef Identifier, SMLoc S); ++ OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands, ++ const AsmToken &Token, ++ SMLoc S); ++ OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands, ++ SMLoc S); ++ OperandMatchResultTy parseAnyRegister(OperandVector &Operands); ++ OperandMatchResultTy parseJumpTarget(OperandVector &Operands); ++ ++ bool searchSymbolAlias(OperandVector &Operands); ++ ++ bool parseOperand(OperandVector &, StringRef Mnemonic); ++ ++ enum MacroExpanderResultTy { ++ MER_NotAMacro, ++ MER_Success, ++ MER_Fail, ++ }; + +- unsigned checkTargetMatchPredicate(MCInst &Inst) override; ++ // Expands assembly pseudo instructions. ++ MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, ++ MCStreamer &Out, ++ const MCSubtargetInfo *STI); + +- unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, +- unsigned Kind) override; ++ bool expandLoadImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, ++ const MCSubtargetInfo *STI); + +- bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo, +- int64_t Lower, int64_t Upper, +- const Twine &Msg); ++ bool expandLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, ++ const MCSubtargetInfo *STI); + +- /// Helper for processing MC instructions that have been successfully matched +- /// by MatchAndEmitInstruction. +- bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands, +- MCStreamer &Out); ++ bool expandLoadAddressLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, ++ const MCSubtargetInfo *STI); + +-// Auto-generated instruction matching functions. +-#define GET_ASSEMBLER_HEADER +-#include "LoongArchGenAsmMatcher.inc" ++ bool reportParseError(Twine ErrorMsg); ++ ++ bool parseMemOffset(const MCExpr *&Res); ++ ++ bool isEvaluated(const MCExpr *Expr); ++ bool parseDirectiveSet(); ++ ++ bool parseSetAssignment(); + +- ParseStatus parseRegister(OperandVector &Operands); +- ParseStatus parseImmediate(OperandVector &Operands); +- ParseStatus parseOperandWithModifier(OperandVector &Operands); +- ParseStatus parseSImm26Operand(OperandVector &Operands); +- ParseStatus parseAtomicMemOp(OperandVector &Operands); ++ bool parseInternalDirectiveReallowModule(); + +- bool parseOperand(OperandVector &Operands, StringRef Mnemonic); ++ int matchCPURegisterName(StringRef Symbol); + +- // Helper to emit the sequence of instructions generated by the +- // "emitLoadAddress*" functions. +- void emitLAInstSeq(MCRegister DestReg, MCRegister TmpReg, +- const MCExpr *Symbol, SmallVectorImpl &Insts, +- SMLoc IDLoc, MCStreamer &Out, bool RelaxHint = false); ++ int matchFPURegisterName(StringRef Name); + +- // Helper to emit pseudo instruction "la.abs $rd, sym". +- void emitLoadAddressAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); ++ int matchFCFRRegisterName(StringRef Name); ++ int matchFCSRRegisterName(StringRef Name); + +- // Helper to emit pseudo instruction "la.pcrel $rd, sym". +- void emitLoadAddressPcrel(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); +- // Helper to emit pseudo instruction "la.pcrel $rd, $rj, sym". +- void emitLoadAddressPcrelLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); ++ int matchLSX128RegisterName(StringRef Name); + +- // Helper to emit pseudo instruction "la.got $rd, sym". +- void emitLoadAddressGot(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); +- // Helper to emit pseudo instruction "la.got $rd, $rj, sym". +- void emitLoadAddressGotLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); ++ int matchLASX256RegisterName(StringRef Name); + +- // Helper to emit pseudo instruction "la.tls.le $rd, sym". +- void emitLoadAddressTLSLE(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); ++ bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, ++ const MCSubtargetInfo *STI); + +- // Helper to emit pseudo instruction "la.tls.ie $rd, sym". +- void emitLoadAddressTLSIE(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); +- // Helper to emit pseudo instruction "la.tls.ie $rd, $rj, sym". +- void emitLoadAddressTLSIELarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); ++ // Helper function that checks if the value of a vector index is within the ++ // boundaries of accepted values for each RegisterKind ++ // Example: VINSGR2VR.B $v0[n], $1 => 16 > n >= 0 ++ bool validateLSXIndex(int Val, int RegKind); + +- // Helper to emit pseudo instruction "la.tls.ld $rd, sym". +- void emitLoadAddressTLSLD(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); +- // Helper to emit pseudo instruction "la.tls.ld $rd, $rj, sym". +- void emitLoadAddressTLSLDLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); ++ void setFeatureBits(uint64_t Feature, StringRef FeatureString) { ++ if (!(getSTI().getFeatureBits()[Feature])) { ++ MCSubtargetInfo &STI = copySTI(); ++ setAvailableFeatures( ++ ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); ++ AssemblerOptions.back()->setFeatures(STI.getFeatureBits()); ++ } ++ } + +- // Helper to emit pseudo instruction "la.tls.gd $rd, sym". +- void emitLoadAddressTLSGD(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); +- // Helper to emit pseudo instruction "la.tls.gd $rd, $rj, sym". +- void emitLoadAddressTLSGDLarge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); ++ void clearFeatureBits(uint64_t Feature, StringRef FeatureString) { ++ if (getSTI().getFeatureBits()[Feature]) { ++ MCSubtargetInfo &STI = copySTI(); ++ setAvailableFeatures( ++ ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); ++ AssemblerOptions.back()->setFeatures(STI.getFeatureBits()); ++ } ++ } + +- // Helper to emit pseudo instruction "li.w/d $rd, $imm". +- void emitLoadImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); ++ void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) { ++ setFeatureBits(Feature, FeatureString); ++ AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits()); ++ } + +- // Helper to emit pseudo instruction "call36 sym" or "tail36 $rj, sym". +- void emitFuncCall36(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, +- bool IsTailCall); ++ void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) { ++ clearFeatureBits(Feature, FeatureString); ++ AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits()); ++ } + + public: + enum LoongArchMatchResultTy { +- Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY, +- Match_RequiresMsbNotLessThanLsb, +- Match_RequiresOpnd2NotR0R1, +- Match_RequiresAMORdDifferRkRj, +- Match_RequiresLAORdDifferRj, ++ Match_RequiresNoZeroRegister = FIRST_TARGET_MATCH_RESULT_TY, ++ Match_RequiresNoRaRegister, ++ Match_RequiresRange0_31, ++ Match_RequiresRange0_63, ++ Match_MsbHigherThanLsb, ++ Match_RequiresPosSizeUImm6, + #define GET_OPERAND_DIAGNOSTIC_TYPES + #include "LoongArchGenAsmMatcher.inc" + #undef GET_OPERAND_DIAGNOSTIC_TYPES + }; + +- static bool classifySymbolRef(const MCExpr *Expr, +- LoongArchMCExpr::VariantKind &Kind); +- +- LoongArchAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, ++ LoongArchAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser, + const MCInstrInfo &MII, const MCTargetOptions &Options) +- : MCTargetAsmParser(Options, STI, MII) { +- Parser.addAliasForDirective(".half", ".2byte"); +- Parser.addAliasForDirective(".hword", ".2byte"); +- Parser.addAliasForDirective(".word", ".4byte"); +- Parser.addAliasForDirective(".dword", ".8byte"); ++ : MCTargetAsmParser(Options, sti, MII), ++ ABI(LoongArchABIInfo::computeTargetABI(Triple(sti.getTargetTriple()), ++ sti.getCPU(), Options)) { ++ MCAsmParserExtension::Initialize(parser); ++ ++ parser.addAliasForDirective(".asciiz", ".asciz"); ++ parser.addAliasForDirective(".half", ".2byte"); ++ parser.addAliasForDirective(".hword", ".2byte"); ++ parser.addAliasForDirective(".word", ".4byte"); ++ parser.addAliasForDirective(".dword", ".8byte"); + + // Initialize the set of available features. +- setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); +- } +-}; ++ setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits())); + +-// Instances of this class represent a parsed LoongArch machine instruction. +-class LoongArchOperand : public MCParsedAsmOperand { +- enum class KindTy { +- Token, +- Register, +- Immediate, +- } Kind; ++ // Remember the initial assembler options. The user can not modify these. ++ AssemblerOptions.push_back( ++ std::make_unique(getSTI().getFeatureBits())); + +- struct RegOp { +- MCRegister RegNum; +- }; ++ // Create an assembler options environment for the user to modify. ++ AssemblerOptions.push_back( ++ std::make_unique(getSTI().getFeatureBits())); + +- struct ImmOp { +- const MCExpr *Val; +- }; ++ getTargetStreamer().updateABIInfo(*this); + +- SMLoc StartLoc, EndLoc; +- union { +- StringRef Tok; +- struct RegOp Reg; +- struct ImmOp Imm; +- }; ++ CurrentFn = nullptr; + +-public: +- LoongArchOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} +- +- bool isToken() const override { return Kind == KindTy::Token; } +- bool isReg() const override { return Kind == KindTy::Register; } +- bool isImm() const override { return Kind == KindTy::Immediate; } +- bool isMem() const override { return false; } +- void setReg(MCRegister PhysReg) { Reg.RegNum = PhysReg; } +- bool isGPR() const { +- return Kind == KindTy::Register && +- LoongArchMCRegisterClasses[LoongArch::GPRRegClassID].contains( +- Reg.RegNum); +- } +- +- static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm, +- LoongArchMCExpr::VariantKind &VK) { +- if (auto *LE = dyn_cast(Expr)) { +- VK = LE->getKind(); +- return false; +- } ++ IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent(); ++ } + +- if (auto CE = dyn_cast(Expr)) { +- Imm = CE->getValue(); +- return true; +- } ++ bool is64Bit() const { ++ return getSTI().getFeatureBits()[LoongArch::Feature64Bit]; ++ } + +- return false; ++ bool isFP64bit() const { ++ return getSTI().getFeatureBits()[LoongArch::FeatureFP64Bit]; + } + +- template bool isUImm() const { +- if (!isImm()) +- return false; ++ const LoongArchABIInfo &getABI() const { return ABI; } ++ bool isABI_LPX32() const { return ABI.IsLPX32(); } ++ bool isABI_LP64() const { return ABI.IsLP64(); } ++ bool isABI_LP32() const { return ABI.IsLP32(); } + +- int64_t Imm; +- LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None; +- bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); +- return IsConstantImm && isUInt(Imm - P) && +- VK == LoongArchMCExpr::VK_LoongArch_None; ++ bool hasLSX() const { ++ return getSTI().getFeatureBits()[LoongArch::FeatureLSX]; + } + +- template bool isSImm() const { +- if (!isImm()) +- return false; ++ bool hasLASX() const { ++ return getSTI().getFeatureBits()[LoongArch::FeatureLASX]; ++ } + +- int64_t Imm; +- LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None; +- bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); +- return IsConstantImm && isShiftedInt(Imm) && +- VK == LoongArchMCExpr::VK_LoongArch_None; ++ bool inPicMode() { ++ return IsPicEnabled; + } + +- bool isBareSymbol() const { +- int64_t Imm; +- LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None; +- // Must be of 'immediate' type but not a constant. +- if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) +- return false; +- return LoongArchAsmParser::classifySymbolRef(getImm(), VK) && +- VK == LoongArchMCExpr::VK_LoongArch_None; +- } +- +- bool isUImm1() const { return isUImm<1>(); } +- bool isUImm2() const { return isUImm<2>(); } +- bool isUImm2plus1() const { return isUImm<2, 1>(); } +- bool isUImm3() const { return isUImm<3>(); } +- bool isUImm4() const { return isUImm<4>(); } +- bool isSImm5() const { return isSImm<5>(); } +- bool isUImm5() const { return isUImm<5>(); } +- bool isUImm6() const { return isUImm<6>(); } +- bool isUImm7() const { return isUImm<7>(); } +- bool isSImm8() const { return isSImm<8>(); } +- bool isSImm8lsl1() const { return isSImm<8, 1>(); } +- bool isSImm8lsl2() const { return isSImm<8, 2>(); } +- bool isSImm8lsl3() const { return isSImm<8, 3>(); } +- bool isUImm8() const { return isUImm<8>(); } +- bool isSImm9lsl3() const { return isSImm<9, 3>(); } +- bool isSImm10() const { return isSImm<10>(); } +- bool isSImm10lsl2() const { return isSImm<10, 2>(); } +- bool isSImm11lsl1() const { return isSImm<11, 1>(); } +- bool isSImm12() const { return isSImm<12>(); } +- +- bool isSImm12addlike() const { +- if (!isImm()) +- return false; ++ bool useSoftFloat() const { ++ return getSTI().getFeatureBits()[LoongArch::FeatureSoftFloat]; ++ } + +- int64_t Imm; +- LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None; +- bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); +- bool IsValidKind = VK == LoongArchMCExpr::VK_LoongArch_None || +- VK == LoongArchMCExpr::VK_LoongArch_PCALA_LO12 || +- VK == LoongArchMCExpr::VK_LoongArch_GOT_PC_LO12 || +- VK == LoongArchMCExpr::VK_LoongArch_TLS_IE_PC_LO12; +- return IsConstantImm +- ? isInt<12>(Imm) && IsValidKind +- : LoongArchAsmParser::classifySymbolRef(getImm(), VK) && +- IsValidKind; +- } +- +- bool isSImm12lu52id() const { +- if (!isImm()) +- return false; ++ const MCExpr *createTargetUnaryExpr(const MCExpr *E, ++ AsmToken::TokenKind OperatorToken, ++ MCContext &Ctx) override { ++ switch(OperatorToken) { ++ default: ++ llvm_unreachable("Unknown token"); ++ return nullptr; ++#if 0 ++ case AsmToken::PercentPlt: ++ return LoongArchMCExpr::create(LoongArchMCExpr::MEK_PLT, E, Ctx); ++#endif ++ } ++ } ++}; + +- int64_t Imm; +- LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None; +- bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); +- bool IsValidKind = VK == LoongArchMCExpr::VK_LoongArch_None || +- VK == LoongArchMCExpr::VK_LoongArch_ABS64_HI12 || +- VK == LoongArchMCExpr::VK_LoongArch_PCALA64_HI12 || +- VK == LoongArchMCExpr::VK_LoongArch_GOT64_HI12 || +- VK == LoongArchMCExpr::VK_LoongArch_GOT64_PC_HI12 || +- VK == LoongArchMCExpr::VK_LoongArch_TLS_LE64_HI12 || +- VK == LoongArchMCExpr::VK_LoongArch_TLS_IE64_HI12 || +- VK == LoongArchMCExpr::VK_LoongArch_TLS_IE64_PC_HI12; +- return IsConstantImm +- ? isInt<12>(Imm) && IsValidKind +- : LoongArchAsmParser::classifySymbolRef(getImm(), VK) && +- IsValidKind; +- } +- +- bool isUImm12() const { return isUImm<12>(); } +- +- bool isUImm12ori() const { +- if (!isImm()) +- return false; ++/// LoongArchOperand - Instances of this class represent a parsed LoongArch machine ++/// instruction. ++class LoongArchOperand : public MCParsedAsmOperand { ++public: ++ /// Broad categories of register classes ++ /// The exact class is finalized by the render method. ++ enum RegKind { ++ RegKind_GPR = 1, /// GPR32 and GPR64 (depending on is64Bit()) ++ RegKind_FGR = 2, /// FGR32, FGR64 (depending on isFP64bit()) ++ RegKind_FCFR = 4, /// FCFR ++ RegKind_FCSR = 8, /// FCSR ++ RegKind_LSX128 = 16, /// LSX128[BHWD] (makes no difference which) ++ RegKind_LASX256 = 32, /// LASX256[BHWD] (makes no difference which) ++ RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCFR | RegKind_FCSR | ++ RegKind_LSX128 | RegKind_LASX256 ++ }; + +- int64_t Imm; +- LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None; +- bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); +- bool IsValidKind = VK == LoongArchMCExpr::VK_LoongArch_None || +- VK == LoongArchMCExpr::VK_LoongArch_ABS_LO12 || +- VK == LoongArchMCExpr::VK_LoongArch_PCALA_LO12 || +- VK == LoongArchMCExpr::VK_LoongArch_GOT_LO12 || +- VK == LoongArchMCExpr::VK_LoongArch_GOT_PC_LO12 || +- VK == LoongArchMCExpr::VK_LoongArch_TLS_LE_LO12 || +- VK == LoongArchMCExpr::VK_LoongArch_TLS_IE_LO12 || +- VK == LoongArchMCExpr::VK_LoongArch_TLS_IE_PC_LO12; +- return IsConstantImm +- ? isUInt<12>(Imm) && IsValidKind +- : LoongArchAsmParser::classifySymbolRef(getImm(), VK) && +- IsValidKind; +- } +- +- bool isSImm13() const { return isSImm<13>(); } +- bool isUImm14() const { return isUImm<14>(); } +- bool isUImm15() const { return isUImm<15>(); } +- +- bool isSImm14lsl2() const { return isSImm<14, 2>(); } +- bool isSImm16() const { return isSImm<16>(); } +- +- bool isSImm16lsl2() const { +- if (!isImm()) +- return false; ++private: ++ enum KindTy { ++ k_Immediate, /// An immediate (possibly involving symbol references) ++ k_Memory, /// Base + Offset Memory Address ++ k_RegisterIndex, /// A register index in one or more RegKind. ++ k_Token, /// A simple token ++ k_RegList, /// A physical register list ++ } Kind; + +- int64_t Imm; +- LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None; +- bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); +- bool IsValidKind = VK == LoongArchMCExpr::VK_LoongArch_None || +- VK == LoongArchMCExpr::VK_LoongArch_B16 || +- VK == LoongArchMCExpr::VK_LoongArch_PCALA_LO12; +- return IsConstantImm +- ? isShiftedInt<16, 2>(Imm) && IsValidKind +- : LoongArchAsmParser::classifySymbolRef(getImm(), VK) && +- IsValidKind; +- } ++public: ++ LoongArchOperand(KindTy K, LoongArchAsmParser &Parser) ++ : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {} + +- bool isSImm20() const { return isSImm<20>(); } ++ ~LoongArchOperand() override { ++ switch (Kind) { ++ case k_Memory: ++ delete Mem.Base; ++ break; ++ case k_RegList: ++ delete RegList.List; ++ break; ++ case k_Immediate: ++ case k_RegisterIndex: ++ case k_Token: ++ break; ++ } ++ } + +- bool isSImm20pcalau12i() const { +- if (!isImm()) +- return false; ++private: ++ /// For diagnostics, and checking the assembler temporary ++ LoongArchAsmParser &AsmParser; + +- int64_t Imm; +- LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None; +- bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); +- bool IsValidKind = VK == LoongArchMCExpr::VK_LoongArch_None || +- VK == LoongArchMCExpr::VK_LoongArch_PCALA_HI20 || +- VK == LoongArchMCExpr::VK_LoongArch_GOT_PC_HI20 || +- VK == LoongArchMCExpr::VK_LoongArch_TLS_IE_PC_HI20 || +- VK == LoongArchMCExpr::VK_LoongArch_TLS_LD_PC_HI20 || +- VK == LoongArchMCExpr::VK_LoongArch_TLS_GD_PC_HI20; +- return IsConstantImm +- ? isInt<20>(Imm) && IsValidKind +- : LoongArchAsmParser::classifySymbolRef(getImm(), VK) && +- IsValidKind; +- } +- +- bool isSImm20lu12iw() const { +- if (!isImm()) +- return false; ++ struct Token { ++ const char *Data; ++ unsigned Length; ++ }; + +- int64_t Imm; +- LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None; +- bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); +- bool IsValidKind = VK == LoongArchMCExpr::VK_LoongArch_None || +- VK == LoongArchMCExpr::VK_LoongArch_ABS_HI20 || +- VK == LoongArchMCExpr::VK_LoongArch_GOT_HI20 || +- VK == LoongArchMCExpr::VK_LoongArch_TLS_GD_HI20 || +- VK == LoongArchMCExpr::VK_LoongArch_TLS_LD_HI20 || +- VK == LoongArchMCExpr::VK_LoongArch_TLS_IE_HI20 || +- VK == LoongArchMCExpr::VK_LoongArch_TLS_LE_HI20; +- return IsConstantImm +- ? isInt<20>(Imm) && IsValidKind +- : LoongArchAsmParser::classifySymbolRef(getImm(), VK) && +- IsValidKind; +- } +- +- bool isSImm20lu32id() const { +- if (!isImm()) +- return false; ++ struct RegIdxOp { ++ unsigned Index; /// Index into the register class ++ RegKind Kind; /// Bitfield of the kinds it could possibly be ++ struct Token Tok; /// The input token this operand originated from. ++ const MCRegisterInfo *RegInfo; ++ }; + +- int64_t Imm; +- LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None; +- bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); +- bool IsValidKind = VK == LoongArchMCExpr::VK_LoongArch_None || +- VK == LoongArchMCExpr::VK_LoongArch_ABS64_LO20 || +- VK == LoongArchMCExpr::VK_LoongArch_PCALA64_LO20 || +- VK == LoongArchMCExpr::VK_LoongArch_GOT64_LO20 || +- VK == LoongArchMCExpr::VK_LoongArch_GOT64_PC_LO20 || +- VK == LoongArchMCExpr::VK_LoongArch_TLS_IE64_LO20 || +- VK == LoongArchMCExpr::VK_LoongArch_TLS_IE64_PC_LO20 || +- VK == LoongArchMCExpr::VK_LoongArch_TLS_LE64_LO20; +- +- return IsConstantImm +- ? isInt<20>(Imm) && IsValidKind +- : LoongArchAsmParser::classifySymbolRef(getImm(), VK) && +- IsValidKind; +- } +- +- bool isSImm20pcaddu18i() const { +- if (!isImm()) +- return false; ++ struct ImmOp { ++ const MCExpr *Val; ++ }; + +- int64_t Imm; +- LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None; +- bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); +- bool IsValidKind = VK == LoongArchMCExpr::VK_LoongArch_None || +- VK == LoongArchMCExpr::VK_LoongArch_CALL36; ++ struct MemOp { ++ LoongArchOperand *Base; ++ const MCExpr *Off; ++ }; + +- return IsConstantImm +- ? isInt<20>(Imm) && IsValidKind +- : LoongArchAsmParser::classifySymbolRef(getImm(), VK) && +- IsValidKind; +- } ++ struct RegListOp { ++ SmallVector *List; ++ }; + +- bool isSImm21lsl2() const { +- if (!isImm()) +- return false; ++ union { ++ struct Token Tok; ++ struct RegIdxOp RegIdx; ++ struct ImmOp Imm; ++ struct MemOp Mem; ++ struct RegListOp RegList; ++ }; + +- int64_t Imm; +- LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None; +- bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); +- bool IsValidKind = VK == LoongArchMCExpr::VK_LoongArch_None || +- VK == LoongArchMCExpr::VK_LoongArch_B21; +- return IsConstantImm +- ? isShiftedInt<21, 2>(Imm) && IsValidKind +- : LoongArchAsmParser::classifySymbolRef(getImm(), VK) && +- IsValidKind; +- } +- +- bool isSImm26Operand() const { +- if (!isImm()) +- return false; ++ SMLoc StartLoc, EndLoc; + +- int64_t Imm; +- LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None; +- bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); +- bool IsValidKind = VK == LoongArchMCExpr::VK_LoongArch_None || +- VK == LoongArchMCExpr::VK_LoongArch_CALL || +- VK == LoongArchMCExpr::VK_LoongArch_CALL_PLT || +- VK == LoongArchMCExpr::VK_LoongArch_B26; +- return IsConstantImm +- ? isShiftedInt<26, 2>(Imm) && IsValidKind +- : LoongArchAsmParser::classifySymbolRef(getImm(), VK) && +- IsValidKind; ++ /// Internal constructor for register kinds ++ static std::unique_ptr CreateReg(unsigned Index, StringRef Str, ++ RegKind RegKind, ++ const MCRegisterInfo *RegInfo, ++ SMLoc S, SMLoc E, ++ LoongArchAsmParser &Parser) { ++ auto Op = std::make_unique(k_RegisterIndex, Parser); ++ Op->RegIdx.Index = Index; ++ Op->RegIdx.RegInfo = RegInfo; ++ Op->RegIdx.Kind = RegKind; ++ Op->RegIdx.Tok.Data = Str.data(); ++ Op->RegIdx.Tok.Length = Str.size(); ++ Op->StartLoc = S; ++ Op->EndLoc = E; ++ return Op; + } + +- bool isImm32() const { return isSImm<32>() || isUImm<32>(); } +- +- /// Gets location of the first token of this operand. +- SMLoc getStartLoc() const override { return StartLoc; } +- /// Gets location of the last token of this operand. +- SMLoc getEndLoc() const override { return EndLoc; } ++public: ++ /// Coerce the register to GPR32 and return the real register for the current ++ /// target. ++ unsigned getGPR32Reg() const { ++ assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); ++ unsigned ClassID = LoongArch::GPR32RegClassID; ++ return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); ++ } + +- unsigned getReg() const override { +- assert(Kind == KindTy::Register && "Invalid type access!"); +- return Reg.RegNum.id(); ++ /// Coerce the register to GPR32 and return the real register for the current ++ /// target. ++ unsigned getGPRMM16Reg() const { ++ assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); ++ unsigned ClassID = LoongArch::GPR32RegClassID; ++ return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); + } + +- const MCExpr *getImm() const { +- assert(Kind == KindTy::Immediate && "Invalid type access!"); +- return Imm.Val; ++ /// Coerce the register to GPR64 and return the real register for the current ++ /// target. ++ unsigned getGPR64Reg() const { ++ assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); ++ unsigned ClassID = LoongArch::GPR64RegClassID; ++ return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); + } + +- StringRef getToken() const { +- assert(Kind == KindTy::Token && "Invalid type access!"); +- return Tok; ++private: ++ /// Coerce the register to FGR64 and return the real register for the current ++ /// target. ++ unsigned getFGR64Reg() const { ++ assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); ++ return RegIdx.RegInfo->getRegClass(LoongArch::FGR64RegClassID) ++ .getRegister(RegIdx.Index); + } + +- void print(raw_ostream &OS) const override { +- auto RegName = [](MCRegister Reg) { +- if (Reg) +- return LoongArchInstPrinter::getRegisterName(Reg); +- else +- return "noreg"; +- }; ++ /// Coerce the register to FGR32 and return the real register for the current ++ /// target. ++ unsigned getFGR32Reg() const { ++ assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); ++ return RegIdx.RegInfo->getRegClass(LoongArch::FGR32RegClassID) ++ .getRegister(RegIdx.Index); ++ } + +- switch (Kind) { +- case KindTy::Immediate: +- OS << *getImm(); +- break; +- case KindTy::Register: +- OS << ""; +- break; +- case KindTy::Token: +- OS << "'" << getToken() << "'"; +- break; +- } ++ /// Coerce the register to FCFR and return the real register for the current ++ /// target. ++ unsigned getFCFRReg() const { ++ assert(isRegIdx() && (RegIdx.Kind & RegKind_FCFR) && "Invalid access!"); ++ return RegIdx.RegInfo->getRegClass(LoongArch::FCFRRegClassID) ++ .getRegister(RegIdx.Index); + } + +- static std::unique_ptr createToken(StringRef Str, SMLoc S) { +- auto Op = std::make_unique(KindTy::Token); +- Op->Tok = Str; +- Op->StartLoc = S; +- Op->EndLoc = S; +- return Op; ++ /// Coerce the register to LSX128 and return the real register for the current ++ /// target. ++ unsigned getLSX128Reg() const { ++ assert(isRegIdx() && (RegIdx.Kind & RegKind_LSX128) && "Invalid access!"); ++ // It doesn't matter which of the LSX128[BHWD] classes we use. They are all ++ // identical ++ unsigned ClassID = LoongArch::LSX128BRegClassID; ++ return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); + } + +- static std::unique_ptr createReg(unsigned RegNo, SMLoc S, +- SMLoc E) { +- auto Op = std::make_unique(KindTy::Register); +- Op->Reg.RegNum = RegNo; +- Op->StartLoc = S; +- Op->EndLoc = E; +- return Op; ++ unsigned getLASX256Reg() const { ++ assert(isRegIdx() && (RegIdx.Kind & RegKind_LASX256) && "Invalid access!"); ++ unsigned ClassID = LoongArch::LASX256BRegClassID; ++ return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); + } + +- static std::unique_ptr createImm(const MCExpr *Val, SMLoc S, +- SMLoc E) { +- auto Op = std::make_unique(KindTy::Immediate); +- Op->Imm.Val = Val; +- Op->StartLoc = S; +- Op->EndLoc = E; +- return Op; ++ /// Coerce the register to CCR and return the real register for the ++ /// current target. ++ unsigned getFCSRReg() const { ++ assert(isRegIdx() && (RegIdx.Kind & RegKind_FCSR) && "Invalid access!"); ++ unsigned ClassID = LoongArch::FCSRRegClassID; ++ return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); + } + ++public: + void addExpr(MCInst &Inst, const MCExpr *Expr) const { +- if (auto CE = dyn_cast(Expr)) ++ // Add as immediate when possible. Null MCExpr = 0. ++ if (!Expr) ++ Inst.addOperand(MCOperand::createImm(0)); ++ else if (const MCConstantExpr *CE = dyn_cast(Expr)) + Inst.addOperand(MCOperand::createImm(CE->getValue())); + else + Inst.addOperand(MCOperand::createExpr(Expr)); + } + +- // Used by the TableGen Code. + void addRegOperands(MCInst &Inst, unsigned N) const { ++ llvm_unreachable("Use a custom parser instead"); ++ } ++ ++ /// Render the operand to an MCInst as a GPR32 ++ /// Asserts if the wrong number of operands are requested, or the operand ++ /// is not a k_RegisterIndex compatible with RegKind_GPR ++ void addGPR32ZeroAsmRegOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); +- Inst.addOperand(MCOperand::createReg(getReg())); ++ Inst.addOperand(MCOperand::createReg(getGPR32Reg())); + } +- void addImmOperands(MCInst &Inst, unsigned N) const { ++ ++ void addGPR32NonZeroAsmRegOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); +- addExpr(Inst, getImm()); ++ Inst.addOperand(MCOperand::createReg(getGPR32Reg())); + } +-}; +-} // end namespace + +-#define GET_REGISTER_MATCHER +-#define GET_SUBTARGET_FEATURE_NAME +-#define GET_MATCHER_IMPLEMENTATION +-#define GET_MNEMONIC_SPELL_CHECKER +-#include "LoongArchGenAsmMatcher.inc" ++ void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const { ++ assert(N == 1 && "Invalid number of operands!"); ++ Inst.addOperand(MCOperand::createReg(getGPR32Reg())); ++ } + +-static MCRegister convertFPR32ToFPR64(MCRegister Reg) { +- assert(Reg >= LoongArch::F0 && Reg <= LoongArch::F31 && "Invalid register"); +- return Reg - LoongArch::F0 + LoongArch::F0_64; +-} ++ void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const { ++ assert(N == 1 && "Invalid number of operands!"); ++ Inst.addOperand(MCOperand::createReg(getGPRMM16Reg())); ++ } + +-// Attempts to match Name as a register (either using the default name or +-// alternative ABI names), setting RegNo to the matching register. Upon +-// failure, returns true and sets RegNo to 0. +-static bool matchRegisterNameHelper(MCRegister &RegNo, StringRef Name) { +- RegNo = MatchRegisterName(Name); +- // The 32-bit and 64-bit FPRs have the same asm name. Check that the initial +- // match always matches the 32-bit variant, and not the 64-bit one. +- assert(!(RegNo >= LoongArch::F0_64 && RegNo <= LoongArch::F31_64)); +- // The default FPR register class is based on the tablegen enum ordering. +- static_assert(LoongArch::F0 < LoongArch::F0_64, +- "FPR matching must be updated"); +- if (RegNo == LoongArch::NoRegister) +- RegNo = MatchRegisterAltName(Name); +- +- return RegNo == LoongArch::NoRegister; +-} ++ void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const { ++ assert(N == 1 && "Invalid number of operands!"); ++ Inst.addOperand(MCOperand::createReg(getGPRMM16Reg())); ++ } + +-bool LoongArchAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc, +- SMLoc &EndLoc) { +- return Error(getLoc(), "invalid register number"); +-} ++ void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const { ++ assert(N == 1 && "Invalid number of operands!"); ++ Inst.addOperand(MCOperand::createReg(getGPRMM16Reg())); ++ } + +-ParseStatus LoongArchAsmParser::tryParseRegister(MCRegister &Reg, +- SMLoc &StartLoc, +- SMLoc &EndLoc) { +- llvm_unreachable("Unimplemented function."); +-} ++ void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst, unsigned N) const { ++ assert(N == 1 && "Invalid number of operands!"); ++ Inst.addOperand(MCOperand::createReg(getGPRMM16Reg())); ++ } + +-bool LoongArchAsmParser::classifySymbolRef(const MCExpr *Expr, +- LoongArchMCExpr::VariantKind &Kind) { +- Kind = LoongArchMCExpr::VK_LoongArch_None; ++ void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst, ++ unsigned N) const { ++ assert(N == 1 && "Invalid number of operands!"); ++ Inst.addOperand(MCOperand::createReg(getGPRMM16Reg())); ++ } + +- if (const LoongArchMCExpr *RE = dyn_cast(Expr)) { +- Kind = RE->getKind(); +- Expr = RE->getSubExpr(); ++ /// Render the operand to an MCInst as a GPR64 ++ /// Asserts if the wrong number of operands are requested, or the operand ++ /// is not a k_RegisterIndex compatible with RegKind_GPR ++ void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const { ++ assert(N == 1 && "Invalid number of operands!"); ++ Inst.addOperand(MCOperand::createReg(getGPR64Reg())); + } + +- MCValue Res; +- if (Expr->evaluateAsRelocatable(Res, nullptr, nullptr)) +- return Res.getRefKind() == LoongArchMCExpr::VK_LoongArch_None; +- return false; +-} ++ void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const { ++ assert(N == 1 && "Invalid number of operands!"); ++ Inst.addOperand(MCOperand::createReg(getFGR64Reg())); ++ } + +-ParseStatus LoongArchAsmParser::parseRegister(OperandVector &Operands) { +- if (!parseOptionalToken(AsmToken::Dollar)) +- return ParseStatus::NoMatch; +- if (getLexer().getKind() != AsmToken::Identifier) +- return ParseStatus::NoMatch; ++ void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const { ++ assert(N == 1 && "Invalid number of operands!"); ++ Inst.addOperand(MCOperand::createReg(getFGR64Reg())); ++ } + +- StringRef Name = getLexer().getTok().getIdentifier(); +- MCRegister RegNo; +- matchRegisterNameHelper(RegNo, Name); +- if (RegNo == LoongArch::NoRegister) +- return ParseStatus::NoMatch; ++ void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const { ++ assert(N == 1 && "Invalid number of operands!"); ++ Inst.addOperand(MCOperand::createReg(getFGR32Reg())); ++ } + +- SMLoc S = getLoc(); +- SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size()); +- getLexer().Lex(); +- Operands.push_back(LoongArchOperand::createReg(RegNo, S, E)); ++ void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const { ++ assert(N == 1 && "Invalid number of operands!"); ++ Inst.addOperand(MCOperand::createReg(getFGR32Reg())); ++ } + +- return ParseStatus::Success; +-} ++ void addFCFRAsmRegOperands(MCInst &Inst, unsigned N) const { ++ assert(N == 1 && "Invalid number of operands!"); ++ Inst.addOperand(MCOperand::createReg(getFCFRReg())); ++ } + +-ParseStatus LoongArchAsmParser::parseImmediate(OperandVector &Operands) { +- SMLoc S = getLoc(); +- SMLoc E; +- const MCExpr *Res; ++ void addLSX128AsmRegOperands(MCInst &Inst, unsigned N) const { ++ assert(N == 1 && "Invalid number of operands!"); ++ Inst.addOperand(MCOperand::createReg(getLSX128Reg())); ++ } + +- switch (getLexer().getKind()) { +- default: +- return ParseStatus::NoMatch; +- case AsmToken::LParen: +- case AsmToken::Dot: +- case AsmToken::Minus: +- case AsmToken::Plus: +- case AsmToken::Exclaim: +- case AsmToken::Tilde: +- case AsmToken::Integer: +- case AsmToken::String: +- case AsmToken::Identifier: +- if (getParser().parseExpression(Res, E)) +- return ParseStatus::Failure; +- break; +- case AsmToken::Percent: +- return parseOperandWithModifier(Operands); ++ void addLASX256AsmRegOperands(MCInst &Inst, unsigned N) const { ++ assert(N == 1 && "Invalid number of operands!"); ++ Inst.addOperand(MCOperand::createReg(getLASX256Reg())); + } + +- Operands.push_back(LoongArchOperand::createImm(Res, S, E)); +- return ParseStatus::Success; +-} ++ void addFCSRAsmRegOperands(MCInst &Inst, unsigned N) const { ++ assert(N == 1 && "Invalid number of operands!"); ++ Inst.addOperand(MCOperand::createReg(getFCSRReg())); ++ } + +-ParseStatus +-LoongArchAsmParser::parseOperandWithModifier(OperandVector &Operands) { +- SMLoc S = getLoc(); +- SMLoc E; ++ template ++ void addConstantUImmOperands(MCInst &Inst, unsigned N) const { ++ assert(N == 1 && "Invalid number of operands!"); ++ uint64_t Imm = getConstantImm() - Offset; ++ Imm &= (1ULL << Bits) - 1; ++ Imm += Offset; ++ Imm += AdjustOffset; ++ Inst.addOperand(MCOperand::createImm(Imm)); ++ } + +- if (getLexer().getKind() != AsmToken::Percent) +- return Error(getLoc(), "expected '%' for operand modifier"); ++ template ++ void addSImmOperands(MCInst &Inst, unsigned N) const { ++ if (isImm() && !isConstantImm()) { ++ addExpr(Inst, getImm()); ++ return; ++ } ++ addConstantSImmOperands(Inst, N); ++ } + +- getParser().Lex(); // Eat '%' ++ template ++ void addUImmOperands(MCInst &Inst, unsigned N) const { ++ if (isImm() && !isConstantImm()) { ++ addExpr(Inst, getImm()); ++ return; ++ } ++ addConstantUImmOperands(Inst, N); ++ } + +- if (getLexer().getKind() != AsmToken::Identifier) +- return Error(getLoc(), "expected valid identifier for operand modifier"); +- StringRef Identifier = getParser().getTok().getIdentifier(); +- LoongArchMCExpr::VariantKind VK = +- LoongArchMCExpr::getVariantKindForName(Identifier); +- if (VK == LoongArchMCExpr::VK_LoongArch_Invalid) +- return Error(getLoc(), "unrecognized operand modifier"); ++ template ++ void addConstantSImmOperands(MCInst &Inst, unsigned N) const { ++ assert(N == 1 && "Invalid number of operands!"); ++ int64_t Imm = getConstantImm() - Offset; ++ Imm = SignExtend64(Imm); ++ Imm += Offset; ++ Imm += AdjustOffset; ++ Inst.addOperand(MCOperand::createImm(Imm)); ++ } + +- getParser().Lex(); // Eat the identifier +- if (getLexer().getKind() != AsmToken::LParen) +- return Error(getLoc(), "expected '('"); +- getParser().Lex(); // Eat '(' ++ void addImmOperands(MCInst &Inst, unsigned N) const { ++ assert(N == 1 && "Invalid number of operands!"); ++ const MCExpr *Expr = getImm(); ++ addExpr(Inst, Expr); ++ } + +- const MCExpr *SubExpr; +- if (getParser().parseParenExpression(SubExpr, E)) +- return ParseStatus::Failure; ++ void addMemOperands(MCInst &Inst, unsigned N) const { ++ assert(N == 2 && "Invalid number of operands!"); + +- const MCExpr *ModExpr = LoongArchMCExpr::create(SubExpr, VK, getContext()); +- Operands.push_back(LoongArchOperand::createImm(ModExpr, S, E)); +- return ParseStatus::Success; +-} ++ Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit() ++ ? getMemBase()->getGPR64Reg() ++ : getMemBase()->getGPR32Reg())); + +-ParseStatus LoongArchAsmParser::parseSImm26Operand(OperandVector &Operands) { +- SMLoc S = getLoc(); +- const MCExpr *Res; ++ const MCExpr *Expr = getMemOff(); ++ addExpr(Inst, Expr); ++ } + +- if (getLexer().getKind() == AsmToken::Percent) +- return parseOperandWithModifier(Operands); ++ void addRegListOperands(MCInst &Inst, unsigned N) const { ++ assert(N == 1 && "Invalid number of operands!"); + +- if (getLexer().getKind() != AsmToken::Identifier) +- return ParseStatus::NoMatch; ++ for (auto RegNo : getRegList()) ++ Inst.addOperand(MCOperand::createReg(RegNo)); ++ } + +- StringRef Identifier; +- if (getParser().parseIdentifier(Identifier)) +- return ParseStatus::Failure; ++ bool isReg() const override { ++ // As a special case until we sort out the definition of div/divu, accept ++ // $0/$zero here so that MCK_ZERO works correctly. ++ return isGPRAsmReg() && RegIdx.Index == 0; ++ } + +- SMLoc E = SMLoc::getFromPointer(S.getPointer() + Identifier.size()); ++ bool isRegIdx() const { return Kind == k_RegisterIndex; } ++ bool isImm() const override { return Kind == k_Immediate; } + +- MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); +- Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); +- Res = LoongArchMCExpr::create(Res, LoongArchMCExpr::VK_LoongArch_CALL, +- getContext()); +- Operands.push_back(LoongArchOperand::createImm(Res, S, E)); +- return ParseStatus::Success; +-} ++ bool isConstantImm() const { ++ int64_t Res; ++ return isImm() && getImm()->evaluateAsAbsolute(Res); ++ } + +-ParseStatus LoongArchAsmParser::parseAtomicMemOp(OperandVector &Operands) { +- // Parse "$r*". +- if (!parseRegister(Operands).isSuccess()) +- return ParseStatus::NoMatch; ++ bool isConstantImmz() const { ++ return isConstantImm() && getConstantImm() == 0; ++ } + +- // If there is a next operand and it is 0, ignore it. Otherwise print a +- // diagnostic message. +- if (parseOptionalToken(AsmToken::Comma)) { +- int64_t ImmVal; +- SMLoc ImmStart = getLoc(); +- if (getParser().parseIntToken(ImmVal, "expected optional integer offset")) +- return ParseStatus::Failure; +- if (ImmVal) +- return Error(ImmStart, "optional integer offset must be 0"); ++ template bool isConstantUImm() const { ++ return isConstantImm() && isUInt(getConstantImm() - Offset); + } + +- return ParseStatus::Success; +-} +-/// Looks at a token type and creates the relevant operand from this +-/// information, adding to Operands. Return true upon an error. +-bool LoongArchAsmParser::parseOperand(OperandVector &Operands, +- StringRef Mnemonic) { +- // Check if the current operand has a custom associated parser, if so, try to +- // custom parse the operand, or fallback to the general approach. +- ParseStatus Result = +- MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); +- if (Result.isSuccess()) +- return false; +- if (Result.isFailure()) +- return true; ++ template bool isSImm() const { ++ return isConstantImm() ? isInt(getConstantImm()) : isImm(); ++ } + +- if (parseRegister(Operands).isSuccess() || +- parseImmediate(Operands).isSuccess()) +- return false; ++ template bool isUImm() const { ++ return isConstantImm() ? isUInt(getConstantImm()) : isImm(); ++ } + +- // Finally we have exhausted all options and must declare defeat. +- return Error(getLoc(), "unknown operand"); +-} ++ template bool isAnyImm() const { ++ return isConstantImm() ? (isInt(getConstantImm()) || ++ isUInt(getConstantImm())) ++ : isImm(); ++ } + +-bool LoongArchAsmParser::ParseInstruction(ParseInstructionInfo &Info, +- StringRef Name, SMLoc NameLoc, +- OperandVector &Operands) { +- // First operand in MCInst is instruction mnemonic. +- Operands.push_back(LoongArchOperand::createToken(Name, NameLoc)); ++ template bool isConstantSImm() const { ++ return isConstantImm() && isInt(getConstantImm() - Offset); ++ } + +- // If there are no more operands, then finish. +- if (parseOptionalToken(AsmToken::EndOfStatement)) +- return false; ++ template bool isConstantUImmRange() const { ++ return isConstantImm() && getConstantImm() >= Bottom && ++ getConstantImm() <= Top; ++ } + +- // Parse first operand. +- if (parseOperand(Operands, Name)) +- return true; ++ bool isToken() const override { ++ // Note: It's not possible to pretend that other operand kinds are tokens. ++ // The matcher emitter checks tokens first. ++ return Kind == k_Token; ++ } + +- // Parse until end of statement, consuming commas between operands. +- while (parseOptionalToken(AsmToken::Comma)) +- if (parseOperand(Operands, Name)) +- return true; ++ bool isMem() const override { return Kind == k_Memory; } + +- // Parse end of statement and return successfully. +- if (parseOptionalToken(AsmToken::EndOfStatement)) +- return false; ++ bool isConstantMemOff() const { ++ return isMem() && isa(getMemOff()); ++ } + +- SMLoc Loc = getLexer().getLoc(); +- getParser().eatToEndOfStatement(); +- return Error(Loc, "unexpected token"); +-} ++ bool isZeroMemOff() const { ++ return isMem() && isa(getMemOff()) && ++ getConstantMemOff() == 0; ++ } + +-void LoongArchAsmParser::emitLAInstSeq(MCRegister DestReg, MCRegister TmpReg, +- const MCExpr *Symbol, +- SmallVectorImpl &Insts, +- SMLoc IDLoc, MCStreamer &Out, +- bool RelaxHint) { +- MCContext &Ctx = getContext(); +- for (LoongArchAsmParser::Inst &Inst : Insts) { +- unsigned Opc = Inst.Opc; +- LoongArchMCExpr::VariantKind VK = Inst.VK; +- const LoongArchMCExpr *LE = +- LoongArchMCExpr::create(Symbol, VK, Ctx, RelaxHint); +- switch (Opc) { +- default: +- llvm_unreachable("unexpected opcode"); +- case LoongArch::PCALAU12I: +- case LoongArch::LU12I_W: +- Out.emitInstruction(MCInstBuilder(Opc).addReg(DestReg).addExpr(LE), +- getSTI()); +- break; +- case LoongArch::ORI: +- case LoongArch::ADDI_W: +- case LoongArch::LD_W: +- case LoongArch::LD_D: { +- if (VK == LoongArchMCExpr::VK_LoongArch_None) { +- Out.emitInstruction( +- MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addImm(0), +- getSTI()); +- continue; +- } +- Out.emitInstruction( +- MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addExpr(LE), +- getSTI()); +- break; ++ // Allow relocation operators. ++ // FIXME: This predicate and others need to look through binary expressions ++ // and determine whether a Value is a constant or not. ++ template ++ bool isMemWithSimmOffset() const { ++ if (!isMem()) ++ return false; ++ if (!getMemBase()->isGPRAsmReg()) ++ return false; ++ if (isa(getMemOff()) || ++ (isConstantMemOff() && ++ isShiftedInt(getConstantMemOff()))) ++ return true; ++ MCValue Res; ++ bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr); ++ return IsReloc && isShiftedInt(Res.getConstant()); ++ } ++ ++ bool isMemWithPtrSizeOffset() const { ++ if (!isMem()) ++ return false; ++ if (!getMemBase()->isGPRAsmReg()) ++ return false; ++ const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32; ++ if (isa(getMemOff()) || ++ (isConstantMemOff() && isIntN(PtrBits, getConstantMemOff()))) ++ return true; ++ MCValue Res; ++ bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr); ++ return IsReloc && isIntN(PtrBits, Res.getConstant()); ++ } ++ ++ bool isMemWithGRPMM16Base() const { ++ return isMem() && getMemBase()->isMM16AsmReg(); ++ } ++ ++ template bool isMemWithUimmOffsetSP() const { ++ return isMem() && isConstantMemOff() && isUInt(getConstantMemOff()) ++ && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == LoongArch::SP); ++ } ++ ++ template bool isMemWithUimmWordAlignedOffsetSP() const { ++ return isMem() && isConstantMemOff() && isUInt(getConstantMemOff()) ++ && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx() ++ && (getMemBase()->getGPR32Reg() == LoongArch::SP); ++ } ++ ++ template ++ bool isScaledUImm() const { ++ return isConstantImm() && ++ isShiftedUInt(getConstantImm()); ++ } ++ ++ template ++ bool isScaledSImm() const { ++ if (isConstantImm() && ++ isShiftedInt(getConstantImm())) ++ return true; ++ // Operand can also be a symbol or symbol plus ++ // offset in case of relocations. ++ if (Kind != k_Immediate) ++ return false; ++ MCValue Res; ++ bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr); ++ return Success && isShiftedInt(Res.getConstant()); ++ } ++ ++ bool isRegList16() const { ++ if (!isRegList()) ++ return false; ++ ++ int Size = RegList.List->size(); ++ if (Size < 2 || Size > 5) ++ return false; ++ ++ unsigned R0 = RegList.List->front(); ++ unsigned R1 = RegList.List->back(); ++ if (!((R0 == LoongArch::S0 && R1 == LoongArch::RA) || ++ (R0 == LoongArch::S0_64 && R1 == LoongArch::RA_64))) ++ return false; ++ ++ int PrevReg = *RegList.List->begin(); ++ for (int i = 1; i < Size - 1; i++) { ++ int Reg = (*(RegList.List))[i]; ++ if ( Reg != PrevReg + 1) ++ return false; ++ PrevReg = Reg; + } +- case LoongArch::LU32I_D: +- Out.emitInstruction(MCInstBuilder(Opc) +- .addReg(DestReg == TmpReg ? DestReg : TmpReg) +- .addReg(DestReg == TmpReg ? DestReg : TmpReg) +- .addExpr(LE), +- getSTI()); ++ ++ return true; ++ } ++ ++ bool isInvNum() const { return Kind == k_Immediate; } ++ ++ bool isLSAImm() const { ++ if (!isConstantImm()) ++ return false; ++ int64_t Val = getConstantImm(); ++ return 1 <= Val && Val <= 4; ++ } ++ ++ bool isRegList() const { return Kind == k_RegList; } ++ ++ StringRef getToken() const { ++ assert(Kind == k_Token && "Invalid access!"); ++ return StringRef(Tok.Data, Tok.Length); ++ } ++ ++ unsigned getReg() const override { ++ // As a special case until we sort out the definition of div/divu, accept ++ // $0/$zero here so that MCK_ZERO works correctly. ++ if (Kind == k_RegisterIndex && RegIdx.Index == 0 && ++ RegIdx.Kind & RegKind_GPR) ++ return getGPR32Reg(); // FIXME: GPR64 too ++ ++ llvm_unreachable("Invalid access!"); ++ return 0; ++ } ++ ++ const MCExpr *getImm() const { ++ assert((Kind == k_Immediate) && "Invalid access!"); ++ return Imm.Val; ++ } ++ ++ int64_t getConstantImm() const { ++ const MCExpr *Val = getImm(); ++ int64_t Value = 0; ++ (void)Val->evaluateAsAbsolute(Value); ++ return Value; ++ } ++ ++ LoongArchOperand *getMemBase() const { ++ assert((Kind == k_Memory) && "Invalid access!"); ++ return Mem.Base; ++ } ++ ++ const MCExpr *getMemOff() const { ++ assert((Kind == k_Memory) && "Invalid access!"); ++ return Mem.Off; ++ } ++ ++ int64_t getConstantMemOff() const { ++ return static_cast(getMemOff())->getValue(); ++ } ++ ++ const SmallVectorImpl &getRegList() const { ++ assert((Kind == k_RegList) && "Invalid access!"); ++ return *(RegList.List); ++ } ++ ++ static std::unique_ptr CreateToken(StringRef Str, SMLoc S, ++ LoongArchAsmParser &Parser) { ++ auto Op = std::make_unique(k_Token, Parser); ++ Op->Tok.Data = Str.data(); ++ Op->Tok.Length = Str.size(); ++ Op->StartLoc = S; ++ Op->EndLoc = S; ++ return Op; ++ } ++ ++ /// Create a numeric register (e.g. $1). The exact register remains ++ /// unresolved until an instruction successfully matches ++ static std::unique_ptr ++ createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo, ++ SMLoc S, SMLoc E, LoongArchAsmParser &Parser) { ++ LLVM_DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n"); ++ return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser); ++ } ++ ++ /// Create a register that is definitely a GPR. ++ /// This is typically only used for named registers such as $gp. ++ static std::unique_ptr ++ createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo, ++ SMLoc S, SMLoc E, LoongArchAsmParser &Parser) { ++ return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser); ++ } ++ ++ /// Create a register that is definitely a FGR. ++ /// This is typically only used for named registers such as $f0. ++ static std::unique_ptr ++ createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo, ++ SMLoc S, SMLoc E, LoongArchAsmParser &Parser) { ++ return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser); ++ } ++ ++ /// Create a register that is definitely an FCFR. ++ /// This is typically only used for named registers such as $fcc0. ++ static std::unique_ptr ++ createFCFRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo, ++ SMLoc S, SMLoc E, LoongArchAsmParser &Parser) { ++ return CreateReg(Index, Str, RegKind_FCFR, RegInfo, S, E, Parser); ++ } ++ ++ /// Create a register that is definitely an FCSR. ++ /// This is typically only used for named registers such as $fcsr0. ++ static std::unique_ptr ++ createFCSRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo, ++ SMLoc S, SMLoc E, LoongArchAsmParser &Parser) { ++ return CreateReg(Index, Str, RegKind_FCSR, RegInfo, S, E, Parser); ++ } ++ ++ /// Create a register that is definitely an LSX128. ++ /// This is typically only used for named registers such as $v0. ++ static std::unique_ptr ++ createLSX128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo, ++ SMLoc S, SMLoc E, LoongArchAsmParser &Parser) { ++ return CreateReg(Index, Str, RegKind_LSX128, RegInfo, S, E, Parser); ++ } ++ ++ static std::unique_ptr ++ createLASX256Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo, ++ SMLoc S, SMLoc E, LoongArchAsmParser &Parser) { ++ return CreateReg(Index, Str, RegKind_LASX256, RegInfo, S, E, Parser); ++ } ++ ++ static std::unique_ptr ++ CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, LoongArchAsmParser &Parser) { ++ auto Op = std::make_unique(k_Immediate, Parser); ++ Op->Imm.Val = Val; ++ Op->StartLoc = S; ++ Op->EndLoc = E; ++ return Op; ++ } ++ ++ static std::unique_ptr ++ CreateMem(std::unique_ptr Base, const MCExpr *Off, SMLoc S, ++ SMLoc E, LoongArchAsmParser &Parser) { ++ auto Op = std::make_unique(k_Memory, Parser); ++ Op->Mem.Base = Base.release(); ++ Op->Mem.Off = Off; ++ Op->StartLoc = S; ++ Op->EndLoc = E; ++ return Op; ++ } ++ ++ static std::unique_ptr ++ CreateRegList(SmallVectorImpl &Regs, SMLoc StartLoc, SMLoc EndLoc, ++ LoongArchAsmParser &Parser) { ++ assert(Regs.size() > 0 && "Empty list not allowed"); ++ ++ auto Op = std::make_unique(k_RegList, Parser); ++ Op->RegList.List = new SmallVector(Regs.begin(), Regs.end()); ++ Op->StartLoc = StartLoc; ++ Op->EndLoc = EndLoc; ++ return Op; ++ } ++ ++ bool isGPRZeroAsmReg() const { ++ return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0; ++ } ++ ++ bool isGPRNonZeroAsmReg() const { ++ return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 && ++ RegIdx.Index <= 31; ++ } ++ ++ bool isGPRAsmReg() const { ++ return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31; ++ } ++ ++ bool isMM16AsmReg() const { ++ if (!(isRegIdx() && RegIdx.Kind)) ++ return false; ++ return ((RegIdx.Index >= 2 && RegIdx.Index <= 7) ++ || RegIdx.Index == 16 || RegIdx.Index == 17); ++ ++ } ++ bool isMM16AsmRegZero() const { ++ if (!(isRegIdx() && RegIdx.Kind)) ++ return false; ++ return (RegIdx.Index == 0 || ++ (RegIdx.Index >= 2 && RegIdx.Index <= 7) || ++ RegIdx.Index == 17); ++ } ++ ++ bool isMM16AsmRegMoveP() const { ++ if (!(isRegIdx() && RegIdx.Kind)) ++ return false; ++ return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) || ++ (RegIdx.Index >= 16 && RegIdx.Index <= 20)); ++ } ++ ++ bool isMM16AsmRegMovePPairFirst() const { ++ if (!(isRegIdx() && RegIdx.Kind)) ++ return false; ++ return RegIdx.Index >= 4 && RegIdx.Index <= 6; ++ } ++ ++ bool isMM16AsmRegMovePPairSecond() const { ++ if (!(isRegIdx() && RegIdx.Kind)) ++ return false; ++ return (RegIdx.Index == 21 || RegIdx.Index == 22 || ++ (RegIdx.Index >= 5 && RegIdx.Index <= 7)); ++ } ++ ++ bool isFGRAsmReg() const { ++ return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31; ++ } ++ ++ bool isStrictlyFGRAsmReg() const { ++ return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31; ++ } ++ ++ bool isFCSRAsmReg() const { ++ return isRegIdx() && RegIdx.Kind & RegKind_FCSR && RegIdx.Index <= 3; ++ } ++ ++ bool isFCFRAsmReg() const { ++ if (!(isRegIdx() && RegIdx.Kind & RegKind_FCFR)) ++ return false; ++ return RegIdx.Index <= 7; ++ } ++ ++ bool isLSX128AsmReg() const { ++ return isRegIdx() && RegIdx.Kind & RegKind_LSX128 && RegIdx.Index <= 31; ++ } ++ ++ bool isLASX256AsmReg() const { ++ return isRegIdx() && RegIdx.Kind & RegKind_LASX256 && RegIdx.Index <= 31; ++ } ++ ++ /// getStartLoc - Get the location of the first token of this operand. ++ SMLoc getStartLoc() const override { return StartLoc; } ++ /// getEndLoc - Get the location of the last token of this operand. ++ SMLoc getEndLoc() const override { return EndLoc; } ++ ++ void print(raw_ostream &OS) const override { ++ switch (Kind) { ++ case k_Immediate: ++ OS << "Imm<"; ++ OS << *Imm.Val; ++ OS << ">"; + break; +- case LoongArch::LU52I_D: +- Out.emitInstruction( +- MCInstBuilder(Opc).addReg(TmpReg).addReg(TmpReg).addExpr(LE), +- getSTI()); ++ case k_Memory: ++ OS << "Mem<"; ++ Mem.Base->print(OS); ++ OS << ", "; ++ OS << *Mem.Off; ++ OS << ">"; + break; +- case LoongArch::ADDI_D: +- Out.emitInstruction( +- MCInstBuilder(Opc) +- .addReg(TmpReg) +- .addReg(DestReg == TmpReg ? TmpReg : LoongArch::R0) +- .addExpr(LE), +- getSTI()); ++ case k_RegisterIndex: ++ OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", " ++ << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">"; + break; +- case LoongArch::ADD_D: +- case LoongArch::LDX_D: +- Out.emitInstruction( +- MCInstBuilder(Opc).addReg(DestReg).addReg(DestReg).addReg(TmpReg), +- getSTI()); ++ case k_Token: ++ OS << getToken(); ++ break; ++ case k_RegList: ++ OS << "RegList< "; ++ for (auto Reg : (*RegList.List)) ++ OS << Reg << " "; ++ OS << ">"; + break; + } + } +-} + +-void LoongArchAsmParser::emitLoadAddressAbs(MCInst &Inst, SMLoc IDLoc, +- MCStreamer &Out) { +- // la.abs $rd, sym +- // expands to: +- // lu12i.w $rd, %abs_hi20(sym) +- // ori $rd, $rd, %abs_lo12(sym) +- // +- // for 64bit appends: +- // lu32i.d $rd, %abs64_lo20(sym) +- // lu52i.d $rd, $rd, %abs64_hi12(sym) +- MCRegister DestReg = Inst.getOperand(0).getReg(); +- const MCExpr *Symbol = Inst.getOpcode() == LoongArch::PseudoLA_ABS +- ? Inst.getOperand(1).getExpr() +- : Inst.getOperand(2).getExpr(); +- InstSeq Insts; +- +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::LU12I_W, LoongArchMCExpr::VK_LoongArch_ABS_HI20)); +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::ORI, LoongArchMCExpr::VK_LoongArch_ABS_LO12)); +- +- if (is64Bit()) { +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::LU32I_D, LoongArchMCExpr::VK_LoongArch_ABS64_LO20)); +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::LU52I_D, LoongArchMCExpr::VK_LoongArch_ABS64_HI12)); +- } +- +- emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out); +-} ++ bool isValidForTie(const LoongArchOperand &Other) const { ++ if (Kind != Other.Kind) ++ return false; + +-void LoongArchAsmParser::emitLoadAddressPcrel(MCInst &Inst, SMLoc IDLoc, +- MCStreamer &Out) { +- // la.pcrel $rd, sym +- // expands to: +- // pcalau12i $rd, %pc_hi20(sym) +- // addi.w/d $rd, rd, %pc_lo12(sym) +- MCRegister DestReg = Inst.getOperand(0).getReg(); +- const MCExpr *Symbol = Inst.getOperand(1).getExpr(); +- InstSeq Insts; +- unsigned ADDI = is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W; +- +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::PCALAU12I, LoongArchMCExpr::VK_LoongArch_PCALA_HI20)); +- Insts.push_back( +- LoongArchAsmParser::Inst(ADDI, LoongArchMCExpr::VK_LoongArch_PCALA_LO12)); +- +- emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out, true); +-} ++ switch (Kind) { ++ default: ++ llvm_unreachable("Unexpected kind"); ++ return false; ++ case k_RegisterIndex: { ++ StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length); ++ StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length); ++ return Token == OtherToken; ++ } ++ } ++ } ++}; // class LoongArchOperand + +-void LoongArchAsmParser::emitLoadAddressPcrelLarge(MCInst &Inst, SMLoc IDLoc, +- MCStreamer &Out) { +- // la.pcrel $rd, $rj, sym +- // expands to: +- // pcalau12i $rd, %pc_hi20(sym) +- // addi.d $rj, $r0, %pc_lo12(sym) +- // lu32i.d $rj, %pc64_lo20(sym) +- // lu52i.d $rj, $rj, %pc64_hi12(sym) +- // add.d $rd, $rd, $rj +- MCRegister DestReg = Inst.getOperand(0).getReg(); +- MCRegister TmpReg = Inst.getOperand(1).getReg(); +- const MCExpr *Symbol = Inst.getOperand(2).getExpr(); +- InstSeq Insts; +- +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::PCALAU12I, LoongArchMCExpr::VK_LoongArch_PCALA_HI20)); +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::ADDI_D, LoongArchMCExpr::VK_LoongArch_PCALA_LO12)); +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::LU32I_D, LoongArchMCExpr::VK_LoongArch_PCALA64_LO20)); +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::LU52I_D, LoongArchMCExpr::VK_LoongArch_PCALA64_HI12)); +- Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D)); +- +- emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out); +-} ++} // end anonymous namespace + +-void LoongArchAsmParser::emitLoadAddressGot(MCInst &Inst, SMLoc IDLoc, +- MCStreamer &Out) { +- // la.got $rd, sym +- // expands to: +- // pcalau12i $rd, %got_pc_hi20(sym) +- // ld.w/d $rd, $rd, %got_pc_lo12(sym) +- MCRegister DestReg = Inst.getOperand(0).getReg(); +- const MCExpr *Symbol = Inst.getOperand(1).getExpr(); +- InstSeq Insts; +- unsigned LD = is64Bit() ? LoongArch::LD_D : LoongArch::LD_W; +- +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::PCALAU12I, LoongArchMCExpr::VK_LoongArch_GOT_PC_HI20)); +- Insts.push_back( +- LoongArchAsmParser::Inst(LD, LoongArchMCExpr::VK_LoongArch_GOT_PC_LO12)); +- +- emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out, true); +-} ++static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) { ++ if (const MCSymbolRefExpr *SRExpr = dyn_cast(Expr)) { ++ return &SRExpr->getSymbol(); ++ } + +-void LoongArchAsmParser::emitLoadAddressGotLarge(MCInst &Inst, SMLoc IDLoc, +- MCStreamer &Out) { +- // la.got $rd, $rj, sym +- // expands to: +- // pcalau12i $rd, %got_pc_hi20(sym) +- // addi.d $rj, $r0, %got_pc_lo12(sym) +- // lu32i.d $rj, %got64_pc_lo20(sym) +- // lu52i.d $rj, $rj, %got64_pc_hi12(sym) +- // ldx.d $rd, $rd, $rj +- MCRegister DestReg = Inst.getOperand(0).getReg(); +- MCRegister TmpReg = Inst.getOperand(1).getReg(); +- const MCExpr *Symbol = Inst.getOperand(2).getExpr(); +- InstSeq Insts; +- +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::PCALAU12I, LoongArchMCExpr::VK_LoongArch_GOT_PC_HI20)); +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::ADDI_D, LoongArchMCExpr::VK_LoongArch_GOT_PC_LO12)); +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::LU32I_D, LoongArchMCExpr::VK_LoongArch_GOT64_PC_LO20)); +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::LU52I_D, LoongArchMCExpr::VK_LoongArch_GOT64_PC_HI12)); +- Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D)); +- +- emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out); +-} ++ if (const MCBinaryExpr *BExpr = dyn_cast(Expr)) { ++ const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS()); ++ const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS()); + +-void LoongArchAsmParser::emitLoadAddressTLSLE(MCInst &Inst, SMLoc IDLoc, +- MCStreamer &Out) { +- // la.tls.le $rd, sym +- // expands to: +- // lu12i.w $rd, %le_hi20(sym) +- // ori $rd, $rd, %le_lo12(sym) +- MCRegister DestReg = Inst.getOperand(0).getReg(); +- const MCExpr *Symbol = Inst.getOperand(1).getExpr(); +- InstSeq Insts; +- +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::LU12I_W, LoongArchMCExpr::VK_LoongArch_TLS_LE_HI20)); +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::ORI, LoongArchMCExpr::VK_LoongArch_TLS_LE_LO12)); +- +- emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out); +-} ++ if (LHSSym) ++ return LHSSym; + +-void LoongArchAsmParser::emitLoadAddressTLSIE(MCInst &Inst, SMLoc IDLoc, +- MCStreamer &Out) { +- // la.tls.ie $rd, sym +- // expands to: +- // pcalau12i $rd, %ie_pc_hi20(sym) +- // ld.w/d $rd, $rd, %ie_pc_lo12(sym) +- MCRegister DestReg = Inst.getOperand(0).getReg(); +- const MCExpr *Symbol = Inst.getOperand(1).getExpr(); +- InstSeq Insts; +- unsigned LD = is64Bit() ? LoongArch::LD_D : LoongArch::LD_W; +- +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::PCALAU12I, LoongArchMCExpr::VK_LoongArch_TLS_IE_PC_HI20)); +- Insts.push_back(LoongArchAsmParser::Inst( +- LD, LoongArchMCExpr::VK_LoongArch_TLS_IE_PC_LO12)); +- +- emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out); +-} ++ if (RHSSym) ++ return RHSSym; + +-void LoongArchAsmParser::emitLoadAddressTLSIELarge(MCInst &Inst, SMLoc IDLoc, +- MCStreamer &Out) { +- // la.tls.ie $rd, $rj, sym +- // expands to: +- // pcalau12i $rd, %ie_pc_hi20(sym) +- // addi.d $rj, $r0, %ie_pc_lo12(sym) +- // lu32i.d $rj, %ie64_pc_lo20(sym) +- // lu52i.d $rj, $rj, %ie64_pc_hi12(sym) +- // ldx.d $rd, $rd, $rj +- MCRegister DestReg = Inst.getOperand(0).getReg(); +- MCRegister TmpReg = Inst.getOperand(1).getReg(); +- const MCExpr *Symbol = Inst.getOperand(2).getExpr(); +- InstSeq Insts; +- +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::PCALAU12I, LoongArchMCExpr::VK_LoongArch_TLS_IE_PC_HI20)); +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::ADDI_D, LoongArchMCExpr::VK_LoongArch_TLS_IE_PC_LO12)); +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::LU32I_D, LoongArchMCExpr::VK_LoongArch_TLS_IE64_PC_LO20)); +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::LU52I_D, LoongArchMCExpr::VK_LoongArch_TLS_IE64_PC_HI12)); +- Insts.push_back(LoongArchAsmParser::Inst(LoongArch::LDX_D)); +- +- emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out); +-} ++ return nullptr; ++ } + +-void LoongArchAsmParser::emitLoadAddressTLSLD(MCInst &Inst, SMLoc IDLoc, +- MCStreamer &Out) { +- // la.tls.ld $rd, sym +- // expands to: +- // pcalau12i $rd, %ld_pc_hi20(sym) +- // addi.w/d $rd, $rd, %got_pc_lo12(sym) +- MCRegister DestReg = Inst.getOperand(0).getReg(); +- const MCExpr *Symbol = Inst.getOperand(1).getExpr(); +- InstSeq Insts; +- unsigned ADDI = is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W; +- +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::PCALAU12I, LoongArchMCExpr::VK_LoongArch_TLS_LD_PC_HI20)); +- Insts.push_back(LoongArchAsmParser::Inst( +- ADDI, LoongArchMCExpr::VK_LoongArch_GOT_PC_LO12)); +- +- emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out); +-} ++ if (const MCUnaryExpr *UExpr = dyn_cast(Expr)) ++ return getSingleMCSymbol(UExpr->getSubExpr()); + +-void LoongArchAsmParser::emitLoadAddressTLSLDLarge(MCInst &Inst, SMLoc IDLoc, +- MCStreamer &Out) { +- // la.tls.ld $rd, $rj, sym +- // expands to: +- // pcalau12i $rd, %ld_pc_hi20(sym) +- // addi.d $rj, $r0, %got_pc_lo12(sym) +- // lu32i.d $rj, %got64_pc_lo20(sym) +- // lu52i.d $rj, $rj, %got64_pc_hi12(sym) +- // add.d $rd, $rd, $rj +- MCRegister DestReg = Inst.getOperand(0).getReg(); +- MCRegister TmpReg = Inst.getOperand(1).getReg(); +- const MCExpr *Symbol = Inst.getOperand(2).getExpr(); +- InstSeq Insts; +- +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::PCALAU12I, LoongArchMCExpr::VK_LoongArch_TLS_LD_PC_HI20)); +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::ADDI_D, LoongArchMCExpr::VK_LoongArch_GOT_PC_LO12)); +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::LU32I_D, LoongArchMCExpr::VK_LoongArch_GOT64_PC_LO20)); +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::LU52I_D, LoongArchMCExpr::VK_LoongArch_GOT64_PC_HI12)); +- Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D)); +- +- emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out); ++ return nullptr; + } + +-void LoongArchAsmParser::emitLoadAddressTLSGD(MCInst &Inst, SMLoc IDLoc, +- MCStreamer &Out) { +- // la.tls.gd $rd, sym +- // expands to: +- // pcalau12i $rd, %gd_pc_hi20(sym) +- // addi.w/d $rd, $rd, %got_pc_lo12(sym) +- MCRegister DestReg = Inst.getOperand(0).getReg(); +- const MCExpr *Symbol = Inst.getOperand(1).getExpr(); +- InstSeq Insts; +- unsigned ADDI = is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W; +- +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::PCALAU12I, LoongArchMCExpr::VK_LoongArch_TLS_GD_PC_HI20)); +- Insts.push_back(LoongArchAsmParser::Inst( +- ADDI, LoongArchMCExpr::VK_LoongArch_GOT_PC_LO12)); +- +- emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out); ++static unsigned countMCSymbolRefExpr(const MCExpr *Expr) { ++ if (isa(Expr)) ++ return 1; ++ ++ if (const MCBinaryExpr *BExpr = dyn_cast(Expr)) ++ return countMCSymbolRefExpr(BExpr->getLHS()) + ++ countMCSymbolRefExpr(BExpr->getRHS()); ++ ++ if (const MCUnaryExpr *UExpr = dyn_cast(Expr)) ++ return countMCSymbolRefExpr(UExpr->getSubExpr()); ++ ++ return 0; + } + +-void LoongArchAsmParser::emitLoadAddressTLSGDLarge(MCInst &Inst, SMLoc IDLoc, +- MCStreamer &Out) { +- // la.tls.gd $rd, $rj, sym +- // expands to: +- // pcalau12i $rd, %gd_pc_hi20(sym) +- // addi.d $rj, $r0, %got_pc_lo12(sym) +- // lu32i.d $rj, %got64_pc_lo20(sym) +- // lu52i.d $rj, $rj, %got64_pc_hi12(sym) +- // add.d $rd, $rd, $rj +- MCRegister DestReg = Inst.getOperand(0).getReg(); +- MCRegister TmpReg = Inst.getOperand(1).getReg(); +- const MCExpr *Symbol = Inst.getOperand(2).getExpr(); +- InstSeq Insts; +- +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::PCALAU12I, LoongArchMCExpr::VK_LoongArch_TLS_GD_PC_HI20)); +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::ADDI_D, LoongArchMCExpr::VK_LoongArch_GOT_PC_LO12)); +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::LU32I_D, LoongArchMCExpr::VK_LoongArch_GOT64_PC_LO20)); +- Insts.push_back(LoongArchAsmParser::Inst( +- LoongArch::LU52I_D, LoongArchMCExpr::VK_LoongArch_GOT64_PC_HI12)); +- Insts.push_back(LoongArchAsmParser::Inst(LoongArch::ADD_D)); +- +- emitLAInstSeq(DestReg, TmpReg, Symbol, Insts, IDLoc, Out); ++bool LoongArchAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, ++ MCStreamer &Out, ++ const MCSubtargetInfo *STI) { ++ const unsigned Opcode = Inst.getOpcode(); ++ const MCInstrDesc &MCID = MII.get(Opcode); ++ ++ Inst.setLoc(IDLoc); ++ ++ // Check branch instructions. ++ if (MCID.isBranch() || MCID.isCall()) { ++ const unsigned Opcode = Inst.getOpcode(); ++ MCOperand Offset; ++ bool check = true; ++ unsigned OffsetOpndIdx, OffsetOpndWidth; ++ switch (Opcode) { ++ default: ++ check = false; ++ break; ++ case LoongArch::BEQ: ++ case LoongArch::BNE: ++ case LoongArch::BLT: ++ case LoongArch::BGE: ++ case LoongArch::BLTU: ++ case LoongArch::BGEU: ++ OffsetOpndIdx = 2; ++ OffsetOpndWidth = 16; ++ break; ++ case LoongArch::BEQZ: ++ case LoongArch::BNEZ: ++ case LoongArch::BCEQZ: ++ case LoongArch::BCNEZ: ++ OffsetOpndIdx = 1; ++ OffsetOpndWidth = 21; ++ break; ++ case LoongArch::B: ++ case LoongArch::BL: ++ OffsetOpndIdx = 0; ++ OffsetOpndWidth = 26; ++ break; ++ } ++ if (check) { ++ assert(MCID.getNumOperands() == OffsetOpndIdx + 1 && ++ "unexpected number of operands"); ++ Offset = Inst.getOperand(OffsetOpndIdx); ++ // Non-Imm situation will be dealed with later on when applying fixups. ++ if (Offset.isImm()) { ++ if (!isIntN(OffsetOpndWidth + 2, Offset.getImm())) ++ return Error(IDLoc, "branch target out of range"); ++ if (offsetToAlignment(Offset.getImm(), Align(1LL << 2))) ++ return Error(IDLoc, "branch to misaligned address"); ++ } ++ } ++ } ++ ++ bool IsPCRelativeLoad = (MCID.TSFlags & LoongArchII::IsPCRelativeLoad) != 0; ++ if ((MCID.mayLoad() || MCID.mayStore()) && !IsPCRelativeLoad) { ++ // Check the offset of memory operand, if it is a symbol ++ // reference or immediate we may have to expand instructions. ++ for (unsigned i = 0; i < MCID.getNumOperands(); i++) { ++ const MCOperandInfo &OpInfo = MCID.operands()[i]; ++ if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) || ++ (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) { ++ MCOperand &Op = Inst.getOperand(i); ++ if (Op.isImm()) { ++ int64_t MemOffset = Op.getImm(); ++ if (MemOffset < -32768 || MemOffset > 32767) { ++ return getParser().hasPendingError(); ++ } ++ } else if (Op.isExpr()) { ++ const MCExpr *Expr = Op.getExpr(); ++ if (Expr->getKind() == MCExpr::SymbolRef) { ++ const MCSymbolRefExpr *SR = ++ static_cast(Expr); ++ if (SR->getKind() == MCSymbolRefExpr::VK_None) { ++ return getParser().hasPendingError(); ++ } ++ } else if (!isEvaluated(Expr)) { ++ return getParser().hasPendingError(); ++ } ++ } ++ } ++ } // for ++ } // if load/store ++ ++ MacroExpanderResultTy ExpandResult = ++ tryExpandInstruction(Inst, IDLoc, Out, STI); ++ switch (ExpandResult) { ++ case MER_NotAMacro: ++ Out.emitInstruction(Inst, *STI); ++ break; ++ case MER_Success: ++ break; ++ case MER_Fail: ++ return true; ++ } ++ ++ return false; + } + +-void LoongArchAsmParser::emitLoadImm(MCInst &Inst, SMLoc IDLoc, +- MCStreamer &Out) { +- MCRegister DestReg = Inst.getOperand(0).getReg(); +- int64_t Imm = Inst.getOperand(1).getImm(); +- MCRegister SrcReg = LoongArch::R0; ++LoongArchAsmParser::MacroExpanderResultTy ++LoongArchAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, ++ const MCSubtargetInfo *STI) { ++ switch (Inst.getOpcode()) { ++ default: ++ return MER_NotAMacro; ++ case LoongArch::LoadImm32: // li.w $rd, $imm32 ++ case LoongArch::LoadImm64: // li.d $rd, $imm64 ++ return expandLoadImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; ++ case LoongArch::LoadAddrLocal: // la.local $rd, symbol ++ case LoongArch::LoadAddrGlobal: // la.global $rd, symbol ++ case LoongArch::LoadAddrGlobal_Alias: // la $rd, symbol ++ case LoongArch::LoadAddrTLS_LE: // la.tls.le $rd, symbol ++ case LoongArch::LoadAddrTLS_IE: // la.tls.ie $rd, symbol ++ case LoongArch::LoadAddrTLS_LD: // la.tls.ld $rd, symbol ++ case LoongArch::LoadAddrTLS_GD: // la.tls.gd $rd, symbol ++ return expandLoadAddress(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; ++ case LoongArch::LoadAddrLocalRR: // la.local $rd, $rt, symbol ++ return expandLoadAddressLarge(Inst, IDLoc, Out, STI) ? MER_Fail ++ : MER_Success; ++ } ++} + +- if (Inst.getOpcode() == LoongArch::PseudoLI_W) +- Imm = SignExtend64<32>(Imm); ++/// Can the value be represented by a unsigned N-bit value and a shift left? ++template static bool isShiftedUIntAtAnyPosition(uint64_t x) { ++ return x && isUInt(x >> llvm::countr_zero(x)); ++} + +- for (LoongArchMatInt::Inst &Inst : LoongArchMatInt::generateInstSeq(Imm)) { +- unsigned Opc = Inst.Opc; +- if (Opc == LoongArch::LU12I_W) +- Out.emitInstruction(MCInstBuilder(Opc).addReg(DestReg).addImm(Inst.Imm), +- getSTI()); ++bool LoongArchAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc, ++ MCStreamer &Out, ++ const MCSubtargetInfo *STI) { ++ const int64_t Imm = Inst.getOperand(1).getImm(); ++ const unsigned DstReg = Inst.getOperand(0).getReg(); ++ LoongArchTargetStreamer &TOut = getTargetStreamer(); ++ bool Is64Bit = Inst.getOpcode() == LoongArch::LoadImm64; ++ unsigned SrcReg = Is64Bit ? LoongArch::ZERO_64 : LoongArch::ZERO; ++ LoongArchAnalyzeImmediate::InstSeq Seq = ++ LoongArchAnalyzeImmediate::generateInstSeq( ++ Is64Bit ? Imm : SignExtend64<32>(Imm), Is64Bit); ++ ++ for (auto &Inst : Seq) { ++ if (Inst.Opc == LoongArch::LU12I_W || Inst.Opc == LoongArch::LU12I_W32) ++ TOut.emitRI(Inst.Opc, DstReg, Inst.Imm, IDLoc, STI); + else +- Out.emitInstruction( +- MCInstBuilder(Opc).addReg(DestReg).addReg(SrcReg).addImm(Inst.Imm), +- getSTI()); +- SrcReg = DestReg; ++ TOut.emitRRI(Inst.Opc, DstReg, SrcReg, Inst.Imm, IDLoc, STI); ++ SrcReg = DstReg; + } +-} + +-void LoongArchAsmParser::emitFuncCall36(MCInst &Inst, SMLoc IDLoc, +- MCStreamer &Out, bool IsTailCall) { +- // call36 sym +- // expands to: +- // pcaddu18i $ra, %call36(sym) +- // jirl $ra, $ra, 0 +- // +- // tail36 $rj, sym +- // expands to: +- // pcaddu18i $rj, %call36(sym) +- // jirl $r0, $rj, 0 +- unsigned ScratchReg = +- IsTailCall ? Inst.getOperand(0).getReg() : (unsigned)LoongArch::R1; +- const MCExpr *Sym = +- IsTailCall ? Inst.getOperand(1).getExpr() : Inst.getOperand(0).getExpr(); +- const LoongArchMCExpr *LE = LoongArchMCExpr::create( +- Sym, llvm::LoongArchMCExpr::VK_LoongArch_CALL36, getContext()); +- +- Out.emitInstruction( +- MCInstBuilder(LoongArch::PCADDU18I).addReg(ScratchReg).addExpr(LE), +- getSTI()); +- Out.emitInstruction( +- MCInstBuilder(LoongArch::JIRL) +- .addReg(IsTailCall ? (unsigned)LoongArch::R0 : ScratchReg) +- .addReg(ScratchReg) +- .addImm(0), +- getSTI()); ++ return false; + } + +-bool LoongArchAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, +- OperandVector &Operands, +- MCStreamer &Out) { +- Inst.setLoc(IDLoc); ++bool LoongArchAsmParser::expandLoadAddress(MCInst &Inst, SMLoc IDLoc, ++ MCStreamer &Out, ++ const MCSubtargetInfo *STI) { ++ LoongArchTargetStreamer &TOut = getTargetStreamer(); ++ const MCExpr *SymExpr = Inst.getOperand(1).getExpr(); ++ const LoongArchMCExpr *HiExpr = nullptr; ++ const LoongArchMCExpr *LoExpr = nullptr; ++ const LoongArchMCExpr *HigherExpr = nullptr; ++ const LoongArchMCExpr *HighestExpr = nullptr; ++ const MCExpr *GotExpr = MCSymbolRefExpr::create( ++ "_GLOBAL_OFFSET_TABLE_", MCSymbolRefExpr::VK_None, getContext()); ++ unsigned DstReg = Inst.getOperand(0).getReg(); ++ ++ MCValue Res; ++ if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) { ++ Error(IDLoc, "expected relocatable expression"); ++ return true; ++ } ++ if (Res.getSymB() != nullptr) { ++ Error(IDLoc, "expected relocatable expression with only one symbol"); ++ return true; ++ } ++ + switch (Inst.getOpcode()) { +- default: +- break; +- case LoongArch::PseudoLA_ABS: +- case LoongArch::PseudoLA_ABS_LARGE: +- emitLoadAddressAbs(Inst, IDLoc, Out); +- return false; +- case LoongArch::PseudoLA_PCREL: +- emitLoadAddressPcrel(Inst, IDLoc, Out); +- return false; +- case LoongArch::PseudoLA_PCREL_LARGE: +- emitLoadAddressPcrelLarge(Inst, IDLoc, Out); +- return false; +- case LoongArch::PseudoLA_GOT: +- emitLoadAddressGot(Inst, IDLoc, Out); +- return false; +- case LoongArch::PseudoLA_GOT_LARGE: +- emitLoadAddressGotLarge(Inst, IDLoc, Out); +- return false; +- case LoongArch::PseudoLA_TLS_LE: +- emitLoadAddressTLSLE(Inst, IDLoc, Out); +- return false; +- case LoongArch::PseudoLA_TLS_IE: +- emitLoadAddressTLSIE(Inst, IDLoc, Out); +- return false; +- case LoongArch::PseudoLA_TLS_IE_LARGE: +- emitLoadAddressTLSIELarge(Inst, IDLoc, Out); +- return false; +- case LoongArch::PseudoLA_TLS_LD: +- emitLoadAddressTLSLD(Inst, IDLoc, Out); +- return false; +- case LoongArch::PseudoLA_TLS_LD_LARGE: +- emitLoadAddressTLSLDLarge(Inst, IDLoc, Out); ++ case LoongArch::LoadAddrLocal: ++ HiExpr = LoongArchMCExpr::create(LoongArchMCExpr::MEK_PCREL_HI, SymExpr, ++ getContext()); ++ LoExpr = LoongArchMCExpr::create(LoongArchMCExpr::MEK_PCREL_LO, SymExpr, ++ getContext()); ++ ++ TOut.emitRX(LoongArch::PCADDU12I_ri, DstReg, MCOperand::createExpr(HiExpr), ++ IDLoc, STI); ++ TOut.emitRRX(LoongArch::ADDI_D_rri, DstReg, DstReg, ++ MCOperand::createExpr(LoExpr), IDLoc, STI); + return false; +- case LoongArch::PseudoLA_TLS_GD: +- emitLoadAddressTLSGD(Inst, IDLoc, Out); ++ case LoongArch::LoadAddrGlobal: ++ case LoongArch::LoadAddrGlobal_Alias: ++ HiExpr = LoongArchMCExpr::create(LoongArchMCExpr::MEK_GOT_HI, SymExpr, ++ getContext()); ++ LoExpr = LoongArchMCExpr::create(LoongArchMCExpr::MEK_GOT_LO, SymExpr, ++ getContext()); ++ TOut.emitRXX(LoongArch::PCADDU12I_rii, DstReg, ++ MCOperand::createExpr(HiExpr), MCOperand::createExpr(GotExpr), ++ IDLoc, STI); ++ TOut.emitRRXX(LoongArch::LD_D_rrii, DstReg, DstReg, ++ MCOperand::createExpr(LoExpr), MCOperand::createExpr(GotExpr), ++ IDLoc, STI); + return false; +- case LoongArch::PseudoLA_TLS_GD_LARGE: +- emitLoadAddressTLSGDLarge(Inst, IDLoc, Out); ++ case LoongArch::LoadAddrTLS_LE: ++ HiExpr = LoongArchMCExpr::create(LoongArchMCExpr::MEK_TLSLE_HI, SymExpr, ++ getContext()); ++ LoExpr = LoongArchMCExpr::create(LoongArchMCExpr::MEK_TLSLE_LO, SymExpr, ++ getContext()); ++ HigherExpr = LoongArchMCExpr::create(LoongArchMCExpr::MEK_TLSLE_HIGHER, ++ SymExpr, getContext()); ++ HighestExpr = LoongArchMCExpr::create(LoongArchMCExpr::MEK_TLSLE_HIGHEST, ++ SymExpr, getContext()); ++ TOut.emitRX(LoongArch::LU12I_W_ri, DstReg, MCOperand::createExpr(HiExpr), ++ IDLoc, STI); ++ TOut.emitRRX(LoongArch::ORI_rri, DstReg, DstReg, ++ MCOperand::createExpr(LoExpr), IDLoc, STI); ++ TOut.emitRX(LoongArch::LU32I_D_ri, DstReg, ++ MCOperand::createExpr(HigherExpr), IDLoc, STI); ++ TOut.emitRRX(LoongArch::LU52I_D_rri, DstReg, DstReg, ++ MCOperand::createExpr(HighestExpr), IDLoc, STI); + return false; +- case LoongArch::PseudoLI_W: +- case LoongArch::PseudoLI_D: +- emitLoadImm(Inst, IDLoc, Out); ++ case LoongArch::LoadAddrTLS_IE: ++ HiExpr = LoongArchMCExpr::create(LoongArchMCExpr::MEK_TLSIE_HI, SymExpr, ++ getContext()); ++ LoExpr = LoongArchMCExpr::create(LoongArchMCExpr::MEK_TLSIE_LO, SymExpr, ++ getContext()); ++ TOut.emitRXX(LoongArch::PCADDU12I_rii, DstReg, ++ MCOperand::createExpr(HiExpr), MCOperand::createExpr(GotExpr), ++ IDLoc, STI); ++ TOut.emitRRXX(LoongArch::LD_D_rrii, DstReg, DstReg, ++ MCOperand::createExpr(LoExpr), MCOperand::createExpr(GotExpr), ++ IDLoc, STI); + return false; +- case LoongArch::PseudoCALL36: +- emitFuncCall36(Inst, IDLoc, Out, /*IsTailCall=*/false); +- return false; +- case LoongArch::PseudoTAIL36: +- emitFuncCall36(Inst, IDLoc, Out, /*IsTailCall=*/true); ++ case LoongArch::LoadAddrTLS_LD: ++ case LoongArch::LoadAddrTLS_GD: ++ HiExpr = LoongArchMCExpr::create(LoongArchMCExpr::MEK_TLSGD_HI, SymExpr, ++ getContext()); ++ LoExpr = LoongArchMCExpr::create(LoongArchMCExpr::MEK_TLSGD_LO, SymExpr, ++ getContext()); ++ TOut.emitRXX(LoongArch::PCADDU12I_rii, DstReg, ++ MCOperand::createExpr(HiExpr), MCOperand::createExpr(GotExpr), ++ IDLoc, STI); ++ TOut.emitRRXX(LoongArch::ADDI_D_rrii, DstReg, DstReg, ++ MCOperand::createExpr(LoExpr), MCOperand::createExpr(GotExpr), ++ IDLoc, STI); + return false; ++ default: ++ llvm_unreachable(""); + } +- Out.emitInstruction(Inst, getSTI()); +- return false; + } + +-unsigned LoongArchAsmParser::checkTargetMatchPredicate(MCInst &Inst) { +- unsigned Opc = Inst.getOpcode(); +- switch (Opc) { ++bool LoongArchAsmParser::expandLoadAddressLarge(MCInst &Inst, SMLoc IDLoc, ++ MCStreamer &Out, ++ const MCSubtargetInfo *STI) { ++ LoongArchTargetStreamer &TOut = getTargetStreamer(); ++ const MCExpr *SymExpr = Inst.getOperand(2).getExpr(); ++ const LoongArchMCExpr *HiExpr = nullptr; ++ const LoongArchMCExpr *LoExpr = nullptr; ++ const LoongArchMCExpr *HigherExpr = nullptr; ++ const LoongArchMCExpr *HighestExpr = nullptr; ++ unsigned DstReg = Inst.getOperand(0).getReg(); ++ unsigned TmpReg = Inst.getOperand(1).getReg(); ++ ++ MCValue Res; ++ if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) { ++ Error(IDLoc, "expected relocatable expression"); ++ return true; ++ } ++ if (Res.getSymB() != nullptr) { ++ Error(IDLoc, "expected relocatable expression with only one symbol"); ++ return true; ++ } ++ ++ switch (Inst.getOpcode()) { ++ case LoongArch::LoadAddrLocalRR: ++ HiExpr = LoongArchMCExpr::create(LoongArchMCExpr::MEK_PCREL_RRHI, SymExpr, ++ getContext()); ++ LoExpr = LoongArchMCExpr::create(LoongArchMCExpr::MEK_PCREL_RRLO, SymExpr, ++ getContext()); ++ HigherExpr = LoongArchMCExpr::create(LoongArchMCExpr::MEK_PCREL_RRHIGHER, ++ SymExpr, getContext()); ++ HighestExpr = LoongArchMCExpr::create(LoongArchMCExpr::MEK_PCREL_RRHIGHEST, ++ SymExpr, getContext()); ++ ++ TOut.emitRRX(LoongArch::PCADDU12I_ri_large, DstReg, TmpReg, ++ MCOperand::createExpr(HiExpr), IDLoc, STI); ++ TOut.emitRRX(LoongArch::ORI_rri, TmpReg, LoongArch::ZERO_64, ++ MCOperand::createExpr(LoExpr), IDLoc, STI); ++ TOut.emitRX(LoongArch::LU32I_D_ri, TmpReg, ++ MCOperand::createExpr(HigherExpr), IDLoc, STI); ++ TOut.emitRRX(LoongArch::LU52I_D_rri, TmpReg, TmpReg, ++ MCOperand::createExpr(HighestExpr), IDLoc, STI); ++ TOut.emitRRR(LoongArch::ADD_D_rrr, DstReg, DstReg, TmpReg, IDLoc, STI); ++ return false; + default: +- if (Opc >= LoongArch::AMADD_D && Opc <= LoongArch::AMXOR_W) { +- unsigned Rd = Inst.getOperand(0).getReg(); +- unsigned Rk = Inst.getOperand(1).getReg(); +- unsigned Rj = Inst.getOperand(2).getReg(); +- if ((Rd == Rk || Rd == Rj) && Rd != LoongArch::R0) +- return Match_RequiresAMORdDifferRkRj; +- } +- break; +- case LoongArch::PseudoLA_PCREL_LARGE: +- case LoongArch::PseudoLA_GOT_LARGE: +- case LoongArch::PseudoLA_TLS_IE_LARGE: +- case LoongArch::PseudoLA_TLS_LD_LARGE: +- case LoongArch::PseudoLA_TLS_GD_LARGE: { +- unsigned Rd = Inst.getOperand(0).getReg(); +- unsigned Rj = Inst.getOperand(1).getReg(); +- if (Rd == Rj) +- return Match_RequiresLAORdDifferRj; +- break; ++ llvm_unreachable(""); + } +- case LoongArch::CSRXCHG: +- case LoongArch::GCSRXCHG: { +- unsigned Rj = Inst.getOperand(2).getReg(); +- if (Rj == LoongArch::R0 || Rj == LoongArch::R1) +- return Match_RequiresOpnd2NotR0R1; ++} ++ ++unsigned LoongArchAsmParser::checkTargetMatchPredicate(MCInst &Inst) { ++ switch (Inst.getOpcode()) { ++ case LoongArch::BSTRINS_W: ++ case LoongArch::BSTRPICK_W: { ++ assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && ++ "Operands must be immediates for bstrins.w/bstrpick.w!"); ++ const signed Msbw = Inst.getOperand(2).getImm(); ++ const signed Lsbw = Inst.getOperand(3).getImm(); ++ if (Msbw < Lsbw) ++ return Match_MsbHigherThanLsb; ++ if ((Lsbw < 0) || (Msbw > 31)) ++ return Match_RequiresRange0_31; + return Match_Success; + } +- case LoongArch::BSTRINS_W: + case LoongArch::BSTRINS_D: +- case LoongArch::BSTRPICK_W: + case LoongArch::BSTRPICK_D: { +- unsigned Opc = Inst.getOpcode(); +- const signed Msb = +- (Opc == LoongArch::BSTRINS_W || Opc == LoongArch::BSTRINS_D) +- ? Inst.getOperand(3).getImm() +- : Inst.getOperand(2).getImm(); +- const signed Lsb = +- (Opc == LoongArch::BSTRINS_W || Opc == LoongArch::BSTRINS_D) +- ? Inst.getOperand(4).getImm() +- : Inst.getOperand(3).getImm(); +- if (Msb < Lsb) +- return Match_RequiresMsbNotLessThanLsb; ++ assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && ++ "Operands must be immediates for bstrins.d/bstrpick.d!"); ++ const signed Msbd = Inst.getOperand(2).getImm(); ++ const signed Lsbd = Inst.getOperand(3).getImm(); ++ if (Msbd < Lsbd) ++ return Match_MsbHigherThanLsb; ++ if ((Lsbd < 0) || (Msbd > 63)) ++ return Match_RequiresRange0_63; + return Match_Success; + } ++ case LoongArch::CSRXCHG32: ++ case LoongArch::CSRXCHG: ++ if (Inst.getOperand(2).getReg() == LoongArch::ZERO || ++ Inst.getOperand(2).getReg() == LoongArch::ZERO_64) ++ return Match_RequiresNoZeroRegister; ++ if (Inst.getOperand(2).getReg() == LoongArch::RA || ++ Inst.getOperand(2).getReg() == LoongArch::RA_64) ++ return Match_RequiresNoRaRegister; ++ return Match_Success; + } + + return Match_Success; + } + +-unsigned +-LoongArchAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, +- unsigned Kind) { +- LoongArchOperand &Op = static_cast(AsmOp); +- if (!Op.isReg()) +- return Match_InvalidOperand; +- +- MCRegister Reg = Op.getReg(); +- // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the +- // register from FPR32 to FPR64 if necessary. +- if (LoongArchMCRegisterClasses[LoongArch::FPR32RegClassID].contains(Reg) && +- Kind == MCK_FPR64) { +- Op.setReg(convertFPR32ToFPR64(Reg)); +- return Match_Success; ++static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, ++ uint64_t ErrorInfo) { ++ if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) { ++ SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc(); ++ if (ErrorLoc == SMLoc()) ++ return Loc; ++ return ErrorLoc; + } +- +- return Match_InvalidOperand; +-} +- +-bool LoongArchAsmParser::generateImmOutOfRangeError( +- OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper, +- const Twine &Msg = "immediate must be an integer in the range") { +- SMLoc ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc(); +- return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]"); ++ return Loc; + } + + bool LoongArchAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, +@@ -1302,227 +1478,848 @@ bool LoongArchAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, + uint64_t &ErrorInfo, + bool MatchingInlineAsm) { + MCInst Inst; +- FeatureBitset MissingFeatures; +- +- auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures, +- MatchingInlineAsm); +- switch (Result) { +- default: +- break; ++ unsigned MatchResult = ++ MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); ++ switch (MatchResult) { + case Match_Success: +- return processInstruction(Inst, IDLoc, Operands, Out); +- case Match_MissingFeature: { +- assert(MissingFeatures.any() && "Unknown missing features!"); +- bool FirstFeature = true; +- std::string Msg = "instruction requires the following:"; +- for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) { +- if (MissingFeatures[i]) { +- Msg += FirstFeature ? " " : ", "; +- Msg += getSubtargetFeatureName(i); +- FirstFeature = false; +- } +- } +- return Error(IDLoc, Msg); +- } +- case Match_MnemonicFail: { +- FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits()); +- std::string Suggestion = LoongArchMnemonicSpellCheck( +- ((LoongArchOperand &)*Operands[0]).getToken(), FBS, 0); +- return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion); +- } ++ if (processInstruction(Inst, IDLoc, Out, STI)) ++ return true; ++ return false; ++ case Match_MissingFeature: ++ Error(IDLoc, "instruction requires a CPU feature not currently enabled"); ++ return true; + case Match_InvalidOperand: { + SMLoc ErrorLoc = IDLoc; + if (ErrorInfo != ~0ULL) { + if (ErrorInfo >= Operands.size()) +- return Error(ErrorLoc, "too few operands for instruction"); ++ return Error(IDLoc, "too few operands for instruction"); + +- ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc(); ++ ErrorLoc = Operands[ErrorInfo]->getStartLoc(); + if (ErrorLoc == SMLoc()) + ErrorLoc = IDLoc; + } +- return Error(ErrorLoc, "invalid operand for instruction"); +- } +- } + +- // Handle the case when the error message is of specific type +- // other than the generic Match_InvalidOperand, and the +- // corresponding operand is missing. +- if (Result > FIRST_TARGET_MATCH_RESULT_TY) { +- SMLoc ErrorLoc = IDLoc; +- if (ErrorInfo != ~0ULL && ErrorInfo >= Operands.size()) +- return Error(ErrorLoc, "too few operands for instruction"); ++ return Error(ErrorLoc, "invalid operand for instruction"); + } +- +- switch (Result) { +- default: +- break; +- case Match_RequiresMsbNotLessThanLsb: { +- SMLoc ErrorStart = Operands[3]->getStartLoc(); +- return Error(ErrorStart, "msb is less than lsb", +- SMRange(ErrorStart, Operands[4]->getEndLoc())); +- } +- case Match_RequiresOpnd2NotR0R1: +- return Error(Operands[2]->getStartLoc(), "must not be $r0 or $r1"); +- case Match_RequiresAMORdDifferRkRj: +- return Error(Operands[1]->getStartLoc(), +- "$rd must be different from both $rk and $rj"); +- case Match_RequiresLAORdDifferRj: +- return Error(Operands[1]->getStartLoc(), "$rd must be different from $rj"); +- case Match_InvalidUImm1: +- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0, +- /*Upper=*/(1 << 1) - 1); +- case Match_InvalidUImm2: +- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0, +- /*Upper=*/(1 << 2) - 1); +- case Match_InvalidUImm2plus1: +- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/1, +- /*Upper=*/(1 << 2)); +- case Match_InvalidUImm3: +- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0, +- /*Upper=*/(1 << 3) - 1); +- case Match_InvalidUImm4: +- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0, +- /*Upper=*/(1 << 4) - 1); +- case Match_InvalidUImm5: +- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0, +- /*Upper=*/(1 << 5) - 1); +- case Match_InvalidUImm6: +- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0, +- /*Upper=*/(1 << 6) - 1); +- case Match_InvalidUImm7: +- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0, +- /*Upper=*/(1 << 7) - 1); +- case Match_InvalidUImm8: +- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0, +- /*Upper=*/(1 << 8) - 1); +- case Match_InvalidUImm12: +- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0, +- /*Upper=*/(1 << 12) - 1); +- case Match_InvalidUImm12ori: +- return generateImmOutOfRangeError( +- Operands, ErrorInfo, /*Lower=*/0, +- /*Upper=*/(1 << 12) - 1, +- "operand must be a symbol with modifier (e.g. %abs_lo12) or an " +- "integer in the range"); +- case Match_InvalidUImm14: +- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0, +- /*Upper=*/(1 << 14) - 1); +- case Match_InvalidUImm15: +- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0, +- /*Upper=*/(1 << 15) - 1); ++ case Match_MnemonicFail: ++ return Error(IDLoc, "invalid instruction"); ++ case Match_RequiresNoZeroRegister: ++ return Error(IDLoc, "invalid operand ($zero) for instruction"); ++ case Match_RequiresNoRaRegister: ++ return Error(IDLoc, "invalid operand ($r1) for instruction"); ++ case Match_InvalidImm0_3: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "immediate must be an integer in range [0, 3]."); ++ case Match_InvalidImm0_7: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "immediate must be an integer in range [0, 7]."); ++ case Match_InvalidImm0_31: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "immediate must be an integer in range [0, 31]."); ++ case Match_InvalidImm0_63: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "immediate must be an integer in range [0, 63]."); ++ case Match_InvalidImm0_4095: ++ case Match_UImm12_Relaxed: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "immediate must be an integer in range [0, 4095]."); ++ case Match_InvalidImm0_32767: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "immediate must be an integer in range [0, 32767]."); ++ case Match_UImm16_Relaxed: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "expected 16-bit unsigned immediate"); ++ case Match_UImm20_0: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "expected 20-bit unsigned immediate"); ++ case Match_UImm26_0: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "expected 26-bit unsigned immediate"); ++ case Match_UImm32_Coerced: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "expected 32-bit immediate"); ++ case Match_InvalidSImm2: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "expected 2-bit signed immediate"); ++ case Match_InvalidSImm3: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "expected 3-bit signed immediate"); + case Match_InvalidSImm5: +- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/-(1 << 4), +- /*Upper=*/(1 << 4) - 1); ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "expected 5-bit signed immediate"); + case Match_InvalidSImm8: +- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/-(1 << 7), +- /*Upper=*/(1 << 7) - 1); +- case Match_InvalidSImm8lsl1: +- return generateImmOutOfRangeError( +- Operands, ErrorInfo, /*Lower=*/-(1 << 8), /*Upper=*/(1 << 8) - 2, +- "immediate must be a multiple of 2 in the range"); +- case Match_InvalidSImm8lsl2: +- return generateImmOutOfRangeError( +- Operands, ErrorInfo, /*Lower=*/-(1 << 9), /*Upper=*/(1 << 9) - 4, +- "immediate must be a multiple of 4 in the range"); +- case Match_InvalidSImm10: +- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/-(1 << 9), +- /*Upper=*/(1 << 9) - 1); +- case Match_InvalidSImm8lsl3: +- return generateImmOutOfRangeError( +- Operands, ErrorInfo, /*Lower=*/-(1 << 10), /*Upper=*/(1 << 10) - 8, +- "immediate must be a multiple of 8 in the range"); +- case Match_InvalidSImm9lsl3: +- return generateImmOutOfRangeError( +- Operands, ErrorInfo, /*Lower=*/-(1 << 11), /*Upper=*/(1 << 11) - 8, +- "immediate must be a multiple of 8 in the range"); +- case Match_InvalidSImm10lsl2: +- return generateImmOutOfRangeError( +- Operands, ErrorInfo, /*Lower=*/-(1 << 11), /*Upper=*/(1 << 11) - 4, +- "immediate must be a multiple of 4 in the range"); +- case Match_InvalidSImm11lsl1: +- return generateImmOutOfRangeError( +- Operands, ErrorInfo, /*Lower=*/-(1 << 11), /*Upper=*/(1 << 11) - 2, +- "immediate must be a multiple of 2 in the range"); ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "expected 8-bit signed immediate"); + case Match_InvalidSImm12: +- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/-(1 << 11), +- /*Upper=*/(1 << 11) - 1); +- case Match_InvalidSImm12addlike: +- return generateImmOutOfRangeError( +- Operands, ErrorInfo, /*Lower=*/-(1 << 11), +- /*Upper=*/(1 << 11) - 1, +- "operand must be a symbol with modifier (e.g. %pc_lo12) or an integer " +- "in the range"); +- case Match_InvalidSImm12lu52id: +- return generateImmOutOfRangeError( +- Operands, ErrorInfo, /*Lower=*/-(1 << 11), +- /*Upper=*/(1 << 11) - 1, +- "operand must be a symbol with modifier (e.g. %pc64_hi12) or an " +- "integer in the range"); +- case Match_InvalidSImm13: +- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/-(1 << 12), +- /*Upper=*/(1 << 12) - 1); +- case Match_InvalidSImm14lsl2: +- return generateImmOutOfRangeError( +- Operands, ErrorInfo, /*Lower=*/-(1 << 15), /*Upper=*/(1 << 15) - 4, +- "immediate must be a multiple of 4 in the range"); ++ case Match_SImm12_Relaxed: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "expected 12-bit signed immediate"); ++ case Match_InvalidSImm14: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "expected 14-bit signed immediate"); ++ case Match_InvalidSImm15: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "expected 15-bit signed immediate"); + case Match_InvalidSImm16: +- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/-(1 << 15), +- /*Upper=*/(1 << 15) - 1); +- case Match_InvalidSImm16lsl2: +- return generateImmOutOfRangeError( +- Operands, ErrorInfo, /*Lower=*/-(1 << 17), /*Upper=*/(1 << 17) - 4, +- "operand must be a symbol with modifier (e.g. %b16) or an integer " +- "in the range"); ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "expected 16-bit signed immediate"); + case Match_InvalidSImm20: +- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/-(1 << 19), +- /*Upper=*/(1 << 19) - 1); +- case Match_InvalidSImm20lu12iw: +- return generateImmOutOfRangeError( +- Operands, ErrorInfo, /*Lower=*/-(1 << 19), +- /*Upper=*/(1 << 19) - 1, +- "operand must be a symbol with modifier (e.g. %abs_hi20) or an integer " +- "in the range"); +- case Match_InvalidSImm20lu32id: +- return generateImmOutOfRangeError( +- Operands, ErrorInfo, /*Lower=*/-(1 << 19), +- /*Upper=*/(1 << 19) - 1, +- "operand must be a symbol with modifier (e.g. %abs64_lo20) or an " +- "integer in the range"); +- case Match_InvalidSImm20pcalau12i: +- return generateImmOutOfRangeError( +- Operands, ErrorInfo, /*Lower=*/-(1 << 19), +- /*Upper=*/(1 << 19) - 1, +- "operand must be a symbol with modifier (e.g. %pc_hi20) or an integer " +- "in the range"); +- case Match_InvalidSImm20pcaddu18i: +- return generateImmOutOfRangeError( +- Operands, ErrorInfo, /*Lower=*/-(1 << 19), +- /*Upper=*/(1 << 19) - 1, +- "operand must be a symbol with modifier (e.g. %call36) or an integer " +- "in the range"); +- case Match_InvalidSImm21lsl2: +- return generateImmOutOfRangeError( +- Operands, ErrorInfo, /*Lower=*/-(1 << 22), /*Upper=*/(1 << 22) - 4, +- "operand must be a symbol with modifier (e.g. %b21) or an integer " +- "in the range"); +- case Match_InvalidSImm26Operand: +- return generateImmOutOfRangeError( +- Operands, ErrorInfo, /*Lower=*/-(1 << 27), /*Upper=*/(1 << 27) - 4, +- "operand must be a bare symbol name or an immediate must be a multiple " +- "of 4 in the range"); +- case Match_InvalidImm32: { +- SMLoc ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc(); +- return Error(ErrorLoc, "operand must be a 32 bit immediate"); +- } +- case Match_InvalidBareSymbol: { +- SMLoc ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc(); +- return Error(ErrorLoc, "operand must be a bare symbol name"); +- } +- } +- llvm_unreachable("Unknown match type detected!"); ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "expected 20-bit signed immediate"); ++ case Match_InvalidSImm21: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "expected 21-bit signed immediate"); ++ case Match_InvalidSImm26: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "expected 26-bit signed immediate"); ++ case Match_SImm32: ++ case Match_SImm32_Relaxed: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "expected 32-bit signed immediate"); ++ case Match_MemSImm14: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "expected memory with 14-bit signed offset"); ++ case Match_MemSImmPtr: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "expected memory with 32-bit signed offset"); ++ case Match_UImm2_1: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "expected immediate in range 1 .. 4"); ++ case Match_MemSImm14Lsl2: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "expected memory with 16-bit signed offset and multiple of 4"); ++ case Match_RequiresRange0_31: { ++ SMLoc ErrorStart = Operands[3]->getStartLoc(); ++ SMLoc ErrorEnd = Operands[4]->getEndLoc(); ++ return Error(ErrorStart, "from lsbw to msbw are not in the range 0 .. 31", ++ SMRange(ErrorStart, ErrorEnd)); ++ } ++ case Match_RequiresPosSizeUImm6: { ++ SMLoc ErrorStart = Operands[3]->getStartLoc(); ++ SMLoc ErrorEnd = Operands[4]->getEndLoc(); ++ return Error(ErrorStart, "size plus position are not in the range 1 .. 63", ++ SMRange(ErrorStart, ErrorEnd)); ++ } ++ case Match_RequiresRange0_63: { ++ SMLoc ErrorStart = Operands[3]->getStartLoc(); ++ SMLoc ErrorEnd = Operands[4]->getEndLoc(); ++ return Error(ErrorStart, "from lsbd to msbd are not in the range 0 .. 63", ++ SMRange(ErrorStart, ErrorEnd)); ++ } ++ case Match_MsbHigherThanLsb: { ++ SMLoc ErrorStart = Operands[3]->getStartLoc(); ++ SMLoc ErrorEnd = Operands[4]->getEndLoc(); ++ return Error(ErrorStart, "msb are not higher than lsb", SMRange(ErrorStart, ErrorEnd)); ++ } ++ case Match_MemZeroOff: ++ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), ++ "expected memory with constant 0 offset"); ++ } ++ ++ llvm_unreachable("Implement any new match types added!"); ++} ++ ++/* ++ * Note: The implementation of this function must be sync with the definition ++ * of GPR32/GPR64 RegisterClass in LoongArchRegisterInfo.td ++ */ ++int LoongArchAsmParser::matchCPURegisterName(StringRef Name) { ++ int CC; ++ ++ CC = StringSwitch(Name) ++ .Cases("zero", "r0", 0) ++ .Cases("a0", "v0", "r4", 1) ++ .Cases("a1", "v1", "r5", 2) ++ .Cases("a2", "r6", 3) ++ .Cases("a3", "r7", 4) ++ .Cases("a4", "r8", 5) ++ .Cases("a5", "r9", 6) ++ .Cases("a6", "r10", 7) ++ .Cases("a7", "r11", 8) ++ .Cases("t0", "r12", 9) ++ .Cases("t1", "r13", 10) ++ .Cases("t2", "r14", 11) ++ .Cases("t3", "r15", 12) ++ .Cases("t4", "r16", 13) ++ .Cases("t5", "r17", 14) ++ .Cases("t6", "r18", 15) ++ .Cases("t7", "r19", 16) ++ .Cases("t8", "r20", 17) ++ .Cases("s0", "r23", 18) ++ .Cases("s1", "r24", 19) ++ .Cases("s2", "r25", 20) ++ .Cases("s3", "r26", 21) ++ .Cases("s4", "r27", 22) ++ .Cases("s5", "r28", 23) ++ .Cases("s6", "r29", 24) ++ .Cases("s7", "r30", 25) ++ .Cases("s8", "r31", 26) ++ .Cases("ra", "r1", 27) ++ .Cases("tp", "r2", 28) ++ .Cases("sp", "r3", 29) ++ .Case("r21", 30) ++ .Cases("fp", "r22", 31) ++ .Default(-1); ++ ++ return CC; ++} ++ ++int LoongArchAsmParser::matchFPURegisterName(StringRef Name) { ++ if (Name[0] == 'f') { ++ int CC; ++ ++ CC = StringSwitch(Name) ++ .Cases("f0", "fa0", "fv0", 0) ++ .Cases("f1", "fa1", "fv1", 1) ++ .Cases("f2", "fa2", 2) ++ .Cases("f3", "fa3", 3) ++ .Cases("f4", "fa4", 4) ++ .Cases("f5", "fa5", 5) ++ .Cases("f6", "fa6", 6) ++ .Cases("f7", "fa7", 7) ++ .Cases("f8", "ft0", 8) ++ .Cases("f9", "ft1", 9) ++ .Cases("f10", "ft2", 10) ++ .Cases("f11", "ft3", 11) ++ .Cases("f12", "ft4", 12) ++ .Cases("f13", "ft5", 13) ++ .Cases("f14", "ft6", 14) ++ .Cases("f15", "ft7", 15) ++ .Cases("f16", "ft8", 16) ++ .Cases("f17", "ft9", 17) ++ .Cases("f18", "ft10", 18) ++ .Cases("f19", "ft11", 19) ++ .Cases("f20", "ft12", 20) ++ .Cases("f21", "ft13", 21) ++ .Cases("f22", "ft14", 22) ++ .Cases("f23", "ft15", 23) ++ .Cases("f24", "fs0", 24) ++ .Cases("f25", "fs1", 25) ++ .Cases("f26", "fs2", 26) ++ .Cases("f27", "fs3", 27) ++ .Cases("f28", "fs4", 28) ++ .Cases("f29", "fs5", 29) ++ .Cases("f30", "fs6", 30) ++ .Cases("f31", "fs7", 31) ++ .Default(-1); ++ ++ return CC; ++ } ++ return -1; ++} ++ ++int LoongArchAsmParser::matchFCFRRegisterName(StringRef Name) { ++ if (Name.starts_with("fcc")) { ++ StringRef NumString = Name.substr(3); ++ unsigned IntVal; ++ if (NumString.getAsInteger(10, IntVal)) ++ return -1; // This is not an integer. ++ if (IntVal > 7) // There are only 8 fcc registers. ++ return -1; ++ return IntVal; ++ } ++ return -1; ++} ++ ++int LoongArchAsmParser::matchFCSRRegisterName(StringRef Name) { ++ if (Name.starts_with("fcsr")) { ++ StringRef NumString = Name.substr(4); ++ unsigned IntVal; ++ if (NumString.getAsInteger(10, IntVal)) ++ return -1; // This is not an integer. ++ if (IntVal > 3) // There are only 4 fcsr registers. ++ return -1; ++ return IntVal; ++ } ++ return -1; ++} ++ ++int LoongArchAsmParser::matchLSX128RegisterName(StringRef Name) { ++ unsigned IntVal; ++ ++ if (Name.front() != 'v' || Name.drop_front(2).getAsInteger(10, IntVal)) ++ return -1; ++ ++ if (IntVal > 31) ++ return -1; ++ ++ return IntVal; ++} ++ ++int LoongArchAsmParser::matchLASX256RegisterName(StringRef Name) { ++ unsigned IntVal; ++ ++ if (Name.front() != 'x' || Name.drop_front(2).getAsInteger(10, IntVal)) ++ return -1; ++ ++ if (IntVal > 31) ++ return -1; ++ ++ return IntVal; ++} ++ ++bool LoongArchAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { ++ MCAsmParser &Parser = getParser(); ++ LLVM_DEBUG(dbgs() << "parseOperand\n"); ++ ++ // Check if the current operand has a custom associated parser, if so, try to ++ // custom parse the operand, or fallback to the general approach. ++ OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); ++ if (ResTy == MatchOperand_Success) ++ return false; ++ // If there wasn't a custom match, try the generic matcher below. Otherwise, ++ // there was a match, but an error occurred, in which case, just return that ++ // the operand parsing failed. ++ if (ResTy == MatchOperand_ParseFail) ++ return true; ++ ++ LLVM_DEBUG(dbgs() << ".. Generic Parser\n"); ++ ++ switch (getLexer().getKind()) { ++ case AsmToken::Dollar: { ++ // Parse the register. ++ SMLoc S = Parser.getTok().getLoc(); ++ ++ // Almost all registers have been parsed by custom parsers. There is only ++ // one exception to this. $zero (and it's alias $0) will reach this point ++ // for div, divu, and similar instructions because it is not an operand ++ // to the instruction definition but an explicit register. Special case ++ // this situation for now. ++ if (parseAnyRegister(Operands) != MatchOperand_NoMatch) ++ return false; ++ ++ // Maybe it is a symbol reference. ++ StringRef Identifier; ++ if (Parser.parseIdentifier(Identifier)) ++ return true; ++ ++ SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); ++ MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier); ++ // Otherwise create a symbol reference. ++ const MCExpr *Res = ++ MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); ++ ++ Operands.push_back(LoongArchOperand::CreateImm(Res, S, E, *this)); ++ return false; ++ } ++ default: { ++ LLVM_DEBUG(dbgs() << ".. generic integer expression\n"); ++ ++ const MCExpr *Expr; ++ SMLoc S = Parser.getTok().getLoc(); // Start location of the operand. ++ if (getParser().parseExpression(Expr)) ++ return true; ++ ++ SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); ++ ++ Operands.push_back(LoongArchOperand::CreateImm(Expr, S, E, *this)); ++ return false; ++ } ++ } // switch(getLexer().getKind()) ++ return true; ++} ++ ++bool LoongArchAsmParser::isEvaluated(const MCExpr *Expr) { ++ switch (Expr->getKind()) { ++ case MCExpr::Constant: ++ return true; ++ case MCExpr::SymbolRef: ++ return (cast(Expr)->getKind() != MCSymbolRefExpr::VK_None); ++ case MCExpr::Binary: { ++ const MCBinaryExpr *BE = cast(Expr); ++ if (!isEvaluated(BE->getLHS())) ++ return false; ++ return isEvaluated(BE->getRHS()); ++ } ++ case MCExpr::Unary: ++ return isEvaluated(cast(Expr)->getSubExpr()); ++ case MCExpr::Target: ++ return true; ++ } ++ return false; ++} ++ ++bool LoongArchAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc, ++ SMLoc &EndLoc) { ++ return !tryParseRegister(Reg, StartLoc, EndLoc).isSuccess(); ++} ++ ++ParseStatus LoongArchAsmParser::tryParseRegister(MCRegister &Reg, ++ SMLoc &StartLoc, ++ SMLoc &EndLoc) { ++ SmallVector, 1> Operands; ++ OperandMatchResultTy ResTy = parseAnyRegister(Operands); ++ if (ResTy == MatchOperand_Success) { ++ assert(Operands.size() == 1); ++ LoongArchOperand &Operand = static_cast(*Operands.front()); ++ StartLoc = Operand.getStartLoc(); ++ EndLoc = Operand.getEndLoc(); ++ ++ // AFAIK, we only support numeric registers and named GPR's in CFI ++ // directives. ++ // Don't worry about eating tokens before failing. Using an unrecognised ++ // register is a parse error. ++ if (Operand.isGPRAsmReg()) { ++ // Resolve to GPR32 or GPR64 appropriately. ++ Reg = is64Bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg(); ++ } ++ ++ return (Reg == (unsigned)-1) ? ParseStatus::NoMatch : ParseStatus::Success; ++ } ++ ++ assert(Operands.size() == 0); ++ return (Reg == (unsigned)-1) ? ParseStatus::NoMatch : ParseStatus::Success; ++} ++ ++bool LoongArchAsmParser::parseMemOffset(const MCExpr *&Res) { ++ return getParser().parseExpression(Res); ++} ++ ++OperandMatchResultTy ++LoongArchAsmParser::parseMemOperand(OperandVector &Operands) { ++ MCAsmParser &Parser = getParser(); ++ LLVM_DEBUG(dbgs() << "parseMemOperand\n"); ++ const MCExpr *IdVal = nullptr; ++ SMLoc S; ++ OperandMatchResultTy Res = MatchOperand_NoMatch; ++ // First operand is the base. ++ S = Parser.getTok().getLoc(); ++ ++ Res = parseAnyRegister(Operands); ++ if (Res != MatchOperand_Success) ++ return Res; ++ ++ if (Parser.getTok().isNot(AsmToken::Comma)) { ++ Error(Parser.getTok().getLoc(), "',' expected"); ++ return MatchOperand_ParseFail; ++ } ++ ++ Parser.Lex(); // Eat the ',' token. ++ ++ if (parseMemOffset(IdVal)) ++ return MatchOperand_ParseFail; ++ ++ SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); ++ ++ // Replace the register operand with the memory operand. ++ std::unique_ptr op( ++ static_cast(Operands.back().release())); ++ // Remove the register from the operands. ++ // "op" will be managed by k_Memory. ++ Operands.pop_back(); ++ ++ // when symbol not defined, error report. ++ if (dyn_cast(IdVal)) { ++ return MatchOperand_ParseFail; ++ } ++ ++ // Add the memory operand. ++ if (dyn_cast(IdVal)) { ++ int64_t Imm; ++ if (IdVal->evaluateAsAbsolute(Imm)) ++ IdVal = MCConstantExpr::create(Imm, getContext()); ++ else ++ return MatchOperand_ParseFail; ++ } ++ ++ Operands.push_back(LoongArchOperand::CreateMem(std::move(op), IdVal, S, E, *this)); ++ return MatchOperand_Success; ++} ++ ++OperandMatchResultTy ++LoongArchAsmParser::parseAMemOperand(OperandVector &Operands) { ++ MCAsmParser &Parser = getParser(); ++ LLVM_DEBUG(dbgs() << "parseAMemOperand\n"); ++ const MCExpr *IdVal = nullptr; ++ SMLoc S; ++ OperandMatchResultTy Res = MatchOperand_NoMatch; ++ // First operand is the base. ++ S = Parser.getTok().getLoc(); ++ ++ Res = parseAnyRegister(Operands); ++ if (Res != MatchOperand_Success) ++ return Res; ++ ++ SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); ++ ++ // AM* instructions allow an optional '0' memory offset. ++ if (Parser.getTok().is(AsmToken::Comma)) { ++ Parser.Lex(); // Eat the ',' token. ++ ++ if (parseMemOffset(IdVal)) ++ return MatchOperand_ParseFail; ++ ++ // when symbol not defined, error report. ++ if (dyn_cast(IdVal)) ++ return MatchOperand_ParseFail; ++ ++ if (dyn_cast(IdVal)) { ++ int64_t Imm; ++ if (IdVal->evaluateAsAbsolute(Imm)) { ++ assert(Imm == 0 && "imm must be 0"); ++ IdVal = MCConstantExpr::create(Imm, getContext()); ++ } else { ++ return MatchOperand_ParseFail; ++ } ++ } ++ } else { ++ // Offset defaults to 0. ++ IdVal = MCConstantExpr::create(0, getContext()); ++ } ++ ++ // Replace the register operand with the memory operand. ++ std::unique_ptr op( ++ static_cast(Operands.back().release())); ++ // Remove the register from the operands. ++ // "op" will be managed by k_Memory. ++ Operands.pop_back(); ++ // Add the memory operand. ++ Operands.push_back( ++ LoongArchOperand::CreateMem(std::move(op), IdVal, S, E, *this)); ++ return MatchOperand_Success; ++} ++ ++bool LoongArchAsmParser::searchSymbolAlias(OperandVector &Operands) { ++ MCAsmParser &Parser = getParser(); ++ MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier()); ++ if (!Sym) ++ return false; ++ ++ SMLoc S = Parser.getTok().getLoc(); ++ if (Sym->isVariable()) { ++ const MCExpr *Expr = Sym->getVariableValue(); ++ if (Expr->getKind() == MCExpr::SymbolRef) { ++ const MCSymbolRefExpr *Ref = static_cast(Expr); ++ StringRef DefSymbol = Ref->getSymbol().getName(); ++ if (DefSymbol.starts_with("$")) { ++ OperandMatchResultTy ResTy = ++ matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S); ++ if (ResTy == MatchOperand_Success) { ++ Parser.Lex(); ++ return true; ++ } ++ if (ResTy == MatchOperand_ParseFail) ++ llvm_unreachable("Should never ParseFail"); ++ } ++ } ++ } else if (Sym->isUnset()) { ++ // If symbol is unset, it might be created in the `parseSetAssignment` ++ // routine as an alias for a numeric register name. ++ // Lookup in the aliases list. ++ auto Entry = RegisterSets.find(Sym->getName()); ++ if (Entry != RegisterSets.end()) { ++ OperandMatchResultTy ResTy = ++ matchAnyRegisterWithoutDollar(Operands, Entry->getValue(), S); ++ if (ResTy == MatchOperand_Success) { ++ Parser.Lex(); ++ return true; ++ } ++ } ++ } ++ ++ return false; ++} ++ ++OperandMatchResultTy ++LoongArchAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands, ++ StringRef Identifier, ++ SMLoc S) { ++ int Index = matchCPURegisterName(Identifier); ++ if (Index != -1) { ++ Operands.push_back(LoongArchOperand::createGPRReg( ++ Index, Identifier, getContext().getRegisterInfo(), S, ++ getLexer().getLoc(), *this)); ++ return MatchOperand_Success; ++ } ++ ++ Index = matchFPURegisterName(Identifier); ++ if (Index != -1) { ++ Operands.push_back(LoongArchOperand::createFGRReg( ++ Index, Identifier, getContext().getRegisterInfo(), S, ++ getLexer().getLoc(), *this)); ++ return MatchOperand_Success; ++ } ++ ++ Index = matchFCFRRegisterName(Identifier); ++ if (Index != -1) { ++ Operands.push_back(LoongArchOperand::createFCFRReg( ++ Index, Identifier, getContext().getRegisterInfo(), S, ++ getLexer().getLoc(), *this)); ++ return MatchOperand_Success; ++ } ++ ++ Index = matchFCSRRegisterName(Identifier); ++ if (Index != -1) { ++ Operands.push_back(LoongArchOperand::createFCSRReg( ++ Index, Identifier, getContext().getRegisterInfo(), S, ++ getLexer().getLoc(), *this)); ++ return MatchOperand_Success; ++ } ++ ++ Index = matchLSX128RegisterName(Identifier); ++ if (Index != -1) { ++ Operands.push_back(LoongArchOperand::createLSX128Reg( ++ Index, Identifier, getContext().getRegisterInfo(), S, ++ getLexer().getLoc(), *this)); ++ return MatchOperand_Success; ++ } ++ ++ Index = matchLASX256RegisterName(Identifier); ++ if (Index != -1) { ++ Operands.push_back(LoongArchOperand::createLASX256Reg( ++ Index, Identifier, getContext().getRegisterInfo(), S, ++ getLexer().getLoc(), *this)); ++ return MatchOperand_Success; ++ } ++ ++ return MatchOperand_NoMatch; ++} ++ ++OperandMatchResultTy ++LoongArchAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, ++ const AsmToken &Token, SMLoc S) { ++ if (Token.is(AsmToken::Identifier)) { ++ LLVM_DEBUG(dbgs() << ".. identifier\n"); ++ StringRef Identifier = Token.getIdentifier(); ++ OperandMatchResultTy ResTy = ++ matchAnyRegisterNameWithoutDollar(Operands, Identifier, S); ++ return ResTy; ++ } else if (Token.is(AsmToken::Integer)) { ++ LLVM_DEBUG(dbgs() << ".. integer\n"); ++ int64_t RegNum = Token.getIntVal(); ++ if (RegNum < 0 || RegNum > 31) { ++ // Show the error, but treat invalid register ++ // number as a normal one to continue parsing ++ // and catch other possible errors. ++ Error(getLexer().getLoc(), "invalid register number"); ++ } ++ Operands.push_back(LoongArchOperand::createNumericReg( ++ RegNum, Token.getString(), getContext().getRegisterInfo(), S, ++ Token.getLoc(), *this)); ++ return MatchOperand_Success; ++ } ++ ++ LLVM_DEBUG(dbgs() << Token.getKind() << "\n"); ++ ++ return MatchOperand_NoMatch; ++} ++ ++OperandMatchResultTy ++LoongArchAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) { ++ auto Token = getLexer().peekTok(false); ++ return matchAnyRegisterWithoutDollar(Operands, Token, S); ++} ++ ++OperandMatchResultTy ++LoongArchAsmParser::parseAnyRegister(OperandVector &Operands) { ++ MCAsmParser &Parser = getParser(); ++ LLVM_DEBUG(dbgs() << "parseAnyRegister\n"); ++ ++ auto Token = Parser.getTok(); ++ ++ SMLoc S = Token.getLoc(); ++ ++ if (Token.isNot(AsmToken::Dollar)) { ++ LLVM_DEBUG(dbgs() << ".. !$ -> try sym aliasing\n"); ++ if (Token.is(AsmToken::Identifier)) { ++ if (searchSymbolAlias(Operands)) ++ return MatchOperand_Success; ++ } ++ LLVM_DEBUG(dbgs() << ".. !symalias -> NoMatch\n"); ++ return MatchOperand_NoMatch; ++ } ++ LLVM_DEBUG(dbgs() << ".. $\n"); ++ ++ OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S); ++ if (ResTy == MatchOperand_Success) { ++ Parser.Lex(); // $ ++ Parser.Lex(); // identifier ++ } ++ return ResTy; ++} ++ ++OperandMatchResultTy ++LoongArchAsmParser::parseJumpTarget(OperandVector &Operands) { ++ MCAsmParser &Parser = getParser(); ++ LLVM_DEBUG(dbgs() << "parseJumpTarget\n"); ++ ++ SMLoc S = getLexer().getLoc(); ++ ++ // Registers are a valid target and have priority over symbols. ++ OperandMatchResultTy ResTy = parseAnyRegister(Operands); ++ if (ResTy != MatchOperand_NoMatch) ++ return ResTy; ++ ++ // Integers and expressions are acceptable ++ const MCExpr *Expr = nullptr; ++ if (Parser.parseExpression(Expr)) { ++ // We have no way of knowing if a symbol was consumed so we must ParseFail ++ return MatchOperand_ParseFail; ++ } ++ Operands.push_back( ++ LoongArchOperand::CreateImm(Expr, S, getLexer().getLoc(), *this)); ++ return MatchOperand_Success; ++} ++ ++static std::string LoongArchMnemonicSpellCheck(StringRef S, ++ const FeatureBitset &FBS, ++ unsigned VariantID = 0); ++ ++bool LoongArchAsmParser::ParseInstruction(ParseInstructionInfo &Info, ++ StringRef Name, SMLoc NameLoc, ++ OperandVector &Operands) { ++ MCAsmParser &Parser = getParser(); ++ LLVM_DEBUG(dbgs() << "ParseInstruction\n"); ++ ++ // We have reached first instruction, module directive are now forbidden. ++ getTargetStreamer().forbidModuleDirective(); ++ ++ // Check if we have valid mnemonic ++ if (!mnemonicIsValid(Name)) { ++ FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits()); ++ std::string Suggestion = LoongArchMnemonicSpellCheck(Name, FBS); ++ return Error(NameLoc, "unknown instruction" + Suggestion); ++ } ++ ++ // First operand in MCInst is instruction mnemonic. ++ Operands.push_back(LoongArchOperand::CreateToken(Name, NameLoc, *this)); ++ ++ // Read the remaining operands. ++ if (getLexer().isNot(AsmToken::EndOfStatement)) { ++ // Read the first operand. ++ if (parseOperand(Operands, Name)) { ++ SMLoc Loc = getLexer().getLoc(); ++ return Error(Loc, "unexpected token in argument list"); ++ } ++ ++ while (getLexer().is(AsmToken::Comma)) { ++ Parser.Lex(); // Eat the comma. ++ // Parse and remember the operand. ++ if (parseOperand(Operands, Name)) { ++ SMLoc Loc = getLexer().getLoc(); ++ return Error(Loc, "unexpected token in argument list"); ++ } ++ } ++ } ++ if (getLexer().isNot(AsmToken::EndOfStatement)) { ++ SMLoc Loc = getLexer().getLoc(); ++ return Error(Loc, "unexpected token in argument list"); ++ } ++ Parser.Lex(); // Consume the EndOfStatement. ++ return false; ++} ++ ++// FIXME: Given that these have the same name, these should both be ++// consistent on affecting the Parser. ++bool LoongArchAsmParser::reportParseError(Twine ErrorMsg) { ++ SMLoc Loc = getLexer().getLoc(); ++ return Error(Loc, ErrorMsg); ++} ++ ++bool LoongArchAsmParser::parseSetAssignment() { ++ StringRef Name; ++ const MCExpr *Value; ++ MCAsmParser &Parser = getParser(); ++ ++ if (Parser.parseIdentifier(Name)) ++ return reportParseError("expected identifier after .set"); ++ ++ if (getLexer().isNot(AsmToken::Comma)) ++ return reportParseError("unexpected token, expected comma"); ++ Lex(); // Eat comma ++ ++ if (!Parser.parseExpression(Value)) { ++ // Parse assignment of an expression including ++ // symbolic registers: ++ // .set $tmp, $BB0-$BB1 ++ // .set r2, $f2 ++ MCSymbol *Sym = getContext().getOrCreateSymbol(Name); ++ Sym->setVariableValue(Value); ++ } else { ++ return reportParseError("expected valid expression after comma"); ++ } ++ ++ return false; ++} ++ ++bool LoongArchAsmParser::parseDirectiveSet() { ++ const AsmToken &Tok = getParser().getTok(); ++ StringRef IdVal = Tok.getString(); ++ SMLoc Loc = Tok.getLoc(); ++ ++ if (IdVal == "bopt") { ++ Warning(Loc, "'bopt' feature is unsupported"); ++ getParser().Lex(); ++ return false; ++ } ++ if (IdVal == "nobopt") { ++ // We're already running in nobopt mode, so nothing to do. ++ getParser().Lex(); ++ return false; ++ } ++ ++ // It is just an identifier, look for an assignment. ++ return parseSetAssignment(); ++} ++ ++bool LoongArchAsmParser::ParseDirective(AsmToken DirectiveID) { ++ // This returns false if this function recognizes the directive ++ // regardless of whether it is successfully handles or reports an ++ // error. Otherwise it returns true to give the generic parser a ++ // chance at recognizing it. ++ ++ MCAsmParser &Parser = getParser(); ++ StringRef IDVal = DirectiveID.getString(); ++ ++ if (IDVal == ".end") { ++ while (getLexer().isNot(AsmToken::Eof)) ++ Parser.Lex(); ++ return false; ++ } ++ ++ if (IDVal == ".set") { ++ parseDirectiveSet(); ++ return false; ++ } ++ ++ if (IDVal == ".llvm_internal_loongarch_reallow_module_directive") { ++ parseInternalDirectiveReallowModule(); ++ return false; ++ } ++ ++ return true; ++} ++ ++bool LoongArchAsmParser::parseInternalDirectiveReallowModule() { ++ // If this is not the end of the statement, report an error. ++ if (getLexer().isNot(AsmToken::EndOfStatement)) { ++ reportParseError("unexpected token, expected end of statement"); ++ return false; ++ } ++ ++ getTargetStreamer().reallowModuleDirective(); ++ ++ getParser().Lex(); // Eat EndOfStatement token. ++ return false; + } + + extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchAsmParser() { + RegisterMCAsmParser X(getTheLoongArch32Target()); +- RegisterMCAsmParser Y(getTheLoongArch64Target()); ++ RegisterMCAsmParser A(getTheLoongArch64Target()); ++} ++ ++#define GET_REGISTER_MATCHER ++#define GET_MATCHER_IMPLEMENTATION ++#define GET_MNEMONIC_SPELL_CHECKER ++#include "LoongArchGenAsmMatcher.inc" ++ ++bool LoongArchAsmParser::mnemonicIsValid(StringRef Mnemonic) { ++ // Find the appropriate table for this asm variant. ++ const MatchEntry *Start, *End; ++ Start = std::begin(MatchTable0); ++ End = std::end(MatchTable0); ++ ++ // Search the table. ++ auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode()); ++ return MnemonicRange.first != MnemonicRange.second; + } +diff --git a/llvm/lib/Target/LoongArch/CMakeLists.txt b/llvm/lib/Target/LoongArch/CMakeLists.txt +index 62e5a0ab6..b429caeee 100644 +--- a/llvm/lib/Target/LoongArch/CMakeLists.txt ++++ b/llvm/lib/Target/LoongArch/CMakeLists.txt +@@ -1,14 +1,15 @@ +-add_llvm_component_group(LoongArch) ++add_llvm_component_group(LoongArch HAS_JIT) + + set(LLVM_TARGET_DEFINITIONS LoongArch.td) + + tablegen(LLVM LoongArchGenAsmMatcher.inc -gen-asm-matcher) + tablegen(LLVM LoongArchGenAsmWriter.inc -gen-asm-writer) ++tablegen(LLVM LoongArchGenCallingConv.inc -gen-callingconv) + tablegen(LLVM LoongArchGenDAGISel.inc -gen-dag-isel) + tablegen(LLVM LoongArchGenDisassemblerTables.inc -gen-disassembler) + tablegen(LLVM LoongArchGenInstrInfo.inc -gen-instr-info) +-tablegen(LLVM LoongArchGenMCPseudoLowering.inc -gen-pseudo-lowering) + tablegen(LLVM LoongArchGenMCCodeEmitter.inc -gen-emitter) ++tablegen(LLVM LoongArchGenMCPseudoLowering.inc -gen-pseudo-lowering) + tablegen(LLVM LoongArchGenRegisterInfo.inc -gen-register-info) + tablegen(LLVM LoongArchGenSubtargetInfo.inc -gen-subtarget) + +@@ -16,16 +17,19 @@ add_public_tablegen_target(LoongArchCommonTableGen) + + add_llvm_target(LoongArchCodeGen + LoongArchAsmPrinter.cpp +- LoongArchExpandAtomicPseudoInsts.cpp +- LoongArchExpandPseudoInsts.cpp +- LoongArchFrameLowering.cpp ++ LoongArchCCState.cpp ++ LoongArchExpandPseudo.cpp + LoongArchInstrInfo.cpp + LoongArchISelDAGToDAG.cpp + LoongArchISelLowering.cpp ++ LoongArchFrameLowering.cpp + LoongArchMCInstLower.cpp ++ LoongArchMachineFunction.cpp ++ LoongArchModuleISelDAGToDAG.cpp + LoongArchRegisterInfo.cpp + LoongArchSubtarget.cpp + LoongArchTargetMachine.cpp ++ LoongArchTargetObjectFile.cpp + LoongArchTargetTransformInfo.cpp + + LINK_COMPONENTS +@@ -37,11 +41,11 @@ add_llvm_target(LoongArchCodeGen + LoongArchDesc + LoongArchInfo + MC +- Scalar + SelectionDAG + Support + Target + TargetParser ++ GlobalISel + + ADD_TO_COMPONENT + LoongArch +diff --git a/llvm/lib/Target/LoongArch/Disassembler/CMakeLists.txt b/llvm/lib/Target/LoongArch/Disassembler/CMakeLists.txt +index 1cce676cf..864be6313 100644 +--- a/llvm/lib/Target/LoongArch/Disassembler/CMakeLists.txt ++++ b/llvm/lib/Target/LoongArch/Disassembler/CMakeLists.txt +@@ -2,10 +2,8 @@ add_llvm_component_library(LLVMLoongArchDisassembler + LoongArchDisassembler.cpp + + LINK_COMPONENTS +- LoongArchDesc +- LoongArchInfo +- MC + MCDisassembler ++ LoongArchInfo + Support + + ADD_TO_COMPONENT +diff --git a/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp b/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp +index 8f61dfe7b..6468a0fc8 100644 +--- a/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp ++++ b/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp +@@ -1,4 +1,4 @@ +-//===-- LoongArchDisassembler.cpp - Disassembler for LoongArch ------------===// ++//===- LoongArchDisassembler.cpp - Disassembler for LoongArch -----------------------===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -6,167 +6,935 @@ + // + //===----------------------------------------------------------------------===// + // +-// This file implements the LoongArchDisassembler class. ++// This file is part of the LoongArch Disassembler. + // + //===----------------------------------------------------------------------===// + +-#include "MCTargetDesc/LoongArchBaseInfo.h" + #include "MCTargetDesc/LoongArchMCTargetDesc.h" +-#include "TargetInfo/LoongArchTargetInfo.h" ++#include "LoongArch.h" ++#include "llvm/ADT/ArrayRef.h" + #include "llvm/MC/MCContext.h" + #include "llvm/MC/MCDecoderOps.h" + #include "llvm/MC/MCDisassembler/MCDisassembler.h" + #include "llvm/MC/MCInst.h" +-#include "llvm/MC/MCInstrInfo.h" + #include "llvm/MC/MCRegisterInfo.h" + #include "llvm/MC/MCSubtargetInfo.h" ++#include "llvm/Support/Compiler.h" ++#include "llvm/Support/Debug.h" ++#include "llvm/Support/ErrorHandling.h" ++#include "llvm/Support/MathExtras.h" + #include "llvm/MC/TargetRegistry.h" +-#include "llvm/Support/Endian.h" ++#include "llvm/Support/raw_ostream.h" ++#include ++#include + + using namespace llvm; + + #define DEBUG_TYPE "loongarch-disassembler" + +-typedef MCDisassembler::DecodeStatus DecodeStatus; ++using DecodeStatus = MCDisassembler::DecodeStatus; + + namespace { ++ + class LoongArchDisassembler : public MCDisassembler { ++ + public: + LoongArchDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) + : MCDisassembler(STI, Ctx) {} + ++ bool isFP64() const { return STI.getFeatureBits()[LoongArch::FeatureFP64Bit]; } ++ ++ bool is64Bit() const { return STI.getFeatureBits()[LoongArch::Feature64Bit]; } ++ + DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, + ArrayRef Bytes, uint64_t Address, + raw_ostream &CStream) const override; + }; +-} // end namespace + +-static MCDisassembler *createLoongArchDisassembler(const Target &T, +- const MCSubtargetInfo &STI, +- MCContext &Ctx) { ++} // end anonymous namespace ++ ++// Forward declare these because the autogenerated code will reference them. ++// Definitions are further down. ++static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, ++ unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder); ++ ++static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, ++ unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder); ++ ++static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, ++ unsigned Insn, ++ uint64_t Address, ++ const void *Decoder); ++ ++static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, ++ unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder); ++ ++static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, ++ unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder); ++ ++static DecodeStatus DecodeFCSRRegisterClass(MCInst &Inst, ++ unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder); ++ ++static DecodeStatus DecodeFCFRRegisterClass(MCInst &Inst, ++ unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder); ++ ++static DecodeStatus DecodeLSX128BRegisterClass(MCInst &Inst, unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder); ++ ++static DecodeStatus DecodeLSX128HRegisterClass(MCInst &Inst, unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder); ++ ++static DecodeStatus DecodeLSX128WRegisterClass(MCInst &Inst, unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder); ++ ++static DecodeStatus DecodeLSX128DRegisterClass(MCInst &Inst, unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder); ++ ++static DecodeStatus DecodeLASX256BRegisterClass(MCInst &Inst, unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder); ++ ++static DecodeStatus DecodeLASX256HRegisterClass(MCInst &Inst, unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder); ++ ++static DecodeStatus DecodeLASX256WRegisterClass(MCInst &Inst, unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder); ++ ++static DecodeStatus DecodeLASX256DRegisterClass(MCInst &Inst, unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder); ++ ++static DecodeStatus DecodeBranchTarget(MCInst &Inst, ++ unsigned Offset, ++ uint64_t Address, ++ const void *Decoder); ++ ++static DecodeStatus DecodeJumpTarget(MCInst &Inst, ++ unsigned Insn, ++ uint64_t Address, ++ const void *Decoder); ++ ++static DecodeStatus DecodeMem(MCInst &Inst, ++ unsigned Insn, ++ uint64_t Address, ++ const void *Decoder); ++ ++static DecodeStatus DecodeAMem(MCInst &Inst, unsigned Insn, uint64_t Address, ++ const void *Decoder); ++ ++static DecodeStatus DecodeMemSimm14(MCInst &Inst, ++ unsigned Insn, ++ uint64_t Address, ++ const void *Decoder); ++ ++static DecodeStatus DecodeLSX128Mem(MCInst &Inst, unsigned Insn, ++ uint64_t Address, const void *Decoder); ++ ++static DecodeStatus DecodeLSX128Mem13(MCInst &Inst, unsigned Insn, ++ uint64_t Address, const void *Decoder); ++ ++static DecodeStatus DecodeLSX128Mem10(MCInst &Inst, unsigned Insn, ++ uint64_t Address, const void *Decoder); ++ ++static DecodeStatus DecodeLASX256Mem13(MCInst &Inst, unsigned Insn, ++ uint64_t Address, const void *Decoder); ++ ++static DecodeStatus DecodeLASX256Mem10(MCInst &Inst, unsigned Insn, ++ uint64_t Address, const void *Decoder); ++ ++static DecodeStatus DecodeLSX128memlsl(MCInst &Inst, unsigned Insn, ++ uint64_t Address, const void *Decoder); ++ ++static DecodeStatus DecodeLSX128memstl(MCInst &Inst, unsigned Insn, ++ uint64_t Address, const void *Decoder); ++ ++static DecodeStatus DecodeLASX256memlsl(MCInst &Inst, unsigned Insn, ++ uint64_t Address, const void *Decoder); ++ ++static DecodeStatus DecodeLASX256memstl(MCInst &Inst, unsigned Insn, ++ uint64_t Address, const void *Decoder); ++ ++static DecodeStatus DecodeLASX256Mem(MCInst &Inst, unsigned Insn, ++ uint64_t Address, const void *Decoder); ++ ++static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, ++ uint64_t Address, ++ const void *Decoder); ++ ++template ++static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value, ++ uint64_t Address, ++ const void *Decoder); ++ ++template ++static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value, ++ uint64_t Address, ++ const void *Decoder) { ++ return DecodeUImmWithOffsetAndScale(Inst, Value, Address, ++ Decoder); ++} ++ ++template ++static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value, ++ uint64_t Address, ++ const void *Decoder); ++ ++/// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't ++/// handle. ++template ++static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, ++ const void *Decoder); ++ ++namespace llvm { ++ ++Target &getTheLoongArch32Target(); ++Target &getTheLoongArch64Target(); ++ ++} // end namespace llvm ++ ++static MCDisassembler *createLoongArchDisassembler( ++ const Target &T, ++ const MCSubtargetInfo &STI, ++ MCContext &Ctx) { + return new LoongArchDisassembler(STI, Ctx); + } + + extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchDisassembler() { +- // Register the disassembler for each target. ++ // Register the disassembler. + TargetRegistry::RegisterMCDisassembler(getTheLoongArch32Target(), + createLoongArchDisassembler); + TargetRegistry::RegisterMCDisassembler(getTheLoongArch64Target(), + createLoongArchDisassembler); + } + +-static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo, +- uint64_t Address, +- const MCDisassembler *Decoder) { +- if (RegNo >= 32) ++#include "LoongArchGenDisassemblerTables.inc" ++ ++static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) { ++ const LoongArchDisassembler *Dis = static_cast(D); ++ const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo(); ++ if (RC == LoongArch::GPR64RegClassID || RC == LoongArch::GPR32RegClassID) { ++ // sync with the GPR32/GPR64 RegisterClass in LoongArchRegisterInfo.td ++ // that just like LoongArchAsmParser.cpp and LoongArchISelLowering.cpp ++ unsigned char indexes[] = { 0, 27, 28, 29, 1, 2, 3, 4, ++ 5, 6, 7, 8, 9, 10, 11, 12, ++ 13, 14, 15, 16, 17, 30, 31, 18, ++ 19, 20, 21, 22, 23, 24, 25, 26 ++ }; ++ assert(RegNo < sizeof(indexes)); ++ return *(RegInfo->getRegClass(RC).begin() + indexes[RegNo]); ++ } ++ return *(RegInfo->getRegClass(RC).begin() + RegNo); ++} ++ ++template ++static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, ++ const void *Decoder) { ++ using DecodeFN = DecodeStatus (*)(MCInst &, unsigned, uint64_t, const void *); ++ ++ // The size of the n field depends on the element size ++ // The register class also depends on this. ++ InsnType tmp = fieldFromInstruction(insn, 17, 5); ++ unsigned NSize = 0; ++ DecodeFN RegDecoder = nullptr; ++ if ((tmp & 0x18) == 0x00) { ++ NSize = 4; ++ RegDecoder = DecodeLSX128BRegisterClass; ++ } else if ((tmp & 0x1c) == 0x10) { ++ NSize = 3; ++ RegDecoder = DecodeLSX128HRegisterClass; ++ } else if ((tmp & 0x1e) == 0x18) { ++ NSize = 2; ++ RegDecoder = DecodeLSX128WRegisterClass; ++ } else if ((tmp & 0x1f) == 0x1c) { ++ NSize = 1; ++ RegDecoder = DecodeLSX128DRegisterClass; ++ } else ++ llvm_unreachable("Invalid encoding"); ++ ++ assert(NSize != 0 && RegDecoder != nullptr); ++ ++ // $vd ++ tmp = fieldFromInstruction(insn, 6, 5); ++ if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) ++ return MCDisassembler::Fail; ++ // $vd_in ++ if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) ++ return MCDisassembler::Fail; ++ // $n ++ tmp = fieldFromInstruction(insn, 16, NSize); ++ MI.addOperand(MCOperand::createImm(tmp)); ++ // $vs ++ tmp = fieldFromInstruction(insn, 11, 5); ++ if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) ++ return MCDisassembler::Fail; ++ // $n2 ++ MI.addOperand(MCOperand::createImm(0)); ++ ++ return MCDisassembler::Success; ++} ++ ++/// Read four bytes from the ArrayRef and return 32 bit word. ++static DecodeStatus readInstruction32(ArrayRef Bytes, uint64_t Address, ++ uint64_t &Size, uint32_t &Insn) { ++ // We want to read exactly 4 Bytes of data. ++ if (Bytes.size() < 4) { ++ Size = 0; + return MCDisassembler::Fail; +- Inst.addOperand(MCOperand::createReg(LoongArch::R0 + RegNo)); ++ } ++ ++ Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) | ++ (Bytes[3] << 24); ++ + return MCDisassembler::Success; + } + +-static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo, ++DecodeStatus LoongArchDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, ++ ArrayRef Bytes, ++ uint64_t Address, ++ raw_ostream &CStream) const { ++ uint32_t Insn; ++ DecodeStatus Result; ++ Size = 0; ++ ++ // Attempt to read the instruction so that we can attempt to decode it. If ++ // the buffer is not 4 bytes long, let the higher level logic figure out ++ // what to do with a size of zero and MCDisassembler::Fail. ++ Result = readInstruction32(Bytes, Address, Size, Insn); ++ if (Result == MCDisassembler::Fail) ++ return MCDisassembler::Fail; ++ ++ // The only instruction size for standard encoded LoongArch. ++ Size = 4; ++ ++ if (is64Bit()) { ++ LLVM_DEBUG(dbgs() << "Trying LoongArch (GPR64) table (32-bit opcodes):\n"); ++ Result = decodeInstruction(DecoderTableLoongArch32, Instr, Insn, ++ Address, this, STI); ++ if (Result != MCDisassembler::Fail) ++ return Result; ++ } ++ ++ LLVM_DEBUG(dbgs() << "Trying LoongArch32 (GPR32) table (32-bit opcodes):\n"); ++ Result = decodeInstruction(DecoderTableLoongArch3232, Instr, Insn, ++ Address, this, STI); ++ if (Result != MCDisassembler::Fail) ++ return Result; ++ ++ return MCDisassembler::Fail; ++} ++ ++static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, ++ unsigned RegNo, + uint64_t Address, +- const MCDisassembler *Decoder) { +- if (RegNo >= 32) ++ const void *Decoder) { ++ if (RegNo > 31) + return MCDisassembler::Fail; +- Inst.addOperand(MCOperand::createReg(LoongArch::F0 + RegNo)); ++ ++ unsigned Reg = getReg(Decoder, LoongArch::GPR64RegClassID, RegNo); ++ Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; + } + +-static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo, ++static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, ++ unsigned RegNo, + uint64_t Address, +- const MCDisassembler *Decoder) { +- if (RegNo >= 32) ++ const void *Decoder) { ++ if (RegNo > 31) + return MCDisassembler::Fail; +- Inst.addOperand(MCOperand::createReg(LoongArch::F0_64 + RegNo)); ++ unsigned Reg = getReg(Decoder, LoongArch::GPR32RegClassID, RegNo); ++ Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; + } + +-static DecodeStatus DecodeCFRRegisterClass(MCInst &Inst, uint64_t RegNo, ++static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, ++ unsigned RegNo, + uint64_t Address, +- const MCDisassembler *Decoder) { +- if (RegNo >= 8) ++ const void *Decoder) { ++ if (static_cast(Decoder)->is64Bit()) ++ return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder); ++ ++ return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); ++} ++ ++static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, ++ unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder) { ++ if (RegNo > 31) ++ return MCDisassembler::Fail; ++ unsigned Reg = getReg(Decoder, LoongArch::FGR64RegClassID, RegNo); ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ return MCDisassembler::Success; ++} ++ ++static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, ++ unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder) { ++ if (RegNo > 31) ++ return MCDisassembler::Fail; ++ ++ unsigned Reg = getReg(Decoder, LoongArch::FGR32RegClassID, RegNo); ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ return MCDisassembler::Success; ++} ++ ++static DecodeStatus DecodeFCSRRegisterClass(MCInst &Inst, ++ unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder) { ++ if (RegNo > 31) + return MCDisassembler::Fail; +- Inst.addOperand(MCOperand::createReg(LoongArch::FCC0 + RegNo)); ++ ++ unsigned Reg = getReg(Decoder, LoongArch::FCSRRegClassID, RegNo); ++ Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; + } + +-static DecodeStatus DecodeFCSRRegisterClass(MCInst &Inst, uint64_t RegNo, ++static DecodeStatus DecodeFCFRRegisterClass(MCInst &Inst, ++ unsigned RegNo, + uint64_t Address, +- const MCDisassembler *Decoder) { +- if (RegNo >= 4) ++ const void *Decoder) { ++ if (RegNo > 7) ++ return MCDisassembler::Fail; ++ ++ unsigned Reg = getReg(Decoder, LoongArch::FCFRRegClassID, RegNo); ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ ++ return MCDisassembler::Success; ++} ++ ++static DecodeStatus DecodeMem(MCInst &Inst, ++ unsigned Insn, ++ uint64_t Address, ++ const void *Decoder) { ++ int Offset = SignExtend32<12>((Insn >> 10) & 0xfff); ++ unsigned Reg = fieldFromInstruction(Insn, 0, 5); ++ unsigned Base = fieldFromInstruction(Insn, 5, 5); ++ ++ Reg = getReg(Decoder, LoongArch::GPR32RegClassID, Reg); ++ Base = getReg(Decoder, LoongArch::GPR32RegClassID, Base); ++ ++ if (Inst.getOpcode() == LoongArch::SC_W || ++ Inst.getOpcode() == LoongArch::SC_D) ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ Inst.addOperand(MCOperand::createReg(Base)); ++ Inst.addOperand(MCOperand::createImm(Offset)); ++ ++ return MCDisassembler::Success; ++} ++ ++static DecodeStatus DecodeAMem(MCInst &Inst, unsigned Insn, uint64_t Address, ++ const void *Decoder) { ++ unsigned Rd = fieldFromInstruction(Insn, 0, 5); ++ unsigned Rj = fieldFromInstruction(Insn, 5, 5); ++ unsigned Rk = fieldFromInstruction(Insn, 10, 5); ++ ++ Rd = getReg(Decoder, LoongArch::GPR32RegClassID, Rd); ++ Rj = getReg(Decoder, LoongArch::GPR32RegClassID, Rj); ++ Rk = getReg(Decoder, LoongArch::GPR32RegClassID, Rk); ++ ++ // Note the operands sequence is "rd,rk,rj". ++ Inst.addOperand(MCOperand::createReg(Rd)); ++ Inst.addOperand(MCOperand::createReg(Rk)); ++ Inst.addOperand(MCOperand::createReg(Rj)); ++ ++ return MCDisassembler::Success; ++} ++ ++static DecodeStatus DecodeMemSimm14(MCInst &Inst, ++ unsigned Insn, ++ uint64_t Address, ++ const void *Decoder) { ++ int Offset = SignExtend32<12>((Insn >> 10) & 0x3fff); ++ unsigned Reg = fieldFromInstruction(Insn, 0, 5); ++ unsigned Base = fieldFromInstruction(Insn, 5, 5); ++ ++ Reg = getReg(Decoder, LoongArch::GPR32RegClassID, Reg); ++ Base = getReg(Decoder, LoongArch::GPR32RegClassID, Base); ++ ++ if (Inst.getOpcode() == LoongArch::SC_W || ++ Inst.getOpcode() == LoongArch::SC_D) ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ Inst.addOperand(MCOperand::createReg(Base)); ++ Inst.addOperand(MCOperand::createImm(Offset)); ++ ++ return MCDisassembler::Success; ++} ++ ++static DecodeStatus DecodeLSX128Mem(MCInst &Inst, unsigned Insn, ++ uint64_t Address, const void *Decoder) { ++ int Offset = SignExtend32<12>(fieldFromInstruction(Insn, 10, 12)); ++ unsigned Reg = fieldFromInstruction(Insn, 0, 5); ++ unsigned Base = fieldFromInstruction(Insn, 5, 5); ++ Reg = getReg(Decoder, LoongArch::LSX128BRegClassID, Reg); ++ Base = getReg(Decoder, LoongArch::GPR32RegClassID, Base); ++ ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ Inst.addOperand(MCOperand::createReg(Base)); ++ ++ Inst.addOperand(MCOperand::createImm(Offset)); ++ ++ return MCDisassembler::Success; ++} ++ ++static DecodeStatus DecodeLSX128Mem13(MCInst &Inst, unsigned Insn, ++ uint64_t Address, const void *Decoder) { ++ int Offset = SignExtend32<13>(fieldFromInstruction(Insn, 5, 13)); ++ unsigned Reg = fieldFromInstruction(Insn, 0, 5); ++ Reg = getReg(Decoder, LoongArch::LSX128BRegClassID, Reg); ++ ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ ++ Inst.addOperand(MCOperand::createImm(Offset)); ++ ++ return MCDisassembler::Success; ++} ++ ++static DecodeStatus DecodeLSX128Mem10(MCInst &Inst, unsigned Insn, ++ uint64_t Address, const void *Decoder) { ++ int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 5, 10)); ++ unsigned Reg = fieldFromInstruction(Insn, 0, 5); ++ Reg = getReg(Decoder, LoongArch::LSX128BRegClassID, Reg); ++ ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ ++ Inst.addOperand(MCOperand::createImm(Offset)); ++ ++ return MCDisassembler::Success; ++} ++ ++static DecodeStatus DecodeLASX256Mem13(MCInst &Inst, unsigned Insn, ++ uint64_t Address, const void *Decoder) { ++ int Offset = SignExtend32<13>(fieldFromInstruction(Insn, 5, 13)); ++ unsigned Reg = fieldFromInstruction(Insn, 0, 5); ++ Reg = getReg(Decoder, LoongArch::LASX256BRegClassID, Reg); ++ ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ ++ Inst.addOperand(MCOperand::createImm(Offset)); ++ ++ return MCDisassembler::Success; ++} ++ ++static DecodeStatus DecodeLASX256Mem10(MCInst &Inst, unsigned Insn, ++ uint64_t Address, const void *Decoder) { ++ int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 5, 10)); ++ unsigned Reg = fieldFromInstruction(Insn, 0, 5); ++ Reg = getReg(Decoder, LoongArch::LASX256BRegClassID, Reg); ++ ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ ++ Inst.addOperand(MCOperand::createImm(Offset)); ++ ++ return MCDisassembler::Success; ++} ++ ++static DecodeStatus DecodeLSX128memstl(MCInst &Inst, unsigned Insn, ++ uint64_t Address, const void *Decoder) { ++ int Offset = SignExtend32<8>(fieldFromInstruction(Insn, 10, 8)); ++ unsigned Reg = fieldFromInstruction(Insn, 0, 5); ++ unsigned Base = fieldFromInstruction(Insn, 5, 5); ++ Reg = getReg(Decoder, LoongArch::LSX128BRegClassID, Reg); ++ Base = getReg(Decoder, LoongArch::GPR32RegClassID, Base); ++ unsigned idx; ++ ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ Inst.addOperand(MCOperand::createReg(Base)); ++ ++ switch (Inst.getOpcode()) { ++ default: ++ assert(false && "Unexpected instruction"); ++ return MCDisassembler::Fail; ++ break; ++ case LoongArch::VSTELM_B: ++ Inst.addOperand(MCOperand::createImm(Offset)); ++ idx = fieldFromInstruction(Insn, 18, 4); ++ Inst.addOperand(MCOperand::createImm(idx)); ++ break; ++ case LoongArch::VSTELM_H: ++ Inst.addOperand(MCOperand::createImm(Offset * 2)); ++ idx = fieldFromInstruction(Insn, 18, 3); ++ Inst.addOperand(MCOperand::createImm(idx)); ++ break; ++ case LoongArch::VSTELM_W: ++ Inst.addOperand(MCOperand::createImm(Offset * 4)); ++ idx = fieldFromInstruction(Insn, 18, 2); ++ Inst.addOperand(MCOperand::createImm(idx)); ++ break; ++ case LoongArch::VSTELM_D: ++ Inst.addOperand(MCOperand::createImm(Offset * 8)); ++ idx = fieldFromInstruction(Insn, 18, 1); ++ Inst.addOperand(MCOperand::createImm(idx)); ++ break; ++ } ++ ++ return MCDisassembler::Success; ++} ++ ++static DecodeStatus DecodeLSX128memlsl(MCInst &Inst, unsigned Insn, ++ uint64_t Address, const void *Decoder) { ++ ++ int Offset; ++ unsigned Reg, Base; ++ switch (Inst.getOpcode()) { ++ default: ++ assert(false && "Unexpected instruction"); ++ return MCDisassembler::Fail; ++ break; ++ case LoongArch::VLDREPL_B: ++ ++ Offset = SignExtend32<12>(fieldFromInstruction(Insn, 10, 12)); ++ Reg = fieldFromInstruction(Insn, 0, 5); ++ Base = fieldFromInstruction(Insn, 5, 5); ++ Reg = getReg(Decoder, LoongArch::LSX128BRegClassID, Reg); ++ Base = getReg(Decoder, LoongArch::GPR32RegClassID, Base); ++ ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ Inst.addOperand(MCOperand::createReg(Base)); ++ ++ Inst.addOperand(MCOperand::createImm(Offset)); ++ break; ++ case LoongArch::VLDREPL_H: ++ ++ Offset = SignExtend32<11>(fieldFromInstruction(Insn, 10, 11)); ++ Reg = fieldFromInstruction(Insn, 0, 5); ++ Base = fieldFromInstruction(Insn, 5, 5); ++ Reg = getReg(Decoder, LoongArch::LSX128HRegClassID, Reg); ++ Base = getReg(Decoder, LoongArch::GPR32RegClassID, Base); ++ ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ Inst.addOperand(MCOperand::createReg(Base)); ++ Inst.addOperand(MCOperand::createImm(Offset * 2)); ++ break; ++ case LoongArch::VLDREPL_W: ++ ++ Offset = SignExtend32<10>(fieldFromInstruction(Insn, 10, 10)); ++ Reg = fieldFromInstruction(Insn, 0, 5); ++ Base = fieldFromInstruction(Insn, 5, 5); ++ Reg = getReg(Decoder, LoongArch::LSX128WRegClassID, Reg); ++ Base = getReg(Decoder, LoongArch::GPR32RegClassID, Base); ++ ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ Inst.addOperand(MCOperand::createReg(Base)); ++ Inst.addOperand(MCOperand::createImm(Offset * 4)); ++ break; ++ case LoongArch::VLDREPL_D: ++ ++ Offset = SignExtend32<9>(fieldFromInstruction(Insn, 10, 9)); ++ Reg = fieldFromInstruction(Insn, 0, 5); ++ Base = fieldFromInstruction(Insn, 5, 5); ++ Reg = getReg(Decoder, LoongArch::LSX128WRegClassID, Reg); ++ Base = getReg(Decoder, LoongArch::GPR32RegClassID, Base); ++ ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ Inst.addOperand(MCOperand::createReg(Base)); ++ Inst.addOperand(MCOperand::createImm(Offset * 8)); ++ break; ++ } ++ ++ return MCDisassembler::Success; ++} ++static DecodeStatus DecodeLASX256Mem(MCInst &Inst, unsigned Insn, ++ uint64_t Address, const void *Decoder) { ++ int Offset = SignExtend32<12>(fieldFromInstruction(Insn, 10, 12)); ++ unsigned Reg = fieldFromInstruction(Insn, 0, 5); ++ unsigned Base = fieldFromInstruction(Insn, 5, 5); ++ Reg = getReg(Decoder, LoongArch::LASX256BRegClassID, Reg); ++ Base = getReg(Decoder, LoongArch::GPR32RegClassID, Base); ++ ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ Inst.addOperand(MCOperand::createReg(Base)); ++ ++ Inst.addOperand(MCOperand::createImm(Offset)); ++ ++ return MCDisassembler::Success; ++} ++ ++static DecodeStatus DecodeLASX256memstl(MCInst &Inst, unsigned Insn, ++ uint64_t Address, const void *Decoder) { ++ int Offset = SignExtend32<8>(fieldFromInstruction(Insn, 10, 8)); ++ unsigned Reg = fieldFromInstruction(Insn, 0, 5); ++ unsigned Base = fieldFromInstruction(Insn, 5, 5); ++ Reg = getReg(Decoder, LoongArch::LASX256BRegClassID, Reg); ++ Base = getReg(Decoder, LoongArch::GPR32RegClassID, Base); ++ unsigned idx; ++ ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ Inst.addOperand(MCOperand::createReg(Base)); ++ ++ switch (Inst.getOpcode()) { ++ default: ++ assert(false && "Unexpected instruction"); + return MCDisassembler::Fail; +- Inst.addOperand(MCOperand::createReg(LoongArch::FCSR0 + RegNo)); ++ break; ++ case LoongArch::XVSTELM_B: ++ Inst.addOperand(MCOperand::createImm(Offset)); ++ idx = fieldFromInstruction(Insn, 18, 5); ++ Inst.addOperand(MCOperand::createImm(idx)); ++ break; ++ case LoongArch::XVSTELM_H: ++ Inst.addOperand(MCOperand::createImm(Offset * 2)); ++ idx = fieldFromInstruction(Insn, 18, 4); ++ Inst.addOperand(MCOperand::createImm(idx)); ++ break; ++ case LoongArch::XVSTELM_W: ++ Inst.addOperand(MCOperand::createImm(Offset * 4)); ++ idx = fieldFromInstruction(Insn, 18, 3); ++ Inst.addOperand(MCOperand::createImm(idx)); ++ break; ++ case LoongArch::XVSTELM_D: ++ Inst.addOperand(MCOperand::createImm(Offset * 8)); ++ idx = fieldFromInstruction(Insn, 18, 2); ++ Inst.addOperand(MCOperand::createImm(idx)); ++ break; ++ } ++ + return MCDisassembler::Success; + } + +-static DecodeStatus DecodeLSX128RegisterClass(MCInst &Inst, uint64_t RegNo, +- uint64_t Address, +- const MCDisassembler *Decoder) { +- if (RegNo >= 32) ++static DecodeStatus DecodeLASX256memlsl(MCInst &Inst, unsigned Insn, ++ uint64_t Address, const void *Decoder) { ++ ++ int Offset; ++ unsigned Reg, Base; ++ switch (Inst.getOpcode()) { ++ default: ++ assert(false && "Unexpected instruction"); + return MCDisassembler::Fail; +- Inst.addOperand(MCOperand::createReg(LoongArch::VR0 + RegNo)); ++ break; ++ case LoongArch::XVLDREPL_B: ++ ++ Offset = SignExtend32<12>(fieldFromInstruction(Insn, 10, 12)); ++ Reg = fieldFromInstruction(Insn, 0, 5); ++ Base = fieldFromInstruction(Insn, 5, 5); ++ Reg = getReg(Decoder, LoongArch::LASX256BRegClassID, Reg); ++ Base = getReg(Decoder, LoongArch::GPR32RegClassID, Base); ++ ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ Inst.addOperand(MCOperand::createReg(Base)); ++ ++ Inst.addOperand(MCOperand::createImm(Offset)); ++ break; ++ case LoongArch::XVLDREPL_H: ++ ++ Offset = SignExtend32<11>(fieldFromInstruction(Insn, 10, 11)); ++ Reg = fieldFromInstruction(Insn, 0, 5); ++ Base = fieldFromInstruction(Insn, 5, 5); ++ Reg = getReg(Decoder, LoongArch::LASX256HRegClassID, Reg); ++ Base = getReg(Decoder, LoongArch::GPR32RegClassID, Base); ++ ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ Inst.addOperand(MCOperand::createReg(Base)); ++ Inst.addOperand(MCOperand::createImm(Offset * 2)); ++ break; ++ case LoongArch::XVLDREPL_W: ++ ++ Offset = SignExtend32<10>(fieldFromInstruction(Insn, 10, 10)); ++ Reg = fieldFromInstruction(Insn, 0, 5); ++ Base = fieldFromInstruction(Insn, 5, 5); ++ Reg = getReg(Decoder, LoongArch::LASX256WRegClassID, Reg); ++ Base = getReg(Decoder, LoongArch::GPR32RegClassID, Base); ++ ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ Inst.addOperand(MCOperand::createReg(Base)); ++ Inst.addOperand(MCOperand::createImm(Offset * 4)); ++ break; ++ case LoongArch::XVLDREPL_D: ++ ++ Offset = SignExtend32<9>(fieldFromInstruction(Insn, 10, 9)); ++ Reg = fieldFromInstruction(Insn, 0, 5); ++ Base = fieldFromInstruction(Insn, 5, 5); ++ Reg = getReg(Decoder, LoongArch::LASX256WRegClassID, Reg); ++ Base = getReg(Decoder, LoongArch::GPR32RegClassID, Base); ++ ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ Inst.addOperand(MCOperand::createReg(Base)); ++ Inst.addOperand(MCOperand::createImm(Offset * 8)); ++ break; ++ } ++ + return MCDisassembler::Success; + } + +-static DecodeStatus DecodeLASX256RegisterClass(MCInst &Inst, uint64_t RegNo, ++static DecodeStatus DecodeFMem(MCInst &Inst, ++ unsigned Insn, ++ uint64_t Address, ++ const void *Decoder) { ++ int Offset = SignExtend32<12>((Insn >> 10) & 0xffff); ++ unsigned Reg = fieldFromInstruction(Insn, 0, 5); ++ unsigned Base = fieldFromInstruction(Insn, 5, 5); ++ Reg = getReg(Decoder, LoongArch::FGR64RegClassID, Reg); ++ Base = getReg(Decoder, LoongArch::GPR32RegClassID, Base); ++ ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ Inst.addOperand(MCOperand::createReg(Base)); ++ Inst.addOperand(MCOperand::createImm(Offset)); ++ ++ return MCDisassembler::Success; ++} ++ ++static DecodeStatus DecodeLSX128BRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, +- const MCDisassembler *Decoder) { +- if (RegNo >= 32) ++ const void *Decoder) { ++ if (RegNo > 31) + return MCDisassembler::Fail; +- Inst.addOperand(MCOperand::createReg(LoongArch::XR0 + RegNo)); ++ unsigned Reg = getReg(Decoder, LoongArch::LSX128BRegClassID, RegNo); ++ Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; + } + +-static DecodeStatus DecodeSCRRegisterClass(MCInst &Inst, uint64_t RegNo, +- uint64_t Address, +- const MCDisassembler *Decoder) { +- if (RegNo >= 4) ++static DecodeStatus DecodeLSX128HRegisterClass(MCInst &Inst, unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder) { ++ if (RegNo > 31) ++ return MCDisassembler::Fail; ++ unsigned Reg = getReg(Decoder, LoongArch::LSX128HRegClassID, RegNo); ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ return MCDisassembler::Success; ++} ++ ++static DecodeStatus DecodeLSX128WRegisterClass(MCInst &Inst, unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder) { ++ if (RegNo > 31) + return MCDisassembler::Fail; +- Inst.addOperand(MCOperand::createReg(LoongArch::SCR0 + RegNo)); ++ unsigned Reg = getReg(Decoder, LoongArch::LSX128WRegClassID, RegNo); ++ Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; + } + +-template +-static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm, +- int64_t Address, +- const MCDisassembler *Decoder) { +- assert(isUInt(Imm) && "Invalid immediate"); +- Inst.addOperand(MCOperand::createImm(Imm + P)); ++static DecodeStatus DecodeLSX128DRegisterClass(MCInst &Inst, unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder) { ++ if (RegNo > 31) ++ return MCDisassembler::Fail; ++ unsigned Reg = getReg(Decoder, LoongArch::LSX128DRegClassID, RegNo); ++ Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; + } + +-template +-static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, +- int64_t Address, +- const MCDisassembler *Decoder) { +- assert(isUInt(Imm) && "Invalid immediate"); +- // Shift left Imm bits, then sign-extend the number in the bottom +- // bits. +- Inst.addOperand(MCOperand::createImm(SignExtend64(Imm << S))); ++static DecodeStatus DecodeLASX256BRegisterClass(MCInst &Inst, unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder) { ++ if (RegNo > 31) ++ return MCDisassembler::Fail; ++ unsigned Reg = getReg(Decoder, LoongArch::LASX256BRegClassID, RegNo); ++ Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; + } + +-#include "LoongArchGenDisassemblerTables.inc" ++static DecodeStatus DecodeLASX256HRegisterClass(MCInst &Inst, unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder) { ++ if (RegNo > 31) ++ return MCDisassembler::Fail; ++ unsigned Reg = getReg(Decoder, LoongArch::LASX256HRegClassID, RegNo); ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ return MCDisassembler::Success; ++} + +-DecodeStatus LoongArchDisassembler::getInstruction(MCInst &MI, uint64_t &Size, +- ArrayRef Bytes, +- uint64_t Address, +- raw_ostream &CS) const { +- uint32_t Insn; +- DecodeStatus Result; ++static DecodeStatus DecodeLASX256WRegisterClass(MCInst &Inst, unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder) { ++ if (RegNo > 31) ++ return MCDisassembler::Fail; ++ unsigned Reg = getReg(Decoder, LoongArch::LASX256WRegClassID, RegNo); ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ return MCDisassembler::Success; ++} + +- // We want to read exactly 4 bytes of data because all LoongArch instructions +- // are fixed 32 bits. +- if (Bytes.size() < 4) { +- Size = 0; ++static DecodeStatus DecodeLASX256DRegisterClass(MCInst &Inst, unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder) { ++ if (RegNo > 31) + return MCDisassembler::Fail; ++ unsigned Reg = getReg(Decoder, LoongArch::LASX256DRegClassID, RegNo); ++ Inst.addOperand(MCOperand::createReg(Reg)); ++ return MCDisassembler::Success; ++} ++ ++static DecodeStatus DecodeBranchTarget(MCInst &Inst, ++ unsigned Offset, ++ uint64_t Address, ++ const void *Decoder) { ++ int32_t BranchOffset; ++ // Similar to LoongArchAsmParser::processInstruction, decode the branch target ++ // for different instructions. ++ switch (Inst.getOpcode()) { ++ default: ++ llvm_unreachable(""); ++ case LoongArch::BEQ: ++ case LoongArch::BNE: ++ case LoongArch::BLT: ++ case LoongArch::BGE: ++ case LoongArch::BLTU: ++ case LoongArch::BGEU: ++ BranchOffset = (SignExtend32<16>(Offset) * 4); ++ break; ++ case LoongArch::BEQZ: ++ case LoongArch::BNEZ: ++ case LoongArch::BCEQZ: ++ case LoongArch::BCNEZ: ++ BranchOffset = (SignExtend32<21>(Offset) * 4); ++ break; ++ case LoongArch::B: ++ case LoongArch::BL: ++ BranchOffset = (SignExtend32<26>(Offset) * 4); ++ break; + } ++ Inst.addOperand(MCOperand::createImm(BranchOffset)); ++ return MCDisassembler::Success; ++} + +- Insn = support::endian::read32le(Bytes.data()); +- // Calling the auto-generated decoder function. +- Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI); +- Size = 4; ++static DecodeStatus DecodeJumpTarget(MCInst &Inst, ++ unsigned Insn, ++ uint64_t Address, ++ const void *Decoder) { ++ unsigned hi10 = fieldFromInstruction(Insn, 0, 10); ++ unsigned lo16 = fieldFromInstruction(Insn, 10, 16); ++ int32_t JumpOffset = SignExtend32<28>((hi10 << 16 | lo16) << 2); ++ Inst.addOperand(MCOperand::createImm(JumpOffset)); ++ return MCDisassembler::Success; ++} + +- return Result; ++template ++static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value, ++ uint64_t Address, ++ const void *Decoder) { ++ Value &= ((1 << Bits) - 1); ++ Value *= Scale; ++ Inst.addOperand(MCOperand::createImm(Value + Offset)); ++ return MCDisassembler::Success; ++} ++ ++template ++static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value, ++ uint64_t Address, ++ const void *Decoder) { ++ int32_t Imm = SignExtend32(Value) * ScaleBy; ++ Inst.addOperand(MCOperand::createImm(Imm + Offset)); ++ return MCDisassembler::Success; + } +diff --git a/llvm/lib/Target/LoongArch/LoongArch.h b/llvm/lib/Target/LoongArch/LoongArch.h +index 09ca089c9..73fd4a628 100644 +--- a/llvm/lib/Target/LoongArch/LoongArch.h ++++ b/llvm/lib/Target/LoongArch/LoongArch.h +@@ -1,4 +1,4 @@ +-//===-- LoongArch.h - Top-level interface for LoongArch ---------*- C++ -*-===// ++//===-- LoongArch.h - Top-level interface for LoongArch representation ----*- C++ -*-===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -6,41 +6,32 @@ + // + //===----------------------------------------------------------------------===// + // +-// This file contains the entry points for global functions defined in the LLVM +-// LoongArch back-end. ++// This file contains the entry points for global functions defined in ++// the LLVM LoongArch back-end. + // + //===----------------------------------------------------------------------===// + + #ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCH_H + #define LLVM_LIB_TARGET_LOONGARCH_LOONGARCH_H + +-#include "MCTargetDesc/LoongArchBaseInfo.h" ++#include "MCTargetDesc/LoongArchMCTargetDesc.h" + #include "llvm/Target/TargetMachine.h" + + namespace llvm { +-class AsmPrinter; +-class FunctionPass; +-class LoongArchTargetMachine; +-class MCInst; +-class MCOperand; +-class MachineInstr; +-class MachineOperand; +-class PassRegistry; ++ class LoongArchTargetMachine; ++ class ModulePass; ++ class FunctionPass; ++ class LoongArchSubtarget; ++ class LoongArchTargetMachine; ++ class InstructionSelector; ++ class PassRegistry; + +-bool lowerLoongArchMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, +- AsmPrinter &AP); +-bool lowerLoongArchMachineOperandToMCOperand(const MachineOperand &MO, +- MCOperand &MCOp, +- const AsmPrinter &AP); ++ FunctionPass *createLoongArchModuleISelDagPass(); ++ FunctionPass *createLoongArchOptimizePICCallPass(); ++ FunctionPass *createLoongArchBranchExpansion(); ++ FunctionPass *createLoongArchExpandPseudoPass(); + +-FunctionPass *createLoongArchExpandAtomicPseudoPass(); +-FunctionPass *createLoongArchISelDag(LoongArchTargetMachine &TM); +-FunctionPass *createLoongArchPreRAExpandPseudoPass(); +-FunctionPass *createLoongArchExpandPseudoPass(); +-void initializeLoongArchDAGToDAGISelPass(PassRegistry &); +-void initializeLoongArchExpandAtomicPseudoPass(PassRegistry &); +-void initializeLoongArchPreRAExpandPseudoPass(PassRegistry &); +-void initializeLoongArchExpandPseudoPass(PassRegistry &); +-} // end namespace llvm ++ void initializeLoongArchBranchExpansionPass(PassRegistry &); ++} // end namespace llvm; + +-#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCH_H ++#endif +diff --git a/llvm/lib/Target/LoongArch/LoongArch.td b/llvm/lib/Target/LoongArch/LoongArch.td +index c2a669931..f38592eba 100644 +--- a/llvm/lib/Target/LoongArch/LoongArch.td ++++ b/llvm/lib/Target/LoongArch/LoongArch.td +@@ -1,180 +1,119 @@ +-//===-- LoongArch.td - Describe the LoongArch Target -------*- tablegen -*-===// ++//===-- LoongArch.td - Describe the LoongArch Target Machine ---------*- tablegen -*-===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. + // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + // + //===----------------------------------------------------------------------===// +- +-include "llvm/Target/Target.td" ++// This is the top level entry point for the LoongArch target. ++//===----------------------------------------------------------------------===// + + //===----------------------------------------------------------------------===// +-// LoongArch subtarget features and instruction predicates. ++// Target-independent interfaces + //===----------------------------------------------------------------------===// + +-// LoongArch is divided into two versions, the 32-bit version (LA32) and the +-// 64-bit version (LA64). +-def Feature64Bit +- : SubtargetFeature<"64bit", "HasLA64", "true", +- "LA64 Basic Integer and Privilege Instruction Set">; +-def Feature32Bit +- : SubtargetFeature<"32bit", "HasLA32", "true", +- "LA32 Basic Integer and Privilege Instruction Set">; +-def IsLA64 +- : Predicate<"Subtarget->is64Bit()">, +- AssemblerPredicate<(all_of Feature64Bit), +- "LA64 Basic Integer and Privilege Instruction Set">; +-def IsLA32 +- : Predicate<"!Subtarget->is64Bit()">, +- AssemblerPredicate<(all_of(not Feature64Bit)), +- "LA32 Basic Integer and Privilege Instruction Set">; +- +-defvar LA32 = DefaultMode; +-def LA64 : HwMode<"+64bit", [IsLA64]>; +- +-// Single Precision floating point +-def FeatureBasicF +- : SubtargetFeature<"f", "HasBasicF", "true", +- "'F' (Single-Precision Floating-Point)">; +-def HasBasicF : Predicate<"Subtarget->hasBasicF()">; +- +-// Double Precision floating point +-def FeatureBasicD +- : SubtargetFeature<"d", "HasBasicD", "true", +- "'D' (Double-Precision Floating-Point)", +- [FeatureBasicF]>; +-def HasBasicD : Predicate<"Subtarget->hasBasicD()">; +- +-// Loongson SIMD eXtension (LSX) +-def FeatureExtLSX +- : SubtargetFeature<"lsx", "HasExtLSX", "true", +- "'LSX' (Loongson SIMD Extension)", [FeatureBasicD]>; +-def HasExtLSX : Predicate<"Subtarget->hasExtLSX()">; +- +-// Loongson Advanced SIMD eXtension (LASX) +-def FeatureExtLASX +- : SubtargetFeature<"lasx", "HasExtLASX", "true", +- "'LASX' (Loongson Advanced SIMD Extension)", +- [FeatureExtLSX]>; +-def HasExtLASX : Predicate<"Subtarget->hasExtLASX()">; +- +-// Loongson VirtualiZation (LVZ) +-def FeatureExtLVZ +- : SubtargetFeature<"lvz", "HasExtLVZ", "true", +- "'LVZ' (Loongson Virtualization Extension)">; +-def HasExtLVZ : Predicate<"Subtarget->hasExtLVZ()">; +- +-// Loongson Binary Translation (LBT) +-def FeatureExtLBT +- : SubtargetFeature<"lbt", "HasExtLBT", "true", +- "'LBT' (Loongson Binary Translation Extension)">; +-def HasExtLBT : Predicate<"Subtarget->hasExtLBT()">; +- +-// Expand la.global as la.pcrel +-def LaGlobalWithPcrel +- : SubtargetFeature<"la-global-with-pcrel", "HasLaGlobalWithPcrel", "true", +- "Expand la.global as la.pcrel">; +-def HasLaGlobalWithPcrel +- : Predicate<"Subtarget->hasLaGlobalWithPcrel()">, +- AssemblerPredicate<(all_of LaGlobalWithPcrel), +- "Expand la.global as la.pcrel">; +- +-// Expand la.global as la.abs +-def LaGlobalWithAbs +- : SubtargetFeature<"la-global-with-abs", "HasLaGlobalWithAbs", "true", +- "Expand la.global as la.abs">; +-def HasLaGlobalWithAbs +- : Predicate<"Subtarget->hasLaGlobalWithAbs()">, +- AssemblerPredicate<(all_of LaGlobalWithAbs), +- "Expand la.global as la.abs">; +- +-// Expand la.local as la.abs +-def LaLocalWithAbs +- : SubtargetFeature<"la-local-with-abs", "HasLaLocalWithAbs", "true", +- "Expand la.local as la.abs">; +-def HasLaLocalWithAbs +- : Predicate<"Subtarget->hasLaLocalWithAbs()">, +- AssemblerPredicate<(all_of LaLocalWithAbs), +- "Expand la.local as la.abs">; +- +-// Unaligned memory access +-def FeatureUAL +- : SubtargetFeature<"ual", "HasUAL", "true", +- "Allow memory accesses to be unaligned">; +- +-def FeatureRelax +- : SubtargetFeature<"relax", "HasLinkerRelax", "true", +- "Enable Linker relaxation">; +- +-// Experimental auto vectorization +-def FeatureAutoVec +- : SubtargetFeature<"auto-vec", "HasExpAutoVec", "true", +- "Experimental auto vectorization">; ++include "llvm/Target/Target.td" + +-// Floating point approximation operation +-def FeatureFrecipe +- : SubtargetFeature<"frecipe", "HasFrecipe", "true", +- "Support frecipe.{s/d} and frsqrte.{s/d} instructions.">; +-def HasFrecipe : Predicate<"Subtarget->hasFrecipe()">; ++// The overall idea of the PredicateControl class is to chop the Predicates list ++// into subsets that are usually overridden independently. This allows ++// subclasses to partially override the predicates of their superclasses without ++// having to re-add all the existing predicates. ++class PredicateControl { ++ // Predicates for the encoding scheme in use such as HasStdEnc ++ list EncodingPredicates = []; ++ // Predicates for the GPR size such as is64Bit ++ list GPRPredicates = []; ++ // Predicates for the FGR size and layout such as IsFP64bit ++ list FGRPredicates = []; ++ // Predicates for the instruction group membership such as ISA's. ++ list InsnPredicates = []; ++ // Predicate for the ISA extension that an instruction belongs to. ++ list ExtPredicate = []; ++ // Predicate for marking the instruction as usable in hard-float mode only. ++ list HardFloatPredicate = []; ++ // Predicates for anything else ++ list AdditionalPredicates = []; ++ list Predicates = !listconcat(EncodingPredicates, ++ GPRPredicates, ++ FGRPredicates, ++ InsnPredicates, ++ HardFloatPredicate, ++ ExtPredicate, ++ AdditionalPredicates); ++} + ++// Like Requires<> but for the AdditionalPredicates list ++class AdditionalRequires preds> { ++ list AdditionalPredicates = preds; ++} + + //===----------------------------------------------------------------------===// +-// Registers, instruction descriptions ... ++// LoongArch Subtarget features // ++//===----------------------------------------------------------------------===// ++ ++def FeatureFP64Bit : SubtargetFeature<"fp64", "IsFP64bit", "true", ++ "Support 64-bit FP registers">; ++def FeatureSingleFloat : SubtargetFeature<"single-float", "IsSingleFloat", ++ "true", "Only supports single precision float">; ++def FeatureSoftFloat : SubtargetFeature<"soft-float", "IsSoftFloat", "true", ++ "Does not support floating point instructions">; ++def Feature64Bit : SubtargetFeature<"64bit", "HasLA64", "true", ++ "Support LA64 ISA", ++ [FeatureFP64Bit]>; ++def FeatureLSX : SubtargetFeature<"lsx", "HasLSX", "true", "Support LSX">; ++ ++def FeatureLASX : SubtargetFeature<"lasx", "HasLASX", "true", "Support LASX", [FeatureLSX]>; ++ ++def FeatureUnalignedAccess ++ : SubtargetFeature<"unaligned-access", "UnalignedAccess", "true", ++ "Allow all unaligned memory access">; ++//===----------------------------------------------------------------------===// ++// Register File, Calling Conv, Instruction Descriptions + //===----------------------------------------------------------------------===// + + include "LoongArchRegisterInfo.td" +-include "LoongArchCallingConv.td" + include "LoongArchInstrInfo.td" ++include "LoongArchCallingConv.td" ++ ++def LoongArchInstrInfo : InstrInfo; ++ ++// Floating point approximation operation ++def FeatureFrecipe ++ : SubtargetFeature<"frecipe", "HasFrecipe", "true", ++ "Support frecipe.{s/d} and frsqrte.{s/d} instructions.">; ++ + + //===----------------------------------------------------------------------===// + // LoongArch processors supported. + //===----------------------------------------------------------------------===// + +-def : ProcessorModel<"generic-la32", NoSchedModel, [Feature32Bit]>; +-def : ProcessorModel<"generic-la64", NoSchedModel, [Feature64Bit, FeatureUAL]>; +- +-// Generic 64-bit processor with double-precision floating-point support. + def : ProcessorModel<"loongarch64", NoSchedModel, [Feature64Bit, +- FeatureUAL, +- FeatureBasicD]>; ++ FeatureUnalignedAccess]>; + +-// Support generic for compatibility with other targets. The triple will be used +-// to change to the appropriate la32/la64 version. +-def : ProcessorModel<"generic", NoSchedModel, []>; ++def : ProcessorModel<"la264", NoSchedModel, [Feature64Bit]>; + +-def : ProcessorModel<"la464", NoSchedModel, [Feature64Bit, +- FeatureUAL, +- FeatureExtLASX, +- FeatureExtLVZ, +- FeatureExtLBT]>; ++def : ProcessorModel<"la364", NoSchedModel, [Feature64Bit]>; + +-//===----------------------------------------------------------------------===// +-// Define the LoongArch target. +-//===----------------------------------------------------------------------===// ++def : ProcessorModel<"la464", NoSchedModel, ++ [Feature64Bit, FeatureUnalignedAccess, FeatureLASX]>; + +-def LoongArchInstrInfo : InstrInfo { +- let guessInstructionProperties = 0; +-} ++def : ProcessorModel<"la664", NoSchedModel, ++ [Feature64Bit, FeatureUnalignedAccess, FeatureLASX]>; + + def LoongArchAsmParser : AsmParser { +- let ShouldEmitMatchRegisterAltName = 1; +- let AllowDuplicateRegisterNames = 1; ++ let ShouldEmitMatchRegisterName = 0; + } + + def LoongArchAsmParserVariant : AsmParserVariant { + int Variant = 0; ++ + // Recognize hard coded registers. + string RegisterPrefix = "$"; + } + +-def LoongArchAsmWriter : AsmWriter { +- int PassSubtarget = 1; +-} +- + def LoongArch : Target { + let InstructionSet = LoongArchInstrInfo; + let AssemblyParsers = [LoongArchAsmParser]; + let AssemblyParserVariants = [LoongArchAsmParserVariant]; +- let AssemblyWriters = [LoongArchAsmWriter]; + let AllowRegisterRenaming = 1; + } +diff --git a/llvm/lib/Target/LoongArch/LoongArch32InstrInfo.td b/llvm/lib/Target/LoongArch/LoongArch32InstrInfo.td +new file mode 100644 +index 000000000..a70d6bf15 +--- /dev/null ++++ b/llvm/lib/Target/LoongArch/LoongArch32InstrInfo.td +@@ -0,0 +1,743 @@ ++//===- LoongArch32InstrInfo.td - Target Description for LoongArch Target -*- tablegen -*-=// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++// ++// This file describes LoongArch32 instructions. ++// ++//===----------------------------------------------------------------------===// ++ ++//===---------------------------------------------------------------------===/ ++// Instruction Definitions. ++//===---------------------------------------------------------------------===/ ++ ++let DecoderNamespace = "LoongArch32" in { ++ /// ++ /// R2 ++ /// ++ def CLO_W : Count1<"clo.w", GPR32Opnd, ctlz>, R2I<0b00100>; ++ def CLZ_W : Int_Reg2<"clz.w", GPR32Opnd, ctlz>, R2I<0b00101>; ++ def CTO_W : Count1<"cto.w", GPR32Opnd, cttz>, R2I<0b00110>; ++ def CTZ_W : Int_Reg2<"ctz.w", GPR32Opnd, cttz>, R2I<0b00111>; ++ ++ def REVB_2H : Int_Reg2<"revb.2h", GPR32Opnd>, R2I<0b01100>;//see below bswap pattern ++ ++ def BITREV_4B : Int_Reg2<"bitrev.4b", GPR32Opnd>, R2I<0b10010>; ++ def BITREV_W : Int_Reg2<"bitrev.w", GPR32Opnd, bitreverse>, R2I<0b10100>; ++ ++ let isCodeGenOnly = 1 in { ++ def EXT_W_H32 : SignExtInReg<"ext.w.h", GPR32Opnd, i16>, R2I<0b10110>; ++ def EXT_W_B32 : SignExtInReg<"ext.w.b", GPR32Opnd, i8>, R2I<0b10111>; ++ ++ } ++ ++ def CPUCFG : Int_Reg2<"cpucfg", GPR32Opnd, int_loongarch_cpucfg>, R2I<0b11011>; ++ def RDTIMEL_W32 : Int_Reg2_Rdtime<"rdtimel.w", GPR32Opnd>, R2I<0b11000>; ++ def RDTIMEH_W32 : Int_Reg2_Rdtime<"rdtimeh.w", GPR32Opnd>, R2I<0b11001>; ++ ++ /// ++ /// R3 ++ /// ++ def ADD_W : Int_Reg3<"add.w", GPR32Opnd, add>, R3I<0b0100000>; ++ def SUB_W : Int_Reg3<"sub.w", GPR32Opnd, sub>, R3I<0b0100010>; ++ ++ let isCodeGenOnly = 1 in { ++ def SLT32 : SetCC_R<"slt", GPR32Opnd, setlt>, R3I<0b0100100>; ++ def SLTU32 : SetCC_R<"sltu", GPR32Opnd, setult>, R3I<0b0100101>; ++ def MASKEQZ32 : Int_Reg3<"maskeqz", GPR32Opnd>, R3I<0b0100110>;//see below patterns ++ def MASKNEZ32 : Int_Reg3<"masknez", GPR32Opnd>, R3I<0b0100111>;//see below patterns ++ ++ def NOR32 : Nor<"nor", GPR32Opnd>, R3I<0b0101000>; ++ def AND32 : Int_Reg3<"and", GPR32Opnd, and>, R3I<0b0101001>; ++ def OR32 : Int_Reg3<"or", GPR32Opnd, or>, R3I<0b0101010>; ++ def XOR32 : Int_Reg3<"xor", GPR32Opnd, xor>, R3I<0b0101011>; ++ def ANDN32 : Int_Reg3<"andn", GPR32Opnd>, R3I<0b0101101>; ++ def ORN32 : Int_Reg3<"orn", GPR32Opnd>, R3I<0b0101100>; ++ } ++ ++ def SLL_W : Shift_Var<"sll.w", GPR32Opnd, shl>, R3I<0b0101110>; ++ def SRL_W : Shift_Var<"srl.w", GPR32Opnd, srl>, R3I<0b0101111>; ++ def SRA_W : Shift_Var<"sra.w", GPR32Opnd, sra>, R3I<0b0110000>; ++ def ROTR_W: Shift_Var<"rotr.w", GPR32Opnd, rotr>, R3I<0b0110110>; ++ ++ def MUL_W : Int_Reg3<"mul.w", GPR32Opnd, mul>, R3I<0b0111000>; ++ def MULH_W : Int_Reg3<"mulh.w", GPR32Opnd, mulhs>, R3I<0b0111001>; ++ def MULH_WU : Int_Reg3<"mulh.wu", GPR32Opnd, mulhu>, R3I<0b0111010>; ++ ++let usesCustomInserter = 1 in { ++ def DIV_W : Int_Reg3<"div.w", GPR32Opnd, sdiv>, R3I<0b1000000>; ++ def MOD_W : Int_Reg3<"mod.w", GPR32Opnd, srem>, R3I<0b1000001>; ++ def DIV_WU : Int_Reg3<"div.wu", GPR32Opnd, udiv>, R3I<0b1000010>; ++ def MOD_WU : Int_Reg3<"mod.wu", GPR32Opnd, urem>, R3I<0b1000011>; ++} ++ ++ def CRC_W_B_W : Int_Reg3<"crc.w.b.w", GPR32Opnd, int_loongarch_crc_w_b_w>, R3I<0b1001000>; ++ def CRC_W_H_W : Int_Reg3<"crc.w.h.w", GPR32Opnd, int_loongarch_crc_w_h_w>, R3I<0b1001001>; ++ def CRC_W_W_W : Int_Reg3<"crc.w.w.w", GPR32Opnd, int_loongarch_crc_w_w_w>, R3I<0b1001010>; ++ def CRCC_W_B_W : Int_Reg3<"crcc.w.b.w", GPR32Opnd, int_loongarch_crcc_w_b_w>, R3I<0b1001100>; ++ def CRCC_W_H_W : Int_Reg3<"crcc.w.h.w", GPR32Opnd, int_loongarch_crcc_w_h_w>, R3I<0b1001101>; ++ def CRCC_W_W_W : Int_Reg3<"crcc.w.w.w", GPR32Opnd, int_loongarch_crcc_w_w_w>, R3I<0b1001110>; ++ /// ++ /// SLLI ++ /// ++ def SLLI_W : Shift_Imm32<"slli.w", GPR32Opnd, shl>, R2_IMM5<0b00>; ++ def SRLI_W : Shift_Imm32<"srli.w", GPR32Opnd, srl>, R2_IMM5<0b01>; ++ def SRAI_W : Shift_Imm32<"srai.w", GPR32Opnd, sra>, R2_IMM5<0b10>; ++ def ROTRI_W : Shift_Imm32<"rotri.w", GPR32Opnd, rotr>, R2_IMM5<0b11>; ++ /// ++ /// Misc ++ /// ++ def ALSL_W : Reg3_Sa<"alsl.w", GPR32Opnd, uimm2_plus1>, R3_SA2<0b00010> { ++ let Pattern = [(set GPR32Opnd:$rd, ++ (add GPR32Opnd:$rk, (shl GPR32Opnd:$rj, immZExt2Alsl:$sa)))]; ++ } ++ def BYTEPICK_W : Reg3_Sa<"bytepick.w", GPR32Opnd, uimm2>, R3_SA2<0b00100>;//pattern:[] ++ ++ def BREAK : Code15<"break", int_loongarch_break>, CODE15<0b1010100>; ++ def SYSCALL : Code15<"syscall", int_loongarch_syscall>, CODE15<0b1010110>; ++ def TRAP : TrapBase; ++ ++ def BSTRINS_W : InsBase_32<"bstrins.w", GPR32Opnd, uimm5, LoongArchBstrins>, ++ INSERT_BIT32<0>; ++ def BSTRPICK_W : PickBase_32<"bstrpick.w", GPR32Opnd, uimm5, LoongArchBstrpick>, ++ INSERT_BIT32<1>; ++ ++ /// ++ /// R2_IMM12 ++ /// ++ let isCodeGenOnly = 1 in { ++ def SLTI32 : SetCC_I<"slti", GPR32Opnd, simm12_32>, R2_IMM12<0b000>; //PatFrag ++ def SLTUI32 : SetCC_I<"sltui", GPR32Opnd, simm12_32>, R2_IMM12<0b001>; //PatFrag ++ } ++ def ADDI_W : Int_Reg2_Imm12<"addi.w", GPR32Opnd, simm12_32, add>, R2_IMM12<0b010>; ++ ++ let isCodeGenOnly = 1 in { ++ def ANDI32 : Int_Reg2_Imm12<"andi", GPR32Opnd, uimm12_32, and>, R2_IMM12<0b101>; ++ def ORI32 : Int_Reg2_Imm12<"ori", GPR32Opnd, uimm12_32, or>, R2_IMM12<0b110>; ++ def XORI32 : Int_Reg2_Imm12<"xori", GPR32Opnd, uimm12_32, xor>, R2_IMM12<0b111>; ++ } ++ ++ /// ++ /// Privilege Instructions ++ /// ++ def CSRRD32 : CSR<"csrrd", GPR32Opnd, uimm14_32, int_loongarch_csrrd_w>, R1_CSR<0b0000000000100>; ++ def CSRWR32 : CSRW<"csrwr", GPR32Opnd, uimm14_32, int_loongarch_csrwr_w>, R1_CSR<0b0000100000100>; ++ def CSRXCHG32 : CSRX<"csrxchg", GPR32Opnd, uimm14_32, int_loongarch_csrxchg_w>, R2_CSR<0b00000100>; ++ def IOCSRRD_B32 : Int_Reg2<"iocsrrd.b", GPR32Opnd, int_loongarch_iocsrrd_b>, R2P<0b000>; ++ def IOCSRRD_H32 : Int_Reg2<"iocsrrd.h", GPR32Opnd, int_loongarch_iocsrrd_h>, R2P<0b001>; ++ def IOCSRRD_W32 : Int_Reg2<"iocsrrd.w", GPR32Opnd, int_loongarch_iocsrrd_w>, R2P<0b010>; ++ def IOCSRWR_B32 : Int_Reg2_Iocsrwr<"iocsrwr.b", GPR32Opnd, GPR32Opnd, int_loongarch_iocsrwr_b>, R2P<0b100>; ++ def IOCSRWR_H32 : Int_Reg2_Iocsrwr<"iocsrwr.h", GPR32Opnd, GPR32Opnd, int_loongarch_iocsrwr_h>, R2P<0b101>; ++ def IOCSRWR_W32 : Int_Reg2_Iocsrwr<"iocsrwr.w", GPR32Opnd, GPR32Opnd, int_loongarch_iocsrwr_w>, R2P<0b110>; ++ def CACOP32 : CAC<"cacop", GPR32Opnd, simm12_32, int_loongarch_cacop_w>, R1_CACHE; ++ def LDDIR32 : LEVEL<"lddir", GPR32Opnd>, R2_LEVEL<0b00000110010000>; ++ def LDPTE32 : SEQ<"ldpte", GPR32Opnd>, R1_SEQ<0b00000110010001>; ++ ++ //def WAIT : Wait<"wait">; ++ // ++ //def IOCSRRD_D : R2P<0b011>, Int_Reg2<"iocsrrd.d", GPR32Opnd>; ++ //def IOCSRWR_D : R2P<0b111>, Int_Reg2<"iocsrwr.d", GPR32Opnd>; ++ // ++ //def TLBINV : IMM32<0b001000>, OP32<"tlbinv">; ++ //def TLBFLUSH : IMM32<0b001001>, OP32<"tlbflush">; ++ //def TLBP : IMM32<0b001010>, OP32<"tlbp">; ++ //def TLBR : IMM32<0b001011>, OP32<"tlbr">; ++ //def TLBWI : IMM32<0b001100>, OP32<"tlbwi">; ++ //def TLBWR : IMM32<0b001101>, OP32<"tlbwr">; ++ ++ /// ++ /// R1_IMM20 ++ /// ++ let isCodeGenOnly = 1 in { ++ def LU12I_W32 : SI20<"lu12i.w", GPR32Opnd, simm20_32>, R1_SI20<0b0001010>; ++ def PCADDI32 : SI20<"pcaddi", GPR32Opnd, simm20_32>, R1_SI20<0b0001100>; ++ def PCALAU12I32 : SI20<"pcalau12i", GPR32Opnd, simm20_32>, R1_SI20<0b0001101>; ++ def PCADDU12I32 : SI20<"pcaddu12i", GPR32Opnd, simm20_32>, R1_SI20<0b0001110>; ++ } ++ ++ let isCodeGenOnly = 1 in { ++ def BEQZ32 : Beqz<"beqz", brtarget, seteq, GPR32Opnd>, R1_IMM21BEQZ<0b010000>; ++ def BNEZ32 : Beqz<"bnez", brtarget, setne, GPR32Opnd>, R1_IMM21BEQZ<0b010001>; ++ ++ def JIRL32 : FJirl<"jirl", calltarget, GPR32Opnd>, R2_IMM16JIRL; ++ ++ def B32 : JumpFB, IMM26B<0b010100>; ++ ++ def BEQ32 : Beq<"beq", brtarget, seteq, GPR32Opnd>, R2_IMM16BEQ<0b010110>; ++ def BNE32 : Beq<"bne", brtarget, setne, GPR32Opnd>, R2_IMM16BEQ<0b010111>; ++ def BLT32 : Beq<"blt", brtarget, setlt, GPR32Opnd>, R2_IMM16BEQ<0b011000>; ++ def BGE32 : Beq<"bge", brtarget, setge, GPR32Opnd>, R2_IMM16BEQ<0b011001>; ++ def BLTU32 : Beq<"bltu", brtarget, setult, GPR32Opnd>, R2_IMM16BEQ<0b011010>; ++ def BGEU32 : Beq<"bgeu", brtarget, setuge, GPR32Opnd>, R2_IMM16BEQ<0b011011>; ++ } ++ ++ /// ++ /// Mem access ++ /// ++ def LL_W : LLBase<"ll.w", GPR32Opnd, mem_simm14_lsl2>, LL_SC<0b000>; ++ def SC_W : SCBase<"sc.w", GPR32Opnd, mem_simm14_lsl2>, LL_SC<0b001>; ++ def LLACQ_W : LLBase_ACQ<"llacq.w", GPR32Opnd>, R2_LL_SC<0b000>; ++ def SCREL_W : SCBase_REL<"screl.w", GPR32Opnd>, R2_LL_SC<0b001>; ++ ++ def PRELD_Raw32 : Preld_Raw<"preld", GPR32Opnd>, PRELD_FM; ++ ++ let isCodeGenOnly = 1 in { ++ def LD_B32 : Ld<"ld.b", GPR32Opnd, mem_simmptr, sextloadi8>, LOAD_STORE<0b0000>; ++ def LD_H32 : Ld<"ld.h", GPR32Opnd, mem_simmptr, sextloadi16, addrDefault>, LOAD_STORE<0b0001>; ++ def LD_W32 : Ld<"ld.w", GPR32Opnd, mem, load, addrDefault>, LOAD_STORE<0b0010>; ++ def ST_B32 : St<"st.b", GPR32Opnd, mem, truncstorei8>, LOAD_STORE<0b0100>; ++ def ST_H32 : St<"st.h", GPR32Opnd, mem, truncstorei16>, LOAD_STORE<0b0101>; ++ def ST_W32 : St<"st.w", GPR32Opnd, mem, store>, LOAD_STORE<0b0110>; ++ def LD_BU32 : Ld<"ld.bu", GPR32Opnd, mem_simmptr, zextloadi8, addrDefault>, LOAD_STORE<0b1000>; ++ def LD_HU32 : Ld<"ld.hu", GPR32Opnd, mem_simmptr, zextloadi16>, LOAD_STORE<0b1001>; ++ ++ def PRELD32 : Preld<"preld", mem, GPR32Opnd>, PRELD_FM_ADDR; ++ ++ def LDPTR_W32 : LdPtr<"ldptr.w", GPR32Opnd>, LL_SC<0b100>; ++ def STPTR_W32 : StPtr<"stptr.w", GPR32Opnd>, LL_SC<0b101>; ++ } ++ ++ def IBAR : Bar<"ibar", int_loongarch_ibar>, BAR_FM<1>; ++ def DBAR : Bar<"dbar", int_loongarch_dbar>, BAR_FM<0>; ++ ++ def LONG_BRANCH_ADDIW : LoongArchPseudo<(outs GPR32Opnd:$dst), ++ (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>; ++ ++ def LONG_BRANCH_ADDIW2Op : LoongArchPseudo<(outs GPR32Opnd:$dst), ++ (ins GPR32Opnd:$src, brtarget:$tgt), []>; ++ ++ def PseudoReturn : PseudoReturnBase; ++ ++ let isCodeGenOnly = 1 in { ++ def LDX_W32 : LDX_FT_LA<"ldx.w", GPR32Opnd, load>, ++ R3MI<0b00010000>; ++ def LDX_HU32 : LDX_FT_LA<"ldx.hu", GPR32Opnd, extloadi16>, ++ R3MI<0b01001000>; ++ def LDX_BU32 : LDX_FT_LA<"ldx.bu", GPR32Opnd, extloadi8>, ++ R3MI<0b01000000>; ++ def STX_W32 : STX_FT_LA<"stx.w", GPR32Opnd, store>, ++ R3MI<0b00110000>; ++ def LDX_H32 : LDX_FT_LA<"ldx.h", GPR32Opnd, sextloadi16>, ++ R3MI<0b00001000>; ++ def LDX_B32 : LDX_FT_LA<"ldx.b", GPR32Opnd, sextloadi8>, ++ R3MI<0b00000000>; ++ def STX_B32 : STX_FT_LA<"stx.b", GPR32Opnd, truncstorei8>, ++ R3MI<0b00100000>; ++ def STX_H32 : STX_FT_LA<"stx.h", GPR32Opnd, truncstorei16>, ++ R3MI<0b00101000>; ++ } ++} ++ ++def LEA_ADDI_W: EffectiveAddress<"addi.w", GPR32Opnd>, LEA_ADDI_FM<0b010>; ++ ++def : LoongArchPat<(LoongArchAddress (i32 tglobaladdr:$in)), ++ (ADDI_W (PCADDU12I32 tglobaladdr:$in) ,0)>,GPR_32; ++def : LoongArchPat<(LoongArchAddress (i32 tblockaddress:$in)), ++ (ADDI_W (PCADDU12I32 tblockaddress:$in),0)>, GPR_32; ++def : LoongArchPat<(LoongArchAddress (i32 tjumptable:$in)), ++ (ADDI_W (PCADDU12I32 tjumptable:$in),0)>, GPR_32; ++def : LoongArchPat<(LoongArchAddress (i32 texternalsym:$in)), ++ (ADDI_W (PCADDU12I32 texternalsym:$in),0)>, GPR_32; ++ ++//===----------------------------------------------------------------------===// ++// Arbitrary patterns that map to one or more instructions ++//===----------------------------------------------------------------------===// ++ ++let isCodeGenOnly = 1 in { ++ def REVB_2W_32 : Int_Reg2<"revb.2w", GPR32Opnd>, R2I<0b01110>; ++ def REVH_2W_32 : Int_Reg2<"revh.2w", GPR32Opnd>, R2I<0b10000>; ++} ++ ++// bswap pattern ++def : LoongArchPat<(bswap GPR32:$rj), (ROTRI_W (REVB_2H GPR32:$rj), 16)>; ++//def : LoongArchPat<(bswap GPR32:$rj), (REVB_2W_32 GPR32:$rj)>; ++//def : LoongArchPat<(bswap GPR32:$rj), (REVH_2W_32 (REVB_2H GPR32:$rj))>; ++ ++// i32 selects ++multiclass SelectInt_Pats { ++ ++// reg, immz ++def : LoongArchPat<(select (Opg (seteq RC:$cond, immz)), RC:$t, RC:$f), ++ (OROp (MASKNEZOp RC:$t, RC:$cond), (MASKEQZOp RC:$f, RC:$cond))>; ++def : LoongArchPat<(select (Opg (setne RC:$cond, immz)), RC:$t, RC:$f), ++ (OROp (MASKEQZOp RC:$t, RC:$cond), (MASKNEZOp RC:$f, RC:$cond))>; ++ ++//def : LoongArchPat<(select (Opg (seteq RC:$cond, imm_type:$imm)), RC:$t, RC:$f), ++// (OROp (MASKNEZOp RC:$t, (XORiOp RC:$cond, imm_type:$imm)), ++// (MASKEQZOp RC:$f, (XORiOp RC:$cond, imm_type:$imm)))>; ++//def : LoongArchPat<(select (Opg (setne RC:$cond, imm_type:$imm)), RC:$t, RC:$f), ++// (OROp (MASKEQZOp RC:$t, (XORiOp RC:$cond, imm_type:$imm)), ++// (MASKNEZOp RC:$f, (XORiOp RC:$cond, imm_type:$imm)))>; ++ ++// reg, immSExt12Plus1 ++//def : LoongArchPat<(select (Opg (setgt RC:$cond, immSExt12Plus1:$imm)), RC:$t, RC:$f), ++// (OROp (MASKNEZOp RC:$t, (SLTiOp RC:$cond, (Plus1 imm:$imm))), ++// (MASKEQZOp RC:$f, (SLTiOp RC:$cond, (Plus1 imm:$imm))))>; ++//def : LoongArchPat<(select (Opg (setugt RC:$cond, immSExt16Plus1:$imm)), RC:$t, RC:$f), ++// (OROp (MASKNEZOp RC:$t, (SLTiuOp RC:$cond, (Plus1 imm:$imm))), ++// (MASKEQZOp RC:$f, (SLTiuOp RC:$cond, (Plus1 imm:$imm))))>; ++ ++def : LoongArchPat<(select (Opg (seteq RC:$cond, immz)), RC:$t, immz), ++ (MASKNEZOp RC:$t, RC:$cond)>; ++def : LoongArchPat<(select (Opg (setne RC:$cond, immz)), RC:$t, immz), ++ (MASKEQZOp RC:$t, RC:$cond)>; ++def : LoongArchPat<(select (Opg (seteq RC:$cond, immz)), immz, RC:$f), ++ (MASKEQZOp RC:$f, RC:$cond)>; ++def : LoongArchPat<(select (Opg (setne RC:$cond, immz)), immz, RC:$f), ++ (MASKNEZOp RC:$f, RC:$cond)>; ++} ++ ++defm : SelectInt_Pats; ++ ++def : LoongArchPat<(select i32:$cond, i32:$t, i32:$f), ++ (OR32 (MASKEQZ32 i32:$t, i32:$cond), ++ (MASKNEZ32 i32:$f, i32:$cond))>; ++def : LoongArchPat<(select i32:$cond, i32:$t, immz), ++ (MASKEQZ32 i32:$t, i32:$cond)>; ++def : LoongArchPat<(select i32:$cond, immz, i32:$f), ++ (MASKNEZ32 i32:$f, i32:$cond)>; ++ ++// truncate ++def : LoongArchPat<(i32 (trunc (assertzext_lt_i32 GPR64:$src))), ++ (EXTRACT_SUBREG GPR64:$src, sub_32)>, GPR_64; ++def : LoongArchPat<(i32 (trunc GPR64:$src)), ++ (SLLI_W (EXTRACT_SUBREG GPR64:$src, sub_32), 0)>, GPR_64; ++ ++// Patterns used for matching away redundant sign extensions. ++// LA32 arithmetic instructions sign extend their result implicitly. ++def : LoongArchPat<(i64 (sext (i32 (add GPR32:$src, GPR32:$src2)))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (ADD_W GPR32:$src, GPR32:$src2), sub_32)>; ++def : LoongArchPat<(i64 (sext (i32 (sub GPR32:$src, GPR32:$src2)))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (SUB_W GPR32:$src, GPR32:$src2), sub_32)>; ++def : LoongArchPat<(i64 (sext (i32 (mul GPR32:$src, GPR32:$src2)))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (MUL_W GPR32:$src, GPR32:$src2), sub_32)>; ++ ++def : LoongArchPat<(store (i32 0), addr:$dst), (ST_W32 ZERO, addr:$dst)>; ++ ++def : InstAlias<"break", (BREAK 0), 0>; ++def : LoongArchInstAlias<"move $dst, $src", ++ (OR32 GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>, GPR_32; ++ ++def immSExt12Plus1 : PatLeaf<(imm), [{ ++ return isInt<13>(N->getSExtValue()) && isInt<12>(N->getSExtValue() + 1); ++}]>; ++ ++def Plus1 : SDNodeXFormgetSExtValue() + 1); }]>; ++ ++multiclass BrcondPats { ++ ++def : LoongArchPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst), ++ (BNEOp RC:$lhs, ZEROReg, bb:$dst)>; ++def : LoongArchPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst), ++ (BEQOp RC:$lhs, ZEROReg, bb:$dst)>; ++def : LoongArchPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst), ++ (BEQOp1 (SLTOp RC:$lhs, RC:$rhs), ZEROReg, bb:$dst)>; ++def : LoongArchPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst), ++ (BEQOp1 (SLTUOp RC:$lhs, RC:$rhs), ZEROReg, bb:$dst)>; ++def : LoongArchPat<(brcond (i32 (setge RC:$lhs, immSExt12:$rhs)), bb:$dst), ++ (BEQOp1 (SLTIOp RC:$lhs, immSExt12:$rhs), ZEROReg, bb:$dst)>; ++def : LoongArchPat<(brcond (i32 (setuge RC:$lhs, immSExt12:$rhs)), bb:$dst), ++ (BEQOp1 (SLTUIOp RC:$lhs, immSExt12:$rhs), ZEROReg, bb:$dst)>; ++def : LoongArchPat<(brcond (i32 (setgt RC:$lhs, immSExt12Plus1:$rhs)), bb:$dst), ++ (BEQOp1 (SLTIOp RC:$lhs, (Plus1 imm:$rhs)), ZEROReg, bb:$dst)>; ++def : LoongArchPat<(brcond (i32 (setugt RC:$lhs, immSExt12Plus1:$rhs)), bb:$dst), ++ (BEQOp1 (SLTUIOp RC:$lhs, (Plus1 imm:$rhs)), ZEROReg, bb:$dst)>; ++def : LoongArchPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst), ++ (BEQOp1 (SLTOp RC:$rhs, RC:$lhs), ZEROReg, bb:$dst)>; ++def : LoongArchPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst), ++ (BEQOp1 (SLTUOp RC:$rhs, RC:$lhs), ZEROReg, bb:$dst)>; ++def : LoongArchPat<(brcond RC:$cond, bb:$dst), ++ (BNEOp RC:$cond, ZEROReg, bb:$dst)>; ++} ++ ++defm : BrcondPats, GPR_64; ++ ++defm atomic_cmp_swap_8 : ternary_atomic_op_failure_ord; ++defm atomic_cmp_swap_16 : ternary_atomic_op_failure_ord; ++defm atomic_cmp_swap_32 : ternary_atomic_op_failure_ord; ++ ++let usesCustomInserter = 1 in { ++ def ATOMIC_LOAD_ADD_I8 : Atomic2Ops; ++ def ATOMIC_LOAD_ADD_I16 : Atomic2Ops; ++ def ATOMIC_LOAD_ADD_I32 : Atomic2Ops; ++ def ATOMIC_LOAD_SUB_I8 : Atomic2Ops; ++ def ATOMIC_LOAD_SUB_I16 : Atomic2Ops; ++ def ATOMIC_LOAD_SUB_I32 : Atomic2Ops; ++ def ATOMIC_LOAD_AND_I8 : Atomic2Ops; ++ def ATOMIC_LOAD_AND_I16 : Atomic2Ops; ++ def ATOMIC_LOAD_AND_I32 : Atomic2Ops; ++ def ATOMIC_LOAD_OR_I8 : Atomic2Ops; ++ def ATOMIC_LOAD_OR_I16 : Atomic2Ops; ++ def ATOMIC_LOAD_OR_I32 : Atomic2Ops; ++ def ATOMIC_LOAD_XOR_I8 : Atomic2Ops; ++ def ATOMIC_LOAD_XOR_I16 : Atomic2Ops; ++ def ATOMIC_LOAD_XOR_I32 : Atomic2Ops; ++ def ATOMIC_LOAD_NAND_I8 : Atomic2Ops; ++ def ATOMIC_LOAD_NAND_I16 : Atomic2Ops; ++ def ATOMIC_LOAD_NAND_I32 : Atomic2Ops; ++ ++ def ATOMIC_SWAP_I8 : Atomic2Ops; ++ def ATOMIC_SWAP_I16 : Atomic2Ops; ++ def ATOMIC_SWAP_I32 : Atomic2Ops; ++ ++ defm I8_ : AtomicCmpSwapInstrs<"8", GPR32>; ++ defm I16_ : AtomicCmpSwapInstrs<"16", GPR32>; ++ defm I32_ : AtomicCmpSwapInstrs<"32", GPR32>; ++ ++ def ATOMIC_LOAD_MAX_I8 : Atomic2Ops; ++ def ATOMIC_LOAD_MAX_I16 : Atomic2Ops; ++ def ATOMIC_LOAD_MAX_I32 : Atomic2Ops; ++ ++ def ATOMIC_LOAD_MIN_I8 : Atomic2Ops; ++ def ATOMIC_LOAD_MIN_I16 : Atomic2Ops; ++ def ATOMIC_LOAD_MIN_I32 : Atomic2Ops; ++ ++ def ATOMIC_LOAD_UMAX_I8 : Atomic2Ops; ++ def ATOMIC_LOAD_UMAX_I16 : Atomic2Ops; ++ def ATOMIC_LOAD_UMAX_I32 : Atomic2Ops; ++ ++ def ATOMIC_LOAD_UMIN_I8 : Atomic2Ops; ++ def ATOMIC_LOAD_UMIN_I16 : Atomic2Ops; ++ def ATOMIC_LOAD_UMIN_I32 : Atomic2Ops; ++} ++ ++def ATOMIC_LOAD_ADD_I8_POSTRA : Atomic2OpsSubwordPostRA; ++def ATOMIC_LOAD_ADD_I16_POSTRA : Atomic2OpsSubwordPostRA; ++def ATOMIC_LOAD_ADD_I32_POSTRA : Atomic2OpsPostRA; ++def ATOMIC_LOAD_SUB_I8_POSTRA : Atomic2OpsSubwordPostRA; ++def ATOMIC_LOAD_SUB_I16_POSTRA : Atomic2OpsSubwordPostRA; ++def ATOMIC_LOAD_SUB_I32_POSTRA : Atomic2OpsPostRA; ++def ATOMIC_LOAD_AND_I8_POSTRA : Atomic2OpsSubwordPostRA; ++def ATOMIC_LOAD_AND_I16_POSTRA : Atomic2OpsSubwordPostRA; ++def ATOMIC_LOAD_AND_I32_POSTRA : Atomic2OpsPostRA; ++def ATOMIC_LOAD_OR_I8_POSTRA : Atomic2OpsSubwordPostRA; ++def ATOMIC_LOAD_OR_I16_POSTRA : Atomic2OpsSubwordPostRA; ++def ATOMIC_LOAD_OR_I32_POSTRA : Atomic2OpsPostRA; ++def ATOMIC_LOAD_XOR_I8_POSTRA : Atomic2OpsSubwordPostRA; ++def ATOMIC_LOAD_XOR_I16_POSTRA : Atomic2OpsSubwordPostRA; ++def ATOMIC_LOAD_XOR_I32_POSTRA : Atomic2OpsPostRA; ++def ATOMIC_LOAD_NAND_I8_POSTRA : Atomic2OpsSubwordPostRA; ++def ATOMIC_LOAD_NAND_I16_POSTRA : Atomic2OpsSubwordPostRA; ++def ATOMIC_LOAD_NAND_I32_POSTRA : Atomic2OpsPostRA; ++ ++def ATOMIC_SWAP_I8_POSTRA : Atomic2OpsSubwordPostRA; ++def ATOMIC_SWAP_I16_POSTRA : Atomic2OpsSubwordPostRA; ++def ATOMIC_SWAP_I32_POSTRA : Atomic2OpsPostRA; ++ ++def ATOMIC_CMP_SWAP_I8_POSTRA : AtomicCmpSwapSubwordPostRA; ++def ATOMIC_CMP_SWAP_I16_POSTRA : AtomicCmpSwapSubwordPostRA; ++def ATOMIC_CMP_SWAP_I32_POSTRA : AtomicCmpSwapPostRA; ++ ++def ATOMIC_LOAD_MAX_I8_POSTRA : Atomic2OpsSubwordPostRA; ++def ATOMIC_LOAD_MAX_I16_POSTRA : Atomic2OpsSubwordPostRA; ++def ATOMIC_LOAD_MAX_I32_POSTRA : Atomic2OpsPostRA; ++ ++def ATOMIC_LOAD_MIN_I8_POSTRA : Atomic2OpsSubwordPostRA; ++def ATOMIC_LOAD_MIN_I16_POSTRA : Atomic2OpsSubwordPostRA; ++def ATOMIC_LOAD_MIN_I32_POSTRA : Atomic2OpsPostRA; ++ ++def ATOMIC_LOAD_UMAX_I8_POSTRA : Atomic2OpsSubwordPostRA; ++def ATOMIC_LOAD_UMAX_I16_POSTRA : Atomic2OpsSubwordPostRA; ++def ATOMIC_LOAD_UMAX_I32_POSTRA : Atomic2OpsPostRA; ++ ++def ATOMIC_LOAD_UMIN_I8_POSTRA : Atomic2OpsSubwordPostRA; ++def ATOMIC_LOAD_UMIN_I16_POSTRA : Atomic2OpsSubwordPostRA; ++def ATOMIC_LOAD_UMIN_I32_POSTRA : Atomic2OpsPostRA; ++ ++def : LoongArchPat<(atomic_load_8 addr:$a), (LD_B32 addr:$a)>; ++def : LoongArchPat<(atomic_load_16 addr:$a), (LD_H32 addr:$a)>; ++def : LoongArchPat<(atomic_load_32 addrimm14lsl2:$a), (LDPTR_W32 addrimm14lsl2:$a)>; ++def : LoongArchPat<(atomic_load_32 addr:$a), (LD_W32 addr:$a)>; ++ ++def : LoongArchPat<(atomic_store_8 GPR32:$v, addr:$a), ++ (ST_B32 GPR32:$v, addr:$a)>; ++def : LoongArchPat<(atomic_store_16 GPR32:$v, addr:$a), ++ (ST_H32 GPR32:$v, addr:$a)>; ++def : LoongArchPat<(atomic_store_32 GPR32:$v, addrimm14lsl2:$a), ++ (STPTR_W32 GPR32:$v, addrimm14lsl2:$a)>; ++def : LoongArchPat<(atomic_store_32 GPR32:$v, addr:$a), ++ (ST_W32 GPR32:$v, addr:$a)>; ++ ++// DBAR hint encoding for LA664 and later micro-architectures, paraphrased from ++// the Linux patch revealing it [1]: ++// ++// - Bit 4: kind of constraint (0: completion, 1: ordering) ++// - Bit 3: barrier for previous read (0: true, 1: false) ++// - Bit 2: barrier for previous write (0: true, 1: false) ++// - Bit 1: barrier for succeeding read (0: true, 1: false) ++// - Bit 0: barrier for succeeding write (0: true, 1: false) ++// ++// Hint 0x700: barrier for "read after read" from the same address, which is ++// e.g. needed by LL-SC loops on older models. (DBAR 0x700 behaves the same as ++// nop if such reordering is disabled on supporting newer models.) ++// ++// [1]: https://lore.kernel.org/loongarch/20230516124536.535343-1-chenhuacai@loongson.cn/ ++// ++// Implementations without support for the finer-granularity hints simply treat ++// all as the full barrier (DBAR 0), so we can unconditionally start emiting the ++// more precise hints right away. ++ ++def : Pat<(atomic_fence 4, timm), (DBAR 0b10100)>; // acquire ++def : Pat<(atomic_fence 5, timm), (DBAR 0b10010)>; // release ++def : Pat<(atomic_fence 6, timm), (DBAR 0b10000)>; // acqrel ++def : Pat<(atomic_fence 7, timm), (DBAR 0b10000)>; // seqcst ++ ++def : LoongArchPat<(i32 (extloadi1 addr:$src)), (LD_BU32 addr:$src)>; ++def : LoongArchPat<(i32 (extloadi8 addr:$src)), (LD_BU32 addr:$src)>; ++def : LoongArchPat<(i32 (extloadi16 addr:$src)), (LD_HU32 addr:$src)>; ++ ++def : LoongArchPat<(store (i32 0), addr:$dst), (ST_W32 ZERO, addr:$dst)>; ++ ++// Patterns for loads/stores with a reg+imm operand. ++let AddedComplexity = 40 in { ++ def : LoadRegImmPat; ++ def : LoadRegImmPat; ++ def : LoadRegImmPat; ++ def : LoadRegImmPat; ++ def : LoadRegImmPat; ++ def : StoreRegImmPat; ++ def : StoreRegImmPat; ++ def : StoreRegImmPat; ++ ++ def : LoadRegImm14Lsl2Pat; ++ def : StoreRegImm14Lsl2Pat; ++} ++ ++let isCall=1, isCTI=1, Defs = [RA] in { ++ ++ class JumpLinkRegPseudo: ++ LoongArchPseudo<(outs), (ins RO:$rj), [(LoongArchJmpLink RO:$rj)]>, ++ PseudoInstExpansion<(JIRLRInst RetReg, ResRO:$rj)> { ++ let hasPostISelHook = 1; ++ } ++ ++ class JumpLinkReg: ++ InstForm<(outs RO:$rd), (ins RO:$rj), !strconcat(opstr, "\t$rd, $rj, 0"), ++ [], FrmR, opstr> { ++ let hasPostISelHook = 1; ++ } ++ ++} ++ ++def JIRLR : JumpLinkReg<"jirl", GPR32Opnd>, R2_IMM16JIRL { ++ let offs16 = 0; ++} ++def JIRLRPseudo : JumpLinkRegPseudo; ++ ++class BrindRegPseudo: ++ LoongArchPseudo<(outs), (ins RO:$rj), [(brind RO:$rj)]>, ++ PseudoInstExpansion<(JIRLRInst RetReg, ResRO:$rj)> { ++ let isTerminator=1; ++ let isBarrier=1; ++ let isBranch = 1; ++ let isIndirectBranch = 1; ++ bit isCTI = 1; ++} ++ ++def JIRLRBRIND : BrindRegPseudo; ++ ++def : LoongArchPat<(addc GPR32:$src, immSExt12:$imm), ++ (ADDI_W GPR32:$src, imm:$imm)>; ++ ++defm : SeteqPats; ++defm : SetlePats; ++defm : SetgtPats; ++defm : SetgePats; ++defm : SetgeImmPats; ++ ++def : LoongArchPat<(i64 (sext (i32 (xor (i32 (trunc (i64 (assertsext GPR64:$rj)))), (immZExt12:$imm12))))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (XORI32 (EXTRACT_SUBREG GPR64:$rj, sub_32), (immZExt12:$imm12)), sub_32)>, GPR_64; ++ ++def : LoongArchPat<(i64 (sext (i32 (add (i32 (trunc (i64 (assertsext GPR64:$rj)))), (i32 (trunc (i64 (assertsext GPR64:$rk)))))))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (ADD_W (EXTRACT_SUBREG GPR64:$rj, sub_32), (EXTRACT_SUBREG GPR64:$rk, sub_32)), sub_32)>, GPR_64; ++ ++def : LoongArchPat<(i64 (sext (i32 (add (i32 (trunc (i64 (assertsext GPR64:$rj)))), (immSExt12:$imm12))))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (ADDI_W (EXTRACT_SUBREG GPR64:$rj, sub_32), (immSExt12:$imm12)), sub_32)>, GPR_64; ++ ++def : LoongArchPat<(i64 (sext (i32 (sra (i32 (trunc (i64 (assertsext GPR64:$rj)))), (i32 (trunc (i64 (assertsext GPR64:$rk)))))))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (SRA_W (EXTRACT_SUBREG GPR64:$rj, sub_32), (EXTRACT_SUBREG GPR64:$rk, sub_32)), sub_32)>, GPR_64; ++ ++def : LoongArchPat<(i64 (sext (i32 (srl (i32 (trunc (i64 (assertsext GPR64:$rj)))), (i32 (trunc (i64 (assertsext GPR64:$rk)))))))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (SRL_W (EXTRACT_SUBREG GPR64:$rj, sub_32), (EXTRACT_SUBREG GPR64:$rk, sub_32)), sub_32)>, GPR_64; ++ ++def : LoongArchPat<(i64 (sext (i32 (mul (i32 (trunc (i64 (assertsext GPR64:$rj)))), (i32 (trunc (i64 (assertsext GPR64:$rk)))))))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (MUL_W (EXTRACT_SUBREG GPR64:$rj, sub_32), (EXTRACT_SUBREG GPR64:$rk, sub_32)), sub_32)>, GPR_64; ++ ++def : LoongArchPat<(i64 (sext (i32 (xor (i32 (trunc (i64 (assertsext GPR64:$rj)))), (i32 (trunc (i64 (assertsext GPR64:$rk)))))))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (XOR32 (EXTRACT_SUBREG GPR64:$rj, sub_32), (EXTRACT_SUBREG GPR64:$rk, sub_32)), sub_32)>, GPR_64; ++ ++def : LoongArchPat<(i64 (sext (i32 (xor (i32 (trunc (i64 (assertsext GPR64:$rj)))), (i32 GPR32:$rk))))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (XOR32 (EXTRACT_SUBREG GPR64:$rj, sub_32), GPR32:$rk), sub_32)>, GPR_64; ++ ++def : LoongArchPat<(i64 (sext (i32 (or (i32 (trunc (i64 (assertsext GPR64:$rj)))), (uimm12_32:$imm12))))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (ORI32 (EXTRACT_SUBREG GPR64:$rj, sub_32), (uimm12_32:$imm12)), sub_32)>, GPR_64; ++ ++def : LoongArchPat<(i64 (sext (i32 (or (i32 (trunc (i64 (assertsext GPR64:$rj)))), (i32 GPR32:$rk))))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (OR32 (EXTRACT_SUBREG GPR64:$rj, sub_32), GPR32:$rk), sub_32)>, GPR_64; ++ ++def : LoongArchPat<(i64 (sext (select i32:$cond, (i32 (trunc (i64 (assertsext GPR64:$t)))), (i32 (trunc (i64 (assertsext GPR64:$f))))))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (OR32 (MASKEQZ32 (EXTRACT_SUBREG GPR64:$t, sub_32), i32:$cond), ++ (MASKNEZ32 (EXTRACT_SUBREG GPR64:$f, sub_32), i32:$cond)), sub_32)>; ++ ++def : LoongArchPat<(i64 (sext (i32 (shl (i32 (trunc (i64 (assertsext GPR64:$rj)))), (i32 (trunc (i64 (assertsext GPR64:$rk)))))))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (SLL_W (EXTRACT_SUBREG GPR64:$rj, sub_32), (EXTRACT_SUBREG GPR64:$rk, sub_32)), sub_32)>, GPR_64; ++ ++def : LoongArchPat<(i64 (sext (i32 (srem (i32 (trunc (i64 (assertsext GPR64:$rj)))), (i32 (trunc (i64 (assertsext GPR64:$rk)))))))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (MOD_W (EXTRACT_SUBREG GPR64:$rj, sub_32), (EXTRACT_SUBREG GPR64:$rk, sub_32)), sub_32)>, GPR_64; ++ ++def : LoongArchPat<(atomic_store_32 (i32 (trunc (i64 (assertsext GPR64:$rj)))), addr:$a), ++ (ST_W32 (EXTRACT_SUBREG GPR64:$rj, sub_32), addr:$a)>, GPR_64; ++ ++def : LoongArchPat<(i64 (sext (i32 (sub (i32 (trunc (i64 (assertsext GPR64:$rj)))), (i32 (trunc (i64 (assertsext GPR64:$rk)))))))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (SUB_W (EXTRACT_SUBREG GPR64:$rj, sub_32), (EXTRACT_SUBREG GPR64:$rk, sub_32)), sub_32)>, GPR_64; ++ ++def : LoongArchPat<(i64 (sext (i32 (udiv (i32 (trunc (i64 (assertsext GPR64:$rj)))), (i32 (trunc (i64 (assertsext GPR64:$rk)))))))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (DIV_WU (EXTRACT_SUBREG GPR64:$rj, sub_32), (EXTRACT_SUBREG GPR64:$rk, sub_32)), sub_32)>, GPR_64; ++ ++def : LoongArchPat<(i64 (sext (i32 (urem (i32 (trunc (i64 (assertsext GPR64:$rj)))), (i32 (trunc (i64 (assertsext GPR64:$rk)))))))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (MOD_WU (EXTRACT_SUBREG GPR64:$rj, sub_32), (EXTRACT_SUBREG GPR64:$rk, sub_32)), sub_32)>, GPR_64; ++ ++def : LoongArchPat<(brcond (i32 (seteq (i32 (trunc (i64 (assertsext GPR64:$rj)))), 0)), bb:$offs21), ++ (BEQZ32 (EXTRACT_SUBREG GPR64:$rj, sub_32), brtarget:$offs21)>; ++ ++def : LoongArchPat<(setne (i32 (trunc (i64 (assertsext GPR64:$rj)))), 0), ++ (SLTU32 ZERO, (EXTRACT_SUBREG GPR64:$rj, sub_32))>; ++ ++def : LoongArchPat<(select i32:$cond, (i32 (trunc (i64 (assertsext GPR64:$t)))), (i32 (trunc (i64 (assertsext GPR64:$f))))), ++ (OR32 (MASKEQZ32 (EXTRACT_SUBREG GPR64:$t, sub_32), i32:$cond), ++ (MASKNEZ32 (EXTRACT_SUBREG GPR64:$f, sub_32), i32:$cond))>; ++ ++def : LoongArchPat<(select (i32 (setne (i32 (trunc (i64 (assertsext GPR64:$cond)))), immz)), immz, i32:$f), ++ (MASKNEZ32 i32:$f, (EXTRACT_SUBREG GPR64:$cond, sub_32))>; ++ ++def : LoongArchPat<(select (i32 (seteq (i32 (trunc (i64 (assertsext GPR64:$cond)))), immz)), immz, i32:$f), ++ (MASKEQZ32 i32:$f, (EXTRACT_SUBREG GPR64:$cond, sub_32))>; ++ ++ def : LoongArchPat<(store (i32 (trunc (i64 (assertsext GPR64:$v)))), addr:$a), ++ (ST_W32 (EXTRACT_SUBREG GPR64:$v, sub_32), addr:$a)>; ++ ++ ++def : LoongArchPat<(i32 (xor GPR32:$rj, (i32 -1))), ++ (NOR32 ZERO, GPR32:$rj)>; ++ ++def : LoongArchPat<(and GPR32:$rj, (i32 (xor GPR32:$rk, (i32 -1)))), ++ (ANDN32 GPR32:$rj, GPR32:$rk)>; ++ ++def : LoongArchPat< ++ (i64 ++ (sext ++ (i32 (and (i32 (trunc (i64 (assertsext GPR64:$rj)))), ++ (i32 (xor (i32 (trunc (i64 (assertsext GPR64:$rk)))), ++ (i32 -1)))) ++ ) ++ ) ++ ), ++ (INSERT_SUBREG ++ (i64 (IMPLICIT_DEF)), ++ (ANDN32 (EXTRACT_SUBREG GPR64:$rj, sub_32), ++ (EXTRACT_SUBREG GPR64:$rk, sub_32)), ++ sub_32 ++ )>; ++ ++def : LoongArchPat< ++ (i64 ++ (sext ++ (i32 (or (i32 (trunc (i64 (assertsext GPR64:$rj)))), ++ (i32 (xor (i32 (trunc (i64 (assertsext GPR64:$rk)))), ++ (i32 -1)))) ++ ) ++ ) ++ ), ++ (INSERT_SUBREG ++ (i64 (IMPLICIT_DEF)), ++ (ORN32 (EXTRACT_SUBREG GPR64:$rj, sub_32), ++ (EXTRACT_SUBREG GPR64:$rk, sub_32)), ++ sub_32 ++ )>; ++ ++def : LoongArchPat<(i64 ++ (sext ++ (i32 (xor (i32 (or (i32 (trunc (i64 (assertsext GPR64:$rj)))), ++ (i32 (trunc (i64 (assertsext GPR64:$rk)))))), ++ (i32 -1)) ++ ) ++ ) ++ ), ++ (INSERT_SUBREG ++ (i64 (IMPLICIT_DEF)), ++ (NOR32 (EXTRACT_SUBREG GPR64:$rj, sub_32), ++ (EXTRACT_SUBREG GPR64:$rk, sub_32)), ++ sub_32 ++ )>; ++ ++def : LoongArchPat<(i64 ++ (sext ++ (i32 (xor (i32 (trunc (i64 (or (i64 (assertsext GPR64:$rj)), ++ (i64 (assertsext GPR64:$rk)))))), ++ (i32 -1)) ++ ) ++ ) ++ ), ++ (INSERT_SUBREG ++ (i64 (IMPLICIT_DEF)), ++ (NOR32 (EXTRACT_SUBREG GPR64:$rk, sub_32), ++ (EXTRACT_SUBREG GPR64:$rj, sub_32)), ++ sub_32 ++ )>; ++ ++def : LoongArchPat<(i64 ++ (sext ++ (i32 (xor (i32 (trunc (i64 (assertsext GPR64:$rj)))), ++ (i32 -1)) ++ ) ++ ) ++ ), ++ (INSERT_SUBREG ++ (i64 (IMPLICIT_DEF)), ++ (NOR32 ZERO, (EXTRACT_SUBREG GPR64:$rj, sub_32)), ++ sub_32 ++ )>; ++ ++def : LoongArchPat<(i64 ++ (zext ++ (i32 (seteq (i32 (trunc (i64 (assertsext GPR64:$rj)))), ++ (i32 0)) ++ ) ++ ) ++ ), ++ (INSERT_SUBREG ++ (i64 (IMPLICIT_DEF)), ++ (SLTUI32 (EXTRACT_SUBREG GPR64:$rj, sub_32), (i32 1)), ++ sub_32 ++ )>; +diff --git a/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp b/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp +index 27979a830..171e75596 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp ++++ b/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp +@@ -1,4 +1,4 @@ +-//===- LoongArchAsmPrinter.cpp - LoongArch LLVM Assembly Printer -*- C++ -*--=// ++//===- LoongArchAsmPrinter.cpp - LoongArch LLVM Assembly Printer --------------------===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -12,190 +12,622 @@ + //===----------------------------------------------------------------------===// + + #include "LoongArchAsmPrinter.h" ++#include "MCTargetDesc/LoongArchInstPrinter.h" ++#include "MCTargetDesc/LoongArchABIInfo.h" ++#include "MCTargetDesc/LoongArchBaseInfo.h" ++#include "MCTargetDesc/LoongArchMCTargetDesc.h" + #include "LoongArch.h" ++#include "LoongArchMCInstLower.h" ++#include "LoongArchMachineFunction.h" ++#include "LoongArchSubtarget.h" + #include "LoongArchTargetMachine.h" +-#include "MCTargetDesc/LoongArchInstPrinter.h" +-#include "TargetInfo/LoongArchTargetInfo.h" +-#include "llvm/CodeGen/AsmPrinter.h" ++#include "LoongArchTargetStreamer.h" ++#include "llvm/ADT/SmallString.h" ++#include "llvm/ADT/StringRef.h" ++#include "llvm/ADT/Twine.h" ++#include "llvm/BinaryFormat/ELF.h" ++#include "llvm/CodeGen/MachineBasicBlock.h" ++#include "llvm/CodeGen/MachineConstantPool.h" ++#include "llvm/CodeGen/MachineFrameInfo.h" ++#include "llvm/CodeGen/MachineFunction.h" ++#include "llvm/CodeGen/MachineInstr.h" ++#include "llvm/CodeGen/MachineJumpTableInfo.h" ++#include "llvm/CodeGen/MachineOperand.h" ++#include "llvm/CodeGen/TargetRegisterInfo.h" ++#include "llvm/CodeGen/TargetSubtargetInfo.h" ++#include "llvm/IR/Attributes.h" ++#include "llvm/IR/BasicBlock.h" ++#include "llvm/IR/DataLayout.h" ++#include "llvm/IR/Function.h" ++#include "llvm/IR/InlineAsm.h" ++#include "llvm/IR/Instructions.h" + #include "llvm/MC/MCContext.h" ++#include "llvm/MC/MCExpr.h" ++#include "llvm/MC/MCInst.h" + #include "llvm/MC/MCInstBuilder.h" ++#include "llvm/MC/MCObjectFileInfo.h" ++#include "llvm/MC/MCSectionELF.h" ++#include "llvm/MC/MCSymbol.h" ++#include "llvm/MC/MCSymbolELF.h" + #include "llvm/MC/TargetRegistry.h" ++#include "llvm/Support/Casting.h" ++#include "llvm/Support/ErrorHandling.h" ++#include "llvm/Support/raw_ostream.h" ++#include "llvm/Target/TargetMachine.h" ++#include "llvm/TargetParser/Triple.h" ++#include ++#include ++#include ++#include ++#include ++#include + + using namespace llvm; + + #define DEBUG_TYPE "loongarch-asm-printer" + +-// Simple pseudo-instructions have their lowering (with expansion to real +-// instructions) auto-generated. ++LoongArchTargetStreamer &LoongArchAsmPrinter::getTargetStreamer() const { ++ return static_cast(*OutStreamer->getTargetStreamer()); ++} ++ ++bool LoongArchAsmPrinter::runOnMachineFunction(MachineFunction &MF) { ++ Subtarget = &MF.getSubtarget(); ++ ++ LoongArchFI = MF.getInfo(); ++ MCP = MF.getConstantPool(); ++ ++ AsmPrinter::runOnMachineFunction(MF); ++ ++ emitXRayTable(); ++ ++ return true; ++} ++ ++bool LoongArchAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) { ++ MCOp = MCInstLowering.LowerOperand(MO); ++ return MCOp.isValid(); ++} ++ + #include "LoongArchGenMCPseudoLowering.inc" + ++// Lower PseudoReturn/PseudoIndirectBranch/PseudoIndirectBranch64 to ++// JIRL as appropriate for the target. ++void LoongArchAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer, ++ const MachineInstr *MI) { ++ bool HasLinkReg = false; ++ MCInst TmpInst0; ++ TmpInst0.setOpcode(LoongArch::JIRL); ++ HasLinkReg = true; ++ ++ MCOperand MCOp; ++ ++ if (HasLinkReg) { ++ unsigned ZeroReg = Subtarget->is64Bit() ? LoongArch::ZERO_64 : LoongArch::ZERO; ++ TmpInst0.addOperand(MCOperand::createReg(ZeroReg)); ++ } ++ ++ lowerOperand(MI->getOperand(0), MCOp); ++ TmpInst0.addOperand(MCOp); ++ ++ TmpInst0.addOperand(MCOperand::createImm(0)); ++ ++ EmitToStreamer(OutStreamer, TmpInst0); ++} ++ ++void LoongArchAsmPrinter::emitPseudoTailBranch(MCStreamer &OutStreamer, ++ const MachineInstr *MI) { ++ MCInst TmpInst; ++ TmpInst.setOpcode(LoongArch::B); ++ ++ MCOperand MCOp; ++ ++ lowerOperand(MI->getOperand(0), MCOp); ++ TmpInst.addOperand(MCOp); ++ ++ EmitToStreamer(OutStreamer, TmpInst); ++} ++ + void LoongArchAsmPrinter::emitInstruction(const MachineInstr *MI) { +- LoongArch_MC::verifyInstructionPredicates( +- MI->getOpcode(), getSubtargetInfo().getFeatureBits()); ++ LoongArchTargetStreamer &TS = getTargetStreamer(); ++ unsigned Opc = MI->getOpcode(); ++ TS.forbidModuleDirective(); ++ ++ if (MI->isDebugValue()) { ++ SmallString<128> Str; ++ raw_svector_ostream OS(Str); + +- // Do any auto-generated pseudo lowerings. +- if (emitPseudoExpansionLowering(*OutStreamer, MI)) ++ PrintDebugValueComment(MI, OS); + return; ++ } ++ if (MI->isDebugLabel()) ++ return; ++ // If we just ended a constant pool, mark it as such. ++ OutStreamer->emitDataRegion(MCDR_DataRegionEnd); ++ InConstantPool = false; + +- switch (MI->getOpcode()) { +- case TargetOpcode::PATCHABLE_FUNCTION_ENTER: ++ switch (Opc) { ++ case LoongArch::PATCHABLE_FUNCTION_ENTER: + LowerPATCHABLE_FUNCTION_ENTER(*MI); + return; +- case TargetOpcode::PATCHABLE_FUNCTION_EXIT: ++ case LoongArch::PATCHABLE_FUNCTION_EXIT: + LowerPATCHABLE_FUNCTION_EXIT(*MI); + return; +- case TargetOpcode::PATCHABLE_TAIL_CALL: ++ case LoongArch::PATCHABLE_TAIL_CALL: + LowerPATCHABLE_TAIL_CALL(*MI); + return; + } ++ MachineBasicBlock::const_instr_iterator I = MI->getIterator(); ++ MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end(); + +- MCInst TmpInst; +- if (!lowerLoongArchMachineInstrToMCInst(MI, TmpInst, *this)) +- EmitToStreamer(*OutStreamer, TmpInst); ++ do { ++ // Do any auto-generated pseudo lowerings. ++ if (emitPseudoExpansionLowering(*OutStreamer, &*I)) ++ continue; ++ if (I->getOpcode() == LoongArch::PseudoReturn || ++ I->getOpcode() == LoongArch::PseudoReturn64){ ++ emitPseudoIndirectBranch(*OutStreamer, &*I); ++ continue; ++ } ++ if (I->getOpcode() == LoongArch::PseudoTailReturn){ ++ emitPseudoTailBranch(*OutStreamer, &*I); ++ continue; ++ } ++ ++ // Some instructions are marked as pseudo right now which ++ // would make the test fail for the wrong reason but ++ // that will be fixed soon. We need this here because we are ++ // removing another test for this situation downstream in the ++ // callchain. ++ // ++ if (I->isPseudo() ++ && !isLongBranchPseudo(I->getOpcode())) ++ llvm_unreachable("Pseudo opcode found in EmitInstruction()"); ++ ++ MCInst TmpInst0; ++ MCInstLowering.Lower(&*I, TmpInst0); ++ EmitToStreamer(*OutStreamer, TmpInst0); ++ } while ((++I != E) && I->isInsideBundle()); + } + +-bool LoongArchAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, +- const char *ExtraCode, +- raw_ostream &OS) { +- // First try the generic code, which knows about modifiers like 'c' and 'n'. +- if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS)) +- return false; ++//===----------------------------------------------------------------------===// ++// ++// LoongArch Asm Directives ++// ++// ++//===----------------------------------------------------------------------===// ++ ++//===----------------------------------------------------------------------===// ++// Set directives ++//===----------------------------------------------------------------------===// ++ ++/// Emit Set directives. ++const char *LoongArchAsmPrinter::getCurrentABIString() const { ++ switch (static_cast(TM).getABI().GetEnumValue()) { ++ case LoongArchABIInfo::ABI::LP32: return "abilp32"; ++ case LoongArchABIInfo::ABI::LPX32: return "abilpx32"; ++ case LoongArchABIInfo::ABI::LP64: return "abilp64"; ++ default: llvm_unreachable("Unknown LoongArch ABI"); ++ } ++} ++ ++void LoongArchAsmPrinter::emitFunctionEntryLabel() { ++ ++ OutStreamer->emitLabel(CurrentFnSym); ++ ++} ++ ++/// EmitFunctionBodyStart - Targets can override this to emit stuff before ++/// the first basic block in the function. ++void LoongArchAsmPrinter::emitFunctionBodyStart() { ++ ++ MCInstLowering.Initialize(&MF->getContext()); ++} ++ ++/// EmitFunctionBodyEnd - Targets can override this to emit stuff after ++/// the last basic block in the function. ++void LoongArchAsmPrinter::emitFunctionBodyEnd() { + +- const MachineOperand &MO = MI->getOperand(OpNo); ++ // Make sure to terminate any constant pools that were at the end ++ // of the function. ++ if (!InConstantPool) ++ return; ++ InConstantPool = false; ++ OutStreamer->emitDataRegion(MCDR_DataRegionEnd); ++} ++ ++void LoongArchAsmPrinter::emitBasicBlockEnd(const MachineBasicBlock &MBB) { ++ AsmPrinter::emitBasicBlockEnd(MBB); ++} ++ ++/// isBlockOnlyReachableByFallthough - Return true if the basic block has ++/// exactly one predecessor and the control transfer mechanism between ++/// the predecessor and this block is a fall-through. ++bool LoongArchAsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock* ++ MBB) const { ++ // The predecessor has to be immediately before this block. ++ const MachineBasicBlock *Pred = *MBB->pred_begin(); ++ ++ // If the predecessor is a switch statement, assume a jump table ++ // implementation, so it is not a fall through. ++ if (const BasicBlock *bb = Pred->getBasicBlock()) ++ if (isa(bb->getTerminator())) ++ return false; ++ ++ // Check default implementation ++ return AsmPrinter::isBlockOnlyReachableByFallthrough(MBB); ++} ++ ++// Print out an operand for an inline asm expression. ++bool LoongArchAsmPrinter::PrintAsmOperand(const MachineInstr *MI, ++ unsigned OpNum, const char *ExtraCode, raw_ostream &O) { ++ // Does this asm operand have a single letter operand modifier? + if (ExtraCode && ExtraCode[0]) { +- if (ExtraCode[1] != 0) +- return true; // Unknown modifier. ++ if (ExtraCode[1] != 0) return true; // Unknown modifier. + ++ const MachineOperand &MO = MI->getOperand(OpNum); + switch (ExtraCode[0]) { + default: +- return true; // Unknown modifier. +- case 'z': // Print $zero register if zero, regular printing otherwise. +- if (MO.isImm() && MO.getImm() == 0) { +- OS << '$' << LoongArchInstPrinter::getRegisterName(LoongArch::R0); ++ // See if this is a generic print operand ++ return AsmPrinter::PrintAsmOperand(MI,OpNum,ExtraCode,O); ++ case 'X': // hex const int ++ if ((MO.getType()) != MachineOperand::MO_Immediate) ++ return true; ++ O << "0x" << Twine::utohexstr(MO.getImm()); ++ return false; ++ case 'x': // hex const int (low 16 bits) ++ if ((MO.getType()) != MachineOperand::MO_Immediate) ++ return true; ++ O << "0x" << Twine::utohexstr(MO.getImm() & 0xffff); ++ return false; ++ case 'd': // decimal const int ++ if ((MO.getType()) != MachineOperand::MO_Immediate) ++ return true; ++ O << MO.getImm(); ++ return false; ++ case 'm': // decimal const int minus 1 ++ if ((MO.getType()) != MachineOperand::MO_Immediate) ++ return true; ++ O << MO.getImm() - 1; ++ return false; ++ case 'y': // exact log2 ++ if ((MO.getType()) != MachineOperand::MO_Immediate) ++ return true; ++ if (!isPowerOf2_64(MO.getImm())) ++ return true; ++ O << Log2_64(MO.getImm()); ++ return false; ++ case 'z': ++ // $r0 if zero, regular printing otherwise ++ if (MO.getType() == MachineOperand::MO_Immediate && MO.getImm() == 0) { ++ O << "$r0"; + return false; + } ++ // If not, call printOperand as normal. + break; +- case 'w': // Print LSX registers. +- if (MO.getReg().id() >= LoongArch::VR0 && +- MO.getReg().id() <= LoongArch::VR31) +- break; +- // The modifier is 'w' but the operand is not an LSX register; Report an +- // unknown operand error. +- return true; +- case 'u': // Print LASX registers. +- if (MO.getReg().id() >= LoongArch::XR0 && +- MO.getReg().id() <= LoongArch::XR31) +- break; +- // The modifier is 'u' but the operand is not an LASX register; Report an +- // unknown operand error. +- return true; +- // TODO: handle other extra codes if any. +- } +- } ++ case 'D': // Second part of a double word register operand ++ case 'L': // Low order register of a double word register operand ++ case 'M': // High order register of a double word register operand ++ { ++ if (OpNum == 0) ++ return true; ++ const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1); ++ if (!FlagsOP.isImm()) ++ return true; ++ const InlineAsm::Flag Flags(FlagsOP.getImm()); ++ const unsigned NumVals = Flags.getNumOperandRegisters(); ++ // Number of registers represented by this operand. We are looking ++ // for 2 for 32 bit mode and 1 for 64 bit mode. ++ if (NumVals != 2) { ++ if (Subtarget->is64Bit() && NumVals == 1 && MO.isReg()) { ++ unsigned Reg = MO.getReg(); ++ O << '$' << LoongArchInstPrinter::getRegisterName(Reg); ++ return false; ++ } ++ return true; ++ } + +- switch (MO.getType()) { +- case MachineOperand::MO_Immediate: +- OS << MO.getImm(); +- return false; +- case MachineOperand::MO_Register: +- OS << '$' << LoongArchInstPrinter::getRegisterName(MO.getReg()); +- return false; +- case MachineOperand::MO_GlobalAddress: +- PrintSymbolOperand(MO, OS); +- return false; +- default: +- llvm_unreachable("not implemented"); ++ unsigned RegOp = OpNum; ++ if (!Subtarget->is64Bit()){ ++ // Endianness reverses which register holds the high or low value ++ // between M and L. ++ switch(ExtraCode[0]) { ++ case 'M': ++ RegOp = OpNum + 1; ++ break; ++ case 'L': ++ RegOp = OpNum; ++ break; ++ case 'D': // Always the second part ++ RegOp = OpNum + 1; ++ } ++ if (RegOp >= MI->getNumOperands()) ++ return true; ++ const MachineOperand &MO = MI->getOperand(RegOp); ++ if (!MO.isReg()) ++ return true; ++ unsigned Reg = MO.getReg(); ++ O << '$' << LoongArchInstPrinter::getRegisterName(Reg); ++ return false; ++ } ++ break; ++ } ++ case 'w': ++ // Print LSX registers for the 'f' constraint ++ // In LLVM, the 'w' modifier doesn't need to do anything. ++ // We can just call printOperand as normal. ++ break; ++ case 'u': ++ // Print LASX registers for the 'f' constraint ++ // In LLVM, the 'u' modifier doesn't need to do anything. ++ // We can just call printOperand as normal. ++ break; ++ } + } + +- return true; ++ printOperand(MI, OpNum, O); ++ return false; + } + + bool LoongArchAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, +- unsigned OpNo, ++ unsigned OpNum, + const char *ExtraCode, +- raw_ostream &OS) { +- // TODO: handle extra code. +- if (ExtraCode) +- return true; +- +- // We only support memory operands like "Base + Offset", where base must be a +- // register, and offset can be a register or an immediate value. +- const MachineOperand &BaseMO = MI->getOperand(OpNo); +- // Base address must be a register. +- if (!BaseMO.isReg()) +- return true; +- // Print the base address register. +- OS << "$" << LoongArchInstPrinter::getRegisterName(BaseMO.getReg()); +- // Print the offset operand. +- const MachineOperand &OffsetMO = MI->getOperand(OpNo + 1); +- if (OffsetMO.isReg()) +- OS << ", $" << LoongArchInstPrinter::getRegisterName(OffsetMO.getReg()); +- else if (OffsetMO.isImm()) +- OS << ", " << OffsetMO.getImm(); +- else +- return true; ++ raw_ostream &O) { ++ assert(OpNum + 1 < MI->getNumOperands() && "Insufficient operands"); ++ const MachineOperand &BaseMO = MI->getOperand(OpNum); ++ const MachineOperand &OffsetMO = MI->getOperand(OpNum + 1); ++ assert(BaseMO.isReg() && "Unexpected base pointer for inline asm memory operand."); ++ assert(OffsetMO.isImm() && "Unexpected offset for inline asm memory operand."); ++ int Offset = OffsetMO.getImm(); ++ ++ // Currently we are expecting either no ExtraCode or 'D','M','L'. ++ if (ExtraCode) { ++ switch (ExtraCode[0]) { ++ case 'D': ++ case 'M': ++ Offset += 4; ++ break; ++ case 'L': ++ break; ++ default: ++ return true; // Unknown modifier. ++ } ++ } ++ ++ O << "$" << LoongArchInstPrinter::getRegisterName(BaseMO.getReg()) << ", " << Offset; + + return false; + } + +-void LoongArchAsmPrinter::LowerPATCHABLE_FUNCTION_ENTER( +- const MachineInstr &MI) { +- const Function &F = MF->getFunction(); +- if (F.hasFnAttribute("patchable-function-entry")) { +- unsigned Num; +- if (F.getFnAttribute("patchable-function-entry") +- .getValueAsString() +- .getAsInteger(10, Num)) ++void LoongArchAsmPrinter::printOperand(const MachineInstr *MI, int opNum, ++ raw_ostream &O) { ++ const MachineOperand &MO = MI->getOperand(opNum); ++ ++ switch (MO.getType()) { ++ case MachineOperand::MO_Register: ++ O << '$' ++ << StringRef(LoongArchInstPrinter::getRegisterName(MO.getReg())).lower(); ++ break; ++ ++ case MachineOperand::MO_Immediate: ++ O << MO.getImm(); ++ break; ++ ++ case MachineOperand::MO_MachineBasicBlock: ++ MO.getMBB()->getSymbol()->print(O, MAI); + return; +- emitNops(Num); +- return; ++ ++ case MachineOperand::MO_GlobalAddress: ++ getSymbol(MO.getGlobal())->print(O, MAI); ++ break; ++ ++ case MachineOperand::MO_BlockAddress: { ++ MCSymbol *BA = GetBlockAddressSymbol(MO.getBlockAddress()); ++ O << BA->getName(); ++ break; ++ } ++ ++ case MachineOperand::MO_ConstantPoolIndex: ++ O << getDataLayout().getPrivateGlobalPrefix() << "CPI" ++ << getFunctionNumber() << "_" << MO.getIndex(); ++ if (MO.getOffset()) ++ O << "+" << MO.getOffset(); ++ break; ++ ++ default: ++ llvm_unreachable(""); + } ++} ++ ++void LoongArchAsmPrinter:: ++printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O) { ++ // Load/Store memory operands -- imm($reg) ++ // If PIC target the target is loaded as the ++ // pattern lw $25,%call16($28) + +- emitSled(MI, SledKind::FUNCTION_ENTER); ++ printOperand(MI, opNum+1, O); ++ O << "("; ++ printOperand(MI, opNum, O); ++ O << ")"; + } + +-void LoongArchAsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI) { +- emitSled(MI, SledKind::FUNCTION_EXIT); ++void LoongArchAsmPrinter:: ++printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O) { ++ // when using stack locations for not load/store instructions ++ // print the same way as all normal 3 operand instructions. ++ printOperand(MI, opNum, O); ++ O << ", "; ++ printOperand(MI, opNum+1, O); + } + +-void LoongArchAsmPrinter::LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI) { +- emitSled(MI, SledKind::TAIL_CALL); ++void LoongArchAsmPrinter:: ++printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O) { ++ for (int i = opNum, e = MI->getNumOperands(); i != e; ++i) { ++ if (i != opNum) O << ", "; ++ printOperand(MI, i, O); ++ } ++} ++ ++void LoongArchAsmPrinter::emitStartOfAsmFile(Module &M) { ++ LoongArchTargetStreamer &TS = getTargetStreamer(); ++ ++ // LoongArchTargetStreamer has an initialization order problem when emitting an ++ // object file directly (see LoongArchTargetELFStreamer for full details). Work ++ // around it by re-initializing the PIC state here. ++ TS.setPic(OutContext.getObjectFileInfo()->isPositionIndependent()); ++ ++ // Compute LoongArch architecture attributes based on the default subtarget ++ // that we'd have constructed. Module level directives aren't LTO ++ // clean anyhow. ++ // FIXME: For ifunc related functions we could iterate over and look ++ // for a feature string that doesn't match the default one. ++ const Triple &TT = TM.getTargetTriple(); ++ StringRef CPU = LoongArch_MC::selectLoongArchCPU(TT, TM.getTargetCPU()); ++ StringRef FS = TM.getTargetFeatureString(); ++ const LoongArchTargetMachine &MTM = static_cast(TM); ++ const LoongArchSubtarget STI(TT, CPU, FS, MTM, std::nullopt); ++ ++ TS.updateABIInfo(STI); ++} ++ ++void LoongArchAsmPrinter::emitInlineAsmStart() const { ++ ++ OutStreamer->addBlankLine(); ++} ++ ++void LoongArchAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, ++ const MCSubtargetInfo *EndInfo) const { ++ OutStreamer->addBlankLine(); ++} ++ ++void LoongArchAsmPrinter::EmitInstrReg(const MCSubtargetInfo &STI, unsigned Opcode, ++ unsigned Reg) { ++ MCInst I; ++ I.setOpcode(Opcode); ++ I.addOperand(MCOperand::createReg(Reg)); ++ OutStreamer->emitInstruction(I, STI); ++} ++ ++void LoongArchAsmPrinter::EmitInstrRegReg(const MCSubtargetInfo &STI, ++ unsigned Opcode, unsigned Reg1, ++ unsigned Reg2) { ++ MCInst I; ++ // ++ // Because of the current td files for LoongArch32, the operands for MTC1 ++ // appear backwards from their normal assembly order. It's not a trivial ++ // change to fix this in the td file so we adjust for it here. ++ // ++ if (Opcode == LoongArch::MOVGR2FR_W) { ++ unsigned Temp = Reg1; ++ Reg1 = Reg2; ++ Reg2 = Temp; ++ } ++ I.setOpcode(Opcode); ++ I.addOperand(MCOperand::createReg(Reg1)); ++ I.addOperand(MCOperand::createReg(Reg2)); ++ OutStreamer->emitInstruction(I, STI); ++} ++ ++void LoongArchAsmPrinter::EmitInstrRegRegReg(const MCSubtargetInfo &STI, ++ unsigned Opcode, unsigned Reg1, ++ unsigned Reg2, unsigned Reg3) { ++ MCInst I; ++ I.setOpcode(Opcode); ++ I.addOperand(MCOperand::createReg(Reg1)); ++ I.addOperand(MCOperand::createReg(Reg2)); ++ I.addOperand(MCOperand::createReg(Reg3)); ++ OutStreamer->emitInstruction(I, STI); ++} ++ ++void LoongArchAsmPrinter::EmitMovFPIntPair(const MCSubtargetInfo &STI, ++ unsigned MovOpc, unsigned Reg1, ++ unsigned Reg2, unsigned FPReg1, ++ unsigned FPReg2, bool LE) { ++ if (!LE) { ++ unsigned temp = Reg1; ++ Reg1 = Reg2; ++ Reg2 = temp; ++ } ++ EmitInstrRegReg(STI, MovOpc, Reg1, FPReg1); ++ EmitInstrRegReg(STI, MovOpc, Reg2, FPReg2); + } + +-void LoongArchAsmPrinter::emitSled(const MachineInstr &MI, SledKind Kind) { ++void LoongArchAsmPrinter::EmitSled(const MachineInstr &MI, SledKind Kind) { ++ const uint8_t NoopsInSledCount = 11; + // For loongarch64 we want to emit the following pattern: + // +- // .Lxray_sled_beginN: +- // B .Lxray_sled_endN +- // 11 NOPs (44 bytes) +- // .Lxray_sled_endN: ++ // .Lxray_sled_N: ++ // ALIGN ++ // B .tmpN ++ // 11 NOP instructions (44 bytes) ++ // .tmpN + // +- // We need the extra bytes because at runtime they may be used for the +- // actual pattern defined at compiler-rt/lib/xray/xray_loongarch64.cpp. +- // The count here should be adjusted accordingly if the implementation +- // changes. +- const int8_t NoopsInSledCount = 11; ++ // We need the 44 bytes (11 instructions) because at runtime, we'd ++ // be patching over the full 48 bytes (12 instructions) with the following ++ // pattern: ++ // ++ // addi.d sp,sp, -16 ;create stack frame ++ // st.d ra, sp, 8 ;save return address ++ // lu12i.w t0,%%abs_hi20(__xray_FunctionEntry/Exit) ++ // ori t0,t0,%%abs_lo12(__xray_FunctionEntry/Exit) ++ // lu32i.d t0,%%abs64_lo20(__xray_FunctionEntry/Exit) ++ // lu52i.d t0,t0,%%abs64_hi12(__xray_FunctionEntry/Exit) ++ // lu12i.w t1,%%abs_hi20(function_id) ++ // ori t1,t1,%%abs_lo12(function_id) ;pass function id ++ // jirl ra, t0, 0 ;call Tracing hook ++ // ld.d ra, sp, 8 ;restore return address ++ // addi.d sp, sp, 16 ;delete stack frame ++ + OutStreamer->emitCodeAlignment(Align(4), &getSubtargetInfo()); +- MCSymbol *BeginOfSled = OutContext.createTempSymbol("xray_sled_begin"); +- MCSymbol *EndOfSled = OutContext.createTempSymbol("xray_sled_end"); +- OutStreamer->emitLabel(BeginOfSled); +- EmitToStreamer(*OutStreamer, +- MCInstBuilder(LoongArch::B) +- .addExpr(MCSymbolRefExpr::create(EndOfSled, OutContext))); +- emitNops(NoopsInSledCount); +- OutStreamer->emitLabel(EndOfSled); +- recordSled(BeginOfSled, MI, Kind, 2); ++ auto CurSled = OutContext.createTempSymbol("xray_sled_", true); ++ OutStreamer->emitLabel(CurSled); ++ auto Target = OutContext.createTempSymbol(); ++ ++ // Emit "B .tmpN" instruction, which jumps over the nop sled to the actual ++ // start of function ++ const MCExpr *TargetExpr = MCSymbolRefExpr::create( ++ Target, MCSymbolRefExpr::VariantKind::VK_None, OutContext); ++ EmitToStreamer(*OutStreamer, MCInstBuilder(LoongArch::BEQ) ++ .addReg(LoongArch::ZERO) ++ .addReg(LoongArch::ZERO) ++ .addExpr(TargetExpr)); ++ ++ for (int8_t I = 0; I < NoopsInSledCount; I++) ++ EmitToStreamer(*OutStreamer, MCInstBuilder(LoongArch::ANDI) ++ .addReg(LoongArch::ZERO) ++ .addReg(LoongArch::ZERO) ++ .addImm(0)); ++ ++ OutStreamer->emitLabel(Target); ++ recordSled(CurSled, MI, Kind, 2); + } + +-bool LoongArchAsmPrinter::runOnMachineFunction(MachineFunction &MF) { +- AsmPrinter::runOnMachineFunction(MF); +- // Emit the XRay table for this function. +- emitXRayTable(); +- return true; ++void LoongArchAsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI) { ++ EmitSled(MI, SledKind::FUNCTION_ENTER); ++} ++ ++void LoongArchAsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI) { ++ EmitSled(MI, SledKind::FUNCTION_EXIT); ++} ++ ++void LoongArchAsmPrinter::LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI) { ++ EmitSled(MI, SledKind::TAIL_CALL); ++} ++ ++void LoongArchAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, ++ raw_ostream &OS) { ++ // TODO: implement ++} ++ ++bool LoongArchAsmPrinter::isLongBranchPseudo(int Opcode) const { ++ return (Opcode == LoongArch::LONG_BRANCH_ADDIW ++ || Opcode == LoongArch::LONG_BRANCH_ADDIW2Op ++ || Opcode == LoongArch::LONG_BRANCH_ADDID ++ || Opcode == LoongArch::LONG_BRANCH_ADDID2Op ++ || Opcode == LoongArch::LONG_BRANCH_PCADDU12I); + } + + // Force static initialization. + extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchAsmPrinter() { + RegisterAsmPrinter X(getTheLoongArch32Target()); +- RegisterAsmPrinter Y(getTheLoongArch64Target()); ++ RegisterAsmPrinter A(getTheLoongArch64Target()); + } +diff --git a/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.h b/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.h +index 693456443..3e4ca8ed1 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.h ++++ b/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.h +@@ -1,4 +1,4 @@ +-//===- LoongArchAsmPrinter.h - LoongArch LLVM Assembly Printer -*- C++ -*--===// ++//===- LoongArchAsmPrinter.h - LoongArch LLVM Assembly Printer -----------*- C++ -*--===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -13,46 +13,123 @@ + #ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHASMPRINTER_H + #define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHASMPRINTER_H + ++#include "LoongArchMCInstLower.h" + #include "LoongArchSubtarget.h" + #include "llvm/CodeGen/AsmPrinter.h" + #include "llvm/MC/MCStreamer.h" + #include "llvm/Support/Compiler.h" ++#include ++#include ++#include + + namespace llvm { + +-class LLVM_LIBRARY_VISIBILITY LoongArchAsmPrinter : public AsmPrinter { +- const MCSubtargetInfo *STI; +- +-public: +- explicit LoongArchAsmPrinter(TargetMachine &TM, +- std::unique_ptr Streamer) +- : AsmPrinter(TM, std::move(Streamer)), STI(TM.getMCSubtargetInfo()) {} +- +- StringRef getPassName() const override { +- return "LoongArch Assembly Printer"; +- } ++class MCOperand; ++class MCSubtargetInfo; ++class MCSymbol; ++class MachineBasicBlock; ++class MachineConstantPool; ++class MachineFunction; ++class MachineInstr; ++class MachineOperand; ++class LoongArchFunctionInfo; ++class LoongArchTargetStreamer; ++class Module; ++class raw_ostream; ++class TargetMachine; + +- bool runOnMachineFunction(MachineFunction &MF) override; ++class LLVM_LIBRARY_VISIBILITY LoongArchAsmPrinter : public AsmPrinter { ++ LoongArchTargetStreamer &getTargetStreamer() const; + +- void emitInstruction(const MachineInstr *MI) override; ++ void EmitInstrWithMacroNoAT(const MachineInstr *MI); + +- bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, +- const char *ExtraCode, raw_ostream &OS) override; +- bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, +- const char *ExtraCode, raw_ostream &OS) override; ++ //===------------------------------------------------------------------===// ++ // XRay implementation ++ //===------------------------------------------------------------------===// + ++public: ++ // XRay-specific lowering for LoongArch. + void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI); + void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI); + void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI); +- void emitSled(const MachineInstr &MI, SledKind Kind); ++ ++private: ++ /// MCP - Keep a pointer to constantpool entries of the current ++ /// MachineFunction. ++ const MachineConstantPool *MCP = nullptr; ++ ++ /// InConstantPool - Maintain state when emitting a sequence of constant ++ /// pool entries so we can properly mark them as data regions. ++ bool InConstantPool = false; ++ ++ void EmitSled(const MachineInstr &MI, SledKind Kind); + + // tblgen'erated function. + bool emitPseudoExpansionLowering(MCStreamer &OutStreamer, + const MachineInstr *MI); +- // Wrapper needed for tblgenned pseudo lowering. +- bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const { +- return lowerLoongArchMachineOperandToMCOperand(MO, MCOp, *this); +- } ++ ++ // Emit PseudoReturn, PseudoReturn64, PseudoIndirectBranch, ++ // and PseudoIndirectBranch64 as a JIRL as appropriate ++ // for the target. ++ void emitPseudoIndirectBranch(MCStreamer &OutStreamer, ++ const MachineInstr *MI); ++ ++ void emitPseudoTailBranch(MCStreamer &OutStreamer, ++ const MachineInstr *MI); ++ ++ // lowerOperand - Convert a MachineOperand into the equivalent MCOperand. ++ bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp); ++ ++ void emitInlineAsmStart() const override; ++ ++ void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, ++ const MCSubtargetInfo *EndInfo) const override; ++ ++ void EmitInstrReg(const MCSubtargetInfo &STI, unsigned Opcode, unsigned Reg); ++ ++ void EmitInstrRegReg(const MCSubtargetInfo &STI, unsigned Opcode, ++ unsigned Reg1, unsigned Reg2); ++ ++ void EmitInstrRegRegReg(const MCSubtargetInfo &STI, unsigned Opcode, ++ unsigned Reg1, unsigned Reg2, unsigned Reg3); ++ ++ void EmitMovFPIntPair(const MCSubtargetInfo &STI, unsigned MovOpc, ++ unsigned Reg1, unsigned Reg2, unsigned FPReg1, ++ unsigned FPReg2, bool LE); ++ ++ bool isLongBranchPseudo(int Opcode) const; ++ ++public: ++ const LoongArchSubtarget *Subtarget; ++ const LoongArchFunctionInfo *LoongArchFI; ++ LoongArchMCInstLower MCInstLowering; ++ ++ explicit LoongArchAsmPrinter(TargetMachine &TM, ++ std::unique_ptr Streamer) ++ : AsmPrinter(TM, std::move(Streamer)), MCInstLowering(*this) {} ++ ++ StringRef getPassName() const override { return "LoongArch Assembly Printer"; } ++ ++ bool runOnMachineFunction(MachineFunction &MF) override; ++ ++ void emitInstruction(const MachineInstr *MI) override; ++ const char *getCurrentABIString() const; ++ void emitFunctionEntryLabel() override; ++ void emitFunctionBodyStart() override; ++ void emitFunctionBodyEnd() override; ++ void emitBasicBlockEnd(const MachineBasicBlock &MBB) override; ++ bool isBlockOnlyReachableByFallthrough( ++ const MachineBasicBlock* MBB) const override; ++ bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, ++ const char *ExtraCode, raw_ostream &O) override; ++ bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, ++ const char *ExtraCode, raw_ostream &O) override; ++ void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O); ++ void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O); ++ void printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O); ++ void printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O); ++ void emitStartOfAsmFile(Module &M) override; ++ void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS); + }; + + } // end namespace llvm +diff --git a/llvm/lib/Target/LoongArch/LoongArchCCState.cpp b/llvm/lib/Target/LoongArch/LoongArchCCState.cpp +new file mode 100644 +index 000000000..6630ca759 +--- /dev/null ++++ b/llvm/lib/Target/LoongArch/LoongArchCCState.cpp +@@ -0,0 +1,165 @@ ++//===---- LoongArchCCState.cpp - CCState with LoongArch specific extensions ---------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++#include "LoongArchCCState.h" ++#include "LoongArchSubtarget.h" ++#include "llvm/IR/Module.h" ++ ++using namespace llvm; ++ ++/// This function returns true if CallSym is a long double emulation routine. ++static bool isF128SoftLibCall(const char *CallSym) { ++ const char *const LibCalls[] = { ++ "__addtf3", "__divtf3", "__eqtf2", "__extenddftf2", ++ "__extendsftf2", "__fixtfdi", "__fixtfsi", "__fixtfti", ++ "__fixunstfdi", "__fixunstfsi", "__fixunstfti", "__floatditf", ++ "__floatsitf", "__floattitf", "__floatunditf", "__floatunsitf", ++ "__floatuntitf", "__getf2", "__gttf2", "__letf2", ++ "__lttf2", "__multf3", "__netf2", "__powitf2", ++ "__subtf3", "__trunctfdf2", "__trunctfsf2", "__unordtf2", ++ "ceill", "copysignl", "cosl", "exp2l", ++ "expl", "floorl", "fmal", "fmaxl", ++ "fmodl", "log10l", "log2l", "logl", ++ "nearbyintl", "powl", "rintl", "roundl", ++ "sinl", "sqrtl", "truncl"}; ++ ++ // Check that LibCalls is sorted alphabetically. ++ auto Comp = [](const char *S1, const char *S2) { return strcmp(S1, S2) < 0; }; ++ assert(std::is_sorted(std::begin(LibCalls), std::end(LibCalls), Comp)); ++ return std::binary_search(std::begin(LibCalls), std::end(LibCalls), ++ CallSym, Comp); ++} ++ ++/// This function returns true if Ty is fp128, {f128} or i128 which was ++/// originally a fp128. ++static bool originalTypeIsF128(const Type *Ty, const char *Func) { ++ if (Ty->isFP128Ty()) ++ return true; ++ ++ if (Ty->isStructTy() && Ty->getStructNumElements() == 1 && ++ Ty->getStructElementType(0)->isFP128Ty()) ++ return true; ++ ++ // If the Ty is i128 and the function being called is a long double emulation ++ // routine, then the original type is f128. ++ return (Func && Ty->isIntegerTy(128) && isF128SoftLibCall(Func)); ++} ++ ++/// Return true if the original type was vXfXX. ++static bool originalEVTTypeIsVectorFloat(EVT Ty) { ++ if (Ty.isVector() && Ty.getVectorElementType().isFloatingPoint()) ++ return true; ++ ++ return false; ++} ++ ++/// Return true if the original type was vXfXX / vXfXX. ++static bool originalTypeIsVectorFloat(const Type * Ty) { ++ if (Ty->isVectorTy() && Ty->isFPOrFPVectorTy()) ++ return true; ++ ++ return false; ++} ++ ++LoongArchCCState::SpecialCallingConvType ++LoongArchCCState::getSpecialCallingConvForCallee(const SDNode *Callee, ++ const LoongArchSubtarget &Subtarget) { ++ LoongArchCCState::SpecialCallingConvType SpecialCallingConv = NoSpecialCallingConv; ++ return SpecialCallingConv; ++} ++ ++void LoongArchCCState::PreAnalyzeCallResultForF128( ++ const SmallVectorImpl &Ins, ++ const Type *RetTy, const char *Call) { ++ for (unsigned i = 0; i < Ins.size(); ++i) { ++ OriginalArgWasF128.push_back( ++ originalTypeIsF128(RetTy, Call)); ++ OriginalArgWasFloat.push_back(RetTy->isFloatingPointTy()); ++ } ++} ++ ++/// Identify lowered values that originated from f128 or float arguments and ++/// record this for use by RetCC_LoongArchLP64LPX32. ++void LoongArchCCState::PreAnalyzeReturnForF128( ++ const SmallVectorImpl &Outs) { ++ const MachineFunction &MF = getMachineFunction(); ++ for (unsigned i = 0; i < Outs.size(); ++i) { ++ OriginalArgWasF128.push_back( ++ originalTypeIsF128(MF.getFunction().getReturnType(), nullptr)); ++ OriginalArgWasFloat.push_back( ++ MF.getFunction().getReturnType()->isFloatingPointTy()); ++ } ++} ++ ++/// Identify lower values that originated from vXfXX and record ++/// this. ++void LoongArchCCState::PreAnalyzeCallResultForVectorFloat( ++ const SmallVectorImpl &Ins, const Type *RetTy) { ++ for (unsigned i = 0; i < Ins.size(); ++i) { ++ OriginalRetWasFloatVector.push_back(originalTypeIsVectorFloat(RetTy)); ++ } ++} ++ ++/// Identify lowered values that originated from vXfXX arguments and record ++/// this. ++void LoongArchCCState::PreAnalyzeReturnForVectorFloat( ++ const SmallVectorImpl &Outs) { ++ for (unsigned i = 0; i < Outs.size(); ++i) { ++ ISD::OutputArg Out = Outs[i]; ++ OriginalRetWasFloatVector.push_back( ++ originalEVTTypeIsVectorFloat(Out.ArgVT)); ++ } ++} ++ ++/// Identify lowered values that originated from f128, float and sret to vXfXX ++/// arguments and record this. ++void LoongArchCCState::PreAnalyzeCallOperands( ++ const SmallVectorImpl &Outs, ++ std::vector &FuncArgs, ++ const char *Func) { ++ for (unsigned i = 0; i < Outs.size(); ++i) { ++ TargetLowering::ArgListEntry FuncArg = FuncArgs[Outs[i].OrigArgIndex]; ++ ++ OriginalArgWasF128.push_back(originalTypeIsF128(FuncArg.Ty, Func)); ++ OriginalArgWasFloat.push_back(FuncArg.Ty->isFloatingPointTy()); ++ OriginalArgWasFloatVector.push_back(FuncArg.Ty->isVectorTy()); ++ CallOperandIsFixed.push_back(Outs[i].IsFixed); ++ } ++} ++ ++/// Identify lowered values that originated from f128, float and vXfXX arguments ++/// and record this. ++void LoongArchCCState::PreAnalyzeFormalArgumentsForF128( ++ const SmallVectorImpl &Ins) { ++ const MachineFunction &MF = getMachineFunction(); ++ for (unsigned i = 0; i < Ins.size(); ++i) { ++ Function::const_arg_iterator FuncArg = MF.getFunction().arg_begin(); ++ ++ // SRet arguments cannot originate from f128 or {f128} returns so we just ++ // push false. We have to handle this specially since SRet arguments ++ // aren't mapped to an original argument. ++ if (Ins[i].Flags.isSRet()) { ++ OriginalArgWasF128.push_back(false); ++ OriginalArgWasFloat.push_back(false); ++ OriginalArgWasFloatVector.push_back(false); ++ continue; ++ } ++ ++ assert(Ins[i].getOrigArgIndex() < MF.getFunction().arg_size()); ++ std::advance(FuncArg, Ins[i].getOrigArgIndex()); ++ ++ OriginalArgWasF128.push_back( ++ originalTypeIsF128(FuncArg->getType(), nullptr)); ++ OriginalArgWasFloat.push_back(FuncArg->getType()->isFloatingPointTy()); ++ ++ // The LoongArch vector ABI exhibits a corner case of sorts or quirk; if the ++ // first argument is actually an SRet pointer to a vector, then the next ++ // argument slot is $a2. ++ OriginalArgWasFloatVector.push_back(FuncArg->getType()->isVectorTy()); ++ } ++} +diff --git a/llvm/lib/Target/LoongArch/LoongArchCCState.h b/llvm/lib/Target/LoongArch/LoongArchCCState.h +new file mode 100644 +index 000000000..1c1a1446e +--- /dev/null ++++ b/llvm/lib/Target/LoongArch/LoongArchCCState.h +@@ -0,0 +1,165 @@ ++//===---- LoongArchCCState.h - CCState with LoongArch specific extensions -----------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++#ifndef LoongArchCCSTATE_H ++#define LoongArchCCSTATE_H ++ ++#include "LoongArchISelLowering.h" ++#include "llvm/ADT/SmallVector.h" ++#include "llvm/CodeGen/CallingConvLower.h" ++ ++namespace llvm { ++class SDNode; ++class LoongArchSubtarget; ++ ++class LoongArchCCState : public CCState { ++public: ++ enum SpecialCallingConvType { NoSpecialCallingConv }; ++ ++ /// Determine the SpecialCallingConvType for the given callee ++ static SpecialCallingConvType ++ getSpecialCallingConvForCallee(const SDNode *Callee, ++ const LoongArchSubtarget &Subtarget); ++ ++private: ++ /// Identify lowered values that originated from f128 arguments and record ++ /// this for use by RetCC_LoongArchLP64LPX32. ++ void PreAnalyzeCallResultForF128(const SmallVectorImpl &Ins, ++ const Type *RetTy, const char * Func); ++ ++ /// Identify lowered values that originated from f128 arguments and record ++ /// this for use by RetCC_LoongArchLP64LPX32. ++ void PreAnalyzeReturnForF128(const SmallVectorImpl &Outs); ++ ++ /// Identify lowered values that originated from f128 arguments and record ++ /// this. ++ void ++ PreAnalyzeCallOperands(const SmallVectorImpl &Outs, ++ std::vector &FuncArgs, ++ const char *Func); ++ ++ /// Identify lowered values that originated from f128 arguments and record ++ /// this for use by RetCC_LoongArchLP64LPX32. ++ void ++ PreAnalyzeFormalArgumentsForF128(const SmallVectorImpl &Ins); ++ ++ void ++ PreAnalyzeCallResultForVectorFloat(const SmallVectorImpl &Ins, ++ const Type *RetTy); ++ ++ void PreAnalyzeFormalArgumentsForVectorFloat( ++ const SmallVectorImpl &Ins); ++ ++ void ++ PreAnalyzeReturnForVectorFloat(const SmallVectorImpl &Outs); ++ ++ /// Records whether the value has been lowered from an f128. ++ SmallVector OriginalArgWasF128; ++ ++ /// Records whether the value has been lowered from float. ++ SmallVector OriginalArgWasFloat; ++ ++ /// Records whether the value has been lowered from a floating point vector. ++ SmallVector OriginalArgWasFloatVector; ++ ++ /// Records whether the return value has been lowered from a floating point ++ /// vector. ++ SmallVector OriginalRetWasFloatVector; ++ ++ /// Records whether the value was a fixed argument. ++ /// See ISD::OutputArg::IsFixed, ++ SmallVector CallOperandIsFixed; ++ ++ // FIXME: This should probably be a fully fledged calling convention. ++ SpecialCallingConvType SpecialCallingConv; ++ ++public: ++ LoongArchCCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF, ++ SmallVectorImpl &locs, LLVMContext &C, ++ SpecialCallingConvType SpecialCC = NoSpecialCallingConv) ++ : CCState(CC, isVarArg, MF, locs, C), SpecialCallingConv(SpecialCC) {} ++ ++ void ++ AnalyzeCallOperands(const SmallVectorImpl &Outs, ++ CCAssignFn Fn, ++ std::vector &FuncArgs, ++ const char *Func) { ++ PreAnalyzeCallOperands(Outs, FuncArgs, Func); ++ CCState::AnalyzeCallOperands(Outs, Fn); ++ OriginalArgWasF128.clear(); ++ OriginalArgWasFloat.clear(); ++ OriginalArgWasFloatVector.clear(); ++ CallOperandIsFixed.clear(); ++ } ++ ++ // The AnalyzeCallOperands in the base class is not usable since we must ++ // provide a means of accessing ArgListEntry::IsFixed. Delete them from this ++ // class. This doesn't stop them being used via the base class though. ++ void AnalyzeCallOperands(const SmallVectorImpl &Outs, ++ CCAssignFn Fn) = delete; ++ void AnalyzeCallOperands(const SmallVectorImpl &Outs, ++ SmallVectorImpl &Flags, ++ CCAssignFn Fn) = delete; ++ ++ void AnalyzeFormalArguments(const SmallVectorImpl &Ins, ++ CCAssignFn Fn) { ++ PreAnalyzeFormalArgumentsForF128(Ins); ++ CCState::AnalyzeFormalArguments(Ins, Fn); ++ OriginalArgWasFloat.clear(); ++ OriginalArgWasF128.clear(); ++ OriginalArgWasFloatVector.clear(); ++ } ++ ++ void AnalyzeCallResult(const SmallVectorImpl &Ins, ++ CCAssignFn Fn, const Type *RetTy, ++ const char *Func) { ++ PreAnalyzeCallResultForF128(Ins, RetTy, Func); ++ PreAnalyzeCallResultForVectorFloat(Ins, RetTy); ++ CCState::AnalyzeCallResult(Ins, Fn); ++ OriginalArgWasFloat.clear(); ++ OriginalArgWasF128.clear(); ++ OriginalArgWasFloatVector.clear(); ++ } ++ ++ void AnalyzeReturn(const SmallVectorImpl &Outs, ++ CCAssignFn Fn) { ++ PreAnalyzeReturnForF128(Outs); ++ PreAnalyzeReturnForVectorFloat(Outs); ++ CCState::AnalyzeReturn(Outs, Fn); ++ OriginalArgWasFloat.clear(); ++ OriginalArgWasF128.clear(); ++ OriginalArgWasFloatVector.clear(); ++ } ++ ++ bool CheckReturn(const SmallVectorImpl &ArgsFlags, ++ CCAssignFn Fn) { ++ PreAnalyzeReturnForF128(ArgsFlags); ++ PreAnalyzeReturnForVectorFloat(ArgsFlags); ++ bool Return = CCState::CheckReturn(ArgsFlags, Fn); ++ OriginalArgWasFloat.clear(); ++ OriginalArgWasF128.clear(); ++ OriginalArgWasFloatVector.clear(); ++ return Return; ++ } ++ ++ bool WasOriginalArgF128(unsigned ValNo) { return OriginalArgWasF128[ValNo]; } ++ bool WasOriginalArgFloat(unsigned ValNo) { ++ return OriginalArgWasFloat[ValNo]; ++ } ++ bool WasOriginalArgVectorFloat(unsigned ValNo) const { ++ return OriginalArgWasFloatVector[ValNo]; ++ } ++ bool WasOriginalRetVectorFloat(unsigned ValNo) const { ++ return OriginalRetWasFloatVector[ValNo]; ++ } ++ bool IsCallOperandFixed(unsigned ValNo) { return CallOperandIsFixed[ValNo]; } ++ SpecialCallingConvType getSpecialCallingConv() { return SpecialCallingConv; } ++}; ++} ++ ++#endif +diff --git a/llvm/lib/Target/LoongArch/LoongArchCallingConv.td b/llvm/lib/Target/LoongArch/LoongArchCallingConv.td +index 984416316..e8564e85b 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchCallingConv.td ++++ b/llvm/lib/Target/LoongArch/LoongArchCallingConv.td +@@ -1,23 +1,310 @@ +-//=- LoongArchCallingConv.td - Calling Conventions LoongArch -*- tablegen -*-=// ++//===-- LoongArchCallingConv.td - Calling Conventions for LoongArch --*- tablegen -*-===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. + // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + // + //===----------------------------------------------------------------------===// ++// This describes the calling conventions for LoongArch architecture. ++//===----------------------------------------------------------------------===// ++ ++/// CCIfSubtarget - Match if the current subtarget has a feature F. ++class CCIfSubtarget ++ : CCIf" ++ "(State.getMachineFunction().getSubtarget()).", ++ F), ++ A>; ++ ++// The inverse of CCIfSubtarget ++class CCIfSubtargetNot : CCIfSubtarget; ++ ++/// Match if the original argument (before lowering) was a float. ++/// For example, this is true for i32's that were lowered from soft-float. ++class CCIfOrigArgWasNotFloat ++ : CCIf<"!static_cast(&State)->WasOriginalArgFloat(ValNo)", ++ A>; ++ ++/// Match if the original argument (before lowering) was a 128-bit float (i.e. ++/// long double). ++class CCIfOrigArgWasF128 ++ : CCIf<"static_cast(&State)->WasOriginalArgF128(ValNo)", A>; ++ ++/// Match if this specific argument is a vararg. ++/// This is slightly different fro CCIfIsVarArg which matches if any argument is ++/// a vararg. ++class CCIfArgIsVarArg ++ : CCIf<"!static_cast(&State)->IsCallOperandFixed(ValNo)", A>; ++ ++/// Match if the return was a floating point vector. ++class CCIfOrigArgWasNotVectorFloat ++ : CCIf<"!static_cast(&State)" ++ "->WasOriginalRetVectorFloat(ValNo)", A>; ++ ++/// Match if the special calling conv is the specified value. ++class CCIfSpecialCallingConv ++ : CCIf<"static_cast(&State)->getSpecialCallingConv() == " ++ "LoongArchCCState::" # CC, A>; ++ ++// For soft-float, f128 values are returned in A0_64 rather than V1_64. ++def RetCC_F128SoftFloat : CallingConv<[ ++ CCAssignToReg<[A0_64, A1_64]> ++]>; ++ + // +-// This describes the calling conventions for the LoongArch architecture. +-// ++// For hard-float, f128 values are returned as a pair of f64's rather than a ++// pair of i64's. ++def RetCC_F128HardFloat : CallingConv<[ ++ //CCBitConvertToType, ++ ++ // Contrary to the ABI documentation, a struct containing a long double is ++ // returned in $f0, and $f1 instead of the usual $f0, and $f2. This is to ++ // match the de facto ABI as implemented by GCC. ++ CCIfInReg>, ++ ++ CCAssignToReg<[A0_64, A1_64]> ++]>; ++ ++// Handle F128 specially since we can't identify the original type during the ++// tablegen-erated code. ++def RetCC_F128 : CallingConv<[ ++ CCIfSubtarget<"useSoftFloat()", ++ CCIfType<[i64], CCDelegateTo>>, ++ CCIfSubtargetNot<"useSoftFloat()", ++ CCIfType<[i64], CCDelegateTo>> ++]>; ++ ++//===----------------------------------------------------------------------===// ++// LoongArch LP32 Calling Convention ++//===----------------------------------------------------------------------===// ++ ++def CC_LoongArchLP32 : CallingConv<[ ++ // Promote i8/i16 arguments to i32. ++ CCIfType<[i1, i8, i16], CCPromoteToType>, ++ ++ // Integer values get stored in stack slots that are 4 bytes in ++ // size and 4-byte aligned. ++ CCIfType<[i32, f32], CCAssignToStack<4, 4>>, ++ ++ // Integer values get stored in stack slots that are 8 bytes in ++ // size and 8-byte aligned. ++ CCIfType<[f64], CCAssignToStack<8, 8>> ++]>; ++ ++// Only the return rules are defined here for LP32. The rules for argument ++// passing are defined in LoongArchISelLowering.cpp. ++def RetCC_LoongArchLP32 : CallingConv<[ ++ // Promote i1/i8/i16 return values to i32. ++ CCIfType<[i1, i8, i16], CCPromoteToType>, ++ ++ // i32 are returned in registers V0, V1, A0, A1, unless the original return ++ // type was a vector of floats. ++ CCIfOrigArgWasNotVectorFloat>>, ++ ++ // f32 are returned in registers F0, F2 ++ CCIfType<[f32], CCAssignToReg<[F0, F1]>>, ++ ++ // f64 arguments are returned in F0_64 and F2_64 in FP64bit mode or ++ // in F0 and F1 in FP32bit mode. ++ CCIfType<[f64], CCIfSubtarget<"isFP64bit()", CCAssignToReg<[F0_64, F1_64]>>> ++]>; ++ ++def CC_LoongArchLP32_FP32 : CustomCallingConv; ++def CC_LoongArchLP32_FP64 : CustomCallingConv; ++def CC_LoongArch_F128 : CustomCallingConv; ++ ++def CC_LoongArchLP32_FP : CallingConv<[ ++ CCIfSubtargetNot<"isFP64bit()", CCDelegateTo>, ++ CCIfSubtarget<"isFP64bit()", CCDelegateTo> ++]>; ++ ++//===----------------------------------------------------------------------===// ++// LoongArch LPX32/LP64 Calling Convention ++//===----------------------------------------------------------------------===// ++ ++def CC_LoongArchLP64LPX32_SoftFloat : CallingConv<[ ++ CCAssignToReg<[A0, A1, A2, A3, ++ A4, A5, A6, A7]>, ++ CCAssignToStack<4, 8> ++]>; ++ ++def CC_LoongArchLP64LPX32 : CallingConv<[ ++ ++ // All integers (except soft-float integers) are promoted to 64-bit. ++ CCIfType<[i8, i16, i32], CCIfOrigArgWasNotFloat>>, ++ ++ // The only i32's we have left are soft-float arguments. ++ CCIfSubtarget<"useSoftFloat()", CCIfType<[i32], CCDelegateTo>>, ++ ++ // Integer arguments are passed in integer registers. ++ //CCIfType<[i64], CCAssignToRegWithShadow<[A0_64, A1_64, A2_64, A3_64, ++ // A4_64, A5_64, A6_64, A7_64], ++ // [F0_64, F1_64, F2_64, F3_64, ++ // F4_64, F5_64, F6_64, F7_64]>>, ++ CCIfType<[i64], CCAssignToReg<[A0_64, A1_64, A2_64, A3_64, ++ A4_64, A5_64, A6_64, A7_64]>>, ++ ++ // f32 arguments are passed in single precision FP registers. ++ CCIfType<[f32], CCAssignToReg<[F0, F1, F2, F3, ++ F4, F5, F6, F7]>>, ++ ++ // f64 arguments are passed in double precision FP registers. ++ CCIfType<[f64], CCAssignToReg<[F0_64, F1_64, F2_64, F3_64, ++ F4_64, F5_64, F6_64, F7_64]>>, ++ ++ // others f32 arguments are passed in single precision FP registers. ++ CCIfType<[f32], CCAssignToReg<[A0, A1, A2, A3, A4, A5, A6, A7]>>, ++ ++ // others f64 arguments are passed in double precision FP registers. ++ CCIfType<[f64], CCAssignToReg<[A0_64, A1_64, A2_64, A3_64, ++ A4_64, A5_64, A6_64, A7_64]>>, ++ ++ CCIfSubtarget<"hasLSX()", ++ CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], ++ CCAssignToRegWithShadow<[VR0, VR1, VR2, VR3, VR4, VR5, VR6, VR7], ++ [A0_64, A1_64, A2_64, A3_64, ++ A4_64, A5_64, A6_64, A7_64]>>>, ++ CCIfSubtarget<"hasLASX()", ++ CCIfType<[v32i8, v16i16, v8i32, v4i64, v8f32, v4f64], ++ CCAssignToRegWithShadow<[XR0, XR1, XR2, XR3, XR4, XR5, XR6, XR7], ++ [A0_64, A1_64, A2_64, A3_64, ++ A4_64, A5_64, A6_64, A7_64]>>>, ++ ++ // All stack parameter slots become 64-bit doublewords and are 8-byte aligned. ++ CCIfType<[f32], CCAssignToStack<4, 8>>, ++ CCIfType<[i64, f64], CCAssignToStack<8, 8>>, ++ CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], ++ CCAssignToStack<16, 16>>, ++ CCIfType<[v32i8, v16i16, v8i32, v4i64, v8f32, v4f64], ++ CCAssignToStack<32, 32>> ++]>; ++ ++// LPX32/LP64 variable arguments. ++// All arguments are passed in integer registers. ++def CC_LoongArchLP64LPX32_VarArg : CallingConv<[ ++ // All integers are promoted to 64-bit. ++ CCIfType<[i8, i16, i32], CCPromoteToType>, ++ ++ CCIfType<[f32], CCAssignToReg<[A0, A1, A2, A3, A4, A5, A6, A7]>>, ++ ++ CCIfType<[i64], CCIfOrigArgWasF128>>, ++ ++ CCIfType<[i64, f64], CCAssignToReg<[A0_64, A1_64, A2_64, A3_64, ++ A4_64, A5_64, A6_64, A7_64]>>, ++ ++ // All stack parameter slots become 64-bit doublewords and are 8-byte aligned. ++ CCIfType<[f32], CCAssignToStack<4, 8>>, ++ CCIfType<[i64, f64], CCAssignToStack<8, 8>> ++]>; ++ ++def RetCC_LoongArchLP64LPX32 : CallingConv<[ ++ // f128 needs to be handled similarly to f32 and f64. However, f128 is not ++ // legal and is lowered to i128 which is further lowered to a pair of i64's. ++ // This presents us with a problem for the calling convention since hard-float ++ // still needs to pass them in FPU registers, and soft-float needs to use $v0, ++ // and $a0 instead of the usual $v0, and $v1. We therefore resort to a ++ // pre-analyze (see PreAnalyzeReturnForF128()) step to pass information on ++ // whether the result was originally an f128 into the tablegen-erated code. ++ // ++ // f128 should only occur for the LP64 ABI where long double is 128-bit. On ++ // LPX32, long double is equivalent to double. ++ CCIfType<[i64], CCIfOrigArgWasF128>>, ++ ++ CCIfType<[i8, i16, i32, i64], CCIfInReg>>, ++ ++ // i64 are returned in registers V0_64, V1_64 ++ CCIfType<[i64], CCAssignToReg<[A0_64, A1_64]>>, ++ ++ CCIfSubtarget<"hasLSX()", ++ CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], CCAssignToReg<[VR0]>>>, ++ ++ CCIfSubtarget<"hasLASX()", ++ CCIfType<[v32i8, v16i16, v8i32, v4i64, v8f32, v4f64], CCAssignToReg<[XR0]>>>, ++ ++ CCIfSubtarget<"hasLASX()", ++ CCIfType<[i64], CCAssignToReg<[A0_64, A1_64]>>>, ++ ++ // f32 are returned in registers F0, F2 ++ CCIfType<[f32], CCAssignToReg<[F0, F1]>>, ++ ++ // f64 are returned in registers D0, D2 ++ CCIfType<[f64], CCAssignToReg<[F0_64, F1_64]>> ++]>; ++ + //===----------------------------------------------------------------------===// ++// LoongArch Calling Convention Dispatch ++//===----------------------------------------------------------------------===// ++ ++def RetCC_LoongArch : CallingConv<[ ++ CCIfSubtarget<"isABI_LPX32()", CCDelegateTo>, ++ CCIfSubtarget<"isABI_LP64()", CCDelegateTo>, ++ CCDelegateTo ++]>; ++ ++def CC_LoongArch_ByVal : CallingConv<[ ++ CCIfSubtarget<"isABI_LP32()", CCIfByVal>>, ++ CCIfByVal> ++]>; ++ ++def CC_LoongArch_FixedArg : CallingConv<[ ++ CCIfByVal>, ++ //CCIfByVal>>, ++ ++ // f128 needs to be handled similarly to f32 and f64 on hard-float. However, ++ // f128 is not legal and is lowered to i128 which is further lowered to a pair ++ // of i64's. ++ // This presents us with a problem for the calling convention since hard-float ++ // still needs to pass them in FPU registers. We therefore resort to a ++ // pre-analyze (see PreAnalyzeFormalArgsForF128()) step to pass information on ++ // whether the argument was originally an f128 into the tablegen-erated code. ++ // ++ // f128 should only occur for the LP64 ABI where long double is 128-bit. On ++ // LPX32, long double is equivalent to double. ++ CCIfType<[i64], ++ CCIfSubtargetNot<"useSoftFloat()", ++ CCIfOrigArgWasF128>>>, ++ ++ CCIfSubtarget<"isABI_LP32()", CCDelegateTo>, ++ CCDelegateTo ++]>; ++ ++def CC_LoongArch_VarArg : CallingConv<[ ++ CCIfByVal>, ++ ++ CCIfSubtarget<"isABI_LP32()", CCDelegateTo>, ++ CCDelegateTo ++]>; ++ ++def CC_LoongArch : CallingConv<[ ++ CCIfVarArg>>, ++ CCDelegateTo ++]>; ++ ++//===----------------------------------------------------------------------===// ++// Callee-saved register lists. ++//===----------------------------------------------------------------------===// ++ ++def CSR_SingleFloatOnly : CalleeSavedRegs<(add (sequence "F%u", 31, 24), RA, FP, ++ (sequence "S%u", 8, 0))>; ++ ++//def CSR_LP32_FPXX : CalleeSavedRegs<(add (sequence "D%u", 15, 10), RA, FP, ++// (sequence "S%u", 8, 0))> { ++// let OtherPreserved = (add (decimate (sequence "F%u", 30, 20), 2)); ++//} + +-def CSR_ILP32S_LP64S +- : CalleeSavedRegs<(add R1, (sequence "R%u", 22, 31))>; ++def CSR_LP32 : CalleeSavedRegs<(add (sequence "F%u_64", 31, 24), RA, FP, ++ (sequence "S%u", 8, 0))>; + +-def CSR_ILP32F_LP64F +- : CalleeSavedRegs<(add CSR_ILP32S_LP64S, (sequence "F%u", 24, 31))>; ++//def CSR_LP32_FP64 : ++// CalleeSavedRegs<(add (decimate (sequence "D%u_64", 30, 20), 2), RA, FP, ++// (sequence "S%u", 8, 0))>; + +-def CSR_ILP32D_LP64D +- : CalleeSavedRegs<(add CSR_ILP32S_LP64S, (sequence "F%u_64", 24, 31))>; ++def CSR_LPX32 : CalleeSavedRegs<(add F20_64, F22_64, F24_64, F26_64, F28_64, ++ F30_64, RA_64, FP_64, ++ (sequence "S%u_64", 8, 0))>; + +-// Needed for implementation of LoongArchRegisterInfo::getNoPreservedMask() +-def CSR_NoRegs : CalleeSavedRegs<(add)>; ++//def CSR_LP64 : CalleeSavedRegs<(add (sequence "D%u_64", 31, 24), RA_64, SP_64, FP_64, ++def CSR_LP64 : CalleeSavedRegs<(add (sequence "F%u_64", 31, 24), RA_64, FP_64, ++ (sequence "S%u_64", 8, 0))>; +diff --git a/llvm/lib/Target/LoongArch/LoongArchExpandAtomicPseudoInsts.cpp b/llvm/lib/Target/LoongArch/LoongArchExpandAtomicPseudoInsts.cpp +deleted file mode 100644 +index 18a532b55..000000000 +--- a/llvm/lib/Target/LoongArch/LoongArchExpandAtomicPseudoInsts.cpp ++++ /dev/null +@@ -1,616 +0,0 @@ +-//==- LoongArchExpandAtomicPseudoInsts.cpp - Expand atomic pseudo instrs. -===// +-// +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +-// +-//===----------------------------------------------------------------------===// +-// +-// This file contains a pass that expands atomic pseudo instructions into +-// target instructions. This pass should be run at the last possible moment, +-// avoiding the possibility for other passes to break the requirements for +-// forward progress in the LL/SC block. +-// +-//===----------------------------------------------------------------------===// +- +-#include "LoongArch.h" +-#include "LoongArchInstrInfo.h" +-#include "LoongArchTargetMachine.h" +- +-#include "llvm/CodeGen/LivePhysRegs.h" +-#include "llvm/CodeGen/MachineFunctionPass.h" +-#include "llvm/CodeGen/MachineInstrBuilder.h" +- +-using namespace llvm; +- +-#define LoongArch_EXPAND_ATOMIC_PSEUDO_NAME \ +- "LoongArch atomic pseudo instruction expansion pass" +- +-namespace { +- +-class LoongArchExpandAtomicPseudo : public MachineFunctionPass { +-public: +- const LoongArchInstrInfo *TII; +- static char ID; +- +- LoongArchExpandAtomicPseudo() : MachineFunctionPass(ID) { +- initializeLoongArchExpandAtomicPseudoPass(*PassRegistry::getPassRegistry()); +- } +- +- bool runOnMachineFunction(MachineFunction &MF) override; +- +- StringRef getPassName() const override { +- return LoongArch_EXPAND_ATOMIC_PSEUDO_NAME; +- } +- +-private: +- bool expandMBB(MachineBasicBlock &MBB); +- bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI); +- bool expandAtomicBinOp(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, AtomicRMWInst::BinOp, +- bool IsMasked, int Width, +- MachineBasicBlock::iterator &NextMBBI); +- bool expandAtomicMinMaxOp(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, +- AtomicRMWInst::BinOp, bool IsMasked, int Width, +- MachineBasicBlock::iterator &NextMBBI); +- bool expandAtomicCmpXchg(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, bool IsMasked, +- int Width, MachineBasicBlock::iterator &NextMBBI); +-}; +- +-char LoongArchExpandAtomicPseudo::ID = 0; +- +-bool LoongArchExpandAtomicPseudo::runOnMachineFunction(MachineFunction &MF) { +- TII = +- static_cast(MF.getSubtarget().getInstrInfo()); +- bool Modified = false; +- for (auto &MBB : MF) +- Modified |= expandMBB(MBB); +- return Modified; +-} +- +-bool LoongArchExpandAtomicPseudo::expandMBB(MachineBasicBlock &MBB) { +- bool Modified = false; +- +- MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); +- while (MBBI != E) { +- MachineBasicBlock::iterator NMBBI = std::next(MBBI); +- Modified |= expandMI(MBB, MBBI, NMBBI); +- MBBI = NMBBI; +- } +- +- return Modified; +-} +- +-bool LoongArchExpandAtomicPseudo::expandMI( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI) { +- switch (MBBI->getOpcode()) { +- case LoongArch::PseudoMaskedAtomicSwap32: +- return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Xchg, true, 32, +- NextMBBI); +- case LoongArch::PseudoAtomicSwap32: +- return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Xchg, false, 32, +- NextMBBI); +- case LoongArch::PseudoMaskedAtomicLoadAdd32: +- return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Add, true, 32, NextMBBI); +- case LoongArch::PseudoMaskedAtomicLoadSub32: +- return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Sub, true, 32, NextMBBI); +- case LoongArch::PseudoAtomicLoadNand32: +- return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Nand, false, 32, +- NextMBBI); +- case LoongArch::PseudoAtomicLoadNand64: +- return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Nand, false, 64, +- NextMBBI); +- case LoongArch::PseudoMaskedAtomicLoadNand32: +- return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Nand, true, 32, +- NextMBBI); +- case LoongArch::PseudoAtomicLoadAdd32: +- return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Add, false, 32, +- NextMBBI); +- case LoongArch::PseudoAtomicLoadSub32: +- return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Sub, false, 32, +- NextMBBI); +- case LoongArch::PseudoAtomicLoadAnd32: +- return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::And, false, 32, +- NextMBBI); +- case LoongArch::PseudoAtomicLoadOr32: +- return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Or, false, 32, NextMBBI); +- case LoongArch::PseudoAtomicLoadXor32: +- return expandAtomicBinOp(MBB, MBBI, AtomicRMWInst::Xor, false, 32, +- NextMBBI); +- case LoongArch::PseudoMaskedAtomicLoadUMax32: +- return expandAtomicMinMaxOp(MBB, MBBI, AtomicRMWInst::UMax, true, 32, +- NextMBBI); +- case LoongArch::PseudoMaskedAtomicLoadUMin32: +- return expandAtomicMinMaxOp(MBB, MBBI, AtomicRMWInst::UMin, true, 32, +- NextMBBI); +- case LoongArch::PseudoCmpXchg32: +- return expandAtomicCmpXchg(MBB, MBBI, false, 32, NextMBBI); +- case LoongArch::PseudoCmpXchg64: +- return expandAtomicCmpXchg(MBB, MBBI, false, 64, NextMBBI); +- case LoongArch::PseudoMaskedCmpXchg32: +- return expandAtomicCmpXchg(MBB, MBBI, true, 32, NextMBBI); +- case LoongArch::PseudoMaskedAtomicLoadMax32: +- return expandAtomicMinMaxOp(MBB, MBBI, AtomicRMWInst::Max, true, 32, +- NextMBBI); +- case LoongArch::PseudoMaskedAtomicLoadMin32: +- return expandAtomicMinMaxOp(MBB, MBBI, AtomicRMWInst::Min, true, 32, +- NextMBBI); +- } +- return false; +-} +- +-static void doAtomicBinOpExpansion(const LoongArchInstrInfo *TII, +- MachineInstr &MI, DebugLoc DL, +- MachineBasicBlock *ThisMBB, +- MachineBasicBlock *LoopMBB, +- MachineBasicBlock *DoneMBB, +- AtomicRMWInst::BinOp BinOp, int Width) { +- Register DestReg = MI.getOperand(0).getReg(); +- Register ScratchReg = MI.getOperand(1).getReg(); +- Register AddrReg = MI.getOperand(2).getReg(); +- Register IncrReg = MI.getOperand(3).getReg(); +- +- // .loop: +- // ll.[w|d] dest, (addr) +- // binop scratch, dest, val +- // sc.[w|d] scratch, scratch, (addr) +- // beqz scratch, loop +- BuildMI(LoopMBB, DL, +- TII->get(Width == 32 ? LoongArch::LL_W : LoongArch::LL_D), DestReg) +- .addReg(AddrReg) +- .addImm(0); +- switch (BinOp) { +- default: +- llvm_unreachable("Unexpected AtomicRMW BinOp"); +- case AtomicRMWInst::Xchg: +- BuildMI(LoopMBB, DL, TII->get(LoongArch::OR), ScratchReg) +- .addReg(IncrReg) +- .addReg(LoongArch::R0); +- break; +- case AtomicRMWInst::Nand: +- BuildMI(LoopMBB, DL, TII->get(LoongArch::AND), ScratchReg) +- .addReg(DestReg) +- .addReg(IncrReg); +- BuildMI(LoopMBB, DL, TII->get(LoongArch::NOR), ScratchReg) +- .addReg(ScratchReg) +- .addReg(LoongArch::R0); +- break; +- case AtomicRMWInst::Add: +- BuildMI(LoopMBB, DL, TII->get(LoongArch::ADD_W), ScratchReg) +- .addReg(DestReg) +- .addReg(IncrReg); +- break; +- case AtomicRMWInst::Sub: +- BuildMI(LoopMBB, DL, TII->get(LoongArch::SUB_W), ScratchReg) +- .addReg(DestReg) +- .addReg(IncrReg); +- break; +- case AtomicRMWInst::And: +- BuildMI(LoopMBB, DL, TII->get(LoongArch::AND), ScratchReg) +- .addReg(DestReg) +- .addReg(IncrReg); +- break; +- case AtomicRMWInst::Or: +- BuildMI(LoopMBB, DL, TII->get(LoongArch::OR), ScratchReg) +- .addReg(DestReg) +- .addReg(IncrReg); +- break; +- case AtomicRMWInst::Xor: +- BuildMI(LoopMBB, DL, TII->get(LoongArch::XOR), ScratchReg) +- .addReg(DestReg) +- .addReg(IncrReg); +- break; +- } +- BuildMI(LoopMBB, DL, +- TII->get(Width == 32 ? LoongArch::SC_W : LoongArch::SC_D), ScratchReg) +- .addReg(ScratchReg) +- .addReg(AddrReg) +- .addImm(0); +- BuildMI(LoopMBB, DL, TII->get(LoongArch::BEQZ)) +- .addReg(ScratchReg) +- .addMBB(LoopMBB); +-} +- +-static void insertMaskedMerge(const LoongArchInstrInfo *TII, DebugLoc DL, +- MachineBasicBlock *MBB, Register DestReg, +- Register OldValReg, Register NewValReg, +- Register MaskReg, Register ScratchReg) { +- assert(OldValReg != ScratchReg && "OldValReg and ScratchReg must be unique"); +- assert(OldValReg != MaskReg && "OldValReg and MaskReg must be unique"); +- assert(ScratchReg != MaskReg && "ScratchReg and MaskReg must be unique"); +- +- // res = oldval ^ ((oldval ^ newval) & masktargetdata); +- BuildMI(MBB, DL, TII->get(LoongArch::XOR), ScratchReg) +- .addReg(OldValReg) +- .addReg(NewValReg); +- BuildMI(MBB, DL, TII->get(LoongArch::AND), ScratchReg) +- .addReg(ScratchReg) +- .addReg(MaskReg); +- BuildMI(MBB, DL, TII->get(LoongArch::XOR), DestReg) +- .addReg(OldValReg) +- .addReg(ScratchReg); +-} +- +-static void doMaskedAtomicBinOpExpansion( +- const LoongArchInstrInfo *TII, MachineInstr &MI, DebugLoc DL, +- MachineBasicBlock *ThisMBB, MachineBasicBlock *LoopMBB, +- MachineBasicBlock *DoneMBB, AtomicRMWInst::BinOp BinOp, int Width) { +- assert(Width == 32 && "Should never need to expand masked 64-bit operations"); +- Register DestReg = MI.getOperand(0).getReg(); +- Register ScratchReg = MI.getOperand(1).getReg(); +- Register AddrReg = MI.getOperand(2).getReg(); +- Register IncrReg = MI.getOperand(3).getReg(); +- Register MaskReg = MI.getOperand(4).getReg(); +- +- // .loop: +- // ll.w destreg, (alignedaddr) +- // binop scratch, destreg, incr +- // xor scratch, destreg, scratch +- // and scratch, scratch, masktargetdata +- // xor scratch, destreg, scratch +- // sc.w scratch, scratch, (alignedaddr) +- // beqz scratch, loop +- BuildMI(LoopMBB, DL, TII->get(LoongArch::LL_W), DestReg) +- .addReg(AddrReg) +- .addImm(0); +- switch (BinOp) { +- default: +- llvm_unreachable("Unexpected AtomicRMW BinOp"); +- case AtomicRMWInst::Xchg: +- BuildMI(LoopMBB, DL, TII->get(LoongArch::ADDI_W), ScratchReg) +- .addReg(IncrReg) +- .addImm(0); +- break; +- case AtomicRMWInst::Add: +- BuildMI(LoopMBB, DL, TII->get(LoongArch::ADD_W), ScratchReg) +- .addReg(DestReg) +- .addReg(IncrReg); +- break; +- case AtomicRMWInst::Sub: +- BuildMI(LoopMBB, DL, TII->get(LoongArch::SUB_W), ScratchReg) +- .addReg(DestReg) +- .addReg(IncrReg); +- break; +- case AtomicRMWInst::Nand: +- BuildMI(LoopMBB, DL, TII->get(LoongArch::AND), ScratchReg) +- .addReg(DestReg) +- .addReg(IncrReg); +- BuildMI(LoopMBB, DL, TII->get(LoongArch::NOR), ScratchReg) +- .addReg(ScratchReg) +- .addReg(LoongArch::R0); +- // TODO: support other AtomicRMWInst. +- } +- +- insertMaskedMerge(TII, DL, LoopMBB, ScratchReg, DestReg, ScratchReg, MaskReg, +- ScratchReg); +- +- BuildMI(LoopMBB, DL, TII->get(LoongArch::SC_W), ScratchReg) +- .addReg(ScratchReg) +- .addReg(AddrReg) +- .addImm(0); +- BuildMI(LoopMBB, DL, TII->get(LoongArch::BEQZ)) +- .addReg(ScratchReg) +- .addMBB(LoopMBB); +-} +- +-bool LoongArchExpandAtomicPseudo::expandAtomicBinOp( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- AtomicRMWInst::BinOp BinOp, bool IsMasked, int Width, +- MachineBasicBlock::iterator &NextMBBI) { +- MachineInstr &MI = *MBBI; +- DebugLoc DL = MI.getDebugLoc(); +- +- MachineFunction *MF = MBB.getParent(); +- auto LoopMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock()); +- auto DoneMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock()); +- +- // Insert new MBBs. +- MF->insert(++MBB.getIterator(), LoopMBB); +- MF->insert(++LoopMBB->getIterator(), DoneMBB); +- +- // Set up successors and transfer remaining instructions to DoneMBB. +- LoopMBB->addSuccessor(LoopMBB); +- LoopMBB->addSuccessor(DoneMBB); +- DoneMBB->splice(DoneMBB->end(), &MBB, MI, MBB.end()); +- DoneMBB->transferSuccessors(&MBB); +- MBB.addSuccessor(LoopMBB); +- +- if (IsMasked) +- doMaskedAtomicBinOpExpansion(TII, MI, DL, &MBB, LoopMBB, DoneMBB, BinOp, +- Width); +- else +- doAtomicBinOpExpansion(TII, MI, DL, &MBB, LoopMBB, DoneMBB, BinOp, Width); +- +- NextMBBI = MBB.end(); +- MI.eraseFromParent(); +- +- LivePhysRegs LiveRegs; +- computeAndAddLiveIns(LiveRegs, *LoopMBB); +- computeAndAddLiveIns(LiveRegs, *DoneMBB); +- +- return true; +-} +- +-static void insertSext(const LoongArchInstrInfo *TII, DebugLoc DL, +- MachineBasicBlock *MBB, Register ValReg, +- Register ShamtReg) { +- BuildMI(MBB, DL, TII->get(LoongArch::SLL_W), ValReg) +- .addReg(ValReg) +- .addReg(ShamtReg); +- BuildMI(MBB, DL, TII->get(LoongArch::SRA_W), ValReg) +- .addReg(ValReg) +- .addReg(ShamtReg); +-} +- +-bool LoongArchExpandAtomicPseudo::expandAtomicMinMaxOp( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- AtomicRMWInst::BinOp BinOp, bool IsMasked, int Width, +- MachineBasicBlock::iterator &NextMBBI) { +- assert(IsMasked == true && +- "Should only need to expand masked atomic max/min"); +- assert(Width == 32 && "Should never need to expand masked 64-bit operations"); +- +- MachineInstr &MI = *MBBI; +- DebugLoc DL = MI.getDebugLoc(); +- MachineFunction *MF = MBB.getParent(); +- auto LoopHeadMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock()); +- auto LoopIfBodyMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock()); +- auto LoopTailMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock()); +- auto DoneMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock()); +- +- // Insert new MBBs. +- MF->insert(++MBB.getIterator(), LoopHeadMBB); +- MF->insert(++LoopHeadMBB->getIterator(), LoopIfBodyMBB); +- MF->insert(++LoopIfBodyMBB->getIterator(), LoopTailMBB); +- MF->insert(++LoopTailMBB->getIterator(), DoneMBB); +- +- // Set up successors and transfer remaining instructions to DoneMBB. +- LoopHeadMBB->addSuccessor(LoopIfBodyMBB); +- LoopHeadMBB->addSuccessor(LoopTailMBB); +- LoopIfBodyMBB->addSuccessor(LoopTailMBB); +- LoopTailMBB->addSuccessor(LoopHeadMBB); +- LoopTailMBB->addSuccessor(DoneMBB); +- DoneMBB->splice(DoneMBB->end(), &MBB, MI, MBB.end()); +- DoneMBB->transferSuccessors(&MBB); +- MBB.addSuccessor(LoopHeadMBB); +- +- Register DestReg = MI.getOperand(0).getReg(); +- Register Scratch1Reg = MI.getOperand(1).getReg(); +- Register Scratch2Reg = MI.getOperand(2).getReg(); +- Register AddrReg = MI.getOperand(3).getReg(); +- Register IncrReg = MI.getOperand(4).getReg(); +- Register MaskReg = MI.getOperand(5).getReg(); +- +- // +- // .loophead: +- // ll.w destreg, (alignedaddr) +- // and scratch2, destreg, mask +- // move scratch1, destreg +- BuildMI(LoopHeadMBB, DL, TII->get(LoongArch::LL_W), DestReg) +- .addReg(AddrReg) +- .addImm(0); +- BuildMI(LoopHeadMBB, DL, TII->get(LoongArch::AND), Scratch2Reg) +- .addReg(DestReg) +- .addReg(MaskReg); +- BuildMI(LoopHeadMBB, DL, TII->get(LoongArch::OR), Scratch1Reg) +- .addReg(DestReg) +- .addReg(LoongArch::R0); +- +- switch (BinOp) { +- default: +- llvm_unreachable("Unexpected AtomicRMW BinOp"); +- // bgeu scratch2, incr, .looptail +- case AtomicRMWInst::UMax: +- BuildMI(LoopHeadMBB, DL, TII->get(LoongArch::BGEU)) +- .addReg(Scratch2Reg) +- .addReg(IncrReg) +- .addMBB(LoopTailMBB); +- break; +- // bgeu incr, scratch2, .looptail +- case AtomicRMWInst::UMin: +- BuildMI(LoopHeadMBB, DL, TII->get(LoongArch::BGEU)) +- .addReg(IncrReg) +- .addReg(Scratch2Reg) +- .addMBB(LoopTailMBB); +- break; +- case AtomicRMWInst::Max: +- insertSext(TII, DL, LoopHeadMBB, Scratch2Reg, MI.getOperand(6).getReg()); +- // bge scratch2, incr, .looptail +- BuildMI(LoopHeadMBB, DL, TII->get(LoongArch::BGE)) +- .addReg(Scratch2Reg) +- .addReg(IncrReg) +- .addMBB(LoopTailMBB); +- break; +- case AtomicRMWInst::Min: +- insertSext(TII, DL, LoopHeadMBB, Scratch2Reg, MI.getOperand(6).getReg()); +- // bge incr, scratch2, .looptail +- BuildMI(LoopHeadMBB, DL, TII->get(LoongArch::BGE)) +- .addReg(IncrReg) +- .addReg(Scratch2Reg) +- .addMBB(LoopTailMBB); +- break; +- // TODO: support other AtomicRMWInst. +- } +- +- // .loopifbody: +- // xor scratch1, destreg, incr +- // and scratch1, scratch1, mask +- // xor scratch1, destreg, scratch1 +- insertMaskedMerge(TII, DL, LoopIfBodyMBB, Scratch1Reg, DestReg, IncrReg, +- MaskReg, Scratch1Reg); +- +- // .looptail: +- // sc.w scratch1, scratch1, (addr) +- // beqz scratch1, loop +- BuildMI(LoopTailMBB, DL, TII->get(LoongArch::SC_W), Scratch1Reg) +- .addReg(Scratch1Reg) +- .addReg(AddrReg) +- .addImm(0); +- BuildMI(LoopTailMBB, DL, TII->get(LoongArch::BEQZ)) +- .addReg(Scratch1Reg) +- .addMBB(LoopHeadMBB); +- +- NextMBBI = MBB.end(); +- MI.eraseFromParent(); +- +- LivePhysRegs LiveRegs; +- computeAndAddLiveIns(LiveRegs, *LoopHeadMBB); +- computeAndAddLiveIns(LiveRegs, *LoopIfBodyMBB); +- computeAndAddLiveIns(LiveRegs, *LoopTailMBB); +- computeAndAddLiveIns(LiveRegs, *DoneMBB); +- +- return true; +-} +- +-bool LoongArchExpandAtomicPseudo::expandAtomicCmpXchg( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, bool IsMasked, +- int Width, MachineBasicBlock::iterator &NextMBBI) { +- MachineInstr &MI = *MBBI; +- DebugLoc DL = MI.getDebugLoc(); +- MachineFunction *MF = MBB.getParent(); +- auto LoopHeadMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock()); +- auto LoopTailMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock()); +- auto TailMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock()); +- auto DoneMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock()); +- +- // Insert new MBBs. +- MF->insert(++MBB.getIterator(), LoopHeadMBB); +- MF->insert(++LoopHeadMBB->getIterator(), LoopTailMBB); +- MF->insert(++LoopTailMBB->getIterator(), TailMBB); +- MF->insert(++TailMBB->getIterator(), DoneMBB); +- +- // Set up successors and transfer remaining instructions to DoneMBB. +- LoopHeadMBB->addSuccessor(LoopTailMBB); +- LoopHeadMBB->addSuccessor(TailMBB); +- LoopTailMBB->addSuccessor(DoneMBB); +- LoopTailMBB->addSuccessor(LoopHeadMBB); +- TailMBB->addSuccessor(DoneMBB); +- DoneMBB->splice(DoneMBB->end(), &MBB, MI, MBB.end()); +- DoneMBB->transferSuccessors(&MBB); +- MBB.addSuccessor(LoopHeadMBB); +- +- Register DestReg = MI.getOperand(0).getReg(); +- Register ScratchReg = MI.getOperand(1).getReg(); +- Register AddrReg = MI.getOperand(2).getReg(); +- Register CmpValReg = MI.getOperand(3).getReg(); +- Register NewValReg = MI.getOperand(4).getReg(); +- +- if (!IsMasked) { +- // .loophead: +- // ll.[w|d] dest, (addr) +- // bne dest, cmpval, tail +- BuildMI(LoopHeadMBB, DL, +- TII->get(Width == 32 ? LoongArch::LL_W : LoongArch::LL_D), DestReg) +- .addReg(AddrReg) +- .addImm(0); +- BuildMI(LoopHeadMBB, DL, TII->get(LoongArch::BNE)) +- .addReg(DestReg) +- .addReg(CmpValReg) +- .addMBB(TailMBB); +- // .looptail: +- // move scratch, newval +- // sc.[w|d] scratch, scratch, (addr) +- // beqz scratch, loophead +- // b done +- BuildMI(LoopTailMBB, DL, TII->get(LoongArch::OR), ScratchReg) +- .addReg(NewValReg) +- .addReg(LoongArch::R0); +- BuildMI(LoopTailMBB, DL, +- TII->get(Width == 32 ? LoongArch::SC_W : LoongArch::SC_D), +- ScratchReg) +- .addReg(ScratchReg) +- .addReg(AddrReg) +- .addImm(0); +- BuildMI(LoopTailMBB, DL, TII->get(LoongArch::BEQZ)) +- .addReg(ScratchReg) +- .addMBB(LoopHeadMBB); +- BuildMI(LoopTailMBB, DL, TII->get(LoongArch::B)).addMBB(DoneMBB); +- } else { +- // .loophead: +- // ll.[w|d] dest, (addr) +- // and scratch, dest, mask +- // bne scratch, cmpval, tail +- Register MaskReg = MI.getOperand(5).getReg(); +- BuildMI(LoopHeadMBB, DL, +- TII->get(Width == 32 ? LoongArch::LL_W : LoongArch::LL_D), DestReg) +- .addReg(AddrReg) +- .addImm(0); +- BuildMI(LoopHeadMBB, DL, TII->get(LoongArch::AND), ScratchReg) +- .addReg(DestReg) +- .addReg(MaskReg); +- BuildMI(LoopHeadMBB, DL, TII->get(LoongArch::BNE)) +- .addReg(ScratchReg) +- .addReg(CmpValReg) +- .addMBB(TailMBB); +- +- // .looptail: +- // andn scratch, dest, mask +- // or scratch, scratch, newval +- // sc.[w|d] scratch, scratch, (addr) +- // beqz scratch, loophead +- // b done +- BuildMI(LoopTailMBB, DL, TII->get(LoongArch::ANDN), ScratchReg) +- .addReg(DestReg) +- .addReg(MaskReg); +- BuildMI(LoopTailMBB, DL, TII->get(LoongArch::OR), ScratchReg) +- .addReg(ScratchReg) +- .addReg(NewValReg); +- BuildMI(LoopTailMBB, DL, +- TII->get(Width == 32 ? LoongArch::SC_W : LoongArch::SC_D), +- ScratchReg) +- .addReg(ScratchReg) +- .addReg(AddrReg) +- .addImm(0); +- BuildMI(LoopTailMBB, DL, TII->get(LoongArch::BEQZ)) +- .addReg(ScratchReg) +- .addMBB(LoopHeadMBB); +- BuildMI(LoopTailMBB, DL, TII->get(LoongArch::B)).addMBB(DoneMBB); +- } +- +- AtomicOrdering FailureOrdering = +- static_cast(MI.getOperand(IsMasked ? 6 : 5).getImm()); +- int hint; +- +- switch (FailureOrdering) { +- case AtomicOrdering::Acquire: +- case AtomicOrdering::AcquireRelease: +- case AtomicOrdering::SequentiallyConsistent: +- // acquire +- hint = 0b10100; +- break; +- default: +- hint = 0x700; +- } +- +- // .tail: +- // dbar 0x700 | acquire +- BuildMI(TailMBB, DL, TII->get(LoongArch::DBAR)).addImm(hint); +- +- NextMBBI = MBB.end(); +- MI.eraseFromParent(); +- +- LivePhysRegs LiveRegs; +- computeAndAddLiveIns(LiveRegs, *LoopHeadMBB); +- computeAndAddLiveIns(LiveRegs, *LoopTailMBB); +- computeAndAddLiveIns(LiveRegs, *TailMBB); +- computeAndAddLiveIns(LiveRegs, *DoneMBB); +- +- return true; +-} +- +-} // end namespace +- +-INITIALIZE_PASS(LoongArchExpandAtomicPseudo, "loongarch-expand-atomic-pseudo", +- LoongArch_EXPAND_ATOMIC_PSEUDO_NAME, false, false) +- +-namespace llvm { +- +-FunctionPass *createLoongArchExpandAtomicPseudoPass() { +- return new LoongArchExpandAtomicPseudo(); +-} +- +-} // end namespace llvm +diff --git a/llvm/lib/Target/LoongArch/LoongArchExpandPseudo.cpp b/llvm/lib/Target/LoongArch/LoongArchExpandPseudo.cpp +new file mode 100644 +index 000000000..07cb50610 +--- /dev/null ++++ b/llvm/lib/Target/LoongArch/LoongArchExpandPseudo.cpp +@@ -0,0 +1,2484 @@ ++//===-- LoongArchExpandPseudoInsts.cpp - Expand pseudo instructions ------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++// ++// This file contains a pass that expands pseudo instructions into target ++// instructions to allow proper scheduling, if-conversion, and other late ++// optimizations. This pass should be run after register allocation but before ++// the post-regalloc scheduling pass. ++// ++// This is currently only used for expanding atomic pseudos after register ++// allocation. We do this to avoid the fast register allocator introducing ++// spills between ll and sc. These stores cause some LoongArch implementations to ++// abort the atomic RMW sequence. ++// ++//===----------------------------------------------------------------------===// ++ ++#include "LoongArch.h" ++#include "LoongArchInstrInfo.h" ++#include "LoongArchSubtarget.h" ++#include "MCTargetDesc/LoongArchMCTargetDesc.h" ++#include "llvm/CodeGen/LivePhysRegs.h" ++#include "llvm/CodeGen/MachineFunctionPass.h" ++#include "llvm/CodeGen/MachineInstrBuilder.h" ++ ++using namespace llvm; ++ ++#define DEBUG_TYPE "loongarch-pseudo" ++ ++namespace { ++ class LoongArchExpandPseudo : public MachineFunctionPass { ++ public: ++ static char ID; ++ LoongArchExpandPseudo() : MachineFunctionPass(ID) {} ++ ++ const LoongArchInstrInfo *TII; ++ const LoongArchSubtarget *STI; ++ ++ bool runOnMachineFunction(MachineFunction &Fn) override; ++ ++ MachineFunctionProperties getRequiredProperties() const override { ++ return MachineFunctionProperties().set( ++ MachineFunctionProperties::Property::NoVRegs); ++ } ++ ++ StringRef getPassName() const override { ++ return "LoongArch pseudo instruction expansion pass"; ++ } ++ ++ private: ++ bool expandAtomicCmpSwap(MachineBasicBlock &MBB, ++ MachineBasicBlock::iterator MBBI, ++ MachineBasicBlock::iterator &NextMBBI); ++ bool expandAtomicCmpSwapSubword(MachineBasicBlock &MBB, ++ MachineBasicBlock::iterator MBBI, ++ MachineBasicBlock::iterator &NextMBBI); ++ ++ bool expandAtomicBinOp(MachineBasicBlock &BB, ++ MachineBasicBlock::iterator I, ++ MachineBasicBlock::iterator &NMBBI, unsigned Size); ++ bool expandXINSERT_BOp(MachineBasicBlock &BB, MachineBasicBlock::iterator I, ++ MachineBasicBlock::iterator &NMBBI); ++ bool expandINSERT_HOp(MachineBasicBlock &BB, MachineBasicBlock::iterator I, ++ MachineBasicBlock::iterator &NMBBI); ++ bool expandXINSERT_FWOp(MachineBasicBlock &BB, ++ MachineBasicBlock::iterator I, ++ MachineBasicBlock::iterator &NMBBI); ++ bool expandAtomicBinOpSubword(MachineBasicBlock &BB, ++ MachineBasicBlock::iterator I, ++ MachineBasicBlock::iterator &NMBBI); ++ ++ bool expandPseudoCall(MachineBasicBlock &BB, ++ MachineBasicBlock::iterator I, ++ MachineBasicBlock::iterator &NMBBI); ++ bool expandPseudoTailCall(MachineBasicBlock &BB, ++ MachineBasicBlock::iterator I); ++ ++ bool expandPseudoTEQ(MachineBasicBlock &BB, ++ MachineBasicBlock::iterator I, ++ MachineBasicBlock::iterator &NMBBI); ++ ++ bool expandLoadAddr(MachineBasicBlock &BB, ++ MachineBasicBlock::iterator I, ++ MachineBasicBlock::iterator &NMBBI); ++ ++ bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, ++ MachineBasicBlock::iterator &NMBB); ++ bool expandMBB(MachineBasicBlock &MBB); ++ }; ++ char LoongArchExpandPseudo::ID = 0; ++} ++ ++bool LoongArchExpandPseudo::expandAtomicCmpSwapSubword( ++ MachineBasicBlock &BB, MachineBasicBlock::iterator I, ++ MachineBasicBlock::iterator &NMBBI) { ++ ++ MachineFunction *MF = BB.getParent(); ++ ++ DebugLoc DL = I->getDebugLoc(); ++ unsigned LL, SC; ++ unsigned ZERO = LoongArch::ZERO; ++ unsigned BNE = LoongArch::BNE32; ++ unsigned BEQ = LoongArch::BEQ32; ++ unsigned SEOp = ++ I->getOpcode() == LoongArch::ATOMIC_CMP_SWAP_I8_POSTRA ? LoongArch::EXT_W_B32 : LoongArch::EXT_W_H32; ++ ++ LL = LoongArch::LL_W; ++ SC = LoongArch::SC_W; ++ ++ unsigned Dest = I->getOperand(0).getReg(); ++ unsigned Ptr = I->getOperand(1).getReg(); ++ unsigned Mask = I->getOperand(2).getReg(); ++ unsigned ShiftCmpVal = I->getOperand(3).getReg(); ++ unsigned Mask2 = I->getOperand(4).getReg(); ++ unsigned ShiftNewVal = I->getOperand(5).getReg(); ++ unsigned ShiftAmnt = I->getOperand(6).getReg(); ++ unsigned Scratch = I->getOperand(8).getReg(); ++ unsigned Scratch2 = I->getOperand(9).getReg(); ++ ++ // insert new blocks after the current block ++ const BasicBlock *LLVM_BB = BB.getBasicBlock(); ++ MachineBasicBlock *loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineFunction::iterator It = ++BB.getIterator(); ++ MF->insert(It, loop1MBB); ++ MF->insert(It, loop2MBB); ++ MF->insert(It, sinkMBB); ++ MF->insert(It, exitMBB); ++ ++ // Transfer the remainder of BB and its successor edges to exitMBB. ++ exitMBB->splice(exitMBB->begin(), &BB, ++ std::next(MachineBasicBlock::iterator(I)), BB.end()); ++ exitMBB->transferSuccessorsAndUpdatePHIs(&BB); ++ ++ // thisMBB: ++ // ... ++ // fallthrough --> loop1MBB ++ BB.addSuccessor(loop1MBB, BranchProbability::getOne()); ++ loop1MBB->addSuccessor(sinkMBB); ++ loop1MBB->addSuccessor(loop2MBB); ++ loop1MBB->normalizeSuccProbs(); ++ loop2MBB->addSuccessor(loop1MBB); ++ loop2MBB->addSuccessor(sinkMBB); ++ loop2MBB->normalizeSuccProbs(); ++ sinkMBB->addSuccessor(exitMBB, BranchProbability::getOne()); ++ ++ // loop1MBB: ++ // ll dest, 0(ptr) ++ // and Mask', dest, Mask ++ // bne Mask', ShiftCmpVal, exitMBB ++ BuildMI(loop1MBB, DL, TII->get(LL), Scratch).addReg(Ptr).addImm(0); ++ BuildMI(loop1MBB, DL, TII->get(LoongArch::AND32), Scratch2) ++ .addReg(Scratch) ++ .addReg(Mask); ++ BuildMI(loop1MBB, DL, TII->get(BNE)) ++ .addReg(Scratch2).addReg(ShiftCmpVal).addMBB(sinkMBB); ++ ++ // loop2MBB: ++ // and dest, dest, mask2 ++ // or dest, dest, ShiftNewVal ++ // sc dest, dest, 0(ptr) ++ // beq dest, $0, loop1MBB ++ BuildMI(loop2MBB, DL, TII->get(LoongArch::AND32), Scratch) ++ .addReg(Scratch, RegState::Kill) ++ .addReg(Mask2); ++ BuildMI(loop2MBB, DL, TII->get(LoongArch::OR32), Scratch) ++ .addReg(Scratch, RegState::Kill) ++ .addReg(ShiftNewVal); ++ BuildMI(loop2MBB, DL, TII->get(SC), Scratch) ++ .addReg(Scratch, RegState::Kill) ++ .addReg(Ptr) ++ .addImm(0); ++ BuildMI(loop2MBB, DL, TII->get(BEQ)) ++ .addReg(Scratch, RegState::Kill) ++ .addReg(ZERO) ++ .addMBB(loop1MBB); ++ ++ // sinkMBB: ++ // srl srlres, Mask', shiftamt ++ // sign_extend dest,srlres ++ BuildMI(sinkMBB, DL, TII->get(LoongArch::SRL_W), Dest) ++ .addReg(Scratch2) ++ .addReg(ShiftAmnt); ++ ++ BuildMI(sinkMBB, DL, TII->get(SEOp), Dest).addReg(Dest); ++ ++ AtomicOrdering Ordering = ++ static_cast(I->getOperand(7).getImm()); ++ int hint; ++ switch (Ordering) { ++ case AtomicOrdering::Acquire: ++ case AtomicOrdering::AcquireRelease: ++ case AtomicOrdering::SequentiallyConsistent: ++ // acquire ++ hint = 0b10100; ++ break; ++ default: ++ hint = 0x700; ++ } ++ MachineBasicBlock::iterator Pos = sinkMBB->begin(); ++ BuildMI(*sinkMBB, Pos, DL, TII->get(LoongArch::DBAR)).addImm(hint); ++ ++ LivePhysRegs LiveRegs; ++ computeAndAddLiveIns(LiveRegs, *loop1MBB); ++ computeAndAddLiveIns(LiveRegs, *loop2MBB); ++ computeAndAddLiveIns(LiveRegs, *sinkMBB); ++ computeAndAddLiveIns(LiveRegs, *exitMBB); ++ ++ NMBBI = BB.end(); ++ I->eraseFromParent(); ++ return true; ++} ++ ++bool LoongArchExpandPseudo::expandAtomicCmpSwap(MachineBasicBlock &BB, ++ MachineBasicBlock::iterator I, ++ MachineBasicBlock::iterator &NMBBI) { ++ ++ const unsigned Size = ++ I->getOpcode() == LoongArch::ATOMIC_CMP_SWAP_I32_POSTRA ? 4 : 8; ++ MachineFunction *MF = BB.getParent(); ++ ++ DebugLoc DL = I->getDebugLoc(); ++ ++ unsigned LL, SC, ZERO, BNE, BEQ, MOVE; ++ ++ if (Size == 4) { ++ LL = LoongArch::LL_W; ++ SC = LoongArch::SC_W; ++ BNE = LoongArch::BNE32; ++ BEQ = LoongArch::BEQ32; ++ ++ ZERO = LoongArch::ZERO; ++ MOVE = LoongArch::OR32; ++ } else { ++ LL = LoongArch::LL_D; ++ SC = LoongArch::SC_D; ++ ZERO = LoongArch::ZERO_64; ++ BNE = LoongArch::BNE; ++ BEQ = LoongArch::BEQ; ++ MOVE = LoongArch::OR; ++ } ++ ++ unsigned Dest = I->getOperand(0).getReg(); ++ unsigned Ptr = I->getOperand(1).getReg(); ++ unsigned OldVal = I->getOperand(2).getReg(); ++ unsigned NewVal = I->getOperand(3).getReg(); ++ unsigned Scratch = I->getOperand(5).getReg(); ++ ++ // insert new blocks after the current block ++ const BasicBlock *LLVM_BB = BB.getBasicBlock(); ++ MachineBasicBlock *loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineFunction::iterator It = ++BB.getIterator(); ++ MF->insert(It, loop1MBB); ++ MF->insert(It, loop2MBB); ++ MF->insert(It, exitMBB); ++ ++ // Transfer the remainder of BB and its successor edges to exitMBB. ++ exitMBB->splice(exitMBB->begin(), &BB, ++ std::next(MachineBasicBlock::iterator(I)), BB.end()); ++ exitMBB->transferSuccessorsAndUpdatePHIs(&BB); ++ ++ // thisMBB: ++ // ... ++ // fallthrough --> loop1MBB ++ BB.addSuccessor(loop1MBB, BranchProbability::getOne()); ++ loop1MBB->addSuccessor(exitMBB); ++ loop1MBB->addSuccessor(loop2MBB); ++ loop1MBB->normalizeSuccProbs(); ++ loop2MBB->addSuccessor(loop1MBB); ++ loop2MBB->addSuccessor(exitMBB); ++ loop2MBB->normalizeSuccProbs(); ++ ++ // loop1MBB: ++ // ll dest, 0(ptr) ++ // bne dest, oldval, exitMBB ++ BuildMI(loop1MBB, DL, TII->get(LL), Dest).addReg(Ptr).addImm(0); ++ BuildMI(loop1MBB, DL, TII->get(BNE)) ++ .addReg(Dest, RegState::Kill).addReg(OldVal).addMBB(exitMBB); ++ ++ // loop2MBB: ++ // move scratch, NewVal ++ // sc Scratch, Scratch, 0(ptr) ++ // beq Scratch, $0, loop1MBB ++ BuildMI(loop2MBB, DL, TII->get(MOVE), Scratch).addReg(NewVal).addReg(ZERO); ++ BuildMI(loop2MBB, DL, TII->get(SC), Scratch) ++ .addReg(Scratch).addReg(Ptr).addImm(0); ++ BuildMI(loop2MBB, DL, TII->get(BEQ)) ++ .addReg(Scratch, RegState::Kill).addReg(ZERO).addMBB(loop1MBB); ++ ++ AtomicOrdering Ordering = ++ static_cast(I->getOperand(4).getImm()); ++ int hint; ++ switch (Ordering) { ++ case AtomicOrdering::Acquire: ++ case AtomicOrdering::AcquireRelease: ++ case AtomicOrdering::SequentiallyConsistent: ++ // TODO: acquire ++ hint = 0; ++ break; ++ default: ++ hint = 0x700; ++ } ++ MachineBasicBlock::iterator Pos = exitMBB->begin(); ++ BuildMI(*exitMBB, Pos, DL, TII->get(LoongArch::DBAR)).addImm(hint); ++ ++ LivePhysRegs LiveRegs; ++ computeAndAddLiveIns(LiveRegs, *loop1MBB); ++ computeAndAddLiveIns(LiveRegs, *loop2MBB); ++ computeAndAddLiveIns(LiveRegs, *exitMBB); ++ ++ NMBBI = BB.end(); ++ I->eraseFromParent(); ++ return true; ++} ++ ++bool LoongArchExpandPseudo::expandXINSERT_FWOp( ++ MachineBasicBlock &BB, MachineBasicBlock::iterator I, ++ MachineBasicBlock::iterator &NMBBI) { ++ ++ MachineFunction *MF = BB.getParent(); ++ ++ DebugLoc DL = I->getDebugLoc(); ++ ++ unsigned isGP64 = 0; ++ switch (I->getOpcode()) { ++ case LoongArch::XINSERT_FW_VIDX64_PSEUDO_POSTRA: ++ isGP64 = 1; ++ break; ++ case LoongArch::XINSERT_FW_VIDX_PSEUDO_POSTRA: ++ break; ++ default: ++ llvm_unreachable("Unknown subword vector pseudo for expansion!"); ++ } ++ ++ unsigned Dest = I->getOperand(0).getReg(); ++ unsigned SrcVecReg = I->getOperand(1).getReg(); ++ unsigned LaneReg = I->getOperand(2).getReg(); ++ unsigned SrcValReg = I->getOperand(3).getReg(); ++ ++ unsigned Dsttmp = I->getOperand(4).getReg(); ++ unsigned RI = I->getOperand(5).getReg(); ++ unsigned RJ = I->getOperand(6).getReg(); ++ Dsttmp = SrcVecReg; ++ ++ const BasicBlock *LLVM_BB = BB.getBasicBlock(); ++ MachineBasicBlock *blocks[11]; ++ MachineFunction::iterator It = ++BB.getIterator(); ++ for (int i = 0; i < 11; i++) { ++ blocks[i] = MF->CreateMachineBasicBlock(LLVM_BB); ++ MF->insert(It, blocks[i]); ++ } ++ ++ MachineBasicBlock *mainMBB = blocks[0]; ++ MachineBasicBlock *FirstMBB = blocks[1]; ++ MachineBasicBlock *sinkMBB = blocks[9]; ++ MachineBasicBlock *exitMBB = blocks[10]; ++ ++ exitMBB->splice(exitMBB->begin(), &BB, std::next(I), BB.end()); ++ exitMBB->transferSuccessorsAndUpdatePHIs(&BB); ++ ++ BB.addSuccessor(mainMBB, BranchProbability::getOne()); ++ for (int i = 1; i < 9; i++) { ++ mainMBB->addSuccessor(blocks[i]); ++ blocks[i]->addSuccessor(sinkMBB); ++ } ++ ++ unsigned ADDI, BLT, ZERO; ++ ADDI = isGP64 ? LoongArch::ADDI_D : LoongArch::ADDI_W; ++ BLT = isGP64 ? LoongArch::BLT : LoongArch::BLT32; ++ ZERO = isGP64 ? LoongArch::ZERO_64 : LoongArch::ZERO; ++ ++ for (int i = 1; i < 8; i++) { ++ BuildMI(mainMBB, DL, TII->get(ADDI), RI).addReg(ZERO).addImm(i); ++ BuildMI(mainMBB, DL, TII->get(BLT)) ++ .addReg(LaneReg) ++ .addReg(RI) ++ .addMBB(blocks[i + 1]); ++ } ++ ++ BuildMI(mainMBB, DL, TII->get(LoongArch::B32)).addMBB(FirstMBB); ++ ++ BuildMI(FirstMBB, DL, TII->get(LoongArch::XVINSGR2VR_W), Dsttmp) ++ .addReg(SrcVecReg) ++ .addReg(RJ) ++ .addImm(7); ++ BuildMI(FirstMBB, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ for (int i = 0; i < 7; i++) { ++ BuildMI(blocks[i + 2], DL, TII->get(LoongArch::XVINSGR2VR_W), Dsttmp) ++ .addReg(SrcVecReg) ++ .addReg(RJ) ++ .addImm(i); ++ BuildMI(blocks[i + 2], DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ } ++ ++ sinkMBB->addSuccessor(exitMBB, BranchProbability::getOne()); ++ BuildMI(sinkMBB, DL, TII->get(LoongArch::XVORI_B), Dest) ++ .addReg(Dsttmp) ++ .addImm(0); ++ ++ LivePhysRegs LiveRegs; ++ for (int i = 0; i < 11; i++) { ++ computeAndAddLiveIns(LiveRegs, *blocks[i]); ++ } ++ ++ NMBBI = BB.end(); ++ I->eraseFromParent(); ++ ++ return true; ++} ++ ++bool LoongArchExpandPseudo::expandINSERT_HOp( ++ MachineBasicBlock &BB, MachineBasicBlock::iterator I, ++ MachineBasicBlock::iterator &NMBBI) { ++ ++ MachineFunction *MF = BB.getParent(); ++ ++ DebugLoc DL = I->getDebugLoc(); ++ ++ unsigned isGP64 = 0; ++ switch (I->getOpcode()) { ++ case LoongArch::INSERT_H_VIDX64_PSEUDO_POSTRA: ++ isGP64 = 1; ++ break; ++ default: ++ llvm_unreachable("Unknown subword vector pseudo for expansion!"); ++ } ++ ++ unsigned Dest = I->getOperand(0).getReg(); ++ unsigned SrcVecReg = I->getOperand(1).getReg(); ++ unsigned LaneReg = I->getOperand(2).getReg(); ++ unsigned SrcValReg = I->getOperand(3).getReg(); ++ ++ unsigned Dsttmp = I->getOperand(4).getReg(); ++ unsigned RI = I->getOperand(5).getReg(); ++ Dsttmp = SrcVecReg; ++ ++ const BasicBlock *LLVM_BB = BB.getBasicBlock(); ++ MachineBasicBlock *blocks[11]; ++ MachineFunction::iterator It = ++BB.getIterator(); ++ for (int i = 0; i < 11; i++) { ++ blocks[i] = MF->CreateMachineBasicBlock(LLVM_BB); ++ MF->insert(It, blocks[i]); ++ } ++ ++ MachineBasicBlock *mainMBB = blocks[0]; ++ MachineBasicBlock *FirstMBB = blocks[1]; ++ MachineBasicBlock *sinkMBB = blocks[9]; ++ MachineBasicBlock *exitMBB = blocks[10]; ++ ++ exitMBB->splice(exitMBB->begin(), &BB, std::next(I), BB.end()); ++ exitMBB->transferSuccessorsAndUpdatePHIs(&BB); ++ ++ BB.addSuccessor(mainMBB, BranchProbability::getOne()); ++ for (int i = 1; i < 9; i++) { ++ mainMBB->addSuccessor(blocks[i]); ++ blocks[i]->addSuccessor(sinkMBB); ++ } ++ ++ unsigned ADDI, BLT, ZERO; ++ ADDI = isGP64 ? LoongArch::ADDI_D : LoongArch::ADDI_W; ++ BLT = isGP64 ? LoongArch::BLT : LoongArch::BLT32; ++ ZERO = isGP64 ? LoongArch::ZERO_64 : LoongArch::ZERO; ++ ++ for (int i = 1; i < 8; i++) { ++ BuildMI(mainMBB, DL, TII->get(ADDI), RI).addReg(ZERO).addImm(i); ++ BuildMI(mainMBB, DL, TII->get(BLT)) ++ .addReg(LaneReg) ++ .addReg(RI) ++ .addMBB(blocks[i + 1]); ++ } ++ ++ BuildMI(mainMBB, DL, TII->get(LoongArch::B32)).addMBB(FirstMBB); ++ ++ BuildMI(FirstMBB, DL, TII->get(LoongArch::VINSGR2VR_H), Dsttmp) ++ .addReg(SrcVecReg) ++ .addReg(SrcValReg) ++ .addImm(7); ++ BuildMI(FirstMBB, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ for (int i = 0; i < 7; i++) { ++ BuildMI(blocks[i + 2], DL, TII->get(LoongArch::VINSGR2VR_H), Dsttmp) ++ .addReg(SrcVecReg) ++ .addReg(SrcValReg) ++ .addImm(i); ++ BuildMI(blocks[i + 2], DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ } ++ ++ sinkMBB->addSuccessor(exitMBB, BranchProbability::getOne()); ++ BuildMI(sinkMBB, DL, TII->get(LoongArch::VORI_B), Dest) ++ .addReg(Dsttmp) ++ .addImm(0); ++ ++ LivePhysRegs LiveRegs; ++ for (int i = 0; i < 11; i++) { ++ computeAndAddLiveIns(LiveRegs, *blocks[i]); ++ } ++ ++ NMBBI = BB.end(); ++ I->eraseFromParent(); ++ ++ return true; ++} ++ ++bool LoongArchExpandPseudo::expandXINSERT_BOp( ++ MachineBasicBlock &BB, MachineBasicBlock::iterator I, ++ MachineBasicBlock::iterator &NMBBI) { ++ ++ MachineFunction *MF = BB.getParent(); ++ ++ DebugLoc DL = I->getDebugLoc(); ++ ++ unsigned isGP64 = 0; ++ switch (I->getOpcode()) { ++ case LoongArch::XINSERT_B_VIDX64_PSEUDO_POSTRA: ++ isGP64 = 1; ++ break; ++ case LoongArch::XINSERT_B_VIDX_PSEUDO_POSTRA: ++ break; ++ default: ++ llvm_unreachable("Unknown subword vector pseudo for expansion!"); ++ } ++ ++ unsigned Dest = I->getOperand(0).getReg(); ++ unsigned SrcVecReg = I->getOperand(1).getReg(); ++ unsigned LaneReg = I->getOperand(2).getReg(); ++ unsigned SrcValReg = I->getOperand(3).getReg(); ++ ++ unsigned R4r = I->getOperand(5).getReg(); ++ unsigned Rib = I->getOperand(6).getReg(); ++ unsigned Ris = I->getOperand(7).getReg(); ++ unsigned R7b1 = I->getOperand(8).getReg(); ++ unsigned R7b2 = I->getOperand(9).getReg(); ++ unsigned R7b3 = I->getOperand(10).getReg(); ++ unsigned R7r80_3 = I->getOperand(11).getReg(); ++ unsigned R7r80l_3 = I->getOperand(12).getReg(); ++ unsigned R7r81_3 = I->getOperand(13).getReg(); ++ unsigned R7r81l_3 = I->getOperand(14).getReg(); ++ unsigned R7r82_3 = I->getOperand(15).getReg(); ++ unsigned R7r82l_3 = I->getOperand(16).getReg(); ++ unsigned RI = I->getOperand(17).getReg(); ++ unsigned tmp_Dst73 = I->getOperand(18).getReg(); ++ unsigned Rimm = I->getOperand(19).getReg(); ++ unsigned R70 = I->getOperand(20).getReg(); ++ tmp_Dst73 = SrcVecReg; ++ ++ const BasicBlock *LLVM_BB = BB.getBasicBlock(); ++ MachineBasicBlock *mainMBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *SevenMBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *SevenMBB0 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *SevenMBB1 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *SevenMBB2 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *SevenMBB3 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *ZeroMBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *ZeroMBB0 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *ZeroMBB1 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *ZeroMBB2 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *ZeroMBB3 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *OneMBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *OneMBB0 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *OneMBB1 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *OneMBB2 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *OneMBB3 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *TwoMBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *TwoMBB0 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *TwoMBB1 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *TwoMBB2 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *TwoMBB3 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *ThreeMBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *ThreeMBB0 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *ThreeMBB1 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *ThreeMBB2 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *ThreeMBB3 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *FourMBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *FourMBB0 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *FourMBB1 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *FourMBB2 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *FourMBB3 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *FiveMBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *FiveMBB0 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *FiveMBB1 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *FiveMBB2 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *FiveMBB3 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *SixMBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *SixMBB0 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *SixMBB1 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *SixMBB2 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *SixMBB3 = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineFunction::iterator It = ++BB.getIterator(); ++ MF->insert(It, mainMBB); ++ MF->insert(It, SevenMBB); ++ MF->insert(It, SevenMBB3); ++ MF->insert(It, SevenMBB0); ++ MF->insert(It, SevenMBB1); ++ MF->insert(It, SevenMBB2); ++ MF->insert(It, ZeroMBB); ++ MF->insert(It, ZeroMBB3); ++ MF->insert(It, ZeroMBB0); ++ MF->insert(It, ZeroMBB1); ++ MF->insert(It, ZeroMBB2); ++ MF->insert(It, OneMBB); ++ MF->insert(It, OneMBB3); ++ MF->insert(It, OneMBB0); ++ MF->insert(It, OneMBB1); ++ MF->insert(It, OneMBB2); ++ MF->insert(It, TwoMBB); ++ MF->insert(It, TwoMBB3); ++ MF->insert(It, TwoMBB0); ++ MF->insert(It, TwoMBB1); ++ MF->insert(It, TwoMBB2); ++ MF->insert(It, ThreeMBB); ++ MF->insert(It, ThreeMBB3); ++ MF->insert(It, ThreeMBB0); ++ MF->insert(It, ThreeMBB1); ++ MF->insert(It, ThreeMBB2); ++ MF->insert(It, FourMBB); ++ MF->insert(It, FourMBB3); ++ MF->insert(It, FourMBB0); ++ MF->insert(It, FourMBB1); ++ MF->insert(It, FourMBB2); ++ MF->insert(It, FiveMBB); ++ MF->insert(It, FiveMBB3); ++ MF->insert(It, FiveMBB0); ++ MF->insert(It, FiveMBB1); ++ MF->insert(It, FiveMBB2); ++ MF->insert(It, SixMBB); ++ MF->insert(It, SixMBB3); ++ MF->insert(It, SixMBB0); ++ MF->insert(It, SixMBB1); ++ MF->insert(It, SixMBB2); ++ MF->insert(It, sinkMBB); ++ MF->insert(It, exitMBB); ++ ++ exitMBB->splice(exitMBB->begin(), &BB, std::next(I), BB.end()); ++ exitMBB->transferSuccessorsAndUpdatePHIs(&BB); ++ ++ BB.addSuccessor(mainMBB, BranchProbability::getOne()); ++ mainMBB->addSuccessor(SevenMBB); ++ mainMBB->addSuccessor(ZeroMBB); ++ mainMBB->addSuccessor(OneMBB); ++ mainMBB->addSuccessor(TwoMBB); ++ mainMBB->addSuccessor(ThreeMBB); ++ mainMBB->addSuccessor(FourMBB); ++ mainMBB->addSuccessor(FiveMBB); ++ mainMBB->addSuccessor(SixMBB); ++ SevenMBB->addSuccessor(SevenMBB0); ++ SevenMBB->addSuccessor(SevenMBB1); ++ SevenMBB->addSuccessor(SevenMBB2); ++ SevenMBB->addSuccessor(SevenMBB3); ++ SevenMBB0->addSuccessor(sinkMBB); ++ SevenMBB1->addSuccessor(sinkMBB); ++ SevenMBB2->addSuccessor(sinkMBB); ++ SevenMBB3->addSuccessor(sinkMBB); ++ ZeroMBB->addSuccessor(ZeroMBB0); ++ ZeroMBB->addSuccessor(ZeroMBB1); ++ ZeroMBB->addSuccessor(ZeroMBB2); ++ ZeroMBB->addSuccessor(ZeroMBB3); ++ ZeroMBB0->addSuccessor(sinkMBB); ++ ZeroMBB1->addSuccessor(sinkMBB); ++ ZeroMBB2->addSuccessor(sinkMBB); ++ ZeroMBB3->addSuccessor(sinkMBB); ++ OneMBB->addSuccessor(OneMBB0); ++ OneMBB->addSuccessor(OneMBB1); ++ OneMBB->addSuccessor(OneMBB2); ++ OneMBB->addSuccessor(OneMBB3); ++ OneMBB0->addSuccessor(sinkMBB); ++ OneMBB1->addSuccessor(sinkMBB); ++ OneMBB2->addSuccessor(sinkMBB); ++ OneMBB3->addSuccessor(sinkMBB); ++ TwoMBB->addSuccessor(TwoMBB0); ++ TwoMBB->addSuccessor(TwoMBB1); ++ TwoMBB->addSuccessor(TwoMBB2); ++ TwoMBB->addSuccessor(TwoMBB3); ++ TwoMBB0->addSuccessor(sinkMBB); ++ TwoMBB1->addSuccessor(sinkMBB); ++ TwoMBB2->addSuccessor(sinkMBB); ++ TwoMBB3->addSuccessor(sinkMBB); ++ ThreeMBB->addSuccessor(ThreeMBB0); ++ ThreeMBB->addSuccessor(ThreeMBB1); ++ ThreeMBB->addSuccessor(ThreeMBB2); ++ ThreeMBB->addSuccessor(ThreeMBB3); ++ ThreeMBB0->addSuccessor(sinkMBB); ++ ThreeMBB1->addSuccessor(sinkMBB); ++ ThreeMBB2->addSuccessor(sinkMBB); ++ ThreeMBB3->addSuccessor(sinkMBB); ++ FourMBB->addSuccessor(FourMBB0); ++ FourMBB->addSuccessor(FourMBB1); ++ FourMBB->addSuccessor(FourMBB2); ++ FourMBB->addSuccessor(FourMBB3); ++ FourMBB0->addSuccessor(sinkMBB); ++ FourMBB1->addSuccessor(sinkMBB); ++ FourMBB2->addSuccessor(sinkMBB); ++ FourMBB3->addSuccessor(sinkMBB); ++ FiveMBB->addSuccessor(FiveMBB0); ++ FiveMBB->addSuccessor(FiveMBB1); ++ FiveMBB->addSuccessor(FiveMBB2); ++ FiveMBB->addSuccessor(FiveMBB3); ++ FiveMBB0->addSuccessor(sinkMBB); ++ FiveMBB1->addSuccessor(sinkMBB); ++ FiveMBB2->addSuccessor(sinkMBB); ++ FiveMBB3->addSuccessor(sinkMBB); ++ SixMBB->addSuccessor(SixMBB0); ++ SixMBB->addSuccessor(SixMBB1); ++ SixMBB->addSuccessor(SixMBB2); ++ SixMBB->addSuccessor(SixMBB3); ++ SixMBB0->addSuccessor(sinkMBB); ++ SixMBB1->addSuccessor(sinkMBB); ++ SixMBB2->addSuccessor(sinkMBB); ++ SixMBB3->addSuccessor(sinkMBB); ++ ++ unsigned SRLI, ADDI, OR, MOD, BLT, ZERO; ++ SRLI = isGP64 ? LoongArch::SRLI_D : LoongArch::SRLI_W; ++ ADDI = isGP64 ? LoongArch::ADDI_D : LoongArch::ADDI_W; ++ OR = isGP64 ? LoongArch::OR : LoongArch::OR32; ++ MOD = isGP64 ? LoongArch::MOD_DU : LoongArch::MOD_WU; ++ BLT = isGP64 ? LoongArch::BLT : LoongArch::BLT32; ++ ZERO = isGP64 ? LoongArch::ZERO_64 : LoongArch::ZERO; ++ ++ BuildMI(mainMBB, DL, TII->get(SRLI), Rimm).addReg(LaneReg).addImm(2); ++ BuildMI(mainMBB, DL, TII->get(ADDI), R4r).addReg(ZERO).addImm(4); ++ BuildMI(mainMBB, DL, TII->get(OR), Rib).addReg(Rimm).addReg(ZERO); ++ BuildMI(mainMBB, DL, TII->get(MOD), Ris).addReg(Rib).addReg(R4r); ++ BuildMI(mainMBB, DL, TII->get(ADDI), RI).addReg(ZERO).addImm(1); ++ BuildMI(mainMBB, DL, TII->get(BLT)).addReg(Rib).addReg(RI).addMBB(ZeroMBB); ++ BuildMI(mainMBB, DL, TII->get(ADDI), RI).addReg(ZERO).addImm(2); ++ BuildMI(mainMBB, DL, TII->get(BLT)).addReg(Rib).addReg(RI).addMBB(OneMBB); ++ BuildMI(mainMBB, DL, TII->get(ADDI), RI).addReg(ZERO).addImm(3); ++ BuildMI(mainMBB, DL, TII->get(BLT)).addReg(Rib).addReg(RI).addMBB(TwoMBB); ++ BuildMI(mainMBB, DL, TII->get(ADDI), RI).addReg(ZERO).addImm(4); ++ BuildMI(mainMBB, DL, TII->get(BLT)).addReg(Rib).addReg(RI).addMBB(ThreeMBB); ++ BuildMI(mainMBB, DL, TII->get(ADDI), RI).addReg(ZERO).addImm(5); ++ BuildMI(mainMBB, DL, TII->get(BLT)).addReg(Rib).addReg(RI).addMBB(FourMBB); ++ BuildMI(mainMBB, DL, TII->get(ADDI), RI).addReg(ZERO).addImm(6); ++ BuildMI(mainMBB, DL, TII->get(BLT)).addReg(Rib).addReg(RI).addMBB(FiveMBB); ++ BuildMI(mainMBB, DL, TII->get(ADDI), RI).addReg(ZERO).addImm(7); ++ BuildMI(mainMBB, DL, TII->get(BLT)).addReg(Rib).addReg(RI).addMBB(SixMBB); ++ BuildMI(mainMBB, DL, TII->get(LoongArch::B32)).addMBB(SevenMBB); ++ ++ BuildMI(SevenMBB, DL, TII->get(LoongArch::XVPICKVE2GR_W), R70) ++ .addReg(SrcVecReg) ++ .addImm(7); ++ BuildMI(SevenMBB, DL, TII->get(ADDI), R7b1).addReg(ZERO).addImm(1); ++ BuildMI(SevenMBB, DL, TII->get(BLT)) ++ .addReg(Ris) ++ .addReg(R7b1) ++ .addMBB(SevenMBB0); ++ BuildMI(SevenMBB, DL, TII->get(ADDI), R7b2).addReg(ZERO).addImm(2); ++ BuildMI(SevenMBB, DL, TII->get(BLT)) ++ .addReg(Ris) ++ .addReg(R7b2) ++ .addMBB(SevenMBB1); ++ BuildMI(SevenMBB, DL, TII->get(ADDI), R7b3).addReg(ZERO).addImm(3); ++ BuildMI(SevenMBB, DL, TII->get(BLT)) ++ .addReg(Ris) ++ .addReg(R7b3) ++ .addMBB(SevenMBB2); ++ BuildMI(SevenMBB, DL, TII->get(LoongArch::B32)).addMBB(SevenMBB3); ++ ++ BuildMI(SevenMBB3, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(SevenMBB3, DL, TII->get(LoongArch::LU12I_W), R7r81l_3) ++ .addImm(0x00fff); ++ BuildMI(SevenMBB3, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xfff); ++ BuildMI(SevenMBB3, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(SevenMBB3, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80_3); ++ BuildMI(SevenMBB3, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(7); ++ BuildMI(SevenMBB3, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(SevenMBB0, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(SevenMBB0, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(8); ++ BuildMI(SevenMBB0, DL, TII->get(LoongArch::LU12I_W), R7r81l_3) ++ .addImm(0xff00f); ++ BuildMI(SevenMBB0, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xfff); ++ BuildMI(SevenMBB0, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(SevenMBB0, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(SevenMBB0, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(7); ++ BuildMI(SevenMBB0, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(SevenMBB1, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(SevenMBB1, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(16); ++ BuildMI(SevenMBB1, DL, TII->get(LoongArch::LU12I_W), R7r81l_3) ++ .addImm(0xffff0); ++ BuildMI(SevenMBB1, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0x0ff); ++ BuildMI(SevenMBB1, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(SevenMBB1, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(SevenMBB1, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(7); ++ BuildMI(SevenMBB1, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(SevenMBB2, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(SevenMBB2, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(24); ++ BuildMI(SevenMBB2, DL, TII->get(LoongArch::LU12I_W), R7r81l_3) ++ .addImm(0xfffff); ++ BuildMI(SevenMBB2, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xf00); ++ BuildMI(SevenMBB2, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(SevenMBB2, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(SevenMBB2, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(7); ++ BuildMI(SevenMBB2, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(ZeroMBB, DL, TII->get(LoongArch::XVPICKVE2GR_W), R70) ++ .addReg(SrcVecReg) ++ .addImm(0); ++ BuildMI(ZeroMBB, DL, TII->get(ADDI), R7b1).addReg(ZERO).addImm(1); ++ BuildMI(ZeroMBB, DL, TII->get(BLT)).addReg(Ris).addReg(R7b1).addMBB(ZeroMBB0); ++ BuildMI(ZeroMBB, DL, TII->get(ADDI), R7b2).addReg(ZERO).addImm(2); ++ BuildMI(ZeroMBB, DL, TII->get(BLT)).addReg(Ris).addReg(R7b2).addMBB(ZeroMBB1); ++ BuildMI(ZeroMBB, DL, TII->get(ADDI), R7b3).addReg(ZERO).addImm(3); ++ BuildMI(ZeroMBB, DL, TII->get(BLT)).addReg(Ris).addReg(R7b3).addMBB(ZeroMBB2); ++ BuildMI(ZeroMBB, DL, TII->get(LoongArch::B32)).addMBB(ZeroMBB3); ++ ++ BuildMI(ZeroMBB3, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(ZeroMBB3, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0x00fff); ++ BuildMI(ZeroMBB3, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xfff); ++ BuildMI(ZeroMBB3, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(ZeroMBB3, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80_3); ++ BuildMI(ZeroMBB3, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(0); ++ BuildMI(ZeroMBB3, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(ZeroMBB0, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(ZeroMBB0, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(8); ++ BuildMI(ZeroMBB0, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0xff00f); ++ BuildMI(ZeroMBB0, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xfff); ++ BuildMI(ZeroMBB0, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(ZeroMBB0, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(ZeroMBB0, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(0); ++ BuildMI(ZeroMBB0, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(ZeroMBB1, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(ZeroMBB1, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(16); ++ BuildMI(ZeroMBB1, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0xffff0); ++ BuildMI(ZeroMBB1, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0x0ff); ++ BuildMI(ZeroMBB1, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(ZeroMBB1, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(ZeroMBB1, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(0); ++ BuildMI(ZeroMBB1, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(ZeroMBB2, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(ZeroMBB2, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(24); ++ BuildMI(ZeroMBB2, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0xfffff); ++ BuildMI(ZeroMBB2, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xf00); ++ BuildMI(ZeroMBB2, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(ZeroMBB2, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(ZeroMBB2, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(0); ++ BuildMI(ZeroMBB2, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(OneMBB, DL, TII->get(LoongArch::XVPICKVE2GR_W), R70) ++ .addReg(SrcVecReg) ++ .addImm(1); ++ BuildMI(OneMBB, DL, TII->get(ADDI), R7b1).addReg(ZERO).addImm(1); ++ BuildMI(OneMBB, DL, TII->get(BLT)).addReg(Ris).addReg(R7b1).addMBB(OneMBB0); ++ BuildMI(OneMBB, DL, TII->get(ADDI), R7b2).addReg(ZERO).addImm(2); ++ BuildMI(OneMBB, DL, TII->get(BLT)).addReg(Ris).addReg(R7b2).addMBB(OneMBB1); ++ BuildMI(OneMBB, DL, TII->get(ADDI), R7b3).addReg(ZERO).addImm(3); ++ BuildMI(OneMBB, DL, TII->get(BLT)).addReg(Ris).addReg(R7b3).addMBB(OneMBB2); ++ BuildMI(OneMBB, DL, TII->get(LoongArch::B32)).addMBB(OneMBB3); ++ ++ BuildMI(OneMBB3, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(OneMBB3, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0x00fff); ++ BuildMI(OneMBB3, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xfff); ++ BuildMI(OneMBB3, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(OneMBB3, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80_3); ++ BuildMI(OneMBB3, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(1); ++ BuildMI(OneMBB3, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(OneMBB0, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(OneMBB0, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(8); ++ BuildMI(OneMBB0, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0xff00f); ++ BuildMI(OneMBB0, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xfff); ++ BuildMI(OneMBB0, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(OneMBB0, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(OneMBB0, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(1); ++ BuildMI(OneMBB0, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(OneMBB1, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(OneMBB1, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(16); ++ BuildMI(OneMBB1, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0xffff0); ++ BuildMI(OneMBB1, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0x0ff); ++ BuildMI(OneMBB1, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(OneMBB1, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(OneMBB1, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(1); ++ BuildMI(OneMBB1, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(OneMBB2, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(OneMBB2, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(24); ++ BuildMI(OneMBB2, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0xfffff); ++ BuildMI(OneMBB2, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xf00); ++ BuildMI(OneMBB2, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(OneMBB2, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(OneMBB2, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(1); ++ BuildMI(OneMBB2, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(TwoMBB, DL, TII->get(LoongArch::XVPICKVE2GR_W), R70) ++ .addReg(SrcVecReg) ++ .addImm(2); ++ BuildMI(TwoMBB, DL, TII->get(ADDI), R7b1).addReg(ZERO).addImm(1); ++ BuildMI(TwoMBB, DL, TII->get(BLT)).addReg(Ris).addReg(R7b1).addMBB(TwoMBB0); ++ BuildMI(TwoMBB, DL, TII->get(ADDI), R7b2).addReg(ZERO).addImm(2); ++ BuildMI(TwoMBB, DL, TII->get(BLT)).addReg(Ris).addReg(R7b2).addMBB(TwoMBB1); ++ BuildMI(TwoMBB, DL, TII->get(ADDI), R7b3).addReg(ZERO).addImm(3); ++ BuildMI(TwoMBB, DL, TII->get(BLT)).addReg(Ris).addReg(R7b3).addMBB(TwoMBB2); ++ BuildMI(TwoMBB, DL, TII->get(LoongArch::B32)).addMBB(TwoMBB3); ++ ++ BuildMI(TwoMBB3, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(TwoMBB3, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0x00fff); ++ BuildMI(TwoMBB3, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xfff); ++ BuildMI(TwoMBB3, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(TwoMBB3, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80_3); ++ BuildMI(TwoMBB3, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(2); ++ BuildMI(TwoMBB3, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(TwoMBB0, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(TwoMBB0, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(8); ++ BuildMI(TwoMBB0, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0xff00f); ++ BuildMI(TwoMBB0, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xfff); ++ BuildMI(TwoMBB0, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(TwoMBB0, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(TwoMBB0, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(2); ++ BuildMI(TwoMBB0, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(TwoMBB1, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(TwoMBB1, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(16); ++ BuildMI(TwoMBB1, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0xffff0); ++ BuildMI(TwoMBB1, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0x0ff); ++ BuildMI(TwoMBB1, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(TwoMBB1, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(TwoMBB1, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(2); ++ BuildMI(TwoMBB1, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(TwoMBB2, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(TwoMBB2, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(24); ++ BuildMI(TwoMBB2, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0xfffff); ++ BuildMI(TwoMBB2, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xf00); ++ BuildMI(TwoMBB2, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(TwoMBB2, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(TwoMBB2, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(2); ++ BuildMI(TwoMBB2, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(ThreeMBB, DL, TII->get(LoongArch::XVPICKVE2GR_W), R70) ++ .addReg(SrcVecReg) ++ .addImm(3); ++ BuildMI(ThreeMBB, DL, TII->get(ADDI), R7b1).addReg(ZERO).addImm(1); ++ BuildMI(ThreeMBB, DL, TII->get(BLT)) ++ .addReg(Ris) ++ .addReg(R7b1) ++ .addMBB(ThreeMBB0); ++ BuildMI(ThreeMBB, DL, TII->get(ADDI), R7b2).addReg(ZERO).addImm(2); ++ BuildMI(ThreeMBB, DL, TII->get(BLT)) ++ .addReg(Ris) ++ .addReg(R7b2) ++ .addMBB(ThreeMBB1); ++ BuildMI(ThreeMBB, DL, TII->get(ADDI), R7b3).addReg(ZERO).addImm(3); ++ BuildMI(ThreeMBB, DL, TII->get(BLT)) ++ .addReg(Ris) ++ .addReg(R7b3) ++ .addMBB(ThreeMBB2); ++ BuildMI(ThreeMBB, DL, TII->get(LoongArch::B32)).addMBB(ThreeMBB3); ++ ++ BuildMI(ThreeMBB3, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(ThreeMBB3, DL, TII->get(LoongArch::LU12I_W), R7r81l_3) ++ .addImm(0x00fff); ++ BuildMI(ThreeMBB3, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xfff); ++ BuildMI(ThreeMBB3, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(ThreeMBB3, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80_3); ++ BuildMI(ThreeMBB3, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(3); ++ BuildMI(ThreeMBB3, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(ThreeMBB0, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(ThreeMBB0, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(8); ++ BuildMI(ThreeMBB0, DL, TII->get(LoongArch::LU12I_W), R7r81l_3) ++ .addImm(0xff00f); ++ BuildMI(ThreeMBB0, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xfff); ++ BuildMI(ThreeMBB0, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(ThreeMBB0, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(ThreeMBB0, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(3); ++ BuildMI(ThreeMBB0, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(ThreeMBB1, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(ThreeMBB1, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(16); ++ BuildMI(ThreeMBB1, DL, TII->get(LoongArch::LU12I_W), R7r81l_3) ++ .addImm(0xffff0); ++ BuildMI(ThreeMBB1, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0x0ff); ++ BuildMI(ThreeMBB1, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(ThreeMBB1, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(ThreeMBB1, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(3); ++ BuildMI(ThreeMBB1, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(ThreeMBB2, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(ThreeMBB2, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(24); ++ BuildMI(ThreeMBB2, DL, TII->get(LoongArch::LU12I_W), R7r81l_3) ++ .addImm(0xfffff); ++ BuildMI(ThreeMBB2, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xf00); ++ BuildMI(ThreeMBB2, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(ThreeMBB2, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(ThreeMBB2, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(3); ++ BuildMI(ThreeMBB2, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(FourMBB, DL, TII->get(LoongArch::XVPICKVE2GR_W), R70) ++ .addReg(SrcVecReg) ++ .addImm(4); ++ BuildMI(FourMBB, DL, TII->get(ADDI), R7b1).addReg(ZERO).addImm(1); ++ BuildMI(FourMBB, DL, TII->get(BLT)).addReg(Ris).addReg(R7b1).addMBB(FourMBB0); ++ BuildMI(FourMBB, DL, TII->get(ADDI), R7b2).addReg(ZERO).addImm(2); ++ BuildMI(FourMBB, DL, TII->get(BLT)).addReg(Ris).addReg(R7b2).addMBB(FourMBB1); ++ BuildMI(FourMBB, DL, TII->get(ADDI), R7b3).addReg(ZERO).addImm(3); ++ BuildMI(FourMBB, DL, TII->get(BLT)).addReg(Ris).addReg(R7b3).addMBB(FourMBB2); ++ BuildMI(FourMBB, DL, TII->get(LoongArch::B32)).addMBB(FourMBB3); ++ ++ BuildMI(FourMBB3, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(FourMBB3, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0x00fff); ++ BuildMI(FourMBB3, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xfff); ++ BuildMI(FourMBB3, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(FourMBB3, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80_3); ++ BuildMI(FourMBB3, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(4); ++ BuildMI(FourMBB3, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(FourMBB0, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(FourMBB0, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(8); ++ BuildMI(FourMBB0, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0xff00f); ++ BuildMI(FourMBB0, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xfff); ++ BuildMI(FourMBB0, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(FourMBB0, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(FourMBB0, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(4); ++ BuildMI(FourMBB0, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(FourMBB1, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(FourMBB1, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(16); ++ BuildMI(FourMBB1, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0xffff0); ++ BuildMI(FourMBB1, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0x0ff); ++ BuildMI(FourMBB1, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(FourMBB1, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(FourMBB1, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(4); ++ BuildMI(FourMBB1, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(FourMBB2, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(FourMBB2, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(24); ++ BuildMI(FourMBB2, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0xfffff); ++ BuildMI(FourMBB2, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xf00); ++ BuildMI(FourMBB2, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(FourMBB2, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(FourMBB2, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(4); ++ BuildMI(FourMBB2, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(FiveMBB, DL, TII->get(LoongArch::XVPICKVE2GR_W), R70) ++ .addReg(SrcVecReg) ++ .addImm(5); ++ BuildMI(FiveMBB, DL, TII->get(ADDI), R7b1).addReg(ZERO).addImm(1); ++ BuildMI(FiveMBB, DL, TII->get(BLT)).addReg(Ris).addReg(R7b1).addMBB(FiveMBB0); ++ BuildMI(FiveMBB, DL, TII->get(ADDI), R7b2).addReg(ZERO).addImm(2); ++ BuildMI(FiveMBB, DL, TII->get(BLT)).addReg(Ris).addReg(R7b2).addMBB(FiveMBB1); ++ BuildMI(FiveMBB, DL, TII->get(ADDI), R7b3).addReg(ZERO).addImm(3); ++ BuildMI(FiveMBB, DL, TII->get(BLT)).addReg(Ris).addReg(R7b3).addMBB(FiveMBB2); ++ BuildMI(FiveMBB, DL, TII->get(LoongArch::B32)).addMBB(FiveMBB3); ++ ++ BuildMI(FiveMBB3, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(FiveMBB3, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0x00fff); ++ BuildMI(FiveMBB3, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xfff); ++ BuildMI(FiveMBB3, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(FiveMBB3, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80_3); ++ BuildMI(FiveMBB3, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(5); ++ BuildMI(FiveMBB3, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(FiveMBB0, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(FiveMBB0, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(8); ++ BuildMI(FiveMBB0, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0xff00f); ++ BuildMI(FiveMBB0, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xfff); ++ BuildMI(FiveMBB0, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(FiveMBB0, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(FiveMBB0, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(5); ++ BuildMI(FiveMBB0, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(FiveMBB1, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(FiveMBB1, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(16); ++ BuildMI(FiveMBB1, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0xffff0); ++ BuildMI(FiveMBB1, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0x0ff); ++ BuildMI(FiveMBB1, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(FiveMBB1, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(FiveMBB1, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(5); ++ BuildMI(FiveMBB1, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(FiveMBB2, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(FiveMBB2, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(24); ++ BuildMI(FiveMBB2, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0xfffff); ++ BuildMI(FiveMBB2, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xf00); ++ BuildMI(FiveMBB2, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(FiveMBB2, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(FiveMBB2, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(5); ++ BuildMI(FiveMBB2, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(SixMBB, DL, TII->get(LoongArch::XVPICKVE2GR_W), R70) ++ .addReg(SrcVecReg) ++ .addImm(6); ++ BuildMI(SixMBB, DL, TII->get(ADDI), R7b1).addReg(ZERO).addImm(1); ++ BuildMI(SixMBB, DL, TII->get(BLT)).addReg(Ris).addReg(R7b1).addMBB(SixMBB0); ++ BuildMI(SixMBB, DL, TII->get(ADDI), R7b2).addReg(ZERO).addImm(2); ++ BuildMI(SixMBB, DL, TII->get(BLT)).addReg(Ris).addReg(R7b2).addMBB(SixMBB1); ++ BuildMI(SixMBB, DL, TII->get(ADDI), R7b3).addReg(ZERO).addImm(3); ++ BuildMI(SixMBB, DL, TII->get(BLT)).addReg(Ris).addReg(R7b3).addMBB(SixMBB2); ++ BuildMI(SixMBB, DL, TII->get(LoongArch::B32)).addMBB(SixMBB3); ++ ++ BuildMI(SixMBB3, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(SixMBB3, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0x00fff); ++ BuildMI(SixMBB3, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xfff); ++ BuildMI(SixMBB3, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(SixMBB3, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80_3); ++ BuildMI(SixMBB3, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(6); ++ BuildMI(SixMBB3, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(SixMBB0, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(SixMBB0, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(8); ++ BuildMI(SixMBB0, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0xff00f); ++ BuildMI(SixMBB0, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xfff); ++ BuildMI(SixMBB0, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(SixMBB0, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(SixMBB0, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(6); ++ BuildMI(SixMBB0, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(SixMBB1, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(SixMBB1, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(16); ++ BuildMI(SixMBB1, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0xffff0); ++ BuildMI(SixMBB1, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0x0ff); ++ BuildMI(SixMBB1, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(SixMBB1, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(SixMBB1, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(6); ++ BuildMI(SixMBB1, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ BuildMI(SixMBB2, DL, TII->get(LoongArch::SLLI_W), R7r80_3) ++ .addReg(SrcValReg) ++ .addImm(24); ++ BuildMI(SixMBB2, DL, TII->get(LoongArch::SRLI_W), R7r80l_3) ++ .addReg(R7r80_3) ++ .addImm(24); ++ BuildMI(SixMBB2, DL, TII->get(LoongArch::LU12I_W), R7r81l_3).addImm(0xfffff); ++ BuildMI(SixMBB2, DL, TII->get(LoongArch::ORI32), R7r81_3) ++ .addReg(R7r81l_3) ++ .addImm(0xf00); ++ BuildMI(SixMBB2, DL, TII->get(LoongArch::AND32), R7r82l_3) ++ .addReg(R70) ++ .addReg(R7r81_3); ++ BuildMI(SixMBB2, DL, TII->get(LoongArch::OR32), R7r82_3) ++ .addReg(R7r82l_3) ++ .addReg(R7r80l_3); ++ BuildMI(SixMBB2, DL, TII->get(LoongArch::XVINSGR2VR_W), tmp_Dst73) ++ .addReg(SrcVecReg) ++ .addReg(R7r82_3) ++ .addImm(6); ++ BuildMI(SixMBB2, DL, TII->get(LoongArch::B32)).addMBB(sinkMBB); ++ ++ sinkMBB->addSuccessor(exitMBB, BranchProbability::getOne()); ++ ++ BuildMI(sinkMBB, DL, TII->get(LoongArch::XVORI_B), Dest) ++ .addReg(tmp_Dst73) ++ .addImm(0); ++ ++ LivePhysRegs LiveRegs; ++ computeAndAddLiveIns(LiveRegs, *mainMBB); ++ computeAndAddLiveIns(LiveRegs, *SevenMBB); ++ computeAndAddLiveIns(LiveRegs, *SevenMBB0); ++ computeAndAddLiveIns(LiveRegs, *SevenMBB1); ++ computeAndAddLiveIns(LiveRegs, *SevenMBB2); ++ computeAndAddLiveIns(LiveRegs, *SevenMBB3); ++ computeAndAddLiveIns(LiveRegs, *ZeroMBB); ++ computeAndAddLiveIns(LiveRegs, *ZeroMBB0); ++ computeAndAddLiveIns(LiveRegs, *ZeroMBB1); ++ computeAndAddLiveIns(LiveRegs, *ZeroMBB2); ++ computeAndAddLiveIns(LiveRegs, *ZeroMBB3); ++ computeAndAddLiveIns(LiveRegs, *OneMBB); ++ computeAndAddLiveIns(LiveRegs, *OneMBB0); ++ computeAndAddLiveIns(LiveRegs, *OneMBB1); ++ computeAndAddLiveIns(LiveRegs, *OneMBB2); ++ computeAndAddLiveIns(LiveRegs, *OneMBB3); ++ computeAndAddLiveIns(LiveRegs, *TwoMBB); ++ computeAndAddLiveIns(LiveRegs, *TwoMBB0); ++ computeAndAddLiveIns(LiveRegs, *TwoMBB1); ++ computeAndAddLiveIns(LiveRegs, *TwoMBB2); ++ computeAndAddLiveIns(LiveRegs, *TwoMBB3); ++ computeAndAddLiveIns(LiveRegs, *ThreeMBB); ++ computeAndAddLiveIns(LiveRegs, *ThreeMBB0); ++ computeAndAddLiveIns(LiveRegs, *ThreeMBB1); ++ computeAndAddLiveIns(LiveRegs, *ThreeMBB2); ++ computeAndAddLiveIns(LiveRegs, *ThreeMBB3); ++ computeAndAddLiveIns(LiveRegs, *FourMBB); ++ computeAndAddLiveIns(LiveRegs, *FourMBB0); ++ computeAndAddLiveIns(LiveRegs, *FourMBB1); ++ computeAndAddLiveIns(LiveRegs, *FourMBB2); ++ computeAndAddLiveIns(LiveRegs, *FourMBB3); ++ computeAndAddLiveIns(LiveRegs, *FiveMBB); ++ computeAndAddLiveIns(LiveRegs, *FiveMBB0); ++ computeAndAddLiveIns(LiveRegs, *FiveMBB1); ++ computeAndAddLiveIns(LiveRegs, *FiveMBB2); ++ computeAndAddLiveIns(LiveRegs, *FiveMBB3); ++ computeAndAddLiveIns(LiveRegs, *SixMBB); ++ computeAndAddLiveIns(LiveRegs, *SixMBB0); ++ computeAndAddLiveIns(LiveRegs, *SixMBB1); ++ computeAndAddLiveIns(LiveRegs, *SixMBB2); ++ computeAndAddLiveIns(LiveRegs, *SixMBB3); ++ computeAndAddLiveIns(LiveRegs, *sinkMBB); ++ computeAndAddLiveIns(LiveRegs, *exitMBB); ++ ++ NMBBI = BB.end(); ++ I->eraseFromParent(); ++ ++ return true; ++} ++ ++bool LoongArchExpandPseudo::expandAtomicBinOpSubword( ++ MachineBasicBlock &BB, MachineBasicBlock::iterator I, ++ MachineBasicBlock::iterator &NMBBI) { ++ ++ MachineFunction *MF = BB.getParent(); ++ ++ DebugLoc DL = I->getDebugLoc(); ++ unsigned LL, SC; ++ unsigned BEQ = LoongArch::BEQ32; ++ unsigned SEOp = LoongArch::EXT_W_H32; ++ ++ LL = LoongArch::LL_W; ++ SC = LoongArch::SC_W; ++ ++ bool IsSwap = false; ++ bool IsNand = false; ++ bool IsMAX = false; ++ bool IsMIN = false; ++ bool IsUnsigned = false; ++ ++ unsigned Opcode = 0; ++ switch (I->getOpcode()) { ++ case LoongArch::ATOMIC_LOAD_NAND_I8_POSTRA: ++ SEOp = LoongArch::EXT_W_B32; ++ LLVM_FALLTHROUGH; ++ case LoongArch::ATOMIC_LOAD_NAND_I16_POSTRA: ++ IsNand = true; ++ break; ++ case LoongArch::ATOMIC_SWAP_I8_POSTRA: ++ SEOp = LoongArch::EXT_W_B32; ++ LLVM_FALLTHROUGH; ++ case LoongArch::ATOMIC_SWAP_I16_POSTRA: ++ IsSwap = true; ++ break; ++ case LoongArch::ATOMIC_LOAD_ADD_I8_POSTRA: ++ SEOp = LoongArch::EXT_W_B32; ++ LLVM_FALLTHROUGH; ++ case LoongArch::ATOMIC_LOAD_ADD_I16_POSTRA: ++ Opcode = LoongArch::ADD_W; ++ break; ++ case LoongArch::ATOMIC_LOAD_MAX_I8_POSTRA: ++ SEOp = LoongArch::EXT_W_B32; ++ LLVM_FALLTHROUGH; ++ case LoongArch::ATOMIC_LOAD_MAX_I16_POSTRA: ++ Opcode = LoongArch::AMMAX_DB_W; ++ IsMAX = true; ++ break; ++ case LoongArch::ATOMIC_LOAD_MIN_I8_POSTRA: ++ SEOp = LoongArch::EXT_W_B32; ++ LLVM_FALLTHROUGH; ++ case LoongArch::ATOMIC_LOAD_MIN_I16_POSTRA: ++ Opcode = LoongArch::AMMIN_DB_W; ++ IsMIN = true; ++ break; ++ case LoongArch::ATOMIC_LOAD_UMAX_I8_POSTRA: ++ SEOp = LoongArch::EXT_W_B32; ++ LLVM_FALLTHROUGH; ++ case LoongArch::ATOMIC_LOAD_UMAX_I16_POSTRA: ++ Opcode = LoongArch::AMMAX_DB_WU; ++ IsMAX = true; ++ IsUnsigned = true; ++ break; ++ case LoongArch::ATOMIC_LOAD_UMIN_I8_POSTRA: ++ SEOp = LoongArch::EXT_W_B32; ++ LLVM_FALLTHROUGH; ++ case LoongArch::ATOMIC_LOAD_UMIN_I16_POSTRA: ++ Opcode = LoongArch::AMMIN_DB_WU; ++ IsMIN = true; ++ IsUnsigned = true; ++ break; ++ case LoongArch::ATOMIC_LOAD_SUB_I8_POSTRA: ++ SEOp = LoongArch::EXT_W_B32; ++ LLVM_FALLTHROUGH; ++ case LoongArch::ATOMIC_LOAD_SUB_I16_POSTRA: ++ Opcode = LoongArch::SUB_W; ++ break; ++ case LoongArch::ATOMIC_LOAD_AND_I8_POSTRA: ++ SEOp = LoongArch::EXT_W_B32; ++ LLVM_FALLTHROUGH; ++ case LoongArch::ATOMIC_LOAD_AND_I16_POSTRA: ++ Opcode = LoongArch::AND32; ++ break; ++ case LoongArch::ATOMIC_LOAD_OR_I8_POSTRA: ++ SEOp = LoongArch::EXT_W_B32; ++ LLVM_FALLTHROUGH; ++ case LoongArch::ATOMIC_LOAD_OR_I16_POSTRA: ++ Opcode = LoongArch::OR32; ++ break; ++ case LoongArch::ATOMIC_LOAD_XOR_I8_POSTRA: ++ SEOp = LoongArch::EXT_W_B32; ++ LLVM_FALLTHROUGH; ++ case LoongArch::ATOMIC_LOAD_XOR_I16_POSTRA: ++ Opcode = LoongArch::XOR32; ++ break; ++ default: ++ llvm_unreachable("Unknown subword atomic pseudo for expansion!"); ++ } ++ ++ unsigned Dest = I->getOperand(0).getReg(); ++ unsigned Ptr = I->getOperand(1).getReg(); ++ unsigned Incr = I->getOperand(2).getReg(); ++ unsigned Mask = I->getOperand(3).getReg(); ++ unsigned Mask2 = I->getOperand(4).getReg(); ++ unsigned ShiftAmnt = I->getOperand(5).getReg(); ++ unsigned OldVal = I->getOperand(6).getReg(); ++ unsigned BinOpRes = I->getOperand(7).getReg(); ++ unsigned StoreVal = I->getOperand(8).getReg(); ++ ++ const BasicBlock *LLVM_BB = BB.getBasicBlock(); ++ MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineFunction::iterator It = ++BB.getIterator(); ++ MF->insert(It, loopMBB); ++ MF->insert(It, sinkMBB); ++ MF->insert(It, exitMBB); ++ ++ exitMBB->splice(exitMBB->begin(), &BB, std::next(I), BB.end()); ++ exitMBB->transferSuccessorsAndUpdatePHIs(&BB); ++ ++ BB.addSuccessor(loopMBB, BranchProbability::getOne()); ++ loopMBB->addSuccessor(sinkMBB); ++ loopMBB->addSuccessor(loopMBB); ++ loopMBB->normalizeSuccProbs(); ++ ++ BuildMI(loopMBB, DL, TII->get(LL), OldVal).addReg(Ptr).addImm(0); ++ if (IsNand) { ++ // and andres, oldval, incr2 ++ // nor binopres, $0, andres ++ // and newval, binopres, mask ++ BuildMI(loopMBB, DL, TII->get(LoongArch::AND32), BinOpRes) ++ .addReg(OldVal) ++ .addReg(Incr); ++ BuildMI(loopMBB, DL, TII->get(LoongArch::NOR32), BinOpRes) ++ .addReg(LoongArch::ZERO) ++ .addReg(BinOpRes); ++ BuildMI(loopMBB, DL, TII->get(LoongArch::AND32), BinOpRes) ++ .addReg(BinOpRes) ++ .addReg(Mask); ++ } else if (IsMAX || IsMIN) { ++ ++ unsigned SLTScratch4 = IsUnsigned ? LoongArch::SLTU32 : LoongArch::SLT32; ++ unsigned CMPIncr = IsMAX ? LoongArch::MASKEQZ32 : LoongArch::MASKNEZ32; ++ unsigned CMPOldVal = IsMAX ? LoongArch::MASKNEZ32 : LoongArch::MASKEQZ32; ++ ++ unsigned Scratch4 = I->getOperand(9).getReg(); ++ unsigned Scratch5 = I->getOperand(10).getReg(); ++ ++ BuildMI(loopMBB, DL, TII->get(LoongArch::AND32), Scratch5) ++ .addReg(OldVal) ++ .addReg(Mask); ++ BuildMI(loopMBB, DL, TII->get(LoongArch::AND32), Incr) ++ .addReg(Incr) ++ .addReg(Mask); ++ BuildMI(loopMBB, DL, TII->get(SLTScratch4), Scratch4) ++ .addReg(Scratch5) ++ .addReg(Incr); ++ BuildMI(loopMBB, DL, TII->get(CMPOldVal), BinOpRes) ++ .addReg(Scratch5) ++ .addReg(Scratch4); ++ BuildMI(loopMBB, DL, TII->get(CMPIncr), Scratch4) ++ .addReg(Incr) ++ .addReg(Scratch4); ++ BuildMI(loopMBB, DL, TII->get(LoongArch::OR32), BinOpRes) ++ .addReg(BinOpRes) ++ .addReg(Scratch4); ++ ++ } else if (!IsSwap) { ++ // binopres, oldval, incr2 ++ // and newval, binopres, mask ++ BuildMI(loopMBB, DL, TII->get(Opcode), BinOpRes) ++ .addReg(OldVal) ++ .addReg(Incr); ++ BuildMI(loopMBB, DL, TII->get(LoongArch::AND32), BinOpRes) ++ .addReg(BinOpRes) ++ .addReg(Mask); ++ } else { // atomic.swap ++ // and newval, incr2, mask ++ BuildMI(loopMBB, DL, TII->get(LoongArch::AND32), BinOpRes) ++ .addReg(Incr) ++ .addReg(Mask); ++ } ++ ++ // and StoreVal, OlddVal, Mask2 ++ // or StoreVal, StoreVal, BinOpRes ++ // StoreVal = sc StoreVal, 0(Ptr) ++ // beq StoreVal, zero, loopMBB ++ BuildMI(loopMBB, DL, TII->get(LoongArch::AND32), StoreVal) ++ .addReg(OldVal) ++ .addReg(Mask2); ++ BuildMI(loopMBB, DL, TII->get(LoongArch::OR32), StoreVal) ++ .addReg(StoreVal) ++ .addReg(BinOpRes); ++ BuildMI(loopMBB, DL, TII->get(SC), StoreVal) ++ .addReg(StoreVal) ++ .addReg(Ptr) ++ .addImm(0); ++ BuildMI(loopMBB, DL, TII->get(BEQ)) ++ .addReg(StoreVal) ++ .addReg(LoongArch::ZERO) ++ .addMBB(loopMBB); ++ ++ // sinkMBB: ++ // and maskedoldval1,oldval,mask ++ // srl srlres,maskedoldval1,shiftamt ++ // sign_extend dest,srlres ++ ++ sinkMBB->addSuccessor(exitMBB, BranchProbability::getOne()); ++ ++ BuildMI(sinkMBB, DL, TII->get(LoongArch::AND32), Dest) ++ .addReg(OldVal) ++ .addReg(Mask); ++ BuildMI(sinkMBB, DL, TII->get(LoongArch::SRL_W), Dest) ++ .addReg(Dest) ++ .addReg(ShiftAmnt); ++ ++ BuildMI(sinkMBB, DL, TII->get(SEOp), Dest).addReg(Dest); ++ ++ LivePhysRegs LiveRegs; ++ computeAndAddLiveIns(LiveRegs, *loopMBB); ++ computeAndAddLiveIns(LiveRegs, *sinkMBB); ++ computeAndAddLiveIns(LiveRegs, *exitMBB); ++ ++ NMBBI = BB.end(); ++ I->eraseFromParent(); ++ ++ return true; ++} ++ ++bool LoongArchExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB, ++ MachineBasicBlock::iterator I, ++ MachineBasicBlock::iterator &NMBBI, ++ unsigned Size) { ++ MachineFunction *MF = BB.getParent(); ++ ++ DebugLoc DL = I->getDebugLoc(); ++ ++ unsigned LL, SC, ZERO, BEQ, SUB; ++ if (Size == 4) { ++ LL = LoongArch::LL_W; ++ SC = LoongArch::SC_W; ++ BEQ = LoongArch::BEQ32; ++ ZERO = LoongArch::ZERO; ++ SUB = LoongArch::SUB_W; ++ } else { ++ LL = LoongArch::LL_D; ++ SC = LoongArch::SC_D; ++ ZERO = LoongArch::ZERO_64; ++ BEQ = LoongArch::BEQ; ++ SUB = LoongArch::SUB_D; ++ } ++ ++ unsigned OldVal = I->getOperand(0).getReg(); ++ unsigned Ptr = I->getOperand(1).getReg(); ++ unsigned Incr = I->getOperand(2).getReg(); ++ unsigned Scratch = I->getOperand(3).getReg(); ++ ++ unsigned Opcode = 0; ++ unsigned OR = 0; ++ unsigned AND = 0; ++ unsigned NOR = 0; ++ bool IsNand = false; ++ bool IsSub = false; ++ switch (I->getOpcode()) { ++ case LoongArch::ATOMIC_LOAD_ADD_I32_POSTRA: ++ Opcode = LoongArch::AMADD_DB_W; ++ break; ++ case LoongArch::ATOMIC_LOAD_SUB_I32_POSTRA: ++ IsSub = true; ++ Opcode = LoongArch::AMADD_DB_W; ++ break; ++ case LoongArch::ATOMIC_LOAD_AND_I32_POSTRA: ++ Opcode = LoongArch::AMAND_DB_W; ++ break; ++ case LoongArch::ATOMIC_LOAD_OR_I32_POSTRA: ++ Opcode = LoongArch::AMOR_DB_W; ++ break; ++ case LoongArch::ATOMIC_LOAD_XOR_I32_POSTRA: ++ Opcode = LoongArch::AMXOR_DB_W; ++ break; ++ case LoongArch::ATOMIC_LOAD_NAND_I32_POSTRA: ++ IsNand = true; ++ AND = LoongArch::AND32; ++ NOR = LoongArch::NOR32; ++ break; ++ case LoongArch::ATOMIC_SWAP_I32_POSTRA: ++ OR = LoongArch::AMSWAP_DB_W; ++ break; ++ case LoongArch::ATOMIC_LOAD_MAX_I32_POSTRA: ++ Opcode = LoongArch::AMMAX_DB_W; ++ break; ++ case LoongArch::ATOMIC_LOAD_MIN_I32_POSTRA: ++ Opcode = LoongArch::AMMIN_DB_W; ++ break; ++ case LoongArch::ATOMIC_LOAD_UMAX_I32_POSTRA: ++ Opcode = LoongArch::AMMAX_DB_WU; ++ break; ++ case LoongArch::ATOMIC_LOAD_UMIN_I32_POSTRA: ++ Opcode = LoongArch::AMMIN_DB_WU; ++ break; ++ case LoongArch::ATOMIC_LOAD_ADD_I64_POSTRA: ++ Opcode = LoongArch::AMADD_DB_D; ++ break; ++ case LoongArch::ATOMIC_LOAD_SUB_I64_POSTRA: ++ IsSub = true; ++ Opcode = LoongArch::AMADD_DB_D; ++ break; ++ case LoongArch::ATOMIC_LOAD_AND_I64_POSTRA: ++ Opcode = LoongArch::AMAND_DB_D; ++ break; ++ case LoongArch::ATOMIC_LOAD_OR_I64_POSTRA: ++ Opcode = LoongArch::AMOR_DB_D; ++ break; ++ case LoongArch::ATOMIC_LOAD_XOR_I64_POSTRA: ++ Opcode = LoongArch::AMXOR_DB_D; ++ break; ++ case LoongArch::ATOMIC_LOAD_NAND_I64_POSTRA: ++ IsNand = true; ++ AND = LoongArch::AND; ++ NOR = LoongArch::NOR; ++ break; ++ case LoongArch::ATOMIC_SWAP_I64_POSTRA: ++ OR = LoongArch::AMSWAP_DB_D; ++ break; ++ case LoongArch::ATOMIC_LOAD_MAX_I64_POSTRA: ++ Opcode = LoongArch::AMMAX_DB_D; ++ break; ++ case LoongArch::ATOMIC_LOAD_MIN_I64_POSTRA: ++ Opcode = LoongArch::AMMIN_DB_D; ++ break; ++ case LoongArch::ATOMIC_LOAD_UMAX_I64_POSTRA: ++ Opcode = LoongArch::AMMAX_DB_DU; ++ break; ++ case LoongArch::ATOMIC_LOAD_UMIN_I64_POSTRA: ++ Opcode = LoongArch::AMMIN_DB_DU; ++ break; ++ default: ++ llvm_unreachable("Unknown pseudo atomic!"); ++ } ++ ++ const BasicBlock *LLVM_BB = BB.getBasicBlock(); ++ MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineFunction::iterator It = ++BB.getIterator(); ++ MF->insert(It, loopMBB); ++ MF->insert(It, exitMBB); ++ ++ exitMBB->splice(exitMBB->begin(), &BB, std::next(I), BB.end()); ++ exitMBB->transferSuccessorsAndUpdatePHIs(&BB); ++ ++ BB.addSuccessor(loopMBB, BranchProbability::getOne()); ++ loopMBB->addSuccessor(exitMBB); ++ if (!Opcode && IsNand) ++ loopMBB->addSuccessor(loopMBB); ++ loopMBB->normalizeSuccProbs(); ++ ++ assert((OldVal != Ptr) && "Clobbered the wrong ptr reg!"); ++ assert((OldVal != Incr) && "Clobbered the wrong reg!"); ++ if (Opcode) { ++ if(IsSub){ ++ BuildMI(loopMBB, DL, TII->get(SUB), Scratch).addReg(ZERO).addReg(Incr); ++ BuildMI(loopMBB, DL, TII->get(Opcode), OldVal).addReg(Scratch).addReg(Ptr).addImm(0); ++ } ++ else{ ++ BuildMI(loopMBB, DL, TII->get(Opcode), OldVal).addReg(Incr).addReg(Ptr).addImm(0); ++ } ++ } else if (IsNand) { ++ assert(AND && NOR && ++ "Unknown nand instruction for atomic pseudo expansion"); ++ BuildMI(loopMBB, DL, TII->get(LL), OldVal).addReg(Ptr).addImm(0); ++ BuildMI(loopMBB, DL, TII->get(AND), Scratch).addReg(OldVal).addReg(Incr); ++ BuildMI(loopMBB, DL, TII->get(NOR), Scratch).addReg(ZERO).addReg(Scratch); ++ BuildMI(loopMBB, DL, TII->get(SC), Scratch).addReg(Scratch).addReg(Ptr).addImm(0); ++ BuildMI(loopMBB, DL, TII->get(BEQ)).addReg(Scratch).addReg(ZERO).addMBB(loopMBB); ++ } else { ++ assert(OR && "Unknown instruction for atomic pseudo expansion!"); ++ BuildMI(loopMBB, DL, TII->get(OR), OldVal).addReg(Incr).addReg(Ptr).addImm(0); ++ } ++ ++ ++ NMBBI = BB.end(); ++ I->eraseFromParent(); ++ ++ LivePhysRegs LiveRegs; ++ computeAndAddLiveIns(LiveRegs, *loopMBB); ++ computeAndAddLiveIns(LiveRegs, *exitMBB); ++ ++ return true; ++} ++ ++bool LoongArchExpandPseudo::expandLoadAddr(MachineBasicBlock &BB, ++ MachineBasicBlock::iterator I, ++ MachineBasicBlock::iterator &NMBBI) { ++ MachineFunction *MF = BB.getParent(); ++ MachineInstr &MI = *I; ++ DebugLoc DL = MI.getDebugLoc(); ++ ++ unsigned Op = MI.getOpcode(); ++ unsigned DestReg = MI.getOperand(0).getReg(); ++ unsigned TmpReg; ++ const MachineOperand &MO = MI.getOperand(1); ++ Reloc::Model RM = MF->getTarget().getRelocationModel(); ++ ++ MachineInstrBuilder MIB1, MIB2, MIB3, MIB4, MIB5; ++ unsigned HiFlag, LoFlag, HigherFlag, HighestFlag; ++ unsigned HiOp, LoOp, HigherOp, HighestOp, LastOp; ++ bool UseGot = false; ++ ++ HiOp = LoongArch::PCADDU12I_ri; ++ LoOp = LoongArch::ORI_rri; ++ HigherOp = LoongArch::LU32I_D_ri; ++ HighestOp = LoongArch::LU52I_D_rri; ++ ++ switch (Op) { ++ case LoongArch::LoadAddrLocal: ++ if (RM == Reloc::Static) { // for jit ++ HiFlag = LoongArchII::MO_ABS_HI; ++ LoFlag = LoongArchII::MO_ABS_LO; ++ HigherFlag = LoongArchII::MO_ABS_HIGHER; ++ HighestFlag = LoongArchII::MO_ABS_HIGHEST; ++ // lu12i.w + ori + lu32i.d + lu52i.d ++ HiOp = LoongArch::LU12I_W; ++ LoOp = LoongArch::ORI; ++ HigherOp = LoongArch::LU32I_D; ++ HighestOp = LoongArch::LU52I_D; ++ } else { ++ // pcaddu12i + addi.d ++ LoFlag = LoongArchII::MO_PCREL_LO; ++ HiFlag = LoongArchII::MO_PCREL_HI; ++ LoOp = LoongArch::ADDI_D_rri; ++ } ++ break; ++ case LoongArch::LoadAddrLocalRR: ++ // pcaddu12i + ori + lu32i.d + lu52i.d + add.d ++ LoFlag = LoongArchII::MO_PCREL_RRLO; ++ HiFlag = LoongArchII::MO_PCREL_RRHI; ++ HigherFlag = LoongArchII::MO_PCREL_RRHIGHER; ++ HighestFlag = LoongArchII::MO_PCREL_RRHIGHEST; ++ LastOp = LoongArch::ADD_D_rrr; ++ break; ++ case LoongArch::LoadAddrGlobal: ++ case LoongArch::LoadAddrGlobal_Alias: ++ // pcaddu12i + ld.d ++ LoFlag = LoongArchII::MO_GOT_LO; ++ HiFlag = LoongArchII::MO_GOT_HI; ++ HiOp = LoongArch::PCADDU12I_rii; ++ LoOp = LoongArch::LD_D_rrii; ++ UseGot = true; ++ break; ++ case LoongArch::LoadAddrGlobalRR: ++ // pcaddu12i + ori + lu32i.d + lu52i.d +ldx.d ++ LoFlag = LoongArchII::MO_GOT_RRLO; ++ HiFlag = LoongArchII::MO_GOT_RRHI; ++ HigherFlag = LoongArchII::MO_GOT_RRHIGHER; ++ HighestFlag = LoongArchII::MO_GOT_RRHIGHEST; ++ HiOp = LoongArch::PCADDU12I_rii; ++ LoOp = LoongArch::ORI_rrii; ++ HigherOp = LoongArch::LU32I_D_rii; ++ HighestOp = LoongArch::LU52I_D_rrii; ++ LastOp = LoongArch::LDX_D_rrr; ++ UseGot = true; ++ break; ++ case LoongArch::LoadAddrTLS_LE: ++ // lu12i.w + ori + lu32i.d + lu52i.d ++ LoFlag = LoongArchII::MO_TLSLE_LO; ++ HiFlag = LoongArchII::MO_TLSLE_HI; ++ HigherFlag = LoongArchII::MO_TLSLE_HIGHER; ++ HighestFlag = LoongArchII::MO_TLSLE_HIGHEST; ++ HiOp = LoongArch::LU12I_W_ri; ++ break; ++ case LoongArch::LoadAddrTLS_IE: ++ // pcaddu12i + ld.d ++ LoFlag = LoongArchII::MO_TLSIE_LO; ++ HiFlag = LoongArchII::MO_TLSIE_HI; ++ HiOp = LoongArch::PCADDU12I_rii; ++ LoOp = LoongArch::LD_D_rrii; ++ UseGot = true; ++ break; ++ case LoongArch::LoadAddrTLS_IE_RR: ++ // pcaddu12i + ori + lu32i.d + lu52i.d +ldx.d ++ LoFlag = LoongArchII::MO_TLSIE_RRLO; ++ HiFlag = LoongArchII::MO_TLSIE_RRHI; ++ HigherFlag = LoongArchII::MO_TLSIE_RRHIGHER; ++ HighestFlag = LoongArchII::MO_TLSIE_RRHIGHEST; ++ HiOp = LoongArch::PCADDU12I_rii; ++ LoOp = LoongArch::ORI_rrii; ++ HigherOp = LoongArch::LU32I_D_rii; ++ HighestOp = LoongArch::LU52I_D_rrii; ++ LastOp = LoongArch::LDX_D_rrr; ++ UseGot = true; ++ break; ++ case LoongArch::LoadAddrTLS_LD: ++ case LoongArch::LoadAddrTLS_GD: ++ // pcaddu12i + addi.d ++ LoFlag = LoongArchII::MO_TLSGD_LO; ++ HiFlag = LoongArchII::MO_TLSGD_HI; ++ HiOp = LoongArch::PCADDU12I_rii; ++ LoOp = LoongArch::ADDI_D_rrii; ++ UseGot = true; ++ break; ++ case LoongArch::LoadAddrTLS_LD_RR: ++ case LoongArch::LoadAddrTLS_GD_RR: ++ // pcaddu12i + ori + lu32i.d + lu52i.d + add.d ++ LoFlag = LoongArchII::MO_TLSGD_RRLO; ++ HiFlag = LoongArchII::MO_TLSGD_RRHI; ++ HigherFlag = LoongArchII::MO_TLSGD_RRHIGHER; ++ HighestFlag = LoongArchII::MO_TLSGD_RRHIGHEST; ++ HiOp = LoongArch::PCADDU12I_rii; ++ LoOp = LoongArch::ORI_rrii; ++ HigherOp = LoongArch::LU32I_D_rii; ++ HighestOp = LoongArch::LU52I_D_rrii; ++ LastOp = LoongArch::ADD_D_rrr; ++ UseGot = true; ++ break; ++ default: ++ break; ++ } ++ ++ MIB1 = BuildMI(BB, I, DL, TII->get(HiOp), DestReg); ++ ++ switch (Op) { ++ case LoongArch::LoadAddrLocal: ++ if (RM == Reloc::Static) { // for jit ++ // la.abs rd, symbol ++ MIB2 = BuildMI(BB, I, DL, TII->get(LoOp), DestReg).addReg(DestReg); ++ MIB3 = BuildMI(BB, I, DL, TII->get(HigherOp), DestReg); ++ MIB4 = BuildMI(BB, I, DL, TII->get(HighestOp), DestReg).addReg(DestReg); ++ if (MO.isJTI()) { ++ MIB1.addJumpTableIndex(MO.getIndex(), HiFlag); ++ MIB2.addJumpTableIndex(MO.getIndex(), LoFlag); ++ MIB3.addJumpTableIndex(MO.getIndex(), HigherFlag); ++ MIB4.addJumpTableIndex(MO.getIndex(), HighestFlag); ++ } else if (MO.isBlockAddress()) { ++ MIB1.addBlockAddress(MO.getBlockAddress(), 0, HiFlag); ++ MIB2.addBlockAddress(MO.getBlockAddress(), 0, LoFlag); ++ MIB3.addBlockAddress(MO.getBlockAddress(), 0, HigherFlag); ++ MIB4.addBlockAddress(MO.getBlockAddress(), 0, HighestFlag); ++ } else { ++ MIB1.addDisp(MO, 0, HiFlag); ++ MIB2.addDisp(MO, 0, LoFlag); ++ MIB3.addDisp(MO, 0, HigherFlag); ++ MIB4.addDisp(MO, 0, HighestFlag); ++ } ++ break; ++ } ++ LLVM_FALLTHROUGH; ++ case LoongArch::LoadAddrGlobal: // la.global rd, symbol ++ case LoongArch::LoadAddrGlobal_Alias: // la rd, symbol ++ case LoongArch::LoadAddrTLS_IE: // la.tls.ie rd, symbol ++ case LoongArch::LoadAddrTLS_LD: // la.tls.ld rd, symbol ++ case LoongArch::LoadAddrTLS_GD: // la.tls.gd rd, symbol ++ MIB2 = BuildMI(BB, I, DL, TII->get(LoOp), DestReg) ++ .addReg(DestReg); ++ if (MO.isJTI()) { ++ MIB1.addJumpTableIndex(MO.getIndex(), HiFlag); ++ MIB2.addJumpTableIndex(MO.getIndex(), LoFlag); ++ } else if (MO.isBlockAddress()) { ++ MIB1.addBlockAddress(MO.getBlockAddress(), 0, HiFlag); ++ MIB2.addBlockAddress(MO.getBlockAddress(), 0, LoFlag); ++ } else { ++ MIB1.addDisp(MO, 0, HiFlag); ++ MIB2.addDisp(MO, 0, LoFlag); ++ } ++ if (UseGot == true) { ++ MIB1.addExternalSymbol("_GLOBAL_OFFSET_TABLE_"); ++ MIB2.addExternalSymbol("_GLOBAL_OFFSET_TABLE_"); ++ } ++ break; ++ ++ // FIXME: The following will never be used now, because there is no ++ // related implementation during target-lowering. ++ case LoongArch::LoadAddrLocalRR: // la.local rd, rs, symbol ++ case LoongArch::LoadAddrGlobalRR: // la.global rd, rs, symbol ++ case LoongArch::LoadAddrTLS_IE_RR: // la.tls.ie rd, rs, symbol ++ case LoongArch::LoadAddrTLS_LD_RR: // la.tls.ld rd, rs, symbol ++ case LoongArch::LoadAddrTLS_GD_RR: // la.tls.gd rd, rs, symbol ++ TmpReg = MI.getOperand(MI.getNumOperands()-1).getReg(); ++ MIB2 = BuildMI(BB, I, DL, TII->get(LoOp), TmpReg) ++ .addReg(TmpReg); ++ MIB3 = BuildMI(BB, I, DL, TII->get(HigherOp), TmpReg); ++ MIB4 = BuildMI(BB, I, DL, TII->get(HighestOp), TmpReg) ++ .addReg(TmpReg); ++ MIB5 = BuildMI(BB, I, DL, TII->get(LastOp), DestReg) ++ .addReg(DestReg) ++ .addReg(TmpReg); ++ if (MO.isJTI()) { ++ MIB1.addJumpTableIndex(MO.getIndex(), HiFlag); ++ MIB2.addJumpTableIndex(MO.getIndex(), LoFlag); ++ MIB3.addJumpTableIndex(MO.getIndex(), HigherFlag); ++ MIB4.addJumpTableIndex(MO.getIndex(), HighestFlag); ++ } else if (MO.isBlockAddress()) { ++ MIB1.addBlockAddress(MO.getBlockAddress(), 0, HiFlag); ++ MIB2.addBlockAddress(MO.getBlockAddress(), 0, LoFlag); ++ MIB3.addBlockAddress(MO.getBlockAddress(), 0, HigherFlag); ++ MIB4.addBlockAddress(MO.getBlockAddress(), 0, HighestFlag); ++ } else { ++ MIB1.addDisp(MO, 0, HiFlag); ++ MIB2.addDisp(MO, 0, LoFlag); ++ MIB3.addDisp(MO, 0, HigherFlag); ++ MIB4.addDisp(MO, 0, HighestFlag); ++ } ++ if (UseGot == true) { ++ MIB1.addExternalSymbol("_GLOBAL_OFFSET_TABLE_"); ++ MIB2.addExternalSymbol("_GLOBAL_OFFSET_TABLE_"); ++ MIB3.addExternalSymbol("_GLOBAL_OFFSET_TABLE_"); ++ MIB4.addExternalSymbol("_GLOBAL_OFFSET_TABLE_"); ++ } ++ break; ++ case LoongArch::LoadAddrTLS_LE: // la.tls.le rd, symbol ++ MIB2 = BuildMI(BB, I, DL, TII->get(LoOp), DestReg) ++ .addReg(DestReg); ++ MIB3 = BuildMI(BB, I, DL, TII->get(HigherOp), DestReg); ++ MIB4 = BuildMI(BB, I, DL, TII->get(HighestOp), DestReg) ++ .addReg(DestReg); ++ if (MO.isJTI()) { ++ MIB1.addJumpTableIndex(MO.getIndex(), HiFlag); ++ MIB2.addJumpTableIndex(MO.getIndex(), LoFlag); ++ MIB3.addJumpTableIndex(MO.getIndex(), HigherFlag); ++ MIB4.addJumpTableIndex(MO.getIndex(), HighestFlag); ++ } else if (MO.isBlockAddress()) { ++ MIB1.addBlockAddress(MO.getBlockAddress(), 0, HiFlag); ++ MIB2.addBlockAddress(MO.getBlockAddress(), 0, LoFlag); ++ MIB3.addBlockAddress(MO.getBlockAddress(), 0, HigherFlag); ++ MIB4.addBlockAddress(MO.getBlockAddress(), 0, HighestFlag); ++ } else { ++ MIB1.addDisp(MO, 0, HiFlag); ++ MIB2.addDisp(MO, 0, LoFlag); ++ MIB3.addDisp(MO, 0, HigherFlag); ++ MIB4.addDisp(MO, 0, HighestFlag); ++ } ++ break; ++ default: ++ break; ++ } ++ ++ MI.eraseFromParent(); ++ ++ return true; ++} ++ ++bool LoongArchExpandPseudo::expandPseudoTailCall( ++ MachineBasicBlock &BB, MachineBasicBlock::iterator I) { ++ ++ MachineInstr &MI = *I; ++ DebugLoc DL = MI.getDebugLoc(); ++ ++ const MachineOperand &MO = MI.getOperand(0); ++ ++ unsigned NoFlag = LoongArchII::MO_NO_FLAG; ++ ++ MachineInstrBuilder MIB = ++ BuildMI(BB, I, DL, TII->get(LoongArch::PseudoTailReturn)); ++ ++ if (MO.isSymbol()) { ++ MIB.addExternalSymbol(MO.getSymbolName(), NoFlag); ++ } else { ++ MIB.addDisp(MO, 0, NoFlag); ++ } ++ ++ MI.eraseFromParent(); ++ ++ return true; ++} ++ ++bool LoongArchExpandPseudo::expandPseudoCall(MachineBasicBlock &BB, ++ MachineBasicBlock::iterator I, ++ MachineBasicBlock::iterator &NMBBI) { ++ MachineFunction *MF = BB.getParent(); ++ MachineInstr &MI = *I; ++ DebugLoc DL = MI.getDebugLoc(); ++ CodeModel::Model M = MF->getTarget().getCodeModel(); ++ Reloc::Model RM = MF->getTarget().getRelocationModel(); ++ ++ unsigned Ra = LoongArch::RA_64; ++ const MachineOperand &MO = MI.getOperand(0); ++ unsigned HiFlag, LoFlag, HigherFlag, HighestFlag, NoFlag; ++ ++ HiFlag = LoongArchII::MO_CALL_HI; ++ LoFlag = LoongArchII::MO_CALL_LO; ++ NoFlag = LoongArchII::MO_NO_FLAG; ++ ++ if (RM == Reloc::Static) { // for jit ++ MachineInstrBuilder MIB1, MIB2, MIB3, MIB4, MIB5; ++ ++ HiFlag = LoongArchII::MO_ABS_HI; ++ LoFlag = LoongArchII::MO_ABS_LO; ++ HigherFlag = LoongArchII::MO_ABS_HIGHER; ++ HighestFlag = LoongArchII::MO_ABS_HIGHEST; ++ // lu12i.w + ori + lu32i.d + lu52i.d + jirl ++ ++ MIB1 = BuildMI(BB, I, DL, TII->get(LoongArch::LU12I_W), Ra); ++ MIB2 = BuildMI(BB, I, DL, TII->get(LoongArch::ORI), Ra) ++ .addReg(Ra); ++ MIB3 = BuildMI(BB, I, DL, TII->get(LoongArch::LU32I_D), Ra); ++ MIB4 = BuildMI(BB, I, DL, TII->get(LoongArch::LU52I_D), Ra) ++ .addReg(Ra); ++ MIB5 = ++ BuildMI(BB, I, DL, TII->get(LoongArch::JIRL), Ra).addReg(Ra).addImm(0); ++ if (MO.isSymbol()) { ++ MIB1.addExternalSymbol(MO.getSymbolName(), HiFlag); ++ MIB2.addExternalSymbol(MO.getSymbolName(), LoFlag); ++ MIB3.addExternalSymbol(MO.getSymbolName(), HigherFlag); ++ MIB4.addExternalSymbol(MO.getSymbolName(), HighestFlag); ++ } else { ++ MIB1.addDisp(MO, 0, HiFlag); ++ MIB2.addDisp(MO, 0, LoFlag); ++ MIB3.addDisp(MO, 0, HigherFlag); ++ MIB4.addDisp(MO, 0, HighestFlag); ++ } ++ } else if (M == CodeModel::Large) { ++ // pcaddu18i + jirl ++ MachineInstrBuilder MIB1; ++ MachineInstrBuilder MIB2; ++ ++ MIB1 = BuildMI(BB, I, DL, TII->get(LoongArch::PCADDU18I), Ra); ++ MIB2 = BuildMI(BB, I, DL, TII->get(LoongArch::JIRL_CALL), Ra).addReg(Ra); ++ if (MO.isSymbol()) { ++ MIB1.addExternalSymbol(MO.getSymbolName(), HiFlag); ++ MIB2.addExternalSymbol(MO.getSymbolName(), LoFlag); ++ } else { ++ MIB1.addDisp(MO, 0, HiFlag); ++ MIB2.addDisp(MO, 0, LoFlag); ++ } ++ } else { ++ // bl ++ MachineInstrBuilder MIB1; ++ MIB1 = BuildMI(BB, I, DL, TII->get(LoongArch::BL)); ++ if (MO.isSymbol()) { ++ MIB1.addExternalSymbol(MO.getSymbolName(), NoFlag); ++ } else { ++ MIB1.addDisp(MO, 0, NoFlag); ++ } ++ } ++ ++ MI.eraseFromParent(); ++ ++ return true; ++} ++ ++bool LoongArchExpandPseudo::expandPseudoTEQ(MachineBasicBlock &BB, ++ MachineBasicBlock::iterator I, ++ MachineBasicBlock::iterator &NMBBI) { ++ MachineInstr &MI = *I; ++ DebugLoc DL = MI.getDebugLoc(); ++ ++ unsigned Divisor = MI.getOperand(0).getReg(); ++ unsigned BneOp = LoongArch::BNE; ++ unsigned Zero = LoongArch::ZERO_64; ++ ++ // beq $Divisor, $zero, 8 ++ BuildMI(BB, I, DL, TII->get(BneOp), Divisor) ++ .addReg(Zero) ++ .addImm(8); ++ // break 7 ++ BuildMI(BB, I, DL, TII->get(LoongArch::BREAK)) ++ .addImm(7);; ++ ++ MI.eraseFromParent(); ++ ++ return true; ++} ++bool LoongArchExpandPseudo::expandMI(MachineBasicBlock &MBB, ++ MachineBasicBlock::iterator MBBI, ++ MachineBasicBlock::iterator &NMBB) { ++ ++ bool Modified = false; ++ ++ switch (MBBI->getOpcode()) { ++ case LoongArch::PseudoTEQ: ++ return expandPseudoTEQ(MBB, MBBI, NMBB); ++ case LoongArch::PseudoCall: ++ return expandPseudoCall(MBB, MBBI, NMBB); ++ case LoongArch::PseudoTailCall: ++ return expandPseudoTailCall(MBB, MBBI); ++ case LoongArch::LoadAddrLocal: ++ case LoongArch::LoadAddrLocalRR: ++ case LoongArch::LoadAddrGlobal: ++ case LoongArch::LoadAddrGlobalRR: ++ case LoongArch::LoadAddrGlobal_Alias: ++ case LoongArch::LoadAddrTLS_LD: ++ case LoongArch::LoadAddrTLS_LD_RR: ++ case LoongArch::LoadAddrTLS_GD: ++ case LoongArch::LoadAddrTLS_GD_RR: ++ case LoongArch::LoadAddrTLS_IE: ++ case LoongArch::LoadAddrTLS_IE_RR: ++ case LoongArch::LoadAddrTLS_LE: ++ return expandLoadAddr(MBB, MBBI, NMBB); ++ case LoongArch::ATOMIC_CMP_SWAP_I32_POSTRA: ++ case LoongArch::ATOMIC_CMP_SWAP_I64_POSTRA: ++ return expandAtomicCmpSwap(MBB, MBBI, NMBB); ++ case LoongArch::ATOMIC_CMP_SWAP_I8_POSTRA: ++ case LoongArch::ATOMIC_CMP_SWAP_I16_POSTRA: ++ return expandAtomicCmpSwapSubword(MBB, MBBI, NMBB); ++ case LoongArch::ATOMIC_SWAP_I8_POSTRA: ++ case LoongArch::ATOMIC_SWAP_I16_POSTRA: ++ case LoongArch::ATOMIC_LOAD_NAND_I8_POSTRA: ++ case LoongArch::ATOMIC_LOAD_NAND_I16_POSTRA: ++ case LoongArch::ATOMIC_LOAD_ADD_I8_POSTRA: ++ case LoongArch::ATOMIC_LOAD_ADD_I16_POSTRA: ++ case LoongArch::ATOMIC_LOAD_SUB_I8_POSTRA: ++ case LoongArch::ATOMIC_LOAD_SUB_I16_POSTRA: ++ case LoongArch::ATOMIC_LOAD_AND_I8_POSTRA: ++ case LoongArch::ATOMIC_LOAD_AND_I16_POSTRA: ++ case LoongArch::ATOMIC_LOAD_OR_I8_POSTRA: ++ case LoongArch::ATOMIC_LOAD_OR_I16_POSTRA: ++ case LoongArch::ATOMIC_LOAD_XOR_I8_POSTRA: ++ case LoongArch::ATOMIC_LOAD_XOR_I16_POSTRA: ++ case LoongArch::ATOMIC_LOAD_MAX_I8_POSTRA: ++ case LoongArch::ATOMIC_LOAD_MAX_I16_POSTRA: ++ case LoongArch::ATOMIC_LOAD_MIN_I8_POSTRA: ++ case LoongArch::ATOMIC_LOAD_MIN_I16_POSTRA: ++ case LoongArch::ATOMIC_LOAD_UMAX_I8_POSTRA: ++ case LoongArch::ATOMIC_LOAD_UMAX_I16_POSTRA: ++ case LoongArch::ATOMIC_LOAD_UMIN_I8_POSTRA: ++ case LoongArch::ATOMIC_LOAD_UMIN_I16_POSTRA: ++ return expandAtomicBinOpSubword(MBB, MBBI, NMBB); ++ case LoongArch::XINSERT_B_VIDX_PSEUDO_POSTRA: ++ case LoongArch::XINSERT_B_VIDX64_PSEUDO_POSTRA: ++ return expandXINSERT_BOp(MBB, MBBI, NMBB); ++ case LoongArch::INSERT_H_VIDX64_PSEUDO_POSTRA: ++ return expandINSERT_HOp(MBB, MBBI, NMBB); ++ case LoongArch::XINSERT_FW_VIDX_PSEUDO_POSTRA: ++ case LoongArch::XINSERT_FW_VIDX64_PSEUDO_POSTRA: ++ return expandXINSERT_FWOp(MBB, MBBI, NMBB); ++ case LoongArch::ATOMIC_LOAD_ADD_I32_POSTRA: ++ case LoongArch::ATOMIC_LOAD_SUB_I32_POSTRA: ++ case LoongArch::ATOMIC_LOAD_AND_I32_POSTRA: ++ case LoongArch::ATOMIC_LOAD_OR_I32_POSTRA: ++ case LoongArch::ATOMIC_LOAD_XOR_I32_POSTRA: ++ case LoongArch::ATOMIC_LOAD_NAND_I32_POSTRA: ++ case LoongArch::ATOMIC_SWAP_I32_POSTRA: ++ case LoongArch::ATOMIC_LOAD_MAX_I32_POSTRA: ++ case LoongArch::ATOMIC_LOAD_MIN_I32_POSTRA: ++ case LoongArch::ATOMIC_LOAD_UMAX_I32_POSTRA: ++ case LoongArch::ATOMIC_LOAD_UMIN_I32_POSTRA: ++ return expandAtomicBinOp(MBB, MBBI, NMBB, 4); ++ case LoongArch::ATOMIC_LOAD_ADD_I64_POSTRA: ++ case LoongArch::ATOMIC_LOAD_SUB_I64_POSTRA: ++ case LoongArch::ATOMIC_LOAD_AND_I64_POSTRA: ++ case LoongArch::ATOMIC_LOAD_OR_I64_POSTRA: ++ case LoongArch::ATOMIC_LOAD_XOR_I64_POSTRA: ++ case LoongArch::ATOMIC_LOAD_NAND_I64_POSTRA: ++ case LoongArch::ATOMIC_SWAP_I64_POSTRA: ++ case LoongArch::ATOMIC_LOAD_MAX_I64_POSTRA: ++ case LoongArch::ATOMIC_LOAD_MIN_I64_POSTRA: ++ case LoongArch::ATOMIC_LOAD_UMAX_I64_POSTRA: ++ case LoongArch::ATOMIC_LOAD_UMIN_I64_POSTRA: ++ return expandAtomicBinOp(MBB, MBBI, NMBB, 8); ++ default: ++ return Modified; ++ } ++} ++ ++bool LoongArchExpandPseudo::expandMBB(MachineBasicBlock &MBB) { ++ bool Modified = false; ++ ++ MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); ++ while (MBBI != E) { ++ MachineBasicBlock::iterator NMBBI = std::next(MBBI); ++ Modified |= expandMI(MBB, MBBI, NMBBI); ++ MBBI = NMBBI; ++ } ++ ++ return Modified; ++} ++ ++bool LoongArchExpandPseudo::runOnMachineFunction(MachineFunction &MF) { ++ STI = &static_cast(MF.getSubtarget()); ++ TII = STI->getInstrInfo(); ++ ++ bool Modified = false; ++ for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E; ++ ++MFI) ++ Modified |= expandMBB(*MFI); ++ ++ if (Modified) ++ MF.RenumberBlocks(); ++ ++ return Modified; ++} ++ ++/// createLoongArchExpandPseudoPass - returns an instance of the pseudo instruction ++/// expansion pass. ++FunctionPass *llvm::createLoongArchExpandPseudoPass() { ++ return new LoongArchExpandPseudo(); ++} +diff --git a/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp b/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp +deleted file mode 100644 +index ad39658f6..000000000 +--- a/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp ++++ /dev/null +@@ -1,653 +0,0 @@ +-//===-- LoongArchExpandPseudoInsts.cpp - Expand pseudo instructions -------===// +-// +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +-// +-//===----------------------------------------------------------------------===// +-// +-// This file contains a pass that expands pseudo instructions into target +-// instructions. +-// +-//===----------------------------------------------------------------------===// +- +-#include "LoongArch.h" +-#include "LoongArchInstrInfo.h" +-#include "LoongArchTargetMachine.h" +-#include "MCTargetDesc/LoongArchBaseInfo.h" +-#include "MCTargetDesc/LoongArchMCTargetDesc.h" +-#include "llvm/CodeGen/LivePhysRegs.h" +-#include "llvm/CodeGen/MachineFunctionPass.h" +-#include "llvm/CodeGen/MachineInstrBuilder.h" +-#include "llvm/CodeGen/MachineOperand.h" +-#include "llvm/CodeGen/Register.h" +-#include "llvm/MC/MCContext.h" +-#include "llvm/Support/CodeGen.h" +-#include "llvm/Support/ErrorHandling.h" +- +-using namespace llvm; +- +-#define LOONGARCH_PRERA_EXPAND_PSEUDO_NAME \ +- "LoongArch Pre-RA pseudo instruction expansion pass" +-#define LOONGARCH_EXPAND_PSEUDO_NAME \ +- "LoongArch pseudo instruction expansion pass" +- +-namespace { +- +-class LoongArchPreRAExpandPseudo : public MachineFunctionPass { +-public: +- const LoongArchInstrInfo *TII; +- static char ID; +- +- LoongArchPreRAExpandPseudo() : MachineFunctionPass(ID) { +- initializeLoongArchPreRAExpandPseudoPass(*PassRegistry::getPassRegistry()); +- } +- +- bool runOnMachineFunction(MachineFunction &MF) override; +- +- void getAnalysisUsage(AnalysisUsage &AU) const override { +- AU.setPreservesCFG(); +- MachineFunctionPass::getAnalysisUsage(AU); +- } +- StringRef getPassName() const override { +- return LOONGARCH_PRERA_EXPAND_PSEUDO_NAME; +- } +- +-private: +- bool expandMBB(MachineBasicBlock &MBB); +- bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI); +- bool expandPcalau12iInstPair(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI, +- unsigned FlagsHi, unsigned SecondOpcode, +- unsigned FlagsLo); +- bool expandLoadAddressPcrel(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI); +- bool expandLoadAddressGot(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI); +- bool expandLoadAddressTLSLE(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI); +- bool expandLoadAddressTLSIE(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI); +- bool expandLoadAddressTLSLD(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI); +- bool expandLoadAddressTLSGD(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI); +-}; +- +-char LoongArchPreRAExpandPseudo::ID = 0; +- +-bool LoongArchPreRAExpandPseudo::runOnMachineFunction(MachineFunction &MF) { +- TII = +- static_cast(MF.getSubtarget().getInstrInfo()); +- bool Modified = false; +- for (auto &MBB : MF) +- Modified |= expandMBB(MBB); +- return Modified; +-} +- +-bool LoongArchPreRAExpandPseudo::expandMBB(MachineBasicBlock &MBB) { +- bool Modified = false; +- +- MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); +- while (MBBI != E) { +- MachineBasicBlock::iterator NMBBI = std::next(MBBI); +- Modified |= expandMI(MBB, MBBI, NMBBI); +- MBBI = NMBBI; +- } +- +- return Modified; +-} +- +-bool LoongArchPreRAExpandPseudo::expandMI( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI) { +- switch (MBBI->getOpcode()) { +- case LoongArch::PseudoLA_PCREL: +- return expandLoadAddressPcrel(MBB, MBBI, NextMBBI); +- case LoongArch::PseudoLA_GOT: +- return expandLoadAddressGot(MBB, MBBI, NextMBBI); +- case LoongArch::PseudoLA_TLS_LE: +- return expandLoadAddressTLSLE(MBB, MBBI, NextMBBI); +- case LoongArch::PseudoLA_TLS_IE: +- return expandLoadAddressTLSIE(MBB, MBBI, NextMBBI); +- case LoongArch::PseudoLA_TLS_LD: +- return expandLoadAddressTLSLD(MBB, MBBI, NextMBBI); +- case LoongArch::PseudoLA_TLS_GD: +- return expandLoadAddressTLSGD(MBB, MBBI, NextMBBI); +- } +- return false; +-} +- +-bool LoongArchPreRAExpandPseudo::expandPcalau12iInstPair( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI, unsigned FlagsHi, +- unsigned SecondOpcode, unsigned FlagsLo) { +- MachineFunction *MF = MBB.getParent(); +- MachineInstr &MI = *MBBI; +- DebugLoc DL = MI.getDebugLoc(); +- +- Register DestReg = MI.getOperand(0).getReg(); +- Register ScratchReg = +- MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass); +- MachineOperand &Symbol = MI.getOperand(1); +- +- BuildMI(MBB, MBBI, DL, TII->get(LoongArch::PCALAU12I), ScratchReg) +- .addDisp(Symbol, 0, FlagsHi); +- +- MachineInstr *SecondMI = +- BuildMI(MBB, MBBI, DL, TII->get(SecondOpcode), DestReg) +- .addReg(ScratchReg) +- .addDisp(Symbol, 0, FlagsLo); +- +- if (MI.hasOneMemOperand()) +- SecondMI->addMemOperand(*MF, *MI.memoperands_begin()); +- +- MI.eraseFromParent(); +- return true; +-} +- +-bool LoongArchPreRAExpandPseudo::expandLoadAddressPcrel( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI) { +- // Code Sequence: +- // pcalau12i $rd, %pc_hi20(sym) +- // addi.w/d $rd, $rd, %pc_lo12(sym) +- MachineFunction *MF = MBB.getParent(); +- const auto &STI = MF->getSubtarget(); +- unsigned SecondOpcode = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W; +- return expandPcalau12iInstPair(MBB, MBBI, NextMBBI, LoongArchII::MO_PCREL_HI, +- SecondOpcode, LoongArchII::MO_PCREL_LO); +-} +- +-bool LoongArchPreRAExpandPseudo::expandLoadAddressGot( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI) { +- // Code Sequence: +- // pcalau12i $rd, %got_pc_hi20(sym) +- // ld.w/d $rd, $rd, %got_pc_lo12(sym) +- MachineFunction *MF = MBB.getParent(); +- const auto &STI = MF->getSubtarget(); +- unsigned SecondOpcode = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W; +- return expandPcalau12iInstPair(MBB, MBBI, NextMBBI, LoongArchII::MO_GOT_PC_HI, +- SecondOpcode, LoongArchII::MO_GOT_PC_LO); +-} +- +-bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSLE( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI) { +- // Code Sequence: +- // lu12i.w $rd, %le_hi20(sym) +- // ori $rd, $rd, %le_lo12(sym) +- // +- // And additionally if generating code using the large code model: +- // +- // lu32i.d $rd, %le64_lo20(sym) +- // lu52i.d $rd, $rd, %le64_hi12(sym) +- MachineFunction *MF = MBB.getParent(); +- MachineInstr &MI = *MBBI; +- DebugLoc DL = MI.getDebugLoc(); +- +- bool Large = MF->getTarget().getCodeModel() == CodeModel::Large; +- Register DestReg = MI.getOperand(0).getReg(); +- Register Parts01 = +- Large ? MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass) +- : DestReg; +- Register Part1 = +- MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass); +- MachineOperand &Symbol = MI.getOperand(1); +- +- BuildMI(MBB, MBBI, DL, TII->get(LoongArch::LU12I_W), Part1) +- .addDisp(Symbol, 0, LoongArchII::MO_LE_HI); +- +- BuildMI(MBB, MBBI, DL, TII->get(LoongArch::ORI), Parts01) +- .addReg(Part1, RegState::Kill) +- .addDisp(Symbol, 0, LoongArchII::MO_LE_LO); +- +- if (Large) { +- Register Parts012 = +- MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass); +- +- BuildMI(MBB, MBBI, DL, TII->get(LoongArch::LU32I_D), Parts012) +- // "rj" is needed due to InstrInfo pattern requirement. +- .addReg(Parts01, RegState::Kill) +- .addDisp(Symbol, 0, LoongArchII::MO_LE64_LO); +- BuildMI(MBB, MBBI, DL, TII->get(LoongArch::LU52I_D), DestReg) +- .addReg(Parts012, RegState::Kill) +- .addDisp(Symbol, 0, LoongArchII::MO_LE64_HI); +- } +- +- MI.eraseFromParent(); +- return true; +-} +- +-bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSIE( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI) { +- // Code Sequence: +- // pcalau12i $rd, %ie_pc_hi20(sym) +- // ld.w/d $rd, $rd, %ie_pc_lo12(sym) +- MachineFunction *MF = MBB.getParent(); +- const auto &STI = MF->getSubtarget(); +- unsigned SecondOpcode = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W; +- return expandPcalau12iInstPair(MBB, MBBI, NextMBBI, LoongArchII::MO_IE_PC_HI, +- SecondOpcode, LoongArchII::MO_IE_PC_LO); +-} +- +-bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSLD( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI) { +- // Code Sequence: +- // pcalau12i $rd, %ld_pc_hi20(sym) +- // addi.w/d $rd, $rd, %got_pc_lo12(sym) +- MachineFunction *MF = MBB.getParent(); +- const auto &STI = MF->getSubtarget(); +- unsigned SecondOpcode = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W; +- return expandPcalau12iInstPair(MBB, MBBI, NextMBBI, LoongArchII::MO_LD_PC_HI, +- SecondOpcode, LoongArchII::MO_GOT_PC_LO); +-} +- +-bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSGD( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI) { +- // Code Sequence: +- // pcalau12i $rd, %gd_pc_hi20(sym) +- // addi.w/d $rd, $rd, %got_pc_lo12(sym) +- MachineFunction *MF = MBB.getParent(); +- const auto &STI = MF->getSubtarget(); +- unsigned SecondOpcode = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W; +- return expandPcalau12iInstPair(MBB, MBBI, NextMBBI, LoongArchII::MO_GD_PC_HI, +- SecondOpcode, LoongArchII::MO_GOT_PC_LO); +-} +- +-class LoongArchExpandPseudo : public MachineFunctionPass { +-public: +- const LoongArchInstrInfo *TII; +- static char ID; +- +- LoongArchExpandPseudo() : MachineFunctionPass(ID) { +- initializeLoongArchExpandPseudoPass(*PassRegistry::getPassRegistry()); +- } +- +- bool runOnMachineFunction(MachineFunction &MF) override; +- +- StringRef getPassName() const override { +- return LOONGARCH_EXPAND_PSEUDO_NAME; +- } +- +-private: +- bool expandMBB(MachineBasicBlock &MBB); +- bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI); +- bool expandCopyCFR(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI); +- bool expandLargeAddressLoad(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI, +- unsigned LastOpcode, unsigned IdentifyingMO); +- bool expandLargeAddressLoad(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI, +- unsigned LastOpcode, unsigned IdentifyingMO, +- const MachineOperand &Symbol, Register DestReg, +- bool EraseFromParent); +- bool expandLoadAddressPcrelLarge(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI); +- bool expandLoadAddressGotLarge(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI); +- bool expandLoadAddressTLSIELarge(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI); +- bool expandLoadAddressTLSLDLarge(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI); +- bool expandLoadAddressTLSGDLarge(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI); +- bool expandFunctionCALL(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI, +- bool IsTailCall); +-}; +- +-char LoongArchExpandPseudo::ID = 0; +- +-bool LoongArchExpandPseudo::runOnMachineFunction(MachineFunction &MF) { +- TII = +- static_cast(MF.getSubtarget().getInstrInfo()); +- +- bool Modified = false; +- for (auto &MBB : MF) +- Modified |= expandMBB(MBB); +- +- return Modified; +-} +- +-bool LoongArchExpandPseudo::expandMBB(MachineBasicBlock &MBB) { +- bool Modified = false; +- +- MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); +- while (MBBI != E) { +- MachineBasicBlock::iterator NMBBI = std::next(MBBI); +- Modified |= expandMI(MBB, MBBI, NMBBI); +- MBBI = NMBBI; +- } +- +- return Modified; +-} +- +-bool LoongArchExpandPseudo::expandMI(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI) { +- switch (MBBI->getOpcode()) { +- case LoongArch::PseudoCopyCFR: +- return expandCopyCFR(MBB, MBBI, NextMBBI); +- case LoongArch::PseudoLA_PCREL_LARGE: +- return expandLoadAddressPcrelLarge(MBB, MBBI, NextMBBI); +- case LoongArch::PseudoLA_GOT_LARGE: +- return expandLoadAddressGotLarge(MBB, MBBI, NextMBBI); +- case LoongArch::PseudoLA_TLS_IE_LARGE: +- return expandLoadAddressTLSIELarge(MBB, MBBI, NextMBBI); +- case LoongArch::PseudoLA_TLS_LD_LARGE: +- return expandLoadAddressTLSLDLarge(MBB, MBBI, NextMBBI); +- case LoongArch::PseudoLA_TLS_GD_LARGE: +- return expandLoadAddressTLSGDLarge(MBB, MBBI, NextMBBI); +- case LoongArch::PseudoCALL: +- case LoongArch::PseudoCALL_MEDIUM: +- case LoongArch::PseudoCALL_LARGE: +- return expandFunctionCALL(MBB, MBBI, NextMBBI, /*IsTailCall=*/false); +- case LoongArch::PseudoTAIL: +- case LoongArch::PseudoTAIL_MEDIUM: +- case LoongArch::PseudoTAIL_LARGE: +- return expandFunctionCALL(MBB, MBBI, NextMBBI, /*IsTailCall=*/true); +- } +- +- return false; +-} +- +-bool LoongArchExpandPseudo::expandCopyCFR( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI) { +- MachineFunction *MF = MBB.getParent(); +- MachineInstr &MI = *MBBI; +- DebugLoc DL = MI.getDebugLoc(); +- +- // Expand: +- // MBB: +- // fcmp.caf.s $dst, $fa0, $fa0 # set $dst 0(false) +- // bceqz $src, SinkBB +- // FalseBB: +- // fcmp.cueq.s $dst, $fa0, $fa0 # set $dst 1(true) +- // SinkBB: +- // fallthrough +- +- const BasicBlock *LLVM_BB = MBB.getBasicBlock(); +- auto *FalseBB = MF->CreateMachineBasicBlock(LLVM_BB); +- auto *SinkBB = MF->CreateMachineBasicBlock(LLVM_BB); +- +- MF->insert(++MBB.getIterator(), FalseBB); +- MF->insert(++FalseBB->getIterator(), SinkBB); +- +- Register DestReg = MI.getOperand(0).getReg(); +- Register SrcReg = MI.getOperand(1).getReg(); +- // DestReg = 0 +- BuildMI(MBB, MBBI, DL, TII->get(LoongArch::SET_CFR_FALSE), DestReg); +- // Insert branch instruction. +- BuildMI(MBB, MBBI, DL, TII->get(LoongArch::BCEQZ)) +- .addReg(SrcReg) +- .addMBB(SinkBB); +- // DestReg = 1 +- BuildMI(FalseBB, DL, TII->get(LoongArch::SET_CFR_TRUE), DestReg); +- +- FalseBB->addSuccessor(SinkBB); +- +- SinkBB->splice(SinkBB->end(), &MBB, MI, MBB.end()); +- SinkBB->transferSuccessors(&MBB); +- +- MBB.addSuccessor(FalseBB); +- MBB.addSuccessor(SinkBB); +- +- NextMBBI = MBB.end(); +- MI.eraseFromParent(); +- +- // Make sure live-ins are correctly attached to this new basic block. +- LivePhysRegs LiveRegs; +- computeAndAddLiveIns(LiveRegs, *FalseBB); +- computeAndAddLiveIns(LiveRegs, *SinkBB); +- +- return true; +-} +- +-bool LoongArchExpandPseudo::expandLargeAddressLoad( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI, unsigned LastOpcode, +- unsigned IdentifyingMO) { +- MachineInstr &MI = *MBBI; +- return expandLargeAddressLoad(MBB, MBBI, NextMBBI, LastOpcode, IdentifyingMO, +- MI.getOperand(2), MI.getOperand(0).getReg(), +- true); +-} +- +-bool LoongArchExpandPseudo::expandLargeAddressLoad( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI, unsigned LastOpcode, +- unsigned IdentifyingMO, const MachineOperand &Symbol, Register DestReg, +- bool EraseFromParent) { +- // Code Sequence: +- // +- // Part1: pcalau12i $dst, %MO1(sym) +- // Part0: addi.d $t8, $zero, %MO0(sym) +- // Part2: lu32i.d $t8, %MO2(sym) +- // Part3: lu52i.d $t8, $t8, %MO3(sym) +- // Fin: LastOpcode $dst, $t8, $dst +- +- unsigned MO0, MO1, MO2, MO3; +- switch (IdentifyingMO) { +- default: +- llvm_unreachable("unsupported identifying MO"); +- case LoongArchII::MO_PCREL_LO: +- MO0 = IdentifyingMO; +- MO1 = LoongArchII::MO_PCREL_HI; +- MO2 = LoongArchII::MO_PCREL64_LO; +- MO3 = LoongArchII::MO_PCREL64_HI; +- break; +- case LoongArchII::MO_GOT_PC_HI: +- case LoongArchII::MO_LD_PC_HI: +- case LoongArchII::MO_GD_PC_HI: +- // These cases relocate just like the GOT case, except for Part1. +- MO0 = LoongArchII::MO_GOT_PC_LO; +- MO1 = IdentifyingMO; +- MO2 = LoongArchII::MO_GOT_PC64_LO; +- MO3 = LoongArchII::MO_GOT_PC64_HI; +- break; +- case LoongArchII::MO_IE_PC_LO: +- MO0 = IdentifyingMO; +- MO1 = LoongArchII::MO_IE_PC_HI; +- MO2 = LoongArchII::MO_IE_PC64_LO; +- MO3 = LoongArchII::MO_IE_PC64_HI; +- break; +- } +- +- MachineInstr &MI = *MBBI; +- DebugLoc DL = MI.getDebugLoc(); +- Register ScratchReg = LoongArch::R20; // $t8 +- +- assert(MBB.getParent()->getSubtarget().is64Bit() && +- "Large code model requires LA64"); +- +- auto Part1 = BuildMI(MBB, MBBI, DL, TII->get(LoongArch::PCALAU12I), DestReg); +- auto Part0 = BuildMI(MBB, MBBI, DL, TII->get(LoongArch::ADDI_D), ScratchReg) +- .addReg(LoongArch::R0); +- auto Part2 = BuildMI(MBB, MBBI, DL, TII->get(LoongArch::LU32I_D), ScratchReg) +- // "rj" is needed due to InstrInfo pattern requirement. +- .addReg(ScratchReg); +- auto Part3 = BuildMI(MBB, MBBI, DL, TII->get(LoongArch::LU52I_D), ScratchReg) +- .addReg(ScratchReg); +- BuildMI(MBB, MBBI, DL, TII->get(LastOpcode), DestReg) +- .addReg(ScratchReg) +- .addReg(DestReg); +- +- if (Symbol.getType() == MachineOperand::MO_ExternalSymbol) { +- const char *SymName = Symbol.getSymbolName(); +- Part0.addExternalSymbol(SymName, MO0); +- Part1.addExternalSymbol(SymName, MO1); +- Part2.addExternalSymbol(SymName, MO2); +- Part3.addExternalSymbol(SymName, MO3); +- } else { +- Part0.addDisp(Symbol, 0, MO0); +- Part1.addDisp(Symbol, 0, MO1); +- Part2.addDisp(Symbol, 0, MO2); +- Part3.addDisp(Symbol, 0, MO3); +- } +- +- if (EraseFromParent) +- MI.eraseFromParent(); +- +- return true; +-} +- +-bool LoongArchExpandPseudo::expandLoadAddressPcrelLarge( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI) { +- // Emit the 5-insn large address load sequence with the `%pc` family of +- // relocs. +- return expandLargeAddressLoad(MBB, MBBI, NextMBBI, LoongArch::ADD_D, +- LoongArchII::MO_PCREL_LO); +-} +- +-bool LoongArchExpandPseudo::expandLoadAddressGotLarge( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI) { +- // Emit the 5-insn large address load sequence with the `%got_pc` family +- // of relocs, loading the result from GOT with `ldx.d` in the end. +- return expandLargeAddressLoad(MBB, MBBI, NextMBBI, LoongArch::LDX_D, +- LoongArchII::MO_GOT_PC_HI); +-} +- +-bool LoongArchExpandPseudo::expandLoadAddressTLSIELarge( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI) { +- // Emit the 5-insn large address load sequence with the `%ie_pc` family +- // of relocs, loading the result with `ldx.d` in the end. +- return expandLargeAddressLoad(MBB, MBBI, NextMBBI, LoongArch::LDX_D, +- LoongArchII::MO_IE_PC_LO); +-} +- +-bool LoongArchExpandPseudo::expandLoadAddressTLSLDLarge( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI) { +- // Emit the 5-insn large address load sequence with the `%got_pc` family +- // of relocs, with the `pcalau12i` insn relocated with `%ld_pc_hi20`. +- return expandLargeAddressLoad(MBB, MBBI, NextMBBI, LoongArch::ADD_D, +- LoongArchII::MO_LD_PC_HI); +-} +- +-bool LoongArchExpandPseudo::expandLoadAddressTLSGDLarge( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI) { +- // Emit the 5-insn large address load sequence with the `%got_pc` family +- // of relocs, with the `pcalau12i` insn relocated with `%gd_pc_hi20`. +- return expandLargeAddressLoad(MBB, MBBI, NextMBBI, LoongArch::ADD_D, +- LoongArchII::MO_GD_PC_HI); +-} +- +-bool LoongArchExpandPseudo::expandFunctionCALL( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- MachineBasicBlock::iterator &NextMBBI, bool IsTailCall) { +- MachineFunction *MF = MBB.getParent(); +- MachineInstr &MI = *MBBI; +- DebugLoc DL = MI.getDebugLoc(); +- const MachineOperand &Func = MI.getOperand(0); +- MachineInstrBuilder CALL; +- unsigned Opcode; +- +- switch (MF->getTarget().getCodeModel()) { +- default: +- report_fatal_error("Unsupported code model"); +- break; +- case CodeModel::Small: { +- // CALL: +- // bl func +- // TAIL: +- // b func +- Opcode = IsTailCall ? LoongArch::PseudoB_TAIL : LoongArch::BL; +- CALL = BuildMI(MBB, MBBI, DL, TII->get(Opcode)).add(Func); +- break; +- } +- case CodeModel::Medium: { +- // CALL: +- // pcaddu18i $ra, %call36(func) +- // jirl $ra, $ra, 0 +- // TAIL: +- // pcaddu18i $t8, %call36(func) +- // jr $t8 +- Opcode = +- IsTailCall ? LoongArch::PseudoJIRL_TAIL : LoongArch::PseudoJIRL_CALL; +- Register ScratchReg = IsTailCall ? LoongArch::R20 : LoongArch::R1; +- MachineInstrBuilder MIB = +- BuildMI(MBB, MBBI, DL, TII->get(LoongArch::PCADDU18I), ScratchReg); +- +- CALL = +- BuildMI(MBB, MBBI, DL, TII->get(Opcode)).addReg(ScratchReg).addImm(0); +- +- if (Func.isSymbol()) +- MIB.addExternalSymbol(Func.getSymbolName(), LoongArchII::MO_CALL36); +- else +- MIB.addDisp(Func, 0, LoongArchII::MO_CALL36); +- break; +- } +- case CodeModel::Large: { +- // Emit the 5-insn large address load sequence, either directly or +- // indirectly in case of going through the GOT, then JIRL_TAIL or +- // JIRL_CALL to $addr. +- Opcode = +- IsTailCall ? LoongArch::PseudoJIRL_TAIL : LoongArch::PseudoJIRL_CALL; +- Register AddrReg = IsTailCall ? LoongArch::R19 : LoongArch::R1; +- +- bool UseGOT = Func.isGlobal() && !Func.getGlobal()->isDSOLocal(); +- unsigned MO = UseGOT ? LoongArchII::MO_GOT_PC_HI : LoongArchII::MO_PCREL_LO; +- unsigned LAOpcode = UseGOT ? LoongArch::LDX_D : LoongArch::ADD_D; +- expandLargeAddressLoad(MBB, MBBI, NextMBBI, LAOpcode, MO, Func, AddrReg, +- false); +- CALL = BuildMI(MBB, MBBI, DL, TII->get(Opcode)).addReg(AddrReg).addImm(0); +- break; +- } +- } +- +- // Transfer implicit operands. +- CALL.copyImplicitOps(MI); +- +- // Transfer MI flags. +- CALL.setMIFlags(MI.getFlags()); +- +- MI.eraseFromParent(); +- return true; +-} +- +-} // end namespace +- +-INITIALIZE_PASS(LoongArchPreRAExpandPseudo, "loongarch-prera-expand-pseudo", +- LOONGARCH_PRERA_EXPAND_PSEUDO_NAME, false, false) +- +-INITIALIZE_PASS(LoongArchExpandPseudo, "loongarch-expand-pseudo", +- LOONGARCH_EXPAND_PSEUDO_NAME, false, false) +- +-namespace llvm { +- +-FunctionPass *createLoongArchPreRAExpandPseudoPass() { +- return new LoongArchPreRAExpandPseudo(); +-} +-FunctionPass *createLoongArchExpandPseudoPass() { +- return new LoongArchExpandPseudo(); +-} +- +-} // end namespace llvm +diff --git a/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td +deleted file mode 100644 +index d6a83c0c8..000000000 +--- a/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td ++++ /dev/null +@@ -1,341 +0,0 @@ +-// LoongArchFloat32InstrInfo.td - Single-Precision Float instr --*- tablegen -*- +-// +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +-// +-//===----------------------------------------------------------------------===// +-// +-// This file describes the baisc single-precision floating-point instructions. +-// +-//===----------------------------------------------------------------------===// +- +-//===----------------------------------------------------------------------===// +-// LoongArch specific DAG Nodes. +-//===----------------------------------------------------------------------===// +- +-def SDT_LoongArchMOVGR2FR_W_LA64 +- : SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisVT<1, i64>]>; +-def SDT_LoongArchMOVFR2GR_S_LA64 +- : SDTypeProfile<1, 1, [SDTCisVT<0, i64>, SDTCisVT<1, f32>]>; +-def SDT_LoongArchFTINT : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>; +- +-def loongarch_movgr2fr_w_la64 +- : SDNode<"LoongArchISD::MOVGR2FR_W_LA64", SDT_LoongArchMOVGR2FR_W_LA64>; +-def loongarch_movfr2gr_s_la64 +- : SDNode<"LoongArchISD::MOVFR2GR_S_LA64", SDT_LoongArchMOVFR2GR_S_LA64>; +-def loongarch_ftint : SDNode<"LoongArchISD::FTINT", SDT_LoongArchFTINT>; +- +-//===----------------------------------------------------------------------===// +-// Instructions +-//===----------------------------------------------------------------------===// +- +-let Predicates = [HasBasicF] in { +- +-// Arithmetic Operation Instructions +-def FADD_S : FP_ALU_3R<0x01008000>; +-def FSUB_S : FP_ALU_3R<0x01028000>; +-def FMUL_S : FP_ALU_3R<0x01048000>; +-def FDIV_S : FP_ALU_3R<0x01068000>; +-def FMADD_S : FP_ALU_4R<0x08100000>; +-def FMSUB_S : FP_ALU_4R<0x08500000>; +-def FNMADD_S : FP_ALU_4R<0x08900000>; +-def FNMSUB_S : FP_ALU_4R<0x08d00000>; +-def FMAX_S : FP_ALU_3R<0x01088000>; +-def FMIN_S : FP_ALU_3R<0x010a8000>; +-def FMAXA_S : FP_ALU_3R<0x010c8000>; +-def FMINA_S : FP_ALU_3R<0x010e8000>; +-def FABS_S : FP_ALU_2R<0x01140400>; +-def FNEG_S : FP_ALU_2R<0x01141400>; +-def FSQRT_S : FP_ALU_2R<0x01144400>; +-def FRECIP_S : FP_ALU_2R<0x01145400>; +-def FRSQRT_S : FP_ALU_2R<0x01146400>; +-def FRECIPE_S : FP_ALU_2R<0x01147400>; +-def FRSQRTE_S : FP_ALU_2R<0x01148400>; +-def FSCALEB_S : FP_ALU_3R<0x01108000>; +-def FLOGB_S : FP_ALU_2R<0x01142400>; +-def FCOPYSIGN_S : FP_ALU_3R<0x01128000>; +-def FCLASS_S : FP_ALU_2R<0x01143400>; +- +- +-// Comparison Instructions +-def FCMP_CAF_S : FP_CMP<0x0c100000>; +-def FCMP_CUN_S : FP_CMP<0x0c140000>; +-def FCMP_CEQ_S : FP_CMP<0x0c120000>; +-def FCMP_CUEQ_S : FP_CMP<0x0c160000>; +-def FCMP_CLT_S : FP_CMP<0x0c110000>; +-def FCMP_CULT_S : FP_CMP<0x0c150000>; +-def FCMP_CLE_S : FP_CMP<0x0c130000>; +-def FCMP_CULE_S : FP_CMP<0x0c170000>; +-def FCMP_CNE_S : FP_CMP<0x0c180000>; +-def FCMP_COR_S : FP_CMP<0x0c1a0000>; +-def FCMP_CUNE_S : FP_CMP<0x0c1c0000>; +-def FCMP_SAF_S : FP_CMP<0x0c108000>; +-def FCMP_SUN_S : FP_CMP<0x0c148000>; +-def FCMP_SEQ_S : FP_CMP<0x0c128000>; +-def FCMP_SUEQ_S : FP_CMP<0x0c168000>; +-def FCMP_SLT_S : FP_CMP<0x0c118000>; +-def FCMP_SULT_S : FP_CMP<0x0c158000>; +-def FCMP_SLE_S : FP_CMP<0x0c138000>; +-def FCMP_SULE_S : FP_CMP<0x0c178000>; +-def FCMP_SNE_S : FP_CMP<0x0c188000>; +-def FCMP_SOR_S : FP_CMP<0x0c1a8000>; +-def FCMP_SUNE_S : FP_CMP<0x0c1c8000>; +- +-// Conversion Instructions +-def FFINT_S_W : FP_CONV<0x011d1000>; +-def FTINT_W_S : FP_CONV<0x011b0400>; +-def FTINTRM_W_S : FP_CONV<0x011a0400>; +-def FTINTRP_W_S : FP_CONV<0x011a4400>; +-def FTINTRZ_W_S : FP_CONV<0x011a8400>; +-def FTINTRNE_W_S : FP_CONV<0x011ac400>; +-def FRINT_S : FP_CONV<0x011e4400>; +- +-// Move Instructions +-def FSEL_xS : FP_SEL<0x0d000000>; +-def FMOV_S : FP_MOV<0x01149400>; +-def MOVGR2FR_W : FP_MOV<0x0114a400, FPR32, GPR>; +-def MOVFR2GR_S : FP_MOV<0x0114b400, GPR, FPR32>; +-let hasSideEffects = 1 in { +-def MOVGR2FCSR : FP_MOV<0x0114c000, FCSR, GPR>; +-def MOVFCSR2GR : FP_MOV<0x0114c800, GPR, FCSR>; +-} // hasSideEffects = 1 +-def MOVFR2CF_xS : FP_MOV<0x0114d000, CFR, FPR32>; +-def MOVCF2FR_xS : FP_MOV<0x0114d400, FPR32, CFR>; +-def MOVGR2CF : FP_MOV<0x0114d800, CFR, GPR>; +-def MOVCF2GR : FP_MOV<0x0114dc00, GPR, CFR>; +- +-// Branch Instructions +-def BCEQZ : FP_BRANCH<0x48000000>; +-def BCNEZ : FP_BRANCH<0x48000100>; +- +-// Common Memory Access Instructions +-def FLD_S : FP_LOAD_2RI12<0x2b000000>; +-def FST_S : FP_STORE_2RI12<0x2b400000>; +-def FLDX_S : FP_LOAD_3R<0x38300000>; +-def FSTX_S : FP_STORE_3R<0x38380000>; +- +-// Bound Check Memory Access Instructions +-def FLDGT_S : FP_LOAD_3R<0x38740000>; +-def FLDLE_S : FP_LOAD_3R<0x38750000>; +-def FSTGT_S : FP_STORE_3R<0x38760000>; +-def FSTLE_S : FP_STORE_3R<0x38770000>; +- +-// Pseudo instructions for spill/reload CFRs. +-let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in +-def PseudoST_CFR : Pseudo<(outs), +- (ins CFR:$ccd, GPR:$rj, grlenimm:$imm)>; +-let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in +-def PseudoLD_CFR : Pseudo<(outs CFR:$ccd), +- (ins GPR:$rj, grlenimm:$imm)>; +- +-// SET_CFR_{FALSE,TRUE} +-// These instructions are defined in order to avoid expensive check error if +-// regular instruction patterns are used. +-// fcmp.caf.s $dst, $fa0, $fa0 +-def SET_CFR_FALSE : SET_CFR<0x0c100000, "fcmp.caf.s">; +-// fcmp.cueq.s $dst, $fa0, $fa0 +-def SET_CFR_TRUE : SET_CFR<0x0c160000, "fcmp.cueq.s">; +- +-// Pseudo instruction for copying CFRs. +-def PseudoCopyCFR : Pseudo<(outs CFR:$dst), (ins CFR:$src)> { +- let mayLoad = 0; +- let mayStore = 0; +- let hasSideEffects = 0; +- let Size = 12; +-} +- +-} // Predicates = [HasBasicF] +- +-//===----------------------------------------------------------------------===// +-// Pseudo-instructions and codegen patterns +-//===----------------------------------------------------------------------===// +- +-/// Generic pattern classes +- +-class PatFpr +- : Pat<(OpNode RegTy:$fj), (Inst $fj)>; +-class PatFprFpr +- : Pat<(OpNode RegTy:$fj, RegTy:$fk), (Inst $fj, $fk)>; +- +-let Predicates = [HasBasicF] in { +- +-/// Float arithmetic operations +- +-def : PatFprFpr; +-def : PatFprFpr; +-def : PatFprFpr; +-def : PatFprFpr; +-def : PatFprFpr; +-def : PatFprFpr; +-def : PatFprFpr; +-def : PatFpr; +-def : PatFpr; +-def : PatFpr; +-def : Pat<(fdiv fpimm1, (fsqrt FPR32:$fj)), (FRSQRT_S FPR32:$fj)>; +-def : Pat<(fcanonicalize FPR32:$fj), (FMAX_S $fj, $fj)>; +-def : Pat<(is_fpclass FPR32:$fj, (i32 timm:$mask)), +- (SLTU R0, (ANDI (MOVFR2GR_S (FCLASS_S FPR32:$fj)), +- (to_fclass_mask timm:$mask)))>; +- +-/// Setcc +- +-// Match non-signaling comparison +- +-class PatFPSetcc +- : Pat<(any_fsetcc RegTy:$fj, RegTy:$fk, cc), +- (CmpInst RegTy:$fj, RegTy:$fk)>; +-// SETOGT/SETOGE/SETUGT/SETUGE/SETGE/SETNE/SETGT will expand into +-// SETOLT/SETOLE/SETULT/SETULE/SETLE/SETEQ/SETLT. +-def : PatFPSetcc; +-def : PatFPSetcc; +-def : PatFPSetcc; +-def : PatFPSetcc; +-def : PatFPSetcc; +-def : PatFPSetcc; +-def : PatFPSetcc; +-def : PatFPSetcc; +-def : PatFPSetcc; +-def : PatFPSetcc; +-def : PatFPSetcc; +-def : PatFPSetcc; +-def : PatFPSetcc; +- +-multiclass PatFPBrcond { +- def : Pat<(brcond (xor (GRLenVT (setcc RegTy:$fj, RegTy:$fk, cc)), -1), +- bb:$imm21), +- (BCEQZ (CmpInst RegTy:$fj, RegTy:$fk), bb:$imm21)>; +- def : Pat<(brcond (GRLenVT (setcc RegTy:$fj, RegTy:$fk, cc)), bb:$imm21), +- (BCNEZ (CmpInst RegTy:$fj, RegTy:$fk), bb:$imm21)>; +-} +- +-defm : PatFPBrcond; +-defm : PatFPBrcond; +-defm : PatFPBrcond; +-defm : PatFPBrcond; +-defm : PatFPBrcond; +-defm : PatFPBrcond; +-defm : PatFPBrcond; +-defm : PatFPBrcond; +-defm : PatFPBrcond; +-defm : PatFPBrcond; +-defm : PatFPBrcond; +- +-// Match signaling comparison +- +-class PatStrictFsetccs +- : Pat<(strict_fsetccs RegTy:$fj, RegTy:$fk, cc), +- (CmpInst RegTy:$fj, RegTy:$fk)>; +-def : PatStrictFsetccs; +-def : PatStrictFsetccs; +-def : PatStrictFsetccs; +-def : PatStrictFsetccs; +-def : PatStrictFsetccs; +-def : PatStrictFsetccs; +-def : PatStrictFsetccs; +-def : PatStrictFsetccs; +-def : PatStrictFsetccs; +-def : PatStrictFsetccs; +-def : PatStrictFsetccs; +- +-/// Select +- +-def : Pat<(select CFR:$cc, FPR32:$fk, FPR32:$fj), +- (FSEL_xS FPR32:$fj, FPR32:$fk, CFR:$cc)>; +- +-/// Selectcc +- +-class PatFPSelectcc +- : Pat<(select (GRLenVT (setcc RegTy:$a, RegTy:$b, cc)), RegTy:$t, RegTy:$f), +- (SelInst RegTy:$f, RegTy:$t, (CmpInst RegTy:$a, RegTy:$b))>; +-def : PatFPSelectcc; +-def : PatFPSelectcc; +-def : PatFPSelectcc; +-def : PatFPSelectcc; +-def : PatFPSelectcc; +-def : PatFPSelectcc; +-def : PatFPSelectcc; +-def : PatFPSelectcc; +-def : PatFPSelectcc; +-def : PatFPSelectcc; +- +-/// Loads +- +-defm : LdPat; +-def : RegRegLdPat; +- +-/// Stores +- +-defm : StPat; +-def : RegRegStPat; +- +-/// Floating point constants +- +-def : Pat<(f32 fpimm0), (MOVGR2FR_W R0)>; +-def : Pat<(f32 fpimm0neg), (FNEG_S (MOVGR2FR_W R0))>; +-def : Pat<(f32 fpimm1), (FFINT_S_W (MOVGR2FR_W (ADDI_W R0, 1)))>; +- +-// FP Conversion +-def : Pat<(loongarch_ftint FPR32:$src), (FTINTRZ_W_S FPR32:$src)>; +- +-// FP reciprocal operation +-def : Pat<(fdiv fpimm1, FPR32:$src), (FRECIP_S $src)>; +- +-let Predicates = [HasFrecipe] in { +-// FP approximate reciprocal operation +-def : Pat<(int_loongarch_frecipe_s FPR32:$src), (FRECIPE_S FPR32:$src)>; +-def : Pat<(int_loongarch_frsqrte_s FPR32:$src), (FRSQRTE_S FPR32:$src)>; +-} +- +-// fmadd.s: fj * fk + fa +-def : Pat<(fma FPR32:$fj, FPR32:$fk, FPR32:$fa), (FMADD_S $fj, $fk, $fa)>; +- +-// fmsub.s: fj * fk - fa +-def : Pat<(fma FPR32:$fj, FPR32:$fk, (fneg FPR32:$fa)), +- (FMSUB_S FPR32:$fj, FPR32:$fk, FPR32:$fa)>; +- +-// fnmadd.s: -(fj * fk + fa) +-def : Pat<(fneg (fma FPR32:$fj, FPR32:$fk, FPR32:$fa)), +- (FNMADD_S FPR32:$fj, FPR32:$fk, FPR32:$fa)>; +- +-// fnmadd.s: -fj * fk - fa (the nsz flag on the FMA) +-def : Pat<(fma_nsz (fneg FPR32:$fj), FPR32:$fk, (fneg FPR32:$fa)), +- (FNMADD_S FPR32:$fj, FPR32:$fk, FPR32:$fa)>; +- +-// fnmsub.s: -(fj * fk - fa) +-def : Pat<(fneg (fma FPR32:$fj, FPR32:$fk, (fneg FPR32:$fa))), +- (FNMSUB_S FPR32:$fj, FPR32:$fk, FPR32:$fa)>; +- +-// fnmsub.s: -fj * fk + fa (the nsz flag on the FMA) +-def : Pat<(fma_nsz (fneg FPR32:$fj), FPR32:$fk, FPR32:$fa), +- (FNMSUB_S FPR32:$fj, FPR32:$fk, FPR32:$fa)>; +-} // Predicates = [HasBasicF] +- +-let Predicates = [HasBasicF, IsLA64] in { +-// GPR -> FPR +-def : Pat<(loongarch_movgr2fr_w_la64 GPR:$src), (MOVGR2FR_W GPR:$src)>; +-// FPR -> GPR +-def : Pat<(loongarch_movfr2gr_s_la64 FPR32:$src), +- (MOVFR2GR_S FPR32:$src)>; +-// int -> f32 +-def : Pat<(f32 (sint_to_fp (i64 (sexti32 (i64 GPR:$src))))), +- (FFINT_S_W (MOVGR2FR_W GPR:$src))>; +-// uint -> f32 +-def : Pat<(f32 (uint_to_fp (i64 (sexti32 (i64 GPR:$src))))), +- (FFINT_S_W (MOVGR2FR_W GPR:$src))>; +-} // Predicates = [HasBasicF, IsLA64] +- +-// FP Rounding +-let Predicates = [HasBasicF, IsLA64] in { +-def : PatFpr; +-} // Predicates = [HasBasicF, IsLA64] +- +-let Predicates = [HasBasicF, IsLA32] in { +-// GPR -> FPR +-def : Pat<(bitconvert (i32 GPR:$src)), (MOVGR2FR_W GPR:$src)>; +-// FPR -> GPR +-def : Pat<(i32 (bitconvert FPR32:$src)), (MOVFR2GR_S FPR32:$src)>; +-// int -> f32 +-def : Pat<(f32 (sint_to_fp (i32 GPR:$src))), (FFINT_S_W (MOVGR2FR_W GPR:$src))>; +-} // Predicates = [HasBasicF, IsLA32] +diff --git a/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td +deleted file mode 100644 +index 30cce8439..000000000 +--- a/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td ++++ /dev/null +@@ -1,317 +0,0 @@ +-// LoongArchFloat64InstrInfo.td - Double-Precision Float instr --*- tablegen -*- +-// +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +-// +-//===----------------------------------------------------------------------===// +-// +-// This file describes the basic double-precision floating-point instructions. +-// +-//===----------------------------------------------------------------------===// +- +-//===----------------------------------------------------------------------===// +-// Instructions +-//===----------------------------------------------------------------------===// +- +-let Predicates = [HasBasicD] in { +- +-// Arithmetic Operation Instructions +-def FADD_D : FP_ALU_3R<0x01010000, FPR64>; +-def FSUB_D : FP_ALU_3R<0x01030000, FPR64>; +-def FMUL_D : FP_ALU_3R<0x01050000, FPR64>; +-def FDIV_D : FP_ALU_3R<0x01070000, FPR64>; +-def FMADD_D : FP_ALU_4R<0x08200000, FPR64>; +-def FMSUB_D : FP_ALU_4R<0x08600000, FPR64>; +-def FNMADD_D : FP_ALU_4R<0x08a00000, FPR64>; +-def FNMSUB_D : FP_ALU_4R<0x08e00000, FPR64>; +-def FMAX_D : FP_ALU_3R<0x01090000, FPR64>; +-def FMIN_D : FP_ALU_3R<0x010b0000, FPR64>; +-def FMAXA_D : FP_ALU_3R<0x010d0000, FPR64>; +-def FMINA_D : FP_ALU_3R<0x010f0000, FPR64>; +-def FABS_D : FP_ALU_2R<0x01140800, FPR64>; +-def FNEG_D : FP_ALU_2R<0x01141800, FPR64>; +-def FSQRT_D : FP_ALU_2R<0x01144800, FPR64>; +-def FRECIP_D : FP_ALU_2R<0x01145800, FPR64>; +-def FRSQRT_D : FP_ALU_2R<0x01146800, FPR64>; +-def FRECIPE_D : FP_ALU_2R<0x01147800, FPR64>; +-def FRSQRTE_D : FP_ALU_2R<0x01148800, FPR64>; +-def FSCALEB_D : FP_ALU_3R<0x01110000, FPR64>; +-def FLOGB_D : FP_ALU_2R<0x01142800, FPR64>; +-def FCOPYSIGN_D : FP_ALU_3R<0x01130000, FPR64>; +-def FCLASS_D : FP_ALU_2R<0x01143800, FPR64>; +- +-// Comparison Instructions +-def FCMP_CAF_D : FP_CMP<0x0c200000, FPR64>; +-def FCMP_CUN_D : FP_CMP<0x0c240000, FPR64>; +-def FCMP_CEQ_D : FP_CMP<0x0c220000, FPR64>; +-def FCMP_CUEQ_D : FP_CMP<0x0c260000, FPR64>; +-def FCMP_CLT_D : FP_CMP<0x0c210000, FPR64>; +-def FCMP_CULT_D : FP_CMP<0x0c250000, FPR64>; +-def FCMP_CLE_D : FP_CMP<0x0c230000, FPR64>; +-def FCMP_CULE_D : FP_CMP<0x0c270000, FPR64>; +-def FCMP_CNE_D : FP_CMP<0x0c280000, FPR64>; +-def FCMP_COR_D : FP_CMP<0x0c2a0000, FPR64>; +-def FCMP_CUNE_D : FP_CMP<0x0c2c0000, FPR64>; +-def FCMP_SAF_D : FP_CMP<0x0c208000, FPR64>; +-def FCMP_SUN_D : FP_CMP<0x0c248000, FPR64>; +-def FCMP_SEQ_D : FP_CMP<0x0c228000, FPR64>; +-def FCMP_SUEQ_D : FP_CMP<0x0c268000, FPR64>; +-def FCMP_SLT_D : FP_CMP<0x0c218000, FPR64>; +-def FCMP_SULT_D : FP_CMP<0x0c258000, FPR64>; +-def FCMP_SLE_D : FP_CMP<0x0c238000, FPR64>; +-def FCMP_SULE_D : FP_CMP<0x0c278000, FPR64>; +-def FCMP_SNE_D : FP_CMP<0x0c288000, FPR64>; +-def FCMP_SOR_D : FP_CMP<0x0c2a8000, FPR64>; +-def FCMP_SUNE_D : FP_CMP<0x0c2c8000, FPR64>; +- +-// Conversion Instructions +-def FFINT_S_L : FP_CONV<0x011d1800, FPR32, FPR64>; +-def FTINT_L_S : FP_CONV<0x011b2400, FPR64, FPR32>; +-def FTINTRM_L_S : FP_CONV<0x011a2400, FPR64, FPR32>; +-def FTINTRP_L_S : FP_CONV<0x011a6400, FPR64, FPR32>; +-def FTINTRZ_L_S : FP_CONV<0x011aa400, FPR64, FPR32>; +-def FTINTRNE_L_S : FP_CONV<0x011ae400, FPR64, FPR32>; +-def FCVT_S_D : FP_CONV<0x01191800, FPR32, FPR64>; +-def FCVT_D_S : FP_CONV<0x01192400, FPR64, FPR32>; +-def FFINT_D_W : FP_CONV<0x011d2000, FPR64, FPR32>; +-def FFINT_D_L : FP_CONV<0x011d2800, FPR64, FPR64>; +-def FTINT_W_D : FP_CONV<0x011b0800, FPR32, FPR64>; +-def FTINT_L_D : FP_CONV<0x011b2800, FPR64, FPR64>; +-def FTINTRM_W_D : FP_CONV<0x011a0800, FPR32, FPR64>; +-def FTINTRM_L_D : FP_CONV<0x011a2800, FPR64, FPR64>; +-def FTINTRP_W_D : FP_CONV<0x011a4800, FPR32, FPR64>; +-def FTINTRP_L_D : FP_CONV<0x011a6800, FPR64, FPR64>; +-def FTINTRZ_W_D : FP_CONV<0x011a8800, FPR32, FPR64>; +-def FTINTRZ_L_D : FP_CONV<0x011aa800, FPR64, FPR64>; +-def FTINTRNE_W_D : FP_CONV<0x011ac800, FPR32, FPR64>; +-def FTINTRNE_L_D : FP_CONV<0x011ae800, FPR64, FPR64>; +-def FRINT_D : FP_CONV<0x011e4800, FPR64, FPR64>; +- +-// Move Instructions +-def FMOV_D : FP_MOV<0x01149800, FPR64, FPR64>; +-def MOVFRH2GR_S : FP_MOV<0x0114bc00, GPR, FPR64>; +-let isCodeGenOnly = 1 in { +-def MOVFR2GR_S_64 : FP_MOV<0x0114b400, GPR, FPR64>; +-def FSEL_xD : FP_SEL<0x0d000000, FPR64>; +-} // isCodeGenOnly = 1 +-let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Constraints = "$dst = $out" in { +-def MOVGR2FRH_W : FPFmtMOV<0x0114ac00, (outs FPR64:$out), +- (ins FPR64:$dst, GPR:$src), +- "$dst, $src">; +-} // hasSideEffects = 0, mayLoad = 0, mayStore = 0, Constraints = "$dst = $out" +- +-// Common Memory Access Instructions +-def FLD_D : FP_LOAD_2RI12<0x2b800000, FPR64>; +-def FST_D : FP_STORE_2RI12<0x2bc00000, FPR64>; +-def FLDX_D : FP_LOAD_3R<0x38340000, FPR64>; +-def FSTX_D : FP_STORE_3R<0x383c0000, FPR64>; +- +-// Bound Check Memory Access Instructions +-def FLDGT_D : FP_LOAD_3R<0x38748000, FPR64>; +-def FLDLE_D : FP_LOAD_3R<0x38758000, FPR64>; +-def FSTGT_D : FP_STORE_3R<0x38768000, FPR64>; +-def FSTLE_D : FP_STORE_3R<0x38778000, FPR64>; +- +-} // Predicates = [HasBasicD] +- +-// Instructions only available on LA64 +-let Predicates = [HasBasicD, IsLA64] in { +-def MOVGR2FR_D : FP_MOV<0x0114a800, FPR64, GPR>; +-def MOVFR2GR_D : FP_MOV<0x0114b800, GPR, FPR64>; +-} // Predicates = [HasBasicD, IsLA64] +- +-// Instructions only available on LA32 +-let Predicates = [HasBasicD, IsLA32], isCodeGenOnly = 1 in { +-def MOVGR2FR_W_64 : FP_MOV<0x0114a400, FPR64, GPR>; +-} // Predicates = [HasBasicD, IsLA32], isCodeGenOnly = 1 +- +-//===----------------------------------------------------------------------===// +-// Pseudo-instructions and codegen patterns +-//===----------------------------------------------------------------------===// +- +-let Predicates = [HasBasicD] in { +- +-/// Float arithmetic operations +- +-def : PatFprFpr; +-def : PatFprFpr; +-def : PatFprFpr; +-def : PatFprFpr; +-def : PatFprFpr; +-def : PatFprFpr; +-def : PatFprFpr; +-def : PatFpr; +-def : PatFpr; +-def : PatFpr; +-def : Pat<(fdiv fpimm1, (fsqrt FPR64:$fj)), (FRSQRT_D FPR64:$fj)>; +-def : Pat<(fcopysign FPR64:$fj, FPR32:$fk), +- (FCOPYSIGN_D FPR64:$fj, (FCVT_D_S FPR32:$fk))>; +-def : Pat<(fcopysign FPR32:$fj, FPR64:$fk), +- (FCOPYSIGN_S FPR32:$fj, (FCVT_S_D FPR64:$fk))>; +-def : Pat<(fcanonicalize FPR64:$fj), (FMAX_D $fj, $fj)>; +-let Predicates = [IsLA32] in { +-def : Pat<(is_fpclass FPR64:$fj, (i32 timm:$mask)), +- (SLTU R0, (ANDI (MOVFR2GR_S_64 (FCLASS_D FPR64:$fj)), +- (to_fclass_mask timm:$mask)))>; +-} // Predicates = [IsLA32] +-let Predicates = [IsLA64] in { +-def : Pat<(is_fpclass FPR64:$fj, (i32 timm:$mask)), +- (SLTU R0, (ANDI (MOVFR2GR_D (FCLASS_D FPR64:$fj)), +- (to_fclass_mask timm:$mask)))>; +-} // Predicates = [IsLA64] +- +-/// Setcc +- +-// Match non-signaling comparison +- +-// SETOGT/SETOGE/SETUGT/SETUGE/SETGE/SETNE/SETGT will expand into +-// SETOLT/SETOLE/SETULT/SETULE/SETLE/SETEQ/SETLT. +-def : PatFPSetcc; +-def : PatFPSetcc; +-def : PatFPSetcc; +-def : PatFPSetcc; +-def : PatFPSetcc; +-def : PatFPSetcc; +-def : PatFPSetcc; +-def : PatFPSetcc; +-def : PatFPSetcc; +-def : PatFPSetcc; +-def : PatFPSetcc; +-def : PatFPSetcc; +-def : PatFPSetcc; +- +-defm : PatFPBrcond; +-defm : PatFPBrcond; +-defm : PatFPBrcond; +-defm : PatFPBrcond; +-defm : PatFPBrcond; +-defm : PatFPBrcond; +-defm : PatFPBrcond; +-defm : PatFPBrcond; +-defm : PatFPBrcond; +-defm : PatFPBrcond; +-defm : PatFPBrcond; +- +-// Match signaling comparison +- +-def : PatStrictFsetccs; +-def : PatStrictFsetccs; +-def : PatStrictFsetccs; +-def : PatStrictFsetccs; +-def : PatStrictFsetccs; +-def : PatStrictFsetccs; +-def : PatStrictFsetccs; +-def : PatStrictFsetccs; +-def : PatStrictFsetccs; +-def : PatStrictFsetccs; +-def : PatStrictFsetccs; +- +-/// Select +- +-def : Pat<(select CFR:$cc, FPR64:$fk, FPR64:$fj), +- (FSEL_xD FPR64:$fj, FPR64:$fk, CFR:$cc)>; +- +-/// Selectcc +- +-def : PatFPSelectcc; +-def : PatFPSelectcc; +-def : PatFPSelectcc; +-def : PatFPSelectcc; +-def : PatFPSelectcc; +-def : PatFPSelectcc; +-def : PatFPSelectcc; +-def : PatFPSelectcc; +-def : PatFPSelectcc; +-def : PatFPSelectcc; +- +-/// Loads +- +-defm : LdPat; +-def : RegRegLdPat; +- +-/// Stores +- +-defm : StPat; +-def : RegRegStPat; +- +-/// FP conversion operations +- +-def : Pat<(loongarch_ftint FPR64:$src), (FTINTRZ_W_D FPR64:$src)>; +-def : Pat<(f64 (loongarch_ftint FPR64:$src)), (FTINTRZ_L_D FPR64:$src)>; +-def : Pat<(loongarch_ftint FPR32:$src), (FTINTRZ_L_S FPR32:$src)>; +- +-// f64 -> f32 +-def : Pat<(f32 (fpround FPR64:$src)), (FCVT_S_D FPR64:$src)>; +-// f32 -> f64 +-def : Pat<(f64 (fpextend FPR32:$src)), (FCVT_D_S FPR32:$src)>; +- +-// FP reciprocal operation +-def : Pat<(fdiv fpimm1, FPR64:$src), (FRECIP_D $src)>; +- +-let Predicates = [HasFrecipe] in { +-// FP approximate reciprocal operation +-def : Pat<(int_loongarch_frecipe_d FPR64:$src), (FRECIPE_D FPR64:$src)>; +-def : Pat<(int_loongarch_frsqrte_d FPR64:$src), (FRSQRTE_D FPR64:$src)>; +-} +- +-// fmadd.d: fj * fk + fa +-def : Pat<(fma FPR64:$fj, FPR64:$fk, FPR64:$fa), (FMADD_D $fj, $fk, $fa)>; +- +-// fmsub.d: fj * fk - fa +-def : Pat<(fma FPR64:$fj, FPR64:$fk, (fneg FPR64:$fa)), +- (FMSUB_D FPR64:$fj, FPR64:$fk, FPR64:$fa)>; +- +-// fnmadd.d: -(fj * fk + fa) +-def : Pat<(fneg (fma FPR64:$fj, FPR64:$fk, FPR64:$fa)), +- (FNMADD_D FPR64:$fj, FPR64:$fk, FPR64:$fa)>; +- +-// fnmadd.d: -fj * fk - fa (the nsz flag on the FMA) +-def : Pat<(fma_nsz (fneg FPR64:$fj), FPR64:$fk, (fneg FPR64:$fa)), +- (FNMADD_D FPR64:$fj, FPR64:$fk, FPR64:$fa)>; +- +-// fnmsub.d: -(fj * fk - fa) +-def : Pat<(fneg (fma FPR64:$fj, FPR64:$fk, (fneg FPR64:$fa))), +- (FNMSUB_D FPR64:$fj, FPR64:$fk, FPR64:$fa)>; +- +-// fnmsub.d: -fj * fk + fa (the nsz flag on the FMA) +-def : Pat<(fma_nsz (fneg FPR64:$fj), FPR64:$fk, FPR64:$fa), +- (FNMSUB_D FPR64:$fj, FPR64:$fk, FPR64:$fa)>; +-} // Predicates = [HasBasicD] +- +-/// Floating point constants +- +-let Predicates = [HasBasicD, IsLA64] in { +-def : Pat<(f64 fpimm0), (MOVGR2FR_D R0)>; +-def : Pat<(f64 fpimm0neg), (FNEG_D (MOVGR2FR_D R0))>; +-def : Pat<(f64 fpimm1), (FFINT_D_L (MOVGR2FR_D (ADDI_D R0, 1)))>; +-} // Predicates = [HasBasicD, IsLA64] +-let Predicates = [HasBasicD, IsLA32] in { +-def : Pat<(f64 fpimm0), (MOVGR2FRH_W (MOVGR2FR_W_64 R0), R0)>; +-def : Pat<(f64 fpimm0neg), (FNEG_D (MOVGR2FRH_W (MOVGR2FR_W_64 R0), R0))>; +-def : Pat<(f64 fpimm1), (FCVT_D_S (FFINT_S_W (MOVGR2FR_W (ADDI_W R0, 1))))>; +-} // Predicates = [HasBasicD, IsLA32] +- +-/// Convert int to FP +- +-let Predicates = [HasBasicD, IsLA64] in { +-def : Pat<(f32 (sint_to_fp GPR:$src)), (FFINT_S_L (MOVGR2FR_D GPR:$src))>; +-def : Pat<(f64 (sint_to_fp (i64 (sexti32 (i64 GPR:$src))))), +- (FFINT_D_W (MOVGR2FR_W GPR:$src))>; +-def : Pat<(f64 (sint_to_fp GPR:$src)), (FFINT_D_L (MOVGR2FR_D GPR:$src))>; +- +-def : Pat<(bitconvert GPR:$src), (MOVGR2FR_D GPR:$src)>; +-} // Predicates = [HasBasicD, IsLA64] +-let Predicates = [HasBasicD, IsLA32] in { +-def : Pat<(f64 (sint_to_fp (i32 GPR:$src))), (FFINT_D_W (MOVGR2FR_W GPR:$src))>; +-} // Predicates = [HasBasicD, IsLA32] +- +-// Convert FP to int +-let Predicates = [HasBasicD, IsLA64] in { +-def : Pat<(bitconvert FPR64:$src), (MOVFR2GR_D FPR64:$src)>; +-} // Predicates = [HasBasicD, IsLA64] +- +-// FP Rounding +-let Predicates = [HasBasicD, IsLA64] in { +-def : PatFpr; +-} // Predicates = [HasBasicD, IsLA64] +diff --git a/llvm/lib/Target/LoongArch/LoongArchFloatInstrFormats.td b/llvm/lib/Target/LoongArch/LoongArchFloatInstrFormats.td +deleted file mode 100644 +index f66f620ca..000000000 +--- a/llvm/lib/Target/LoongArch/LoongArchFloatInstrFormats.td ++++ /dev/null +@@ -1,232 +0,0 @@ +-// LoongArchFloatInstrFormats.td - LoongArch FP Instr Formats -*- tablegen -*-// +-// +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +-// +-//===----------------------------------------------------------------------===// +- +-//===----------------------------------------------------------------------===// +-// Describe LoongArch floating-point instructions format +-// +-// opcode - operation code. +-// fd - destination register operand. +-// {c/f}{j/k/a} - source register operand. +-// immN - immediate data operand. +-// +-//===----------------------------------------------------------------------===// +- +-// Some FP instructions are defined twice, for accepting FPR32 and FPR64, but +-// with the same mnemonic. Also some are codegen-only definitions that +-// nevertheless require a "normal" mnemonic. +-// +-// In order to accommodate these needs, the instruction defs have names +-// suffixed with `_x[SD]` or `_64`, that will get trimmed before the mnemonics +-// are derived. +-class deriveFPInsnMnemonic { +- string ret = deriveInsnMnemonic.ret; +-} +- +-// 2R-type +-// +-class FPFmt2R op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<5> fj; +- bits<5> fd; +- +- let Inst{31-0} = op; +- let Inst{9-5} = fj; +- let Inst{4-0} = fd; +-} +- +-// 3R-type +-// +-class FPFmt3R op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<5> fk; +- bits<5> fj; +- bits<5> fd; +- +- let Inst{31-0} = op; +- let Inst{14-10} = fk; +- let Inst{9-5} = fj; +- let Inst{4-0} = fd; +-} +- +-// 4R-type +-// +-class FPFmt4R op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<5> fa; +- bits<5> fk; +- bits<5> fj; +- bits<5> fd; +- +- let Inst{31-0} = op; +- let Inst{19-15} = fa; +- let Inst{14-10} = fk; +- let Inst{9-5} = fj; +- let Inst{4-0} = fd; +-} +- +-// 2RI12-type +-// +-class FPFmt2RI12 op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<12> imm12; +- bits<5> rj; +- bits<5> fd; +- +- let Inst{31-0} = op; +- let Inst{21-10} = imm12; +- let Inst{9-5} = rj; +- let Inst{4-0} = fd; +-} +- +-// FmtFCMP +-// +-class FPFmtFCMP op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<5> fk; +- bits<5> fj; +- bits<3> cd; +- +- let Inst{31-0} = op; +- let Inst{14-10} = fk; +- let Inst{9-5} = fj; +- let Inst{2-0} = cd; +-} +- +-// FPFmtBR +-// +-class FPFmtBR op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<21> imm21; +- bits<3> cj; +- +- let Inst{31-0} = op; +- let Inst{25-10} = imm21{15-0}; +- let Inst{7-5} = cj; +- let Inst{4-0} = imm21{20-16}; +-} +- +-// FmtFSEL +-// +-class FPFmtFSEL op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<3> ca; +- bits<5> fk; +- bits<5> fj; +- bits<5> fd; +- +- let Inst{31-0} = op; +- let Inst{17-15} = ca; +- let Inst{14-10} = fk; +- let Inst{9-5} = fj; +- let Inst{4-0} = fd; +-} +- +-// FPFmtMOV +-// +-class FPFmtMOV op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<5> src; +- bits<5> dst; +- +- let Inst{31-0} = op; +- let Inst{9-5} = src; +- let Inst{4-0} = dst; +-} +- +-// FPFmtMEM +-// +-class FPFmtMEM op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<5> rk; +- bits<5> rj; +- bits<5> fd; +- +- let Inst{31-0} = op; +- let Inst{14-10} = rk; +- let Inst{9-5} = rj; +- let Inst{4-0} = fd; +-} +- +-//===----------------------------------------------------------------------===// +-// Instruction class templates +-//===----------------------------------------------------------------------===// +- +-let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { +-class FP_ALU_2R op, RegisterClass rc = FPR32> +- : FPFmt2R; +- +-class FP_ALU_3R op, RegisterClass rc = FPR32> +- : FPFmt3R; +- +-class FP_ALU_4R op, RegisterClass rc = FPR32> +- : FPFmt4R; +-} // hasSideEffects = 0, mayLoad = 0, mayStore = 0 +- +-let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { +-class FP_CMP op, RegisterClass rc = FPR32> +- : FPFmtFCMP; +- +-class FP_CONV op, RegisterClass rcd = FPR32, RegisterClass rcs = FPR32> +- : FPFmt2R; +- +-class FP_MOV op, RegisterClass rcd = FPR32, RegisterClass rcs = FPR32> +- : FPFmtMOV; +- +-class FP_SEL op, RegisterClass rc = FPR32> +- : FPFmtFSEL; +- +-class FP_BRANCH opcode> +- : FPFmtBR { +- let isBranch = 1; +- let isTerminator = 1; +-} +-} // hasSideEffects = 0, mayLoad = 0, mayStore = 0 +- +-let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { +-class FP_LOAD_3R op, RegisterClass rc = FPR32> +- : FPFmtMEM; +-class FP_LOAD_2RI12 op, RegisterClass rc = FPR32> +- : FPFmt2RI12; +-} // hasSideEffects = 0, mayLoad = 1, mayStore = 0 +- +-let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { +-class FP_STORE_3R op, RegisterClass rc = FPR32> +- : FPFmtMEM; +-class FP_STORE_2RI12 op, RegisterClass rc = FPR32> +- : FPFmt2RI12; +-} // hasSideEffects = 0, mayLoad = 0, mayStore = 1 +- +-// This class is used to define `SET_CFR_{FALSE,TRUE}` instructions which are +-// used to expand `PseudoCopyCFR`. +-class SET_CFR op, string opcstr> +- : FP_CMP { +- let isCodeGenOnly = 1; +- let fj = 0; // fa0 +- let fk = 0; // fa0 +- let AsmString = opcstr # "\t$cd, $$fa0, $$fa0"; +- let OutOperandList = (outs CFR:$cd); +- let InOperandList = (ins); +-} +diff --git a/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp +index dc2d61a6e..a36f6e901 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp ++++ b/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp +@@ -1,4 +1,4 @@ +-//===-- LoongArchFrameLowering.cpp - LoongArch Frame Information -*- C++ -*-==// ++//===-- LoongArchFrameLowering.cpp - LoongArch Frame Information --------------------===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -11,198 +11,151 @@ + //===----------------------------------------------------------------------===// + + #include "LoongArchFrameLowering.h" +-#include "LoongArchMachineFunctionInfo.h" +-#include "LoongArchSubtarget.h" + #include "MCTargetDesc/LoongArchBaseInfo.h" +-#include "MCTargetDesc/LoongArchMCTargetDesc.h" ++#include "MCTargetDesc/LoongArchABIInfo.h" ++#include "LoongArchInstrInfo.h" ++#include "LoongArchMachineFunction.h" ++#include "LoongArchTargetMachine.h" ++#include "LoongArchRegisterInfo.h" ++#include "LoongArchSubtarget.h" ++#include "llvm/ADT/BitVector.h" ++#include "llvm/ADT/StringRef.h" ++#include "llvm/ADT/StringSwitch.h" ++#include "llvm/CodeGen/MachineBasicBlock.h" + #include "llvm/CodeGen/MachineFrameInfo.h" + #include "llvm/CodeGen/MachineFunction.h" ++#include "llvm/CodeGen/MachineInstr.h" + #include "llvm/CodeGen/MachineInstrBuilder.h" ++#include "llvm/CodeGen/MachineModuleInfo.h" ++#include "llvm/CodeGen/MachineOperand.h" + #include "llvm/CodeGen/MachineRegisterInfo.h" + #include "llvm/CodeGen/RegisterScavenging.h" +-#include "llvm/IR/DiagnosticInfo.h" ++#include "llvm/CodeGen/TargetInstrInfo.h" ++#include "llvm/CodeGen/TargetRegisterInfo.h" ++#include "llvm/CodeGen/TargetSubtargetInfo.h" ++#include "llvm/IR/DataLayout.h" ++#include "llvm/IR/DebugLoc.h" ++#include "llvm/IR/Function.h" + #include "llvm/MC/MCDwarf.h" ++#include "llvm/MC/MCRegisterInfo.h" ++#include "llvm/MC/MachineLocation.h" ++#include "llvm/Support/CodeGen.h" ++#include "llvm/Support/ErrorHandling.h" ++#include "llvm/Support/MathExtras.h" ++#include "llvm/Target/TargetOptions.h" ++#include ++#include ++#include ++#include + + using namespace llvm; + +-#define DEBUG_TYPE "loongarch-frame-lowering" +- +-// Return true if the specified function should have a dedicated frame +-// pointer register. This is true if frame pointer elimination is +-// disabled, if it needs dynamic stack realignment, if the function has +-// variable sized allocas, or if the frame address is taken. +-bool LoongArchFrameLowering::hasFP(const MachineFunction &MF) const { +- const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); +- +- const MachineFrameInfo &MFI = MF.getFrameInfo(); +- return MF.getTarget().Options.DisableFramePointerElim(MF) || +- RegInfo->hasStackRealignment(MF) || MFI.hasVarSizedObjects() || +- MFI.isFrameAddressTaken(); +-} +- +-bool LoongArchFrameLowering::hasBP(const MachineFunction &MF) const { ++// We would like to split the SP adjustment to reduce prologue/epilogue ++// as following instructions. In this way, the offset of the callee saved ++// register could fit in a single store. ++uint64_t ++LoongArchFrameLowering::getFirstSPAdjustAmount(const MachineFunction &MF, ++ bool IsPrologue) const { + const MachineFrameInfo &MFI = MF.getFrameInfo(); +- const TargetRegisterInfo *TRI = STI.getRegisterInfo(); +- +- return MFI.hasVarSizedObjects() && TRI->hasStackRealignment(MF); +-} +- +-void LoongArchFrameLowering::adjustReg(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, +- const DebugLoc &DL, Register DestReg, +- Register SrcReg, int64_t Val, +- MachineInstr::MIFlag Flag) const { +- const LoongArchInstrInfo *TII = STI.getInstrInfo(); +- bool IsLA64 = STI.is64Bit(); +- unsigned Addi = IsLA64 ? LoongArch::ADDI_D : LoongArch::ADDI_W; +- +- if (DestReg == SrcReg && Val == 0) +- return; +- +- if (isInt<12>(Val)) { +- // addi.w/d $DstReg, $SrcReg, Val +- BuildMI(MBB, MBBI, DL, TII->get(Addi), DestReg) +- .addReg(SrcReg) +- .addImm(Val) +- .setMIFlag(Flag); +- return; +- } +- +- // Try to split the offset across two ADDIs. We need to keep the stack pointer +- // aligned after each ADDI. We need to determine the maximum value we can put +- // in each ADDI. In the negative direction, we can use -2048 which is always +- // sufficiently aligned. In the positive direction, we need to find the +- // largest 12-bit immediate that is aligned. Exclude -4096 since it can be +- // created with LU12I.W. +- assert(getStackAlign().value() < 2048 && "Stack alignment too large"); +- int64_t MaxPosAdjStep = 2048 - getStackAlign().value(); +- if (Val > -4096 && Val <= (2 * MaxPosAdjStep)) { +- int64_t FirstAdj = Val < 0 ? -2048 : MaxPosAdjStep; +- Val -= FirstAdj; +- BuildMI(MBB, MBBI, DL, TII->get(Addi), DestReg) +- .addReg(SrcReg) +- .addImm(FirstAdj) +- .setMIFlag(Flag); +- BuildMI(MBB, MBBI, DL, TII->get(Addi), DestReg) +- .addReg(DestReg, RegState::Kill) +- .addImm(Val) +- .setMIFlag(Flag); +- return; +- } ++ const std::vector &CSI = MFI.getCalleeSavedInfo(); ++ uint64_t StackSize = MFI.getStackSize(); + +- unsigned Opc = IsLA64 ? LoongArch::ADD_D : LoongArch::ADD_W; +- if (Val < 0) { +- Val = -Val; +- Opc = IsLA64 ? LoongArch::SUB_D : LoongArch::SUB_W; ++ // Return the FirstSPAdjustAmount if the StackSize can not fit in signed ++ // 12-bit and there exists a callee saved register need to be pushed. ++ if (!isInt<12>(StackSize)) { ++ // FirstSPAdjustAmount is choosed as (2048 - StackAlign) ++ // because 2048 will cause sp = sp + 2048 in epilogue split into ++ // multi-instructions. The offset smaller than 2048 can fit in signle ++ // load/store instruction and we have to stick with the stack alignment. ++ return CSI.size() > 0 ? 2048 - getStackAlign().value() ++ : (IsPrologue ? 2048 : 0); + } +- +- MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); +- Register ScratchReg = MRI.createVirtualRegister(&LoongArch::GPRRegClass); +- TII->movImm(MBB, MBBI, DL, ScratchReg, Val, Flag); +- BuildMI(MBB, MBBI, DL, TII->get(Opc), DestReg) +- .addReg(SrcReg) +- .addReg(ScratchReg, RegState::Kill) +- .setMIFlag(Flag); +-} +- +-// Determine the size of the frame and maximum call frame size. +-void LoongArchFrameLowering::determineFrameLayout(MachineFunction &MF) const { +- MachineFrameInfo &MFI = MF.getFrameInfo(); +- +- // Get the number of bytes to allocate from the FrameInfo. +- uint64_t FrameSize = MFI.getStackSize(); +- +- // Make sure the frame is aligned. +- FrameSize = alignTo(FrameSize, getStackAlign()); +- +- // Update frame info. +- MFI.setStackSize(FrameSize); +-} +- +-static uint64_t estimateFunctionSizeInBytes(const LoongArchInstrInfo *TII, +- const MachineFunction &MF) { +- uint64_t FuncSize = 0; +- for (auto &MBB : MF) +- for (auto &MI : MBB) +- FuncSize += TII->getInstSizeInBytes(MI); +- return FuncSize; +-} +- +-static bool needScavSlotForCFR(MachineFunction &MF) { +- if (!MF.getSubtarget().hasBasicF()) +- return false; +- for (auto &MBB : MF) +- for (auto &MI : MBB) +- if (MI.getOpcode() == LoongArch::PseudoST_CFR) +- return true; +- return false; ++ return 0; + } + +-void LoongArchFrameLowering::processFunctionBeforeFrameFinalized( +- MachineFunction &MF, RegScavenger *RS) const { +- const LoongArchRegisterInfo *RI = STI.getRegisterInfo(); +- const TargetRegisterClass &RC = LoongArch::GPRRegClass; +- const LoongArchInstrInfo *TII = STI.getInstrInfo(); +- LoongArchMachineFunctionInfo *LAFI = +- MF.getInfo(); +- MachineFrameInfo &MFI = MF.getFrameInfo(); +- +- unsigned ScavSlotsNum = 0; +- +- // Far branches beyond 27-bit offset require a spill slot for scratch register. +- bool IsLargeFunction = !isInt<27>(estimateFunctionSizeInBytes(TII, MF)); +- if (IsLargeFunction) +- ScavSlotsNum = 1; +- +- // estimateStackSize has been observed to under-estimate the final stack +- // size, so give ourselves wiggle-room by checking for stack size +- // representable an 11-bit signed field rather than 12-bits. +- if (!isInt<11>(MFI.estimateStackSize(MF))) +- ScavSlotsNum = std::max(ScavSlotsNum, 1u); +- +- // For CFR spill. +- if (needScavSlotForCFR(MF)) +- ++ScavSlotsNum; +- +- // Create emergency spill slots. +- for (unsigned i = 0; i < ScavSlotsNum; ++i) { +- int FI = MFI.CreateStackObject(RI->getSpillSize(RC), RI->getSpillAlign(RC), +- false); +- RS->addScavengingFrameIndex(FI); +- if (IsLargeFunction && LAFI->getBranchRelaxationSpillFrameIndex() == -1) +- LAFI->setBranchRelaxationSpillFrameIndex(FI); +- LLVM_DEBUG(dbgs() << "Allocated FI(" << FI +- << ") as the emergency spill slot.\n"); +- } +-} ++//===----------------------------------------------------------------------===// ++// ++// Stack Frame Processing methods ++// +----------------------------+ ++// ++// The stack is allocated decrementing the stack pointer on ++// the first instruction of a function prologue. Once decremented, ++// all stack references are done thought a positive offset ++// from the stack/frame pointer, so the stack is considering ++// to grow up! Otherwise terrible hacks would have to be made ++// to get this stack ABI compliant :) ++// ++// The stack frame required by the ABI (after call): ++// Offset ++// ++// 0 ---------- ++// 4 Args to pass ++// . Alloca allocations ++// . Local Area ++// . CPU "Callee Saved" Registers ++// . saved FP ++// . saved RA ++// . FPU "Callee Saved" Registers ++// StackSize ----------- ++// ++// Offset - offset from sp after stack allocation on function prologue ++// ++// The sp is the stack pointer subtracted/added from the stack size ++// at the Prologue/Epilogue ++// ++// References to the previous stack (to obtain arguments) are done ++// with offsets that exceeds the stack size: (stacksize+(4*(num_arg-1)) ++// ++// Examples: ++// - reference to the actual stack frame ++// for any local area var there is smt like : FI >= 0, StackOffset: 4 ++// st.w REGX, SP, 4 ++// ++// - reference to previous stack frame ++// suppose there's a load to the 5th arguments : FI < 0, StackOffset: 16. ++// The emitted instruction will be something like: ++// ld.w REGX, SP, 16+StackSize ++// ++// Since the total stack size is unknown on LowerFormalArguments, all ++// stack references (ObjectOffset) created to reference the function ++// arguments, are negative numbers. This way, on eliminateFrameIndex it's ++// possible to detect those references and the offsets are adjusted to ++// their real location. ++// ++//===----------------------------------------------------------------------===// ++// ++LoongArchFrameLowering::LoongArchFrameLowering(const LoongArchSubtarget &STI) ++ : TargetFrameLowering(StackGrowsDown, STI.getStackAlignment(), 0, ++ STI.getStackAlignment()), STI(STI) {} + + void LoongArchFrameLowering::emitPrologue(MachineFunction &MF, + MachineBasicBlock &MBB) const { + MachineFrameInfo &MFI = MF.getFrameInfo(); +- auto *LoongArchFI = MF.getInfo(); +- const LoongArchRegisterInfo *RI = STI.getRegisterInfo(); +- const LoongArchInstrInfo *TII = STI.getInstrInfo(); +- MachineBasicBlock::iterator MBBI = MBB.begin(); +- bool IsLA64 = STI.is64Bit(); +- +- Register SPReg = LoongArch::R3; +- Register FPReg = LoongArch::R22; ++ LoongArchFunctionInfo *LoongArchFI = MF.getInfo(); + +- // Debug location must be unknown since the first debug location is used +- // to determine the end of the prologue. +- DebugLoc DL; +- // All calls are tail calls in GHC calling conv, and functions have no +- // prologue/epilogue. +- if (MF.getFunction().getCallingConv() == CallingConv::GHC) +- return; +- // Determine the correct frame layout +- determineFrameLayout(MF); ++ const LoongArchInstrInfo &TII = ++ *static_cast(STI.getInstrInfo()); ++ const LoongArchRegisterInfo &RegInfo = ++ *static_cast(STI.getRegisterInfo()); ++ MachineBasicBlock::iterator MBBI = MBB.begin(); ++ DebugLoc dl; ++ LoongArchABIInfo ABI = STI.getABI(); ++ unsigned SP = ABI.GetStackPtr(); ++ unsigned FP = ABI.GetFramePtr(); ++ unsigned ZERO = ABI.GetNullPtr(); ++ unsigned MOVE = ABI.GetGPRMoveOp(); ++ unsigned ADDI = ABI.GetPtrAddiOp(); ++ unsigned AND = ABI.IsLP64() ? LoongArch::AND : LoongArch::AND32; ++ unsigned SLLI = ABI.IsLP64() ? LoongArch::SLLI_D : LoongArch::SLLI_W; ++ ++ const TargetRegisterClass *RC = ABI.ArePtrs64bit() ? ++ &LoongArch::GPR64RegClass : &LoongArch::GPR32RegClass; + + // First, compute final stack size. + uint64_t StackSize = MFI.getStackSize(); + uint64_t RealStackSize = StackSize; + +- // Early exit if there is no need to allocate space in the stack. ++ // No need to allocate space on the stack. + if (StackSize == 0 && !MFI.adjustsStack()) + return; + +@@ -213,46 +166,69 @@ void LoongArchFrameLowering::emitPrologue(MachineFunction &MF, + StackSize = FirstSPAdjustAmount; + + // Adjust stack. +- adjustReg(MBB, MBBI, DL, SPReg, SPReg, -StackSize, MachineInstr::FrameSetup); ++ TII.adjustReg(SP, SP, -StackSize, MBB, MBBI, MachineInstr::FrameSetup); + if (FirstSPAdjustAmount != 2048 || SecondSPAdjustAmount == 0) { + // Emit ".cfi_def_cfa_offset StackSize". + unsigned CFIIndex = + MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, StackSize)); +- BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) +- .addCFIIndex(CFIIndex) +- .setMIFlag(MachineInstr::FrameSetup); ++ BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) ++ .addCFIIndex(CFIIndex); + } + +- const auto &CSI = MFI.getCalleeSavedInfo(); ++ MachineModuleInfo &MMI = MF.getMMI(); ++ const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); + +- // The frame pointer is callee-saved, and code has been generated for us to +- // save it to the stack. We need to skip over the storing of callee-saved +- // registers as the frame pointer must be modified after it has been saved +- // to the stack, not before. +- std::advance(MBBI, CSI.size()); +- +- // Iterate over list of callee-saved registers and emit .cfi_offset +- // directives. +- for (const auto &Entry : CSI) { +- int64_t Offset = MFI.getObjectOffset(Entry.getFrameIdx()); +- unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( +- nullptr, RI->getDwarfRegNum(Entry.getReg(), true), Offset)); +- BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) +- .addCFIIndex(CFIIndex) +- .setMIFlag(MachineInstr::FrameSetup); ++ const std::vector &CSI = MFI.getCalleeSavedInfo(); ++ ++ if (!CSI.empty()) { ++ // Find the instruction past the last instruction that saves a callee-saved ++ // register to the stack. ++ for (unsigned i = 0; i < CSI.size(); ++i) ++ ++MBBI; ++ ++ // Iterate over list of callee-saved registers and emit .cfi_offset ++ // directives. ++ for (std::vector::const_iterator I = CSI.begin(), ++ E = CSI.end(); I != E; ++I) { ++ int64_t Offset = MFI.getObjectOffset(I->getFrameIdx()); ++ unsigned Reg = I->getReg(); ++ unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( ++ nullptr, MRI->getDwarfRegNum(Reg, true), Offset)); ++ BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) ++ .addCFIIndex(CFIIndex); ++ } + } + +- // Generate new FP. +- if (hasFP(MF)) { +- adjustReg(MBB, MBBI, DL, FPReg, SPReg, +- StackSize - LoongArchFI->getVarArgsSaveSize(), +- MachineInstr::FrameSetup); ++ if (LoongArchFI->callsEhReturn()) { ++ // Insert instructions that spill eh data registers. ++ for (int I = 0; I < 4; ++I) { ++ if (!MBB.isLiveIn(ABI.GetEhDataReg(I))) ++ MBB.addLiveIn(ABI.GetEhDataReg(I)); ++ TII.storeRegToStackSlot(MBB, MBBI, ABI.GetEhDataReg(I), false, ++ LoongArchFI->getEhDataRegFI(I), RC, &RegInfo, Register()); ++ } ++ ++ // Emit .cfi_offset directives for eh data registers. ++ for (int I = 0; I < 4; ++I) { ++ int64_t Offset = MFI.getObjectOffset(LoongArchFI->getEhDataRegFI(I)); ++ unsigned Reg = MRI->getDwarfRegNum(ABI.GetEhDataReg(I), true); ++ unsigned CFIIndex = MF.addFrameInst( ++ MCCFIInstruction::createOffset(nullptr, Reg, Offset)); ++ BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) ++ .addCFIIndex(CFIIndex); ++ } ++ } + +- // Emit ".cfi_def_cfa $fp, LoongArchFI->getVarArgsSaveSize()" ++ // If framepointer enabled, set it to point to the stack pointer on entry. ++ if (hasFP(MF)) { ++ // Insert instruction "addi.w/d $fp, $sp, StackSize" at this location. ++ TII.adjustReg(FP, SP, StackSize - LoongArchFI->getVarArgsSaveSize(), MBB, ++ MBBI, MachineInstr::FrameSetup); ++ // Emit ".cfi_def_cfa $fp, $varargs_size". + unsigned CFIIndex = MF.addFrameInst( +- MCCFIInstruction::cfiDefCfa(nullptr, RI->getDwarfRegNum(FPReg, true), ++ MCCFIInstruction::cfiDefCfa(nullptr, MRI->getDwarfRegNum(FP, true), + LoongArchFI->getVarArgsSaveSize())); +- BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) ++ BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex) + .setMIFlag(MachineInstr::FrameSetup); + } +@@ -262,8 +238,8 @@ void LoongArchFrameLowering::emitPrologue(MachineFunction &MF, + if (hasFP(MF)) { + assert(SecondSPAdjustAmount > 0 && + "SecondSPAdjustAmount should be greater than zero"); +- adjustReg(MBB, MBBI, DL, SPReg, SPReg, -SecondSPAdjustAmount, +- MachineInstr::FrameSetup); ++ TII.adjustReg(SP, SP, -SecondSPAdjustAmount, MBB, MBBI, ++ MachineInstr::FrameSetup); + } else { + // FIXME: RegScavenger will place the spill instruction before the + // prologue if a VReg is created in the prologue. This will pollute the +@@ -271,46 +247,48 @@ void LoongArchFrameLowering::emitPrologue(MachineFunction &MF, + // the `addi.w/d` instruction for stack adjustment to ensure that VReg + // will not be created. + for (int Val = SecondSPAdjustAmount; Val > 0; Val -= 2048) +- BuildMI(MBB, MBBI, DL, +- TII->get(IsLA64 ? LoongArch::ADDI_D : LoongArch::ADDI_W), SPReg) +- .addReg(SPReg) ++ BuildMI(MBB, MBBI, dl, TII.get(ADDI), SP) ++ .addReg(SP) + .addImm(Val < 2048 ? -Val : -2048) + .setMIFlag(MachineInstr::FrameSetup); +- + // If we are using a frame-pointer, and thus emitted ".cfi_def_cfa fp, 0", +- // don't emit an sp-based .cfi_def_cfa_offset +- // Emit ".cfi_def_cfa_offset RealStackSize" ++ // don't emit an sp-based .cfi_def_cfa_offset. ++ // Emit ".cfi_def_cfa_offset StackSize" + unsigned CFIIndex = MF.addFrameInst( +- MCCFIInstruction::cfiDefCfaOffset(nullptr, RealStackSize)); +- BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) ++ MCCFIInstruction::cfiDefCfaOffset(nullptr, MFI.getStackSize())); ++ BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex) + .setMIFlag(MachineInstr::FrameSetup); + } + } + ++ // Realign stack. + if (hasFP(MF)) { +- // Realign stack. +- if (RI->hasStackRealignment(MF)) { +- unsigned Align = Log2(MFI.getMaxAlign()); +- assert(Align > 0 && "The stack realignment size is invalid!"); +- BuildMI(MBB, MBBI, DL, +- TII->get(IsLA64 ? LoongArch::BSTRINS_D : LoongArch::BSTRINS_W), +- SPReg) +- .addReg(SPReg) +- .addReg(LoongArch::R0) +- .addImm(Align - 1) +- .addImm(0) +- .setMIFlag(MachineInstr::FrameSetup); +- // FP will be used to restore the frame in the epilogue, so we need +- // another base register BP to record SP after re-alignment. SP will +- // track the current stack after allocating variable sized objects. ++ if (RegInfo.hasStackRealignment(MF)) { ++ // addiu $Reg, $zero, -MaxAlignment ++ // andi $sp, $sp, $Reg ++ unsigned VR = MF.getRegInfo().createVirtualRegister(RC); ++ assert((Log2(MFI.getMaxAlign()) < 16) && ++ "Function's alignment size requirement is not supported."); ++ int MaxAlign = -(int)MFI.getMaxAlign().value(); ++ int Alignment = (int)MFI.getMaxAlign().value(); ++ ++ if (Alignment <= 2048) { ++ BuildMI(MBB, MBBI, dl, TII.get(ADDI), VR).addReg(ZERO).addImm(MaxAlign); ++ BuildMI(MBB, MBBI, dl, TII.get(AND), SP).addReg(SP).addReg(VR); ++ } else { ++ const unsigned NrBitsToZero = llvm::countr_zero((unsigned)Alignment); ++ BuildMI(MBB, MBBI, dl, TII.get(ADDI), VR).addReg(ZERO).addImm(-1); ++ BuildMI(MBB, MBBI, dl, TII.get(SLLI), VR) ++ .addReg(VR) ++ .addImm(NrBitsToZero); ++ BuildMI(MBB, MBBI, dl, TII.get(AND), SP).addReg(SP).addReg(VR); ++ } ++ + if (hasBP(MF)) { +- // move BP, $sp +- BuildMI(MBB, MBBI, DL, TII->get(LoongArch::OR), +- LoongArchABI::getBPReg()) +- .addReg(SPReg) +- .addReg(LoongArch::R0) +- .setMIFlag(MachineInstr::FrameSetup); ++ // move $s7, $sp ++ unsigned BP = STI.isABI_LP64() ? LoongArch::S7_64 : LoongArch::S7; ++ BuildMI(MBB, MBBI, dl, TII.get(MOVE), BP).addReg(SP).addReg(ZERO); + } + } + } +@@ -318,166 +296,80 @@ void LoongArchFrameLowering::emitPrologue(MachineFunction &MF, + + void LoongArchFrameLowering::emitEpilogue(MachineFunction &MF, + MachineBasicBlock &MBB) const { +- const LoongArchRegisterInfo *RI = STI.getRegisterInfo(); +- MachineFrameInfo &MFI = MF.getFrameInfo(); +- auto *LoongArchFI = MF.getInfo(); +- Register SPReg = LoongArch::R3; +- // All calls are tail calls in GHC calling conv, and functions have no +- // prologue/epilogue. +- if (MF.getFunction().getCallingConv() == CallingConv::GHC) +- return; + MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator(); +- DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); ++ MachineFrameInfo &MFI = MF.getFrameInfo(); ++ LoongArchFunctionInfo *LoongArchFI = MF.getInfo(); + +- const auto &CSI = MFI.getCalleeSavedInfo(); +- // Skip to before the restores of callee-saved registers. +- auto LastFrameDestroy = MBBI; +- if (!CSI.empty()) +- LastFrameDestroy = std::prev(MBBI, CSI.size()); ++ const LoongArchInstrInfo &TII = ++ *static_cast(STI.getInstrInfo()); ++ const LoongArchRegisterInfo &RegInfo = ++ *static_cast(STI.getRegisterInfo()); ++ ++ DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); ++ LoongArchABIInfo ABI = STI.getABI(); ++ unsigned SP = ABI.GetStackPtr(); ++ unsigned FP = ABI.GetFramePtr(); + + // Get the number of bytes from FrameInfo. + uint64_t StackSize = MFI.getStackSize(); + + // Restore the stack pointer. +- if (RI->hasStackRealignment(MF) || MFI.hasVarSizedObjects()) { +- assert(hasFP(MF) && "frame pointer should not have been eliminated"); +- adjustReg(MBB, LastFrameDestroy, DL, SPReg, LoongArch::R22, +- -StackSize + LoongArchFI->getVarArgsSaveSize(), +- MachineInstr::FrameDestroy); ++ if (hasFP(MF) && ++ (RegInfo.hasStackRealignment(MF) || MFI.hasVarSizedObjects())) { ++ // Find the first instruction that restores a callee-saved register. ++ MachineBasicBlock::iterator I = MBBI; ++ for (unsigned i = 0; i < MFI.getCalleeSavedInfo().size(); ++i) ++ --I; ++ TII.adjustReg(SP, FP, -(StackSize - LoongArchFI->getVarArgsSaveSize()), MBB, ++ I); + } + + uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF); + if (FirstSPAdjustAmount) { +- uint64_t SecondSPAdjustAmount = StackSize - FirstSPAdjustAmount; ++ uint64_t SecondSPAdjustAmount = MFI.getStackSize() - FirstSPAdjustAmount; + assert(SecondSPAdjustAmount > 0 && + "SecondSPAdjustAmount should be greater than zero"); ++ // Find the first instruction that restores a callee-saved register. ++ MachineBasicBlock::iterator I = MBBI; ++ for (unsigned i = 0; i < MFI.getCalleeSavedInfo().size(); ++i) ++ --I; + +- adjustReg(MBB, LastFrameDestroy, DL, SPReg, SPReg, SecondSPAdjustAmount, +- MachineInstr::FrameDestroy); +- StackSize = FirstSPAdjustAmount; ++ TII.adjustReg(SP, SP, SecondSPAdjustAmount, MBB, I); + } + +- // Deallocate stack +- adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackSize, MachineInstr::FrameDestroy); +-} ++ if (LoongArchFI->callsEhReturn()) { ++ const TargetRegisterClass *RC = ++ ABI.ArePtrs64bit() ? &LoongArch::GPR64RegClass : &LoongArch::GPR32RegClass; + +-// We would like to split the SP adjustment to reduce prologue/epilogue +-// as following instructions. In this way, the offset of the callee saved +-// register could fit in a single store. +-// e.g. +-// addi.d $sp, $sp, -2032 +-// st.d $ra, $sp, 2024 +-// st.d $fp, $sp, 2016 +-// addi.d $sp, $sp, -16 +-uint64_t +-LoongArchFrameLowering::getFirstSPAdjustAmount(const MachineFunction &MF, +- bool IsPrologue) const { +- const MachineFrameInfo &MFI = MF.getFrameInfo(); +- const std::vector &CSI = MFI.getCalleeSavedInfo(); ++ // Find first instruction that restores a callee-saved register. ++ MachineBasicBlock::iterator I = MBBI; ++ for (unsigned i = 0; i < MFI.getCalleeSavedInfo().size(); ++i) ++ --I; + +- // Return the FirstSPAdjustAmount if the StackSize can not fit in a signed +- // 12-bit and there exists a callee-saved register needing to be pushed. +- if (!isInt<12>(MFI.getStackSize())) { +- // FirstSPAdjustAmount is chosen as (2048 - StackAlign) because 2048 will +- // cause sp = sp + 2048 in the epilogue to be split into multiple +- // instructions. Offsets smaller than 2048 can fit in a single load/store +- // instruction, and we have to stick with the stack alignment. +- // So (2048 - StackAlign) will satisfy the stack alignment. +- // +- // FIXME: This place may seem odd. When using multiple ADDI instructions to +- // adjust the stack in Prologue, and there are no callee-saved registers, we +- // can take advantage of the logic of split sp ajustment to reduce code +- // changes. +- return CSI.size() > 0 ? 2048 - getStackAlign().value() +- : (IsPrologue ? 2048 : 0); ++ // Insert instructions that restore eh data registers. ++ for (int J = 0; J < 4; ++J) ++ TII.loadRegFromStackSlot(MBB, I, ABI.GetEhDataReg(J), ++ LoongArchFI->getEhDataRegFI(J), RC, &RegInfo, Register()); + } +- return 0; +-} +- +-void LoongArchFrameLowering::determineCalleeSaves(MachineFunction &MF, +- BitVector &SavedRegs, +- RegScavenger *RS) const { +- TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); +- // Unconditionally spill RA and FP only if the function uses a frame +- // pointer. +- if (hasFP(MF)) { +- SavedRegs.set(LoongArch::R1); +- SavedRegs.set(LoongArch::R22); +- } +- // Mark BP as used if function has dedicated base pointer. +- if (hasBP(MF)) +- SavedRegs.set(LoongArchABI::getBPReg()); +-} +- +-// Do not preserve stack space within prologue for outgoing variables if the +-// function contains variable size objects. +-// Let eliminateCallFramePseudoInstr preserve stack space for it. +-bool LoongArchFrameLowering::hasReservedCallFrame( +- const MachineFunction &MF) const { +- return !MF.getFrameInfo().hasVarSizedObjects(); +-} +- +-// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions. +-MachineBasicBlock::iterator +-LoongArchFrameLowering::eliminateCallFramePseudoInstr( +- MachineFunction &MF, MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MI) const { +- Register SPReg = LoongArch::R3; +- DebugLoc DL = MI->getDebugLoc(); +- +- if (!hasReservedCallFrame(MF)) { +- // If space has not been reserved for a call frame, ADJCALLSTACKDOWN and +- // ADJCALLSTACKUP must be converted to instructions manipulating the stack +- // pointer. This is necessary when there is a variable length stack +- // allocation (e.g. alloca), which means it's not possible to allocate +- // space for outgoing arguments from within the function prologue. +- int64_t Amount = MI->getOperand(0).getImm(); +- +- if (Amount != 0) { +- // Ensure the stack remains aligned after adjustment. +- Amount = alignSPAdjust(Amount); +- +- if (MI->getOpcode() == LoongArch::ADJCALLSTACKDOWN) +- Amount = -Amount; + +- adjustReg(MBB, MI, DL, SPReg, SPReg, Amount, MachineInstr::NoFlags); +- } +- } +- +- return MBB.erase(MI); +-} +- +-bool LoongArchFrameLowering::spillCalleeSavedRegisters( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, +- ArrayRef CSI, const TargetRegisterInfo *TRI) const { +- if (CSI.empty()) +- return true; ++ if (FirstSPAdjustAmount) ++ StackSize = FirstSPAdjustAmount; + +- MachineFunction *MF = MBB.getParent(); +- const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo(); +- +- // Insert the spill to the stack frame. +- for (auto &CS : CSI) { +- Register Reg = CS.getReg(); +- // If the register is RA and the return address is taken by method +- // LoongArchTargetLowering::lowerRETURNADDR, don't set kill flag. +- bool IsKill = +- !(Reg == LoongArch::R1 && MF->getFrameInfo().isReturnAddressTaken()); +- const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); +- TII.storeRegToStackSlot(MBB, MI, Reg, IsKill, CS.getFrameIdx(), RC, TRI, +- Register()); +- } ++ if (!StackSize) ++ return; + +- return true; ++ // Final adjust stack. ++ TII.adjustReg(SP, SP, StackSize, MBB, MBBI); + } + +-StackOffset LoongArchFrameLowering::getFrameIndexReference( +- const MachineFunction &MF, int FI, Register &FrameReg) const { ++StackOffset ++LoongArchFrameLowering::getFrameIndexReference(const MachineFunction &MF, ++ int FI, ++ Register &FrameReg) const { + const MachineFrameInfo &MFI = MF.getFrameInfo(); + const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo(); +- auto *LoongArchFI = MF.getInfo(); +- uint64_t StackSize = MFI.getStackSize(); +- uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF); ++ LoongArchABIInfo ABI = STI.getABI(); ++ const auto *LoongArchFI = MF.getInfo(); + + // Callee-saved registers should be referenced relative to the stack + // pointer (positive offset), otherwise use the frame pointer (negative +@@ -488,40 +380,182 @@ StackOffset LoongArchFrameLowering::getFrameIndexReference( + StackOffset Offset = + StackOffset::getFixed(MFI.getObjectOffset(FI) - getOffsetOfLocalArea() + + MFI.getOffsetAdjustment()); ++ uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF); + + if (CSI.size()) { + MinCSFI = CSI[0].getFrameIdx(); + MaxCSFI = CSI[CSI.size() - 1].getFrameIdx(); + } + +- if (FI >= MinCSFI && FI <= MaxCSFI) { +- FrameReg = LoongArch::R3; ++ bool EhDataRegFI = LoongArchFI->isEhDataRegFI(FI); ++ if ((FI >= MinCSFI && FI <= MaxCSFI) || EhDataRegFI) { ++ FrameReg = ABI.GetStackPtr(); ++ + if (FirstSPAdjustAmount) + Offset += StackOffset::getFixed(FirstSPAdjustAmount); + else +- Offset += StackOffset::getFixed(StackSize); ++ Offset += StackOffset::getFixed(MFI.getStackSize()); + } else if (RI->hasStackRealignment(MF) && !MFI.isFixedObjectIndex(FI)) { + // If the stack was realigned, the frame pointer is set in order to allow + // SP to be restored, so we need another base register to record the stack + // after realignment. +- FrameReg = hasBP(MF) ? LoongArchABI::getBPReg() : LoongArch::R3; +- Offset += StackOffset::getFixed(StackSize); ++ FrameReg = hasBP(MF) ? ABI.GetBasePtr() : ABI.GetStackPtr(); ++ Offset += StackOffset::getFixed(MFI.getStackSize()); + } else { + FrameReg = RI->getFrameRegister(MF); + if (hasFP(MF)) + Offset += StackOffset::getFixed(LoongArchFI->getVarArgsSaveSize()); + else +- Offset += StackOffset::getFixed(StackSize); ++ Offset += StackOffset::getFixed(MFI.getStackSize()); + } +- + return Offset; + } + +-bool LoongArchFrameLowering::enableShrinkWrapping( +- const MachineFunction &MF) const { +- // Keep the conventional code flow when not optimizing. +- if (MF.getFunction().hasOptNone()) +- return false; ++bool LoongArchFrameLowering::spillCalleeSavedRegisters( ++ MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, ++ ArrayRef CSI, const TargetRegisterInfo *TRI) const { ++ MachineFunction *MF = MBB.getParent(); ++ const TargetInstrInfo &TII = *STI.getInstrInfo(); ++ ++ for (unsigned i = 0, e = CSI.size(); i != e; ++i) { ++ // Add the callee-saved register as live-in. Do not add if the register is ++ // RA and return address is taken, because it has already been added in ++ // method LoongArchTargetLowering::lowerRETURNADDR. ++ // It's killed at the spill, unless the register is RA and return address ++ // is taken. ++ unsigned Reg = CSI[i].getReg(); ++ bool IsRAAndRetAddrIsTaken = (Reg == LoongArch::RA || Reg == LoongArch::RA_64) ++ && MF->getFrameInfo().isReturnAddressTaken(); ++ if (!IsRAAndRetAddrIsTaken) ++ MBB.addLiveIn(Reg); ++ ++ // Insert the spill to the stack frame. ++ bool IsKill = !IsRAAndRetAddrIsTaken; ++ const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); ++ TII.storeRegToStackSlot(MBB, MI, Reg, IsKill, ++ CSI[i].getFrameIdx(), RC, TRI, Register()); ++ } + + return true; + } ++ ++bool ++LoongArchFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { ++ const MachineFrameInfo &MFI = MF.getFrameInfo(); ++ // Reserve call frame if the size of the maximum call frame fits into 12-bit ++ // immediate field and there are no variable sized objects on the stack. ++ // Make sure the second register scavenger spill slot can be accessed with one ++ // instruction. ++ return isInt<12>(MFI.getMaxCallFrameSize() + getStackAlignment()) && ++ !MFI.hasVarSizedObjects(); ++} ++ ++/// Mark \p Reg and all registers aliasing it in the bitset. ++static void setAliasRegs(MachineFunction &MF, BitVector &SavedRegs, ++ unsigned Reg) { ++ const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); ++ for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) ++ SavedRegs.set(*AI); ++} ++ ++void LoongArchFrameLowering::determineCalleeSaves(MachineFunction &MF, ++ BitVector &SavedRegs, ++ RegScavenger *RS) const { ++ TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); ++ const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); ++ LoongArchFunctionInfo *LoongArchFI = MF.getInfo(); ++ LoongArchABIInfo ABI = STI.getABI(); ++ unsigned FP = ABI.GetFramePtr(); ++ unsigned BP = ABI.IsLP64() ? LoongArch::S7_64 : LoongArch::S7; ++ ++ // Mark $fp as used if function has dedicated frame pointer. ++ if (hasFP(MF)) ++ setAliasRegs(MF, SavedRegs, FP); ++ // Mark $s7 as used if function has dedicated base pointer. ++ if (hasBP(MF)) ++ setAliasRegs(MF, SavedRegs, BP); ++ ++ // Create spill slots for eh data registers if function calls eh_return. ++ if (LoongArchFI->callsEhReturn()) ++ LoongArchFI->createEhDataRegsFI(MF); ++ ++ // Set scavenging frame index if necessary. ++ uint64_t MaxSPOffset = estimateStackSize(MF); ++ ++ // If there is a variable ++ // sized object on the stack, the estimation cannot account for it. ++ if (isIntN(12, MaxSPOffset) && ++ !MF.getFrameInfo().hasVarSizedObjects()) ++ return; ++ ++ const TargetRegisterClass &RC = ++ ABI.ArePtrs64bit() ? LoongArch::GPR64RegClass : LoongArch::GPR32RegClass; ++ int FI = MF.getFrameInfo().CreateStackObject(TRI->getSpillSize(RC), ++ TRI->getSpillAlign(RC), false); ++ RS->addScavengingFrameIndex(FI); ++} ++ ++// hasFP - Return true if the specified function should have a dedicated frame ++// pointer register. This is true if the function has variable sized allocas, ++// if it needs dynamic stack realignment, if frame pointer elimination is ++// disabled, or if the frame address is taken. ++bool LoongArchFrameLowering::hasFP(const MachineFunction &MF) const { ++ const MachineFrameInfo &MFI = MF.getFrameInfo(); ++ const TargetRegisterInfo *TRI = STI.getRegisterInfo(); ++ ++ return MF.getTarget().Options.DisableFramePointerElim(MF) || ++ MFI.hasVarSizedObjects() || MFI.isFrameAddressTaken() || ++ TRI->hasStackRealignment(MF); ++} ++ ++bool LoongArchFrameLowering::hasBP(const MachineFunction &MF) const { ++ const MachineFrameInfo &MFI = MF.getFrameInfo(); ++ const TargetRegisterInfo *TRI = STI.getRegisterInfo(); ++ ++ return MFI.hasVarSizedObjects() && TRI->hasStackRealignment(MF); ++} ++ ++// Estimate the size of the stack, including the incoming arguments. We need to ++// account for register spills, local objects, reserved call frame and incoming ++// arguments. This is required to determine the largest possible positive offset ++// from $sp so that it can be determined if an emergency spill slot for stack ++// addresses is required. ++uint64_t LoongArchFrameLowering:: ++estimateStackSize(const MachineFunction &MF) const { ++ const MachineFrameInfo &MFI = MF.getFrameInfo(); ++ const TargetRegisterInfo &TRI = *STI.getRegisterInfo(); ++ ++ int64_t Size = 0; ++ ++ // Iterate over fixed sized objects which are incoming arguments. ++ for (int I = MFI.getObjectIndexBegin(); I != 0; ++I) ++ if (MFI.getObjectOffset(I) > 0) ++ Size += MFI.getObjectSize(I); ++ ++ // Conservatively assume all callee-saved registers will be saved. ++ for (const MCPhysReg *R = TRI.getCalleeSavedRegs(&MF); *R; ++R) { ++ unsigned RegSize = TRI.getSpillSize(*TRI.getMinimalPhysRegClass(*R)); ++ Size = alignTo(Size + RegSize, RegSize); ++ } ++ ++ // Get the size of the rest of the frame objects and any possible reserved ++ // call frame, accounting for alignment. ++ return Size + MFI.estimateStackSize(MF); ++} ++ ++// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions ++MachineBasicBlock::iterator LoongArchFrameLowering:: ++eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, ++ MachineBasicBlock::iterator I) const { ++ unsigned SP = STI.getABI().IsLP64() ? LoongArch::SP_64 : LoongArch::SP; ++ ++ if (!hasReservedCallFrame(MF)) { ++ int64_t Amount = I->getOperand(0).getImm(); ++ if (I->getOpcode() == LoongArch::ADJCALLSTACKDOWN) ++ Amount = -Amount; ++ ++ STI.getInstrInfo()->adjustReg(SP, SP, Amount, MBB, I); ++ } ++ ++ return MBB.erase(I); ++} +diff --git a/llvm/lib/Target/LoongArch/LoongArchFrameLowering.h b/llvm/lib/Target/LoongArch/LoongArchFrameLowering.h +index 57d2565c3..74aabaeb4 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchFrameLowering.h ++++ b/llvm/lib/Target/LoongArch/LoongArchFrameLowering.h +@@ -1,4 +1,4 @@ +-//=- LoongArchFrameLowering.h - TargetFrameLowering for LoongArch -*- C++ -*--// ++//===-- LoongArchFrameLowering.h - Define frame lowering for LoongArch ----*- C++ -*-===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -6,62 +6,66 @@ + // + //===----------------------------------------------------------------------===// + // +-// This class implements LoongArch-specific bits of TargetFrameLowering class. ++// + // + //===----------------------------------------------------------------------===// + + #ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHFRAMELOWERING_H + #define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHFRAMELOWERING_H + ++#include "LoongArch.h" + #include "llvm/CodeGen/TargetFrameLowering.h" + + namespace llvm { +-class LoongArchSubtarget; ++ class LoongArchSubtarget; + + class LoongArchFrameLowering : public TargetFrameLowering { + const LoongArchSubtarget &STI; + + public: +- explicit LoongArchFrameLowering(const LoongArchSubtarget &STI) +- : TargetFrameLowering(StackGrowsDown, +- /*StackAlignment=*/Align(16), +- /*LocalAreaOffset=*/0), +- STI(STI) {} ++ explicit LoongArchFrameLowering(const LoongArchSubtarget &STI); + ++ /// emitProlog/emitEpilog - These methods insert prolog and epilog code into ++ /// the function. + void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override; + void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; + +- void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, +- RegScavenger *RS) const override; +- +- void processFunctionBeforeFrameFinalized(MachineFunction &MF, +- RegScavenger *RS) const override; ++ StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, ++ Register &FrameReg) const override; + +- bool hasReservedCallFrame(const MachineFunction &MF) const override; +- MachineBasicBlock::iterator +- eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MI) const override; + bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + ArrayRef CSI, + const TargetRegisterInfo *TRI) const override; + +- StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, +- Register &FrameReg) const override; ++ bool hasReservedCallFrame(const MachineFunction &MF) const override; ++ ++ void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, ++ RegScavenger *RS) const override; + + bool hasFP(const MachineFunction &MF) const override; ++ + bool hasBP(const MachineFunction &MF) const; + ++ bool enableShrinkWrapping(const MachineFunction &MF) const override { ++ return true; ++ } ++ ++ MachineBasicBlock::iterator ++ eliminateCallFramePseudoInstr(MachineFunction &MF, ++ MachineBasicBlock &MBB, ++ MachineBasicBlock::iterator I) const override; ++ ++ // Get the first stack adjustment amount for split the SP adjustment. ++ // Return 0 if we don't want to to split the SP adjustment in prologue and ++ // epilogue. + uint64_t getFirstSPAdjustAmount(const MachineFunction &MF, + bool IsPrologue = false) const; + +- bool enableShrinkWrapping(const MachineFunction &MF) const override; +- +-private: +- void determineFrameLayout(MachineFunction &MF) const; +- void adjustReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- const DebugLoc &DL, Register DestReg, Register SrcReg, +- int64_t Val, MachineInstr::MIFlag Flag) const; ++protected: ++ uint64_t estimateStackSize(const MachineFunction &MF) const; + }; +-} // end namespace llvm +-#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHFRAMELOWERING_H ++ ++} // End llvm namespace ++ ++#endif +diff --git a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp +index 726856bda..2643ae194 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp ++++ b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp +@@ -1,4 +1,4 @@ +-//=- LoongArchISelDAGToDAG.cpp - A dag to dag inst selector for LoongArch -===// ++//===-- LoongArchISelDAGToDAG.cpp - A Dag to Dag Inst Selector for LoongArch --------===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -11,319 +11,242 @@ + //===----------------------------------------------------------------------===// + + #include "LoongArchISelDAGToDAG.h" +-#include "LoongArchISelLowering.h" ++#include "LoongArch.h" ++#include "LoongArchMachineFunction.h" ++#include "LoongArchRegisterInfo.h" ++#include "MCTargetDesc/LoongArchAnalyzeImmediate.h" ++#include "MCTargetDesc/LoongArchBaseInfo.h" + #include "MCTargetDesc/LoongArchMCTargetDesc.h" +-#include "MCTargetDesc/LoongArchMatInt.h" +-#include "llvm/Support/KnownBits.h" ++#include "llvm/CodeGen/MachineConstantPool.h" ++#include "llvm/CodeGen/MachineFrameInfo.h" ++#include "llvm/CodeGen/MachineFunction.h" ++#include "llvm/CodeGen/MachineInstrBuilder.h" ++#include "llvm/CodeGen/MachineRegisterInfo.h" ++#include "llvm/CodeGen/SelectionDAGNodes.h" ++#include "llvm/IR/CFG.h" ++#include "llvm/IR/Dominators.h" ++#include "llvm/IR/GlobalValue.h" ++#include "llvm/IR/Instructions.h" ++#include "llvm/IR/Intrinsics.h" ++#include "llvm/IR/IntrinsicsLoongArch.h" ++#include "llvm/IR/Type.h" ++#include "llvm/Support/Debug.h" ++#include "llvm/Support/ErrorHandling.h" + #include "llvm/Support/raw_ostream.h" +- ++#include "llvm/Target/TargetMachine.h" + using namespace llvm; + + #define DEBUG_TYPE "loongarch-isel" +-#define PASS_NAME "LoongArch DAG->DAG Pattern Instruction Selection" +- +-char LoongArchDAGToDAGISel::ID; + +-INITIALIZE_PASS(LoongArchDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false) ++//===----------------------------------------------------------------------===// ++// Instruction Selector Implementation ++//===----------------------------------------------------------------------===// + +-void LoongArchDAGToDAGISel::Select(SDNode *Node) { +- // If we have a custom node, we have already selected. +- if (Node->isMachineOpcode()) { +- LLVM_DEBUG(dbgs() << "== "; Node->dump(CurDAG); dbgs() << "\n"); +- Node->setNodeId(-1); +- return; +- } ++//===----------------------------------------------------------------------===// ++// LoongArchDAGToDAGISel - LoongArch specific code to select LoongArch machine ++// instructions for SelectionDAG operations. ++//===----------------------------------------------------------------------===// + +- // Instruction Selection not handled by the auto-generated tablegen selection +- // should be handled here. +- unsigned Opcode = Node->getOpcode(); +- MVT GRLenVT = Subtarget->getGRLenVT(); +- SDLoc DL(Node); +- MVT VT = Node->getSimpleValueType(0); ++void LoongArchDAGToDAGISel::PostprocessISelDAG() { doPeepholeLoadStoreADDI(); } + +- switch (Opcode) { +- default: +- break; +- case ISD::Constant: { +- int64_t Imm = cast(Node)->getSExtValue(); +- if (Imm == 0 && VT == GRLenVT) { +- SDValue New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, +- LoongArch::R0, GRLenVT); +- ReplaceNode(Node, New.getNode()); +- return; +- } +- SDNode *Result = nullptr; +- SDValue SrcReg = CurDAG->getRegister(LoongArch::R0, GRLenVT); +- // The instructions in the sequence are handled here. +- for (LoongArchMatInt::Inst &Inst : LoongArchMatInt::generateInstSeq(Imm)) { +- SDValue SDImm = CurDAG->getTargetConstant(Inst.Imm, DL, GRLenVT); +- if (Inst.Opc == LoongArch::LU12I_W) +- Result = CurDAG->getMachineNode(LoongArch::LU12I_W, DL, GRLenVT, SDImm); +- else +- Result = CurDAG->getMachineNode(Inst.Opc, DL, GRLenVT, SrcReg, SDImm); +- SrcReg = SDValue(Result, 0); +- } ++void LoongArchDAGToDAGISel::getAnalysisUsage(AnalysisUsage &AU) const { ++ AU.addRequired(); ++ SelectionDAGISel::getAnalysisUsage(AU); ++} + +- ReplaceNode(Node, Result); +- return; +- } +- case ISD::FrameIndex: { +- SDValue Imm = CurDAG->getTargetConstant(0, DL, GRLenVT); +- int FI = cast(Node)->getIndex(); +- SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT); +- unsigned ADDIOp = +- Subtarget->is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W; +- ReplaceNode(Node, CurDAG->getMachineNode(ADDIOp, DL, VT, TFI, Imm)); +- return; +- } +- case ISD::BITCAST: { +- if (VT.is128BitVector() || VT.is256BitVector()) { +- ReplaceUses(SDValue(Node, 0), Node->getOperand(0)); +- CurDAG->RemoveDeadNode(Node); +- return; +- } +- break; +- } +- case ISD::BUILD_VECTOR: { +- // Select appropriate [x]vrepli.[bhwd] instructions for constant splats of +- // 128/256-bit when LSX/LASX is enabled. +- BuildVectorSDNode *BVN = cast(Node); +- APInt SplatValue, SplatUndef; +- unsigned SplatBitSize; +- bool HasAnyUndefs; +- unsigned Op; +- EVT ViaVecTy; +- bool Is128Vec = BVN->getValueType(0).is128BitVector(); +- bool Is256Vec = BVN->getValueType(0).is256BitVector(); ++bool LoongArchDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { ++ Subtarget = &static_cast(MF.getSubtarget()); ++ bool Ret = SelectionDAGISel::runOnMachineFunction(MF); + +- if (!Subtarget->hasExtLSX() || (!Is128Vec && !Is256Vec)) +- break; +- if (!BVN->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, +- HasAnyUndefs, 8)) +- break; ++ return Ret; ++} + +- switch (SplatBitSize) { +- default: +- break; +- case 8: +- Op = Is256Vec ? LoongArch::PseudoXVREPLI_B : LoongArch::PseudoVREPLI_B; +- ViaVecTy = Is256Vec ? MVT::v32i8 : MVT::v16i8; +- break; +- case 16: +- Op = Is256Vec ? LoongArch::PseudoXVREPLI_H : LoongArch::PseudoVREPLI_H; +- ViaVecTy = Is256Vec ? MVT::v16i16 : MVT::v8i16; +- break; +- case 32: +- Op = Is256Vec ? LoongArch::PseudoXVREPLI_W : LoongArch::PseudoVREPLI_W; +- ViaVecTy = Is256Vec ? MVT::v8i32 : MVT::v4i32; +- break; +- case 64: +- Op = Is256Vec ? LoongArch::PseudoXVREPLI_D : LoongArch::PseudoVREPLI_D; +- ViaVecTy = Is256Vec ? MVT::v4i64 : MVT::v2i64; +- break; +- } ++/// Match frameindex ++bool LoongArchDAGToDAGISel::selectAddrFrameIndex(SDValue Addr, SDValue &Base, ++ SDValue &Offset) const { ++ if (FrameIndexSDNode *FIN = dyn_cast(Addr)) { ++ EVT ValTy = Addr.getValueType(); + +- SDNode *Res; +- // If we have a signed 10 bit integer, we can splat it directly. +- if (SplatValue.isSignedIntN(10)) { +- SDValue Imm = CurDAG->getTargetConstant(SplatValue, DL, +- ViaVecTy.getVectorElementType()); +- Res = CurDAG->getMachineNode(Op, DL, ViaVecTy, Imm); +- ReplaceNode(Node, Res); +- return; +- } +- break; +- } ++ Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy); ++ Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), ValTy); ++ return true; + } +- +- // Select the default instruction. +- SelectCode(Node); ++ return false; + } + +-bool LoongArchDAGToDAGISel::SelectInlineAsmMemoryOperand( +- const SDValue &Op, InlineAsm::ConstraintCode ConstraintID, +- std::vector &OutOps) { +- SDValue Base = Op; +- SDValue Offset = +- CurDAG->getTargetConstant(0, SDLoc(Op), Subtarget->getGRLenVT()); +- switch (ConstraintID) { +- default: +- llvm_unreachable("unexpected asm memory constraint"); +- // Reg+Reg addressing. +- case InlineAsm::ConstraintCode::k: +- Base = Op.getOperand(0); +- Offset = Op.getOperand(1); +- break; +- // Reg+simm12 addressing. +- case InlineAsm::ConstraintCode::m: +- if (CurDAG->isBaseWithConstantOffset(Op)) { +- ConstantSDNode *CN = dyn_cast(Op.getOperand(1)); +- if (isIntN(12, CN->getSExtValue())) { +- Base = Op.getOperand(0); +- Offset = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Op), +- Op.getValueType()); +- } +- } +- break; +- // Reg+0 addressing. +- case InlineAsm::ConstraintCode::ZB: +- break; +- // Reg+(simm14<<2) addressing. +- case InlineAsm::ConstraintCode::ZC: +- if (CurDAG->isBaseWithConstantOffset(Op)) { +- ConstantSDNode *CN = dyn_cast(Op.getOperand(1)); +- if (isIntN(16, CN->getSExtValue()) && +- isAligned(Align(4ULL), CN->getZExtValue())) { +- Base = Op.getOperand(0); +- Offset = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Op), +- Op.getValueType()); ++/// Match frameindex+offset and frameindex|offset ++bool LoongArchDAGToDAGISel::selectAddrFrameIndexOffset( ++ SDValue Addr, SDValue &Base, SDValue &Offset, unsigned OffsetBits, ++ unsigned ShiftAmount = 0) const { ++ if (CurDAG->isBaseWithConstantOffset(Addr)) { ++ ConstantSDNode *CN = dyn_cast(Addr.getOperand(1)); ++ if (isIntN(OffsetBits + ShiftAmount, CN->getSExtValue())) { ++ EVT ValTy = Addr.getValueType(); ++ ++ // If the first operand is a FI, get the TargetFI Node ++ if (FrameIndexSDNode *FIN = ++ dyn_cast(Addr.getOperand(0))) ++ Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy); ++ else { ++ Base = Addr.getOperand(0); ++ // If base is a FI, additional offset calculation is done in ++ // eliminateFrameIndex, otherwise we need to check the alignment ++ const Align Alignment(1ULL << ShiftAmount); ++ if (!isAligned(Alignment, CN->getZExtValue())) ++ return false; + } ++ ++ Offset = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), ++ ValTy); ++ return true; + } +- break; + } +- OutOps.push_back(Base); +- OutOps.push_back(Offset); + return false; + } + +-bool LoongArchDAGToDAGISel::SelectBaseAddr(SDValue Addr, SDValue &Base) { +- // If this is FrameIndex, select it directly. Otherwise just let it get +- // selected to a register independently. +- if (auto *FIN = dyn_cast(Addr)) +- Base = +- CurDAG->getTargetFrameIndex(FIN->getIndex(), Subtarget->getGRLenVT()); +- else +- Base = Addr; +- return true; +-} ++/// ComplexPattern used on LoongArchInstrInfo ++/// Used on LoongArch Load/Store instructions ++bool LoongArchDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base, ++ SDValue &Offset) const { ++ // if Address is FI, get the TargetFrameIndex. ++ if (selectAddrFrameIndex(Addr, Base, Offset)) ++ return true; + +-// Fold constant addresses. +-bool LoongArchDAGToDAGISel::SelectAddrConstant(SDValue Addr, SDValue &Base, +- SDValue &Offset) { +- SDLoc DL(Addr); +- MVT VT = Addr.getSimpleValueType(); ++ if (!TM.isPositionIndependent()) { ++ if ((Addr.getOpcode() == ISD::TargetExternalSymbol || ++ Addr.getOpcode() == ISD::TargetGlobalAddress)) ++ return false; ++ } + +- if (!isa(Addr)) +- return false; ++ // Addresses of the form FI+const or FI|const ++ if (selectAddrFrameIndexOffset(Addr, Base, Offset, 12)) ++ return true; + +- // If the constant is a simm12, we can fold the whole constant and use R0 as +- // the base. +- int64_t CVal = cast(Addr)->getSExtValue(); +- if (!isInt<12>(CVal)) +- return false; +- Base = CurDAG->getRegister(LoongArch::R0, VT); +- Offset = CurDAG->getTargetConstant(SignExtend64<12>(CVal), DL, VT); +- return true; ++ return false; + } + +-bool LoongArchDAGToDAGISel::selectNonFIBaseAddr(SDValue Addr, SDValue &Base) { +- // If this is FrameIndex, don't select it. +- if (isa(Addr)) +- return false; ++/// ComplexPattern used on LoongArchInstrInfo ++/// Used on LoongArch Load/Store instructions ++bool LoongArchDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base, ++ SDValue &Offset) const { + Base = Addr; ++ Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), Addr.getValueType()); + return true; + } + +-bool LoongArchDAGToDAGISel::selectShiftMask(SDValue N, unsigned ShiftWidth, +- SDValue &ShAmt) { +- // Shift instructions on LoongArch only read the lower 5 or 6 bits of the +- // shift amount. If there is an AND on the shift amount, we can bypass it if +- // it doesn't affect any of those bits. +- if (N.getOpcode() == ISD::AND && isa(N.getOperand(1))) { +- const APInt &AndMask = N->getConstantOperandAPInt(1); ++bool LoongArchDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base, ++ SDValue &Offset) const { ++ return selectAddrRegImm(Addr, Base, Offset) || ++ selectAddrDefault(Addr, Base, Offset); ++} + +- // Since the max shift amount is a power of 2 we can subtract 1 to make a +- // mask that covers the bits needed to represent all shift amounts. +- assert(isPowerOf2_32(ShiftWidth) && "Unexpected max shift amount!"); +- APInt ShMask(AndMask.getBitWidth(), ShiftWidth - 1); ++bool LoongArchDAGToDAGISel::selectAddrRegImm12(SDValue Addr, SDValue &Base, ++ SDValue &Offset) const { ++ if (selectAddrFrameIndex(Addr, Base, Offset)) ++ return true; + +- if (ShMask.isSubsetOf(AndMask)) { +- ShAmt = N.getOperand(0); +- return true; +- } ++ if (selectAddrFrameIndexOffset(Addr, Base, Offset, 12)) ++ return true; + +- // SimplifyDemandedBits may have optimized the mask so try restoring any +- // bits that are known zero. +- KnownBits Known = CurDAG->computeKnownBits(N->getOperand(0)); +- if (ShMask.isSubsetOf(AndMask | Known.Zero)) { +- ShAmt = N.getOperand(0); +- return true; +- } +- } else if (N.getOpcode() == LoongArchISD::BSTRPICK) { +- // Similar to the above AND, if there is a BSTRPICK on the shift amount, we +- // can bypass it. +- assert(isPowerOf2_32(ShiftWidth) && "Unexpected max shift amount!"); +- assert(isa(N.getOperand(1)) && "Illegal msb operand!"); +- assert(isa(N.getOperand(2)) && "Illegal lsb operand!"); +- uint64_t msb = N.getConstantOperandVal(1), lsb = N.getConstantOperandVal(2); +- if (lsb == 0 && Log2_32(ShiftWidth) <= msb + 1) { +- ShAmt = N.getOperand(0); +- return true; +- } +- } else if (N.getOpcode() == ISD::SUB && +- isa(N.getOperand(0))) { +- uint64_t Imm = N.getConstantOperandVal(0); +- // If we are shifting by N-X where N == 0 mod Size, then just shift by -X to +- // generate a NEG instead of a SUB of a constant. +- if (Imm != 0 && Imm % ShiftWidth == 0) { +- SDLoc DL(N); +- EVT VT = N.getValueType(); +- SDValue Zero = +- CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, LoongArch::R0, VT); +- unsigned NegOpc = VT == MVT::i64 ? LoongArch::SUB_D : LoongArch::SUB_W; +- MachineSDNode *Neg = +- CurDAG->getMachineNode(NegOpc, DL, VT, Zero, N.getOperand(1)); +- ShAmt = SDValue(Neg, 0); +- return true; +- } +- } ++ return false; ++} + +- ShAmt = N; +- return true; ++bool LoongArchDAGToDAGISel::selectIntAddrSImm12(SDValue Addr, SDValue &Base, ++ SDValue &Offset) const { ++ if (selectAddrFrameIndex(Addr, Base, Offset)) ++ return true; ++ ++ if (selectAddrFrameIndexOffset(Addr, Base, Offset, 12)) ++ return true; ++ ++ return selectAddrDefault(Addr, Base, Offset); + } + +-bool LoongArchDAGToDAGISel::selectSExti32(SDValue N, SDValue &Val) { +- if (N.getOpcode() == ISD::SIGN_EXTEND_INREG && +- cast(N.getOperand(1))->getVT() == MVT::i32) { +- Val = N.getOperand(0); ++bool LoongArchDAGToDAGISel::selectIntAddrSImm10Lsl1(SDValue Addr, SDValue &Base, ++ SDValue &Offset) const { ++ if (selectAddrFrameIndex(Addr, Base, Offset)) + return true; +- } +- if (N.getOpcode() == LoongArchISD::BSTRPICK && +- N.getConstantOperandVal(1) < UINT64_C(0X1F) && +- N.getConstantOperandVal(2) == UINT64_C(0)) { +- Val = N; ++ ++ if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10, 1)) + return true; +- } +- MVT VT = N.getSimpleValueType(); +- if (CurDAG->ComputeNumSignBits(N) > (VT.getSizeInBits() - 32)) { +- Val = N; ++ ++ return selectAddrDefault(Addr, Base, Offset); ++} ++ ++bool LoongArchDAGToDAGISel::selectIntAddrSImm10(SDValue Addr, SDValue &Base, ++ SDValue &Offset) const { ++ if (selectAddrFrameIndex(Addr, Base, Offset)) + return true; +- } + +- return false; ++ if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10)) ++ return true; ++ ++ return selectAddrDefault(Addr, Base, Offset); + } + +-bool LoongArchDAGToDAGISel::selectZExti32(SDValue N, SDValue &Val) { +- if (N.getOpcode() == ISD::AND) { +- auto *C = dyn_cast(N.getOperand(1)); +- if (C && C->getZExtValue() == UINT64_C(0xFFFFFFFF)) { +- Val = N.getOperand(0); +- return true; +- } +- } +- MVT VT = N.getSimpleValueType(); +- APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(), 32); +- if (CurDAG->MaskedValueIsZero(N, Mask)) { +- Val = N; ++bool LoongArchDAGToDAGISel::selectIntAddrSImm10Lsl2(SDValue Addr, SDValue &Base, ++ SDValue &Offset) const { ++ if (selectAddrFrameIndex(Addr, Base, Offset)) ++ return true; ++ ++ if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10, 2)) ++ return true; ++ ++ return selectAddrDefault(Addr, Base, Offset); ++} ++ ++bool LoongArchDAGToDAGISel::selectIntAddrSImm11Lsl1(SDValue Addr, SDValue &Base, ++ SDValue &Offset) const { ++ if (selectAddrFrameIndex(Addr, Base, Offset)) ++ return true; ++ ++ if (selectAddrFrameIndexOffset(Addr, Base, Offset, 11, 1)) ++ return true; ++ ++ return selectAddrDefault(Addr, Base, Offset); ++} ++ ++bool LoongArchDAGToDAGISel::selectIntAddrSImm9Lsl3(SDValue Addr, SDValue &Base, ++ SDValue &Offset) const { ++ if (selectAddrFrameIndex(Addr, Base, Offset)) ++ return true; ++ ++ if (selectAddrFrameIndexOffset(Addr, Base, Offset, 9, 3)) ++ return true; ++ ++ return selectAddrDefault(Addr, Base, Offset); ++} ++ ++bool LoongArchDAGToDAGISel::selectIntAddrSImm14Lsl2(SDValue Addr, SDValue &Base, ++ SDValue &Offset) const { ++ if (selectAddrFrameIndex(Addr, Base, Offset)) ++ return true; ++ ++ if (selectAddrFrameIndexOffset(Addr, Base, Offset, 14, 2)) + return true; +- } + + return false; + } + ++bool LoongArchDAGToDAGISel::selectIntAddrSImm10Lsl3(SDValue Addr, SDValue &Base, ++ SDValue &Offset) const { ++ if (selectAddrFrameIndex(Addr, Base, Offset)) ++ return true; ++ ++ if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10, 3)) ++ return true; ++ ++ return selectAddrDefault(Addr, Base, Offset); ++} ++ ++// Select constant vector splats. ++// ++// Returns true and sets Imm if: ++// * LSX is enabled ++// * N is a ISD::BUILD_VECTOR representing a constant splat + bool LoongArchDAGToDAGISel::selectVSplat(SDNode *N, APInt &Imm, + unsigned MinSizeInBits) const { +- if (!Subtarget->hasExtLSX()) ++ if (!(Subtarget->hasLSX() || Subtarget->hasLASX())) + return false; + + BuildVectorSDNode *Node = dyn_cast(N); +@@ -336,7 +259,7 @@ bool LoongArchDAGToDAGISel::selectVSplat(SDNode *N, APInt &Imm, + bool HasAnyUndefs; + + if (!Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs, +- MinSizeInBits, /*IsBigEndian=*/false)) ++ MinSizeInBits)) + return false; + + Imm = SplatValue; +@@ -344,8 +267,25 @@ bool LoongArchDAGToDAGISel::selectVSplat(SDNode *N, APInt &Imm, + return true; + } + +-template +-bool LoongArchDAGToDAGISel::selectVSplatImm(SDValue N, SDValue &SplatVal) { ++// Select constant vector splats. ++// ++// In addition to the requirements of selectVSplat(), this function returns ++// true and sets Imm if: ++// * The splat value is the same width as the elements of the vector ++// * The splat value fits in an integer with the specified signed-ness and ++// width. ++// ++// This function looks through ISD::BITCAST nodes. ++// TODO: This might not be appropriate for big-endian LSX since BITCAST is ++// sometimes a shuffle in big-endian mode. ++// ++// It's worth noting that this function is not used as part of the selection ++// of [v/xv]ldi.[bhwd] since it does not permit using the wrong-typed ++// [v/xv]ldi.[bhwd] instruction to achieve the desired bit pattern. ++// [v/xv]ldi.[bhwd] is selected in LoongArchDAGToDAGISel::selectNode. ++bool LoongArchDAGToDAGISel::selectVSplatCommon(SDValue N, SDValue &Imm, ++ bool Signed, ++ unsigned ImmBitSize) const { + APInt ImmValue; + EVT EltTy = N->getValueType(0).getVectorElementType(); + +@@ -354,14 +294,74 @@ bool LoongArchDAGToDAGISel::selectVSplatImm(SDValue N, SDValue &SplatVal) { + + if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) && + ImmValue.getBitWidth() == EltTy.getSizeInBits()) { +- if (IsSigned && ImmValue.isSignedIntN(ImmBitSize)) { +- SplatVal = CurDAG->getTargetConstant(ImmValue.getSExtValue(), SDLoc(N), +- Subtarget->getGRLenVT()); ++ ++ if ((Signed && ImmValue.isSignedIntN(ImmBitSize)) || ++ (!Signed && ImmValue.isIntN(ImmBitSize))) { ++ Imm = CurDAG->getTargetConstant(ImmValue, SDLoc(N), EltTy); + return true; + } +- if (!IsSigned && ImmValue.isIntN(ImmBitSize)) { +- SplatVal = CurDAG->getTargetConstant(ImmValue.getZExtValue(), SDLoc(N), +- Subtarget->getGRLenVT()); ++ } ++ ++ return false; ++} ++ ++// Select constant vector splats. ++bool LoongArchDAGToDAGISel::selectVSplatUimm1(SDValue N, SDValue &Imm) const { ++ return selectVSplatCommon(N, Imm, false, 1); ++} ++ ++bool LoongArchDAGToDAGISel::selectVSplatUimm2(SDValue N, SDValue &Imm) const { ++ return selectVSplatCommon(N, Imm, false, 2); ++} ++ ++bool LoongArchDAGToDAGISel::selectVSplatUimm3(SDValue N, SDValue &Imm) const { ++ return selectVSplatCommon(N, Imm, false, 3); ++} ++ ++bool LoongArchDAGToDAGISel::selectVSplatUimm4(SDValue N, SDValue &Imm) const { ++ return selectVSplatCommon(N, Imm, false, 4); ++} ++ ++bool LoongArchDAGToDAGISel::selectVSplatUimm5(SDValue N, SDValue &Imm) const { ++ return selectVSplatCommon(N, Imm, false, 5); ++} ++ ++bool LoongArchDAGToDAGISel::selectVSplatUimm6(SDValue N, SDValue &Imm) const { ++ return selectVSplatCommon(N, Imm, false, 6); ++} ++ ++bool LoongArchDAGToDAGISel::selectVSplatUimm8(SDValue N, SDValue &Imm) const { ++ return selectVSplatCommon(N, Imm, false, 8); ++} ++ ++bool LoongArchDAGToDAGISel::selectVSplatSimm5(SDValue N, SDValue &Imm) const { ++ return selectVSplatCommon(N, Imm, true, 5); ++} ++ ++// Select constant vector splats whose value is a power of 2. ++// ++// In addition to the requirements of selectVSplat(), this function returns ++// true and sets Imm if: ++// * The splat value is the same width as the elements of the vector ++// * The splat value is a power of two. ++// ++// This function looks through ISD::BITCAST nodes. ++// TODO: This might not be appropriate for big-endian LSX since BITCAST is ++// sometimes a shuffle in big-endian mode. ++bool LoongArchDAGToDAGISel::selectVSplatUimmPow2(SDValue N, ++ SDValue &Imm) const { ++ APInt ImmValue; ++ EVT EltTy = N->getValueType(0).getVectorElementType(); ++ ++ if (N->getOpcode() == ISD::BITCAST) ++ N = N->getOperand(0); ++ ++ if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) && ++ ImmValue.getBitWidth() == EltTy.getSizeInBits()) { ++ int32_t Log2 = ImmValue.exactLogBase2(); ++ ++ if (Log2 != -1) { ++ Imm = CurDAG->getTargetConstant(Log2, SDLoc(N), EltTy); + return true; + } + } +@@ -370,7 +370,7 @@ bool LoongArchDAGToDAGISel::selectVSplatImm(SDValue N, SDValue &SplatVal) { + } + + bool LoongArchDAGToDAGISel::selectVSplatUimmInvPow2(SDValue N, +- SDValue &SplatImm) const { ++ SDValue &Imm) const { + APInt ImmValue; + EVT EltTy = N->getValueType(0).getVectorElementType(); + +@@ -382,7 +382,7 @@ bool LoongArchDAGToDAGISel::selectVSplatUimmInvPow2(SDValue N, + int32_t Log2 = (~ImmValue).exactLogBase2(); + + if (Log2 != -1) { +- SplatImm = CurDAG->getTargetConstant(Log2, SDLoc(N), EltTy); ++ Imm = CurDAG->getTargetConstant(Log2, SDLoc(N), EltTy); + return true; + } + } +@@ -390,8 +390,18 @@ bool LoongArchDAGToDAGISel::selectVSplatUimmInvPow2(SDValue N, + return false; + } + +-bool LoongArchDAGToDAGISel::selectVSplatUimmPow2(SDValue N, +- SDValue &SplatImm) const { ++// Select constant vector splats whose value only has a consecutive sequence ++// of left-most bits set (e.g. 0b11...1100...00). ++// ++// In addition to the requirements of selectVSplat(), this function returns ++// true and sets Imm if: ++// * The splat value is the same width as the elements of the vector ++// * The splat value is a consecutive sequence of left-most bits. ++// ++// This function looks through ISD::BITCAST nodes. ++// TODO: This might not be appropriate for big-endian LSX since BITCAST is ++// sometimes a shuffle in big-endian mode. ++bool LoongArchDAGToDAGISel::selectVSplatMaskL(SDValue N, SDValue &Imm) const { + APInt ImmValue; + EVT EltTy = N->getValueType(0).getVectorElementType(); + +@@ -400,10 +410,13 @@ bool LoongArchDAGToDAGISel::selectVSplatUimmPow2(SDValue N, + + if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) && + ImmValue.getBitWidth() == EltTy.getSizeInBits()) { +- int32_t Log2 = ImmValue.exactLogBase2(); ++ // Extract the run of set bits starting with bit zero from the bitwise ++ // inverse of ImmValue, and test that the inverse of this is the same ++ // as the original value. ++ if (ImmValue == ~(~ImmValue & ~(~ImmValue + 1))) { + +- if (Log2 != -1) { +- SplatImm = CurDAG->getTargetConstant(Log2, SDLoc(N), EltTy); ++ Imm = CurDAG->getTargetConstant(ImmValue.popcount() - 1, SDLoc(N), ++ EltTy); + return true; + } + } +@@ -411,8 +424,458 @@ bool LoongArchDAGToDAGISel::selectVSplatUimmPow2(SDValue N, + return false; + } + +-// This pass converts a legalized DAG into a LoongArch-specific DAG, ready +-// for instruction scheduling. +-FunctionPass *llvm::createLoongArchISelDag(LoongArchTargetMachine &TM) { +- return new LoongArchDAGToDAGISel(TM); ++// Select constant vector splats whose value only has a consecutive sequence ++// of right-most bits set (e.g. 0b00...0011...11). ++// ++// In addition to the requirements of selectVSplat(), this function returns ++// true and sets Imm if: ++// * The splat value is the same width as the elements of the vector ++// * The splat value is a consecutive sequence of right-most bits. ++// ++// This function looks through ISD::BITCAST nodes. ++// TODO: This might not be appropriate for big-endian LSX since BITCAST is ++// sometimes a shuffle in big-endian mode. ++bool LoongArchDAGToDAGISel::selectVSplatMaskR(SDValue N, SDValue &Imm) const { ++ APInt ImmValue; ++ EVT EltTy = N->getValueType(0).getVectorElementType(); ++ ++ if (N->getOpcode() == ISD::BITCAST) ++ N = N->getOperand(0); ++ ++ if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) && ++ ImmValue.getBitWidth() == EltTy.getSizeInBits()) { ++ // Extract the run of set bits starting with bit zero, and test that the ++ // result is the same as the original value ++ if (ImmValue == (ImmValue & ~(ImmValue + 1))) { ++ Imm = CurDAG->getTargetConstant(ImmValue.popcount() - 1, SDLoc(N), ++ EltTy); ++ return true; ++ } ++ } ++ ++ return false; ++} ++ ++bool LoongArchDAGToDAGISel::trySelect(SDNode *Node) { ++ unsigned Opcode = Node->getOpcode(); ++ SDLoc DL(Node); ++ ++ /// ++ // Instruction Selection not handled by the auto-generated ++ // tablegen selection should be handled here. ++ /// ++ switch(Opcode) { ++ default: break; ++ case ISD::ConstantFP: { ++ ConstantFPSDNode *CN = dyn_cast(Node); ++ if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) { ++ if (Subtarget->is64Bit()) { ++ SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, ++ LoongArch::ZERO_64, MVT::i64); ++ ReplaceNode(Node, ++ CurDAG->getMachineNode(LoongArch::MOVGR2FR_D, DL, MVT::f64, Zero)); ++ } ++ return true; ++ } ++ break; ++ } ++ ++ case ISD::Constant: { ++ const ConstantSDNode *CN = dyn_cast(Node); ++ MVT VT = CN->getSimpleValueType(0); ++ int64_t Imm = CN->getSExtValue(); ++ LoongArchAnalyzeImmediate::InstSeq Seq = ++ LoongArchAnalyzeImmediate::generateInstSeq(Imm, VT == MVT::i64); ++ SDLoc DL(CN); ++ SDNode *Result = nullptr; ++ SDValue SrcReg = CurDAG->getRegister( ++ VT == MVT::i64 ? LoongArch::ZERO_64 : LoongArch::ZERO, VT); ++ ++ // The instructions in the sequence are handled here. ++ for (LoongArchAnalyzeImmediate::Inst &Inst : Seq) { ++ SDValue SDImm = CurDAG->getTargetConstant(Inst.Imm, DL, VT); ++ if (Inst.Opc == LoongArch::LU12I_W || Inst.Opc == LoongArch::LU12I_W32) ++ Result = CurDAG->getMachineNode(Inst.Opc, DL, VT, SDImm); ++ else ++ Result = CurDAG->getMachineNode(Inst.Opc, DL, VT, SrcReg, SDImm); ++ SrcReg = SDValue(Result, 0); ++ } ++ ReplaceNode(Node, Result); ++ return true; ++ } ++ ++ case ISD::BUILD_VECTOR: { ++ // Select appropriate vldi.[bhwd] instructions for constant splats of ++ // 128-bit when LSX is enabled. Select appropriate xvldi.[bhwd] instructions ++ // for constant splats of 256-bit when LASX is enabled. Fixup any register ++ // class mismatches that occur as a result. ++ // ++ // This allows the compiler to use a wider range of immediates than would ++ // otherwise be allowed. If, for example, v4i32 could only use [v/xv]ldi.h ++ // then it would not be possible to load { 0x01010101, 0x01010101, ++ // 0x01010101, 0x01010101 } without using a constant pool. This would be ++ // sub-optimal when // '[v/xv]ldi.b vd, 1' is capable of producing that ++ // bit-pattern in the same set/ of registers. Similarly, [v/xv]ldi.h isn't ++ // capable of producing { 0x00000000, 0x00000001, 0x00000000, 0x00000001 } ++ // but '[v/xv]ldi.d vd, 1' can. ++ ++ const LoongArchABIInfo &ABI = ++ static_cast(TM).getABI(); ++ ++ BuildVectorSDNode *BVN = cast(Node); ++ APInt SplatValue, SplatUndef; ++ unsigned SplatBitSize; ++ bool HasAnyUndefs; ++ unsigned LdiOp; ++ EVT ResVecTy = BVN->getValueType(0); ++ EVT ViaVecTy; ++ ++ if ((!Subtarget->hasLSX() || !BVN->getValueType(0).is128BitVector()) && ++ (!Subtarget->hasLASX() || !BVN->getValueType(0).is256BitVector())) ++ return false; ++ ++ if (!BVN->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, ++ HasAnyUndefs, 8)) ++ return false; ++ ++ bool IsLASX256 = BVN->getValueType(0).is256BitVector(); ++ ++ switch (SplatBitSize) { ++ default: ++ return false; ++ case 8: ++ LdiOp = IsLASX256 ? LoongArch::XVLDI_B : LoongArch::VLDI_B; ++ ViaVecTy = IsLASX256 ? MVT::v32i8 : MVT::v16i8; ++ break; ++ case 16: ++ LdiOp = IsLASX256 ? LoongArch::XVLDI_H : LoongArch::VLDI_H; ++ ViaVecTy = IsLASX256 ? MVT::v16i16 : MVT::v8i16; ++ break; ++ case 32: ++ LdiOp = IsLASX256 ? LoongArch::XVLDI_W : LoongArch::VLDI_W; ++ ViaVecTy = IsLASX256 ? MVT::v8i32 : MVT::v4i32; ++ break; ++ case 64: ++ LdiOp = IsLASX256 ? LoongArch::XVLDI_D : LoongArch::VLDI_D; ++ ViaVecTy = IsLASX256 ? MVT::v4i64 : MVT::v2i64; ++ break; ++ } ++ ++ SDNode *Res; ++ ++ // If we have a signed 13 bit integer, we can splat it directly. ++ // ++ // If we have something bigger we can synthesize the value into a GPR and ++ // splat from there. ++ if (SplatValue.isSignedIntN(10)) { ++ SDValue Imm = CurDAG->getTargetConstant(SplatValue, DL, ++ ViaVecTy.getVectorElementType()); ++ ++ Res = CurDAG->getMachineNode(LdiOp, DL, ViaVecTy, Imm); ++ } else if (SplatValue.isSignedIntN(12)) { ++ bool Is32BitSplat = SplatBitSize < 64 ? true : false; ++ const unsigned ADDIOp = ++ Is32BitSplat ? LoongArch::ADDI_W : LoongArch::ADDI_D; ++ const MVT SplatMVT = Is32BitSplat ? MVT::i32 : MVT::i64; ++ SDValue ZeroVal = CurDAG->getRegister( ++ Is32BitSplat ? LoongArch::ZERO : LoongArch::ZERO_64, SplatMVT); ++ ++ const unsigned FILLOp = ++ (SplatBitSize == 16) ++ ? (IsLASX256 ? LoongArch::XVREPLGR2VR_H : LoongArch::VREPLGR2VR_H) ++ : (SplatBitSize == 32 ++ ? (IsLASX256 ? LoongArch::XVREPLGR2VR_W ++ : LoongArch::VREPLGR2VR_W) ++ : (SplatBitSize == 64 ++ ? (IsLASX256 ? LoongArch::XVREPLGR2VR_D ++ : LoongArch::VREPLGR2VR_D) ++ : 0)); ++ ++ assert(FILLOp != 0 && "Unknown FILL Op for splat synthesis!"); ++ ++ short Lo = SplatValue.getLoBits(12).getSExtValue(); ++ SDValue LoVal = CurDAG->getTargetConstant(Lo, DL, SplatMVT); ++ ++ Res = CurDAG->getMachineNode(ADDIOp, DL, SplatMVT, ZeroVal, LoVal); ++ Res = CurDAG->getMachineNode(FILLOp, DL, ViaVecTy, SDValue(Res, 0)); ++ } else if (SplatValue.isSignedIntN(16) && SplatBitSize == 16) { ++ const unsigned Lo = SplatValue.getLoBits(12).getZExtValue(); ++ const unsigned Hi = SplatValue.lshr(12).getLoBits(4).getZExtValue(); ++ SDValue ZeroVal = CurDAG->getRegister(LoongArch::ZERO, MVT::i32); ++ ++ SDValue LoVal = CurDAG->getTargetConstant(Lo, DL, MVT::i32); ++ SDValue HiVal = CurDAG->getTargetConstant(Hi, DL, MVT::i32); ++ if (Hi) ++ Res = CurDAG->getMachineNode(LoongArch::LU12I_W32, DL, MVT::i32, HiVal); ++ ++ if (Lo) ++ Res = CurDAG->getMachineNode(LoongArch::ORI32, DL, MVT::i32, ++ Hi ? SDValue(Res, 0) : ZeroVal, LoVal); ++ ++ assert((Hi || Lo) && "Zero case reached 32 bit case splat synthesis!"); ++ const unsigned FILLOp = ++ IsLASX256 ? LoongArch::XVREPLGR2VR_H : LoongArch::VREPLGR2VR_H; ++ EVT FILLTy = IsLASX256 ? MVT::v16i16 : MVT::v8i16; ++ Res = CurDAG->getMachineNode(FILLOp, DL, FILLTy, SDValue(Res, 0)); ++ } else if (SplatValue.isSignedIntN(32) && SplatBitSize == 32) { ++ // Only handle the cases where the splat size agrees with the size ++ // of the SplatValue here. ++ const unsigned Lo = SplatValue.getLoBits(12).getZExtValue(); ++ const unsigned Hi = SplatValue.lshr(12).getLoBits(20).getZExtValue(); ++ SDValue ZeroVal = CurDAG->getRegister(LoongArch::ZERO, MVT::i32); ++ ++ SDValue LoVal = CurDAG->getTargetConstant(Lo, DL, MVT::i32); ++ SDValue HiVal = CurDAG->getTargetConstant(Hi, DL, MVT::i32); ++ if (Hi) ++ Res = CurDAG->getMachineNode(LoongArch::LU12I_W32, DL, MVT::i32, HiVal); ++ ++ if (Lo) ++ Res = CurDAG->getMachineNode(LoongArch::ORI32, DL, MVT::i32, ++ Hi ? SDValue(Res, 0) : ZeroVal, LoVal); ++ ++ assert((Hi || Lo) && "Zero case reached 32 bit case splat synthesis!"); ++ const unsigned FILLOp = ++ IsLASX256 ? LoongArch::XVREPLGR2VR_W : LoongArch::VREPLGR2VR_W; ++ EVT FILLTy = IsLASX256 ? MVT::v8i32 : MVT::v4i32; ++ Res = CurDAG->getMachineNode(FILLOp, DL, FILLTy, SDValue(Res, 0)); ++ ++ } else if ((SplatValue.isSignedIntN(32) && SplatBitSize == 64 && ++ ABI.IsLP64()) || ++ (SplatValue.isSignedIntN(64))) { ++ ++ int64_t Imm = SplatValue.getSExtValue(); ++ LoongArchAnalyzeImmediate::InstSeq Seq = ++ LoongArchAnalyzeImmediate::generateInstSeq(Imm, true); ++ SDValue SrcReg = CurDAG->getRegister(LoongArch::ZERO_64, MVT::i64); ++ ++ for (LoongArchAnalyzeImmediate::Inst &Inst : Seq) { ++ SDValue SDImm = CurDAG->getTargetConstant(Inst.Imm, DL, MVT::i64); ++ if (Inst.Opc == LoongArch::LU12I_W || Inst.Opc == LoongArch::LU12I_W32) ++ Res = CurDAG->getMachineNode(Inst.Opc, DL, MVT::i64, SDImm); ++ else ++ Res = CurDAG->getMachineNode(Inst.Opc, DL, MVT::i64, SrcReg, SDImm); ++ SrcReg = SDValue(Res, 0); ++ } ++ ++ const unsigned FILLOp = ++ IsLASX256 ? LoongArch::XVREPLGR2VR_D : LoongArch::VREPLGR2VR_D; ++ EVT FILLTy = IsLASX256 ? MVT::v4i64 : MVT::v2i64; ++ Res = CurDAG->getMachineNode(FILLOp, DL, FILLTy, SDValue(Res, 0)); ++ ++ } else ++ return false; ++ ++ if (ResVecTy != ViaVecTy) { ++ // If LdiOp is writing to a different register class to ResVecTy, then ++ // fix it up here. This COPY_TO_REGCLASS should never cause a move.v ++ // since the source and destination register sets contain the same ++ // registers. ++ const TargetLowering *TLI = getTargetLowering(); ++ MVT ResVecTySimple = ResVecTy.getSimpleVT(); ++ const TargetRegisterClass *RC = TLI->getRegClassFor(ResVecTySimple); ++ Res = CurDAG->getMachineNode( ++ LoongArch::COPY_TO_REGCLASS, DL, ResVecTy, SDValue(Res, 0), ++ CurDAG->getTargetConstant(RC->getID(), DL, MVT::i32)); ++ } ++ ++ ReplaceNode(Node, Res); ++ return true; ++ } ++ } ++ ++ return false; ++} ++ ++/// Select instructions not customized! Used for ++/// expanded, promoted and normal instructions ++void LoongArchDAGToDAGISel::Select(SDNode *Node) { ++ // If we have a custom node, we already have selected! ++ if (Node->isMachineOpcode()) { ++ LLVM_DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n"); ++ Node->setNodeId(-1); ++ return; ++ } ++ ++ // See if subclasses can handle this node. ++ if (trySelect(Node)) ++ return; ++ ++ // Select the default instruction ++ SelectCode(Node); ++} ++ ++bool LoongArchDAGToDAGISel:: ++SelectInlineAsmMemoryOperand(const SDValue &Op, ++ InlineAsm::ConstraintCode ConstraintID, ++ std::vector &OutOps) { ++ SDValue Base, Offset; ++ ++ switch(ConstraintID) { ++ default: ++ llvm_unreachable("Unexpected asm memory constraint"); ++ // All memory constraints can at least accept raw pointers. ++ case InlineAsm::ConstraintCode::i: ++ OutOps.push_back(Op); ++ OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32)); ++ return false; ++ case InlineAsm::ConstraintCode::m: ++ if (selectAddrRegImm12(Op, Base, Offset)) { ++ OutOps.push_back(Base); ++ OutOps.push_back(Offset); ++ return false; ++ } ++ OutOps.push_back(Op); ++ OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32)); ++ return false; ++ case InlineAsm::ConstraintCode::R: ++ if (selectAddrRegImm12(Op, Base, Offset)) { ++ OutOps.push_back(Base); ++ OutOps.push_back(Offset); ++ return false; ++ } ++ OutOps.push_back(Op); ++ OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32)); ++ return false; ++ case InlineAsm::ConstraintCode::ZC: ++ if (selectIntAddrSImm14Lsl2(Op, Base, Offset)) { ++ OutOps.push_back(Base); ++ OutOps.push_back(Offset); ++ return false; ++ } ++ OutOps.push_back(Op); ++ OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32)); ++ return false; ++ case InlineAsm::ConstraintCode::ZB: ++ OutOps.push_back(Op); ++ OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32)); ++ return false; ++ } ++ return true; ++} ++ ++// This optimisation is ported from RISCV. ++// Merge an ADDI into the offset of a load/store instruction where possible. ++// (load (addi base, off1), off2) -> (load base, off1+off2) ++// (store val, (addi base, off1), off2) -> (store val, base, off1+off2) ++// This is possible when off1+off2 fits a 12-bit immediate. ++void LoongArchDAGToDAGISel::doPeepholeLoadStoreADDI() { ++ SelectionDAG::allnodes_iterator Position(CurDAG->getRoot().getNode()); ++ ++Position; ++ ++ while (Position != CurDAG->allnodes_begin()) { ++ SDNode *N = &*--Position; ++ // Skip dead nodes and any non-machine opcodes. ++ if (N->use_empty() || !N->isMachineOpcode()) ++ continue; ++ ++ int OffsetOpIdx; ++ int BaseOpIdx; ++ ++ // TODO: handle more instructions. ++ switch (N->getMachineOpcode()) { ++ default: ++ continue; ++ case LoongArch::LD_B: ++ case LoongArch::LD_B32: ++ case LoongArch::LD_BU: ++ case LoongArch::LD_BU32: ++ case LoongArch::LD_H: ++ case LoongArch::LD_H32: ++ case LoongArch::LD_HU: ++ case LoongArch::LD_HU32: ++ case LoongArch::LD_W: ++ case LoongArch::LD_W32: ++ case LoongArch::LD_WU: ++ case LoongArch::LD_D: ++ BaseOpIdx = 0; ++ OffsetOpIdx = 1; ++ break; ++ case LoongArch::ST_B: ++ case LoongArch::ST_B32: ++ case LoongArch::ST_H: ++ case LoongArch::ST_H32: ++ case LoongArch::ST_W: ++ case LoongArch::ST_W32: ++ case LoongArch::ST_D: ++ BaseOpIdx = 1; ++ OffsetOpIdx = 2; ++ break; ++ } ++ ++ if (!isa(N->getOperand(OffsetOpIdx))) ++ continue; ++ ++ SDValue Base = N->getOperand(BaseOpIdx); ++ ++ // If the base is an ADDI, we can merge it in to the load/store. ++ // TODO: handle more instructions, i.e. ADDI_W. ++ if (!Base.isMachineOpcode() || Base.getMachineOpcode() != LoongArch::ADDI_D) ++ continue; ++ ++ SDValue ImmOperand = Base.getOperand(1); ++ uint64_t Offset2 = N->getConstantOperandVal(OffsetOpIdx); ++ ++ if (auto *Const = dyn_cast(ImmOperand)) { ++ int64_t Offset1 = Const->getSExtValue(); ++ int64_t CombinedOffset = Offset1 + Offset2; ++ if (!isInt<12>(CombinedOffset)) ++ continue; ++ ImmOperand = CurDAG->getTargetConstant(CombinedOffset, SDLoc(ImmOperand), ++ ImmOperand.getValueType()); ++ // TODO: handle below cases. ++#if 0 ++ } else if (auto *GA = dyn_cast(ImmOperand)) { ++ // If the off1 in (addi base, off1) is a global variable's address (its ++ // low part, really), then we can rely on the alignment of that variable ++ // to provide a margin of safety before off1 can overflow the 12 bits. ++ // Check if off2 falls within that margin; if so off1+off2 can't overflow. ++ const DataLayout &DL = CurDAG->getDataLayout(); ++ Align Alignment = GA->getGlobal()->getPointerAlignment(DL); ++ if (Offset2 != 0 && Alignment <= Offset2) ++ continue; ++ int64_t Offset1 = GA->getOffset(); ++ int64_t CombinedOffset = Offset1 + Offset2; ++ ImmOperand = CurDAG->getTargetGlobalAddress( ++ GA->getGlobal(), SDLoc(ImmOperand), ImmOperand.getValueType(), ++ CombinedOffset, GA->getTargetFlags()); ++ } else if (auto *CP = dyn_cast(ImmOperand)) { ++ // Ditto. ++ Align Alignment = CP->getAlign(); ++ if (Offset2 != 0 && Alignment <= Offset2) ++ continue; ++ int64_t Offset1 = CP->getOffset(); ++ int64_t CombinedOffset = Offset1 + Offset2; ++ ImmOperand = CurDAG->getTargetConstantPool( ++ CP->getConstVal(), ImmOperand.getValueType(), CP->getAlign(), ++ CombinedOffset, CP->getTargetFlags()); ++#endif ++ } else { ++ continue; ++ } ++ ++ LLVM_DEBUG(dbgs() << "Folding add-immediate into mem-op:\nBase: "); ++ LLVM_DEBUG(Base->dump(CurDAG)); ++ LLVM_DEBUG(dbgs() << "\nN: "); ++ LLVM_DEBUG(N->dump(CurDAG)); ++ LLVM_DEBUG(dbgs() << "\n"); ++ ++ // Modify the offset operand of the load/store. ++ if (BaseOpIdx == 0) // Load ++ CurDAG->UpdateNodeOperands(N, Base.getOperand(0), ImmOperand, ++ N->getOperand(2)); ++ else // Store ++ CurDAG->UpdateNodeOperands(N, N->getOperand(0), Base.getOperand(0), ++ ImmOperand, N->getOperand(3)); ++ ++ // The add-immediate may now be dead, in which case remove it. ++ if (Base.getNode()->use_empty()) ++ CurDAG->RemoveDeadNode(Base.getNode()); ++ } ++} ++ ++char LoongArchDAGToDAGISel::ID = 0; ++ ++FunctionPass *llvm::createLoongArchISelDag(LoongArchTargetMachine &TM, ++ CodeGenOptLevel OptLevel) { ++ return new LoongArchDAGToDAGISel(TM, OptLevel); + } +diff --git a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h +index 48a178bfe..aa3d00233 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h ++++ b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h +@@ -1,4 +1,4 @@ +-//=- LoongArchISelDAGToDAG.h - A dag to dag inst selector for LoongArch ---===// ++//===---- LoongArchISelDAGToDAG.h - A Dag to Dag Inst Selector for LoongArch --------===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -14,61 +14,140 @@ + #define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELDAGTODAG_H + + #include "LoongArch.h" ++#include "LoongArchSubtarget.h" + #include "LoongArchTargetMachine.h" + #include "llvm/CodeGen/SelectionDAGISel.h" + +-// LoongArch-specific code to select LoongArch machine instructions for +-// SelectionDAG operations. ++//===----------------------------------------------------------------------===// ++// Instruction Selector Implementation ++//===----------------------------------------------------------------------===// ++ ++//===----------------------------------------------------------------------===// ++// LoongArchDAGToDAGISel - LoongArch specific code to select LoongArch machine ++// instructions for SelectionDAG operations. ++//===----------------------------------------------------------------------===// + namespace llvm { +-class LoongArchDAGToDAGISel : public SelectionDAGISel { +- const LoongArchSubtarget *Subtarget = nullptr; + ++class LoongArchDAGToDAGISel : public SelectionDAGISel { + public: + static char ID; + +- LoongArchDAGToDAGISel() = delete; +- +- explicit LoongArchDAGToDAGISel(LoongArchTargetMachine &TM) +- : SelectionDAGISel(ID, TM) {} ++ explicit LoongArchDAGToDAGISel(LoongArchTargetMachine &TM, CodeGenOptLevel OL) ++ : SelectionDAGISel(ID, TM, OL), Subtarget(nullptr) {} + +- bool runOnMachineFunction(MachineFunction &MF) override { +- Subtarget = &MF.getSubtarget(); +- return SelectionDAGISel::runOnMachineFunction(MF); ++ // Pass Name ++ StringRef getPassName() const override { ++ return "LoongArch DAG->DAG Pattern Instruction Selection"; + } + +- void Select(SDNode *Node) override; ++ bool runOnMachineFunction(MachineFunction &MF) override; + +- bool SelectInlineAsmMemoryOperand(const SDValue &Op, +- InlineAsm::ConstraintCode ConstraintID, +- std::vector &OutOps) override; ++ void PostprocessISelDAG() override; + +- bool SelectBaseAddr(SDValue Addr, SDValue &Base); +- bool SelectAddrConstant(SDValue Addr, SDValue &Base, SDValue &Offset); +- bool selectNonFIBaseAddr(SDValue Addr, SDValue &Base); ++ void getAnalysisUsage(AnalysisUsage &AU) const override; + +- bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt); +- bool selectShiftMaskGRLen(SDValue N, SDValue &ShAmt) { +- return selectShiftMask(N, Subtarget->getGRLen(), ShAmt); +- } +- bool selectShiftMask32(SDValue N, SDValue &ShAmt) { +- return selectShiftMask(N, 32, ShAmt); +- } ++private: ++ /// Keep a pointer to the LoongArchSubtarget around so that we can make the right ++ /// decision when generating code for different targets. ++ const LoongArchSubtarget *Subtarget; ++ // Include the pieces autogenerated from the target description. ++ #include "LoongArchGenDAGISel.inc" + +- bool selectSExti32(SDValue N, SDValue &Val); +- bool selectZExti32(SDValue N, SDValue &Val); ++ void doPeepholeLoadStoreADDI(); + +- bool selectVSplat(SDNode *N, APInt &Imm, unsigned MinSizeInBits) const; ++ bool selectAddrFrameIndex(SDValue Addr, SDValue &Base, SDValue &Offset) const; ++ ++ bool selectAddrFrameIndexOffset(SDValue Addr, SDValue &Base, SDValue &Offset, ++ unsigned OffsetBits, ++ unsigned ShiftAmount) const; ++ ++ // Complex Pattern. ++ /// (reg + imm). ++ bool selectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset) const; + +- template +- bool selectVSplatImm(SDValue N, SDValue &SplatVal); ++ /// Fall back on this function if all else fails. ++ bool selectAddrDefault(SDValue Addr, SDValue &Base, SDValue &Offset) const; + +- bool selectVSplatUimmInvPow2(SDValue N, SDValue &SplatImm) const; +- bool selectVSplatUimmPow2(SDValue N, SDValue &SplatImm) const; ++ /// Match integer address pattern. ++ bool selectIntAddr(SDValue Addr, SDValue &Base, SDValue &Offset) const; + +-// Include the pieces autogenerated from the target description. +-#include "LoongArchGenDAGISel.inc" ++ bool selectAddrRegImm12(SDValue Addr, SDValue &Base, ++ SDValue &Offset) const; ++ ++ /// Match addr+simm12 and addr ++ bool selectIntAddrSImm12(SDValue Addr, SDValue &Base, ++ SDValue &Offset) const; ++ ++ bool selectIntAddrSImm10(SDValue Addr, SDValue &Base, ++ SDValue &Offset) const; ++ ++ bool selectIntAddrSImm10Lsl1(SDValue Addr, SDValue &Base, ++ SDValue &Offset) const; ++ ++ bool selectIntAddrSImm10Lsl2(SDValue Addr, SDValue &Base, ++ SDValue &Offset) const; ++ ++ bool selectIntAddrSImm9Lsl3(SDValue Addr, SDValue &Base, ++ SDValue &Offset) const; ++ ++ bool selectIntAddrSImm11Lsl1(SDValue Addr, SDValue &Base, ++ SDValue &Offset) const; ++ ++ bool selectIntAddrSImm14Lsl2(SDValue Addr, SDValue &Base, ++ SDValue &Offset) const; ++ ++ bool selectIntAddrSImm10Lsl3(SDValue Addr, SDValue &Base, ++ SDValue &Offset) const; ++ ++ /// Select constant vector splats. ++ bool selectVSplat(SDNode *N, APInt &Imm, unsigned MinSizeInBits) const; ++ /// Select constant vector splats whose value fits in a given integer. ++ bool selectVSplatCommon(SDValue N, SDValue &Imm, bool Signed, ++ unsigned ImmBitSize) const; ++ /// Select constant vector splats whose value fits in a uimm1. ++ bool selectVSplatUimm1(SDValue N, SDValue &Imm) const; ++ /// Select constant vector splats whose value fits in a uimm2. ++ bool selectVSplatUimm2(SDValue N, SDValue &Imm) const; ++ /// Select constant vector splats whose value fits in a uimm3. ++ bool selectVSplatUimm3(SDValue N, SDValue &Imm) const; ++ /// Select constant vector splats whose value fits in a uimm4. ++ bool selectVSplatUimm4(SDValue N, SDValue &Imm) const; ++ /// Select constant vector splats whose value fits in a uimm5. ++ bool selectVSplatUimm5(SDValue N, SDValue &Imm) const; ++ /// Select constant vector splats whose value fits in a uimm6. ++ bool selectVSplatUimm6(SDValue N, SDValue &Imm) const; ++ /// Select constant vector splats whose value fits in a uimm8. ++ bool selectVSplatUimm8(SDValue N, SDValue &Imm) const; ++ /// Select constant vector splats whose value fits in a simm5. ++ bool selectVSplatSimm5(SDValue N, SDValue &Imm) const; ++ /// Select constant vector splats whose value is a power of 2. ++ bool selectVSplatUimmPow2(SDValue N, SDValue &Imm) const; ++ /// Select constant vector splats whose value is the inverse of a ++ /// power of 2. ++ bool selectVSplatUimmInvPow2(SDValue N, SDValue &Imm) const; ++ /// Select constant vector splats whose value is a run of set bits ++ /// ending at the most significant bit ++ bool selectVSplatMaskL(SDValue N, SDValue &Imm) const; ++ /// Select constant vector splats whose value is a run of set bits ++ /// starting at bit zero. ++ bool selectVSplatMaskR(SDValue N, SDValue &Imm) const; ++ ++ void Select(SDNode *N) override; ++ ++ bool trySelect(SDNode *Node); ++ ++ // getImm - Return a target constant with the specified value. ++ inline SDValue getImm(const SDNode *Node, uint64_t Imm) { ++ return CurDAG->getTargetConstant(Imm, SDLoc(Node), Node->getValueType(0)); ++ } ++ ++ bool SelectInlineAsmMemoryOperand(const SDValue &Op, ++ InlineAsm::ConstraintCode ConstraintID, ++ std::vector &OutOps) override; + }; + +-} // end namespace llvm ++FunctionPass *createLoongArchISelDag(LoongArchTargetMachine &TM, ++ CodeGenOptLevel OptLevel); ++} + +-#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELDAGTODAG_H ++#endif +diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +index 907aae13d..9b216a655 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp ++++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +@@ -1,4 +1,4 @@ +-//=- LoongArchISelLowering.cpp - LoongArch DAG Lowering Implementation ---===// ++//===- LoongArchISelLowering.cpp - LoongArch DAG Lowering Implementation ------------===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -6,4944 +6,8314 @@ + // + //===----------------------------------------------------------------------===// + // +-// This file defines the interfaces that LoongArch uses to lower LLVM code into +-// a selection DAG. ++// This file defines the interfaces that LoongArch uses to lower LLVM code into a ++// selection DAG. + // + //===----------------------------------------------------------------------===// + + #include "LoongArchISelLowering.h" +-#include "LoongArch.h" +-#include "LoongArchMachineFunctionInfo.h" ++#include "MCTargetDesc/LoongArchBaseInfo.h" ++#include "MCTargetDesc/LoongArchInstPrinter.h" ++#include "MCTargetDesc/LoongArchMCTargetDesc.h" ++#include "LoongArchCCState.h" ++#include "LoongArchInstrInfo.h" ++#include "LoongArchMachineFunction.h" + #include "LoongArchRegisterInfo.h" + #include "LoongArchSubtarget.h" + #include "LoongArchTargetMachine.h" +-#include "MCTargetDesc/LoongArchBaseInfo.h" +-#include "MCTargetDesc/LoongArchMCTargetDesc.h" ++#include "LoongArchTargetObjectFile.h" ++#include "llvm/ADT/APFloat.h" ++#include "llvm/ADT/APInt.h" ++#include "llvm/ADT/ArrayRef.h" ++#include "llvm/ADT/STLExtras.h" ++#include "llvm/ADT/SmallVector.h" + #include "llvm/ADT/Statistic.h" +-#include "llvm/ADT/StringExtras.h" ++#include "llvm/ADT/StringRef.h" ++#include "llvm/ADT/StringSwitch.h" ++#include "llvm/CodeGen/CallingConvLower.h" ++#include "llvm/CodeGen/FunctionLoweringInfo.h" + #include "llvm/CodeGen/ISDOpcodes.h" ++#include "llvm/CodeGen/MachineBasicBlock.h" ++#include "llvm/CodeGen/MachineFrameInfo.h" ++#include "llvm/CodeGen/MachineFunction.h" ++#include "llvm/CodeGen/MachineInstr.h" ++#include "llvm/CodeGen/MachineInstrBuilder.h" ++#include "llvm/CodeGen/MachineJumpTableInfo.h" ++#include "llvm/CodeGen/MachineMemOperand.h" ++#include "llvm/CodeGen/MachineOperand.h" ++#include "llvm/CodeGen/MachineRegisterInfo.h" ++#include "llvm/CodeGen/MachineValueType.h" + #include "llvm/CodeGen/RuntimeLibcalls.h" ++#include "llvm/CodeGen/SelectionDAG.h" + #include "llvm/CodeGen/SelectionDAGNodes.h" +-#include "llvm/IR/IRBuilder.h" ++#include "llvm/CodeGen/TargetFrameLowering.h" ++#include "llvm/CodeGen/TargetInstrInfo.h" ++#include "llvm/CodeGen/TargetRegisterInfo.h" ++#include "llvm/CodeGen/TargetSubtargetInfo.h" ++#include "llvm/CodeGen/ValueTypes.h" ++#include "llvm/IR/CallingConv.h" ++#include "llvm/IR/Constants.h" ++#include "llvm/IR/DataLayout.h" ++#include "llvm/IR/DebugLoc.h" ++#include "llvm/IR/DerivedTypes.h" ++#include "llvm/IR/Function.h" ++#include "llvm/IR/GlobalValue.h" ++#include "llvm/IR/Intrinsics.h" + #include "llvm/IR/IntrinsicsLoongArch.h" ++#include "llvm/IR/Type.h" ++#include "llvm/IR/Value.h" ++#include "llvm/MC/MCContext.h" ++#include "llvm/MC/MCRegisterInfo.h" ++#include "llvm/Support/Casting.h" + #include "llvm/Support/CodeGen.h" ++#include "llvm/Support/CommandLine.h" ++#include "llvm/Support/Compiler.h" + #include "llvm/Support/Debug.h" + #include "llvm/Support/ErrorHandling.h" +-#include "llvm/Support/KnownBits.h" + #include "llvm/Support/MathExtras.h" ++#include "llvm/Support/raw_ostream.h" ++#include "llvm/Target/TargetMachine.h" ++#include "llvm/Target/TargetOptions.h" ++#include "llvm/TargetParser/Triple.h" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + + using namespace llvm; + +-#define DEBUG_TYPE "loongarch-isel-lowering" ++#define DEBUG_TYPE "loongarch-lower" + + STATISTIC(NumTailCalls, "Number of tail calls"); + +-static cl::opt ZeroDivCheck("loongarch-check-zero-division", cl::Hidden, +- cl::desc("Trap on integer division by zero."), +- cl::init(false)); +- +-LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM, +- const LoongArchSubtarget &STI) +- : TargetLowering(TM), Subtarget(STI) { +- +- MVT GRLenVT = Subtarget.getGRLenVT(); +- +- // Set up the register classes. +- +- addRegisterClass(GRLenVT, &LoongArch::GPRRegClass); +- if (Subtarget.hasBasicF()) +- addRegisterClass(MVT::f32, &LoongArch::FPR32RegClass); +- if (Subtarget.hasBasicD()) +- addRegisterClass(MVT::f64, &LoongArch::FPR64RegClass); +- +- static const MVT::SimpleValueType LSXVTs[] = { +- MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64, MVT::v4f32, MVT::v2f64}; +- static const MVT::SimpleValueType LASXVTs[] = { +- MVT::v32i8, MVT::v16i16, MVT::v8i32, MVT::v4i64, MVT::v8f32, MVT::v4f64}; +- +- if (Subtarget.hasExtLSX()) +- for (MVT VT : LSXVTs) +- addRegisterClass(VT, &LoongArch::LSX128RegClass); ++static cl::opt ++NoZeroDivCheck("mnocheck-zero-division", cl::Hidden, ++ cl::desc("LoongArch: Don't trap on integer division by zero."), ++ cl::init(false)); ++ ++static const MCPhysReg LoongArch64DPRegs[8] = { ++ LoongArch::F0_64, LoongArch::F1_64, LoongArch::F2_64, LoongArch::F3_64, ++ LoongArch::F4_64, LoongArch::F5_64, LoongArch::F6_64, LoongArch::F7_64 ++}; ++ ++// If I is a shifted mask, set the size (SMSize) and the first bit of the ++// mask (SMLsb), and return true. ++// For example, if I is 0x003ff800, (SMLsb, SMSize) = (11, 11). ++static bool isShiftedMask(uint64_t I, uint64_t &SMLsb, uint64_t &SMSize) { ++ if (!isShiftedMask_64(I)) ++ return false; + +- if (Subtarget.hasExtLASX()) +- for (MVT VT : LASXVTs) +- addRegisterClass(VT, &LoongArch::LASX256RegClass); ++ SMSize = popcount(I); ++ SMLsb = llvm::countr_zero(I); ++ return true; ++} + +- // Set operations for LA32 and LA64. ++SDValue LoongArchTargetLowering::getTargetNode(GlobalAddressSDNode *N, EVT Ty, ++ SelectionDAG &DAG, ++ unsigned Flag) const { ++ return DAG.getTargetGlobalAddress(N->getGlobal(), SDLoc(N), Ty, 0, Flag); ++} + +- setLoadExtAction({ISD::EXTLOAD, ISD::SEXTLOAD, ISD::ZEXTLOAD}, GRLenVT, +- MVT::i1, Promote); ++SDValue LoongArchTargetLowering::getTargetNode(ExternalSymbolSDNode *N, EVT Ty, ++ SelectionDAG &DAG, ++ unsigned Flag) const { ++ return DAG.getTargetExternalSymbol(N->getSymbol(), Ty, Flag); ++} + +- setOperationAction(ISD::SHL_PARTS, GRLenVT, Custom); +- setOperationAction(ISD::SRA_PARTS, GRLenVT, Custom); +- setOperationAction(ISD::SRL_PARTS, GRLenVT, Custom); +- setOperationAction(ISD::FP_TO_SINT, GRLenVT, Custom); +- setOperationAction(ISD::ROTL, GRLenVT, Expand); +- setOperationAction(ISD::CTPOP, GRLenVT, Expand); ++SDValue LoongArchTargetLowering::getTargetNode(BlockAddressSDNode *N, EVT Ty, ++ SelectionDAG &DAG, ++ unsigned Flag) const { ++ return DAG.getTargetBlockAddress(N->getBlockAddress(), Ty, N->getOffset(), Flag); ++} + +- setOperationAction({ISD::GlobalAddress, ISD::BlockAddress, ISD::ConstantPool, +- ISD::JumpTable, ISD::GlobalTLSAddress}, +- GRLenVT, Custom); ++SDValue LoongArchTargetLowering::getTargetNode(JumpTableSDNode *N, EVT Ty, ++ SelectionDAG &DAG, ++ unsigned Flag) const { ++ return DAG.getTargetJumpTable(N->getIndex(), Ty, Flag); ++} + +- setOperationAction(ISD::EH_DWARF_CFA, GRLenVT, Custom); ++SDValue LoongArchTargetLowering::getTargetNode(ConstantPoolSDNode *N, EVT Ty, ++ SelectionDAG &DAG, ++ unsigned Flag) const { ++ return DAG.getTargetConstantPool(N->getConstVal(), Ty, N->getAlign(), ++ N->getOffset(), Flag); ++} + +- setOperationAction(ISD::DYNAMIC_STACKALLOC, GRLenVT, Expand); +- setOperationAction({ISD::STACKSAVE, ISD::STACKRESTORE}, MVT::Other, Expand); +- setOperationAction(ISD::VASTART, MVT::Other, Custom); +- setOperationAction({ISD::VAARG, ISD::VACOPY, ISD::VAEND}, MVT::Other, Expand); ++const char *LoongArchTargetLowering::getTargetNodeName(unsigned Opcode) const { ++ switch ((LoongArchISD::NodeType)Opcode) { ++ case LoongArchISD::FIRST_NUMBER: break; ++ case LoongArchISD::JmpLink: return "LoongArchISD::JmpLink"; ++ case LoongArchISD::TailCall: return "LoongArchISD::TailCall"; ++ case LoongArchISD::GlobalAddress: return "LoongArchISD::GlobalAddress"; ++ case LoongArchISD::Ret: return "LoongArchISD::Ret"; ++ case LoongArchISD::ERet: return "LoongArchISD::ERet"; ++ case LoongArchISD::EH_RETURN: return "LoongArchISD::EH_RETURN"; ++ case LoongArchISD::FPBrcond: return "LoongArchISD::FPBrcond"; ++ case LoongArchISD::FPCmp: return "LoongArchISD::FPCmp"; ++ case LoongArchISD::CMovFP_T: return "LoongArchISD::CMovFP_T"; ++ case LoongArchISD::CMovFP_F: return "LoongArchISD::CMovFP_F"; ++ case LoongArchISD::TruncIntFP: return "LoongArchISD::TruncIntFP"; ++ case LoongArchISD::BSTRPICK: return "LoongArchISD::BSTRPICK"; ++ case LoongArchISD::BSTRINS: return "LoongArchISD::BSTRINS"; ++ case LoongArchISD::VALL_ZERO: ++ return "LoongArchISD::VALL_ZERO"; ++ case LoongArchISD::VANY_ZERO: ++ return "LoongArchISD::VANY_ZERO"; ++ case LoongArchISD::VALL_NONZERO: ++ return "LoongArchISD::VALL_NONZERO"; ++ case LoongArchISD::VANY_NONZERO: ++ return "LoongArchISD::VANY_NONZERO"; ++ case LoongArchISD::VEXTRACT_SEXT_ELT: ++ return "LoongArchISD::VEXTRACT_SEXT_ELT"; ++ case LoongArchISD::VEXTRACT_ZEXT_ELT: ++ return "LoongArchISD::VEXTRACT_ZEXT_ELT"; ++ case LoongArchISD::VNOR: ++ return "LoongArchISD::VNOR"; ++ case LoongArchISD::VSHF: ++ return "LoongArchISD::VSHF"; ++ case LoongArchISD::SHF: ++ return "LoongArchISD::SHF"; ++ case LoongArchISD::VPACKEV: ++ return "LoongArchISD::VPACKEV"; ++ case LoongArchISD::VPACKOD: ++ return "LoongArchISD::VPACKOD"; ++ case LoongArchISD::VILVH: ++ return "LoongArchISD::VILVH"; ++ case LoongArchISD::VILVL: ++ return "LoongArchISD::VILVL"; ++ case LoongArchISD::VPICKEV: ++ return "LoongArchISD::VPICKEV"; ++ case LoongArchISD::VPICKOD: ++ return "LoongArchISD::VPICKOD"; ++ case LoongArchISD::INSVE: ++ return "LoongArchISD::INSVE"; ++ case LoongArchISD::VROR: ++ return "LoongArchISD::VROR"; ++ case LoongArchISD::VRORI: ++ return "LoongArchISD::VRORI"; ++ case LoongArchISD::XVBROADCAST: ++ return "LoongArchISD::XVBROADCAST"; ++ case LoongArchISD::VBROADCAST: ++ return "LoongArchISD::VBROADCAST"; ++ case LoongArchISD::VABSD: ++ return "LoongArchISD::VABSD"; ++ case LoongArchISD::UVABSD: ++ return "LoongArchISD::UVABSD"; ++ case LoongArchISD::XVPICKVE: ++ return "LoongArchISD::XVPICKVE"; ++ case LoongArchISD::XVPERMI: ++ return "LoongArchISD::XVPERMI"; ++ case LoongArchISD::XVSHUF4I: ++ return "LoongArchISD::XVSHUF4I"; ++ case LoongArchISD::REVBD: ++ return "LoongArchISD::REVBD"; ++ case LoongArchISD::FSEL: ++ return "LoongArchISD::FSEL"; ++ } ++ return nullptr; ++} + +- setOperationAction(ISD::DEBUGTRAP, MVT::Other, Legal); +- setOperationAction(ISD::TRAP, MVT::Other, Legal); ++LoongArchTargetLowering::LoongArchTargetLowering(const LoongArchTargetMachine &TM, ++ const LoongArchSubtarget &STI) ++ : TargetLowering(TM), Subtarget(STI), ABI(TM.getABI()) { ++ // Set up the register classes ++ addRegisterClass(MVT::i32, &LoongArch::GPR32RegClass); + +- setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom); +- setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom); +- setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); ++ if (Subtarget.is64Bit()) ++ addRegisterClass(MVT::i64, &LoongArch::GPR64RegClass); + +- // Expand bitreverse.i16 with native-width bitrev and shift for now, before +- // we get to know which of sll and revb.2h is faster. +- setOperationAction(ISD::BITREVERSE, MVT::i8, Custom); +- setOperationAction(ISD::BITREVERSE, GRLenVT, Legal); ++ // LoongArch does not have i1 type, so use i32 for ++ // setcc operations results (slt, sgt, ...). ++ setBooleanContents(ZeroOrOneBooleanContent); ++ setBooleanVectorContents(ZeroOrNegativeOneBooleanContent); + +- // LA32 does not have REVB.2W and REVB.D due to the 64-bit operands, and +- // the narrower REVB.W does not exist. But LA32 does have REVB.2H, so i16 +- // and i32 could still be byte-swapped relatively cheaply. +- setOperationAction(ISD::BSWAP, MVT::i16, Custom); ++ // Load extented operations for i1 types must be promoted ++ for (MVT VT : MVT::integer_valuetypes()) { ++ setLoadExtAction(ISD::EXTLOAD, VT, MVT::i1, Promote); ++ setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::i1, Promote); ++ setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote); ++ } ++ ++ // LoongArch doesn't have extending float->double load/store. Set LoadExtAction ++ // for f32, f16 ++ for (MVT VT : MVT::fp_valuetypes()) { ++ setLoadExtAction(ISD::EXTLOAD, VT, MVT::f32, Expand); ++ setLoadExtAction(ISD::EXTLOAD, VT, MVT::f16, Expand); ++ } ++ ++ // Set LoadExtAction for f16 vectors to Expand ++ for (MVT VT : MVT::fp_fixedlen_vector_valuetypes()) { ++ MVT F16VT = MVT::getVectorVT(MVT::f16, VT.getVectorNumElements()); ++ if (F16VT.isValid()) ++ setLoadExtAction(ISD::EXTLOAD, VT, F16VT, Expand); ++ } ++ ++ setTruncStoreAction(MVT::f32, MVT::f16, Expand); ++ setTruncStoreAction(MVT::f64, MVT::f16, Expand); ++ ++ setTruncStoreAction(MVT::f64, MVT::f32, Expand); ++ ++ // Used by legalize types to correctly generate the setcc result. ++ // Without this, every float setcc comes with a AND/OR with the result, ++ // we don't want this, since the fpcmp result goes to a flag register, ++ // which is used implicitly by brcond and select operations. ++ AddPromotedToType(ISD::SETCC, MVT::i1, MVT::i32); ++ ++ // LoongArch Custom Operations ++ setOperationAction(ISD::BR_JT, MVT::Other, Expand); ++ setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); ++ setOperationAction(ISD::BlockAddress, MVT::i32, Custom); ++ setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom); ++ setOperationAction(ISD::JumpTable, MVT::i32, Custom); ++ setOperationAction(ISD::ConstantPool, MVT::i32, Custom); ++ setOperationAction(ISD::SELECT, MVT::f32, Custom); ++ setOperationAction(ISD::SELECT, MVT::f64, Custom); ++ setOperationAction(ISD::SELECT, MVT::i32, Custom); ++ setOperationAction(ISD::SETCC, MVT::f32, Custom); ++ setOperationAction(ISD::SETCC, MVT::f64, Custom); ++ setOperationAction(ISD::BRCOND, MVT::Other, Custom); ++ setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); + +- setOperationAction(ISD::BR_JT, MVT::Other, Expand); +- setOperationAction(ISD::BR_CC, GRLenVT, Expand); +- setOperationAction(ISD::SELECT_CC, GRLenVT, Expand); +- setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); +- setOperationAction({ISD::SMUL_LOHI, ISD::UMUL_LOHI}, GRLenVT, Expand); ++ if (Subtarget.is64Bit()) { ++ setOperationAction(ISD::GlobalAddress, MVT::i64, Custom); ++ setOperationAction(ISD::BlockAddress, MVT::i64, Custom); ++ setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom); ++ setOperationAction(ISD::JumpTable, MVT::i64, Custom); ++ setOperationAction(ISD::ConstantPool, MVT::i64, Custom); ++ setOperationAction(ISD::SELECT, MVT::i64, Custom); ++ setOperationAction(ISD::LOAD, MVT::i64, Legal); ++ setOperationAction(ISD::STORE, MVT::i64, Legal); ++ setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); ++ setOperationAction(ISD::SHL_PARTS, MVT::i64, Custom); ++ setOperationAction(ISD::SRA_PARTS, MVT::i64, Custom); ++ setOperationAction(ISD::SRL_PARTS, MVT::i64, Custom); ++ } + +- setOperationAction(ISD::FP_TO_UINT, GRLenVT, Custom); +- setOperationAction(ISD::UINT_TO_FP, GRLenVT, Expand); ++ if (!Subtarget.is64Bit()) { ++ setOperationAction(ISD::SHL_PARTS, MVT::i32, Custom); ++ setOperationAction(ISD::SRA_PARTS, MVT::i32, Custom); ++ setOperationAction(ISD::SRL_PARTS, MVT::i32, Custom); ++ } ++ ++ setOperationAction(ISD::EH_DWARF_CFA, MVT::i32, Custom); ++ if (Subtarget.is64Bit()) ++ setOperationAction(ISD::EH_DWARF_CFA, MVT::i64, Custom); ++ ++ setOperationAction(ISD::SDIV, MVT::i32, Expand); ++ setOperationAction(ISD::SREM, MVT::i32, Expand); ++ setOperationAction(ISD::UDIV, MVT::i32, Expand); ++ setOperationAction(ISD::UREM, MVT::i32, Expand); ++ setOperationAction(ISD::SDIV, MVT::i64, Expand); ++ setOperationAction(ISD::SREM, MVT::i64, Expand); ++ setOperationAction(ISD::UDIV, MVT::i64, Expand); ++ setOperationAction(ISD::UREM, MVT::i64, Expand); ++ ++ // Operations not directly supported by LoongArch. ++ setOperationAction(ISD::BR_CC, MVT::f32, Expand); ++ setOperationAction(ISD::BR_CC, MVT::f64, Expand); ++ setOperationAction(ISD::BR_CC, MVT::i32, Expand); ++ setOperationAction(ISD::BR_CC, MVT::i64, Expand); ++ setOperationAction(ISD::SELECT_CC, MVT::i32, Expand); ++ setOperationAction(ISD::SELECT_CC, MVT::i64, Expand); ++ setOperationAction(ISD::SELECT_CC, MVT::f32, Expand); ++ setOperationAction(ISD::SELECT_CC, MVT::f64, Expand); ++ setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand); ++ setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand); ++ setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand); ++ setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand); ++ setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); ++ setOperationAction(ISD::CTPOP, MVT::i32, Expand); ++ setOperationAction(ISD::CTPOP, MVT::i64, Expand); ++ setOperationAction(ISD::ROTL, MVT::i32, Expand); ++ setOperationAction(ISD::ROTL, MVT::i64, Expand); ++ setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); ++ setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Expand); ++ ++ setOperationAction(ISD::FSIN, MVT::f32, Expand); ++ setOperationAction(ISD::FSIN, MVT::f64, Expand); ++ setOperationAction(ISD::FCOS, MVT::f32, Expand); ++ setOperationAction(ISD::FCOS, MVT::f64, Expand); ++ setOperationAction(ISD::FSINCOS, MVT::f32, Expand); ++ setOperationAction(ISD::FSINCOS, MVT::f64, Expand); ++ setOperationAction(ISD::FPOW, MVT::f32, Expand); ++ setOperationAction(ISD::FPOW, MVT::f64, Expand); ++ setOperationAction(ISD::FLOG, MVT::f32, Expand); ++ setOperationAction(ISD::FRINT, MVT::f32, Legal); ++ setOperationAction(ISD::FRINT, MVT::f64, Legal); ++ ++ setOperationAction(ISD::FLOG10, MVT::f32, Expand); ++ setOperationAction(ISD::FEXP, MVT::f32, Expand); ++ setOperationAction(ISD::FMA, MVT::f32, Legal); ++ setOperationAction(ISD::FMA, MVT::f64, Legal); ++ setOperationAction(ISD::FREM, MVT::f32, Expand); ++ setOperationAction(ISD::FREM, MVT::f64, Expand); ++ ++ setOperationAction(ISD::FMINNUM_IEEE, MVT::f32, Legal); ++ setOperationAction(ISD::FMINNUM_IEEE, MVT::f64, Legal); ++ setOperationAction(ISD::FMAXNUM_IEEE, MVT::f32, Legal); ++ setOperationAction(ISD::FMAXNUM_IEEE, MVT::f64, Legal); ++ ++ // Lower f16 conversion operations into library calls ++ setOperationAction(ISD::FP16_TO_FP, MVT::f32, Expand); ++ setOperationAction(ISD::FP_TO_FP16, MVT::f32, Expand); ++ setOperationAction(ISD::FP16_TO_FP, MVT::f64, Expand); ++ setOperationAction(ISD::FP_TO_FP16, MVT::f64, Expand); ++ ++ setOperationAction(ISD::EH_RETURN, MVT::Other, Custom); ++ ++ setOperationAction(ISD::VASTART, MVT::Other, Custom); ++ setOperationAction(ISD::VAARG, MVT::Other, Custom); ++ setOperationAction(ISD::VACOPY, MVT::Other, Expand); ++ setOperationAction(ISD::VAEND, MVT::Other, Expand); ++ ++ // Use the default for now ++ setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); ++ setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); + +- // Set operations for LA64 only. ++ if (!Subtarget.is64Bit()) { ++ setOperationAction(ISD::ATOMIC_LOAD, MVT::i64, Expand); ++ setOperationAction(ISD::ATOMIC_STORE, MVT::i64, Expand); ++ } + + if (Subtarget.is64Bit()) { +- setOperationAction(ISD::SHL, MVT::i32, Custom); +- setOperationAction(ISD::SRA, MVT::i32, Custom); +- setOperationAction(ISD::SRL, MVT::i32, Custom); +- setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); +- setOperationAction(ISD::BITCAST, MVT::i32, Custom); +- setOperationAction(ISD::ROTR, MVT::i32, Custom); +- setOperationAction(ISD::ROTL, MVT::i32, Custom); +- setOperationAction(ISD::CTTZ, MVT::i32, Custom); +- setOperationAction(ISD::CTLZ, MVT::i32, Custom); +- setOperationAction(ISD::EH_DWARF_CFA, MVT::i32, Custom); +- setOperationAction(ISD::READ_REGISTER, MVT::i32, Custom); +- setOperationAction(ISD::WRITE_REGISTER, MVT::i32, Custom); +- setOperationAction(ISD::INTRINSIC_VOID, MVT::i32, Custom); +- setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i32, Custom); +- setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i32, Custom); +- +- setOperationAction(ISD::BITREVERSE, MVT::i32, Custom); +- setOperationAction(ISD::BSWAP, MVT::i32, Custom); +- } +- +- // Set operations for LA32 only. +- +- if (!Subtarget.is64Bit()) { +- setOperationAction(ISD::READ_REGISTER, MVT::i64, Custom); +- setOperationAction(ISD::WRITE_REGISTER, MVT::i64, Custom); +- setOperationAction(ISD::INTRINSIC_VOID, MVT::i64, Custom); +- setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom); +- setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i64, Custom); +- +- // Set libcalls. +- setLibcallName(RTLIB::MUL_I128, nullptr); +- // The MULO libcall is not part of libgcc, only compiler-rt. +- setLibcallName(RTLIB::MULO_I64, nullptr); +- } +- +- // The MULO libcall is not part of libgcc, only compiler-rt. +- setLibcallName(RTLIB::MULO_I128, nullptr); +- +- setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom); +- +- static const ISD::CondCode FPCCToExpand[] = { +- ISD::SETOGT, ISD::SETOGE, ISD::SETUGT, ISD::SETUGE, +- ISD::SETGE, ISD::SETNE, ISD::SETGT}; +- +- // Set operations for 'F' feature. +- +- if (Subtarget.hasBasicF()) { +- setCondCodeAction(FPCCToExpand, MVT::f32, Expand); +- +- setOperationAction(ISD::SELECT_CC, MVT::f32, Expand); +- setOperationAction(ISD::BR_CC, MVT::f32, Expand); +- setOperationAction(ISD::FMA, MVT::f32, Legal); +- setOperationAction(ISD::FMINNUM_IEEE, MVT::f32, Legal); +- setOperationAction(ISD::FMAXNUM_IEEE, MVT::f32, Legal); +- setOperationAction(ISD::STRICT_FSETCCS, MVT::f32, Legal); +- setOperationAction(ISD::STRICT_FSETCC, MVT::f32, Legal); +- setOperationAction(ISD::IS_FPCLASS, MVT::f32, Legal); +- setOperationAction(ISD::FSIN, MVT::f32, Expand); +- setOperationAction(ISD::FCOS, MVT::f32, Expand); +- setOperationAction(ISD::FSINCOS, MVT::f32, Expand); +- setOperationAction(ISD::FPOW, MVT::f32, Expand); +- setOperationAction(ISD::FREM, MVT::f32, Expand); +- +- if (Subtarget.is64Bit()) +- setOperationAction(ISD::FRINT, MVT::f32, Legal); +- +- if (!Subtarget.hasBasicD()) { +- setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom); +- if (Subtarget.is64Bit()) { +- setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom); +- setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom); +- } +- } ++ setLoadExtAction(ISD::EXTLOAD, MVT::i64, MVT::i32, Custom); ++ setTruncStoreAction(MVT::i64, MVT::i32, Custom); + } + +- // Set operations for 'D' feature. +- +- if (Subtarget.hasBasicD()) { +- setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f32, Expand); +- setTruncStoreAction(MVT::f64, MVT::f32, Expand); +- setCondCodeAction(FPCCToExpand, MVT::f64, Expand); +- +- setOperationAction(ISD::SELECT_CC, MVT::f64, Expand); +- setOperationAction(ISD::BR_CC, MVT::f64, Expand); +- setOperationAction(ISD::STRICT_FSETCCS, MVT::f64, Legal); +- setOperationAction(ISD::STRICT_FSETCC, MVT::f64, Legal); +- setOperationAction(ISD::FMA, MVT::f64, Legal); +- setOperationAction(ISD::FMINNUM_IEEE, MVT::f64, Legal); +- setOperationAction(ISD::FMAXNUM_IEEE, MVT::f64, Legal); +- setOperationAction(ISD::IS_FPCLASS, MVT::f64, Legal); +- setOperationAction(ISD::FSIN, MVT::f64, Expand); +- setOperationAction(ISD::FCOS, MVT::f64, Expand); +- setOperationAction(ISD::FSINCOS, MVT::f64, Expand); +- setOperationAction(ISD::FPOW, MVT::f64, Expand); +- setOperationAction(ISD::FREM, MVT::f64, Expand); +- +- if (Subtarget.is64Bit()) +- setOperationAction(ISD::FRINT, MVT::f64, Legal); +- } +- +- // Set operations for 'LSX' feature. +- +- if (Subtarget.hasExtLSX()) { +- for (MVT VT : MVT::fixedlen_vector_valuetypes()) { +- // Expand all truncating stores and extending loads. +- for (MVT InnerVT : MVT::fixedlen_vector_valuetypes()) { +- setTruncStoreAction(VT, InnerVT, Expand); +- setLoadExtAction(ISD::SEXTLOAD, VT, InnerVT, Expand); +- setLoadExtAction(ISD::ZEXTLOAD, VT, InnerVT, Expand); +- setLoadExtAction(ISD::EXTLOAD, VT, InnerVT, Expand); ++ setOperationAction(ISD::TRAP, MVT::Other, Legal); ++ setOperationAction(ISD::BITREVERSE, MVT::i32, Legal); ++ setOperationAction(ISD::BITREVERSE, MVT::i64, Legal); ++ ++ setTargetDAGCombine(ISD::SELECT); ++ setTargetDAGCombine(ISD::AND); ++ setTargetDAGCombine(ISD::OR); ++ setTargetDAGCombine(ISD::AssertZext); ++ setTargetDAGCombine(ISD::SHL); ++ setTargetDAGCombine(ISD::SIGN_EXTEND); ++ setTargetDAGCombine(ISD::ZERO_EXTEND); ++ setTargetDAGCombine(ISD::ADD); ++ setTargetDAGCombine(ISD::SUB); ++ setTargetDAGCombine(ISD::MUL); ++ setTargetDAGCombine(ISD::SRL); ++ setTargetDAGCombine(ISD::SRA); ++ ++ if (ABI.IsLP32()) { ++ // These libcalls are not available in 32-bit. ++ setLibcallName(RTLIB::SHL_I128, nullptr); ++ setLibcallName(RTLIB::SRL_I128, nullptr); ++ setLibcallName(RTLIB::SRA_I128, nullptr); ++ } ++ ++ if (Subtarget.hasLSX() || Subtarget.hasLASX()) { ++ // Expand all truncating stores and extending loads. ++ for (MVT VT0 : MVT::vector_valuetypes()) { ++ for (MVT VT1 : MVT::vector_valuetypes()) { ++ setTruncStoreAction(VT0, VT1, Expand); ++ setLoadExtAction(ISD::SEXTLOAD, VT0, VT1, Expand); ++ setLoadExtAction(ISD::ZEXTLOAD, VT0, VT1, Expand); ++ setLoadExtAction(ISD::EXTLOAD, VT0, VT1, Expand); + } +- // By default everything must be expanded. Then we will selectively turn +- // on ones that can be effectively codegen'd. +- for (unsigned Op = 0; Op < ISD::BUILTIN_OP_END; ++Op) +- setOperationAction(Op, VT, Expand); + } ++ } + +- for (MVT VT : LSXVTs) { +- setOperationAction({ISD::LOAD, ISD::STORE}, VT, Legal); +- setOperationAction(ISD::BITCAST, VT, Legal); +- setOperationAction(ISD::UNDEF, VT, Legal); +- +- setOperationAction(ISD::INSERT_VECTOR_ELT, VT, Custom); +- setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Legal); +- setOperationAction(ISD::BUILD_VECTOR, VT, Custom); +- +- setOperationAction(ISD::SETCC, VT, Legal); +- setOperationAction(ISD::VSELECT, VT, Legal); +- } +- for (MVT VT : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64}) { +- setOperationAction(ISD::VECTOR_SHUFFLE, VT, Custom); +- setOperationAction({ISD::ADD, ISD::SUB}, VT, Legal); +- setOperationAction({ISD::UMAX, ISD::UMIN, ISD::SMAX, ISD::SMIN}, VT, +- Legal); +- setOperationAction({ISD::MUL, ISD::SDIV, ISD::SREM, ISD::UDIV, ISD::UREM}, +- VT, Legal); +- setOperationAction({ISD::AND, ISD::OR, ISD::XOR}, VT, Legal); +- setOperationAction({ISD::SHL, ISD::SRA, ISD::SRL}, VT, Legal); +- setOperationAction({ISD::CTPOP, ISD::CTLZ}, VT, Legal); +- setOperationAction({ISD::MULHS, ISD::MULHU}, VT, Legal); +- setCondCodeAction( +- {ISD::SETNE, ISD::SETGE, ISD::SETGT, ISD::SETUGE, ISD::SETUGT}, VT, +- Expand); +- } +- for (MVT VT : {MVT::v4i32, MVT::v2i64}) { +- setOperationAction({ISD::SINT_TO_FP, ISD::UINT_TO_FP}, VT, Legal); +- setOperationAction({ISD::FP_TO_SINT, ISD::FP_TO_UINT}, VT, Legal); +- } +- for (MVT VT : {MVT::v4f32, MVT::v2f64}) { +- setOperationAction({ISD::FADD, ISD::FSUB}, VT, Legal); +- setOperationAction({ISD::FMUL, ISD::FDIV}, VT, Legal); +- setOperationAction(ISD::FMA, VT, Legal); +- setOperationAction(ISD::FSQRT, VT, Legal); +- setOperationAction(ISD::FNEG, VT, Legal); +- setCondCodeAction({ISD::SETGE, ISD::SETGT, ISD::SETOGE, ISD::SETOGT, +- ISD::SETUGE, ISD::SETUGT}, +- VT, Expand); ++ if (Subtarget.hasLSX()) { ++ addLSXIntType(MVT::v16i8, &LoongArch::LSX128BRegClass); ++ addLSXIntType(MVT::v8i16, &LoongArch::LSX128HRegClass); ++ addLSXIntType(MVT::v4i32, &LoongArch::LSX128WRegClass); ++ addLSXIntType(MVT::v2i64, &LoongArch::LSX128DRegClass); ++ addLSXFloatType(MVT::v4f32, &LoongArch::LSX128WRegClass); ++ addLSXFloatType(MVT::v2f64, &LoongArch::LSX128DRegClass); ++ ++ // f16 is a storage-only type, always promote it to f32. ++ setOperationAction(ISD::SETCC, MVT::f16, Promote); ++ setOperationAction(ISD::BR_CC, MVT::f16, Promote); ++ setOperationAction(ISD::SELECT_CC, MVT::f16, Promote); ++ setOperationAction(ISD::SELECT, MVT::f16, Promote); ++ setOperationAction(ISD::FADD, MVT::f16, Promote); ++ setOperationAction(ISD::FSUB, MVT::f16, Promote); ++ setOperationAction(ISD::FMUL, MVT::f16, Promote); ++ setOperationAction(ISD::FDIV, MVT::f16, Promote); ++ setOperationAction(ISD::FREM, MVT::f16, Promote); ++ setOperationAction(ISD::FMA, MVT::f16, Promote); ++ setOperationAction(ISD::FNEG, MVT::f16, Promote); ++ setOperationAction(ISD::FABS, MVT::f16, Promote); ++ setOperationAction(ISD::FCEIL, MVT::f16, Promote); ++ setOperationAction(ISD::FCOPYSIGN, MVT::f16, Promote); ++ setOperationAction(ISD::FCOS, MVT::f16, Promote); ++ setOperationAction(ISD::FP_EXTEND, MVT::f16, Promote); ++ setOperationAction(ISD::FFLOOR, MVT::f16, Promote); ++ setOperationAction(ISD::FNEARBYINT, MVT::f16, Promote); ++ setOperationAction(ISD::FPOW, MVT::f16, Promote); ++ setOperationAction(ISD::FPOWI, MVT::f16, Promote); ++ setOperationAction(ISD::FRINT, MVT::f16, Promote); ++ setOperationAction(ISD::FSIN, MVT::f16, Promote); ++ setOperationAction(ISD::FSINCOS, MVT::f16, Promote); ++ setOperationAction(ISD::FSQRT, MVT::f16, Promote); ++ setOperationAction(ISD::FEXP, MVT::f16, Promote); ++ setOperationAction(ISD::FEXP2, MVT::f16, Promote); ++ setOperationAction(ISD::FLOG, MVT::f16, Promote); ++ setOperationAction(ISD::FLOG2, MVT::f16, Promote); ++ setOperationAction(ISD::FLOG10, MVT::f16, Promote); ++ setOperationAction(ISD::FROUND, MVT::f16, Promote); ++ setOperationAction(ISD::FTRUNC, MVT::f16, Promote); ++ setOperationAction(ISD::FMINNUM, MVT::f16, Promote); ++ setOperationAction(ISD::FMAXNUM, MVT::f16, Promote); ++ setOperationAction(ISD::FMINIMUM, MVT::f16, Promote); ++ setOperationAction(ISD::FMAXIMUM, MVT::f16, Promote); ++ ++ setTargetDAGCombine(ISD::AND); ++ setTargetDAGCombine(ISD::OR); ++ setTargetDAGCombine(ISD::SRA); ++ setTargetDAGCombine(ISD::VSELECT); ++ setTargetDAGCombine(ISD::XOR); ++ } ++ ++ if (Subtarget.hasLASX()) { ++ addLASXIntType(MVT::v32i8, &LoongArch::LASX256BRegClass); ++ addLASXIntType(MVT::v16i16, &LoongArch::LASX256HRegClass); ++ addLASXIntType(MVT::v8i32, &LoongArch::LASX256WRegClass); ++ addLASXIntType(MVT::v4i64, &LoongArch::LASX256DRegClass); ++ addLASXFloatType(MVT::v8f32, &LoongArch::LASX256WRegClass); ++ addLASXFloatType(MVT::v4f64, &LoongArch::LASX256DRegClass); ++ ++ // f16 is a storage-only type, always promote it to f32. ++ setOperationAction(ISD::SETCC, MVT::f16, Promote); ++ setOperationAction(ISD::BR_CC, MVT::f16, Promote); ++ setOperationAction(ISD::SELECT_CC, MVT::f16, Promote); ++ setOperationAction(ISD::SELECT, MVT::f16, Promote); ++ setOperationAction(ISD::FADD, MVT::f16, Promote); ++ setOperationAction(ISD::FSUB, MVT::f16, Promote); ++ setOperationAction(ISD::FMUL, MVT::f16, Promote); ++ setOperationAction(ISD::FDIV, MVT::f16, Promote); ++ setOperationAction(ISD::FREM, MVT::f16, Promote); ++ setOperationAction(ISD::FMA, MVT::f16, Promote); ++ setOperationAction(ISD::FNEG, MVT::f16, Promote); ++ setOperationAction(ISD::FABS, MVT::f16, Promote); ++ setOperationAction(ISD::FCEIL, MVT::f16, Promote); ++ setOperationAction(ISD::FCOPYSIGN, MVT::f16, Promote); ++ setOperationAction(ISD::FCOS, MVT::f16, Promote); ++ setOperationAction(ISD::FP_EXTEND, MVT::f16, Promote); ++ setOperationAction(ISD::FFLOOR, MVT::f16, Promote); ++ setOperationAction(ISD::FNEARBYINT, MVT::f16, Promote); ++ setOperationAction(ISD::FPOW, MVT::f16, Promote); ++ setOperationAction(ISD::FPOWI, MVT::f16, Promote); ++ setOperationAction(ISD::FRINT, MVT::f16, Promote); ++ setOperationAction(ISD::FSIN, MVT::f16, Promote); ++ setOperationAction(ISD::FSINCOS, MVT::f16, Promote); ++ setOperationAction(ISD::FSQRT, MVT::f16, Promote); ++ setOperationAction(ISD::FEXP, MVT::f16, Promote); ++ setOperationAction(ISD::FEXP2, MVT::f16, Promote); ++ setOperationAction(ISD::FLOG, MVT::f16, Promote); ++ setOperationAction(ISD::FLOG2, MVT::f16, Promote); ++ setOperationAction(ISD::FLOG10, MVT::f16, Promote); ++ setOperationAction(ISD::FROUND, MVT::f16, Promote); ++ setOperationAction(ISD::FTRUNC, MVT::f16, Promote); ++ setOperationAction(ISD::FMINNUM, MVT::f16, Promote); ++ setOperationAction(ISD::FMAXNUM, MVT::f16, Promote); ++ setOperationAction(ISD::FMINIMUM, MVT::f16, Promote); ++ setOperationAction(ISD::FMAXIMUM, MVT::f16, Promote); ++ ++ setTargetDAGCombine(ISD::AND); ++ setTargetDAGCombine(ISD::OR); ++ setTargetDAGCombine(ISD::SRA); ++ setTargetDAGCombine(ISD::VSELECT); ++ setTargetDAGCombine(ISD::XOR); ++ } ++ ++ if (!Subtarget.useSoftFloat()) { ++ addRegisterClass(MVT::f32, &LoongArch::FGR32RegClass); ++ ++ // When dealing with single precision only, use libcalls ++ if (!Subtarget.isSingleFloat()) { ++ if (Subtarget.isFP64bit()) ++ addRegisterClass(MVT::f64, &LoongArch::FGR64RegClass); + } + } + +- // Set operations for 'LASX' feature. ++ setOperationAction(ISD::SMUL_LOHI, MVT::i32, Custom); ++ setOperationAction(ISD::UMUL_LOHI, MVT::i32, Custom); + +- if (Subtarget.hasExtLASX()) { +- for (MVT VT : LASXVTs) { +- setOperationAction({ISD::LOAD, ISD::STORE}, VT, Legal); +- setOperationAction(ISD::BITCAST, VT, Legal); +- setOperationAction(ISD::UNDEF, VT, Legal); ++ if (Subtarget.is64Bit()) ++ setOperationAction(ISD::MUL, MVT::i64, Custom); + +- setOperationAction(ISD::INSERT_VECTOR_ELT, VT, Custom); +- setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Custom); +- setOperationAction(ISD::BUILD_VECTOR, VT, Custom); +- +- setOperationAction(ISD::SETCC, VT, Legal); +- setOperationAction(ISD::VSELECT, VT, Legal); +- } +- for (MVT VT : {MVT::v4i64, MVT::v8i32, MVT::v16i16, MVT::v32i8}) { +- setOperationAction(ISD::VECTOR_SHUFFLE, VT, Custom); +- setOperationAction({ISD::ADD, ISD::SUB}, VT, Legal); +- setOperationAction({ISD::UMAX, ISD::UMIN, ISD::SMAX, ISD::SMIN}, VT, +- Legal); +- setOperationAction({ISD::MUL, ISD::SDIV, ISD::SREM, ISD::UDIV, ISD::UREM}, +- VT, Legal); +- setOperationAction({ISD::AND, ISD::OR, ISD::XOR}, VT, Legal); +- setOperationAction({ISD::SHL, ISD::SRA, ISD::SRL}, VT, Legal); +- setOperationAction({ISD::CTPOP, ISD::CTLZ}, VT, Legal); +- setOperationAction({ISD::MULHS, ISD::MULHU}, VT, Legal); +- setCondCodeAction( +- {ISD::SETNE, ISD::SETGE, ISD::SETGT, ISD::SETUGE, ISD::SETUGT}, VT, +- Expand); +- } +- for (MVT VT : {MVT::v8i32, MVT::v4i32, MVT::v4i64}) { +- setOperationAction({ISD::SINT_TO_FP, ISD::UINT_TO_FP}, VT, Legal); +- setOperationAction({ISD::FP_TO_SINT, ISD::FP_TO_UINT}, VT, Legal); +- } +- for (MVT VT : {MVT::v8f32, MVT::v4f64}) { +- setOperationAction({ISD::FADD, ISD::FSUB}, VT, Legal); +- setOperationAction({ISD::FMUL, ISD::FDIV}, VT, Legal); +- setOperationAction(ISD::FMA, VT, Legal); +- setOperationAction(ISD::FSQRT, VT, Legal); +- setOperationAction(ISD::FNEG, VT, Legal); +- setCondCodeAction({ISD::SETGE, ISD::SETGT, ISD::SETOGE, ISD::SETOGT, +- ISD::SETUGE, ISD::SETUGT}, +- VT, Expand); +- } ++ if (Subtarget.is64Bit()) { ++ setOperationAction(ISD::SMUL_LOHI, MVT::i64, Custom); ++ setOperationAction(ISD::UMUL_LOHI, MVT::i64, Custom); ++ setOperationAction(ISD::SDIVREM, MVT::i64, Custom); ++ setOperationAction(ISD::UDIVREM, MVT::i64, Custom); + } + +- // Set DAG combine for LA32 and LA64. ++ setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom); ++ setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i64, Custom); + +- setTargetDAGCombine(ISD::AND); +- setTargetDAGCombine(ISD::OR); +- setTargetDAGCombine(ISD::SRL); ++ setOperationAction(ISD::SDIVREM, MVT::i32, Custom); ++ setOperationAction(ISD::UDIVREM, MVT::i32, Custom); ++ setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom); ++ setOperationAction(ISD::LOAD, MVT::i32, Legal); ++ setOperationAction(ISD::STORE, MVT::i32, Legal); + +- // Set DAG combine for 'LSX' feature. ++ setTargetDAGCombine(ISD::MUL); + +- if (Subtarget.hasExtLSX()) +- setTargetDAGCombine(ISD::INTRINSIC_WO_CHAIN); ++ setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); ++ setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom); ++ setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom); + +- // Compute derived properties from the register classes. +- computeRegisterProperties(Subtarget.getRegisterInfo()); ++ // Replace the accumulator-based multiplies with a ++ // three register instruction. ++ setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand); ++ setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand); ++ setOperationAction(ISD::MUL, MVT::i32, Legal); ++ setOperationAction(ISD::MULHS, MVT::i32, Legal); ++ setOperationAction(ISD::MULHU, MVT::i32, Legal); ++ ++ // Replace the accumulator-based division/remainder with separate ++ // three register division and remainder instructions. ++ setOperationAction(ISD::SDIVREM, MVT::i32, Expand); ++ setOperationAction(ISD::UDIVREM, MVT::i32, Expand); ++ setOperationAction(ISD::SDIV, MVT::i32, Legal); ++ setOperationAction(ISD::UDIV, MVT::i32, Legal); ++ setOperationAction(ISD::SREM, MVT::i32, Legal); ++ setOperationAction(ISD::UREM, MVT::i32, Legal); ++ ++ // Replace the accumulator-based multiplies with a ++ // three register instruction. ++ setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand); ++ setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand); ++ setOperationAction(ISD::MUL, MVT::i64, Legal); ++ setOperationAction(ISD::MULHS, MVT::i64, Legal); ++ setOperationAction(ISD::MULHU, MVT::i64, Legal); ++ ++ // Replace the accumulator-based division/remainder with separate ++ // three register division and remainder instructions. ++ setOperationAction(ISD::SDIVREM, MVT::i64, Expand); ++ setOperationAction(ISD::UDIVREM, MVT::i64, Expand); ++ setOperationAction(ISD::SDIV, MVT::i64, Legal); ++ setOperationAction(ISD::UDIV, MVT::i64, Legal); ++ setOperationAction(ISD::SREM, MVT::i64, Legal); ++ setOperationAction(ISD::UREM, MVT::i64, Legal); ++ ++ MaxGluedStoresPerMemcpy = 4; + +- setStackPointerRegisterToSaveRestore(LoongArch::R3); ++ setMinFunctionAlignment(Align(4)); + +- setBooleanContents(ZeroOrOneBooleanContent); +- setBooleanVectorContents(ZeroOrNegativeOneBooleanContent); ++ // The arguments on the stack are defined in terms of 4-byte slots on LP32 ++ // and 8-byte slots on LPX32/LP64. ++ setMinStackArgumentAlignment((ABI.IsLPX32() || ABI.IsLP64()) ? Align(8) ++ : Align(4)); + +- setMaxAtomicSizeInBitsSupported(Subtarget.getGRLen()); ++ setStackPointerRegisterToSaveRestore(ABI.IsLP64() ? LoongArch::SP_64 : LoongArch::SP); + +- setMinCmpXchgSizeInBits(32); ++ if (Subtarget.hasLASX()) { ++ // = 16*32/2; the smallest memcpy; ++ MaxStoresPerMemcpy = 16; ++ } else if (Subtarget.hasLSX()) { ++ MaxStoresPerMemcpy = 65535; ++ } else { ++ MaxStoresPerMemcpy = 16; ++ } + +- // Function alignments. +- setMinFunctionAlignment(Align(4)); +- // Set preferred alignments. +- setPrefFunctionAlignment(Subtarget.getPrefFunctionAlignment()); +- setPrefLoopAlignment(Subtarget.getPrefLoopAlignment()); +- setMaxBytesForAlignment(Subtarget.getMaxBytesForAlignment()); +-} +- +-bool LoongArchTargetLowering::isOffsetFoldingLegal( +- const GlobalAddressSDNode *GA) const { +- // In order to maximise the opportunity for common subexpression elimination, +- // keep a separate ADD node for the global address offset instead of folding +- // it in the global address node. Later peephole optimisations may choose to +- // fold it back in when profitable. +- return false; +-} ++ if (Subtarget.is64Bit()) ++ setMaxAtomicSizeInBitsSupported(64); ++ else ++ setMaxAtomicSizeInBitsSupported(32); + +-SDValue LoongArchTargetLowering::LowerOperation(SDValue Op, +- SelectionDAG &DAG) const { +- switch (Op.getOpcode()) { +- case ISD::ATOMIC_FENCE: +- return lowerATOMIC_FENCE(Op, DAG); +- case ISD::EH_DWARF_CFA: +- return lowerEH_DWARF_CFA(Op, DAG); +- case ISD::GlobalAddress: +- return lowerGlobalAddress(Op, DAG); +- case ISD::GlobalTLSAddress: +- return lowerGlobalTLSAddress(Op, DAG); +- case ISD::INTRINSIC_WO_CHAIN: +- return lowerINTRINSIC_WO_CHAIN(Op, DAG); +- case ISD::INTRINSIC_W_CHAIN: +- return lowerINTRINSIC_W_CHAIN(Op, DAG); +- case ISD::INTRINSIC_VOID: +- return lowerINTRINSIC_VOID(Op, DAG); +- case ISD::BlockAddress: +- return lowerBlockAddress(Op, DAG); +- case ISD::JumpTable: +- return lowerJumpTable(Op, DAG); +- case ISD::SHL_PARTS: +- return lowerShiftLeftParts(Op, DAG); +- case ISD::SRA_PARTS: +- return lowerShiftRightParts(Op, DAG, true); +- case ISD::SRL_PARTS: +- return lowerShiftRightParts(Op, DAG, false); +- case ISD::ConstantPool: +- return lowerConstantPool(Op, DAG); +- case ISD::FP_TO_SINT: +- return lowerFP_TO_SINT(Op, DAG); +- case ISD::BITCAST: +- return lowerBITCAST(Op, DAG); +- case ISD::UINT_TO_FP: +- return lowerUINT_TO_FP(Op, DAG); +- case ISD::SINT_TO_FP: +- return lowerSINT_TO_FP(Op, DAG); +- case ISD::VASTART: +- return lowerVASTART(Op, DAG); +- case ISD::FRAMEADDR: +- return lowerFRAMEADDR(Op, DAG); +- case ISD::RETURNADDR: +- return lowerRETURNADDR(Op, DAG); +- case ISD::WRITE_REGISTER: +- return lowerWRITE_REGISTER(Op, DAG); +- case ISD::INSERT_VECTOR_ELT: +- return lowerINSERT_VECTOR_ELT(Op, DAG); +- case ISD::EXTRACT_VECTOR_ELT: +- return lowerEXTRACT_VECTOR_ELT(Op, DAG); +- case ISD::BUILD_VECTOR: +- return lowerBUILD_VECTOR(Op, DAG); +- case ISD::VECTOR_SHUFFLE: +- return lowerVECTOR_SHUFFLE(Op, DAG); +- } +- return SDValue(); ++ computeRegisterProperties(Subtarget.getRegisterInfo()); + } + +-SDValue LoongArchTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op, +- SelectionDAG &DAG) const { +- // TODO: custom shuffle. +- return SDValue(); ++// Enable LSX support for the given integer type and Register class. ++void LoongArchTargetLowering::addLSXIntType(MVT::SimpleValueType Ty, ++ const TargetRegisterClass *RC) { ++ addRegisterClass(Ty, RC); ++ ++ // Expand all builtin opcodes. ++ for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc) ++ setOperationAction(Opc, Ty, Expand); ++ ++ setOperationAction(ISD::BITCAST, Ty, Legal); ++ setOperationAction(ISD::LOAD, Ty, Legal); ++ setOperationAction(ISD::STORE, Ty, Legal); ++ setOperationAction(ISD::EXTRACT_VECTOR_ELT, Ty, Custom); ++ setOperationAction(ISD::INSERT_VECTOR_ELT, Ty, Custom); ++ setOperationAction(ISD::BUILD_VECTOR, Ty, Custom); ++ setOperationAction(ISD::ABS, Ty, Legal); ++ setOperationAction(ISD::UNDEF, Ty, Legal); ++ setOperationAction(ISD::EXTRACT_SUBVECTOR, Ty, Legal); ++ setOperationAction(ISD::CONCAT_VECTORS, Ty, Legal); ++ ++ if (Ty == MVT::v4i32 || Ty == MVT::v2i64) { ++ setOperationAction(ISD::FP_TO_SINT, Ty, Custom); ++ setOperationAction(ISD::FP_TO_UINT, Ty, Custom); ++ } ++ ++ setOperationAction(ISD::ADD, Ty, Legal); ++ setOperationAction(ISD::AND, Ty, Legal); ++ setOperationAction(ISD::CTLZ, Ty, Legal); ++ setOperationAction(ISD::CTPOP, Ty, Legal); ++ setOperationAction(ISD::MUL, Ty, Legal); ++ setOperationAction(ISD::OR, Ty, Legal); ++ setOperationAction(ISD::SDIV, Ty, Legal); ++ setOperationAction(ISD::SREM, Ty, Legal); ++ setOperationAction(ISD::SHL, Ty, Legal); ++ setOperationAction(ISD::SRA, Ty, Legal); ++ setOperationAction(ISD::SRL, Ty, Legal); ++ setOperationAction(ISD::SUB, Ty, Legal); ++ setOperationAction(ISD::SMAX, Ty, Legal); ++ setOperationAction(ISD::SMIN, Ty, Legal); ++ setOperationAction(ISD::UDIV, Ty, Legal); ++ setOperationAction(ISD::UREM, Ty, Legal); ++ setOperationAction(ISD::UMAX, Ty, Legal); ++ setOperationAction(ISD::UMIN, Ty, Legal); ++ setOperationAction(ISD::VECTOR_SHUFFLE, Ty, Custom); ++ setOperationAction(ISD::VSELECT, Ty, Legal); ++ setOperationAction(ISD::XOR, Ty, Legal); ++ setOperationAction(ISD::MULHS, Ty, Legal); ++ setOperationAction(ISD::MULHU, Ty, Legal); ++ ++ if (Ty == MVT::v4i32 || Ty == MVT::v2i64) { ++ setOperationAction(ISD::SINT_TO_FP, Ty, Custom); ++ setOperationAction(ISD::UINT_TO_FP, Ty, Custom); ++ } ++ ++ setOperationAction(ISD::SETCC, Ty, Legal); ++ setCondCodeAction(ISD::SETNE, Ty, Expand); ++ setCondCodeAction(ISD::SETGE, Ty, Expand); ++ setCondCodeAction(ISD::SETGT, Ty, Expand); ++ setCondCodeAction(ISD::SETUGE, Ty, Expand); ++ setCondCodeAction(ISD::SETUGT, Ty, Expand); + } + +-static bool isConstantOrUndef(const SDValue Op) { +- if (Op->isUndef()) +- return true; +- if (isa(Op)) +- return true; +- if (isa(Op)) +- return true; +- return false; ++// Enable LASX support for the given integer type and Register class. ++void LoongArchTargetLowering::addLASXIntType(MVT::SimpleValueType Ty, ++ const TargetRegisterClass *RC) { ++ addRegisterClass(Ty, RC); ++ ++ // Expand all builtin opcodes. ++ for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc) ++ setOperationAction(Opc, Ty, Expand); ++ ++ // FIXME ++ setOperationAction(ISD::BITCAST, Ty, Legal); ++ setOperationAction(ISD::LOAD, Ty, Legal); ++ setOperationAction(ISD::STORE, Ty, Legal); ++ setOperationAction(ISD::EXTRACT_VECTOR_ELT, Ty, Custom); ++ setOperationAction(ISD::INSERT_VECTOR_ELT, Ty, Custom); ++ setOperationAction(ISD::BUILD_VECTOR, Ty, Custom); ++ setOperationAction(ISD::CONCAT_VECTORS, Ty, Legal); ++ setOperationAction(ISD::UNDEF, Ty, Legal); ++ setOperationAction(ISD::UADDSAT, Ty, Legal); ++ setOperationAction(ISD::SADDSAT, Ty, Legal); ++ setOperationAction(ISD::USUBSAT, Ty, Legal); ++ setOperationAction(ISD::SSUBSAT, Ty, Legal); ++ setOperationAction(ISD::ABS, Ty, Legal); ++ ++ setOperationAction(ISD::ADD, Ty, Legal); ++ setOperationAction(ISD::AND, Ty, Legal); ++ setOperationAction(ISD::CTLZ, Ty, Legal); ++ setOperationAction(ISD::CTPOP, Ty, Legal); ++ setOperationAction(ISD::MUL, Ty, Legal); ++ setOperationAction(ISD::OR, Ty, Legal); ++ setOperationAction(ISD::SDIV, Ty, Legal); ++ setOperationAction(ISD::SREM, Ty, Legal); ++ setOperationAction(ISD::SHL, Ty, Legal); ++ setOperationAction(ISD::SRA, Ty, Legal); ++ setOperationAction(ISD::SRL, Ty, Legal); ++ setOperationAction(ISD::SUB, Ty, Legal); ++ setOperationAction(ISD::SMAX, Ty, Legal); ++ setOperationAction(ISD::SMIN, Ty, Legal); ++ setOperationAction(ISD::UDIV, Ty, Legal); ++ setOperationAction(ISD::UREM, Ty, Legal); ++ setOperationAction(ISD::UMAX, Ty, Legal); ++ setOperationAction(ISD::UMIN, Ty, Legal); ++ setOperationAction(ISD::VECTOR_SHUFFLE, Ty, Custom); ++ setOperationAction(ISD::VSELECT, Ty, Legal); ++ setOperationAction(ISD::XOR, Ty, Legal); ++ setOperationAction(ISD::INSERT_SUBVECTOR, Ty, Legal); ++ setOperationAction(ISD::MULHS, Ty, Legal); ++ setOperationAction(ISD::MULHU, Ty, Legal); ++ ++ setOperationAction(ISD::SIGN_EXTEND_VECTOR_INREG, Ty, Legal); ++ setOperationAction(ISD::ZERO_EXTEND_VECTOR_INREG, Ty, Legal); ++ ++ setOperationAction(ISD::SIGN_EXTEND, Ty, Legal); ++ setOperationAction(ISD::ZERO_EXTEND, Ty, Legal); ++ ++ if (Ty == MVT::v8i32 || Ty == MVT::v4i64) { ++ setOperationAction(ISD::SINT_TO_FP, Ty, Custom); ++ setOperationAction(ISD::UINT_TO_FP, Ty, Custom); ++ } ++ ++ setTargetDAGCombine(ISD::CONCAT_VECTORS); ++ ++ setOperationAction(ISD::SETCC, Ty, Legal); ++ setCondCodeAction(ISD::SETNE, Ty, Expand); ++ setCondCodeAction(ISD::SETGE, Ty, Expand); ++ setCondCodeAction(ISD::SETGT, Ty, Expand); ++ setCondCodeAction(ISD::SETUGE, Ty, Expand); ++ setCondCodeAction(ISD::SETUGT, Ty, Expand); + } + +-static bool isConstantOrUndefBUILD_VECTOR(const BuildVectorSDNode *Op) { +- for (unsigned i = 0; i < Op->getNumOperands(); ++i) +- if (isConstantOrUndef(Op->getOperand(i))) +- return true; +- return false; ++// Enable LSX support for the given floating-point type and Register class. ++void LoongArchTargetLowering::addLSXFloatType(MVT::SimpleValueType Ty, ++ const TargetRegisterClass *RC) { ++ addRegisterClass(Ty, RC); ++ ++ // Expand all builtin opcodes. ++ for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc) ++ setOperationAction(Opc, Ty, Expand); ++ ++ setOperationAction(ISD::LOAD, Ty, Legal); ++ setOperationAction(ISD::STORE, Ty, Legal); ++ setOperationAction(ISD::BITCAST, Ty, Legal); ++ setOperationAction(ISD::EXTRACT_VECTOR_ELT, Ty, Legal); ++ setOperationAction(ISD::INSERT_VECTOR_ELT, Ty, Custom); ++ setOperationAction(ISD::UNDEF, Ty, Legal); ++ setOperationAction(ISD::BUILD_VECTOR, Ty, Custom); ++ setOperationAction(ISD::CONCAT_VECTORS, Ty, Legal); ++ ++ if (Ty == MVT::v4f32 || Ty == MVT::v2f64) { ++ setOperationAction(ISD::FP_TO_SINT, Ty, Custom); ++ setOperationAction(ISD::FP_TO_UINT, Ty, Custom); ++ } ++ ++ setOperationAction(ISD::FADD, Ty, Legal); ++ setOperationAction(ISD::FDIV, Ty, Legal); ++ setOperationAction(ISD::FMA, Ty, Legal); ++ setOperationAction(ISD::FMUL, Ty, Legal); ++ setOperationAction(ISD::FSQRT, Ty, Legal); ++ setOperationAction(ISD::FSUB, Ty, Legal); ++ setOperationAction(ISD::VSELECT, Ty, Legal); ++ setOperationAction(ISD::FNEG, Ty, Legal); ++ setOperationAction(ISD::FRINT, Ty, Legal); ++ ++ setOperationAction(ISD::SETCC, Ty, Legal); ++ setCondCodeAction(ISD::SETOGE, Ty, Expand); ++ setCondCodeAction(ISD::SETOGT, Ty, Expand); ++ setCondCodeAction(ISD::SETUGE, Ty, Expand); ++ setCondCodeAction(ISD::SETUGT, Ty, Expand); ++ setCondCodeAction(ISD::SETGE, Ty, Expand); ++ setCondCodeAction(ISD::SETGT, Ty, Expand); + } + +-SDValue LoongArchTargetLowering::lowerBUILD_VECTOR(SDValue Op, +- SelectionDAG &DAG) const { +- BuildVectorSDNode *Node = cast(Op); +- EVT ResTy = Op->getValueType(0); +- SDLoc DL(Op); +- APInt SplatValue, SplatUndef; +- unsigned SplatBitSize; +- bool HasAnyUndefs; +- bool Is128Vec = ResTy.is128BitVector(); +- bool Is256Vec = ResTy.is256BitVector(); ++// Enable LASX support for the given floating-point type and Register class. ++void LoongArchTargetLowering::addLASXFloatType(MVT::SimpleValueType Ty, ++ const TargetRegisterClass *RC) { ++ addRegisterClass(Ty, RC); ++ ++ // Expand all builtin opcodes. ++ for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc) ++ setOperationAction(Opc, Ty, Expand); ++ ++ setOperationAction(ISD::LOAD, Ty, Legal); ++ setOperationAction(ISD::STORE, Ty, Legal); ++ setOperationAction(ISD::BITCAST, Ty, Legal); ++ setOperationAction(ISD::EXTRACT_VECTOR_ELT, Ty, Custom); ++ setOperationAction(ISD::INSERT_VECTOR_ELT, Ty, Custom); ++ setOperationAction(ISD::BUILD_VECTOR, Ty, Custom); ++ setOperationAction(ISD::UNDEF, Ty, Legal); ++ setOperationAction(ISD::CONCAT_VECTORS, Ty, Legal); ++ ++ setOperationAction(ISD::FADD, Ty, Legal); ++ setOperationAction(ISD::FDIV, Ty, Legal); ++ setOperationAction(ISD::FMA, Ty, Legal); ++ setOperationAction(ISD::FMUL, Ty, Legal); ++ setOperationAction(ISD::FSQRT, Ty, Legal); ++ setOperationAction(ISD::FSUB, Ty, Legal); ++ setOperationAction(ISD::VSELECT, Ty, Legal); ++ setOperationAction(ISD::FNEG, Ty, Legal); ++ setOperationAction(ISD::FRINT, Ty, Legal); ++ ++ if (Ty == MVT::v8f32 || Ty == MVT::v4f64) { ++ setOperationAction(ISD::FP_TO_SINT, Ty, Custom); ++ setOperationAction(ISD::FP_TO_UINT, Ty, Custom); ++ } ++ ++ setOperationAction(ISD::SETCC, Ty, Legal); ++ setCondCodeAction(ISD::SETOGE, Ty, Expand); ++ setCondCodeAction(ISD::SETOGT, Ty, Expand); ++ setCondCodeAction(ISD::SETUGE, Ty, Expand); ++ setCondCodeAction(ISD::SETUGT, Ty, Expand); ++ setCondCodeAction(ISD::SETGE, Ty, Expand); ++ setCondCodeAction(ISD::SETGT, Ty, Expand); ++} + +- if ((!Subtarget.hasExtLSX() || !Is128Vec) && +- (!Subtarget.hasExtLASX() || !Is256Vec)) +- return SDValue(); ++bool LoongArchTargetLowering::allowsMisalignedMemoryAccesses( ++ EVT VT, unsigned AddrSpace, Align Alignment, MachineMemOperand::Flags Flags, ++ unsigned *Fast) const { ++ if (!Subtarget.allowUnalignedAccess()) ++ return false; + +- if (Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs, +- /*MinSplatBits=*/8) && +- SplatBitSize <= 64) { +- // We can only cope with 8, 16, 32, or 64-bit elements. +- if (SplatBitSize != 8 && SplatBitSize != 16 && SplatBitSize != 32 && +- SplatBitSize != 64) +- return SDValue(); ++ // TODO: set reasonable speed number. ++ if (Fast) ++ *Fast = 1; ++ return true; ++} + +- EVT ViaVecTy; ++EVT LoongArchTargetLowering::getSetCCResultType(const DataLayout &, LLVMContext &, ++ EVT VT) const { ++ if (!VT.isVector()) ++ return MVT::i32; ++ return VT.changeVectorElementTypeToInteger(); ++} + +- switch (SplatBitSize) { +- default: +- return SDValue(); +- case 8: +- ViaVecTy = Is128Vec ? MVT::v16i8 : MVT::v32i8; +- break; +- case 16: +- ViaVecTy = Is128Vec ? MVT::v8i16 : MVT::v16i16; +- break; +- case 32: +- ViaVecTy = Is128Vec ? MVT::v4i32 : MVT::v8i32; +- break; +- case 64: +- ViaVecTy = Is128Vec ? MVT::v2i64 : MVT::v4i64; +- break; +- } ++static LoongArch::CondCode condCodeToFCC(ISD::CondCode CC) { ++ switch (CC) { ++ default: llvm_unreachable("Unknown fp condition code!"); ++ case ISD::SETEQ: ++ case ISD::SETOEQ: return LoongArch::FCOND_OEQ; ++ case ISD::SETUNE: return LoongArch::FCOND_UNE; ++ case ISD::SETLT: ++ case ISD::SETOLT: return LoongArch::FCOND_OLT; ++ case ISD::SETGT: ++ case ISD::SETOGT: return LoongArch::FCOND_OGT; ++ case ISD::SETLE: ++ case ISD::SETOLE: return LoongArch::FCOND_OLE; ++ case ISD::SETGE: ++ case ISD::SETOGE: return LoongArch::FCOND_OGE; ++ case ISD::SETULT: return LoongArch::FCOND_ULT; ++ case ISD::SETULE: return LoongArch::FCOND_ULE; ++ case ISD::SETUGT: return LoongArch::FCOND_UGT; ++ case ISD::SETUGE: return LoongArch::FCOND_UGE; ++ case ISD::SETUO: return LoongArch::FCOND_UN; ++ case ISD::SETO: return LoongArch::FCOND_OR; ++ case ISD::SETNE: ++ case ISD::SETONE: return LoongArch::FCOND_ONE; ++ case ISD::SETUEQ: return LoongArch::FCOND_UEQ; ++ } ++} + +- // SelectionDAG::getConstant will promote SplatValue appropriately. +- SDValue Result = DAG.getConstant(SplatValue, DL, ViaVecTy); ++/// This function returns true if the floating point conditional branches and ++/// conditional moves which use condition code CC should be inverted. ++static bool invertFPCondCodeUser(LoongArch::CondCode CC) { ++ if (CC >= LoongArch::FCOND_F && CC <= LoongArch::FCOND_SUNE) ++ return false; + +- // Bitcast to the type we originally wanted. +- if (ViaVecTy != ResTy) +- Result = DAG.getNode(ISD::BITCAST, SDLoc(Node), ResTy, Result); ++ assert((CC >= LoongArch::FCOND_T && CC <= LoongArch::FCOND_GT) && ++ "Illegal Condition Code"); + +- return Result; +- } ++ return true; ++} + +- if (DAG.isSplatValue(Op, /*AllowUndefs=*/false)) ++// Creates and returns an FPCmp node from a setcc node. ++// Returns Op if setcc is not a floating point comparison. ++static SDValue createFPCmp(SelectionDAG &DAG, const SDValue &Op) { ++ // must be a SETCC node ++ if (Op.getOpcode() != ISD::SETCC) + return Op; + +- if (!isConstantOrUndefBUILD_VECTOR(Node)) { +- // Use INSERT_VECTOR_ELT operations rather than expand to stores. +- // The resulting code is the same length as the expansion, but it doesn't +- // use memory operations. +- EVT ResTy = Node->getValueType(0); ++ SDValue LHS = Op.getOperand(0); + +- assert(ResTy.isVector()); ++ if (!LHS.getValueType().isFloatingPoint()) ++ return Op; + +- unsigned NumElts = ResTy.getVectorNumElements(); +- SDValue Vector = DAG.getUNDEF(ResTy); +- for (unsigned i = 0; i < NumElts; ++i) { +- Vector = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, ResTy, Vector, +- Node->getOperand(i), +- DAG.getConstant(i, DL, Subtarget.getGRLenVT())); +- } +- return Vector; +- } ++ SDValue RHS = Op.getOperand(1); ++ SDLoc DL(Op); + +- return SDValue(); ++ // Assume the 3rd operand is a CondCodeSDNode. Add code to check the type of ++ // node if necessary. ++ ISD::CondCode CC = cast(Op.getOperand(2))->get(); ++ ++ return DAG.getNode(LoongArchISD::FPCmp, DL, MVT::Glue, LHS, RHS, ++ DAG.getConstant(condCodeToFCC(CC), DL, MVT::i32)); + } + +-SDValue +-LoongArchTargetLowering::lowerEXTRACT_VECTOR_ELT(SDValue Op, +- SelectionDAG &DAG) const { +- EVT VecTy = Op->getOperand(0)->getValueType(0); +- SDValue Idx = Op->getOperand(1); +- EVT EltTy = VecTy.getVectorElementType(); +- unsigned NumElts = VecTy.getVectorNumElements(); ++// Creates and returns a CMovFPT/F node. ++static SDValue createCMovFP(SelectionDAG &DAG, SDValue Cond, SDValue True, ++ SDValue False, const SDLoc &DL) { ++ ConstantSDNode *CC = cast(Cond.getOperand(2)); ++ bool invert = invertFPCondCodeUser((LoongArch::CondCode)CC->getSExtValue()); ++ SDValue FCC0 = DAG.getRegister(LoongArch::FCC0, MVT::i32); + +- if (isa(Idx) && +- (EltTy == MVT::i32 || EltTy == MVT::i64 || EltTy == MVT::f32 || +- EltTy == MVT::f64 || Idx->getAsZExtVal() < NumElts / 2)) +- return Op; ++ return DAG.getNode((invert ? LoongArchISD::CMovFP_F : LoongArchISD::CMovFP_T), DL, ++ True.getValueType(), True, FCC0, False, Cond); + +- return SDValue(); + } + +-SDValue +-LoongArchTargetLowering::lowerINSERT_VECTOR_ELT(SDValue Op, +- SelectionDAG &DAG) const { +- if (isa(Op->getOperand(2))) +- return Op; +- return SDValue(); +-} ++static SDValue performSELECTCombine(SDNode *N, SelectionDAG &DAG, ++ TargetLowering::DAGCombinerInfo &DCI, ++ const LoongArchSubtarget &Subtarget) { ++ if (DCI.isBeforeLegalizeOps()) ++ return SDValue(); + +-SDValue LoongArchTargetLowering::lowerATOMIC_FENCE(SDValue Op, +- SelectionDAG &DAG) const { +- SDLoc DL(Op); +- SyncScope::ID FenceSSID = +- static_cast(Op.getConstantOperandVal(2)); ++ SDValue SetCC = N->getOperand(0); + +- // singlethread fences only synchronize with signal handlers on the same +- // thread and thus only need to preserve instruction order, not actually +- // enforce memory ordering. +- if (FenceSSID == SyncScope::SingleThread) +- // MEMBARRIER is a compiler barrier; it codegens to a no-op. +- return DAG.getNode(ISD::MEMBARRIER, DL, MVT::Other, Op.getOperand(0)); ++ if ((SetCC.getOpcode() != ISD::SETCC) || ++ !SetCC.getOperand(0).getValueType().isInteger()) ++ return SDValue(); + +- return Op; +-} ++ SDValue False = N->getOperand(2); ++ EVT FalseTy = False.getValueType(); + +-SDValue LoongArchTargetLowering::lowerWRITE_REGISTER(SDValue Op, +- SelectionDAG &DAG) const { ++ if (!FalseTy.isInteger()) ++ return SDValue(); + +- if (Subtarget.is64Bit() && Op.getOperand(2).getValueType() == MVT::i32) { +- DAG.getContext()->emitError( +- "On LA64, only 64-bit registers can be written."); +- return Op.getOperand(0); +- } ++ ConstantSDNode *FalseC = dyn_cast(False); + +- if (!Subtarget.is64Bit() && Op.getOperand(2).getValueType() == MVT::i64) { +- DAG.getContext()->emitError( +- "On LA32, only 32-bit registers can be written."); +- return Op.getOperand(0); +- } ++ // If the RHS (False) is 0, we swap the order of the operands ++ // of ISD::SELECT (obviously also inverting the condition) so that we can ++ // take advantage of conditional moves using the $0 register. ++ // Example: ++ // return (a != 0) ? x : 0; ++ // load $reg, x ++ // movz $reg, $0, a ++ if (!FalseC) ++ return SDValue(); + +- return Op; +-} ++ const SDLoc DL(N); + +-SDValue LoongArchTargetLowering::lowerFRAMEADDR(SDValue Op, +- SelectionDAG &DAG) const { +- if (!isa(Op.getOperand(0))) { +- DAG.getContext()->emitError("argument to '__builtin_frame_address' must " +- "be a constant integer"); +- return SDValue(); +- } ++ if (!FalseC->getZExtValue()) { ++ ISD::CondCode CC = cast(SetCC.getOperand(2))->get(); ++ SDValue True = N->getOperand(1); + +- MachineFunction &MF = DAG.getMachineFunction(); +- MF.getFrameInfo().setFrameAddressIsTaken(true); +- Register FrameReg = Subtarget.getRegisterInfo()->getFrameRegister(MF); +- EVT VT = Op.getValueType(); +- SDLoc DL(Op); +- SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), DL, FrameReg, VT); +- unsigned Depth = Op.getConstantOperandVal(0); +- int GRLenInBytes = Subtarget.getGRLen() / 8; ++ SetCC = DAG.getSetCC(DL, SetCC.getValueType(), SetCC.getOperand(0), ++ SetCC.getOperand(1), ++ ISD::getSetCCInverse(CC, SetCC.getValueType())); + +- while (Depth--) { +- int Offset = -(GRLenInBytes * 2); +- SDValue Ptr = DAG.getNode(ISD::ADD, DL, VT, FrameAddr, +- DAG.getIntPtrConstant(Offset, DL)); +- FrameAddr = +- DAG.getLoad(VT, DL, DAG.getEntryNode(), Ptr, MachinePointerInfo()); ++ return DAG.getNode(ISD::SELECT, DL, FalseTy, SetCC, False, True); + } +- return FrameAddr; +-} + +-SDValue LoongArchTargetLowering::lowerRETURNADDR(SDValue Op, +- SelectionDAG &DAG) const { +- if (verifyReturnAddressArgumentIsConstant(Op, DAG)) ++ // If both operands are integer constants there's a possibility that we ++ // can do some interesting optimizations. ++ SDValue True = N->getOperand(1); ++ ConstantSDNode *TrueC = dyn_cast(True); ++ ++ if (!TrueC || !True.getValueType().isInteger()) + return SDValue(); + +- // Currently only support lowering return address for current frame. +- if (Op.getConstantOperandVal(0) != 0) { +- DAG.getContext()->emitError( +- "return address can only be determined for the current frame"); ++ // We'll also ignore MVT::i64 operands as this optimizations proves ++ // to be ineffective because of the required sign extensions as the result ++ // of a SETCC operator is always MVT::i32 for non-vector types. ++ if (True.getValueType() == MVT::i64) + return SDValue(); +- } + +- MachineFunction &MF = DAG.getMachineFunction(); +- MF.getFrameInfo().setReturnAddressIsTaken(true); +- MVT GRLenVT = Subtarget.getGRLenVT(); ++ int64_t Diff = TrueC->getSExtValue() - FalseC->getSExtValue(); + +- // Return the value of the return address register, marking it an implicit +- // live-in. +- Register Reg = MF.addLiveIn(Subtarget.getRegisterInfo()->getRARegister(), +- getRegClassFor(GRLenVT)); +- return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), Reg, GRLenVT); +-} ++ // 1) (a < x) ? y : y-1 ++ // slti $reg1, a, x ++ // addiu $reg2, $reg1, y-1 ++ if (Diff == 1) ++ return DAG.getNode(ISD::ADD, DL, SetCC.getValueType(), SetCC, False); + +-SDValue LoongArchTargetLowering::lowerEH_DWARF_CFA(SDValue Op, +- SelectionDAG &DAG) const { +- MachineFunction &MF = DAG.getMachineFunction(); +- auto Size = Subtarget.getGRLen() / 8; +- auto FI = MF.getFrameInfo().CreateFixedObject(Size, 0, false); +- return DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout())); ++ // 2) (a < x) ? y-1 : y ++ // slti $reg1, a, x ++ // xor $reg1, $reg1, 1 ++ // addiu $reg2, $reg1, y-1 ++ if (Diff == -1) { ++ ISD::CondCode CC = cast(SetCC.getOperand(2))->get(); ++ SetCC = DAG.getSetCC(DL, SetCC.getValueType(), SetCC.getOperand(0), ++ SetCC.getOperand(1), ++ ISD::getSetCCInverse(CC, SetCC.getValueType())); ++ return DAG.getNode(ISD::ADD, DL, SetCC.getValueType(), SetCC, True); ++ } ++ ++ // Could not optimize. ++ return SDValue(); + } + +-SDValue LoongArchTargetLowering::lowerVASTART(SDValue Op, +- SelectionDAG &DAG) const { +- MachineFunction &MF = DAG.getMachineFunction(); +- auto *FuncInfo = MF.getInfo(); ++static SDValue performANDCombine(SDNode *N, SelectionDAG &DAG, ++ TargetLowering::DAGCombinerInfo &DCI, ++ const LoongArchSubtarget &Subtarget) { + +- SDLoc DL(Op); +- SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), +- getPointerTy(MF.getDataLayout())); ++ if (Subtarget.hasLSX()) { + +- // vastart just stores the address of the VarArgsFrameIndex slot into the +- // memory location argument. +- const Value *SV = cast(Op.getOperand(2))->getValue(); +- return DAG.getStore(Op.getOperand(0), DL, FI, Op.getOperand(1), +- MachinePointerInfo(SV)); +-} +- +-SDValue LoongArchTargetLowering::lowerUINT_TO_FP(SDValue Op, +- SelectionDAG &DAG) const { +- assert(Subtarget.is64Bit() && Subtarget.hasBasicF() && +- !Subtarget.hasBasicD() && "unexpected target features"); +- +- SDLoc DL(Op); +- SDValue Op0 = Op.getOperand(0); +- if (Op0->getOpcode() == ISD::AND) { +- auto *C = dyn_cast(Op0.getOperand(1)); +- if (C && C->getZExtValue() < UINT64_C(0xFFFFFFFF)) +- return Op; ++ // Fold zero extensions into LoongArchISD::VEXTRACT_[SZ]EXT_ELT ++ // ++ // Performs the following transformations: ++ // - Changes LoongArchISD::VEXTRACT_[SZ]EXT_ELT to zero extension if its ++ // sign/zero-extension is completely overwritten by the new one performed ++ // by the ISD::AND. ++ // - Removes redundant zero extensions performed by an ISD::AND. ++ SDValue Op0 = N->getOperand(0); ++ SDValue Op1 = N->getOperand(1); ++ unsigned Op0Opcode = Op0->getOpcode(); ++ ++ // (and (LoongArchVExtract[SZ]Ext $a, $b, $c), imm:$d) ++ // where $d + 1 == 2^n and n == 32 ++ // or $d + 1 == 2^n and n <= 32 and ZExt ++ // -> (LoongArchVExtractZExt $a, $b, $c) ++ if (Op0Opcode == LoongArchISD::VEXTRACT_SEXT_ELT || ++ Op0Opcode == LoongArchISD::VEXTRACT_ZEXT_ELT) { ++ ConstantSDNode *Mask = dyn_cast(Op1); ++ ++ if (Mask) { ++ ++ int32_t Log2IfPositive = (Mask->getAPIntValue() + 1).exactLogBase2(); ++ ++ if (Log2IfPositive > 0) { ++ SDValue Op0Op2 = Op0->getOperand(2); ++ EVT ExtendTy = cast(Op0Op2)->getVT(); ++ unsigned ExtendTySize = ExtendTy.getSizeInBits(); ++ unsigned Log2 = Log2IfPositive; ++ ++ if ((Op0Opcode == LoongArchISD::VEXTRACT_ZEXT_ELT && ++ Log2 >= ExtendTySize) || ++ Log2 == ExtendTySize) { ++ SDValue Ops[] = {Op0->getOperand(0), Op0->getOperand(1), Op0Op2}; ++ return DAG.getNode(LoongArchISD::VEXTRACT_ZEXT_ELT, SDLoc(Op0), ++ Op0->getVTList(), ++ ArrayRef(Ops, Op0->getNumOperands())); ++ } ++ } ++ } ++ } + } + +- if (Op0->getOpcode() == LoongArchISD::BSTRPICK && +- Op0.getConstantOperandVal(1) < UINT64_C(0X1F) && +- Op0.getConstantOperandVal(2) == UINT64_C(0)) +- return Op; ++ if (DCI.isBeforeLegalizeOps()) ++ return SDValue(); + +- if (Op0.getOpcode() == ISD::AssertZext && +- dyn_cast(Op0.getOperand(1))->getVT().bitsLT(MVT::i32)) +- return Op; ++ SDValue FirstOperand = N->getOperand(0); ++ unsigned FirstOperandOpc = FirstOperand.getOpcode(); ++ SDValue Mask = N->getOperand(1); ++ EVT ValTy = N->getValueType(0); ++ SDLoc DL(N); + +- EVT OpVT = Op0.getValueType(); +- EVT RetVT = Op.getValueType(); +- RTLIB::Libcall LC = RTLIB::getUINTTOFP(OpVT, RetVT); +- MakeLibCallOptions CallOptions; +- CallOptions.setTypeListBeforeSoften(OpVT, RetVT, true); +- SDValue Chain = SDValue(); +- SDValue Result; +- std::tie(Result, Chain) = +- makeLibCall(DAG, LC, Op.getValueType(), Op0, CallOptions, DL, Chain); +- return Result; +-} ++ uint64_t Lsb = 0, SMLsb, SMSize; ++ ConstantSDNode *CN; ++ SDValue NewOperand; ++ unsigned Opc; + +-SDValue LoongArchTargetLowering::lowerSINT_TO_FP(SDValue Op, +- SelectionDAG &DAG) const { +- assert(Subtarget.is64Bit() && Subtarget.hasBasicF() && +- !Subtarget.hasBasicD() && "unexpected target features"); ++ // Op's second operand must be a shifted mask. ++ if (!(CN = dyn_cast(Mask)) || ++ !isShiftedMask(CN->getZExtValue(), SMLsb, SMSize)) ++ return SDValue(); + +- SDLoc DL(Op); +- SDValue Op0 = Op.getOperand(0); ++ if (FirstOperandOpc == ISD::SRA || FirstOperandOpc == ISD::SRL) { ++ // Pattern match BSTRPICK. ++ // $dst = and ((sra or srl) $src , lsb), (2**size - 1) ++ // => bstrpick $dst, $src, lsb+size-1, lsb + +- if ((Op0.getOpcode() == ISD::AssertSext || +- Op0.getOpcode() == ISD::SIGN_EXTEND_INREG) && +- dyn_cast(Op0.getOperand(1))->getVT().bitsLE(MVT::i32)) +- return Op; ++ // The second operand of the shift must be an immediate. ++ if (!(CN = dyn_cast(FirstOperand.getOperand(1)))) ++ return SDValue(); + +- EVT OpVT = Op0.getValueType(); +- EVT RetVT = Op.getValueType(); +- RTLIB::Libcall LC = RTLIB::getSINTTOFP(OpVT, RetVT); +- MakeLibCallOptions CallOptions; +- CallOptions.setTypeListBeforeSoften(OpVT, RetVT, true); +- SDValue Chain = SDValue(); +- SDValue Result; +- std::tie(Result, Chain) = +- makeLibCall(DAG, LC, Op.getValueType(), Op0, CallOptions, DL, Chain); +- return Result; +-} ++ Lsb = CN->getZExtValue(); + +-SDValue LoongArchTargetLowering::lowerBITCAST(SDValue Op, +- SelectionDAG &DAG) const { ++ // Return if the shifted mask does not start at bit 0 or the sum of its size ++ // and Lsb exceeds the word's size. ++ if (SMLsb != 0 || Lsb + SMSize > ValTy.getSizeInBits()) ++ return SDValue(); + +- SDLoc DL(Op); +- SDValue Op0 = Op.getOperand(0); ++ Opc = LoongArchISD::BSTRPICK; ++ NewOperand = FirstOperand.getOperand(0); ++ } else { ++ // Pattern match BSTRPICK. ++ // $dst = and $src, (2**size - 1) , if size > 12 ++ // => bstrpick $dst, $src, lsb+size-1, lsb , lsb = 0 ++ ++ // If the mask is <= 0xfff, andi can be used instead. ++ if (CN->getZExtValue() <= 0xfff) ++ return SDValue(); ++ // Return if the mask doesn't start at position 0. ++ if (SMLsb) ++ return SDValue(); + +- if (Op.getValueType() == MVT::f32 && Op0.getValueType() == MVT::i32 && +- Subtarget.is64Bit() && Subtarget.hasBasicF()) { +- SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op0); +- return DAG.getNode(LoongArchISD::MOVGR2FR_W_LA64, DL, MVT::f32, NewOp0); ++ Opc = LoongArchISD::BSTRPICK; ++ NewOperand = FirstOperand; + } +- return Op; ++ return DAG.getNode(Opc, DL, ValTy, NewOperand, ++ DAG.getConstant((Lsb + SMSize - 1), DL, MVT::i32), ++ DAG.getConstant(Lsb, DL, MVT::i32)); + } + +-SDValue LoongArchTargetLowering::lowerFP_TO_SINT(SDValue Op, +- SelectionDAG &DAG) const { ++// Determine if the specified node is a constant vector splat. ++// ++// Returns true and sets Imm if: ++// * N is a ISD::BUILD_VECTOR representing a constant splat ++static bool isVSplat(SDValue N, APInt &Imm) { ++ BuildVectorSDNode *Node = dyn_cast(N.getNode()); + +- SDLoc DL(Op); ++ if (!Node) ++ return false; + +- if (Op.getValueSizeInBits() > 32 && Subtarget.hasBasicF() && +- !Subtarget.hasBasicD()) { +- SDValue Dst = +- DAG.getNode(LoongArchISD::FTINT, DL, MVT::f32, Op.getOperand(0)); +- return DAG.getNode(LoongArchISD::MOVFR2GR_S_LA64, DL, MVT::i64, Dst); +- } ++ APInt SplatValue, SplatUndef; ++ unsigned SplatBitSize; ++ bool HasAnyUndefs; + +- EVT FPTy = EVT::getFloatingPointVT(Op.getValueSizeInBits()); +- SDValue Trunc = DAG.getNode(LoongArchISD::FTINT, DL, FPTy, Op.getOperand(0)); +- return DAG.getNode(ISD::BITCAST, DL, Op.getValueType(), Trunc); +-} ++ if (!Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs, ++ 8)) ++ return false; + +-static SDValue getTargetNode(GlobalAddressSDNode *N, SDLoc DL, EVT Ty, +- SelectionDAG &DAG, unsigned Flags) { +- return DAG.getTargetGlobalAddress(N->getGlobal(), DL, Ty, 0, Flags); +-} ++ Imm = SplatValue; + +-static SDValue getTargetNode(BlockAddressSDNode *N, SDLoc DL, EVT Ty, +- SelectionDAG &DAG, unsigned Flags) { +- return DAG.getTargetBlockAddress(N->getBlockAddress(), Ty, N->getOffset(), +- Flags); ++ return true; + } + +-static SDValue getTargetNode(ConstantPoolSDNode *N, SDLoc DL, EVT Ty, +- SelectionDAG &DAG, unsigned Flags) { +- return DAG.getTargetConstantPool(N->getConstVal(), Ty, N->getAlign(), +- N->getOffset(), Flags); +-} ++// Test whether the given node is an all-ones build_vector. ++static bool isVectorAllOnes(SDValue N) { ++ // Look through bitcasts. Endianness doesn't matter because we are looking ++ // for an all-ones value. ++ if (N->getOpcode() == ISD::BITCAST) ++ N = N->getOperand(0); + +-static SDValue getTargetNode(JumpTableSDNode *N, SDLoc DL, EVT Ty, +- SelectionDAG &DAG, unsigned Flags) { +- return DAG.getTargetJumpTable(N->getIndex(), Ty, Flags); +-} ++ BuildVectorSDNode *BVN = dyn_cast(N); + +-template +-SDValue LoongArchTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG, +- CodeModel::Model M, +- bool IsLocal) const { +- SDLoc DL(N); +- EVT Ty = getPointerTy(DAG.getDataLayout()); +- SDValue Addr = getTargetNode(N, DL, Ty, DAG, 0); ++ if (!BVN) ++ return false; + +- switch (M) { +- default: +- report_fatal_error("Unsupported code model"); ++ APInt SplatValue, SplatUndef; ++ unsigned SplatBitSize; ++ bool HasAnyUndefs; + +- case CodeModel::Large: { +- assert(Subtarget.is64Bit() && "Large code model requires LA64"); ++ // Endianness doesn't matter in this context because we are looking for ++ // an all-ones value. ++ if (BVN->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs)) ++ return SplatValue.isAllOnes(); + +- // This is not actually used, but is necessary for successfully matching +- // the PseudoLA_*_LARGE nodes. +- SDValue Tmp = DAG.getConstant(0, DL, Ty); +- if (IsLocal) +- // This generates the pattern (PseudoLA_PCREL_LARGE tmp sym), that +- // eventually becomes the desired 5-insn code sequence. +- return SDValue(DAG.getMachineNode(LoongArch::PseudoLA_PCREL_LARGE, DL, Ty, +- Tmp, Addr), +- 0); ++ return false; ++} + +- // This generates the pattern (PseudoLA_GOT_LARGE tmp sym), that eventually +- // becomes the desired 5-insn code sequence. +- return SDValue( +- DAG.getMachineNode(LoongArch::PseudoLA_GOT_LARGE, DL, Ty, Tmp, Addr), +- 0); +- } ++// Test whether N is the bitwise inverse of OfNode. ++static bool isBitwiseInverse(SDValue N, SDValue OfNode) { ++ if (N->getOpcode() != ISD::XOR) ++ return false; + +- case CodeModel::Small: +- case CodeModel::Medium: +- if (IsLocal) +- // This generates the pattern (PseudoLA_PCREL sym), which expands to +- // (addi.w/d (pcalau12i %pc_hi20(sym)) %pc_lo12(sym)). +- return SDValue( +- DAG.getMachineNode(LoongArch::PseudoLA_PCREL, DL, Ty, Addr), 0); +- +- // This generates the pattern (PseudoLA_GOT sym), which expands to (ld.w/d +- // (pcalau12i %got_pc_hi20(sym)) %got_pc_lo12(sym)). +- return SDValue(DAG.getMachineNode(LoongArch::PseudoLA_GOT, DL, Ty, Addr), +- 0); +- } +-} ++ if (isVectorAllOnes(N->getOperand(0))) ++ return N->getOperand(1) == OfNode; + +-SDValue LoongArchTargetLowering::lowerBlockAddress(SDValue Op, +- SelectionDAG &DAG) const { +- return getAddr(cast(Op), DAG, +- DAG.getTarget().getCodeModel()); +-} ++ if (isVectorAllOnes(N->getOperand(1))) ++ return N->getOperand(0) == OfNode; + +-SDValue LoongArchTargetLowering::lowerJumpTable(SDValue Op, +- SelectionDAG &DAG) const { +- return getAddr(cast(Op), DAG, +- DAG.getTarget().getCodeModel()); ++ return false; + } + +-SDValue LoongArchTargetLowering::lowerConstantPool(SDValue Op, +- SelectionDAG &DAG) const { +- return getAddr(cast(Op), DAG, +- DAG.getTarget().getCodeModel()); +-} ++static SDValue performSet(SDNode *N, SelectionDAG &DAG, ++ TargetLowering::DAGCombinerInfo &DCI, ++ const LoongArchSubtarget &Subtarget) { ++ ++ SDValue Op0 = N->getOperand(0); ++ SDValue Op1 = N->getOperand(1); ++ SDValue N1, N2; ++ if (Op0->getOpcode() == ISD::BUILD_VECTOR && ++ (Op1->getValueType(0).is128BitVector() || ++ Op1->getValueType(0).is256BitVector())) { ++ N1 = Op0; ++ N2 = Op1; ++ } else if (Op1->getOpcode() == ISD::BUILD_VECTOR && ++ (Op0->getValueType(0).is128BitVector() || ++ Op0->getValueType(0).is256BitVector())) { ++ N1 = Op1; ++ N2 = Op0; ++ } else ++ return SDValue(); + +-SDValue LoongArchTargetLowering::lowerGlobalAddress(SDValue Op, +- SelectionDAG &DAG) const { +- GlobalAddressSDNode *N = cast(Op); +- assert(N->getOffset() == 0 && "unexpected offset in global node"); +- auto CM = DAG.getTarget().getCodeModel(); +- const GlobalValue *GV = N->getGlobal(); ++ APInt Mask1, Mask2; ++ if (!isVSplat(N1, Mask1)) ++ return SDValue(); + +- if (GV->isDSOLocal() && isa(GV)) { +- if (auto GCM = dyn_cast(GV)->getCodeModel()) +- CM = *GCM; +- } ++ if (!N1->getValueType(0).isSimple()) ++ return SDValue(); + +- return getAddr(N, DAG, CM, GV->isDSOLocal()); +-} ++ ConstantSDNode *C1; ++ uint64_t Imm; ++ unsigned ImmL; ++ if (!(C1 = dyn_cast(N1.getOperand(0))) || ++ !isPowerOf2_64(C1->getZExtValue())) ++ return SDValue(); + +-SDValue LoongArchTargetLowering::getStaticTLSAddr(GlobalAddressSDNode *N, +- SelectionDAG &DAG, +- unsigned Opc, +- bool Large) const { +- SDLoc DL(N); +- EVT Ty = getPointerTy(DAG.getDataLayout()); +- MVT GRLenVT = Subtarget.getGRLenVT(); ++ Imm = C1->getZExtValue(); ++ ImmL = Log2_64(Imm); ++ MVT VT = N1->getSimpleValueType(0).SimpleTy; ++ ++ SDNode *Res; ++ ++ if (Subtarget.hasLASX() && N->getValueType(0).is256BitVector()) { ++ if (VT == MVT::v32i8 && ImmL < 8) ++ Res = DAG.getMachineNode(LoongArch::XVBITSETI_B, SDLoc(N), VT, N2, ++ DAG.getTargetConstant(ImmL, SDLoc(N), MVT::i32)); ++ else if (VT == MVT::v16i16 && ImmL < 16) ++ Res = DAG.getMachineNode(LoongArch::XVBITSETI_H, SDLoc(N), VT, N2, ++ DAG.getTargetConstant(ImmL, SDLoc(N), MVT::i32)); ++ else if (VT == MVT::v8i32 && ImmL < 32) ++ Res = DAG.getMachineNode(LoongArch::XVBITSETI_W, SDLoc(N), VT, N2, ++ DAG.getTargetConstant(ImmL, SDLoc(N), MVT::i32)); ++ else if (VT == MVT::v4i64 && ImmL < 64) ++ Res = DAG.getMachineNode(LoongArch::XVBITSETI_D, SDLoc(N), VT, N2, ++ DAG.getTargetConstant(ImmL, SDLoc(N), MVT::i32)); ++ else ++ return SDValue(); ++ } else if (N->getValueType(0).is128BitVector()) { ++ if (VT == MVT::v16i8 && ImmL < 8) ++ Res = DAG.getMachineNode(LoongArch::VBITSETI_B, SDLoc(N), VT, N2, ++ DAG.getTargetConstant(ImmL, SDLoc(N), MVT::i32)); ++ else if (VT == MVT::v8i16 && ImmL < 16) ++ Res = DAG.getMachineNode(LoongArch::VBITSETI_H, SDLoc(N), VT, N2, ++ DAG.getTargetConstant(ImmL, SDLoc(N), MVT::i32)); ++ else if (VT == MVT::v4i32 && ImmL < 32) ++ Res = DAG.getMachineNode(LoongArch::VBITSETI_W, SDLoc(N), VT, N2, ++ DAG.getTargetConstant(ImmL, SDLoc(N), MVT::i32)); ++ else if (VT == MVT::v2i64 && ImmL < 64) ++ Res = DAG.getMachineNode(LoongArch::VBITSETI_D, SDLoc(N), VT, N2, ++ DAG.getTargetConstant(ImmL, SDLoc(N), MVT::i32)); ++ else ++ return SDValue(); + +- // This is not actually used, but is necessary for successfully matching the +- // PseudoLA_*_LARGE nodes. +- SDValue Tmp = DAG.getConstant(0, DL, Ty); +- SDValue Addr = DAG.getTargetGlobalAddress(N->getGlobal(), DL, Ty, 0, 0); +- SDValue Offset = Large +- ? SDValue(DAG.getMachineNode(Opc, DL, Ty, Tmp, Addr), 0) +- : SDValue(DAG.getMachineNode(Opc, DL, Ty, Addr), 0); ++ } else ++ return SDValue(); + +- // Add the thread pointer. +- return DAG.getNode(ISD::ADD, DL, Ty, Offset, +- DAG.getRegister(LoongArch::R2, GRLenVT)); ++ return SDValue(Res, 0); + } + +-SDValue LoongArchTargetLowering::getDynamicTLSAddr(GlobalAddressSDNode *N, +- SelectionDAG &DAG, +- unsigned Opc, +- bool Large) const { +- SDLoc DL(N); +- EVT Ty = getPointerTy(DAG.getDataLayout()); +- IntegerType *CallTy = Type::getIntNTy(*DAG.getContext(), Ty.getSizeInBits()); +- +- // This is not actually used, but is necessary for successfully matching the +- // PseudoLA_*_LARGE nodes. +- SDValue Tmp = DAG.getConstant(0, DL, Ty); ++static SDValue performORCombine(SDNode *N, SelectionDAG &DAG, ++ TargetLowering::DAGCombinerInfo &DCI, ++ const LoongArchSubtarget &Subtarget) { + +- // Use a PC-relative addressing mode to access the dynamic GOT address. +- SDValue Addr = DAG.getTargetGlobalAddress(N->getGlobal(), DL, Ty, 0, 0); +- SDValue Load = Large ? SDValue(DAG.getMachineNode(Opc, DL, Ty, Tmp, Addr), 0) +- : SDValue(DAG.getMachineNode(Opc, DL, Ty, Addr), 0); ++ SDValue Res; ++ if (Subtarget.hasLSX() && (N->getValueType(0).is128BitVector() || ++ N->getValueType(0).is256BitVector())) { ++ SDValue Op0 = N->getOperand(0); ++ SDValue Op1 = N->getOperand(1); ++ ++ if (Op0->getOpcode() == ISD::AND && Op1->getOpcode() == ISD::AND) { ++ SDValue Op0Op0 = Op0->getOperand(0); ++ SDValue Op0Op1 = Op0->getOperand(1); ++ SDValue Op1Op0 = Op1->getOperand(0); ++ SDValue Op1Op1 = Op1->getOperand(1); ++ ++ SDValue IfSet, IfClr, Cond; ++ bool IsConstantMask = false; ++ APInt Mask, InvMask; ++ ++ // If Op0Op0 is an appropriate mask, try to find it's inverse in either ++ // Op1Op0, or Op1Op1. Keep track of the Cond, IfSet, and IfClr nodes, ++ // while looking. IfClr will be set if we find a valid match. ++ if (isVSplat(Op0Op0, Mask)) { ++ Cond = Op0Op0; ++ IfSet = Op0Op1; ++ ++ if (isVSplat(Op1Op0, InvMask) && ++ Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask) ++ IfClr = Op1Op1; ++ else if (isVSplat(Op1Op1, InvMask) && ++ Mask.getBitWidth() == InvMask.getBitWidth() && ++ Mask == ~InvMask) ++ IfClr = Op1Op0; ++ ++ IsConstantMask = true; ++ } + +- // Prepare argument list to generate call. +- ArgListTy Args; +- ArgListEntry Entry; +- Entry.Node = Load; +- Entry.Ty = CallTy; +- Args.push_back(Entry); ++ // If IfClr is not yet set, and Op0Op1 is an appropriate mask, try the ++ // same thing again using this mask. IfClr will be set if we find a valid ++ // match. ++ if (!IfClr.getNode() && isVSplat(Op0Op1, Mask)) { ++ Cond = Op0Op1; ++ IfSet = Op0Op0; ++ ++ if (isVSplat(Op1Op0, InvMask) && ++ Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask) ++ IfClr = Op1Op1; ++ else if (isVSplat(Op1Op1, InvMask) && ++ Mask.getBitWidth() == InvMask.getBitWidth() && ++ Mask == ~InvMask) ++ IfClr = Op1Op0; ++ ++ IsConstantMask = true; ++ } + +- // Setup call to __tls_get_addr. +- TargetLowering::CallLoweringInfo CLI(DAG); +- CLI.setDebugLoc(DL) +- .setChain(DAG.getEntryNode()) +- .setLibCallee(CallingConv::C, CallTy, +- DAG.getExternalSymbol("__tls_get_addr", Ty), +- std::move(Args)); ++ // If IfClr is not yet set, try looking for a non-constant match. ++ // IfClr will be set if we find a valid match amongst the eight ++ // possibilities. ++ if (!IfClr.getNode()) { ++ if (isBitwiseInverse(Op0Op0, Op1Op0)) { ++ Cond = Op1Op0; ++ IfSet = Op1Op1; ++ IfClr = Op0Op1; ++ } else if (isBitwiseInverse(Op0Op1, Op1Op0)) { ++ Cond = Op1Op0; ++ IfSet = Op1Op1; ++ IfClr = Op0Op0; ++ } else if (isBitwiseInverse(Op0Op0, Op1Op1)) { ++ Cond = Op1Op1; ++ IfSet = Op1Op0; ++ IfClr = Op0Op1; ++ } else if (isBitwiseInverse(Op0Op1, Op1Op1)) { ++ Cond = Op1Op1; ++ IfSet = Op1Op0; ++ IfClr = Op0Op0; ++ } else if (isBitwiseInverse(Op1Op0, Op0Op0)) { ++ Cond = Op0Op0; ++ IfSet = Op0Op1; ++ IfClr = Op1Op1; ++ } else if (isBitwiseInverse(Op1Op1, Op0Op0)) { ++ Cond = Op0Op0; ++ IfSet = Op0Op1; ++ IfClr = Op1Op0; ++ } else if (isBitwiseInverse(Op1Op0, Op0Op1)) { ++ Cond = Op0Op1; ++ IfSet = Op0Op0; ++ IfClr = Op1Op1; ++ } else if (isBitwiseInverse(Op1Op1, Op0Op1)) { ++ Cond = Op0Op1; ++ IfSet = Op0Op0; ++ IfClr = Op1Op0; ++ } ++ } + +- return LowerCallTo(CLI).first; +-} ++ // At this point, IfClr will be set if we have a valid match. ++ if (IfClr.getNode()) { ++ assert(Cond.getNode() && IfSet.getNode()); + +-SDValue +-LoongArchTargetLowering::lowerGlobalTLSAddress(SDValue Op, +- SelectionDAG &DAG) const { +- if (DAG.getMachineFunction().getFunction().getCallingConv() == +- CallingConv::GHC) +- report_fatal_error("In GHC calling convention TLS is not supported"); ++ // Fold degenerate cases. ++ if (IsConstantMask) { ++ if (Mask.isAllOnes()) ++ return IfSet; ++ else if (Mask == 0) ++ return IfClr; ++ } + +- bool Large = DAG.getTarget().getCodeModel() == CodeModel::Large; +- assert((!Large || Subtarget.is64Bit()) && "Large code model requires LA64"); ++ // Transform the DAG into an equivalent VSELECT. ++ return DAG.getNode(ISD::VSELECT, SDLoc(N), N->getValueType(0), Cond, ++ IfSet, IfClr); ++ } ++ } + +- GlobalAddressSDNode *N = cast(Op); +- assert(N->getOffset() == 0 && "unexpected offset in global node"); +- +- SDValue Addr; +- switch (getTargetMachine().getTLSModel(N->getGlobal())) { +- case TLSModel::GeneralDynamic: +- // In this model, application code calls the dynamic linker function +- // __tls_get_addr to locate TLS offsets into the dynamic thread vector at +- // runtime. +- Addr = getDynamicTLSAddr(N, DAG, +- Large ? LoongArch::PseudoLA_TLS_GD_LARGE +- : LoongArch::PseudoLA_TLS_GD, +- Large); +- break; +- case TLSModel::LocalDynamic: +- // Same as GeneralDynamic, except for assembly modifiers and relocation +- // records. +- Addr = getDynamicTLSAddr(N, DAG, +- Large ? LoongArch::PseudoLA_TLS_LD_LARGE +- : LoongArch::PseudoLA_TLS_LD, +- Large); +- break; +- case TLSModel::InitialExec: +- // This model uses the GOT to resolve TLS offsets. +- Addr = getStaticTLSAddr(N, DAG, +- Large ? LoongArch::PseudoLA_TLS_IE_LARGE +- : LoongArch::PseudoLA_TLS_IE, +- Large); +- break; +- case TLSModel::LocalExec: +- // This model is used when static linking as the TLS offsets are resolved +- // during program linking. +- // +- // This node doesn't need an extra argument for the large code model. +- Addr = getStaticTLSAddr(N, DAG, LoongArch::PseudoLA_TLS_LE); +- break; ++ if (Res = performSet(N, DAG, DCI, Subtarget)) ++ return Res; + } + +- return Addr; +-} ++ // Pattern match BSTRINS. ++ // $dst = or (and $src1 , mask0), (and (shl $src, lsb), mask1), ++ // where mask1 = (2**size - 1) << lsb, mask0 = ~mask1 ++ // => bstrins $dst, $src, lsb+size-1, lsb, $src1 ++ if (DCI.isBeforeLegalizeOps()) ++ return SDValue(); + +-template +-static SDValue checkIntrinsicImmArg(SDValue Op, unsigned ImmOp, +- SelectionDAG &DAG, bool IsSigned = false) { +- auto *CImm = cast(Op->getOperand(ImmOp)); +- // Check the ImmArg. +- if ((IsSigned && !isInt(CImm->getSExtValue())) || +- (!IsSigned && !isUInt(CImm->getZExtValue()))) { +- DAG.getContext()->emitError(Op->getOperationName(0) + +- ": argument out of range."); +- return DAG.getNode(ISD::UNDEF, SDLoc(Op), Op.getValueType()); +- } +- return SDValue(); +-} ++ SDValue And0 = N->getOperand(0), And1 = N->getOperand(1); ++ uint64_t SMLsb0, SMSize0, SMLsb1, SMSize1; ++ ConstantSDNode *CN, *CN1; + +-SDValue +-LoongArchTargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op, +- SelectionDAG &DAG) const { +- SDLoc DL(Op); +- switch (Op.getConstantOperandVal(0)) { +- default: +- return SDValue(); // Don't custom lower most intrinsics. +- case Intrinsic::thread_pointer: { +- EVT PtrVT = getPointerTy(DAG.getDataLayout()); +- return DAG.getRegister(LoongArch::R2, PtrVT); +- } +- case Intrinsic::loongarch_lsx_vpickve2gr_d: +- case Intrinsic::loongarch_lsx_vpickve2gr_du: +- case Intrinsic::loongarch_lsx_vreplvei_d: +- case Intrinsic::loongarch_lasx_xvrepl128vei_d: +- return checkIntrinsicImmArg<1>(Op, 2, DAG); +- case Intrinsic::loongarch_lsx_vreplvei_w: +- case Intrinsic::loongarch_lasx_xvrepl128vei_w: +- case Intrinsic::loongarch_lasx_xvpickve2gr_d: +- case Intrinsic::loongarch_lasx_xvpickve2gr_du: +- case Intrinsic::loongarch_lasx_xvpickve_d: +- case Intrinsic::loongarch_lasx_xvpickve_d_f: +- return checkIntrinsicImmArg<2>(Op, 2, DAG); +- case Intrinsic::loongarch_lasx_xvinsve0_d: +- return checkIntrinsicImmArg<2>(Op, 3, DAG); +- case Intrinsic::loongarch_lsx_vsat_b: +- case Intrinsic::loongarch_lsx_vsat_bu: +- case Intrinsic::loongarch_lsx_vrotri_b: +- case Intrinsic::loongarch_lsx_vsllwil_h_b: +- case Intrinsic::loongarch_lsx_vsllwil_hu_bu: +- case Intrinsic::loongarch_lsx_vsrlri_b: +- case Intrinsic::loongarch_lsx_vsrari_b: +- case Intrinsic::loongarch_lsx_vreplvei_h: +- case Intrinsic::loongarch_lasx_xvsat_b: +- case Intrinsic::loongarch_lasx_xvsat_bu: +- case Intrinsic::loongarch_lasx_xvrotri_b: +- case Intrinsic::loongarch_lasx_xvsllwil_h_b: +- case Intrinsic::loongarch_lasx_xvsllwil_hu_bu: +- case Intrinsic::loongarch_lasx_xvsrlri_b: +- case Intrinsic::loongarch_lasx_xvsrari_b: +- case Intrinsic::loongarch_lasx_xvrepl128vei_h: +- case Intrinsic::loongarch_lasx_xvpickve_w: +- case Intrinsic::loongarch_lasx_xvpickve_w_f: +- return checkIntrinsicImmArg<3>(Op, 2, DAG); +- case Intrinsic::loongarch_lasx_xvinsve0_w: +- return checkIntrinsicImmArg<3>(Op, 3, DAG); +- case Intrinsic::loongarch_lsx_vsat_h: +- case Intrinsic::loongarch_lsx_vsat_hu: +- case Intrinsic::loongarch_lsx_vrotri_h: +- case Intrinsic::loongarch_lsx_vsllwil_w_h: +- case Intrinsic::loongarch_lsx_vsllwil_wu_hu: +- case Intrinsic::loongarch_lsx_vsrlri_h: +- case Intrinsic::loongarch_lsx_vsrari_h: +- case Intrinsic::loongarch_lsx_vreplvei_b: +- case Intrinsic::loongarch_lasx_xvsat_h: +- case Intrinsic::loongarch_lasx_xvsat_hu: +- case Intrinsic::loongarch_lasx_xvrotri_h: +- case Intrinsic::loongarch_lasx_xvsllwil_w_h: +- case Intrinsic::loongarch_lasx_xvsllwil_wu_hu: +- case Intrinsic::loongarch_lasx_xvsrlri_h: +- case Intrinsic::loongarch_lasx_xvsrari_h: +- case Intrinsic::loongarch_lasx_xvrepl128vei_b: +- return checkIntrinsicImmArg<4>(Op, 2, DAG); +- case Intrinsic::loongarch_lsx_vsrlni_b_h: +- case Intrinsic::loongarch_lsx_vsrani_b_h: +- case Intrinsic::loongarch_lsx_vsrlrni_b_h: +- case Intrinsic::loongarch_lsx_vsrarni_b_h: +- case Intrinsic::loongarch_lsx_vssrlni_b_h: +- case Intrinsic::loongarch_lsx_vssrani_b_h: +- case Intrinsic::loongarch_lsx_vssrlni_bu_h: +- case Intrinsic::loongarch_lsx_vssrani_bu_h: +- case Intrinsic::loongarch_lsx_vssrlrni_b_h: +- case Intrinsic::loongarch_lsx_vssrarni_b_h: +- case Intrinsic::loongarch_lsx_vssrlrni_bu_h: +- case Intrinsic::loongarch_lsx_vssrarni_bu_h: +- case Intrinsic::loongarch_lasx_xvsrlni_b_h: +- case Intrinsic::loongarch_lasx_xvsrani_b_h: +- case Intrinsic::loongarch_lasx_xvsrlrni_b_h: +- case Intrinsic::loongarch_lasx_xvsrarni_b_h: +- case Intrinsic::loongarch_lasx_xvssrlni_b_h: +- case Intrinsic::loongarch_lasx_xvssrani_b_h: +- case Intrinsic::loongarch_lasx_xvssrlni_bu_h: +- case Intrinsic::loongarch_lasx_xvssrani_bu_h: +- case Intrinsic::loongarch_lasx_xvssrlrni_b_h: +- case Intrinsic::loongarch_lasx_xvssrarni_b_h: +- case Intrinsic::loongarch_lasx_xvssrlrni_bu_h: +- case Intrinsic::loongarch_lasx_xvssrarni_bu_h: +- return checkIntrinsicImmArg<4>(Op, 3, DAG); +- case Intrinsic::loongarch_lsx_vsat_w: +- case Intrinsic::loongarch_lsx_vsat_wu: +- case Intrinsic::loongarch_lsx_vrotri_w: +- case Intrinsic::loongarch_lsx_vsllwil_d_w: +- case Intrinsic::loongarch_lsx_vsllwil_du_wu: +- case Intrinsic::loongarch_lsx_vsrlri_w: +- case Intrinsic::loongarch_lsx_vsrari_w: +- case Intrinsic::loongarch_lsx_vslei_bu: +- case Intrinsic::loongarch_lsx_vslei_hu: +- case Intrinsic::loongarch_lsx_vslei_wu: +- case Intrinsic::loongarch_lsx_vslei_du: +- case Intrinsic::loongarch_lsx_vslti_bu: +- case Intrinsic::loongarch_lsx_vslti_hu: +- case Intrinsic::loongarch_lsx_vslti_wu: +- case Intrinsic::loongarch_lsx_vslti_du: +- case Intrinsic::loongarch_lsx_vbsll_v: +- case Intrinsic::loongarch_lsx_vbsrl_v: +- case Intrinsic::loongarch_lasx_xvsat_w: +- case Intrinsic::loongarch_lasx_xvsat_wu: +- case Intrinsic::loongarch_lasx_xvrotri_w: +- case Intrinsic::loongarch_lasx_xvsllwil_d_w: +- case Intrinsic::loongarch_lasx_xvsllwil_du_wu: +- case Intrinsic::loongarch_lasx_xvsrlri_w: +- case Intrinsic::loongarch_lasx_xvsrari_w: +- case Intrinsic::loongarch_lasx_xvslei_bu: +- case Intrinsic::loongarch_lasx_xvslei_hu: +- case Intrinsic::loongarch_lasx_xvslei_wu: +- case Intrinsic::loongarch_lasx_xvslei_du: +- case Intrinsic::loongarch_lasx_xvslti_bu: +- case Intrinsic::loongarch_lasx_xvslti_hu: +- case Intrinsic::loongarch_lasx_xvslti_wu: +- case Intrinsic::loongarch_lasx_xvslti_du: +- case Intrinsic::loongarch_lasx_xvbsll_v: +- case Intrinsic::loongarch_lasx_xvbsrl_v: +- return checkIntrinsicImmArg<5>(Op, 2, DAG); +- case Intrinsic::loongarch_lsx_vseqi_b: +- case Intrinsic::loongarch_lsx_vseqi_h: +- case Intrinsic::loongarch_lsx_vseqi_w: +- case Intrinsic::loongarch_lsx_vseqi_d: +- case Intrinsic::loongarch_lsx_vslei_b: +- case Intrinsic::loongarch_lsx_vslei_h: +- case Intrinsic::loongarch_lsx_vslei_w: +- case Intrinsic::loongarch_lsx_vslei_d: +- case Intrinsic::loongarch_lsx_vslti_b: +- case Intrinsic::loongarch_lsx_vslti_h: +- case Intrinsic::loongarch_lsx_vslti_w: +- case Intrinsic::loongarch_lsx_vslti_d: +- case Intrinsic::loongarch_lasx_xvseqi_b: +- case Intrinsic::loongarch_lasx_xvseqi_h: +- case Intrinsic::loongarch_lasx_xvseqi_w: +- case Intrinsic::loongarch_lasx_xvseqi_d: +- case Intrinsic::loongarch_lasx_xvslei_b: +- case Intrinsic::loongarch_lasx_xvslei_h: +- case Intrinsic::loongarch_lasx_xvslei_w: +- case Intrinsic::loongarch_lasx_xvslei_d: +- case Intrinsic::loongarch_lasx_xvslti_b: +- case Intrinsic::loongarch_lasx_xvslti_h: +- case Intrinsic::loongarch_lasx_xvslti_w: +- case Intrinsic::loongarch_lasx_xvslti_d: +- return checkIntrinsicImmArg<5>(Op, 2, DAG, /*IsSigned=*/true); +- case Intrinsic::loongarch_lsx_vsrlni_h_w: +- case Intrinsic::loongarch_lsx_vsrani_h_w: +- case Intrinsic::loongarch_lsx_vsrlrni_h_w: +- case Intrinsic::loongarch_lsx_vsrarni_h_w: +- case Intrinsic::loongarch_lsx_vssrlni_h_w: +- case Intrinsic::loongarch_lsx_vssrani_h_w: +- case Intrinsic::loongarch_lsx_vssrlni_hu_w: +- case Intrinsic::loongarch_lsx_vssrani_hu_w: +- case Intrinsic::loongarch_lsx_vssrlrni_h_w: +- case Intrinsic::loongarch_lsx_vssrarni_h_w: +- case Intrinsic::loongarch_lsx_vssrlrni_hu_w: +- case Intrinsic::loongarch_lsx_vssrarni_hu_w: +- case Intrinsic::loongarch_lsx_vfrstpi_b: +- case Intrinsic::loongarch_lsx_vfrstpi_h: +- case Intrinsic::loongarch_lasx_xvsrlni_h_w: +- case Intrinsic::loongarch_lasx_xvsrani_h_w: +- case Intrinsic::loongarch_lasx_xvsrlrni_h_w: +- case Intrinsic::loongarch_lasx_xvsrarni_h_w: +- case Intrinsic::loongarch_lasx_xvssrlni_h_w: +- case Intrinsic::loongarch_lasx_xvssrani_h_w: +- case Intrinsic::loongarch_lasx_xvssrlni_hu_w: +- case Intrinsic::loongarch_lasx_xvssrani_hu_w: +- case Intrinsic::loongarch_lasx_xvssrlrni_h_w: +- case Intrinsic::loongarch_lasx_xvssrarni_h_w: +- case Intrinsic::loongarch_lasx_xvssrlrni_hu_w: +- case Intrinsic::loongarch_lasx_xvssrarni_hu_w: +- case Intrinsic::loongarch_lasx_xvfrstpi_b: +- case Intrinsic::loongarch_lasx_xvfrstpi_h: +- return checkIntrinsicImmArg<5>(Op, 3, DAG); +- case Intrinsic::loongarch_lsx_vsat_d: +- case Intrinsic::loongarch_lsx_vsat_du: +- case Intrinsic::loongarch_lsx_vrotri_d: +- case Intrinsic::loongarch_lsx_vsrlri_d: +- case Intrinsic::loongarch_lsx_vsrari_d: +- case Intrinsic::loongarch_lasx_xvsat_d: +- case Intrinsic::loongarch_lasx_xvsat_du: +- case Intrinsic::loongarch_lasx_xvrotri_d: +- case Intrinsic::loongarch_lasx_xvsrlri_d: +- case Intrinsic::loongarch_lasx_xvsrari_d: +- return checkIntrinsicImmArg<6>(Op, 2, DAG); +- case Intrinsic::loongarch_lsx_vsrlni_w_d: +- case Intrinsic::loongarch_lsx_vsrani_w_d: +- case Intrinsic::loongarch_lsx_vsrlrni_w_d: +- case Intrinsic::loongarch_lsx_vsrarni_w_d: +- case Intrinsic::loongarch_lsx_vssrlni_w_d: +- case Intrinsic::loongarch_lsx_vssrani_w_d: +- case Intrinsic::loongarch_lsx_vssrlni_wu_d: +- case Intrinsic::loongarch_lsx_vssrani_wu_d: +- case Intrinsic::loongarch_lsx_vssrlrni_w_d: +- case Intrinsic::loongarch_lsx_vssrarni_w_d: +- case Intrinsic::loongarch_lsx_vssrlrni_wu_d: +- case Intrinsic::loongarch_lsx_vssrarni_wu_d: +- case Intrinsic::loongarch_lasx_xvsrlni_w_d: +- case Intrinsic::loongarch_lasx_xvsrani_w_d: +- case Intrinsic::loongarch_lasx_xvsrlrni_w_d: +- case Intrinsic::loongarch_lasx_xvsrarni_w_d: +- case Intrinsic::loongarch_lasx_xvssrlni_w_d: +- case Intrinsic::loongarch_lasx_xvssrani_w_d: +- case Intrinsic::loongarch_lasx_xvssrlni_wu_d: +- case Intrinsic::loongarch_lasx_xvssrani_wu_d: +- case Intrinsic::loongarch_lasx_xvssrlrni_w_d: +- case Intrinsic::loongarch_lasx_xvssrarni_w_d: +- case Intrinsic::loongarch_lasx_xvssrlrni_wu_d: +- case Intrinsic::loongarch_lasx_xvssrarni_wu_d: +- return checkIntrinsicImmArg<6>(Op, 3, DAG); +- case Intrinsic::loongarch_lsx_vsrlni_d_q: +- case Intrinsic::loongarch_lsx_vsrani_d_q: +- case Intrinsic::loongarch_lsx_vsrlrni_d_q: +- case Intrinsic::loongarch_lsx_vsrarni_d_q: +- case Intrinsic::loongarch_lsx_vssrlni_d_q: +- case Intrinsic::loongarch_lsx_vssrani_d_q: +- case Intrinsic::loongarch_lsx_vssrlni_du_q: +- case Intrinsic::loongarch_lsx_vssrani_du_q: +- case Intrinsic::loongarch_lsx_vssrlrni_d_q: +- case Intrinsic::loongarch_lsx_vssrarni_d_q: +- case Intrinsic::loongarch_lsx_vssrlrni_du_q: +- case Intrinsic::loongarch_lsx_vssrarni_du_q: +- case Intrinsic::loongarch_lasx_xvsrlni_d_q: +- case Intrinsic::loongarch_lasx_xvsrani_d_q: +- case Intrinsic::loongarch_lasx_xvsrlrni_d_q: +- case Intrinsic::loongarch_lasx_xvsrarni_d_q: +- case Intrinsic::loongarch_lasx_xvssrlni_d_q: +- case Intrinsic::loongarch_lasx_xvssrani_d_q: +- case Intrinsic::loongarch_lasx_xvssrlni_du_q: +- case Intrinsic::loongarch_lasx_xvssrani_du_q: +- case Intrinsic::loongarch_lasx_xvssrlrni_d_q: +- case Intrinsic::loongarch_lasx_xvssrarni_d_q: +- case Intrinsic::loongarch_lasx_xvssrlrni_du_q: +- case Intrinsic::loongarch_lasx_xvssrarni_du_q: +- return checkIntrinsicImmArg<7>(Op, 3, DAG); +- case Intrinsic::loongarch_lsx_vnori_b: +- case Intrinsic::loongarch_lsx_vshuf4i_b: +- case Intrinsic::loongarch_lsx_vshuf4i_h: +- case Intrinsic::loongarch_lsx_vshuf4i_w: +- case Intrinsic::loongarch_lasx_xvnori_b: +- case Intrinsic::loongarch_lasx_xvshuf4i_b: +- case Intrinsic::loongarch_lasx_xvshuf4i_h: +- case Intrinsic::loongarch_lasx_xvshuf4i_w: +- case Intrinsic::loongarch_lasx_xvpermi_d: +- return checkIntrinsicImmArg<8>(Op, 2, DAG); +- case Intrinsic::loongarch_lsx_vshuf4i_d: +- case Intrinsic::loongarch_lsx_vpermi_w: +- case Intrinsic::loongarch_lsx_vbitseli_b: +- case Intrinsic::loongarch_lsx_vextrins_b: +- case Intrinsic::loongarch_lsx_vextrins_h: +- case Intrinsic::loongarch_lsx_vextrins_w: +- case Intrinsic::loongarch_lsx_vextrins_d: +- case Intrinsic::loongarch_lasx_xvshuf4i_d: +- case Intrinsic::loongarch_lasx_xvpermi_w: +- case Intrinsic::loongarch_lasx_xvpermi_q: +- case Intrinsic::loongarch_lasx_xvbitseli_b: +- case Intrinsic::loongarch_lasx_xvextrins_b: +- case Intrinsic::loongarch_lasx_xvextrins_h: +- case Intrinsic::loongarch_lasx_xvextrins_w: +- case Intrinsic::loongarch_lasx_xvextrins_d: +- return checkIntrinsicImmArg<8>(Op, 3, DAG); +- case Intrinsic::loongarch_lsx_vrepli_b: +- case Intrinsic::loongarch_lsx_vrepli_h: +- case Intrinsic::loongarch_lsx_vrepli_w: +- case Intrinsic::loongarch_lsx_vrepli_d: +- case Intrinsic::loongarch_lasx_xvrepli_b: +- case Intrinsic::loongarch_lasx_xvrepli_h: +- case Intrinsic::loongarch_lasx_xvrepli_w: +- case Intrinsic::loongarch_lasx_xvrepli_d: +- return checkIntrinsicImmArg<10>(Op, 1, DAG, /*IsSigned=*/true); +- case Intrinsic::loongarch_lsx_vldi: +- case Intrinsic::loongarch_lasx_xvldi: +- return checkIntrinsicImmArg<13>(Op, 1, DAG, /*IsSigned=*/true); +- } +-} +- +-// Helper function that emits error message for intrinsics with chain and return +-// merge values of a UNDEF and the chain. +-static SDValue emitIntrinsicWithChainErrorMessage(SDValue Op, +- StringRef ErrorMsg, +- SelectionDAG &DAG) { +- DAG.getContext()->emitError(Op->getOperationName(0) + ": " + ErrorMsg + "."); +- return DAG.getMergeValues({DAG.getUNDEF(Op.getValueType()), Op.getOperand(0)}, +- SDLoc(Op)); +-} ++ // See if Op's first operand matches (and $src1 , mask0). ++ if (And0.getOpcode() != ISD::AND) ++ return SDValue(); + +-SDValue +-LoongArchTargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op, +- SelectionDAG &DAG) const { +- SDLoc DL(Op); +- MVT GRLenVT = Subtarget.getGRLenVT(); +- EVT VT = Op.getValueType(); +- SDValue Chain = Op.getOperand(0); +- const StringRef ErrorMsgOOR = "argument out of range"; +- const StringRef ErrorMsgReqLA64 = "requires loongarch64"; +- const StringRef ErrorMsgReqF = "requires basic 'f' target feature"; ++ if (!(CN = dyn_cast(And0.getOperand(1))) || ++ !isShiftedMask(~CN->getSExtValue(), SMLsb0, SMSize0)) ++ return SDValue(); + +- switch (Op.getConstantOperandVal(1)) { +- default: +- return Op; +- case Intrinsic::loongarch_crc_w_b_w: +- case Intrinsic::loongarch_crc_w_h_w: +- case Intrinsic::loongarch_crc_w_w_w: +- case Intrinsic::loongarch_crc_w_d_w: +- case Intrinsic::loongarch_crcc_w_b_w: +- case Intrinsic::loongarch_crcc_w_h_w: +- case Intrinsic::loongarch_crcc_w_w_w: +- case Intrinsic::loongarch_crcc_w_d_w: +- return emitIntrinsicWithChainErrorMessage(Op, ErrorMsgReqLA64, DAG); +- case Intrinsic::loongarch_csrrd_w: +- case Intrinsic::loongarch_csrrd_d: { +- unsigned Imm = Op.getConstantOperandVal(2); +- return !isUInt<14>(Imm) +- ? emitIntrinsicWithChainErrorMessage(Op, ErrorMsgOOR, DAG) +- : DAG.getNode(LoongArchISD::CSRRD, DL, {GRLenVT, MVT::Other}, +- {Chain, DAG.getConstant(Imm, DL, GRLenVT)}); +- } +- case Intrinsic::loongarch_csrwr_w: +- case Intrinsic::loongarch_csrwr_d: { +- unsigned Imm = Op.getConstantOperandVal(3); +- return !isUInt<14>(Imm) +- ? emitIntrinsicWithChainErrorMessage(Op, ErrorMsgOOR, DAG) +- : DAG.getNode(LoongArchISD::CSRWR, DL, {GRLenVT, MVT::Other}, +- {Chain, Op.getOperand(2), +- DAG.getConstant(Imm, DL, GRLenVT)}); +- } +- case Intrinsic::loongarch_csrxchg_w: +- case Intrinsic::loongarch_csrxchg_d: { +- unsigned Imm = Op.getConstantOperandVal(4); +- return !isUInt<14>(Imm) +- ? emitIntrinsicWithChainErrorMessage(Op, ErrorMsgOOR, DAG) +- : DAG.getNode(LoongArchISD::CSRXCHG, DL, {GRLenVT, MVT::Other}, +- {Chain, Op.getOperand(2), Op.getOperand(3), +- DAG.getConstant(Imm, DL, GRLenVT)}); +- } +- case Intrinsic::loongarch_iocsrrd_d: { +- return DAG.getNode( +- LoongArchISD::IOCSRRD_D, DL, {GRLenVT, MVT::Other}, +- {Chain, DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op.getOperand(2))}); +- } +-#define IOCSRRD_CASE(NAME, NODE) \ +- case Intrinsic::loongarch_##NAME: { \ +- return DAG.getNode(LoongArchISD::NODE, DL, {GRLenVT, MVT::Other}, \ +- {Chain, Op.getOperand(2)}); \ +- } +- IOCSRRD_CASE(iocsrrd_b, IOCSRRD_B); +- IOCSRRD_CASE(iocsrrd_h, IOCSRRD_H); +- IOCSRRD_CASE(iocsrrd_w, IOCSRRD_W); +-#undef IOCSRRD_CASE +- case Intrinsic::loongarch_cpucfg: { +- return DAG.getNode(LoongArchISD::CPUCFG, DL, {GRLenVT, MVT::Other}, +- {Chain, Op.getOperand(2)}); +- } +- case Intrinsic::loongarch_lddir_d: { +- unsigned Imm = Op.getConstantOperandVal(3); +- return !isUInt<8>(Imm) +- ? emitIntrinsicWithChainErrorMessage(Op, ErrorMsgOOR, DAG) +- : Op; +- } +- case Intrinsic::loongarch_movfcsr2gr: { +- if (!Subtarget.hasBasicF()) +- return emitIntrinsicWithChainErrorMessage(Op, ErrorMsgReqF, DAG); +- unsigned Imm = Op.getConstantOperandVal(2); +- return !isUInt<2>(Imm) +- ? emitIntrinsicWithChainErrorMessage(Op, ErrorMsgOOR, DAG) +- : DAG.getNode(LoongArchISD::MOVFCSR2GR, DL, {VT, MVT::Other}, +- {Chain, DAG.getConstant(Imm, DL, GRLenVT)}); +- } +- case Intrinsic::loongarch_lsx_vld: +- case Intrinsic::loongarch_lsx_vldrepl_b: +- case Intrinsic::loongarch_lasx_xvld: +- case Intrinsic::loongarch_lasx_xvldrepl_b: +- return !isInt<12>(cast(Op.getOperand(3))->getSExtValue()) +- ? emitIntrinsicWithChainErrorMessage(Op, ErrorMsgOOR, DAG) +- : SDValue(); +- case Intrinsic::loongarch_lsx_vldrepl_h: +- case Intrinsic::loongarch_lasx_xvldrepl_h: +- return !isShiftedInt<11, 1>( +- cast(Op.getOperand(3))->getSExtValue()) +- ? emitIntrinsicWithChainErrorMessage( +- Op, "argument out of range or not a multiple of 2", DAG) +- : SDValue(); +- case Intrinsic::loongarch_lsx_vldrepl_w: +- case Intrinsic::loongarch_lasx_xvldrepl_w: +- return !isShiftedInt<10, 2>( +- cast(Op.getOperand(3))->getSExtValue()) +- ? emitIntrinsicWithChainErrorMessage( +- Op, "argument out of range or not a multiple of 4", DAG) +- : SDValue(); +- case Intrinsic::loongarch_lsx_vldrepl_d: +- case Intrinsic::loongarch_lasx_xvldrepl_d: +- return !isShiftedInt<9, 3>( +- cast(Op.getOperand(3))->getSExtValue()) +- ? emitIntrinsicWithChainErrorMessage( +- Op, "argument out of range or not a multiple of 8", DAG) +- : SDValue(); +- } +-} ++ // See if Op's second operand matches (and (shl $src, lsb), mask1). ++ if (And1.getOpcode() == ISD::AND && ++ And1.getOperand(0).getOpcode() == ISD::SHL) { + +-// Helper function that emits error message for intrinsics with void return +-// value and return the chain. +-static SDValue emitIntrinsicErrorMessage(SDValue Op, StringRef ErrorMsg, +- SelectionDAG &DAG) { ++ if (!(CN = dyn_cast(And1.getOperand(1))) || ++ !isShiftedMask(CN->getZExtValue(), SMLsb1, SMSize1)) ++ return SDValue(); + +- DAG.getContext()->emitError(Op->getOperationName(0) + ": " + ErrorMsg + "."); +- return Op.getOperand(0); +-} ++ // The shift masks must have the same least significant bit and size. ++ if (SMLsb0 != SMLsb1 || SMSize0 != SMSize1) ++ return SDValue(); + +-SDValue LoongArchTargetLowering::lowerINTRINSIC_VOID(SDValue Op, +- SelectionDAG &DAG) const { +- SDLoc DL(Op); +- MVT GRLenVT = Subtarget.getGRLenVT(); +- SDValue Chain = Op.getOperand(0); +- uint64_t IntrinsicEnum = Op.getConstantOperandVal(1); +- SDValue Op2 = Op.getOperand(2); +- const StringRef ErrorMsgOOR = "argument out of range"; +- const StringRef ErrorMsgReqLA64 = "requires loongarch64"; +- const StringRef ErrorMsgReqLA32 = "requires loongarch32"; +- const StringRef ErrorMsgReqF = "requires basic 'f' target feature"; +- +- switch (IntrinsicEnum) { +- default: +- // TODO: Add more Intrinsics. +- return SDValue(); +- case Intrinsic::loongarch_cacop_d: +- case Intrinsic::loongarch_cacop_w: { +- if (IntrinsicEnum == Intrinsic::loongarch_cacop_d && !Subtarget.is64Bit()) +- return emitIntrinsicErrorMessage(Op, ErrorMsgReqLA64, DAG); +- if (IntrinsicEnum == Intrinsic::loongarch_cacop_w && Subtarget.is64Bit()) +- return emitIntrinsicErrorMessage(Op, ErrorMsgReqLA32, DAG); +- // call void @llvm.loongarch.cacop.[d/w](uimm5, rj, simm12) +- unsigned Imm1 = Op2->getAsZExtVal(); +- int Imm2 = cast(Op.getOperand(4))->getSExtValue(); +- if (!isUInt<5>(Imm1) || !isInt<12>(Imm2)) +- return emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG); +- return Op; +- } +- case Intrinsic::loongarch_dbar: { +- unsigned Imm = Op2->getAsZExtVal(); +- return !isUInt<15>(Imm) +- ? emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG) +- : DAG.getNode(LoongArchISD::DBAR, DL, MVT::Other, Chain, +- DAG.getConstant(Imm, DL, GRLenVT)); +- } +- case Intrinsic::loongarch_ibar: { +- unsigned Imm = Op2->getAsZExtVal(); +- return !isUInt<15>(Imm) +- ? emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG) +- : DAG.getNode(LoongArchISD::IBAR, DL, MVT::Other, Chain, +- DAG.getConstant(Imm, DL, GRLenVT)); +- } +- case Intrinsic::loongarch_break: { +- unsigned Imm = Op2->getAsZExtVal(); +- return !isUInt<15>(Imm) +- ? emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG) +- : DAG.getNode(LoongArchISD::BREAK, DL, MVT::Other, Chain, +- DAG.getConstant(Imm, DL, GRLenVT)); +- } +- case Intrinsic::loongarch_movgr2fcsr: { +- if (!Subtarget.hasBasicF()) +- return emitIntrinsicErrorMessage(Op, ErrorMsgReqF, DAG); +- unsigned Imm = Op2->getAsZExtVal(); +- return !isUInt<2>(Imm) +- ? emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG) +- : DAG.getNode(LoongArchISD::MOVGR2FCSR, DL, MVT::Other, Chain, +- DAG.getConstant(Imm, DL, GRLenVT), +- DAG.getNode(ISD::ANY_EXTEND, DL, GRLenVT, +- Op.getOperand(3))); +- } +- case Intrinsic::loongarch_syscall: { +- unsigned Imm = Op2->getAsZExtVal(); +- return !isUInt<15>(Imm) +- ? emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG) +- : DAG.getNode(LoongArchISD::SYSCALL, DL, MVT::Other, Chain, +- DAG.getConstant(Imm, DL, GRLenVT)); +- } +-#define IOCSRWR_CASE(NAME, NODE) \ +- case Intrinsic::loongarch_##NAME: { \ +- SDValue Op3 = Op.getOperand(3); \ +- return Subtarget.is64Bit() \ +- ? DAG.getNode(LoongArchISD::NODE, DL, MVT::Other, Chain, \ +- DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2), \ +- DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op3)) \ +- : DAG.getNode(LoongArchISD::NODE, DL, MVT::Other, Chain, Op2, \ +- Op3); \ +- } +- IOCSRWR_CASE(iocsrwr_b, IOCSRWR_B); +- IOCSRWR_CASE(iocsrwr_h, IOCSRWR_H); +- IOCSRWR_CASE(iocsrwr_w, IOCSRWR_W); +-#undef IOCSRWR_CASE +- case Intrinsic::loongarch_iocsrwr_d: { +- return !Subtarget.is64Bit() +- ? emitIntrinsicErrorMessage(Op, ErrorMsgReqLA64, DAG) +- : DAG.getNode(LoongArchISD::IOCSRWR_D, DL, MVT::Other, Chain, +- Op2, +- DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, +- Op.getOperand(3))); +- } +-#define ASRT_LE_GT_CASE(NAME) \ +- case Intrinsic::loongarch_##NAME: { \ +- return !Subtarget.is64Bit() \ +- ? emitIntrinsicErrorMessage(Op, ErrorMsgReqLA64, DAG) \ +- : Op; \ +- } +- ASRT_LE_GT_CASE(asrtle_d) +- ASRT_LE_GT_CASE(asrtgt_d) +-#undef ASRT_LE_GT_CASE +- case Intrinsic::loongarch_ldpte_d: { +- unsigned Imm = Op.getConstantOperandVal(3); +- return !Subtarget.is64Bit() +- ? emitIntrinsicErrorMessage(Op, ErrorMsgReqLA64, DAG) +- : !isUInt<8>(Imm) ? emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG) +- : Op; +- } +- case Intrinsic::loongarch_lsx_vst: +- case Intrinsic::loongarch_lasx_xvst: +- return !isInt<12>(cast(Op.getOperand(4))->getSExtValue()) +- ? emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG) +- : SDValue(); +- case Intrinsic::loongarch_lasx_xvstelm_b: +- return (!isInt<8>(cast(Op.getOperand(4))->getSExtValue()) || +- !isUInt<5>(Op.getConstantOperandVal(5))) +- ? emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG) +- : SDValue(); +- case Intrinsic::loongarch_lsx_vstelm_b: +- return (!isInt<8>(cast(Op.getOperand(4))->getSExtValue()) || +- !isUInt<4>(Op.getConstantOperandVal(5))) +- ? emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG) +- : SDValue(); +- case Intrinsic::loongarch_lasx_xvstelm_h: +- return (!isShiftedInt<8, 1>( +- cast(Op.getOperand(4))->getSExtValue()) || +- !isUInt<4>(Op.getConstantOperandVal(5))) +- ? emitIntrinsicErrorMessage( +- Op, "argument out of range or not a multiple of 2", DAG) +- : SDValue(); +- case Intrinsic::loongarch_lsx_vstelm_h: +- return (!isShiftedInt<8, 1>( +- cast(Op.getOperand(4))->getSExtValue()) || +- !isUInt<3>(Op.getConstantOperandVal(5))) +- ? emitIntrinsicErrorMessage( +- Op, "argument out of range or not a multiple of 2", DAG) +- : SDValue(); +- case Intrinsic::loongarch_lasx_xvstelm_w: +- return (!isShiftedInt<8, 2>( +- cast(Op.getOperand(4))->getSExtValue()) || +- !isUInt<3>(Op.getConstantOperandVal(5))) +- ? emitIntrinsicErrorMessage( +- Op, "argument out of range or not a multiple of 4", DAG) +- : SDValue(); +- case Intrinsic::loongarch_lsx_vstelm_w: +- return (!isShiftedInt<8, 2>( +- cast(Op.getOperand(4))->getSExtValue()) || +- !isUInt<2>(Op.getConstantOperandVal(5))) +- ? emitIntrinsicErrorMessage( +- Op, "argument out of range or not a multiple of 4", DAG) +- : SDValue(); +- case Intrinsic::loongarch_lasx_xvstelm_d: +- return (!isShiftedInt<8, 3>( +- cast(Op.getOperand(4))->getSExtValue()) || +- !isUInt<2>(Op.getConstantOperandVal(5))) +- ? emitIntrinsicErrorMessage( +- Op, "argument out of range or not a multiple of 8", DAG) +- : SDValue(); +- case Intrinsic::loongarch_lsx_vstelm_d: +- return (!isShiftedInt<8, 3>( +- cast(Op.getOperand(4))->getSExtValue()) || +- !isUInt<1>(Op.getConstantOperandVal(5))) +- ? emitIntrinsicErrorMessage( +- Op, "argument out of range or not a multiple of 8", DAG) +- : SDValue(); +- } +-} ++ SDValue Shl = And1.getOperand(0); + +-SDValue LoongArchTargetLowering::lowerShiftLeftParts(SDValue Op, +- SelectionDAG &DAG) const { +- SDLoc DL(Op); +- SDValue Lo = Op.getOperand(0); +- SDValue Hi = Op.getOperand(1); +- SDValue Shamt = Op.getOperand(2); +- EVT VT = Lo.getValueType(); ++ if (!(CN = dyn_cast(Shl.getOperand(1)))) ++ return SDValue(); + +- // if Shamt-GRLen < 0: // Shamt < GRLen +- // Lo = Lo << Shamt +- // Hi = (Hi << Shamt) | ((Lo >>u 1) >>u (GRLen-1 ^ Shamt)) +- // else: +- // Lo = 0 +- // Hi = Lo << (Shamt-GRLen) +- +- SDValue Zero = DAG.getConstant(0, DL, VT); +- SDValue One = DAG.getConstant(1, DL, VT); +- SDValue MinusGRLen = DAG.getConstant(-(int)Subtarget.getGRLen(), DL, VT); +- SDValue GRLenMinus1 = DAG.getConstant(Subtarget.getGRLen() - 1, DL, VT); +- SDValue ShamtMinusGRLen = DAG.getNode(ISD::ADD, DL, VT, Shamt, MinusGRLen); +- SDValue GRLenMinus1Shamt = DAG.getNode(ISD::XOR, DL, VT, Shamt, GRLenMinus1); +- +- SDValue LoTrue = DAG.getNode(ISD::SHL, DL, VT, Lo, Shamt); +- SDValue ShiftRight1Lo = DAG.getNode(ISD::SRL, DL, VT, Lo, One); +- SDValue ShiftRightLo = +- DAG.getNode(ISD::SRL, DL, VT, ShiftRight1Lo, GRLenMinus1Shamt); +- SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, VT, Hi, Shamt); +- SDValue HiTrue = DAG.getNode(ISD::OR, DL, VT, ShiftLeftHi, ShiftRightLo); +- SDValue HiFalse = DAG.getNode(ISD::SHL, DL, VT, Lo, ShamtMinusGRLen); ++ unsigned Shamt = CN->getZExtValue(); + +- SDValue CC = DAG.getSetCC(DL, VT, ShamtMinusGRLen, Zero, ISD::SETLT); ++ // Return if the shift amount and the first bit position of mask are not the ++ // same. ++ EVT ValTy = N->getValueType(0); ++ if ((Shamt != SMLsb0) || (SMLsb0 + SMSize0 > ValTy.getSizeInBits())) ++ return SDValue(); ++ ++ SDLoc DL(N); ++ return DAG.getNode(LoongArchISD::BSTRINS, DL, ValTy, Shl.getOperand(0), ++ DAG.getConstant((SMLsb0 + SMSize0 - 1), DL, MVT::i32), ++ DAG.getConstant(SMLsb0, DL, MVT::i32), ++ And0.getOperand(0)); ++ } else { ++ // Pattern match BSTRINS. ++ // $dst = or (and $src, mask0), mask1 ++ // where mask0 = ((1 << SMSize0) -1) << SMLsb0 ++ // => bstrins $dst, $src, SMLsb0+SMSize0-1, SMLsb0 ++ if (~CN->getSExtValue() == ((((int64_t)1 << SMSize0) - 1) << SMLsb0) && ++ (SMSize0 + SMLsb0 <= 64)) { ++ // Check if AND instruction has constant as argument ++ bool isConstCase = And1.getOpcode() != ISD::AND; ++ if (And1.getOpcode() == ISD::AND) { ++ if (!(CN1 = dyn_cast(And1->getOperand(1)))) ++ return SDValue(); ++ } else { ++ if (!(CN1 = dyn_cast(N->getOperand(1)))) ++ return SDValue(); ++ } ++ // Don't generate BSTRINS if constant OR operand doesn't fit into bits ++ // cleared by constant AND operand. ++ if (CN->getSExtValue() & CN1->getSExtValue()) ++ return SDValue(); + +- Lo = DAG.getNode(ISD::SELECT, DL, VT, CC, LoTrue, Zero); +- Hi = DAG.getNode(ISD::SELECT, DL, VT, CC, HiTrue, HiFalse); ++ SDLoc DL(N); ++ EVT ValTy = N->getOperand(0)->getValueType(0); ++ SDValue Const1; ++ SDValue SrlX; ++ if (!isConstCase) { ++ Const1 = DAG.getConstant(SMLsb0, DL, MVT::i32); ++ SrlX = DAG.getNode(ISD::SRL, DL, And1->getValueType(0), And1, Const1); ++ } ++ return DAG.getNode( ++ LoongArchISD::BSTRINS, DL, N->getValueType(0), ++ isConstCase ++ ? DAG.getConstant(CN1->getSExtValue() >> SMLsb0, DL, ValTy) ++ : SrlX, ++ DAG.getConstant(ValTy.getSizeInBits() / 8 < 8 ? (SMLsb0 + (SMSize0 & 31) - 1) ++ : (SMLsb0 + SMSize0 - 1), ++ DL, MVT::i32), ++ DAG.getConstant(SMLsb0, DL, MVT::i32), ++ And0->getOperand(0)); + +- SDValue Parts[2] = {Lo, Hi}; +- return DAG.getMergeValues(Parts, DL); ++ } ++ return SDValue(); ++ } + } + +-SDValue LoongArchTargetLowering::lowerShiftRightParts(SDValue Op, +- SelectionDAG &DAG, +- bool IsSRA) const { +- SDLoc DL(Op); +- SDValue Lo = Op.getOperand(0); +- SDValue Hi = Op.getOperand(1); +- SDValue Shamt = Op.getOperand(2); +- EVT VT = Lo.getValueType(); +- +- // SRA expansion: +- // if Shamt-GRLen < 0: // Shamt < GRLen +- // Lo = (Lo >>u Shamt) | ((Hi << 1) << (ShAmt ^ GRLen-1)) +- // Hi = Hi >>s Shamt +- // else: +- // Lo = Hi >>s (Shamt-GRLen); +- // Hi = Hi >>s (GRLen-1) ++static bool ++shouldTransformMulToShiftsAddsSubs(APInt C, EVT VT, ++ SelectionDAG &DAG, ++ const LoongArchSubtarget &Subtarget) { ++ // Estimate the number of operations the below transform will turn a ++ // constant multiply into. The number is approximately equal to the minimal ++ // number of powers of two that constant can be broken down to by adding ++ // or subtracting them. + // +- // SRL expansion: +- // if Shamt-GRLen < 0: // Shamt < GRLen +- // Lo = (Lo >>u Shamt) | ((Hi << 1) << (ShAmt ^ GRLen-1)) +- // Hi = Hi >>u Shamt +- // else: +- // Lo = Hi >>u (Shamt-GRLen); +- // Hi = 0; +- +- unsigned ShiftRightOp = IsSRA ? ISD::SRA : ISD::SRL; +- +- SDValue Zero = DAG.getConstant(0, DL, VT); +- SDValue One = DAG.getConstant(1, DL, VT); +- SDValue MinusGRLen = DAG.getConstant(-(int)Subtarget.getGRLen(), DL, VT); +- SDValue GRLenMinus1 = DAG.getConstant(Subtarget.getGRLen() - 1, DL, VT); +- SDValue ShamtMinusGRLen = DAG.getNode(ISD::ADD, DL, VT, Shamt, MinusGRLen); +- SDValue GRLenMinus1Shamt = DAG.getNode(ISD::XOR, DL, VT, Shamt, GRLenMinus1); +- +- SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, VT, Lo, Shamt); +- SDValue ShiftLeftHi1 = DAG.getNode(ISD::SHL, DL, VT, Hi, One); +- SDValue ShiftLeftHi = +- DAG.getNode(ISD::SHL, DL, VT, ShiftLeftHi1, GRLenMinus1Shamt); +- SDValue LoTrue = DAG.getNode(ISD::OR, DL, VT, ShiftRightLo, ShiftLeftHi); +- SDValue HiTrue = DAG.getNode(ShiftRightOp, DL, VT, Hi, Shamt); +- SDValue LoFalse = DAG.getNode(ShiftRightOp, DL, VT, Hi, ShamtMinusGRLen); +- SDValue HiFalse = +- IsSRA ? DAG.getNode(ISD::SRA, DL, VT, Hi, GRLenMinus1) : Zero; ++ // If we have taken more than 10[1] / 8[2] steps to attempt the ++ // optimization for a native sized value, it is more than likely that this ++ // optimization will make things worse. ++ // ++ // [1] LA64 requires 4 instructions at most to materialize any constant, ++ // multiplication requires at least 4 cycles, but another cycle (or two) ++ // to retrieve the result from corresponding registers. ++ // ++ // [2] LA32 requires 2 instructions at most to materialize any constant, ++ // multiplication requires at least 4 cycles, but another cycle (or two) ++ // to retrieve the result from corresponding registers. ++ // ++ // TODO: ++ // - MaxSteps needs to consider the `VT` of the constant for the current ++ // target. ++ // - Consider to perform this optimization after type legalization. ++ // That allows to remove a workaround for types not supported natively. ++ // - Take in account `-Os, -Oz` flags because this optimization ++ // increases code size. ++ unsigned MaxSteps = Subtarget.isABI_LP32() ? 8 : 10; ++ ++ SmallVector WorkStack(1, C); ++ unsigned Steps = 0; ++ unsigned BitWidth = C.getBitWidth(); ++ ++ while (!WorkStack.empty()) { ++ APInt Val = WorkStack.pop_back_val(); ++ ++ if (Val == 0 || Val == 1) ++ continue; + +- SDValue CC = DAG.getSetCC(DL, VT, ShamtMinusGRLen, Zero, ISD::SETLT); ++ if (Steps >= MaxSteps) ++ return false; + +- Lo = DAG.getNode(ISD::SELECT, DL, VT, CC, LoTrue, LoFalse); +- Hi = DAG.getNode(ISD::SELECT, DL, VT, CC, HiTrue, HiFalse); ++ if (Val.isPowerOf2()) { ++ ++Steps; ++ continue; ++ } + +- SDValue Parts[2] = {Lo, Hi}; +- return DAG.getMergeValues(Parts, DL); +-} ++ APInt Floor = APInt(BitWidth, 1) << Val.logBase2(); ++ APInt Ceil = Val.isNegative() ? APInt(BitWidth, 0) ++ : APInt(BitWidth, 1) << C.ceilLogBase2(); + +-// Returns the opcode of the target-specific SDNode that implements the 32-bit +-// form of the given Opcode. +-static LoongArchISD::NodeType getLoongArchWOpcode(unsigned Opcode) { +- switch (Opcode) { +- default: +- llvm_unreachable("Unexpected opcode"); +- case ISD::SHL: +- return LoongArchISD::SLL_W; +- case ISD::SRA: +- return LoongArchISD::SRA_W; +- case ISD::SRL: +- return LoongArchISD::SRL_W; +- case ISD::ROTR: +- return LoongArchISD::ROTR_W; +- case ISD::ROTL: +- return LoongArchISD::ROTL_W; +- case ISD::CTTZ: +- return LoongArchISD::CTZ_W; +- case ISD::CTLZ: +- return LoongArchISD::CLZ_W; +- } +-} +- +-// Converts the given i8/i16/i32 operation to a target-specific SelectionDAG +-// node. Because i8/i16/i32 isn't a legal type for LA64, these operations would +-// otherwise be promoted to i64, making it difficult to select the +-// SLL_W/.../*W later one because the fact the operation was originally of +-// type i8/i16/i32 is lost. +-static SDValue customLegalizeToWOp(SDNode *N, SelectionDAG &DAG, int NumOp, +- unsigned ExtOpc = ISD::ANY_EXTEND) { +- SDLoc DL(N); +- LoongArchISD::NodeType WOpcode = getLoongArchWOpcode(N->getOpcode()); +- SDValue NewOp0, NewRes; ++ if ((Val - Floor).ule(Ceil - Val)) { ++ WorkStack.push_back(Floor); ++ WorkStack.push_back(Val - Floor); ++ } else { ++ WorkStack.push_back(Ceil); ++ WorkStack.push_back(Ceil - Val); ++ } + +- switch (NumOp) { +- default: +- llvm_unreachable("Unexpected NumOp"); +- case 1: { +- NewOp0 = DAG.getNode(ExtOpc, DL, MVT::i64, N->getOperand(0)); +- NewRes = DAG.getNode(WOpcode, DL, MVT::i64, NewOp0); +- break; +- } +- case 2: { +- NewOp0 = DAG.getNode(ExtOpc, DL, MVT::i64, N->getOperand(0)); +- SDValue NewOp1 = DAG.getNode(ExtOpc, DL, MVT::i64, N->getOperand(1)); +- NewRes = DAG.getNode(WOpcode, DL, MVT::i64, NewOp0, NewOp1); +- break; +- } +- // TODO:Handle more NumOp. ++ ++Steps; + } + +- // ReplaceNodeResults requires we maintain the same type for the return +- // value. +- return DAG.getNode(ISD::TRUNCATE, DL, N->getValueType(0), NewRes); +-} ++ // If the value being multiplied is not supported natively, we have to pay ++ // an additional legalization cost, conservatively assume an increase in the ++ // cost of 3 instructions per step. This values for this heuristic were ++ // determined experimentally. ++ unsigned RegisterSize = DAG.getTargetLoweringInfo() ++ .getRegisterType(*DAG.getContext(), VT) ++ .getSizeInBits(); ++ Steps *= (VT.getSizeInBits() != RegisterSize) * 3; ++ if (Steps > 27) ++ return false; + +-// Helper function that emits error message for intrinsics with/without chain +-// and return a UNDEF or and the chain as the results. +-static void emitErrorAndReplaceIntrinsicResults( +- SDNode *N, SmallVectorImpl &Results, SelectionDAG &DAG, +- StringRef ErrorMsg, bool WithChain = true) { +- DAG.getContext()->emitError(N->getOperationName(0) + ": " + ErrorMsg + "."); +- Results.push_back(DAG.getUNDEF(N->getValueType(0))); +- if (!WithChain) +- return; +- Results.push_back(N->getOperand(0)); +-} +- +-template +-static void +-replaceVPICKVE2GRResults(SDNode *Node, SmallVectorImpl &Results, +- SelectionDAG &DAG, const LoongArchSubtarget &Subtarget, +- unsigned ResOp) { +- const StringRef ErrorMsgOOR = "argument out of range"; +- unsigned Imm = Node->getConstantOperandVal(2); +- if (!isUInt(Imm)) { +- emitErrorAndReplaceIntrinsicResults(Node, Results, DAG, ErrorMsgOOR, +- /*WithChain=*/false); +- return; +- } +- SDLoc DL(Node); +- SDValue Vec = Node->getOperand(1); ++ return true; ++} + +- SDValue PickElt = +- DAG.getNode(ResOp, DL, Subtarget.getGRLenVT(), Vec, +- DAG.getConstant(Imm, DL, Subtarget.getGRLenVT()), +- DAG.getValueType(Vec.getValueType().getVectorElementType())); +- Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, Node->getValueType(0), +- PickElt.getValue(0))); ++static SDValue genConstMult(SDValue X, APInt C, const SDLoc &DL, EVT VT, ++ EVT ShiftTy, SelectionDAG &DAG) { ++ // Return 0. ++ if (C == 0) ++ return DAG.getConstant(0, DL, VT); ++ ++ // Return x. ++ if (C == 1) ++ return X; ++ ++ // If c is power of 2, return (shl x, log2(c)). ++ if (C.isPowerOf2()) ++ return DAG.getNode(ISD::SHL, DL, VT, X, ++ DAG.getConstant(C.logBase2(), DL, ShiftTy)); ++ ++ unsigned BitWidth = C.getBitWidth(); ++ APInt Floor = APInt(BitWidth, 1) << C.logBase2(); ++ APInt Ceil = C.isNegative() ? APInt(BitWidth, 0) : ++ APInt(BitWidth, 1) << C.ceilLogBase2(); ++ ++ // If |c - floor_c| <= |c - ceil_c|, ++ // where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))), ++ // return (add constMult(x, floor_c), constMult(x, c - floor_c)). ++ if ((C - Floor).ule(Ceil - C)) { ++ SDValue Op0 = genConstMult(X, Floor, DL, VT, ShiftTy, DAG); ++ SDValue Op1 = genConstMult(X, C - Floor, DL, VT, ShiftTy, DAG); ++ return DAG.getNode(ISD::ADD, DL, VT, Op0, Op1); ++ } ++ ++ // If |c - floor_c| > |c - ceil_c|, ++ // return (sub constMult(x, ceil_c), constMult(x, ceil_c - c)). ++ SDValue Op0 = genConstMult(X, Ceil, DL, VT, ShiftTy, DAG); ++ SDValue Op1 = genConstMult(X, Ceil - C, DL, VT, ShiftTy, DAG); ++ return DAG.getNode(ISD::SUB, DL, VT, Op0, Op1); + } + +-static void replaceVecCondBranchResults(SDNode *N, +- SmallVectorImpl &Results, +- SelectionDAG &DAG, +- const LoongArchSubtarget &Subtarget, +- unsigned ResOp) { ++static SDValue performLogicCombine(SDNode *N, SelectionDAG &DAG, ++ const LoongArchSubtarget &Subtarget) { ++ + SDLoc DL(N); +- SDValue Vec = N->getOperand(1); ++ SDValue N0 = N->getOperand(0); ++ SDValue N1 = N->getOperand(1); ++ ++ if (!(N0->getOpcode() == ISD::TRUNCATE && N1->getOpcode() == ISD::TRUNCATE)) ++ return SDValue(); ++ ++ if (!(N->getValueType(0).isSimple() && N0->getValueType(0).isSimple() && ++ N1->getValueType(0).isSimple() && ++ N0->getOperand(0)->getValueType(0).isSimple() && ++ N1->getOperand(0)->getValueType(0).isSimple())) ++ return SDValue(); ++ ++ if (!(N->getValueType(0).isSimple() && N0->getValueType(0).isSimple() && ++ N1->getValueType(0).isSimple() && ++ N0->getOperand(0)->getValueType(0).isSimple() && ++ N1->getOperand(0)->getValueType(0).isSimple())) ++ return SDValue(); + +- SDValue CB = DAG.getNode(ResOp, DL, Subtarget.getGRLenVT(), Vec); +- Results.push_back( +- DAG.getNode(ISD::TRUNCATE, DL, N->getValueType(0), CB.getValue(0))); ++ if (!(N->getSimpleValueType(0).SimpleTy == MVT::i32 && ++ N0->getSimpleValueType(0).SimpleTy == MVT::i32 && ++ N1->getSimpleValueType(0).SimpleTy == MVT::i32)) ++ return SDValue(); ++ ++ if (!(N0->getOperand(0)->getSimpleValueType(0).SimpleTy == MVT::i64 && ++ N1->getOperand(0)->getSimpleValueType(0).SimpleTy == MVT::i64)) ++ return SDValue(); ++ ++ SDValue SubReg = DAG.getTargetConstant(LoongArch::sub_32, DL, MVT::i32); ++ SDValue Val0 = SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, ++ N0->getValueType(0), ++ N0->getOperand(0), SubReg), ++ 0); ++ SDValue Val1 = SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, ++ N1->getValueType(0), ++ N1->getOperand(0), SubReg), ++ 0); ++ ++ return DAG.getNode(N->getOpcode(), DL, N0->getValueType(0), Val0, Val1); + } + +-static void +-replaceINTRINSIC_WO_CHAINResults(SDNode *N, SmallVectorImpl &Results, +- SelectionDAG &DAG, ++static SDValue performMULCombine(SDNode *N, SelectionDAG &DAG, ++ const TargetLowering::DAGCombinerInfo &DCI, ++ const LoongArchTargetLowering *TL, + const LoongArchSubtarget &Subtarget) { +- switch (N->getConstantOperandVal(0)) { +- default: +- llvm_unreachable("Unexpected Intrinsic."); +- case Intrinsic::loongarch_lsx_vpickve2gr_b: +- replaceVPICKVE2GRResults<4>(N, Results, DAG, Subtarget, +- LoongArchISD::VPICK_SEXT_ELT); +- break; +- case Intrinsic::loongarch_lsx_vpickve2gr_h: +- case Intrinsic::loongarch_lasx_xvpickve2gr_w: +- replaceVPICKVE2GRResults<3>(N, Results, DAG, Subtarget, +- LoongArchISD::VPICK_SEXT_ELT); +- break; +- case Intrinsic::loongarch_lsx_vpickve2gr_w: +- replaceVPICKVE2GRResults<2>(N, Results, DAG, Subtarget, +- LoongArchISD::VPICK_SEXT_ELT); +- break; +- case Intrinsic::loongarch_lsx_vpickve2gr_bu: +- replaceVPICKVE2GRResults<4>(N, Results, DAG, Subtarget, +- LoongArchISD::VPICK_ZEXT_ELT); +- break; +- case Intrinsic::loongarch_lsx_vpickve2gr_hu: +- case Intrinsic::loongarch_lasx_xvpickve2gr_wu: +- replaceVPICKVE2GRResults<3>(N, Results, DAG, Subtarget, +- LoongArchISD::VPICK_ZEXT_ELT); +- break; +- case Intrinsic::loongarch_lsx_vpickve2gr_wu: +- replaceVPICKVE2GRResults<2>(N, Results, DAG, Subtarget, +- LoongArchISD::VPICK_ZEXT_ELT); +- break; +- case Intrinsic::loongarch_lsx_bz_b: +- case Intrinsic::loongarch_lsx_bz_h: +- case Intrinsic::loongarch_lsx_bz_w: +- case Intrinsic::loongarch_lsx_bz_d: +- case Intrinsic::loongarch_lasx_xbz_b: +- case Intrinsic::loongarch_lasx_xbz_h: +- case Intrinsic::loongarch_lasx_xbz_w: +- case Intrinsic::loongarch_lasx_xbz_d: +- replaceVecCondBranchResults(N, Results, DAG, Subtarget, +- LoongArchISD::VALL_ZERO); +- break; +- case Intrinsic::loongarch_lsx_bz_v: +- case Intrinsic::loongarch_lasx_xbz_v: +- replaceVecCondBranchResults(N, Results, DAG, Subtarget, +- LoongArchISD::VANY_ZERO); +- break; +- case Intrinsic::loongarch_lsx_bnz_b: +- case Intrinsic::loongarch_lsx_bnz_h: +- case Intrinsic::loongarch_lsx_bnz_w: +- case Intrinsic::loongarch_lsx_bnz_d: +- case Intrinsic::loongarch_lasx_xbnz_b: +- case Intrinsic::loongarch_lasx_xbnz_h: +- case Intrinsic::loongarch_lasx_xbnz_w: +- case Intrinsic::loongarch_lasx_xbnz_d: +- replaceVecCondBranchResults(N, Results, DAG, Subtarget, +- LoongArchISD::VALL_NONZERO); +- break; +- case Intrinsic::loongarch_lsx_bnz_v: +- case Intrinsic::loongarch_lasx_xbnz_v: +- replaceVecCondBranchResults(N, Results, DAG, Subtarget, +- LoongArchISD::VANY_NONZERO); +- break; +- } ++ EVT VT = N->getValueType(0); ++ ++ SDValue Res; ++ if ((Res = performLogicCombine(N, DAG, Subtarget))) ++ return Res; ++ ++ if (ConstantSDNode *C = dyn_cast(N->getOperand(1))) ++ if (!VT.isVector() && shouldTransformMulToShiftsAddsSubs( ++ C->getAPIntValue(), VT, DAG, Subtarget)) ++ return genConstMult(N->getOperand(0), C->getAPIntValue(), SDLoc(N), VT, ++ TL->getScalarShiftAmountTy(DAG.getDataLayout(), VT), ++ DAG); ++ ++ return SDValue(N, 0); + } + +-void LoongArchTargetLowering::ReplaceNodeResults( +- SDNode *N, SmallVectorImpl &Results, SelectionDAG &DAG) const { +- SDLoc DL(N); +- EVT VT = N->getValueType(0); +- switch (N->getOpcode()) { +- default: +- llvm_unreachable("Don't know how to legalize this operation"); +- case ISD::SHL: +- case ISD::SRA: +- case ISD::SRL: +- case ISD::ROTR: +- assert(VT == MVT::i32 && Subtarget.is64Bit() && +- "Unexpected custom legalisation"); +- if (N->getOperand(1).getOpcode() != ISD::Constant) { +- Results.push_back(customLegalizeToWOp(N, DAG, 2)); +- break; +- } +- break; +- case ISD::ROTL: +- ConstantSDNode *CN; +- if ((CN = dyn_cast(N->getOperand(1)))) { +- Results.push_back(customLegalizeToWOp(N, DAG, 2)); +- break; +- } +- break; +- case ISD::FP_TO_SINT: { +- assert(VT == MVT::i32 && Subtarget.is64Bit() && +- "Unexpected custom legalisation"); +- SDValue Src = N->getOperand(0); +- EVT FVT = EVT::getFloatingPointVT(N->getValueSizeInBits(0)); +- if (getTypeAction(*DAG.getContext(), Src.getValueType()) != +- TargetLowering::TypeSoftenFloat) { +- SDValue Dst = DAG.getNode(LoongArchISD::FTINT, DL, FVT, Src); +- Results.push_back(DAG.getNode(ISD::BITCAST, DL, VT, Dst)); +- return; +- } +- // If the FP type needs to be softened, emit a library call using the 'si' +- // version. If we left it to default legalization we'd end up with 'di'. +- RTLIB::Libcall LC; +- LC = RTLIB::getFPTOSINT(Src.getValueType(), VT); +- MakeLibCallOptions CallOptions; +- EVT OpVT = Src.getValueType(); +- CallOptions.setTypeListBeforeSoften(OpVT, VT, true); +- SDValue Chain = SDValue(); +- SDValue Result; +- std::tie(Result, Chain) = +- makeLibCall(DAG, LC, VT, Src, CallOptions, DL, Chain); +- Results.push_back(Result); +- break; +- } +- case ISD::BITCAST: { +- SDValue Src = N->getOperand(0); +- EVT SrcVT = Src.getValueType(); +- if (VT == MVT::i32 && SrcVT == MVT::f32 && Subtarget.is64Bit() && +- Subtarget.hasBasicF()) { +- SDValue Dst = +- DAG.getNode(LoongArchISD::MOVFR2GR_S_LA64, DL, MVT::i64, Src); +- Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Dst)); +- } +- break; +- } +- case ISD::FP_TO_UINT: { +- assert(VT == MVT::i32 && Subtarget.is64Bit() && +- "Unexpected custom legalisation"); +- auto &TLI = DAG.getTargetLoweringInfo(); +- SDValue Tmp1, Tmp2; +- TLI.expandFP_TO_UINT(N, Tmp1, Tmp2, DAG); +- Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Tmp1)); +- break; +- } +- case ISD::BSWAP: { +- SDValue Src = N->getOperand(0); +- assert((VT == MVT::i16 || VT == MVT::i32) && +- "Unexpected custom legalization"); +- MVT GRLenVT = Subtarget.getGRLenVT(); +- SDValue NewSrc = DAG.getNode(ISD::ANY_EXTEND, DL, GRLenVT, Src); +- SDValue Tmp; +- switch (VT.getSizeInBits()) { +- default: +- llvm_unreachable("Unexpected operand width"); +- case 16: +- Tmp = DAG.getNode(LoongArchISD::REVB_2H, DL, GRLenVT, NewSrc); +- break; +- case 32: +- // Only LA64 will get to here due to the size mismatch between VT and +- // GRLenVT, LA32 lowering is directly defined in LoongArchInstrInfo. +- Tmp = DAG.getNode(LoongArchISD::REVB_2W, DL, GRLenVT, NewSrc); +- break; ++// Fold sign-extensions into LoongArchISD::VEXTRACT_[SZ]EXT_ELT for LSX. ++// ++// Performs the following transformations: ++// - Changes LoongArchISD::VEXTRACT_[SZ]EXT_ELT to sign extension if its ++// sign/zero-extension is completely overwritten by the new one performed by ++// the ISD::SRA and ISD::SHL nodes. ++// - Removes redundant sign extensions performed by an ISD::SRA and ISD::SHL ++// sequence. ++static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG, ++ TargetLowering::DAGCombinerInfo &DCI, ++ const LoongArchSubtarget &Subtarget) { ++ ++ SDValue Res; ++ if ((Res = performLogicCombine(N, DAG, Subtarget))) ++ return Res; ++ ++ if (Subtarget.hasLSX() || Subtarget.hasLASX()) { ++ SDValue Op0 = N->getOperand(0); ++ SDValue Op1 = N->getOperand(1); ++ ++ // (sra (shl (LoongArchVExtract[SZ]Ext $a, $b, $c), imm:$d), imm:$d) ++ // where $d + sizeof($c) == 32 ++ // or $d + sizeof($c) <= 32 and SExt ++ // -> (LoongArchVExtractSExt $a, $b, $c) ++ if (Op0->getOpcode() == ISD::SHL && Op1 == Op0->getOperand(1)) { ++ SDValue Op0Op0 = Op0->getOperand(0); ++ ConstantSDNode *ShAmount = dyn_cast(Op1); ++ ++ if (!ShAmount) ++ return SDValue(); ++ ++ if (Op0Op0->getOpcode() != LoongArchISD::VEXTRACT_SEXT_ELT && ++ Op0Op0->getOpcode() != LoongArchISD::VEXTRACT_ZEXT_ELT) ++ return SDValue(); ++ ++ EVT ExtendTy = cast(Op0Op0->getOperand(2))->getVT(); ++ unsigned TotalBits = ShAmount->getZExtValue() + ExtendTy.getSizeInBits(); ++ ++ if (TotalBits == 32 || ++ (Op0Op0->getOpcode() == LoongArchISD::VEXTRACT_SEXT_ELT && ++ TotalBits <= 32)) { ++ SDValue Ops[] = {Op0Op0->getOperand(0), Op0Op0->getOperand(1), ++ Op0Op0->getOperand(2)}; ++ return DAG.getNode(LoongArchISD::VEXTRACT_SEXT_ELT, SDLoc(Op0Op0), ++ Op0Op0->getVTList(), ++ ArrayRef(Ops, Op0Op0->getNumOperands())); ++ } + } +- Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, VT, Tmp)); +- break; + } +- case ISD::BITREVERSE: { +- SDValue Src = N->getOperand(0); +- assert((VT == MVT::i8 || (VT == MVT::i32 && Subtarget.is64Bit())) && +- "Unexpected custom legalization"); +- MVT GRLenVT = Subtarget.getGRLenVT(); +- SDValue NewSrc = DAG.getNode(ISD::ANY_EXTEND, DL, GRLenVT, Src); +- SDValue Tmp; +- switch (VT.getSizeInBits()) { +- default: +- llvm_unreachable("Unexpected operand width"); +- case 8: +- Tmp = DAG.getNode(LoongArchISD::BITREV_4B, DL, GRLenVT, NewSrc); +- break; +- case 32: +- Tmp = DAG.getNode(LoongArchISD::BITREV_W, DL, GRLenVT, NewSrc); +- break; +- } +- Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, VT, Tmp)); ++ ++ return SDValue(); ++} ++ ++// combine vsub/vslt/vbitsel.v to vabsd ++static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG) { ++ assert((N->getOpcode() == ISD::VSELECT) && "Need ISD::VSELECT"); ++ ++ SDLoc dl(N); ++ SDValue Cond = N->getOperand(0); ++ SDValue TrueOpnd = N->getOperand(1); ++ SDValue FalseOpnd = N->getOperand(2); ++ ++ if (Cond.getOpcode() != ISD::SETCC || TrueOpnd.getOpcode() != ISD::SUB || ++ FalseOpnd.getOpcode() != ISD::SUB) ++ return SDValue(); ++ ++ if (!(Cond.hasOneUse() || TrueOpnd.hasOneUse() || FalseOpnd.hasOneUse())) ++ return SDValue(); ++ ++ ISD::CondCode CC = cast(Cond.getOperand(2))->get(); ++ ++ switch (CC) { ++ default: ++ return SDValue(); ++ case ISD::SETUGT: ++ case ISD::SETUGE: ++ case ISD::SETGT: ++ case ISD::SETGE: + break; +- } +- case ISD::CTLZ: +- case ISD::CTTZ: { +- assert(VT == MVT::i32 && Subtarget.is64Bit() && +- "Unexpected custom legalisation"); +- Results.push_back(customLegalizeToWOp(N, DAG, 1)); ++ case ISD::SETULT: ++ case ISD::SETULE: ++ case ISD::SETLT: ++ case ISD::SETLE: ++ std::swap(TrueOpnd, FalseOpnd); + break; + } +- case ISD::INTRINSIC_W_CHAIN: { +- SDValue Chain = N->getOperand(0); +- SDValue Op2 = N->getOperand(2); +- MVT GRLenVT = Subtarget.getGRLenVT(); +- const StringRef ErrorMsgOOR = "argument out of range"; +- const StringRef ErrorMsgReqLA64 = "requires loongarch64"; +- const StringRef ErrorMsgReqF = "requires basic 'f' target feature"; + +- switch (N->getConstantOperandVal(1)) { +- default: +- llvm_unreachable("Unexpected Intrinsic."); +- case Intrinsic::loongarch_movfcsr2gr: { +- if (!Subtarget.hasBasicF()) { +- emitErrorAndReplaceIntrinsicResults(N, Results, DAG, ErrorMsgReqF); +- return; +- } +- unsigned Imm = Op2->getAsZExtVal(); +- if (!isUInt<2>(Imm)) { +- emitErrorAndReplaceIntrinsicResults(N, Results, DAG, ErrorMsgOOR); +- return; +- } +- SDValue MOVFCSR2GRResults = DAG.getNode( +- LoongArchISD::MOVFCSR2GR, SDLoc(N), {MVT::i64, MVT::Other}, +- {Chain, DAG.getConstant(Imm, DL, GRLenVT)}); +- Results.push_back( +- DAG.getNode(ISD::TRUNCATE, DL, VT, MOVFCSR2GRResults.getValue(0))); +- Results.push_back(MOVFCSR2GRResults.getValue(1)); +- break; +- } +-#define CRC_CASE_EXT_BINARYOP(NAME, NODE) \ +- case Intrinsic::loongarch_##NAME: { \ +- SDValue NODE = DAG.getNode( \ +- LoongArchISD::NODE, DL, {MVT::i64, MVT::Other}, \ +- {Chain, DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2), \ +- DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(3))}); \ +- Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, VT, NODE.getValue(0))); \ +- Results.push_back(NODE.getValue(1)); \ +- break; \ +- } +- CRC_CASE_EXT_BINARYOP(crc_w_b_w, CRC_W_B_W) +- CRC_CASE_EXT_BINARYOP(crc_w_h_w, CRC_W_H_W) +- CRC_CASE_EXT_BINARYOP(crc_w_w_w, CRC_W_W_W) +- CRC_CASE_EXT_BINARYOP(crcc_w_b_w, CRCC_W_B_W) +- CRC_CASE_EXT_BINARYOP(crcc_w_h_w, CRCC_W_H_W) +- CRC_CASE_EXT_BINARYOP(crcc_w_w_w, CRCC_W_W_W) +-#undef CRC_CASE_EXT_BINARYOP +- +-#define CRC_CASE_EXT_UNARYOP(NAME, NODE) \ +- case Intrinsic::loongarch_##NAME: { \ +- SDValue NODE = DAG.getNode( \ +- LoongArchISD::NODE, DL, {MVT::i64, MVT::Other}, \ +- {Chain, Op2, \ +- DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(3))}); \ +- Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, VT, NODE.getValue(0))); \ +- Results.push_back(NODE.getValue(1)); \ +- break; \ +- } +- CRC_CASE_EXT_UNARYOP(crc_w_d_w, CRC_W_D_W) +- CRC_CASE_EXT_UNARYOP(crcc_w_d_w, CRCC_W_D_W) +-#undef CRC_CASE_EXT_UNARYOP +-#define CSR_CASE(ID) \ +- case Intrinsic::loongarch_##ID: { \ +- if (!Subtarget.is64Bit()) \ +- emitErrorAndReplaceIntrinsicResults(N, Results, DAG, ErrorMsgReqLA64); \ +- break; \ +- } +- CSR_CASE(csrrd_d); +- CSR_CASE(csrwr_d); +- CSR_CASE(csrxchg_d); +- CSR_CASE(iocsrrd_d); +-#undef CSR_CASE +- case Intrinsic::loongarch_csrrd_w: { +- unsigned Imm = Op2->getAsZExtVal(); +- if (!isUInt<14>(Imm)) { +- emitErrorAndReplaceIntrinsicResults(N, Results, DAG, ErrorMsgOOR); +- return; +- } +- SDValue CSRRDResults = +- DAG.getNode(LoongArchISD::CSRRD, DL, {GRLenVT, MVT::Other}, +- {Chain, DAG.getConstant(Imm, DL, GRLenVT)}); +- Results.push_back( +- DAG.getNode(ISD::TRUNCATE, DL, VT, CSRRDResults.getValue(0))); +- Results.push_back(CSRRDResults.getValue(1)); +- break; +- } +- case Intrinsic::loongarch_csrwr_w: { +- unsigned Imm = N->getConstantOperandVal(3); +- if (!isUInt<14>(Imm)) { +- emitErrorAndReplaceIntrinsicResults(N, Results, DAG, ErrorMsgOOR); +- return; +- } +- SDValue CSRWRResults = +- DAG.getNode(LoongArchISD::CSRWR, DL, {GRLenVT, MVT::Other}, +- {Chain, DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2), +- DAG.getConstant(Imm, DL, GRLenVT)}); +- Results.push_back( +- DAG.getNode(ISD::TRUNCATE, DL, VT, CSRWRResults.getValue(0))); +- Results.push_back(CSRWRResults.getValue(1)); +- break; +- } +- case Intrinsic::loongarch_csrxchg_w: { +- unsigned Imm = N->getConstantOperandVal(4); +- if (!isUInt<14>(Imm)) { +- emitErrorAndReplaceIntrinsicResults(N, Results, DAG, ErrorMsgOOR); +- return; +- } +- SDValue CSRXCHGResults = DAG.getNode( +- LoongArchISD::CSRXCHG, DL, {GRLenVT, MVT::Other}, +- {Chain, DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2), +- DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(3)), +- DAG.getConstant(Imm, DL, GRLenVT)}); +- Results.push_back( +- DAG.getNode(ISD::TRUNCATE, DL, VT, CSRXCHGResults.getValue(0))); +- Results.push_back(CSRXCHGResults.getValue(1)); +- break; +- } +-#define IOCSRRD_CASE(NAME, NODE) \ +- case Intrinsic::loongarch_##NAME: { \ +- SDValue IOCSRRDResults = \ +- DAG.getNode(LoongArchISD::NODE, DL, {MVT::i64, MVT::Other}, \ +- {Chain, DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2)}); \ +- Results.push_back( \ +- DAG.getNode(ISD::TRUNCATE, DL, VT, IOCSRRDResults.getValue(0))); \ +- Results.push_back(IOCSRRDResults.getValue(1)); \ +- break; \ +- } +- IOCSRRD_CASE(iocsrrd_b, IOCSRRD_B); +- IOCSRRD_CASE(iocsrrd_h, IOCSRRD_H); +- IOCSRRD_CASE(iocsrrd_w, IOCSRRD_W); +-#undef IOCSRRD_CASE +- case Intrinsic::loongarch_cpucfg: { +- SDValue CPUCFGResults = +- DAG.getNode(LoongArchISD::CPUCFG, DL, {GRLenVT, MVT::Other}, +- {Chain, DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2)}); +- Results.push_back( +- DAG.getNode(ISD::TRUNCATE, DL, VT, CPUCFGResults.getValue(0))); +- Results.push_back(CPUCFGResults.getValue(1)); +- break; +- } +- case Intrinsic::loongarch_lddir_d: { +- if (!Subtarget.is64Bit()) { +- emitErrorAndReplaceIntrinsicResults(N, Results, DAG, ErrorMsgReqLA64); +- return; +- } +- break; +- } ++ SDValue Op1 = Cond.getOperand(0); ++ SDValue Op2 = Cond.getOperand(1); ++ ++ if (TrueOpnd.getOperand(0) == Op1 && TrueOpnd.getOperand(1) == Op2 && ++ FalseOpnd.getOperand(0) == Op2 && FalseOpnd.getOperand(1) == Op1) { ++ if (ISD::isSignedIntSetCC(CC)) { ++ return DAG.getNode(LoongArchISD::VABSD, dl, ++ N->getOperand(1).getValueType(), Op1, Op2, ++ DAG.getTargetConstant(0, dl, MVT::i32)); ++ } else { ++ return DAG.getNode(LoongArchISD::UVABSD, dl, ++ N->getOperand(1).getValueType(), Op1, Op2, ++ DAG.getTargetConstant(0, dl, MVT::i32)); + } +- break; + } +- case ISD::READ_REGISTER: { +- if (Subtarget.is64Bit()) +- DAG.getContext()->emitError( +- "On LA64, only 64-bit registers can be read."); ++ return SDValue(); ++} ++ ++static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG, ++ const LoongArchSubtarget &Subtarget) { ++ ++ EVT Ty = N->getValueType(0); ++ ++ if ((Subtarget.hasLSX() && Ty.is128BitVector() && Ty.isInteger()) || ++ (Subtarget.hasLASX() && Ty.is256BitVector() && Ty.isInteger())) { ++ // Try the following combines: ++ // (xor (or $a, $b), (build_vector allones)) ++ // (xor (or $a, $b), (bitcast (build_vector allones))) ++ SDValue Op0 = N->getOperand(0); ++ SDValue Op1 = N->getOperand(1); ++ SDValue NotOp; ++ ++ if (ISD::isBuildVectorAllOnes(Op0.getNode())) ++ NotOp = Op1; ++ else if (ISD::isBuildVectorAllOnes(Op1.getNode())) ++ NotOp = Op0; + else +- DAG.getContext()->emitError( +- "On LA32, only 32-bit registers can be read."); +- Results.push_back(DAG.getUNDEF(VT)); +- Results.push_back(N->getOperand(0)); +- break; +- } +- case ISD::INTRINSIC_WO_CHAIN: { +- replaceINTRINSIC_WO_CHAINResults(N, Results, DAG, Subtarget); +- break; +- } ++ return SDValue(); ++ ++ if (NotOp->getOpcode() == ISD::OR) ++ return DAG.getNode(LoongArchISD::VNOR, SDLoc(N), Ty, NotOp->getOperand(0), ++ NotOp->getOperand(1)); + } ++ ++ return SDValue(); + } + +-static SDValue performANDCombine(SDNode *N, SelectionDAG &DAG, +- TargetLowering::DAGCombinerInfo &DCI, +- const LoongArchSubtarget &Subtarget) { +- if (DCI.isBeforeLegalizeOps()) ++// When using a 256-bit vector is less expensive than using a 128-bit vector, ++// use this function to convert a 128-bit vector to a 256-bit vector. ++static SDValue ++performCONCAT_VECTORSCombine(SDNode *N, SelectionDAG &DAG, ++ TargetLowering::DAGCombinerInfo &DCI, ++ const LoongArchSubtarget &Subtarget) { ++ ++ assert((N->getOpcode() == ISD::CONCAT_VECTORS) && "Need ISD::CONCAT_VECTORS"); ++ if (DCI.isAfterLegalizeDAG()) + return SDValue(); + +- SDValue FirstOperand = N->getOperand(0); +- SDValue SecondOperand = N->getOperand(1); +- unsigned FirstOperandOpc = FirstOperand.getOpcode(); +- EVT ValTy = N->getValueType(0); + SDLoc DL(N); +- uint64_t lsb, msb; +- unsigned SMIdx, SMLen; +- ConstantSDNode *CN; +- SDValue NewOperand; +- MVT GRLenVT = Subtarget.getGRLenVT(); ++ SDValue Top0 = N->getOperand(0); ++ SDValue Top1 = N->getOperand(1); + +- // Op's second operand must be a shifted mask. +- if (!(CN = dyn_cast(SecondOperand)) || +- !isShiftedMask_64(CN->getZExtValue(), SMIdx, SMLen)) ++ // Check for cheaper optimizations. ++ if (!((Top0->getOpcode() == ISD::SIGN_EXTEND) && ++ (Top1->getOpcode() == ISD::SIGN_EXTEND))) ++ return SDValue(); ++ if (!((Top0->getOperand(0)->getOpcode() == ISD::ADD) && ++ (Top1->getOperand(0)->getOpcode() == ISD::ADD))) + return SDValue(); + +- if (FirstOperandOpc == ISD::SRA || FirstOperandOpc == ISD::SRL) { +- // Pattern match BSTRPICK. +- // $dst = and ((sra or srl) $src , lsb), (2**len - 1) +- // => BSTRPICK $dst, $src, msb, lsb +- // where msb = lsb + len - 1 ++ SDValue Op_a0 = Top0->getOperand(0); ++ SDValue Op_a1 = Top1->getOperand(0); ++ for (int i = 0; i < 2; i++) { ++ if (!((Op_a0->getOperand(i)->getOpcode() == ISD::BUILD_VECTOR) && ++ (Op_a1->getOperand(i)->getOpcode() == ISD::BUILD_VECTOR))) ++ return SDValue(); ++ } + +- // The second operand of the shift must be an immediate. +- if (!(CN = dyn_cast(FirstOperand.getOperand(1)))) ++ SDValue Ops_b[] = {Op_a0->getOperand(0), Op_a0->getOperand(1), ++ Op_a1->getOperand(0), Op_a1->getOperand(1)}; ++ for (int i = 0; i < 4; i++) { ++ if (Ops_b[i]->getNumOperands() != 2) + return SDValue(); ++ } + +- lsb = CN->getZExtValue(); ++ // Currently only a single case is handled, and more optimization scenarios ++ // will be added in the future. ++ SDValue Ops_e[] = {Ops_b[0]->getOperand(0), Ops_b[0]->getOperand(1), ++ Ops_b[2]->getOperand(0), Ops_b[2]->getOperand(1), ++ Ops_b[1]->getOperand(0), Ops_b[1]->getOperand(1), ++ Ops_b[3]->getOperand(0), Ops_b[3]->getOperand(1)}; ++ for (int i = 0; i < 8; i++) { ++ if (dyn_cast(Ops_e[i])) ++ return SDValue(); ++ if (i < 4) { ++ if (cast(Ops_e[i]->getOperand(1))->getSExtValue() != ++ (2 * i)) ++ return SDValue(); ++ } else { ++ if (cast(Ops_e[i]->getOperand(1))->getSExtValue() != ++ (2 * i - 7)) ++ return SDValue(); ++ } ++ } + +- // Return if the shifted mask does not start at bit 0 or the sum of its +- // length and lsb exceeds the word's size. +- if (SMIdx != 0 || lsb + SMLen > ValTy.getSizeInBits()) ++ for (int i = 0; i < 5; i = i + 4) { ++ if (!((Ops_e[i]->getOperand(0) == Ops_e[i + 1]->getOperand(0)) && ++ (Ops_e[i + 1]->getOperand(0) == Ops_e[i + 2]->getOperand(0)) && ++ (Ops_e[i + 2]->getOperand(0) == Ops_e[i + 3]->getOperand(0)))) + return SDValue(); ++ } ++ return SDValue(DAG.getMachineNode(LoongArch::XVHADDW_D_W, DL, MVT::v4i64, ++ Ops_e[6]->getOperand(0), ++ Ops_e[0]->getOperand(0)), ++ 0); ++} + +- NewOperand = FirstOperand.getOperand(0); +- } else { +- // Pattern match BSTRPICK. +- // $dst = and $src, (2**len- 1) , if len > 12 +- // => BSTRPICK $dst, $src, msb, lsb +- // where lsb = 0 and msb = len - 1 ++static SDValue performParity(SDNode *N, SelectionDAG &DAG, ++ TargetLowering::DAGCombinerInfo &DCI, ++ const LoongArchSubtarget &Subtarget) { + +- // If the mask is <= 0xfff, andi can be used instead. +- if (CN->getZExtValue() <= 0xfff) ++ SDLoc DL(N); ++ SDValue T = N->getOperand(0); ++ if (!(N->getValueType(0).isSimple() && T->getValueType(0).isSimple())) ++ return SDValue(); ++ ++ if (DCI.isAfterLegalizeDAG()) ++ return SDValue(); ++ ++ SDValue Ops[4]; ++ bool pos_e = false; ++ bool pos_o = false; ++ ++ for (int i = 0; i < 4; i++) { ++ Ops[i] = T->getOperand(i); ++ if (!Ops[i]->getValueType(0).isSimple()) ++ return SDValue(); ++ if (Ops[i]->getOpcode() != ISD::EXTRACT_VECTOR_ELT) + return SDValue(); + +- // Return if the MSB exceeds. +- if (SMIdx + SMLen > ValTy.getSizeInBits()) ++ if (!dyn_cast(Ops[i]->getOperand(1))) + return SDValue(); + +- if (SMIdx > 0) { +- // Omit if the constant has more than 2 uses. This a conservative +- // decision. Whether it is a win depends on the HW microarchitecture. +- // However it should always be better for 1 and 2 uses. +- if (CN->use_size() > 2) +- return SDValue(); +- // Return if the constant can be composed by a single LU12I.W. +- if ((CN->getZExtValue() & 0xfff) == 0) +- return SDValue(); +- // Return if the constand can be composed by a single ADDI with +- // the zero register. +- if (CN->getSExtValue() >= -2048 && CN->getSExtValue() < 0) +- return SDValue(); +- } ++ if (cast(Ops[i]->getOperand(1))->getSExtValue() == ++ (2 * i)) { ++ pos_e = true; ++ } else if (cast(Ops[i]->getOperand(1))->getSExtValue() == ++ (2 * i + 1)) { ++ pos_o = true; ++ } else ++ return SDValue(); ++ } + +- lsb = SMIdx; +- NewOperand = FirstOperand; ++ if (!(N->getSimpleValueType(0).SimpleTy == MVT::v4i64 && ++ T->getSimpleValueType(0).SimpleTy == MVT::v4i32)) ++ return SDValue(); ++ ++ for (int j = 0; j < 3; j++) { ++ if (Ops[j]->getOperand(0) != Ops[j + 1]->getOperand(0)) ++ return SDValue(); + } ++ if (pos_e) { ++ if (N->getOpcode() == ISD::SIGN_EXTEND) { ++ if (Ops[0]->getOperand(0)->getOpcode() == ISD::ADD) ++ return SDValue(DAG.getMachineNode(LoongArch::XVADDWEV_D_W, DL, ++ MVT::v4i64, ++ Ops[0]->getOperand(0)->getOperand(1), ++ Ops[0]->getOperand(0)->getOperand(0)), ++ 0); ++ else if (Ops[0]->getOperand(0)->getOpcode() == ISD::SUB) ++ return SDValue(DAG.getMachineNode(LoongArch::XVSUBWEV_D_W, DL, ++ MVT::v4i64, ++ Ops[0]->getOperand(0)->getOperand(0), ++ Ops[0]->getOperand(0)->getOperand(1)), ++ 0); ++ } else if (N->getOpcode() == ISD::ZERO_EXTEND) { ++ if (Ops[0]->getOperand(0)->getOpcode() == ISD::ADD) ++ return SDValue(DAG.getMachineNode(LoongArch::XVADDWEV_D_WU, DL, ++ MVT::v4i64, ++ Ops[0]->getOperand(0)->getOperand(1), ++ Ops[0]->getOperand(0)->getOperand(0)), ++ 0); ++ else if (Ops[0]->getOperand(0)->getOpcode() == ISD::SUB) ++ return SDValue(DAG.getMachineNode(LoongArch::XVSUBWEV_D_WU, DL, ++ MVT::v4i64, ++ Ops[0]->getOperand(0)->getOperand(0), ++ Ops[0]->getOperand(0)->getOperand(1)), ++ 0); ++ } ++ } else if (pos_o) { ++ if (N->getOpcode() == ISD::SIGN_EXTEND) { ++ if (Ops[0]->getOperand(0)->getOpcode() == ISD::ADD) ++ return SDValue(DAG.getMachineNode(LoongArch::XVADDWOD_D_W, DL, ++ MVT::v4i64, ++ Ops[0]->getOperand(0)->getOperand(1), ++ Ops[0]->getOperand(0)->getOperand(0)), ++ 0); ++ else if (Ops[0]->getOperand(0)->getOpcode() == ISD::SUB) ++ return SDValue(DAG.getMachineNode(LoongArch::XVSUBWOD_D_W, DL, ++ MVT::v4i64, ++ Ops[0]->getOperand(0)->getOperand(0), ++ Ops[0]->getOperand(0)->getOperand(1)), ++ 0); ++ } else if (N->getOpcode() == ISD::ZERO_EXTEND) { ++ if (Ops[0]->getOperand(0)->getOpcode() == ISD::ADD) ++ return SDValue(DAG.getMachineNode(LoongArch::XVADDWOD_D_WU, DL, ++ MVT::v4i64, ++ Ops[0]->getOperand(0)->getOperand(1), ++ Ops[0]->getOperand(0)->getOperand(0)), ++ 0); ++ else if (Ops[0]->getOperand(0)->getOpcode() == ISD::SUB) ++ return SDValue(DAG.getMachineNode(LoongArch::XVSUBWOD_D_WU, DL, ++ MVT::v4i64, ++ Ops[0]->getOperand(0)->getOperand(0), ++ Ops[0]->getOperand(0)->getOperand(1)), ++ 0); ++ } ++ } else ++ return SDValue(); + +- msb = lsb + SMLen - 1; +- SDValue NR0 = DAG.getNode(LoongArchISD::BSTRPICK, DL, ValTy, NewOperand, +- DAG.getConstant(msb, DL, GRLenVT), +- DAG.getConstant(lsb, DL, GRLenVT)); +- if (FirstOperandOpc == ISD::SRA || FirstOperandOpc == ISD::SRL || lsb == 0) +- return NR0; +- // Try to optimize to +- // bstrpick $Rd, $Rs, msb, lsb +- // slli $Rd, $Rd, lsb +- return DAG.getNode(ISD::SHL, DL, ValTy, NR0, +- DAG.getConstant(lsb, DL, GRLenVT)); ++ return SDValue(); + } + +-static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG, +- TargetLowering::DAGCombinerInfo &DCI, +- const LoongArchSubtarget &Subtarget) { +- if (DCI.isBeforeLegalizeOps()) +- return SDValue(); ++// Optimize zero extension and sign extension of data ++static SDValue performExtend(SDNode *N, SelectionDAG &DAG, ++ TargetLowering::DAGCombinerInfo &DCI, ++ const LoongArchSubtarget &Subtarget) { + +- // $dst = srl (and $src, Mask), Shamt +- // => +- // BSTRPICK $dst, $src, MaskIdx+MaskLen-1, Shamt +- // when Mask is a shifted mask, and MaskIdx <= Shamt <= MaskIdx+MaskLen-1 +- // ++ if (!Subtarget.hasLASX()) ++ return SDValue(); + +- SDValue FirstOperand = N->getOperand(0); +- ConstantSDNode *CN; +- EVT ValTy = N->getValueType(0); + SDLoc DL(N); +- MVT GRLenVT = Subtarget.getGRLenVT(); +- unsigned MaskIdx, MaskLen; +- uint64_t Shamt; +- +- // The first operand must be an AND and the second operand of the AND must be +- // a shifted mask. +- if (FirstOperand.getOpcode() != ISD::AND || +- !(CN = dyn_cast(FirstOperand.getOperand(1))) || +- !isShiftedMask_64(CN->getZExtValue(), MaskIdx, MaskLen)) +- return SDValue(); ++ SDValue T = N->getOperand(0); + +- // The second operand (shift amount) must be an immediate. +- if (!(CN = dyn_cast(N->getOperand(1)))) ++ if (T->getOpcode() == ISD::BUILD_VECTOR) ++ return performParity(N, DAG, DCI, Subtarget); ++ ++ if (T->getOpcode() != ISD::ADD && T->getOpcode() != ISD::SUB) + return SDValue(); + +- Shamt = CN->getZExtValue(); +- if (MaskIdx <= Shamt && Shamt <= MaskIdx + MaskLen - 1) +- return DAG.getNode(LoongArchISD::BSTRPICK, DL, ValTy, +- FirstOperand->getOperand(0), +- DAG.getConstant(MaskIdx + MaskLen - 1, DL, GRLenVT), +- DAG.getConstant(Shamt, DL, GRLenVT)); ++ SDValue T0 = T->getOperand(0); ++ SDValue T1 = T->getOperand(1); + +- return SDValue(); +-} ++ if (!(T0->getOpcode() == ISD::BUILD_VECTOR && ++ T1->getOpcode() == ISD::BUILD_VECTOR)) ++ return SDValue(); + +-static SDValue performORCombine(SDNode *N, SelectionDAG &DAG, +- TargetLowering::DAGCombinerInfo &DCI, +- const LoongArchSubtarget &Subtarget) { +- MVT GRLenVT = Subtarget.getGRLenVT(); +- EVT ValTy = N->getValueType(0); +- SDValue N0 = N->getOperand(0), N1 = N->getOperand(1); +- ConstantSDNode *CN0, *CN1; +- SDLoc DL(N); +- unsigned ValBits = ValTy.getSizeInBits(); +- unsigned MaskIdx0, MaskLen0, MaskIdx1, MaskLen1; +- unsigned Shamt; +- bool SwapAndRetried = false; ++ if (DCI.isAfterLegalizeDAG()) ++ return SDValue(); + +- if (DCI.isBeforeLegalizeOps()) ++ if (!(T->getValueType(0).isSimple() && T0->getValueType(0).isSimple() && ++ T1->getValueType(0).isSimple() && N->getValueType(0).isSimple())) + return SDValue(); + +- if (ValBits != 32 && ValBits != 64) ++ if (!(N->getSimpleValueType(0).SimpleTy == MVT::v4i64 && ++ T->getSimpleValueType(0).SimpleTy == MVT::v4i32 && ++ T0->getSimpleValueType(0).SimpleTy == MVT::v4i32 && ++ T1->getSimpleValueType(0).SimpleTy == MVT::v4i32)) + return SDValue(); + +-Retry: +- // 1st pattern to match BSTRINS: +- // R = or (and X, mask0), (and (shl Y, lsb), mask1) +- // where mask1 = (2**size - 1) << lsb, mask0 = ~mask1 +- // => +- // R = BSTRINS X, Y, msb, lsb (where msb = lsb + size - 1) +- if (N0.getOpcode() == ISD::AND && +- (CN0 = dyn_cast(N0.getOperand(1))) && +- isShiftedMask_64(~CN0->getSExtValue(), MaskIdx0, MaskLen0) && +- N1.getOpcode() == ISD::AND && N1.getOperand(0).getOpcode() == ISD::SHL && +- (CN1 = dyn_cast(N1.getOperand(1))) && +- isShiftedMask_64(CN1->getZExtValue(), MaskIdx1, MaskLen1) && +- MaskIdx0 == MaskIdx1 && MaskLen0 == MaskLen1 && +- (CN1 = dyn_cast(N1.getOperand(0).getOperand(1))) && +- (Shamt = CN1->getZExtValue()) == MaskIdx0 && +- (MaskIdx0 + MaskLen0 <= ValBits)) { +- LLVM_DEBUG(dbgs() << "Perform OR combine: match pattern 1\n"); +- return DAG.getNode(LoongArchISD::BSTRINS, DL, ValTy, N0.getOperand(0), +- N1.getOperand(0).getOperand(0), +- DAG.getConstant((MaskIdx0 + MaskLen0 - 1), DL, GRLenVT), +- DAG.getConstant(MaskIdx0, DL, GRLenVT)); +- } +- +- // 2nd pattern to match BSTRINS: +- // R = or (and X, mask0), (shl (and Y, mask1), lsb) +- // where mask1 = (2**size - 1), mask0 = ~(mask1 << lsb) +- // => +- // R = BSTRINS X, Y, msb, lsb (where msb = lsb + size - 1) +- if (N0.getOpcode() == ISD::AND && +- (CN0 = dyn_cast(N0.getOperand(1))) && +- isShiftedMask_64(~CN0->getSExtValue(), MaskIdx0, MaskLen0) && +- N1.getOpcode() == ISD::SHL && N1.getOperand(0).getOpcode() == ISD::AND && +- (CN1 = dyn_cast(N1.getOperand(1))) && +- (Shamt = CN1->getZExtValue()) == MaskIdx0 && +- (CN1 = dyn_cast(N1.getOperand(0).getOperand(1))) && +- isShiftedMask_64(CN1->getZExtValue(), MaskIdx1, MaskLen1) && +- MaskLen0 == MaskLen1 && MaskIdx1 == 0 && +- (MaskIdx0 + MaskLen0 <= ValBits)) { +- LLVM_DEBUG(dbgs() << "Perform OR combine: match pattern 2\n"); +- return DAG.getNode(LoongArchISD::BSTRINS, DL, ValTy, N0.getOperand(0), +- N1.getOperand(0).getOperand(0), +- DAG.getConstant((MaskIdx0 + MaskLen0 - 1), DL, GRLenVT), +- DAG.getConstant(MaskIdx0, DL, GRLenVT)); +- } +- +- // 3rd pattern to match BSTRINS: +- // R = or (and X, mask0), (and Y, mask1) +- // where ~mask0 = (2**size - 1) << lsb, mask0 & mask1 = 0 +- // => +- // R = BSTRINS X, (shr (and Y, mask1), lsb), msb, lsb +- // where msb = lsb + size - 1 +- if (N0.getOpcode() == ISD::AND && N1.getOpcode() == ISD::AND && +- (CN0 = dyn_cast(N0.getOperand(1))) && +- isShiftedMask_64(~CN0->getSExtValue(), MaskIdx0, MaskLen0) && +- (MaskIdx0 + MaskLen0 <= 64) && +- (CN1 = dyn_cast(N1->getOperand(1))) && +- (CN1->getSExtValue() & CN0->getSExtValue()) == 0) { +- LLVM_DEBUG(dbgs() << "Perform OR combine: match pattern 3\n"); +- return DAG.getNode(LoongArchISD::BSTRINS, DL, ValTy, N0.getOperand(0), +- DAG.getNode(ISD::SRL, DL, N1->getValueType(0), N1, +- DAG.getConstant(MaskIdx0, DL, GRLenVT)), +- DAG.getConstant(ValBits == 32 +- ? (MaskIdx0 + (MaskLen0 & 31) - 1) +- : (MaskIdx0 + MaskLen0 - 1), +- DL, GRLenVT), +- DAG.getConstant(MaskIdx0, DL, GRLenVT)); +- } +- +- // 4th pattern to match BSTRINS: +- // R = or (and X, mask), (shl Y, shamt) +- // where mask = (2**shamt - 1) +- // => +- // R = BSTRINS X, Y, ValBits - 1, shamt +- // where ValBits = 32 or 64 +- if (N0.getOpcode() == ISD::AND && N1.getOpcode() == ISD::SHL && +- (CN0 = dyn_cast(N0.getOperand(1))) && +- isShiftedMask_64(CN0->getZExtValue(), MaskIdx0, MaskLen0) && +- MaskIdx0 == 0 && (CN1 = dyn_cast(N1.getOperand(1))) && +- (Shamt = CN1->getZExtValue()) == MaskLen0 && +- (MaskIdx0 + MaskLen0 <= ValBits)) { +- LLVM_DEBUG(dbgs() << "Perform OR combine: match pattern 4\n"); +- return DAG.getNode(LoongArchISD::BSTRINS, DL, ValTy, N0.getOperand(0), +- N1.getOperand(0), +- DAG.getConstant((ValBits - 1), DL, GRLenVT), +- DAG.getConstant(Shamt, DL, GRLenVT)); +- } +- +- // 5th pattern to match BSTRINS: +- // R = or (and X, mask), const +- // where ~mask = (2**size - 1) << lsb, mask & const = 0 +- // => +- // R = BSTRINS X, (const >> lsb), msb, lsb +- // where msb = lsb + size - 1 +- if (N0.getOpcode() == ISD::AND && +- (CN0 = dyn_cast(N0.getOperand(1))) && +- isShiftedMask_64(~CN0->getSExtValue(), MaskIdx0, MaskLen0) && +- (CN1 = dyn_cast(N1)) && +- (CN1->getSExtValue() & CN0->getSExtValue()) == 0) { +- LLVM_DEBUG(dbgs() << "Perform OR combine: match pattern 5\n"); +- return DAG.getNode( +- LoongArchISD::BSTRINS, DL, ValTy, N0.getOperand(0), +- DAG.getConstant(CN1->getSExtValue() >> MaskIdx0, DL, ValTy), +- DAG.getConstant(ValBits == 32 ? (MaskIdx0 + (MaskLen0 & 31) - 1) +- : (MaskIdx0 + MaskLen0 - 1), +- DL, GRLenVT), +- DAG.getConstant(MaskIdx0, DL, GRLenVT)); +- } +- +- // 6th pattern. +- // a = b | ((c & mask) << shamt), where all positions in b to be overwritten +- // by the incoming bits are known to be zero. +- // => +- // a = BSTRINS b, c, shamt + MaskLen - 1, shamt +- // +- // Note that the 1st pattern is a special situation of the 6th, i.e. the 6th +- // pattern is more common than the 1st. So we put the 1st before the 6th in +- // order to match as many nodes as possible. +- ConstantSDNode *CNMask, *CNShamt; +- unsigned MaskIdx, MaskLen; +- if (N1.getOpcode() == ISD::SHL && N1.getOperand(0).getOpcode() == ISD::AND && +- (CNMask = dyn_cast(N1.getOperand(0).getOperand(1))) && +- isShiftedMask_64(CNMask->getZExtValue(), MaskIdx, MaskLen) && +- MaskIdx == 0 && (CNShamt = dyn_cast(N1.getOperand(1))) && +- CNShamt->getZExtValue() + MaskLen <= ValBits) { +- Shamt = CNShamt->getZExtValue(); +- APInt ShMask(ValBits, CNMask->getZExtValue() << Shamt); +- if (ShMask.isSubsetOf(DAG.computeKnownBits(N0).Zero)) { +- LLVM_DEBUG(dbgs() << "Perform OR combine: match pattern 6\n"); +- return DAG.getNode(LoongArchISD::BSTRINS, DL, ValTy, N0, +- N1.getOperand(0).getOperand(0), +- DAG.getConstant(Shamt + MaskLen - 1, DL, GRLenVT), +- DAG.getConstant(Shamt, DL, GRLenVT)); +- } +- } ++ SDValue Opse0[4]; ++ SDValue Opse1[4]; + +- // 7th pattern. +- // a = b | ((c << shamt) & shifted_mask), where all positions in b to be +- // overwritten by the incoming bits are known to be zero. +- // => +- // a = BSTRINS b, c, MaskIdx + MaskLen - 1, MaskIdx +- // +- // Similarly, the 7th pattern is more common than the 2nd. So we put the 2nd +- // before the 7th in order to match as many nodes as possible. +- if (N1.getOpcode() == ISD::AND && +- (CNMask = dyn_cast(N1.getOperand(1))) && +- isShiftedMask_64(CNMask->getZExtValue(), MaskIdx, MaskLen) && +- N1.getOperand(0).getOpcode() == ISD::SHL && +- (CNShamt = dyn_cast(N1.getOperand(0).getOperand(1))) && +- CNShamt->getZExtValue() == MaskIdx) { +- APInt ShMask(ValBits, CNMask->getZExtValue()); +- if (ShMask.isSubsetOf(DAG.computeKnownBits(N0).Zero)) { +- LLVM_DEBUG(dbgs() << "Perform OR combine: match pattern 7\n"); +- return DAG.getNode(LoongArchISD::BSTRINS, DL, ValTy, N0, +- N1.getOperand(0).getOperand(0), +- DAG.getConstant(MaskIdx + MaskLen - 1, DL, GRLenVT), +- DAG.getConstant(MaskIdx, DL, GRLenVT)); ++ for (int i = 0; i < 4; i++) { ++ if (T->getOpcode() == ISD::ADD) { ++ Opse0[i] = T1->getOperand(i); ++ Opse1[i] = T0->getOperand(i); ++ } else if (T->getOpcode() == ISD::SUB) { ++ Opse0[i] = T0->getOperand(i); ++ Opse1[i] = T1->getOperand(i); + } +- } + +- // (or a, b) and (or b, a) are equivalent, so swap the operands and retry. +- if (!SwapAndRetried) { +- std::swap(N0, N1); +- SwapAndRetried = true; +- goto Retry; +- } ++ if (Opse0[i]->getOpcode() != ISD::EXTRACT_VECTOR_ELT || ++ Opse1[i]->getOpcode() != ISD::EXTRACT_VECTOR_ELT) ++ return SDValue(); + +- SwapAndRetried = false; +-Retry2: +- // 8th pattern. +- // a = b | (c & shifted_mask), where all positions in b to be overwritten by +- // the incoming bits are known to be zero. +- // => +- // a = BSTRINS b, c >> MaskIdx, MaskIdx + MaskLen - 1, MaskIdx +- // +- // Similarly, the 8th pattern is more common than the 4th and 5th patterns. So +- // we put it here in order to match as many nodes as possible or generate less +- // instructions. +- if (N1.getOpcode() == ISD::AND && +- (CNMask = dyn_cast(N1.getOperand(1))) && +- isShiftedMask_64(CNMask->getZExtValue(), MaskIdx, MaskLen)) { +- APInt ShMask(ValBits, CNMask->getZExtValue()); +- if (ShMask.isSubsetOf(DAG.computeKnownBits(N0).Zero)) { +- LLVM_DEBUG(dbgs() << "Perform OR combine: match pattern 8\n"); +- return DAG.getNode(LoongArchISD::BSTRINS, DL, ValTy, N0, +- DAG.getNode(ISD::SRL, DL, N1->getValueType(0), +- N1->getOperand(0), +- DAG.getConstant(MaskIdx, DL, GRLenVT)), +- DAG.getConstant(MaskIdx + MaskLen - 1, DL, GRLenVT), +- DAG.getConstant(MaskIdx, DL, GRLenVT)); +- } ++ if (!(dyn_cast(Opse0[i]->getOperand(1)) && ++ dyn_cast(Opse1[i]->getOperand(1)))) ++ return SDValue(); ++ ++ if (cast(Opse0[i]->getOperand(1))->getSExtValue() != ++ (2 * i + 1) || ++ cast(Opse1[i]->getOperand(1))->getSExtValue() != ++ (2 * i)) ++ return SDValue(); ++ ++ if (i > 0 && (Opse0[i]->getOperand(0) != Opse0[i - 1]->getOperand(0) || ++ Opse1[i]->getOperand(0) != Opse1[i - 1]->getOperand(0))) ++ return SDValue(); + } +- // Swap N0/N1 and retry. +- if (!SwapAndRetried) { +- std::swap(N0, N1); +- SwapAndRetried = true; +- goto Retry2; ++ ++ if (N->getOpcode() == ISD::SIGN_EXTEND) { ++ if (T->getOpcode() == ISD::ADD) ++ return SDValue(DAG.getMachineNode(LoongArch::XVHADDW_D_W, DL, MVT::v4i64, ++ Opse0[0]->getOperand(0), ++ Opse1[0]->getOperand(0)), ++ 0); ++ else if (T->getOpcode() == ISD::SUB) ++ return SDValue(DAG.getMachineNode(LoongArch::XVHSUBW_D_W, DL, MVT::v4i64, ++ Opse0[0]->getOperand(0), ++ Opse1[0]->getOperand(0)), ++ 0); ++ } else if (N->getOpcode() == ISD::ZERO_EXTEND) { ++ if (T->getOpcode() == ISD::ADD) ++ return SDValue(DAG.getMachineNode(LoongArch::XVHADDW_DU_WU, DL, ++ MVT::v4i64, Opse0[0]->getOperand(0), ++ Opse1[0]->getOperand(0)), ++ 0); ++ else if (T->getOpcode() == ISD::SUB) ++ return SDValue(DAG.getMachineNode(LoongArch::XVHSUBW_DU_WU, DL, ++ MVT::v4i64, Opse0[0]->getOperand(0), ++ Opse1[0]->getOperand(0)), ++ 0); + } + + return SDValue(); + } + +-// Combine (loongarch_bitrev_w (loongarch_revb_2w X)) to loongarch_bitrev_4b. +-static SDValue performBITREV_WCombine(SDNode *N, SelectionDAG &DAG, +- TargetLowering::DAGCombinerInfo &DCI, +- const LoongArchSubtarget &Subtarget) { +- if (DCI.isBeforeLegalizeOps()) +- return SDValue(); ++static SDValue performSIGN_EXTENDCombine(SDNode *N, SelectionDAG &DAG, ++ TargetLowering::DAGCombinerInfo &DCI, ++ const LoongArchSubtarget &Subtarget) { ++ ++ assert((N->getOpcode() == ISD::SIGN_EXTEND) && "Need ISD::SIGN_EXTEND"); ++ ++ SDLoc DL(N); ++ SDValue Top = N->getOperand(0); + +- SDValue Src = N->getOperand(0); +- if (Src.getOpcode() != LoongArchISD::REVB_2W) ++ SDValue Res; ++ if (Res = performExtend(N, DAG, DCI, Subtarget)) ++ return Res; ++ ++ if (!(Top->getOpcode() == ISD::CopyFromReg)) + return SDValue(); + +- return DAG.getNode(LoongArchISD::BITREV_4B, SDLoc(N), N->getValueType(0), +- Src.getOperand(0)); +-} ++ if ((Top->getOperand(0)->getOpcode() == ISD::EntryToken) && ++ (N->getValueType(0) == MVT::i64)) { + +-template +-static SDValue legalizeIntrinsicImmArg(SDNode *Node, unsigned ImmOp, +- SelectionDAG &DAG, +- const LoongArchSubtarget &Subtarget, +- bool IsSigned = false) { +- SDLoc DL(Node); +- auto *CImm = cast(Node->getOperand(ImmOp)); +- // Check the ImmArg. +- if ((IsSigned && !isInt(CImm->getSExtValue())) || +- (!IsSigned && !isUInt(CImm->getZExtValue()))) { +- DAG.getContext()->emitError(Node->getOperationName(0) + +- ": argument out of range."); +- return DAG.getNode(ISD::UNDEF, DL, Subtarget.getGRLenVT()); +- } +- return DAG.getConstant(CImm->getZExtValue(), DL, Subtarget.getGRLenVT()); +-} ++ SDValue SubReg = DAG.getTargetConstant(LoongArch::sub_32, DL, MVT::i32); ++ SDNode *Res = DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MVT::i64); + +-template +-static SDValue lowerVectorSplatImm(SDNode *Node, unsigned ImmOp, +- SelectionDAG &DAG, bool IsSigned = false) { +- SDLoc DL(Node); +- EVT ResTy = Node->getValueType(0); +- auto *CImm = cast(Node->getOperand(ImmOp)); ++ Res = DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, DL, MVT::i64, ++ SDValue(Res, 0), Top, SubReg); + +- // Check the ImmArg. +- if ((IsSigned && !isInt(CImm->getSExtValue())) || +- (!IsSigned && !isUInt(CImm->getZExtValue()))) { +- DAG.getContext()->emitError(Node->getOperationName(0) + +- ": argument out of range."); +- return DAG.getNode(ISD::UNDEF, DL, ResTy); ++ return SDValue(Res, 0); + } +- return DAG.getConstant( +- APInt(ResTy.getScalarType().getSizeInBits(), +- IsSigned ? CImm->getSExtValue() : CImm->getZExtValue(), IsSigned), +- DL, ResTy); +-} + +-static SDValue truncateVecElts(SDNode *Node, SelectionDAG &DAG) { +- SDLoc DL(Node); +- EVT ResTy = Node->getValueType(0); +- SDValue Vec = Node->getOperand(2); +- SDValue Mask = DAG.getConstant(Vec.getScalarValueSizeInBits() - 1, DL, ResTy); +- return DAG.getNode(ISD::AND, DL, ResTy, Vec, Mask); ++ return SDValue(); + } + +-static SDValue lowerVectorBitClear(SDNode *Node, SelectionDAG &DAG) { +- SDLoc DL(Node); +- EVT ResTy = Node->getValueType(0); +- SDValue One = DAG.getConstant(1, DL, ResTy); +- SDValue Bit = +- DAG.getNode(ISD::SHL, DL, ResTy, One, truncateVecElts(Node, DAG)); ++static SDValue performZERO_EXTENDCombine(SDNode *N, SelectionDAG &DAG, ++ TargetLowering::DAGCombinerInfo &DCI, ++ const LoongArchSubtarget &Subtarget) { + +- return DAG.getNode(ISD::AND, DL, ResTy, Node->getOperand(1), +- DAG.getNOT(DL, Bit, ResTy)); +-} ++ assert((N->getOpcode() == ISD::ZERO_EXTEND) && "Need ISD::ZERO_EXTEND"); + +-template +-static SDValue lowerVectorBitClearImm(SDNode *Node, SelectionDAG &DAG) { +- SDLoc DL(Node); +- EVT ResTy = Node->getValueType(0); +- auto *CImm = cast(Node->getOperand(2)); +- // Check the unsigned ImmArg. +- if (!isUInt(CImm->getZExtValue())) { +- DAG.getContext()->emitError(Node->getOperationName(0) + +- ": argument out of range."); +- return DAG.getNode(ISD::UNDEF, DL, ResTy); +- } ++ SDLoc DL(N); + +- APInt BitImm = APInt(ResTy.getScalarSizeInBits(), 1) << CImm->getAPIntValue(); +- SDValue Mask = DAG.getConstant(~BitImm, DL, ResTy); ++ SDValue Res; ++ if (Res = performExtend(N, DAG, DCI, Subtarget)) ++ return Res; + +- return DAG.getNode(ISD::AND, DL, ResTy, Node->getOperand(1), Mask); ++ return SDValue(); + } + +-template +-static SDValue lowerVectorBitSetImm(SDNode *Node, SelectionDAG &DAG) { +- SDLoc DL(Node); +- EVT ResTy = Node->getValueType(0); +- auto *CImm = cast(Node->getOperand(2)); +- // Check the unsigned ImmArg. +- if (!isUInt(CImm->getZExtValue())) { +- DAG.getContext()->emitError(Node->getOperationName(0) + +- ": argument out of range."); +- return DAG.getNode(ISD::UNDEF, DL, ResTy); +- } ++SDValue LoongArchTargetLowering:: ++PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { ++ SelectionDAG &DAG = DCI.DAG; ++ SDValue Val; + +- APInt Imm = APInt(ResTy.getScalarSizeInBits(), 1) << CImm->getAPIntValue(); +- SDValue BitImm = DAG.getConstant(Imm, DL, ResTy); +- return DAG.getNode(ISD::OR, DL, ResTy, Node->getOperand(1), BitImm); ++ switch (N->getOpcode()) { ++ default: break; ++ case ISD::AND: ++ return performANDCombine(N, DAG, DCI, Subtarget); ++ case ISD::OR: ++ return performORCombine(N, DAG, DCI, Subtarget); ++ case ISD::XOR: ++ return performXORCombine(N, DAG, Subtarget); ++ case ISD::MUL: ++ return performMULCombine(N, DAG, DCI, this, Subtarget); ++ case ISD::SRA: ++ return performSRACombine(N, DAG, DCI, Subtarget); ++ case ISD::SELECT: ++ return performSELECTCombine(N, DAG, DCI, Subtarget); ++ case ISD::VSELECT: ++ return performVSELECTCombine(N, DAG); ++ case ISD::CONCAT_VECTORS: ++ return performCONCAT_VECTORSCombine(N, DAG, DCI, Subtarget); ++ case ISD::SIGN_EXTEND: ++ return performSIGN_EXTENDCombine(N, DAG, DCI, Subtarget); ++ case ISD::ZERO_EXTEND: ++ return performZERO_EXTENDCombine(N, DAG, DCI, Subtarget); ++ case ISD::ADD: ++ case ISD::SUB: ++ case ISD::SHL: ++ case ISD::SRL: ++ return performLogicCombine(N, DAG, Subtarget); ++ } ++ return SDValue(); + } + +-template +-static SDValue lowerVectorBitRevImm(SDNode *Node, SelectionDAG &DAG) { +- SDLoc DL(Node); +- EVT ResTy = Node->getValueType(0); +- auto *CImm = cast(Node->getOperand(2)); +- // Check the unsigned ImmArg. +- if (!isUInt(CImm->getZExtValue())) { +- DAG.getContext()->emitError(Node->getOperationName(0) + +- ": argument out of range."); +- return DAG.getNode(ISD::UNDEF, DL, ResTy); ++static SDValue lowerLSXSplatZExt(SDValue Op, unsigned OpNr, SelectionDAG &DAG) { ++ EVT ResVecTy = Op->getValueType(0); ++ EVT ViaVecTy = ResVecTy; ++ SDLoc DL(Op); ++ ++ // When ResVecTy == MVT::v2i64, LaneA is the upper 32 bits of the lane and ++ // LaneB is the lower 32-bits. Otherwise LaneA and LaneB are alternating ++ // lanes. ++ SDValue LaneA = Op->getOperand(OpNr); ++ SDValue LaneB; ++ ++ if (ResVecTy == MVT::v2i64) { ++ // In case of the index being passed as an immediate value, set the upper ++ // lane to 0 so that the splati.d instruction can be matched. ++ if (isa(LaneA)) ++ LaneB = DAG.getConstant(0, DL, MVT::i32); ++ // Having the index passed in a register, set the upper lane to the same ++ // value as the lower - this results in the BUILD_VECTOR node not being ++ // expanded through stack. This way we are able to pattern match the set of ++ // nodes created here to splat.d. ++ else ++ LaneB = LaneA; ++ ViaVecTy = MVT::v4i32; ++ } else ++ LaneB = LaneA; ++ ++ SDValue Ops[16] = {LaneA, LaneB, LaneA, LaneB, LaneA, LaneB, LaneA, LaneB, ++ LaneA, LaneB, LaneA, LaneB, LaneA, LaneB, LaneA, LaneB}; ++ ++ SDValue Result = DAG.getBuildVector( ++ ViaVecTy, DL, ArrayRef(Ops, ViaVecTy.getVectorNumElements())); ++ ++ if (ViaVecTy != ResVecTy) { ++ SDValue One = DAG.getConstant(1, DL, ViaVecTy); ++ Result = DAG.getNode(ISD::BITCAST, DL, ResVecTy, ++ DAG.getNode(ISD::AND, DL, ViaVecTy, Result, One)); + } + +- APInt Imm = APInt(ResTy.getScalarSizeInBits(), 1) << CImm->getAPIntValue(); +- SDValue BitImm = DAG.getConstant(Imm, DL, ResTy); +- return DAG.getNode(ISD::XOR, DL, ResTy, Node->getOperand(1), BitImm); ++ return Result; + } + +-static SDValue +-performINTRINSIC_WO_CHAINCombine(SDNode *N, SelectionDAG &DAG, +- TargetLowering::DAGCombinerInfo &DCI, ++static SDValue lowerLSXSplatImm(SDValue Op, unsigned ImmOp, SelectionDAG &DAG, ++ bool IsSigned = false) { ++ return DAG.getConstant( ++ APInt(Op->getValueType(0).getScalarType().getSizeInBits(), ++ Op->getConstantOperandVal(ImmOp), IsSigned), ++ SDLoc(Op), Op->getValueType(0)); ++} ++ ++static SDValue getBuildVectorSplat(EVT VecTy, SDValue SplatValue, ++ SelectionDAG &DAG) { ++ EVT ViaVecTy = VecTy; ++ SDValue SplatValueA = SplatValue; ++ SDValue SplatValueB = SplatValue; ++ SDLoc DL(SplatValue); ++ ++ if (VecTy == MVT::v2i64) { ++ // v2i64 BUILD_VECTOR must be performed via v4i32 so split into i32's. ++ ViaVecTy = MVT::v4i32; ++ ++ SplatValueA = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, SplatValue); ++ SplatValueB = DAG.getNode(ISD::SRL, DL, MVT::i64, SplatValue, ++ DAG.getConstant(32, DL, MVT::i32)); ++ SplatValueB = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, SplatValueB); ++ } ++ ++ SDValue Ops[32] = {SplatValueA, SplatValueB, SplatValueA, SplatValueB, ++ SplatValueA, SplatValueB, SplatValueA, SplatValueB, ++ SplatValueA, SplatValueB, SplatValueA, SplatValueB, ++ SplatValueA, SplatValueB, SplatValueA, SplatValueB, ++ SplatValueA, SplatValueB, SplatValueA, SplatValueB, ++ SplatValueA, SplatValueB, SplatValueA, SplatValueB, ++ SplatValueA, SplatValueB, SplatValueA, SplatValueB, ++ SplatValueA, SplatValueB, SplatValueA, SplatValueB}; ++ ++ SDValue Result = DAG.getBuildVector( ++ ViaVecTy, DL, ArrayRef(Ops, ViaVecTy.getVectorNumElements())); ++ ++ if (VecTy != ViaVecTy) ++ Result = DAG.getNode(ISD::BITCAST, DL, VecTy, Result); ++ ++ return Result; ++} ++ ++static SDValue truncateVecElts(SDValue Op, SelectionDAG &DAG) { ++ SDLoc DL(Op); ++ EVT ResTy = Op->getValueType(0); ++ SDValue Vec = Op->getOperand(2); ++ MVT ResEltTy = ++ (ResTy == MVT::v2i64 || ResTy == MVT::v4i64) ? MVT::i64 : MVT::i32; ++ SDValue ConstValue = ++ DAG.getConstant(Vec.getScalarValueSizeInBits() - 1, DL, ResEltTy); ++ SDValue SplatVec = getBuildVectorSplat(ResTy, ConstValue, DAG); ++ ++ return DAG.getNode(ISD::AND, DL, ResTy, Vec, SplatVec); ++} ++ ++static SDValue lowerLSXBitClear(SDValue Op, SelectionDAG &DAG) { ++ EVT ResTy = Op->getValueType(0); ++ SDLoc DL(Op); ++ SDValue One = DAG.getConstant(1, DL, ResTy); ++ SDValue Bit = DAG.getNode(ISD::SHL, DL, ResTy, One, truncateVecElts(Op, DAG)); ++ ++ return DAG.getNode(ISD::AND, DL, ResTy, Op->getOperand(1), ++ DAG.getNOT(DL, Bit, ResTy)); ++} ++ ++static SDValue lowerLSXLoadIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr, ++ const LoongArchSubtarget &Subtarget) { ++ SDLoc DL(Op); ++ SDValue ChainIn = Op->getOperand(0); ++ SDValue Address = Op->getOperand(2); ++ SDValue Offset = Op->getOperand(3); ++ EVT ResTy = Op->getValueType(0); ++ EVT PtrTy = Address->getValueType(0); ++ ++ // For LP64 addresses have the underlying type MVT::i64. This intrinsic ++ // however takes an i32 signed constant offset. The actual type of the ++ // intrinsic is a scaled signed i12. ++ if (Subtarget.isABI_LP64()) ++ Offset = DAG.getNode(ISD::SIGN_EXTEND, DL, PtrTy, Offset); ++ ++ Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset); ++ return DAG.getLoad(ResTy, DL, ChainIn, Address, MachinePointerInfo(), ++ Align(16)); ++} ++ ++static SDValue lowerLASXLoadIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr, + const LoongArchSubtarget &Subtarget) { +- SDLoc DL(N); +- switch (N->getConstantOperandVal(0)) { +- default: +- break; +- case Intrinsic::loongarch_lsx_vadd_b: +- case Intrinsic::loongarch_lsx_vadd_h: +- case Intrinsic::loongarch_lsx_vadd_w: +- case Intrinsic::loongarch_lsx_vadd_d: +- case Intrinsic::loongarch_lasx_xvadd_b: +- case Intrinsic::loongarch_lasx_xvadd_h: +- case Intrinsic::loongarch_lasx_xvadd_w: +- case Intrinsic::loongarch_lasx_xvadd_d: +- return DAG.getNode(ISD::ADD, DL, N->getValueType(0), N->getOperand(1), +- N->getOperand(2)); +- case Intrinsic::loongarch_lsx_vaddi_bu: +- case Intrinsic::loongarch_lsx_vaddi_hu: +- case Intrinsic::loongarch_lsx_vaddi_wu: +- case Intrinsic::loongarch_lsx_vaddi_du: +- case Intrinsic::loongarch_lasx_xvaddi_bu: +- case Intrinsic::loongarch_lasx_xvaddi_hu: +- case Intrinsic::loongarch_lasx_xvaddi_wu: +- case Intrinsic::loongarch_lasx_xvaddi_du: +- return DAG.getNode(ISD::ADD, DL, N->getValueType(0), N->getOperand(1), +- lowerVectorSplatImm<5>(N, 2, DAG)); +- case Intrinsic::loongarch_lsx_vsub_b: +- case Intrinsic::loongarch_lsx_vsub_h: +- case Intrinsic::loongarch_lsx_vsub_w: +- case Intrinsic::loongarch_lsx_vsub_d: +- case Intrinsic::loongarch_lasx_xvsub_b: +- case Intrinsic::loongarch_lasx_xvsub_h: +- case Intrinsic::loongarch_lasx_xvsub_w: +- case Intrinsic::loongarch_lasx_xvsub_d: +- return DAG.getNode(ISD::SUB, DL, N->getValueType(0), N->getOperand(1), +- N->getOperand(2)); +- case Intrinsic::loongarch_lsx_vsubi_bu: +- case Intrinsic::loongarch_lsx_vsubi_hu: +- case Intrinsic::loongarch_lsx_vsubi_wu: +- case Intrinsic::loongarch_lsx_vsubi_du: +- case Intrinsic::loongarch_lasx_xvsubi_bu: +- case Intrinsic::loongarch_lasx_xvsubi_hu: +- case Intrinsic::loongarch_lasx_xvsubi_wu: +- case Intrinsic::loongarch_lasx_xvsubi_du: +- return DAG.getNode(ISD::SUB, DL, N->getValueType(0), N->getOperand(1), +- lowerVectorSplatImm<5>(N, 2, DAG)); +- case Intrinsic::loongarch_lsx_vneg_b: +- case Intrinsic::loongarch_lsx_vneg_h: +- case Intrinsic::loongarch_lsx_vneg_w: +- case Intrinsic::loongarch_lsx_vneg_d: +- case Intrinsic::loongarch_lasx_xvneg_b: +- case Intrinsic::loongarch_lasx_xvneg_h: +- case Intrinsic::loongarch_lasx_xvneg_w: +- case Intrinsic::loongarch_lasx_xvneg_d: +- return DAG.getNode( +- ISD::SUB, DL, N->getValueType(0), +- DAG.getConstant( +- APInt(N->getValueType(0).getScalarType().getSizeInBits(), 0, +- /*isSigned=*/true), +- SDLoc(N), N->getValueType(0)), +- N->getOperand(1)); +- case Intrinsic::loongarch_lsx_vmax_b: +- case Intrinsic::loongarch_lsx_vmax_h: +- case Intrinsic::loongarch_lsx_vmax_w: +- case Intrinsic::loongarch_lsx_vmax_d: +- case Intrinsic::loongarch_lasx_xvmax_b: +- case Intrinsic::loongarch_lasx_xvmax_h: +- case Intrinsic::loongarch_lasx_xvmax_w: +- case Intrinsic::loongarch_lasx_xvmax_d: +- return DAG.getNode(ISD::SMAX, DL, N->getValueType(0), N->getOperand(1), +- N->getOperand(2)); +- case Intrinsic::loongarch_lsx_vmax_bu: +- case Intrinsic::loongarch_lsx_vmax_hu: +- case Intrinsic::loongarch_lsx_vmax_wu: +- case Intrinsic::loongarch_lsx_vmax_du: +- case Intrinsic::loongarch_lasx_xvmax_bu: +- case Intrinsic::loongarch_lasx_xvmax_hu: +- case Intrinsic::loongarch_lasx_xvmax_wu: +- case Intrinsic::loongarch_lasx_xvmax_du: +- return DAG.getNode(ISD::UMAX, DL, N->getValueType(0), N->getOperand(1), +- N->getOperand(2)); +- case Intrinsic::loongarch_lsx_vmaxi_b: +- case Intrinsic::loongarch_lsx_vmaxi_h: +- case Intrinsic::loongarch_lsx_vmaxi_w: +- case Intrinsic::loongarch_lsx_vmaxi_d: +- case Intrinsic::loongarch_lasx_xvmaxi_b: +- case Intrinsic::loongarch_lasx_xvmaxi_h: +- case Intrinsic::loongarch_lasx_xvmaxi_w: +- case Intrinsic::loongarch_lasx_xvmaxi_d: +- return DAG.getNode(ISD::SMAX, DL, N->getValueType(0), N->getOperand(1), +- lowerVectorSplatImm<5>(N, 2, DAG, /*IsSigned=*/true)); +- case Intrinsic::loongarch_lsx_vmaxi_bu: +- case Intrinsic::loongarch_lsx_vmaxi_hu: +- case Intrinsic::loongarch_lsx_vmaxi_wu: +- case Intrinsic::loongarch_lsx_vmaxi_du: +- case Intrinsic::loongarch_lasx_xvmaxi_bu: +- case Intrinsic::loongarch_lasx_xvmaxi_hu: +- case Intrinsic::loongarch_lasx_xvmaxi_wu: +- case Intrinsic::loongarch_lasx_xvmaxi_du: +- return DAG.getNode(ISD::UMAX, DL, N->getValueType(0), N->getOperand(1), +- lowerVectorSplatImm<5>(N, 2, DAG)); +- case Intrinsic::loongarch_lsx_vmin_b: +- case Intrinsic::loongarch_lsx_vmin_h: +- case Intrinsic::loongarch_lsx_vmin_w: +- case Intrinsic::loongarch_lsx_vmin_d: +- case Intrinsic::loongarch_lasx_xvmin_b: +- case Intrinsic::loongarch_lasx_xvmin_h: +- case Intrinsic::loongarch_lasx_xvmin_w: +- case Intrinsic::loongarch_lasx_xvmin_d: +- return DAG.getNode(ISD::SMIN, DL, N->getValueType(0), N->getOperand(1), +- N->getOperand(2)); +- case Intrinsic::loongarch_lsx_vmin_bu: +- case Intrinsic::loongarch_lsx_vmin_hu: +- case Intrinsic::loongarch_lsx_vmin_wu: +- case Intrinsic::loongarch_lsx_vmin_du: +- case Intrinsic::loongarch_lasx_xvmin_bu: +- case Intrinsic::loongarch_lasx_xvmin_hu: +- case Intrinsic::loongarch_lasx_xvmin_wu: +- case Intrinsic::loongarch_lasx_xvmin_du: +- return DAG.getNode(ISD::UMIN, DL, N->getValueType(0), N->getOperand(1), +- N->getOperand(2)); +- case Intrinsic::loongarch_lsx_vmini_b: +- case Intrinsic::loongarch_lsx_vmini_h: +- case Intrinsic::loongarch_lsx_vmini_w: +- case Intrinsic::loongarch_lsx_vmini_d: +- case Intrinsic::loongarch_lasx_xvmini_b: +- case Intrinsic::loongarch_lasx_xvmini_h: +- case Intrinsic::loongarch_lasx_xvmini_w: +- case Intrinsic::loongarch_lasx_xvmini_d: +- return DAG.getNode(ISD::SMIN, DL, N->getValueType(0), N->getOperand(1), +- lowerVectorSplatImm<5>(N, 2, DAG, /*IsSigned=*/true)); +- case Intrinsic::loongarch_lsx_vmini_bu: +- case Intrinsic::loongarch_lsx_vmini_hu: +- case Intrinsic::loongarch_lsx_vmini_wu: +- case Intrinsic::loongarch_lsx_vmini_du: +- case Intrinsic::loongarch_lasx_xvmini_bu: +- case Intrinsic::loongarch_lasx_xvmini_hu: +- case Intrinsic::loongarch_lasx_xvmini_wu: +- case Intrinsic::loongarch_lasx_xvmini_du: +- return DAG.getNode(ISD::UMIN, DL, N->getValueType(0), N->getOperand(1), +- lowerVectorSplatImm<5>(N, 2, DAG)); +- case Intrinsic::loongarch_lsx_vmul_b: +- case Intrinsic::loongarch_lsx_vmul_h: +- case Intrinsic::loongarch_lsx_vmul_w: +- case Intrinsic::loongarch_lsx_vmul_d: +- case Intrinsic::loongarch_lasx_xvmul_b: +- case Intrinsic::loongarch_lasx_xvmul_h: +- case Intrinsic::loongarch_lasx_xvmul_w: +- case Intrinsic::loongarch_lasx_xvmul_d: +- return DAG.getNode(ISD::MUL, DL, N->getValueType(0), N->getOperand(1), +- N->getOperand(2)); +- case Intrinsic::loongarch_lsx_vmadd_b: +- case Intrinsic::loongarch_lsx_vmadd_h: +- case Intrinsic::loongarch_lsx_vmadd_w: +- case Intrinsic::loongarch_lsx_vmadd_d: +- case Intrinsic::loongarch_lasx_xvmadd_b: +- case Intrinsic::loongarch_lasx_xvmadd_h: +- case Intrinsic::loongarch_lasx_xvmadd_w: +- case Intrinsic::loongarch_lasx_xvmadd_d: { +- EVT ResTy = N->getValueType(0); +- return DAG.getNode(ISD::ADD, SDLoc(N), ResTy, N->getOperand(1), +- DAG.getNode(ISD::MUL, SDLoc(N), ResTy, N->getOperand(2), +- N->getOperand(3))); ++ SDLoc DL(Op); ++ SDValue ChainIn = Op->getOperand(0); ++ SDValue Address = Op->getOperand(2); ++ SDValue Offset = Op->getOperand(3); ++ EVT ResTy = Op->getValueType(0); ++ EVT PtrTy = Address->getValueType(0); ++ ++ // For LP64 addresses have the underlying type MVT::i64. This intrinsic ++ // however takes an i32 signed constant offset. The actual type of the ++ // intrinsic is a scaled signed i12. ++ if (Subtarget.isABI_LP64()) ++ Offset = DAG.getNode(ISD::SIGN_EXTEND, DL, PtrTy, Offset); ++ ++ Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset); ++ return DAG.getLoad(ResTy, DL, ChainIn, Address, MachinePointerInfo(), ++ Align(32)); ++} ++ ++static SDValue lowerLASXVLDRIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr, ++ const LoongArchSubtarget &Subtarget) { ++ SDLoc DL(Op); ++ SDValue ChainIn = Op->getOperand(0); ++ SDValue Address = Op->getOperand(2); ++ SDValue Offset = Op->getOperand(3); ++ EVT ResTy = Op->getValueType(0); ++ EVT PtrTy = Address->getValueType(0); ++ ++ // For LP64 addresses have the underlying type MVT::i64. This intrinsic ++ // however takes an i32 signed constant offset. The actual type of the ++ // intrinsic is a scaled signed i12. ++ if (Subtarget.isABI_LP64()) ++ Offset = DAG.getNode(ISD::SIGN_EXTEND, DL, PtrTy, Offset); ++ ++ Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset); ++ return DAG.getNode(LoongArchISD::XVBROADCAST, DL, ++ DAG.getVTList(ResTy, MVT::Other), ChainIn, Address); ++} ++ ++static SDValue lowerLSXVLDRIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr, ++ const LoongArchSubtarget &Subtarget) { ++ SDLoc DL(Op); ++ SDValue ChainIn = Op->getOperand(0); ++ SDValue Address = Op->getOperand(2); ++ SDValue Offset = Op->getOperand(3); ++ EVT ResTy = Op->getValueType(0); ++ EVT PtrTy = Address->getValueType(0); ++ ++ // For LP64 addresses have the underlying type MVT::i64. This intrinsic ++ // however takes an i32 signed constant offset. The actual type of the ++ // intrinsic is a scaled signed i12. ++ if (Subtarget.isABI_LP64()) ++ Offset = DAG.getNode(ISD::SIGN_EXTEND, DL, PtrTy, Offset); ++ ++ Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset); ++ return DAG.getNode(LoongArchISD::VBROADCAST, DL, ++ DAG.getVTList(ResTy, MVT::Other), ChainIn, Address); ++} ++ ++static SDValue lowerLSXStoreIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr, ++ const LoongArchSubtarget &Subtarget) { ++ SDLoc DL(Op); ++ SDValue ChainIn = Op->getOperand(0); ++ SDValue Value = Op->getOperand(2); ++ SDValue Address = Op->getOperand(3); ++ SDValue Offset = Op->getOperand(4); ++ EVT PtrTy = Address->getValueType(0); ++ ++ // For LP64 addresses have the underlying type MVT::i64. This intrinsic ++ // however takes an i32 signed constant offset. The actual type of the ++ // intrinsic is a scaled signed i12. ++ if (Subtarget.isABI_LP64()) ++ Offset = DAG.getNode(ISD::SIGN_EXTEND, DL, PtrTy, Offset); ++ ++ Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset); ++ ++ return DAG.getStore(ChainIn, DL, Value, Address, MachinePointerInfo(), ++ Align(16)); ++} ++ ++static SDValue lowerLASXStoreIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr, ++ const LoongArchSubtarget &Subtarget) { ++ SDLoc DL(Op); ++ SDValue ChainIn = Op->getOperand(0); ++ SDValue Value = Op->getOperand(2); ++ SDValue Address = Op->getOperand(3); ++ SDValue Offset = Op->getOperand(4); ++ EVT PtrTy = Address->getValueType(0); ++ ++ // For LP64 addresses have the underlying type MVT::i64. This intrinsic ++ // however takes an i32 signed constant offset. The actual type of the ++ // intrinsic is a scaled signed i12. ++ if (Subtarget.isABI_LP64()) ++ Offset = DAG.getNode(ISD::SIGN_EXTEND, DL, PtrTy, Offset); ++ ++ Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset); ++ ++ return DAG.getStore(ChainIn, DL, Value, Address, MachinePointerInfo(), ++ Align(32)); ++} ++ ++static SDValue LowerSUINT_TO_FP(unsigned ExtOpcode, SDValue Op, SelectionDAG &DAG) { ++ ++ EVT ResTy = Op->getValueType(0); ++ SDValue Op0 = Op->getOperand(0); ++ EVT ViaTy = Op0->getValueType(0); ++ SDLoc DL(Op); ++ ++ if (!ResTy.isVector()) { ++ if(ResTy.getScalarSizeInBits() == ViaTy.getScalarSizeInBits()) ++ return DAG.getNode(ISD::BITCAST, DL, ResTy, Op0); ++ else if(ResTy.getScalarSizeInBits() > ViaTy.getScalarSizeInBits()) { ++ Op0 = DAG.getNode(ISD::BITCAST, DL, MVT::f32, Op0); ++ return DAG.getNode(ISD::FP_EXTEND, DL, MVT::f64, Op0); ++ } else { ++ Op0 = DAG.getNode(ISD::BITCAST, DL, MVT::f64, Op0); ++ return DAG.getNode(ISD::TRUNCATE, DL, MVT::f32, Op0); ++ } ++ + } +- case Intrinsic::loongarch_lsx_vmsub_b: +- case Intrinsic::loongarch_lsx_vmsub_h: +- case Intrinsic::loongarch_lsx_vmsub_w: +- case Intrinsic::loongarch_lsx_vmsub_d: +- case Intrinsic::loongarch_lasx_xvmsub_b: +- case Intrinsic::loongarch_lasx_xvmsub_h: +- case Intrinsic::loongarch_lasx_xvmsub_w: +- case Intrinsic::loongarch_lasx_xvmsub_d: { +- EVT ResTy = N->getValueType(0); +- return DAG.getNode(ISD::SUB, SDLoc(N), ResTy, N->getOperand(1), +- DAG.getNode(ISD::MUL, SDLoc(N), ResTy, N->getOperand(2), +- N->getOperand(3))); ++ ++ if (ResTy.getScalarSizeInBits() == ViaTy.getScalarSizeInBits()) { ++ // v4i32 => v4f32 v8i32 => v8f32 ++ // v2i64 => v2f64 v4i64 => v4f64 ++ // do nothing ++ } else if (ResTy.getScalarSizeInBits() > ViaTy.getScalarSizeInBits()) { ++ // v4i32 => v4i64 => v4f64 ++ Op0 = DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v8i32, {Op0, Op0}); ++ Op0 = DAG.getNode(ExtOpcode, DL, MVT::v4i64, Op0); ++ } else { ++ // v4i64 => v4f32 ++ SDValue Ops[4]; ++ for (unsigned i = 0; i < 4; i++) { ++ SDValue I64 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i64, Op0, ++ DAG.getConstant(i, DL, MVT::i32)); ++ Ops[i] = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, I64); ++ } ++ Op0 = DAG.getBuildVector(MVT::v4i32, DL, ArrayRef(Ops, 4)); + } +- case Intrinsic::loongarch_lsx_vdiv_b: +- case Intrinsic::loongarch_lsx_vdiv_h: +- case Intrinsic::loongarch_lsx_vdiv_w: +- case Intrinsic::loongarch_lsx_vdiv_d: +- case Intrinsic::loongarch_lasx_xvdiv_b: +- case Intrinsic::loongarch_lasx_xvdiv_h: +- case Intrinsic::loongarch_lasx_xvdiv_w: +- case Intrinsic::loongarch_lasx_xvdiv_d: +- return DAG.getNode(ISD::SDIV, DL, N->getValueType(0), N->getOperand(1), +- N->getOperand(2)); +- case Intrinsic::loongarch_lsx_vdiv_bu: +- case Intrinsic::loongarch_lsx_vdiv_hu: +- case Intrinsic::loongarch_lsx_vdiv_wu: +- case Intrinsic::loongarch_lsx_vdiv_du: +- case Intrinsic::loongarch_lasx_xvdiv_bu: +- case Intrinsic::loongarch_lasx_xvdiv_hu: +- case Intrinsic::loongarch_lasx_xvdiv_wu: +- case Intrinsic::loongarch_lasx_xvdiv_du: +- return DAG.getNode(ISD::UDIV, DL, N->getValueType(0), N->getOperand(1), +- N->getOperand(2)); +- case Intrinsic::loongarch_lsx_vmod_b: +- case Intrinsic::loongarch_lsx_vmod_h: +- case Intrinsic::loongarch_lsx_vmod_w: +- case Intrinsic::loongarch_lsx_vmod_d: +- case Intrinsic::loongarch_lasx_xvmod_b: +- case Intrinsic::loongarch_lasx_xvmod_h: +- case Intrinsic::loongarch_lasx_xvmod_w: +- case Intrinsic::loongarch_lasx_xvmod_d: +- return DAG.getNode(ISD::SREM, DL, N->getValueType(0), N->getOperand(1), +- N->getOperand(2)); +- case Intrinsic::loongarch_lsx_vmod_bu: +- case Intrinsic::loongarch_lsx_vmod_hu: +- case Intrinsic::loongarch_lsx_vmod_wu: +- case Intrinsic::loongarch_lsx_vmod_du: +- case Intrinsic::loongarch_lasx_xvmod_bu: +- case Intrinsic::loongarch_lasx_xvmod_hu: +- case Intrinsic::loongarch_lasx_xvmod_wu: +- case Intrinsic::loongarch_lasx_xvmod_du: +- return DAG.getNode(ISD::UREM, DL, N->getValueType(0), N->getOperand(1), +- N->getOperand(2)); +- case Intrinsic::loongarch_lsx_vand_v: +- case Intrinsic::loongarch_lasx_xvand_v: +- return DAG.getNode(ISD::AND, DL, N->getValueType(0), N->getOperand(1), +- N->getOperand(2)); +- case Intrinsic::loongarch_lsx_vor_v: +- case Intrinsic::loongarch_lasx_xvor_v: +- return DAG.getNode(ISD::OR, DL, N->getValueType(0), N->getOperand(1), +- N->getOperand(2)); +- case Intrinsic::loongarch_lsx_vxor_v: +- case Intrinsic::loongarch_lasx_xvxor_v: +- return DAG.getNode(ISD::XOR, DL, N->getValueType(0), N->getOperand(1), +- N->getOperand(2)); +- case Intrinsic::loongarch_lsx_vnor_v: +- case Intrinsic::loongarch_lasx_xvnor_v: { +- SDValue Res = DAG.getNode(ISD::OR, DL, N->getValueType(0), N->getOperand(1), +- N->getOperand(2)); +- return DAG.getNOT(DL, Res, Res->getValueType(0)); ++ ++ return Op0; ++} ++ ++static SDValue LowerFP_TO_SUINT(unsigned FPToSUI, unsigned ExtOpcode, ++ SDValue Op, SelectionDAG &DAG) { ++ ++ EVT ResTy = Op->getValueType(0); ++ SDValue Op0 = Op->getOperand(0); ++ EVT ViaTy = Op0->getValueType(0); ++ SDLoc DL(Op); ++ ++ if (ResTy.getScalarSizeInBits() == ViaTy.getScalarSizeInBits()) { ++ // v4f32 => v4i32 v8f32 => v8i32 ++ // v2f64 => v2i64 v4f64 => v4i64 ++ // do nothing ++ Op0 = DAG.getNode(FPToSUI, DL, ResTy, Op0); ++ } else if (ResTy.getScalarSizeInBits() > ViaTy.getScalarSizeInBits()) { ++ // v4f32 => v4i32 => v4i64 ++ Op0 = DAG.getNode(FPToSUI, DL, MVT::v4i32, Op0); ++ Op0 = DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v8i32, {Op0, Op0}); ++ Op0 = DAG.getNode(ExtOpcode, DL, MVT::v4i64, Op0); ++ } else { ++ SDValue Ops[4]; ++ Ops[0] = DAG.getNode(FPToSUI, DL, MVT::i32, ++ DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f64, Op0, ++ DAG.getConstant(0, DL, MVT::i64))); ++ Ops[1] = DAG.getNode(FPToSUI, DL, MVT::i32, ++ DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f64, Op0, ++ DAG.getConstant(1, DL, MVT::i64))); ++ Ops[2] = DAG.getNode(FPToSUI, DL, MVT::i32, ++ DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f64, Op0, ++ DAG.getConstant(2, DL, MVT::i64))); ++ Ops[3] = DAG.getNode(FPToSUI, DL, MVT::i32, ++ DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f64, Op0, ++ DAG.getConstant(3, DL, MVT::i64))); ++ ++ Op0 = DAG.getBuildVector(MVT::v4i32, DL, ArrayRef(Ops, 4)); ++ } ++ ++ return Op0; ++} ++ ++// Lower VECTOR_SHUFFLE into SHF (if possible). ++// ++// SHF splits the vector into blocks of four elements, then shuffles these ++// elements according to a <4 x i2> constant (encoded as an integer immediate). ++// ++// It is therefore possible to lower into SHF when the mask takes the form: ++// ++// When undef's appear they are treated as if they were whatever value is ++// necessary in order to fit the above forms. ++// ++// For example: ++// %2 = shufflevector <8 x i16> %0, <8 x i16> undef, ++// <8 x i32> ++// is lowered to: ++// (VSHUF4I_H $v0, $v1, 27) ++// where the 27 comes from: ++// 3 + (2 << 2) + (1 << 4) + (0 << 6) ++static SDValue lowerVECTOR_SHUFFLE_SHF(SDValue Op, EVT ResTy, ++ SmallVector Indices, ++ SelectionDAG &DAG) { ++ int SHFIndices[4] = {-1, -1, -1, -1}; ++ ++ if (Indices.size() < 4) ++ return SDValue(); ++ ++ for (unsigned i = 0; i < 4; ++i) { ++ for (unsigned j = i; j < Indices.size(); j += 4) { ++ int Idx = Indices[j]; ++ ++ // Convert from vector index to 4-element subvector index ++ // If an index refers to an element outside of the subvector then give up ++ if (Idx != -1) { ++ Idx -= 4 * (j / 4); ++ if (Idx < 0 || Idx >= 4) ++ return SDValue(); ++ } ++ ++ // If the mask has an undef, replace it with the current index. ++ // Note that it might still be undef if the current index is also undef ++ if (SHFIndices[i] == -1) ++ SHFIndices[i] = Idx; ++ ++ // Check that non-undef values are the same as in the mask. If they ++ // aren't then give up ++ if (!(Idx == -1 || Idx == SHFIndices[i])) ++ return SDValue(); ++ } ++ } ++ ++ // Calculate the immediate. Replace any remaining undefs with zero ++ APInt Imm(32, 0); ++ for (int i = 3; i >= 0; --i) { ++ int Idx = SHFIndices[i]; ++ ++ if (Idx == -1) ++ Idx = 0; ++ ++ Imm <<= 2; ++ Imm |= Idx & 0x3; ++ } ++ ++ SDLoc DL(Op); ++ return DAG.getNode(LoongArchISD::SHF, DL, ResTy, ++ DAG.getConstant(Imm, DL, MVT::i32), Op->getOperand(0)); ++} ++ ++/// Determine whether a range fits a regular pattern of values. ++/// This function accounts for the possibility of jumping over the End iterator. ++template ++static bool ++fitsRegularPattern(typename SmallVectorImpl::const_iterator Begin, ++ unsigned CheckStride, ++ typename SmallVectorImpl::const_iterator End, ++ ValType ExpectedIndex, unsigned ExpectedIndexStride) { ++ auto &I = Begin; ++ ++ while (I != End) { ++ if (*I != -1 && *I != ExpectedIndex) ++ return false; ++ ExpectedIndex += ExpectedIndexStride; ++ ++ // Incrementing past End is undefined behaviour so we must increment one ++ // step at a time and check for End at each step. ++ for (unsigned n = 0; n < CheckStride && I != End; ++n, ++I) ++ ; // Empty loop body. ++ } ++ return true; ++} ++ ++// Determine whether VECTOR_SHUFFLE is a VREPLVEI. ++// ++// It is a VREPLVEI when the mask is: ++// ++// where x is any valid index. ++// ++// When undef's appear in the mask they are treated as if they were whatever ++// value is necessary in order to fit the above form. ++static bool isVECTOR_SHUFFLE_VREPLVEI(SDValue Op, EVT ResTy, ++ SmallVector Indices, ++ SelectionDAG &DAG) { ++ assert((Indices.size() % 2) == 0); ++ ++ int SplatIndex = -1; ++ for (const auto &V : Indices) { ++ if (V != -1) { ++ SplatIndex = V; ++ break; ++ } ++ } ++ ++ return fitsRegularPattern(Indices.begin(), 1, Indices.end(), SplatIndex, ++ 0); ++} ++ ++// Lower VECTOR_SHUFFLE into VPACKEV (if possible). ++// ++// VPACKEV interleaves the even elements from each vector. ++// ++// It is possible to lower into VPACKEV when the mask consists of two of the ++// following forms interleaved: ++// <0, 2, 4, ...> ++// ++// where n is the number of elements in the vector. ++// For example: ++// <0, 0, 2, 2, 4, 4, ...> ++// <0, n, 2, n+2, 4, n+4, ...> ++// ++// When undef's appear in the mask they are treated as if they were whatever ++// value is necessary in order to fit the above forms. ++static SDValue lowerVECTOR_SHUFFLE_VPACKEV(SDValue Op, EVT ResTy, ++ SmallVector Indices, ++ SelectionDAG &DAG) { ++ assert((Indices.size() % 2) == 0); ++ ++ SDValue Vj; ++ SDValue Vk; ++ const auto &Begin = Indices.begin(); ++ const auto &End = Indices.end(); ++ ++ // Check even elements are taken from the even elements of one half or the ++ // other and pick an operand accordingly. ++ if (fitsRegularPattern(Begin, 2, End, 0, 2)) ++ Vj = Op->getOperand(0); ++ else if (fitsRegularPattern(Begin, 2, End, Indices.size(), 2)) ++ Vj = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ // Check odd elements are taken from the even elements of one half or the ++ // other and pick an operand accordingly. ++ if (fitsRegularPattern(Begin + 1, 2, End, 0, 2)) ++ Vk = Op->getOperand(0); ++ else if (fitsRegularPattern(Begin + 1, 2, End, Indices.size(), 2)) ++ Vk = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ return DAG.getNode(LoongArchISD::VPACKEV, SDLoc(Op), ResTy, Vk, Vj); ++} ++ ++// Lower VECTOR_SHUFFLE into VPACKOD (if possible). ++// ++// VPACKOD interleaves the odd elements from each vector. ++// ++// It is possible to lower into VPACKOD when the mask consists of two of the ++// following forms interleaved: ++// <1, 3, 5, ...> ++// ++// where n is the number of elements in the vector. ++// For example: ++// <1, 1, 3, 3, 5, 5, ...> ++// <1, n+1, 3, n+3, 5, n+5, ...> ++// ++// When undef's appear in the mask they are treated as if they were whatever ++// value is necessary in order to fit the above forms. ++static SDValue lowerVECTOR_SHUFFLE_VPACKOD(SDValue Op, EVT ResTy, ++ SmallVector Indices, ++ SelectionDAG &DAG) { ++ assert((Indices.size() % 2) == 0); ++ ++ SDValue Vj; ++ SDValue Vk; ++ const auto &Begin = Indices.begin(); ++ const auto &End = Indices.end(); ++ ++ // Check even elements are taken from the odd elements of one half or the ++ // other and pick an operand accordingly. ++ if (fitsRegularPattern(Begin, 2, End, 1, 2)) ++ Vj = Op->getOperand(0); ++ else if (fitsRegularPattern(Begin, 2, End, Indices.size() + 1, 2)) ++ Vj = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ // Check odd elements are taken from the odd elements of one half or the ++ // other and pick an operand accordingly. ++ if (fitsRegularPattern(Begin + 1, 2, End, 1, 2)) ++ Vk = Op->getOperand(0); ++ else if (fitsRegularPattern(Begin + 1, 2, End, Indices.size() + 1, 2)) ++ Vk = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ return DAG.getNode(LoongArchISD::VPACKOD, SDLoc(Op), ResTy, Vk, Vj); ++} ++ ++// Lower VECTOR_SHUFFLE into VILVL (if possible). ++// ++// VILVL interleaves consecutive elements from the right (lowest-indexed) half ++// of each vector. ++// ++// It is possible to lower into VILVL when the mask consists of two of the ++// following forms interleaved: ++// <0, 1, 2, ...> ++// ++// where n is the number of elements in the vector. ++// For example: ++// <0, 0, 1, 1, 2, 2, ...> ++// <0, n, 1, n+1, 2, n+2, ...> ++// ++// When undef's appear in the mask they are treated as if they were whatever ++// value is necessary in order to fit the above forms. ++static SDValue lowerVECTOR_SHUFFLE_VILVL(SDValue Op, EVT ResTy, ++ SmallVector Indices, ++ SelectionDAG &DAG) { ++ assert((Indices.size() % 2) == 0); ++ ++ SDValue Vj; ++ SDValue Vk; ++ const auto &Begin = Indices.begin(); ++ const auto &End = Indices.end(); ++ ++ // Check even elements are taken from the right (lowest-indexed) elements of ++ // one half or the other and pick an operand accordingly. ++ if (fitsRegularPattern(Begin, 2, End, 0, 1)) ++ Vj = Op->getOperand(0); ++ else if (fitsRegularPattern(Begin, 2, End, Indices.size(), 1)) ++ Vj = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ // Check odd elements are taken from the right (lowest-indexed) elements of ++ // one half or the other and pick an operand accordingly. ++ if (fitsRegularPattern(Begin + 1, 2, End, 0, 1)) ++ Vk = Op->getOperand(0); ++ else if (fitsRegularPattern(Begin + 1, 2, End, Indices.size(), 1)) ++ Vk = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ return DAG.getNode(LoongArchISD::VILVL, SDLoc(Op), ResTy, Vk, Vj); ++} ++ ++// Lower VECTOR_SHUFFLE into VILVH (if possible). ++// ++// VILVH interleaves consecutive elements from the left (highest-indexed) half ++// of each vector. ++// ++// It is possible to lower into VILVH when the mask consists of two of the ++// following forms interleaved: ++// ++// ++// where n is the number of elements in the vector and x is half n. ++// For example: ++// ++// ++// ++// When undef's appear in the mask they are treated as if they were whatever ++// value is necessary in order to fit the above forms. ++static SDValue lowerVECTOR_SHUFFLE_VILVH(SDValue Op, EVT ResTy, ++ SmallVector Indices, ++ SelectionDAG &DAG) { ++ assert((Indices.size() % 2) == 0); ++ ++ unsigned HalfSize = Indices.size() / 2; ++ SDValue Vj; ++ SDValue Vk; ++ const auto &Begin = Indices.begin(); ++ const auto &End = Indices.end(); ++ ++ // Check even elements are taken from the left (highest-indexed) elements of ++ // one half or the other and pick an operand accordingly. ++ if (fitsRegularPattern(Begin, 2, End, HalfSize, 1)) ++ Vj = Op->getOperand(0); ++ else if (fitsRegularPattern(Begin, 2, End, Indices.size() + HalfSize, 1)) ++ Vj = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ // Check odd elements are taken from the left (highest-indexed) elements of ++ // one half or the other and pick an operand accordingly. ++ if (fitsRegularPattern(Begin + 1, 2, End, HalfSize, 1)) ++ Vk = Op->getOperand(0); ++ else if (fitsRegularPattern(Begin + 1, 2, End, Indices.size() + HalfSize, ++ 1)) ++ Vk = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ return DAG.getNode(LoongArchISD::VILVH, SDLoc(Op), ResTy, Vk, Vj); ++} ++ ++// Lower VECTOR_SHUFFLE into VPICKEV (if possible). ++// ++// VPICKEV copies the even elements of each vector into the result vector. ++// ++// It is possible to lower into VPICKEV when the mask consists of two of the ++// following forms concatenated: ++// <0, 2, 4, ...> ++// ++// where n is the number of elements in the vector. ++// For example: ++// <0, 2, 4, ..., 0, 2, 4, ...> ++// <0, 2, 4, ..., n, n+2, n+4, ...> ++// ++// When undef's appear in the mask they are treated as if they were whatever ++// value is necessary in order to fit the above forms. ++static SDValue lowerVECTOR_SHUFFLE_VPICKEV(SDValue Op, EVT ResTy, ++ SmallVector Indices, ++ SelectionDAG &DAG) { ++ assert((Indices.size() % 2) == 0); ++ ++ SDValue Vj; ++ SDValue Vk; ++ const auto &Begin = Indices.begin(); ++ const auto &Mid = Indices.begin() + Indices.size() / 2; ++ const auto &End = Indices.end(); ++ ++ if (fitsRegularPattern(Begin, 1, Mid, 0, 2)) ++ Vj = Op->getOperand(0); ++ else if (fitsRegularPattern(Begin, 1, Mid, Indices.size(), 2)) ++ Vj = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ if (fitsRegularPattern(Mid, 1, End, 0, 2)) ++ Vk = Op->getOperand(0); ++ else if (fitsRegularPattern(Mid, 1, End, Indices.size(), 2)) ++ Vk = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ return DAG.getNode(LoongArchISD::VPICKEV, SDLoc(Op), ResTy, Vk, Vj); ++} ++ ++// Lower VECTOR_SHUFFLE into VPICKOD (if possible). ++// ++// VPICKOD copies the odd elements of each vector into the result vector. ++// ++// It is possible to lower into VPICKOD when the mask consists of two of the ++// following forms concatenated: ++// <1, 3, 5, ...> ++// ++// where n is the number of elements in the vector. ++// For example: ++// <1, 3, 5, ..., 1, 3, 5, ...> ++// <1, 3, 5, ..., n+1, n+3, n+5, ...> ++// ++// When undef's appear in the mask they are treated as if they were whatever ++// value is necessary in order to fit the above forms. ++static SDValue lowerVECTOR_SHUFFLE_VPICKOD(SDValue Op, EVT ResTy, ++ SmallVector Indices, ++ SelectionDAG &DAG) { ++ assert((Indices.size() % 2) == 0); ++ ++ SDValue Vj; ++ SDValue Vk; ++ const auto &Begin = Indices.begin(); ++ const auto &Mid = Indices.begin() + Indices.size() / 2; ++ const auto &End = Indices.end(); ++ ++ if (fitsRegularPattern(Begin, 1, Mid, 1, 2)) ++ Vj = Op->getOperand(0); ++ else if (fitsRegularPattern(Begin, 1, Mid, Indices.size() + 1, 2)) ++ Vj = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ if (fitsRegularPattern(Mid, 1, End, 1, 2)) ++ Vk = Op->getOperand(0); ++ else if (fitsRegularPattern(Mid, 1, End, Indices.size() + 1, 2)) ++ Vk = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ return DAG.getNode(LoongArchISD::VPICKOD, SDLoc(Op), ResTy, Vk, Vj); ++} ++ ++// Lower VECTOR_SHUFFLE into VSHF. ++// ++// This mostly consists of converting the shuffle indices in Indices into a ++// BUILD_VECTOR and adding it as an operand to the resulting VSHF. There is ++// also code to eliminate unused operands of the VECTOR_SHUFFLE. For example, ++// if the type is v8i16 and all the indices are less than 8 then the second ++// operand is unused and can be replaced with anything. We choose to replace it ++// with the used operand since this reduces the number of instructions overall. ++static SDValue lowerVECTOR_SHUFFLE_VSHF(SDValue Op, EVT ResTy, ++ SmallVector Indices, ++ SelectionDAG &DAG) { ++ SmallVector Ops; ++ SDValue Op0; ++ SDValue Op1; ++ EVT MaskVecTy = ResTy.changeVectorElementTypeToInteger(); ++ EVT MaskEltTy = MaskVecTy.getVectorElementType(); ++ bool Using1stVec = false; ++ bool Using2ndVec = false; ++ SDLoc DL(Op); ++ int ResTyNumElts = ResTy.getVectorNumElements(); ++ ++ for (int i = 0; i < ResTyNumElts; ++i) { ++ // Idx == -1 means UNDEF ++ int Idx = Indices[i]; ++ ++ if (0 <= Idx && Idx < ResTyNumElts) ++ Using1stVec = true; ++ if (ResTyNumElts <= Idx && Idx < ResTyNumElts * 2) ++ Using2ndVec = true; ++ } ++ ++ for (SmallVector::iterator I = Indices.begin(); I != Indices.end(); ++ ++I) ++ Ops.push_back(DAG.getTargetConstant(*I, DL, MaskEltTy)); ++ ++ SDValue MaskVec = DAG.getBuildVector(MaskVecTy, DL, Ops); ++ ++ if (Using1stVec && Using2ndVec) { ++ Op0 = Op->getOperand(0); ++ Op1 = Op->getOperand(1); ++ } else if (Using1stVec) ++ Op0 = Op1 = Op->getOperand(0); ++ else if (Using2ndVec) ++ Op0 = Op1 = Op->getOperand(1); ++ else ++ llvm_unreachable("shuffle vector mask references neither vector operand?"); ++ ++ // VECTOR_SHUFFLE concatenates the vectors in an vectorwise fashion. ++ // <0b00, 0b01> + <0b10, 0b11> -> <0b00, 0b01, 0b10, 0b11> ++ // VSHF concatenates the vectors in a bitwise fashion: ++ // <0b00, 0b01> + <0b10, 0b11> -> ++ // 0b0100 + 0b1110 -> 0b01001110 ++ // <0b10, 0b11, 0b00, 0b01> ++ // We must therefore swap the operands to get the correct result. ++ return DAG.getNode(LoongArchISD::VSHF, DL, ResTy, MaskVec, Op1, Op0); ++} ++ ++static SDValue lowerVECTOR_SHUFFLE_XVILVL(SDValue Op, EVT ResTy, ++ SmallVector Indices, ++ SelectionDAG &DAG) { ++ assert((Indices.size() % 2) == 0); ++ ++ SDValue Xj; ++ SDValue Xk; ++ const auto &Begin = Indices.begin(); ++ const auto &End = Indices.end(); ++ unsigned HalfSize = Indices.size() / 2; ++ ++ if (fitsRegularPattern(Begin, 2, End - HalfSize, 0, 1) && ++ fitsRegularPattern(Begin + HalfSize, 2, End, HalfSize, 1)) ++ Xj = Op->getOperand(0); ++ else if (fitsRegularPattern(Begin, 2, End - HalfSize, Indices.size(), ++ 1) && ++ fitsRegularPattern(Begin + HalfSize, 2, End, ++ Indices.size() + HalfSize, 1)) ++ Xj = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ if (fitsRegularPattern(Begin + 1, 2, End - HalfSize, 0, 1) && ++ fitsRegularPattern(Begin + 1 + HalfSize, 2, End, HalfSize, 1)) ++ Xk = Op->getOperand(0); ++ else if (fitsRegularPattern(Begin + 1, 2, End - HalfSize, Indices.size(), ++ 1) && ++ fitsRegularPattern(Begin + 1 + HalfSize, 2, End, ++ Indices.size() + HalfSize, 1)) ++ Xk = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ return DAG.getNode(LoongArchISD::VILVL, SDLoc(Op), ResTy, Xk, Xj); ++} ++ ++static SDValue lowerVECTOR_SHUFFLE_XVILVH(SDValue Op, EVT ResTy, ++ SmallVector Indices, ++ SelectionDAG &DAG) { ++ assert((Indices.size() % 2) == 0); ++ ++ unsigned HalfSize = Indices.size() / 2; ++ unsigned LeftSize = HalfSize / 2; ++ SDValue Xj; ++ SDValue Xk; ++ const auto &Begin = Indices.begin(); ++ const auto &End = Indices.end(); ++ ++ if (fitsRegularPattern(Begin, 2, End - HalfSize, HalfSize - LeftSize, ++ 1) && ++ fitsRegularPattern(Begin + HalfSize, 2, End, HalfSize + LeftSize, 1)) ++ Xj = Op->getOperand(0); ++ else if (fitsRegularPattern(Begin, 2, End - HalfSize, ++ Indices.size() + HalfSize - LeftSize, 1) && ++ fitsRegularPattern(Begin + HalfSize, 2, End, ++ Indices.size() + HalfSize + LeftSize, 1)) ++ Xj = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ if (fitsRegularPattern(Begin + 1, 2, End - HalfSize, HalfSize - LeftSize, ++ 1) && ++ fitsRegularPattern(Begin + 1 + HalfSize, 2, End, HalfSize + LeftSize, ++ 1)) ++ Xk = Op->getOperand(0); ++ else if (fitsRegularPattern(Begin + 1, 2, End - HalfSize, ++ Indices.size() + HalfSize - LeftSize, 1) && ++ fitsRegularPattern(Begin + 1 + HalfSize, 2, End, ++ Indices.size() + HalfSize + LeftSize, 1)) ++ Xk = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ return DAG.getNode(LoongArchISD::VILVH, SDLoc(Op), ResTy, Xk, Xj); ++} ++ ++static SDValue lowerVECTOR_SHUFFLE_XVPACKEV(SDValue Op, EVT ResTy, ++ SmallVector Indices, ++ SelectionDAG &DAG) { ++ assert((Indices.size() % 2) == 0); ++ ++ SDValue Xj; ++ SDValue Xk; ++ const auto &Begin = Indices.begin(); ++ const auto &End = Indices.end(); ++ unsigned HalfSize = Indices.size() / 2; ++ ++ if (fitsRegularPattern(Begin, 2, End, 0, 2) && ++ fitsRegularPattern(Begin + HalfSize, 2, End, HalfSize, 2)) ++ Xj = Op->getOperand(0); ++ else if (fitsRegularPattern(Begin, 2, End, Indices.size(), 2) && ++ fitsRegularPattern(Begin + HalfSize, 2, End, ++ Indices.size() + HalfSize, 2)) ++ Xj = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ if (fitsRegularPattern(Begin + 1, 2, End, 0, 2) && ++ fitsRegularPattern(Begin + 1 + HalfSize, 2, End, HalfSize, 2)) ++ Xk = Op->getOperand(0); ++ else if (fitsRegularPattern(Begin + 1, 2, End, Indices.size(), 2) && ++ fitsRegularPattern(Begin + 1 + HalfSize, 2, End, ++ Indices.size() + HalfSize, 2)) ++ Xk = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ return DAG.getNode(LoongArchISD::VPACKEV, SDLoc(Op), ResTy, Xk, Xj); ++} ++ ++static SDValue lowerVECTOR_SHUFFLE_XVPACKOD(SDValue Op, EVT ResTy, ++ SmallVector Indices, ++ SelectionDAG &DAG) { ++ assert((Indices.size() % 2) == 0); ++ ++ SDValue Xj; ++ SDValue Xk; ++ const auto &Begin = Indices.begin(); ++ const auto &End = Indices.end(); ++ unsigned HalfSize = Indices.size() / 2; ++ ++ if (fitsRegularPattern(Begin, 2, End, 1, 2) && ++ fitsRegularPattern(Begin + HalfSize, 2, End, HalfSize + 1, 2)) ++ Xj = Op->getOperand(0); ++ else if (fitsRegularPattern(Begin, 2, End, Indices.size() + 1, 2) && ++ fitsRegularPattern(Begin + HalfSize, 2, End, ++ Indices.size() + HalfSize + 1, 2)) ++ Xj = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ if (fitsRegularPattern(Begin + 1, 2, End, 1, 2) && ++ fitsRegularPattern(Begin + 1 + HalfSize, 2, End, HalfSize + 1, 2)) ++ Xk = Op->getOperand(0); ++ else if (fitsRegularPattern(Begin + 1, 2, End, Indices.size() + 1, 2) && ++ fitsRegularPattern(Begin + 1 + HalfSize, 2, End, ++ Indices.size() + HalfSize + 1, 2)) ++ Xk = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ return DAG.getNode(LoongArchISD::VPACKOD, SDLoc(Op), ResTy, Xk, Xj); ++} ++ ++static bool isVECTOR_SHUFFLE_XVREPLVEI(SDValue Op, EVT ResTy, ++ SmallVector Indices, ++ SelectionDAG &DAG) { ++ assert((Indices.size() % 2) == 0); ++ unsigned HalfSize = Indices.size() / 2; ++ ++ for (unsigned i = 0; i < HalfSize; i++) { ++ if (Indices[i] == -1 || Indices[HalfSize + i] == -1) ++ return false; ++ if (Indices[0] != Indices[i] || Indices[HalfSize] != Indices[HalfSize + i]) ++ return false; ++ } ++ return true; ++} ++ ++static SDValue lowerVECTOR_SHUFFLE_XVPICKEV(SDValue Op, EVT ResTy, ++ SmallVector Indices, ++ SelectionDAG &DAG) { ++ assert((Indices.size() % 2) == 0); ++ ++ SDValue Xj; ++ SDValue Xk; ++ const auto &Begin = Indices.begin(); ++ const auto &LeftMid = Indices.begin() + Indices.size() / 4; ++ const auto &End = Indices.end(); ++ const auto &RightMid = Indices.end() - Indices.size() / 4; ++ const auto &Mid = Indices.begin() + Indices.size() / 2; ++ unsigned HalfSize = Indices.size() / 2; ++ ++ if (fitsRegularPattern(Begin, 1, LeftMid, 0, 2) && ++ fitsRegularPattern(Mid, 1, RightMid, HalfSize, 2)) ++ Xj = Op->getOperand(0); ++ else if (fitsRegularPattern(Begin, 1, LeftMid, Indices.size(), 2) && ++ fitsRegularPattern(Mid, 1, RightMid, Indices.size() + HalfSize, ++ 2)) ++ Xj = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ if (fitsRegularPattern(LeftMid, 1, Mid, 0, 2) && ++ fitsRegularPattern(RightMid, 1, End, HalfSize, 2)) ++ Xk = Op->getOperand(0); ++ else if (fitsRegularPattern(LeftMid, 1, Mid, Indices.size(), 2) && ++ fitsRegularPattern(RightMid, 1, End, Indices.size() + HalfSize, ++ 2)) ++ Xk = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ return DAG.getNode(LoongArchISD::VPICKEV, SDLoc(Op), ResTy, Xk, Xj); ++} ++ ++static SDValue lowerVECTOR_SHUFFLE_XVPICKOD(SDValue Op, EVT ResTy, ++ SmallVector Indices, ++ SelectionDAG &DAG) { ++ assert((Indices.size() % 2) == 0); ++ ++ SDValue Xj; ++ SDValue Xk; ++ const auto &Begin = Indices.begin(); ++ const auto &LeftMid = Indices.begin() + Indices.size() / 4; ++ const auto &Mid = Indices.begin() + Indices.size() / 2; ++ const auto &RightMid = Indices.end() - Indices.size() / 4; ++ const auto &End = Indices.end(); ++ unsigned HalfSize = Indices.size() / 2; ++ ++ if (fitsRegularPattern(Begin, 1, LeftMid, 1, 2) && ++ fitsRegularPattern(Mid, 1, RightMid, HalfSize + 1, 2)) ++ Xj = Op->getOperand(0); ++ else if (fitsRegularPattern(Begin, 1, LeftMid, Indices.size() + 1, 2) && ++ fitsRegularPattern(Mid, 1, RightMid, ++ Indices.size() + HalfSize + 1, 2)) ++ Xj = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ if (fitsRegularPattern(LeftMid, 1, Mid, 1, 2) && ++ fitsRegularPattern(RightMid, 1, End, HalfSize + 1, 2)) ++ Xk = Op->getOperand(0); ++ else if (fitsRegularPattern(LeftMid, 1, Mid, Indices.size() + 1, 2) && ++ fitsRegularPattern(RightMid, 1, End, ++ Indices.size() + HalfSize + 1, 2)) ++ Xk = Op->getOperand(1); ++ else ++ return SDValue(); ++ ++ return DAG.getNode(LoongArchISD::VPICKOD, SDLoc(Op), ResTy, Xk, Xj); ++} ++ ++static SDValue lowerVECTOR_SHUFFLE_XSHF(SDValue Op, EVT ResTy, ++ SmallVector Indices, ++ SelectionDAG &DAG) { ++ int SHFIndices[4] = {-1, -1, -1, -1}; ++ ++ // If the size of the mask is 4, it should not be converted to SHF node, ++ // because SHF only corresponds to type b/h/w instruction but no type d. ++ if (Indices.size() <= 4) ++ return SDValue(); ++ ++ int HalfSize = Indices.size() / 2; ++ for (int i = 0; i < 4; ++i) { ++ for (int j = i; j < HalfSize; j += 4) { ++ int Idx = Indices[j]; ++ // check mxshf ++ if (Idx + HalfSize != Indices[j + HalfSize]) ++ return SDValue(); ++ ++ // Convert from vector index to 4-element subvector index ++ // If an index refers to an element outside of the subvector then give up ++ if (Idx != -1) { ++ Idx -= 4 * (j / 4); ++ if (Idx < 0 || Idx >= 4) ++ return SDValue(); ++ } ++ ++ // If the mask has an undef, replace it with the current index. ++ // Note that it might still be undef if the current index is also undef ++ if (SHFIndices[i] == -1) ++ SHFIndices[i] = Idx; ++ ++ // Check that non-undef values are the same as in the mask. If they ++ // aren't then give up ++ if (!(Idx == -1 || Idx == SHFIndices[i])) ++ return SDValue(); ++ } ++ } ++ ++ // Calculate the immediate. Replace any remaining undefs with zero ++ APInt Imm(32, 0); ++ for (int i = 3; i >= 0; --i) { ++ int Idx = SHFIndices[i]; ++ ++ if (Idx == -1) ++ Idx = 0; ++ ++ Imm <<= 2; ++ Imm |= Idx & 0x3; ++ } ++ SDLoc DL(Op); ++ return DAG.getNode(LoongArchISD::SHF, DL, ResTy, ++ DAG.getConstant(Imm, DL, MVT::i32), Op->getOperand(0)); ++} ++ ++static bool isConstantOrUndef(const SDValue Op) { ++ if (Op->isUndef()) ++ return true; ++ if (isa(Op)) ++ return true; ++ if (isa(Op)) ++ return true; ++ return false; ++} ++ ++static bool isConstantOrUndefBUILD_VECTOR(const BuildVectorSDNode *Op) { ++ for (unsigned i = 0; i < Op->getNumOperands(); ++i) ++ if (isConstantOrUndef(Op->getOperand(i))) ++ return true; ++ return false; ++} ++ ++static bool isLASXBySplatBitSize(unsigned SplatBitSize, EVT &ViaVecTy) { ++ switch (SplatBitSize) { ++ default: ++ return false; ++ case 8: ++ ViaVecTy = MVT::v32i8; ++ break; ++ case 16: ++ ViaVecTy = MVT::v16i16; ++ break; ++ case 32: ++ ViaVecTy = MVT::v8i32; ++ break; ++ case 64: ++ ViaVecTy = MVT::v4i64; ++ break; ++ case 128: ++ // There's no fill.q to fall back on for 64-bit values ++ return false; ++ } ++ ++ return true; ++} ++ ++static bool isLSXBySplatBitSize(unsigned SplatBitSize, EVT &ViaVecTy) { ++ switch (SplatBitSize) { ++ default: ++ return false; ++ case 8: ++ ViaVecTy = MVT::v16i8; ++ break; ++ case 16: ++ ViaVecTy = MVT::v8i16; ++ break; ++ case 32: ++ ViaVecTy = MVT::v4i32; ++ break; ++ case 64: ++ // There's no fill.d to fall back on for 64-bit values ++ return false; ++ } ++ ++ return true; ++} ++ ++bool LoongArchTargetLowering::isCheapToSpeculateCttz(Type *) const { ++ return true; ++} ++ ++bool LoongArchTargetLowering::isCheapToSpeculateCtlz(Type *) const { ++ return true; ++} ++ ++void LoongArchTargetLowering::LowerOperationWrapper( ++ SDNode *N, SmallVectorImpl &Results, SelectionDAG &DAG) const { ++ SDValue Res = LowerOperation(SDValue(N, 0), DAG); ++ ++ if (!Res.getNode()) ++ return; ++ ++ assert((N->getNumValues() <= Res->getNumValues()) && ++ "Lowering returned the wrong number of results!"); ++ ++ for (unsigned I = 0, E = Res->getNumValues(); I != E; ++I) ++ Results.push_back(Res.getValue(I)); ++} ++ ++void LoongArchTargetLowering::ReplaceNodeResults( ++ SDNode *N, SmallVectorImpl &Results, SelectionDAG &DAG) const { ++ SDLoc DL(N); ++ switch (N->getOpcode()) { ++ default: ++ return LowerOperationWrapper(N, Results, DAG); ++ case LoongArchISD::VABSD: ++ case LoongArchISD::UVABSD: { ++ EVT VT = N->getValueType(0); ++ assert(VT.isVector() && "Unexpected VT"); ++ if (getTypeAction(*DAG.getContext(), VT) == TypePromoteInteger) { ++ EVT PromoteVT; ++ if (VT.getVectorNumElements() == 2) ++ PromoteVT = MVT::v2i64; ++ else if (VT.getVectorNumElements() == 4) ++ PromoteVT = MVT::v4i32; ++ else if (VT.getVectorNumElements() == 8) ++ PromoteVT = MVT::v8i16; ++ else ++ return; ++ ++ SDValue N0 = ++ DAG.getNode(ISD::ANY_EXTEND, DL, PromoteVT, N->getOperand(0)); ++ SDValue N1 = ++ DAG.getNode(ISD::ANY_EXTEND, DL, PromoteVT, N->getOperand(1)); ++ ++ SDValue Vabsd = ++ DAG.getNode(N->getOpcode(), DL, PromoteVT, N0, N1, N->getOperand(2)); ++ ++ Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, VT, Vabsd)); ++ } ++ return; ++ } ++ } ++} ++ ++SDValue LoongArchTargetLowering::LowerOperation(SDValue Op, ++ SelectionDAG &DAG) const { ++ switch (Op.getOpcode()) { ++ case ISD::STORE: ++ return lowerSTORE(Op, DAG); ++ case ISD::INTRINSIC_WO_CHAIN: ++ return lowerINTRINSIC_WO_CHAIN(Op, DAG); ++ case ISD::INTRINSIC_W_CHAIN: ++ return lowerINTRINSIC_W_CHAIN(Op, DAG); ++ case ISD::INTRINSIC_VOID: ++ return lowerINTRINSIC_VOID(Op, DAG); ++ case ISD::EXTRACT_VECTOR_ELT: ++ return lowerEXTRACT_VECTOR_ELT(Op, DAG); ++ case ISD::INSERT_VECTOR_ELT: ++ return lowerINSERT_VECTOR_ELT(Op, DAG); ++ case ISD::BUILD_VECTOR: ++ return lowerBUILD_VECTOR(Op, DAG); ++ case ISD::VECTOR_SHUFFLE: ++ return lowerVECTOR_SHUFFLE(Op, DAG); ++ case ISD::UINT_TO_FP: ++ return lowerUINT_TO_FP(Op, DAG); ++ case ISD::SINT_TO_FP: ++ return lowerSINT_TO_FP(Op, DAG); ++ case ISD::FP_TO_UINT: ++ return lowerFP_TO_UINT(Op, DAG); ++ case ISD::FP_TO_SINT: ++ return lowerFP_TO_SINT(Op, DAG); ++ case ISD::BRCOND: ++ return lowerBRCOND(Op, DAG); ++ case ISD::ConstantPool: ++ return lowerConstantPool(Op, DAG); ++ case ISD::GlobalAddress: ++ return lowerGlobalAddress(Op, DAG); ++ case ISD::BlockAddress: ++ return lowerBlockAddress(Op, DAG); ++ case ISD::GlobalTLSAddress: ++ return lowerGlobalTLSAddress(Op, DAG); ++ case ISD::JumpTable: ++ return lowerJumpTable(Op, DAG); ++ case ISD::SELECT: ++ return lowerSELECT(Op, DAG); ++ case ISD::SETCC: ++ return lowerSETCC(Op, DAG); ++ case ISD::VASTART: ++ return lowerVASTART(Op, DAG); ++ case ISD::VAARG: ++ return lowerVAARG(Op, DAG); ++ case ISD::FRAMEADDR: ++ return lowerFRAMEADDR(Op, DAG); ++ case ISD::RETURNADDR: ++ return lowerRETURNADDR(Op, DAG); ++ case ISD::EH_RETURN: ++ return lowerEH_RETURN(Op, DAG); ++ case ISD::ATOMIC_FENCE: ++ return lowerATOMIC_FENCE(Op, DAG); ++ case ISD::SHL_PARTS: ++ return lowerShiftLeftParts(Op, DAG); ++ case ISD::SRA_PARTS: ++ return lowerShiftRightParts(Op, DAG, true); ++ case ISD::SRL_PARTS: ++ return lowerShiftRightParts(Op, DAG, false); ++ case ISD::EH_DWARF_CFA: ++ return lowerEH_DWARF_CFA(Op, DAG); ++ } ++ return SDValue(); ++} ++ ++//===----------------------------------------------------------------------===// ++// Lower helper functions ++//===----------------------------------------------------------------------===// ++ ++template ++SDValue LoongArchTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG, ++ bool IsLocal) const { ++ SDLoc DL(N); ++ EVT Ty = getPointerTy(DAG.getDataLayout()); ++ ++ if (isPositionIndependent()) { ++ SDValue Addr = getTargetNode(N, Ty, DAG, 0U); ++ if (IsLocal) ++ // Use PC-relative addressing to access the symbol. ++ return SDValue(DAG.getMachineNode(LoongArch::LoadAddrLocal, DL, Ty, Addr), ++ 0); ++ ++ // Use PC-relative addressing to access the GOT for this symbol, then load ++ // the address from the GOT. ++ return SDValue(DAG.getMachineNode(LoongArch::LoadAddrGlobal, DL, Ty, Addr), ++ 0); ++ } ++ ++ SDValue Addr = getTargetNode(N, Ty, DAG, 0U); ++ return SDValue(DAG.getMachineNode(LoongArch::LoadAddrLocal, DL, Ty, Addr), 0); ++} ++ ++// addLiveIn - This helper function adds the specified physical register to the ++// MachineFunction as a live in value. It also creates a corresponding ++// virtual register for it. ++static unsigned addLiveIn(MachineFunction &MF, unsigned PReg, ++ const TargetRegisterClass *RC) { ++ unsigned VReg = MF.getRegInfo().createVirtualRegister(RC); ++ MF.getRegInfo().addLiveIn(PReg, VReg); ++ return VReg; ++} ++ ++static MachineBasicBlock *insertDivByZeroTrap(MachineInstr &MI, ++ MachineBasicBlock &MBB, ++ const TargetInstrInfo &TII, ++ bool Is64Bit) { ++ if (NoZeroDivCheck) ++ return &MBB; ++ ++ // Insert pseudo instruction(PseudoTEQ), will expand: ++ // beq $divisor_reg, $zero, 8 ++ // break 7 ++ MachineBasicBlock::iterator I(MI); ++ MachineInstrBuilder MIB; ++ MachineOperand &Divisor = MI.getOperand(2); ++ unsigned TeqOp = LoongArch::PseudoTEQ; ++ ++ MIB = BuildMI(MBB, std::next(I), MI.getDebugLoc(), TII.get(TeqOp)) ++ .addReg(Divisor.getReg(), getKillRegState(Divisor.isKill())); ++ ++ // Use the 32-bit sub-register if this is a 64-bit division. ++ //if (Is64Bit) ++ // MIB->getOperand(0).setSubReg(LoongArch::sub_32); ++ ++ // Clear Divisor's kill flag. ++ Divisor.setIsKill(false); ++ ++ // We would normally delete the original instruction here but in this case ++ // we only needed to inject an additional instruction rather than replace it. ++ ++ return &MBB; ++} ++ ++MachineBasicBlock * ++LoongArchTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, ++ MachineBasicBlock *BB) const { ++ switch (MI.getOpcode()) { ++ default: ++ llvm_unreachable("Unexpected instr type to insert"); ++ case LoongArch::FILL_FW_PSEUDO: ++ return emitFILL_FW(MI, BB); ++ case LoongArch::FILL_FD_PSEUDO: ++ return emitFILL_FD(MI, BB); ++ case LoongArch::SNZ_B_PSEUDO: ++ return emitLSXCBranchPseudo(MI, BB, LoongArch::VSETALLNEZ_B); ++ case LoongArch::SNZ_H_PSEUDO: ++ return emitLSXCBranchPseudo(MI, BB, LoongArch::VSETALLNEZ_H); ++ case LoongArch::SNZ_W_PSEUDO: ++ return emitLSXCBranchPseudo(MI, BB, LoongArch::VSETALLNEZ_W); ++ case LoongArch::SNZ_D_PSEUDO: ++ return emitLSXCBranchPseudo(MI, BB, LoongArch::VSETALLNEZ_D); ++ case LoongArch::SNZ_V_PSEUDO: ++ return emitLSXCBranchPseudo(MI, BB, LoongArch::VSETNEZ_V); ++ case LoongArch::SZ_B_PSEUDO: ++ return emitLSXCBranchPseudo(MI, BB, LoongArch::VSETANYEQZ_B); ++ case LoongArch::SZ_H_PSEUDO: ++ return emitLSXCBranchPseudo(MI, BB, LoongArch::VSETANYEQZ_H); ++ case LoongArch::SZ_W_PSEUDO: ++ return emitLSXCBranchPseudo(MI, BB, LoongArch::VSETANYEQZ_W); ++ case LoongArch::SZ_D_PSEUDO: ++ return emitLSXCBranchPseudo(MI, BB, LoongArch::VSETANYEQZ_D); ++ case LoongArch::SZ_V_PSEUDO: ++ return emitLSXCBranchPseudo(MI, BB, LoongArch::VSETEQZ_V); ++ case LoongArch::XSNZ_B_PSEUDO: ++ return emitLSXCBranchPseudo(MI, BB, LoongArch::XVSETALLNEZ_B); ++ case LoongArch::XSNZ_H_PSEUDO: ++ return emitLSXCBranchPseudo(MI, BB, LoongArch::XVSETALLNEZ_H); ++ case LoongArch::XSNZ_W_PSEUDO: ++ return emitLSXCBranchPseudo(MI, BB, LoongArch::XVSETALLNEZ_W); ++ case LoongArch::XSNZ_D_PSEUDO: ++ return emitLSXCBranchPseudo(MI, BB, LoongArch::XVSETALLNEZ_D); ++ case LoongArch::XSNZ_V_PSEUDO: ++ return emitLSXCBranchPseudo(MI, BB, LoongArch::XVSETNEZ_V); ++ case LoongArch::XSZ_B_PSEUDO: ++ return emitLSXCBranchPseudo(MI, BB, LoongArch::XVSETANYEQZ_B); ++ case LoongArch::XSZ_H_PSEUDO: ++ return emitLSXCBranchPseudo(MI, BB, LoongArch::XVSETANYEQZ_H); ++ case LoongArch::XSZ_W_PSEUDO: ++ return emitLSXCBranchPseudo(MI, BB, LoongArch::XVSETANYEQZ_W); ++ case LoongArch::XSZ_D_PSEUDO: ++ return emitLSXCBranchPseudo(MI, BB, LoongArch::XVSETANYEQZ_D); ++ case LoongArch::XSZ_V_PSEUDO: ++ return emitLSXCBranchPseudo(MI, BB, LoongArch::XVSETEQZ_V); ++ case LoongArch::INSERT_FW_PSEUDO: ++ return emitINSERT_FW(MI, BB); ++ case LoongArch::INSERT_FD_PSEUDO: ++ return emitINSERT_FD(MI, BB); ++ case LoongArch::XINSERT_H_PSEUDO: ++ return emitXINSERT_BH(MI, BB, 2); ++ case LoongArch::XCOPY_FW_PSEUDO: ++ return emitXCOPY_FW(MI, BB); ++ case LoongArch::XCOPY_FD_PSEUDO: ++ return emitXCOPY_FD(MI, BB); ++ case LoongArch::XINSERT_FW_PSEUDO: ++ return emitXINSERT_FW(MI, BB); ++ case LoongArch::COPY_FW_PSEUDO: ++ return emitCOPY_FW(MI, BB); ++ case LoongArch::XFILL_FW_PSEUDO: ++ return emitXFILL_FW(MI, BB); ++ case LoongArch::XFILL_FD_PSEUDO: ++ return emitXFILL_FD(MI, BB); ++ case LoongArch::COPY_FD_PSEUDO: ++ return emitCOPY_FD(MI, BB); ++ case LoongArch::XINSERT_FD_PSEUDO: ++ return emitXINSERT_FD(MI, BB); ++ case LoongArch::XINSERT_B_PSEUDO: ++ return emitXINSERT_BH(MI, BB, 1); ++ case LoongArch::CONCAT_VECTORS_B_PSEUDO: ++ return emitCONCAT_VECTORS(MI, BB, 1); ++ case LoongArch::CONCAT_VECTORS_H_PSEUDO: ++ return emitCONCAT_VECTORS(MI, BB, 2); ++ case LoongArch::CONCAT_VECTORS_W_PSEUDO: ++ case LoongArch::CONCAT_VECTORS_FW_PSEUDO: ++ return emitCONCAT_VECTORS(MI, BB, 4); ++ case LoongArch::CONCAT_VECTORS_D_PSEUDO: ++ case LoongArch::CONCAT_VECTORS_FD_PSEUDO: ++ return emitCONCAT_VECTORS(MI, BB, 8); ++ case LoongArch::XCOPY_FW_GPR_PSEUDO: ++ return emitXCOPY_FW_GPR(MI, BB); ++ ++ case LoongArch::ATOMIC_LOAD_ADD_I8: ++ return emitAtomicBinaryPartword(MI, BB, 1); ++ case LoongArch::ATOMIC_LOAD_ADD_I16: ++ return emitAtomicBinaryPartword(MI, BB, 2); ++ case LoongArch::ATOMIC_LOAD_ADD_I32: ++ return emitAtomicBinary(MI, BB); ++ case LoongArch::ATOMIC_LOAD_ADD_I64: ++ return emitAtomicBinary(MI, BB); ++ ++ case LoongArch::ATOMIC_LOAD_AND_I8: ++ return emitAtomicBinaryPartword(MI, BB, 1); ++ case LoongArch::ATOMIC_LOAD_AND_I16: ++ return emitAtomicBinaryPartword(MI, BB, 2); ++ case LoongArch::ATOMIC_LOAD_AND_I32: ++ return emitAtomicBinary(MI, BB); ++ case LoongArch::ATOMIC_LOAD_AND_I64: ++ return emitAtomicBinary(MI, BB); ++ ++ case LoongArch::ATOMIC_LOAD_OR_I8: ++ return emitAtomicBinaryPartword(MI, BB, 1); ++ case LoongArch::ATOMIC_LOAD_OR_I16: ++ return emitAtomicBinaryPartword(MI, BB, 2); ++ case LoongArch::ATOMIC_LOAD_OR_I32: ++ return emitAtomicBinary(MI, BB); ++ case LoongArch::ATOMIC_LOAD_OR_I64: ++ return emitAtomicBinary(MI, BB); ++ ++ case LoongArch::ATOMIC_LOAD_XOR_I8: ++ return emitAtomicBinaryPartword(MI, BB, 1); ++ case LoongArch::ATOMIC_LOAD_XOR_I16: ++ return emitAtomicBinaryPartword(MI, BB, 2); ++ case LoongArch::ATOMIC_LOAD_XOR_I32: ++ return emitAtomicBinary(MI, BB); ++ case LoongArch::ATOMIC_LOAD_XOR_I64: ++ return emitAtomicBinary(MI, BB); ++ ++ case LoongArch::ATOMIC_LOAD_NAND_I8: ++ return emitAtomicBinaryPartword(MI, BB, 1); ++ case LoongArch::ATOMIC_LOAD_NAND_I16: ++ return emitAtomicBinaryPartword(MI, BB, 2); ++ case LoongArch::ATOMIC_LOAD_NAND_I32: ++ return emitAtomicBinary(MI, BB); ++ case LoongArch::ATOMIC_LOAD_NAND_I64: ++ return emitAtomicBinary(MI, BB); ++ ++ case LoongArch::ATOMIC_LOAD_SUB_I8: ++ return emitAtomicBinaryPartword(MI, BB, 1); ++ case LoongArch::ATOMIC_LOAD_SUB_I16: ++ return emitAtomicBinaryPartword(MI, BB, 2); ++ case LoongArch::ATOMIC_LOAD_SUB_I32: ++ return emitAtomicBinary(MI, BB); ++ case LoongArch::ATOMIC_LOAD_SUB_I64: ++ return emitAtomicBinary(MI, BB); ++ ++ case LoongArch::ATOMIC_SWAP_I8: ++ return emitAtomicBinaryPartword(MI, BB, 1); ++ case LoongArch::ATOMIC_SWAP_I16: ++ return emitAtomicBinaryPartword(MI, BB, 2); ++ case LoongArch::ATOMIC_SWAP_I32: ++ return emitAtomicBinary(MI, BB); ++ case LoongArch::ATOMIC_SWAP_I64: ++ return emitAtomicBinary(MI, BB); ++ ++ case LoongArch::XINSERT_B_VIDX_PSEUDO: ++ case LoongArch::XINSERT_B_VIDX64_PSEUDO: ++ return emitXINSERT_B(MI, BB); ++ case LoongArch::INSERT_H_VIDX64_PSEUDO: ++ return emitINSERT_H_VIDX(MI, BB); ++ case LoongArch::XINSERT_FW_VIDX_PSEUDO: ++ return emitXINSERT_DF_VIDX(MI, BB, false); ++ case LoongArch::XINSERT_FW_VIDX64_PSEUDO: ++ return emitXINSERT_DF_VIDX(MI, BB, true); ++ ++ case LoongArch::ATOMIC_LOAD_MAX_I8: ++ return emitAtomicBinaryPartword(MI, BB, 1); ++ case LoongArch::ATOMIC_LOAD_MAX_I16: ++ return emitAtomicBinaryPartword(MI, BB, 2); ++ case LoongArch::ATOMIC_LOAD_MAX_I32: ++ return emitAtomicBinary(MI, BB); ++ case LoongArch::ATOMIC_LOAD_MAX_I64: ++ return emitAtomicBinary(MI, BB); ++ ++ case LoongArch::ATOMIC_LOAD_MIN_I8: ++ return emitAtomicBinaryPartword(MI, BB, 1); ++ case LoongArch::ATOMIC_LOAD_MIN_I16: ++ return emitAtomicBinaryPartword(MI, BB, 2); ++ case LoongArch::ATOMIC_LOAD_MIN_I32: ++ return emitAtomicBinary(MI, BB); ++ case LoongArch::ATOMIC_LOAD_MIN_I64: ++ return emitAtomicBinary(MI, BB); ++ ++ case LoongArch::ATOMIC_LOAD_UMAX_I8: ++ return emitAtomicBinaryPartword(MI, BB, 1); ++ case LoongArch::ATOMIC_LOAD_UMAX_I16: ++ return emitAtomicBinaryPartword(MI, BB, 2); ++ case LoongArch::ATOMIC_LOAD_UMAX_I32: ++ return emitAtomicBinary(MI, BB); ++ case LoongArch::ATOMIC_LOAD_UMAX_I64: ++ return emitAtomicBinary(MI, BB); ++ ++ case LoongArch::ATOMIC_LOAD_UMIN_I8: ++ return emitAtomicBinaryPartword(MI, BB, 1); ++ case LoongArch::ATOMIC_LOAD_UMIN_I16: ++ return emitAtomicBinaryPartword(MI, BB, 2); ++ case LoongArch::ATOMIC_LOAD_UMIN_I32: ++ return emitAtomicBinary(MI, BB); ++ case LoongArch::ATOMIC_LOAD_UMIN_I64: ++ return emitAtomicBinary(MI, BB); ++ ++ case LoongArch::I8_ATOMIC_CMP_SWAP_ACQUIRE: ++ case LoongArch::I8_ATOMIC_CMP_SWAP_ACQ_REL: ++ case LoongArch::I8_ATOMIC_CMP_SWAP_MONOTONIC: ++ case LoongArch::I8_ATOMIC_CMP_SWAP_RELEASE: ++ case LoongArch::I8_ATOMIC_CMP_SWAP_SEQ_CST: ++ return emitAtomicCmpSwapPartword(MI, BB, 1); ++ case LoongArch::I16_ATOMIC_CMP_SWAP_ACQUIRE: ++ case LoongArch::I16_ATOMIC_CMP_SWAP_ACQ_REL: ++ case LoongArch::I16_ATOMIC_CMP_SWAP_MONOTONIC: ++ case LoongArch::I16_ATOMIC_CMP_SWAP_RELEASE: ++ case LoongArch::I16_ATOMIC_CMP_SWAP_SEQ_CST: ++ return emitAtomicCmpSwapPartword(MI, BB, 2); ++ case LoongArch::I32_ATOMIC_CMP_SWAP_ACQUIRE: ++ case LoongArch::I32_ATOMIC_CMP_SWAP_ACQ_REL: ++ case LoongArch::I32_ATOMIC_CMP_SWAP_MONOTONIC: ++ case LoongArch::I32_ATOMIC_CMP_SWAP_RELEASE: ++ case LoongArch::I32_ATOMIC_CMP_SWAP_SEQ_CST: ++ case LoongArch::I64_ATOMIC_CMP_SWAP_ACQUIRE: ++ case LoongArch::I64_ATOMIC_CMP_SWAP_ACQ_REL: ++ case LoongArch::I64_ATOMIC_CMP_SWAP_MONOTONIC: ++ case LoongArch::I64_ATOMIC_CMP_SWAP_RELEASE: ++ case LoongArch::I64_ATOMIC_CMP_SWAP_SEQ_CST: ++ return emitAtomicCmpSwap(MI, BB); ++ ++ case LoongArch::PseudoSELECT_I: ++ case LoongArch::PseudoSELECT_I64: ++ case LoongArch::PseudoSELECT_S: ++ case LoongArch::PseudoSELECT_D64: ++ return emitPseudoSELECT(MI, BB, false, LoongArch::BNE32); ++ ++ case LoongArch::PseudoSELECTFP_T_I: ++ case LoongArch::PseudoSELECTFP_T_I64: ++ return emitPseudoSELECT(MI, BB, true, LoongArch::BCNEZ); ++ ++ case LoongArch::PseudoSELECTFP_F_I: ++ case LoongArch::PseudoSELECTFP_F_I64: ++ return emitPseudoSELECT(MI, BB, true, LoongArch::BCEQZ); ++ case LoongArch::DIV_W: ++ case LoongArch::DIV_WU: ++ case LoongArch::MOD_W: ++ case LoongArch::MOD_WU: ++ return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), false); ++ case LoongArch::DIV_D: ++ case LoongArch::DIV_DU: ++ case LoongArch::MOD_D: ++ case LoongArch::MOD_DU: ++ return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), true); ++ } ++} ++ ++MachineBasicBlock *LoongArchTargetLowering::emitXINSERT_DF_VIDX( ++ MachineInstr &MI, MachineBasicBlock *BB, bool IsGPR64) const { ++ ++ MachineFunction *MF = BB->getParent(); ++ MachineRegisterInfo &RegInfo = MF->getRegInfo(); ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ DebugLoc DL = MI.getDebugLoc(); ++ ++ unsigned insertOp; ++ insertOp = IsGPR64 ? LoongArch::XINSERT_FW_VIDX64_PSEUDO_POSTRA ++ : LoongArch::XINSERT_FW_VIDX_PSEUDO_POSTRA; ++ ++ unsigned DstReg = MI.getOperand(0).getReg(); ++ unsigned SrcVecReg = MI.getOperand(1).getReg(); ++ unsigned LaneReg = MI.getOperand(2).getReg(); ++ unsigned SrcValReg = MI.getOperand(3).getReg(); ++ unsigned Dest = RegInfo.createVirtualRegister(RegInfo.getRegClass(DstReg)); ++ ++ MachineBasicBlock::iterator II(MI); ++ ++ unsigned VecCopy = ++ RegInfo.createVirtualRegister(RegInfo.getRegClass(SrcVecReg)); ++ unsigned LaneCopy = ++ RegInfo.createVirtualRegister(RegInfo.getRegClass(LaneReg)); ++ unsigned ValCopy = ++ RegInfo.createVirtualRegister(RegInfo.getRegClass(SrcValReg)); ++ ++ const TargetRegisterClass *RC = ++ IsGPR64 ? &LoongArch::GPR64RegClass : &LoongArch::GPR32RegClass; ++ unsigned RI = RegInfo.createVirtualRegister(RC); ++ ++ unsigned Rj = RegInfo.createVirtualRegister(&LoongArch::GPR32RegClass); ++ unsigned Xj = RegInfo.createVirtualRegister(&LoongArch::LASX256WRegClass); ++ BuildMI(*BB, II, DL, TII->get(LoongArch::SUBREG_TO_REG), Xj) ++ .addImm(0) ++ .addReg(SrcValReg) ++ .addImm(LoongArch::sub_lo); ++ BuildMI(*BB, II, DL, TII->get(LoongArch::XVPICKVE2GR_W), Rj) ++ .addReg(Xj) ++ .addImm(0); ++ ++ BuildMI(*BB, II, DL, TII->get(LoongArch::COPY), VecCopy).addReg(SrcVecReg); ++ BuildMI(*BB, II, DL, TII->get(LoongArch::COPY), LaneCopy).addReg(LaneReg); ++ BuildMI(*BB, II, DL, TII->get(LoongArch::COPY), ValCopy).addReg(SrcValReg); ++ ++ BuildMI(*BB, II, DL, TII->get(insertOp)) ++ .addReg(DstReg, RegState::Define | RegState::EarlyClobber) ++ .addReg(VecCopy) ++ .addReg(LaneCopy) ++ .addReg(ValCopy) ++ .addReg(Dest, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead) ++ .addReg(RI, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead) ++ .addReg(Rj, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead); ++ ++ MI.eraseFromParent(); ++ ++ return BB; ++} ++ ++MachineBasicBlock * ++LoongArchTargetLowering::emitINSERT_H_VIDX(MachineInstr &MI, ++ MachineBasicBlock *BB) const { ++ ++ MachineFunction *MF = BB->getParent(); ++ MachineRegisterInfo &RegInfo = MF->getRegInfo(); ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ DebugLoc DL = MI.getDebugLoc(); ++ ++ unsigned insertOp; ++ unsigned isGP64 = 0; ++ switch (MI.getOpcode()) { ++ case LoongArch::INSERT_H_VIDX64_PSEUDO: ++ isGP64 = 1; ++ insertOp = LoongArch::INSERT_H_VIDX64_PSEUDO_POSTRA; ++ break; ++ default: ++ llvm_unreachable("Unknown pseudo vector for replacement!"); ++ } ++ ++ unsigned DstReg = MI.getOperand(0).getReg(); ++ unsigned SrcVecReg = MI.getOperand(1).getReg(); ++ unsigned LaneReg = MI.getOperand(2).getReg(); ++ unsigned SrcValReg = MI.getOperand(3).getReg(); ++ unsigned Dest = RegInfo.createVirtualRegister(RegInfo.getRegClass(DstReg)); ++ ++ MachineBasicBlock::iterator II(MI); ++ ++ unsigned VecCopy = ++ RegInfo.createVirtualRegister(RegInfo.getRegClass(SrcVecReg)); ++ unsigned LaneCopy = ++ RegInfo.createVirtualRegister(RegInfo.getRegClass(LaneReg)); ++ unsigned ValCopy = ++ RegInfo.createVirtualRegister(RegInfo.getRegClass(SrcValReg)); ++ ++ const TargetRegisterClass *RC = ++ isGP64 ? &LoongArch::GPR64RegClass : &LoongArch::GPR32RegClass; ++ unsigned RI = RegInfo.createVirtualRegister(RC); ++ ++ BuildMI(*BB, II, DL, TII->get(LoongArch::COPY), VecCopy).addReg(SrcVecReg); ++ BuildMI(*BB, II, DL, TII->get(LoongArch::COPY), LaneCopy).addReg(LaneReg); ++ BuildMI(*BB, II, DL, TII->get(LoongArch::COPY), ValCopy).addReg(SrcValReg); ++ ++ BuildMI(*BB, II, DL, TII->get(insertOp)) ++ .addReg(DstReg, RegState::Define | RegState::EarlyClobber) ++ .addReg(VecCopy) ++ .addReg(LaneCopy) ++ .addReg(ValCopy) ++ .addReg(Dest, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead) ++ .addReg(RI, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead); ++ ++ MI.eraseFromParent(); ++ ++ return BB; ++} ++ ++MachineBasicBlock * ++LoongArchTargetLowering::emitXINSERT_B(MachineInstr &MI, ++ MachineBasicBlock *BB) const { ++ ++ MachineFunction *MF = BB->getParent(); ++ MachineRegisterInfo &RegInfo = MF->getRegInfo(); ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ DebugLoc DL = MI.getDebugLoc(); ++ ++ unsigned insertOp; ++ unsigned isGP64 = 0; ++ switch (MI.getOpcode()) { ++ case LoongArch::XINSERT_B_VIDX64_PSEUDO: ++ isGP64 = 1; ++ insertOp = LoongArch::XINSERT_B_VIDX64_PSEUDO_POSTRA; ++ break; ++ case LoongArch::XINSERT_B_VIDX_PSEUDO: ++ insertOp = LoongArch::XINSERT_B_VIDX_PSEUDO_POSTRA; ++ break; ++ default: ++ llvm_unreachable("Unknown pseudo vector for replacement!"); ++ } ++ ++ unsigned DstReg = MI.getOperand(0).getReg(); ++ unsigned SrcVecReg = MI.getOperand(1).getReg(); ++ unsigned LaneReg = MI.getOperand(2).getReg(); ++ unsigned SrcValReg = MI.getOperand(3).getReg(); ++ unsigned Dest = RegInfo.createVirtualRegister(RegInfo.getRegClass(DstReg)); ++ ++ MachineBasicBlock::iterator II(MI); ++ ++ unsigned VecCopy = ++ RegInfo.createVirtualRegister(RegInfo.getRegClass(SrcVecReg)); ++ unsigned LaneCopy = ++ RegInfo.createVirtualRegister(RegInfo.getRegClass(LaneReg)); ++ unsigned ValCopy = ++ RegInfo.createVirtualRegister(RegInfo.getRegClass(SrcValReg)); ++ const TargetRegisterClass *RC = ++ isGP64 ? &LoongArch::GPR64RegClass : &LoongArch::GPR32RegClass; ++ unsigned Rimm = RegInfo.createVirtualRegister(RC); ++ unsigned R4r = RegInfo.createVirtualRegister(RC); ++ unsigned Rib = RegInfo.createVirtualRegister(RC); ++ unsigned Ris = RegInfo.createVirtualRegister(RC); ++ unsigned R7b1 = RegInfo.createVirtualRegister(RC); ++ unsigned R7b2 = RegInfo.createVirtualRegister(RC); ++ unsigned R7b3 = RegInfo.createVirtualRegister(RC); ++ unsigned RI = RegInfo.createVirtualRegister(RC); ++ ++ unsigned R7r80_3 = RegInfo.createVirtualRegister(&LoongArch::GPR32RegClass); ++ unsigned R7r80l_3 = RegInfo.createVirtualRegister(&LoongArch::GPR32RegClass); ++ unsigned R7r81_3 = RegInfo.createVirtualRegister(&LoongArch::GPR32RegClass); ++ unsigned R7r81l_3 = RegInfo.createVirtualRegister(&LoongArch::GPR32RegClass); ++ unsigned R7r82_3 = RegInfo.createVirtualRegister(&LoongArch::GPR32RegClass); ++ unsigned R7r82l_3 = RegInfo.createVirtualRegister(&LoongArch::GPR32RegClass); ++ unsigned R70 = RegInfo.createVirtualRegister(&LoongArch::GPR32RegClass); ++ unsigned tmp_Dst73 = ++ RegInfo.createVirtualRegister(&LoongArch::LASX256BRegClass); ++ ++ BuildMI(*BB, II, DL, TII->get(LoongArch::COPY), VecCopy).addReg(SrcVecReg); ++ BuildMI(*BB, II, DL, TII->get(LoongArch::COPY), LaneCopy).addReg(LaneReg); ++ BuildMI(*BB, II, DL, TII->get(LoongArch::COPY), ValCopy).addReg(SrcValReg); ++ ++ BuildMI(*BB, II, DL, TII->get(insertOp)) ++ .addReg(DstReg, RegState::Define | RegState::EarlyClobber) ++ .addReg(VecCopy) ++ .addReg(LaneCopy) ++ .addReg(ValCopy) ++ .addReg(Dest, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead) ++ .addReg(R4r, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead) ++ .addReg(Rib, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead) ++ .addReg(Ris, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead) ++ .addReg(R7b1, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead) ++ .addReg(R7b2, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead) ++ .addReg(R7b3, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead) ++ .addReg(R7r80_3, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead) ++ .addReg(R7r80l_3, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead) ++ .addReg(R7r81_3, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead) ++ .addReg(R7r81l_3, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead) ++ .addReg(R7r82_3, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead) ++ .addReg(R7r82l_3, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead) ++ .addReg(RI, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead) ++ .addReg(tmp_Dst73, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead) ++ .addReg(Rimm, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead) ++ .addReg(R70, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead); ++ ++ MI.eraseFromParent(); ++ ++ return BB; ++} ++ ++const TargetRegisterClass * ++LoongArchTargetLowering::getRepRegClassFor(MVT VT) const { ++ return TargetLowering::getRepRegClassFor(VT); ++} ++ ++// This function also handles LoongArch::ATOMIC_SWAP_I32 (when BinOpcode == 0), and ++// LoongArch::ATOMIC_LOAD_NAND_I32 (when Nand == true) ++MachineBasicBlock * ++LoongArchTargetLowering::emitAtomicBinary(MachineInstr &MI, ++ MachineBasicBlock *BB) const { ++ ++ MachineFunction *MF = BB->getParent(); ++ MachineRegisterInfo &RegInfo = MF->getRegInfo(); ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ DebugLoc DL = MI.getDebugLoc(); ++ ++ unsigned AtomicOp; ++ switch (MI.getOpcode()) { ++ case LoongArch::ATOMIC_LOAD_ADD_I32: ++ AtomicOp = LoongArch::ATOMIC_LOAD_ADD_I32_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_SUB_I32: ++ AtomicOp = LoongArch::ATOMIC_LOAD_SUB_I32_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_AND_I32: ++ AtomicOp = LoongArch::ATOMIC_LOAD_AND_I32_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_OR_I32: ++ AtomicOp = LoongArch::ATOMIC_LOAD_OR_I32_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_XOR_I32: ++ AtomicOp = LoongArch::ATOMIC_LOAD_XOR_I32_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_NAND_I32: ++ AtomicOp = LoongArch::ATOMIC_LOAD_NAND_I32_POSTRA; ++ break; ++ case LoongArch::ATOMIC_SWAP_I32: ++ AtomicOp = LoongArch::ATOMIC_SWAP_I32_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_MAX_I32: ++ AtomicOp = LoongArch::ATOMIC_LOAD_MAX_I32_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_MIN_I32: ++ AtomicOp = LoongArch::ATOMIC_LOAD_MIN_I32_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_UMAX_I32: ++ AtomicOp = LoongArch::ATOMIC_LOAD_UMAX_I32_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_UMIN_I32: ++ AtomicOp = LoongArch::ATOMIC_LOAD_UMIN_I32_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_ADD_I64: ++ AtomicOp = LoongArch::ATOMIC_LOAD_ADD_I64_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_SUB_I64: ++ AtomicOp = LoongArch::ATOMIC_LOAD_SUB_I64_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_AND_I64: ++ AtomicOp = LoongArch::ATOMIC_LOAD_AND_I64_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_OR_I64: ++ AtomicOp = LoongArch::ATOMIC_LOAD_OR_I64_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_XOR_I64: ++ AtomicOp = LoongArch::ATOMIC_LOAD_XOR_I64_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_NAND_I64: ++ AtomicOp = LoongArch::ATOMIC_LOAD_NAND_I64_POSTRA; ++ break; ++ case LoongArch::ATOMIC_SWAP_I64: ++ AtomicOp = LoongArch::ATOMIC_SWAP_I64_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_MAX_I64: ++ AtomicOp = LoongArch::ATOMIC_LOAD_MAX_I64_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_MIN_I64: ++ AtomicOp = LoongArch::ATOMIC_LOAD_MIN_I64_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_UMAX_I64: ++ AtomicOp = LoongArch::ATOMIC_LOAD_UMAX_I64_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_UMIN_I64: ++ AtomicOp = LoongArch::ATOMIC_LOAD_UMIN_I64_POSTRA; ++ break; ++ default: ++ llvm_unreachable("Unknown pseudo atomic for replacement!"); ++ } ++ ++ unsigned OldVal = MI.getOperand(0).getReg(); ++ unsigned Ptr = MI.getOperand(1).getReg(); ++ unsigned Incr = MI.getOperand(2).getReg(); ++ unsigned Scratch = RegInfo.createVirtualRegister(RegInfo.getRegClass(OldVal)); ++ ++ MachineBasicBlock::iterator II(MI); ++ ++ // The scratch registers here with the EarlyClobber | Define | Implicit ++ // flags is used to persuade the register allocator and the machine ++ // verifier to accept the usage of this register. This has to be a real ++ // register which has an UNDEF value but is dead after the instruction which ++ // is unique among the registers chosen for the instruction. ++ ++ // The EarlyClobber flag has the semantic properties that the operand it is ++ // attached to is clobbered before the rest of the inputs are read. Hence it ++ // must be unique among the operands to the instruction. ++ // The Define flag is needed to coerce the machine verifier that an Undef ++ // value isn't a problem. ++ // The Dead flag is needed as the value in scratch isn't used by any other ++ // instruction. Kill isn't used as Dead is more precise. ++ // The implicit flag is here due to the interaction between the other flags ++ // and the machine verifier. ++ ++ // For correctness purpose, a new pseudo is introduced here. We need this ++ // new pseudo, so that FastRegisterAllocator does not see an ll/sc sequence ++ // that is spread over >1 basic blocks. A register allocator which ++ // introduces (or any codegen infact) a store, can violate the expectations ++ // of the hardware. ++ // ++ // An atomic read-modify-write sequence starts with a linked load ++ // instruction and ends with a store conditional instruction. The atomic ++ // read-modify-write sequence fails if any of the following conditions ++ // occur between the execution of ll and sc: ++ // * A coherent store is completed by another process or coherent I/O ++ // module into the block of synchronizable physical memory containing ++ // the word. The size and alignment of the block is ++ // implementation-dependent. ++ // * A coherent store is executed between an LL and SC sequence on the ++ // same processor to the block of synchornizable physical memory ++ // containing the word. ++ // ++ ++ unsigned PtrCopy = RegInfo.createVirtualRegister(RegInfo.getRegClass(Ptr)); ++ unsigned IncrCopy = RegInfo.createVirtualRegister(RegInfo.getRegClass(Incr)); ++ ++ BuildMI(*BB, II, DL, TII->get(LoongArch::COPY), IncrCopy).addReg(Incr); ++ BuildMI(*BB, II, DL, TII->get(LoongArch::COPY), PtrCopy).addReg(Ptr); ++ ++ BuildMI(*BB, II, DL, TII->get(AtomicOp)) ++ .addReg(OldVal, RegState::Define | RegState::EarlyClobber) ++ .addReg(PtrCopy) ++ .addReg(IncrCopy) ++ .addReg(Scratch, RegState::Define | RegState::EarlyClobber | ++ RegState::Implicit | RegState::Dead); ++ ++ MI.eraseFromParent(); ++ ++ return BB; ++} ++ ++MachineBasicBlock *LoongArchTargetLowering::emitSignExtendToI32InReg( ++ MachineInstr &MI, MachineBasicBlock *BB, unsigned Size, unsigned DstReg, ++ unsigned SrcReg) const { ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ const DebugLoc &DL = MI.getDebugLoc(); ++ if (Size == 1) { ++ BuildMI(BB, DL, TII->get(LoongArch::EXT_W_B32), DstReg).addReg(SrcReg); ++ return BB; ++ } ++ ++ if (Size == 2) { ++ BuildMI(BB, DL, TII->get(LoongArch::EXT_W_H32), DstReg).addReg(SrcReg); ++ return BB; ++ } ++ ++ MachineFunction *MF = BB->getParent(); ++ MachineRegisterInfo &RegInfo = MF->getRegInfo(); ++ const TargetRegisterClass *RC = getRegClassFor(MVT::i32); ++ unsigned ScrReg = RegInfo.createVirtualRegister(RC); ++ ++ assert(Size < 32); ++ int64_t ShiftImm = 32 - (Size * 8); ++ ++ BuildMI(BB, DL, TII->get(LoongArch::SLLI_W), ScrReg).addReg(SrcReg).addImm(ShiftImm); ++ BuildMI(BB, DL, TII->get(LoongArch::SRAI_W), DstReg).addReg(ScrReg).addImm(ShiftImm); ++ ++ return BB; ++} ++ ++MachineBasicBlock *LoongArchTargetLowering::emitAtomicBinaryPartword( ++ MachineInstr &MI, MachineBasicBlock *BB, unsigned Size) const { ++ assert((Size == 1 || Size == 2) && ++ "Unsupported size for EmitAtomicBinaryPartial."); ++ ++ MachineFunction *MF = BB->getParent(); ++ MachineRegisterInfo &RegInfo = MF->getRegInfo(); ++ const TargetRegisterClass *RC = getRegClassFor(MVT::i32); ++ const bool ArePtrs64bit = ABI.ArePtrs64bit(); ++ const TargetRegisterClass *RCp = ++ getRegClassFor(ArePtrs64bit ? MVT::i64 : MVT::i32); ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ DebugLoc DL = MI.getDebugLoc(); ++ ++ unsigned Dest = MI.getOperand(0).getReg(); ++ unsigned Ptr = MI.getOperand(1).getReg(); ++ unsigned Incr = MI.getOperand(2).getReg(); ++ ++ unsigned AlignedAddr = RegInfo.createVirtualRegister(RCp); ++ unsigned ShiftAmt = RegInfo.createVirtualRegister(RC); ++ unsigned Mask = RegInfo.createVirtualRegister(RC); ++ unsigned Mask2 = RegInfo.createVirtualRegister(RC); ++ unsigned Incr2 = RegInfo.createVirtualRegister(RC); ++ unsigned MaskLSB2 = RegInfo.createVirtualRegister(RCp); ++ unsigned PtrLSB2 = RegInfo.createVirtualRegister(RC); ++ unsigned MaskUpper = RegInfo.createVirtualRegister(RC); ++ unsigned MaskUppest = RegInfo.createVirtualRegister(RC); ++ unsigned Scratch = RegInfo.createVirtualRegister(RC); ++ unsigned Scratch2 = RegInfo.createVirtualRegister(RC); ++ unsigned Scratch3 = RegInfo.createVirtualRegister(RC); ++ unsigned Scratch4 = RegInfo.createVirtualRegister(RC); ++ unsigned Scratch5 = RegInfo.createVirtualRegister(RC); ++ ++ unsigned AtomicOp = 0; ++ switch (MI.getOpcode()) { ++ case LoongArch::ATOMIC_LOAD_NAND_I8: ++ AtomicOp = LoongArch::ATOMIC_LOAD_NAND_I8_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_NAND_I16: ++ AtomicOp = LoongArch::ATOMIC_LOAD_NAND_I16_POSTRA; ++ break; ++ case LoongArch::ATOMIC_SWAP_I8: ++ AtomicOp = LoongArch::ATOMIC_SWAP_I8_POSTRA; ++ break; ++ case LoongArch::ATOMIC_SWAP_I16: ++ AtomicOp = LoongArch::ATOMIC_SWAP_I16_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_MAX_I8: ++ AtomicOp = LoongArch::ATOMIC_LOAD_MAX_I8_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_MAX_I16: ++ AtomicOp = LoongArch::ATOMIC_LOAD_MAX_I16_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_MIN_I8: ++ AtomicOp = LoongArch::ATOMIC_LOAD_MIN_I8_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_MIN_I16: ++ AtomicOp = LoongArch::ATOMIC_LOAD_MIN_I16_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_UMAX_I8: ++ AtomicOp = LoongArch::ATOMIC_LOAD_UMAX_I8_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_UMAX_I16: ++ AtomicOp = LoongArch::ATOMIC_LOAD_UMAX_I16_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_UMIN_I8: ++ AtomicOp = LoongArch::ATOMIC_LOAD_UMIN_I8_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_UMIN_I16: ++ AtomicOp = LoongArch::ATOMIC_LOAD_UMIN_I16_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_ADD_I8: ++ AtomicOp = LoongArch::ATOMIC_LOAD_ADD_I8_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_ADD_I16: ++ AtomicOp = LoongArch::ATOMIC_LOAD_ADD_I16_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_SUB_I8: ++ AtomicOp = LoongArch::ATOMIC_LOAD_SUB_I8_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_SUB_I16: ++ AtomicOp = LoongArch::ATOMIC_LOAD_SUB_I16_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_AND_I8: ++ AtomicOp = LoongArch::ATOMIC_LOAD_AND_I8_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_AND_I16: ++ AtomicOp = LoongArch::ATOMIC_LOAD_AND_I16_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_OR_I8: ++ AtomicOp = LoongArch::ATOMIC_LOAD_OR_I8_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_OR_I16: ++ AtomicOp = LoongArch::ATOMIC_LOAD_OR_I16_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_XOR_I8: ++ AtomicOp = LoongArch::ATOMIC_LOAD_XOR_I8_POSTRA; ++ break; ++ case LoongArch::ATOMIC_LOAD_XOR_I16: ++ AtomicOp = LoongArch::ATOMIC_LOAD_XOR_I16_POSTRA; ++ break; ++ default: ++ llvm_unreachable("Unknown subword atomic pseudo for expansion!"); ++ } ++ ++ // insert new blocks after the current block ++ const BasicBlock *LLVM_BB = BB->getBasicBlock(); ++ MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineFunction::iterator It = ++BB->getIterator(); ++ MF->insert(It, exitMBB); ++ ++ // Transfer the remainder of BB and its successor edges to exitMBB. ++ exitMBB->splice(exitMBB->begin(), BB, ++ std::next(MachineBasicBlock::iterator(MI)), BB->end()); ++ exitMBB->transferSuccessorsAndUpdatePHIs(BB); ++ ++ BB->addSuccessor(exitMBB, BranchProbability::getOne()); ++ ++ // thisMBB: ++ // addiu masklsb2,$0,-4 # 0xfffffffc ++ // and alignedaddr,ptr,masklsb2 ++ // andi ptrlsb2,ptr,3 ++ // sll shiftamt,ptrlsb2,3 ++ // ori maskupper,$0,255 # 0xff ++ // sll mask,maskupper,shiftamt ++ // nor mask2,$0,mask ++ // sll incr2,incr,shiftamt ++ ++ int64_t MaskImm = (Size == 1) ? 255 : 4095; ++ BuildMI(BB, DL, TII->get(ABI.GetPtrAddiOp()), MaskLSB2) ++ .addReg(ABI.GetNullPtr()).addImm(-4); ++ BuildMI(BB, DL, TII->get(ABI.GetPtrAndOp()), AlignedAddr) ++ .addReg(Ptr).addReg(MaskLSB2); ++ BuildMI(BB, DL, TII->get(LoongArch::ANDI32), PtrLSB2) ++ .addReg(Ptr, 0, ArePtrs64bit ? LoongArch::sub_32 : 0).addImm(3); ++ BuildMI(BB, DL, TII->get(LoongArch::SLLI_W), ShiftAmt).addReg(PtrLSB2).addImm(3); ++ ++ if(MaskImm==4095){ ++ BuildMI(BB, DL, TII->get(LoongArch::LU12I_W32), MaskUppest).addImm(0xf); ++ BuildMI(BB, DL, TII->get(LoongArch::ORI32), MaskUpper) ++ .addReg(MaskUppest).addImm(MaskImm); ++ } ++ else{ ++ BuildMI(BB, DL, TII->get(LoongArch::ORI32), MaskUpper) ++ .addReg(LoongArch::ZERO).addImm(MaskImm); ++ } ++ ++ BuildMI(BB, DL, TII->get(LoongArch::SLL_W), Mask) ++ .addReg(MaskUpper).addReg(ShiftAmt); ++ BuildMI(BB, DL, TII->get(LoongArch::NOR32), Mask2).addReg(LoongArch::ZERO).addReg(Mask); ++ BuildMI(BB, DL, TII->get(LoongArch::SLL_W), Incr2).addReg(Incr).addReg(ShiftAmt); ++ ++ ++ // The purposes of the flags on the scratch registers is explained in ++ // emitAtomicBinary. In summary, we need a scratch register which is going to ++ // be undef, that is unique among registers chosen for the instruction. ++ ++ BuildMI(BB, DL, TII->get(AtomicOp)) ++ .addReg(Dest, RegState::Define | RegState::EarlyClobber) ++ .addReg(AlignedAddr) ++ .addReg(Incr2) ++ .addReg(Mask) ++ .addReg(Mask2) ++ .addReg(ShiftAmt) ++ .addReg(Scratch, RegState::EarlyClobber | RegState::Define | ++ RegState::Dead | RegState::Implicit) ++ .addReg(Scratch2, RegState::EarlyClobber | RegState::Define | ++ RegState::Dead | RegState::Implicit) ++ .addReg(Scratch3, RegState::EarlyClobber | RegState::Define | ++ RegState::Dead | RegState::Implicit) ++ .addReg(Scratch4, RegState::EarlyClobber | RegState::Define | ++ RegState::Dead | RegState::Implicit) ++ .addReg(Scratch5, RegState::EarlyClobber | RegState::Define | ++ RegState::Dead | RegState::Implicit); ++ ++ MI.eraseFromParent(); // The instruction is gone now. ++ ++ return exitMBB; ++} ++ ++// Lower atomic compare and swap to a pseudo instruction, taking care to ++// define a scratch register for the pseudo instruction's expansion. The ++// instruction is expanded after the register allocator as to prevent ++// the insertion of stores between the linked load and the store conditional. ++ ++MachineBasicBlock * ++LoongArchTargetLowering::emitAtomicCmpSwap(MachineInstr &MI, ++ MachineBasicBlock *BB) const { ++ unsigned Op = MI.getOpcode(); ++ assert((Op == LoongArch::I32_ATOMIC_CMP_SWAP_ACQUIRE || ++ Op == LoongArch::I32_ATOMIC_CMP_SWAP_ACQ_REL || ++ Op == LoongArch::I32_ATOMIC_CMP_SWAP_MONOTONIC || ++ Op == LoongArch::I32_ATOMIC_CMP_SWAP_RELEASE || ++ Op == LoongArch::I32_ATOMIC_CMP_SWAP_SEQ_CST || ++ Op == LoongArch::I64_ATOMIC_CMP_SWAP_ACQUIRE || ++ Op == LoongArch::I64_ATOMIC_CMP_SWAP_ACQ_REL || ++ Op == LoongArch::I64_ATOMIC_CMP_SWAP_MONOTONIC || ++ Op == LoongArch::I64_ATOMIC_CMP_SWAP_RELEASE || ++ Op == LoongArch::I64_ATOMIC_CMP_SWAP_SEQ_CST) && ++ "Unsupported atomic psseudo for EmitAtomicCmpSwap."); ++ ++ const unsigned Size = (Op == LoongArch::I32_ATOMIC_CMP_SWAP_ACQUIRE || ++ Op == LoongArch::I32_ATOMIC_CMP_SWAP_ACQ_REL || ++ Op == LoongArch::I32_ATOMIC_CMP_SWAP_MONOTONIC || ++ Op == LoongArch::I32_ATOMIC_CMP_SWAP_RELEASE || ++ Op == LoongArch::I32_ATOMIC_CMP_SWAP_SEQ_CST) ++ ? 4 ++ : 8; ++ ++ MachineFunction *MF = BB->getParent(); ++ MachineRegisterInfo &MRI = MF->getRegInfo(); ++ const TargetRegisterClass *RC = getRegClassFor(MVT::getIntegerVT(Size * 8)); ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ DebugLoc DL = MI.getDebugLoc(); ++ ++ unsigned AtomicOp = Size == 4 ? LoongArch::ATOMIC_CMP_SWAP_I32_POSTRA ++ : LoongArch::ATOMIC_CMP_SWAP_I64_POSTRA; ++ unsigned Dest = MI.getOperand(0).getReg(); ++ unsigned Ptr = MI.getOperand(1).getReg(); ++ unsigned OldVal = MI.getOperand(2).getReg(); ++ unsigned NewVal = MI.getOperand(3).getReg(); ++ ++ unsigned Scratch = MRI.createVirtualRegister(RC); ++ MachineBasicBlock::iterator II(MI); ++ ++ // We need to create copies of the various registers and kill them at the ++ // atomic pseudo. If the copies are not made, when the atomic is expanded ++ // after fast register allocation, the spills will end up outside of the ++ // blocks that their values are defined in, causing livein errors. ++ ++ unsigned PtrCopy = MRI.createVirtualRegister(MRI.getRegClass(Ptr)); ++ unsigned OldValCopy = MRI.createVirtualRegister(MRI.getRegClass(OldVal)); ++ unsigned NewValCopy = MRI.createVirtualRegister(MRI.getRegClass(NewVal)); ++ ++ BuildMI(*BB, II, DL, TII->get(LoongArch::COPY), PtrCopy).addReg(Ptr); ++ BuildMI(*BB, II, DL, TII->get(LoongArch::COPY), OldValCopy).addReg(OldVal); ++ BuildMI(*BB, II, DL, TII->get(LoongArch::COPY), NewValCopy).addReg(NewVal); ++ ++ AtomicOrdering Ordering; ++ switch (Op) { ++ case LoongArch::I32_ATOMIC_CMP_SWAP_ACQUIRE: ++ case LoongArch::I64_ATOMIC_CMP_SWAP_ACQUIRE: ++ Ordering = AtomicOrdering::Acquire; ++ break; ++ case LoongArch::I32_ATOMIC_CMP_SWAP_ACQ_REL: ++ case LoongArch::I64_ATOMIC_CMP_SWAP_ACQ_REL: ++ Ordering = AtomicOrdering::AcquireRelease; ++ break; ++ case LoongArch::I32_ATOMIC_CMP_SWAP_SEQ_CST: ++ case LoongArch::I64_ATOMIC_CMP_SWAP_SEQ_CST: ++ Ordering = AtomicOrdering::SequentiallyConsistent; ++ break; ++ case LoongArch::I32_ATOMIC_CMP_SWAP_RELEASE: ++ case LoongArch::I64_ATOMIC_CMP_SWAP_RELEASE: ++ Ordering = AtomicOrdering::Release; ++ break; ++ case LoongArch::I32_ATOMIC_CMP_SWAP_MONOTONIC: ++ case LoongArch::I64_ATOMIC_CMP_SWAP_MONOTONIC: ++ Ordering = AtomicOrdering::Monotonic; ++ break; ++ } ++ ++ // The purposes of the flags on the scratch registers is explained in ++ // emitAtomicBinary. In summary, we need a scratch register which is going to ++ // be undef, that is unique among registers chosen for the instruction. ++ ++ BuildMI(*BB, II, DL, TII->get(AtomicOp)) ++ .addReg(Dest, RegState::Define | RegState::EarlyClobber) ++ .addReg(PtrCopy, RegState::Kill) ++ .addReg(OldValCopy, RegState::Kill) ++ .addReg(NewValCopy, RegState::Kill) ++ .addImm(static_cast(Ordering)) ++ .addReg(Scratch, RegState::EarlyClobber | RegState::Define | ++ RegState::Dead | RegState::Implicit); ++ ++ MI.eraseFromParent(); // The instruction is gone now. ++ ++ return BB; ++} ++ ++MachineBasicBlock *LoongArchTargetLowering::emitAtomicCmpSwapPartword( ++ MachineInstr &MI, MachineBasicBlock *BB, unsigned Size) const { ++ assert((Size == 1 || Size == 2) && ++ "Unsupported size for EmitAtomicCmpSwapPartial."); ++ unsigned Op = MI.getOpcode(); ++ assert((Op == LoongArch::I8_ATOMIC_CMP_SWAP_ACQUIRE || ++ Op == LoongArch::I8_ATOMIC_CMP_SWAP_ACQ_REL || ++ Op == LoongArch::I8_ATOMIC_CMP_SWAP_MONOTONIC || ++ Op == LoongArch::I8_ATOMIC_CMP_SWAP_RELEASE || ++ Op == LoongArch::I8_ATOMIC_CMP_SWAP_SEQ_CST || ++ Op == LoongArch::I16_ATOMIC_CMP_SWAP_ACQUIRE || ++ Op == LoongArch::I16_ATOMIC_CMP_SWAP_ACQ_REL || ++ Op == LoongArch::I16_ATOMIC_CMP_SWAP_MONOTONIC || ++ Op == LoongArch::I16_ATOMIC_CMP_SWAP_RELEASE || ++ Op == LoongArch::I16_ATOMIC_CMP_SWAP_SEQ_CST) && ++ "Unsupported atomic psseudo for EmitAtomicCmpSwapPartword."); ++ ++ MachineFunction *MF = BB->getParent(); ++ MachineRegisterInfo &RegInfo = MF->getRegInfo(); ++ const TargetRegisterClass *RC = getRegClassFor(MVT::i32); ++ const bool ArePtrs64bit = ABI.ArePtrs64bit(); ++ const TargetRegisterClass *RCp = ++ getRegClassFor(ArePtrs64bit ? MVT::i64 : MVT::i32); ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ DebugLoc DL = MI.getDebugLoc(); ++ ++ unsigned Dest = MI.getOperand(0).getReg(); ++ unsigned Ptr = MI.getOperand(1).getReg(); ++ unsigned CmpVal = MI.getOperand(2).getReg(); ++ unsigned NewVal = MI.getOperand(3).getReg(); ++ ++ unsigned AlignedAddr = RegInfo.createVirtualRegister(RCp); ++ unsigned ShiftAmt = RegInfo.createVirtualRegister(RC); ++ unsigned Mask = RegInfo.createVirtualRegister(RC); ++ unsigned Mask2 = RegInfo.createVirtualRegister(RC); ++ unsigned ShiftedCmpVal = RegInfo.createVirtualRegister(RC); ++ unsigned ShiftedNewVal = RegInfo.createVirtualRegister(RC); ++ unsigned MaskLSB2 = RegInfo.createVirtualRegister(RCp); ++ unsigned PtrLSB2 = RegInfo.createVirtualRegister(RC); ++ unsigned MaskUpper = RegInfo.createVirtualRegister(RC); ++ unsigned MaskUppest = RegInfo.createVirtualRegister(RC); ++ unsigned Mask3 = RegInfo.createVirtualRegister(RC); ++ unsigned MaskedCmpVal = RegInfo.createVirtualRegister(RC); ++ unsigned MaskedNewVal = RegInfo.createVirtualRegister(RC); ++ unsigned AtomicOp = Size == 1 ? LoongArch::ATOMIC_CMP_SWAP_I8_POSTRA ++ : LoongArch::ATOMIC_CMP_SWAP_I16_POSTRA; ++ ++ // The scratch registers here with the EarlyClobber | Define | Dead | Implicit ++ // flags are used to coerce the register allocator and the machine verifier to ++ // accept the usage of these registers. ++ // The EarlyClobber flag has the semantic properties that the operand it is ++ // attached to is clobbered before the rest of the inputs are read. Hence it ++ // must be unique among the operands to the instruction. ++ // The Define flag is needed to coerce the machine verifier that an Undef ++ // value isn't a problem. ++ // The Dead flag is needed as the value in scratch isn't used by any other ++ // instruction. Kill isn't used as Dead is more precise. ++ unsigned Scratch = RegInfo.createVirtualRegister(RC); ++ unsigned Scratch2 = RegInfo.createVirtualRegister(RC); ++ ++ // insert new blocks after the current block ++ const BasicBlock *LLVM_BB = BB->getBasicBlock(); ++ MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB); ++ MachineFunction::iterator It = ++BB->getIterator(); ++ MF->insert(It, exitMBB); ++ ++ // Transfer the remainder of BB and its successor edges to exitMBB. ++ exitMBB->splice(exitMBB->begin(), BB, ++ std::next(MachineBasicBlock::iterator(MI)), BB->end()); ++ exitMBB->transferSuccessorsAndUpdatePHIs(BB); ++ ++ BB->addSuccessor(exitMBB, BranchProbability::getOne()); ++ ++ // thisMBB: ++ // addiu masklsb2,$0,-4 # 0xfffffffc ++ // and alignedaddr,ptr,masklsb2 ++ // andi ptrlsb2,ptr,3 ++ // xori ptrlsb2,ptrlsb2,3 # Only for BE ++ // sll shiftamt,ptrlsb2,3 ++ // ori maskupper,$0,255 # 0xff ++ // sll mask,maskupper,shiftamt ++ // nor mask2,$0,mask ++ // andi maskedcmpval,cmpval,255 ++ // sll shiftedcmpval,maskedcmpval,shiftamt ++ // andi maskednewval,newval,255 ++ // sll shiftednewval,maskednewval,shiftamt ++ ++ int64_t MaskImm = (Size == 1) ? 255 : 4095; ++ BuildMI(BB, DL, TII->get(ArePtrs64bit ? LoongArch::ADDI_D : LoongArch::ADDI_W), MaskLSB2) ++ .addReg(ABI.GetNullPtr()).addImm(-4); ++ BuildMI(BB, DL, TII->get(ArePtrs64bit ? LoongArch::AND : LoongArch::AND32), AlignedAddr) ++ .addReg(Ptr).addReg(MaskLSB2); ++ BuildMI(BB, DL, TII->get(LoongArch::ANDI32), PtrLSB2) ++ .addReg(Ptr, 0, ArePtrs64bit ? LoongArch::sub_32 : 0).addImm(3); ++ BuildMI(BB, DL, TII->get(LoongArch::SLLI_W), ShiftAmt).addReg(PtrLSB2).addImm(3); ++ ++ if(MaskImm==4095){ ++ BuildMI(BB, DL, TII->get(LoongArch::LU12I_W32), MaskUppest).addImm(0xf); ++ BuildMI(BB, DL, TII->get(LoongArch::ORI32), MaskUpper) ++ .addReg(MaskUppest).addImm(MaskImm); ++ } ++ else{ ++ BuildMI(BB, DL, TII->get(LoongArch::ORI32), MaskUpper) ++ .addReg(LoongArch::ZERO).addImm(MaskImm); ++ } ++ ++ BuildMI(BB, DL, TII->get(LoongArch::SLL_W), Mask) ++ .addReg(MaskUpper).addReg(ShiftAmt); ++ BuildMI(BB, DL, TII->get(LoongArch::NOR32), Mask2).addReg(LoongArch::ZERO).addReg(Mask); ++ if(MaskImm==4095){ ++ BuildMI(BB, DL, TII->get(LoongArch::ORI32), Mask3) ++ .addReg(MaskUppest).addImm(MaskImm); ++ BuildMI(BB, DL, TII->get(LoongArch::AND32), MaskedCmpVal) ++ .addReg(CmpVal).addReg(Mask3); ++ BuildMI(BB, DL, TII->get(LoongArch::SLL_W), ShiftedCmpVal) ++ .addReg(MaskedCmpVal).addReg(ShiftAmt); ++ BuildMI(BB, DL, TII->get(LoongArch::AND32), MaskedNewVal) ++ .addReg(NewVal).addReg(Mask3); ++ } ++ else{ ++ BuildMI(BB, DL, TII->get(LoongArch::ANDI32), MaskedCmpVal) ++ .addReg(CmpVal).addImm(MaskImm); ++ BuildMI(BB, DL, TII->get(LoongArch::SLL_W), ShiftedCmpVal) ++ .addReg(MaskedCmpVal).addReg(ShiftAmt); ++ BuildMI(BB, DL, TII->get(LoongArch::ANDI32), MaskedNewVal) ++ .addReg(NewVal).addImm(MaskImm); ++ } ++ BuildMI(BB, DL, TII->get(LoongArch::SLL_W), ShiftedNewVal) ++ .addReg(MaskedNewVal).addReg(ShiftAmt); ++ ++ AtomicOrdering Ordering; ++ switch (Op) { ++ case LoongArch::I8_ATOMIC_CMP_SWAP_ACQUIRE: ++ case LoongArch::I16_ATOMIC_CMP_SWAP_ACQUIRE: ++ Ordering = AtomicOrdering::Acquire; ++ break; ++ case LoongArch::I8_ATOMIC_CMP_SWAP_ACQ_REL: ++ case LoongArch::I16_ATOMIC_CMP_SWAP_ACQ_REL: ++ Ordering = AtomicOrdering::AcquireRelease; ++ break; ++ case LoongArch::I8_ATOMIC_CMP_SWAP_SEQ_CST: ++ case LoongArch::I16_ATOMIC_CMP_SWAP_SEQ_CST: ++ Ordering = AtomicOrdering::SequentiallyConsistent; ++ break; ++ case LoongArch::I8_ATOMIC_CMP_SWAP_RELEASE: ++ case LoongArch::I16_ATOMIC_CMP_SWAP_RELEASE: ++ Ordering = AtomicOrdering::Release; ++ break; ++ case LoongArch::I8_ATOMIC_CMP_SWAP_MONOTONIC: ++ case LoongArch::I16_ATOMIC_CMP_SWAP_MONOTONIC: ++ Ordering = AtomicOrdering::Monotonic; ++ break; ++ } ++ // The purposes of the flags on the scratch registers are explained in ++ // emitAtomicBinary. In summary, we need a scratch register which is going to ++ // be undef, that is unique among the register chosen for the instruction. ++ ++ BuildMI(BB, DL, TII->get(AtomicOp)) ++ .addReg(Dest, RegState::Define | RegState::EarlyClobber) ++ .addReg(AlignedAddr) ++ .addReg(Mask) ++ .addReg(ShiftedCmpVal) ++ .addReg(Mask2) ++ .addReg(ShiftedNewVal) ++ .addReg(ShiftAmt) ++ .addImm(static_cast(Ordering)) ++ .addReg(Scratch, RegState::EarlyClobber | RegState::Define | ++ RegState::Dead | RegState::Implicit) ++ .addReg(Scratch2, RegState::EarlyClobber | RegState::Define | ++ RegState::Dead | RegState::Implicit); ++ ++ MI.eraseFromParent(); // The instruction is gone now. ++ ++ return exitMBB; ++} ++ ++SDValue LoongArchTargetLowering::lowerBRCOND(SDValue Op, SelectionDAG &DAG) const { ++ // The first operand is the chain, the second is the condition, the third is ++ // the block to branch to if the condition is true. ++ SDValue Chain = Op.getOperand(0); ++ SDValue Dest = Op.getOperand(2); ++ SDLoc DL(Op); ++ ++ SDValue CondRes = createFPCmp(DAG, Op.getOperand(1)); ++ ++ // Return if flag is not set by a floating point comparison. ++ if (CondRes.getOpcode() != LoongArchISD::FPCmp) ++ return Op; ++ ++ SDValue CCNode = CondRes.getOperand(2); ++ LoongArch::CondCode CC = ++ (LoongArch::CondCode)cast(CCNode)->getZExtValue(); ++ unsigned Opc = invertFPCondCodeUser(CC) ? LoongArch::BRANCH_F : LoongArch::BRANCH_T; ++ SDValue BrCode = DAG.getConstant(Opc, DL, MVT::i32); ++ SDValue FCC0 = DAG.getRegister(LoongArch::FCC0, MVT::i32); ++ return DAG.getNode(LoongArchISD::FPBrcond, DL, Op.getValueType(), Chain, BrCode, ++ FCC0, Dest, CondRes); ++} ++ ++SDValue LoongArchTargetLowering::lowerSELECT(SDValue Op, ++ SelectionDAG &DAG) const { ++ SDValue Cond = createFPCmp(DAG, Op.getOperand(0)); ++ ++ // Return if flag is not set by a floating point comparison. ++ if (Cond.getOpcode() != LoongArchISD::FPCmp) ++ return Op; ++ ++ SDValue N1 = Op.getOperand(1); ++ SDValue N2 = Op.getOperand(2); ++ SDLoc DL(Op); ++ ++ ConstantSDNode *CC = cast(Cond.getOperand(2)); ++ bool invert = invertFPCondCodeUser((LoongArch::CondCode)CC->getSExtValue()); ++ SDValue FCC = DAG.getRegister(LoongArch::FCC0, MVT::i32); ++ ++ if (Op->getSimpleValueType(0).SimpleTy == MVT::f64 || ++ Op->getSimpleValueType(0).SimpleTy == MVT::f32) { ++ if (invert) ++ return DAG.getNode(LoongArchISD::FSEL, DL, N1.getValueType(), N1, FCC, N2, ++ Cond); ++ else ++ return DAG.getNode(LoongArchISD::FSEL, DL, N1.getValueType(), N2, FCC, N1, ++ Cond); ++ ++ } else ++ return Op; ++} ++ ++SDValue LoongArchTargetLowering::lowerSETCC(SDValue Op, SelectionDAG &DAG) const { ++ SDValue Cond = createFPCmp(DAG, Op); ++ ++ assert(Cond.getOpcode() == LoongArchISD::FPCmp && ++ "Floating point operand expected."); ++ ++ SDLoc DL(Op); ++ SDValue True = DAG.getConstant(1, DL, MVT::i32); ++ SDValue False = DAG.getConstant(0, DL, MVT::i32); ++ ++ return createCMovFP(DAG, Cond, True, False, DL); ++} ++ ++SDValue LoongArchTargetLowering::lowerGlobalAddress(SDValue Op, ++ SelectionDAG &DAG) const { ++ GlobalAddressSDNode *N = cast(Op); ++ ++ const GlobalValue *GV = N->getGlobal(); ++ bool IsLocal = getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV); ++ SDValue Addr = getAddr(N, DAG, IsLocal); ++ ++ return Addr; ++} ++ ++SDValue LoongArchTargetLowering::lowerBlockAddress(SDValue Op, ++ SelectionDAG &DAG) const { ++ BlockAddressSDNode *N = cast(Op); ++ ++ return getAddr(N, DAG); ++} ++ ++SDValue LoongArchTargetLowering:: ++lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const ++{ ++ GlobalAddressSDNode *GA = cast(Op); ++ if (DAG.getTarget().useEmulatedTLS()) ++ return LowerToTLSEmulatedModel(GA, DAG); ++ ++ SDLoc DL(GA); ++ const GlobalValue *GV = GA->getGlobal(); ++ EVT PtrVT = getPointerTy(DAG.getDataLayout()); ++ ++ TLSModel::Model model = getTargetMachine().getTLSModel(GV); ++ ++ if (model == TLSModel::GeneralDynamic || model == TLSModel::LocalDynamic) { ++ // General Dynamic TLS Model && Local Dynamic TLS Model ++ unsigned PtrSize = PtrVT.getSizeInBits(); ++ IntegerType *PtrTy = Type::getIntNTy(*DAG.getContext(), PtrSize); ++ // SDValue Addr = DAG.getTargetGlobalAddress(GV, DL, PtrTy, 0, 0); ++ SDValue Addr = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, 0U); ++ SDValue Load = SDValue(DAG.getMachineNode(LoongArch::LoadAddrTLS_GD , ++ DL, PtrVT, Addr), 0); ++ SDValue TlsGetAddr = DAG.getExternalSymbol("__tls_get_addr", PtrVT); ++ ++ ArgListTy Args; ++ ArgListEntry Entry; ++ Entry.Node = Load; ++ Entry.Ty = PtrTy; ++ Args.push_back(Entry); ++ ++ TargetLowering::CallLoweringInfo CLI(DAG); ++ CLI.setDebugLoc(DL) ++ .setChain(DAG.getEntryNode()) ++ .setLibCallee(CallingConv::C, PtrTy, TlsGetAddr, std::move(Args)); ++ std::pair CallResult = LowerCallTo(CLI); ++ ++ SDValue Ret = CallResult.first; ++ ++ return Ret; ++ } ++ ++ SDValue Addr = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, 0U); ++ SDValue Offset; ++ if (model == TLSModel::InitialExec) { ++ // Initial Exec TLS Model ++ Offset = SDValue(DAG.getMachineNode(LoongArch::LoadAddrTLS_IE, DL, ++ PtrVT, Addr), 0); ++ } else { ++ // Local Exec TLS Model ++ assert(model == TLSModel::LocalExec); ++ Offset = SDValue(DAG.getMachineNode(LoongArch::LoadAddrTLS_LE, DL, ++ PtrVT, Addr), 0); ++ } ++ ++ SDValue ThreadPointer = DAG.getRegister((PtrVT == MVT::i32) ++ ? LoongArch::TP ++ : LoongArch::TP_64, PtrVT); ++ return DAG.getNode(ISD::ADD, DL, PtrVT, ThreadPointer, Offset); ++} ++ ++SDValue LoongArchTargetLowering:: ++lowerJumpTable(SDValue Op, SelectionDAG &DAG) const ++{ ++ JumpTableSDNode *N = cast(Op); ++ ++ return getAddr(N, DAG); ++} ++ ++SDValue LoongArchTargetLowering:: ++lowerConstantPool(SDValue Op, SelectionDAG &DAG) const ++{ ++ ConstantPoolSDNode *N = cast(Op); ++ ++ return getAddr(N, DAG); ++} ++ ++SDValue LoongArchTargetLowering::lowerVASTART(SDValue Op, SelectionDAG &DAG) const { ++ MachineFunction &MF = DAG.getMachineFunction(); ++ LoongArchFunctionInfo *FuncInfo = MF.getInfo(); ++ ++ SDLoc DL(Op); ++ SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), ++ getPointerTy(MF.getDataLayout())); ++ ++ // vastart just stores the address of the VarArgsFrameIndex slot into the ++ // memory location argument. ++ const Value *SV = cast(Op.getOperand(2))->getValue(); ++ return DAG.getStore(Op.getOperand(0), DL, FI, Op.getOperand(1), ++ MachinePointerInfo(SV)); ++} ++ ++SDValue LoongArchTargetLowering::lowerVAARG(SDValue Op, SelectionDAG &DAG) const { ++ SDNode *Node = Op.getNode(); ++ EVT VT = Node->getValueType(0); ++ SDValue Chain = Node->getOperand(0); ++ SDValue VAListPtr = Node->getOperand(1); ++ const Align Align = ++ llvm::MaybeAlign(Node->getConstantOperandVal(3)).valueOrOne(); ++ const Value *SV = cast(Node->getOperand(2))->getValue(); ++ SDLoc DL(Node); ++ unsigned ArgSlotSizeInBytes = (ABI.IsLPX32() || ABI.IsLP64()) ? 8 : 4; ++ ++ SDValue VAListLoad = DAG.getLoad(getPointerTy(DAG.getDataLayout()), DL, Chain, ++ VAListPtr, MachinePointerInfo(SV)); ++ SDValue VAList = VAListLoad; ++ ++ // Re-align the pointer if necessary. ++ // It should only ever be necessary for 64-bit types on LP32 since the minimum ++ // argument alignment is the same as the maximum type alignment for LPX32/LP64. ++ // ++ // FIXME: We currently align too often. The code generator doesn't notice ++ // when the pointer is still aligned from the last va_arg (or pair of ++ // va_args for the i64 on LP32 case). ++ if (Align > getMinStackArgumentAlignment()) { ++ VAList = DAG.getNode( ++ ISD::ADD, DL, VAList.getValueType(), VAList, ++ DAG.getConstant(Align.value() - 1, DL, VAList.getValueType())); ++ ++ VAList = DAG.getNode( ++ ISD::AND, DL, VAList.getValueType(), VAList, ++ DAG.getConstant(-(int64_t)Align.value(), DL, VAList.getValueType())); ++ } ++ ++ // Increment the pointer, VAList, to the next vaarg. ++ auto &TD = DAG.getDataLayout(); ++ unsigned ArgSizeInBytes = ++ TD.getTypeAllocSize(VT.getTypeForEVT(*DAG.getContext())); ++ SDValue Tmp3 = ++ DAG.getNode(ISD::ADD, DL, VAList.getValueType(), VAList, ++ DAG.getConstant(alignTo(ArgSizeInBytes, ArgSlotSizeInBytes), ++ DL, VAList.getValueType())); ++ // Store the incremented VAList to the legalized pointer ++ Chain = DAG.getStore(VAListLoad.getValue(1), DL, Tmp3, VAListPtr, ++ MachinePointerInfo(SV)); ++ ++ // Load the actual argument out of the pointer VAList ++ return DAG.getLoad(VT, DL, Chain, VAList, MachinePointerInfo()); ++} ++ ++SDValue LoongArchTargetLowering:: ++lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const { ++ // check the depth ++ assert((cast(Op.getOperand(0))->getZExtValue() == 0) && ++ "Frame address can only be determined for current frame."); ++ ++ MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); ++ MFI.setFrameAddressIsTaken(true); ++ EVT VT = Op.getValueType(); ++ SDLoc DL(Op); ++ SDValue FrameAddr = DAG.getCopyFromReg( ++ DAG.getEntryNode(), DL, ABI.IsLP64() ? LoongArch::FP_64 : LoongArch::FP, VT); ++ return FrameAddr; ++} ++ ++SDValue LoongArchTargetLowering::lowerRETURNADDR(SDValue Op, ++ SelectionDAG &DAG) const { ++ if (verifyReturnAddressArgumentIsConstant(Op, DAG)) ++ return SDValue(); ++ ++ // check the depth ++ assert((cast(Op.getOperand(0))->getZExtValue() == 0) && ++ "Return address can be determined only for current frame."); ++ ++ MachineFunction &MF = DAG.getMachineFunction(); ++ MachineFrameInfo &MFI = MF.getFrameInfo(); ++ MVT VT = Op.getSimpleValueType(); ++ unsigned RA = ABI.IsLP64() ? LoongArch::RA_64 : LoongArch::RA; ++ MFI.setReturnAddressIsTaken(true); ++ ++ // Return RA, which contains the return address. Mark it an implicit live-in. ++ unsigned Reg = MF.addLiveIn(RA, getRegClassFor(VT)); ++ return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), Reg, VT); ++} ++ ++// An EH_RETURN is the result of lowering llvm.eh.return which in turn is ++// generated from __builtin_eh_return (offset, handler) ++// The effect of this is to adjust the stack pointer by "offset" ++// and then branch to "handler". ++SDValue LoongArchTargetLowering::lowerEH_RETURN(SDValue Op, SelectionDAG &DAG) ++ const { ++ MachineFunction &MF = DAG.getMachineFunction(); ++ LoongArchFunctionInfo *LoongArchFI = MF.getInfo(); ++ ++ LoongArchFI->setCallsEhReturn(); ++ SDValue Chain = Op.getOperand(0); ++ SDValue Offset = Op.getOperand(1); ++ SDValue Handler = Op.getOperand(2); ++ SDLoc DL(Op); ++ EVT Ty = ABI.IsLP64() ? MVT::i64 : MVT::i32; ++ ++ // Store stack offset in A1, store jump target in A0. Glue CopyToReg and ++ // EH_RETURN nodes, so that instructions are emitted back-to-back. ++ unsigned OffsetReg = ABI.IsLP64() ? LoongArch::A1_64 : LoongArch::A1; ++ unsigned AddrReg = ABI.IsLP64() ? LoongArch::A0_64 : LoongArch::A0; ++ Chain = DAG.getCopyToReg(Chain, DL, OffsetReg, Offset, SDValue()); ++ Chain = DAG.getCopyToReg(Chain, DL, AddrReg, Handler, Chain.getValue(1)); ++ return DAG.getNode(LoongArchISD::EH_RETURN, DL, MVT::Other, Chain, ++ DAG.getRegister(OffsetReg, Ty), ++ DAG.getRegister(AddrReg, getPointerTy(MF.getDataLayout())), ++ Chain.getValue(1)); ++} ++ ++SDValue LoongArchTargetLowering::lowerATOMIC_FENCE(SDValue Op, ++ SelectionDAG &DAG) const { ++ // TODO: handle SyncScope::SingleThread. ++ return Op; ++} ++ ++SDValue LoongArchTargetLowering::lowerShiftLeftParts(SDValue Op, ++ SelectionDAG &DAG) const { ++ SDLoc DL(Op); ++ MVT VT = Subtarget.is64Bit() ? MVT::i64 : MVT::i32; ++ ++ SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1); ++ SDValue Shamt = Op.getOperand(2); ++ // if shamt < (VT.bits): ++ // lo = (shl lo, shamt) ++ // hi = (or (shl hi, shamt) (srl (srl lo, 1), (xor shamt, (VT.bits-1)))) ++ // else: ++ // lo = 0 ++ // hi = (shl lo, shamt[4:0]) ++ SDValue Not = ++ DAG.getNode(ISD::XOR, DL, MVT::i32, Shamt, ++ DAG.getConstant(VT.getSizeInBits() - 1, DL, MVT::i32)); ++ SDValue ShiftRight1Lo = DAG.getNode(ISD::SRL, DL, VT, Lo, ++ DAG.getConstant(1, DL, VT)); ++ SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, VT, ShiftRight1Lo, Not); ++ SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, VT, Hi, Shamt); ++ SDValue Or = DAG.getNode(ISD::OR, DL, VT, ShiftLeftHi, ShiftRightLo); ++ SDValue ShiftLeftLo = DAG.getNode(ISD::SHL, DL, VT, Lo, Shamt); ++ SDValue Cond = DAG.getNode(ISD::AND, DL, MVT::i32, Shamt, ++ DAG.getConstant(VT.getSizeInBits(), DL, MVT::i32)); ++ Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond, ++ DAG.getConstant(0, DL, VT), ShiftLeftLo); ++ Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond, ShiftLeftLo, Or); ++ ++ SDValue Ops[2] = {Lo, Hi}; ++ return DAG.getMergeValues(Ops, DL); ++} ++ ++SDValue LoongArchTargetLowering::lowerShiftRightParts(SDValue Op, SelectionDAG &DAG, ++ bool IsSRA) const { ++ SDLoc DL(Op); ++ SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1); ++ SDValue Shamt = Op.getOperand(2); ++ MVT VT = Subtarget.is64Bit() ? MVT::i64 : MVT::i32; ++ ++ // if shamt < (VT.bits): ++ // lo = (or (shl (shl hi, 1), (xor shamt, (VT.bits-1))) (srl lo, shamt)) ++ // if isSRA: ++ // hi = (sra hi, shamt) ++ // else: ++ // hi = (srl hi, shamt) ++ // else: ++ // if isSRA: ++ // lo = (sra hi, shamt[4:0]) ++ // hi = (sra hi, 31) ++ // else: ++ // lo = (srl hi, shamt[4:0]) ++ // hi = 0 ++ SDValue Not = ++ DAG.getNode(ISD::XOR, DL, MVT::i32, Shamt, ++ DAG.getConstant(VT.getSizeInBits() - 1, DL, MVT::i32)); ++ SDValue ShiftLeft1Hi = ++ DAG.getNode(ISD::SHL, DL, VT, Hi, DAG.getConstant(1, DL, VT)); ++ SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, VT, ShiftLeft1Hi, Not); ++ SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, VT, Lo, Shamt); ++ SDValue Or = DAG.getNode(ISD::OR, DL, VT, ShiftLeftHi, ShiftRightLo); ++ SDValue ShiftRightHi = DAG.getNode(IsSRA ? ISD::SRA : ISD::SRL, ++ DL, VT, Hi, Shamt); ++ SDValue Cond = DAG.getNode(ISD::AND, DL, MVT::i32, Shamt, ++ DAG.getConstant(VT.getSizeInBits(), DL, MVT::i32)); ++ SDValue Ext = DAG.getNode(ISD::SRA, DL, VT, Hi, ++ DAG.getConstant(VT.getSizeInBits() - 1, DL, VT)); ++ Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond, ShiftRightHi, Or); ++ Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond, ++ IsSRA ? Ext : DAG.getConstant(0, DL, VT), ShiftRightHi); ++ ++ SDValue Ops[2] = {Lo, Hi}; ++ return DAG.getMergeValues(Ops, DL); ++} ++ ++// Lower (store (fp_to_sint $fp) $ptr) to (store (TruncIntFP $fp), $ptr). ++static SDValue lowerFP_TO_SINT_STORE(StoreSDNode *SD, SelectionDAG &DAG, ++ bool SingleFloat) { ++ SDValue Val = SD->getValue(); ++ ++ if (Val.getOpcode() != ISD::FP_TO_SINT || ++ (Val.getValueSizeInBits() > 32 && SingleFloat)) ++ return SDValue(); ++ ++ EVT FPTy = EVT::getFloatingPointVT(Val.getValueSizeInBits()); ++ SDValue Tr = DAG.getNode(LoongArchISD::TruncIntFP, SDLoc(Val), FPTy, ++ Val.getOperand(0)); ++ return DAG.getStore(SD->getChain(), SDLoc(SD), Tr, SD->getBasePtr(), ++ SD->getPointerInfo(), SD->getAlign(), ++ SD->getMemOperand()->getFlags()); ++} ++ ++SDValue LoongArchTargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const { ++ StoreSDNode *SD = cast(Op); ++ return lowerFP_TO_SINT_STORE(SD, DAG, Subtarget.isSingleFloat()); ++} ++ ++SDValue LoongArchTargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op, ++ SelectionDAG &DAG) const { ++ SDLoc DL(Op); ++ unsigned Intrinsic = cast(Op->getOperand(0))->getZExtValue(); ++ switch (Intrinsic) { ++ default: ++ return SDValue(); ++ case Intrinsic::loongarch_lsx_vaddi_bu: ++ case Intrinsic::loongarch_lsx_vaddi_hu: ++ case Intrinsic::loongarch_lsx_vaddi_wu: ++ case Intrinsic::loongarch_lsx_vaddi_du: ++ return DAG.getNode(ISD::ADD, DL, Op->getValueType(0), Op->getOperand(1), ++ lowerLSXSplatImm(Op, 2, DAG)); ++ case Intrinsic::loongarch_lsx_vand_v: ++ case Intrinsic::loongarch_lasx_xvand_v: ++ return DAG.getNode(ISD::AND, DL, Op->getValueType(0), Op->getOperand(1), ++ Op->getOperand(2)); ++ case Intrinsic::loongarch_lsx_vbitclr_b: ++ case Intrinsic::loongarch_lsx_vbitclr_h: ++ case Intrinsic::loongarch_lsx_vbitclr_w: ++ case Intrinsic::loongarch_lsx_vbitclr_d: ++ return lowerLSXBitClear(Op, DAG); ++ case Intrinsic::loongarch_lsx_vdiv_b: ++ case Intrinsic::loongarch_lsx_vdiv_h: ++ case Intrinsic::loongarch_lsx_vdiv_w: ++ case Intrinsic::loongarch_lsx_vdiv_d: ++ return DAG.getNode(ISD::SDIV, DL, Op->getValueType(0), Op->getOperand(1), ++ Op->getOperand(2)); ++ case Intrinsic::loongarch_lsx_vdiv_bu: ++ case Intrinsic::loongarch_lsx_vdiv_hu: ++ case Intrinsic::loongarch_lsx_vdiv_wu: ++ case Intrinsic::loongarch_lsx_vdiv_du: ++ return DAG.getNode(ISD::UDIV, DL, Op->getValueType(0), Op->getOperand(1), ++ Op->getOperand(2)); ++ case Intrinsic::loongarch_lsx_vfdiv_s: ++ case Intrinsic::loongarch_lsx_vfdiv_d: ++ return DAG.getNode(ISD::FDIV, DL, Op->getValueType(0), Op->getOperand(1), ++ Op->getOperand(2)); ++ case Intrinsic::loongarch_lsx_vffint_s_wu: ++ case Intrinsic::loongarch_lsx_vffint_d_lu: ++ return DAG.getNode(ISD::UINT_TO_FP, DL, Op->getValueType(0), ++ Op->getOperand(1)); ++ case Intrinsic::loongarch_lsx_vffint_s_w: ++ case Intrinsic::loongarch_lsx_vffint_d_l: ++ return DAG.getNode(ISD::SINT_TO_FP, DL, Op->getValueType(0), ++ Op->getOperand(1)); ++ case Intrinsic::loongarch_lsx_vfmul_s: ++ case Intrinsic::loongarch_lsx_vfmul_d: ++ return DAG.getNode(ISD::FMUL, DL, Op->getValueType(0), Op->getOperand(1), ++ Op->getOperand(2)); ++ case Intrinsic::loongarch_lsx_vfrint_s: ++ case Intrinsic::loongarch_lsx_vfrint_d: ++ return DAG.getNode(ISD::FRINT, DL, Op->getValueType(0), Op->getOperand(1)); ++ case Intrinsic::loongarch_lsx_vfsqrt_s: ++ case Intrinsic::loongarch_lsx_vfsqrt_d: ++ return DAG.getNode(ISD::FSQRT, DL, Op->getValueType(0), Op->getOperand(1)); ++ case Intrinsic::loongarch_lsx_vftintrz_wu_s: ++ case Intrinsic::loongarch_lsx_vftintrz_lu_d: ++ return DAG.getNode(ISD::FP_TO_UINT, DL, Op->getValueType(0), ++ Op->getOperand(1)); ++ case Intrinsic::loongarch_lsx_vpackev_b: ++ case Intrinsic::loongarch_lsx_vpackev_h: ++ case Intrinsic::loongarch_lsx_vpackev_w: ++ case Intrinsic::loongarch_lsx_vpackev_d: ++ return DAG.getNode(LoongArchISD::VPACKEV, DL, Op->getValueType(0), ++ Op->getOperand(1), Op->getOperand(2)); ++ case Intrinsic::loongarch_lsx_vilvh_b: ++ case Intrinsic::loongarch_lsx_vilvh_h: ++ case Intrinsic::loongarch_lsx_vilvh_w: ++ case Intrinsic::loongarch_lsx_vilvh_d: ++ return DAG.getNode(LoongArchISD::VILVH, DL, Op->getValueType(0), ++ Op->getOperand(1), Op->getOperand(2)); ++ case Intrinsic::loongarch_lsx_vpackod_b: ++ case Intrinsic::loongarch_lsx_vpackod_h: ++ case Intrinsic::loongarch_lsx_vpackod_w: ++ case Intrinsic::loongarch_lsx_vpackod_d: ++ return DAG.getNode(LoongArchISD::VPACKOD, DL, Op->getValueType(0), ++ Op->getOperand(1), Op->getOperand(2)); ++ case Intrinsic::loongarch_lsx_vilvl_b: ++ case Intrinsic::loongarch_lsx_vilvl_h: ++ case Intrinsic::loongarch_lsx_vilvl_w: ++ case Intrinsic::loongarch_lsx_vilvl_d: ++ return DAG.getNode(LoongArchISD::VILVL, DL, Op->getValueType(0), ++ Op->getOperand(1), Op->getOperand(2)); ++ case Intrinsic::loongarch_lsx_vmadd_b: ++ case Intrinsic::loongarch_lsx_vmadd_h: ++ case Intrinsic::loongarch_lsx_vmadd_w: ++ case Intrinsic::loongarch_lsx_vmadd_d: { ++ EVT ResTy = Op->getValueType(0); ++ return DAG.getNode(ISD::ADD, SDLoc(Op), ResTy, Op->getOperand(1), ++ DAG.getNode(ISD::MUL, SDLoc(Op), ResTy, ++ Op->getOperand(2), Op->getOperand(3))); ++ } ++ case Intrinsic::loongarch_lsx_vmax_b: ++ case Intrinsic::loongarch_lsx_vmax_h: ++ case Intrinsic::loongarch_lsx_vmax_w: ++ case Intrinsic::loongarch_lsx_vmax_d: ++ return DAG.getNode(ISD::SMAX, DL, Op->getValueType(0), Op->getOperand(1), ++ Op->getOperand(2)); ++ case Intrinsic::loongarch_lsx_vmax_bu: ++ case Intrinsic::loongarch_lsx_vmax_hu: ++ case Intrinsic::loongarch_lsx_vmax_wu: ++ case Intrinsic::loongarch_lsx_vmax_du: ++ return DAG.getNode(ISD::UMAX, DL, Op->getValueType(0), Op->getOperand(1), ++ Op->getOperand(2)); ++ case Intrinsic::loongarch_lsx_vmin_b: ++ case Intrinsic::loongarch_lsx_vmin_h: ++ case Intrinsic::loongarch_lsx_vmin_w: ++ case Intrinsic::loongarch_lsx_vmin_d: ++ return DAG.getNode(ISD::SMIN, DL, Op->getValueType(0), Op->getOperand(1), ++ Op->getOperand(2)); ++ case Intrinsic::loongarch_lsx_vmin_bu: ++ case Intrinsic::loongarch_lsx_vmin_hu: ++ case Intrinsic::loongarch_lsx_vmin_wu: ++ case Intrinsic::loongarch_lsx_vmin_du: ++ return DAG.getNode(ISD::UMIN, DL, Op->getValueType(0), Op->getOperand(1), ++ Op->getOperand(2)); ++ case Intrinsic::loongarch_lsx_vmini_bu: ++ case Intrinsic::loongarch_lsx_vmini_hu: ++ case Intrinsic::loongarch_lsx_vmini_wu: ++ case Intrinsic::loongarch_lsx_vmini_du: ++ return DAG.getNode(ISD::UMIN, DL, Op->getValueType(0), Op->getOperand(1), ++ lowerLSXSplatImm(Op, 2, DAG)); ++ case Intrinsic::loongarch_lsx_vmod_b: ++ case Intrinsic::loongarch_lsx_vmod_h: ++ case Intrinsic::loongarch_lsx_vmod_w: ++ case Intrinsic::loongarch_lsx_vmod_d: ++ return DAG.getNode(ISD::SREM, DL, Op->getValueType(0), Op->getOperand(1), ++ Op->getOperand(2)); ++ case Intrinsic::loongarch_lsx_vmod_bu: ++ case Intrinsic::loongarch_lsx_vmod_hu: ++ case Intrinsic::loongarch_lsx_vmod_wu: ++ case Intrinsic::loongarch_lsx_vmod_du: ++ return DAG.getNode(ISD::UREM, DL, Op->getValueType(0), Op->getOperand(1), ++ Op->getOperand(2)); ++ case Intrinsic::loongarch_lsx_vmul_b: ++ case Intrinsic::loongarch_lsx_vmul_h: ++ case Intrinsic::loongarch_lsx_vmul_w: ++ case Intrinsic::loongarch_lsx_vmul_d: ++ return DAG.getNode(ISD::MUL, DL, Op->getValueType(0), Op->getOperand(1), ++ Op->getOperand(2)); ++ case Intrinsic::loongarch_lsx_vmsub_b: ++ case Intrinsic::loongarch_lsx_vmsub_h: ++ case Intrinsic::loongarch_lsx_vmsub_w: ++ case Intrinsic::loongarch_lsx_vmsub_d: { ++ EVT ResTy = Op->getValueType(0); ++ return DAG.getNode(ISD::SUB, SDLoc(Op), ResTy, Op->getOperand(1), ++ DAG.getNode(ISD::MUL, SDLoc(Op), ResTy, ++ Op->getOperand(2), Op->getOperand(3))); ++ } ++ case Intrinsic::loongarch_lsx_vclz_b: ++ case Intrinsic::loongarch_lsx_vclz_h: ++ case Intrinsic::loongarch_lsx_vclz_w: ++ case Intrinsic::loongarch_lsx_vclz_d: ++ return DAG.getNode(ISD::CTLZ, DL, Op->getValueType(0), Op->getOperand(1)); ++ case Intrinsic::loongarch_lsx_vnor_v: ++ case Intrinsic::loongarch_lasx_xvnor_v: { ++ SDValue Res = DAG.getNode(ISD::OR, DL, Op->getValueType(0), ++ Op->getOperand(1), Op->getOperand(2)); ++ return DAG.getNOT(DL, Res, Res->getValueType(0)); ++ } ++ case Intrinsic::loongarch_lsx_vor_v: ++ case Intrinsic::loongarch_lasx_xvor_v: ++ return DAG.getNode(ISD::OR, DL, Op->getValueType(0), Op->getOperand(1), ++ Op->getOperand(2)); ++ case Intrinsic::loongarch_lsx_vpickev_b: ++ case Intrinsic::loongarch_lsx_vpickev_h: ++ case Intrinsic::loongarch_lsx_vpickev_w: ++ case Intrinsic::loongarch_lsx_vpickev_d: ++ return DAG.getNode(LoongArchISD::VPICKEV, DL, Op->getValueType(0), ++ Op->getOperand(1), Op->getOperand(2)); ++ case Intrinsic::loongarch_lsx_vpickod_b: ++ case Intrinsic::loongarch_lsx_vpickod_h: ++ case Intrinsic::loongarch_lsx_vpickod_w: ++ case Intrinsic::loongarch_lsx_vpickod_d: ++ return DAG.getNode(LoongArchISD::VPICKOD, DL, Op->getValueType(0), ++ Op->getOperand(1), Op->getOperand(2)); ++ case Intrinsic::loongarch_lsx_vpcnt_b: ++ case Intrinsic::loongarch_lsx_vpcnt_h: ++ case Intrinsic::loongarch_lsx_vpcnt_w: ++ case Intrinsic::loongarch_lsx_vpcnt_d: ++ return DAG.getNode(ISD::CTPOP, DL, Op->getValueType(0), Op->getOperand(1)); ++ case Intrinsic::loongarch_lsx_vsat_b: ++ case Intrinsic::loongarch_lsx_vsat_h: ++ case Intrinsic::loongarch_lsx_vsat_w: ++ case Intrinsic::loongarch_lsx_vsat_d: ++ case Intrinsic::loongarch_lsx_vsat_bu: ++ case Intrinsic::loongarch_lsx_vsat_hu: ++ case Intrinsic::loongarch_lsx_vsat_wu: ++ case Intrinsic::loongarch_lsx_vsat_du: { ++ // Report an error for out of range values. ++ int64_t Max; ++ switch (Intrinsic) { ++ case Intrinsic::loongarch_lsx_vsat_b: ++ case Intrinsic::loongarch_lsx_vsat_bu: ++ Max = 7; ++ break; ++ case Intrinsic::loongarch_lsx_vsat_h: ++ case Intrinsic::loongarch_lsx_vsat_hu: ++ Max = 15; ++ break; ++ case Intrinsic::loongarch_lsx_vsat_w: ++ case Intrinsic::loongarch_lsx_vsat_wu: ++ Max = 31; ++ break; ++ case Intrinsic::loongarch_lsx_vsat_d: ++ case Intrinsic::loongarch_lsx_vsat_du: ++ Max = 63; ++ break; ++ default: ++ llvm_unreachable("Unmatched intrinsic"); ++ } ++ int64_t Value = cast(Op->getOperand(2))->getSExtValue(); ++ if (Value < 0 || Value > Max) ++ report_fatal_error("Immediate out of range"); ++ return SDValue(); ++ } ++ case Intrinsic::loongarch_lsx_vshuf4i_b: ++ case Intrinsic::loongarch_lsx_vshuf4i_h: ++ case Intrinsic::loongarch_lsx_vshuf4i_w: ++ // case Intrinsic::loongarch_lsx_vshuf4i_d: ++ { ++ int64_t Value = cast(Op->getOperand(2))->getSExtValue(); ++ if (Value < 0 || Value > 255) ++ report_fatal_error("Immediate out of range"); ++ return DAG.getNode(LoongArchISD::SHF, DL, Op->getValueType(0), ++ Op->getOperand(2), Op->getOperand(1)); ++ } ++ case Intrinsic::loongarch_lsx_vsll_b: ++ case Intrinsic::loongarch_lsx_vsll_h: ++ case Intrinsic::loongarch_lsx_vsll_w: ++ case Intrinsic::loongarch_lsx_vsll_d: ++ return DAG.getNode(ISD::SHL, DL, Op->getValueType(0), Op->getOperand(1), ++ truncateVecElts(Op, DAG)); ++ case Intrinsic::loongarch_lsx_vslli_b: ++ case Intrinsic::loongarch_lsx_vslli_h: ++ case Intrinsic::loongarch_lsx_vslli_w: ++ case Intrinsic::loongarch_lsx_vslli_d: ++ return DAG.getNode(ISD::SHL, DL, Op->getValueType(0), Op->getOperand(1), ++ lowerLSXSplatImm(Op, 2, DAG)); ++ case Intrinsic::loongarch_lsx_vreplve_b: ++ case Intrinsic::loongarch_lsx_vreplve_h: ++ case Intrinsic::loongarch_lsx_vreplve_w: ++ case Intrinsic::loongarch_lsx_vreplve_d: ++ // We can't lower via VECTOR_SHUFFLE because it requires constant shuffle ++ // masks, nor can we lower via BUILD_VECTOR & EXTRACT_VECTOR_ELT because ++ // EXTRACT_VECTOR_ELT can't extract i64's on LoongArch32. ++ // Instead we lower to LoongArchISD::VSHF and match from there. ++ return DAG.getNode(LoongArchISD::VSHF, DL, Op->getValueType(0), ++ lowerLSXSplatZExt(Op, 2, DAG), Op->getOperand(1), ++ Op->getOperand(1)); ++ case Intrinsic::loongarch_lsx_vreplvei_b: ++ case Intrinsic::loongarch_lsx_vreplvei_h: ++ case Intrinsic::loongarch_lsx_vreplvei_w: ++ case Intrinsic::loongarch_lsx_vreplvei_d: ++ return DAG.getNode(LoongArchISD::VSHF, DL, Op->getValueType(0), ++ lowerLSXSplatImm(Op, 2, DAG), Op->getOperand(1), ++ Op->getOperand(1)); ++ case Intrinsic::loongarch_lsx_vsra_b: ++ case Intrinsic::loongarch_lsx_vsra_h: ++ case Intrinsic::loongarch_lsx_vsra_w: ++ case Intrinsic::loongarch_lsx_vsra_d: ++ return DAG.getNode(ISD::SRA, DL, Op->getValueType(0), Op->getOperand(1), ++ truncateVecElts(Op, DAG)); ++ case Intrinsic::loongarch_lsx_vsrari_b: ++ case Intrinsic::loongarch_lsx_vsrari_h: ++ case Intrinsic::loongarch_lsx_vsrari_w: ++ case Intrinsic::loongarch_lsx_vsrari_d: { ++ // Report an error for out of range values. ++ int64_t Max; ++ switch (Intrinsic) { ++ case Intrinsic::loongarch_lsx_vsrari_b: ++ Max = 7; ++ break; ++ case Intrinsic::loongarch_lsx_vsrari_h: ++ Max = 15; ++ break; ++ case Intrinsic::loongarch_lsx_vsrari_w: ++ Max = 31; ++ break; ++ case Intrinsic::loongarch_lsx_vsrari_d: ++ Max = 63; ++ break; ++ default: ++ llvm_unreachable("Unmatched intrinsic"); ++ } ++ int64_t Value = cast(Op->getOperand(2))->getSExtValue(); ++ if (Value < 0 || Value > Max) ++ report_fatal_error("Immediate out of range"); ++ return SDValue(); ++ } ++ case Intrinsic::loongarch_lsx_vsrl_b: ++ case Intrinsic::loongarch_lsx_vsrl_h: ++ case Intrinsic::loongarch_lsx_vsrl_w: ++ case Intrinsic::loongarch_lsx_vsrl_d: ++ return DAG.getNode(ISD::SRL, DL, Op->getValueType(0), Op->getOperand(1), ++ truncateVecElts(Op, DAG)); ++ case Intrinsic::loongarch_lsx_vsrli_b: ++ case Intrinsic::loongarch_lsx_vsrli_h: ++ case Intrinsic::loongarch_lsx_vsrli_w: ++ case Intrinsic::loongarch_lsx_vsrli_d: ++ return DAG.getNode(ISD::SRL, DL, Op->getValueType(0), Op->getOperand(1), ++ lowerLSXSplatImm(Op, 2, DAG)); ++ case Intrinsic::loongarch_lsx_vsrlri_b: ++ case Intrinsic::loongarch_lsx_vsrlri_h: ++ case Intrinsic::loongarch_lsx_vsrlri_w: ++ case Intrinsic::loongarch_lsx_vsrlri_d: { ++ // Report an error for out of range values. ++ int64_t Max; ++ switch (Intrinsic) { ++ case Intrinsic::loongarch_lsx_vsrlri_b: ++ Max = 7; ++ break; ++ case Intrinsic::loongarch_lsx_vsrlri_h: ++ Max = 15; ++ break; ++ case Intrinsic::loongarch_lsx_vsrlri_w: ++ Max = 31; ++ break; ++ case Intrinsic::loongarch_lsx_vsrlri_d: ++ Max = 63; ++ break; ++ default: ++ llvm_unreachable("Unmatched intrinsic"); ++ } ++ int64_t Value = cast(Op->getOperand(2))->getSExtValue(); ++ if (Value < 0 || Value > Max) ++ report_fatal_error("Immediate out of range"); ++ return SDValue(); ++ } ++ case Intrinsic::loongarch_lsx_vsubi_bu: ++ case Intrinsic::loongarch_lsx_vsubi_hu: ++ case Intrinsic::loongarch_lsx_vsubi_wu: ++ case Intrinsic::loongarch_lsx_vsubi_du: ++ return DAG.getNode(ISD::SUB, DL, Op->getValueType(0), Op->getOperand(1), ++ lowerLSXSplatImm(Op, 2, DAG)); ++ case Intrinsic::loongarch_lsx_vshuf_h: ++ case Intrinsic::loongarch_lsx_vshuf_w: ++ case Intrinsic::loongarch_lsx_vshuf_d: ++ case Intrinsic::loongarch_lasx_xvshuf_h: ++ case Intrinsic::loongarch_lasx_xvshuf_w: ++ case Intrinsic::loongarch_lasx_xvshuf_d: ++ return DAG.getNode(LoongArchISD::VSHF, DL, Op->getValueType(0), ++ Op->getOperand(1), Op->getOperand(2), Op->getOperand(3)); ++ case Intrinsic::loongarch_lsx_vxor_v: ++ case Intrinsic::loongarch_lasx_xvxor_v: ++ return DAG.getNode(ISD::XOR, DL, Op->getValueType(0), Op->getOperand(1), ++ Op->getOperand(2)); ++ case Intrinsic::loongarch_lsx_vrotr_b: ++ case Intrinsic::loongarch_lsx_vrotr_h: ++ case Intrinsic::loongarch_lsx_vrotr_w: ++ case Intrinsic::loongarch_lsx_vrotr_d: ++ return DAG.getNode(LoongArchISD::VROR, DL, Op->getValueType(0), ++ Op->getOperand(1), Op->getOperand(2)); ++ case Intrinsic::loongarch_lsx_vrotri_b: ++ case Intrinsic::loongarch_lsx_vrotri_h: ++ case Intrinsic::loongarch_lsx_vrotri_w: ++ case Intrinsic::loongarch_lsx_vrotri_d: ++ return DAG.getNode(LoongArchISD::VRORI, DL, Op->getValueType(0), ++ Op->getOperand(1), Op->getOperand(2)); ++ case Intrinsic::thread_pointer: { ++ EVT PtrVT = getPointerTy(DAG.getDataLayout()); ++ if (PtrVT == MVT::i64) ++ return DAG.getRegister(LoongArch::TP_64, MVT::i64); ++ return DAG.getRegister(LoongArch::TP, MVT::i32); ++ } ++ } ++} ++ ++SDValue ++LoongArchTargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op, ++ SelectionDAG &DAG) const { ++ unsigned Intr = cast(Op->getOperand(1))->getZExtValue(); ++ switch (Intr) { ++ default: ++ return SDValue(); ++ case Intrinsic::loongarch_lsx_vld: ++ return lowerLSXLoadIntr(Op, DAG, Intr, Subtarget); ++ case Intrinsic::loongarch_lasx_xvld: ++ return lowerLASXLoadIntr(Op, DAG, Intr, Subtarget); ++ case Intrinsic::loongarch_lasx_xvldrepl_b: ++ case Intrinsic::loongarch_lasx_xvldrepl_h: ++ case Intrinsic::loongarch_lasx_xvldrepl_w: ++ case Intrinsic::loongarch_lasx_xvldrepl_d: ++ return lowerLASXVLDRIntr(Op, DAG, Intr, Subtarget); ++ case Intrinsic::loongarch_lsx_vldrepl_b: ++ case Intrinsic::loongarch_lsx_vldrepl_h: ++ case Intrinsic::loongarch_lsx_vldrepl_w: ++ case Intrinsic::loongarch_lsx_vldrepl_d: ++ return lowerLSXVLDRIntr(Op, DAG, Intr, Subtarget); ++ } ++} ++ ++SDValue LoongArchTargetLowering::lowerINTRINSIC_VOID(SDValue Op, ++ SelectionDAG &DAG) const { ++ unsigned Intr = cast(Op->getOperand(1))->getZExtValue(); ++ switch (Intr) { ++ default: ++ return SDValue(); ++ case Intrinsic::loongarch_lsx_vst: ++ return lowerLSXStoreIntr(Op, DAG, Intr, Subtarget); ++ case Intrinsic::loongarch_lasx_xvst: ++ return lowerLASXStoreIntr(Op, DAG, Intr, Subtarget); ++ } ++} ++ ++// Lower ISD::EXTRACT_VECTOR_ELT into LoongArchISD::VEXTRACT_SEXT_ELT. ++// ++// The non-value bits resulting from ISD::EXTRACT_VECTOR_ELT are undefined. We ++// choose to sign-extend but we could have equally chosen zero-extend. The ++// DAGCombiner will fold any sign/zero extension of the ISD::EXTRACT_VECTOR_ELT ++// result into this node later (possibly changing it to a zero-extend in the ++// process). ++SDValue ++LoongArchTargetLowering::lowerEXTRACT_VECTOR_ELT(SDValue Op, ++ SelectionDAG &DAG) const { ++ SDLoc DL(Op); ++ EVT ResTy = Op->getValueType(0); ++ SDValue Op0 = Op->getOperand(0); ++ SDValue Op1 = Op->getOperand(1); ++ EVT VecTy = Op0->getValueType(0); ++ ++ if (!VecTy.is128BitVector() && !VecTy.is256BitVector()) ++ return SDValue(); ++ ++ EVT EltTy = VecTy.getVectorElementType(); ++ ++ if (ResTy.isInteger()) { ++ if (VecTy.is128BitVector()) ++ return DAG.getNode(LoongArchISD::VEXTRACT_SEXT_ELT, DL, ResTy, Op0, Op1, ++ DAG.getValueType(EltTy)); ++ ++ ConstantSDNode *cn = dyn_cast(Op1); ++ if (!cn) ++ return SDValue(); ++ ++ if (EltTy == MVT::i32 || EltTy == MVT::i64) ++ return DAG.getNode(LoongArchISD::VEXTRACT_SEXT_ELT, DL, ResTy, Op0, Op1, ++ DAG.getValueType(EltTy)); ++ } else if (ResTy.isFloatingPoint() && VecTy.is256BitVector() && ++ (EltTy == MVT::f32 || isa(Op1))) { ++ return Op; ++ } ++ ++ return SDValue(); ++} ++ ++SDValue ++LoongArchTargetLowering::lowerINSERT_VECTOR_ELT(SDValue Op, ++ SelectionDAG &DAG) const { ++ if (isa(Op.getOperand(2))) ++ return Op; ++ return SDValue(); ++} ++ ++// Lowers ISD::BUILD_VECTOR into appropriate SelectionDAG nodes for the ++// backend. ++// ++// Lowers according to the following rules: ++// - Constant splats are legal as-is as long as the SplatBitSize is a power of ++// 2 less than or equal to 64 and the value fits into a signed 10-bit ++// immediate ++// - Constant splats are lowered to bitconverted BUILD_VECTORs if SplatBitSize ++// is a power of 2 less than or equal to 64 and the value does not fit into a ++// signed 10-bit immediate ++// - Non-constant splats are legal as-is. ++// - Non-constant non-splats are lowered to sequences of INSERT_VECTOR_ELT. ++// - All others are illegal and must be expanded. ++SDValue LoongArchTargetLowering::lowerBUILD_VECTOR(SDValue Op, ++ SelectionDAG &DAG) const { ++ BuildVectorSDNode *Node = cast(Op); ++ EVT ResTy = Op->getValueType(0); ++ SDLoc DL(Op); ++ APInt SplatValue, SplatUndef; ++ unsigned SplatBitSize; ++ bool HasAnyUndefs; ++ ++ if ((!Subtarget.hasLSX() || !ResTy.is128BitVector()) && ++ (!Subtarget.hasLASX() || !ResTy.is256BitVector())) ++ return SDValue(); ++ ++ if (Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs, ++ 8) && ++ SplatBitSize <= 64) { ++ // We can only cope with 8, 16, 32, or 64-bit elements ++ if ((ResTy.is128BitVector() && SplatBitSize != 8 && SplatBitSize != 16 && ++ SplatBitSize != 32 && SplatBitSize != 64) || ++ (ResTy.is256BitVector() && SplatBitSize != 8 && SplatBitSize != 16 && ++ SplatBitSize != 32 && SplatBitSize != 64)) ++ return SDValue(); ++ ++ // If the value isn't an integer type we will have to bitcast ++ // from an integer type first. Also, if there are any undefs, we must ++ // lower them to defined values first. ++ if (ResTy.isInteger() && !HasAnyUndefs) ++ return Op; ++ ++ EVT ViaVecTy; ++ ++ if ((ResTy.is128BitVector() && ++ !isLSXBySplatBitSize(SplatBitSize, ViaVecTy)) || ++ (ResTy.is256BitVector() && ++ !isLASXBySplatBitSize(SplatBitSize, ViaVecTy))) ++ return SDValue(); ++ ++ // SelectionDAG::getConstant will promote SplatValue appropriately. ++ SDValue Result = DAG.getConstant(SplatValue, DL, ViaVecTy); ++ ++ // Bitcast to the type we originally wanted ++ if (ViaVecTy != ResTy) ++ Result = DAG.getNode(ISD::BITCAST, SDLoc(Node), ResTy, Result); ++ ++ return Result; ++ } else if (DAG.isSplatValue(Op, /* AllowUndefs */ false)) ++ return Op; ++ else if (!isConstantOrUndefBUILD_VECTOR(Node)) { ++ // Use INSERT_VECTOR_ELT operations rather than expand to stores. ++ // The resulting code is the same length as the expansion, but it doesn't ++ // use memory operations ++ EVT ResTy = Node->getValueType(0); ++ ++ assert(ResTy.isVector()); ++ ++ unsigned NumElts = ResTy.getVectorNumElements(); ++ SDValue Vector = DAG.getUNDEF(ResTy); ++ for (unsigned i = 0; i < NumElts; ++i) { ++ Vector = ++ DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, ResTy, Vector, ++ Node->getOperand(i), DAG.getConstant(i, DL, MVT::i32)); ++ } ++ return Vector; ++ } ++ ++ return SDValue(); ++} ++ ++SDValue LoongArchTargetLowering::lowerUINT_TO_FP(SDValue Op, ++ SelectionDAG &DAG) const { ++ SDLoc DL(Op); ++ EVT ResTy = Op->getValueType(0); ++ Op = LowerSUINT_TO_FP(ISD::ZERO_EXTEND_VECTOR_INREG, Op, DAG); ++ if (!ResTy.isVector()) ++ return Op; ++ return DAG.getNode(ISD::UINT_TO_FP, DL, ResTy, Op); ++} ++ ++SDValue LoongArchTargetLowering::lowerSINT_TO_FP(SDValue Op, ++ SelectionDAG &DAG) const { ++ SDLoc DL(Op); ++ EVT ResTy = Op->getValueType(0); ++ Op = LowerSUINT_TO_FP(ISD::SIGN_EXTEND_VECTOR_INREG, Op, DAG); ++ if (!ResTy.isVector()) ++ return Op; ++ return DAG.getNode(ISD::SINT_TO_FP, DL, ResTy, Op); ++} ++ ++SDValue LoongArchTargetLowering::lowerFP_TO_UINT(SDValue Op, ++ SelectionDAG &DAG) const { ++ if (!Op->getValueType(0).isVector()) ++ return SDValue(); ++ return LowerFP_TO_SUINT(ISD::FP_TO_UINT, ISD::ZERO_EXTEND_VECTOR_INREG, Op, ++ DAG); ++} ++ ++SDValue LoongArchTargetLowering::lowerFP_TO_SINT(SDValue Op, ++ SelectionDAG &DAG) const { ++ if (Op->getValueType(0).isVector()) ++ return LowerFP_TO_SUINT(ISD::FP_TO_SINT, ISD::SIGN_EXTEND_VECTOR_INREG, Op, ++ DAG); ++ ++ if (Op.getValueSizeInBits() > 32 && Subtarget.isSingleFloat()) ++ return SDValue(); ++ ++ EVT FPTy = EVT::getFloatingPointVT(Op.getValueSizeInBits()); ++ SDValue Trunc = ++ DAG.getNode(LoongArchISD::TruncIntFP, SDLoc(Op), FPTy, Op.getOperand(0)); ++ return DAG.getNode(ISD::BITCAST, SDLoc(Op), Op.getValueType(), Trunc); ++} ++ ++static bool checkUndef(ArrayRef Mask, int Lo, int Hi) { ++ ++ for (int i = Lo, end = Hi; i != end; i++, Hi++) ++ if (!((Mask[i] == -1) || (Mask[i] == Hi))) ++ return false; ++ return true; ++} ++ ++static bool CheckRev(ArrayRef Mask) { ++ ++ int Num = Mask.size() - 1; ++ for (long unsigned int i = 0; i < Mask.size(); i++, Num--) ++ if (Mask[i] != Num) ++ return false; ++ return true; ++} ++ ++static bool checkHalf(ArrayRef Mask, int Lo, int Hi, int base) { ++ ++ for (int i = Lo; i < Hi; i++) ++ if (Mask[i] != (base + i)) ++ return false; ++ return true; ++} ++ ++static SDValue lowerHalfHalf(const SDLoc &DL, MVT VT, SDValue Op1, SDValue Op2, ++ ArrayRef Mask, SelectionDAG &DAG) { ++ ++ int Num = VT.getVectorNumElements(); ++ int HalfNum = Num / 2; ++ ++ if (Op1->isUndef() || Op2->isUndef() || Mask.size() > (long unsigned int)Num) ++ return SDValue(); ++ ++ if (checkHalf(Mask, HalfNum, Num, Num) && checkHalf(Mask, 0, HalfNum, 0)) { ++ return SDValue(DAG.getMachineNode(LoongArch::XVPERMI_Q, DL, VT, Op2, Op1, ++ DAG.getTargetConstant(48, DL, MVT::i32)), ++ 0); ++ } ++ ++ return SDValue(); ++} ++ ++static bool checkHalfUndef(ArrayRef Mask, int Lo, int Hi) { ++ ++ for (int i = Lo; i < Hi; i++) ++ if (Mask[i] != -1) ++ return false; ++ return true; ++} ++ ++// Lowering vectors with half undef data, ++// use EXTRACT_SUBVECTOR and INSERT_SUBVECTOR instead of VECTOR_SHUFFLE ++static SDValue lowerHalfUndef(const SDLoc &DL, MVT VT, SDValue Op1, SDValue Op2, ++ ArrayRef Mask, SelectionDAG &DAG) { ++ ++ int Num = VT.getVectorNumElements(); ++ int HalfNum = Num / 2; ++ MVT HalfVT = MVT::getVectorVT(VT.getVectorElementType(), HalfNum); ++ MVT VT1 = Op1.getSimpleValueType(); ++ SDValue Op; ++ ++ bool check1 = Op1->isUndef() && (!Op2->isUndef()); ++ bool check2 = Op2->isUndef() && (!Op1->isUndef()); ++ ++ if ((check1 || check2) && (VT1 == VT)) { ++ if (check1) { ++ Op = DAG.getNode(ISD::BITCAST, DL, MVT::v4i64, Op2); ++ } else if (check2) { ++ Op = DAG.getNode(ISD::BITCAST, DL, MVT::v4i64, Op1); ++ } ++ ++ if (VT == MVT::v32i8 && CheckRev(Mask)) { ++ SDValue Vector; ++ SDValue Rev[4]; ++ SDValue Ext[4]; ++ for (int i = 0; i < 4; i++) { ++ Ext[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i64, Op, ++ DAG.getConstant(i, DL, MVT::i32)); ++ Rev[i] = DAG.getNode(LoongArchISD::REVBD, DL, MVT::i64, Ext[i]); ++ } ++ ++ Vector = ++ DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, MVT::v4i64, DAG.getUNDEF(VT), ++ Rev[3], DAG.getConstant(3, DL, MVT::i32)); ++ Vector = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, MVT::v4i64, Vector, ++ Rev[2], DAG.getConstant(2, DL, MVT::i32)); ++ Vector = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, MVT::v4i64, Vector, ++ Rev[1], DAG.getConstant(1, DL, MVT::i32)); ++ Vector = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, MVT::v4i64, Vector, ++ Rev[0], DAG.getConstant(0, DL, MVT::i32)); ++ ++ Vector = DAG.getNode(ISD::BITCAST, DL, MVT::v32i8, Vector); ++ ++ return Vector; ++ } ++ } ++ ++ if (checkHalfUndef(Mask, HalfNum, Num) && checkUndef(Mask, 0, HalfNum)) { ++ SDValue High = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, HalfVT, Op1, ++ DAG.getConstant(HalfNum, DL, MVT::i64)); ++ return DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VT, DAG.getUNDEF(VT), High, ++ DAG.getConstant(0, DL, MVT::i64)); ++ } ++ ++ if (checkHalfUndef(Mask, HalfNum, Num) && (VT == MVT::v8i32) && ++ (Mask[0] == 0) && (Mask[1] == 1) && (Mask[2] == (Num + 2)) && ++ (Mask[3] == (Num + 3))) { ++ ++ SDValue Val1 = ++ SDValue(DAG.getMachineNode(LoongArch::XVPERMI_Q, DL, VT, Op2, Op1, ++ DAG.getTargetConstant(32, DL, MVT::i32)), ++ 0); ++ ++ SDValue Val2 = ++ SDValue(DAG.getMachineNode(LoongArch::XVPERMI_D, DL, VT, Val1, ++ DAG.getTargetConstant(12, DL, MVT::i32)), ++ 0); ++ ++ SDValue Val3 = SDValue( ++ DAG.getMachineNode(LoongArch::XVPERMI_Q, DL, VT, Val2, DAG.getUNDEF(VT), ++ DAG.getTargetConstant(2, DL, MVT::i32)), ++ 0); ++ return Val3; ++ } ++ ++ if (checkHalfUndef(Mask, 0, HalfNum) && checkUndef(Mask, HalfNum, Num)) { ++ SDValue Low = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, HalfVT, Op1, ++ DAG.getConstant(0, DL, MVT::i32)); ++ return DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VT, DAG.getUNDEF(VT), Low, ++ DAG.getConstant(HalfNum, DL, MVT::i32)); ++ } ++ ++ if (checkHalfUndef(Mask, 0, HalfNum) && (VT == MVT::v8i32) && ++ (Mask[HalfNum] == HalfNum) && (Mask[HalfNum + 1] == (HalfNum + 1)) && ++ (Mask[HalfNum + 2] == (2 * Num - 2)) && ++ (Mask[HalfNum + 3] == (2 * Num - 1))) { ++ ++ SDValue Val1 = ++ SDValue(DAG.getMachineNode(LoongArch::XVPERMI_Q, DL, VT, Op2, Op1, ++ DAG.getTargetConstant(49, DL, MVT::i32)), ++ 0); ++ ++ SDValue Val2 = ++ SDValue(DAG.getMachineNode(LoongArch::XVPERMI_D, DL, VT, Val1, ++ DAG.getTargetConstant(12, DL, MVT::i32)), ++ 0); ++ ++ SDValue Val3 = SDValue( ++ DAG.getMachineNode(LoongArch::XVPERMI_Q, DL, VT, Val2, DAG.getUNDEF(VT), ++ DAG.getTargetConstant(32, DL, MVT::i32)), ++ 0); ++ return Val3; ++ } ++ ++ if ((VT == MVT::v8i32) || (VT == MVT::v4i64)) { ++ int def = 0; ++ int j = 0; ++ int ext[3]; ++ int ins[3]; ++ bool useOp1[3] = {true, true, true}; ++ bool checkdef = true; ++ ++ for (int i = 0; i < Num; i++) { ++ if (def > 2) { ++ checkdef = false; ++ break; ++ } ++ if (Mask[i] != -1) { ++ def++; ++ ins[j] = i; ++ if (Mask[i] >= Num) { ++ ext[j] = Mask[i] - Num; ++ useOp1[j] = false; ++ } else { ++ ext[j] = Mask[i]; ++ } ++ j++; ++ } ++ } ++ ++ if (checkdef) { ++ SDValue Vector = DAG.getUNDEF(VT); ++ EVT EltTy = VT.getVectorElementType(); ++ SDValue Ext[2]; ++ ++ if (check1 || check2) { ++ for (int i = 0; i < def; i++) { ++ if (check1) { ++ Ext[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltTy, Op2, ++ DAG.getConstant(ext[i], DL, MVT::i32)); ++ Vector = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, VT, Vector, Ext[i], ++ DAG.getConstant(ins[i], DL, MVT::i32)); ++ } else if (check2) { ++ Ext[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltTy, Op1, ++ DAG.getConstant(ext[i], DL, MVT::i32)); ++ Vector = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, VT, Vector, Ext[i], ++ DAG.getConstant(ins[i], DL, MVT::i32)); ++ } ++ } ++ return Vector; ++ } else { ++ for (int i = 0; i < def; i++) { ++ if (!useOp1[i]) { ++ Ext[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltTy, Op2, ++ DAG.getConstant(ext[i], DL, MVT::i32)); ++ Vector = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, VT, Vector, Ext[i], ++ DAG.getConstant(ins[i], DL, MVT::i32)); ++ } else { ++ Ext[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltTy, Op1, ++ DAG.getConstant(ext[i], DL, MVT::i32)); ++ Vector = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, VT, Vector, Ext[i], ++ DAG.getConstant(ins[i], DL, MVT::i32)); ++ } ++ } ++ return Vector; ++ } ++ } ++ } ++ ++ return SDValue(); ++} ++ ++static SDValue lowerHalfUndef_LSX(const SDLoc &DL, EVT ResTy, MVT VT, ++ SDValue Op1, SDValue Op2, ArrayRef Mask, ++ SelectionDAG &DAG) { ++ ++ MVT VT1 = Op1.getSimpleValueType(); ++ ++ bool check1 = Op1->isUndef() && (!Op2->isUndef()); ++ bool check2 = Op2->isUndef() && (!Op1->isUndef()); ++ ++ if ((check1 || check2) && (VT1 == VT)) { ++ SDValue Op; ++ ++ if (VT == MVT::v16i8 && CheckRev(Mask)) { ++ ++ if (check1) { ++ Op = DAG.getNode(ISD::BITCAST, DL, MVT::v2i64, Op2); ++ } else if (check2) { ++ Op = DAG.getNode(ISD::BITCAST, DL, MVT::v2i64, Op1); ++ } ++ ++ SDValue Vector; ++ SDValue Rev[2]; ++ SDValue Ext[2]; ++ for (int i = 0; i < 2; i++) { ++ Ext[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i64, Op, ++ DAG.getConstant(i, DL, MVT::i32)); ++ Rev[i] = DAG.getNode(LoongArchISD::REVBD, DL, MVT::i64, Ext[i]); ++ } ++ ++ Vector = ++ DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, MVT::v2i64, DAG.getUNDEF(VT), ++ Rev[1], DAG.getConstant(1, DL, MVT::i32)); ++ Vector = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, MVT::v2i64, Vector, ++ Rev[0], DAG.getConstant(0, DL, MVT::i32)); ++ ++ Vector = DAG.getNode(ISD::BITCAST, DL, MVT::v16i8, Vector); ++ ++ return Vector; ++ } ++ } ++ ++ return SDValue(); ++} ++ ++// Use SDNode of LoongArchINSVE instead of ++// a series of EXTRACT_VECTOR_ELT and INSERT_VECTOR_ELT ++static SDValue lowerVECTOR_SHUFFLE_INSVE(const SDLoc &DL, MVT VT, EVT ResTy, ++ SDValue Op1, SDValue Op2, ++ ArrayRef Mask, ++ SelectionDAG &DAG) { ++ ++ int Num = VT.getVectorNumElements(); ++ if (ResTy == MVT::v16i16 || ResTy == MVT::v32i8) ++ return SDValue(); ++ ++ int CheckOne = 0; ++ int CheckOther = 0; ++ int Idx; ++ ++ for (int i = 0; i < Num; i++) { ++ if ((Mask[i] == i) || (Mask[i] == -1)) { ++ CheckOther++; ++ } else if (Mask[i] == Num) { ++ CheckOne++; ++ Idx = i; ++ } else ++ return SDValue(); ++ } ++ ++ if ((CheckOne != 1) || (CheckOther != (Num - 1))) ++ return SDValue(); ++ else { ++ return DAG.getNode(LoongArchISD::INSVE, DL, ResTy, Op1, Op2, ++ DAG.getConstant(Idx, DL, MVT::i32)); ++ } ++ ++ return SDValue(); ++} ++ ++static SDValue lowerVECTOR_SHUFFLE_XVPICKVE(const SDLoc &DL, MVT VT, EVT ResTy, ++ SDValue Op1, SDValue Op2, ++ ArrayRef Mask, ++ SelectionDAG &DAG) { ++ ++ int Num = VT.getVectorNumElements(); ++ if (ResTy == MVT::v16i16 || ResTy == MVT::v32i8 || ++ (!ISD::isBuildVectorAllZeros(Op1.getNode()))) ++ return SDValue(); ++ ++ bool CheckV = true; ++ ++ if ((Mask[0] < Num) || (Mask[0] > (2 * Num - 1))) ++ CheckV = false; ++ ++ for (int i = 1; i < Num; i++) { ++ if (Mask[i] != 0) { ++ CheckV = false; ++ break; ++ } ++ } ++ ++ if (!CheckV) ++ return SDValue(); ++ else { ++ return DAG.getNode(LoongArchISD::XVPICKVE, DL, ResTy, Op1, Op2, ++ DAG.getConstant(Mask[0] - Num, DL, MVT::i32)); ++ } ++ ++ return SDValue(); ++} ++ ++static SDValue lowerVECTOR_SHUFFLE_XVSHUF(const SDLoc &DL, MVT VT, EVT ResTy, ++ SDValue Op1, SDValue Op2, ++ ArrayRef Mask, ++ SelectionDAG &DAG) { ++ ++ if (VT == MVT::v4i64) { ++ int Num = VT.getVectorNumElements(); ++ ++ bool CheckV = true; ++ for (int i = 0; i < Num; i++) { ++ if (Mask[i] != (i * 2)) { ++ CheckV = false; ++ break; ++ } ++ } ++ ++ if (!CheckV) ++ return SDValue(); ++ else { ++ SDValue Res = DAG.getNode(LoongArchISD::XVSHUF4I, DL, ResTy, Op1, Op2, ++ DAG.getConstant(8, DL, MVT::i32)); ++ return DAG.getNode(LoongArchISD::XVPERMI, DL, ResTy, Res, ++ DAG.getConstant(0xD8, DL, MVT::i32)); ++ } ++ } else ++ return SDValue(); ++} ++ ++// Lower VECTOR_SHUFFLE into one of a number of instructions depending on the ++// indices in the shuffle. ++SDValue LoongArchTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op, ++ SelectionDAG &DAG) const { ++ ShuffleVectorSDNode *Node = cast(Op); ++ EVT ResTy = Op->getValueType(0); ++ ArrayRef Mask = Node->getMask(); ++ SDValue Op1 = Op.getOperand(0); ++ SDValue Op2 = Op.getOperand(1); ++ MVT VT = Op.getSimpleValueType(); ++ SDLoc DL(Op); ++ ++ if (ResTy.is128BitVector()) { ++ ++ int ResTyNumElts = ResTy.getVectorNumElements(); ++ SmallVector Indices; ++ ++ for (int i = 0; i < ResTyNumElts; ++i) ++ Indices.push_back(Node->getMaskElt(i)); ++ ++ SDValue Result; ++ if (isVECTOR_SHUFFLE_VREPLVEI(Op, ResTy, Indices, DAG)) ++ return lowerVECTOR_SHUFFLE_VSHF(Op, ResTy, Indices, DAG); ++ if ((Result = lowerVECTOR_SHUFFLE_VPACKEV(Op, ResTy, Indices, DAG))) ++ return Result; ++ if ((Result = lowerVECTOR_SHUFFLE_VPACKOD(Op, ResTy, Indices, DAG))) ++ return Result; ++ if ((Result = lowerVECTOR_SHUFFLE_VILVH(Op, ResTy, Indices, DAG))) ++ return Result; ++ if ((Result = lowerVECTOR_SHUFFLE_VILVL(Op, ResTy, Indices, DAG))) ++ return Result; ++ if ((Result = lowerVECTOR_SHUFFLE_VPICKEV(Op, ResTy, Indices, DAG))) ++ return Result; ++ if ((Result = lowerVECTOR_SHUFFLE_VPICKOD(Op, ResTy, Indices, DAG))) ++ return Result; ++ if ((Result = lowerVECTOR_SHUFFLE_SHF(Op, ResTy, Indices, DAG))) ++ return Result; ++ if ((Result = lowerHalfUndef_LSX(DL, ResTy, VT, Op1, Op2, Mask, DAG))) ++ return Result; ++ return lowerVECTOR_SHUFFLE_VSHF(Op, ResTy, Indices, DAG); ++ ++ } else if (ResTy.is256BitVector()) { ++ int ResTyNumElts = ResTy.getVectorNumElements(); ++ SmallVector Indices; ++ ++ for (int i = 0; i < ResTyNumElts; ++i) ++ Indices.push_back(Node->getMaskElt(i)); ++ ++ SDValue Result; ++ if ((Result = lowerHalfHalf(DL, VT, Op1, Op2, Mask, DAG))) ++ return Result; ++ if ((Result = lowerHalfUndef(DL, VT, Op1, Op2, Mask, DAG))) ++ return Result; ++ if (isVECTOR_SHUFFLE_XVREPLVEI(Op, ResTy, Indices, DAG)) ++ return SDValue(); ++ if ((Result = lowerVECTOR_SHUFFLE_XVPACKEV(Op, ResTy, Indices, DAG))) ++ return Result; ++ if ((Result = lowerVECTOR_SHUFFLE_XVPACKOD(Op, ResTy, Indices, DAG))) ++ return Result; ++ if ((Result = lowerVECTOR_SHUFFLE_XVILVH(Op, ResTy, Indices, DAG))) ++ return Result; ++ if ((Result = lowerVECTOR_SHUFFLE_XVILVL(Op, ResTy, Indices, DAG))) ++ return Result; ++ if ((Result = lowerVECTOR_SHUFFLE_XVPICKEV(Op, ResTy, Indices, DAG))) ++ return Result; ++ if ((Result = lowerVECTOR_SHUFFLE_XVPICKOD(Op, ResTy, Indices, DAG))) ++ return Result; ++ if ((Result = lowerVECTOR_SHUFFLE_XSHF(Op, ResTy, Indices, DAG))) ++ return Result; ++ if ((Result = ++ lowerVECTOR_SHUFFLE_INSVE(DL, VT, ResTy, Op1, Op2, Mask, DAG))) ++ return Result; ++ if ((Result = ++ lowerVECTOR_SHUFFLE_XVPICKVE(DL, VT, ResTy, Op1, Op2, Mask, DAG))) ++ return Result; ++ if ((Result = ++ lowerVECTOR_SHUFFLE_XVSHUF(DL, VT, ResTy, Op1, Op2, Mask, DAG))) ++ return Result; ++ } ++ ++ return SDValue(); ++} ++ ++SDValue LoongArchTargetLowering::lowerEH_DWARF_CFA(SDValue Op, ++ SelectionDAG &DAG) const { ++ ++ // Return a fixed StackObject with offset 0 which points to the old stack ++ // pointer. ++ MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); ++ EVT ValTy = Op->getValueType(0); ++ int FI = MFI.CreateFixedObject(Op.getValueSizeInBits() / 8, 0, false); ++ return DAG.getFrameIndex(FI, ValTy); ++} ++ ++// Check whether the tail call optimization conditions are met ++bool LoongArchTargetLowering::isEligibleForTailCallOptimization( ++ const CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF, ++ unsigned NextStackOffset, const LoongArchFunctionInfo &FI) const { ++ ++ auto CalleeCC = CLI.CallConv; ++ auto IsVarArg = CLI.IsVarArg; ++ auto &Outs = CLI.Outs; ++ auto &Caller = MF.getFunction(); ++ auto CallerCC = Caller.getCallingConv(); ++ ++ if (Caller.getFnAttribute("disable-tail-calls").getValueAsString() == "true") ++ return false; ++ ++ if (Caller.hasFnAttribute("interrupt")) ++ return false; ++ ++ if (IsVarArg) ++ return false; ++ ++ if (getTargetMachine().getCodeModel() == CodeModel::Large) ++ return false; ++ ++ if (getTargetMachine().getRelocationModel() == Reloc::Static) ++ return false; ++ ++ // Do not tail call optimize if the stack is used to pass parameters. ++ if (CCInfo.getStackSize() != 0) ++ return false; ++ ++ // Do not tail call optimize functions with byval parameters. ++ for (auto &Arg : Outs) ++ if (Arg.Flags.isByVal()) ++ return false; ++ ++ // Do not tail call optimize if either caller or callee uses structret ++ // semantics. ++ auto IsCallerStructRet = Caller.hasStructRetAttr(); ++ auto IsCalleeStructRet = Outs.empty() ? false : Outs[0].Flags.isSRet(); ++ if (IsCallerStructRet || IsCalleeStructRet) ++ return false; ++ ++ // The callee has to preserve all registers the caller needs to preserve. ++ const LoongArchRegisterInfo *TRI = Subtarget.getRegisterInfo(); ++ const uint32_t *CallerPreserved = TRI->getCallPreservedMask(MF, CallerCC); ++ if (CalleeCC != CallerCC) { ++ const uint32_t *CalleePreserved = TRI->getCallPreservedMask(MF, CalleeCC); ++ if (!TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved)) ++ return false; ++ } ++ ++ // Return false if either the callee or caller has a byval argument. ++ if (CCInfo.getInRegsParamsCount() > 0 || FI.hasByvalArg()) ++ return false; ++ ++ // Return true if the callee's argument area is no larger than the ++ // caller's. ++ return NextStackOffset <= FI.getIncomingArgSize(); ++} ++ ++//===----------------------------------------------------------------------===// ++// Calling Convention Implementation ++//===----------------------------------------------------------------------===// ++ ++//===----------------------------------------------------------------------===// ++// TODO: Implement a generic logic using tblgen that can support this. ++// LoongArch LP32 ABI rules: ++// --- ++// i32 - Passed in A0, A1, A2, A3 and stack ++// f32 - Only passed in f32 registers if no int reg has been used yet to hold ++// an argument. Otherwise, passed in A1, A2, A3 and stack. ++// f64 - Only passed in two aliased f32 registers if no int reg has been used ++// yet to hold an argument. Otherwise, use A2, A3 and stack. If A1 is ++// not used, it must be shadowed. If only A3 is available, shadow it and ++// go to stack. ++// vXiX - Received as scalarized i32s, passed in A0 - A3 and the stack. ++// vXf32 - Passed in either a pair of registers {A0, A1}, {A2, A3} or {A0 - A3} ++// with the remainder spilled to the stack. ++// vXf64 - Passed in either {A0, A1, A2, A3} or {A2, A3} and in both cases ++// spilling the remainder to the stack. ++// ++// For vararg functions, all arguments are passed in A0, A1, A2, A3 and stack. ++//===----------------------------------------------------------------------===// ++ ++static bool CC_LoongArchLP32(unsigned ValNo, MVT ValVT, MVT LocVT, ++ CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, ++ CCState &State, ArrayRef F64Regs) { ++ static const MCPhysReg IntRegs[] = { LoongArch::A0, LoongArch::A1, LoongArch::A2, LoongArch::A3 }; ++ ++ const LoongArchCCState * LoongArchState = static_cast(&State); ++ ++ static const MCPhysReg F32Regs[] = { LoongArch::F12, LoongArch::F14 }; ++ ++ static const MCPhysReg FloatVectorIntRegs[] = { LoongArch::A0, LoongArch::A2 }; ++ ++ // Do not process byval args here. ++ if (ArgFlags.isByVal()) ++ return true; ++ ++ ++ // Promote i8 and i16 ++ if (LocVT == MVT::i8 || LocVT == MVT::i16) { ++ LocVT = MVT::i32; ++ if (ArgFlags.isSExt()) ++ LocInfo = CCValAssign::SExt; ++ else if (ArgFlags.isZExt()) ++ LocInfo = CCValAssign::ZExt; ++ else ++ LocInfo = CCValAssign::AExt; ++ } ++ ++ unsigned Reg; ++ ++ // f32 and f64 are allocated in A0, A1, A2, A3 when either of the following ++ // is true: function is vararg, argument is 3rd or higher, there is previous ++ // argument which is not f32 or f64. ++ bool AllocateFloatsInIntReg = State.isVarArg() || ValNo > 1 || ++ State.getFirstUnallocated(F32Regs) != ValNo; ++ Align OrigAlign = ArgFlags.getNonZeroOrigAlign(); ++ bool isI64 = (ValVT == MVT::i32 && OrigAlign == Align(8)); ++ bool isVectorFloat = LoongArchState->WasOriginalArgVectorFloat(ValNo); ++ ++ // The LoongArch vector ABI for floats passes them in a pair of registers ++ if (ValVT == MVT::i32 && isVectorFloat) { ++ // This is the start of an vector that was scalarized into an unknown number ++ // of components. It doesn't matter how many there are. Allocate one of the ++ // notional 8 byte aligned registers which map onto the argument stack, and ++ // shadow the register lost to alignment requirements. ++ if (ArgFlags.isSplit()) { ++ Reg = State.AllocateReg(FloatVectorIntRegs); ++ if (Reg == LoongArch::A2) ++ State.AllocateReg(LoongArch::A1); ++ else if (Reg == 0) ++ State.AllocateReg(LoongArch::A3); ++ } else { ++ // If we're an intermediate component of the split, we can just attempt to ++ // allocate a register directly. ++ Reg = State.AllocateReg(IntRegs); ++ } ++ } else if (ValVT == MVT::i32 || (ValVT == MVT::f32 && AllocateFloatsInIntReg)) { ++ Reg = State.AllocateReg(IntRegs); ++ // If this is the first part of an i64 arg, ++ // the allocated register must be either A0 or A2. ++ if (isI64 && (Reg == LoongArch::A1 || Reg == LoongArch::A3)) ++ Reg = State.AllocateReg(IntRegs); ++ LocVT = MVT::i32; ++ } else if (ValVT == MVT::f64 && AllocateFloatsInIntReg) { ++ // Allocate int register and shadow next int register. If first ++ // available register is LoongArch::A1 or LoongArch::A3, shadow it too. ++ Reg = State.AllocateReg(IntRegs); ++ if (Reg == LoongArch::A1 || Reg == LoongArch::A3) ++ Reg = State.AllocateReg(IntRegs); ++ State.AllocateReg(IntRegs); ++ LocVT = MVT::i32; ++ } else if (ValVT.isFloatingPoint() && !AllocateFloatsInIntReg) { ++ // we are guaranteed to find an available float register ++ if (ValVT == MVT::f32) { ++ Reg = State.AllocateReg(F32Regs); ++ // Shadow int register ++ State.AllocateReg(IntRegs); ++ } else { ++ Reg = State.AllocateReg(F64Regs); ++ // Shadow int registers ++ unsigned Reg2 = State.AllocateReg(IntRegs); ++ if (Reg2 == LoongArch::A1 || Reg2 == LoongArch::A3) ++ State.AllocateReg(IntRegs); ++ State.AllocateReg(IntRegs); ++ } ++ } else ++ llvm_unreachable("Cannot handle this ValVT."); ++ ++ if (!Reg) { ++ unsigned Offset = State.AllocateStack(ValVT.getStoreSize(), OrigAlign); ++ State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); ++ } else ++ State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); ++ ++ return false; ++} ++ ++static bool CC_LoongArchLP32_FP32(unsigned ValNo, MVT ValVT, ++ MVT LocVT, CCValAssign::LocInfo LocInfo, ++ ISD::ArgFlagsTy ArgFlags, CCState &State) { ++ static const MCPhysReg F64Regs[] = {LoongArch::F0_64, LoongArch::F1_64, LoongArch::F2_64, \ ++ LoongArch::F3_64, LoongArch::F4_64, LoongArch::F5_64, \ ++ LoongArch::F6_64, LoongArch::F7_64 }; ++ ++ return CC_LoongArchLP32(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State, F64Regs); ++} ++ ++static bool CC_LoongArchLP32_FP64(unsigned ValNo, MVT ValVT, ++ MVT LocVT, CCValAssign::LocInfo LocInfo, ++ ISD::ArgFlagsTy ArgFlags, CCState &State) { ++ static const MCPhysReg F64Regs[] = {LoongArch::F0_64, LoongArch::F1_64, LoongArch::F2_64, \ ++ LoongArch::F3_64, LoongArch::F4_64, LoongArch::F5_64, \ ++ LoongArch::F6_64, LoongArch::F7_64 }; ++ ++ return CC_LoongArchLP32(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State, F64Regs); ++} ++ ++static bool CC_LoongArch_F128(unsigned ValNo, MVT ValVT, ++ MVT LocVT, CCValAssign::LocInfo LocInfo, ++ ISD::ArgFlagsTy ArgFlags, CCState &State) LLVM_ATTRIBUTE_UNUSED; ++ ++static bool CC_LoongArch_F128(unsigned ValNo, MVT ValVT, ++ MVT LocVT, CCValAssign::LocInfo LocInfo, ++ ISD::ArgFlagsTy ArgFlags, CCState &State) { ++ ++ static const MCPhysReg ArgRegs[8] = { ++ LoongArch::A0_64, LoongArch::A1_64, LoongArch::A2_64, LoongArch::A3_64, ++ LoongArch::A4_64, LoongArch::A5_64, LoongArch::A6_64, LoongArch::A7_64}; ++ ++ unsigned Idx = State.getFirstUnallocated(ArgRegs); ++ // Skip 'odd' register if necessary. ++ if (!ArgFlags.isSplitEnd() && Idx != std::size(ArgRegs) && Idx % 2 == 1) ++ State.AllocateReg(ArgRegs); ++ return true; ++} ++ ++static bool CC_LoongArchLP32(unsigned ValNo, MVT ValVT, MVT LocVT, ++ CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, ++ CCState &State) LLVM_ATTRIBUTE_UNUSED; ++ ++#include "LoongArchGenCallingConv.inc" ++ ++ CCAssignFn *LoongArchTargetLowering::CCAssignFnForCall() const{ ++ return CC_LoongArch; ++ } ++ ++ CCAssignFn *LoongArchTargetLowering::CCAssignFnForReturn() const{ ++ return RetCC_LoongArch; ++ } ++ ++//===----------------------------------------------------------------------===// ++// Call Calling Convention Implementation ++//===----------------------------------------------------------------------===// ++SDValue LoongArchTargetLowering::passArgOnStack(SDValue StackPtr, unsigned Offset, ++ SDValue Chain, SDValue Arg, ++ const SDLoc &DL, bool IsTailCall, ++ SelectionDAG &DAG) const { ++ if (!IsTailCall) { ++ SDValue PtrOff = ++ DAG.getNode(ISD::ADD, DL, getPointerTy(DAG.getDataLayout()), StackPtr, ++ DAG.getIntPtrConstant(Offset, DL)); ++ return DAG.getStore(Chain, DL, Arg, PtrOff, MachinePointerInfo()); ++ } ++ ++ MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); ++ int FI = MFI.CreateFixedObject(Arg.getValueSizeInBits() / 8, Offset, false); ++ SDValue FIN = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout())); ++ return DAG.getStore(Chain, DL, Arg, FIN, MachinePointerInfo(), MaybeAlign(), ++ MachineMemOperand::MOVolatile); ++} ++ ++void LoongArchTargetLowering::getOpndList( ++ SmallVectorImpl &Ops, ++ std::deque> &RegsToPass, bool IsPICCall, ++ bool GlobalOrExternal, bool IsCallReloc, CallLoweringInfo &CLI, ++ SDValue Callee, SDValue Chain, bool IsTailCall) const { ++ // Build a sequence of copy-to-reg nodes chained together with token ++ // chain and flag operands which copy the outgoing args into registers. ++ // The InFlag in necessary since all emitted instructions must be ++ // stuck together. ++ SDValue InFlag; ++ ++ Ops.push_back(Callee); ++ ++ for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { ++ Chain = CLI.DAG.getCopyToReg(Chain, CLI.DL, RegsToPass[i].first, ++ RegsToPass[i].second, InFlag); ++ InFlag = Chain.getValue(1); ++ } ++ ++ // Add argument registers to the end of the list so that they are ++ // known live into the call. ++ for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) ++ Ops.push_back(CLI.DAG.getRegister(RegsToPass[i].first, ++ RegsToPass[i].second.getValueType())); ++ ++ if (!IsTailCall) { ++ // Add a register mask operand representing the call-preserved registers. ++ const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo(); ++ const uint32_t *Mask = ++ TRI->getCallPreservedMask(CLI.DAG.getMachineFunction(), CLI.CallConv); ++ assert(Mask && "Missing call preserved mask for calling convention"); ++ Ops.push_back(CLI.DAG.getRegisterMask(Mask)); ++ } ++ ++ if (InFlag.getNode()) ++ Ops.push_back(InFlag); ++} ++ ++void LoongArchTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI, ++ SDNode *Node) const { ++ switch (MI.getOpcode()) { ++ default: ++ return; ++ } ++} ++ ++/// LowerCall - functions arguments are copied from virtual regs to ++/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. ++SDValue ++LoongArchTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, ++ SmallVectorImpl &InVals) const { ++ SelectionDAG &DAG = CLI.DAG; ++ SDLoc DL = CLI.DL; ++ SmallVectorImpl &Outs = CLI.Outs; ++ SmallVectorImpl &OutVals = CLI.OutVals; ++ SmallVectorImpl &Ins = CLI.Ins; ++ SDValue Chain = CLI.Chain; ++ SDValue Callee = CLI.Callee; ++ bool &IsTailCall = CLI.IsTailCall; ++ CallingConv::ID CallConv = CLI.CallConv; ++ bool IsVarArg = CLI.IsVarArg; ++ ++ MachineFunction &MF = DAG.getMachineFunction(); ++ MachineFrameInfo &MFI = MF.getFrameInfo(); ++ const TargetFrameLowering *TFL = Subtarget.getFrameLowering(); ++ bool IsPIC = isPositionIndependent(); ++ ++ // Analyze operands of the call, assigning locations to each operand. ++ SmallVector ArgLocs; ++ LoongArchCCState CCInfo( ++ CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs, *DAG.getContext(), ++ LoongArchCCState::getSpecialCallingConvForCallee(Callee.getNode(), Subtarget)); ++ ++ const ExternalSymbolSDNode *ES = ++ dyn_cast_or_null(Callee.getNode()); ++ ++ // There is one case where CALLSEQ_START..CALLSEQ_END can be nested, which ++ // is during the lowering of a call with a byval argument which produces ++ // a call to memcpy. For the LP32 case, this causes the caller to allocate ++ // stack space for the reserved argument area for the callee, then recursively ++ // again for the memcpy call. In the NEWABI case, this doesn't occur as those ++ // ABIs mandate that the callee allocates the reserved argument area. We do ++ // still produce nested CALLSEQ_START..CALLSEQ_END with zero space though. ++ // ++ // If the callee has a byval argument and memcpy is used, we are mandated ++ // to already have produced a reserved argument area for the callee for LP32. ++ // Therefore, the reserved argument area can be reused for both calls. ++ // ++ // Other cases of calling memcpy cannot have a chain with a CALLSEQ_START ++ // present, as we have yet to hook that node onto the chain. ++ // ++ // Hence, the CALLSEQ_START and CALLSEQ_END nodes can be eliminated in this ++ // case. GCC does a similar trick, in that wherever possible, it calculates ++ // the maximum out going argument area (including the reserved area), and ++ // preallocates the stack space on entrance to the caller. ++ // ++ // FIXME: We should do the same for efficiency and space. ++ ++ bool MemcpyInByVal = ES && ++ StringRef(ES->getSymbol()) == StringRef("memcpy") && ++ Chain.getOpcode() == ISD::CALLSEQ_START; ++ ++ CCInfo.AnalyzeCallOperands(Outs, CC_LoongArch, CLI.getArgs(), ++ ES ? ES->getSymbol() : nullptr); ++ ++ // Get a count of how many bytes are to be pushed on the stack. ++ unsigned StackSize = CCInfo.getStackSize(); ++ ++ // Check if it's really possible to do a tail call. Restrict it to functions ++ // that are part of this compilation unit. ++ if (IsTailCall) { ++ IsTailCall = isEligibleForTailCallOptimization( ++ CCInfo, CLI, MF, StackSize, *MF.getInfo()); ++ if (GlobalAddressSDNode *G = dyn_cast(Callee)) { ++ if (G->getGlobal()->hasExternalWeakLinkage()) ++ IsTailCall = false; ++ } ++ } ++ if (!IsTailCall && CLI.CB && CLI.CB->isMustTailCall()) ++ report_fatal_error("failed to perform tail call elimination on a call " ++ "site marked musttail"); ++ ++ if (IsTailCall) ++ ++NumTailCalls; ++ ++ // Chain is the output chain of the last Load/Store or CopyToReg node. ++ // ByValChain is the output chain of the last Memcpy node created for copying ++ // byval arguments to the stack. ++ unsigned StackAlignment = TFL->getStackAlignment(); ++ StackSize = alignTo(StackSize, StackAlignment); ++ SDValue NextStackOffsetVal = DAG.getIntPtrConstant(StackSize, DL, true); ++ ++ if (!(IsTailCall || MemcpyInByVal)) ++ Chain = DAG.getCALLSEQ_START(Chain, StackSize, 0, DL); ++ ++ SDValue StackPtr = ++ DAG.getCopyFromReg(Chain, DL, ABI.IsLP64() ? LoongArch::SP_64 : LoongArch::SP, ++ getPointerTy(DAG.getDataLayout())); ++ ++ std::deque> RegsToPass; ++ SmallVector MemOpChains; ++ ++ CCInfo.rewindByValRegsInfo(); ++ ++ // Walk the register/memloc assignments, inserting copies/loads. ++ for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { ++ SDValue Arg = OutVals[i]; ++ CCValAssign &VA = ArgLocs[i]; ++ MVT ValVT = VA.getValVT(), LocVT = VA.getLocVT(); ++ ISD::ArgFlagsTy Flags = Outs[i].Flags; ++ bool UseUpperBits = false; ++ ++ // ByVal Arg. ++ if (Flags.isByVal()) { ++ unsigned FirstByValReg, LastByValReg; ++ unsigned ByValIdx = CCInfo.getInRegsParamsProcessed(); ++ CCInfo.getInRegsParamInfo(ByValIdx, FirstByValReg, LastByValReg); ++ ++ assert(Flags.getByValSize() && ++ "ByVal args of size 0 should have been ignored by front-end."); ++ assert(ByValIdx < CCInfo.getInRegsParamsCount()); ++ assert(!IsTailCall && ++ "Do not tail-call optimize if there is a byval argument."); ++ passByValArg(Chain, DL, RegsToPass, MemOpChains, StackPtr, MFI, DAG, Arg, ++ FirstByValReg, LastByValReg, Flags, ++ VA); ++ CCInfo.nextInRegsParam(); ++ continue; ++ } ++ ++ // Promote the value if needed. ++ switch (VA.getLocInfo()) { ++ default: ++ llvm_unreachable("Unknown loc info!"); ++ case CCValAssign::Full: ++ if (VA.isRegLoc()) { ++ if ((ValVT == MVT::f32 && LocVT == MVT::i32) || ++ (ValVT == MVT::f64 && LocVT == MVT::i64) || ++ (ValVT == MVT::i64 && LocVT == MVT::f64)) ++ Arg = DAG.getNode(ISD::BITCAST, DL, LocVT, Arg); ++ } ++ break; ++ case CCValAssign::BCvt: ++ Arg = DAG.getNode(ISD::BITCAST, DL, LocVT, Arg); ++ break; ++ case CCValAssign::SExtUpper: ++ UseUpperBits = true; ++ LLVM_FALLTHROUGH; ++ case CCValAssign::SExt: ++ Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, LocVT, Arg); ++ break; ++ case CCValAssign::ZExtUpper: ++ UseUpperBits = true; ++ LLVM_FALLTHROUGH; ++ case CCValAssign::ZExt: ++ Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, LocVT, Arg); ++ break; ++ case CCValAssign::AExtUpper: ++ UseUpperBits = true; ++ LLVM_FALLTHROUGH; ++ case CCValAssign::AExt: ++ Arg = DAG.getNode(ISD::ANY_EXTEND, DL, LocVT, Arg); ++ break; ++ } ++ ++ if (UseUpperBits) { ++ unsigned ValSizeInBits = Outs[i].ArgVT.getSizeInBits(); ++ unsigned LocSizeInBits = VA.getLocVT().getSizeInBits(); ++ Arg = DAG.getNode( ++ ISD::SHL, DL, VA.getLocVT(), Arg, ++ DAG.getConstant(LocSizeInBits - ValSizeInBits, DL, VA.getLocVT())); ++ } ++ ++ // Arguments that can be passed on register must be kept at ++ // RegsToPass vector ++ if (VA.isRegLoc()) { ++ RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); ++ continue; ++ } ++ ++ // Register can't get to this point... ++ assert(VA.isMemLoc()); ++ ++ // emit ISD::STORE whichs stores the ++ // parameter value to a stack Location ++ MemOpChains.push_back(passArgOnStack(StackPtr, VA.getLocMemOffset(), ++ Chain, Arg, DL, IsTailCall, DAG)); + } +- case Intrinsic::loongarch_lsx_vandi_b: +- case Intrinsic::loongarch_lasx_xvandi_b: +- return DAG.getNode(ISD::AND, DL, N->getValueType(0), N->getOperand(1), +- lowerVectorSplatImm<8>(N, 2, DAG)); +- case Intrinsic::loongarch_lsx_vori_b: +- case Intrinsic::loongarch_lasx_xvori_b: +- return DAG.getNode(ISD::OR, DL, N->getValueType(0), N->getOperand(1), +- lowerVectorSplatImm<8>(N, 2, DAG)); +- case Intrinsic::loongarch_lsx_vxori_b: +- case Intrinsic::loongarch_lasx_xvxori_b: +- return DAG.getNode(ISD::XOR, DL, N->getValueType(0), N->getOperand(1), +- lowerVectorSplatImm<8>(N, 2, DAG)); +- case Intrinsic::loongarch_lsx_vsll_b: +- case Intrinsic::loongarch_lsx_vsll_h: +- case Intrinsic::loongarch_lsx_vsll_w: +- case Intrinsic::loongarch_lsx_vsll_d: +- case Intrinsic::loongarch_lasx_xvsll_b: +- case Intrinsic::loongarch_lasx_xvsll_h: +- case Intrinsic::loongarch_lasx_xvsll_w: +- case Intrinsic::loongarch_lasx_xvsll_d: +- return DAG.getNode(ISD::SHL, DL, N->getValueType(0), N->getOperand(1), +- truncateVecElts(N, DAG)); +- case Intrinsic::loongarch_lsx_vslli_b: +- case Intrinsic::loongarch_lasx_xvslli_b: +- return DAG.getNode(ISD::SHL, DL, N->getValueType(0), N->getOperand(1), +- lowerVectorSplatImm<3>(N, 2, DAG)); +- case Intrinsic::loongarch_lsx_vslli_h: +- case Intrinsic::loongarch_lasx_xvslli_h: +- return DAG.getNode(ISD::SHL, DL, N->getValueType(0), N->getOperand(1), +- lowerVectorSplatImm<4>(N, 2, DAG)); +- case Intrinsic::loongarch_lsx_vslli_w: +- case Intrinsic::loongarch_lasx_xvslli_w: +- return DAG.getNode(ISD::SHL, DL, N->getValueType(0), N->getOperand(1), +- lowerVectorSplatImm<5>(N, 2, DAG)); +- case Intrinsic::loongarch_lsx_vslli_d: +- case Intrinsic::loongarch_lasx_xvslli_d: +- return DAG.getNode(ISD::SHL, DL, N->getValueType(0), N->getOperand(1), +- lowerVectorSplatImm<6>(N, 2, DAG)); +- case Intrinsic::loongarch_lsx_vsrl_b: +- case Intrinsic::loongarch_lsx_vsrl_h: +- case Intrinsic::loongarch_lsx_vsrl_w: +- case Intrinsic::loongarch_lsx_vsrl_d: +- case Intrinsic::loongarch_lasx_xvsrl_b: +- case Intrinsic::loongarch_lasx_xvsrl_h: +- case Intrinsic::loongarch_lasx_xvsrl_w: +- case Intrinsic::loongarch_lasx_xvsrl_d: +- return DAG.getNode(ISD::SRL, DL, N->getValueType(0), N->getOperand(1), +- truncateVecElts(N, DAG)); +- case Intrinsic::loongarch_lsx_vsrli_b: +- case Intrinsic::loongarch_lasx_xvsrli_b: +- return DAG.getNode(ISD::SRL, DL, N->getValueType(0), N->getOperand(1), +- lowerVectorSplatImm<3>(N, 2, DAG)); +- case Intrinsic::loongarch_lsx_vsrli_h: +- case Intrinsic::loongarch_lasx_xvsrli_h: +- return DAG.getNode(ISD::SRL, DL, N->getValueType(0), N->getOperand(1), +- lowerVectorSplatImm<4>(N, 2, DAG)); +- case Intrinsic::loongarch_lsx_vsrli_w: +- case Intrinsic::loongarch_lasx_xvsrli_w: +- return DAG.getNode(ISD::SRL, DL, N->getValueType(0), N->getOperand(1), +- lowerVectorSplatImm<5>(N, 2, DAG)); +- case Intrinsic::loongarch_lsx_vsrli_d: +- case Intrinsic::loongarch_lasx_xvsrli_d: +- return DAG.getNode(ISD::SRL, DL, N->getValueType(0), N->getOperand(1), +- lowerVectorSplatImm<6>(N, 2, DAG)); +- case Intrinsic::loongarch_lsx_vsra_b: +- case Intrinsic::loongarch_lsx_vsra_h: +- case Intrinsic::loongarch_lsx_vsra_w: +- case Intrinsic::loongarch_lsx_vsra_d: +- case Intrinsic::loongarch_lasx_xvsra_b: +- case Intrinsic::loongarch_lasx_xvsra_h: +- case Intrinsic::loongarch_lasx_xvsra_w: +- case Intrinsic::loongarch_lasx_xvsra_d: +- return DAG.getNode(ISD::SRA, DL, N->getValueType(0), N->getOperand(1), +- truncateVecElts(N, DAG)); +- case Intrinsic::loongarch_lsx_vsrai_b: +- case Intrinsic::loongarch_lasx_xvsrai_b: +- return DAG.getNode(ISD::SRA, DL, N->getValueType(0), N->getOperand(1), +- lowerVectorSplatImm<3>(N, 2, DAG)); +- case Intrinsic::loongarch_lsx_vsrai_h: +- case Intrinsic::loongarch_lasx_xvsrai_h: +- return DAG.getNode(ISD::SRA, DL, N->getValueType(0), N->getOperand(1), +- lowerVectorSplatImm<4>(N, 2, DAG)); +- case Intrinsic::loongarch_lsx_vsrai_w: +- case Intrinsic::loongarch_lasx_xvsrai_w: +- return DAG.getNode(ISD::SRA, DL, N->getValueType(0), N->getOperand(1), +- lowerVectorSplatImm<5>(N, 2, DAG)); +- case Intrinsic::loongarch_lsx_vsrai_d: +- case Intrinsic::loongarch_lasx_xvsrai_d: +- return DAG.getNode(ISD::SRA, DL, N->getValueType(0), N->getOperand(1), +- lowerVectorSplatImm<6>(N, 2, DAG)); +- case Intrinsic::loongarch_lsx_vclz_b: +- case Intrinsic::loongarch_lsx_vclz_h: +- case Intrinsic::loongarch_lsx_vclz_w: +- case Intrinsic::loongarch_lsx_vclz_d: +- case Intrinsic::loongarch_lasx_xvclz_b: +- case Intrinsic::loongarch_lasx_xvclz_h: +- case Intrinsic::loongarch_lasx_xvclz_w: +- case Intrinsic::loongarch_lasx_xvclz_d: +- return DAG.getNode(ISD::CTLZ, DL, N->getValueType(0), N->getOperand(1)); +- case Intrinsic::loongarch_lsx_vpcnt_b: +- case Intrinsic::loongarch_lsx_vpcnt_h: +- case Intrinsic::loongarch_lsx_vpcnt_w: +- case Intrinsic::loongarch_lsx_vpcnt_d: +- case Intrinsic::loongarch_lasx_xvpcnt_b: +- case Intrinsic::loongarch_lasx_xvpcnt_h: +- case Intrinsic::loongarch_lasx_xvpcnt_w: +- case Intrinsic::loongarch_lasx_xvpcnt_d: +- return DAG.getNode(ISD::CTPOP, DL, N->getValueType(0), N->getOperand(1)); +- case Intrinsic::loongarch_lsx_vbitclr_b: +- case Intrinsic::loongarch_lsx_vbitclr_h: +- case Intrinsic::loongarch_lsx_vbitclr_w: +- case Intrinsic::loongarch_lsx_vbitclr_d: +- case Intrinsic::loongarch_lasx_xvbitclr_b: +- case Intrinsic::loongarch_lasx_xvbitclr_h: +- case Intrinsic::loongarch_lasx_xvbitclr_w: +- case Intrinsic::loongarch_lasx_xvbitclr_d: +- return lowerVectorBitClear(N, DAG); +- case Intrinsic::loongarch_lsx_vbitclri_b: +- case Intrinsic::loongarch_lasx_xvbitclri_b: +- return lowerVectorBitClearImm<3>(N, DAG); +- case Intrinsic::loongarch_lsx_vbitclri_h: +- case Intrinsic::loongarch_lasx_xvbitclri_h: +- return lowerVectorBitClearImm<4>(N, DAG); +- case Intrinsic::loongarch_lsx_vbitclri_w: +- case Intrinsic::loongarch_lasx_xvbitclri_w: +- return lowerVectorBitClearImm<5>(N, DAG); +- case Intrinsic::loongarch_lsx_vbitclri_d: +- case Intrinsic::loongarch_lasx_xvbitclri_d: +- return lowerVectorBitClearImm<6>(N, DAG); +- case Intrinsic::loongarch_lsx_vbitset_b: +- case Intrinsic::loongarch_lsx_vbitset_h: +- case Intrinsic::loongarch_lsx_vbitset_w: +- case Intrinsic::loongarch_lsx_vbitset_d: +- case Intrinsic::loongarch_lasx_xvbitset_b: +- case Intrinsic::loongarch_lasx_xvbitset_h: +- case Intrinsic::loongarch_lasx_xvbitset_w: +- case Intrinsic::loongarch_lasx_xvbitset_d: { +- EVT VecTy = N->getValueType(0); +- SDValue One = DAG.getConstant(1, DL, VecTy); +- return DAG.getNode( +- ISD::OR, DL, VecTy, N->getOperand(1), +- DAG.getNode(ISD::SHL, DL, VecTy, One, truncateVecElts(N, DAG))); +- } +- case Intrinsic::loongarch_lsx_vbitseti_b: +- case Intrinsic::loongarch_lasx_xvbitseti_b: +- return lowerVectorBitSetImm<3>(N, DAG); +- case Intrinsic::loongarch_lsx_vbitseti_h: +- case Intrinsic::loongarch_lasx_xvbitseti_h: +- return lowerVectorBitSetImm<4>(N, DAG); +- case Intrinsic::loongarch_lsx_vbitseti_w: +- case Intrinsic::loongarch_lasx_xvbitseti_w: +- return lowerVectorBitSetImm<5>(N, DAG); +- case Intrinsic::loongarch_lsx_vbitseti_d: +- case Intrinsic::loongarch_lasx_xvbitseti_d: +- return lowerVectorBitSetImm<6>(N, DAG); +- case Intrinsic::loongarch_lsx_vbitrev_b: +- case Intrinsic::loongarch_lsx_vbitrev_h: +- case Intrinsic::loongarch_lsx_vbitrev_w: +- case Intrinsic::loongarch_lsx_vbitrev_d: +- case Intrinsic::loongarch_lasx_xvbitrev_b: +- case Intrinsic::loongarch_lasx_xvbitrev_h: +- case Intrinsic::loongarch_lasx_xvbitrev_w: +- case Intrinsic::loongarch_lasx_xvbitrev_d: { +- EVT VecTy = N->getValueType(0); +- SDValue One = DAG.getConstant(1, DL, VecTy); +- return DAG.getNode( +- ISD::XOR, DL, VecTy, N->getOperand(1), +- DAG.getNode(ISD::SHL, DL, VecTy, One, truncateVecElts(N, DAG))); +- } +- case Intrinsic::loongarch_lsx_vbitrevi_b: +- case Intrinsic::loongarch_lasx_xvbitrevi_b: +- return lowerVectorBitRevImm<3>(N, DAG); +- case Intrinsic::loongarch_lsx_vbitrevi_h: +- case Intrinsic::loongarch_lasx_xvbitrevi_h: +- return lowerVectorBitRevImm<4>(N, DAG); +- case Intrinsic::loongarch_lsx_vbitrevi_w: +- case Intrinsic::loongarch_lasx_xvbitrevi_w: +- return lowerVectorBitRevImm<5>(N, DAG); +- case Intrinsic::loongarch_lsx_vbitrevi_d: +- case Intrinsic::loongarch_lasx_xvbitrevi_d: +- return lowerVectorBitRevImm<6>(N, DAG); +- case Intrinsic::loongarch_lsx_vfadd_s: +- case Intrinsic::loongarch_lsx_vfadd_d: +- case Intrinsic::loongarch_lasx_xvfadd_s: +- case Intrinsic::loongarch_lasx_xvfadd_d: +- return DAG.getNode(ISD::FADD, DL, N->getValueType(0), N->getOperand(1), +- N->getOperand(2)); +- case Intrinsic::loongarch_lsx_vfsub_s: +- case Intrinsic::loongarch_lsx_vfsub_d: +- case Intrinsic::loongarch_lasx_xvfsub_s: +- case Intrinsic::loongarch_lasx_xvfsub_d: +- return DAG.getNode(ISD::FSUB, DL, N->getValueType(0), N->getOperand(1), +- N->getOperand(2)); +- case Intrinsic::loongarch_lsx_vfmul_s: +- case Intrinsic::loongarch_lsx_vfmul_d: +- case Intrinsic::loongarch_lasx_xvfmul_s: +- case Intrinsic::loongarch_lasx_xvfmul_d: +- return DAG.getNode(ISD::FMUL, DL, N->getValueType(0), N->getOperand(1), +- N->getOperand(2)); +- case Intrinsic::loongarch_lsx_vfdiv_s: +- case Intrinsic::loongarch_lsx_vfdiv_d: +- case Intrinsic::loongarch_lasx_xvfdiv_s: +- case Intrinsic::loongarch_lasx_xvfdiv_d: +- return DAG.getNode(ISD::FDIV, DL, N->getValueType(0), N->getOperand(1), +- N->getOperand(2)); +- case Intrinsic::loongarch_lsx_vfmadd_s: +- case Intrinsic::loongarch_lsx_vfmadd_d: +- case Intrinsic::loongarch_lasx_xvfmadd_s: +- case Intrinsic::loongarch_lasx_xvfmadd_d: +- return DAG.getNode(ISD::FMA, DL, N->getValueType(0), N->getOperand(1), +- N->getOperand(2), N->getOperand(3)); +- case Intrinsic::loongarch_lsx_vinsgr2vr_b: +- return DAG.getNode(ISD::INSERT_VECTOR_ELT, SDLoc(N), N->getValueType(0), +- N->getOperand(1), N->getOperand(2), +- legalizeIntrinsicImmArg<4>(N, 3, DAG, Subtarget)); +- case Intrinsic::loongarch_lsx_vinsgr2vr_h: +- case Intrinsic::loongarch_lasx_xvinsgr2vr_w: +- return DAG.getNode(ISD::INSERT_VECTOR_ELT, SDLoc(N), N->getValueType(0), +- N->getOperand(1), N->getOperand(2), +- legalizeIntrinsicImmArg<3>(N, 3, DAG, Subtarget)); +- case Intrinsic::loongarch_lsx_vinsgr2vr_w: +- case Intrinsic::loongarch_lasx_xvinsgr2vr_d: +- return DAG.getNode(ISD::INSERT_VECTOR_ELT, SDLoc(N), N->getValueType(0), +- N->getOperand(1), N->getOperand(2), +- legalizeIntrinsicImmArg<2>(N, 3, DAG, Subtarget)); +- case Intrinsic::loongarch_lsx_vinsgr2vr_d: +- return DAG.getNode(ISD::INSERT_VECTOR_ELT, SDLoc(N), N->getValueType(0), +- N->getOperand(1), N->getOperand(2), +- legalizeIntrinsicImmArg<1>(N, 3, DAG, Subtarget)); +- case Intrinsic::loongarch_lsx_vreplgr2vr_b: +- case Intrinsic::loongarch_lsx_vreplgr2vr_h: +- case Intrinsic::loongarch_lsx_vreplgr2vr_w: +- case Intrinsic::loongarch_lsx_vreplgr2vr_d: +- case Intrinsic::loongarch_lasx_xvreplgr2vr_b: +- case Intrinsic::loongarch_lasx_xvreplgr2vr_h: +- case Intrinsic::loongarch_lasx_xvreplgr2vr_w: +- case Intrinsic::loongarch_lasx_xvreplgr2vr_d: { +- EVT ResTy = N->getValueType(0); +- SmallVector Ops(ResTy.getVectorNumElements(), N->getOperand(1)); +- return DAG.getBuildVector(ResTy, DL, Ops); ++ ++ // Transform all store nodes into one single node because all store ++ // nodes are independent of each other. ++ if (!MemOpChains.empty()) ++ Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains); ++ ++ // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every ++ // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol ++ // node so that legalize doesn't hack it. ++ ++ bool GlobalOrExternal = false, IsCallReloc = false; ++ ++ if (GlobalAddressSDNode *G = dyn_cast(Callee)) { ++ Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, ++ getPointerTy(DAG.getDataLayout()), 0, ++ LoongArchII::MO_NO_FLAG); ++ GlobalOrExternal = true; + } +- case Intrinsic::loongarch_lsx_vreplve_b: +- case Intrinsic::loongarch_lsx_vreplve_h: +- case Intrinsic::loongarch_lsx_vreplve_w: +- case Intrinsic::loongarch_lsx_vreplve_d: +- case Intrinsic::loongarch_lasx_xvreplve_b: +- case Intrinsic::loongarch_lasx_xvreplve_h: +- case Intrinsic::loongarch_lasx_xvreplve_w: +- case Intrinsic::loongarch_lasx_xvreplve_d: +- return DAG.getNode(LoongArchISD::VREPLVE, DL, N->getValueType(0), +- N->getOperand(1), +- DAG.getNode(ISD::ANY_EXTEND, DL, Subtarget.getGRLenVT(), +- N->getOperand(2))); ++ else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) { ++ const char *Sym = S->getSymbol(); ++ Callee = DAG.getTargetExternalSymbol( ++ Sym, getPointerTy(DAG.getDataLayout()), LoongArchII::MO_NO_FLAG); ++ ++ GlobalOrExternal = true; + } +- return SDValue(); +-} + +-SDValue LoongArchTargetLowering::PerformDAGCombine(SDNode *N, +- DAGCombinerInfo &DCI) const { +- SelectionDAG &DAG = DCI.DAG; +- switch (N->getOpcode()) { +- default: +- break; +- case ISD::AND: +- return performANDCombine(N, DAG, DCI, Subtarget); +- case ISD::OR: +- return performORCombine(N, DAG, DCI, Subtarget); +- case ISD::SRL: +- return performSRLCombine(N, DAG, DCI, Subtarget); +- case LoongArchISD::BITREV_W: +- return performBITREV_WCombine(N, DAG, DCI, Subtarget); +- case ISD::INTRINSIC_WO_CHAIN: +- return performINTRINSIC_WO_CHAINCombine(N, DAG, DCI, Subtarget); ++ SmallVector Ops(1, Chain); ++ SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); ++ ++ getOpndList(Ops, RegsToPass, IsPIC, GlobalOrExternal, IsCallReloc, CLI, ++ Callee, Chain, IsTailCall); ++ ++ if (IsTailCall) { ++ MF.getFrameInfo().setHasTailCall(); ++ return DAG.getNode(LoongArchISD::TailCall, DL, MVT::Other, Ops); + } +- return SDValue(); ++ ++ Chain = DAG.getNode(LoongArchISD::JmpLink, DL, NodeTys, Ops); ++ DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge); ++ SDValue InFlag = Chain.getValue(1); ++ ++ // Create the CALLSEQ_END node in the case of where it is not a call to ++ // memcpy. ++ if (!(MemcpyInByVal)) { ++ Chain = DAG.getCALLSEQ_END(Chain, NextStackOffsetVal, ++ DAG.getIntPtrConstant(0, DL, true), InFlag, DL); ++ InFlag = Chain.getValue(1); ++ } ++ ++ // Handle result values, copying them out of physregs into vregs that we ++ // return. ++ return LowerCallResult(Chain, InFlag, CallConv, IsVarArg, Ins, DL, DAG, ++ InVals, CLI); + } + +-static MachineBasicBlock *insertDivByZeroTrap(MachineInstr &MI, +- MachineBasicBlock *MBB) { +- if (!ZeroDivCheck) +- return MBB; +- +- // Build instructions: +- // MBB: +- // div(or mod) $dst, $dividend, $divisor +- // bnez $divisor, SinkMBB +- // BreakMBB: +- // break 7 // BRK_DIVZERO +- // SinkMBB: +- // fallthrough +- const BasicBlock *LLVM_BB = MBB->getBasicBlock(); +- MachineFunction::iterator It = ++MBB->getIterator(); +- MachineFunction *MF = MBB->getParent(); +- auto BreakMBB = MF->CreateMachineBasicBlock(LLVM_BB); +- auto SinkMBB = MF->CreateMachineBasicBlock(LLVM_BB); +- MF->insert(It, BreakMBB); +- MF->insert(It, SinkMBB); +- +- // Transfer the remainder of MBB and its successor edges to SinkMBB. +- SinkMBB->splice(SinkMBB->end(), MBB, std::next(MI.getIterator()), MBB->end()); +- SinkMBB->transferSuccessorsAndUpdatePHIs(MBB); +- +- const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo(); +- DebugLoc DL = MI.getDebugLoc(); +- MachineOperand &Divisor = MI.getOperand(2); +- Register DivisorReg = Divisor.getReg(); ++/// LowerCallResult - Lower the result values of a call into the ++/// appropriate copies out of appropriate physical registers. ++SDValue LoongArchTargetLowering::LowerCallResult( ++ SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool IsVarArg, ++ const SmallVectorImpl &Ins, const SDLoc &DL, ++ SelectionDAG &DAG, SmallVectorImpl &InVals, ++ TargetLowering::CallLoweringInfo &CLI) const { ++ // Assign locations to each value returned by this call. ++ SmallVector RVLocs; ++ LoongArchCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs, ++ *DAG.getContext()); ++ ++ const ExternalSymbolSDNode *ES = ++ dyn_cast_or_null(CLI.Callee.getNode()); ++ CCInfo.AnalyzeCallResult(Ins, RetCC_LoongArch, CLI.RetTy, ++ ES ? ES->getSymbol() : nullptr); ++ ++ // Copy all of the result registers out of their specified physreg. ++ for (unsigned i = 0; i != RVLocs.size(); ++i) { ++ CCValAssign &VA = RVLocs[i]; ++ assert(VA.isRegLoc() && "Can only return in registers!"); + +- // MBB: +- BuildMI(MBB, DL, TII.get(LoongArch::BNEZ)) +- .addReg(DivisorReg, getKillRegState(Divisor.isKill())) +- .addMBB(SinkMBB); +- MBB->addSuccessor(BreakMBB); +- MBB->addSuccessor(SinkMBB); ++ SDValue Val = DAG.getCopyFromReg(Chain, DL, RVLocs[i].getLocReg(), ++ RVLocs[i].getLocVT(), InFlag); ++ Chain = Val.getValue(1); ++ InFlag = Val.getValue(2); ++ ++ if (VA.isUpperBitsInLoc()) { ++ unsigned ValSizeInBits = Ins[i].ArgVT.getSizeInBits(); ++ unsigned LocSizeInBits = VA.getLocVT().getSizeInBits(); ++ unsigned Shift = ++ VA.getLocInfo() == CCValAssign::ZExtUpper ? ISD::SRL : ISD::SRA; ++ Val = DAG.getNode( ++ Shift, DL, VA.getLocVT(), Val, ++ DAG.getConstant(LocSizeInBits - ValSizeInBits, DL, VA.getLocVT())); ++ } + +- // BreakMBB: +- // See linux header file arch/loongarch/include/uapi/asm/break.h for the +- // definition of BRK_DIVZERO. +- BuildMI(BreakMBB, DL, TII.get(LoongArch::BREAK)).addImm(7 /*BRK_DIVZERO*/); +- BreakMBB->addSuccessor(SinkMBB); ++ switch (VA.getLocInfo()) { ++ default: ++ llvm_unreachable("Unknown loc info!"); ++ case CCValAssign::Full: ++ break; ++ case CCValAssign::BCvt: ++ Val = DAG.getNode(ISD::BITCAST, DL, VA.getValVT(), Val); ++ break; ++ case CCValAssign::AExt: ++ case CCValAssign::AExtUpper: ++ Val = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Val); ++ break; ++ case CCValAssign::ZExt: ++ case CCValAssign::ZExtUpper: ++ Val = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), Val, ++ DAG.getValueType(VA.getValVT())); ++ Val = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Val); ++ break; ++ case CCValAssign::SExt: ++ case CCValAssign::SExtUpper: ++ Val = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), Val, ++ DAG.getValueType(VA.getValVT())); ++ Val = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Val); ++ break; ++ } + +- // Clear Divisor's kill flag. +- Divisor.setIsKill(false); ++ InVals.push_back(Val); ++ } + +- return SinkMBB; ++ return Chain; + } + +-static MachineBasicBlock * +-emitVecCondBranchPseudo(MachineInstr &MI, MachineBasicBlock *BB, +- const LoongArchSubtarget &Subtarget) { +- unsigned CondOpc; +- switch (MI.getOpcode()) { ++static SDValue UnpackFromArgumentSlot(SDValue Val, const CCValAssign &VA, ++ EVT ArgVT, const SDLoc &DL, ++ SelectionDAG &DAG) { ++ MVT LocVT = VA.getLocVT(); ++ EVT ValVT = VA.getValVT(); ++ ++ // Shift into the upper bits if necessary. ++ switch (VA.getLocInfo()) { + default: +- llvm_unreachable("Unexpected opcode"); +- case LoongArch::PseudoVBZ: +- CondOpc = LoongArch::VSETEQZ_V; +- break; +- case LoongArch::PseudoVBZ_B: +- CondOpc = LoongArch::VSETANYEQZ_B; +- break; +- case LoongArch::PseudoVBZ_H: +- CondOpc = LoongArch::VSETANYEQZ_H; +- break; +- case LoongArch::PseudoVBZ_W: +- CondOpc = LoongArch::VSETANYEQZ_W; +- break; +- case LoongArch::PseudoVBZ_D: +- CondOpc = LoongArch::VSETANYEQZ_D; +- break; +- case LoongArch::PseudoVBNZ: +- CondOpc = LoongArch::VSETNEZ_V; +- break; +- case LoongArch::PseudoVBNZ_B: +- CondOpc = LoongArch::VSETALLNEZ_B; +- break; +- case LoongArch::PseudoVBNZ_H: +- CondOpc = LoongArch::VSETALLNEZ_H; +- break; +- case LoongArch::PseudoVBNZ_W: +- CondOpc = LoongArch::VSETALLNEZ_W; +- break; +- case LoongArch::PseudoVBNZ_D: +- CondOpc = LoongArch::VSETALLNEZ_D; +- break; +- case LoongArch::PseudoXVBZ: +- CondOpc = LoongArch::XVSETEQZ_V; +- break; +- case LoongArch::PseudoXVBZ_B: +- CondOpc = LoongArch::XVSETANYEQZ_B; +- break; +- case LoongArch::PseudoXVBZ_H: +- CondOpc = LoongArch::XVSETANYEQZ_H; + break; +- case LoongArch::PseudoXVBZ_W: +- CondOpc = LoongArch::XVSETANYEQZ_W; ++ case CCValAssign::AExtUpper: ++ case CCValAssign::SExtUpper: ++ case CCValAssign::ZExtUpper: { ++ unsigned ValSizeInBits = ArgVT.getSizeInBits(); ++ unsigned LocSizeInBits = VA.getLocVT().getSizeInBits(); ++ unsigned Opcode = ++ VA.getLocInfo() == CCValAssign::ZExtUpper ? ISD::SRL : ISD::SRA; ++ Val = DAG.getNode( ++ Opcode, DL, VA.getLocVT(), Val, ++ DAG.getConstant(LocSizeInBits - ValSizeInBits, DL, VA.getLocVT())); + break; +- case LoongArch::PseudoXVBZ_D: +- CondOpc = LoongArch::XVSETANYEQZ_D; +- break; +- case LoongArch::PseudoXVBNZ: +- CondOpc = LoongArch::XVSETNEZ_V; ++ } ++ } ++ ++ // If this is an value smaller than the argument slot size (32-bit for LP32, ++ // 64-bit for LPX32/LP64), it has been promoted in some way to the argument slot ++ // size. Extract the value and insert any appropriate assertions regarding ++ // sign/zero extension. ++ switch (VA.getLocInfo()) { ++ default: ++ llvm_unreachable("Unknown loc info!"); ++ case CCValAssign::Full: + break; +- case LoongArch::PseudoXVBNZ_B: +- CondOpc = LoongArch::XVSETALLNEZ_B; ++ case CCValAssign::AExtUpper: ++ case CCValAssign::AExt: ++ Val = DAG.getNode(ISD::TRUNCATE, DL, ValVT, Val); + break; +- case LoongArch::PseudoXVBNZ_H: +- CondOpc = LoongArch::XVSETALLNEZ_H; ++ case CCValAssign::SExtUpper: ++ case CCValAssign::SExt: { ++ if ((ArgVT == MVT::i1) || (ArgVT == MVT::i8) || (ArgVT == MVT::i16)) { ++ SDValue SubReg = DAG.getTargetConstant(LoongArch::sub_32, DL, MVT::i32); ++ Val = SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, ValVT, ++ Val, SubReg), ++ 0); ++ } else { ++ Val = ++ DAG.getNode(ISD::AssertSext, DL, LocVT, Val, DAG.getValueType(ValVT)); ++ Val = DAG.getNode(ISD::TRUNCATE, DL, ValVT, Val); ++ } + break; +- case LoongArch::PseudoXVBNZ_W: +- CondOpc = LoongArch::XVSETALLNEZ_W; ++ } ++ case CCValAssign::ZExtUpper: ++ case CCValAssign::ZExt: ++ Val = DAG.getNode(ISD::AssertZext, DL, LocVT, Val, DAG.getValueType(ValVT)); ++ Val = DAG.getNode(ISD::TRUNCATE, DL, ValVT, Val); + break; +- case LoongArch::PseudoXVBNZ_D: +- CondOpc = LoongArch::XVSETALLNEZ_D; ++ case CCValAssign::BCvt: ++ Val = DAG.getNode(ISD::BITCAST, DL, ValVT, Val); + break; + } + +- const TargetInstrInfo *TII = Subtarget.getInstrInfo(); +- const BasicBlock *LLVM_BB = BB->getBasicBlock(); +- DebugLoc DL = MI.getDebugLoc(); +- MachineRegisterInfo &MRI = BB->getParent()->getRegInfo(); +- MachineFunction::iterator It = ++BB->getIterator(); ++ return Val; ++} + +- MachineFunction *F = BB->getParent(); +- MachineBasicBlock *FalseBB = F->CreateMachineBasicBlock(LLVM_BB); +- MachineBasicBlock *TrueBB = F->CreateMachineBasicBlock(LLVM_BB); +- MachineBasicBlock *SinkBB = F->CreateMachineBasicBlock(LLVM_BB); +- +- F->insert(It, FalseBB); +- F->insert(It, TrueBB); +- F->insert(It, SinkBB); +- +- // Transfer the remainder of MBB and its successor edges to Sink. +- SinkBB->splice(SinkBB->end(), BB, std::next(MI.getIterator()), BB->end()); +- SinkBB->transferSuccessorsAndUpdatePHIs(BB); +- +- // Insert the real instruction to BB. +- Register FCC = MRI.createVirtualRegister(&LoongArch::CFRRegClass); +- BuildMI(BB, DL, TII->get(CondOpc), FCC).addReg(MI.getOperand(1).getReg()); +- +- // Insert branch. +- BuildMI(BB, DL, TII->get(LoongArch::BCNEZ)).addReg(FCC).addMBB(TrueBB); +- BB->addSuccessor(FalseBB); +- BB->addSuccessor(TrueBB); +- +- // FalseBB. +- Register RD1 = MRI.createVirtualRegister(&LoongArch::GPRRegClass); +- BuildMI(FalseBB, DL, TII->get(LoongArch::ADDI_W), RD1) +- .addReg(LoongArch::R0) +- .addImm(0); +- BuildMI(FalseBB, DL, TII->get(LoongArch::PseudoBR)).addMBB(SinkBB); +- FalseBB->addSuccessor(SinkBB); ++//===----------------------------------------------------------------------===// ++// Formal Arguments Calling Convention Implementation ++//===----------------------------------------------------------------------===// ++/// LowerFormalArguments - transform physical registers into virtual registers ++/// and generate load operations for arguments places on the stack. ++SDValue LoongArchTargetLowering::LowerFormalArguments( ++ SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, ++ const SmallVectorImpl &Ins, const SDLoc &DL, ++ SelectionDAG &DAG, SmallVectorImpl &InVals) const { ++ MachineFunction &MF = DAG.getMachineFunction(); ++ MachineFrameInfo &MFI = MF.getFrameInfo(); ++ LoongArchFunctionInfo *LoongArchFI = MF.getInfo(); + +- // TrueBB. +- Register RD2 = MRI.createVirtualRegister(&LoongArch::GPRRegClass); +- BuildMI(TrueBB, DL, TII->get(LoongArch::ADDI_W), RD2) +- .addReg(LoongArch::R0) +- .addImm(1); +- TrueBB->addSuccessor(SinkBB); ++ LoongArchFI->setVarArgsFrameIndex(0); + +- // SinkBB: merge the results. +- BuildMI(*SinkBB, SinkBB->begin(), DL, TII->get(LoongArch::PHI), +- MI.getOperand(0).getReg()) +- .addReg(RD1) +- .addMBB(FalseBB) +- .addReg(RD2) +- .addMBB(TrueBB); ++ // Used with vargs to acumulate store chains. ++ std::vector OutChains; + +- // The pseudo instruction is gone now. +- MI.eraseFromParent(); +- return SinkBB; +-} ++ // Assign locations to all of the incoming arguments. ++ SmallVector ArgLocs; ++ LoongArchCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs, ++ *DAG.getContext()); ++ const Function &Func = DAG.getMachineFunction().getFunction(); ++ Function::const_arg_iterator FuncArg = Func.arg_begin(); + +-static MachineBasicBlock * +-emitPseudoXVINSGR2VR(MachineInstr &MI, MachineBasicBlock *BB, +- const LoongArchSubtarget &Subtarget) { +- unsigned InsOp; +- unsigned HalfSize; +- switch (MI.getOpcode()) { +- default: +- llvm_unreachable("Unexpected opcode"); +- case LoongArch::PseudoXVINSGR2VR_B: +- HalfSize = 16; +- InsOp = LoongArch::VINSGR2VR_B; +- break; +- case LoongArch::PseudoXVINSGR2VR_H: +- HalfSize = 8; +- InsOp = LoongArch::VINSGR2VR_H; +- break; +- } +- const TargetInstrInfo *TII = Subtarget.getInstrInfo(); +- const TargetRegisterClass *RC = &LoongArch::LASX256RegClass; +- const TargetRegisterClass *SubRC = &LoongArch::LSX128RegClass; +- DebugLoc DL = MI.getDebugLoc(); +- MachineRegisterInfo &MRI = BB->getParent()->getRegInfo(); +- // XDst = vector_insert XSrc, Elt, Idx +- Register XDst = MI.getOperand(0).getReg(); +- Register XSrc = MI.getOperand(1).getReg(); +- Register Elt = MI.getOperand(2).getReg(); +- unsigned Idx = MI.getOperand(3).getImm(); +- +- Register ScratchReg1 = XSrc; +- if (Idx >= HalfSize) { +- ScratchReg1 = MRI.createVirtualRegister(RC); +- BuildMI(*BB, MI, DL, TII->get(LoongArch::XVPERMI_Q), ScratchReg1) +- .addReg(XSrc) +- .addReg(XSrc) +- .addImm(1); +- } ++ CCInfo.AnalyzeFormalArguments(Ins, CC_LoongArch_FixedArg); ++ LoongArchFI->setFormalArgInfo(CCInfo.getStackSize(), ++ CCInfo.getInRegsParamsCount() > 0); ++ ++ unsigned CurArgIdx = 0; ++ CCInfo.rewindByValRegsInfo(); ++ ++ for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { ++ CCValAssign &VA = ArgLocs[i]; ++ if (Ins[i].isOrigArg()) { ++ std::advance(FuncArg, Ins[i].getOrigArgIndex() - CurArgIdx); ++ CurArgIdx = Ins[i].getOrigArgIndex(); ++ } ++ EVT ValVT = VA.getValVT(); ++ ISD::ArgFlagsTy Flags = Ins[i].Flags; ++ bool IsRegLoc = VA.isRegLoc(); ++ ++ if (Flags.isByVal()) { ++ assert(Ins[i].isOrigArg() && "Byval arguments cannot be implicit"); ++ unsigned FirstByValReg, LastByValReg; ++ unsigned ByValIdx = CCInfo.getInRegsParamsProcessed(); ++ CCInfo.getInRegsParamInfo(ByValIdx, FirstByValReg, LastByValReg); ++ ++ assert(Flags.getByValSize() && ++ "ByVal args of size 0 should have been ignored by front-end."); ++ assert(ByValIdx < CCInfo.getInRegsParamsCount()); ++ copyByValRegs(Chain, DL, OutChains, DAG, Flags, InVals, &*FuncArg, ++ FirstByValReg, LastByValReg, VA, CCInfo); ++ CCInfo.nextInRegsParam(); ++ continue; ++ } + +- Register ScratchSubReg1 = MRI.createVirtualRegister(SubRC); +- Register ScratchSubReg2 = MRI.createVirtualRegister(SubRC); +- BuildMI(*BB, MI, DL, TII->get(LoongArch::COPY), ScratchSubReg1) +- .addReg(ScratchReg1, 0, LoongArch::sub_128); +- BuildMI(*BB, MI, DL, TII->get(InsOp), ScratchSubReg2) +- .addReg(ScratchSubReg1) +- .addReg(Elt) +- .addImm(Idx >= HalfSize ? Idx - HalfSize : Idx); ++ // Arguments stored on registers ++ if (IsRegLoc) { ++ MVT RegVT = VA.getLocVT(); ++ unsigned ArgReg = VA.getLocReg(); ++ const TargetRegisterClass *RC = getRegClassFor(RegVT); ++ ++ // Transform the arguments stored on ++ // physical registers into virtual ones ++ unsigned Reg = addLiveIn(DAG.getMachineFunction(), ArgReg, RC); ++ SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, RegVT); ++ ++ ArgValue = UnpackFromArgumentSlot(ArgValue, VA, Ins[i].ArgVT, DL, DAG); ++ ++ // Handle floating point arguments passed in integer registers and ++ // long double arguments passed in floating point registers. ++ if ((RegVT == MVT::i32 && ValVT == MVT::f32) || ++ (RegVT == MVT::i64 && ValVT == MVT::f64) || ++ (RegVT == MVT::f64 && ValVT == MVT::i64)) ++ ArgValue = DAG.getNode(ISD::BITCAST, DL, ValVT, ArgValue); ++ else if (ABI.IsLP32() && RegVT == MVT::i32 && ++ ValVT == MVT::f64) { ++ // TODO: lp32 ++ } + +- Register ScratchReg2 = XDst; +- if (Idx >= HalfSize) +- ScratchReg2 = MRI.createVirtualRegister(RC); ++ InVals.push_back(ArgValue); ++ } else { // VA.isRegLoc() ++ MVT LocVT = VA.getLocVT(); ++ ++ if (ABI.IsLP32()) { ++ // We ought to be able to use LocVT directly but LP32 sets it to i32 ++ // when allocating floating point values to integer registers. ++ // This shouldn't influence how we load the value into registers unless ++ // we are targeting softfloat. ++ if (VA.getValVT().isFloatingPoint() && !Subtarget.useSoftFloat()) ++ LocVT = VA.getValVT(); ++ } + +- BuildMI(*BB, MI, DL, TII->get(LoongArch::SUBREG_TO_REG), ScratchReg2) +- .addImm(0) +- .addReg(ScratchSubReg2) +- .addImm(LoongArch::sub_128); ++ // sanity check ++ assert(VA.isMemLoc()); + +- if (Idx >= HalfSize) +- BuildMI(*BB, MI, DL, TII->get(LoongArch::XVPERMI_Q), XDst) +- .addReg(XSrc) +- .addReg(ScratchReg2) +- .addImm(2); ++ // The stack pointer offset is relative to the caller stack frame. ++ int FI = MFI.CreateFixedObject(LocVT.getSizeInBits() / 8, ++ VA.getLocMemOffset(), true); + +- MI.eraseFromParent(); +- return BB; +-} ++ // Create load nodes to retrieve arguments from the stack ++ SDValue FIN = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout())); ++ SDValue ArgValue = DAG.getLoad( ++ LocVT, DL, Chain, FIN, ++ MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI)); ++ OutChains.push_back(ArgValue.getValue(1)); + +-MachineBasicBlock *LoongArchTargetLowering::EmitInstrWithCustomInserter( +- MachineInstr &MI, MachineBasicBlock *BB) const { +- const TargetInstrInfo *TII = Subtarget.getInstrInfo(); +- DebugLoc DL = MI.getDebugLoc(); ++ ArgValue = UnpackFromArgumentSlot(ArgValue, VA, Ins[i].ArgVT, DL, DAG); + +- switch (MI.getOpcode()) { +- default: +- llvm_unreachable("Unexpected instr type to insert"); +- case LoongArch::DIV_W: +- case LoongArch::DIV_WU: +- case LoongArch::MOD_W: +- case LoongArch::MOD_WU: +- case LoongArch::DIV_D: +- case LoongArch::DIV_DU: +- case LoongArch::MOD_D: +- case LoongArch::MOD_DU: +- return insertDivByZeroTrap(MI, BB); +- break; +- case LoongArch::WRFCSR: { +- BuildMI(*BB, MI, DL, TII->get(LoongArch::MOVGR2FCSR), +- LoongArch::FCSR0 + MI.getOperand(0).getImm()) +- .addReg(MI.getOperand(1).getReg()); +- MI.eraseFromParent(); +- return BB; ++ InVals.push_back(ArgValue); ++ } + } +- case LoongArch::RDFCSR: { +- MachineInstr *ReadFCSR = +- BuildMI(*BB, MI, DL, TII->get(LoongArch::MOVFCSR2GR), +- MI.getOperand(0).getReg()) +- .addReg(LoongArch::FCSR0 + MI.getOperand(1).getImm()); +- ReadFCSR->getOperand(1).setIsUndef(); +- MI.eraseFromParent(); +- return BB; ++ ++ for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { ++ // The loongarch ABIs for returning structs by value requires that we copy ++ // the sret argument into $v0 for the return. Save the argument into ++ // a virtual register so that we can access it from the return points. ++ if (Ins[i].Flags.isSRet()) { ++ unsigned Reg = LoongArchFI->getSRetReturnReg(); ++ if (!Reg) { ++ Reg = MF.getRegInfo().createVirtualRegister( ++ getRegClassFor(ABI.IsLP64() ? MVT::i64 : MVT::i32)); ++ LoongArchFI->setSRetReturnReg(Reg); ++ } ++ SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), DL, Reg, InVals[i]); ++ Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Copy, Chain); ++ break; ++ } + } +- case LoongArch::PseudoVBZ: +- case LoongArch::PseudoVBZ_B: +- case LoongArch::PseudoVBZ_H: +- case LoongArch::PseudoVBZ_W: +- case LoongArch::PseudoVBZ_D: +- case LoongArch::PseudoVBNZ: +- case LoongArch::PseudoVBNZ_B: +- case LoongArch::PseudoVBNZ_H: +- case LoongArch::PseudoVBNZ_W: +- case LoongArch::PseudoVBNZ_D: +- case LoongArch::PseudoXVBZ: +- case LoongArch::PseudoXVBZ_B: +- case LoongArch::PseudoXVBZ_H: +- case LoongArch::PseudoXVBZ_W: +- case LoongArch::PseudoXVBZ_D: +- case LoongArch::PseudoXVBNZ: +- case LoongArch::PseudoXVBNZ_B: +- case LoongArch::PseudoXVBNZ_H: +- case LoongArch::PseudoXVBNZ_W: +- case LoongArch::PseudoXVBNZ_D: +- return emitVecCondBranchPseudo(MI, BB, Subtarget); +- case LoongArch::PseudoXVINSGR2VR_B: +- case LoongArch::PseudoXVINSGR2VR_H: +- return emitPseudoXVINSGR2VR(MI, BB, Subtarget); ++ ++ if (IsVarArg) ++ writeVarArgRegs(OutChains, Chain, DL, DAG, CCInfo); ++ ++ // All stores are grouped in one node to allow the matching between ++ // the size of Ins and InVals. This only happens when on varg functions ++ if (!OutChains.empty()) { ++ OutChains.push_back(Chain); ++ Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains); + } ++ ++ return Chain; + } + +-bool LoongArchTargetLowering::allowsMisalignedMemoryAccesses( +- EVT VT, unsigned AddrSpace, Align Alignment, MachineMemOperand::Flags Flags, +- unsigned *Fast) const { +- if (!Subtarget.hasUAL()) +- return false; ++//===----------------------------------------------------------------------===// ++// Return Value Calling Convention Implementation ++//===----------------------------------------------------------------------===// + +- // TODO: set reasonable speed number. +- if (Fast) +- *Fast = 1; +- return true; ++bool ++LoongArchTargetLowering::CanLowerReturn(CallingConv::ID CallConv, ++ MachineFunction &MF, bool IsVarArg, ++ const SmallVectorImpl &Outs, ++ LLVMContext &Context) const { ++ SmallVector RVLocs; ++ LoongArchCCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context); ++ return CCInfo.CheckReturn(Outs, RetCC_LoongArch); + } + +-const char *LoongArchTargetLowering::getTargetNodeName(unsigned Opcode) const { +- switch ((LoongArchISD::NodeType)Opcode) { +- case LoongArchISD::FIRST_NUMBER: +- break; ++bool ++LoongArchTargetLowering::shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const { ++ if ((ABI.IsLPX32() || ABI.IsLP64()) && Type == MVT::i32) ++ return true; + +-#define NODE_NAME_CASE(node) \ +- case LoongArchISD::node: \ +- return "LoongArchISD::" #node; +- +- // TODO: Add more target-dependent nodes later. +- NODE_NAME_CASE(CALL) +- NODE_NAME_CASE(CALL_MEDIUM) +- NODE_NAME_CASE(CALL_LARGE) +- NODE_NAME_CASE(RET) +- NODE_NAME_CASE(TAIL) +- NODE_NAME_CASE(TAIL_MEDIUM) +- NODE_NAME_CASE(TAIL_LARGE) +- NODE_NAME_CASE(SLL_W) +- NODE_NAME_CASE(SRA_W) +- NODE_NAME_CASE(SRL_W) +- NODE_NAME_CASE(BSTRINS) +- NODE_NAME_CASE(BSTRPICK) +- NODE_NAME_CASE(MOVGR2FR_W_LA64) +- NODE_NAME_CASE(MOVFR2GR_S_LA64) +- NODE_NAME_CASE(FTINT) +- NODE_NAME_CASE(REVB_2H) +- NODE_NAME_CASE(REVB_2W) +- NODE_NAME_CASE(BITREV_4B) +- NODE_NAME_CASE(BITREV_W) +- NODE_NAME_CASE(ROTR_W) +- NODE_NAME_CASE(ROTL_W) +- NODE_NAME_CASE(CLZ_W) +- NODE_NAME_CASE(CTZ_W) +- NODE_NAME_CASE(DBAR) +- NODE_NAME_CASE(IBAR) +- NODE_NAME_CASE(BREAK) +- NODE_NAME_CASE(SYSCALL) +- NODE_NAME_CASE(CRC_W_B_W) +- NODE_NAME_CASE(CRC_W_H_W) +- NODE_NAME_CASE(CRC_W_W_W) +- NODE_NAME_CASE(CRC_W_D_W) +- NODE_NAME_CASE(CRCC_W_B_W) +- NODE_NAME_CASE(CRCC_W_H_W) +- NODE_NAME_CASE(CRCC_W_W_W) +- NODE_NAME_CASE(CRCC_W_D_W) +- NODE_NAME_CASE(CSRRD) +- NODE_NAME_CASE(CSRWR) +- NODE_NAME_CASE(CSRXCHG) +- NODE_NAME_CASE(IOCSRRD_B) +- NODE_NAME_CASE(IOCSRRD_H) +- NODE_NAME_CASE(IOCSRRD_W) +- NODE_NAME_CASE(IOCSRRD_D) +- NODE_NAME_CASE(IOCSRWR_B) +- NODE_NAME_CASE(IOCSRWR_H) +- NODE_NAME_CASE(IOCSRWR_W) +- NODE_NAME_CASE(IOCSRWR_D) +- NODE_NAME_CASE(CPUCFG) +- NODE_NAME_CASE(MOVGR2FCSR) +- NODE_NAME_CASE(MOVFCSR2GR) +- NODE_NAME_CASE(CACOP_D) +- NODE_NAME_CASE(CACOP_W) +- NODE_NAME_CASE(VPICK_SEXT_ELT) +- NODE_NAME_CASE(VPICK_ZEXT_ELT) +- NODE_NAME_CASE(VREPLVE) +- NODE_NAME_CASE(VALL_ZERO) +- NODE_NAME_CASE(VANY_ZERO) +- NODE_NAME_CASE(VALL_NONZERO) +- NODE_NAME_CASE(VANY_NONZERO) +- } +-#undef NODE_NAME_CASE +- return nullptr; ++ return IsSigned; + } + +-//===----------------------------------------------------------------------===// +-// Calling Convention Implementation +-//===----------------------------------------------------------------------===// ++SDValue ++LoongArchTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, ++ bool IsVarArg, ++ const SmallVectorImpl &Outs, ++ const SmallVectorImpl &OutVals, ++ const SDLoc &DL, SelectionDAG &DAG) const { ++ // CCValAssign - represent the assignment of ++ // the return value to a location ++ SmallVector RVLocs; ++ MachineFunction &MF = DAG.getMachineFunction(); + +-// Eight general-purpose registers a0-a7 used for passing integer arguments, +-// with a0-a1 reused to return values. Generally, the GPRs are used to pass +-// fixed-point arguments, and floating-point arguments when no FPR is available +-// or with soft float ABI. +-const MCPhysReg ArgGPRs[] = {LoongArch::R4, LoongArch::R5, LoongArch::R6, +- LoongArch::R7, LoongArch::R8, LoongArch::R9, +- LoongArch::R10, LoongArch::R11}; +-// Eight floating-point registers fa0-fa7 used for passing floating-point +-// arguments, and fa0-fa1 are also used to return values. +-const MCPhysReg ArgFPR32s[] = {LoongArch::F0, LoongArch::F1, LoongArch::F2, +- LoongArch::F3, LoongArch::F4, LoongArch::F5, +- LoongArch::F6, LoongArch::F7}; +-// FPR32 and FPR64 alias each other. +-const MCPhysReg ArgFPR64s[] = { +- LoongArch::F0_64, LoongArch::F1_64, LoongArch::F2_64, LoongArch::F3_64, +- LoongArch::F4_64, LoongArch::F5_64, LoongArch::F6_64, LoongArch::F7_64}; +- +-const MCPhysReg ArgVRs[] = {LoongArch::VR0, LoongArch::VR1, LoongArch::VR2, +- LoongArch::VR3, LoongArch::VR4, LoongArch::VR5, +- LoongArch::VR6, LoongArch::VR7}; +- +-const MCPhysReg ArgXRs[] = {LoongArch::XR0, LoongArch::XR1, LoongArch::XR2, +- LoongArch::XR3, LoongArch::XR4, LoongArch::XR5, +- LoongArch::XR6, LoongArch::XR7}; +- +-// Pass a 2*GRLen argument that has been split into two GRLen values through +-// registers or the stack as necessary. +-static bool CC_LoongArchAssign2GRLen(unsigned GRLen, CCState &State, +- CCValAssign VA1, ISD::ArgFlagsTy ArgFlags1, +- unsigned ValNo2, MVT ValVT2, MVT LocVT2, +- ISD::ArgFlagsTy ArgFlags2) { +- unsigned GRLenInBytes = GRLen / 8; +- if (Register Reg = State.AllocateReg(ArgGPRs)) { +- // At least one half can be passed via register. +- State.addLoc(CCValAssign::getReg(VA1.getValNo(), VA1.getValVT(), Reg, +- VA1.getLocVT(), CCValAssign::Full)); +- } else { +- // Both halves must be passed on the stack, with proper alignment. +- Align StackAlign = +- std::max(Align(GRLenInBytes), ArgFlags1.getNonZeroOrigAlign()); +- State.addLoc( +- CCValAssign::getMem(VA1.getValNo(), VA1.getValVT(), +- State.AllocateStack(GRLenInBytes, StackAlign), +- VA1.getLocVT(), CCValAssign::Full)); +- State.addLoc(CCValAssign::getMem( +- ValNo2, ValVT2, State.AllocateStack(GRLenInBytes, Align(GRLenInBytes)), +- LocVT2, CCValAssign::Full)); +- return false; +- } +- if (Register Reg = State.AllocateReg(ArgGPRs)) { +- // The second half can also be passed via register. +- State.addLoc( +- CCValAssign::getReg(ValNo2, ValVT2, Reg, LocVT2, CCValAssign::Full)); +- } else { +- // The second half is passed via the stack, without additional alignment. +- State.addLoc(CCValAssign::getMem( +- ValNo2, ValVT2, State.AllocateStack(GRLenInBytes, Align(GRLenInBytes)), +- LocVT2, CCValAssign::Full)); +- } +- return false; +-} ++ // CCState - Info about the registers and stack slot. ++ LoongArchCCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext()); + +-// Implements the LoongArch calling convention. Returns true upon failure. +-static bool CC_LoongArch(const DataLayout &DL, LoongArchABI::ABI ABI, +- unsigned ValNo, MVT ValVT, +- CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, +- CCState &State, bool IsFixed, bool IsRet, +- Type *OrigTy) { +- unsigned GRLen = DL.getLargestLegalIntTypeSizeInBits(); +- assert((GRLen == 32 || GRLen == 64) && "Unspport GRLen"); +- MVT GRLenVT = GRLen == 32 ? MVT::i32 : MVT::i64; +- MVT LocVT = ValVT; +- +- // Any return value split into more than two values can't be returned +- // directly. +- if (IsRet && ValNo > 1) +- return true; ++ // Analyze return values. ++ CCInfo.AnalyzeReturn(Outs, RetCC_LoongArch); + +- // If passing a variadic argument, or if no FPR is available. +- bool UseGPRForFloat = true; ++ SDValue Flag; ++ SmallVector RetOps(1, Chain); + +- switch (ABI) { +- default: +- llvm_unreachable("Unexpected ABI"); +- case LoongArchABI::ABI_ILP32S: +- case LoongArchABI::ABI_ILP32F: +- case LoongArchABI::ABI_LP64F: +- report_fatal_error("Unimplemented ABI"); +- break; +- case LoongArchABI::ABI_ILP32D: +- case LoongArchABI::ABI_LP64D: +- UseGPRForFloat = !IsFixed; +- break; +- case LoongArchABI::ABI_LP64S: +- break; +- } ++ // Copy the result values into the output registers. ++ for (unsigned i = 0; i != RVLocs.size(); ++i) { ++ SDValue Val = OutVals[i]; ++ CCValAssign &VA = RVLocs[i]; ++ assert(VA.isRegLoc() && "Can only return in registers!"); ++ bool UseUpperBits = false; + +- // FPR32 and FPR64 alias each other. +- if (State.getFirstUnallocated(ArgFPR32s) == std::size(ArgFPR32s)) +- UseGPRForFloat = true; +- +- if (UseGPRForFloat && ValVT == MVT::f32) { +- LocVT = GRLenVT; +- LocInfo = CCValAssign::BCvt; +- } else if (UseGPRForFloat && GRLen == 64 && ValVT == MVT::f64) { +- LocVT = MVT::i64; +- LocInfo = CCValAssign::BCvt; +- } else if (UseGPRForFloat && GRLen == 32 && ValVT == MVT::f64) { +- // TODO: Handle passing f64 on LA32 with D feature. +- report_fatal_error("Passing f64 with GPR on LA32 is undefined"); +- } +- +- // If this is a variadic argument, the LoongArch calling convention requires +- // that it is assigned an 'even' or 'aligned' register if it has (2*GRLen)/8 +- // byte alignment. An aligned register should be used regardless of whether +- // the original argument was split during legalisation or not. The argument +- // will not be passed by registers if the original type is larger than +- // 2*GRLen, so the register alignment rule does not apply. +- unsigned TwoGRLenInBytes = (2 * GRLen) / 8; +- if (!IsFixed && ArgFlags.getNonZeroOrigAlign() == TwoGRLenInBytes && +- DL.getTypeAllocSize(OrigTy) == TwoGRLenInBytes) { +- unsigned RegIdx = State.getFirstUnallocated(ArgGPRs); +- // Skip 'odd' register if necessary. +- if (RegIdx != std::size(ArgGPRs) && RegIdx % 2 == 1) +- State.AllocateReg(ArgGPRs); +- } +- +- SmallVectorImpl &PendingLocs = State.getPendingLocs(); +- SmallVectorImpl &PendingArgFlags = +- State.getPendingArgFlags(); +- +- assert(PendingLocs.size() == PendingArgFlags.size() && +- "PendingLocs and PendingArgFlags out of sync"); +- +- // Split arguments might be passed indirectly, so keep track of the pending +- // values. +- if (ValVT.isScalarInteger() && (ArgFlags.isSplit() || !PendingLocs.empty())) { +- LocVT = GRLenVT; +- LocInfo = CCValAssign::Indirect; +- PendingLocs.push_back( +- CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo)); +- PendingArgFlags.push_back(ArgFlags); +- if (!ArgFlags.isSplitEnd()) { +- return false; ++ switch (VA.getLocInfo()) { ++ default: ++ llvm_unreachable("Unknown loc info!"); ++ case CCValAssign::Full: ++ break; ++ case CCValAssign::BCvt: ++ Val = DAG.getNode(ISD::BITCAST, DL, VA.getLocVT(), Val); ++ break; ++ case CCValAssign::AExtUpper: ++ UseUpperBits = true; ++ LLVM_FALLTHROUGH; ++ case CCValAssign::AExt: ++ Val = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Val); ++ break; ++ case CCValAssign::ZExtUpper: ++ UseUpperBits = true; ++ LLVM_FALLTHROUGH; ++ case CCValAssign::ZExt: ++ Val = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Val); ++ break; ++ case CCValAssign::SExtUpper: ++ UseUpperBits = true; ++ LLVM_FALLTHROUGH; ++ case CCValAssign::SExt: ++ Val = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Val); ++ break; + } +- } + +- // If the split argument only had two elements, it should be passed directly +- // in registers or on the stack. +- if (ValVT.isScalarInteger() && ArgFlags.isSplitEnd() && +- PendingLocs.size() <= 2) { +- assert(PendingLocs.size() == 2 && "Unexpected PendingLocs.size()"); +- // Apply the normal calling convention rules to the first half of the +- // split argument. +- CCValAssign VA = PendingLocs[0]; +- ISD::ArgFlagsTy AF = PendingArgFlags[0]; +- PendingLocs.clear(); +- PendingArgFlags.clear(); +- return CC_LoongArchAssign2GRLen(GRLen, State, VA, AF, ValNo, ValVT, LocVT, +- ArgFlags); +- } +- +- // Allocate to a register if possible, or else a stack slot. +- Register Reg; +- unsigned StoreSizeBytes = GRLen / 8; +- Align StackAlign = Align(GRLen / 8); +- +- if (ValVT == MVT::f32 && !UseGPRForFloat) +- Reg = State.AllocateReg(ArgFPR32s); +- else if (ValVT == MVT::f64 && !UseGPRForFloat) +- Reg = State.AllocateReg(ArgFPR64s); +- else if (ValVT.is128BitVector()) +- Reg = State.AllocateReg(ArgVRs); +- else if (ValVT.is256BitVector()) +- Reg = State.AllocateReg(ArgXRs); +- else +- Reg = State.AllocateReg(ArgGPRs); +- +- unsigned StackOffset = +- Reg ? 0 : State.AllocateStack(StoreSizeBytes, StackAlign); +- +- // If we reach this point and PendingLocs is non-empty, we must be at the +- // end of a split argument that must be passed indirectly. +- if (!PendingLocs.empty()) { +- assert(ArgFlags.isSplitEnd() && "Expected ArgFlags.isSplitEnd()"); +- assert(PendingLocs.size() > 2 && "Unexpected PendingLocs.size()"); +- for (auto &It : PendingLocs) { +- if (Reg) +- It.convertToReg(Reg); +- else +- It.convertToMem(StackOffset); +- State.addLoc(It); ++ if (UseUpperBits) { ++ unsigned ValSizeInBits = Outs[i].ArgVT.getSizeInBits(); ++ unsigned LocSizeInBits = VA.getLocVT().getSizeInBits(); ++ Val = DAG.getNode( ++ ISD::SHL, DL, VA.getLocVT(), Val, ++ DAG.getConstant(LocSizeInBits - ValSizeInBits, DL, VA.getLocVT())); + } +- PendingLocs.clear(); +- PendingArgFlags.clear(); +- return false; +- } +- assert((!UseGPRForFloat || LocVT == GRLenVT) && +- "Expected an GRLenVT at this stage"); + +- if (Reg) { +- State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); +- return false; ++ Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Val, Flag); ++ ++ // Guarantee that all emitted copies are stuck together with flags. ++ Flag = Chain.getValue(1); ++ RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); + } + +- // When a floating-point value is passed on the stack, no bit-cast is needed. +- if (ValVT.isFloatingPoint()) { +- LocVT = ValVT; +- LocInfo = CCValAssign::Full; ++ // The loongarch ABIs for returning structs by value requires that we copy ++ // the sret argument into $v0 for the return. We saved the argument into ++ // a virtual register in the entry block, so now we copy the value out ++ // and into $v0. ++ if (MF.getFunction().hasStructRetAttr()) { ++ LoongArchFunctionInfo *LoongArchFI = MF.getInfo(); ++ unsigned Reg = LoongArchFI->getSRetReturnReg(); ++ ++ if (!Reg) ++ llvm_unreachable("sret virtual register not created in the entry block"); ++ SDValue Val = ++ DAG.getCopyFromReg(Chain, DL, Reg, getPointerTy(DAG.getDataLayout())); ++ unsigned A0 = ABI.IsLP64() ? LoongArch::A0_64 : LoongArch::A0; ++ ++ Chain = DAG.getCopyToReg(Chain, DL, A0, Val, Flag); ++ Flag = Chain.getValue(1); ++ RetOps.push_back(DAG.getRegister(A0, getPointerTy(DAG.getDataLayout()))); + } + +- State.addLoc(CCValAssign::getMem(ValNo, ValVT, StackOffset, LocVT, LocInfo)); +- return false; +-} ++ RetOps[0] = Chain; // Update chain. + +-void LoongArchTargetLowering::analyzeInputArgs( +- MachineFunction &MF, CCState &CCInfo, +- const SmallVectorImpl &Ins, bool IsRet, +- LoongArchCCAssignFn Fn) const { +- FunctionType *FType = MF.getFunction().getFunctionType(); +- for (unsigned i = 0, e = Ins.size(); i != e; ++i) { +- MVT ArgVT = Ins[i].VT; +- Type *ArgTy = nullptr; +- if (IsRet) +- ArgTy = FType->getReturnType(); +- else if (Ins[i].isOrigArg()) +- ArgTy = FType->getParamType(Ins[i].getOrigArgIndex()); +- LoongArchABI::ABI ABI = +- MF.getSubtarget().getTargetABI(); +- if (Fn(MF.getDataLayout(), ABI, i, ArgVT, CCValAssign::Full, Ins[i].Flags, +- CCInfo, /*IsFixed=*/true, IsRet, ArgTy)) { +- LLVM_DEBUG(dbgs() << "InputArg #" << i << " has unhandled type " << ArgVT +- << '\n'); +- llvm_unreachable(""); +- } +- } ++ // Add the flag if we have it. ++ if (Flag.getNode()) ++ RetOps.push_back(Flag); ++ ++ // Standard return on LoongArch is a "jr $ra" ++ return DAG.getNode(LoongArchISD::Ret, DL, MVT::Other, RetOps); + } + +-void LoongArchTargetLowering::analyzeOutputArgs( +- MachineFunction &MF, CCState &CCInfo, +- const SmallVectorImpl &Outs, bool IsRet, +- CallLoweringInfo *CLI, LoongArchCCAssignFn Fn) const { +- for (unsigned i = 0, e = Outs.size(); i != e; ++i) { +- MVT ArgVT = Outs[i].VT; +- Type *OrigTy = CLI ? CLI->getArgs()[Outs[i].OrigArgIndex].Ty : nullptr; +- LoongArchABI::ABI ABI = +- MF.getSubtarget().getTargetABI(); +- if (Fn(MF.getDataLayout(), ABI, i, ArgVT, CCValAssign::Full, Outs[i].Flags, +- CCInfo, Outs[i].IsFixed, IsRet, OrigTy)) { +- LLVM_DEBUG(dbgs() << "OutputArg #" << i << " has unhandled type " << ArgVT +- << "\n"); +- llvm_unreachable(""); ++//===----------------------------------------------------------------------===// ++// LoongArch Inline Assembly Support ++//===----------------------------------------------------------------------===// ++ ++/// getConstraintType - Given a constraint letter, return the type of ++/// constraint it is for this target. ++LoongArchTargetLowering::ConstraintType ++LoongArchTargetLowering::getConstraintType(StringRef Constraint) const { ++ // LoongArch specific constraints ++ // GCC config/loongarch/constraints.md ++ // ++ // 'f': Floating Point register ++ // 'G': Floating-point 0 ++ // 'l': Signed 16-bit constant ++ // 'R': Memory address that can be used in a non-macro load or store ++ // "ZC" Memory address with 16-bit and 4 bytes aligned offset ++ // "ZB" Memory address with 0 offset ++ ++ if (Constraint.size() == 1) { ++ switch (Constraint[0]) { ++ default : break; ++ case 'f': ++ return C_RegisterClass; ++ case 'l': ++ case 'G': ++#if 1 ++ return C_Other; ++#else ++// FIXME: return C_Immediate for l/G/I/J/K. How to test? ++ case 'I': ++ case 'J': ++ case 'K': ++ return C_Immediate; ++#endif ++ case 'R': ++ return C_Memory; + } + } ++ ++ if (Constraint == "ZC" || Constraint == "ZB") ++ return C_Memory; ++ ++ return TargetLowering::getConstraintType(Constraint); + } + +-// Convert Val to a ValVT. Should not be called for CCValAssign::Indirect +-// values. +-static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val, +- const CCValAssign &VA, const SDLoc &DL) { +- switch (VA.getLocInfo()) { ++/// Examine constraint type and operand type and determine a weight value. ++/// This object must already have been set up with the operand type ++/// and the current alternative constraint selected. ++TargetLowering::ConstraintWeight ++LoongArchTargetLowering::getSingleConstraintMatchWeight( ++ AsmOperandInfo &info, const char *constraint) const { ++ ConstraintWeight weight = CW_Invalid; ++ Value *CallOperandVal = info.CallOperandVal; ++ // If we don't have a value, we can't do a match, ++ // but allow it at the lowest weight. ++ if (!CallOperandVal) ++ return CW_Default; ++ Type *type = CallOperandVal->getType(); ++ // Look at the constraint type. ++ switch (*constraint) { + default: +- llvm_unreachable("Unexpected CCValAssign::LocInfo"); +- case CCValAssign::Full: +- case CCValAssign::Indirect: ++ weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint); + break; +- case CCValAssign::BCvt: +- if (VA.getLocVT() == MVT::i64 && VA.getValVT() == MVT::f32) +- Val = DAG.getNode(LoongArchISD::MOVGR2FR_W_LA64, DL, MVT::f32, Val); +- else +- Val = DAG.getNode(ISD::BITCAST, DL, VA.getValVT(), Val); ++ case 'f': // FPU ++ if (Subtarget.hasLSX() && type->isVectorTy() && ++ type->getPrimitiveSizeInBits() == 128) ++ weight = CW_Register; ++ else if (Subtarget.hasLASX() && type->isVectorTy() && ++ type->getPrimitiveSizeInBits() == 256) ++ weight = CW_Register; ++ else if (type->isFloatTy()) ++ weight = CW_Register; ++ break; ++ case 'l': // signed 16 bit immediate ++ case 'I': // signed 12 bit immediate ++ case 'J': // integer zero ++ case 'G': // floating-point zero ++ case 'K': // unsigned 12 bit immediate ++ if (isa(CallOperandVal)) ++ weight = CW_Constant; ++ break; ++ case 'm': ++ case 'R': ++ weight = CW_Memory; + break; + } +- return Val; ++ return weight; + } + +-static SDValue unpackFromRegLoc(SelectionDAG &DAG, SDValue Chain, +- const CCValAssign &VA, const SDLoc &DL, +- const LoongArchTargetLowering &TLI) { +- MachineFunction &MF = DAG.getMachineFunction(); +- MachineRegisterInfo &RegInfo = MF.getRegInfo(); +- EVT LocVT = VA.getLocVT(); +- SDValue Val; +- const TargetRegisterClass *RC = TLI.getRegClassFor(LocVT.getSimpleVT()); +- Register VReg = RegInfo.createVirtualRegister(RC); +- RegInfo.addLiveIn(VA.getLocReg(), VReg); +- Val = DAG.getCopyFromReg(Chain, DL, VReg, LocVT); ++/// This is a helper function to parse a physical register string and split it ++/// into non-numeric and numeric parts (Prefix and Reg). The first boolean flag ++/// that is returned indicates whether parsing was successful. The second flag ++/// is true if the numeric part exists. ++static std::pair parsePhysicalReg(StringRef C, StringRef &Prefix, ++ unsigned long long &Reg) { ++ if (C.empty() || C.front() != '{' || C.back() != '}') ++ return std::make_pair(false, false); + +- return convertLocVTToValVT(DAG, Val, VA, DL); +-} ++ // Search for the first numeric character. ++ StringRef::const_iterator I, B = C.begin() + 1, E = C.end() - 1; ++ I = std::find_if(B, E, isdigit); + +-// The caller is responsible for loading the full value if the argument is +-// passed with CCValAssign::Indirect. +-static SDValue unpackFromMemLoc(SelectionDAG &DAG, SDValue Chain, +- const CCValAssign &VA, const SDLoc &DL) { +- MachineFunction &MF = DAG.getMachineFunction(); +- MachineFrameInfo &MFI = MF.getFrameInfo(); +- EVT ValVT = VA.getValVT(); +- int FI = MFI.CreateFixedObject(ValVT.getStoreSize(), VA.getLocMemOffset(), +- /*IsImmutable=*/true); +- SDValue FIN = DAG.getFrameIndex( +- FI, MVT::getIntegerVT(DAG.getDataLayout().getPointerSizeInBits(0))); ++ Prefix = StringRef(B, I - B); + +- ISD::LoadExtType ExtType; +- switch (VA.getLocInfo()) { +- default: +- llvm_unreachable("Unexpected CCValAssign::LocInfo"); +- case CCValAssign::Full: +- case CCValAssign::Indirect: +- case CCValAssign::BCvt: +- ExtType = ISD::NON_EXTLOAD; +- break; +- } +- return DAG.getExtLoad( +- ExtType, DL, VA.getLocVT(), Chain, FIN, +- MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI), ValVT); ++ // The second flag is set to false if no numeric characters were found. ++ if (I == E) ++ return std::make_pair(true, false); ++ ++ // Parse the numeric characters. ++ return std::make_pair(!getAsUnsignedInteger(StringRef(I, E - I), 10, Reg), ++ true); + } + +-static SDValue convertValVTToLocVT(SelectionDAG &DAG, SDValue Val, +- const CCValAssign &VA, const SDLoc &DL) { +- EVT LocVT = VA.getLocVT(); ++EVT LoongArchTargetLowering::getTypeForExtReturn(LLVMContext &Context, EVT VT, ++ ISD::NodeType) const { ++ bool Cond = !Subtarget.isABI_LP32() && VT.getSizeInBits() == 32; ++ EVT MinVT = getRegisterType(Context, Cond ? MVT::i64 : MVT::i32); ++ return VT.bitsLT(MinVT) ? MinVT : VT; ++} + +- switch (VA.getLocInfo()) { +- default: +- llvm_unreachable("Unexpected CCValAssign::LocInfo"); +- case CCValAssign::Full: +- break; +- case CCValAssign::BCvt: +- if (VA.getLocVT() == MVT::i64 && VA.getValVT() == MVT::f32) +- Val = DAG.getNode(LoongArchISD::MOVFR2GR_S_LA64, DL, MVT::i64, Val); +- else +- Val = DAG.getNode(ISD::BITCAST, DL, LocVT, Val); +- break; +- } +- return Val; ++static const TargetRegisterClass *getRegisterClassForVT(MVT VT, bool Is64Bit) { ++ // Newer llvm versions (>= 12) do not require simple VTs for constraints and ++ // they use MVT::Other for constraints with complex VTs. For more details, ++ // please see https://reviews.llvm.org/D91710. ++ if (VT == MVT::Other || VT.getSizeInBits() <= 32) ++ return &LoongArch::GPR32RegClass; ++ if (VT.getSizeInBits() <= 64) ++ return Is64Bit ? &LoongArch::GPR64RegClass : &LoongArch::GPR32RegClass; ++ return nullptr; + } + +-static bool CC_LoongArch_GHC(unsigned ValNo, MVT ValVT, MVT LocVT, +- CCValAssign::LocInfo LocInfo, +- ISD::ArgFlagsTy ArgFlags, CCState &State) { +- if (LocVT == MVT::i32 || LocVT == MVT::i64) { +- // Pass in STG registers: Base, Sp, Hp, R1, R2, R3, R4, R5, SpLim +- // s0 s1 s2 s3 s4 s5 s6 s7 s8 +- static const MCPhysReg GPRList[] = { +- LoongArch::R23, LoongArch::R24, LoongArch::R25, +- LoongArch::R26, LoongArch::R27, LoongArch::R28, +- LoongArch::R29, LoongArch::R30, LoongArch::R31}; +- if (unsigned Reg = State.AllocateReg(GPRList)) { +- State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); +- return false; +- } +- } ++std::pair LoongArchTargetLowering:: ++parseRegForInlineAsmConstraint(StringRef C, MVT VT) const { ++ const TargetRegisterInfo *TRI = ++ Subtarget.getRegisterInfo(); ++ const TargetRegisterClass *RC; ++ StringRef Prefix; ++ unsigned long long Reg; + +- if (LocVT == MVT::f32) { +- // Pass in STG registers: F1, F2, F3, F4 +- // fs0,fs1,fs2,fs3 +- static const MCPhysReg FPR32List[] = {LoongArch::F24, LoongArch::F25, +- LoongArch::F26, LoongArch::F27}; +- if (unsigned Reg = State.AllocateReg(FPR32List)) { +- State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); +- return false; ++ std::pair R = parsePhysicalReg(C, Prefix, Reg); ++ ++ if (!R.first) ++ return std::make_pair(0U, nullptr); ++ ++ if (!R.second) ++ return std::make_pair(0U, nullptr); ++ ++ if (Prefix == "$f") { // Parse $f0-$f31. ++ // If the size of FP registers is 64-bit or Reg is an even number, select ++ // the 64-bit register class. Otherwise, select the 32-bit register class. ++ if (VT == MVT::Other) ++ VT = (Subtarget.isFP64bit() || !(Reg % 2)) ? MVT::f64 : MVT::f32; ++ ++ RC = getRegClassFor(VT); ++ } ++ else if (Prefix == "$vr") { // Parse $vr0-$vr31. ++ RC = getRegClassFor((VT == MVT::Other) ? MVT::v16i8 : VT); ++ } ++ else if (Prefix == "$xr") { // Parse $xr0-$xr31. ++ RC = getRegClassFor((VT == MVT::Other) ? MVT::v16i8 : VT); ++ } ++ else if (Prefix == "$fcc") // Parse $fcc0-$fcc7. ++ RC = TRI->getRegClass(LoongArch::FCFRRegClassID); ++ else { // Parse $r0-$r31. ++ assert(Prefix == "$r"); ++ if ((RC = getRegisterClassForVT(VT, Subtarget.is64Bit())) == nullptr) { ++ // This will generate an error message. ++ return std::make_pair(0U, nullptr); + } + } + +- if (LocVT == MVT::f64) { +- // Pass in STG registers: D1, D2, D3, D4 +- // fs4,fs5,fs6,fs7 +- static const MCPhysReg FPR64List[] = {LoongArch::F28_64, LoongArch::F29_64, +- LoongArch::F30_64, LoongArch::F31_64}; +- if (unsigned Reg = State.AllocateReg(FPR64List)) { +- State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); +- return false; ++ assert(Reg < RC->getNumRegs()); ++ ++ if (RC == &LoongArch::GPR64RegClass || RC == &LoongArch::GPR32RegClass) { ++ // Sync with the GPR32/GPR64 RegisterClass in LoongArchRegisterInfo.td ++ // that just like LoongArchAsmParser.cpp ++ switch (Reg) { ++ case 0: return std::make_pair(*(RC->begin() + 0), RC); // r0 ++ case 1: return std::make_pair(*(RC->begin() + 27), RC); // r1 ++ case 2: return std::make_pair(*(RC->begin() + 28), RC); // r2 ++ case 3: return std::make_pair(*(RC->begin() + 29), RC); // r3 ++ case 4: return std::make_pair(*(RC->begin() + 1), RC); // r4 ++ case 5: return std::make_pair(*(RC->begin() + 2), RC); // r5 ++ case 6: return std::make_pair(*(RC->begin() + 3), RC); // r6 ++ case 7: return std::make_pair(*(RC->begin() + 4), RC); // r7 ++ case 8: return std::make_pair(*(RC->begin() + 5), RC); // r8 ++ case 9: return std::make_pair(*(RC->begin() + 6), RC); // r9 ++ case 10: return std::make_pair(*(RC->begin() + 7), RC); // r10 ++ case 11: return std::make_pair(*(RC->begin() + 8), RC); // r11 ++ case 12: return std::make_pair(*(RC->begin() + 9), RC); // r12 ++ case 13: return std::make_pair(*(RC->begin() + 10), RC); // r13 ++ case 14: return std::make_pair(*(RC->begin() + 11), RC); // r14 ++ case 15: return std::make_pair(*(RC->begin() + 12), RC); // r15 ++ case 16: return std::make_pair(*(RC->begin() + 13), RC); // r16 ++ case 17: return std::make_pair(*(RC->begin() + 14), RC); // r17 ++ case 18: return std::make_pair(*(RC->begin() + 15), RC); // r18 ++ case 19: return std::make_pair(*(RC->begin() + 16), RC); // r19 ++ case 20: return std::make_pair(*(RC->begin() + 17), RC); // r20 ++ case 21: return std::make_pair(*(RC->begin() + 30), RC); // r21 ++ case 22: return std::make_pair(*(RC->begin() + 31), RC); // r22 ++ case 23: return std::make_pair(*(RC->begin() + 18), RC); // r23 ++ case 24: return std::make_pair(*(RC->begin() + 19), RC); // r24 ++ case 25: return std::make_pair(*(RC->begin() + 20), RC); // r25 ++ case 26: return std::make_pair(*(RC->begin() + 21), RC); // r26 ++ case 27: return std::make_pair(*(RC->begin() + 22), RC); // r27 ++ case 28: return std::make_pair(*(RC->begin() + 23), RC); // r28 ++ case 29: return std::make_pair(*(RC->begin() + 24), RC); // r29 ++ case 30: return std::make_pair(*(RC->begin() + 25), RC); // r30 ++ case 31: return std::make_pair(*(RC->begin() + 26), RC); // r31 + } + } +- +- report_fatal_error("No registers left in GHC calling convention"); +- return true; ++ return std::make_pair(*(RC->begin() + Reg), RC); + } + +-// Transform physical registers into virtual registers. +-SDValue LoongArchTargetLowering::LowerFormalArguments( +- SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, +- const SmallVectorImpl &Ins, const SDLoc &DL, +- SelectionDAG &DAG, SmallVectorImpl &InVals) const { +- +- MachineFunction &MF = DAG.getMachineFunction(); +- +- switch (CallConv) { +- default: +- llvm_unreachable("Unsupported calling convention"); +- case CallingConv::C: +- case CallingConv::Fast: +- break; +- case CallingConv::GHC: +- if (!MF.getSubtarget().hasFeature(LoongArch::FeatureBasicF) || +- !MF.getSubtarget().hasFeature(LoongArch::FeatureBasicD)) +- report_fatal_error( +- "GHC calling convention requires the F and D extensions"); ++/// Given a register class constraint, like 'r', if this corresponds directly ++/// to an LLVM register class, return a register of 0 and the register class ++/// pointer. ++std::pair ++LoongArchTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, ++ StringRef Constraint, ++ MVT VT) const { ++ if (Constraint.size() == 1) { ++ switch (Constraint[0]) { ++ case 'r': ++ return std::make_pair(0U, getRegisterClassForVT(VT, Subtarget.is64Bit())); ++ case 'f': // FPU or LSX register ++ if (VT == MVT::v16i8) ++ return std::make_pair(0U, &LoongArch::LSX128BRegClass); ++ else if (VT == MVT::v8i16) ++ return std::make_pair(0U, &LoongArch::LSX128HRegClass); ++ else if (VT == MVT::v4i32 || VT == MVT::v4f32) ++ return std::make_pair(0U, &LoongArch::LSX128WRegClass); ++ else if (VT == MVT::v2i64 || VT == MVT::v2f64) ++ return std::make_pair(0U, &LoongArch::LSX128DRegClass); ++ else if (VT == MVT::v32i8) ++ return std::make_pair(0U, &LoongArch::LASX256BRegClass); ++ else if (VT == MVT::v16i16) ++ return std::make_pair(0U, &LoongArch::LASX256HRegClass); ++ else if (VT == MVT::v8i32 || VT == MVT::v8f32) ++ return std::make_pair(0U, &LoongArch::LASX256WRegClass); ++ else if (VT == MVT::v4i64 || VT == MVT::v4f64) ++ return std::make_pair(0U, &LoongArch::LASX256DRegClass); ++ else if (VT == MVT::f32) ++ return std::make_pair(0U, &LoongArch::FGR32RegClass); ++ else if (VT == MVT::f64) ++ return std::make_pair(0U, &LoongArch::FGR64RegClass); ++ break; ++ } + } + +- EVT PtrVT = getPointerTy(DAG.getDataLayout()); +- MVT GRLenVT = Subtarget.getGRLenVT(); +- unsigned GRLenInBytes = Subtarget.getGRLen() / 8; +- // Used with varargs to acumulate store chains. +- std::vector OutChains; ++ std::pair R; ++ R = parseRegForInlineAsmConstraint(Constraint, VT); + +- // Assign locations to all of the incoming arguments. +- SmallVector ArgLocs; +- CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext()); ++ if (R.second) ++ return R; + +- if (CallConv == CallingConv::GHC) +- CCInfo.AnalyzeFormalArguments(Ins, CC_LoongArch_GHC); +- else +- analyzeInputArgs(MF, CCInfo, Ins, /*IsRet=*/false, CC_LoongArch); ++ return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT); ++} + +- for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { +- CCValAssign &VA = ArgLocs[i]; +- SDValue ArgValue; +- if (VA.isRegLoc()) +- ArgValue = unpackFromRegLoc(DAG, Chain, VA, DL, *this); +- else +- ArgValue = unpackFromMemLoc(DAG, Chain, VA, DL); +- if (VA.getLocInfo() == CCValAssign::Indirect) { +- // If the original argument was split and passed by reference, we need to +- // load all parts of it here (using the same address). +- InVals.push_back(DAG.getLoad(VA.getValVT(), DL, Chain, ArgValue, +- MachinePointerInfo())); +- unsigned ArgIndex = Ins[i].OrigArgIndex; +- unsigned ArgPartOffset = Ins[i].PartOffset; +- assert(ArgPartOffset == 0); +- while (i + 1 != e && Ins[i + 1].OrigArgIndex == ArgIndex) { +- CCValAssign &PartVA = ArgLocs[i + 1]; +- unsigned PartOffset = Ins[i + 1].PartOffset - ArgPartOffset; +- SDValue Offset = DAG.getIntPtrConstant(PartOffset, DL); +- SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, ArgValue, Offset); +- InVals.push_back(DAG.getLoad(PartVA.getValVT(), DL, Chain, Address, +- MachinePointerInfo())); +- ++i; ++/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops ++/// vector. If it is invalid, don't add anything to Ops. ++void LoongArchTargetLowering::LowerAsmOperandForConstraint(SDValue Op, ++ StringRef Constraint, ++ std::vector&Ops, ++ SelectionDAG &DAG) const { ++ SDLoc DL(Op); ++ SDValue Result; ++ ++ // Only support length 1 constraints for now. ++ if (Constraint.size() > 1) return; ++ ++ char ConstraintLetter = Constraint[0]; ++ switch (ConstraintLetter) { ++ default: break; // This will fall through to the generic implementation ++ case 'l': // Signed 16 bit constant ++ // If this fails, the parent routine will give an error ++ if (ConstantSDNode *C = dyn_cast(Op)) { ++ EVT Type = Op.getValueType(); ++ int64_t Val = C->getSExtValue(); ++ if (isInt<16>(Val)) { ++ Result = DAG.getTargetConstant(Val, DL, Type); ++ break; + } +- continue; + } +- InVals.push_back(ArgValue); +- } +- +- if (IsVarArg) { +- ArrayRef ArgRegs = ArrayRef(ArgGPRs); +- unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs); +- const TargetRegisterClass *RC = &LoongArch::GPRRegClass; +- MachineFrameInfo &MFI = MF.getFrameInfo(); +- MachineRegisterInfo &RegInfo = MF.getRegInfo(); +- auto *LoongArchFI = MF.getInfo(); +- +- // Offset of the first variable argument from stack pointer, and size of +- // the vararg save area. For now, the varargs save area is either zero or +- // large enough to hold a0-a7. +- int VaArgOffset, VarArgsSaveSize; +- +- // If all registers are allocated, then all varargs must be passed on the +- // stack and we don't need to save any argregs. +- if (ArgRegs.size() == Idx) { +- VaArgOffset = CCInfo.getStackSize(); +- VarArgsSaveSize = 0; +- } else { +- VarArgsSaveSize = GRLenInBytes * (ArgRegs.size() - Idx); +- VaArgOffset = -VarArgsSaveSize; ++ return; ++ case 'I': // Signed 12 bit constant ++ // If this fails, the parent routine will give an error ++ if (ConstantSDNode *C = dyn_cast(Op)) { ++ EVT Type = Op.getValueType(); ++ int64_t Val = C->getSExtValue(); ++ if (isInt<12>(Val)) { ++ Result = DAG.getTargetConstant(Val, DL, Type); ++ break; ++ } + } +- +- // Record the frame index of the first variable argument +- // which is a value necessary to VASTART. +- int FI = MFI.CreateFixedObject(GRLenInBytes, VaArgOffset, true); +- LoongArchFI->setVarArgsFrameIndex(FI); +- +- // If saving an odd number of registers then create an extra stack slot to +- // ensure that the frame pointer is 2*GRLen-aligned, which in turn ensures +- // offsets to even-numbered registered remain 2*GRLen-aligned. +- if (Idx % 2) { +- MFI.CreateFixedObject(GRLenInBytes, VaArgOffset - (int)GRLenInBytes, +- true); +- VarArgsSaveSize += GRLenInBytes; ++ return; ++ case 'J': // integer zero ++ if (ConstantSDNode *C = dyn_cast(Op)) { ++ EVT Type = Op.getValueType(); ++ int64_t Val = C->getZExtValue(); ++ if (Val == 0) { ++ Result = DAG.getTargetConstant(0, DL, Type); ++ break; ++ } + } +- +- // Copy the integer registers that may have been used for passing varargs +- // to the vararg save area. +- for (unsigned I = Idx; I < ArgRegs.size(); +- ++I, VaArgOffset += GRLenInBytes) { +- const Register Reg = RegInfo.createVirtualRegister(RC); +- RegInfo.addLiveIn(ArgRegs[I], Reg); +- SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, GRLenVT); +- FI = MFI.CreateFixedObject(GRLenInBytes, VaArgOffset, true); +- SDValue PtrOff = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout())); +- SDValue Store = DAG.getStore(Chain, DL, ArgValue, PtrOff, +- MachinePointerInfo::getFixedStack(MF, FI)); +- cast(Store.getNode()) +- ->getMemOperand() +- ->setValue((Value *)nullptr); +- OutChains.push_back(Store); ++ return; ++ case 'G': // floating-point zero ++ if (ConstantFPSDNode *C = dyn_cast(Op)) { ++ if (C->isZero()) { ++ EVT Type = Op.getValueType(); ++ Result = DAG.getTargetConstantFP(0, DL, Type); ++ break; ++ } ++ } ++ return; ++ case 'K': // unsigned 12 bit immediate ++ if (ConstantSDNode *C = dyn_cast(Op)) { ++ EVT Type = Op.getValueType(); ++ uint64_t Val = (uint64_t)C->getZExtValue(); ++ if (isUInt<12>(Val)) { ++ Result = DAG.getTargetConstant(Val, DL, Type); ++ break; ++ } + } +- LoongArchFI->setVarArgsSaveSize(VarArgsSaveSize); ++ return; + } + +- // All stores are grouped in one node to allow the matching between +- // the size of Ins and InVals. This only happens for vararg functions. +- if (!OutChains.empty()) { +- OutChains.push_back(Chain); +- Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains); ++ if (Result.getNode()) { ++ Ops.push_back(Result); ++ return; + } + +- return Chain; +-} +- +-bool LoongArchTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const { +- return CI->isTailCall(); ++ TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG); + } + +-// Check if the return value is used as only a return value, as otherwise +-// we can't perform a tail-call. +-bool LoongArchTargetLowering::isUsedByReturnOnly(SDNode *N, +- SDValue &Chain) const { +- if (N->getNumValues() != 1) +- return false; +- if (!N->hasNUsesOfValue(1, 0)) +- return false; +- +- SDNode *Copy = *N->use_begin(); +- if (Copy->getOpcode() != ISD::CopyToReg) ++bool LoongArchTargetLowering::isLegalAddressingMode(const DataLayout &DL, ++ const AddrMode &AM, Type *Ty, ++ unsigned AS, Instruction *I) const { ++ // No global is ever allowed as a base. ++ if (AM.BaseGV) + return false; + +- // If the ISD::CopyToReg has a glue operand, we conservatively assume it +- // isn't safe to perform a tail call. +- if (Copy->getGluedNode()) ++ switch (AM.Scale) { ++ case 0: // "r+i" or just "i", depending on HasBaseReg. ++ break; ++ case 1: ++ if (!AM.HasBaseReg) // allow "r+i". ++ break; ++ return false; // disallow "r+r" or "r+r+i". ++ default: + return false; +- +- // The copy must be used by a LoongArchISD::RET, and nothing else. +- bool HasRet = false; +- for (SDNode *Node : Copy->uses()) { +- if (Node->getOpcode() != LoongArchISD::RET) +- return false; +- HasRet = true; + } + +- if (!HasRet) +- return false; +- +- Chain = Copy->getOperand(0); + return true; + } + +-// Check whether the call is eligible for tail call optimization. +-bool LoongArchTargetLowering::isEligibleForTailCallOptimization( +- CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF, +- const SmallVectorImpl &ArgLocs) const { ++bool ++LoongArchTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const { ++ // The LoongArch target isn't yet aware of offsets. ++ return false; ++} + +- auto CalleeCC = CLI.CallConv; +- auto &Outs = CLI.Outs; +- auto &Caller = MF.getFunction(); +- auto CallerCC = Caller.getCallingConv(); ++EVT LoongArchTargetLowering::getOptimalMemOpType( ++ const MemOp &Op, const AttributeList &FuncAttributes) const { ++ if (!FuncAttributes.hasFnAttr(Attribute::NoImplicitFloat)) { ++ if (Op.size() >= 16) { ++ if (Op.size() >= 32 && Subtarget.hasLASX()) { ++ return MVT::v32i8; ++ } ++ if (Subtarget.hasLSX()) ++ return MVT::v16i8; ++ } ++ } + +- // Do not tail call opt if the stack is used to pass parameters. +- if (CCInfo.getStackSize() != 0) +- return false; ++ if (Subtarget.is64Bit()) ++ return MVT::i64; + +- // Do not tail call opt if any parameters need to be passed indirectly. +- for (auto &VA : ArgLocs) +- if (VA.getLocInfo() == CCValAssign::Indirect) +- return false; ++ return MVT::i32; ++} + +- // Do not tail call opt if either caller or callee uses struct return +- // semantics. +- auto IsCallerStructRet = Caller.hasStructRetAttr(); +- auto IsCalleeStructRet = Outs.empty() ? false : Outs[0].Flags.isSRet(); +- if (IsCallerStructRet || IsCalleeStructRet) ++/// isFPImmLegal - Returns true if the target can instruction select the ++/// specified FP immediate natively. If false, the legalizer will ++/// materialize the FP immediate as a load from a constant pool. ++bool LoongArchTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT, ++ bool ForCodeSize) const { ++ if (VT != MVT::f32 && VT != MVT::f64) + return false; +- +- // Do not tail call opt if either the callee or caller has a byval argument. +- for (auto &Arg : Outs) +- if (Arg.Flags.isByVal()) +- return false; +- +- // The callee has to preserve all registers the caller needs to preserve. +- const LoongArchRegisterInfo *TRI = Subtarget.getRegisterInfo(); +- const uint32_t *CallerPreserved = TRI->getCallPreservedMask(MF, CallerCC); +- if (CalleeCC != CallerCC) { +- const uint32_t *CalleePreserved = TRI->getCallPreservedMask(MF, CalleeCC); +- if (!TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved)) +- return false; +- } +- return true; ++ if (Imm.isNegZero()) ++ return false; ++ return (Imm.isZero() || Imm.isExactlyValue(+1.0)); + } + +-static Align getPrefTypeAlign(EVT VT, SelectionDAG &DAG) { +- return DAG.getDataLayout().getPrefTypeAlign( +- VT.getTypeForEVT(*DAG.getContext())); ++bool LoongArchTargetLowering::useSoftFloat() const { ++ return Subtarget.useSoftFloat(); + } + +-// Lower a call to a callseq_start + CALL + callseq_end chain, and add input +-// and output parameter nodes. +-SDValue +-LoongArchTargetLowering::LowerCall(CallLoweringInfo &CLI, +- SmallVectorImpl &InVals) const { +- SelectionDAG &DAG = CLI.DAG; +- SDLoc &DL = CLI.DL; +- SmallVectorImpl &Outs = CLI.Outs; +- SmallVectorImpl &OutVals = CLI.OutVals; +- SmallVectorImpl &Ins = CLI.Ins; +- SDValue Chain = CLI.Chain; +- SDValue Callee = CLI.Callee; +- CallingConv::ID CallConv = CLI.CallConv; +- bool IsVarArg = CLI.IsVarArg; +- EVT PtrVT = getPointerTy(DAG.getDataLayout()); +- MVT GRLenVT = Subtarget.getGRLenVT(); +- bool &IsTailCall = CLI.IsTailCall; ++// Return whether the an instruction can potentially be optimized to a tail ++// call. This will cause the optimizers to attempt to move, or duplicate, ++// return instructions to help enable tail call optimizations for this ++// instruction. ++bool LoongArchTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const { ++ return CI->isTailCall(); ++} + ++void LoongArchTargetLowering::copyByValRegs( ++ SDValue Chain, const SDLoc &DL, std::vector &OutChains, ++ SelectionDAG &DAG, const ISD::ArgFlagsTy &Flags, ++ SmallVectorImpl &InVals, const Argument *FuncArg, ++ unsigned FirstReg, unsigned LastReg, const CCValAssign &VA, ++ LoongArchCCState &State) const { + MachineFunction &MF = DAG.getMachineFunction(); ++ MachineFrameInfo &MFI = MF.getFrameInfo(); ++ unsigned GPRSizeInBytes = Subtarget.getGPRSizeInBytes(); ++ unsigned NumRegs = LastReg - FirstReg; ++ unsigned RegAreaSize = NumRegs * GPRSizeInBytes; ++ unsigned FrameObjSize = std::max(Flags.getByValSize(), RegAreaSize); ++ int FrameObjOffset; ++ ArrayRef ByValArgRegs = ABI.GetByValArgRegs(); ++ ++ if (RegAreaSize) ++ FrameObjOffset = -(int)((ByValArgRegs.size() - FirstReg) * GPRSizeInBytes); ++ else ++ FrameObjOffset = VA.getLocMemOffset(); ++ ++ // Create frame object. ++ EVT PtrTy = getPointerTy(DAG.getDataLayout()); ++ // Make the fixed object stored to mutable so that the load instructions ++ // referencing it have their memory dependencies added. ++ // Set the frame object as isAliased which clears the underlying objects ++ // vector in ScheduleDAGInstrs::buildSchedGraph() resulting in addition of all ++ // stores as dependencies for loads referencing this fixed object. ++ int FI = MFI.CreateFixedObject(FrameObjSize, FrameObjOffset, false, true); ++ SDValue FIN = DAG.getFrameIndex(FI, PtrTy); ++ InVals.push_back(FIN); ++ ++ if (!NumRegs) ++ return; + +- // Analyze the operands of the call, assigning locations to each operand. +- SmallVector ArgLocs; +- CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext()); ++ // Copy arg registers. ++ MVT RegTy = MVT::getIntegerVT(GPRSizeInBytes * 8); ++ const TargetRegisterClass *RC = getRegClassFor(RegTy); + +- if (CallConv == CallingConv::GHC) +- ArgCCInfo.AnalyzeCallOperands(Outs, CC_LoongArch_GHC); +- else +- analyzeOutputArgs(MF, ArgCCInfo, Outs, /*IsRet=*/false, &CLI, CC_LoongArch); ++ for (unsigned I = 0; I < NumRegs; ++I) { ++ unsigned ArgReg = ByValArgRegs[FirstReg + I]; ++ unsigned VReg = addLiveIn(MF, ArgReg, RC); ++ unsigned Offset = I * GPRSizeInBytes; ++ SDValue StorePtr = DAG.getNode(ISD::ADD, DL, PtrTy, FIN, ++ DAG.getConstant(Offset, DL, PtrTy)); ++ SDValue Store = DAG.getStore(Chain, DL, DAG.getRegister(VReg, RegTy), ++ StorePtr, MachinePointerInfo(FuncArg, Offset)); ++ OutChains.push_back(Store); ++ } ++} + +- // Check if it's really possible to do a tail call. +- if (IsTailCall) +- IsTailCall = isEligibleForTailCallOptimization(ArgCCInfo, CLI, MF, ArgLocs); ++// Copy byVal arg to registers and stack. ++void LoongArchTargetLowering::passByValArg( ++ SDValue Chain, const SDLoc &DL, ++ std::deque> &RegsToPass, ++ SmallVectorImpl &MemOpChains, SDValue StackPtr, ++ MachineFrameInfo &MFI, SelectionDAG &DAG, SDValue Arg, unsigned FirstReg, ++ unsigned LastReg, const ISD::ArgFlagsTy &Flags, ++ const CCValAssign &VA) const { ++ unsigned ByValSizeInBytes = Flags.getByValSize(); ++ unsigned OffsetInBytes = 0; // From beginning of struct ++ unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes(); ++ Align Alignment = ++ std::min(Flags.getNonZeroByValAlign(), Align(RegSizeInBytes)); ++ EVT PtrTy = getPointerTy(DAG.getDataLayout()), ++ RegTy = MVT::getIntegerVT(RegSizeInBytes * 8); ++ unsigned NumRegs = LastReg - FirstReg; ++ ++ if (NumRegs) { ++ ArrayRef ArgRegs = ABI.GetByValArgRegs(); ++ bool LeftoverBytes = (NumRegs * RegSizeInBytes > ByValSizeInBytes); ++ unsigned I = 0; ++ ++ // Copy words to registers. ++ for (; I < NumRegs - LeftoverBytes; ++I, OffsetInBytes += RegSizeInBytes) { ++ SDValue LoadPtr = DAG.getNode(ISD::ADD, DL, PtrTy, Arg, ++ DAG.getConstant(OffsetInBytes, DL, PtrTy)); ++ SDValue LoadVal = DAG.getLoad(RegTy, DL, Chain, LoadPtr, ++ MachinePointerInfo(), Alignment); ++ MemOpChains.push_back(LoadVal.getValue(1)); ++ unsigned ArgReg = ArgRegs[FirstReg + I]; ++ RegsToPass.push_back(std::make_pair(ArgReg, LoadVal)); ++ } + +- if (IsTailCall) +- ++NumTailCalls; +- else if (CLI.CB && CLI.CB->isMustTailCall()) +- report_fatal_error("failed to perform tail call elimination on a call " +- "site marked musttail"); ++ // Return if the struct has been fully copied. ++ if (ByValSizeInBytes == OffsetInBytes) ++ return; + +- // Get a count of how many bytes are to be pushed on the stack. +- unsigned NumBytes = ArgCCInfo.getStackSize(); ++ // Copy the remainder of the byval argument with sub-word loads and shifts. ++ if (LeftoverBytes) { ++ SDValue Val; + +- // Create local copies for byval args. +- SmallVector ByValArgs; +- for (unsigned i = 0, e = Outs.size(); i != e; ++i) { +- ISD::ArgFlagsTy Flags = Outs[i].Flags; +- if (!Flags.isByVal()) +- continue; ++ for (unsigned LoadSizeInBytes = RegSizeInBytes / 2, TotalBytesLoaded = 0; ++ OffsetInBytes < ByValSizeInBytes; LoadSizeInBytes /= 2) { ++ unsigned RemainingSizeInBytes = ByValSizeInBytes - OffsetInBytes; + +- SDValue Arg = OutVals[i]; +- unsigned Size = Flags.getByValSize(); +- Align Alignment = Flags.getNonZeroByValAlign(); ++ if (RemainingSizeInBytes < LoadSizeInBytes) ++ continue; + +- int FI = +- MF.getFrameInfo().CreateStackObject(Size, Alignment, /*isSS=*/false); +- SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout())); +- SDValue SizeNode = DAG.getConstant(Size, DL, GRLenVT); ++ // Load subword. ++ SDValue LoadPtr = DAG.getNode(ISD::ADD, DL, PtrTy, Arg, ++ DAG.getConstant(OffsetInBytes, DL, ++ PtrTy)); ++ SDValue LoadVal = DAG.getExtLoad( ++ ISD::ZEXTLOAD, DL, RegTy, Chain, LoadPtr, MachinePointerInfo(), ++ MVT::getIntegerVT(LoadSizeInBytes * 8), Alignment); ++ MemOpChains.push_back(LoadVal.getValue(1)); + +- Chain = DAG.getMemcpy(Chain, DL, FIPtr, Arg, SizeNode, Alignment, +- /*IsVolatile=*/false, +- /*AlwaysInline=*/false, /*isTailCall=*/IsTailCall, +- MachinePointerInfo(), MachinePointerInfo()); +- ByValArgs.push_back(FIPtr); +- } ++ // Shift the loaded value. ++ unsigned Shamt; + +- if (!IsTailCall) +- Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, CLI.DL); ++ Shamt = TotalBytesLoaded * 8; + +- // Copy argument values to their designated locations. +- SmallVector> RegsToPass; +- SmallVector MemOpChains; +- SDValue StackPtr; +- for (unsigned i = 0, j = 0, e = ArgLocs.size(); i != e; ++i) { +- CCValAssign &VA = ArgLocs[i]; +- SDValue ArgValue = OutVals[i]; +- ISD::ArgFlagsTy Flags = Outs[i].Flags; ++ SDValue Shift = DAG.getNode(ISD::SHL, DL, RegTy, LoadVal, ++ DAG.getConstant(Shamt, DL, MVT::i32)); + +- // Promote the value if needed. +- // For now, only handle fully promoted and indirect arguments. +- if (VA.getLocInfo() == CCValAssign::Indirect) { +- // Store the argument in a stack slot and pass its address. +- Align StackAlign = +- std::max(getPrefTypeAlign(Outs[i].ArgVT, DAG), +- getPrefTypeAlign(ArgValue.getValueType(), DAG)); +- TypeSize StoredSize = ArgValue.getValueType().getStoreSize(); +- // If the original argument was split and passed by reference, we need to +- // store the required parts of it here (and pass just one address). +- unsigned ArgIndex = Outs[i].OrigArgIndex; +- unsigned ArgPartOffset = Outs[i].PartOffset; +- assert(ArgPartOffset == 0); +- // Calculate the total size to store. We don't have access to what we're +- // actually storing other than performing the loop and collecting the +- // info. +- SmallVector> Parts; +- while (i + 1 != e && Outs[i + 1].OrigArgIndex == ArgIndex) { +- SDValue PartValue = OutVals[i + 1]; +- unsigned PartOffset = Outs[i + 1].PartOffset - ArgPartOffset; +- SDValue Offset = DAG.getIntPtrConstant(PartOffset, DL); +- EVT PartVT = PartValue.getValueType(); +- +- StoredSize += PartVT.getStoreSize(); +- StackAlign = std::max(StackAlign, getPrefTypeAlign(PartVT, DAG)); +- Parts.push_back(std::make_pair(PartValue, Offset)); +- ++i; +- } +- SDValue SpillSlot = DAG.CreateStackTemporary(StoredSize, StackAlign); +- int FI = cast(SpillSlot)->getIndex(); +- MemOpChains.push_back( +- DAG.getStore(Chain, DL, ArgValue, SpillSlot, +- MachinePointerInfo::getFixedStack(MF, FI))); +- for (const auto &Part : Parts) { +- SDValue PartValue = Part.first; +- SDValue PartOffset = Part.second; +- SDValue Address = +- DAG.getNode(ISD::ADD, DL, PtrVT, SpillSlot, PartOffset); +- MemOpChains.push_back( +- DAG.getStore(Chain, DL, PartValue, Address, +- MachinePointerInfo::getFixedStack(MF, FI))); +- } +- ArgValue = SpillSlot; +- } else { +- ArgValue = convertValVTToLocVT(DAG, ArgValue, VA, DL); +- } ++ if (Val.getNode()) ++ Val = DAG.getNode(ISD::OR, DL, RegTy, Val, Shift); ++ else ++ Val = Shift; + +- // Use local copy if it is a byval arg. +- if (Flags.isByVal()) +- ArgValue = ByValArgs[j++]; ++ OffsetInBytes += LoadSizeInBytes; ++ TotalBytesLoaded += LoadSizeInBytes; ++ Alignment = std::min(Alignment, Align(LoadSizeInBytes)); ++ } + +- if (VA.isRegLoc()) { +- // Queue up the argument copies and emit them at the end. +- RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue)); +- } else { +- assert(VA.isMemLoc() && "Argument not register or memory"); +- assert(!IsTailCall && "Tail call not allowed if stack is used " +- "for passing parameters"); +- +- // Work out the address of the stack slot. +- if (!StackPtr.getNode()) +- StackPtr = DAG.getCopyFromReg(Chain, DL, LoongArch::R3, PtrVT); +- SDValue Address = +- DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr, +- DAG.getIntPtrConstant(VA.getLocMemOffset(), DL)); +- +- // Emit the store. +- MemOpChains.push_back( +- DAG.getStore(Chain, DL, ArgValue, Address, MachinePointerInfo())); ++ unsigned ArgReg = ArgRegs[FirstReg + I]; ++ RegsToPass.push_back(std::make_pair(ArgReg, Val)); ++ return; + } + } + +- // Join the stores, which are independent of one another. +- if (!MemOpChains.empty()) +- Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains); +- +- SDValue Glue; +- +- // Build a sequence of copy-to-reg nodes, chained and glued together. +- for (auto &Reg : RegsToPass) { +- Chain = DAG.getCopyToReg(Chain, DL, Reg.first, Reg.second, Glue); +- Glue = Chain.getValue(1); +- } +- +- // If the callee is a GlobalAddress/ExternalSymbol node, turn it into a +- // TargetGlobalAddress/TargetExternalSymbol node so that legalize won't +- // split it and then direct call can be matched by PseudoCALL. +- if (GlobalAddressSDNode *S = dyn_cast(Callee)) { +- const GlobalValue *GV = S->getGlobal(); +- unsigned OpFlags = +- getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV) +- ? LoongArchII::MO_CALL +- : LoongArchII::MO_CALL_PLT; +- Callee = DAG.getTargetGlobalAddress(S->getGlobal(), DL, PtrVT, 0, OpFlags); +- } else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) { +- unsigned OpFlags = getTargetMachine().shouldAssumeDSOLocal( +- *MF.getFunction().getParent(), nullptr) +- ? LoongArchII::MO_CALL +- : LoongArchII::MO_CALL_PLT; +- Callee = DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT, OpFlags); +- } +- +- // The first call operand is the chain and the second is the target address. +- SmallVector Ops; +- Ops.push_back(Chain); +- Ops.push_back(Callee); +- +- // Add argument registers to the end of the list so that they are +- // known live into the call. +- for (auto &Reg : RegsToPass) +- Ops.push_back(DAG.getRegister(Reg.first, Reg.second.getValueType())); ++ // Copy remainder of byval arg to it with memcpy. ++ unsigned MemCpySize = ByValSizeInBytes - OffsetInBytes; ++ SDValue Src = DAG.getNode(ISD::ADD, DL, PtrTy, Arg, ++ DAG.getConstant(OffsetInBytes, DL, PtrTy)); ++ SDValue Dst = DAG.getNode(ISD::ADD, DL, PtrTy, StackPtr, ++ DAG.getIntPtrConstant(VA.getLocMemOffset(), DL)); ++ Chain = DAG.getMemcpy( ++ Chain, DL, Dst, Src, DAG.getConstant(MemCpySize, DL, PtrTy), ++ Align(Alignment), /*isVolatile=*/false, /*AlwaysInline=*/false, ++ /*isTailCall=*/false, MachinePointerInfo(), MachinePointerInfo()); ++ MemOpChains.push_back(Chain); ++} + +- if (!IsTailCall) { +- // Add a register mask operand representing the call-preserved registers. +- const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo(); +- const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv); +- assert(Mask && "Missing call preserved mask for calling convention"); +- Ops.push_back(DAG.getRegisterMask(Mask)); +- } ++void LoongArchTargetLowering::writeVarArgRegs(std::vector &OutChains, ++ SDValue Chain, const SDLoc &DL, ++ SelectionDAG &DAG, ++ CCState &State) const { ++ ArrayRef ArgRegs = ABI.GetVarArgRegs(); ++ unsigned Idx = State.getFirstUnallocated(ArgRegs); ++ unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes(); ++ MVT RegTy = MVT::getIntegerVT(RegSizeInBytes * 8); ++ const TargetRegisterClass *RC = getRegClassFor(RegTy); ++ MachineFunction &MF = DAG.getMachineFunction(); ++ MachineFrameInfo &MFI = MF.getFrameInfo(); ++ LoongArchFunctionInfo *LoongArchFI = MF.getInfo(); + +- // Glue the call to the argument copies, if any. +- if (Glue.getNode()) +- Ops.push_back(Glue); ++ // Offset of the first variable argument from stack pointer. ++ int VaArgOffset, VarArgsSaveSize; + +- // Emit the call. +- SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); +- unsigned Op; +- switch (DAG.getTarget().getCodeModel()) { +- default: +- report_fatal_error("Unsupported code model"); +- case CodeModel::Small: +- Op = IsTailCall ? LoongArchISD::TAIL : LoongArchISD::CALL; +- break; +- case CodeModel::Medium: +- assert(Subtarget.is64Bit() && "Medium code model requires LA64"); +- Op = IsTailCall ? LoongArchISD::TAIL_MEDIUM : LoongArchISD::CALL_MEDIUM; +- break; +- case CodeModel::Large: +- assert(Subtarget.is64Bit() && "Large code model requires LA64"); +- Op = IsTailCall ? LoongArchISD::TAIL_LARGE : LoongArchISD::CALL_LARGE; +- break; +- } ++ if (ArgRegs.size() == Idx) { ++ VaArgOffset = alignTo(State.getStackSize(), RegSizeInBytes); ++ VarArgsSaveSize = 0; ++ } else { ++ VarArgsSaveSize = (int)(RegSizeInBytes * (ArgRegs.size() - Idx)); ++ VaArgOffset = -VarArgsSaveSize; ++ } ++ ++ // Record the frame index of the first variable argument ++ // which is a value necessary to VASTART. ++ int FI = MFI.CreateFixedObject(RegSizeInBytes, VaArgOffset, true); ++ LoongArchFI->setVarArgsFrameIndex(FI); ++ ++ // If saving an odd number of registers then create an extra stack slot to ++ // ensure that the frame pointer is 2*GRLEN-aligned, which in turn ensures ++ // offsets to even-numbered registered remain 2*GRLEN-aligned. ++ if (Idx % 2) { ++ MFI.CreateFixedObject(RegSizeInBytes, VaArgOffset - (int)RegSizeInBytes, ++ true); ++ VarArgsSaveSize += RegSizeInBytes; ++ } ++ ++ // Copy the integer registers that have not been used for argument passing ++ // to the argument register save area. For LP32, the save area is allocated ++ // in the caller's stack frame, while for LPX32/LP64, it is allocated in the ++ // callee's stack frame. ++ for (unsigned I = Idx; I < ArgRegs.size(); ++ ++I, VaArgOffset += RegSizeInBytes) { ++ unsigned Reg = addLiveIn(MF, ArgRegs[I], RC); ++ SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, RegTy); ++ FI = MFI.CreateFixedObject(RegSizeInBytes, VaArgOffset, true); ++ SDValue PtrOff = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout())); ++ SDValue Store = ++ DAG.getStore(Chain, DL, ArgValue, PtrOff, MachinePointerInfo()); ++ cast(Store.getNode())->getMemOperand()->setValue( ++ (Value *)nullptr); ++ OutChains.push_back(Store); ++ } ++ LoongArchFI->setVarArgsSaveSize(VarArgsSaveSize); ++} + +- if (IsTailCall) { +- MF.getFrameInfo().setHasTailCall(); +- SDValue Ret = DAG.getNode(Op, DL, NodeTys, Ops); +- DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge); +- return Ret; +- } ++void LoongArchTargetLowering::HandleByVal(CCState *State, unsigned &Size, ++ Align Alignment) const { ++ const TargetFrameLowering *TFL = Subtarget.getFrameLowering(); + +- Chain = DAG.getNode(Op, DL, NodeTys, Ops); +- DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge); +- Glue = Chain.getValue(1); ++ assert(Size && "Byval argument's size shouldn't be 0."); + +- // Mark the end of the call, which is glued to the call itself. +- Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, Glue, DL); +- Glue = Chain.getValue(1); ++ Alignment = std::min(Alignment, TFL->getStackAlign()); + +- // Assign locations to each value returned by this call. +- SmallVector RVLocs; +- CCState RetCCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext()); +- analyzeInputArgs(MF, RetCCInfo, Ins, /*IsRet=*/true, CC_LoongArch); ++ unsigned FirstReg = 0; ++ unsigned NumRegs = 0; ++ unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes(); ++ ArrayRef IntArgRegs = ABI.GetByValArgRegs(); ++ // FIXME: The LP32 case actually describes no shadow registers. ++ const MCPhysReg *ShadowRegs = ++ ABI.IsLP32() ? IntArgRegs.data() : LoongArch64DPRegs; + +- // Copy all of the result registers out of their specified physreg. +- for (auto &VA : RVLocs) { +- // Copy the value out. +- SDValue RetValue = +- DAG.getCopyFromReg(Chain, DL, VA.getLocReg(), VA.getLocVT(), Glue); +- // Glue the RetValue to the end of the call sequence. +- Chain = RetValue.getValue(1); +- Glue = RetValue.getValue(2); ++ // We used to check the size as well but we can't do that anymore since ++ // CCState::HandleByVal() rounds up the size after calling this function. ++ assert(Alignment >= Align(RegSizeInBytes) && ++ "Byval argument's alignment should be a multiple of RegSizeInBytes."); + +- RetValue = convertLocVTToValVT(DAG, RetValue, VA, DL); ++ FirstReg = State->getFirstUnallocated(IntArgRegs); + +- InVals.push_back(RetValue); ++ // If Alignment > RegSizeInBytes, the first arg register must be even. ++ // FIXME: This condition happens to do the right thing but it's not the ++ // right way to test it. We want to check that the stack frame offset ++ // of the register is aligned. ++ if ((Alignment > RegSizeInBytes) && (FirstReg % 2)) { ++ State->AllocateReg(IntArgRegs[FirstReg], ShadowRegs[FirstReg]); ++ ++FirstReg; ++ // assert(true && "debug#######################################"); + } + +- return Chain; +-} +- +-bool LoongArchTargetLowering::CanLowerReturn( +- CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, +- const SmallVectorImpl &Outs, LLVMContext &Context) const { +- SmallVector RVLocs; +- CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context); ++ // Mark the registers allocated. ++ // Size = alignTo(Size, RegSizeInBytes); ++ // for (unsigned I = FirstReg; Size > 0 && (I < IntArgRegs.size()); ++ // Size -= RegSizeInBytes, ++I, ++NumRegs) ++ // State->AllocateReg(IntArgRegs[I], ShadowRegs[I]); + +- for (unsigned i = 0, e = Outs.size(); i != e; ++i) { +- LoongArchABI::ABI ABI = +- MF.getSubtarget().getTargetABI(); +- if (CC_LoongArch(MF.getDataLayout(), ABI, i, Outs[i].VT, CCValAssign::Full, +- Outs[i].Flags, CCInfo, /*IsFixed=*/true, /*IsRet=*/true, +- nullptr)) +- return false; +- } +- return true; ++ State->addInRegsParamInfo(FirstReg, FirstReg + NumRegs); + } + +-SDValue LoongArchTargetLowering::LowerReturn( +- SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, +- const SmallVectorImpl &Outs, +- const SmallVectorImpl &OutVals, const SDLoc &DL, +- SelectionDAG &DAG) const { +- // Stores the assignment of the return value to a location. +- SmallVector RVLocs; +- +- // Info about the registers and stack slot. +- CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs, +- *DAG.getContext()); +- +- analyzeOutputArgs(DAG.getMachineFunction(), CCInfo, Outs, /*IsRet=*/true, +- nullptr, CC_LoongArch); +- if (CallConv == CallingConv::GHC && !RVLocs.empty()) +- report_fatal_error("GHC functions return void only"); +- SDValue Glue; +- SmallVector RetOps(1, Chain); +- +- // Copy the result values into the output registers. +- for (unsigned i = 0, e = RVLocs.size(); i < e; ++i) { +- CCValAssign &VA = RVLocs[i]; +- assert(VA.isRegLoc() && "Can only return in registers!"); ++MachineBasicBlock *LoongArchTargetLowering::emitPseudoSELECT(MachineInstr &MI, ++ MachineBasicBlock *BB, ++ bool isFPCmp, ++ unsigned Opc) const { ++ const TargetInstrInfo *TII = ++ Subtarget.getInstrInfo(); ++ DebugLoc DL = MI.getDebugLoc(); + +- // Handle a 'normal' return. +- SDValue Val = convertValVTToLocVT(DAG, OutVals[i], VA, DL); +- Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Val, Glue); ++ // To "insert" a SELECT instruction, we actually have to insert the ++ // diamond control-flow pattern. The incoming instruction knows the ++ // destination vreg to set, the condition code register to branch on, the ++ // true/false values to select between, and a branch opcode to use. ++ const BasicBlock *LLVM_BB = BB->getBasicBlock(); ++ MachineFunction::iterator It = ++BB->getIterator(); + +- // Guarantee that all emitted copies are stuck together. +- Glue = Chain.getValue(1); +- RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); ++ // thisMBB: ++ // ... ++ // TrueVal = ... ++ // setcc r1, r2, r3 ++ // bNE r1, r0, copy1MBB ++ // fallthrough --> copy0MBB ++ MachineBasicBlock *thisMBB = BB; ++ MachineFunction *F = BB->getParent(); ++ MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB); ++ F->insert(It, copy0MBB); ++ F->insert(It, sinkMBB); ++ ++ // Transfer the remainder of BB and its successor edges to sinkMBB. ++ sinkMBB->splice(sinkMBB->begin(), BB, ++ std::next(MachineBasicBlock::iterator(MI)), BB->end()); ++ sinkMBB->transferSuccessorsAndUpdatePHIs(BB); ++ ++ // Next, add the true and fallthrough blocks as its successors. ++ BB->addSuccessor(copy0MBB); ++ BB->addSuccessor(sinkMBB); ++ ++ if (isFPCmp) { ++ // bc1[tf] cc, sinkMBB ++ BuildMI(BB, DL, TII->get(Opc)) ++ .addReg(MI.getOperand(1).getReg()) ++ .addMBB(sinkMBB); ++ } else { ++ BuildMI(BB, DL, TII->get(Opc)) ++ .addReg(MI.getOperand(1).getReg()) ++ .addReg(LoongArch::ZERO) ++ .addMBB(sinkMBB); + } + +- RetOps[0] = Chain; // Update chain. ++ // copy0MBB: ++ // %FalseValue = ... ++ // # fallthrough to sinkMBB ++ BB = copy0MBB; + +- // Add the glue node if we have it. +- if (Glue.getNode()) +- RetOps.push_back(Glue); ++ // Update machine-CFG edges ++ BB->addSuccessor(sinkMBB); + +- return DAG.getNode(LoongArchISD::RET, DL, MVT::Other, RetOps); +-} ++ // sinkMBB: ++ // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ] ++ // ... ++ BB = sinkMBB; + +-bool LoongArchTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT, +- bool ForCodeSize) const { +- // TODO: Maybe need more checks here after vector extension is supported. +- if (VT == MVT::f32 && !Subtarget.hasBasicF()) +- return false; +- if (VT == MVT::f64 && !Subtarget.hasBasicD()) +- return false; +- return (Imm.isZero() || Imm.isExactlyValue(+1.0)); +-} ++ BuildMI(*BB, BB->begin(), DL, TII->get(LoongArch::PHI), MI.getOperand(0).getReg()) ++ .addReg(MI.getOperand(2).getReg()) ++ .addMBB(thisMBB) ++ .addReg(MI.getOperand(3).getReg()) ++ .addMBB(copy0MBB); + +-bool LoongArchTargetLowering::isCheapToSpeculateCttz(Type *) const { +- return true; +-} ++ MI.eraseFromParent(); // The pseudo instruction is gone now. + +-bool LoongArchTargetLowering::isCheapToSpeculateCtlz(Type *) const { +- return true; ++ return BB; + } + +-bool LoongArchTargetLowering::shouldInsertFencesForAtomic( +- const Instruction *I) const { +- if (!Subtarget.is64Bit()) +- return isa(I) || isa(I); ++MachineBasicBlock *LoongArchTargetLowering::emitLSXCBranchPseudo( ++ MachineInstr &MI, MachineBasicBlock *BB, unsigned BranchOp) const { + +- if (isa(I)) +- return true; +- +- // On LA64, atomic store operations with IntegerBitWidth of 32 and 64 do not +- // require fences beacuse we can use amswap_db.[w/d]. +- if (isa(I)) { +- unsigned Size = I->getOperand(0)->getType()->getIntegerBitWidth(); +- return (Size == 8 || Size == 16); +- } ++ MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ const TargetRegisterClass *RC = &LoongArch::GPR32RegClass; ++ DebugLoc DL = MI.getDebugLoc(); ++ const BasicBlock *LLVM_BB = BB->getBasicBlock(); ++ MachineFunction::iterator It = std::next(MachineFunction::iterator(BB)); ++ MachineFunction *F = BB->getParent(); ++ MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB); ++ F->insert(It, FBB); ++ F->insert(It, TBB); ++ F->insert(It, Sink); ++ ++ // Transfer the remainder of BB and its successor edges to Sink. ++ Sink->splice(Sink->begin(), BB, std::next(MachineBasicBlock::iterator(MI)), ++ BB->end()); ++ Sink->transferSuccessorsAndUpdatePHIs(BB); ++ ++ // Add successors. ++ BB->addSuccessor(FBB); ++ BB->addSuccessor(TBB); ++ FBB->addSuccessor(Sink); ++ TBB->addSuccessor(Sink); ++ // Insert the real bnz.b instruction to $BB. ++ BuildMI(BB, DL, TII->get(BranchOp)) ++ .addReg(LoongArch::FCC0) ++ .addReg(MI.getOperand(1).getReg()); ++ ++ BuildMI(BB, DL, TII->get(LoongArch::BCNEZ)) ++ .addReg(LoongArch::FCC0) ++ .addMBB(TBB); ++ ++ // Fill $FBB. ++ unsigned RD1 = RegInfo.createVirtualRegister(RC); ++ BuildMI(*FBB, FBB->end(), DL, TII->get(LoongArch::ADDI_W), RD1) ++ .addReg(LoongArch::ZERO) ++ .addImm(0); ++ BuildMI(*FBB, FBB->end(), DL, TII->get(LoongArch::B32)).addMBB(Sink); + +- return false; +-} ++ // Fill $TBB. ++ unsigned RD2 = RegInfo.createVirtualRegister(RC); ++ BuildMI(*TBB, TBB->end(), DL, TII->get(LoongArch::ADDI_W), RD2) ++ .addReg(LoongArch::ZERO) ++ .addImm(1); + +-EVT LoongArchTargetLowering::getSetCCResultType(const DataLayout &DL, +- LLVMContext &Context, +- EVT VT) const { +- if (!VT.isVector()) +- return getPointerTy(DL); +- return VT.changeVectorElementTypeToInteger(); +-} ++ // Insert phi function to $Sink. ++ BuildMI(*Sink, Sink->begin(), DL, TII->get(LoongArch::PHI), ++ MI.getOperand(0).getReg()) ++ .addReg(RD1) ++ .addMBB(FBB) ++ .addReg(RD2) ++ .addMBB(TBB); + +-bool LoongArchTargetLowering::hasAndNot(SDValue Y) const { +- // TODO: Support vectors. +- return Y.getValueType().isScalarInteger() && !isa(Y); ++ MI.eraseFromParent(); // The pseudo instruction is gone now. ++ return Sink; + } + +-bool LoongArchTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info, +- const CallInst &I, +- MachineFunction &MF, +- unsigned Intrinsic) const { +- switch (Intrinsic) { +- default: +- return false; +- case Intrinsic::loongarch_masked_atomicrmw_xchg_i32: +- case Intrinsic::loongarch_masked_atomicrmw_add_i32: +- case Intrinsic::loongarch_masked_atomicrmw_sub_i32: +- case Intrinsic::loongarch_masked_atomicrmw_nand_i32: +- Info.opc = ISD::INTRINSIC_W_CHAIN; +- Info.memVT = MVT::i32; +- Info.ptrVal = I.getArgOperand(0); +- Info.offset = 0; +- Info.align = Align(4); +- Info.flags = MachineMemOperand::MOLoad | MachineMemOperand::MOStore | +- MachineMemOperand::MOVolatile; +- return true; +- // TODO: Add more Intrinsics later. ++// Emit the COPY_FW pseudo instruction. ++// ++// copy_fw_pseudo $fd, $vk, n ++// => ++// vreplvei.w $rt, $vk, $n ++// copy $rt, $fd ++// ++// When n is zero, the equivalent operation can be performed with (potentially) ++// zero instructions due to register overlaps. ++MachineBasicBlock * ++LoongArchTargetLowering::emitCOPY_FW(MachineInstr &MI, ++ MachineBasicBlock *BB) const { ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); ++ DebugLoc DL = MI.getDebugLoc(); ++ unsigned Fd = MI.getOperand(0).getReg(); ++ unsigned Vk = MI.getOperand(1).getReg(); ++ unsigned Lane = MI.getOperand(2).getImm(); ++ ++ if (Lane == 0) { ++ unsigned Vj = Vk; ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::COPY), Fd) ++ .addReg(Vj, 0, LoongArch::sub_lo); ++ } else { ++ unsigned Vj = RegInfo.createVirtualRegister(&LoongArch::LSX128WRegClass); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::VREPLVEI_W), Vj) ++ .addReg(Vk) ++ .addImm(Lane); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::COPY), Fd) ++ .addReg(Vj, 0, LoongArch::sub_lo); + } ++ ++ MI.eraseFromParent(); // The pseudo instruction is gone now. ++ return BB; + } + +-TargetLowering::AtomicExpansionKind +-LoongArchTargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const { +- // TODO: Add more AtomicRMWInst that needs to be extended. ++// Emit the COPY_FD pseudo instruction. ++// ++// copy_fd_pseudo $fd, $vj, n ++// => ++// vreplvei.d $vd, $vj, $n ++// copy $fd, $vd:sub_64 ++// ++// When n is zero, the equivalent operation can be performed with (potentially) ++// zero instructions due to register overlaps. ++MachineBasicBlock * ++LoongArchTargetLowering::emitCOPY_FD(MachineInstr &MI, ++ MachineBasicBlock *BB) const { ++ assert(Subtarget.isFP64bit()); + +- // Since floating-point operation requires a non-trivial set of data +- // operations, use CmpXChg to expand. +- if (AI->isFloatingPointOperation() || +- AI->getOperation() == AtomicRMWInst::UIncWrap || +- AI->getOperation() == AtomicRMWInst::UDecWrap) +- return AtomicExpansionKind::CmpXChg; ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); ++ unsigned Fd = MI.getOperand(0).getReg(); ++ unsigned Vk = MI.getOperand(1).getReg(); ++ unsigned Lane = MI.getOperand(2).getImm(); ++ DebugLoc DL = MI.getDebugLoc(); + +- unsigned Size = AI->getType()->getPrimitiveSizeInBits(); +- if (Size == 8 || Size == 16) +- return AtomicExpansionKind::MaskedIntrinsic; +- return AtomicExpansionKind::None; +-} ++ if (Lane == 0) ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::COPY), Fd) ++ .addReg(Vk, 0, LoongArch::sub_64); ++ else { ++ unsigned Vj = RegInfo.createVirtualRegister(&LoongArch::LSX128DRegClass); ++ assert(Lane == 1); + +-static Intrinsic::ID +-getIntrinsicForMaskedAtomicRMWBinOp(unsigned GRLen, +- AtomicRMWInst::BinOp BinOp) { +- if (GRLen == 64) { +- switch (BinOp) { +- default: +- llvm_unreachable("Unexpected AtomicRMW BinOp"); +- case AtomicRMWInst::Xchg: +- return Intrinsic::loongarch_masked_atomicrmw_xchg_i64; +- case AtomicRMWInst::Add: +- return Intrinsic::loongarch_masked_atomicrmw_add_i64; +- case AtomicRMWInst::Sub: +- return Intrinsic::loongarch_masked_atomicrmw_sub_i64; +- case AtomicRMWInst::Nand: +- return Intrinsic::loongarch_masked_atomicrmw_nand_i64; +- case AtomicRMWInst::UMax: +- return Intrinsic::loongarch_masked_atomicrmw_umax_i64; +- case AtomicRMWInst::UMin: +- return Intrinsic::loongarch_masked_atomicrmw_umin_i64; +- case AtomicRMWInst::Max: +- return Intrinsic::loongarch_masked_atomicrmw_max_i64; +- case AtomicRMWInst::Min: +- return Intrinsic::loongarch_masked_atomicrmw_min_i64; +- // TODO: support other AtomicRMWInst. +- } ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::VREPLVEI_D), Vj) ++ .addReg(Vk) ++ .addImm(Lane); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::COPY), Fd) ++ .addReg(Vj, 0, LoongArch::sub_64); + } + +- if (GRLen == 32) { +- switch (BinOp) { +- default: +- llvm_unreachable("Unexpected AtomicRMW BinOp"); +- case AtomicRMWInst::Xchg: +- return Intrinsic::loongarch_masked_atomicrmw_xchg_i32; +- case AtomicRMWInst::Add: +- return Intrinsic::loongarch_masked_atomicrmw_add_i32; +- case AtomicRMWInst::Sub: +- return Intrinsic::loongarch_masked_atomicrmw_sub_i32; +- case AtomicRMWInst::Nand: +- return Intrinsic::loongarch_masked_atomicrmw_nand_i32; +- // TODO: support other AtomicRMWInst. +- } ++ MI.eraseFromParent(); // The pseudo instruction is gone now. ++ return BB; ++} ++ ++MachineBasicBlock * ++LoongArchTargetLowering::emitXCOPY_FW(MachineInstr &MI, ++ MachineBasicBlock *BB) const { ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); ++ DebugLoc DL = MI.getDebugLoc(); ++ unsigned Fd = MI.getOperand(0).getReg(); ++ unsigned Xk = MI.getOperand(1).getReg(); ++ unsigned Lane = MI.getOperand(2).getImm(); ++ unsigned Rj = RegInfo.createVirtualRegister(&LoongArch::GPR32RegClass); ++ unsigned Xj = Xk; ++ ++ if (Lane == 0) { ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::COPY), Fd) ++ .addReg(Xj, 0, LoongArch::sub_lo); ++ } else { ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::XVPICKVE2GR_WU), Rj) ++ .addReg(Xk) ++ .addImm(Lane); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::COPY), Fd).addReg(Rj); + } + +- llvm_unreachable("Unexpected GRLen\n"); +-} +- +-TargetLowering::AtomicExpansionKind +-LoongArchTargetLowering::shouldExpandAtomicCmpXchgInIR( +- AtomicCmpXchgInst *CI) const { +- unsigned Size = CI->getCompareOperand()->getType()->getPrimitiveSizeInBits(); +- if (Size == 8 || Size == 16) +- return AtomicExpansionKind::MaskedIntrinsic; +- return AtomicExpansionKind::None; +-} +- +-Value *LoongArchTargetLowering::emitMaskedAtomicCmpXchgIntrinsic( +- IRBuilderBase &Builder, AtomicCmpXchgInst *CI, Value *AlignedAddr, +- Value *CmpVal, Value *NewVal, Value *Mask, AtomicOrdering Ord) const { +- AtomicOrdering FailOrd = CI->getFailureOrdering(); +- Value *FailureOrdering = +- Builder.getIntN(Subtarget.getGRLen(), static_cast(FailOrd)); +- +- // TODO: Support cmpxchg on LA32. +- Intrinsic::ID CmpXchgIntrID = Intrinsic::loongarch_masked_cmpxchg_i64; +- CmpVal = Builder.CreateSExt(CmpVal, Builder.getInt64Ty()); +- NewVal = Builder.CreateSExt(NewVal, Builder.getInt64Ty()); +- Mask = Builder.CreateSExt(Mask, Builder.getInt64Ty()); +- Type *Tys[] = {AlignedAddr->getType()}; +- Function *MaskedCmpXchg = +- Intrinsic::getDeclaration(CI->getModule(), CmpXchgIntrID, Tys); +- Value *Result = Builder.CreateCall( +- MaskedCmpXchg, {AlignedAddr, CmpVal, NewVal, Mask, FailureOrdering}); +- Result = Builder.CreateTrunc(Result, Builder.getInt32Ty()); +- return Result; ++ MI.eraseFromParent(); // The pseudo instruction is gone now. ++ return BB; + } + +-Value *LoongArchTargetLowering::emitMaskedAtomicRMWIntrinsic( +- IRBuilderBase &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr, +- Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const { +- // In the case of an atomicrmw xchg with a constant 0/-1 operand, replace +- // the atomic instruction with an AtomicRMWInst::And/Or with appropriate +- // mask, as this produces better code than the LL/SC loop emitted by +- // int_loongarch_masked_atomicrmw_xchg. +- if (AI->getOperation() == AtomicRMWInst::Xchg && +- isa(AI->getValOperand())) { +- ConstantInt *CVal = cast(AI->getValOperand()); +- if (CVal->isZero()) +- return Builder.CreateAtomicRMW(AtomicRMWInst::And, AlignedAddr, +- Builder.CreateNot(Mask, "Inv_Mask"), +- AI->getAlign(), Ord); +- if (CVal->isMinusOne()) +- return Builder.CreateAtomicRMW(AtomicRMWInst::Or, AlignedAddr, Mask, +- AI->getAlign(), Ord); +- } +- +- unsigned GRLen = Subtarget.getGRLen(); +- Value *Ordering = +- Builder.getIntN(GRLen, static_cast(AI->getOrdering())); +- Type *Tys[] = {AlignedAddr->getType()}; +- Function *LlwOpScwLoop = Intrinsic::getDeclaration( +- AI->getModule(), +- getIntrinsicForMaskedAtomicRMWBinOp(GRLen, AI->getOperation()), Tys); +- +- if (GRLen == 64) { +- Incr = Builder.CreateSExt(Incr, Builder.getInt64Ty()); +- Mask = Builder.CreateSExt(Mask, Builder.getInt64Ty()); +- ShiftAmt = Builder.CreateSExt(ShiftAmt, Builder.getInt64Ty()); +- } +- +- Value *Result; +- +- // Must pass the shift amount needed to sign extend the loaded value prior +- // to performing a signed comparison for min/max. ShiftAmt is the number of +- // bits to shift the value into position. Pass GRLen-ShiftAmt-ValWidth, which +- // is the number of bits to left+right shift the value in order to +- // sign-extend. +- if (AI->getOperation() == AtomicRMWInst::Min || +- AI->getOperation() == AtomicRMWInst::Max) { +- const DataLayout &DL = AI->getModule()->getDataLayout(); +- unsigned ValWidth = +- DL.getTypeStoreSizeInBits(AI->getValOperand()->getType()); +- Value *SextShamt = +- Builder.CreateSub(Builder.getIntN(GRLen, GRLen - ValWidth), ShiftAmt); +- Result = Builder.CreateCall(LlwOpScwLoop, +- {AlignedAddr, Incr, Mask, SextShamt, Ordering}); ++MachineBasicBlock * ++LoongArchTargetLowering::emitXCOPY_FD(MachineInstr &MI, ++ MachineBasicBlock *BB) const { ++ assert(Subtarget.isFP64bit()); ++ ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); ++ unsigned Fd = MI.getOperand(0).getReg(); ++ unsigned Xk = MI.getOperand(1).getReg(); ++ unsigned Lane = MI.getOperand(2).getImm(); ++ DebugLoc DL = MI.getDebugLoc(); ++ ++ unsigned Rj = RegInfo.createVirtualRegister(&LoongArch::GPR64RegClass); ++ if (Lane == 0) { ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::COPY), Fd) ++ .addReg(Xk, 0, LoongArch::sub_64); + } else { +- Result = +- Builder.CreateCall(LlwOpScwLoop, {AlignedAddr, Incr, Mask, Ordering}); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::XVPICKVE2GR_DU), Rj) ++ .addReg(Xk) ++ .addImm(Lane); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::COPY), Fd).addReg(Rj); + } + +- if (GRLen == 64) +- Result = Builder.CreateTrunc(Result, Builder.getInt32Ty()); +- return Result; ++ MI.eraseFromParent(); // The pseudo instruction is gone now. ++ return BB; + } + +-bool LoongArchTargetLowering::isFMAFasterThanFMulAndFAdd( +- const MachineFunction &MF, EVT VT) const { +- VT = VT.getScalarType(); ++MachineBasicBlock *LoongArchTargetLowering::emitCONCAT_VECTORS( ++ MachineInstr &MI, MachineBasicBlock *BB, unsigned Bytes) const { + +- if (!VT.isSimple()) +- return false; ++ MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ DebugLoc DL = MI.getDebugLoc(); ++ unsigned Xd = MI.getOperand(0).getReg(); ++ unsigned SubReg1 = MI.getOperand(1).getReg(); ++ unsigned SubReg2 = MI.getOperand(2).getReg(); ++ const TargetRegisterClass *RC = nullptr; + +- switch (VT.getSimpleVT().SimpleTy) { +- case MVT::f32: +- case MVT::f64: +- return true; ++ switch (Bytes) { + default: ++ llvm_unreachable("Unexpected size"); ++ case 1: ++ RC = &LoongArch::LASX256BRegClass; ++ break; ++ case 2: ++ RC = &LoongArch::LASX256HRegClass; ++ break; ++ case 4: ++ RC = &LoongArch::LASX256WRegClass; ++ break; ++ case 8: ++ RC = &LoongArch::LASX256DRegClass; + break; + } + +- return false; +-} ++ unsigned X0 = RegInfo.createVirtualRegister(RC); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::SUBREG_TO_REG), X0) ++ .addImm(0) ++ .addReg(SubReg1) ++ .addImm(LoongArch::sub_128); ++ unsigned X1 = RegInfo.createVirtualRegister(RC); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::SUBREG_TO_REG), X1) ++ .addImm(0) ++ .addReg(SubReg2) ++ .addImm(LoongArch::sub_128); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::XVPERMI_Q), Xd) ++ .addReg(X0) ++ .addReg(X1) ++ .addImm(2); + +-Register LoongArchTargetLowering::getExceptionPointerRegister( +- const Constant *PersonalityFn) const { +- return LoongArch::R4; ++ MI.eraseFromParent(); // The pseudo instruction is gone now. ++ return BB; + } + +-Register LoongArchTargetLowering::getExceptionSelectorRegister( +- const Constant *PersonalityFn) const { +- return LoongArch::R5; ++// xcopy_fw_gpr_pseudo $fd, $xs, $rk ++// => ++// bb: addi.d $rt1, zero, 4 ++// bge $lane, $rt1 hbb ++// lbb:xvreplve.w $xt1, $xs, $lane ++// copy $rf0, $xt1 ++// b sink ++// hbb: addi.d $rt2, $lane, -4 ++// xvpermi.q $xt2 $xs, 1 ++// xvreplve.w $xt3, $xt2, $rt2 ++// copy $rf1, $xt3 ++// sink:phi ++MachineBasicBlock * ++LoongArchTargetLowering::emitXCOPY_FW_GPR(MachineInstr &MI, ++ MachineBasicBlock *BB) const { ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); ++ DebugLoc DL = MI.getDebugLoc(); ++ unsigned Xs = MI.getOperand(1).getReg(); ++ unsigned Lane = MI.getOperand(2).getReg(); ++ ++ const TargetRegisterClass *RC = &LoongArch::GPR64RegClass; ++ const BasicBlock *LLVM_BB = BB->getBasicBlock(); ++ MachineFunction::iterator It = std::next(MachineFunction::iterator(BB)); ++ MachineFunction *F = BB->getParent(); ++ MachineBasicBlock *HBB = F->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *LBB = F->CreateMachineBasicBlock(LLVM_BB); ++ MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB); ++ F->insert(It, LBB); ++ F->insert(It, HBB); ++ F->insert(It, Sink); ++ ++ Sink->splice(Sink->begin(), BB, std::next(MachineBasicBlock::iterator(MI)), ++ BB->end()); ++ Sink->transferSuccessorsAndUpdatePHIs(BB); ++ ++ BB->addSuccessor(LBB); ++ BB->addSuccessor(HBB); ++ HBB->addSuccessor(Sink); ++ LBB->addSuccessor(Sink); ++ ++ unsigned Rt1 = RegInfo.createVirtualRegister(RC); ++ BuildMI(BB, DL, TII->get(LoongArch::ADDI_D), Rt1) ++ .addReg(LoongArch::ZERO_64) ++ .addImm(4); ++ BuildMI(BB, DL, TII->get(LoongArch::BGE)) ++ .addReg(Lane) ++ .addReg(Rt1) ++ .addMBB(HBB); ++ ++ unsigned Xt1 = RegInfo.createVirtualRegister(&LoongArch::LASX256WRegClass); ++ unsigned Rf0 = RegInfo.createVirtualRegister(&LoongArch::FGR32RegClass); ++ BuildMI(*LBB, LBB->end(), DL, TII->get(LoongArch::XVREPLVE_W_N), Xt1) ++ .addReg(Xs) ++ .addReg(Lane); ++ BuildMI(*LBB, LBB->end(), DL, TII->get(LoongArch::COPY), Rf0) ++ .addReg(Xt1, 0, LoongArch::sub_lo); ++ BuildMI(*LBB, LBB->end(), DL, TII->get(LoongArch::B)).addMBB(Sink); ++ ++ unsigned Xt2 = RegInfo.createVirtualRegister(&LoongArch::LASX256WRegClass); ++ unsigned Xt3 = RegInfo.createVirtualRegister(&LoongArch::LASX256WRegClass); ++ unsigned Rt2 = RegInfo.createVirtualRegister(RC); ++ unsigned Rf1 = RegInfo.createVirtualRegister(&LoongArch::FGR32RegClass); ++ BuildMI(*HBB, HBB->end(), DL, TII->get(LoongArch::ADDI_D), Rt2) ++ .addReg(Lane) ++ .addImm(-4); ++ BuildMI(*HBB, HBB->end(), DL, TII->get(LoongArch::XVPERMI_Q), Xt2) ++ .addReg(Xs) ++ .addReg(Xs) ++ .addImm(1); ++ BuildMI(*HBB, HBB->end(), DL, TII->get(LoongArch::XVREPLVE_W_N), Xt3) ++ .addReg(Xt2) ++ .addReg(Rt2); ++ BuildMI(*HBB, HBB->end(), DL, TII->get(LoongArch::COPY), Rf1) ++ .addReg(Xt3, 0, LoongArch::sub_lo); ++ ++ BuildMI(*Sink, Sink->begin(), DL, TII->get(LoongArch::PHI), ++ MI.getOperand(0).getReg()) ++ .addReg(Rf0) ++ .addMBB(LBB) ++ .addReg(Rf1) ++ .addMBB(HBB); ++ ++ MI.eraseFromParent(); // The pseudo instruction is gone now. ++ return Sink; + } + +-//===----------------------------------------------------------------------===// +-// LoongArch Inline Assembly Support +-//===----------------------------------------------------------------------===// ++MachineBasicBlock * ++LoongArchTargetLowering::emitXINSERT_BH(MachineInstr &MI, MachineBasicBlock *BB, ++ unsigned Size) const { ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); ++ DebugLoc DL = MI.getDebugLoc(); ++ unsigned Xd = MI.getOperand(0).getReg(); ++ unsigned Xd_in = MI.getOperand(1).getReg(); ++ unsigned Lane = MI.getOperand(2).getImm(); ++ unsigned Fs = MI.getOperand(3).getReg(); ++ const TargetRegisterClass *VecRC = nullptr; ++ const TargetRegisterClass *SubVecRC = nullptr; ++ unsigned HalfSize = 0; ++ unsigned InsertOp = 0; ++ ++ if (Size == 1) { ++ VecRC = &LoongArch::LASX256BRegClass; ++ SubVecRC = &LoongArch::LSX128BRegClass; ++ HalfSize = 16; ++ InsertOp = LoongArch::VINSGR2VR_B; ++ } else if (Size == 2) { ++ VecRC = &LoongArch::LASX256HRegClass; ++ SubVecRC = &LoongArch::LSX128HRegClass; ++ HalfSize = 8; ++ InsertOp = LoongArch::VINSGR2VR_H; ++ } else { ++ llvm_unreachable("Unexpected type"); ++ } + +-LoongArchTargetLowering::ConstraintType +-LoongArchTargetLowering::getConstraintType(StringRef Constraint) const { +- // LoongArch specific constraints in GCC: config/loongarch/constraints.md +- // +- // 'f': A floating-point register (if available). +- // 'k': A memory operand whose address is formed by a base register and +- // (optionally scaled) index register. +- // 'l': A signed 16-bit constant. +- // 'm': A memory operand whose address is formed by a base register and +- // offset that is suitable for use in instructions with the same +- // addressing mode as st.w and ld.w. +- // 'I': A signed 12-bit constant (for arithmetic instructions). +- // 'J': Integer zero. +- // 'K': An unsigned 12-bit constant (for logic instructions). +- // "ZB": An address that is held in a general-purpose register. The offset is +- // zero. +- // "ZC": A memory operand whose address is formed by a base register and +- // offset that is suitable for use in instructions with the same +- // addressing mode as ll.w and sc.w. +- if (Constraint.size() == 1) { +- switch (Constraint[0]) { +- default: +- break; +- case 'f': +- return C_RegisterClass; +- case 'l': +- case 'I': +- case 'J': +- case 'K': +- return C_Immediate; +- case 'k': +- return C_Memory; +- } ++ unsigned Xk = Xd_in; ++ unsigned Imm = Lane; ++ if (Lane >= HalfSize) { ++ Xk = RegInfo.createVirtualRegister(VecRC); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::XVPERMI_Q), Xk) ++ .addReg(Xd_in) ++ .addReg(Xd_in) ++ .addImm(1); ++ Imm = Lane - HalfSize; + } + +- if (Constraint == "ZC" || Constraint == "ZB") +- return C_Memory; ++ unsigned Xk128 = RegInfo.createVirtualRegister(SubVecRC); ++ unsigned Xd128 = RegInfo.createVirtualRegister(SubVecRC); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::COPY), Xk128) ++ .addReg(Xk, 0, LoongArch::sub_128); ++ BuildMI(*BB, MI, DL, TII->get(InsertOp), Xd128) ++ .addReg(Xk128) ++ .addReg(Fs) ++ .addImm(Imm); + +- // 'm' is handled here. +- return TargetLowering::getConstraintType(Constraint); +-} ++ unsigned Xd256 = Xd; ++ if (Lane >= HalfSize) { ++ Xd256 = RegInfo.createVirtualRegister(VecRC); ++ } + +-InlineAsm::ConstraintCode LoongArchTargetLowering::getInlineAsmMemConstraint( +- StringRef ConstraintCode) const { +- return StringSwitch(ConstraintCode) +- .Case("k", InlineAsm::ConstraintCode::k) +- .Case("ZB", InlineAsm::ConstraintCode::ZB) +- .Case("ZC", InlineAsm::ConstraintCode::ZC) +- .Default(TargetLowering::getInlineAsmMemConstraint(ConstraintCode)); +-} ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::SUBREG_TO_REG), Xd256) ++ .addImm(0) ++ .addReg(Xd128) ++ .addImm(LoongArch::sub_128); + +-std::pair +-LoongArchTargetLowering::getRegForInlineAsmConstraint( +- const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const { +- // First, see if this is a constraint that directly corresponds to a LoongArch +- // register class. +- if (Constraint.size() == 1) { +- switch (Constraint[0]) { +- case 'r': +- // TODO: Support fixed vectors up to GRLen? +- if (VT.isVector()) +- break; +- return std::make_pair(0U, &LoongArch::GPRRegClass); +- case 'f': +- if (Subtarget.hasBasicF() && VT == MVT::f32) +- return std::make_pair(0U, &LoongArch::FPR32RegClass); +- if (Subtarget.hasBasicD() && VT == MVT::f64) +- return std::make_pair(0U, &LoongArch::FPR64RegClass); +- if (Subtarget.hasExtLSX() && +- TRI->isTypeLegalForClass(LoongArch::LSX128RegClass, VT)) +- return std::make_pair(0U, &LoongArch::LSX128RegClass); +- if (Subtarget.hasExtLASX() && +- TRI->isTypeLegalForClass(LoongArch::LASX256RegClass, VT)) +- return std::make_pair(0U, &LoongArch::LASX256RegClass); +- break; +- default: +- break; +- } ++ if (Lane >= HalfSize) { ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::XVPERMI_Q), Xd) ++ .addReg(Xd_in) ++ .addReg(Xd256) ++ .addImm(2); + } + +- // TargetLowering::getRegForInlineAsmConstraint uses the name of the TableGen +- // record (e.g. the "R0" in `def R0`) to choose registers for InlineAsm +- // constraints while the official register name is prefixed with a '$'. So we +- // clip the '$' from the original constraint string (e.g. {$r0} to {r0}.) +- // before it being parsed. And TargetLowering::getRegForInlineAsmConstraint is +- // case insensitive, so no need to convert the constraint to upper case here. +- // +- // For now, no need to support ABI names (e.g. `$a0`) as clang will correctly +- // decode the usage of register name aliases into their official names. And +- // AFAIK, the not yet upstreamed `rustc` for LoongArch will always use +- // official register names. +- if (Constraint.starts_with("{$r") || Constraint.starts_with("{$f") || +- Constraint.starts_with("{$vr") || Constraint.starts_with("{$xr")) { +- bool IsFP = Constraint[2] == 'f'; +- std::pair Temp = Constraint.split('$'); +- std::pair R; +- R = TargetLowering::getRegForInlineAsmConstraint( +- TRI, join_items("", Temp.first, Temp.second), VT); +- // Match those names to the widest floating point register type available. +- if (IsFP) { +- unsigned RegNo = R.first; +- if (LoongArch::F0 <= RegNo && RegNo <= LoongArch::F31) { +- if (Subtarget.hasBasicD() && (VT == MVT::f64 || VT == MVT::Other)) { +- unsigned DReg = RegNo - LoongArch::F0 + LoongArch::F0_64; +- return std::make_pair(DReg, &LoongArch::FPR64RegClass); +- } +- } +- } +- return R; +- } ++ MI.eraseFromParent(); // The pseudo instruction is gone now. ++ return BB; ++} + +- return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT); ++MachineBasicBlock * ++LoongArchTargetLowering::emitXINSERT_FW(MachineInstr &MI, ++ MachineBasicBlock *BB) const { ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); ++ DebugLoc DL = MI.getDebugLoc(); ++ unsigned Xd = MI.getOperand(0).getReg(); ++ unsigned Xd_in = MI.getOperand(1).getReg(); ++ unsigned Lane = MI.getOperand(2).getImm(); ++ unsigned Fs = MI.getOperand(3).getReg(); ++ unsigned Xj = RegInfo.createVirtualRegister(&LoongArch::LASX256WRegClass); ++ unsigned Rj = RegInfo.createVirtualRegister(&LoongArch::GPR32RegClass); ++ ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::SUBREG_TO_REG), Xj) ++ .addImm(0) ++ .addReg(Fs) ++ .addImm(LoongArch::sub_lo); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::XVPICKVE2GR_WU), Rj) ++ .addReg(Xj) ++ .addImm(0); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::XVINSGR2VR_W), Xd) ++ .addReg(Xd_in) ++ .addReg(Rj) ++ .addImm(Lane); ++ ++ MI.eraseFromParent(); // The pseudo instruction is gone now. ++ return BB; + } + +-void LoongArchTargetLowering::LowerAsmOperandForConstraint( +- SDValue Op, StringRef Constraint, std::vector &Ops, +- SelectionDAG &DAG) const { +- // Currently only support length 1 constraints. +- if (Constraint.size() == 1) { +- switch (Constraint[0]) { +- case 'l': +- // Validate & create a 16-bit signed immediate operand. +- if (auto *C = dyn_cast(Op)) { +- uint64_t CVal = C->getSExtValue(); +- if (isInt<16>(CVal)) +- Ops.push_back( +- DAG.getTargetConstant(CVal, SDLoc(Op), Subtarget.getGRLenVT())); +- } +- return; +- case 'I': +- // Validate & create a 12-bit signed immediate operand. +- if (auto *C = dyn_cast(Op)) { +- uint64_t CVal = C->getSExtValue(); +- if (isInt<12>(CVal)) +- Ops.push_back( +- DAG.getTargetConstant(CVal, SDLoc(Op), Subtarget.getGRLenVT())); +- } +- return; +- case 'J': +- // Validate & create an integer zero operand. +- if (auto *C = dyn_cast(Op)) +- if (C->getZExtValue() == 0) +- Ops.push_back( +- DAG.getTargetConstant(0, SDLoc(Op), Subtarget.getGRLenVT())); +- return; +- case 'K': +- // Validate & create a 12-bit unsigned immediate operand. +- if (auto *C = dyn_cast(Op)) { +- uint64_t CVal = C->getZExtValue(); +- if (isUInt<12>(CVal)) +- Ops.push_back( +- DAG.getTargetConstant(CVal, SDLoc(Op), Subtarget.getGRLenVT())); +- } +- return; +- default: +- break; +- } +- } +- TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG); ++// Emit the INSERT_FW pseudo instruction. ++// ++// insert_fw_pseudo $vd, $vd_in, $n, $fs ++// => ++// subreg_to_reg $vj:sub_lo, $fs ++// vpickve2gr.w rj, vj, 0 ++// vinsgr2vr.w, vd, rj, lane ++MachineBasicBlock * ++LoongArchTargetLowering::emitINSERT_FW(MachineInstr &MI, ++ MachineBasicBlock *BB) const { ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); ++ DebugLoc DL = MI.getDebugLoc(); ++ unsigned Vd = MI.getOperand(0).getReg(); ++ unsigned Vd_in = MI.getOperand(1).getReg(); ++ unsigned Lane = MI.getOperand(2).getImm(); ++ unsigned Fs = MI.getOperand(3).getReg(); ++ unsigned Rj = RegInfo.createVirtualRegister(&LoongArch::GPR32RegClass); ++ unsigned Vj = RegInfo.createVirtualRegister(&LoongArch::LSX128WRegClass); ++ ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::SUBREG_TO_REG), Vj) ++ .addImm(0) ++ .addReg(Fs) ++ .addImm(LoongArch::sub_lo); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::VPICKVE2GR_W), Rj) ++ .addReg(Vj) ++ .addImm(0); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::VINSGR2VR_W), Vd) ++ .addReg(Vd_in) ++ .addReg(Rj) ++ .addImm(Lane); ++ ++ MI.eraseFromParent(); // The pseudo instruction is gone now. ++ return BB; + } + +-#define GET_REGISTER_MATCHER +-#include "LoongArchGenAsmMatcher.inc" ++// Emit the INSERT_FD pseudo instruction. ++// insert_fd_pseudo $vd, $fs, n ++// => ++// subreg_to_reg $vk:sub_64, $fs ++// vpickve2gr.d rj, vk, 0 ++// vinsgr2vr.d vd, rj, lane ++MachineBasicBlock * ++LoongArchTargetLowering::emitINSERT_FD(MachineInstr &MI, ++ MachineBasicBlock *BB) const { ++ assert(Subtarget.isFP64bit()); + +-Register +-LoongArchTargetLowering::getRegisterByName(const char *RegName, LLT VT, +- const MachineFunction &MF) const { +- std::pair Name = StringRef(RegName).split('$'); +- std::string NewRegName = Name.second.str(); +- Register Reg = MatchRegisterAltName(NewRegName); +- if (Reg == LoongArch::NoRegister) +- Reg = MatchRegisterName(NewRegName); +- if (Reg == LoongArch::NoRegister) +- report_fatal_error( +- Twine("Invalid register name \"" + StringRef(RegName) + "\".")); +- BitVector ReservedRegs = Subtarget.getRegisterInfo()->getReservedRegs(MF); +- if (!ReservedRegs.test(Reg)) +- report_fatal_error(Twine("Trying to obtain non-reserved register \"" + +- StringRef(RegName) + "\".")); +- return Reg; +-} +- +-bool LoongArchTargetLowering::decomposeMulByConstant(LLVMContext &Context, +- EVT VT, SDValue C) const { +- // TODO: Support vectors. +- if (!VT.isScalarInteger()) +- return false; ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); ++ DebugLoc DL = MI.getDebugLoc(); ++ unsigned Vd = MI.getOperand(0).getReg(); ++ unsigned Vd_in = MI.getOperand(1).getReg(); ++ unsigned Lane = MI.getOperand(2).getImm(); ++ unsigned Fs = MI.getOperand(3).getReg(); ++ unsigned Vj = RegInfo.createVirtualRegister(&LoongArch::LSX128DRegClass); ++ unsigned Rj = RegInfo.createVirtualRegister(&LoongArch::GPR64RegClass); ++ ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::SUBREG_TO_REG), Vj) ++ .addImm(0) ++ .addReg(Fs) ++ .addImm(LoongArch::sub_64); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::VPICKVE2GR_D), Rj) ++ .addReg(Vj) ++ .addImm(0); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::VINSGR2VR_D), Vd) ++ .addReg(Vd_in) ++ .addReg(Rj) ++ .addImm(Lane); + +- // Omit the optimization if the data size exceeds GRLen. +- if (VT.getSizeInBits() > Subtarget.getGRLen()) +- return false; ++ MI.eraseFromParent(); // The pseudo instruction is gone now. ++ return BB; ++} + +- if (auto *ConstNode = dyn_cast(C.getNode())) { +- const APInt &Imm = ConstNode->getAPIntValue(); +- // Break MUL into (SLLI + ADD/SUB) or ALSL. +- if ((Imm + 1).isPowerOf2() || (Imm - 1).isPowerOf2() || +- (1 - Imm).isPowerOf2() || (-1 - Imm).isPowerOf2()) +- return true; +- // Break MUL into (ALSL x, (SLLI x, imm0), imm1). +- if (ConstNode->hasOneUse() && +- ((Imm - 2).isPowerOf2() || (Imm - 4).isPowerOf2() || +- (Imm - 8).isPowerOf2() || (Imm - 16).isPowerOf2())) +- return true; +- // Break (MUL x, imm) into (ADD (SLLI x, s0), (SLLI x, s1)), +- // in which the immediate has two set bits. Or Break (MUL x, imm) +- // into (SUB (SLLI x, s0), (SLLI x, s1)), in which the immediate +- // equals to (1 << s0) - (1 << s1). +- if (ConstNode->hasOneUse() && !(Imm.sge(-2048) && Imm.sle(4095))) { +- unsigned Shifts = Imm.countr_zero(); +- // Reject immediates which can be composed via a single LUI. +- if (Shifts >= 12) +- return false; +- // Reject multiplications can be optimized to +- // (SLLI (ALSL x, x, 1/2/3/4), s). +- APInt ImmPop = Imm.ashr(Shifts); +- if (ImmPop == 3 || ImmPop == 5 || ImmPop == 9 || ImmPop == 17) +- return false; +- // We do not consider the case `(-Imm - ImmSmall).isPowerOf2()`, +- // since it needs one more instruction than other 3 cases. +- APInt ImmSmall = APInt(Imm.getBitWidth(), 1ULL << Shifts, true); +- if ((Imm - ImmSmall).isPowerOf2() || (Imm + ImmSmall).isPowerOf2() || +- (ImmSmall - Imm).isPowerOf2()) +- return true; +- } +- } ++MachineBasicBlock * ++LoongArchTargetLowering::emitXINSERT_FD(MachineInstr &MI, ++ MachineBasicBlock *BB) const { ++ assert(Subtarget.isFP64bit()); + +- return false; ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); ++ DebugLoc DL = MI.getDebugLoc(); ++ unsigned Xd = MI.getOperand(0).getReg(); ++ unsigned Xd_in = MI.getOperand(1).getReg(); ++ unsigned Lane = MI.getOperand(2).getImm(); ++ unsigned Fs = MI.getOperand(3).getReg(); ++ unsigned Xj = RegInfo.createVirtualRegister(&LoongArch::LASX256DRegClass); ++ ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::SUBREG_TO_REG), Xj) ++ .addImm(0) ++ .addReg(Fs) ++ .addImm(LoongArch::sub_64); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::XVINSVE0_D), Xd) ++ .addReg(Xd_in) ++ .addReg(Xj) ++ .addImm(Lane); ++ ++ MI.eraseFromParent(); // The pseudo instruction is gone now. ++ return BB; + } + +-bool LoongArchTargetLowering::isLegalAddressingMode(const DataLayout &DL, +- const AddrMode &AM, +- Type *Ty, unsigned AS, +- Instruction *I) const { +- // LoongArch has four basic addressing modes: +- // 1. reg +- // 2. reg + 12-bit signed offset +- // 3. reg + 14-bit signed offset left-shifted by 2 +- // 4. reg1 + reg2 +- // TODO: Add more checks after support vector extension. ++// Emit the FILL_FW pseudo instruction. ++// ++// fill_fw_pseudo $vd, $fs ++// => ++// implicit_def $vt1 ++// insert_subreg $vt2:subreg_lo, $vt1, $fs ++// vreplvei.w vd, vt2, 0 ++MachineBasicBlock * ++LoongArchTargetLowering::emitFILL_FW(MachineInstr &MI, ++ MachineBasicBlock *BB) const { ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); ++ DebugLoc DL = MI.getDebugLoc(); ++ unsigned Vd = MI.getOperand(0).getReg(); ++ unsigned Fs = MI.getOperand(1).getReg(); ++ unsigned Vj1 = RegInfo.createVirtualRegister(&LoongArch::LSX128WRegClass); ++ unsigned Vj2 = RegInfo.createVirtualRegister(&LoongArch::LSX128WRegClass); ++ ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::IMPLICIT_DEF), Vj1); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::INSERT_SUBREG), Vj2) ++ .addReg(Vj1) ++ .addReg(Fs) ++ .addImm(LoongArch::sub_lo); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::VREPLVEI_W), Vd) ++ .addReg(Vj2) ++ .addImm(0); + +- // No global is ever allowed as a base. +- if (AM.BaseGV) +- return false; ++ MI.eraseFromParent(); // The pseudo instruction is gone now. ++ return BB; ++} + +- // Require a 12 or 14 bit signed offset. +- if (!isInt<12>(AM.BaseOffs) || !isShiftedInt<14, 2>(AM.BaseOffs)) +- return false; ++// Emit the FILL_FD pseudo instruction. ++// ++// fill_fd_pseudo $vd, $fs ++// => ++// implicit_def $vt1 ++// insert_subreg $vt2:subreg_64, $vt1, $fs ++// vreplvei.d vd, vt2, 0 ++MachineBasicBlock * ++LoongArchTargetLowering::emitFILL_FD(MachineInstr &MI, ++ MachineBasicBlock *BB) const { ++ assert(Subtarget.isFP64bit()); + +- switch (AM.Scale) { +- case 0: +- // "i" is not allowed. +- if (!AM.HasBaseReg) +- return false; +- // Otherwise we have "r+i". +- break; +- case 1: +- // "r+r+i" is not allowed. +- if (AM.HasBaseReg && AM.BaseOffs != 0) +- return false; +- // Otherwise we have "r+r" or "r+i". +- break; +- case 2: +- // "2*r+r" or "2*r+i" is not allowed. +- if (AM.HasBaseReg || AM.BaseOffs) +- return false; +- // Otherwise we have "r+r". +- break; +- default: +- return false; +- } ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); ++ DebugLoc DL = MI.getDebugLoc(); ++ unsigned Vd = MI.getOperand(0).getReg(); ++ unsigned Fs = MI.getOperand(1).getReg(); ++ unsigned Vj1 = RegInfo.createVirtualRegister(&LoongArch::LSX128DRegClass); ++ unsigned Vj2 = RegInfo.createVirtualRegister(&LoongArch::LSX128DRegClass); ++ ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::IMPLICIT_DEF), Vj1); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::INSERT_SUBREG), Vj2) ++ .addReg(Vj1) ++ .addReg(Fs) ++ .addImm(LoongArch::sub_64); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::VREPLVEI_D), Vd) ++ .addReg(Vj2) ++ .addImm(0); + +- return true; ++ MI.eraseFromParent(); // The pseudo instruction is gone now. ++ return BB; ++} ++ ++// Emit the XFILL_FW pseudo instruction. ++// ++// xfill_fw_pseudo $xd, $fs ++// => ++// implicit_def $xt1 ++// insert_subreg $xt2:subreg_lo, $xt1, $fs ++// xvreplve0.w xd, xt2, 0 ++MachineBasicBlock * ++LoongArchTargetLowering::emitXFILL_FW(MachineInstr &MI, ++ MachineBasicBlock *BB) const { ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); ++ DebugLoc DL = MI.getDebugLoc(); ++ unsigned Xd = MI.getOperand(0).getReg(); ++ unsigned Fs = MI.getOperand(1).getReg(); ++ unsigned Xj1 = RegInfo.createVirtualRegister(&LoongArch::LASX256WRegClass); ++ unsigned Xj2 = RegInfo.createVirtualRegister(&LoongArch::LASX256WRegClass); ++ ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::IMPLICIT_DEF), Xj1); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::INSERT_SUBREG), Xj2) ++ .addReg(Xj1) ++ .addReg(Fs) ++ .addImm(LoongArch::sub_lo); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::XVREPLVE0_W), Xd).addReg(Xj2); ++ ++ MI.eraseFromParent(); // The pseudo instruction is gone now. ++ return BB; + } + +-bool LoongArchTargetLowering::isLegalICmpImmediate(int64_t Imm) const { +- return isInt<12>(Imm); ++// Emit the XFILL_FD pseudo instruction. ++// ++// xfill_fd_pseudo $xd, $fs ++// => ++// implicit_def $xt1 ++// insert_subreg $xt2:subreg_64, $xt1, $fs ++// xvreplve0.d xd, xt2, 0 ++MachineBasicBlock * ++LoongArchTargetLowering::emitXFILL_FD(MachineInstr &MI, ++ MachineBasicBlock *BB) const { ++ assert(Subtarget.isFP64bit()); ++ ++ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); ++ MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); ++ DebugLoc DL = MI.getDebugLoc(); ++ unsigned Xd = MI.getOperand(0).getReg(); ++ unsigned Fs = MI.getOperand(1).getReg(); ++ unsigned Xj1 = RegInfo.createVirtualRegister(&LoongArch::LASX256DRegClass); ++ unsigned Xj2 = RegInfo.createVirtualRegister(&LoongArch::LASX256DRegClass); ++ ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::IMPLICIT_DEF), Xj1); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::INSERT_SUBREG), Xj2) ++ .addReg(Xj1) ++ .addReg(Fs) ++ .addImm(LoongArch::sub_64); ++ BuildMI(*BB, MI, DL, TII->get(LoongArch::XVREPLVE0_D), Xd).addReg(Xj2); ++ ++ MI.eraseFromParent(); // The pseudo instruction is gone now. ++ return BB; + } + + bool LoongArchTargetLowering::isLegalAddImmediate(int64_t Imm) const { +- return isInt<12>(Imm); +-} +- +-bool LoongArchTargetLowering::isZExtFree(SDValue Val, EVT VT2) const { +- // Zexts are free if they can be combined with a load. +- // Don't advertise i32->i64 zextload as being free for LA64. It interacts +- // poorly with type legalization of compares preferring sext. +- if (auto *LD = dyn_cast(Val)) { +- EVT MemVT = LD->getMemoryVT(); +- if ((MemVT == MVT::i8 || MemVT == MVT::i16) && +- (LD->getExtensionType() == ISD::NON_EXTLOAD || +- LD->getExtensionType() == ISD::ZEXTLOAD)) +- return true; ++ bool IsLegal = false; ++ if (Subtarget.hasLSX() || Subtarget.hasLASX()) { ++ return isUInt<5>(Imm); + } +- +- return TargetLowering::isZExtFree(Val, VT2); ++ return IsLegal; + } + +-bool LoongArchTargetLowering::isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const { +- return Subtarget.is64Bit() && SrcVT == MVT::i32 && DstVT == MVT::i64; ++bool LoongArchTargetLowering::isFMAFasterThanFMulAndFAdd( ++ const MachineFunction &MF, EVT VT) const { ++ ++ VT = VT.getScalarType(); ++ ++ if (!VT.isSimple()) ++ return false; ++ ++ switch (VT.getSimpleVT().SimpleTy) { ++ case MVT::f32: ++ case MVT::f64: ++ return true; ++ default: ++ break; ++ } ++ ++ return false; + } + +-bool LoongArchTargetLowering::hasAndNotCompare(SDValue Y) const { +- // TODO: Support vectors. +- if (Y.getValueType().isVector()) ++bool LoongArchTargetLowering::isExtractSubvectorCheap(EVT ResVT, EVT SrcVT, ++ unsigned Index) const { ++ if (!isOperationLegalOrCustom(ISD::EXTRACT_SUBVECTOR, ResVT)) + return false; + +- return !isa(Y); ++ return ( ++ (ResVT != MVT::v16i8) && (ResVT != MVT::v8i16) && ++ (Index == 0 || (Index == ResVT.getVectorNumElements() && ++ (ResVT.getSizeInBits() == SrcVT.getSizeInBits() / 2)))); + } + +-ISD::NodeType LoongArchTargetLowering::getExtendForAtomicCmpSwapArg() const { +- // TODO: LAMCAS will use amcas{_DB,}.[bhwd] which does not require extension. +- return ISD::SIGN_EXTEND; ++Register ++LoongArchTargetLowering::getRegisterByName(const char *RegName, LLT VT, ++ const MachineFunction &MF) const { ++ // Named registers is expected to be fairly rare. For now, just support $r2 ++ // and $r21 since the linux kernel uses them. ++ if (Subtarget.is64Bit()) { ++ Register Reg = StringSwitch(RegName) ++ .Case("$r2", LoongArch::TP_64) ++ .Case("$r21", LoongArch::T9_64) ++ .Default(Register()); ++ if (Reg) ++ return Reg; ++ } else { ++ Register Reg = StringSwitch(RegName) ++ .Case("$r2", LoongArch::TP) ++ .Case("$r21", LoongArch::T9) ++ .Default(Register()); ++ if (Reg) ++ return Reg; ++ } ++ report_fatal_error("Invalid register name global variable"); + } +diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h +index 9e9ac0b82..73ff01dec 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h ++++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h +@@ -1,4 +1,4 @@ +-//=- LoongArchISelLowering.h - LoongArch DAG Lowering Interface -*- C++ -*-===// ++//===- LoongArchISelLowering.h - LoongArch DAG Lowering Interface ---------*- C++ -*-===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -6,313 +6,551 @@ + // + //===----------------------------------------------------------------------===// + // +-// This file defines the interfaces that LoongArch uses to lower LLVM code into +-// a selection DAG. ++// This file defines the interfaces that LoongArch uses to lower LLVM code into a ++// selection DAG. + // + //===----------------------------------------------------------------------===// + + #ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H + #define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H + ++#include "MCTargetDesc/LoongArchABIInfo.h" ++#include "MCTargetDesc/LoongArchBaseInfo.h" ++#include "MCTargetDesc/LoongArchMCTargetDesc.h" + #include "LoongArch.h" + #include "llvm/CodeGen/CallingConvLower.h" ++#include "llvm/CodeGen/ISDOpcodes.h" ++#include "llvm/CodeGen/MachineMemOperand.h" ++#include "llvm/CodeGen/MachineValueType.h" + #include "llvm/CodeGen/SelectionDAG.h" ++#include "llvm/CodeGen/SelectionDAGNodes.h" + #include "llvm/CodeGen/TargetLowering.h" ++#include "llvm/CodeGen/ValueTypes.h" ++#include "llvm/IR/CallingConv.h" ++#include "llvm/IR/InlineAsm.h" ++#include "llvm/IR/Type.h" ++#include "llvm/Target/TargetMachine.h" ++#include ++#include ++#include ++#include ++#include ++#include + + namespace llvm { ++ ++class Argument; ++class CCState; ++class CCValAssign; ++class FastISel; ++class FunctionLoweringInfo; ++class MachineBasicBlock; ++class MachineFrameInfo; ++class MachineInstr; ++class LoongArchCCState; ++class LoongArchFunctionInfo; + class LoongArchSubtarget; +-namespace LoongArchISD { +-enum NodeType : unsigned { +- FIRST_NUMBER = ISD::BUILTIN_OP_END, +- +- // TODO: add more LoongArchISDs +- CALL, +- CALL_MEDIUM, +- CALL_LARGE, +- RET, +- TAIL, +- TAIL_MEDIUM, +- TAIL_LARGE, +- +- // 32-bit shifts, directly matching the semantics of the named LoongArch +- // instructions. +- SLL_W, +- SRA_W, +- SRL_W, +- +- ROTL_W, +- ROTR_W, +- +- // FPR<->GPR transfer operations +- MOVGR2FR_W_LA64, +- MOVFR2GR_S_LA64, +- MOVFCSR2GR, +- MOVGR2FCSR, +- +- FTINT, +- +- // Bit counting operations +- CLZ_W, +- CTZ_W, +- +- BSTRINS, +- BSTRPICK, +- +- // Byte-swapping and bit-reversal +- REVB_2H, +- REVB_2W, +- BITREV_4B, +- BITREV_W, +- +- // Intrinsic operations start ============================================ +- BREAK, +- CACOP_D, +- CACOP_W, +- DBAR, +- IBAR, +- SYSCALL, +- +- // CRC check operations +- CRC_W_B_W, +- CRC_W_H_W, +- CRC_W_W_W, +- CRC_W_D_W, +- CRCC_W_B_W, +- CRCC_W_H_W, +- CRCC_W_W_W, +- CRCC_W_D_W, +- +- CSRRD, +- +- // Write new value to CSR and return old value. +- // Operand 0: A chain pointer. +- // Operand 1: The new value to write. +- // Operand 2: The address of the required CSR. +- // Result 0: The old value of the CSR. +- // Result 1: The new chain pointer. +- CSRWR, +- +- // Similar to CSRWR but with a write mask. +- // Operand 0: A chain pointer. +- // Operand 1: The new value to write. +- // Operand 2: The write mask. +- // Operand 3: The address of the required CSR. +- // Result 0: The old value of the CSR. +- // Result 1: The new chain pointer. +- CSRXCHG, +- +- // IOCSR access operations +- IOCSRRD_B, +- IOCSRRD_W, +- IOCSRRD_H, +- IOCSRRD_D, +- IOCSRWR_B, +- IOCSRWR_H, +- IOCSRWR_W, +- IOCSRWR_D, +- +- // Read CPU configuration information operation +- CPUCFG, +- +- // Vector Shuffle +- VREPLVE, +- +- // Extended vector element extraction +- VPICK_SEXT_ELT, +- VPICK_ZEXT_ELT, +- +- // Vector comparisons +- VALL_ZERO, +- VANY_ZERO, +- VALL_NONZERO, +- VANY_NONZERO, +- +- // Intrinsic operations end ============================================= +-}; +-} // end namespace LoongArchISD +- +-class LoongArchTargetLowering : public TargetLowering { +- const LoongArchSubtarget &Subtarget; +- +-public: +- explicit LoongArchTargetLowering(const TargetMachine &TM, +- const LoongArchSubtarget &STI); +- +- const LoongArchSubtarget &getSubtarget() const { return Subtarget; } +- +- bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; +- +- // Provide custom lowering hooks for some operations. +- SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; +- void ReplaceNodeResults(SDNode *N, SmallVectorImpl &Results, +- SelectionDAG &DAG) const override; +- +- SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; +- +- // This method returns the name of a target specific DAG node. +- const char *getTargetNodeName(unsigned Opcode) const override; +- +- // Lower incoming arguments, copy physregs into vregs. +- SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, +- bool IsVarArg, +- const SmallVectorImpl &Ins, +- const SDLoc &DL, SelectionDAG &DAG, +- SmallVectorImpl &InVals) const override; +- bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, +- bool IsVarArg, +- const SmallVectorImpl &Outs, +- LLVMContext &Context) const override; +- SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, +- const SmallVectorImpl &Outs, +- const SmallVectorImpl &OutVals, const SDLoc &DL, +- SelectionDAG &DAG) const override; +- SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, +- SmallVectorImpl &InVals) const override; +- bool isCheapToSpeculateCttz(Type *Ty) const override; +- bool isCheapToSpeculateCtlz(Type *Ty) const override; +- bool hasAndNot(SDValue Y) const override; +- TargetLowering::AtomicExpansionKind +- shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override; +- +- Value *emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI, +- Value *AlignedAddr, Value *Incr, +- Value *Mask, Value *ShiftAmt, +- AtomicOrdering Ord) const override; +- +- EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, +- EVT VT) const override; +- TargetLowering::AtomicExpansionKind +- shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *CI) const override; +- Value *emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder, +- AtomicCmpXchgInst *CI, +- Value *AlignedAddr, Value *CmpVal, +- Value *NewVal, Value *Mask, +- AtomicOrdering Ord) const override; +- +- bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, +- MachineFunction &MF, +- unsigned Intrinsic) const override; +- +- bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, +- EVT VT) const override; +- +- Register +- getExceptionPointerRegister(const Constant *PersonalityFn) const override; +- +- Register +- getExceptionSelectorRegister(const Constant *PersonalityFn) const override; +- +- ISD::NodeType getExtendForAtomicOps() const override { +- return ISD::SIGN_EXTEND; +- } +- +- ISD::NodeType getExtendForAtomicCmpSwapArg() const override; +- +- Register getRegisterByName(const char *RegName, LLT VT, +- const MachineFunction &MF) const override; +- bool mayBeEmittedAsTailCall(const CallInst *CI) const override; +- +- bool decomposeMulByConstant(LLVMContext &Context, EVT VT, +- SDValue C) const override; +- +- bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override; +- +- bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, +- unsigned AS, +- Instruction *I = nullptr) const override; +- +- bool isLegalICmpImmediate(int64_t Imm) const override; +- bool isLegalAddImmediate(int64_t Imm) const override; +- bool isZExtFree(SDValue Val, EVT VT2) const override; +- bool isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const override; +- +- bool hasAndNotCompare(SDValue Y) const override; +- +- bool convertSelectOfConstantsToMath(EVT VT) const override { return true; } +- +- bool allowsMisalignedMemoryAccesses( +- EVT VT, unsigned AddrSpace = 0, Align Alignment = Align(1), +- MachineMemOperand::Flags Flags = MachineMemOperand::MONone, +- unsigned *Fast = nullptr) const override; +- +- bool isShuffleMaskLegal(ArrayRef Mask, EVT VT) const override { +- return false; +- } +- +-private: +- /// Target-specific function used to lower LoongArch calling conventions. +- typedef bool LoongArchCCAssignFn(const DataLayout &DL, LoongArchABI::ABI ABI, +- unsigned ValNo, MVT ValVT, +- CCValAssign::LocInfo LocInfo, +- ISD::ArgFlagsTy ArgFlags, CCState &State, +- bool IsFixed, bool IsReg, Type *OrigTy); +- +- void analyzeInputArgs(MachineFunction &MF, CCState &CCInfo, +- const SmallVectorImpl &Ins, bool IsRet, +- LoongArchCCAssignFn Fn) const; +- void analyzeOutputArgs(MachineFunction &MF, CCState &CCInfo, +- const SmallVectorImpl &Outs, +- bool IsRet, CallLoweringInfo *CLI, +- LoongArchCCAssignFn Fn) const; +- +- template +- SDValue getAddr(NodeTy *N, SelectionDAG &DAG, CodeModel::Model M, +- bool IsLocal = true) const; +- SDValue getStaticTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG, +- unsigned Opc, bool Large = false) const; +- SDValue getDynamicTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG, +- unsigned Opc, bool Large = false) const; +- SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; +- SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; +- SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const; +- SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; +- SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const; +- SDValue lowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const; +- +- MachineBasicBlock * +- EmitInstrWithCustomInserter(MachineInstr &MI, +- MachineBasicBlock *BB) const override; +- SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const; +- SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const; +- SDValue lowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const; +- SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const; +- SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const; +- SDValue lowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const; +- SDValue lowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) const; +- SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const; +- SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; +- SDValue lowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const; +- SDValue lowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const; +- SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; +- SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; +- SDValue lowerWRITE_REGISTER(SDValue Op, SelectionDAG &DAG) const; +- SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; +- SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; +- SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const; +- SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const; +- +- bool isFPImmLegal(const APFloat &Imm, EVT VT, +- bool ForCodeSize) const override; +- +- bool shouldInsertFencesForAtomic(const Instruction *I) const override; +- +- ConstraintType getConstraintType(StringRef Constraint) const override; +- +- InlineAsm::ConstraintCode +- getInlineAsmMemConstraint(StringRef ConstraintCode) const override; +- +- std::pair +- getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, +- StringRef Constraint, MVT VT) const override; +- +- void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, +- std::vector &Ops, +- SelectionDAG &DAG) const override; +- +- bool isEligibleForTailCallOptimization( +- CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF, +- const SmallVectorImpl &ArgLocs) const; +-}; ++class LoongArchTargetMachine; ++class SelectionDAG; ++class TargetLibraryInfo; ++class TargetRegisterClass; ++ ++ namespace LoongArchISD { ++ ++ enum NodeType : unsigned { ++ // Start the numbering from where ISD NodeType finishes. ++ FIRST_NUMBER = ISD::BUILTIN_OP_END, ++ ++ // Jump and link (call) ++ JmpLink, ++ ++ // Tail call ++ TailCall, ++ ++ // global address ++ GlobalAddress, ++ ++ // Floating Point Branch Conditional ++ FPBrcond, ++ ++ // Floating Point Compare ++ FPCmp, ++ ++ // Floating Point Conditional Moves ++ CMovFP_T, ++ CMovFP_F, ++ FSEL, ++ ++ // FP-to-int truncation node. ++ TruncIntFP, ++ ++ // Return ++ Ret, ++ ++ // error trap Return ++ ERet, ++ ++ // Software Exception Return. ++ EH_RETURN, ++ ++ BSTRPICK, ++ BSTRINS, ++ ++ // Vector comparisons. ++ // These take a vector and return a boolean. ++ VALL_ZERO, ++ VANY_ZERO, ++ VALL_NONZERO, ++ VANY_NONZERO, ++ ++ // Vector Shuffle with mask as an operand ++ VSHF, // Generic shuffle ++ SHF, // 4-element set shuffle. ++ VPACKEV, // Interleave even elements ++ VPACKOD, // Interleave odd elements ++ VILVH, // Interleave left elements ++ VILVL, // Interleave right elements ++ VPICKEV, // Pack even elements ++ VPICKOD, // Pack odd elements ++ ++ // Vector Lane Copy ++ INSVE, // Copy element from one vector to another ++ ++ // Combined (XOR (OR $a, $b), -1) ++ VNOR, ++ ++ VROR, ++ VRORI, ++ XVPICKVE, ++ XVPERMI, ++ XVSHUF4I, ++ REVBD, ++ ++ // Extended vector element extraction ++ VEXTRACT_SEXT_ELT, ++ VEXTRACT_ZEXT_ELT, ++ ++ XVBROADCAST, ++ VBROADCAST, ++ VABSD, ++ UVABSD, ++ }; ++ ++ } // ene namespace LoongArchISD ++ ++ //===--------------------------------------------------------------------===// ++ // TargetLowering Implementation ++ //===--------------------------------------------------------------------===// ++ ++ class LoongArchTargetLowering : public TargetLowering { ++ public: ++ explicit LoongArchTargetLowering(const LoongArchTargetMachine &TM, ++ const LoongArchSubtarget &STI); ++ ++ bool allowsMisalignedMemoryAccesses( ++ EVT VT, unsigned AddrSpace = 0, Align Alignment = Align(1), ++ MachineMemOperand::Flags Flags = MachineMemOperand::MONone, ++ unsigned *Fast = nullptr) const override; ++ ++ /// Enable LSX support for the given integer type and Register ++ /// class. ++ void addLSXIntType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC); ++ ++ /// Enable LSX support for the given floating-point type and ++ /// Register class. ++ void addLSXFloatType(MVT::SimpleValueType Ty, ++ const TargetRegisterClass *RC); ++ ++ /// Enable LASX support for the given integer type and Register ++ /// class. ++ void addLASXIntType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC); ++ ++ /// Enable LASX support for the given floating-point type and ++ /// Register class. ++ void addLASXFloatType(MVT::SimpleValueType Ty, ++ const TargetRegisterClass *RC); ++ ++ MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override { ++ return MVT::i32; ++ } ++ ++ EVT getTypeForExtReturn(LLVMContext &Context, EVT VT, ++ ISD::NodeType) const override; ++ ++ bool isCheapToSpeculateCttz(Type *Ty) const override; ++ bool isCheapToSpeculateCtlz(Type *Ty) const override; ++ ++ bool isLegalAddImmediate(int64_t) const override; ++ ++ /// Return the correct alignment for the current calling convention. ++ Align getABIAlignmentForCallingConv(Type *ArgTy, ++ const DataLayout &DL) const override { ++ const Align ABIAlign = DL.getABITypeAlign(ArgTy); ++ if (ArgTy->isVectorTy()) ++ return std::min(ABIAlign, Align(8)); ++ return ABIAlign; ++ } ++ ++ ISD::NodeType getExtendForAtomicOps() const override { ++ return ISD::SIGN_EXTEND; ++ } ++ ++ bool isExtractSubvectorCheap(EVT ResVT, EVT SrcVT, ++ unsigned Index) const override; ++ ++ void LowerOperationWrapper(SDNode *N, ++ SmallVectorImpl &Results, ++ SelectionDAG &DAG) const override; ++ ++ /// LowerOperation - Provide custom lowering hooks for some operations. ++ SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; ++ ++ bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, ++ EVT VT) const override; ++ ++ /// ReplaceNodeResults - Replace the results of node with an illegal result ++ /// type with new values built out of custom code. ++ /// ++ void ReplaceNodeResults(SDNode *N, SmallVectorImpl&Results, ++ SelectionDAG &DAG) const override; ++ ++ /// getTargetNodeName - This method returns the name of a target specific ++ // DAG node. ++ const char *getTargetNodeName(unsigned Opcode) const override; ++ ++ /// getSetCCResultType - get the ISD::SETCC result ValueType ++ EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, ++ EVT VT) const override; ++ ++ SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; ++ ++ MachineBasicBlock * ++ EmitInstrWithCustomInserter(MachineInstr &MI, ++ MachineBasicBlock *MBB) const override; ++ ++ bool isShuffleMaskLegal(ArrayRef Mask, EVT VT) const override { ++ return false; ++ } ++ ++ const TargetRegisterClass *getRepRegClassFor(MVT VT) const override; ++ ++ void AdjustInstrPostInstrSelection(MachineInstr &MI, ++ SDNode *Node) const override; ++ ++ void HandleByVal(CCState *, unsigned &, Align) const override; ++ ++ Register getRegisterByName(const char* RegName, LLT VT, ++ const MachineFunction &MF) const override; ++ ++ /// If a physical register, this returns the register that receives the ++ /// exception address on entry to an EH pad. ++ Register ++ getExceptionPointerRegister(const Constant *PersonalityFn) const override { ++ return ABI.IsLP64() ? LoongArch::A0_64 : LoongArch::A0; ++ } ++ ++ /// If a physical register, this returns the register that receives the ++ /// exception typeid on entry to a landing pad. ++ Register ++ getExceptionSelectorRegister(const Constant *PersonalityFn) const override { ++ return ABI.IsLP64() ? LoongArch::A1_64 : LoongArch::A1; ++ } ++ ++ bool isJumpTableRelative() const override { ++ return getTargetMachine().isPositionIndependent(); ++ } ++ ++ CCAssignFn *CCAssignFnForCall() const; ++ ++ CCAssignFn *CCAssignFnForReturn() const; ++ ++ private: ++ template ++ SDValue getAddr(NodeTy *N, SelectionDAG &DAG, bool IsLocal = true) const; ++ ++ /// This function fills Ops, which is the list of operands that will later ++ /// be used when a function call node is created. It also generates ++ /// copyToReg nodes to set up argument registers. ++ void getOpndList(SmallVectorImpl &Ops, ++ std::deque> &RegsToPass, ++ bool IsPICCall, bool GlobalOrExternal, bool IsCallReloc, ++ CallLoweringInfo &CLI, SDValue Callee, SDValue Chain, ++ bool IsTailCall) const; ++ ++ SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const; ++ ++ // Subtarget Info ++ const LoongArchSubtarget &Subtarget; ++ // Cache the ABI from the TargetMachine, we use it everywhere. ++ const LoongArchABIInfo &ABI; ++ ++ // Create a TargetGlobalAddress node. ++ SDValue getTargetNode(GlobalAddressSDNode *N, EVT Ty, SelectionDAG &DAG, ++ unsigned Flag) const; ++ ++ // Create a TargetExternalSymbol node. ++ SDValue getTargetNode(ExternalSymbolSDNode *N, EVT Ty, SelectionDAG &DAG, ++ unsigned Flag) const; ++ ++ // Create a TargetBlockAddress node. ++ SDValue getTargetNode(BlockAddressSDNode *N, EVT Ty, SelectionDAG &DAG, ++ unsigned Flag) const; ++ ++ // Create a TargetJumpTable node. ++ SDValue getTargetNode(JumpTableSDNode *N, EVT Ty, SelectionDAG &DAG, ++ unsigned Flag) const; ++ ++ // Create a TargetConstantPool node. ++ SDValue getTargetNode(ConstantPoolSDNode *N, EVT Ty, SelectionDAG &DAG, ++ unsigned Flag) const; ++ ++ // Lower Operand helpers ++ SDValue LowerCallResult(SDValue Chain, SDValue InFlag, ++ CallingConv::ID CallConv, bool isVarArg, ++ const SmallVectorImpl &Ins, ++ const SDLoc &dl, SelectionDAG &DAG, ++ SmallVectorImpl &InVals, ++ TargetLowering::CallLoweringInfo &CLI) const; ++ ++ // Lower Operand specifics ++ SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerFP_TO_UINT(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const; ++ /// Lower VECTOR_SHUFFLE into one of a number of instructions ++ /// depending on the indices in the shuffle. ++ SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerBRCOND(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerSELECT(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerSETCC(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerVAARG(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerFABS(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const; ++ SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const; ++ SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG& DAG) const; ++ SDValue lowerShiftRightParts(SDValue Op, SelectionDAG& DAG, ++ bool IsSRA) const; ++ SDValue lowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const; ++ ++ /// isEligibleForTailCallOptimization - Check whether the call is eligible ++ /// for tail call optimization. ++ bool ++ isEligibleForTailCallOptimization(const CCState &CCInfo, ++ CallLoweringInfo &CLI, MachineFunction &MF, ++ unsigned NextStackOffset, ++ const LoongArchFunctionInfo &FI) const; ++ ++ /// copyByValArg - Copy argument registers which were used to pass a byval ++ /// argument to the stack. Create a stack frame object for the byval ++ /// argument. ++ void copyByValRegs(SDValue Chain, const SDLoc &DL, ++ std::vector &OutChains, SelectionDAG &DAG, ++ const ISD::ArgFlagsTy &Flags, ++ SmallVectorImpl &InVals, ++ const Argument *FuncArg, unsigned FirstReg, ++ unsigned LastReg, const CCValAssign &VA, ++ LoongArchCCState &State) const; ++ ++ /// passByValArg - Pass a byval argument in registers or on stack. ++ void passByValArg(SDValue Chain, const SDLoc &DL, ++ std::deque> &RegsToPass, ++ SmallVectorImpl &MemOpChains, SDValue StackPtr, ++ MachineFrameInfo &MFI, SelectionDAG &DAG, SDValue Arg, ++ unsigned FirstReg, unsigned LastReg, ++ const ISD::ArgFlagsTy &Flags, ++ const CCValAssign &VA) const; ++ ++ /// writeVarArgRegs - Write variable function arguments passed in registers ++ /// to the stack. Also create a stack frame object for the first variable ++ /// argument. ++ void writeVarArgRegs(std::vector &OutChains, SDValue Chain, ++ const SDLoc &DL, SelectionDAG &DAG, ++ CCState &State) const; ++ ++ SDValue ++ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, ++ const SmallVectorImpl &Ins, ++ const SDLoc &dl, SelectionDAG &DAG, ++ SmallVectorImpl &InVals) const override; ++ ++ SDValue passArgOnStack(SDValue StackPtr, unsigned Offset, SDValue Chain, ++ SDValue Arg, const SDLoc &DL, bool IsTailCall, ++ SelectionDAG &DAG) const; ++ ++ SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, ++ SmallVectorImpl &InVals) const override; ++ ++ bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, ++ bool isVarArg, ++ const SmallVectorImpl &Outs, ++ LLVMContext &Context) const override; ++ ++ SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, ++ const SmallVectorImpl &Outs, ++ const SmallVectorImpl &OutVals, ++ const SDLoc &dl, SelectionDAG &DAG) const override; ++ ++ bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const override; ++ ++ // Inline asm support ++ ConstraintType getConstraintType(StringRef Constraint) const override; ++ ++ /// Examine constraint string and operand type and determine a weight value. ++ /// The operand object must already have been set up with the operand type. ++ ConstraintWeight getSingleConstraintMatchWeight( ++ AsmOperandInfo &info, const char *constraint) const override; ++ ++ /// This function parses registers that appear in inline-asm constraints. ++ /// It returns pair (0, 0) on failure. ++ std::pair ++ parseRegForInlineAsmConstraint(StringRef C, MVT VT) const; ++ ++ std::pair ++ getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, ++ StringRef Constraint, MVT VT) const override; ++ ++ /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops ++ /// vector. If it is invalid, don't add anything to Ops. If hasMemory is ++ /// true it means one of the asm constraint of the inline asm instruction ++ /// being processed is 'm'. ++ void LowerAsmOperandForConstraint(SDValue Op, ++ StringRef Constraint, ++ std::vector &Ops, ++ SelectionDAG &DAG) const override; ++ ++ InlineAsm::ConstraintCode ++ getInlineAsmMemConstraint(StringRef ConstraintCode) const override { ++ if (ConstraintCode == "R") ++ return InlineAsm::ConstraintCode::R; ++ else if (ConstraintCode == "ZC") ++ return InlineAsm::ConstraintCode::ZC; ++ else if (ConstraintCode == "ZB") ++ return InlineAsm::ConstraintCode::ZB; ++ return TargetLowering::getInlineAsmMemConstraint(ConstraintCode); ++ } ++ ++ bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, ++ Type *Ty, unsigned AS, ++ Instruction *I = nullptr) const override; ++ ++ bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; ++ ++ EVT getOptimalMemOpType(const MemOp &Op, ++ const AttributeList &FuncAttributes) const override; ++ ++ /// isFPImmLegal - Returns true if the target can instruction select the ++ /// specified FP immediate natively. If false, the legalizer will ++ /// materialize the FP immediate as a load from a constant pool. ++ bool isFPImmLegal(const APFloat &Imm, EVT VT, ++ bool ForCodeSize) const override; ++ ++ bool useSoftFloat() const override; ++ ++ bool shouldInsertFencesForAtomic(const Instruction *I) const override { ++ return isa(I) || isa(I); ++ } ++ ++ bool mayBeEmittedAsTailCall(const CallInst *CI) const override; ++ ++ /// Emit a sign-extension using sll/sra, seb, or seh appropriately. ++ MachineBasicBlock *emitSignExtendToI32InReg(MachineInstr &MI, ++ MachineBasicBlock *BB, ++ unsigned Size, unsigned DstReg, ++ unsigned SrcRec) const; ++ ++ MachineBasicBlock *emitLoadAddress(MachineInstr &MI, ++ MachineBasicBlock *BB) const; ++ MachineBasicBlock *emitAtomicBinary(MachineInstr &MI, ++ MachineBasicBlock *BB) const; ++ MachineBasicBlock *emitAtomicBinaryPartword(MachineInstr &MI, ++ MachineBasicBlock *BB, ++ unsigned Size) const; ++ ++ MachineBasicBlock *emitXINSERT_B(MachineInstr &MI, ++ MachineBasicBlock *BB) const; ++ MachineBasicBlock *emitINSERT_H_VIDX(MachineInstr &MI, ++ MachineBasicBlock *BB) const; ++ ++ MachineBasicBlock *emitAtomicCmpSwap(MachineInstr &MI, ++ MachineBasicBlock *BB) const; ++ MachineBasicBlock *emitAtomicCmpSwapPartword(MachineInstr &MI, ++ MachineBasicBlock *BB, ++ unsigned Size) const; ++ MachineBasicBlock *emitSEL_D(MachineInstr &MI, MachineBasicBlock *BB) const; ++ ++ MachineBasicBlock *emitPseudoSELECT(MachineInstr &MI, MachineBasicBlock *BB, ++ bool isFPCmp, unsigned Opc) const; ++ ++ /// SE ++ MachineBasicBlock *emitLSXCBranchPseudo(MachineInstr &MI, ++ MachineBasicBlock *BB, ++ unsigned BranchOp) const; ++ /// Emit the COPY_FW pseudo instruction ++ MachineBasicBlock *emitCOPY_FW(MachineInstr &MI, ++ MachineBasicBlock *BB) const; ++ /// Emit the COPY_FD pseudo instruction ++ MachineBasicBlock *emitCOPY_FD(MachineInstr &MI, ++ MachineBasicBlock *BB) const; ++ ++ MachineBasicBlock *emitXCOPY_FW(MachineInstr &MI, ++ MachineBasicBlock *BB) const; ++ ++ MachineBasicBlock *emitXCOPY_FD(MachineInstr &MI, ++ MachineBasicBlock *BB) const; ++ ++ MachineBasicBlock *emitCONCAT_VECTORS(MachineInstr &MI, ++ MachineBasicBlock *BB, ++ unsigned Bytes) const; ++ ++ MachineBasicBlock *emitXCOPY_FW_GPR(MachineInstr &MI, ++ MachineBasicBlock *BB) const; ++ ++ MachineBasicBlock *emitXINSERT_BH(MachineInstr &MI, MachineBasicBlock *BB, ++ unsigned EltSizeInBytes) const; ++ ++ MachineBasicBlock *emitXINSERT_FW(MachineInstr &MI, ++ MachineBasicBlock *BB) const; ++ ++ /// Emit the INSERT_FW pseudo instruction ++ MachineBasicBlock *emitINSERT_FW(MachineInstr &MI, ++ MachineBasicBlock *BB) const; ++ /// Emit the INSERT_FD pseudo instruction ++ MachineBasicBlock *emitINSERT_FD(MachineInstr &MI, ++ MachineBasicBlock *BB) const; ++ ++ MachineBasicBlock *emitXINSERT_FD(MachineInstr &MI, ++ MachineBasicBlock *BB) const; ++ ++ MachineBasicBlock *emitXINSERT_DF_VIDX(MachineInstr &MI, ++ MachineBasicBlock *BB, ++ bool IsGPR64) const; ++ /// Emit the FILL_FW pseudo instruction ++ MachineBasicBlock *emitFILL_FW(MachineInstr &MI, ++ MachineBasicBlock *BB) const; ++ /// Emit the FILL_FD pseudo instruction ++ MachineBasicBlock *emitFILL_FD(MachineInstr &MI, ++ MachineBasicBlock *BB) const; ++ ++ MachineBasicBlock *emitXFILL_FW(MachineInstr &MI, ++ MachineBasicBlock *BB) const; ++ MachineBasicBlock *emitXFILL_FD(MachineInstr &MI, ++ MachineBasicBlock *BB) const; ++ }; + + } // end namespace llvm + +diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrFormats.td b/llvm/lib/Target/LoongArch/LoongArchInstrFormats.td +index 6ffc8823b..87f57b017 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchInstrFormats.td ++++ b/llvm/lib/Target/LoongArch/LoongArchInstrFormats.td +@@ -1,4 +1,4 @@ +-//===- LoongArchInstrFormats.td - LoongArch Instr. Formats -*- tablegen -*-===// ++//===-- LoongArchInstrFormats.td - LoongArch Instruction Formats -----*- tablegen -*-===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -9,392 +9,812 @@ + //===----------------------------------------------------------------------===// + // Describe LoongArch instructions format + // +-// opcode - operation code. +-// rd - destination register operand. +-// r{j/k} - source register operand. +-// immN - immediate data operand. ++// CPU INSTRUCTION FORMATS ++// ++// opcode - operation code. ++// rs - src reg. ++// rt - dst reg (on a 2 regs instr) or src reg (on a 3 reg instr). ++// rd - dst reg, only used on 3 regs instr. ++// shamt - only used on shift instructions, contains the shift amount. ++// funct - combined with opcode field give us an operation code. + // + //===----------------------------------------------------------------------===// + +-class LAInst pattern = []> +- : Instruction { ++class StdArch { ++ ++ bits<32> Inst; ++} ++ ++// Format specifies the encoding used by the instruction. This is part of the ++// ad-hoc solution used to emit machine instruction encodings by our machine ++// code emitter. ++class Format val> { ++ bits<4> Value = val; ++} ++ ++def Pseudo : Format<0>; ++def FrmR : Format<1>; ++def FrmI : Format<2>; ++def FrmJ : Format<3>; ++def FrmFR : Format<4>; ++def FrmFI : Format<5>; ++def FrmOther : Format<6>; ++ ++// Generic LoongArch Format ++class InstLA pattern, Format f> ++ : Instruction ++{ + field bits<32> Inst; +- // SoftFail is a field the disassembler can use to provide a way for +- // instructions to not match without killing the whole decode process. It is +- // mainly used for ARM, but Tablegen expects this field to exist or it fails +- // to build the decode table. +- field bits<32> SoftFail = 0; ++ Format Form = f; + + let Namespace = "LoongArch"; ++ + let Size = 4; ++ + let OutOperandList = outs; +- let InOperandList = ins; +- let AsmString = opcstr # "\t" # opnstr; +- let Pattern = pattern; ++ let InOperandList = ins; ++ let AsmString = asmstr; ++ let Pattern = pattern; ++ ++ // ++ // Attributes specific to LoongArch instructions... ++ // ++ bits<4> FormBits = Form.Value; ++ bit isCTI = 0; // Any form of Control Transfer Instruction. ++ // Required for LoongArch ++ bit hasForbiddenSlot = 0; // Instruction has a forbidden slot. ++ bit IsPCRelativeLoad = 0; // Load instruction with implicit source register ++ // ($pc) and with explicit offset and destination ++ // register ++ bit hasFCCRegOperand = 0; // Instruction uses $fcc register ++ ++ // TSFlags layout should be kept in sync with MCTargetDesc/LoongArchBaseInfo.h. ++ let TSFlags{3-0} = FormBits; ++ let TSFlags{4} = isCTI; ++ let TSFlags{5} = hasForbiddenSlot; ++ let TSFlags{6} = IsPCRelativeLoad; ++ let TSFlags{7} = hasFCCRegOperand; ++ ++ let DecoderNamespace = "LoongArch"; ++ ++ field bits<32> SoftFail = 0; + } + +-// Pseudo instructions +-class Pseudo pattern = [], string opcstr = "", +- string opnstr = ""> +- : LAInst { +- let isPseudo = 1; +- let isCodeGenOnly = 1; ++class InstForm pattern, ++ Format f, string opstr = ""> : ++ InstLA { ++ string BaseOpcode = opstr; ++ string Arch; + } + +-class deriveInsnMnemonic { +- string ret = !tolower(!subst("@", "_", !subst("_", ".", !subst("__", "@", name)))); ++class LoongArch_str { ++ string Arch; ++ string BaseOpcode = opstr; + } + +-// 2R-type +-// +-class Fmt2R op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { ++//===-----------------------------------------------------------===// ++// Format instruction classes in the LoongArch ++//===-----------------------------------------------------------===// ++ ++// R2 classes: 2 registers ++// ++class R2 : StdArch { + bits<5> rj; + bits<5> rd; + +- let Inst{31-0} = op; + let Inst{9-5} = rj; + let Inst{4-0} = rd; + } + +-// 3R-type +-// +-class Fmt3R op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { ++class R2I op> ++ : R2 { ++ let Inst{31-15} = 0x0; ++ let Inst{14-10} = op; ++} ++ ++class R2F op> ++ : R2 { ++ bits<5> fj; ++ bits<5> fd; ++ ++ let Inst{31-20} = 0x11; ++ let Inst{19-10} = op; ++ let Inst{9-5} = fj; ++ let Inst{4-0} = fd; ++} ++ ++class MOVFI op> ++ : R2 { ++ bits<5> rj; ++ bits<5> fd; ++ ++ let Inst{31-20} = 0x11; ++ let Inst{19-10} = op; ++ let Inst{9-5} = rj; ++ let Inst{4-0} = fd; ++} ++ ++class MOVIF op> ++ : R2 { ++ bits<5> fj; ++ bits<5> rd; ++ ++ let Inst{31-20} = 0x11; ++ let Inst{19-10} = op; ++ let Inst{9-5} = fj; ++ let Inst{4-0} = rd; ++} ++ ++class R2P op> ++ : R2 { ++ let Inst{31-13} = 0x3240; ++ let Inst{12-10} = op; ++} ++ ++// R2_LL_SC classes: two registers for llacq/screl.[w/d] instructions ++class R2_LL_SC op> ++ : R2 { ++ let Inst{31-13} = 0x1c2bc; ++ let Inst{12-10} = op; ++} ++ ++class R2_CSR op> ++ : StdArch { ++ bits<5> rj; ++ bits<5> rd; ++ bits<14> csr; ++ ++ let Inst{31-24} = op; ++ let Inst{23-10} = csr; ++ let Inst{9-5} = rj; ++ let Inst{4-0} = rd; ++} ++ ++class R2_SI16 op> ++ : StdArch { ++ bits<5> rd; ++ bits<5> rj; ++ bits<16> si16; ++ ++ let Inst{31-26} = op; ++ let Inst{25-10} = si16; ++ let Inst{9-5} = rj; ++ let Inst{4-0} = rd; ++} ++ ++class R2_COND op, bits<5> cond> ++ : StdArch { ++ bits<5> fj; ++ bits<5> fk; ++ bits<3> cd; ++ ++ let Inst{31-22} = 0x30; ++ let Inst{21-20} = op; ++ let Inst{19-15} = cond; ++ let Inst{14-10} = fk; ++ let Inst{9-5} = fj; ++ let Inst{4-3} = 0b00; ++ let Inst{2-0} = cd; ++} ++ ++class R2_LEVEL op> ++ : StdArch { ++ bits<5> rj; ++ bits<5> rd; ++ bits<8> level; ++ ++ let Inst{31-18} = op; ++ let Inst{17-10} = level; ++ let Inst{9-5} = rj; ++ let Inst{4-0} = rd; ++} ++ ++class IMM32 op> ++ : StdArch { ++ let Inst{31-16} = 0x0648; ++ let Inst{15-10} = op; ++ let Inst{9-0} = 0; ++} ++ ++class WAIT_FM : StdArch { ++ bits<15> hint; ++ ++ let Inst{31-15} = 0xc91; ++ let Inst{14-0} = hint; ++} ++ ++class R2_INVTLB : StdArch { ++ bits<5> rj; ++ bits<5> op; ++ bits<5> rk; ++ ++ let Inst{31-15} = 0xc93; ++ let Inst{14-10} = rk; ++ let Inst{9-5} = rj; ++ let Inst{4-0} = op; ++} ++ ++class BAR_FM op> ++ : StdArch { ++ bits<15> hint; ++ ++ let Inst{31-16} = 0x3872; ++ let Inst{15} = op; ++ let Inst{14-0} = hint; ++} ++ ++class PRELD_FM : StdArch { ++ bits<5> rj; ++ bits<5> hint; ++ bits<12> imm12; ++ ++ let Inst{31-22} = 0xab; ++ let Inst{21-10} = imm12; ++ let Inst{9-5} = rj; ++ let Inst{4-0} = hint; ++} ++ ++class PRELD_FM_ADDR : StdArch { ++ bits<5> rj; ++ bits<5> hint; ++ bits<12> addr; ++ ++ let Inst{31-22} = 0xab; ++ let Inst{21-10} = addr; ++ let Inst{9-5} = rj; ++ let Inst{4-0} = hint; ++} ++ ++// R3 classes: 3 registers ++// ++class R3 : StdArch { + bits<5> rk; + bits<5> rj; + bits<5> rd; + +- let Inst{31-0} = op; + let Inst{14-10} = rk; + let Inst{9-5} = rj; + let Inst{4-0} = rd; + } + +-// 3RI2-type +-// +-class Fmt3RI2 op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<2> imm2; ++class R3I op> ++ : R3 { ++ let Inst{31-22} = 0x0; ++ let Inst{21-15} = op; ++} ++ ++class R3F op> ++ : R3 { ++ bits<5> fk; ++ bits<5> fj; ++ bits<5> fd; ++ ++ let Inst{31-21} = 0x8; ++ let Inst{20-15} = op; ++ let Inst{14-10} = fk; ++ let Inst{9-5} = fj; ++ let Inst{4-0} = fd; ++} ++ ++class R3MI op> ++ : R3 { ++ let Inst{31-23} = 0x70; ++ let Inst{22-15} = op; ++} ++ ++class AM op> : StdArch { ++ bits<5> rk; ++ bits<17> addr; // rj + 12 bits offset 0 ++ bits<5> rd; ++ ++ let Inst{31-21} = 0x1c3; ++ let Inst{20-15} = op; ++ let Inst{14-10} = rk; ++ let Inst{9-5} = addr{16-12}; ++ let Inst{4-0} = rd; ++} ++ ++class AM_V1_1 op> : StdArch { ++ bits<5> rk; ++ bits<17> addr; // rj + 12 bits offset 0 ++ bits<5> rd; ++ ++ let Inst{31-19} = 0x70b; ++ let Inst{18-15} = op; ++ let Inst{14-10} = rk; ++ let Inst{9-5} = addr{16-12}; ++ let Inst{4-0} = rd; ++} ++ ++class R3MF op> ++ : R3 { ++ bits<5> fd; ++ ++ let Inst{31-23} = 0x70; ++ let Inst{22-15} = op; ++ let Inst{4-0} = fd; ++} ++ ++class R3_SA2 op> ++ : StdArch { + bits<5> rk; + bits<5> rj; + bits<5> rd; ++ bits<2> sa; + +- let Inst{31-0} = op; +- let Inst{16-15} = imm2; ++ let Inst{31-22} = 0x0; ++ let Inst{21-17} = op; ++ let Inst{16-15} = sa; + let Inst{14-10} = rk; + let Inst{9-5} = rj; + let Inst{4-0} = rd; + } + +-// 3RI3-type +-// +-class Fmt3RI3 op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<3> imm3; ++class R3_SA3 : StdArch { + bits<5> rk; + bits<5> rj; + bits<5> rd; ++ bits<3> sa; + +- let Inst{31-0} = op; +- let Inst{17-15} = imm3; ++ let Inst{31-18} = 3; ++ let Inst{17-15} = sa; + let Inst{14-10} = rk; + let Inst{9-5} = rj; + let Inst{4-0} = rd; + } + +-// 2RI5-type +-// +-class Fmt2RI5 op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<5> imm5; ++// R4 classes: 4 registers ++// ++class R4MUL op> ++ : StdArch { ++ bits<5> fa; ++ bits<5> fk; ++ bits<5> fj; ++ bits<5> fd; ++ ++ let Inst{31-24} = 0x8; ++ let Inst{23-20} = op; ++ let Inst{19-15} = fa; ++ let Inst{14-10} = fk; ++ let Inst{9-5} = fj; ++ let Inst{4-0} = fd; ++} ++ ++class R4CMP op> ++ : StdArch { ++ bits<5> cond; ++ bits<5> fk; ++ bits<5> fj; ++ bits<3> cd; ++ ++ let Inst{31-22} = 0x30; ++ let Inst{21-20} = op; ++ let Inst{19-15} = cond; ++ let Inst{14-10} = fk; ++ let Inst{9-5} = fj; ++ let Inst{4-3} = 0; ++ let Inst{2-0} = cd; ++} ++ ++class R4SEL : StdArch { ++ bits<3> ca; ++ bits<5> fk; ++ bits<5> fj; ++ bits<5> fd; ++ ++ let Inst{31-18} = 0x340; ++ let Inst{17-15} = ca; ++ let Inst{14-10} = fk; ++ let Inst{9-5} = fj; ++ let Inst{4-0} = fd; ++} ++ ++// R2_IMM5 classes: 2registers and 1 5bit-immediate ++// ++class R2_IMM5 op> ++ : StdArch { + bits<5> rj; + bits<5> rd; ++ bits<5> imm5; + +- let Inst{31-0} = op; ++ let Inst{31-20} = 0x4; ++ let Inst{19-18} = op; ++ let Inst{17-15} = 0x1; + let Inst{14-10} = imm5; + let Inst{9-5} = rj; + let Inst{4-0} = rd; + } + +-// 2RI6-type +-// +-class Fmt2RI6 op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<6> imm6; ++// R2_IMM6 classes: 2registers and 1 6bit-immediate ++// ++class R2_IMM6 op> ++ : StdArch { + bits<5> rj; + bits<5> rd; ++ bits<6> imm6; + +- let Inst{31-0} = op; ++ let Inst{31-20} = 0x4; ++ let Inst{19-18} = op; ++ let Inst{17-16} = 0x1; + let Inst{15-10} = imm6; + let Inst{9-5} = rj; + let Inst{4-0} = rd; + } + +-// 2RI8-type +-// +-class Fmt2RI8 op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<8> imm8; ++// R2_IMM12 classes: 2 registers and 1 12bit-immediate ++// ++class LOAD_STORE op> ++ : StdArch { ++ bits<5> rd; ++ bits<17> addr; ++ ++ let Inst{31-26} = 0xa; ++ let Inst{25-22} = op; ++ let Inst{21-10} = addr{11-0}; ++ let Inst{9-5} = addr{16-12}; ++ let Inst{4-0} = rd; ++} ++// for reloc ++class LOAD_STORE_RRI op> ++ : StdArch { + bits<5> rj; + bits<5> rd; ++ bits<12> imm12; + +- let Inst{31-0} = op; +- let Inst{17-10} = imm8; ++ let Inst{31-26} = 0xa; ++ let Inst{25-22} = op; ++ let Inst{21-10} = imm12; + let Inst{9-5} = rj; + let Inst{4-0} = rd; + } + +-// 2RI12-type +-// +-class Fmt2RI12 op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<12> imm12; ++ ++class R2_IMM12 op> ++ : StdArch { + bits<5> rj; + bits<5> rd; ++ bits<12> imm12; + +- let Inst{31-0} = op; ++ let Inst{31-25} = 0x1; ++ let Inst{24-22} = op; + let Inst{21-10} = imm12; + let Inst{9-5} = rj; + let Inst{4-0} = rd; + } + +-// 2RI14-type +-// +-class Fmt2RI14 op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<14> imm14; ++class LEA_ADDI_FM op> ++ : StdArch { ++ bits<5> rd; ++ bits<17> addr; ++ ++ let Inst{31-25} = 0x1; ++ let Inst{24-22} = op; ++ let Inst{21-10} = addr{11-0}; ++ let Inst{9-5} = addr{16-12}; ++ let Inst{4-0} = rd; ++} ++ ++// R2_IMM14 classes: 2 registers and 1 14bit-immediate ++// ++class LL_SC op> ++ : StdArch { ++ bits<5> rd; ++ bits<19> addr; ++ ++ let Inst{31-27} = 4; ++ let Inst{26-24} = op; ++ let Inst{23-10} = addr{13-0}; ++ let Inst{9-5} = addr{18-14}; ++ let Inst{4-0} = rd; ++} ++ ++// R2_IMM16 classes: 2 registers and 1 16bit-immediate ++// ++class R2_IMM16BEQ op> ++ : StdArch { + bits<5> rj; + bits<5> rd; ++ bits<16> offs16; + +- let Inst{31-0} = op; +- let Inst{23-10} = imm14; ++ let Inst{31-26} = op; ++ let Inst{25-10} = offs16; + let Inst{9-5} = rj; + let Inst{4-0} = rd; + } + +-// 2RI16-type +-// +-class Fmt2RI16 op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<16> imm16; ++class R2_IMM16JIRL : StdArch { + bits<5> rj; + bits<5> rd; ++ bits<16> offs16; + +- let Inst{31-0} = op; +- let Inst{25-10} = imm16; ++ let Inst{31-26} = 0x13; ++ let Inst{25-10} = offs16; + let Inst{9-5} = rj; + let Inst{4-0} = rd; + } + +-// 1RI20-type +-// +-class Fmt1RI20 op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<20> imm20; ++// R1_IMM21 classes: 1 registers and 1 21bit-immediate ++// ++class R1_IMM21BEQZ op> ++ : StdArch { ++ bits<5> rj; ++ bits<21> offs21; ++ ++ let Inst{31-26} = op; ++ let Inst{25-10} = offs21{15-0}; ++ let Inst{9-5} = rj; ++ let Inst{4-0} = offs21{20-16}; ++} ++ ++class R1_CSR op> ++ : StdArch { + bits<5> rd; ++ bits<14> csr; + +- let Inst{31-0} = op; +- let Inst{24-5} = imm20; ++ let Inst{31-24} = op{7-0}; ++ let Inst{23-10} = csr; ++ let Inst{9-5} = op{12-8}; + let Inst{4-0} = rd; + } + +-// 1RI21-type +-// +-class Fmt1RI21 op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<21> imm21; ++class R1_SI20 op> ++ : StdArch { ++ bits<5> rd; ++ bits<20> si20; ++ ++ let Inst{31-25} = op; ++ let Inst{24-5} = si20; ++ let Inst{4-0} = rd; ++} ++ ++class R1_CACHE : StdArch { + bits<5> rj; ++ bits<5> op; ++ bits<12> si12; + +- let Inst{31-0} = op; +- let Inst{25-10} = imm21{15-0}; ++ let Inst{31-22} = 0x18; ++ let Inst{21-10} = si12; + let Inst{9-5} = rj; +- let Inst{4-0} = imm21{20-16}; ++ let Inst{4-0} = op; ++} ++ ++class R1_SEQ op> ++ : StdArch { ++ bits<5> rj; ++ bits<5> offset; ++ bits<8> seq; ++ ++ let Inst{31-18} = op; ++ let Inst{17-10} = seq; ++ let Inst{9-5} = rj; ++ let Inst{4-0} = 0b00000; ++} ++ ++class R1_BCEQZ op> ++ : StdArch { ++ bits<21> offset; ++ bits<3> cj; ++ ++ let Inst{31-26} = 0x12; ++ let Inst{25-10} = offset{15-0}; ++ let Inst{9-8} = op; ++ let Inst{7-5} = cj; ++ let Inst{4-0} = offset{20-16}; ++} ++ ++// IMM26 classes: 1 26bit-immediate ++// ++class IMM26B op> ++ : StdArch { ++ bits<26> offset26; ++ ++ let Inst{31-26} = op; ++ let Inst{25-10} = offset26{15-0}; ++ let Inst{9-0} = offset26{25-16}; ++} ++ ++// LoongArch Pseudo Instructions Format ++class LoongArchPseudo pattern> : ++ InstLA { ++ let isCodeGenOnly = 1; ++ let isPseudo = 1; ++} ++ ++// Pseudo-instructions for alternate assembly syntax (never used by codegen). ++// These are aliases that require C++ handling to convert to the target ++// instruction, while InstAliases can be handled directly by tblgen. ++class LoongArchAsmPseudoInst: ++ InstLA { ++ let isPseudo = 1; ++ let Pattern = []; + } + +-// I15-type +-// +-class FmtI15 op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<15> imm15; ++// ++// Misc instruction classes ++class ASSERT op> ++ : StdArch { ++ bits<5> rk; ++ bits<5> rj; + +- let Inst{31-0} = op; +- let Inst{14-0} = imm15; ++ let Inst{31-17} = 0x0; ++ let Inst{16-15} = op; ++ let Inst{14-10} = rk; ++ let Inst{9-5} = rj; ++ let Inst{4-0} = 0x0; + } + +-// I26-type +-// +-class FmtI26 op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<26> imm26; ++class CODE15 op> ++ : StdArch { ++ bits<15> Code; + +- let Inst{31-0} = op; +- let Inst{25-10} = imm26{15-0}; +- let Inst{9-0} = imm26{25-16}; ++ let Inst{31-22} = 0x0; ++ let Inst{21-15} = op; ++ let Inst{14-0} = Code; + } + +-// FmtBSTR_W +-// +-class FmtBSTR_W op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { ++class INSERT_BIT32 op> ++ : StdArch { + bits<5> msbw; + bits<5> lsbw; + bits<5> rj; + bits<5> rd; + +- let Inst{31-0} = op; ++ let Inst{31-21} = 0x3; + let Inst{20-16} = msbw; ++ let Inst{15} = op; + let Inst{14-10} = lsbw; + let Inst{9-5} = rj; + let Inst{4-0} = rd; + } + +-// FmtBSTR_D +-// +-class FmtBSTR_D op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { ++class INSERT_BIT64 op> ++ : StdArch { + bits<6> msbd; + bits<6> lsbd; + bits<5> rj; + bits<5> rd; + +- let Inst{31-0} = op; ++ let Inst{31-23} = 0x1; ++ let Inst{22} = op; + let Inst{21-16} = msbd; + let Inst{15-10} = lsbd; + let Inst{9-5} = rj; + let Inst{4-0} = rd; + } + +-// FmtASRT +-// +-class FmtASRT op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<5> rk; ++class MOVGPR2FCSR: StdArch { ++ bits<5> fcsr; + bits<5> rj; + +- let Inst{31-0} = op; +- let Inst{14-10} = rk; ++ let Inst{31-10} = 0x4530; + let Inst{9-5} = rj; ++ let Inst{4-0} = fcsr; + } + +-// FmtPRELD +-// < 0b0010101011 | I12 | rj | I5> +-class FmtPRELD pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<12> imm12; +- bits<5> rj; +- bits<5> imm5; ++class MOVFCSR2GPR: StdArch { ++ bits<5> fcsr; ++ bits<5> rd; + +- let Inst{31-22} = 0b0010101011; +- let Inst{21-10} = imm12; +- let Inst{9-5} = rj; +- let Inst{4-0} = imm5; ++ let Inst{31-10} = 0x4532; ++ let Inst{9-5} = fcsr; ++ let Inst{4-0} = rd; + } + +-// FmtPRELDX +-// < 0b00111000001011000 | rk | rj | I5> +-class FmtPRELDX pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<5> rk; ++class MOVFGR2FCFR: StdArch { ++ bits<3> cd; ++ bits<5> fj; ++ ++ let Inst{31-10} = 0x4534; ++ let Inst{9-5} = fj; ++ let Inst{4-3} = 0; ++ let Inst{2-0} = cd; ++} ++ ++class MOVFCFR2FGR: StdArch { ++ bits<3> cj; ++ bits<5> fd; ++ ++ let Inst{31-10} = 0x4535; ++ let Inst{9-8} = 0; ++ let Inst{7-5} = cj; ++ let Inst{4-0} = fd; ++} ++ ++class MOVGPR2FCFR: StdArch { ++ bits<3> cd; + bits<5> rj; +- bits<5> imm5; + +- let Inst{31-15} = 0b00111000001011000; +- let Inst{14-10} = rk; ++ let Inst{31-10} = 0x4536; + let Inst{9-5} = rj; +- let Inst{4-0} = imm5; ++ let Inst{4-3} = 0; ++ let Inst{2-0} = cd; + } + +-// FmtCSR +-// +-class FmtCSR op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<14> csr_num; ++class MOVFCFR2GPR: StdArch { ++ bits<3> cj; + bits<5> rd; + +- let Inst{31-0} = op; +- let Inst{23-10} = csr_num; ++ let Inst{31-10} = 0x4537; ++ let Inst{9-8} = 0; ++ let Inst{7-5} = cj; + let Inst{4-0} = rd; + } + +-// FmtCSRXCHG +-// +-class FmtCSRXCHG op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<14> csr_num; +- bits<5> rj; +- bits<5> rd; ++class LoongArchInst : InstLA<(outs), (ins), "", [], FrmOther> { ++} ++class JMP_OFFS_2R op> : LoongArchInst { ++ bits<5> rs; ++ bits<5> rd; ++ bits<16> offset; + +- let Inst{31-0} = op; +- let Inst{23-10} = csr_num; +- let Inst{9-5} = rj; +- let Inst{4-0} = rd; ++ bits<32> Inst; ++ ++ let Inst{31-26} = op; ++ let Inst{25-10} = offset; ++ let Inst{9-5} = rs; ++ let Inst{4-0} = rd; + } + +-// FmtCACOP +-// <0b0000011000 | I12 | rj | I5> +-class FmtCACOP pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<12> imm12; +- bits<5> rj; +- bits<5> op; ++class FJ op> : StdArch ++{ ++ bits<26> target; + +- let Inst{31-22} = 0b0000011000; +- let Inst{21-10} = imm12; +- let Inst{9-5} = rj; +- let Inst{4-0} = op; ++ let Inst{31-26} = op; ++ let Inst{25-10} = target{15-0}; ++ let Inst{9-0} = target{25-16}; + } + +-// FmtIMM32 +-// +-class FmtI32 op, list pattern = []> +- : LAInst<(outs), (ins), deriveInsnMnemonic.ret, "", pattern> { +- let Inst{31-0} = op; ++class LUI_FM : StdArch { ++ bits<5> rt; ++ bits<16> imm16; ++ ++ let Inst{31-26} = 0xf; ++ let Inst{25-21} = 0; ++ let Inst{20-16} = rt; ++ let Inst{15-0} = imm16; + } + +-// FmtINVTLB +-// <0b00000110010010011 | rk | rj | I5> +-class FmtINVTLB pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<5> rk; ++class R2_IMM12M_STD op> : StdArch { + bits<5> rj; +- bits<5> op; ++ bits<5> rd; ++ bits<12> imm12; + +- let Inst{31-15} = 0b00000110010010011; +- let Inst{14-10} = rk; ++ let Inst{31-26} = 0xa; ++ let Inst{25-22} = op; ++ let Inst{21-10} = imm12; + let Inst{9-5} = rj; +- let Inst{4-0} = op; ++ let Inst{4-0} = rd; + } + +-// FmtLDPTE +-// <0b00000110010001 | seq | rj | 00000> +-class FmtLDPTE pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<8> seq; +- bits<5> rj; ++class LLD_2R Code> : LoongArchInst { ++ bits<5> rd; ++ bits<19> addr; ++ bits<5> rj = addr{18-14}; ++ bits<14> offset = addr{13-0}; + +- let Inst{31-18} = 0b00000110010001; +- let Inst{17-10} = seq; ++ bits<32> Inst; ++ ++ let Inst{31-27} = 0x4; ++ let Inst{26-24} = Code; ++ let Inst{23-10} = offset; + let Inst{9-5} = rj; +- let Inst{4-0} = 0b00000; ++ let Inst{4-0} = rd; + } ++ ++class CEQS_FM op> { ++ bits<5> fj; ++ bits<5> fk; ++ bits<3> cd; ++ bits<5> cond; ++ ++ bits<32> Inst; ++ ++ let Inst{31-22} = 0x30; ++ let Inst{21-20} = op; ++ let Inst{19-15} = cond; ++ let Inst{14-10} = fk; ++ let Inst{9-5} = fj; ++ let Inst{4-3} = 0b00; ++ let Inst{2-0} = cd; ++} ++ +diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp +index 6576100d3..605281574 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp ++++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp +@@ -1,4 +1,4 @@ +-//=- LoongArchInstrInfo.cpp - LoongArch Instruction Information -*- C++ -*-===// ++//===- LoongArchInstrInfo.cpp - LoongArch Instruction Information -------------------===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -11,396 +11,614 @@ + //===----------------------------------------------------------------------===// + + #include "LoongArchInstrInfo.h" +-#include "LoongArch.h" +-#include "LoongArchMachineFunctionInfo.h" +-#include "LoongArchRegisterInfo.h" ++#include "LoongArchSubtarget.h" ++#include "MCTargetDesc/LoongArchAnalyzeImmediate.h" ++#include "MCTargetDesc/LoongArchBaseInfo.h" + #include "MCTargetDesc/LoongArchMCTargetDesc.h" +-#include "MCTargetDesc/LoongArchMatInt.h" ++#include "llvm/ADT/SmallVector.h" ++#include "llvm/CodeGen/MachineBasicBlock.h" ++#include "llvm/CodeGen/MachineFrameInfo.h" ++#include "llvm/CodeGen/MachineFunction.h" ++#include "llvm/CodeGen/MachineInstr.h" ++#include "llvm/CodeGen/MachineInstrBuilder.h" ++#include "llvm/CodeGen/MachineOperand.h" + #include "llvm/CodeGen/RegisterScavenging.h" +-#include "llvm/MC/MCInstBuilder.h" ++#include "llvm/CodeGen/TargetOpcodes.h" ++#include "llvm/CodeGen/TargetSubtargetInfo.h" ++#include "llvm/IR/DebugLoc.h" ++#include "llvm/MC/MCInstrDesc.h" ++#include "llvm/Target/TargetMachine.h" ++#include + + using namespace llvm; + + #define GET_INSTRINFO_CTOR_DTOR + #include "LoongArchGenInstrInfo.inc" + +-LoongArchInstrInfo::LoongArchInstrInfo(LoongArchSubtarget &STI) ++// Pin the vtable to this file. ++void LoongArchInstrInfo::anchor() {} ++LoongArchInstrInfo::LoongArchInstrInfo(const LoongArchSubtarget &STI) + : LoongArchGenInstrInfo(LoongArch::ADJCALLSTACKDOWN, + LoongArch::ADJCALLSTACKUP), +- STI(STI) {} ++ RI(), Subtarget(STI) {} + +-MCInst LoongArchInstrInfo::getNop() const { +- return MCInstBuilder(LoongArch::ANDI) +- .addReg(LoongArch::R0) +- .addReg(LoongArch::R0) +- .addImm(0); ++const LoongArchRegisterInfo &LoongArchInstrInfo::getRegisterInfo() const { ++ return RI; + } + +-void LoongArchInstrInfo::copyPhysReg(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, +- const DebugLoc &DL, MCRegister DstReg, +- MCRegister SrcReg, bool KillSrc) const { +- if (LoongArch::GPRRegClass.contains(DstReg, SrcReg)) { +- BuildMI(MBB, MBBI, DL, get(LoongArch::OR), DstReg) +- .addReg(SrcReg, getKillRegState(KillSrc)) +- .addReg(LoongArch::R0); +- return; ++/// isLoadFromStackSlot - If the specified machine instruction is a direct ++/// load from a stack slot, return the virtual or physical register number of ++/// the destination along with the FrameIndex of the loaded stack slot. If ++/// not, return 0. This predicate must return 0 if the instruction has ++/// any side effects other than loading from the stack slot. ++unsigned LoongArchInstrInfo::isLoadFromStackSlot(const MachineInstr &MI, ++ int &FrameIndex) const { ++ unsigned Opc = MI.getOpcode(); ++ if ((Opc == LoongArch::LD_W) || (Opc == LoongArch::LD_D) || ++ (Opc == LoongArch::FLD_S) || (Opc == LoongArch::FLD_D)) { ++ if ((MI.getOperand(1).isFI()) && // is a stack slot ++ (MI.getOperand(2).isImm()) && // the imm is zero ++ (isZeroImm(MI.getOperand(2)))) { ++ FrameIndex = MI.getOperand(1).getIndex(); ++ return MI.getOperand(0).getReg(); ++ } + } ++ return 0; ++} + +- // VR->VR copies. +- if (LoongArch::LSX128RegClass.contains(DstReg, SrcReg)) { +- BuildMI(MBB, MBBI, DL, get(LoongArch::VORI_B), DstReg) +- .addReg(SrcReg, getKillRegState(KillSrc)) +- .addImm(0); +- return; ++/// isStoreToStackSlot - If the specified machine instruction is a direct ++/// store to a stack slot, return the virtual or physical register number of ++/// the source reg along with the FrameIndex of the loaded stack slot. If ++/// not, return 0. This predicate must return 0 if the instruction has ++/// any side effects other than storing to the stack slot. ++unsigned LoongArchInstrInfo::isStoreToStackSlot(const MachineInstr &MI, ++ int &FrameIndex) const { ++ unsigned Opc = MI.getOpcode(); ++ if ((Opc == LoongArch::ST_D) || (Opc == LoongArch::ST_W) || ++ (Opc == LoongArch::FST_S) ||(Opc == LoongArch::FST_D)) { ++ if ((MI.getOperand(1).isFI()) && // is a stack slot ++ (MI.getOperand(2).isImm()) && // the imm is zero ++ (isZeroImm(MI.getOperand(2)))) { ++ FrameIndex = MI.getOperand(1).getIndex(); ++ return MI.getOperand(0).getReg(); ++ } + } ++ return 0; ++} + +- // XR->XR copies. +- if (LoongArch::LASX256RegClass.contains(DstReg, SrcReg)) { +- BuildMI(MBB, MBBI, DL, get(LoongArch::XVORI_B), DstReg) +- .addReg(SrcReg, getKillRegState(KillSrc)) +- .addImm(0); +- return; ++void LoongArchInstrInfo::copyPhysReg(MachineBasicBlock &MBB, ++ MachineBasicBlock::iterator I, ++ const DebugLoc &DL, MCRegister DestReg, ++ MCRegister SrcReg, bool KillSrc) const { ++ unsigned Opc = 0, ZeroReg = 0; ++ unsigned ZeroImm = 1; ++ if (LoongArch::GPR32RegClass.contains(DestReg)) { // Copy to CPU Reg. ++ if (LoongArch::GPR32RegClass.contains(SrcReg)) { ++ Opc = LoongArch::OR32, ZeroReg = LoongArch::ZERO; ++ } ++ else if (LoongArch::FGR32RegClass.contains(SrcReg)) ++ Opc = LoongArch::MOVFR2GR_S; ++ else if (LoongArch::FCFRRegClass.contains(SrcReg)) ++ Opc = LoongArch::MOVCF2GR; + } +- +- // GPR->CFR copy. +- if (LoongArch::CFRRegClass.contains(DstReg) && +- LoongArch::GPRRegClass.contains(SrcReg)) { +- BuildMI(MBB, MBBI, DL, get(LoongArch::MOVGR2CF), DstReg) +- .addReg(SrcReg, getKillRegState(KillSrc)); +- return; ++ else if (LoongArch::GPR32RegClass.contains(SrcReg)) { // Copy from CPU Reg. ++ if (LoongArch::FGR32RegClass.contains(DestReg)) ++ Opc = LoongArch::MOVGR2FR_W; ++ else if (LoongArch::FCFRRegClass.contains(DestReg)) ++ Opc = LoongArch::MOVGR2CF; + } +- // CFR->GPR copy. +- if (LoongArch::GPRRegClass.contains(DstReg) && +- LoongArch::CFRRegClass.contains(SrcReg)) { +- BuildMI(MBB, MBBI, DL, get(LoongArch::MOVCF2GR), DstReg) +- .addReg(SrcReg, getKillRegState(KillSrc)); +- return; ++ else if (LoongArch::FGR32RegClass.contains(DestReg, SrcReg)) ++ Opc = LoongArch::FMOV_S; ++ else if (LoongArch::FGR64RegClass.contains(DestReg, SrcReg)) ++ Opc = LoongArch::FMOV_D; ++ else if (LoongArch::GPR64RegClass.contains(DestReg)) { // Copy to CPU64 Reg. ++ if (LoongArch::GPR64RegClass.contains(SrcReg)) ++ Opc = LoongArch::OR, ZeroReg = LoongArch::ZERO_64; ++ else if (LoongArch::FGR64RegClass.contains(SrcReg)) ++ Opc = LoongArch::MOVFR2GR_D; ++ else if (LoongArch::FCFRRegClass.contains(SrcReg)) ++ Opc = LoongArch::MOVCF2GR; + } +- // CFR->CFR copy. +- if (LoongArch::CFRRegClass.contains(DstReg, SrcReg)) { +- BuildMI(MBB, MBBI, DL, get(LoongArch::PseudoCopyCFR), DstReg) +- .addReg(SrcReg, getKillRegState(KillSrc)); +- return; ++ else if (LoongArch::GPR64RegClass.contains(SrcReg)) { // Copy from CPU64 Reg. ++ if (LoongArch::FGR64RegClass.contains(DestReg)) ++ Opc = LoongArch::MOVGR2FR_D; ++ else if (LoongArch::FCFRRegClass.contains(DestReg)) ++ Opc = LoongArch::MOVGR2CF; ++ } ++ else if (LoongArch::FGR32RegClass.contains(DestReg)) // Copy to FGR32 Reg ++ Opc = LoongArch::MOVCF2FR; ++ else if (LoongArch::FGR32RegClass.contains(SrcReg)) // Copy from FGR32 Reg ++ Opc = LoongArch::MOVFR2CF; ++ else if (LoongArch::FGR64RegClass.contains(DestReg)) // Copy to FGR64 Reg ++ Opc = LoongArch::MOVCF2FR; ++ else if (LoongArch::FGR64RegClass.contains(SrcReg)) // Copy from FGR64 Reg ++ Opc = LoongArch::MOVFR2CF; ++ else if (LoongArch::LSX128BRegClass.contains(DestReg)) { // Copy to LSX reg ++ if (LoongArch::LSX128BRegClass.contains(SrcReg)) ++ Opc = LoongArch::VORI_B, ZeroImm = 0; ++ } else if (LoongArch::LASX256BRegClass.contains( ++ DestReg)) { // Copy to LASX reg ++ if (LoongArch::LASX256BRegClass.contains(SrcReg)) ++ Opc = LoongArch::XVORI_B, ZeroImm = 0; + } + +- // FPR->FPR copies. +- unsigned Opc; +- if (LoongArch::FPR32RegClass.contains(DstReg, SrcReg)) { +- Opc = LoongArch::FMOV_S; +- } else if (LoongArch::FPR64RegClass.contains(DstReg, SrcReg)) { +- Opc = LoongArch::FMOV_D; +- } else if (LoongArch::GPRRegClass.contains(DstReg) && +- LoongArch::FPR32RegClass.contains(SrcReg)) { +- // FPR32 -> GPR copies +- Opc = LoongArch::MOVFR2GR_S; +- } else if (LoongArch::GPRRegClass.contains(DstReg) && +- LoongArch::FPR64RegClass.contains(SrcReg)) { +- // FPR64 -> GPR copies +- Opc = LoongArch::MOVFR2GR_D; +- } else { +- // TODO: support other copies. +- llvm_unreachable("Impossible reg-to-reg copy"); ++ assert(Opc && "Cannot copy registers"); ++ ++ MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc)); ++ ++ if (DestReg) ++ MIB.addReg(DestReg, RegState::Define); ++ ++ if (SrcReg) ++ MIB.addReg(SrcReg, getKillRegState(KillSrc)); ++ ++ if (ZeroReg) ++ MIB.addReg(ZeroReg); ++ ++ if (!ZeroImm) ++ MIB.addImm(0); ++} ++ ++static bool isORCopyInst(const MachineInstr &MI) { ++ switch (MI.getOpcode()) { ++ default: ++ break; ++ case LoongArch::OR: ++ if (MI.getOperand(2).getReg() == LoongArch::ZERO_64) ++ return true; ++ break; ++ case LoongArch::OR32: ++ if (MI.getOperand(2).getReg() == LoongArch::ZERO) ++ return true; ++ break; + } ++ return false; ++} + +- BuildMI(MBB, MBBI, DL, get(Opc), DstReg) +- .addReg(SrcReg, getKillRegState(KillSrc)); ++/// We check for the common case of 'or', as it's LoongArch' preferred instruction ++/// for GPRs but we have to check the operands to ensure that is the case. ++/// Other move instructions for LoongArch are directly identifiable. ++std::optional ++LoongArchInstrInfo::isCopyInstrImpl(const MachineInstr &MI) const { ++ if (MI.isMoveReg() || isORCopyInst(MI)) { ++ return DestSourcePair{MI.getOperand(0), MI.getOperand(1)}; ++ } ++ return std::nullopt; + } + +-void LoongArchInstrInfo::storeRegToStackSlot( +- MachineBasicBlock &MBB, MachineBasicBlock::iterator I, Register SrcReg, +- bool IsKill, int FI, const TargetRegisterClass *RC, +- const TargetRegisterInfo *TRI, Register VReg) const { +- MachineFunction *MF = MBB.getParent(); +- MachineFrameInfo &MFI = MF->getFrameInfo(); +- +- unsigned Opcode; +- if (LoongArch::GPRRegClass.hasSubClassEq(RC)) +- Opcode = TRI->getRegSizeInBits(LoongArch::GPRRegClass) == 32 +- ? LoongArch::ST_W +- : LoongArch::ST_D; +- else if (LoongArch::FPR32RegClass.hasSubClassEq(RC)) +- Opcode = LoongArch::FST_S; +- else if (LoongArch::FPR64RegClass.hasSubClassEq(RC)) +- Opcode = LoongArch::FST_D; +- else if (LoongArch::LSX128RegClass.hasSubClassEq(RC)) +- Opcode = LoongArch::VST; +- else if (LoongArch::LASX256RegClass.hasSubClassEq(RC)) +- Opcode = LoongArch::XVST; +- else if (LoongArch::CFRRegClass.hasSubClassEq(RC)) +- Opcode = LoongArch::PseudoST_CFR; +- else +- llvm_unreachable("Can't store this register to stack slot"); ++void LoongArchInstrInfo:: ++storeRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, ++ Register SrcReg, bool isKill, int FI, ++ const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, ++ int64_t Offset) const { ++ DebugLoc DL; ++ MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOStore); + +- MachineMemOperand *MMO = MF->getMachineMemOperand( +- MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOStore, +- MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); ++ unsigned Opc = 0; ++ if (LoongArch::GPR32RegClass.hasSubClassEq(RC)) ++ Opc = LoongArch::ST_W; ++ else if (LoongArch::GPR64RegClass.hasSubClassEq(RC)) ++ Opc = LoongArch::ST_D; ++ else if (LoongArch::FGR64RegClass.hasSubClassEq(RC)) ++ Opc = LoongArch::FST_D; ++ else if (LoongArch::FGR32RegClass.hasSubClassEq(RC)) ++ Opc = LoongArch::FST_S; + +- BuildMI(MBB, I, DebugLoc(), get(Opcode)) +- .addReg(SrcReg, getKillRegState(IsKill)) ++ else if (TRI->isTypeLegalForClass(*RC, MVT::v16i8)) ++ Opc = LoongArch::VST; ++ else if (TRI->isTypeLegalForClass(*RC, MVT::v8i16)) ++ Opc = LoongArch::VST_H; ++ else if (TRI->isTypeLegalForClass(*RC, MVT::v4i32) || ++ TRI->isTypeLegalForClass(*RC, MVT::v4f32)) ++ Opc = LoongArch::VST_W; ++ else if (TRI->isTypeLegalForClass(*RC, MVT::v2i64) || ++ TRI->isTypeLegalForClass(*RC, MVT::v2f64)) ++ Opc = LoongArch::VST_D; ++ else if (TRI->isTypeLegalForClass(*RC, MVT::v32i8)) ++ Opc = LoongArch::XVST; ++ else if (TRI->isTypeLegalForClass(*RC, MVT::v16i16)) ++ Opc = LoongArch::XVST_H; ++ else if (TRI->isTypeLegalForClass(*RC, MVT::v8i32) || ++ TRI->isTypeLegalForClass(*RC, MVT::v8f32)) ++ Opc = LoongArch::XVST_W; ++ else if (TRI->isTypeLegalForClass(*RC, MVT::v4i64) || ++ TRI->isTypeLegalForClass(*RC, MVT::v4f64)) ++ Opc = LoongArch::XVST_D; ++ ++ assert(Opc && "Register class not handled!"); ++ BuildMI(MBB, I, DL, get(Opc)) ++ .addReg(SrcReg, getKillRegState(isKill)) + .addFrameIndex(FI) +- .addImm(0) ++ .addImm(Offset) + .addMemOperand(MMO); + } + +-void LoongArchInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator I, +- Register DstReg, int FI, +- const TargetRegisterClass *RC, +- const TargetRegisterInfo *TRI, +- Register VReg) const { +- MachineFunction *MF = MBB.getParent(); +- MachineFrameInfo &MFI = MF->getFrameInfo(); +- +- unsigned Opcode; +- if (LoongArch::GPRRegClass.hasSubClassEq(RC)) +- Opcode = TRI->getRegSizeInBits(LoongArch::GPRRegClass) == 32 +- ? LoongArch::LD_W +- : LoongArch::LD_D; +- else if (LoongArch::FPR32RegClass.hasSubClassEq(RC)) +- Opcode = LoongArch::FLD_S; +- else if (LoongArch::FPR64RegClass.hasSubClassEq(RC)) +- Opcode = LoongArch::FLD_D; +- else if (LoongArch::LSX128RegClass.hasSubClassEq(RC)) +- Opcode = LoongArch::VLD; +- else if (LoongArch::LASX256RegClass.hasSubClassEq(RC)) +- Opcode = LoongArch::XVLD; +- else if (LoongArch::CFRRegClass.hasSubClassEq(RC)) +- Opcode = LoongArch::PseudoLD_CFR; +- else +- llvm_unreachable("Can't load this register from stack slot"); ++void LoongArchInstrInfo:: ++loadRegFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, ++ Register DestReg, int FI, const TargetRegisterClass *RC, ++ const TargetRegisterInfo *TRI, int64_t Offset) const { ++ DebugLoc DL; ++ if (I != MBB.end()) ++ DL = I->getDebugLoc(); ++ MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOLoad); ++ unsigned Opc = 0; ++ ++ if (LoongArch::GPR32RegClass.hasSubClassEq(RC)) ++ Opc = LoongArch::LD_W; ++ else if (LoongArch::GPR64RegClass.hasSubClassEq(RC)) ++ Opc = LoongArch::LD_D; ++ else if (LoongArch::FGR32RegClass.hasSubClassEq(RC)) ++ Opc = LoongArch::FLD_S; ++ else if (LoongArch::FGR64RegClass.hasSubClassEq(RC)) ++ Opc = LoongArch::FLD_D; ++ else if (TRI->isTypeLegalForClass(*RC, MVT::v16i8)) ++ Opc = LoongArch::VLD; ++ else if (TRI->isTypeLegalForClass(*RC, MVT::v8i16)) ++ Opc = LoongArch::VLD_H; ++ else if (TRI->isTypeLegalForClass(*RC, MVT::v4i32) || ++ TRI->isTypeLegalForClass(*RC, MVT::v4f32)) ++ Opc = LoongArch::VLD_W; ++ else if (TRI->isTypeLegalForClass(*RC, MVT::v2i64) || ++ TRI->isTypeLegalForClass(*RC, MVT::v2f64)) ++ Opc = LoongArch::VLD_D; ++ else if (TRI->isTypeLegalForClass(*RC, MVT::v32i8)) ++ Opc = LoongArch::XVLD; ++ else if (TRI->isTypeLegalForClass(*RC, MVT::v16i16)) ++ Opc = LoongArch::XVLD_H; ++ else if (TRI->isTypeLegalForClass(*RC, MVT::v8i32) || ++ TRI->isTypeLegalForClass(*RC, MVT::v8f32)) ++ Opc = LoongArch::XVLD_W; ++ else if (TRI->isTypeLegalForClass(*RC, MVT::v4i64) || ++ TRI->isTypeLegalForClass(*RC, MVT::v4f64)) ++ Opc = LoongArch::XVLD_D; + +- MachineMemOperand *MMO = MF->getMachineMemOperand( +- MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad, +- MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); ++ assert(Opc && "Register class not handled!"); + +- BuildMI(MBB, I, DebugLoc(), get(Opcode), DstReg) ++ BuildMI(MBB, I, DL, get(Opc), DestReg) + .addFrameIndex(FI) +- .addImm(0) ++ .addImm(Offset) + .addMemOperand(MMO); + } + +-void LoongArchInstrInfo::movImm(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, +- const DebugLoc &DL, Register DstReg, +- uint64_t Val, MachineInstr::MIFlag Flag) const { +- Register SrcReg = LoongArch::R0; ++bool LoongArchInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { ++ MachineBasicBlock &MBB = *MI.getParent(); ++ switch (MI.getDesc().getOpcode()) { ++ default: ++ return false; ++ case LoongArch::RetRA: ++ expandRetRA(MBB, MI); ++ break; ++ case LoongArch::ERet: ++ expandERet(MBB, MI); ++ break; ++ case LoongArch::PseudoFFINT_S_W: ++ expandCvtFPInt(MBB, MI, LoongArch::FFINT_S_W, LoongArch::MOVGR2FR_W, false); ++ break; ++ case LoongArch::PseudoFFINT_S_L: ++ expandCvtFPInt(MBB, MI, LoongArch::FFINT_S_L, LoongArch::MOVGR2FR_D, true); ++ break; ++ case LoongArch::PseudoFFINT_D_W: ++ expandCvtFPInt(MBB, MI, LoongArch::FFINT_D_W, LoongArch::MOVGR2FR_W, true); ++ break; ++ case LoongArch::PseudoFFINT_D_L: ++ expandCvtFPInt(MBB, MI, LoongArch::FFINT_D_L, LoongArch::MOVGR2FR_D, true); ++ break; ++ case LoongArch::LoongArcheh_return32: ++ case LoongArch::LoongArcheh_return64: ++ expandEhReturn(MBB, MI); ++ break; ++ } ++ ++ MBB.erase(MI); ++ return true; ++} ++ ++/// getOppositeBranchOpc - Return the inverse of the specified ++/// opcode, e.g. turning BEQ to BNE. ++unsigned LoongArchInstrInfo::getOppositeBranchOpc(unsigned Opc) const { ++ switch (Opc) { ++ default: llvm_unreachable("Illegal opcode!"); ++ case LoongArch::BEQ32: return LoongArch::BNE32; ++ case LoongArch::BEQ: return LoongArch::BNE; ++ case LoongArch::BNE32: return LoongArch::BEQ32; ++ case LoongArch::BNE: return LoongArch::BEQ; ++ case LoongArch::BEQZ32: return LoongArch::BNEZ32; ++ case LoongArch::BEQZ: return LoongArch::BNEZ; ++ case LoongArch::BNEZ32: return LoongArch::BEQZ32; ++ case LoongArch::BNEZ: return LoongArch::BEQZ; ++ case LoongArch::BCEQZ: return LoongArch::BCNEZ; ++ case LoongArch::BCNEZ: return LoongArch::BCEQZ; ++ case LoongArch::BLT32: return LoongArch::BGE32; ++ case LoongArch::BLT: return LoongArch::BGE; ++ case LoongArch::BGE32: return LoongArch::BLT32; ++ case LoongArch::BGE: return LoongArch::BLT; ++ case LoongArch::BLTU32: return LoongArch::BGEU32; ++ case LoongArch::BLTU: return LoongArch::BGEU; ++ case LoongArch::BGEU32: return LoongArch::BLTU32; ++ case LoongArch::BGEU: return LoongArch::BLTU; ++ } ++} ++ ++void LoongArchInstrInfo::adjustReg(unsigned DestReg, unsigned SrcReg, ++ int64_t Amount, MachineBasicBlock &MBB, ++ MachineBasicBlock::iterator I, ++ MachineInstr::MIFlag Flag) const { ++ LoongArchABIInfo ABI = Subtarget.getABI(); ++ DebugLoc DL; ++ unsigned ADDI = ABI.GetPtrAddiOp(); ++ ++ if (Amount == 0) ++ return; + +- if (!STI.is64Bit() && !isInt<32>(Val)) +- report_fatal_error("Should only materialize 32-bit constants for LA32"); ++ if (isInt<12>(Amount)) { ++ // addi $DestReg, $SrcReg, amount ++ BuildMI(MBB, I, DL, get(ADDI), DestReg) ++ .addReg(SrcReg) ++ .addImm(Amount) ++ .setMIFlag(Flag); ++ } else { ++ // For numbers which are not 12bit integers we synthesize Amount inline ++ // then add or subtract it from $SrcReg. ++ unsigned Opc = ABI.GetPtrAddOp(); ++ if (Amount < 0) { ++ Opc = ABI.GetPtrSubOp(); ++ Amount = -Amount; ++ } ++ unsigned Reg = loadImmediate(Amount, MBB, I, DL); ++ BuildMI(MBB, I, DL, get(Opc), DestReg) ++ .addReg(SrcReg) ++ .addReg(Reg, RegState::Kill) ++ .setMIFlag(Flag); ++ } ++} + +- auto Seq = LoongArchMatInt::generateInstSeq(Val); +- assert(!Seq.empty()); ++/// This function generates the sequence of instructions needed to get the ++/// result of adding register REG and immediate IMM. ++unsigned LoongArchInstrInfo::loadImmediate(int64_t Imm, MachineBasicBlock &MBB, ++ MachineBasicBlock::iterator II, ++ const DebugLoc &DL) const { ++ const TargetRegisterClass *RC = Subtarget.isABI_LP64() ++ ? &LoongArch::GPR64RegClass ++ : &LoongArch::GPR32RegClass; ++ LoongArchAnalyzeImmediate::InstSeq Seq = ++ LoongArchAnalyzeImmediate::generateInstSeq(Imm, Subtarget.is64Bit()); ++ unsigned DstReg = MBB.getParent()->getRegInfo().createVirtualRegister(RC); ++ unsigned SrcReg = ++ Subtarget.isABI_LP64() ? LoongArch::ZERO_64 : LoongArch::ZERO; + ++ // Build the instructions in Seq. + for (auto &Inst : Seq) { +- switch (Inst.Opc) { +- case LoongArch::LU12I_W: +- BuildMI(MBB, MBBI, DL, get(Inst.Opc), DstReg) +- .addImm(Inst.Imm) +- .setMIFlag(Flag); +- break; +- case LoongArch::ADDI_W: +- case LoongArch::ORI: +- case LoongArch::LU32I_D: // "rj" is needed due to InstrInfo pattern +- case LoongArch::LU52I_D: +- BuildMI(MBB, MBBI, DL, get(Inst.Opc), DstReg) ++ if (Inst.Opc == LoongArch::LU12I_W || Inst.Opc == LoongArch::LU12I_W32) ++ BuildMI(MBB, II, DL, get(Inst.Opc), DstReg).addImm(Inst.Imm); ++ else ++ BuildMI(MBB, II, DL, get(Inst.Opc), DstReg) + .addReg(SrcReg, RegState::Kill) +- .addImm(Inst.Imm) +- .setMIFlag(Flag); +- break; +- default: +- assert(false && "Unknown insn emitted by LoongArchMatInt"); +- } +- +- // Only the first instruction has $zero as its source. ++ .addImm(Inst.Imm); + SrcReg = DstReg; + } ++ return DstReg; + } + +-unsigned LoongArchInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const { +- unsigned Opcode = MI.getOpcode(); ++unsigned LoongArchInstrInfo::getAnalyzableBrOpc(unsigned Opc) const { ++ return (Opc == LoongArch::B || Opc == LoongArch::B32 || ++ Opc == LoongArch::BEQZ || Opc == LoongArch::BEQZ32 || ++ Opc == LoongArch::BNEZ || Opc == LoongArch::BNEZ32 || ++ Opc == LoongArch::BCEQZ || ++ Opc == LoongArch::BCNEZ || ++ Opc == LoongArch::BEQ || Opc == LoongArch::BEQ32 || ++ Opc == LoongArch::BNE || Opc == LoongArch::BNE32 || ++ Opc == LoongArch::BLT || Opc == LoongArch::BLT32 || ++ Opc == LoongArch::BGE || Opc == LoongArch::BGE32 || ++ Opc == LoongArch::BLTU || Opc == LoongArch::BLTU32 || ++ Opc == LoongArch::BGEU || Opc == LoongArch::BGEU32) ? Opc : 0; ++} + +- if (Opcode == TargetOpcode::INLINEASM || +- Opcode == TargetOpcode::INLINEASM_BR) { +- const MachineFunction *MF = MI.getParent()->getParent(); +- const MCAsmInfo *MAI = MF->getTarget().getMCAsmInfo(); +- return getInlineAsmLength(MI.getOperand(0).getSymbolName(), *MAI); ++void LoongArchInstrInfo::expandRetRA(MachineBasicBlock &MBB, ++ MachineBasicBlock::iterator I) const { ++ ++ MachineInstrBuilder MIB; ++ ++ if (Subtarget.is64Bit()) ++ MIB = BuildMI(MBB, I, I->getDebugLoc(), get(LoongArch::PseudoReturn64)) ++ .addReg(LoongArch::RA_64, RegState::Undef); ++ else ++ MIB = BuildMI(MBB, I, I->getDebugLoc(), get(LoongArch::PseudoReturn)) ++ .addReg(LoongArch::RA, RegState::Undef); ++ ++ // Retain any imp-use flags. ++ for (auto & MO : I->operands()) { ++ if (MO.isImplicit()) ++ MIB.add(MO); + } +- return MI.getDesc().getSize(); + } + +-MachineBasicBlock * +-LoongArchInstrInfo::getBranchDestBlock(const MachineInstr &MI) const { +- assert(MI.getDesc().isBranch() && "Unexpected opcode!"); +- // The branch target is always the last operand. +- return MI.getOperand(MI.getNumExplicitOperands() - 1).getMBB(); ++void LoongArchInstrInfo::expandERet(MachineBasicBlock &MBB, ++ MachineBasicBlock::iterator I) const { ++ BuildMI(MBB, I, I->getDebugLoc(), get(LoongArch::ERTN)); + } + +-static void parseCondBranch(MachineInstr &LastInst, MachineBasicBlock *&Target, +- SmallVectorImpl &Cond) { +- // Block ends with fall-through condbranch. +- assert(LastInst.getDesc().isConditionalBranch() && +- "Unknown conditional branch"); +- int NumOp = LastInst.getNumExplicitOperands(); +- Target = LastInst.getOperand(NumOp - 1).getMBB(); ++std::pair ++LoongArchInstrInfo::compareOpndSize(unsigned Opc, ++ const MachineFunction &MF) const { ++ const MCInstrDesc &Desc = get(Opc); ++ assert(Desc.NumOperands == 2 && "Unary instruction expected."); ++ const LoongArchRegisterInfo *RI = &getRegisterInfo(); ++ unsigned DstRegSize = RI->getRegSizeInBits(*getRegClass(Desc, 0, RI, MF)); ++ unsigned SrcRegSize = RI->getRegSizeInBits(*getRegClass(Desc, 1, RI, MF)); + +- Cond.push_back(MachineOperand::CreateImm(LastInst.getOpcode())); +- for (int i = 0; i < NumOp - 1; i++) +- Cond.push_back(LastInst.getOperand(i)); ++ return std::make_pair(DstRegSize > SrcRegSize, DstRegSize < SrcRegSize); + } + +-bool LoongArchInstrInfo::analyzeBranch(MachineBasicBlock &MBB, +- MachineBasicBlock *&TBB, +- MachineBasicBlock *&FBB, +- SmallVectorImpl &Cond, +- bool AllowModify) const { +- TBB = FBB = nullptr; +- Cond.clear(); +- +- // If the block has no terminators, it just falls into the block after it. +- MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); +- if (I == MBB.end() || !isUnpredicatedTerminator(*I)) +- return false; ++void LoongArchInstrInfo::expandCvtFPInt(MachineBasicBlock &MBB, ++ MachineBasicBlock::iterator I, ++ unsigned CvtOpc, unsigned MovOpc, ++ bool IsI64) const { ++ const MCInstrDesc &CvtDesc = get(CvtOpc), &MovDesc = get(MovOpc); ++ const MachineOperand &Dst = I->getOperand(0), &Src = I->getOperand(1); ++ unsigned DstReg = Dst.getReg(), SrcReg = Src.getReg(), TmpReg = DstReg; ++ unsigned KillSrc = getKillRegState(Src.isKill()); ++ DebugLoc DL = I->getDebugLoc(); ++ bool DstIsLarger, SrcIsLarger; + +- // Count the number of terminators and find the first unconditional or +- // indirect branch. +- MachineBasicBlock::iterator FirstUncondOrIndirectBr = MBB.end(); +- int NumTerminators = 0; +- for (auto J = I.getReverse(); J != MBB.rend() && isUnpredicatedTerminator(*J); +- J++) { +- NumTerminators++; +- if (J->getDesc().isUnconditionalBranch() || +- J->getDesc().isIndirectBranch()) { +- FirstUncondOrIndirectBr = J.getReverse(); +- } +- } ++ std::tie(DstIsLarger, SrcIsLarger) = ++ compareOpndSize(CvtOpc, *MBB.getParent()); + +- // If AllowModify is true, we can erase any terminators after +- // FirstUncondOrIndirectBR. +- if (AllowModify && FirstUncondOrIndirectBr != MBB.end()) { +- while (std::next(FirstUncondOrIndirectBr) != MBB.end()) { +- std::next(FirstUncondOrIndirectBr)->eraseFromParent(); +- NumTerminators--; +- } +- I = FirstUncondOrIndirectBr; +- } ++ if (DstIsLarger) ++ TmpReg = getRegisterInfo().getSubReg(DstReg, LoongArch::sub_lo); + +- // Handle a single unconditional branch. +- if (NumTerminators == 1 && I->getDesc().isUnconditionalBranch()) { +- TBB = getBranchDestBlock(*I); +- return false; +- } ++ if (SrcIsLarger) ++ DstReg = getRegisterInfo().getSubReg(DstReg, LoongArch::sub_lo); + +- // Handle a single conditional branch. +- if (NumTerminators == 1 && I->getDesc().isConditionalBranch()) { +- parseCondBranch(*I, TBB, Cond); +- return false; +- } ++ BuildMI(MBB, I, DL, MovDesc, TmpReg).addReg(SrcReg, KillSrc); ++ BuildMI(MBB, I, DL, CvtDesc, DstReg).addReg(TmpReg, RegState::Kill); ++} + +- // Handle a conditional branch followed by an unconditional branch. +- if (NumTerminators == 2 && std::prev(I)->getDesc().isConditionalBranch() && +- I->getDesc().isUnconditionalBranch()) { +- parseCondBranch(*std::prev(I), TBB, Cond); +- FBB = getBranchDestBlock(*I); +- return false; +- } ++void LoongArchInstrInfo::expandEhReturn(MachineBasicBlock &MBB, ++ MachineBasicBlock::iterator I) const { ++ // This pseudo instruction is generated as part of the lowering of ++ // ISD::EH_RETURN. We convert it to a stack increment by OffsetReg, and ++ // indirect jump to TargetReg ++ LoongArchABIInfo ABI = Subtarget.getABI(); ++ unsigned ADD = ABI.GetPtrAddOp(); ++ unsigned SP = Subtarget.is64Bit() ? LoongArch::SP_64 : LoongArch::SP; ++ unsigned RA = Subtarget.is64Bit() ? LoongArch::RA_64 : LoongArch::RA; ++ unsigned T8 = Subtarget.is64Bit() ? LoongArch::T8_64 : LoongArch::T8; ++ unsigned ZERO = Subtarget.is64Bit() ? LoongArch::ZERO_64 : LoongArch::ZERO; ++ unsigned OffsetReg = I->getOperand(0).getReg(); ++ unsigned TargetReg = I->getOperand(1).getReg(); + +- // Otherwise, we can't handle this. +- return true; ++ // add $ra, $v0, $zero ++ // add $sp, $sp, $v1 ++ // jr $ra (via RetRA) ++ const TargetMachine &TM = MBB.getParent()->getTarget(); ++ if (TM.isPositionIndependent()) ++ BuildMI(MBB, I, I->getDebugLoc(), get(ADD), T8) ++ .addReg(TargetReg) ++ .addReg(ZERO); ++ BuildMI(MBB, I, I->getDebugLoc(), get(ADD), RA) ++ .addReg(TargetReg) ++ .addReg(ZERO); ++ BuildMI(MBB, I, I->getDebugLoc(), get(ADD), SP).addReg(SP).addReg(OffsetReg); ++ expandRetRA(MBB, I); + } + +-bool LoongArchInstrInfo::isBranchOffsetInRange(unsigned BranchOp, +- int64_t BrOffset) const { +- switch (BranchOp) { +- default: +- llvm_unreachable("Unknown branch instruction!"); +- case LoongArch::BEQ: +- case LoongArch::BNE: +- case LoongArch::BLT: +- case LoongArch::BGE: +- case LoongArch::BLTU: +- case LoongArch::BGEU: +- return isInt<18>(BrOffset); +- case LoongArch::BEQZ: +- case LoongArch::BNEZ: +- case LoongArch::BCEQZ: +- case LoongArch::BCNEZ: +- return isInt<23>(BrOffset); +- case LoongArch::B: +- case LoongArch::PseudoBR: +- return isInt<28>(BrOffset); +- } ++ ++bool LoongArchInstrInfo::isZeroImm(const MachineOperand &op) const { ++ return op.isImm() && op.getImm() == 0; + } + +-unsigned LoongArchInstrInfo::removeBranch(MachineBasicBlock &MBB, +- int *BytesRemoved) const { +- if (BytesRemoved) +- *BytesRemoved = 0; +- MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); +- if (I == MBB.end()) +- return 0; ++/// insertNoop - If data hazard condition is found insert the target nop ++/// instruction. ++// FIXME: This appears to be dead code. ++void LoongArchInstrInfo:: ++insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const ++{ ++ DebugLoc DL; ++ BuildMI(MBB, MI, DL, get(LoongArch::NOP)); ++} + +- if (!I->getDesc().isBranch()) +- return 0; ++MachineMemOperand * ++LoongArchInstrInfo::GetMemOperand(MachineBasicBlock &MBB, int FI, ++ MachineMemOperand::Flags Flags) const { ++ MachineFunction &MF = *MBB.getParent(); ++ MachineFrameInfo &MFI = MF.getFrameInfo(); + +- // Remove the branch. +- if (BytesRemoved) +- *BytesRemoved += getInstSizeInBytes(*I); +- I->eraseFromParent(); ++ return MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(MF, FI), ++ Flags, MFI.getObjectSize(FI), ++ MFI.getObjectAlign(FI)); ++} ++ ++//===----------------------------------------------------------------------===// ++// Branch Analysis ++//===----------------------------------------------------------------------===// + +- I = MBB.end(); ++void LoongArchInstrInfo::AnalyzeCondBr(const MachineInstr *Inst, unsigned Opc, ++ MachineBasicBlock *&BB, ++ SmallVectorImpl &Cond) const { ++ assert(getAnalyzableBrOpc(Opc) && "Not an analyzable branch"); ++ int NumOp = Inst->getNumExplicitOperands(); + +- if (I == MBB.begin()) +- return 1; +- --I; +- if (!I->getDesc().isConditionalBranch()) +- return 1; ++ // for both int and fp branches, the last explicit operand is the ++ // MBB. ++ BB = Inst->getOperand(NumOp-1).getMBB(); ++ Cond.push_back(MachineOperand::CreateImm(Opc)); + +- // Remove the branch. +- if (BytesRemoved) +- *BytesRemoved += getInstSizeInBytes(*I); +- I->eraseFromParent(); +- return 2; ++ for (int i = 0; i < NumOp-1; i++) ++ Cond.push_back(Inst->getOperand(i)); + } + +-// Inserts a branch into the end of the specific MachineBasicBlock, returning +-// the number of instructions inserted. +-unsigned LoongArchInstrInfo::insertBranch( +- MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, +- ArrayRef Cond, const DebugLoc &DL, int *BytesAdded) const { +- if (BytesAdded) +- *BytesAdded = 0; ++bool LoongArchInstrInfo::analyzeBranch(MachineBasicBlock &MBB, ++ MachineBasicBlock *&TBB, ++ MachineBasicBlock *&FBB, ++ SmallVectorImpl &Cond, ++ bool AllowModify) const { ++ SmallVector BranchInstrs; ++ BranchType BT = analyzeBranch(MBB, TBB, FBB, Cond, AllowModify, BranchInstrs); ++ ++ return (BT == BT_None) || (BT == BT_Indirect); ++} + ++MachineInstr * ++LoongArchInstrInfo::BuildCondBr(MachineBasicBlock &MBB, MachineBasicBlock *TBB, ++ const DebugLoc &DL, ++ ArrayRef Cond) const { ++ unsigned Opc = Cond[0].getImm(); ++ const MCInstrDesc &MCID = get(Opc); ++ MachineInstrBuilder MIB = BuildMI(&MBB, DL, MCID); ++ ++ for (unsigned i = 1; i < Cond.size(); ++i) { ++ assert((Cond[i].isImm() || Cond[i].isReg()) && ++ "Cannot copy operand for conditional branch!"); ++ MIB.add(Cond[i]); ++ } ++ MIB.addMBB(TBB); ++ return MIB.getInstr(); ++} ++ ++unsigned LoongArchInstrInfo::insertBranch(MachineBasicBlock &MBB, ++ MachineBasicBlock *TBB, ++ MachineBasicBlock *FBB, ++ ArrayRef Cond, ++ const DebugLoc &DL, ++ int *BytesAdded) const { ++ unsigned UncondBrOpc = LoongArch::B; + // Shouldn't be a fall through. + assert(TBB && "insertBranch must not be told to insert a fallthrough"); +- assert(Cond.size() <= 3 && Cond.size() != 1 && +- "LoongArch branch conditions have at most two components!"); ++ if (BytesAdded) ++ *BytesAdded = 0; + ++ // # of condition operands: ++ // Unconditional branches: 0 ++ // Floating point branches: 1 (opc) ++ // Int BranchZero: 2 (opc, reg) ++ // Int Branch: 3 (opc, reg0, reg1) ++ assert((Cond.size() <= 3) && ++ "# of LoongArch branch conditions must be <= 3!"); ++ ++ // Two-way Conditional branch. ++ if (FBB) { ++ MachineInstr &MI1 = *BuildCondBr(MBB, TBB, DL, Cond); ++ if (BytesAdded) ++ *BytesAdded += getInstSizeInBytes(MI1); ++ MachineInstr &MI2 = *BuildMI(&MBB, DL, get(UncondBrOpc)).addMBB(FBB); ++ if (BytesAdded) ++ *BytesAdded += getInstSizeInBytes(MI2); ++ return 2; ++ } ++ ++ // One way branch. + // Unconditional branch. + if (Cond.empty()) { +- MachineInstr &MI = *BuildMI(&MBB, DL, get(LoongArch::PseudoBR)).addMBB(TBB); ++ MachineInstr &MI = *BuildMI(&MBB, DL, get(UncondBrOpc)).addMBB(TBB); + if (BytesAdded) + *BytesAdded += getInstSizeInBytes(MI); +- return 1; + } +- +- // Either a one or two-way conditional branch. +- MachineInstrBuilder MIB = BuildMI(&MBB, DL, get(Cond[0].getImm())); +- for (unsigned i = 1; i < Cond.size(); ++i) +- MIB.add(Cond[i]); +- MIB.addMBB(TBB); +- if (BytesAdded) +- *BytesAdded += getInstSizeInBytes(*MIB); +- +- // One-way conditional branch. +- if (!FBB) +- return 1; +- +- // Two-way conditional branch. +- MachineInstr &MI = *BuildMI(&MBB, DL, get(LoongArch::PseudoBR)).addMBB(FBB); +- if (BytesAdded) +- *BytesAdded += getInstSizeInBytes(MI); +- return 2; ++ else {// Conditional branch. ++ MachineInstr &MI = *BuildCondBr(MBB, TBB, DL, Cond); ++ if (BytesAdded) ++ *BytesAdded += getInstSizeInBytes(MI); ++ } ++ return 1; + } + + void LoongArchInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB, +@@ -416,121 +634,407 @@ void LoongArchInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB, + + MachineFunction *MF = MBB.getParent(); + MachineRegisterInfo &MRI = MF->getRegInfo(); +- const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); +- LoongArchMachineFunctionInfo *LAFI = +- MF->getInfo(); ++ const LoongArchSubtarget &Subtarget = MF->getSubtarget(); ++ bool is64 = Subtarget.isABI_LP64(); ++ const TargetRegisterClass *RC = ++ is64 ? &LoongArch::GPR64RegClass : &LoongArch::GPR32RegClass; + +- if (!isInt<32>(BrOffset)) ++ if (!is64 && !isInt<32>(BrOffset)) + report_fatal_error( + "Branch offsets outside of the signed 32-bit range not supported"); + +- Register ScratchReg = MRI.createVirtualRegister(&LoongArch::GPRRegClass); ++ unsigned ScratchReg = MRI.createVirtualRegister(RC); ++ unsigned ZeroReg = is64 ? LoongArch::ZERO_64 : LoongArch::ZERO; + auto II = MBB.end(); + +- MachineInstr &PCALAU12I = +- *BuildMI(MBB, II, DL, get(LoongArch::PCALAU12I), ScratchReg) +- .addMBB(&DestBB, LoongArchII::MO_PCREL_HI); +- MachineInstr &ADDI = +- *BuildMI(MBB, II, DL, +- get(STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W), +- ScratchReg) +- .addReg(ScratchReg) +- .addMBB(&DestBB, LoongArchII::MO_PCREL_LO); +- BuildMI(MBB, II, DL, get(LoongArch::PseudoBRIND)) ++ MachineInstr &Pcaddu12iMI = ++ *BuildMI(MBB, II, DL, get(LoongArch::LONG_BRANCH_PCADDU12I), ScratchReg) ++ .addMBB(&DestBB, LoongArchII::MO_PCREL_HI); ++ BuildMI(MBB, II, DL, get(LoongArch::LONG_BRANCH_ADDID2Op), ScratchReg) ++ .addReg(ScratchReg) ++ .addMBB(&DestBB, LoongArchII::MO_PCREL_LO); ++ BuildMI(MBB, II, DL, get(LoongArch::JIRL)) ++ .addReg(ZeroReg) + .addReg(ScratchReg, RegState::Kill) + .addImm(0); +- + RS->enterBasicBlockEnd(MBB); +- Register Scav = RS->scavengeRegisterBackwards( +- LoongArch::GPRRegClass, PCALAU12I.getIterator(), /*RestoreAfter=*/false, +- /*SPAdj=*/0, /*AllowSpill=*/false); +- if (Scav != LoongArch::NoRegister) +- RS->setRegUsed(Scav); +- else { +- // When there is no scavenged register, it needs to specify a register. +- // Specify t8 register because it won't be used too often. +- Scav = LoongArch::R20; +- int FrameIndex = LAFI->getBranchRelaxationSpillFrameIndex(); +- if (FrameIndex == -1) +- report_fatal_error("The function size is incorrectly estimated."); +- storeRegToStackSlot(MBB, PCALAU12I, Scav, /*IsKill=*/true, FrameIndex, +- &LoongArch::GPRRegClass, TRI, Register()); +- TRI->eliminateFrameIndex(std::prev(PCALAU12I.getIterator()), +- /*SpAdj=*/0, /*FIOperandNum=*/1); +- PCALAU12I.getOperand(1).setMBB(&RestoreBB); +- ADDI.getOperand(2).setMBB(&RestoreBB); +- loadRegFromStackSlot(RestoreBB, RestoreBB.end(), Scav, FrameIndex, +- &LoongArch::GPRRegClass, TRI, Register()); +- TRI->eliminateFrameIndex(RestoreBB.back(), +- /*SpAdj=*/0, /*FIOperandNum=*/1); +- } ++ unsigned Scav = RS->scavengeRegisterBackwards( ++ *RC, MachineBasicBlock::iterator(Pcaddu12iMI), false, 0); + MRI.replaceRegWith(ScratchReg, Scav); + MRI.clearVirtRegs(); ++ RS->setRegUsed(Scav); + } + +-static unsigned getOppositeBranchOpc(unsigned Opc) { +- switch (Opc) { +- default: +- llvm_unreachable("Unrecognized conditional branch"); +- case LoongArch::BEQ: +- return LoongArch::BNE; +- case LoongArch::BNE: +- return LoongArch::BEQ; +- case LoongArch::BEQZ: +- return LoongArch::BNEZ; +- case LoongArch::BNEZ: +- return LoongArch::BEQZ; +- case LoongArch::BCEQZ: +- return LoongArch::BCNEZ; +- case LoongArch::BCNEZ: +- return LoongArch::BCEQZ; +- case LoongArch::BLT: +- return LoongArch::BGE; +- case LoongArch::BGE: +- return LoongArch::BLT; +- case LoongArch::BLTU: +- return LoongArch::BGEU; +- case LoongArch::BGEU: +- return LoongArch::BLTU; ++unsigned LoongArchInstrInfo::removeBranch(MachineBasicBlock &MBB, ++ int *BytesRemoved) const { ++ if (BytesRemoved) ++ *BytesRemoved = 0; ++ ++ MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend(); ++ unsigned removed = 0; ++ ++ // Up to 2 branches are removed. ++ // Note that indirect branches are not removed. ++ while (I != REnd && removed < 2) { ++ // Skip past debug instructions. ++ if (I->isDebugInstr()) { ++ ++I; ++ continue; ++ } ++ if (!getAnalyzableBrOpc(I->getOpcode())) ++ break; ++ // Remove the branch. ++ I->eraseFromParent(); ++ if (BytesRemoved) ++ *BytesRemoved += getInstSizeInBytes(*I); ++ I = MBB.rbegin(); ++ ++removed; + } ++ ++ return removed; + } + ++/// reverseBranchCondition - Return the inverse opcode of the ++/// specified Branch instruction. + bool LoongArchInstrInfo::reverseBranchCondition( + SmallVectorImpl &Cond) const { +- assert((Cond.size() && Cond.size() <= 3) && "Invalid branch condition!"); ++ assert( (Cond.size() && Cond.size() <= 3) && ++ "Invalid LoongArch branch condition!"); + Cond[0].setImm(getOppositeBranchOpc(Cond[0].getImm())); + return false; + } + ++LoongArchInstrInfo::BranchType LoongArchInstrInfo::analyzeBranch( ++ MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, ++ SmallVectorImpl &Cond, bool AllowModify, ++ SmallVectorImpl &BranchInstrs) const { ++ MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend(); ++ ++ // Skip all the debug instructions. ++ while (I != REnd && I->isDebugInstr()) ++ ++I; ++ ++ if (I == REnd || !isUnpredicatedTerminator(*I)) { ++ // This block ends with no branches (it just falls through to its succ). ++ // Leave TBB/FBB null. ++ TBB = FBB = nullptr; ++ return BT_NoBranch; ++ } ++ ++ MachineInstr *LastInst = &*I; ++ unsigned LastOpc = LastInst->getOpcode(); ++ BranchInstrs.push_back(LastInst); ++ ++ // Not an analyzable branch (e.g., indirect jump). ++ if (!getAnalyzableBrOpc(LastOpc)) ++ return LastInst->isIndirectBranch() ? BT_Indirect : BT_None; ++ ++ // Get the second to last instruction in the block. ++ unsigned SecondLastOpc = 0; ++ MachineInstr *SecondLastInst = nullptr; ++ ++ // Skip past any debug instruction to see if the second last actual ++ // is a branch. ++ ++I; ++ while (I != REnd && I->isDebugInstr()) ++ ++I; ++ ++ if (I != REnd) { ++ SecondLastInst = &*I; ++ SecondLastOpc = getAnalyzableBrOpc(SecondLastInst->getOpcode()); ++ ++ // Not an analyzable branch (must be an indirect jump). ++ if (isUnpredicatedTerminator(*SecondLastInst) && !SecondLastOpc) ++ return BT_None; ++ } ++ ++ // If there is only one terminator instruction, process it. ++ if (!SecondLastOpc) { ++ // Unconditional branch. ++ if (LastInst->isUnconditionalBranch()) { ++ TBB = LastInst->getOperand(0).getMBB(); ++ return BT_Uncond; ++ } ++ ++ // Conditional branch ++ AnalyzeCondBr(LastInst, LastOpc, TBB, Cond); ++ return BT_Cond; ++ } ++ ++ // If we reached here, there are two branches. ++ // If there are three terminators, we don't know what sort of block this is. ++ if (++I != REnd && isUnpredicatedTerminator(*I)) ++ return BT_None; ++ ++ BranchInstrs.insert(BranchInstrs.begin(), SecondLastInst); ++ ++ // If second to last instruction is an unconditional branch, ++ // analyze it and remove the last instruction. ++ if (SecondLastInst->isUnconditionalBranch()) { ++ // Return if the last instruction cannot be removed. ++ if (!AllowModify) ++ return BT_None; ++ ++ TBB = SecondLastInst->getOperand(0).getMBB(); ++ LastInst->eraseFromParent(); ++ BranchInstrs.pop_back(); ++ return BT_Uncond; ++ } ++ ++ // Conditional branch followed by an unconditional branch. ++ // The last one must be unconditional. ++ if (!LastInst->isUnconditionalBranch()) ++ return BT_None; ++ ++ AnalyzeCondBr(SecondLastInst, SecondLastOpc, TBB, Cond); ++ FBB = LastInst->getOperand(0).getMBB(); ++ ++ return BT_CondUncond; ++} ++ ++MachineBasicBlock * ++LoongArchInstrInfo::getBranchDestBlock(const MachineInstr &MI) const { ++ assert(MI.getDesc().isBranch() && "Unexpected opcode!"); ++ // The branch target is always the last operand. ++ int NumOp = MI.getNumExplicitOperands(); ++ return MI.getOperand(NumOp - 1).getMBB(); ++} ++ ++bool LoongArchInstrInfo::isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const { ++/* ++ switch (BranchOpc) { ++ case LoongArch::B: ++ case LoongArch::BAL: ++ case LoongArch::BAL_BR: ++ case LoongArch::BC1F: ++ case LoongArch::BC1FL: ++ case LoongArch::BC1T: ++ case LoongArch::BC1TL: ++ case LoongArch::BEQ: case LoongArch::BEQ64: ++ case LoongArch::BEQL: ++ case LoongArch::BGEZ: case LoongArch::BGEZ64: ++ case LoongArch::BGEZL: ++ case LoongArch::BGEZAL: ++ case LoongArch::BGEZALL: ++ case LoongArch::BGTZ: case LoongArch::BGTZ64: ++ case LoongArch::BGTZL: ++ case LoongArch::BLEZ: case LoongArch::BLEZ64: ++ case LoongArch::BLEZL: ++ case LoongArch::BLTZ: case LoongArch::BLTZ64: ++ case LoongArch::BLTZL: ++ case LoongArch::BLTZAL: ++ case LoongArch::BLTZALL: ++ case LoongArch::BNE: case LoongArch::BNE64: ++ case LoongArch::BNEL: ++ return isInt<18>(BrOffset); ++ ++ case LoongArch::BC1EQZ: ++ case LoongArch::BC1NEZ: ++ case LoongArch::BC2EQZ: ++ case LoongArch::BC2NEZ: ++ case LoongArch::BEQC: case LoongArch::BEQC64: ++ case LoongArch::BNEC: case LoongArch::BNEC64: ++ case LoongArch::BGEC: case LoongArch::BGEC64: ++ case LoongArch::BGEUC: case LoongArch::BGEUC64: ++ case LoongArch::BGEZC: case LoongArch::BGEZC64: ++ case LoongArch::BGTZC: case LoongArch::BGTZC64: ++ case LoongArch::BLEZC: case LoongArch::BLEZC64: ++ case LoongArch::BLTC: case LoongArch::BLTC64: ++ case LoongArch::BLTUC: case LoongArch::BLTUC64: ++ case LoongArch::BLTZC: case LoongArch::BLTZC64: ++ case LoongArch::BNVC: ++ case LoongArch::BOVC: ++ case LoongArch::BGEZALC: ++ case LoongArch::BEQZALC: ++ case LoongArch::BGTZALC: ++ case LoongArch::BLEZALC: ++ case LoongArch::BLTZALC: ++ case LoongArch::BNEZALC: ++ return isInt<18>(BrOffset); ++ ++ case LoongArch::BEQZC: case LoongArch::BEQZC64: ++ case LoongArch::BNEZC: case LoongArch::BNEZC64: ++ return isInt<23>(BrOffset); ++ } ++ */ ++ switch (BranchOpc) { ++ case LoongArch::B: case LoongArch::B32: ++ return isInt<28>(BrOffset); ++ ++ case LoongArch::BEQZ: case LoongArch::BEQZ32: ++ case LoongArch::BNEZ: case LoongArch::BNEZ32: ++ case LoongArch::BCEQZ: ++ case LoongArch::BCNEZ: ++ return isInt<23>(BrOffset); ++ ++ case LoongArch::BEQ: case LoongArch::BEQ32: ++ case LoongArch::BNE: case LoongArch::BNE32: ++ case LoongArch::BLT: case LoongArch::BLT32: ++ case LoongArch::BGE: case LoongArch::BGE32: ++ case LoongArch::BLTU: case LoongArch::BLTU32: ++ case LoongArch::BGEU: case LoongArch::BGEU32: ++ return isInt<18>(BrOffset); ++ } ++ ++ llvm_unreachable("Unknown branch instruction!"); ++} ++ ++ ++/// Predicate for distingushing between control transfer instructions and all ++/// other instructions for handling forbidden slots. Consider inline assembly ++/// as unsafe as well. ++bool LoongArchInstrInfo::SafeInForbiddenSlot(const MachineInstr &MI) const { ++ if (MI.isInlineAsm()) ++ return false; ++ ++ return (MI.getDesc().TSFlags & LoongArchII::IsCTI) == 0; ++} ++ ++/// Predicate for distingushing instructions that have forbidden slots. ++bool LoongArchInstrInfo::HasForbiddenSlot(const MachineInstr &MI) const { ++ return (MI.getDesc().TSFlags & LoongArchII::HasForbiddenSlot) != 0; ++} ++ ++/// Return the number of bytes of code the specified instruction may be. ++unsigned LoongArchInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const { ++ switch (MI.getOpcode()) { ++ default: ++ return MI.getDesc().getSize(); ++ case TargetOpcode::INLINEASM: { // Inline Asm: Variable size. ++ const MachineFunction *MF = MI.getParent()->getParent(); ++ const char *AsmStr = MI.getOperand(0).getSymbolName(); ++ return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo()); ++ } ++ } ++} ++ ++MachineInstrBuilder ++LoongArchInstrInfo::genInstrWithNewOpc(unsigned NewOpc, ++ MachineBasicBlock::iterator I) const { ++ MachineInstrBuilder MIB; ++ ++ int ZeroOperandPosition = -1; ++ bool BranchWithZeroOperand = false; ++ if (I->isBranch() && !I->isPseudo()) { ++ auto TRI = I->getParent()->getParent()->getSubtarget().getRegisterInfo(); ++ ZeroOperandPosition = I->findRegisterUseOperandIdx(LoongArch::ZERO, false, TRI); ++ BranchWithZeroOperand = ZeroOperandPosition != -1; ++ } ++ ++ MIB = BuildMI(*I->getParent(), I, I->getDebugLoc(), get(NewOpc)); ++ ++ if (NewOpc == LoongArch::JIRL) { ++ MIB->removeOperand(0); ++ for (unsigned J = 0, E = I->getDesc().getNumOperands(); J < E; ++J) { ++ MIB.add(I->getOperand(J)); ++ } ++ MIB.addImm(0); ++ } else { ++ for (unsigned J = 0, E = I->getDesc().getNumOperands(); J < E; ++J) { ++ if (BranchWithZeroOperand && (unsigned)ZeroOperandPosition == J) ++ continue; ++ ++ MIB.add(I->getOperand(J)); ++ } ++ } ++ ++ MIB.copyImplicitOps(*I); ++ MIB.cloneMemRefs(*I); ++ return MIB; ++} ++ ++bool LoongArchInstrInfo::findCommutedOpIndices(const MachineInstr &MI, ++ unsigned &SrcOpIdx1, ++ unsigned &SrcOpIdx2) const { ++ assert(!MI.isBundle() && ++ "TargetInstrInfo::findCommutedOpIndices() can't handle bundles"); ++ ++ const MCInstrDesc &MCID = MI.getDesc(); ++ if (!MCID.isCommutable()) ++ return false; ++ ++ return TargetInstrInfo::findCommutedOpIndices(MI, SrcOpIdx1, SrcOpIdx2); ++} ++ ++// bstrins, bstrpick have the following constraints: ++// 0 <= lsb <= msb <= High ++static bool verifyBstrInstruction(const MachineInstr &MI, StringRef &ErrInfo, ++ const int64_t High) { ++ MachineOperand MOMsb = MI.getOperand(2); ++ if (!MOMsb.isImm()) { ++ ErrInfo = "Msb operand is not an immediate!"; ++ return false; ++ } ++ MachineOperand MOLsb = MI.getOperand(3); ++ if (!MOLsb.isImm()) { ++ ErrInfo = "Lsb operand is not an immediate!"; ++ return false; ++ } ++ ++ int64_t Lsb = MOLsb.getImm(); ++ if (!((0 <= Lsb) && (Lsb <= High))) { ++ ErrInfo = "Lsb operand is out of range!"; ++ return false; ++ } ++ ++ int64_t Msb = MOMsb.getImm(); ++ if (!((0 <= Msb) && (Msb <= High))) { ++ ErrInfo = "Msb operand is out of range!"; ++ return false; ++ } ++ ++ if (!(Lsb <= Msb)) { ++ ErrInfo = "Lsb operand is not less than or equal to msb operand!"; ++ return false; ++ } ++ ++ return true; ++} ++ ++// Perform target specific instruction verification. ++bool LoongArchInstrInfo::verifyInstruction(const MachineInstr &MI, ++ StringRef &ErrInfo) const { ++ // Verify that bstrins and bstrpick instructions are well formed. ++ switch (MI.getOpcode()) { ++ case LoongArch::BSTRINS_W: ++ case LoongArch::BSTRPICK_W: ++ return verifyBstrInstruction(MI, ErrInfo, 31); ++ case LoongArch::BSTRINS_D: ++ case LoongArch::BSTRPICK_D: ++ return verifyBstrInstruction(MI, ErrInfo, 63); ++ default: ++ return true; ++ } ++ ++ return true; ++} ++ + std::pair + LoongArchInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const { + return std::make_pair(TF, 0u); + } + +-ArrayRef> ++ArrayRef> + LoongArchInstrInfo::getSerializableDirectMachineOperandTargetFlags() const { +- using namespace LoongArchII; +- // TODO: Add more target flags. +- static const std::pair TargetFlags[] = { +- {MO_CALL, "loongarch-call"}, +- {MO_CALL_PLT, "loongarch-call-plt"}, +- {MO_PCREL_HI, "loongarch-pcrel-hi"}, +- {MO_PCREL_LO, "loongarch-pcrel-lo"}, +- {MO_PCREL64_LO, "loongarch-pcrel64-lo"}, +- {MO_PCREL64_HI, "loongarch-pcrel64-hi"}, +- {MO_GOT_PC_HI, "loongarch-got-pc-hi"}, +- {MO_GOT_PC_LO, "loongarch-got-pc-lo"}, +- {MO_GOT_PC64_LO, "loongarch-got-pc64-lo"}, +- {MO_GOT_PC64_HI, "loongarch-got-pc64-hi"}, +- {MO_LE_HI, "loongarch-le-hi"}, +- {MO_LE_LO, "loongarch-le-lo"}, +- {MO_LE64_LO, "loongarch-le64-lo"}, +- {MO_LE64_HI, "loongarch-le64-hi"}, +- {MO_IE_PC_HI, "loongarch-ie-pc-hi"}, +- {MO_IE_PC_LO, "loongarch-ie-pc-lo"}, +- {MO_IE_PC64_LO, "loongarch-ie-pc64-lo"}, +- {MO_IE_PC64_HI, "loongarch-ie-pc64-hi"}, +- {MO_LD_PC_HI, "loongarch-ld-pc-hi"}, +- {MO_GD_PC_HI, "loongarch-gd-pc-hi"}}; +- return ArrayRef(TargetFlags); ++ using namespace LoongArchII; ++ ++ static const std::pair Flags[] = { ++ {MO_PCREL_HI, "larch-pcrel-hi"}, ++ {MO_PCREL_LO, "larch-pcrel-lo"}, ++ {MO_TLSGD_HI, "larch-tlsgd-hi"}, ++ {MO_TLSGD_LO, "larch-tlsgd-lo"}, ++ {MO_TLSIE_HI, "larch-tlsie-hi"}, ++ {MO_TLSIE_LO, "larch-tlsie-lo"}, ++ {MO_TLSLE_HI, "larch-tlsle-hi"}, ++ {MO_TLSLE_LO, "larch-tlsle-lo"}, ++ {MO_ABS_HI, "larch-abs-hi"}, ++ {MO_ABS_LO, "larch-abs-lo"}, ++ {MO_ABS_HIGHER, "larch-abs-higher"}, ++ {MO_ABS_HIGHEST, "larch-abs-highest"}, ++ {MO_GOT_HI, "larch-got-hi"}, ++ {MO_GOT_LO, "larch-got-lo"}, ++ {MO_CALL_HI, "larch-call-hi"}, ++ {MO_CALL_LO, "larch-call-lo"} ++ }; ++ return ArrayRef(Flags); + } +diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.h b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.h +index 4b145d0ba..76fb894ce 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.h ++++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.h +@@ -1,4 +1,4 @@ +-//=- LoongArchInstrInfo.h - LoongArch Instruction Information ---*- C++ -*-===// ++//===- LoongArchInstrInfo.h - LoongArch Instruction Information -----------*- C++ -*-===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -8,76 +8,184 @@ + // + // This file contains the LoongArch implementation of the TargetInstrInfo class. + // ++// FIXME: We need to override TargetInstrInfo::getInlineAsmLength method in ++// order for LoongArchLongBranch pass to work correctly when the code has inline ++// assembly. The returned value doesn't have to be the asm instruction's exact ++// size in bytes; LoongArchLongBranch only expects it to be the correct upper bound. + //===----------------------------------------------------------------------===// + + #ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHINSTRINFO_H + #define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHINSTRINFO_H + ++#include "MCTargetDesc/LoongArchMCTargetDesc.h" ++#include "LoongArch.h" + #include "LoongArchRegisterInfo.h" ++#include "llvm/ADT/ArrayRef.h" ++#include "llvm/CodeGen/MachineBasicBlock.h" ++#include "llvm/CodeGen/MachineInstrBuilder.h" ++#include "llvm/CodeGen/MachineMemOperand.h" + #include "llvm/CodeGen/TargetInstrInfo.h" ++#include + + #define GET_INSTRINFO_HEADER + #include "LoongArchGenInstrInfo.inc" + + namespace llvm { + ++class MachineInstr; ++class MachineOperand; + class LoongArchSubtarget; ++class TargetRegisterClass; ++class TargetRegisterInfo; + + class LoongArchInstrInfo : public LoongArchGenInstrInfo { +-public: +- explicit LoongArchInstrInfo(LoongArchSubtarget &STI); +- +- MCInst getNop() const override; ++ virtual void anchor(); ++ const LoongArchRegisterInfo RI; ++ const LoongArchSubtarget &Subtarget; + +- void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg, ++public: ++ enum BranchType { ++ BT_None, // Couldn't analyze branch. ++ BT_NoBranch, // No branches found. ++ BT_Uncond, // One unconditional branch. ++ BT_Cond, // One conditional branch. ++ BT_CondUncond, // A conditional branch followed by an unconditional branch. ++ BT_Indirect // One indirct branch. ++ }; ++ ++ explicit LoongArchInstrInfo(const LoongArchSubtarget &STI); ++ ++ /// isLoadFromStackSlot - If the specified machine instruction is a direct ++ /// load from a stack slot, return the virtual or physical register number of ++ /// the destination along with the FrameIndex of the loaded stack slot. If ++ /// not, return 0. This predicate must return 0 if the instruction has ++ /// any side effects other than loading from the stack slot. ++ unsigned isLoadFromStackSlot(const MachineInstr &MI, ++ int &FrameIndex) const override; ++ ++ /// isStoreToStackSlot - If the specified machine instruction is a direct ++ /// store to a stack slot, return the virtual or physical register number of ++ /// the source reg along with the FrameIndex of the loaded stack slot. If ++ /// not, return 0. This predicate must return 0 if the instruction has ++ /// any side effects other than storing to the stack slot. ++ unsigned isStoreToStackSlot(const MachineInstr &MI, ++ int &FrameIndex) const override; ++ ++ void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, ++ const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, + bool KillSrc) const override; + +- void storeRegToStackSlot(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, Register SrcReg, +- bool IsKill, int FrameIndex, +- const TargetRegisterClass *RC, +- const TargetRegisterInfo *TRI, +- Register VReg) const override; +- void loadRegFromStackSlot(MachineBasicBlock &MBB, +- MachineBasicBlock::iterator MBBI, Register DstReg, +- int FrameIndex, const TargetRegisterClass *RC, +- const TargetRegisterInfo *TRI, +- Register VReg) const override; +- +- // Materializes the given integer Val into DstReg. +- void movImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, +- const DebugLoc &DL, Register DstReg, uint64_t Val, +- MachineInstr::MIFlag Flag = MachineInstr::NoFlags) const; +- +- unsigned getInstSizeInBytes(const MachineInstr &MI) const override; +- +- MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override; +- ++ /// Branch Analysis + bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, + MachineBasicBlock *&FBB, + SmallVectorImpl &Cond, + bool AllowModify) const override; + +- bool isBranchOffsetInRange(unsigned BranchOpc, +- int64_t BrOffset) const override; +- + unsigned removeBranch(MachineBasicBlock &MBB, + int *BytesRemoved = nullptr) const override; + + unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, + MachineBasicBlock *FBB, ArrayRef Cond, +- const DebugLoc &dl, ++ const DebugLoc &DL, + int *BytesAdded = nullptr) const override; + + void insertIndirectBranch(MachineBasicBlock &MBB, + MachineBasicBlock &NewDestBB, + MachineBasicBlock &RestoreBB, const DebugLoc &DL, +- int64_t BrOffset, RegScavenger *RS) const override; +- ++ int64_t BrOffset, ++ RegScavenger *RS = nullptr) const override; + bool + reverseBranchCondition(SmallVectorImpl &Cond) const override; + ++ BranchType analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, ++ MachineBasicBlock *&FBB, ++ SmallVectorImpl &Cond, ++ bool AllowModify, ++ SmallVectorImpl &BranchInstrs) const; ++ ++ /// Get the block that branch instruction jumps to. ++ MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override; ++ ++ /// Determine if the branch target is in range. ++ bool isBranchOffsetInRange(unsigned BranchOpc, ++ int64_t BrOffset) const override; ++ ++ /// Predicate to determine if an instruction can go in a forbidden slot. ++ bool SafeInForbiddenSlot(const MachineInstr &MI) const; ++ ++ /// Predicate to determine if an instruction has a forbidden slot. ++ bool HasForbiddenSlot(const MachineInstr &MI) const; ++ ++ /// Insert nop instruction when hazard condition is found ++ void insertNoop(MachineBasicBlock &MBB, ++ MachineBasicBlock::iterator MI) const override; ++ ++ /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As ++ /// such, whenever a client has an instance of instruction info, it should ++ /// always be able to get register info as well (through this method). ++ const LoongArchRegisterInfo &getRegisterInfo() const; ++ ++ bool expandPostRAPseudo(MachineInstr &MI) const override; ++ ++ unsigned getOppositeBranchOpc(unsigned Opc) const; ++ ++ /// Emit a series of instructions to load an immediate. ++ unsigned loadImmediate(int64_t Imm, MachineBasicBlock &MBB, ++ MachineBasicBlock::iterator II, ++ const DebugLoc &DL) const; ++ ++ /// Return the number of bytes of code the specified instruction may be. ++ unsigned getInstSizeInBytes(const MachineInstr &MI) const override; ++ ++ void storeRegToStackSlot(MachineBasicBlock &MBB, ++ MachineBasicBlock::iterator MBBI, Register SrcReg, ++ bool IsKill, int FrameIndex, ++ const TargetRegisterClass *RC, ++ const TargetRegisterInfo *TRI, ++ Register VReg) const override { ++ storeRegToStack(MBB, MBBI, SrcReg, IsKill, FrameIndex, RC, TRI, 0); ++ } ++ ++ void loadRegFromStackSlot(MachineBasicBlock &MBB, ++ MachineBasicBlock::iterator MBBI, Register DestReg, ++ int FrameIndex, const TargetRegisterClass *RC, ++ const TargetRegisterInfo *TRI, ++ Register VReg) const override { ++ loadRegFromStack(MBB, MBBI, DestReg, FrameIndex, RC, TRI, 0); ++ } ++ ++ void storeRegToStack(MachineBasicBlock &MBB, ++ MachineBasicBlock::iterator MI, ++ Register SrcReg, bool isKill, int FrameIndex, ++ const TargetRegisterClass *RC, ++ const TargetRegisterInfo *TRI, ++ int64_t Offset) const; ++ ++ void loadRegFromStack(MachineBasicBlock &MBB, ++ MachineBasicBlock::iterator MI, ++ Register DestReg, int FrameIndex, ++ const TargetRegisterClass *RC, ++ const TargetRegisterInfo *TRI, ++ int64_t Offset) const; ++ ++ /// Adjust register value(DestReg = SrcReg + Amount). ++ void ++ adjustReg(unsigned DestReg, unsigned SrcReg, int64_t Amount, ++ MachineBasicBlock &MBB, MachineBasicBlock::iterator I, ++ MachineInstr::MIFlag Flag = MachineInstr::MIFlag::NoFlags) const; ++ ++ /// Create an instruction which has the same operands and memory operands ++ /// as MI but has a new opcode. ++ MachineInstrBuilder genInstrWithNewOpc(unsigned NewOpc, ++ MachineBasicBlock::iterator I) const; ++ ++ bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, ++ unsigned &SrcOpIdx2) const override; ++ ++ /// Perform target specific instruction verification. ++ bool verifyInstruction(const MachineInstr &MI, ++ StringRef &ErrInfo) const override; ++ + std::pair + decomposeMachineOperandsTargetFlags(unsigned TF) const override; + +@@ -85,23 +193,53 @@ public: + getSerializableDirectMachineOperandTargetFlags() const override; + + protected: +- const LoongArchSubtarget &STI; +-}; ++ /// If the specific machine instruction is a instruction that moves/copies ++ /// value from one register to another register return true along with ++ /// @Source machine operand and @Destination machine operand. ++ std::optional ++ isCopyInstrImpl(const MachineInstr &MI) const override; ++ ++private: ++ ++ bool isZeroImm(const MachineOperand &op) const; ++ ++ MachineMemOperand *GetMemOperand(MachineBasicBlock &MBB, int FI, ++ MachineMemOperand::Flags Flags) const; ++ ++ unsigned getAnalyzableBrOpc(unsigned Opc) const; ++ ++ void AnalyzeCondBr(const MachineInstr *Inst, unsigned Opc, ++ MachineBasicBlock *&BB, ++ SmallVectorImpl &Cond) const; + +-namespace LoongArch { +- +-// Mask assignments for floating-point. +-static constexpr unsigned FClassMaskSignalingNaN = 0x001; +-static constexpr unsigned FClassMaskQuietNaN = 0x002; +-static constexpr unsigned FClassMaskNegativeInfinity = 0x004; +-static constexpr unsigned FClassMaskNegativeNormal = 0x008; +-static constexpr unsigned FClassMaskNegativeSubnormal = 0x010; +-static constexpr unsigned FClassMaskNegativeZero = 0x020; +-static constexpr unsigned FClassMaskPositiveInfinity = 0x040; +-static constexpr unsigned FClassMaskPositiveNormal = 0x080; +-static constexpr unsigned FClassMaskPositiveSubnormal = 0x100; +-static constexpr unsigned FClassMaskPositiveZero = 0x200; +-} // namespace LoongArch ++ MachineInstr * ++ BuildCondBr(MachineBasicBlock &MBB, MachineBasicBlock *TBB, ++ const DebugLoc &DL, ArrayRef Cond) const; ++ ++ void expandRetRA(MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const; ++ ++ void expandERet(MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const; ++ ++ std::pair compareOpndSize(unsigned Opc, ++ const MachineFunction &MF) const; ++ ++ /// Expand pseudo Int-to-FP conversion instructions. ++ /// ++ /// For example, the following pseudo instruction ++ /// PseudoCVT_D32_W D2, A5 ++ /// gets expanded into these two instructions: ++ /// MTC1 F4, A5 ++ /// CVT_D32_W D2, F4 ++ /// ++ /// We do this expansion post-RA to avoid inserting a floating point copy ++ /// instruction between MTC1 and CVT_D32_W. ++ void expandCvtFPInt(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, ++ unsigned CvtOpc, unsigned MovOpc, bool IsI64) const; ++ ++ void expandEhReturn(MachineBasicBlock &MBB, ++ MachineBasicBlock::iterator I) const; ++}; + + } // end namespace llvm ++ + #endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHINSTRINFO_H +diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td +index ae73a8ac7..268bdea94 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td ++++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td +@@ -1,4 +1,4 @@ +-//== LoongArchInstrInfo.td - Target Description for LoongArch -*- tablegen -*-// ++//===- LoongArchInstrInfo.td - Target Description for LoongArch Target -*- tablegen -*-=// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -6,1971 +6,1048 @@ + // + //===----------------------------------------------------------------------===// + // +-// This file describes the LoongArch instructions in TableGen format. ++// This file contains the LoongArch implementation of the TargetInstrInfo class. + // + //===----------------------------------------------------------------------===// ++include "LoongArchInstrFormats.td" + +-//===----------------------------------------------------------------------===// +-// LoongArch specific DAG Nodes. +-//===----------------------------------------------------------------------===// ++def SDT_Bstrpick : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>, ++ SDTCisVT<2, i32>, SDTCisSameAs<2, 3>]>; ++def SDT_Bstrins : SDTypeProfile<1, 4, [SDTCisInt<0>, SDTCisSameAs<0, 1>, ++ SDTCisVT<2, i32>, SDTCisSameAs<2, 3>, ++ SDTCisSameAs<0, 4>]>; + +-// Target-independent type requirements, but with target-specific formats. +-def SDT_CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>, +- SDTCisVT<1, i32>]>; +-def SDT_CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, +- SDTCisVT<1, i32>]>; +- +-// Target-dependent type requirements. +-def SDT_LoongArchCall : SDTypeProfile<0, -1, [SDTCisVT<0, GRLenVT>]>; +-def SDT_LoongArchIntBinOpW : SDTypeProfile<1, 2, [ +- SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<0, i64> +-]>; +- +-def SDT_LoongArchBStrIns: SDTypeProfile<1, 4, [ +- SDTCisInt<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<3>, +- SDTCisSameAs<3, 4> +-]>; +- +-def SDT_LoongArchBStrPick: SDTypeProfile<1, 3, [ +- SDTCisInt<0>, SDTCisSameAs<0, 1>, SDTCisInt<2>, SDTCisSameAs<2, 3> +-]>; +- +-// "VI" means no output and an integer input. +-def SDT_LoongArchVI : SDTypeProfile<0, 1, [SDTCisVT<0, GRLenVT>]>; +- +-def SDT_LoongArchCsrrd : SDTypeProfile<1, 1, [SDTCisInt<0>, +- SDTCisVT<1, GRLenVT>]>; +-def SDT_LoongArchCsrwr : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>, +- SDTCisVT<2, GRLenVT>]>; +-def SDT_LoongArchCsrxchg : SDTypeProfile<1, 3, [SDTCisInt<0>, +- SDTCisSameAs<0, 1>, +- SDTCisSameAs<0, 2>, +- SDTCisVT<3, GRLenVT>]>; +-def SDT_LoongArchIocsrwr : SDTypeProfile<0, 2, [SDTCisInt<0>, +- SDTCisSameAs<0, 1>]>; +-def SDT_LoongArchMovgr2fcsr : SDTypeProfile<0, 2, [SDTCisVT<0, GRLenVT>, +- SDTCisSameAs<0, 1>]>; +-def SDT_LoongArchMovfcsr2gr : SDTypeProfile<1, 1, [SDTCisVT<0, GRLenVT>, +- SDTCisSameAs<0, 1>]>; +- +-// TODO: Add LoongArch specific DAG Nodes +-// Target-independent nodes, but with target-specific formats. +-def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart, +- [SDNPHasChain, SDNPOutGlue]>; +-def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd, +- [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; +- +-// Target-dependent nodes. +-def loongarch_call : SDNode<"LoongArchISD::CALL", SDT_LoongArchCall, +- [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, +- SDNPVariadic]>; +-def loongarch_ret : SDNode<"LoongArchISD::RET", SDTNone, +- [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; +-def loongarch_tail : SDNode<"LoongArchISD::TAIL", SDT_LoongArchCall, +- [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, +- SDNPVariadic]>; +-def loongarch_call_medium : SDNode<"LoongArchISD::CALL_MEDIUM", SDT_LoongArchCall, +- [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, +- SDNPVariadic]>; +-def loongarch_tail_medium : SDNode<"LoongArchISD::TAIL_MEDIUM", SDT_LoongArchCall, +- [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, +- SDNPVariadic]>; +-def loongarch_call_large : SDNode<"LoongArchISD::CALL_LARGE", SDT_LoongArchCall, +- [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, +- SDNPVariadic]>; +-def loongarch_tail_large : SDNode<"LoongArchISD::TAIL_LARGE", SDT_LoongArchCall, +- [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, +- SDNPVariadic]>; +-def loongarch_sll_w : SDNode<"LoongArchISD::SLL_W", SDT_LoongArchIntBinOpW>; +-def loongarch_sra_w : SDNode<"LoongArchISD::SRA_W", SDT_LoongArchIntBinOpW>; +-def loongarch_srl_w : SDNode<"LoongArchISD::SRL_W", SDT_LoongArchIntBinOpW>; +-def loongarch_rotr_w : SDNode<"LoongArchISD::ROTR_W", SDT_LoongArchIntBinOpW>; +-def loongarch_rotl_w : SDNode<"LoongArchISD::ROTL_W", SDT_LoongArchIntBinOpW>; +-def loongarch_crc_w_b_w +- : SDNode<"LoongArchISD::CRC_W_B_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>; +-def loongarch_crc_w_h_w +- : SDNode<"LoongArchISD::CRC_W_H_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>; +-def loongarch_crc_w_w_w +- : SDNode<"LoongArchISD::CRC_W_W_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>; +-def loongarch_crc_w_d_w +- : SDNode<"LoongArchISD::CRC_W_D_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>; +-def loongarch_crcc_w_b_w : SDNode<"LoongArchISD::CRCC_W_B_W", +- SDT_LoongArchIntBinOpW, [SDNPHasChain]>; +-def loongarch_crcc_w_h_w : SDNode<"LoongArchISD::CRCC_W_H_W", +- SDT_LoongArchIntBinOpW, [SDNPHasChain]>; +-def loongarch_crcc_w_w_w : SDNode<"LoongArchISD::CRCC_W_W_W", +- SDT_LoongArchIntBinOpW, [SDNPHasChain]>; +-def loongarch_crcc_w_d_w : SDNode<"LoongArchISD::CRCC_W_D_W", +- SDT_LoongArchIntBinOpW, [SDNPHasChain]>; +-def loongarch_bstrins +- : SDNode<"LoongArchISD::BSTRINS", SDT_LoongArchBStrIns>; +-def loongarch_bstrpick +- : SDNode<"LoongArchISD::BSTRPICK", SDT_LoongArchBStrPick>; +-def loongarch_revb_2h : SDNode<"LoongArchISD::REVB_2H", SDTUnaryOp>; +-def loongarch_revb_2w : SDNode<"LoongArchISD::REVB_2W", SDTUnaryOp>; +-def loongarch_bitrev_4b : SDNode<"LoongArchISD::BITREV_4B", SDTUnaryOp>; +-def loongarch_bitrev_w : SDNode<"LoongArchISD::BITREV_W", SDTUnaryOp>; +-def loongarch_clzw : SDNode<"LoongArchISD::CLZ_W", SDTIntBitCountUnaryOp>; +-def loongarch_ctzw : SDNode<"LoongArchISD::CTZ_W", SDTIntBitCountUnaryOp>; +-def loongarch_dbar : SDNode<"LoongArchISD::DBAR", SDT_LoongArchVI, +- [SDNPHasChain, SDNPSideEffect]>; +-def loongarch_ibar : SDNode<"LoongArchISD::IBAR", SDT_LoongArchVI, +- [SDNPHasChain, SDNPSideEffect]>; +-def loongarch_break : SDNode<"LoongArchISD::BREAK", SDT_LoongArchVI, +- [SDNPHasChain, SDNPSideEffect]>; +-def loongarch_movfcsr2gr : SDNode<"LoongArchISD::MOVFCSR2GR", +- SDT_LoongArchMovfcsr2gr, [SDNPHasChain]>; +-def loongarch_movgr2fcsr : SDNode<"LoongArchISD::MOVGR2FCSR", +- SDT_LoongArchMovgr2fcsr, +- [SDNPHasChain, SDNPSideEffect]>; +-def loongarch_syscall : SDNode<"LoongArchISD::SYSCALL", SDT_LoongArchVI, +- [SDNPHasChain, SDNPSideEffect]>; +-def loongarch_csrrd : SDNode<"LoongArchISD::CSRRD", SDT_LoongArchCsrrd, +- [SDNPHasChain, SDNPSideEffect]>; +-def loongarch_csrwr : SDNode<"LoongArchISD::CSRWR", SDT_LoongArchCsrwr, +- [SDNPHasChain, SDNPSideEffect]>; +-def loongarch_csrxchg : SDNode<"LoongArchISD::CSRXCHG", +- SDT_LoongArchCsrxchg, +- [SDNPHasChain, SDNPSideEffect]>; +-def loongarch_iocsrrd_b : SDNode<"LoongArchISD::IOCSRRD_B", SDTUnaryOp, +- [SDNPHasChain, SDNPSideEffect]>; +-def loongarch_iocsrrd_h : SDNode<"LoongArchISD::IOCSRRD_H", SDTUnaryOp, +- [SDNPHasChain, SDNPSideEffect]>; +-def loongarch_iocsrrd_w : SDNode<"LoongArchISD::IOCSRRD_W", SDTUnaryOp, +- [SDNPHasChain, SDNPSideEffect]>; +-def loongarch_iocsrrd_d : SDNode<"LoongArchISD::IOCSRRD_D", SDTUnaryOp, +- [SDNPHasChain, SDNPSideEffect]>; +-def loongarch_iocsrwr_b : SDNode<"LoongArchISD::IOCSRWR_B", +- SDT_LoongArchIocsrwr, +- [SDNPHasChain, SDNPSideEffect]>; +-def loongarch_iocsrwr_h : SDNode<"LoongArchISD::IOCSRWR_H", +- SDT_LoongArchIocsrwr, +- [SDNPHasChain, SDNPSideEffect]>; +-def loongarch_iocsrwr_w : SDNode<"LoongArchISD::IOCSRWR_W", +- SDT_LoongArchIocsrwr, +- [SDNPHasChain, SDNPSideEffect]>; +-def loongarch_iocsrwr_d : SDNode<"LoongArchISD::IOCSRWR_D", +- SDT_LoongArchIocsrwr, +- [SDNPHasChain, SDNPSideEffect]>; +-def loongarch_cpucfg : SDNode<"LoongArchISD::CPUCFG", SDTUnaryOp, +- [SDNPHasChain]>; +- +-def to_fclass_mask: SDNodeXFormgetZExtValue(); +- unsigned Mask = 0; +- if (Check & fcSNan) +- Mask |= LoongArch::FClassMaskSignalingNaN; +- if (Check & fcQNan) +- Mask |= LoongArch::FClassMaskQuietNaN; +- if (Check & fcPosInf) +- Mask |= LoongArch::FClassMaskPositiveInfinity; +- if (Check & fcNegInf) +- Mask |= LoongArch::FClassMaskNegativeInfinity; +- if (Check & fcPosNormal) +- Mask |= LoongArch::FClassMaskPositiveNormal; +- if (Check & fcNegNormal) +- Mask |= LoongArch::FClassMaskNegativeNormal; +- if (Check & fcPosSubnormal) +- Mask |= LoongArch::FClassMaskPositiveSubnormal; +- if (Check & fcNegSubnormal) +- Mask |= LoongArch::FClassMaskNegativeSubnormal; +- if (Check & fcPosZero) +- Mask |= LoongArch::FClassMaskPositiveZero; +- if (Check & fcNegZero) +- Mask |= LoongArch::FClassMaskNegativeZero; +- return CurDAG->getTargetConstant(Mask, SDLoc(N), Subtarget->getGRLenVT()); +-}]>; ++def SDT_REVBD : SDTypeProfile<1, 1, [SDTCisInt<0>]>; ++def LoongArchREVBD : SDNode<"LoongArchISD::REVBD", SDT_REVBD>; + +-//===----------------------------------------------------------------------===// +-// Operand and SDNode transformation definitions. +-//===----------------------------------------------------------------------===// ++def LoongArchBstrpick : SDNode<"LoongArchISD::BSTRPICK", SDT_Bstrpick>; + +-class ImmAsmOperand +- : AsmOperandClass { +- let Name = prefix # "Imm" # width # suffix; +- let DiagnosticType = !strconcat("Invalid", Name); +- let RenderMethod = "addImmOperands"; +-} ++def LoongArchBstrins : SDNode<"LoongArchISD::BSTRINS", SDT_Bstrins>; + +-class SImmAsmOperand +- : ImmAsmOperand<"S", width, suffix> { +-} ++def SDT_LoongArchEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>; + +-class UImmAsmOperand +- : ImmAsmOperand<"U", width, suffix> { +-} ++def LoongArchehret : SDNode<"LoongArchISD::EH_RETURN", SDT_LoongArchEHRET, ++ [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; + +-// A parse method for "$r*" or "$r*, 0", where the 0 is be silently ignored. +-// Only used for "AM*" instructions, in order to be compatible with GAS. +-def AtomicMemAsmOperand : AsmOperandClass { +- let Name = "AtomicMemAsmOperand"; +- let RenderMethod = "addRegOperands"; +- let PredicateMethod = "isGPR"; +- let ParserMethod = "parseAtomicMemOp"; +-} ++//===---------------------------------------------------------------------===/ ++// Operand, Complex Patterns and Transformations Definitions. ++//===---------------------------------------------------------------------===/ + +-def GPRMemAtomic : RegisterOperand { +- let ParserMatchClass = AtomicMemAsmOperand; +- let PrintMethod = "printAtomicMemOp"; +-} +- +-// A parameterized register class alternative to i32imm/i64imm from Target.td. +-def grlenimm : Operand; +-def imm32 : Operand { +- let ParserMatchClass = ImmAsmOperand<"", 32, "">; +-} ++def assertzext_lt_i32 : PatFrag<(ops node:$src), (assertzext node:$src), [{ ++ return cast(N->getOperand(1))->getVT().bitsLT(MVT::i32); ++}]>; + +-def uimm1 : Operand, ImmLeaf(Imm);}]>{ +- let ParserMatchClass = UImmAsmOperand<1>; +-} ++def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>; ++def immZExt12 : PatLeaf<(imm), [{ return isUInt<12>(N->getZExtValue()); }]>; ++def immSExt12 : PatLeaf<(imm), [{ return isInt<12>(N->getSExtValue()); }]>; ++def immSExt13 : PatLeaf<(imm), [{ return isInt<13>(N->getSExtValue()); }]>; ++ ++def immZExt2Alsl : ImmLeaf(Imm - 1);}]>; ++//class ImmAsmOperand : AsmOperandClass { ++// let RenderMethod = "addImmOperands"; ++// let PredicateMethod = "isImmediate<" # Low # "," # High # ">"; ++// let DiagnosticString = "operand must be an immediate in the range [" # Low # "," # High # "]"; ++//} ++// ++//def Imm8AsmOperand: ImmAsmOperand<8,8> { let Name = "Imm8"; } ++//def imm8 : Operand, ImmLeaf { ++// let ParserMatchClass = Imm8AsmOperand; ++//} + +-def uimm2 : Operand, ImmLeaf(Imm);}]> { +- let ParserMatchClass = UImmAsmOperand<2>; +-} ++def HasLSX : Predicate<"Subtarget->hasLSX()">, ++ AssemblerPredicate<(all_of FeatureLSX)>; ++def HasLASX : Predicate<"Subtarget->hasLASX()">, ++ AssemblerPredicate<(all_of FeatureLASX)>; ++def HasFrecipe : Predicate<"Subtarget->hasFrecipe()">; + +-def uimm2_plus1 : Operand, +- ImmLeaf(Imm - 1);}]> { +- let ParserMatchClass = UImmAsmOperand<2, "plus1">; +- let EncoderMethod = "getImmOpValueSub1"; +- let DecoderMethod = "decodeUImmOperand<2, 1>"; ++class EXT_LSX { ++ list ExtPredicate = [HasLSX]; + } + +-def uimm3 : Operand, ImmLeaf(Imm);}]> { +- let ParserMatchClass = UImmAsmOperand<3>; ++class EXT_LASX { ++ list ExtPredicate = [HasLASX]; + } + +-def uimm4 : Operand, ImmLeaf(Imm);}]> { +- let ParserMatchClass = UImmAsmOperand<4>; ++class SImmOperand : AsmOperandClass { ++ let Name = "SImm" # width; ++ let DiagnosticType = "InvalidSImm" # width; ++ let RenderMethod = "addImmOperands"; ++ let PredicateMethod = "isSImm<" # width # ">"; + } + +-def uimm5 : Operand, ImmLeaf(Imm);}]> { +- let ParserMatchClass = UImmAsmOperand<5>; ++def SImm2Operand : SImmOperand<2>; ++def simm2 : Operand, ImmLeaf= -2 && Imm < 2; }]> { ++ let ParserMatchClass = SImm2Operand; ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<2>"; + } +- +-def uimm6 : Operand, ImmLeaf(Imm);}]> { +- let ParserMatchClass = UImmAsmOperand<6>; ++def SImm3Operand : SImmOperand<3>; ++def simm3 : Operand, ImmLeaf= -4 && Imm < 4; }]> { ++ let ParserMatchClass = SImm3Operand; ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<3>"; + } + +-def uimm7 : Operand { +- let ParserMatchClass = UImmAsmOperand<7>; ++def SImm5Operand : SImmOperand<5>; ++def simm5 : Operand, ImmLeaf= -16 && Imm < 16; }]> { ++ let ParserMatchClass = SImm5Operand; ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<5>"; + } + +-def uimm8 : Operand, ImmLeaf(Imm);}]> { +- let ParserMatchClass = UImmAsmOperand<8>; ++def simm5_32 : Operand, ImmLeaf= -16 && Imm < 16; }]> { ++ let ParserMatchClass = SImm5Operand; ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<5>"; + } + +-class UImm12Operand : Operand, +- ImmLeaf (Imm);}]> { +- let DecoderMethod = "decodeUImmOperand<12>"; ++def SImm8Operand : SImmOperand<8>; ++def simm8 : Operand, ImmLeaf= -128 && Imm < 128; }]> { ++ let ParserMatchClass = SImm8Operand; ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<8>"; + } +- +-def uimm12 : UImm12Operand { +- let ParserMatchClass = UImmAsmOperand<12>; ++def simm8_32 : Operand, ImmLeaf= -128 && Imm < 128; }]> { ++ let ParserMatchClass = SImm8Operand; ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<8>"; + } + +-def uimm12_ori : UImm12Operand { +- let ParserMatchClass = UImmAsmOperand<12, "ori">; ++def SImm12Operand : SImmOperand<12>; ++def simm12 : Operand, ImmLeaf= -2048 && Imm < 2048; }]> { ++ let ParserMatchClass = SImm12Operand; ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<12>"; + } +- +-def uimm14 : Operand, +- ImmLeaf (Imm);}]> { +- let ParserMatchClass = UImmAsmOperand<14>; ++def simm12_32 : Operand, ImmLeaf= -2048 && Imm < 2048; }]> { ++ let ParserMatchClass = SImm12Operand; ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<12>"; + } + +-def uimm15 : Operand, +- ImmLeaf (Imm);}]> { +- let ParserMatchClass = UImmAsmOperand<15>; ++def SImm14Operand : SImmOperand<14>; ++def simm14 : Operand, ImmLeaf= -8192 && Imm < 8192; }]> { ++ let ParserMatchClass = SImm14Operand; ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<14>"; + } + +-def simm5 : Operand { +- let ParserMatchClass = SImmAsmOperand<5>; +- let DecoderMethod = "decodeSImmOperand<5>"; ++def SImm15Operand : SImmOperand<15>; ++def simm15 : Operand, ImmLeaf= -16384 && Imm < 16384; }]> { ++ let ParserMatchClass = SImm15Operand; ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<15>"; + } + +-def simm8 : Operand { +- let ParserMatchClass = SImmAsmOperand<8>; +- let DecoderMethod = "decodeSImmOperand<8>"; ++def SImm16Operand : SImmOperand<16>; ++def simm16 : Operand, ImmLeaf= -32768 && Imm < 32768; }]> { ++ let ParserMatchClass = SImm16Operand; ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>"; + } + +-foreach I = [1, 2, 3] in { +-def simm8_lsl # I : Operand { +- let ParserMatchClass = SImmAsmOperand<8, "lsl" # I>; +- let EncoderMethod = "getImmOpValueAsr<" # I # ">"; +- let DecoderMethod = "decodeSImmOperand<8," # I # ">"; ++def SImm20Operand : SImmOperand<20>; ++def simm20 : Operand, ImmLeaf= -524288 && Imm < 524288; }]> { ++ let ParserMatchClass = SImm20Operand; ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<20>"; + } ++def simm20_32 : Operand, ImmLeaf= -524288 && Imm < 524288; }]> { ++ let ParserMatchClass = SImm20Operand; ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<20>"; + } + +-def simm9_lsl3 : Operand { +- let ParserMatchClass = SImmAsmOperand<9, "lsl3">; +- let EncoderMethod = "getImmOpValueAsr<3>"; +- let DecoderMethod = "decodeSImmOperand<9, 3>"; ++def SImm21Operand : SImmOperand<21>; ++def simm21 : Operand, ImmLeaf= -1048576 && Imm < 1048576; }]> { ++ let ParserMatchClass = SImm21Operand; ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<21>"; + } + +-def simm10 : Operand { +- let ParserMatchClass = SImmAsmOperand<10>; ++def SImm26Operand : SImmOperand<26>; ++def simm26 : Operand, ImmLeaf= -33554432 && Imm < 33554432; }]> { ++ let ParserMatchClass = SImm26Operand; ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<26>"; + } + +-def simm10_lsl2 : Operand { +- let ParserMatchClass = SImmAsmOperand<10, "lsl2">; +- let EncoderMethod = "getImmOpValueAsr<2>"; +- let DecoderMethod = "decodeSImmOperand<10, 2>"; ++def UImm1Operand : AsmOperandClass { ++ let Name = "UImm1"; ++ let RenderMethod = "addUImmOperands<1>"; ++ let PredicateMethod = "isUImm<1>"; ++ let DiagnosticType = "InvalidImm0_1"; + } + +-def simm11_lsl1 : Operand { +- let ParserMatchClass = SImmAsmOperand<11, "lsl1">; +- let EncoderMethod = "getImmOpValueAsr<1>"; +- let DecoderMethod = "decodeSImmOperand<11, 1>"; ++def UImm2Operand : AsmOperandClass { ++ let Name = "UImm2"; ++ let RenderMethod = "addUImmOperands<2>"; ++ let PredicateMethod = "isUImm<2>"; ++ let DiagnosticType = "InvalidImm0_3"; + } + +-class SImm12Operand : Operand, +- ImmLeaf (Imm);}]> { +- let DecoderMethod = "decodeSImmOperand<12>"; ++def UImm3Operand : AsmOperandClass { ++ let Name = "UImm3"; ++ let RenderMethod = "addUImmOperands<3>"; ++ let PredicateMethod = "isUImm<3>"; ++ let DiagnosticType = "InvalidImm0_7"; + } + +-def simm12 : SImm12Operand { +- let ParserMatchClass = SImmAsmOperand<12>; ++def UImm4Operand : AsmOperandClass { ++ let Name = "UImm4"; ++ let RenderMethod = "addUImmOperands<4>"; ++ let PredicateMethod = "isUImm<4>"; ++ let DiagnosticType = "InvalidImm0_15"; + } + +-def simm12_addlike : SImm12Operand { +- let ParserMatchClass = SImmAsmOperand<12, "addlike">; ++def UImm5Operand : AsmOperandClass { ++ let Name = "UImm5"; ++ let RenderMethod = "addUImmOperands<5>"; ++ let PredicateMethod = "isUImm<5>"; ++ let DiagnosticType = "InvalidImm0_31"; + } + +-def simm12_lu52id : SImm12Operand { +- let ParserMatchClass = SImmAsmOperand<12, "lu52id">; ++def uimm1i : Operand, ImmLeaf= 0 && Imm < 2; }]> { ++ let PrintMethod = "printUImm<1>"; ++ let ParserMatchClass = UImm1Operand; + } + +-def simm13 : Operand { +- let ParserMatchClass = SImmAsmOperand<13>; +- let DecoderMethod = "decodeSImmOperand<13>"; ++def uimm2 : Operand, ImmLeaf= 0 && Imm < 4; }]> { ++ let PrintMethod = "printUImm<2>"; ++ let ParserMatchClass = UImm2Operand; + } + +-def simm14_lsl2 : Operand, +- ImmLeaf(Imm);}]> { +- let ParserMatchClass = SImmAsmOperand<14, "lsl2">; +- let EncoderMethod = "getImmOpValueAsr<2>"; +- let DecoderMethod = "decodeSImmOperand<14, 2>"; ++def uimm3 : Operand, ImmLeaf= 0 && Imm < 8; }]> { ++ let PrintMethod = "printUImm<3>"; ++ let ParserMatchClass = UImm3Operand; + } + +-def simm16 : Operand { +- let ParserMatchClass = SImmAsmOperand<16>; +- let DecoderMethod = "decodeSImmOperand<16>"; ++def uimm4i : Operand, ImmLeaf= 0 && Imm < 16; }]> { ++ let PrintMethod = "printUImm<4>"; ++ let ParserMatchClass = UImm4Operand; + } + +-def simm16_lsl2 : Operand, +- ImmLeaf(Imm>>2);}]> { +- let ParserMatchClass = SImmAsmOperand<16, "lsl2">; +- let EncoderMethod = "getImmOpValueAsr<2>"; +- let DecoderMethod = "decodeSImmOperand<16, 2>"; ++def uimm5 : Operand, ImmLeaf= 0 && Imm < 32; }]> { ++ let PrintMethod = "printUImm<5>"; ++ let ParserMatchClass = UImm5Operand; + } + +-def simm16_lsl2_br : Operand { +- let ParserMatchClass = SImmAsmOperand<16, "lsl2">; +- let EncoderMethod = "getImmOpValueAsr<2>"; +- let DecoderMethod = "decodeSImmOperand<16, 2>"; ++def UImm6Operand : AsmOperandClass { ++ let Name = "UImm6"; ++ let RenderMethod = "addUImmOperands<16>"; ++ let PredicateMethod = "isUImm<6>"; ++ let DiagnosticType = "InvalidImm0_63"; + } +- +-class SImm20Operand : Operand { +- let DecoderMethod = "decodeSImmOperand<20>"; ++def uimm6 : Operand, ImmLeaf= 0 && Imm < 64; }]> { ++ let PrintMethod = "printUImm<6>"; ++ let ParserMatchClass = UImm6Operand; + } + +-def simm20 : SImm20Operand { +- let ParserMatchClass = SImmAsmOperand<20>; ++def UImm7Operand : AsmOperandClass { ++ let Name = "UImm7"; ++ let RenderMethod = "addUImmOperands<16>"; ++ let PredicateMethod = "isUImm<7>"; ++ let DiagnosticType = "InvalidImm0_127"; + } + +-def simm20_pcalau12i : SImm20Operand { +- let ParserMatchClass = SImmAsmOperand<20, "pcalau12i">; ++def uimm7i : Operand, ImmLeaf= 0 && Imm < 128; }]> { ++ let PrintMethod = "printUImm<7>"; ++ let ParserMatchClass = UImm7Operand; + } + +-def simm20_lu12iw : SImm20Operand { +- let ParserMatchClass = SImmAsmOperand<20, "lu12iw">; ++def UImm12Operand : AsmOperandClass { ++ let Name = "UImm12"; ++ let RenderMethod = "addUImmOperands<12>"; ++ let PredicateMethod = "isUImm<12>"; ++ let DiagnosticType = "InvalidImm0_4095"; + } +- +-def simm20_lu32id : SImm20Operand { +- let ParserMatchClass = SImmAsmOperand<20, "lu32id">; ++def uimm12 : Operand, ImmLeaf= 0 && Imm < 4096; }]> { ++ let PrintMethod = "printUImm<12>"; ++ let ParserMatchClass = UImm12Operand; + } +- +-def simm20_pcaddu18i : SImm20Operand { +- let ParserMatchClass = SImmAsmOperand<20, "pcaddu18i">; ++def uimm12_32 : Operand, ImmLeaf= 0 && Imm < 4096; }]> { ++ let PrintMethod = "printUImm<12>"; ++ let ParserMatchClass = UImm12Operand; + } + +-def simm21_lsl2 : Operand { +- let ParserMatchClass = SImmAsmOperand<21, "lsl2">; +- let EncoderMethod = "getImmOpValueAsr<2>"; +- let DecoderMethod = "decodeSImmOperand<21, 2>"; ++def UImm15Operand : AsmOperandClass { ++ let Name = "UImm15"; ++ let RenderMethod = "addUImmOperands<15>"; ++ let PredicateMethod = "isUImm<15>"; ++ let DiagnosticType = "InvalidImm0_32767"; + } +- +-def SImm26OperandB: AsmOperandClass { +- let Name = "SImm26OperandB"; +- let PredicateMethod = "isSImm26Operand"; +- let RenderMethod = "addImmOperands"; +- let DiagnosticType = "InvalidSImm26Operand"; +- let ParserMethod = "parseImmediate"; ++def uimm15 : Operand, ImmLeaf= 0 && Imm < 32768; }]> { ++ let PrintMethod = "printUImm<15>"; ++ let ParserMatchClass = UImm15Operand; + } + +-// A symbol or an imm used in B/PseudoBR. +-def simm26_b : Operand { +- let ParserMatchClass = SImm26OperandB; +- let EncoderMethod = "getImmOpValueAsr<2>"; +- let DecoderMethod = "decodeSImmOperand<26, 2>"; ++def UImm14Operand : AsmOperandClass { ++ let Name = "UImm14"; ++ let RenderMethod = "addUImmOperands<14>"; ++ let PredicateMethod = "isUImm<14>"; ++ let DiagnosticType = "InvalidImm0_16383"; + } +- +-def SImm26OperandBL: AsmOperandClass { +- let Name = "SImm26OperandBL"; +- let PredicateMethod = "isSImm26Operand"; +- let RenderMethod = "addImmOperands"; +- let DiagnosticType = "InvalidSImm26Operand"; +- let ParserMethod = "parseSImm26Operand"; ++def uimm14 : Operand, ImmLeaf= 0 && Imm < 16384; }]> { ++ let PrintMethod = "printUImm<14>"; ++ let ParserMatchClass = UImm14Operand; + } +- +-// A symbol or an imm used in BL/PseudoCALL/PseudoTAIL. +-def simm26_symbol : Operand { +- let ParserMatchClass = SImm26OperandBL; +- let EncoderMethod = "getImmOpValueAsr<2>"; +- let DecoderMethod = "decodeSImmOperand<26, 2>"; ++def uimm14_32 : Operand, ImmLeaf= 0 && Imm < 16384; }]> { ++ let PrintMethod = "printUImm<14>"; ++ let ParserMatchClass = UImm14Operand; + } + +-// A 32-bit signed immediate with the lowest 16 bits zeroed, suitable for +-// direct use with `addu16i.d`. +-def simm16_lsl16 : Operand, +- ImmLeaf(Imm);}]>; +- +-// A 32-bit signed immediate expressible with a pair of `addu16i.d + addi` for +-// use in additions. +-def simm32_hi16_lo12: Operand, ImmLeaf(Imm - SignExtend64<12>(Imm)); +-}]>; +- +-def BareSymbol : AsmOperandClass { +- let Name = "BareSymbol"; +- let RenderMethod = "addImmOperands"; +- let DiagnosticType = "InvalidBareSymbol"; +- let ParserMethod = "parseImmediate"; ++def UImm8Operand : AsmOperandClass { ++ let Name = "UImm8"; ++ let RenderMethod = "addUImmOperands<8>"; ++ let PredicateMethod = "isUImm<8>"; ++ let DiagnosticType = "InvalidImm0_255"; + } +- +-// A bare symbol used in "PseudoLA_*" instructions. +-def bare_symbol : Operand { +- let ParserMatchClass = BareSymbol; ++def uimm8_64 : Operand, ImmLeaf= 0 && Imm < 256; }]> { ++ let PrintMethod = "printUImm<8>"; ++ let ParserMatchClass = UImm8Operand; + } + +-// Standalone (codegen-only) immleaf patterns. +- +-// A 12-bit signed immediate plus one where the imm range will be [-2047, 2048]. +-def simm12_plus1 : ImmLeaf(Imm) && Imm != -2048) || Imm == 2048;}]>; +- +-// Return the negation of an immediate value. +-def NegImm : SDNodeXFormgetTargetConstant(-N->getSExtValue(), SDLoc(N), +- N->getValueType(0)); +-}]>; ++def uimm8_32 : Operand, ImmLeaf= 0 && Imm < 256; }]> { ++ let PrintMethod = "printUImm<8>"; ++ let ParserMatchClass = UImm8Operand; ++} + +-// FP immediate patterns. +-def fpimm0 : PatLeaf<(fpimm), [{return N->isExactlyValue(+0.0);}]>; +-def fpimm0neg : PatLeaf<(fpimm), [{return N->isExactlyValue(-0.0);}]>; +-def fpimm1 : PatLeaf<(fpimm), [{return N->isExactlyValue(+1.0);}]>; ++def addr : ++ComplexPattern; + +-// Return an immediate subtracted from 32. +-def ImmSubFrom32 : SDNodeXFormgetTargetConstant(32 - N->getZExtValue(), SDLoc(N), +- N->getValueType(0)); +-}]>; ++def addrDefault : ++ComplexPattern; + +-// Return the lowest 12 bits of the signed immediate. +-def LO12: SDNodeXFormgetTargetConstant(SignExtend64<12>(N->getSExtValue()), +- SDLoc(N), N->getValueType(0)); +-}]>; ++def addrRegImm : ++ComplexPattern; + +-// Return the higher 16 bits of the signed immediate. +-def HI16 : SDNodeXFormgetTargetConstant(N->getSExtValue() >> 16, SDLoc(N), +- N->getValueType(0)); +-}]>; +- +-// Return the higher 16 bits of the signed immediate, adjusted for use within an +-// `addu16i.d + addi` pair. +-def HI16ForAddu16idAddiPair: SDNodeXFormgetSExtValue(); +- return CurDAG->getTargetConstant((Imm - SignExtend64<12>(Imm)) >> 16, +- SDLoc(N), N->getValueType(0)); +-}]>; ++def addrimm14lsl2 : ComplexPattern; + +-def BaseAddr : ComplexPattern; +-def AddrConstant : ComplexPattern; +-def NonFIBaseAddr : ComplexPattern; ++class ConstantUImmAsmOperandClass Supers = [], ++ int Offset = 0> : AsmOperandClass { ++ let Name = "ConstantUImm" # Bits # "_" # Offset; ++ let RenderMethod = "addConstantUImmOperands<" # Bits # ", " # Offset # ">"; ++ let PredicateMethod = "isConstantUImm<" # Bits # ", " # Offset # ">"; ++ let SuperClasses = Supers; ++ let DiagnosticType = "UImm" # Bits # "_" # Offset; ++} ++class SImmAsmOperandClass Supers = []> ++ : AsmOperandClass { ++ let Name = "SImm" # Bits; ++ let RenderMethod = "addSImmOperands<" # Bits # ">"; ++ let PredicateMethod = "isSImm<" # Bits # ">"; ++ let SuperClasses = Supers; ++ let DiagnosticType = "SImm" # Bits; ++} ++class UImmAnyAsmOperandClass Supers = []> ++ : AsmOperandClass { ++ let Name = "ImmAny"; ++ let RenderMethod = "addConstantUImmOperands<32>"; ++ let PredicateMethod = "isSImm<" # Bits # ">"; ++ let SuperClasses = Supers; ++ let DiagnosticType = "ImmAny"; ++} + +-def fma_nsz : PatFrag<(ops node:$fj, node:$fk, node:$fa), +- (fma node:$fj, node:$fk, node:$fa), [{ +- return N->getFlags().hasNoSignedZeros(); +-}]>; ++def UImm32CoercedAsmOperandClass : UImmAnyAsmOperandClass<33, []> { ++ let Name = "UImm32_Coerced"; ++ let DiagnosticType = "UImm32_Coerced"; ++} ++def SImm32RelaxedAsmOperandClass ++ : SImmAsmOperandClass<32, [UImm32CoercedAsmOperandClass]> { ++ let Name = "SImm32_Relaxed"; ++ let PredicateMethod = "isAnyImm<33>"; ++ let DiagnosticType = "SImm32_Relaxed"; ++} ++def SImm32AsmOperandClass ++ : SImmAsmOperandClass<32, [SImm32RelaxedAsmOperandClass]>; ++def ConstantUImm26AsmOperandClass ++ : ConstantUImmAsmOperandClass<26, [SImm32AsmOperandClass]>; + +-// Check if (add r, imm) can be optimized to (ADDI (ADDI r, imm0), imm1), +-// in which imm = imm0 + imm1, and both imm0 & imm1 are simm12. +-def AddiPair : PatLeaf<(imm), [{ +- if (!N->hasOneUse()) +- return false; +- // The immediate operand must be in range [-4096,-2049] or [2048,4094]. +- int64_t Imm = N->getSExtValue(); +- return (-4096 <= Imm && Imm <= -2049) || (2048 <= Imm && Imm <= 4094); +-}]>; ++def ConstantUImm20AsmOperandClass ++ : ConstantUImmAsmOperandClass<20, [ConstantUImm26AsmOperandClass]>; + +-// Return -2048 if immediate is negative or 2047 if positive. +-def AddiPairImmLarge : SDNodeXFormgetSExtValue() < 0 ? -2048 : 2047; +- return CurDAG->getTargetConstant(Imm, SDLoc(N), +- N->getValueType(0)); +-}]>; ++def ConstantUImm2Plus1AsmOperandClass ++ : ConstantUImmAsmOperandClass<2, [ConstantUImm20AsmOperandClass], 1>; + +-// Return imm - (imm < 0 ? -2048 : 2047). +-def AddiPairImmSmall : SDNodeXFormgetSExtValue(); +- int64_t Adj = Imm < 0 ? -2048 : 2047; +- return CurDAG->getTargetConstant(Imm - Adj, SDLoc(N), +- N->getValueType(0)); +-}]>; ++class UImmAsmOperandClass Supers = []> ++ : AsmOperandClass { ++ let Name = "UImm" # Bits; ++ let RenderMethod = "addUImmOperands<" # Bits # ">"; ++ let PredicateMethod = "isUImm<" # Bits # ">"; ++ let SuperClasses = Supers; ++ let DiagnosticType = "UImm" # Bits; ++} + +-// Check if (mul r, imm) can be optimized to (SLLI (ALSL r, r, i0), i1), +-// in which imm = (1 + (1 << i0)) << i1. +-def AlslSlliImm : PatLeaf<(imm), [{ +- if (!N->hasOneUse()) +- return false; +- uint64_t Imm = N->getZExtValue(); +- unsigned I1 = llvm::countr_zero(Imm); +- uint64_t Rem = Imm >> I1; +- return Rem == 3 || Rem == 5 || Rem == 9 || Rem == 17; +-}]>; ++def UImm16RelaxedAsmOperandClass ++ : UImmAsmOperandClass<16, [ConstantUImm20AsmOperandClass]> { ++ let Name = "UImm16_Relaxed"; ++ let PredicateMethod = "isAnyImm<16>"; ++ let DiagnosticType = "UImm16_Relaxed"; ++} + +-def AlslSlliImmI1 : SDNodeXFormgetZExtValue(); +- unsigned I1 = llvm::countr_zero(Imm); +- return CurDAG->getTargetConstant(I1, SDLoc(N), +- N->getValueType(0)); +-}]>; ++def ConstantSImm14Lsl2AsmOperandClass : AsmOperandClass { ++ let Name = "SImm14Lsl2"; ++ let RenderMethod = "addImmOperands"; ++ let PredicateMethod = "isScaledSImm<14, 2>"; ++ let SuperClasses = [UImm16RelaxedAsmOperandClass]; ++ let DiagnosticType = "SImm14_Lsl2"; ++} + +-def AlslSlliImmI0 : SDNodeXFormgetZExtValue(); +- unsigned I1 = llvm::countr_zero(Imm); +- uint64_t I0; +- switch (Imm >> I1) { +- case 3: I0 = 1; break; +- case 5: I0 = 2; break; +- case 9: I0 = 3; break; +- default: I0 = 4; break; ++foreach I = {2} in ++ def simm14_lsl # I : Operand { ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<14, " # I # ">"; ++ let ParserMatchClass = ++ !cast("ConstantSImm14Lsl" # I # "AsmOperandClass"); + } +- return CurDAG->getTargetConstant(I0, SDLoc(N), +- N->getValueType(0)); +-}]>; +- +-// Check if (and r, imm) can be optimized to (BSTRINS r, R0, msb, lsb), +-// in which imm = ~((2^^(msb-lsb+1) - 1) << lsb). +-def BstrinsImm : PatLeaf<(imm), [{ +- if (!N->hasOneUse()) +- return false; +- uint64_t Imm = N->getZExtValue(); +- // andi can be used instead if Imm <= 0xfff. +- if (Imm <= 0xfff) +- return false; +- unsigned MaskIdx, MaskLen; +- return N->getValueType(0).getSizeInBits() == 32 +- ? llvm::isShiftedMask_32(~Imm, MaskIdx, MaskLen) +- : llvm::isShiftedMask_64(~Imm, MaskIdx, MaskLen); +-}]>; +- +-def BstrinsMsb: SDNodeXFormgetZExtValue(); +- unsigned MaskIdx, MaskLen; +- N->getValueType(0).getSizeInBits() == 32 +- ? llvm::isShiftedMask_32(~Imm, MaskIdx, MaskLen) +- : llvm::isShiftedMask_64(~Imm, MaskIdx, MaskLen); +- return CurDAG->getTargetConstant(MaskIdx + MaskLen - 1, SDLoc(N), +- N->getValueType(0)); +-}]>; + +-def BstrinsLsb: SDNodeXFormgetZExtValue(); +- unsigned MaskIdx, MaskLen; +- N->getValueType(0).getSizeInBits() == 32 +- ? llvm::isShiftedMask_32(~Imm, MaskIdx, MaskLen) +- : llvm::isShiftedMask_64(~Imm, MaskIdx, MaskLen); +- return CurDAG->getTargetConstant(MaskIdx, SDLoc(N), N->getValueType(0)); +-}]>; ++def uimm16_64_relaxed : Operand { ++ let PrintMethod = "printUImm<16>"; ++ let ParserMatchClass = ++ !cast("UImm16RelaxedAsmOperandClass"); ++} + +-//===----------------------------------------------------------------------===// +-// Instruction Formats +-//===----------------------------------------------------------------------===// ++def uimm2_plus1 : Operand { ++ let PrintMethod = "printUImm<2, 1>"; ++ let EncoderMethod = "getUImmWithOffsetEncoding<2, 1>"; ++ let DecoderMethod = "DecodeUImmWithOffset<2, 1>"; ++ let ParserMatchClass = ConstantUImm2Plus1AsmOperandClass; ++} + +-include "LoongArchInstrFormats.td" +-include "LoongArchFloatInstrFormats.td" +-include "LoongArchLSXInstrFormats.td" +-include "LoongArchLASXInstrFormats.td" +-include "LoongArchLBTInstrFormats.td" ++// like simm32 but coerces simm32 to uimm32. ++def uimm32_coerced : Operand { ++ let ParserMatchClass = !cast("UImm32CoercedAsmOperandClass"); ++} + +-//===----------------------------------------------------------------------===// +-// Instruction Class Templates +-//===----------------------------------------------------------------------===// ++def imm64: Operand; + +-let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { +-class ALU_3R op> +- : Fmt3R; +-class ALU_2R op> +- : Fmt2R; +- +-class ALU_3RI2 op, Operand ImmOpnd> +- : Fmt3RI2; +-class ALU_3RI3 op, Operand ImmOpnd> +- : Fmt3RI3; +-class ALU_2RI5 op, Operand ImmOpnd> +- : Fmt2RI5; +-class ALU_2RI6 op, Operand ImmOpnd> +- : Fmt2RI6; +-class ALU_2RI12 op, Operand ImmOpnd> +- : Fmt2RI12; +-class ALU_2RI16 op, Operand ImmOpnd> +- : Fmt2RI16; +-class ALU_1RI20 op, Operand ImmOpnd> +- : Fmt1RI20; +-} // hasSideEffects = 0, mayLoad = 0, mayStore = 0 +- +-let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in +-class MISC_I15 op> +- : FmtI15; +- +-let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in +-class RDTIME_2R op> +- : Fmt2R; +- +-let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { +-class BrCC_2RI16 op> +- : Fmt2RI16 { +- let isBranch = 1; +- let isTerminator = 1; ++def LoongArchMemAsmOperand : AsmOperandClass { ++ let Name = "Mem"; ++ let ParserMethod = "parseMemOperand"; + } +-class BrCCZ_1RI21 op> +- : Fmt1RI21 { +- let isBranch = 1; +- let isTerminator = 1; ++ ++def LoongArchAMemAsmOperand : AsmOperandClass { ++ let Name = "AMem"; ++ let ParserMethod = "parseAMemOperand"; ++ let RenderMethod = "addMemOperands"; ++ let PredicateMethod = "isZeroMemOff"; ++ let DiagnosticType = "MemZeroOff"; + } +-class Br_I26 op> +- : FmtI26 { +- let isBranch = 1; +- let isTerminator = 1; +- let isBarrier = 1; ++ ++def LoongArchMemSimm14AsmOperand : AsmOperandClass { ++ let Name = "MemOffsetSimm14"; ++ let SuperClasses = [LoongArchMemAsmOperand]; ++ let RenderMethod = "addMemOperands"; ++ let ParserMethod = "parseMemOperand"; ++ let PredicateMethod = "isMemWithSimmOffset<14>"; ++ let DiagnosticType = "MemSImm14"; + } +-} // hasSideEffects = 0, mayLoad = 0, mayStore = 0 + +-let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { +-class LOAD_3R op> +- : Fmt3R; +-class LOAD_2RI12 op> +- : Fmt2RI12; +-class LOAD_2RI14 op> +- : Fmt2RI14; +-} // hasSideEffects = 0, mayLoad = 1, mayStore = 0 +- +-let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { +-class STORE_3R op> +- : Fmt3R; +-class STORE_2RI12 op> +- : Fmt2RI12; +-class STORE_2RI14 op> +- : Fmt2RI14; +-} // hasSideEffects = 0, mayLoad = 0, mayStore = 1 +- +-let hasSideEffects = 0, mayLoad = 1, mayStore = 1, Constraints = "@earlyclobber $rd" in +-class AM_3R op> +- : Fmt3R; ++foreach I = {2} in ++ def LoongArchMemSimm14Lsl # I # AsmOperand : AsmOperandClass { ++ let Name = "MemOffsetSimm14_" # I; ++ let SuperClasses = [LoongArchMemAsmOperand]; ++ let RenderMethod = "addMemOperands"; ++ let ParserMethod = "parseMemOperand"; ++ let PredicateMethod = "isMemWithSimmOffset<14, " # I # ">"; ++ let DiagnosticType = "MemSImm14Lsl" # I; ++ } + +-let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { +-class LLBase op> +- : Fmt2RI14; +-class LLBase_ACQ op> +- : Fmt2R; ++def LoongArchMemSimmPtrAsmOperand : AsmOperandClass { ++ let Name = "MemOffsetSimmPtr"; ++ let SuperClasses = [LoongArchMemAsmOperand]; ++ let RenderMethod = "addMemOperands"; ++ let ParserMethod = "parseMemOperand"; ++ let PredicateMethod = "isMemWithPtrSizeOffset"; ++ let DiagnosticType = "MemSImmPtr"; + } + +-let hasSideEffects = 0, mayLoad = 0, mayStore = 1, Constraints = "$rd = $dst" in { +-class SCBase op> +- : Fmt2RI14; +-class SCBase_128 op> +- : Fmt3R; +-class SCBase_REL op> +- : Fmt2R; ++class mem_generic : Operand { ++ let PrintMethod = "printMemOperand"; ++ let MIOperandInfo = (ops ptr_rc, simm12); ++ let EncoderMethod = "getMemEncoding"; ++ let ParserMatchClass = LoongArchMemAsmOperand; ++ let OperandType = "OPERAND_MEMORY"; + } + +-let hasSideEffects = 1 in +-class IOCSRRD op> +- : Fmt2R; ++// Address operand ++def mem : mem_generic; + +-let hasSideEffects = 1 in +-class IOCSRWR op> +- : Fmt2R; +- +-//===----------------------------------------------------------------------===// +-// Basic Integer Instructions +-//===----------------------------------------------------------------------===// +- +-// Arithmetic Operation Instructions +-def ADD_W : ALU_3R<0x00100000>; +-def SUB_W : ALU_3R<0x00110000>; +-def ADDI_W : ALU_2RI12<0x02800000, simm12_addlike>; +-def ALSL_W : ALU_3RI2<0x00040000, uimm2_plus1>; +-def LU12I_W : ALU_1RI20<0x14000000, simm20_lu12iw>; +-def SLT : ALU_3R<0x00120000>; +-def SLTU : ALU_3R<0x00128000>; +-def SLTI : ALU_2RI12<0x02000000, simm12>; +-def SLTUI : ALU_2RI12<0x02400000, simm12>; +-def PCADDI : ALU_1RI20<0x18000000, simm20>; +-def PCADDU12I : ALU_1RI20<0x1c000000, simm20>; +-def PCALAU12I : ALU_1RI20<0x1a000000, simm20_pcalau12i>; +-def AND : ALU_3R<0x00148000>; +-def OR : ALU_3R<0x00150000>; +-def NOR : ALU_3R<0x00140000>; +-def XOR : ALU_3R<0x00158000>; +-def ANDN : ALU_3R<0x00168000>; +-def ORN : ALU_3R<0x00160000>; +-def ANDI : ALU_2RI12<0x03400000, uimm12>; +-def ORI : ALU_2RI12<0x03800000, uimm12_ori>; +-def XORI : ALU_2RI12<0x03c00000, uimm12>; +-def MUL_W : ALU_3R<0x001c0000>; +-def MULH_W : ALU_3R<0x001c8000>; +-def MULH_WU : ALU_3R<0x001d0000>; +-let usesCustomInserter = true in { +-def DIV_W : ALU_3R<0x00200000>; +-def MOD_W : ALU_3R<0x00208000>; +-def DIV_WU : ALU_3R<0x00210000>; +-def MOD_WU : ALU_3R<0x00218000>; +-} // usesCustomInserter = true +- +-// Bit-shift Instructions +-def SLL_W : ALU_3R<0x00170000>; +-def SRL_W : ALU_3R<0x00178000>; +-def SRA_W : ALU_3R<0x00180000>; +-def ROTR_W : ALU_3R<0x001b0000>; +- +-def SLLI_W : ALU_2RI5<0x00408000, uimm5>; +-def SRLI_W : ALU_2RI5<0x00448000, uimm5>; +-def SRAI_W : ALU_2RI5<0x00488000, uimm5>; +-def ROTRI_W : ALU_2RI5<0x004c8000, uimm5>; +- +-// Bit-manipulation Instructions +-def EXT_W_B : ALU_2R<0x00005c00>; +-def EXT_W_H : ALU_2R<0x00005800>; +-def CLO_W : ALU_2R<0x00001000>; +-def CLZ_W : ALU_2R<0x00001400>; +-def CTO_W : ALU_2R<0x00001800>; +-def CTZ_W : ALU_2R<0x00001c00>; +-def BYTEPICK_W : ALU_3RI2<0x00080000, uimm2>; +-def REVB_2H : ALU_2R<0x00003000>; +-def BITREV_4B : ALU_2R<0x00004800>; +-def BITREV_W : ALU_2R<0x00005000>; +-let Constraints = "$rd = $dst" in { +-def BSTRINS_W : FmtBSTR_W<0x00600000, (outs GPR:$dst), +- (ins GPR:$rd, GPR:$rj, uimm5:$msbw, uimm5:$lsbw), +- "$rd, $rj, $msbw, $lsbw">; +-} +-def BSTRPICK_W : FmtBSTR_W<0x00608000, (outs GPR:$rd), +- (ins GPR:$rj, uimm5:$msbw, uimm5:$lsbw), +- "$rd, $rj, $msbw, $lsbw">; +-def MASKEQZ : ALU_3R<0x00130000>; +-def MASKNEZ : ALU_3R<0x00138000>; +- +-// Branch Instructions +-def BEQ : BrCC_2RI16<0x58000000>; +-def BNE : BrCC_2RI16<0x5c000000>; +-def BLT : BrCC_2RI16<0x60000000>; +-def BGE : BrCC_2RI16<0x64000000>; +-def BLTU : BrCC_2RI16<0x68000000>; +-def BGEU : BrCC_2RI16<0x6c000000>; +-def BEQZ : BrCCZ_1RI21<0x40000000>; +-def BNEZ : BrCCZ_1RI21<0x44000000>; +-def B : Br_I26<0x50000000>; +- +-let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1, Defs=[R1] in +-def BL : FmtI26<0x54000000, (outs), (ins simm26_symbol:$imm26), "$imm26">; +-let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +-def JIRL : Fmt2RI16<0x4c000000, (outs GPR:$rd), +- (ins GPR:$rj, simm16_lsl2:$imm16), "$rd, $rj, $imm16">; +- +-// Common Memory Access Instructions +-def LD_B : LOAD_2RI12<0x28000000>; +-def LD_H : LOAD_2RI12<0x28400000>; +-def LD_W : LOAD_2RI12<0x28800000>; +-def LD_BU : LOAD_2RI12<0x2a000000>; +-def LD_HU : LOAD_2RI12<0x2a400000>; +-def ST_B : STORE_2RI12<0x29000000>; +-def ST_H : STORE_2RI12<0x29400000>; +-def ST_W : STORE_2RI12<0x29800000>; +-let hasSideEffects = 0, mayLoad = 1, mayStore = 1 in +-def PRELD : FmtPRELD<(outs), (ins uimm5:$imm5, GPR:$rj, simm12:$imm12), +- "$imm5, $rj, $imm12">; +- +-// Atomic Memory Access Instructions +-def LL_W : LLBase<0x20000000>; +-def SC_W : SCBase<0x21000000>; +-def LLACQ_W : LLBase_ACQ<0x38578000>; +-def SCREL_W : SCBase_REL<0x38578400>; +- +-// Barrier Instructions +-def DBAR : MISC_I15<0x38720000>; +-def IBAR : MISC_I15<0x38728000>; +- +-// Other Miscellaneous Instructions +-def SYSCALL : MISC_I15<0x002b0000>; +-def BREAK : MISC_I15<0x002a0000>; +-def RDTIMEL_W : RDTIME_2R<0x00006000>; +-def RDTIMEH_W : RDTIME_2R<0x00006400>; +-def CPUCFG : ALU_2R<0x00006c00>; +- +-// Cache Maintenance Instructions +-def CACOP : FmtCACOP<(outs), (ins uimm5:$op, GPR:$rj, simm12:$imm12), +- "$op, $rj, $imm12">; +- +-/// LA64 instructions +- +-let Predicates = [IsLA64] in { +- +-// Arithmetic Operation Instructions for 64-bits +-def ADD_D : ALU_3R<0x00108000>; +-def SUB_D : ALU_3R<0x00118000>; +-def ADDI_D : ALU_2RI12<0x02c00000, simm12_addlike>; +-def ADDU16I_D : ALU_2RI16<0x10000000, simm16>; +-def ALSL_WU : ALU_3RI2<0x00060000, uimm2_plus1>; +-def ALSL_D : ALU_3RI2<0x002c0000, uimm2_plus1>; +-let Constraints = "$rd = $dst" in { +-let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +-def LU32I_D : Fmt1RI20<0x16000000, (outs GPR:$dst), +- (ins GPR:$rd, simm20_lu32id:$imm20), +- "$rd, $imm20">; +-} +-def LU52I_D : ALU_2RI12<0x03000000, simm12_lu52id>; +-def PCADDU18I : ALU_1RI20<0x1e000000, simm20_pcaddu18i>; +-def MUL_D : ALU_3R<0x001d8000>; +-def MULH_D : ALU_3R<0x001e0000>; +-def MULH_DU : ALU_3R<0x001e8000>; +-def MULW_D_W : ALU_3R<0x001f0000>; +-def MULW_D_WU : ALU_3R<0x001f8000>; +-let usesCustomInserter = true in { +-def DIV_D : ALU_3R<0x00220000>; +-def MOD_D : ALU_3R<0x00228000>; +-def DIV_DU : ALU_3R<0x00230000>; +-def MOD_DU : ALU_3R<0x00238000>; +-} // usesCustomInserter = true +- +-// Bit-shift Instructions for 64-bits +-def SLL_D : ALU_3R<0x00188000>; +-def SRL_D : ALU_3R<0x00190000>; +-def SRA_D : ALU_3R<0x00198000>; +-def ROTR_D : ALU_3R<0x001b8000>; +-def SLLI_D : ALU_2RI6<0x00410000, uimm6>; +-def SRLI_D : ALU_2RI6<0x00450000, uimm6>; +-def SRAI_D : ALU_2RI6<0x00490000, uimm6>; +-def ROTRI_D : ALU_2RI6<0x004d0000, uimm6>; +- +-// Bit-manipulation Instructions for 64-bits +-def CLO_D : ALU_2R<0x00002000>; +-def CLZ_D : ALU_2R<0x00002400>; +-def CTO_D : ALU_2R<0x00002800>; +-def CTZ_D : ALU_2R<0x00002c00>; +-def BYTEPICK_D : ALU_3RI3<0x000c0000, uimm3>; +-def REVB_4H : ALU_2R<0x00003400>; +-def REVB_2W : ALU_2R<0x00003800>; +-def REVB_D : ALU_2R<0x00003c00>; +-def REVH_2W : ALU_2R<0x00004000>; +-def REVH_D : ALU_2R<0x00004400>; +-def BITREV_8B : ALU_2R<0x00004c00>; +-def BITREV_D : ALU_2R<0x00005400>; +-let Constraints = "$rd = $dst" in { +-def BSTRINS_D : FmtBSTR_D<0x00800000, (outs GPR:$dst), +- (ins GPR:$rd, GPR:$rj, uimm6:$msbd, uimm6:$lsbd), +- "$rd, $rj, $msbd, $lsbd">; +-} +-def BSTRPICK_D : FmtBSTR_D<0x00c00000, (outs GPR:$rd), +- (ins GPR:$rj, uimm6:$msbd, uimm6:$lsbd), +- "$rd, $rj, $msbd, $lsbd">; +- +-// Common Memory Access Instructions for 64-bits +-def LD_WU : LOAD_2RI12<0x2a800000>; +-def LD_D : LOAD_2RI12<0x28c00000>; +-def ST_D : STORE_2RI12<0x29c00000>; +-def LDX_B : LOAD_3R<0x38000000>; +-def LDX_H : LOAD_3R<0x38040000>; +-def LDX_W : LOAD_3R<0x38080000>; +-def LDX_D : LOAD_3R<0x380c0000>; +-def LDX_BU : LOAD_3R<0x38200000>; +-def LDX_HU : LOAD_3R<0x38240000>; +-def LDX_WU : LOAD_3R<0x38280000>; +-def STX_B : STORE_3R<0x38100000>; +-def STX_H : STORE_3R<0x38140000>; +-def STX_W : STORE_3R<0x38180000>; +-def STX_D : STORE_3R<0x381c0000>; +-def LDPTR_W : LOAD_2RI14<0x24000000>; +-def LDPTR_D : LOAD_2RI14<0x26000000>; +-def STPTR_W : STORE_2RI14<0x25000000>; +-def STPTR_D : STORE_2RI14<0x27000000>; +-let hasSideEffects = 0, mayLoad = 1, mayStore = 1 in +-def PRELDX : FmtPRELDX<(outs), (ins uimm5:$imm5, GPR:$rj, GPR:$rk), +- "$imm5, $rj, $rk">; +- +-// Bound Check Memory Access Instructions +-def LDGT_B : LOAD_3R<0x38780000>; +-def LDGT_H : LOAD_3R<0x38788000>; +-def LDGT_W : LOAD_3R<0x38790000>; +-def LDGT_D : LOAD_3R<0x38798000>; +-def LDLE_B : LOAD_3R<0x387a0000>; +-def LDLE_H : LOAD_3R<0x387a8000>; +-def LDLE_W : LOAD_3R<0x387b0000>; +-def LDLE_D : LOAD_3R<0x387b8000>; +-def STGT_B : STORE_3R<0x387c0000>; +-def STGT_H : STORE_3R<0x387c8000>; +-def STGT_W : STORE_3R<0x387d0000>; +-def STGT_D : STORE_3R<0x387d8000>; +-def STLE_B : STORE_3R<0x387e0000>; +-def STLE_H : STORE_3R<0x387e8000>; +-def STLE_W : STORE_3R<0x387f0000>; +-def STLE_D : STORE_3R<0x387f8000>; +- +-// Atomic Memory Access Instructions for 64-bits +-def AMSWAP_B : AM_3R<0x385c0000>; +-def AMSWAP_H : AM_3R<0x385c8000>; +-def AMSWAP_W : AM_3R<0x38600000>; +-def AMSWAP_D : AM_3R<0x38608000>; +-def AMADD_B : AM_3R<0x385d0000>; +-def AMADD_H : AM_3R<0x385d8000>; +-def AMADD_W : AM_3R<0x38610000>; +-def AMADD_D : AM_3R<0x38618000>; +-def AMAND_W : AM_3R<0x38620000>; +-def AMAND_D : AM_3R<0x38628000>; +-def AMOR_W : AM_3R<0x38630000>; +-def AMOR_D : AM_3R<0x38638000>; +-def AMXOR_W : AM_3R<0x38640000>; +-def AMXOR_D : AM_3R<0x38648000>; +-def AMMAX_W : AM_3R<0x38650000>; +-def AMMAX_D : AM_3R<0x38658000>; +-def AMMIN_W : AM_3R<0x38660000>; +-def AMMIN_D : AM_3R<0x38668000>; +-def AMMAX_WU : AM_3R<0x38670000>; +-def AMMAX_DU : AM_3R<0x38678000>; +-def AMMIN_WU : AM_3R<0x38680000>; +-def AMMIN_DU : AM_3R<0x38688000>; +-def AMSWAP__DB_B : AM_3R<0x385e0000>; +-def AMSWAP__DB_H : AM_3R<0x385e8000>; +-def AMSWAP__DB_W : AM_3R<0x38690000>; +-def AMSWAP__DB_D : AM_3R<0x38698000>; +-def AMADD__DB_B : AM_3R<0x385f0000>; +-def AMADD__DB_H : AM_3R<0x385f8000>; +-def AMADD__DB_W : AM_3R<0x386a0000>; +-def AMADD__DB_D : AM_3R<0x386a8000>; +-def AMAND__DB_W : AM_3R<0x386b0000>; +-def AMAND__DB_D : AM_3R<0x386b8000>; +-def AMOR__DB_W : AM_3R<0x386c0000>; +-def AMOR__DB_D : AM_3R<0x386c8000>; +-def AMXOR__DB_W : AM_3R<0x386d0000>; +-def AMXOR__DB_D : AM_3R<0x386d8000>; +-def AMMAX__DB_W : AM_3R<0x386e0000>; +-def AMMAX__DB_D : AM_3R<0x386e8000>; +-def AMMIN__DB_W : AM_3R<0x386f0000>; +-def AMMIN__DB_D : AM_3R<0x386f8000>; +-def AMMAX__DB_WU : AM_3R<0x38700000>; +-def AMMAX__DB_DU : AM_3R<0x38708000>; +-def AMMIN__DB_WU : AM_3R<0x38710000>; +-def AMMIN__DB_DU : AM_3R<0x38718000>; +-def AMCAS_B : AM_3R<0x38580000>; +-def AMCAS_H : AM_3R<0x38588000>; +-def AMCAS_W : AM_3R<0x38590000>; +-def AMCAS_D : AM_3R<0x38598000>; +-def AMCAS__DB_B : AM_3R<0x385a0000>; +-def AMCAS__DB_H : AM_3R<0x385a8000>; +-def AMCAS__DB_W : AM_3R<0x385b0000>; +-def AMCAS__DB_D : AM_3R<0x385b8000>; +-def LL_D : LLBase<0x22000000>; +-def SC_D : SCBase<0x23000000>; +-def SC_Q : SCBase_128<0x38570000>; +-def LLACQ_D : LLBase_ACQ<0x38578800>; +-def SCREL_D : SCBase_REL<0x38578C00>; +- +-// CRC Check Instructions +-def CRC_W_B_W : ALU_3R<0x00240000>; +-def CRC_W_H_W : ALU_3R<0x00248000>; +-def CRC_W_W_W : ALU_3R<0x00250000>; +-def CRC_W_D_W : ALU_3R<0x00258000>; +-def CRCC_W_B_W : ALU_3R<0x00260000>; +-def CRCC_W_H_W : ALU_3R<0x00268000>; +-def CRCC_W_W_W : ALU_3R<0x00270000>; +-def CRCC_W_D_W : ALU_3R<0x00278000>; +- +-// Other Miscellaneous Instructions for 64-bits +-def ASRTLE_D : FmtASRT<0x00010000, (outs), (ins GPR:$rj, GPR:$rk), +- "$rj, $rk">; +-def ASRTGT_D : FmtASRT<0x00018000, (outs), (ins GPR:$rj, GPR:$rk), +- "$rj, $rk">; +-def RDTIME_D : RDTIME_2R<0x00006800>; +-} // Predicates = [IsLA64] ++def amem : mem_generic { ++ let PrintMethod = "printAMemOperand"; ++ let EncoderMethod = "getAMemEncoding"; ++ let ParserMatchClass = LoongArchAMemAsmOperand; ++} + +-//===----------------------------------------------------------------------===// +-// Pseudo-instructions and codegen patterns +-// +-// Naming convention: For 'generic' pattern classes, we use the naming +-// convention PatTy1Ty2. +-//===----------------------------------------------------------------------===// ++def mem_simmptr : mem_generic { ++ let ParserMatchClass = LoongArchMemSimmPtrAsmOperand; ++} + +-/// Generic pattern classes +- +-class PatGprGpr +- : Pat<(OpNode GPR:$rj, GPR:$rk), (Inst GPR:$rj, GPR:$rk)>; +-class PatGprGpr_32 +- : Pat<(sext_inreg (OpNode GPR:$rj, GPR:$rk), i32), (Inst GPR:$rj, GPR:$rk)>; +-class PatGpr +- : Pat<(OpNode GPR:$rj), (Inst GPR:$rj)>; +- +-class PatGprImm +- : Pat<(OpNode GPR:$rj, ImmOpnd:$imm), +- (Inst GPR:$rj, ImmOpnd:$imm)>; +-class PatGprImm_32 +- : Pat<(sext_inreg (OpNode GPR:$rj, ImmOpnd:$imm), i32), +- (Inst GPR:$rj, ImmOpnd:$imm)>; +- +-/// Predicates +-def AddLike: PatFrags<(ops node:$A, node:$B), +- [(add node:$A, node:$B), (or node:$A, node:$B)], [{ +- return N->getOpcode() == ISD::ADD || isOrEquivalentToAdd(N); +-}]>; ++foreach I = {2} in ++ def mem_simm14_lsl # I : mem_generic { ++ let MIOperandInfo = (ops ptr_rc, !cast("simm14_lsl" # I)); ++ let EncoderMethod = "getSimm14MemEncoding<" # I # ">"; ++ let ParserMatchClass = ++ !cast("LoongArchMemSimm14Lsl" # I # "AsmOperand"); ++ } + +-/// Simple arithmetic operations +- +-// Match both a plain shift and one where the shift amount is masked (this is +-// typically introduced when the legalizer promotes the shift amount and +-// zero-extends it). For LoongArch, the mask is unnecessary as shifts in the +-// base ISA only read the least significant 5 bits (LA32) or 6 bits (LA64). +-def shiftMaskGRLen +- : ComplexPattern; +-def shiftMask32 : ComplexPattern; +- +-def sexti32 : ComplexPattern; +-def zexti32 : ComplexPattern; +- +-class shiftop +- : PatFrag<(ops node:$val, node:$count), +- (operator node:$val, (GRLenVT (shiftMaskGRLen node:$count)))>; +-class shiftopw +- : PatFrag<(ops node:$val, node:$count), +- (operator node:$val, (i64 (shiftMask32 node:$count)))>; +- +-def mul_const_oneuse : PatFrag<(ops node:$A, node:$B), +- (mul node:$A, node:$B), [{ +- if (auto *N1C = dyn_cast(N->getOperand(1))) +- return N1C->hasOneUse(); +- return false; +-}]>; ++def mem_ea : Operand { ++ let PrintMethod = "printMemOperandEA"; ++ let MIOperandInfo = (ops ptr_rc, simm12); ++ let EncoderMethod = "getMemEncoding"; ++ let OperandType = "OPERAND_MEMORY"; ++} + +-let Predicates = [IsLA32] in { +-def : PatGprGpr; +-def : PatGprImm; +-def : PatGprGpr; +-def : PatGprGpr; +-def : PatGprGpr; +-def : PatGprGpr; +-def : PatGprGpr; +-def : PatGprGpr; +-def : PatGprGpr; +-def : PatGprGpr; +-def : PatGprGpr; +-def : PatGprImm; +- +-foreach Idx = 1...3 in { +- defvar ShamtA = !mul(8, Idx); +- defvar ShamtB = !mul(8, !sub(4, Idx)); +- def : Pat<(or (shl GPR:$rk, (i32 ShamtA)), (srl GPR:$rj, (i32 ShamtB))), +- (BYTEPICK_W GPR:$rj, GPR:$rk, Idx)>; +-} +-} // Predicates = [IsLA32] +- +-let Predicates = [IsLA64] in { +-def : PatGprGpr; +-def : PatGprGpr_32; +-def : PatGprImm; +-def : PatGprImm_32; +-def : PatGprGpr; +-def : PatGprGpr_32; +-def : PatGprGpr; +-def : PatGprGpr; +-def : PatGprGpr; +-def : PatGprGpr; +-def : PatGprGpr; +-def : PatGprGpr; +-def : PatGprImm; +-def : PatGprImm_32; +-def : Pat<(loongarch_rotl_w GPR:$rj, uimm5:$imm), +- (ROTRI_W GPR:$rj, (ImmSubFrom32 uimm5:$imm))>; +-def : Pat<(sext_inreg (loongarch_rotl_w GPR:$rj, uimm5:$imm), i32), +- (ROTRI_W GPR:$rj, (ImmSubFrom32 uimm5:$imm))>; +-// TODO: Select "_W[U]" instructions for i32xi32 if only lower 32 bits of the +-// product are used. +-def : PatGprGpr; +-def : PatGprGpr; +-def : PatGprGpr; +-// Select MULW_D_W for calculating the full 64 bits product of i32xi32 signed +-// multiplication. +-def : Pat<(i64 (mul (sext_inreg GPR:$rj, i32), (sext_inreg GPR:$rk, i32))), +- (MULW_D_W GPR:$rj, GPR:$rk)>; +-// Select MULW_D_WU for calculating the full 64 bits product of i32xi32 +-// unsigned multiplication. +-def : Pat<(i64 (mul (loongarch_bstrpick GPR:$rj, (i64 31), (i64 0)), +- (loongarch_bstrpick GPR:$rk, (i64 31), (i64 0)))), +- (MULW_D_WU GPR:$rj, GPR:$rk)>; +- +-def : Pat<(add GPR:$rj, simm16_lsl16:$imm), +- (ADDU16I_D GPR:$rj, (HI16 $imm))>; +-def : Pat<(add GPR:$rj, simm32_hi16_lo12:$imm), +- (ADDI_D (ADDU16I_D GPR:$rj, (HI16ForAddu16idAddiPair $imm)), +- (LO12 $imm))>; +-def : Pat<(sext_inreg (add GPR:$rj, simm32_hi16_lo12:$imm), i32), +- (ADDI_W (ADDU16I_D GPR:$rj, (HI16ForAddu16idAddiPair $imm)), +- (LO12 $imm))>; +- +-let Predicates = [IsLA32] in { +-def : Pat<(add GPR:$rj, (AddiPair:$im)), +- (ADDI_W (ADDI_W GPR:$rj, (AddiPairImmLarge AddiPair:$im)), +- (AddiPairImmSmall AddiPair:$im))>; +-} // Predicates = [IsLA32] +- +-let Predicates = [IsLA64] in { +-def : Pat<(add GPR:$rj, (AddiPair:$im)), +- (ADDI_D (ADDI_D GPR:$rj, (AddiPairImmLarge AddiPair:$im)), +- (AddiPairImmSmall AddiPair:$im))>; +-def : Pat<(sext_inreg (add GPR:$rj, (AddiPair:$im)), i32), +- (ADDI_W (ADDI_W GPR:$rj, (AddiPairImmLarge AddiPair:$im)), +- (AddiPairImmSmall AddiPair:$im))>; +-} // Predicates = [IsLA64] +- +-let Predicates = [IsLA32] in { +-foreach Idx0 = 1...4 in { +- foreach Idx1 = 1...4 in { +- defvar CImm = !add(1, !shl(!add(1, !shl(1, Idx0)), Idx1)); +- def : Pat<(mul_const_oneuse GPR:$r, (i32 CImm)), +- (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i32 Idx0)), +- GPR:$r, (i32 Idx1))>; +- } ++def LoongArchJumpTargetAsmOperand : AsmOperandClass { ++ let Name = "JumpTarget"; ++ let ParserMethod = "parseJumpTarget"; ++ let PredicateMethod = "isImm"; ++ let RenderMethod = "addImmOperands"; + } +-foreach Idx0 = 1...4 in { +- foreach Idx1 = 1...4 in { +- defvar Cb = !add(1, !shl(1, Idx0)); +- defvar CImm = !add(Cb, !shl(Cb, Idx1)); +- def : Pat<(mul_const_oneuse GPR:$r, (i32 CImm)), +- (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i32 Idx0)), +- (ALSL_W GPR:$r, GPR:$r, (i32 Idx0)), (i32 Idx1))>; +- } ++ ++def jmptarget : Operand { ++ let EncoderMethod = "getJumpTargetOpValue"; ++ let ParserMatchClass = LoongArchJumpTargetAsmOperand; + } +-} // Predicates = [IsLA32] +- +-let Predicates = [IsLA64] in { +-foreach Idx0 = 1...4 in { +- foreach Idx1 = 1...4 in { +- defvar CImm = !add(1, !shl(!add(1, !shl(1, Idx0)), Idx1)); +- def : Pat<(sext_inreg (mul_const_oneuse GPR:$r, (i64 CImm)), i32), +- (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i64 Idx0)), +- GPR:$r, (i64 Idx1))>; +- def : Pat<(mul_const_oneuse GPR:$r, (i64 CImm)), +- (ALSL_D (ALSL_D GPR:$r, GPR:$r, (i64 Idx0)), +- GPR:$r, (i64 Idx1))>; +- } ++ ++def brtarget : Operand { ++ let EncoderMethod = "getBranchTargetOpValue"; ++ let OperandType = "OPERAND_PCREL"; ++ let DecoderMethod = "DecodeBranchTarget"; ++ let ParserMatchClass = LoongArchJumpTargetAsmOperand; + } +-foreach Idx0 = 1...4 in { +- foreach Idx1 = 1...4 in { +- defvar Cb = !add(1, !shl(1, Idx0)); +- defvar CImm = !add(Cb, !shl(Cb, Idx1)); +- def : Pat<(sext_inreg (mul_const_oneuse GPR:$r, (i64 CImm)), i32), +- (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i64 Idx0)), +- (ALSL_W GPR:$r, GPR:$r, (i64 Idx0)), (i64 Idx1))>; +- def : Pat<(mul_const_oneuse GPR:$r, (i64 CImm)), +- (ALSL_D (ALSL_D GPR:$r, GPR:$r, (i64 Idx0)), +- (ALSL_D GPR:$r, GPR:$r, (i64 Idx0)), (i64 Idx1))>; +- } ++ ++def calltarget : Operand { ++ let EncoderMethod = "getJumpTargetOpValue"; ++ let ParserMatchClass = LoongArchJumpTargetAsmOperand; + } +-} // Predicates = [IsLA64] +- +-let Predicates = [IsLA32] in { +-def : Pat<(mul GPR:$rj, (AlslSlliImm:$im)), +- (SLLI_W (ALSL_W GPR:$rj, GPR:$rj, (AlslSlliImmI0 AlslSlliImm:$im)), +- (AlslSlliImmI1 AlslSlliImm:$im))>; +-} // Predicates = [IsLA32] +- +-let Predicates = [IsLA64] in { +-def : Pat<(sext_inreg (mul GPR:$rj, (AlslSlliImm:$im)), i32), +- (SLLI_W (ALSL_W GPR:$rj, GPR:$rj, (AlslSlliImmI0 AlslSlliImm:$im)), +- (AlslSlliImmI1 AlslSlliImm:$im))>; +-def : Pat<(mul GPR:$rj, (AlslSlliImm:$im)), +- (SLLI_D (ALSL_D GPR:$rj, GPR:$rj, (AlslSlliImmI0 AlslSlliImm:$im)), +- (AlslSlliImmI1 AlslSlliImm:$im))>; +-} // Predicates = [IsLA64] +- +-foreach Idx = 1...7 in { +- defvar ShamtA = !mul(8, Idx); +- defvar ShamtB = !mul(8, !sub(8, Idx)); +- def : Pat<(or (shl GPR:$rk, (i64 ShamtA)), (srl GPR:$rj, (i64 ShamtB))), +- (BYTEPICK_D GPR:$rj, GPR:$rk, Idx)>; +-} +- +-foreach Idx = 1...3 in { +- defvar ShamtA = !mul(8, Idx); +- defvar ShamtB = !mul(8, !sub(4, Idx)); +- // NOTE: the srl node would already be transformed into a loongarch_bstrpick +- // by the time this pattern gets to execute, hence the weird construction. +- def : Pat<(sext_inreg (or (shl GPR:$rk, (i64 ShamtA)), +- (loongarch_bstrpick GPR:$rj, (i64 31), +- (i64 ShamtB))), i32), +- (BYTEPICK_W GPR:$rj, GPR:$rk, Idx)>; +-} +-} // Predicates = [IsLA64] +- +-def : PatGprGpr; +-def : PatGprImm; +-def : PatGprGpr; +-def : PatGprImm; +-def : PatGprGpr; +-def : PatGprImm; +-def : Pat<(not GPR:$rj), (NOR GPR:$rj, R0)>; +-def : Pat<(not (or GPR:$rj, GPR:$rk)), (NOR GPR:$rj, GPR:$rk)>; +-def : Pat<(or GPR:$rj, (not GPR:$rk)), (ORN GPR:$rj, GPR:$rk)>; +-def : Pat<(and GPR:$rj, (not GPR:$rk)), (ANDN GPR:$rj, GPR:$rk)>; +- +-let Predicates = [IsLA32] in { +-def : Pat<(and GPR:$rj, BstrinsImm:$imm), +- (BSTRINS_W GPR:$rj, R0, (BstrinsMsb BstrinsImm:$imm), +- (BstrinsLsb BstrinsImm:$imm))>; +-} // Predicates = [IsLA32] +- +-let Predicates = [IsLA64] in { +-def : Pat<(and GPR:$rj, BstrinsImm:$imm), +- (BSTRINS_D GPR:$rj, R0, (BstrinsMsb BstrinsImm:$imm), +- (BstrinsLsb BstrinsImm:$imm))>; +-} // Predicates = [IsLA64] +- +-/// Traps +- +-// We lower `trap` to `amswap.w rd:$r0, rk:$r1, rj:$r0`, as this is guaranteed +-// to trap with an INE (non-existent on LA32, explicitly documented to INE on +-// LA64). And the resulting signal is different from `debugtrap` like on some +-// other existing ports so programs/porters might have an easier time. +-def PseudoUNIMP : Pseudo<(outs), (ins), [(trap)]>, +- PseudoInstExpansion<(AMSWAP_W R0, R1, R0)>; +- +-// We lower `debugtrap` to `break 0`, as this is guaranteed to exist and work, +-// even for LA32 Primary. Also, because so far the ISA does not provide a +-// specific trap instruction/kind exclusively for alerting the debugger, +-// every other project uses the generic immediate of 0 for this. +-def : Pat<(debugtrap), (BREAK 0)>; +- +-/// Bit counting operations +- +-let Predicates = [IsLA64] in { +-def : PatGpr; +-def : PatGpr; +-def : Pat<(ctlz (not GPR:$rj)), (CLO_D GPR:$rj)>; +-def : Pat<(cttz (not GPR:$rj)), (CTO_D GPR:$rj)>; +-def : PatGpr; +-def : PatGpr; +-def : Pat<(loongarch_clzw (not GPR:$rj)), (CLO_W GPR:$rj)>; +-def : Pat<(loongarch_ctzw (not GPR:$rj)), (CTO_W GPR:$rj)>; +-} // Predicates = [IsLA64] +- +-let Predicates = [IsLA32] in { +-def : PatGpr; +-def : PatGpr; +-def : Pat<(ctlz (not GPR:$rj)), (CLO_W GPR:$rj)>; +-def : Pat<(cttz (not GPR:$rj)), (CTO_W GPR:$rj)>; +-} // Predicates = [IsLA32] +- +-/// FrameIndex calculations +-let Predicates = [IsLA32] in { +-def : Pat<(AddLike (i32 BaseAddr:$rj), simm12:$imm12), +- (ADDI_W (i32 BaseAddr:$rj), simm12:$imm12)>; +-} // Predicates = [IsLA32] +-let Predicates = [IsLA64] in { +-def : Pat<(AddLike (i64 BaseAddr:$rj), simm12:$imm12), +- (ADDI_D (i64 BaseAddr:$rj), simm12:$imm12)>; +-} // Predicates = [IsLA64] +- +-/// Shifted addition +-let Predicates = [IsLA32] in { +-def : Pat<(add GPR:$rk, (shl GPR:$rj, uimm2_plus1:$imm2)), +- (ALSL_W GPR:$rj, GPR:$rk, uimm2_plus1:$imm2)>; +-} // Predicates = [IsLA32] +-let Predicates = [IsLA64] in { +-def : Pat<(add GPR:$rk, (shl GPR:$rj, uimm2_plus1:$imm2)), +- (ALSL_D GPR:$rj, GPR:$rk, uimm2_plus1:$imm2)>; +-def : Pat<(sext_inreg (add GPR:$rk, (shl GPR:$rj, uimm2_plus1:$imm2)), i32), +- (ALSL_W GPR:$rj, GPR:$rk, uimm2_plus1:$imm2)>; +-def : Pat<(loongarch_bstrpick (add GPR:$rk, (shl GPR:$rj, uimm2_plus1:$imm2)), +- (i64 31), (i64 0)), +- (ALSL_WU GPR:$rj, GPR:$rk, uimm2_plus1:$imm2)>; +-} // Predicates = [IsLA64] +- +-/// Shift +- +-let Predicates = [IsLA32] in { +-def : PatGprGpr, SLL_W>; +-def : PatGprGpr, SRA_W>; +-def : PatGprGpr, SRL_W>; +-def : PatGprImm; +-def : PatGprImm; +-def : PatGprImm; +-} // Predicates = [IsLA32] +- +-let Predicates = [IsLA64] in { +-def : PatGprGpr, SLL_W>; +-def : PatGprGpr, SRA_W>; +-def : PatGprGpr, SRL_W>; +-def : PatGprGpr, SLL_D>; +-def : PatGprGpr, SRA_D>; +-def : PatGprGpr, SRL_D>; +-def : PatGprImm; +-def : PatGprImm; +-def : PatGprImm; +-} // Predicates = [IsLA64] +- +-/// sext and zext +- +-def : Pat<(sext_inreg GPR:$rj, i8), (EXT_W_B GPR:$rj)>; +-def : Pat<(sext_inreg GPR:$rj, i16), (EXT_W_H GPR:$rj)>; +- +-let Predicates = [IsLA64] in { +-def : Pat<(sext_inreg GPR:$rj, i32), (ADDI_W GPR:$rj, 0)>; +-} // Predicates = [IsLA64] +- +-/// Setcc +- +-def : PatGprGpr; +-def : PatGprImm; +-def : PatGprGpr; +-def : PatGprImm; +- +-// Define pattern expansions for setcc operations that aren't directly +-// handled by a LoongArch instruction. +-def : Pat<(seteq GPR:$rj, 0), (SLTUI GPR:$rj, 1)>; +-def : Pat<(seteq GPR:$rj, GPR:$rk), (SLTUI (XOR GPR:$rj, GPR:$rk), 1)>; +-let Predicates = [IsLA32] in { +-def : Pat<(seteq GPR:$rj, simm12_plus1:$imm12), +- (SLTUI (ADDI_W GPR:$rj, (NegImm simm12_plus1:$imm12)), 1)>; +-} // Predicates = [IsLA32] +-let Predicates = [IsLA64] in { +-def : Pat<(seteq GPR:$rj, simm12_plus1:$imm12), +- (SLTUI (ADDI_D GPR:$rj, (NegImm simm12_plus1:$imm12)), 1)>; +-} // Predicates = [IsLA64] +-def : Pat<(setne GPR:$rj, 0), (SLTU R0, GPR:$rj)>; +-def : Pat<(setne GPR:$rj, GPR:$rk), (SLTU R0, (XOR GPR:$rj, GPR:$rk))>; +-let Predicates = [IsLA32] in { +-def : Pat<(setne GPR:$rj, simm12_plus1:$imm12), +- (SLTU R0, (ADDI_W GPR:$rj, (NegImm simm12_plus1:$imm12)))>; +-} // Predicates = [IsLA32] +-let Predicates = [IsLA64] in { +-def : Pat<(setne GPR:$rj, simm12_plus1:$imm12), +- (SLTU R0, (ADDI_D GPR:$rj, (NegImm simm12_plus1:$imm12)))>; +-} // Predicates = [IsLA64] +-def : Pat<(setugt GPR:$rj, GPR:$rk), (SLTU GPR:$rk, GPR:$rj)>; +-def : Pat<(setuge GPR:$rj, GPR:$rk), (XORI (SLTU GPR:$rj, GPR:$rk), 1)>; +-def : Pat<(setule GPR:$rj, GPR:$rk), (XORI (SLTU GPR:$rk, GPR:$rj), 1)>; +-def : Pat<(setgt GPR:$rj, GPR:$rk), (SLT GPR:$rk, GPR:$rj)>; +-def : Pat<(setge GPR:$rj, GPR:$rk), (XORI (SLT GPR:$rj, GPR:$rk), 1)>; +-def : Pat<(setle GPR:$rj, GPR:$rk), (XORI (SLT GPR:$rk, GPR:$rj), 1)>; +- +-/// Select +- +-def : Pat<(select GPR:$cond, GPR:$t, 0), (MASKEQZ GPR:$t, GPR:$cond)>; +-def : Pat<(select GPR:$cond, 0, GPR:$f), (MASKNEZ GPR:$f, GPR:$cond)>; +-def : Pat<(select GPR:$cond, GPR:$t, GPR:$f), +- (OR (MASKEQZ GPR:$t, GPR:$cond), (MASKNEZ GPR:$f, GPR:$cond))>; +- +-/// Branches and jumps +- +-class BccPat +- : Pat<(brcond (GRLenVT (CondOp GPR:$rj, GPR:$rd)), bb:$imm16), +- (Inst GPR:$rj, GPR:$rd, bb:$imm16)>; +- +-def : BccPat; +-def : BccPat; +-def : BccPat; +-def : BccPat; +-def : BccPat; +-def : BccPat; +- +-class BccSwapPat +- : Pat<(brcond (GRLenVT (CondOp GPR:$rd, GPR:$rj)), bb:$imm16), +- (InstBcc GPR:$rj, GPR:$rd, bb:$imm16)>; +- +-// Condition codes that don't have matching LoongArch branch instructions, but +-// are trivially supported by swapping the two input operands. +-def : BccSwapPat; +-def : BccSwapPat; +-def : BccSwapPat; +-def : BccSwapPat; +- +-// An extra pattern is needed for a brcond without a setcc (i.e. where the +-// condition was calculated elsewhere). +-def : Pat<(brcond GPR:$rj, bb:$imm21), (BNEZ GPR:$rj, bb:$imm21)>; +- +-def : Pat<(brcond (GRLenVT (seteq GPR:$rj, 0)), bb:$imm21), +- (BEQZ GPR:$rj, bb:$imm21)>; +-def : Pat<(brcond (GRLenVT (setne GPR:$rj, 0)), bb:$imm21), +- (BNEZ GPR:$rj, bb:$imm21)>; +- +-let isBarrier = 1, isBranch = 1, isTerminator = 1 in +-def PseudoBR : Pseudo<(outs), (ins simm26_b:$imm26), [(br bb:$imm26)]>, +- PseudoInstExpansion<(B simm26_b:$imm26)>; +- +-let isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in +-def PseudoBRIND : Pseudo<(outs), (ins GPR:$rj, simm16_lsl2:$imm16)>, +- PseudoInstExpansion<(JIRL R0, GPR:$rj, simm16_lsl2:$imm16)>; +- +-def : Pat<(brind GPR:$rj), (PseudoBRIND GPR:$rj, 0)>; +-def : Pat<(brind (add GPR:$rj, simm16_lsl2:$imm16)), +- (PseudoBRIND GPR:$rj, simm16_lsl2:$imm16)>; +- +-// Function call with 'Small' code model. +-let isCall = 1, Defs = [R1] in +-def PseudoCALL : Pseudo<(outs), (ins bare_symbol:$func)>; +- +-def : Pat<(loongarch_call tglobaladdr:$func), (PseudoCALL tglobaladdr:$func)>; +-def : Pat<(loongarch_call texternalsym:$func), (PseudoCALL texternalsym:$func)>; +- +-// Function call with 'Medium' code model. +-let isCall = 1, Defs = [R1, R20], Size = 8 in +-def PseudoCALL_MEDIUM : Pseudo<(outs), (ins bare_symbol:$func)>; +- +-let Predicates = [IsLA64] in { +-def : Pat<(loongarch_call_medium tglobaladdr:$func), +- (PseudoCALL_MEDIUM tglobaladdr:$func)>; +-def : Pat<(loongarch_call_medium texternalsym:$func), +- (PseudoCALL_MEDIUM texternalsym:$func)>; +-} // Predicates = [IsLA64] +- +-// Function call with 'Large' code model. +-let isCall = 1, Defs = [R1, R20], Size = 24 in +-def PseudoCALL_LARGE: Pseudo<(outs), (ins bare_symbol:$func)>; +- +-let Predicates = [IsLA64] in { +-def : Pat<(loongarch_call_large tglobaladdr:$func), +- (PseudoCALL_LARGE tglobaladdr:$func)>; +-def : Pat<(loongarch_call_large texternalsym:$func), +- (PseudoCALL_LARGE texternalsym:$func)>; +-} // Predicates = [IsLA64] +- +-let isCall = 1, Defs = [R1] in +-def PseudoCALLIndirect : Pseudo<(outs), (ins GPR:$rj), +- [(loongarch_call GPR:$rj)]>, +- PseudoInstExpansion<(JIRL R1, GPR:$rj, 0)>; +-let Predicates = [IsLA64] in { +-def : Pat<(loongarch_call_medium GPR:$rj), (PseudoCALLIndirect GPR:$rj)>; +-def : Pat<(loongarch_call_large GPR:$rj), (PseudoCALLIndirect GPR:$rj)>; +-} +- +-let isCall = 1, hasSideEffects = 0, mayStore = 0, mayLoad = 0, Defs = [R1] in +-def PseudoJIRL_CALL : Pseudo<(outs), (ins GPR:$rj, simm16_lsl2:$imm16)>, +- PseudoInstExpansion<(JIRL R1, GPR:$rj, +- simm16_lsl2:$imm16)>; +- +-let isBarrier = 1, isReturn = 1, isTerminator = 1 in +-def PseudoRET : Pseudo<(outs), (ins), [(loongarch_ret)]>, +- PseudoInstExpansion<(JIRL R0, R1, 0)>; +- +-// Tail call with 'Small' code model. +-let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [R3] in +-def PseudoTAIL : Pseudo<(outs), (ins bare_symbol:$dst)>; +- +-def : Pat<(loongarch_tail (iPTR tglobaladdr:$dst)), +- (PseudoTAIL tglobaladdr:$dst)>; +-def : Pat<(loongarch_tail (iPTR texternalsym:$dst)), +- (PseudoTAIL texternalsym:$dst)>; +- +-// Tail call with 'Medium' code model. +-let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, +- Uses = [R3], Defs = [R20], Size = 8 in +-def PseudoTAIL_MEDIUM : Pseudo<(outs), (ins bare_symbol:$dst)>; +- +-let Predicates = [IsLA64] in { +-def : Pat<(loongarch_tail_medium (iPTR tglobaladdr:$dst)), +- (PseudoTAIL_MEDIUM tglobaladdr:$dst)>; +-def : Pat<(loongarch_tail_medium (iPTR texternalsym:$dst)), +- (PseudoTAIL_MEDIUM texternalsym:$dst)>; +-} // Predicates = [IsLA64] +- +-// Tail call with 'Large' code model. +-let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, +- Uses = [R3], Defs = [R19, R20], Size = 24 in +-def PseudoTAIL_LARGE : Pseudo<(outs), (ins bare_symbol:$dst)>; +- +-let Predicates = [IsLA64] in { +-def : Pat<(loongarch_tail_large (iPTR tglobaladdr:$dst)), +- (PseudoTAIL_LARGE tglobaladdr:$dst)>; +-def : Pat<(loongarch_tail_large (iPTR texternalsym:$dst)), +- (PseudoTAIL_LARGE texternalsym:$dst)>; +-} // Predicates = [IsLA64] +- +-let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [R3] in +-def PseudoTAILIndirect : Pseudo<(outs), (ins GPRT:$rj), +- [(loongarch_tail GPRT:$rj)]>, +- PseudoInstExpansion<(JIRL R0, GPR:$rj, 0)>; +-let Predicates = [IsLA64] in { +-def : Pat<(loongarch_tail_medium GPR:$rj), (PseudoTAILIndirect GPR:$rj)>; +-def : Pat<(loongarch_tail_large GPR:$rj), (PseudoTAILIndirect GPR:$rj)>; +-} +- +-let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, +- hasSideEffects = 0, mayStore = 0, mayLoad = 0, Uses = [R3] in +-def PseudoB_TAIL : Pseudo<(outs), (ins simm26_b:$imm26)>, +- PseudoInstExpansion<(B simm26_b:$imm26)>; +- +-let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, +- hasSideEffects = 0, mayStore = 0, mayLoad = 0, Uses = [R3] in +-def PseudoJIRL_TAIL : Pseudo<(outs), (ins GPR:$rj, simm16_lsl2:$imm16)>, +- PseudoInstExpansion<(JIRL R0, GPR:$rj, +- simm16_lsl2:$imm16)>; +- +-/// call36/taill36 macro instructions +-let isCall = 1, isBarrier = 1, isCodeGenOnly = 0, isAsmParserOnly = 1, +- Defs = [R1], Size = 8, hasSideEffects = 0, mayStore = 0, mayLoad = 0 in +-def PseudoCALL36 : Pseudo<(outs), (ins bare_symbol:$dst), [], +- "call36", "$dst">, +- Requires<[IsLA64]>; +-let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [R3], +- isCodeGenOnly = 0, isAsmParserOnly = 1, Size = 8, hasSideEffects = 0, +- mayStore = 0, mayLoad = 0 in +-def PseudoTAIL36 : Pseudo<(outs), (ins GPR:$tmp, bare_symbol:$dst), [], +- "tail36", "$tmp, $dst">, +- Requires<[IsLA64]>; +- +-/// Load address (la*) macro instructions. +- +-// Define isCodeGenOnly = 0 to expose them to tablegened assembly parser. +-let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0, +- isAsmParserOnly = 1 in { +-def PseudoLA_ABS : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], +- "la.abs", "$dst, $src">; +-def PseudoLA_ABS_LARGE : Pseudo<(outs GPR:$dst), +- (ins GPR:$tmp, bare_symbol:$src), [], +- "la.abs", "$dst, $src">; +-def PseudoLA_PCREL : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], +- "la.pcrel", "$dst, $src">; +-let Defs = [R20], Size = 20 in +-def PseudoLA_PCREL_LARGE : Pseudo<(outs GPR:$dst), +- (ins GPR:$tmp, bare_symbol:$src), [], +- "la.pcrel", "$dst, $tmp, $src">, +- Requires<[IsLA64]>; +-def PseudoLA_TLS_LE : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], +- "la.tls.le", "$dst, $src">; +-} +-let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 0, +- isAsmParserOnly = 1 in { +-def PseudoLA_GOT : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], +- "la.got", "$dst, $src">; +-def PseudoLA_TLS_IE : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], +- "la.tls.ie", "$dst, $src">; +-def PseudoLA_TLS_LD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], +- "la.tls.ld", "$dst, $src">; +-def PseudoLA_TLS_GD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], +- "la.tls.gd", "$dst, $src">; +-let Defs = [R20], Size = 20 in { +-def PseudoLA_GOT_LARGE : Pseudo<(outs GPR:$dst), +- (ins GPR:$tmp, bare_symbol:$src), [], +- "la.got", "$dst, $tmp, $src">, +- Requires<[IsLA64]>; +-def PseudoLA_TLS_IE_LARGE : Pseudo<(outs GPR:$dst), +- (ins GPR:$tmp, bare_symbol:$src), [], +- "la.tls.ie", "$dst, $tmp, $src">, +- Requires<[IsLA64]>; +-def PseudoLA_TLS_LD_LARGE : Pseudo<(outs GPR:$dst), +- (ins GPR:$tmp, bare_symbol:$src), [], +- "la.tls.ld", "$dst, $tmp, $src">, +- Requires<[IsLA64]>; +-def PseudoLA_TLS_GD_LARGE : Pseudo<(outs GPR:$dst), +- (ins GPR:$tmp, bare_symbol:$src), [], +- "la.tls.gd", "$dst, $tmp, $src">, +- Requires<[IsLA64]>; +-} // Defs = [R20], Size = 20 +-} +- +-// Load address inst alias: "la", "la.global" and "la.local". +-// Default: +-// la = la.global = la.got +-// la.local = la.pcrel +-// With feature "+la-global-with-pcrel": +-// la = la.global = la.pcrel +-// With feature "+la-global-with-abs": +-// la = la.global = la.abs +-// With feature "+la-local-with-abs": +-// la.local = la.abs +-// With features "+la-global-with-pcrel,+la-global-with-abs"(disorder): +-// la = la.global = la.pcrel +-// Note: To keep consistent with gnu-as behavior, the "la" can only have one +-// register operand. +-def : InstAlias<"la $dst, $src", (PseudoLA_GOT GPR:$dst, bare_symbol:$src)>; +-def : InstAlias<"la.global $dst, $src", +- (PseudoLA_GOT GPR:$dst, bare_symbol:$src)>; +-def : InstAlias<"la.global $dst, $tmp, $src", +- (PseudoLA_GOT_LARGE GPR:$dst, GPR:$tmp, bare_symbol:$src)>; +-def : InstAlias<"la.local $dst, $src", +- (PseudoLA_PCREL GPR:$dst, bare_symbol:$src)>; +-def : InstAlias<"la.local $dst, $tmp, $src", +- (PseudoLA_PCREL_LARGE GPR:$dst, GPR:$tmp, bare_symbol:$src)>; +- +-// Note: Keep HasLaGlobalWithPcrel before HasLaGlobalWithAbs to ensure +-// "la-global-with-pcrel" takes effect when bose "la-global-with-pcrel" and +-// "la-global-with-abs" are enabled. +-let Predicates = [HasLaGlobalWithPcrel] in { +-def : InstAlias<"la $dst, $src", (PseudoLA_PCREL GPR:$dst, bare_symbol:$src)>; +-def : InstAlias<"la.global $dst, $src", +- (PseudoLA_PCREL GPR:$dst, bare_symbol:$src)>; +-def : InstAlias<"la.global $dst, $tmp, $src", +- (PseudoLA_PCREL_LARGE GPR:$dst, GPR:$tmp, bare_symbol:$src)>; +-} // Predicates = [HasLaGlobalWithPcrel] +- +-let Predicates = [HasLaGlobalWithAbs] in { +-def : InstAlias<"la $dst, $src", (PseudoLA_ABS GPR:$dst, bare_symbol:$src)>; +-def : InstAlias<"la.global $dst, $src", +- (PseudoLA_ABS GPR:$dst, bare_symbol:$src)>; +-def : InstAlias<"la.global $dst, $tmp, $src", +- (PseudoLA_ABS_LARGE GPR:$dst, GPR:$tmp, bare_symbol:$src)>; +-} // Predicates = [HasLaGlobalWithAbs] +- +-let Predicates = [HasLaLocalWithAbs] in { +-def : InstAlias<"la.local $dst, $src", +- (PseudoLA_ABS GPR:$dst, bare_symbol:$src)>; +-def : InstAlias<"la.local $dst, $tmp, $src", +- (PseudoLA_ABS_LARGE GPR:$dst, GPR:$tmp, bare_symbol:$src)>; +-} // Predicates = [HasLaLocalWithAbs] +- +-/// BSTRINS and BSTRPICK +- +-let Predicates = [IsLA32] in { +-def : Pat<(loongarch_bstrins GPR:$rd, GPR:$rj, uimm5:$msbd, uimm5:$lsbd), +- (BSTRINS_W GPR:$rd, GPR:$rj, uimm5:$msbd, uimm5:$lsbd)>; +-def : Pat<(loongarch_bstrpick GPR:$rj, uimm5:$msbd, uimm5:$lsbd), +- (BSTRPICK_W GPR:$rj, uimm5:$msbd, uimm5:$lsbd)>; +-} // Predicates = [IsLA32] +- +-let Predicates = [IsLA64] in { +-def : Pat<(loongarch_bstrins GPR:$rd, GPR:$rj, uimm6:$msbd, uimm6:$lsbd), +- (BSTRINS_D GPR:$rd, GPR:$rj, uimm6:$msbd, uimm6:$lsbd)>; +-def : Pat<(loongarch_bstrpick GPR:$rj, uimm6:$msbd, uimm6:$lsbd), +- (BSTRPICK_D GPR:$rj, uimm6:$msbd, uimm6:$lsbd)>; +-} // Predicates = [IsLA64] +- +-/// Byte-swapping and bit-reversal +- +-def : Pat<(loongarch_revb_2h GPR:$rj), (REVB_2H GPR:$rj)>; +-def : Pat<(loongarch_bitrev_4b GPR:$rj), (BITREV_4B GPR:$rj)>; +- +-let Predicates = [IsLA32] in { +-def : Pat<(bswap GPR:$rj), (ROTRI_W (REVB_2H GPR:$rj), 16)>; +-def : Pat<(bitreverse GPR:$rj), (BITREV_W GPR:$rj)>; +-def : Pat<(bswap (bitreverse GPR:$rj)), (BITREV_4B GPR:$rj)>; +-def : Pat<(bitreverse (bswap GPR:$rj)), (BITREV_4B GPR:$rj)>; +-} // Predicates = [IsLA32] +- +-let Predicates = [IsLA64] in { +-def : Pat<(loongarch_revb_2w GPR:$rj), (REVB_2W GPR:$rj)>; +-def : Pat<(bswap GPR:$rj), (REVB_D GPR:$rj)>; +-def : Pat<(loongarch_bitrev_w GPR:$rj), (BITREV_W GPR:$rj)>; +-def : Pat<(bitreverse GPR:$rj), (BITREV_D GPR:$rj)>; +-def : Pat<(bswap (bitreverse GPR:$rj)), (BITREV_8B GPR:$rj)>; +-def : Pat<(bitreverse (bswap GPR:$rj)), (BITREV_8B GPR:$rj)>; +-} // Predicates = [IsLA64] +- +-/// Loads +- +-multiclass LdPat { +- def : Pat<(vt (LoadOp BaseAddr:$rj)), (Inst BaseAddr:$rj, 0)>; +- def : Pat<(vt (LoadOp (AddrConstant GPR:$rj, simm12:$imm12))), +- (Inst GPR:$rj, simm12:$imm12)>; +- def : Pat<(vt (LoadOp (AddLike BaseAddr:$rj, simm12:$imm12))), +- (Inst BaseAddr:$rj, simm12:$imm12)>; +-} +- +-defm : LdPat; +-defm : LdPat; +-defm : LdPat; +-defm : LdPat; +-defm : LdPat, Requires<[IsLA32]>; +-defm : LdPat; +-defm : LdPat; +-let Predicates = [IsLA64] in { +-defm : LdPat; +-defm : LdPat; +-defm : LdPat; +-defm : LdPat; +-} // Predicates = [IsLA64] +- +-// LA64 register-register-addressed loads +-let Predicates = [IsLA64] in { +-class RegRegLdPat +- : Pat<(vt (LoadOp (add NonFIBaseAddr:$rj, GPR:$rk))), +- (Inst NonFIBaseAddr:$rj, GPR:$rk)>; +- +-def : RegRegLdPat; +-def : RegRegLdPat; +-def : RegRegLdPat; +-def : RegRegLdPat; +-def : RegRegLdPat; +-def : RegRegLdPat; +-def : RegRegLdPat; +-def : RegRegLdPat; +-def : RegRegLdPat; +-def : RegRegLdPat; +-} // Predicates = [IsLA64] +- +-/// Stores +- +-multiclass StPat { +- def : Pat<(StoreOp (vt StTy:$rd), BaseAddr:$rj), +- (Inst StTy:$rd, BaseAddr:$rj, 0)>; +- def : Pat<(StoreOp (vt StTy:$rs2), (AddrConstant GPR:$rj, simm12:$imm12)), +- (Inst StTy:$rs2, GPR:$rj, simm12:$imm12)>; +- def : Pat<(StoreOp (vt StTy:$rd), (AddLike BaseAddr:$rj, simm12:$imm12)), +- (Inst StTy:$rd, BaseAddr:$rj, simm12:$imm12)>; +-} +- +-defm : StPat; +-defm : StPat; +-defm : StPat, Requires<[IsLA32]>; +-let Predicates = [IsLA64] in { +-defm : StPat; +-defm : StPat; +-} // Predicates = [IsLA64] +- +-let Predicates = [IsLA64] in { +-def : Pat<(i64 (sextloadi32 (AddLike BaseAddr:$rj, simm14_lsl2:$imm14))), +- (LDPTR_W BaseAddr:$rj, simm14_lsl2:$imm14)>; +-def : Pat<(i64 (load (AddLike BaseAddr:$rj, simm14_lsl2:$imm14))), +- (LDPTR_D BaseAddr:$rj, simm14_lsl2:$imm14)>; +-def : Pat<(truncstorei32 (i64 GPR:$rd), +- (AddLike BaseAddr:$rj, simm14_lsl2:$imm14)), +- (STPTR_W GPR:$rd, BaseAddr:$rj, simm14_lsl2:$imm14)>; +-def : Pat<(store (i64 GPR:$rd), (AddLike BaseAddr:$rj, simm14_lsl2:$imm14)), +- (STPTR_D GPR:$rd, BaseAddr:$rj, simm14_lsl2:$imm14)>; +-} // Predicates = [IsLA64] +- +-// LA64 register-register-addressed stores +-let Predicates = [IsLA64] in { +-class RegRegStPat +- : Pat<(StoreOp (vt StTy:$rd), (add NonFIBaseAddr:$rj, GPR:$rk)), +- (Inst StTy:$rd, NonFIBaseAddr:$rj, GPR:$rk)>; +- +-def : RegRegStPat; +-def : RegRegStPat; +-def : RegRegStPat; +-def : RegRegStPat; +-} // Predicates = [IsLA64] +- +-/// Atomic loads and stores +- +-// DBAR hint encoding for LA664 and later micro-architectures, paraphrased from +-// the Linux patch revealing it [1]: +-// +-// - Bit 4: kind of constraint (0: completion, 1: ordering) +-// - Bit 3: barrier for previous read (0: true, 1: false) +-// - Bit 2: barrier for previous write (0: true, 1: false) +-// - Bit 1: barrier for succeeding read (0: true, 1: false) +-// - Bit 0: barrier for succeeding write (0: true, 1: false) +-// +-// Hint 0x700: barrier for "read after read" from the same address, which is +-// e.g. needed by LL-SC loops on older models. (DBAR 0x700 behaves the same as +-// nop if such reordering is disabled on supporting newer models.) ++ + // +-// [1]: https://lore.kernel.org/loongarch/20230516124536.535343-1-chenhuacai@loongson.cn/ ++//SDNode + // +-// Implementations without support for the finer-granularity hints simply treat +-// all as the full barrier (DBAR 0), so we can unconditionally start emiting the +-// more precise hints right away. +- +-def : Pat<(atomic_fence 4, timm), (DBAR 0b10100)>; // acquire +-def : Pat<(atomic_fence 5, timm), (DBAR 0b10010)>; // release +-def : Pat<(atomic_fence 6, timm), (DBAR 0b10000)>; // acqrel +-def : Pat<(atomic_fence 7, timm), (DBAR 0b10000)>; // seqcst +- +-defm : LdPat; +-defm : LdPat; +-defm : LdPat; +- +-class release_seqcst_store +- : PatFrag<(ops node:$val, node:$ptr), (base node:$val, node:$ptr), [{ +- AtomicOrdering Ordering = cast(N)->getSuccessOrdering(); +- return isReleaseOrStronger(Ordering); +-}]>; +- +-class unordered_monotonic_store +- : PatFrag<(ops node:$val, node:$ptr), (base node:$val, node:$ptr), [{ +- AtomicOrdering Ordering = cast(N)->getSuccessOrdering(); +- return !isReleaseOrStronger(Ordering); +-}]>; +- +-def atomic_store_release_seqcst_32 : release_seqcst_store; +-def atomic_store_release_seqcst_64 : release_seqcst_store; +-def atomic_store_unordered_monotonic_32 +- : unordered_monotonic_store; +-def atomic_store_unordered_monotonic_64 +- : unordered_monotonic_store; +- +-defm : StPat; +-defm : StPat; +-defm : StPat, +- Requires<[IsLA32]>; +- +-def PseudoAtomicStoreW +- : Pseudo<(outs GPR:$dst), (ins GPR:$rk, GPR:$rj)>, +- PseudoInstExpansion<(AMSWAP__DB_W R0, GPR:$rk, GPRMemAtomic:$rj)>; ++def IsGP64bit : Predicate<"Subtarget->is64Bit()">, ++ AssemblerPredicate<(all_of Feature64Bit)>; ++def IsGP32bit : Predicate<"!Subtarget->is64Bit()">, ++ AssemblerPredicate<(all_of (not Feature64Bit))>; ++def SDT_LoongArchCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; ++def SDT_LoongArchCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; + +-def : Pat<(atomic_store_release_seqcst_32 GPR:$rj, GPR:$rk), +- (PseudoAtomicStoreW GPR:$rj, GPR:$rk)>; ++def LoongArchRet : SDNode<"LoongArchISD::Ret", SDTNone, ++ [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; ++def LoongArchERet : SDNode<"LoongArchISD::ERet", SDTNone, ++ [SDNPHasChain, SDNPOptInGlue, SDNPSideEffect]>; + +-let Predicates = [IsLA64] in { +-def PseudoAtomicStoreD +- : Pseudo<(outs GPR:$dst), (ins GPR:$rk, GPR:$rj)>, +- PseudoInstExpansion<(AMSWAP__DB_D R0, GPR:$rk, GPRMemAtomic:$rj)>; ++def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_LoongArchCallSeqStart, ++ [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>; ++def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_LoongArchCallSeqEnd, ++ [SDNPHasChain, SDNPSideEffect, ++ SDNPOptInGlue, SDNPOutGlue]>; ++def LoongArchAddress : SDNode<"LoongArchISD::GlobalAddress", SDTIntUnaryOp>; + +-def : Pat<(atomic_store_release_seqcst_64 GPR:$rj, GPR:$rk), +- (PseudoAtomicStoreD GPR:$rj, GPR:$rk)>; ++// Return RA. ++let isReturn=1, isTerminator=1, isBarrier=1, hasCtrlDep=1, isCTI=1 in { ++ def RetRA : LoongArchPseudo<(outs), (ins), [(LoongArchRet)]>; + +-defm : LdPat; +-defm : StPat; +-defm : StPat; +-} // Predicates = [IsLA64] +- +-/// Atomic Ops +- +-class PseudoMaskedAM +- : Pseudo<(outs GPR:$res, GPR:$scratch), +- (ins GPR:$addr, GPR:$incr, GPR:$mask, grlenimm:$ordering)> { +- let Constraints = "@earlyclobber $res,@earlyclobber $scratch"; +- let mayLoad = 1; +- let mayStore = 1; +- let hasSideEffects = 0; +- let Size = 36; ++ let hasSideEffects=1 in ++ def ERet : LoongArchPseudo<(outs), (ins), [(LoongArchERet)]>; + } + +-def PseudoMaskedAtomicSwap32 : PseudoMaskedAM; +-def PseudoMaskedAtomicLoadAdd32 : PseudoMaskedAM; +-def PseudoMaskedAtomicLoadSub32 : PseudoMaskedAM; +-def PseudoMaskedAtomicLoadNand32 : PseudoMaskedAM; +- +-class PseudoAM : Pseudo<(outs GPR:$res, GPR:$scratch), +- (ins GPR:$addr, GPR:$incr, grlenimm:$ordering)> { +- let Constraints = "@earlyclobber $res,@earlyclobber $scratch"; +- let mayLoad = 1; +- let mayStore = 1; +- let hasSideEffects = 0; +- let Size = 24; +-} +- +-def PseudoAtomicSwap32 : PseudoAM; +-def PseudoAtomicLoadNand32 : PseudoAM; +-def PseudoAtomicLoadNand64 : PseudoAM; +-def PseudoAtomicLoadAdd32 : PseudoAM; +-def PseudoAtomicLoadSub32 : PseudoAM; +-def PseudoAtomicLoadAnd32 : PseudoAM; +-def PseudoAtomicLoadOr32 : PseudoAM; +-def PseudoAtomicLoadXor32 : PseudoAM; +- +-multiclass PseudoBinPat { +- def : Pat<(!cast(Op#"_monotonic") GPR:$addr, GPR:$incr), +- (BinInst GPR:$addr, GPR:$incr, 2)>; +- def : Pat<(!cast(Op#"_acquire") GPR:$addr, GPR:$incr), +- (BinInst GPR:$addr, GPR:$incr, 4)>; +- def : Pat<(!cast(Op#"_release") GPR:$addr, GPR:$incr), +- (BinInst GPR:$addr, GPR:$incr, 5)>; +- def : Pat<(!cast(Op#"_acq_rel") GPR:$addr, GPR:$incr), +- (BinInst GPR:$addr, GPR:$incr, 6)>; +- def : Pat<(!cast(Op#"_seq_cst") GPR:$addr, GPR:$incr), +- (BinInst GPR:$addr, GPR:$incr, 7)>; +-} +- +-class PseudoMaskedAMUMinUMax +- : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2), +- (ins GPR:$addr, GPR:$incr, GPR:$mask, grlenimm:$ordering)> { +- let Constraints = "@earlyclobber $res,@earlyclobber $scratch1," +- "@earlyclobber $scratch2"; +- let mayLoad = 1; +- let mayStore = 1; +- let hasSideEffects = 0; +- let Size = 48; ++let Defs = [SP], Uses = [SP], hasSideEffects = 1 in { ++def ADJCALLSTACKDOWN : LoongArchPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), ++ [(callseq_start timm:$amt1, timm:$amt2)]>; ++def ADJCALLSTACKUP : LoongArchPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), ++ [(callseq_end timm:$amt1, timm:$amt2)]>; + } + +-def PseudoMaskedAtomicLoadUMax32 : PseudoMaskedAMUMinUMax; +-def PseudoMaskedAtomicLoadUMin32 : PseudoMaskedAMUMinUMax; +- +-class PseudoMaskedAMMinMax +- : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2), +- (ins GPR:$addr, GPR:$incr, GPR:$mask, grlenimm:$sextshamt, +- grlenimm:$ordering)> { +- let Constraints = "@earlyclobber $res,@earlyclobber $scratch1," +- "@earlyclobber $scratch2"; +- let mayLoad = 1; +- let mayStore = 1; +- let hasSideEffects = 0; +- let Size = 56; +-} ++class LoongArchPat : Pat, PredicateControl; + +-def PseudoMaskedAtomicLoadMax32 : PseudoMaskedAMMinMax; +-def PseudoMaskedAtomicLoadMin32 : PseudoMaskedAMMinMax; ++def SDT_LoongArchJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>; + +-/// Compare and exchange ++def LoongArchJmpLink : SDNode<"LoongArchISD::JmpLink",SDT_LoongArchJmpLink, ++ [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, ++ SDNPVariadic]>; + +-class PseudoCmpXchg +- : Pseudo<(outs GPR:$res, GPR:$scratch), +- (ins GPR:$addr, GPR:$cmpval, GPR:$newval, grlenimm:$fail_order)> { +- let Constraints = "@earlyclobber $res,@earlyclobber $scratch"; +- let mayLoad = 1; +- let mayStore = 1; +- let hasSideEffects = 0; +- let Size = 36; +-} ++def LoongArchTailCall : SDNode<"LoongArchISD::TailCall", SDT_LoongArchJmpLink, ++ [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; + +-def PseudoCmpXchg32 : PseudoCmpXchg; +-def PseudoCmpXchg64 : PseudoCmpXchg; ++class GPR_32 { list GPRPredicates = [IsGP32bit]; } ++class GPR_64 { list GPRPredicates = [IsGP64bit]; } + +-def PseudoMaskedCmpXchg32 +- : Pseudo<(outs GPR:$res, GPR:$scratch), +- (ins GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, +- grlenimm:$fail_order)> { +- let Constraints = "@earlyclobber $res,@earlyclobber $scratch"; ++//===---------------------------------------------------------------------===/ ++// Instruction Class Templates ++//===---------------------------------------------------------------------===/ ++///R2 ++class Int_Reg2 ++ : InstForm<(outs RO:$rd), (ins RO:$rj), ++ !strconcat(opstr, "\t$rd, $rj"), ++ [(set RO:$rd, (OpNode RO:$rj))], ++ FrmR, opstr>; ++ ++class Int_Reg2_Iocsrrd ++ : InstForm<(outs RD:$rd), (ins RS:$rj), ++ !strconcat(opstr, "\t$rd, $rj"), ++ [(set RD:$rd, (OpNode RS:$rj))], ++ FrmR, opstr>; ++ ++class Int_Reg2_Rdtime ++ : InstForm<(outs RO:$rd, RO:$rj), (ins), ++ !strconcat(opstr, "\t$rd, $rj"), ++ [(set (OpNode RO:$rd, RO:$rj))], ++ FrmR, opstr>; ++ ++class Int_Reg2_Iocsrwr ++ : InstForm<(outs), (ins RD:$rd, RS:$rj), ++ !strconcat(opstr, "\t$rd, $rj"), ++ [(set (OpNode RD:$rd, RS:$rj))], ++ FrmR, opstr>; ++ ++class Float_Reg2 ++ : InstForm<(outs RO:$fd), (ins RO:$fj), ++ !strconcat(opstr, "\t$fd, $fj"), ++ [(set RO:$fd, (OpNode RO:$fj))], ++ FrmFR, opstr>; ++ ++class Count1 ++ : InstForm<(outs RO:$rd), (ins RO:$rj), ++ !strconcat(opstr, "\t$rd, $rj"), ++ [(set RO:$rd, (OpNode (not RO:$rj)))], ++ FrmR, opstr>; ++ ++class SignExtInReg ++ : InstForm<(outs RO:$rd), (ins RO:$rj), !strconcat(opstr, "\t$rd, $rj"), ++ [(set RO:$rd, (sext_inreg RO:$rj, vt))], FrmR, opstr>; ++ ++///R3 ++class Int_Reg3 ++ : InstForm<(outs RO:$rd), (ins RO:$rj, RO:$rk), ++ !strconcat(opstr, "\t$rd, $rj, $rk"), ++ [(set RO:$rd, (OpNode RO:$rj, RO:$rk))], ++ FrmR, opstr>; ++ ++class Int_Reg3_Crc ++ : InstForm<(outs RS:$rd), (ins RD:$rj, RS:$rk), ++ !strconcat(opstr, "\t$rd, $rj, $rk"), ++ [(set RS:$rd, (OpNode RD:$rj, RS:$rk))], ++ FrmR, opstr>; ++ ++class SetCC_R ++ : InstForm<(outs GPR32Opnd:$rd), (ins RO:$rj, RO:$rk), ++ !strconcat(opstr, "\t$rd, $rj, $rk"), ++ [(set GPR32Opnd:$rd, (OpNode RO:$rj, RO:$rk))], ++ FrmR, opstr>; ++ ++class SetCC_I ++ : InstForm<(outs GPR32Opnd:$rd), (ins RO:$rj, ImmOpnd:$imm12), ++ !strconcat(opstr, "\t$rd, $rj, $imm12"), ++ [(set GPR32Opnd:$rd, (OpNode RO:$rj, ImmOpnd:$imm12))], ++ FrmR, opstr>; ++ ++class ATOMIC ++ : InstForm<(outs RD:$rd), (ins RD:$rk, MO:$addr), ++ !strconcat(opstr, "\t$rd, $rk, $addr"), ++ [(set RD:$rd, (OpNode RD:$rk, Addr:$addr))], ++ FrmR, opstr> { ++ let DecoderMethod = "DecodeAMem"; ++ let canFoldAsLoad = 1; ++ string BaseOpcode = opstr; ++ let mayLoad = 1; ++ let mayStore = 1; ++ let Constraints = "@earlyclobber $rd"; ++} ++ ++class Nor ++ : InstForm<(outs RO:$rd), (ins RO:$rj, RO:$rk), ++ !strconcat(opstr, "\t$rd, $rj, $rk"), ++ [(set RO:$rd, (not (or RO:$rj, RO:$rk)))], ++ FrmR, opstr>; ++ ++class Shift_Var ++ : InstForm<(outs RO:$rd), (ins RO:$rj, GPR32Opnd:$rk), ++ !strconcat(opstr, "\t$rd, $rj, $rk"), ++ [(set RO:$rd, (OpNode RO:$rj, GPR32Opnd:$rk))], ++ FrmR, opstr>; ++ ++class Float_Reg3 ++ : InstForm<(outs RO:$fd), (ins RO:$fj, RO:$fk), ++ !strconcat(opstr, "\t$fd, $fj, $fk"), ++ [(set RO:$fd, (OpNode RO:$fj, RO:$fk))], ++ FrmR, opstr>; ++ ++class Float_Reg3_MA ++ : InstForm<(outs RO:$fd), (ins RO:$fj, RO:$fk), ++ !strconcat(opstr, "\t$fd, $fj, $fk"), ++ [(set RO:$fd, (OpNode (fabs RO:$fj), (fabs RO:$fk)))], ++ FrmR, opstr>; ++ ++class Float_Int_Reg3 ++ : InstForm<(outs RD:$fd), (ins RS:$rj, RS:$rk), ++ !strconcat(opstr, "\t$fd, $rj, $rk"), ++ [(set RS:$fd, (OpNode RS:$rj, RS:$rk))], ++ FrmR, opstr>; ++ ++///R4 ++class Mul_Reg4 ++ : InstForm<(outs RO:$fd), (ins RO:$fj, RO:$fk, RO:$fa), ++ !strconcat(opstr, "\t$fd, $fj, $fk, $fa"), ++ [], ++ FrmFR, opstr>; ++ ++class NMul_Reg4 ++ : InstForm<(outs RO:$fd), (ins RO:$fj, RO:$fk, RO:$fa), ++ !strconcat(opstr, "\t$fd, $fj, $fk, $fa"), ++ [], ++ FrmFR, opstr>; ++ ++///R2_IMM5 ++class Shift_Imm32 ++ : InstForm<(outs RO:$rd), (ins RO:$rj, uimm5:$imm5), ++ !strconcat(opstr, "\t$rd, $rj, $imm5"), ++ [(set RO:$rd, (OpNode RO:$rj, uimm5:$imm5))], ++ FrmR, opstr>; ++ ++///R2_IMM6 ++class Shift_Imm64 ++ : InstForm<(outs RO:$rd), (ins RO:$rj, uimm6:$imm6), ++ !strconcat(opstr, "\t$rd, $rj, $imm6"), ++ [(set RO:$rd, (OpNode RO:$rj, uimm6:$imm6))], ++ FrmR, opstr>; ++ ++///LOAD_STORE ++class FLd ++ : InstForm<(outs RD:$rd), (ins MO:$addr), ++ !strconcat(opstr, "\t$rd, $addr"), ++ [(set RD:$rd, (OpNode addrDefault:$addr))], ++ FrmR, opstr> { ++ let DecoderMethod = "DecodeFMem"; ++ let mayLoad = 1; ++} ++ ++class Ld ++ : InstForm<(outs RD:$rd), (ins MO:$addr), ++ !strconcat(opstr, "\t$rd, $addr"), ++ [(set RD:$rd, (OpNode Addr:$addr))], ++ FrmR, opstr> { ++ let DecoderMethod = "DecodeMem"; ++ let canFoldAsLoad = 1; ++ string BaseOpcode = opstr; ++ let mayLoad = 1; ++} ++ ++class FSt ++ : InstForm<(outs), (ins RD:$rd, MO:$addr), ++ !strconcat(opstr, "\t$rd, $addr"), ++ [(OpNode RD:$rd, addrDefault:$addr)], ++ FrmR, opstr> { ++ let DecoderMethod = "DecodeFMem"; ++ let mayStore = 1; ++} ++ ++class St ++ : InstForm<(outs), (ins RS:$rd, MO:$addr), ++ !strconcat(opstr, "\t$rd, $addr"), ++ [(OpNode RS:$rd, addr:$addr)], ++ FrmR, opstr> { ++ let DecoderMethod = "DecodeMem"; ++ string BaseOpcode = opstr; ++ let mayStore = 1; ++} ++ ++/// R2_IMM12 ++class Int_Reg2_Imm12 ++ : InstForm<(outs RO:$rd), (ins RO:$rj, ImmOpnd:$imm12), ++ !strconcat(opstr, "\t$rd, $rj, $imm12"), ++ [(set RO:$rd, (OpNode RO:$rj, ImmOpnd:$imm12))], ++ FrmR, opstr>; ++class RELOC_rrii ++ : InstForm<(outs RO:$rd), (ins RO:$rj, ImmOpnd:$imm12, ImmOpnd:$i12), ++ !strconcat(opstr, "\t$rd, $rj, $imm12"), ++ [(set RO:$rd, (OpNode RO:$rj, ImmOpnd:$imm12, ImmOpnd:$i12))], ++ FrmR, opstr>; ++ ++///R2_IMM14 ++class LdPtr ++ : InstForm<(outs RO:$rd), (ins mem_simm14_lsl2:$addr), ++ !strconcat(opstr, "\t$rd, $addr"), ++ [], FrmI, opstr>{ ++ let DecoderMethod = "DecodeMemSimm14"; ++ let canFoldAsLoad = 1; ++ string BaseOpcode = opstr; ++ let mayLoad = 1; ++} ++ ++class StPtr ++ : InstForm<(outs), (ins RO:$rd, mem_simm14_lsl2:$addr), ++ !strconcat(opstr, "\t$rd, $addr"), ++ [], FrmI, opstr> { ++ let DecoderMethod = "DecodeMemSimm14"; ++ string BaseOpcode = opstr; ++ let mayStore = 1; ++} ++ ++///R2_IMM16 ++class FJirl ++ : InstForm<(outs RO:$rd), (ins RO:$rj, opnd:$offs16), ++ !strconcat(opstr, "\t$rd, $rj, $offs16"), ++ [], FrmJ, opstr>; ++ ++class Beq ++ : InstForm<(outs), (ins RO:$rj, RO:$rd, opnd:$offs16), ++ !strconcat(opstr, "\t$rj, $rd, $offs16"), ++ [(brcond (i32 (cond_op RO:$rj, RO:$rd)), bb:$offs16)], ++ FrmI, opstr> { ++ let isBranch = 1; ++ let isTerminator = 1; ++ bit isCTI = 1; ++} ++ ++///R1_IMM21 ++class Beqz ++ : InstForm<(outs), (ins RO:$rj, opnd:$offs21), ++ !strconcat(opstr, "\t$rj, $offs21"), ++ [(brcond (i32 (cond_op RO:$rj, 0)), bb:$offs21)], ++ FrmI, opstr> { ++ let isBranch = 1; ++ let isTerminator = 1; ++ bit isCTI = 1; ++} ++ ++///IMM26 ++class JumpFB : ++ InstForm<(outs), (ins opnd:$offset26), !strconcat(opstr, "\t$offset26"), ++ [(operator targetoperator:$offset26)], FrmJ, opstr> { ++ let isBranch = 1; ++ let isTerminator=1; ++ let isBarrier=1; ++ let DecoderMethod = "DecodeJumpTarget"; ++ bit isCTI = 1; ++} ++ ++/// R3_SA ++class Reg3_Sa ++ : InstForm<(outs RO:$rd), (ins RO:$rj, RO:$rk, ImmOpnd:$sa), ++ !strconcat(opstr, "\t$rd, $rj, $rk, $sa"), ++ [(set RO:$rd, (OpNode RO:$rj, RO:$rk, ImmOpnd:$sa))], ++ FrmR, opstr>; ++ ++class Reg3_SaU ++ : InstForm<(outs RD:$rd), (ins RS:$rj, RS:$rk, ImmOpnd:$sa), ++ !strconcat(opstr, "\t$rd, $rj, $rk, $sa"), ++ [(set RD:$rd, (OpNode RS:$rj, RS:$rk, ImmOpnd:$sa))], ++ FrmR, opstr>; ++ ++/// Assert ++class Assert ++ : InstForm<(outs), (ins RO:$rj, RO:$rk), ++ !strconcat(opstr, "\t$rj, $rk"), ++ [(set (OpNode RO:$rj, RO:$rk))], ++ FrmR, opstr>; ++ ++class Code15 ++ : InstForm<(outs), (ins uimm15:$Code), ++ !strconcat(opstr, "\t$Code"), ++ [(set (OpNode uimm15:$Code))], ++ FrmOther, opstr>; ++ ++class TrapBase ++ : LoongArchPseudo<(outs), (ins), [(trap)]>, ++ PseudoInstExpansion<(RealInst 0)> { ++ let isBarrier = 1; ++ let isTerminator = 1; ++ let isCodeGenOnly = 1; ++ let isCTI = 1; ++} ++ ++class CSR ++ : InstForm<(outs RO:$rd), (ins ImmOpnd:$csr), ++ !strconcat(opstr, "\t$rd, $csr"), ++ [(set RO:$rd, (OpNode ImmOpnd:$csr))], ++ FrmOther, opstr>; ++ ++class CSRW ++ : InstForm<(outs RO:$dst), (ins RO:$rd, ImmOpnd:$csr), ++ !strconcat(opstr, "\t$rd, $csr"), ++ [(set RO:$dst, (OpNode RO:$rd, ImmOpnd:$csr))], ++ FrmOther, opstr>{ ++ let Constraints = "$rd = $dst"; ++} ++ ++class CSRX ++ : InstForm<(outs RO:$dst), (ins RO:$rd, RO:$rj, ImmOpnd:$csr), ++ !strconcat(opstr, "\t$rd, $rj, $csr"), ++ [(set RO:$dst, (OpNode RO:$rd, RO:$rj, ImmOpnd:$csr))], ++ FrmOther, opstr>{ ++ let Constraints = "$rd = $dst"; ++} ++ ++class CAC ++ : InstForm<(outs), (ins uimm5:$op, RO:$rj, ImmOpnd:$si12), ++ !strconcat(opstr, "\t$op, $rj, $si12"), ++ [(set (OpNode uimm5:$op, RO:$rj, ImmOpnd:$si12))], ++ FrmOther, opstr>; ++ ++class LEVEL ++ : InstForm<(outs RO:$rd), (ins RO:$rj, uimm8_64:$level), ++ !strconcat(opstr, "\t$rd, $rj, $level"), ++ [(set RO:$rd, (OpNode RO:$rj, uimm8_64:$level))], ++ FrmOther, opstr>; ++ ++class SEQ ++ : InstForm<(outs), (ins RO:$rj, uimm8_64:$seq), ++ !strconcat(opstr, "\t$rj, $seq"), ++ [(set (OpNode RO:$rj, uimm8_64:$seq))], ++ FrmOther, opstr>; ++ ++class Wait ++ : InstForm<(outs), (ins uimm15:$hint), ++ !strconcat(opstr, "\t$hint"), ++ [(set (OpNode uimm15:$hint))], ++ FrmOther, opstr>; ++ ++class Invtlb ++ : InstForm<(outs), (ins uimm5:$op, RO:$rj, RO:$rk), ++ !strconcat(opstr, "\t$op, $rj, $rk"), ++ [(set (OpNode uimm5:$op, RO:$rj, RO:$rk))], ++ FrmOther, opstr>; ++ ++class OP32 ++ : InstForm<(outs), (ins), ++ !strconcat(opstr, ""), ++ [(set (OpNode))], ++ FrmOther, opstr>; ++ ++class Bar ++ : InstForm<(outs), (ins uimm15:$hint), ++ !strconcat(opstr, "\t$hint"), ++ [(set (OpNode uimm15:$hint))], ++ FrmOther, opstr>; ++ ++//class CA op, string opstr> ++// : R3_CA; ++ ++class SI16_R2 ++ : InstForm<(outs RO:$rd), (ins RO:$rj, simm16:$si16), ++ !strconcat(opstr, "\t$rd, $rj, $si16"), ++ [(set RO:$rd, (OpNode RO:$rj, simm16:$si16))], ++ FrmR, opstr>; ++ ++class SI20 ++ : InstForm<(outs RO:$rd), (ins ImmOpnd:$si20), ++ !strconcat(opstr, "\t$rd, $si20"), ++ [(set RO:$rd, (OpNode ImmOpnd:$si20))], ++ FrmR, opstr>; ++class SI20_2R ++ : InstForm<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$si20), ++ !strconcat(opstr, "\t$rd, $rt, $si20"), ++ [(set RO:$rd, (OpNode RO:$rt, ImmOpnd:$si20))], ++ FrmR, opstr>; ++ ++let isCodeGenOnly = 1, Constraints = "$dst = $rd" in ++class SI20_R2 ++ : InstForm<(outs RO:$dst), (ins RO:$rd, ImmOpnd:$si20), ++ !strconcat(opstr, "\t$rd, $si20"), ++ [(set RO:$dst, (OpNode RO:$rd, ImmOpnd:$si20))], ++ FrmR, opstr>; ++class RELOC_rii ++ : InstForm<(outs RO:$rd), (ins ImmOpnd:$si20, ImmOpnd:$i20), ++ !strconcat(opstr, "\t$rd, $si20"), ++ [(set RO:$rd, (OpNode ImmOpnd:$si20, ImmOpnd:$i20))], ++ FrmR, opstr>; ++ ++// preld ++class Preld ++ : InstForm<(outs), (ins RO:$rj, MemOpnd:$addr, uimm5:$hint), ++ !strconcat(opstr, "\t$hint, $rj, $addr"), ++ [(set (OpNode RO:$rj, MemOpnd:$addr, uimm5:$hint))], ++ FrmR, opstr>; ++class Preld_Raw ++ : InstForm<(outs), (ins RO:$rj, simm12:$imm12, uimm5:$hint), ++ !strconcat(opstr, "\t$hint, $rj, $imm12"), ++ [], ++ FrmR, opstr>; ++class IsCall { ++ bit isCall = 1; ++ bit isCTI = 1; ++} ++ ++class EffectiveAddress ++ : InstForm<(outs RO:$rd), (ins mem_ea:$addr), ++ !strconcat(opstr, "\t$rd, $addr"), ++ [(set RO:$rd, addr:$addr)], FrmI, ++ !strconcat(opstr, "_lea")> { ++ let isCodeGenOnly = 1; ++ let hasNoSchedulingInfo = 1; ++ let DecoderMethod = "DecodeMem"; ++} ++ ++def PtrRC : Operand { ++ let MIOperandInfo = (ops ptr_rc); ++ let DecoderMethod = "DecodePtrRegisterClass"; ++ let ParserMatchClass = GPR32AsmOperand; ++} ++ ++class Atomic2Ops : ++ LoongArchPseudo<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr), ++ [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]>; ++ ++class Atomic2OpsPostRA : ++ LoongArchPseudo<(outs RC:$dst), (ins PtrRC:$ptr, RC:$incr), []> { + let mayLoad = 1; + let mayStore = 1; +- let hasSideEffects = 0; +- let Size = 44; + } + +-class PseudoMaskedAMMinMaxPat +- : Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, GPR:$shiftamt, +- timm:$ordering), +- (AMInst GPR:$addr, GPR:$incr, GPR:$mask, GPR:$shiftamt, +- timm:$ordering)>; +- +-class AtomicPat +- : Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, timm:$ordering), +- (AMInst GPR:$addr, GPR:$incr, GPR:$mask, timm:$ordering)>; ++class Atomic2OpsSubwordPostRA : ++ LoongArchPseudo<(outs RC:$dst), (ins PtrRC:$ptr, RC:$incr, RC:$mask, RC:$mask2, ++ RC:$shiftamnt), []>; ++class AtomicCmpSwap : ++ LoongArchPseudo<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap), ++ [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]>; + + // These atomic cmpxchg PatFrags only care about the failure ordering. +-// The PatFrags defined by multiclass `ternary_atomic_op_ord` in +-// TargetSelectionDAG.td care about the merged memory ordering that is the +-// stronger one between success and failure. But for LoongArch LL-SC we only +-// need to care about the failure ordering as explained in PR #67391. So we +-// define these PatFrags that will be used to define cmpxchg pats below. ++// In llvm <= 13, the PatFrags defined by multiclass `ternary_atomic_op_ord` ++// in TargetSelectionDAG.td only care about the success ordering while llvm > 13 ++// care about the `merged` ordering which is the stronger one of success and ++// failure. See https://reviews.llvm.org/D106729. But for LoongArch LL-SC we ++// only need to care about the failure ordering as explained in ++// https://github.com/llvm/llvm-project/pull/67391. So we defined these ++// PatFrags. + multiclass ternary_atomic_op_failure_ord { + def NAME#_failure_monotonic : PatFrag<(ops node:$ptr, node:$cmp, node:$val), + (!cast(NAME) node:$ptr, node:$cmp, node:$val), [{ +@@ -1999,305 +1076,922 @@ multiclass ternary_atomic_op_failure_ord { + }]>; + } + +-defm atomic_cmp_swap_32 : ternary_atomic_op_failure_ord; + defm atomic_cmp_swap_64 : ternary_atomic_op_failure_ord; + +-let Predicates = [IsLA64] in { +-def : AtomicPat; +-def : Pat<(atomic_swap_32 GPR:$addr, GPR:$incr), +- (AMSWAP__DB_W GPR:$incr, GPR:$addr)>; +-def : Pat<(atomic_swap_64 GPR:$addr, GPR:$incr), +- (AMSWAP__DB_D GPR:$incr, GPR:$addr)>; +-def : Pat<(atomic_load_add_64 GPR:$rj, GPR:$rk), +- (AMADD__DB_D GPR:$rk, GPR:$rj)>; +-def : AtomicPat; +-def : Pat<(atomic_load_sub_32 GPR:$rj, GPR:$rk), +- (AMADD__DB_W (SUB_W R0, GPR:$rk), GPR:$rj)>; +-def : Pat<(atomic_load_sub_64 GPR:$rj, GPR:$rk), +- (AMADD__DB_D (SUB_D R0, GPR:$rk), GPR:$rj)>; +-def : AtomicPat; +-defm : PseudoBinPat<"atomic_load_nand_64", PseudoAtomicLoadNand64>; +-def : AtomicPat; +-def : Pat<(atomic_load_add_32 GPR:$rj, GPR:$rk), +- (AMADD__DB_W GPR:$rk, GPR:$rj)>; +-def : Pat<(atomic_load_and_32 GPR:$rj, GPR:$rk), +- (AMAND__DB_W GPR:$rk, GPR:$rj)>; +-def : Pat<(atomic_load_and_64 GPR:$rj, GPR:$rk), +- (AMAND__DB_D GPR:$rk, GPR:$rj)>; +-def : Pat<(atomic_load_or_32 GPR:$rj, GPR:$rk), +- (AMOR__DB_W GPR:$rk, GPR:$rj)>; +-def : Pat<(atomic_load_or_64 GPR:$rj, GPR:$rk), +- (AMOR__DB_D GPR:$rk, GPR:$rj)>; +-def : Pat<(atomic_load_xor_32 GPR:$rj, GPR:$rk), +- (AMXOR__DB_W GPR:$rk, GPR:$rj)>; +-def : Pat<(atomic_load_xor_64 GPR:$rj, GPR:$rk), +- (AMXOR__DB_D GPR:$rk, GPR:$rj)>; +- +-def : Pat<(atomic_load_umin_32 GPR:$rj, GPR:$rk), +- (AMMIN__DB_WU GPR:$rk, GPR:$rj)>; +-def : Pat<(atomic_load_umin_64 GPR:$rj, GPR:$rk), +- (AMMIN__DB_DU GPR:$rk, GPR:$rj)>; +-def : Pat<(atomic_load_umax_32 GPR:$rj, GPR:$rk), +- (AMMAX__DB_WU GPR:$rk, GPR:$rj)>; +-def : Pat<(atomic_load_umax_64 GPR:$rj, GPR:$rk), +- (AMMAX__DB_DU GPR:$rk, GPR:$rj)>; +- +-def : Pat<(atomic_load_min_32 GPR:$rj, GPR:$rk), +- (AMMIN__DB_W GPR:$rk, GPR:$rj)>; +-def : Pat<(atomic_load_min_64 GPR:$rj, GPR:$rk), +- (AMMIN__DB_D GPR:$rk, GPR:$rj)>; +-def : Pat<(atomic_load_max_32 GPR:$rj, GPR:$rk), +- (AMMAX__DB_W GPR:$rk, GPR:$rj)>; +-def : Pat<(atomic_load_max_64 GPR:$rj, GPR:$rk), +- (AMMAX__DB_D GPR:$rk, GPR:$rj)>; +- +-def : AtomicPat; +-def : AtomicPat; +- +-// Ordering constants must be kept in sync with the AtomicOrdering enum in +-// AtomicOrdering.h. +-multiclass PseudoCmpXchgPat { +- def : Pat<(vt (!cast(Op#"_failure_monotonic") GPR:$addr, GPR:$cmp, GPR:$new)), +- (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 2)>; +- def : Pat<(vt (!cast(Op#"_failure_acquire") GPR:$addr, GPR:$cmp, GPR:$new)), +- (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 4)>; +- def : Pat<(vt (!cast(Op#"_failure_release") GPR:$addr, GPR:$cmp, GPR:$new)), +- (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 5)>; +- def : Pat<(vt (!cast(Op#"_failure_acq_rel") GPR:$addr, GPR:$cmp, GPR:$new)), +- (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 6)>; +- def : Pat<(vt (!cast(Op#"_failure_seq_cst") GPR:$addr, GPR:$cmp, GPR:$new)), +- (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 7)>; +-} +- +-defm : PseudoCmpXchgPat<"atomic_cmp_swap_32", PseudoCmpXchg32>; +-defm : PseudoCmpXchgPat<"atomic_cmp_swap_64", PseudoCmpXchg64, i64>; +-def : Pat<(int_loongarch_masked_cmpxchg_i64 +- GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$fail_order), +- (PseudoMaskedCmpXchg32 +- GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$fail_order)>; +- +-def : PseudoMaskedAMMinMaxPat; +-def : PseudoMaskedAMMinMaxPat; +-} // Predicates = [IsLA64] +- +-defm : PseudoBinPat<"atomic_load_nand_32", PseudoAtomicLoadNand32>; +- +-let Predicates = [IsLA32] in { +-def : AtomicPat; +-defm : PseudoBinPat<"atomic_swap_32", PseudoAtomicSwap32>; +-def : AtomicPat; +-def : AtomicPat; +-def : AtomicPat; +-defm : PseudoBinPat<"atomic_load_add_32", PseudoAtomicLoadAdd32>; +-defm : PseudoBinPat<"atomic_load_sub_32", PseudoAtomicLoadSub32>; +-defm : PseudoBinPat<"atomic_load_and_32", PseudoAtomicLoadAnd32>; +-defm : PseudoBinPat<"atomic_load_or_32", PseudoAtomicLoadOr32>; +-defm : PseudoBinPat<"atomic_load_xor_32", PseudoAtomicLoadXor32>; +-} // Predicates = [IsLA32] +- +-/// Intrinsics +- +-def : Pat<(int_loongarch_cacop_d timm:$op, i64:$rj, timm:$imm12), +- (CACOP timm:$op, GPR:$rj, timm:$imm12)>; +-def : Pat<(int_loongarch_cacop_w i32:$op, i32:$rj, i32:$imm12), +- (CACOP timm:$op, GPR:$rj, timm:$imm12)>; +-def : Pat<(loongarch_dbar uimm15:$imm15), (DBAR uimm15:$imm15)>; +-def : Pat<(loongarch_ibar uimm15:$imm15), (IBAR uimm15:$imm15)>; +-def : Pat<(loongarch_break uimm15:$imm15), (BREAK uimm15:$imm15)>; +-def : Pat<(loongarch_syscall uimm15:$imm15), (SYSCALL uimm15:$imm15)>; +- +-let Predicates = [IsLA64] in { +-// CRC Check Instructions +-def : PatGprGpr; +-def : PatGprGpr; +-def : PatGprGpr; +-def : PatGprGpr; +-def : PatGprGpr; +-def : PatGprGpr; +-def : PatGprGpr; +-def : PatGprGpr; +-} // Predicates = [IsLA64] +- +-/// Other pseudo-instructions +- +-// Pessimistically assume the stack pointer will be clobbered +-let Defs = [R3], Uses = [R3] in { +-def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), +- [(callseq_start timm:$amt1, timm:$amt2)]>; +-def ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), +- [(callseq_end timm:$amt1, timm:$amt2)]>; +-} // Defs = [R3], Uses = [R3] ++multiclass AtomicCmpSwapInstrs { ++ def ATOMIC_CMP_SWAP_MONOTONIC : ++ AtomicCmpSwap("atomic_cmp_swap_"#Bits#"_failure_monotonic"), ++ RC>; ++ def ATOMIC_CMP_SWAP_ACQUIRE : ++ AtomicCmpSwap("atomic_cmp_swap_"#Bits#"_failure_acquire"), ++ RC>; ++ def ATOMIC_CMP_SWAP_RELEASE : ++ AtomicCmpSwap("atomic_cmp_swap_"#Bits#"_failure_release"), ++ RC>; ++ def ATOMIC_CMP_SWAP_ACQ_REL : ++ AtomicCmpSwap("atomic_cmp_swap_"#Bits#"_failure_acq_rel"), ++ RC>; ++ def ATOMIC_CMP_SWAP_SEQ_CST : ++ AtomicCmpSwap("atomic_cmp_swap_"#Bits#"_failure_seq_cst"), ++ RC>; ++} ++ ++class AtomicCmpSwapPostRA : ++ LoongArchPseudo<(outs RC:$dst), ++ (ins PtrRC:$ptr, RC:$cmp, RC:$swap, i32imm:$ordering), []> { ++ let mayLoad = 1; ++ let mayStore = 1; ++} + +-//===----------------------------------------------------------------------===// +-// Assembler Pseudo Instructions +-//===----------------------------------------------------------------------===// ++class AtomicCmpSwapSubwordPostRA : ++ LoongArchPseudo<(outs RC:$dst), ++ (ins PtrRC:$ptr, RC:$mask, RC:$ShiftCmpVal, RC:$mask2, ++ RC:$ShiftNewVal, RC:$ShiftAmt, i32imm:$ordering), []> { ++ let mayLoad = 1; ++ let mayStore = 1; ++} + +-def : InstAlias<"nop", (ANDI R0, R0, 0)>; +-def : InstAlias<"move $dst, $src", (OR GPR:$dst, GPR:$src, R0)>; +-// `ret` is supported since binutils commit 20f2e2686c79a5ac (version 2.40 and +-// later). +-def : InstAlias<"ret", (JIRL R0, R1, 0)>; +-def : InstAlias<"jr $rj", (JIRL R0, GPR:$rj, 0)>; +- +-// Branches implemented with alias. +-// Always output the canonical mnemonic for the pseudo branch instructions. +-// The GNU tools emit the canonical mnemonic for the branch pseudo instructions +-// as well (e.g. "bgt" will be recognised by the assembler but never printed by +-// objdump). Match this behaviour by setting a zero weight. +-def : InstAlias<"bgt $rj, $rd, $imm16", +- (BLT GPR:$rd, GPR:$rj, simm16_lsl2_br:$imm16), 0>; +-def : InstAlias<"bgtu $rj, $rd, $imm16", +- (BLTU GPR:$rd, GPR:$rj, simm16_lsl2_br:$imm16), 0>; +-def : InstAlias<"ble $rj, $rd, $imm16", +- (BGE GPR:$rd, GPR:$rj, simm16_lsl2_br:$imm16), 0>; +-def : InstAlias<"bleu $rj, $rd, $imm16", +- (BGEU GPR:$rd, GPR:$rj, simm16_lsl2_br:$imm16), 0>; +-def : InstAlias<"bltz $rd, $imm16", +- (BLT GPR:$rd, R0, simm16_lsl2_br:$imm16), 0>; +-def : InstAlias<"bgtz $rj, $imm16", +- (BLT R0, GPR:$rj, simm16_lsl2_br:$imm16), 0>; +-def : InstAlias<"blez $rj, $imm16", +- (BGE R0, GPR:$rj, simm16_lsl2_br:$imm16), 0>; +-def : InstAlias<"bgez $rd, $imm16", +- (BGE GPR:$rd, R0, simm16_lsl2_br:$imm16), 0>; +- +-// Load immediate. +-let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0, +- isAsmParserOnly = 1 in { +-def PseudoLI_W : Pseudo<(outs GPR:$rd), (ins imm32:$imm), [], +- "li.w", "$rd, $imm">; +-def PseudoLI_D : Pseudo<(outs GPR:$rd), (ins grlenimm:$imm), [], +- "li.d", "$rd, $imm">, Requires<[IsLA64]>; ++class LoongArchInstAlias : ++ InstAlias, PredicateControl; ++ ++//===---------------------------------------------------------------------===/ ++// Instruction Definitions. ++//===---------------------------------------------------------------------===/ ++/// ++/// R2 ++/// ++ ++def CLO_D : Count1<"clo.d", GPR64Opnd, ctlz>, R2I<0b01000>; ++def CLZ_D : Int_Reg2<"clz.d", GPR64Opnd, ctlz>, R2I<0b01001>; ++def CTO_D : Count1<"cto.d", GPR64Opnd, cttz>, R2I<0b01010>; ++def CTZ_D : Int_Reg2<"ctz.d", GPR64Opnd, cttz>, R2I<0b01011>; ++ ++def REVB_4H : Int_Reg2<"revb.4h", GPR64Opnd>, R2I<0b01101>; //[] ++def REVB_2W : Int_Reg2<"revb.2w", GPR64Opnd>, R2I<0b01110>; ++def REVB_D : Int_Reg2<"revb.d", GPR64Opnd, LoongArchREVBD>, R2I<0b01111>; ++def REVH_2W : Int_Reg2<"revh.2w", GPR64Opnd>, R2I<0b10000>; ++def REVH_D : Int_Reg2<"revh.d", GPR64Opnd>, R2I<0b10001>; //[] ++ ++def BITREV_8B : Int_Reg2<"bitrev.8b", GPR64Opnd>, R2I<0b10011>; //[] ++def BITREV_D : Int_Reg2<"bitrev.d", GPR64Opnd, bitreverse>, R2I<0b10101>; ++ ++def EXT_W_H : SignExtInReg<"ext.w.h", GPR64Opnd, i16>, R2I<0b10110>; ++def EXT_W_B : SignExtInReg<"ext.w.b", GPR64Opnd, i8>, R2I<0b10111>; ++ ++def RDTIME_D : Int_Reg2_Rdtime<"rdtime.d", GPR64Opnd>, R2I<0b11010>; ++def RDTIMEL_W : Int_Reg2_Rdtime<"rdtimel.w", GPR64Opnd>, R2I<0b11000>; ++def RDTIMEH_W : Int_Reg2_Rdtime<"rdtimeh.w", GPR64Opnd>, R2I<0b11001>; ++/// ++/// R3 ++/// ++def ADD_D : Int_Reg3<"add.d", GPR64Opnd, add>, R3I<0b0100001>; ++def SUB_D : Int_Reg3<"sub.d", GPR64Opnd, sub>, R3I<0b0100011>; ++ ++def SLT : SetCC_R<"slt", GPR64Opnd, setlt>, R3I<0b0100100>; ++def SLTU : SetCC_R<"sltu", GPR64Opnd, setult>, R3I<0b0100101>; ++def MASKEQZ : Int_Reg3<"maskeqz", GPR64Opnd>, R3I<0b0100110>; //[] ++def MASKNEZ : Int_Reg3<"masknez", GPR64Opnd>, R3I<0b0100111>; //[] ++ ++def NOR : Nor<"nor", GPR64Opnd>, R3I<0b0101000>; ++def AND : Int_Reg3<"and", GPR64Opnd, and>, R3I<0b0101001>; ++def OR : Int_Reg3<"or", GPR64Opnd, or>, R3I<0b0101010>; ++def XOR : Int_Reg3<"xor", GPR64Opnd, xor>, R3I<0b0101011>; ++def ORN : Int_Reg3<"orn", GPR64Opnd>, R3I<0b0101100>; ++def ANDN : Int_Reg3<"andn", GPR64Opnd>, R3I<0b0101101>; ++ ++def SLL_D : Shift_Var<"sll.d", GPR64Opnd, shl>, R3I<0b0110001>; ++def SRL_D : Shift_Var<"srl.d", GPR64Opnd, srl>, R3I<0b0110010>; ++def SRA_D : Shift_Var<"sra.d", GPR64Opnd, sra>, R3I<0b0110011>; ++def ROTR_D: Shift_Var<"rotr.d", GPR64Opnd, rotr>, R3I<0b0110111>; ++ ++def MUL_D : Int_Reg3<"mul.d", GPR64Opnd, mul>, R3I<0b0111011>; ++def MULH_D : Int_Reg3<"mulh.d", GPR64Opnd, mulhs>, R3I<0b0111100>; ++def MULH_DU : Int_Reg3<"mulh.du", GPR64Opnd, mulhu>, R3I<0b0111101>; ++def MULW_D_W : Int_Reg3<"mulw.d.w", GPR64Opnd>, R3I<0b0111110>; ++def MULW_D_WU : Int_Reg3<"mulw.d.wu", GPR64Opnd>, R3I<0b0111111>; ++ ++let usesCustomInserter = 1 in { ++def DIV_D : Int_Reg3<"div.d", GPR64Opnd, sdiv>, R3I<0b1000100>; ++def MOD_D : Int_Reg3<"mod.d", GPR64Opnd, srem>, R3I<0b1000101>; ++def DIV_DU : Int_Reg3<"div.du", GPR64Opnd, udiv>, R3I<0b1000110>; ++def MOD_DU : Int_Reg3<"mod.du", GPR64Opnd, urem>, R3I<0b1000111>; ++} ++ ++def CRC_W_D_W : Int_Reg3_Crc<"crc.w.d.w", GPR64Opnd, GPR32Opnd, int_loongarch_crc_w_d_w>, R3I<0b1001011>; ++def CRCC_W_D_W : Int_Reg3_Crc<"crcc.w.d.w", GPR64Opnd, GPR32Opnd, int_loongarch_crcc_w_d_w>, R3I<0b1001111>; ++/// ++/// SLLI ++/// ++def SLLI_D : Shift_Imm64<"slli.d", GPR64Opnd, shl>, R2_IMM6<0b00>; ++def SRLI_D : Shift_Imm64<"srli.d", GPR64Opnd, srl>, R2_IMM6<0b01>; ++def SRAI_D : Shift_Imm64<"srai.d", GPR64Opnd, sra>, R2_IMM6<0b10>; ++def ROTRI_D : Shift_Imm64<"rotri.d", GPR64Opnd, rotr>, R2_IMM6<0b11>; ++/// ++/// Misc ++/// ++def ALSL_WU : Reg3_SaU<"alsl.wu", GPR64Opnd, GPR32Opnd, uimm2_plus1>, R3_SA2<0b00011> { ++ let Pattern = [(set GPR64Opnd:$rd, ++ (i64 (zext (add GPR32Opnd:$rk, (shl GPR32Opnd:$rj, immZExt2Alsl:$sa)))))]; ++} ++ ++def ALSL_D : Reg3_Sa<"alsl.d", GPR64Opnd, uimm2_plus1>, R3_SA2<0b10110> { ++ let Pattern = [(set GPR64Opnd:$rd, ++ (add GPR64Opnd:$rk, (shl GPR64Opnd:$rj, immZExt2Alsl:$sa)))]; ++} ++def BYTEPICK_D : Reg3_Sa<"bytepick.d", GPR64Opnd, uimm3>, R3_SA3; //[] ++ ++def ASRTLE_D : Assert<"asrtle.d", GPR64Opnd, int_loongarch_asrtle_d>, ASSERT<0b10>; ++def ASRTGT_D : Assert<"asrtgt.d", GPR64Opnd, int_loongarch_asrtgt_d>, ASSERT<0b11>; ++ ++def DBCL : Code15<"dbcl">, CODE15<0b1010101>; ++def HYPCALL : Code15<"hypcall">, CODE15<0b1010111>; ++ ++/// ++/// R2_IMM12 ++/// ++def SLTI : SetCC_I<"slti", GPR64Opnd, simm12, setlt>, R2_IMM12<0b000>; ++def SLTUI : SetCC_I<"sltui", GPR64Opnd, simm12, setult>, R2_IMM12<0b001>; ++def ADDI_W64 : Int_Reg2_Imm12<"addi.w", GPR64Opnd, simm12>, R2_IMM12<0b010>; ++def ADDI_D : Int_Reg2_Imm12<"addi.d", GPR64Opnd, simm12, add>, R2_IMM12<0b011>; ++def LU52I_D : Int_Reg2_Imm12<"lu52i.d", GPR64Opnd, simm12>, R2_IMM12<0b100>; ++def ANDI : Int_Reg2_Imm12<"andi", GPR64Opnd, uimm12, and>, R2_IMM12<0b101>; ++def ORI : Int_Reg2_Imm12<"ori", GPR64Opnd, uimm12, or>, R2_IMM12<0b110>; ++def XORI : Int_Reg2_Imm12<"xori", GPR64Opnd, uimm12, xor>, R2_IMM12<0b111>; ++ ++/// ++/// Privilege Instructions ++/// ++def CSRRD : CSR<"csrrd", GPR64Opnd, uimm14, int_loongarch_csrrd_d>, R1_CSR<0b0000000000100>; ++def CSRWR : CSRW<"csrwr", GPR64Opnd, uimm14, int_loongarch_csrwr_d>, R1_CSR<0b0000100000100>; ++def CSRXCHG : CSRX<"csrxchg", GPR64Opnd, uimm14, int_loongarch_csrxchg_d>, R2_CSR<0b00000100>; ++def IOCSRRD_D : Int_Reg2_Iocsrrd<"iocsrrd.d", GPR64Opnd, GPR32Opnd, int_loongarch_iocsrrd_d>, R2P<0b011>; ++def IOCSRWR_D : Int_Reg2_Iocsrwr<"iocsrwr.d", GPR64Opnd, GPR32Opnd, int_loongarch_iocsrwr_d>, R2P<0b111>; ++def CACOP : CAC<"cacop", GPR64Opnd, simm12, int_loongarch_cacop_d>, R1_CACHE; ++def LDDIR : LEVEL<"lddir", GPR64Opnd>, R2_LEVEL<0b00000110010000>; ++def LDPTE : SEQ<"ldpte", GPR64Opnd>, R1_SEQ<0b00000110010001>; ++ ++def IDLE : Wait<"idle">, WAIT_FM; ++def INVTLB : Invtlb<"invtlb", GPR64Opnd>, R2_INVTLB; ++// ++def IOCSRRD_B : Int_Reg2<"iocsrrd.b", GPR64Opnd>, R2P<0b000>; ++def IOCSRRD_H : Int_Reg2<"iocsrrd.h", GPR64Opnd>, R2P<0b001>; ++def IOCSRRD_W : Int_Reg2<"iocsrrd.w", GPR64Opnd>, R2P<0b010>; ++// ++def TLBCLR : OP32<"tlbclr", int_loongarch_tlbclr>, IMM32<0b001000>; ++def TLBFLUSH : OP32<"tlbflush", int_loongarch_tlbflush>, IMM32<0b001001>; ++def TLBSRCH : OP32<"tlbsrch", int_loongarch_tlbsrch>, IMM32<0b001010>; ++def TLBRD : OP32<"tlbrd", int_loongarch_tlbrd>, IMM32<0b001011>; ++def TLBWR : OP32<"tlbwr", int_loongarch_tlbwr>, IMM32<0b001100>; ++def TLBFILL : OP32<"tlbfill", int_loongarch_tlbfill>, IMM32<0b001101>; ++def ERTN : OP32<"ertn">, IMM32<0b001110>; ++ ++/// ++/// R1_IMM20 ++/// ++def ADDU16I_D : SI16_R2<"addu16i.d", GPR64Opnd>, R2_SI16<0b000100>; ++def LU12I_W : SI20<"lu12i.w", GPR64Opnd, simm20>, R1_SI20<0b0001010>; ++def LU32I_D : SI20<"lu32i.d", GPR64Opnd, simm20>, R1_SI20<0b0001011>; ++def LU32I_D_R2 : SI20_R2<"lu32i.d", GPR64Opnd, simm20>, R1_SI20<0b0001011>; ++def PCADDI : SI20<"pcaddi", GPR64Opnd, simm20>, R1_SI20<0b0001100>; ++def PCALAU12I : SI20<"pcalau12i", GPR64Opnd, simm20>, R1_SI20<0b0001101>; ++def PCADDU12I : SI20<"pcaddu12i", GPR64Opnd, simm20>, R1_SI20<0b0001110>; ++def PCADDU18I : SI20<"pcaddu18i", GPR64Opnd, simm20>, R1_SI20<0b0001111>; ++ ++ ++def BEQZ : Beqz<"beqz", brtarget, seteq, GPR64Opnd>, R1_IMM21BEQZ<0b010000>; ++def BNEZ : Beqz<"bnez", brtarget, setne, GPR64Opnd>, R1_IMM21BEQZ<0b010001>; ++ ++def JIRL : FJirl<"jirl", simm16, GPR64Opnd>, R2_IMM16JIRL; ++let isCall = 1, isCTI=1, isCodeGenOnly = 1 in { ++def JIRL_CALL : FJirl<"jirl", simm16, GPR64Opnd>, R2_IMM16JIRL; ++} ++ ++def B : JumpFB, IMM26B<0b010100>; ++ ++def BEQ : Beq<"beq", brtarget, seteq, GPR64Opnd>, R2_IMM16BEQ<0b010110>; ++def BNE : Beq<"bne", brtarget, setne, GPR64Opnd>, R2_IMM16BEQ<0b010111>; ++def BLT : Beq<"blt", brtarget, setlt, GPR64Opnd>, R2_IMM16BEQ<0b011000>; ++def BGE : Beq<"bge", brtarget, setge, GPR64Opnd>, R2_IMM16BEQ<0b011001>; ++def BLTU : Beq<"bltu", brtarget, setult, GPR64Opnd>, R2_IMM16BEQ<0b011010>; ++def BGEU : Beq<"bgeu", brtarget, setuge, GPR64Opnd>, R2_IMM16BEQ<0b011011>; ++ ++/// ++/// Mem access ++/// ++class LLBase : ++ InstForm<(outs RO:$rd), (ins MO:$addr), !strconcat(opstr, "\t$rd, $addr"), ++ [], FrmI, opstr> { ++ let DecoderMethod = "DecodeMemSimm14"; ++ let mayLoad = 1; + } + +-//===----------------------------------------------------------------------===// +-// Basic Floating-Point Instructions +-//===----------------------------------------------------------------------===// ++let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { ++class LLBase_ACQ ++ : InstForm<(outs RO:$rd), (ins RO:$rj), ++ !strconcat(opstr, "\t$rd, $rj"), ++ [], FrmR, opstr>; ++} ++ ++class SCBase : ++ InstForm<(outs RO:$dst), (ins RO:$rd, MO:$addr), ++ !strconcat(opstr, "\t$rd, $addr"), [], FrmI> { ++ let DecoderMethod = "DecodeMemSimm14"; ++ let mayStore = 1; ++ let Constraints = "$rd = $dst"; ++} ++ ++let hasSideEffects = 0, mayLoad = 0, mayStore = 1, Constraints = "$rd = $dst" in { ++class SCBase_128 : ++ InstForm<(outs RO:$dst), (ins RO:$rd, RO:$rk, RO:$rj), ++ !strconcat(opstr, "\t$rd, $rk, $rj"), ++ [], FrmR, opstr>; ++ ++class SCBase_REL : ++ InstForm<(outs RO:$dst), (ins RO:$rd, RO:$rj), ++ !strconcat(opstr, "\t$rd, $rj"), ++ [], FrmR, opstr>; ++} ++ ++class STGT_LE : ++ InstForm<(outs), (ins RO:$rd, RO:$rj, RO:$rk), ++ !strconcat(opstr, "\t$rd, $rj, $rk"), ++ [], FrmI, opstr>; ++ ++class Float_STGT_LE ++ : InstForm<(outs), (ins RD:$fd, RS:$rj, RS:$rk), ++ !strconcat(opstr, "\t$fd, $rj, $rk"), ++ [], FrmR, opstr>; ++ ++def LL_D : LLBase<"ll.d", GPR64Opnd, mem_simm14_lsl2>, LL_SC<0b010>; ++def SC_D : SCBase<"sc.d", GPR64Opnd, mem_simm14_lsl2>, LL_SC<0b011>; ++def SC_Q : SCBase_128<"sc.q", GPR64Opnd>, R3MI<0b10101110>; ++def LLACQ_D : LLBase_ACQ<"llacq.d", GPR64Opnd>, R2_LL_SC<0b010>; ++def SCREL_D : SCBase_REL<"screl.d", GPR64Opnd>, R2_LL_SC<0b011>; ++ ++def LDPTR_W : LdPtr<"ldptr.w", GPR64Opnd>, LL_SC<0b100>; ++def STPTR_W : StPtr<"stptr.w", GPR64Opnd>, LL_SC<0b101>; ++def LDPTR_D : LdPtr<"ldptr.d", GPR64Opnd>, LL_SC<0b110>; ++def STPTR_D : StPtr<"stptr.d", GPR64Opnd>, LL_SC<0b111>; ++ ++def LD_B : Ld<"ld.b", GPR64Opnd, mem, sextloadi8>, LOAD_STORE<0b0000>; ++def LD_H : Ld<"ld.h", GPR64Opnd, mem, sextloadi16>, LOAD_STORE<0b0001>; ++def LD_W : Ld<"ld.w", GPR64Opnd, mem, sextloadi32>, LOAD_STORE<0b0010>; ++def LD_D : Ld<"ld.d", GPR64Opnd, mem_simmptr, load>, LOAD_STORE<0b0011>; ++def ST_B : St<"st.b", GPR64Opnd, mem, truncstorei8>, LOAD_STORE<0b0100>; ++def ST_H : St<"st.h", GPR64Opnd, mem, truncstorei16>, LOAD_STORE<0b0101>; ++def ST_W : St<"st.w", GPR64Opnd, mem, truncstorei32>, LOAD_STORE<0b0110>; ++def ST_D : St<"st.d", GPR64Opnd, mem_simmptr, store>, LOAD_STORE<0b0111>; ++def LD_BU : Ld<"ld.bu", GPR64Opnd, mem, zextloadi8>, LOAD_STORE<0b1000>; ++def LD_HU : Ld<"ld.hu", GPR64Opnd, mem, zextloadi16>, LOAD_STORE<0b1001>; ++def LD_WU : Ld<"ld.wu", GPR64Opnd, mem, zextloadi32>, LOAD_STORE<0b1010>; ++ ++def AMSWAP_W : ATOMIC<"amswap.w", GPR32Opnd, amem>, AM<0b000000>; ++def AMSWAP_D : ATOMIC<"amswap.d", GPR64Opnd, amem>, AM<0b000001>; ++def AMADD_W : ATOMIC<"amadd.w", GPR32Opnd, amem>, AM<0b000010>; ++def AMADD_D : ATOMIC<"amadd.d", GPR64Opnd, amem>, AM<0b000011>; ++def AMAND_W : ATOMIC<"amand.w", GPR32Opnd, amem>, AM<0b000100>; ++def AMAND_D : ATOMIC<"amand.d", GPR64Opnd, amem>, AM<0b000101>; ++def AMOR_W : ATOMIC<"amor.w", GPR32Opnd, amem>, AM<0b000110>; ++def AMOR_D : ATOMIC<"amor.d", GPR64Opnd, amem>, AM<0b000111>; ++def AMXOR_W : ATOMIC<"amxor.w", GPR32Opnd, amem>, AM<0b001000>; ++def AMXOR_D : ATOMIC<"amxor.d", GPR64Opnd, amem>, AM<0b001001>; ++def AMMAX_W : ATOMIC<"ammax.w", GPR32Opnd, amem>, AM<0b001010>; ++def AMMAX_D : ATOMIC<"ammax.d", GPR64Opnd, amem>, AM<0b001011>; ++def AMMIN_W : ATOMIC<"ammin.w", GPR32Opnd, amem>, AM<0b001100>; ++def AMMIN_D : ATOMIC<"ammin.d", GPR64Opnd, amem>, AM<0b001101>; ++def AMMAX_WU : ATOMIC<"ammax.wu", GPR32Opnd, amem>, AM<0b001110>; ++def AMMAX_DU : ATOMIC<"ammax.du", GPR64Opnd, amem>, AM<0b001111>; ++def AMMIN_WU : ATOMIC<"ammin.wu", GPR32Opnd, amem>, AM<0b010000>; ++def AMMIN_DU : ATOMIC<"ammin.du", GPR64Opnd, amem>, AM<0b010001>; ++ ++ ++def AMSWAP_DB_W : ATOMIC<"amswap_db.w", GPR32Opnd, amem>, AM<0b010010>; ++def AMSWAP_DB_D : ATOMIC<"amswap_db.d", GPR64Opnd, amem>, AM<0b010011>; ++def AMADD_DB_W : ATOMIC<"amadd_db.w", GPR32Opnd, amem>, AM<0b010100>; ++def AMADD_DB_D : ATOMIC<"amadd_db.d", GPR64Opnd, amem>, AM<0b010101>; ++def AMAND_DB_W : ATOMIC<"amand_db.w", GPR32Opnd, amem>, AM<0b010110>; ++def AMAND_DB_D : ATOMIC<"amand_db.d", GPR64Opnd, amem>, AM<0b010111>; ++def AMOR_DB_W : ATOMIC<"amor_db.w", GPR32Opnd, amem>, AM<0b011000>; ++def AMOR_DB_D : ATOMIC<"amor_db.d", GPR64Opnd, amem>, AM<0b011001>; ++def AMXOR_DB_W : ATOMIC<"amxor_db.w", GPR32Opnd, amem>, AM<0b011010>; ++def AMXOR_DB_D : ATOMIC<"amxor_db.d", GPR64Opnd, amem>, AM<0b011011>; ++def AMMAX_DB_W : ATOMIC<"ammax_db.w", GPR32Opnd, amem>, AM<0b011100>; ++def AMMAX_DB_D : ATOMIC<"ammax_db.d", GPR64Opnd, amem>, AM<0b011101>; ++def AMMIN_DB_W : ATOMIC<"ammin_db.w", GPR32Opnd, amem>, AM<0b011110>; ++def AMMIN_DB_D : ATOMIC<"ammin_db.d", GPR64Opnd, amem>, AM<0b011111>; ++def AMMAX_DB_WU : ATOMIC<"ammax_db.wu", GPR32Opnd, amem>, AM<0b100000>; ++def AMMAX_DB_DU : ATOMIC<"ammax_db.du", GPR64Opnd, amem>, AM<0b100001>; ++def AMMIN_DB_WU : ATOMIC<"ammin_db.wu", GPR32Opnd, amem>, AM<0b100010>; ++def AMMIN_DB_DU : ATOMIC<"ammin_db.du", GPR64Opnd, amem>, AM<0b100011>; ++ ++// LoongArch V1.1 atomic instructions ++def AMCAS_B : ATOMIC<"amcas.b", GPR64Opnd, amem>, AM_V1_1<0b0000>; ++def AMCAS_H : ATOMIC<"amcas.h", GPR64Opnd, amem>, AM_V1_1<0b0001>; ++def AMCAS_W : ATOMIC<"amcas.w", GPR64Opnd, amem>, AM_V1_1<0b0010>; ++def AMCAS_D : ATOMIC<"amcas.d", GPR64Opnd, amem>, AM_V1_1<0b0011>; ++def AMCAS_DB_B : ATOMIC<"amcas_db.b", GPR64Opnd, amem>, AM_V1_1<0b0100>; ++def AMCAS_DB_H : ATOMIC<"amcas_db.h", GPR64Opnd, amem>, AM_V1_1<0b0101>; ++def AMCAS_DB_W : ATOMIC<"amcas_db.w", GPR64Opnd, amem>, AM_V1_1<0b0110>; ++def AMCAS_DB_D : ATOMIC<"amcas_db.d", GPR64Opnd, amem>, AM_V1_1<0b0111>; ++def AMSWAP_B : ATOMIC<"amswap.b", GPR64Opnd, amem>, AM_V1_1<0b1000>; ++def AMSWAP_H : ATOMIC<"amswap.h", GPR64Opnd, amem>, AM_V1_1<0b1001>; ++def AMADD_B : ATOMIC<"amadd.b", GPR64Opnd, amem>, AM_V1_1<0b1010>; ++def AMADD_H : ATOMIC<"amadd.h", GPR64Opnd, amem>, AM_V1_1<0b1011>; ++def AMSWAP_DB_B : ATOMIC<"amswap_db.b", GPR64Opnd, amem>, AM_V1_1<0b1100>; ++def AMSWAP_DB_H : ATOMIC<"amswap_db.h", GPR64Opnd, amem>, AM_V1_1<0b1101>; ++def AMADD_DB_B : ATOMIC<"amadd_db.b", GPR64Opnd, amem>, AM_V1_1<0b1110>; ++def AMADD_DB_H : ATOMIC<"amadd_db.h", GPR64Opnd, amem>, AM_V1_1<0b1111>; ++ ++def LDGT_B : Int_Reg3<"ldgt.b", GPR64Opnd>, R3MI<0b11110000>; ++def LDGT_H : Int_Reg3<"ldgt.h", GPR64Opnd>, R3MI<0b11110001>; ++def LDGT_W : Int_Reg3<"ldgt.w", GPR64Opnd>, R3MI<0b11110010>; ++def LDGT_D : Int_Reg3<"ldgt.d", GPR64Opnd>, R3MI<0b11110011>; ++def LDLE_B : Int_Reg3<"ldle.b", GPR64Opnd>, R3MI<0b11110100>; ++def LDLE_H : Int_Reg3<"ldle.h", GPR64Opnd>, R3MI<0b11110101>; ++def LDLE_W : Int_Reg3<"ldle.w", GPR64Opnd>, R3MI<0b11110110>; ++def LDLE_D : Int_Reg3<"ldle.d", GPR64Opnd>, R3MI<0b11110111>; ++def STGT_B : STGT_LE<"stgt.b", GPR64Opnd>, R3MI<0b11111000>; ++def STGT_H : STGT_LE<"stgt.h", GPR64Opnd>, R3MI<0b11111001>; ++def STGT_W : STGT_LE<"stgt.w", GPR64Opnd>, R3MI<0b11111010>; ++def STGT_D : STGT_LE<"stgt.d", GPR64Opnd>, R3MI<0b11111011>; ++def STLE_B : STGT_LE<"stle.b", GPR64Opnd>, R3MI<0b11111100>; ++def STLE_H : STGT_LE<"stle.h", GPR64Opnd>, R3MI<0b11111101>; ++def STLE_W : STGT_LE<"stle.w", GPR64Opnd>, R3MI<0b11111110>; ++def STLE_D : STGT_LE<"stle.d", GPR64Opnd>, R3MI<0b11111111>; ++ ++let isCodeGenOnly = 1 in { ++def PRELD : Preld<"preld", mem, GPR64Opnd>, PRELD_FM_ADDR; ++} ++ ++def PRELD_Raw : Preld_Raw<"preld", GPR64Opnd>, PRELD_FM; ++ ++let isCall=1, isCTI=1, Defs = [RA] in { ++ class JumpLink : ++ InstForm<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"), ++ [(LoongArchJmpLink tglobaladdr:$target)], FrmJ, opstr> { ++ let DecoderMethod = "DecodeJumpTarget"; ++ } ++} ++def LONG_BRANCH_PCADDU12I : LoongArchPseudo<(outs GPR64Opnd:$dst), ++ (ins brtarget:$tgt), []>, GPR_64; ++ ++def LONG_BRANCH_ADDID2Op : LoongArchPseudo<(outs GPR64Opnd:$dst), ++ (ins GPR64Opnd:$src, brtarget:$tgt), []>, GPR_64; ++ ++def LONG_BRANCH_ADDID : LoongArchPseudo<(outs GPR64Opnd:$dst), ++ (ins GPR64Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>, GPR_64; ++ ++def LEA_ADDI_D: EffectiveAddress<"addi.d", GPR64Opnd>, LEA_ADDI_FM<0b011>, GPR_64; ++ ++class PseudoReturnBase : LoongArchPseudo<(outs), (ins RO:$rs), ++ []> { ++ let isTerminator = 1; ++ let isBarrier = 1; ++ let isReturn = 1; ++ let isCodeGenOnly = 1; ++ let hasCtrlDep = 1; ++ let hasExtraSrcRegAllocReq = 1; ++ bit isCTI = 1; ++} ++ ++def PseudoReturn64 : PseudoReturnBase; ++//def PseudoReturn : PseudoReturnBase; + +-include "LoongArchFloat32InstrInfo.td" +-include "LoongArchFloat64InstrInfo.td" + +-let Predicates = [HasBasicF], usesCustomInserter = 1 in { +- def WRFCSR : Pseudo<(outs), (ins uimm2:$fcsr, GPR:$src), +- [(loongarch_movgr2fcsr uimm2:$fcsr, GRLenVT:$src)]>; +- def RDFCSR : Pseudo<(outs GPR:$rd), (ins uimm2:$fcsr), +- [(set GPR:$rd, (loongarch_movfcsr2gr uimm2:$fcsr))]>; ++let isCall=1, isCTI=1, Defs=[RA], isCodeGenOnly=1 in { ++def PseudoCall : LoongArchPseudo<(outs), (ins calltarget:$target), ++ []>; + } + +-//===----------------------------------------------------------------------===// +-// Privilege Instructions +-//===----------------------------------------------------------------------===// ++let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in ++def PseudoTailCall : LoongArchPseudo<(outs), (ins calltarget:$target), ++ []>; + +-// CSR Access Instructions +-let hasSideEffects = 1 in +-def CSRRD : FmtCSR<0x04000000, (outs GPR:$rd), (ins uimm14:$csr_num), +- "$rd, $csr_num">; +-let hasSideEffects = 1, Constraints = "$rd = $dst" in { +-def CSRWR : FmtCSR<0x04000020, (outs GPR:$dst), +- (ins GPR:$rd, uimm14:$csr_num), "$rd, $csr_num">; +-def CSRXCHG : FmtCSRXCHG<0x04000000, (outs GPR:$dst), +- (ins GPR:$rd, GPR:$rj, uimm14:$csr_num), +- "$rd, $rj, $csr_num">; +-} // hasSideEffects = 1, Constraints = "$rd = $dst" +- +-// IOCSR Access Instructions +-def IOCSRRD_B : IOCSRRD<0x06480000>; +-def IOCSRRD_H : IOCSRRD<0x06480400>; +-def IOCSRRD_W : IOCSRRD<0x06480800>; +-def IOCSRWR_B : IOCSRWR<0x06481000>; +-def IOCSRWR_H : IOCSRWR<0x06481400>; +-def IOCSRWR_W : IOCSRWR<0x06481800>; +-let Predicates = [IsLA64] in { +-def IOCSRRD_D : IOCSRRD<0x06480c00>; +-def IOCSRWR_D : IOCSRWR<0x06481c00>; +-} // Predicates = [IsLA64] +- +-// TLB Maintenance Instructions +-let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in { +-def TLBSRCH : FmtI32<0x06482800>; +-def TLBRD : FmtI32<0x06482c00>; +-def TLBWR : FmtI32<0x06483000>; +-def TLBFILL : FmtI32<0x06483400>; +-def TLBCLR : FmtI32<0x06482000>; +-def TLBFLUSH : FmtI32<0x06482400>; +-def INVTLB : FmtINVTLB<(outs), (ins GPR:$rk, GPR:$rj, uimm5:$op), +- "$op, $rj, $rk">; +-} // hasSideEffects = 1, mayLoad = 0, mayStore = 0 +- +-// Software Page Walking Instructions +-def LDDIR : Fmt2RI8<0x06400000, (outs GPR:$rd), +- (ins GPR:$rj, uimm8:$imm8), "$rd, $rj, $imm8">; +-def LDPTE : FmtLDPTE<(outs), (ins GPR:$rj, uimm8:$seq), "$rj, $seq">; +- +- +-// Other Miscellaneous Instructions +-let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in +-def ERTN : FmtI32<0x06483800>; +-def DBCL : MISC_I15<0x002a8000>; +-def IDLE : MISC_I15<0x06488000>; ++class PseudoTailBase : LoongArchPseudo<(outs), (ins opnd:$offset26), ++ []> { ++ let isTerminator = 1; ++ let isBarrier = 1; ++ let isReturn = 1; ++ let isCodeGenOnly = 1; ++} ++def PseudoTailReturn : PseudoTailBase; + +-//===----------------------------------------------------------------------===// +-// Privilege Intrinsics +-//===----------------------------------------------------------------------===// + +-def : Pat<(loongarch_csrrd uimm14:$imm14), (CSRRD uimm14:$imm14)>; +-def : Pat<(loongarch_csrwr GPR:$rd, uimm14:$imm14), +- (CSRWR GPR:$rd, uimm14:$imm14)>; +-def : Pat<(loongarch_csrxchg GPR:$rd, GPR:$rj, uimm14:$imm14), +- (CSRXCHG GPR:$rd, GPR:$rj, uimm14:$imm14)>; +- +-def : Pat<(loongarch_iocsrrd_b GPR:$rj), (IOCSRRD_B GPR:$rj)>; +-def : Pat<(loongarch_iocsrrd_h GPR:$rj), (IOCSRRD_H GPR:$rj)>; +-def : Pat<(loongarch_iocsrrd_w GPR:$rj), (IOCSRRD_W GPR:$rj)>; +- +-def : Pat<(loongarch_iocsrwr_b GPR:$rd, GPR:$rj), (IOCSRWR_B GPR:$rd, GPR:$rj)>; +-def : Pat<(loongarch_iocsrwr_h GPR:$rd, GPR:$rj), (IOCSRWR_H GPR:$rd, GPR:$rj)>; +-def : Pat<(loongarch_iocsrwr_w GPR:$rd, GPR:$rj), (IOCSRWR_W GPR:$rd, GPR:$rj)>; +- +-def : Pat<(loongarch_cpucfg GPR:$rj), (CPUCFG GPR:$rj)>; +- +-let Predicates = [IsLA64] in { +-def : Pat<(loongarch_iocsrrd_d GPR:$rj), (IOCSRRD_D GPR:$rj)>; +-def : Pat<(loongarch_iocsrwr_d GPR:$rd, GPR:$rj), (IOCSRWR_D GPR:$rd, GPR:$rj)>; +-def : Pat<(int_loongarch_asrtle_d GPR:$rj, GPR:$rk), +- (ASRTLE_D GPR:$rj, GPR:$rk)>; +-def : Pat<(int_loongarch_asrtgt_d GPR:$rj, GPR:$rk), +- (ASRTGT_D GPR:$rj, GPR:$rk)>; +-def : Pat<(int_loongarch_lddir_d GPR:$rj, timm:$imm8), +- (LDDIR GPR:$rj, timm:$imm8)>; +-def : Pat<(int_loongarch_ldpte_d GPR:$rj, timm:$imm8), +- (LDPTE GPR:$rj, timm:$imm8)>; +-} // Predicates = [IsLA64] ++def : LoongArchPat<(LoongArchTailCall tglobaladdr:$dst), ++ (PseudoTailCall tglobaladdr:$dst)>; + +-//===----------------------------------------------------------------------===// +-// LSX Instructions +-//===----------------------------------------------------------------------===// +-include "LoongArchLSXInstrInfo.td" ++def : LoongArchPat<(LoongArchTailCall texternalsym:$dst), ++ (PseudoTailCall texternalsym:$dst)>; ++ ++let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, isIndirectBranch = 1, Uses = [SP] in ++def PseudoTAILIndirect : LoongArchPseudo<(outs), (ins GPRTC64Opnd:$rj), [(LoongArchTailCall GPRTC64Opnd:$rj)]>, ++ PseudoInstExpansion<(JIRL ZERO_64, GPR64Opnd:$rj, 0)>; ++ ++ ++def : LoongArchPat<(LoongArchJmpLink tglobaladdr:$dst), ++ (PseudoCall tglobaladdr:$dst)>; ++ ++def : LoongArchPat<(LoongArchJmpLink (i32 texternalsym:$dst)), ++ (PseudoCall texternalsym:$dst)>; ++def : LoongArchPat<(LoongArchJmpLink (i64 texternalsym:$dst)), ++ (PseudoCall texternalsym:$dst)>; ++ ++def : LoongArchPat<(LoongArchJmpLink (i64 texternalsym:$dst)), ++ (PseudoCall texternalsym:$dst)>; ++ ++def BL : JumpLink<"bl", calltarget>, FJ<0b010101>; ++ ++class IsAsCheapAsAMove { ++ bit isAsCheapAsAMove = 1; ++} ++class LoadUpper: ++ InstForm<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"), ++ [], FrmI, opstr>, IsAsCheapAsAMove { ++ let hasSideEffects = 0; ++ let isReMaterializable = 1; ++ let mayLoad = 1; ++} ++ ++let isCodeGenOnly = 1 in { ++def LAPCREL : LoadUpper<"la.pcrel", GPR64Opnd, uimm16_64_relaxed>, LUI_FM, GPR_64; ++} ++ ++def NOP : LoongArchPseudo<(outs), (ins), []>, ++ PseudoInstExpansion<(ANDI ZERO_64, ZERO_64, 0)>; ++ ++def : LoongArchInstAlias<"nop", (ANDI ZERO_64, ZERO_64, 0), 1>; ++def : LoongArchInstAlias<"jr $rd", (JIRL ZERO_64, GPR64Opnd:$rd, 0), 1>; ++def : LoongArchInstAlias<"move $dst, $src", ++ (OR GPR64Opnd:$dst, GPR64Opnd:$src, ZERO_64), 1>, GPR_64; ++ ++def UImm12RelaxedAsmOperandClass ++: UImmAsmOperandClass<12, [ConstantUImm20AsmOperandClass]> { ++ let Name = "UImm12_Relaxed"; ++ let PredicateMethod = "isAnyImm<12>"; ++ let DiagnosticType = "UImm12_Relaxed"; ++} ++ ++def SImm12RelaxedAsmOperandClass ++: SImmAsmOperandClass<12, [UImm12RelaxedAsmOperandClass]> { ++ let Name = "SImm12_Relaxed"; ++ let PredicateMethod = "isAnyImm<12>"; ++ let DiagnosticType = "SImm12_Relaxed"; ++} ++ ++def simm12_relaxed : Operand { ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<12>"; ++ let ParserMatchClass = !cast("SImm12RelaxedAsmOperandClass"); ++} ++ ++def : LoongArchPat<(i64 (anyext GPR32:$src)), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$src, sub_32)>,GPR_64; ++ ++let usesCustomInserter = 1 in { ++ def ATOMIC_LOAD_ADD_I64 : Atomic2Ops; ++ def ATOMIC_LOAD_SUB_I64 : Atomic2Ops; ++ def ATOMIC_LOAD_AND_I64 : Atomic2Ops; ++ def ATOMIC_LOAD_OR_I64 : Atomic2Ops; ++ def ATOMIC_LOAD_XOR_I64 : Atomic2Ops; ++ def ATOMIC_LOAD_NAND_I64 : Atomic2Ops; ++ def ATOMIC_SWAP_I64 : Atomic2Ops; ++ ++ defm I64_ : AtomicCmpSwapInstrs<"64", GPR64>; ++ ++ def ATOMIC_LOAD_MAX_I64 : Atomic2Ops; ++ def ATOMIC_LOAD_MIN_I64 : Atomic2Ops; ++ def ATOMIC_LOAD_UMAX_I64 : Atomic2Ops; ++ def ATOMIC_LOAD_UMIN_I64 : Atomic2Ops; ++} ++ ++def ATOMIC_LOAD_ADD_I64_POSTRA : Atomic2OpsPostRA; ++def ATOMIC_LOAD_SUB_I64_POSTRA : Atomic2OpsPostRA; ++def ATOMIC_LOAD_AND_I64_POSTRA : Atomic2OpsPostRA; ++def ATOMIC_LOAD_OR_I64_POSTRA : Atomic2OpsPostRA; ++def ATOMIC_LOAD_XOR_I64_POSTRA : Atomic2OpsPostRA; ++def ATOMIC_LOAD_NAND_I64_POSTRA : Atomic2OpsPostRA; ++ ++def ATOMIC_SWAP_I64_POSTRA : Atomic2OpsPostRA; ++ ++def ATOMIC_CMP_SWAP_I64_POSTRA : AtomicCmpSwapPostRA; ++ ++def ATOMIC_LOAD_MAX_I64_POSTRA : Atomic2OpsPostRA; ++ ++def ATOMIC_LOAD_MIN_I64_POSTRA : Atomic2OpsPostRA; ++ ++def ATOMIC_LOAD_UMAX_I64_POSTRA : Atomic2OpsPostRA; ++ ++def ATOMIC_LOAD_UMIN_I64_POSTRA : Atomic2OpsPostRA; ++ ++def : LoongArchPat<(atomic_load_8 addr:$a), (LD_B addr:$a)>, GPR_64; ++def : LoongArchPat<(atomic_load_16 addr:$a), (LD_H addr:$a)>, GPR_64; ++def : LoongArchPat<(atomic_load_32 addrimm14lsl2:$a), (LDPTR_W addrimm14lsl2:$a)>, GPR_64; ++def : LoongArchPat<(atomic_load_32 addr:$a), (LD_W addr:$a)>, GPR_64; ++def : LoongArchPat<(atomic_load_64 addrimm14lsl2:$a), (LDPTR_D addrimm14lsl2:$a)>, GPR_64; ++def : LoongArchPat<(atomic_load_64 addr:$a), (LD_D addr:$a)>, GPR_64; ++ ++def : LoongArchPat<(atomic_store_8 GPR64:$v, addr:$a), ++ (ST_B GPR64:$v, addr:$a)>, GPR_64; ++def : LoongArchPat<(atomic_store_16 GPR64:$v, addr:$a), ++ (ST_H GPR64:$v, addr:$a)>, GPR_64; ++def : LoongArchPat<(atomic_store_32 GPR64:$v, addrimm14lsl2:$a), ++ (STPTR_W GPR64:$v, addrimm14lsl2:$a)>, GPR_64; ++def : LoongArchPat<(atomic_store_32 GPR64:$v, addr:$a), ++ (ST_W GPR64:$v, addr:$a)>, GPR_64; ++def : LoongArchPat<(atomic_store_64 GPR64:$v, addrimm14lsl2:$a), ++ (STPTR_D GPR64:$v, addrimm14lsl2:$a)>, GPR_64; ++def : LoongArchPat<(atomic_store_64 GPR64:$v, addr:$a), ++ (ST_D GPR64:$v, addr:$a)>, GPR_64; ++ ++def : LoongArchPat<(bswap GPR64:$rt), (REVH_D (REVB_4H GPR64:$rt))>; ++ ++def immZExt5 : ImmLeaf; ++ ++def immZExtRange2To64 : PatLeaf<(imm), [{ ++ return isUInt<7>(N->getZExtValue()) && (N->getZExtValue() >= 2) && ++ (N->getZExtValue() <= 64); ++}]>; ++ ++// bstrins and bstrpick ++class InsBase ++ : InstForm<(outs RO:$rd), (ins RO:$rj, ImmOpnd:$msbd, ImmOpnd:$lsbd, RO:$src), ++ !strconcat(opstr, "\t$rd, $rj, $msbd, $lsbd"), ++ [(set RO:$rd, (OpNode RO:$rj, ImmOpnd:$msbd, ImmOpnd:$lsbd, RO:$src))], ++ FrmR, opstr> { ++ let Constraints = "$src = $rd"; ++ } ++ ++class InsBase_32 ++ : InstForm<(outs RO:$rd), (ins RO:$rj, ImmOpnd:$msbw, ImmOpnd:$lsbw, RO:$src), ++ !strconcat(opstr, "\t$rd, $rj, $msbw, $lsbw"), ++ [(set RO:$rd, (OpNode RO:$rj, ImmOpnd:$msbw, ImmOpnd:$lsbw, RO:$src))], ++ FrmR, opstr> { ++ let Constraints = "$src = $rd"; ++} ++ ++class PickBase ++ : InstForm<(outs RO:$rd), (ins RO:$rj, ImmOpnd:$msbd, ImmOpnd:$lsbd), ++ !strconcat(opstr, "\t$rd, $rj, $msbd, $lsbd"), ++ [(set RO:$rd, (Op RO:$rj, ImmOpnd:$msbd, ImmOpnd:$lsbd))], ++ FrmR, opstr>; ++ ++class PickBase_32 ++ : InstForm<(outs RO:$rd), (ins RO:$rj, ImmOpnd:$msbw, ImmOpnd:$lsbw), ++ !strconcat(opstr, "\t$rd, $rj, $msbw, $lsbw"), ++ [(set RO:$rd, (Op RO:$rj, ImmOpnd:$msbw, ImmOpnd:$lsbw))], ++ FrmR, opstr>; ++ ++ def BSTRINS_D : InsBase<"bstrins.d", GPR64Opnd, uimm6, LoongArchBstrins>, ++ INSERT_BIT64<0>; ++ def BSTRPICK_D : PickBase<"bstrpick.d", GPR64Opnd, uimm6, LoongArchBstrpick>, ++ INSERT_BIT64<1>; ++ ++let isCodeGenOnly = 1 in { ++ def ZEXT64_32 : InstForm<(outs GPR64Opnd:$rd), ++ (ins GPR32Opnd:$rj, uimm6:$msbd, ++ uimm6:$lsbd), ++ "bstrpick.d $rd, $rj, $msbd, $lsbd", [], FrmR, "bstrpick.d">, ++ INSERT_BIT64<1>; ++} ++ ++//32-to-64-bit extension ++def : LoongArchPat<(i64 (zext GPR32:$src)), (ZEXT64_32 GPR32:$src, 31, 0)>; ++def : LoongArchPat<(i64 (extloadi1 addr:$src)), (LD_B addr:$src)>, ++ GPR_64; ++def : LoongArchPat<(i64 (extloadi8 addr:$src)), (LD_B addr:$src)>, ++ GPR_64; ++def : LoongArchPat<(i64 (extloadi16 addr:$src)), (LD_H addr:$src)>, ++ GPR_64; ++def : LoongArchPat<(i64 (extloadi32 addr:$src)), (LD_W addr:$src)>, ++ GPR_64; ++ ++class LDX_FT_LA : ++ InstForm<(outs DRC:$rd), (ins PtrRC:$rj, PtrRC:$rk), ++ !strconcat(opstr, "\t$rd, $rj, $rk"), ++ [(set DRC:$rd, (OpNode (add iPTR:$rj, iPTR:$rk)))], ++ FrmR, opstr> { ++ let AddedComplexity = 20; ++ let canFoldAsLoad = 1; ++ string BaseOpcode = opstr; ++ let mayLoad = 1; ++} ++ ++class STX_FT_LA : ++ InstForm<(outs), (ins DRC:$rd, PtrRC:$rj, PtrRC:$rk), ++ !strconcat(opstr, "\t$rd, $rj, $rk"), ++ [(OpNode DRC:$rd, (add iPTR:$rj, iPTR:$rk))], ++ FrmI, opstr> { ++ string BaseOpcode = opstr; ++ let mayStore = 1; ++ let AddedComplexity = 20; ++} ++ ++ ++def LDX_B : LDX_FT_LA<"ldx.b", GPR64Opnd, sextloadi8>, ++ R3MI<0b00000000>; ++def LDX_H : LDX_FT_LA<"ldx.h", GPR64Opnd, sextloadi16>, ++ R3MI<0b00001000>; ++def LDX_W : LDX_FT_LA<"ldx.w", GPR64Opnd, sextloadi32>, ++ R3MI<0b00010000>; ++def LDX_D : LDX_FT_LA<"ldx.d", GPR64Opnd, load>, ++ R3MI<0b00011000>; ++def STX_B : STX_FT_LA<"stx.b", GPR64Opnd, truncstorei8>, ++ R3MI<0b00100000>; ++def STX_H : STX_FT_LA<"stx.h", GPR64Opnd, truncstorei16>, ++ R3MI<0b00101000>; ++def STX_W : STX_FT_LA<"stx.w", GPR64Opnd, truncstorei32>, ++ R3MI<0b00110000>; ++def STX_D : STX_FT_LA<"stx.d", GPR64Opnd, store>, ++ R3MI<0b00111000>; ++def LDX_BU : LDX_FT_LA<"ldx.bu", GPR64Opnd, extloadi8>, ++ R3MI<0b01000000>; ++def LDX_HU : LDX_FT_LA<"ldx.hu", GPR64Opnd, extloadi16>, ++ R3MI<0b01001000>; ++def LDX_WU : LDX_FT_LA<"ldx.wu", GPR64Opnd, zextloadi32>, ++ R3MI<0b01010000>; ++ ++//def : LoongArchPat<(bswap GPR64:$rj), (REVH_D (REVB_4H GPR64:$rj))>; ++//def : LoongArchPat<(bswap GPR64:$rj), (ROTRI_D (REVB_2W GPR64:$rj), 32)>; ++def : LoongArchPat<(bswap GPR64:$rj), (REVB_D GPR64:$rj)>; ++ ++let isCodeGenOnly = 1 in { ++ def SLLI_D_64_32 : Shift_Imm64<"", GPR64Opnd>, R2_IMM6<0b00>, GPR_64 { ++ let imm6 = 0; ++ let AsmString = "slli.d\t$rd, $rj, 32"; ++ let InOperandList = (ins GPR32:$rj); ++ let OutOperandList = (outs GPR64:$rd); ++ } ++ ++ let imm5 = 0, ++ AsmString = "slli.w\t$rd, $rj, 0", ++ OutOperandList = (outs GPR64:$rd) in { ++ let InOperandList = (ins GPR32:$rj) in ++ def SLLI_W_64_32 : Shift_Imm32<"", GPR32Opnd>, R2_IMM5<0b00>, GPR_64; ++ let InOperandList = (ins GPR64:$rj) in ++ def SLLI_W_64_64 : Shift_Imm32<"", GPR32Opnd>, R2_IMM5<0b00>, GPR_64; ++ } ++ ++ let AsmString = "sltui\t$rd, $rj, $imm12", ++ OutOperandList = (outs GPR64:$rd) in { ++ let InOperandList = (ins GPR64:$rj, simm12:$imm12) in ++ def SLTUI_64 : SetCC_I<"", GPR64Opnd, simm12>, R2_IMM12<0b001>, GPR_64; ++ } ++} ++ ++// 32-to-64-bit extension ++//def : LoongArchPat<(i64 (zext GPR32:$src)), (SRLI_D (SLLI_D_64_32 GPR32:$src), 32)>, GPR_64; ++def : LoongArchPat<(i64 (sext GPR32:$src)), (SLLI_W_64_32 GPR32:$src)>, GPR_64; ++def : LoongArchPat<(i64 (sext_inreg GPR64:$src, i32)), (SLLI_W_64_64 GPR64:$src)>, GPR_64; ++ ++let Uses = [A0, A1], isTerminator = 1, isReturn = 1, isBarrier = 1, isCTI = 1 in { ++ def LoongArcheh_return32 : LoongArchPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst), ++ [(LoongArchehret GPR32:$spoff, GPR32:$dst)]>; ++ def LoongArcheh_return64 : LoongArchPseudo<(outs), (ins GPR64:$spoff,GPR64:$dst), ++ [(LoongArchehret GPR64:$spoff, GPR64:$dst)]>; ++} ++ ++def : LoongArchPat<(select i32:$cond, i64:$t, i64:$f), ++ (OR (MASKEQZ i64:$t, (SLLI_W_64_32 i32:$cond)), ++ (MASKNEZ i64:$f, (SLLI_W_64_32 i32:$cond)))>; ++// setcc patterns ++multiclass SeteqPats { ++ def : LoongArchPat<(seteq RC:$lhs, 0), ++ (SLTiuOp RC:$lhs, 1)>; ++ def : LoongArchPat<(setne RC:$lhs, 0), ++ (SLTuOp ZEROReg, RC:$lhs)>; ++ def : LoongArchPat<(seteq RC:$lhs, RC:$rhs), ++ (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>; ++ def : LoongArchPat<(setne RC:$lhs, RC:$rhs), ++ (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>; ++} ++ ++multiclass SetlePats { ++ def : LoongArchPat<(setle RC:$lhs, RC:$rhs), ++ (XORiOp (SLTOp RC:$rhs, RC:$lhs), 1)>; ++ def : LoongArchPat<(setule RC:$lhs, RC:$rhs), ++ (XORiOp (SLTuOp RC:$rhs, RC:$lhs), 1)>; ++} ++ ++multiclass SetgtPats { ++ def : LoongArchPat<(setgt RC:$lhs, RC:$rhs), ++ (SLTOp RC:$rhs, RC:$lhs)>; ++ def : LoongArchPat<(setugt RC:$lhs, RC:$rhs), ++ (SLTuOp RC:$rhs, RC:$lhs)>; ++} ++ ++multiclass SetgePats { ++ def : LoongArchPat<(setge RC:$lhs, RC:$rhs), ++ (XORiOp (SLTOp RC:$lhs, RC:$rhs), 1)>; ++ def : LoongArchPat<(setuge RC:$lhs, RC:$rhs), ++ (XORiOp (SLTuOp RC:$lhs, RC:$rhs), 1)>; ++} ++ ++multiclass SetgeImmPats { ++ def : LoongArchPat<(setge RC:$lhs, immSExt12:$rhs), ++ (XORiOp (SLTiOp RC:$lhs, immSExt12:$rhs), 1)>; ++ def : LoongArchPat<(setuge RC:$lhs, immSExt12:$rhs), ++ (XORiOp (SLTiuOp RC:$lhs, immSExt12:$rhs), 1)>; ++} ++ ++class LoadRegImmPat : ++ LoongArchPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>; ++ ++class StoreRegImmPat : ++ LoongArchPat<(Node ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>; ++ ++class LoadRegImm14Lsl2Pat : ++ LoongArchPat<(ValTy (Node addrimm14lsl2:$a)), (LoadInst addrimm14lsl2:$a)>; ++ ++class StoreRegImm14Lsl2Pat : ++ LoongArchPat<(Node ValTy:$v, addrimm14lsl2:$a), (StoreInst ValTy:$v, addrimm14lsl2:$a)>; ++ ++// Patterns for loads/stores with a reg+imm operand. ++// let AddedComplexity = 40 so that these instructions are selected instead of ++// LDX/STX which needs one more register and an ANDI instruction. ++let AddedComplexity = 40 in { ++ def : LoadRegImmPat; ++ def : LoadRegImmPat; ++ def : LoadRegImmPat; ++ def : LoadRegImmPat; ++ def : LoadRegImmPat; ++ def : LoadRegImmPat; ++ def : LoadRegImmPat; ++ def : StoreRegImmPat; ++ def : StoreRegImmPat; ++ def : StoreRegImmPat; ++ def : StoreRegImmPat; ++ ++ def : LoadRegImm14Lsl2Pat; ++ def : LoadRegImm14Lsl2Pat; ++ def : StoreRegImm14Lsl2Pat; ++ def : StoreRegImm14Lsl2Pat; ++} + + //===----------------------------------------------------------------------===// +-// LASX Instructions ++// Base Extension Support + //===----------------------------------------------------------------------===// ++ ++include "LoongArch32InstrInfo.td" ++include "LoongArchInstrInfoF.td" ++include "LoongArchLSXInstrFormats.td" ++include "LoongArchLSXInstrInfo.td" ++include "LoongArchLASXInstrFormats.td" + include "LoongArchLASXInstrInfo.td" + +-//===----------------------------------------------------------------------===// +-// LVZ Instructions +-//===----------------------------------------------------------------------===// +-include "LoongArchLVZInstrInfo.td" ++defm : SeteqPats, GPR_64; ++defm : SetlePats, GPR_64; ++defm : SetgtPats, GPR_64; ++defm : SetgePats, GPR_64; ++defm : SetgeImmPats, GPR_64; ++ ++/// ++/// for relocation ++/// ++let isCodeGenOnly = 1 in { ++def PCADDU12I_ri : SI20<"pcaddu12i", GPR64Opnd, simm20>, R1_SI20<0b0001110>; ++def PCADDU12I_ri_large : SI20_2R<"pcaddu12i", GPR64Opnd, simm20>, R1_SI20<0b0001110>; ++def PCADDU12I_rii : RELOC_rii<"pcaddu12i", GPR64Opnd, simm20>, R1_SI20<0b0001110>; ++def ORI_rri : Int_Reg2_Imm12<"ori", GPR64Opnd, uimm12, or>, R2_IMM12<0b110>; ++def ORI_rrii : RELOC_rrii<"ori", GPR64Opnd, uimm12>, R2_IMM12<0b110>; ++def LU12I_W_ri : SI20<"lu12i.w", GPR64Opnd, simm20>, R1_SI20<0b0001010>; ++def LU32I_D_ri : SI20<"lu32i.d", GPR64Opnd, simm20>, R1_SI20<0b0001011>; ++def LU32I_D_rii : RELOC_rii<"lu32i.d", GPR64Opnd, simm20>, R1_SI20<0b0001011>; ++def LU52I_D_rri : Int_Reg2_Imm12<"lu52i.d", GPR64Opnd, simm12>, R2_IMM12<0b100>; ++def LU52I_D_rrii : RELOC_rrii<"lu52i.d", GPR64Opnd, simm12>, R2_IMM12<0b100>; ++def ADDI_D_rri : Int_Reg2_Imm12<"addi.d", GPR64Opnd, simm12, add>, R2_IMM12<0b011>; ++def ADDI_D_rrii : RELOC_rrii<"addi.d", GPR64Opnd, simm12>, R2_IMM12<0b011>; ++def LD_D_rri : Ld<"ld.d", GPR64Opnd, mem_simmptr, load>, LOAD_STORE<0b0011>; ++def LD_D_rrii : RELOC_rrii<"ld.d", GPR64Opnd, simm12>, LOAD_STORE_RRI<0b0011>; ++def ADD_D_rrr : Int_Reg3<"add.d", GPR64Opnd, add>, R3I<0b0100001>; ++def LDX_D_rrr : LDX_FT_LA<"ldx.d", GPR64Opnd, load>, ++ R3MI<0b00011000>; ++} + + //===----------------------------------------------------------------------===// +-// LBT Instructions ++// Assembler Pseudo Instructions + //===----------------------------------------------------------------------===// +-include "LoongArchLBTInstrInfo.td" ++def LoadImm32 : LoongArchAsmPseudoInst<(outs GPR32Opnd:$rd), ++ (ins uimm32_coerced:$imm32), ++ "li.w\t$rd, $imm32">; ++def LoadImm64 : LoongArchAsmPseudoInst<(outs GPR64Opnd:$rd), ++ (ins imm64:$imm64), ++ "li.d\t$rd, $imm64">; ++// load address ++def LoadAddrLocal : LoongArchAsmPseudoInst<(outs GPR64Opnd:$rd), ++ (ins imm64:$imm64), ++ "la.local\t$rd, $imm64">; ++def : InstAlias<"la.pcrel $rd, $imm", ++ (LoadAddrLocal GPR64Opnd:$rd, imm64:$imm), 1>; ++def LoadAddrGlobal : LoongArchAsmPseudoInst<(outs GPR64Opnd:$rd), ++ (ins imm64:$imm64), ++ "la.global\t$rd, $imm64">; ++def LoadAddrGlobal_Alias : LoongArchAsmPseudoInst<(outs GPR64Opnd:$rd), ++ (ins imm64:$imm64), ++ "la\t$rd, $imm64">; ++def : InstAlias<"la.got $rd, $imm", ++ (LoadAddrGlobal GPR64Opnd:$rd, imm64:$imm), 1>; ++ ++def LoadAddrTLS_LE : LoongArchAsmPseudoInst<(outs GPR64Opnd:$rd), ++ (ins imm64:$imm64), ++ "la.tls.le\t$rd, $imm64">; ++def LoadAddrTLS_IE : LoongArchAsmPseudoInst<(outs GPR64Opnd:$rd), ++ (ins imm64:$imm64), ++ "la.tls.ie\t$rd, $imm64">; ++def LoadAddrTLS_GD : LoongArchAsmPseudoInst<(outs GPR64Opnd:$rd), ++ (ins imm64:$imm64), ++ "la.tls.gd\t$rd, $imm64">; ++def LoadAddrTLS_LD : LoongArchAsmPseudoInst<(outs GPR64Opnd:$rd), ++ (ins imm64:$imm64), ++ "la.tls.ld\t$rd, $imm64">; ++ ++// load address with a temp reg ++def LoadAddrLocalRR : LoongArchAsmPseudoInst<(outs GPR64Opnd:$rd), ++ (ins GPR64Opnd:$rt, imm64:$imm64), ++ "la.local\t$rd, $rt, $imm64">; ++def LoadAddrGlobalRR : LoongArchAsmPseudoInst<(outs GPR64Opnd:$rd), ++ (ins GPR64Opnd:$rt, imm64:$imm64), ++ "la.global\t$rd, $rt, $imm64">; ++def LoadAddrTLS_IE_RR : LoongArchAsmPseudoInst<(outs GPR64Opnd:$rd), ++ (ins GPR64Opnd:$rt, imm64:$imm64), ++ "la.tls.ie\t$rd, $rt, $imm64">; ++def LoadAddrTLS_GD_RR : LoongArchAsmPseudoInst<(outs GPR64Opnd:$rd), ++ (ins GPR64Opnd:$rt, imm64:$imm64), ++ "la.tls.gd\t$rd, $rt, $imm64">; ++def LoadAddrTLS_LD_RR : LoongArchAsmPseudoInst<(outs GPR64Opnd:$rd), ++ (ins GPR64Opnd:$rt, imm64:$imm64), ++ "la.tls.ld\t$rd, $rt, $imm64">; ++ ++// trap when div zero ++def PseudoTEQ : LoongArchPseudo<(outs), (ins GPR64Opnd:$rt), []>; ++ ++ ++def : LoongArchPat<(i64 (sext (i32 (add GPR32:$src, immSExt12:$imm12)))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (ADDI_W GPR32:$src, immSExt12:$imm12), sub_32)>; ++ ++def : LoongArchPat<(i64 (sext (i32 (add GPR32:$src, GPR32:$src2)))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (ADD_W GPR32:$src, GPR32:$src2), sub_32)>; ++ ++def : LoongArchPat<(i64 (sext (i32 (sub GPR32:$src, GPR32:$src2)))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (SUB_W GPR32:$src, GPR32:$src2), sub_32)>; ++ ++def : LoongArchPat<(i64 (sext (i32 (mul GPR32:$src, GPR32:$src2)))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (MUL_W GPR32:$src, GPR32:$src2), sub_32)>; ++ ++def : LoongArchPat<(i64 (sext (i32 (shl GPR32:$src, immZExt5:$imm5)))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (SLLI_W GPR32:$src, immZExt5:$imm5), sub_32)>; ++ ++def : LoongArchPat<(i64 (sext (i32 (shl GPR32:$src, GPR32:$src2)))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (SLL_W GPR32:$src, GPR32:$src2), sub_32)>; ++ ++def : LoongArchPat<(i64 (sext (i32 (srl GPR32:$src, immZExt5:$imm5)))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (SRLI_W GPR32:$src, immZExt5:$imm5), sub_32)>; ++ ++def : LoongArchPat<(i64 (sext (i32 (srl GPR32:$src, GPR32:$src2)))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (SRL_W GPR32:$src, GPR32:$src2), sub_32)>; ++ ++def : LoongArchPat<(i64 (sext (i32 (sra GPR32:$src, immZExt5:$imm5)))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (SRAI_W GPR32:$src, immZExt5:$imm5), sub_32)>; ++ ++def : LoongArchPat<(i64 (sext (i32 (sra GPR32:$src, GPR32:$src2)))), ++ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), ++ (SRA_W GPR32:$src, GPR32:$src2), sub_32)>; ++ ++ ++def : LoongArchPat<(i64 (xor GPR64:$rj, (i64 -1))), ++ (NOR ZERO_64, GPR64:$rj)>; ++ ++def : LoongArchPat<(and GPR64:$rj, (i64 (xor GPR64:$rk, (i64 -1)))), ++ (ANDN GPR64:$rj, GPR64:$rk)>; ++ ++def : LoongArchPat<(i64 (or GPR64:$rj, (xor GPR64:$rk, (i64 -1)))), ++ (ORN GPR64:$rj, GPR64:$rk)>; ++ ++def : LoongArchPat<(i64 (zext (i32 (seteq GPR64:$rj, (i64 0))))), ++ (SLTUI_64 GPR64:$rj, (i64 1))>; ++ ++ ++def : LoongArchPat<(i64 (zext (i32 (srl GPR32:$src, immZExt5:$imm5)))), ++ (BSTRPICK_D (INSERT_SUBREG ++ (i64 (IMPLICIT_DEF)), GPR32:$src, sub_32), ++ (i32 31), immZExt5:$imm5)>; +diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfoF.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfoF.td +new file mode 100644 +index 000000000..473a8a0fa +--- /dev/null ++++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfoF.td +@@ -0,0 +1,642 @@ ++//===- LoongArchInstrInfoF.td - Target Description for LoongArch Target -*- tablegen -*-=// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++// ++// This file contains the LoongArch implementation of the TargetInstrInfo class. ++// ++//===----------------------------------------------------------------------===// ++// FP immediate patterns. ++def fpimm0 : PatLeaf<(fpimm), [{ ++ return N->isExactlyValue(+0.0); ++}]>; ++ ++def fpimm0neg : PatLeaf<(fpimm), [{ ++ return N->isExactlyValue(-0.0); ++}]>; ++ ++def fpimm1 : PatLeaf<(fpimm), [{ ++ return N->isExactlyValue(+1.0); ++}]>; ++ ++def IsNotSoftFloat : Predicate<"!Subtarget->useSoftFloat()">, ++ AssemblerPredicate<(all_of FeatureSoftFloat)>; ++ ++class HARDFLOAT { list HardFloatPredicate = [IsNotSoftFloat]; } ++ ++def SDT_LoongArchTruncIntFP : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>; ++ ++def LoongArchTruncIntFP : SDNode<"LoongArchISD::TruncIntFP", SDT_LoongArchTruncIntFP>; ++ ++def SDT_LoongArchFPBrcond : SDTypeProfile<0, 3, [SDTCisInt<0>, ++ SDTCisVT<1, i32>, ++ SDTCisVT<2, OtherVT>]>; ++ ++def LoongArchFPBrcond : SDNode<"LoongArchISD::FPBrcond", SDT_LoongArchFPBrcond, ++ [SDNPHasChain, SDNPOptInGlue]>; ++ ++def SDT_LoongArchCMovFP : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisVT<2, i32>, ++ SDTCisSameAs<1, 3>]>; ++ ++def LoongArchCMovFP_T : SDNode<"LoongArchISD::CMovFP_T", SDT_LoongArchCMovFP, [SDNPInGlue]>; ++ ++def LoongArchCMovFP_F : SDNode<"LoongArchISD::CMovFP_F", SDT_LoongArchCMovFP, [SDNPInGlue]>; ++ ++def SDT_LoongArchFPCmp : SDTypeProfile<0, 3, [SDTCisSameAs<0, 1>, SDTCisFP<1>, ++ SDTCisVT<2, i32>]>; ++ ++def LoongArchFPCmp : SDNode<"LoongArchISD::FPCmp", SDT_LoongArchFPCmp, [SDNPOutGlue]>; ++ ++def SDT_LoongArchFSEL : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, ++ SDTCisVT<2, i32>, ++ SDTCisSameAs<1, 3>]>; ++ ++def LoongArchFSEL : SDNode<"LoongArchISD::FSEL", SDT_LoongArchFSEL, ++ [SDNPInGlue]>; ++ ++//===---------------------------------------------------------------------===/ ++//Instruction Class Templates ++//===---------------------------------------------------------------------===/ ++ ++class Float_MOVF ++ : InstForm<(outs RO:$rd), (ins RC:$fj), ++ !strconcat(opstr, "\t$rd, $fj"), ++ [(set RO:$rd, (OpNode RC:$fj))], ++ FrmFR, opstr>, HARDFLOAT { ++ let isMoveReg = 1; ++} ++ ++class Float_MOVT ++ : InstForm<(outs RO:$fd), (ins RC:$rj), ++ !strconcat(opstr, "\t$fd, $rj"), ++ [(set RO:$fd, (OpNode RC:$rj))], ++ FrmFR, opstr>, HARDFLOAT { ++ let isMoveReg = 1; ++} ++ ++class Float_CVT ++ : InstForm<(outs RO:$fd), (ins RS:$fj), ++ !strconcat(opstr, "\t$fd, $fj"), ++ [(set RO:$fd, (OpNode RS:$fj))], ++ FrmFR, opstr>, ++ HARDFLOAT { ++ let hasSideEffects = 0; ++} ++ ++/// float mov ++class Gpr_2_Fcsr ++ : InstForm<(outs FCSROpnd:$fcsr), (ins RO:$rj), ++ !strconcat(opstr, "\t$fcsr, $rj"), ++ [(set FCSROpnd:$fcsr, (OpNode RO:$rj))], ++ FrmR, opstr>; ++class Fcsr_2_Gpr ++ : InstForm<(outs RO:$rd), (ins FCSROpnd:$fcsr), ++ !strconcat(opstr, "\t$rd, $fcsr"), ++ [(set RO:$rd, (OpNode FCSROpnd:$fcsr))], ++ FrmR, opstr>; ++class Fgr_2_Fcfr ++ : InstForm<(outs FCFROpnd:$cd), (ins RO:$fj), ++ !strconcat(opstr, "\t$cd, $fj"), ++ [(set FCFROpnd:$cd, (OpNode RO:$fj))], ++ FrmR, opstr>; ++class Fcfr_2_Fgr ++ : InstForm<(outs RO:$fd), (ins FCFROpnd:$cj), ++ !strconcat(opstr, "\t$fd, $cj"), ++ [(set RO:$fd, (OpNode FCFROpnd:$cj))], ++ FrmR, opstr>; ++class Gpr_2_Fcfr ++ : InstForm<(outs FCFROpnd:$cd), (ins RO:$rj), ++ !strconcat(opstr, "\t$cd, $rj"), ++ [(set FCFROpnd:$cd, (OpNode RO:$rj))], ++ FrmR, opstr>; ++class Fcfr_2_Gpr ++ : InstForm<(outs RO:$rd), (ins FCFROpnd:$cj), ++ !strconcat(opstr, "\t$rd, $cj"), ++ [(set RO:$rd, (OpNode FCFROpnd:$cj))], ++ FrmR, opstr>; ++ ++class FLDX : ++ InstForm<(outs DRC:$fd), (ins PtrRC:$rj, PtrRC:$rk), ++ !strconcat(opstr, "\t$fd, $rj, $rk"), ++ [(set DRC:$fd, (OpNode (add iPTR:$rj, iPTR:$rk)))], ++ FrmR, opstr> { ++ let AddedComplexity = 20; ++} ++ ++class FSTX : ++ InstForm<(outs), (ins DRC:$fd, PtrRC:$rj, PtrRC:$rk), ++ !strconcat(opstr, "\t$fd, $rj, $rk"), ++ [(OpNode DRC:$fd, (add iPTR:$rj, iPTR:$rk))], ++ FrmR, opstr> { ++ let AddedComplexity = 20; ++} ++ ++/// f{maxa/mina}.{s/d} ++class Float_Reg3_Fmaxa ++ : InstForm<(outs RO:$fd), (ins RO:$fj, RO:$fk), ++ !strconcat(opstr, "\t$fd, $fj, $fk"), ++ [], FrmR, opstr>; ++/// frecip ++class Float_Reg2_Frecip ++ : InstForm<(outs RO:$fd), (ins RO:$fj), ++ !strconcat(opstr, "\t$fd, $fj"), ++ [(set RO:$fd, (OpNode fpimm1, RO:$fj))], ++ FrmR, opstr>; ++/// frsqrt ++class Float_Reg2_Frsqrt ++ : InstForm<(outs RO:$fd), (ins RO:$fj), ++ !strconcat(opstr, "\t$fd, $fj"), ++ [(set RO:$fd, (OpNode fpimm1, (fsqrt RO:$fj)))], ++ FrmR, opstr>; ++ ++class BceqzBr : ++ InstForm<(outs), (ins FCFROpnd:$cj, opnd:$offset), ++ !strconcat(opstr, "\t$cj, $offset"), ++ [(LoongArchFPBrcond Op, FCFROpnd:$cj, bb:$offset)], ++ FrmFI, opstr>, HARDFLOAT { ++ let isBranch = 1; ++ let isTerminator = 1; ++ let hasFCCRegOperand = 1; ++} ++ ++class FCMP_COND ++ : InstForm<(outs FCFROpnd:$cd), (ins RO:$fj, RO:$fk), ++ !strconcat("fcmp.", CondStr, ".", TypeStr, "\t$cd, $fj, $fk"), ++ [(set FCFROpnd:$cd, (OpNode RO:$fj, RO:$fk))], ++ FrmOther, ++ !strconcat("fcmp.", CondStr, ".", TypeStr)> { ++ bit isCTI = 1; // for what? from Mips32r6InstrInfo.td line 219 ++} ++ ++class FIELD_CMP_COND Val> { ++ bits<5> Value = Val; ++} ++def FIELD_CMP_COND_CAF : FIELD_CMP_COND<0x0>; ++def FIELD_CMP_COND_CUN : FIELD_CMP_COND<0x8>; ++def FIELD_CMP_COND_CEQ : FIELD_CMP_COND<0x4>; ++def FIELD_CMP_COND_CUEQ : FIELD_CMP_COND<0xC>; ++def FIELD_CMP_COND_CLT : FIELD_CMP_COND<0x2>; ++def FIELD_CMP_COND_CULT : FIELD_CMP_COND<0xA>; ++def FIELD_CMP_COND_CLE : FIELD_CMP_COND<0x6>; ++def FIELD_CMP_COND_CULE : FIELD_CMP_COND<0xE>; ++def FIELD_CMP_COND_CNE : FIELD_CMP_COND<0x10>; ++def FIELD_CMP_COND_COR : FIELD_CMP_COND<0x14>; ++def FIELD_CMP_COND_CUNE : FIELD_CMP_COND<0x18>; ++def FIELD_CMP_COND_SAF : FIELD_CMP_COND<0x1>; ++def FIELD_CMP_COND_SUN : FIELD_CMP_COND<0x9>; ++def FIELD_CMP_COND_SEQ : FIELD_CMP_COND<0x5>; ++def FIELD_CMP_COND_SUEQ : FIELD_CMP_COND<0xD>; ++def FIELD_CMP_COND_SLT : FIELD_CMP_COND<0x3>; ++def FIELD_CMP_COND_SULT : FIELD_CMP_COND<0xB>; ++def FIELD_CMP_COND_SLE : FIELD_CMP_COND<0x7>; ++def FIELD_CMP_COND_SULE : FIELD_CMP_COND<0xF>; ++def FIELD_CMP_COND_SNE : FIELD_CMP_COND<0x11>; ++def FIELD_CMP_COND_SOR : FIELD_CMP_COND<0x15>; ++def FIELD_CMP_COND_SUNE : FIELD_CMP_COND<0x19>; ++ ++multiclass FCMP_COND_M op, string TypeStr, ++ RegisterOperand RO> { ++ def FCMP_CAF_#NAME : FCMP_COND<"caf", TypeStr, RO>, ++ R2_COND; ++ def FCMP_CUN_#NAME : FCMP_COND<"cun", TypeStr, RO, setuo>, ++ R2_COND; ++ def FCMP_CEQ_#NAME : FCMP_COND<"ceq", TypeStr, RO, setoeq>, ++ R2_COND; ++ def FCMP_CUEQ_#NAME : FCMP_COND<"cueq", TypeStr, RO, setueq>, ++ R2_COND; ++ def FCMP_CLT_#NAME : FCMP_COND<"clt", TypeStr, RO, setolt>, ++ R2_COND; ++ def FCMP_CULT_#NAME : FCMP_COND<"cult", TypeStr, RO, setult>, ++ R2_COND; ++ def FCMP_CLE_#NAME : FCMP_COND<"cle", TypeStr, RO, setole>, ++ R2_COND; ++ def FCMP_CULE_#NAME : FCMP_COND<"cule", TypeStr, RO, setule>, ++ R2_COND; ++ def FCMP_CNE_#NAME : FCMP_COND<"cne", TypeStr, RO, setone>, ++ R2_COND; ++ def FCMP_COR_#NAME : FCMP_COND<"cor", TypeStr, RO, seto>, ++ R2_COND; ++ def FCMP_CUNE_#NAME : FCMP_COND<"cune", TypeStr, RO, setune>, ++ R2_COND; ++ ++ def FCMP_SAF_#NAME : FCMP_COND<"saf", TypeStr, RO>, ++ R2_COND; ++ def FCMP_SUN_#NAME : FCMP_COND<"sun", TypeStr, RO>, ++ R2_COND; ++ def FCMP_SEQ_#NAME : FCMP_COND<"seq", TypeStr, RO>, ++ R2_COND; ++ def FCMP_SUEQ_#NAME : FCMP_COND<"sueq", TypeStr, RO>, ++ R2_COND; ++ def FCMP_SLT_#NAME : FCMP_COND<"slt", TypeStr, RO>, ++ R2_COND; ++ def FCMP_SULT_#NAME : FCMP_COND<"sult", TypeStr, RO>, ++ R2_COND; ++ def FCMP_SLE_#NAME : FCMP_COND<"sle", TypeStr, RO>, ++ R2_COND; ++ def FCMP_SULE_#NAME : FCMP_COND<"sule", TypeStr, RO>, ++ R2_COND; ++ def FCMP_SNE_#NAME : FCMP_COND<"sne", TypeStr, RO>, ++ R2_COND; ++ def FCMP_SOR_#NAME : FCMP_COND<"sor", TypeStr, RO>, ++ R2_COND; ++ def FCMP_SUNE_#NAME : FCMP_COND<"sune", TypeStr, RO>, ++ R2_COND; ++} ++ ++//// comparisons supported via another comparison ++//multiclass FCmp_Pats { ++// def : LoongArchPat<(seteq VT:$lhs, VT:$rhs), ++// (!cast("FCMP_CEQ_"#NAME) VT:$lhs, VT:$rhs)>; ++// def : LoongArchPat<(setgt VT:$lhs, VT:$rhs), ++// (!cast("FCMP_CLE_"#NAME) VT:$rhs, VT:$lhs)>; ++// def : LoongArchPat<(setge VT:$lhs, VT:$rhs), ++// (!cast("FCMP_CLT_"#NAME) VT:$rhs, VT:$lhs)>; ++// def : LoongArchPat<(setlt VT:$lhs, VT:$rhs), ++// (!cast("FCMP_CLT_"#NAME) VT:$lhs, VT:$rhs)>; ++// def : LoongArchPat<(setle VT:$lhs, VT:$rhs), ++// (!cast("FCMP_CLE_"#NAME) VT:$lhs, VT:$rhs)>; ++// def : LoongArchPat<(setne VT:$lhs, VT:$rhs), ++// (NOROp ++// (!cast("FCMP_CEQ_"#NAME) VT:$lhs, VT:$rhs), ++// ZEROReg)>; ++//} ++ ++ ++/// ++/// R2 ++/// ++def FABS_S : Float_Reg2<"fabs.s", FGR32Opnd, fabs>, R2F<0b0100000001>; ++def FABS_D : Float_Reg2<"fabs.d", FGR64Opnd, fabs>, R2F<0b0100000010>; ++def FNEG_S : Float_Reg2<"fneg.s", FGR32Opnd, fneg>, R2F<0b0100000101>; ++def FNEG_D : Float_Reg2<"fneg.d", FGR64Opnd, fneg>, R2F<0b0100000110>; ++def FLOGB_S : Float_Reg2<"flogb.s", FGR32Opnd>, R2F<0b0100001001>; ++def FLOGB_D : Float_Reg2<"flogb.d", FGR64Opnd>, R2F<0b0100001010>; ++def FCLASS_S : Float_Reg2<"fclass.s", FGR32Opnd>, R2F<0b0100001101>; ++def FCLASS_D : Float_Reg2<"fclass.d", FGR64Opnd>, R2F<0b0100001110>; ++def FSQRT_S : Float_Reg2<"fsqrt.s", FGR32Opnd, fsqrt>, R2F<0b0100010001>; ++def FSQRT_D : Float_Reg2<"fsqrt.d", FGR64Opnd, fsqrt>, R2F<0b0100010010>; ++def FRECIP_S : Float_Reg2_Frecip<"frecip.s", FGR32Opnd, fdiv>, R2F<0b0100010101>; ++def FRECIP_D : Float_Reg2_Frecip<"frecip.d", FGR64Opnd, fdiv>, R2F<0b0100010110>; ++def FRECIPE_S : Float_Reg2<"frecipe.s", FGR32Opnd>, R2F<0b0100011101>; ++def FRECIPE_D : Float_Reg2<"frecipe.d", FGR64Opnd>, R2F<0b0100011110>; ++def FRSQRT_S : Float_Reg2_Frsqrt<"frsqrt.s", FGR32Opnd, fdiv>, R2F<0b0100011001>; ++def FRSQRT_D : Float_Reg2_Frsqrt<"frsqrt.d", FGR64Opnd, fdiv>, R2F<0b0100011010>; ++def FRSQRTE_S : Float_Reg2<"frsqrte.s", FGR32Opnd>, R2F<0b0100100001>; ++def FRSQRTE_D : Float_Reg2<"frsqrte.d", FGR64Opnd>, R2F<0b0100100010>; ++def FMOV_S : Float_Reg2<"fmov.s", FGR32Opnd>, R2F<0b0100100101>; ++def FMOV_D : Float_Reg2<"fmov.d", FGR64Opnd>, R2F<0b0100100110>; ++ ++def MOVGR2FR_W : Float_MOVT<"movgr2fr.w", FGR32Opnd, GPR32Opnd, bitconvert>, MOVFI<0b0100101001>; ++def MOVGR2FR_D : Float_MOVT<"movgr2fr.d", FGR64Opnd, GPR64Opnd, bitconvert>, MOVFI<0b0100101010>; ++def MOVGR2FRH_W : Float_MOVT<"movgr2frh.w", FGR64Opnd, GPR32Opnd>, MOVFI<0b0100101011>; //not realize ++def MOVFR2GR_S : Float_MOVF<"movfr2gr.s", GPR32Opnd, FGR32Opnd, bitconvert>, MOVIF<0b0100101101>; ++def MOVFR2GR_D : Float_MOVF<"movfr2gr.d", GPR64Opnd, FGR64Opnd, bitconvert>, MOVIF<0b0100101110>; ++def MOVFRH2GR_S : Float_MOVF<"movfrh2gr.s", GPR32Opnd, FGR32Opnd>, MOVIF<0b0100101111>; //not realize ++ ++let isCodeGenOnly = 1 in { ++ def MOVFR2GR_DS : Float_MOVF<"movfr2gr.s", GPR64Opnd, FGR32Opnd>, MOVIF<0b0100101101>; ++} ++ ++def FCVT_S_D : Float_CVT<"fcvt.s.d", FGR32Opnd, FGR64Opnd>, R2F<0b1001000110>; ++def FCVT_D_S : Float_CVT<"fcvt.d.s", FGR64Opnd, FGR32Opnd>, R2F<0b1001001001>; ++ ++def FTINTRM_W_S : Float_Reg2<"ftintrm.w.s", FGR32Opnd>, R2F<0b1010000001>; ++def FTINTRM_W_D : Float_Reg2<"ftintrm.w.d", FGR64Opnd>, R2F<0b1010000010>; ++def FTINTRM_L_S : Float_Reg2<"ftintrm.l.s", FGR32Opnd>, R2F<0b1010001001>; ++def FTINTRM_L_D : Float_Reg2<"ftintrm.l.d", FGR64Opnd>, R2F<0b1010001010>; ++def FTINTRP_W_S : Float_Reg2<"ftintrp.w.s", FGR32Opnd>, R2F<0b1010010001>; ++def FTINTRP_W_D : Float_Reg2<"ftintrp.w.d", FGR64Opnd>, R2F<0b1010010010>; ++def FTINTRP_L_S : Float_Reg2<"ftintrp.l.s", FGR32Opnd>, R2F<0b1010011001>; ++def FTINTRP_L_D : Float_Reg2<"ftintrp.l.d", FGR64Opnd>, R2F<0b1010011010>; ++def FTINTRZ_W_S : Float_Reg2<"ftintrz.w.s", FGR32Opnd>, R2F<0b1010100001>; ++def FTINTRZ_L_D : Float_Reg2<"ftintrz.l.d", FGR64Opnd>, R2F<0b1010101010>; ++def FTINTRNE_W_S : Float_Reg2<"ftintrne.w.s", FGR32Opnd>, R2F<0b1010110001>; ++def FTINTRNE_W_D : Float_Reg2<"ftintrne.w.d", FGR64Opnd>, R2F<0b1010110010>; ++def FTINTRNE_L_S : Float_Reg2<"ftintrne.l.s", FGR32Opnd>, R2F<0b1010111001>; ++def FTINTRNE_L_D : Float_Reg2<"ftintrne.l.d", FGR64Opnd>, R2F<0b1010111010>; ++ ++def FTINT_W_S : Float_CVT<"ftint.w.s", FGR32Opnd, FGR32Opnd>, R2F<0b1011000001>; ++def FTINT_W_D : Float_CVT<"ftint.w.d", FGR32Opnd, FGR64Opnd>, R2F<0b1011000010>; ++def FTINT_L_S : Float_CVT<"ftint.l.s", FGR64Opnd, FGR32Opnd>, R2F<0b1011001001>; ++def FTINT_L_D : Float_CVT<"ftint.l.d", FGR64Opnd, FGR64Opnd>, R2F<0b1011001010>; ++def FFINT_S_W : Float_CVT<"ffint.s.w", FGR32Opnd, FGR32Opnd>, R2F<0b1101000100>; ++def FFINT_S_L : Float_CVT<"ffint.s.l", FGR32Opnd, FGR64Opnd>, R2F<0b1101000110>; ++def FFINT_D_W : Float_CVT<"ffint.d.w", FGR64Opnd, FGR32Opnd>, R2F<0b1101001000>; ++def FFINT_D_L : Float_CVT<"ffint.d.l", FGR64Opnd, FGR64Opnd>, R2F<0b1101001010>; ++ ++def FRINT_S : Float_Reg2<"frint.s", FGR32Opnd, frint>, R2F<0b1110010001>; ++def FRINT_D : Float_Reg2<"frint.d", FGR64Opnd, frint>, R2F<0b1110010010>; ++ ++/// ++/// R3 ++/// ++def FADD_S : Float_Reg3<"fadd.s", FGR32Opnd, fadd>, R3F<0b000001>; ++def FADD_D : Float_Reg3<"fadd.d", FGR64Opnd, fadd>, R3F<0b000010>; ++def FSUB_S : Float_Reg3<"fsub.s", FGR32Opnd, fsub>, R3F<0b000101>; ++def FSUB_D : Float_Reg3<"fsub.d", FGR64Opnd, fsub>, R3F<0b000110>; ++def FMUL_S : Float_Reg3<"fmul.s", FGR32Opnd, fmul>, R3F<0b001001>; ++def FMUL_D : Float_Reg3<"fmul.d", FGR64Opnd, fmul>, R3F<0b001010>; ++def FDIV_S : Float_Reg3<"fdiv.s", FGR32Opnd, fdiv>, R3F<0b001101>; ++def FDIV_D : Float_Reg3<"fdiv.d", FGR64Opnd, fdiv>, R3F<0b001110>; ++def FMAX_S : Float_Reg3<"fmax.s", FGR32Opnd, fmaxnum_ieee>, R3F<0b010001>; ++def FMAX_D : Float_Reg3<"fmax.d", FGR64Opnd, fmaxnum_ieee>, R3F<0b010010>; ++def FMIN_S : Float_Reg3<"fmin.s", FGR32Opnd, fminnum_ieee>, R3F<0b010101>; ++def FMIN_D : Float_Reg3<"fmin.d", FGR64Opnd, fminnum_ieee>, R3F<0b010110>; ++def FMAXA_S : Float_Reg3_Fmaxa<"fmaxa.s", FGR32Opnd>, R3F<0b011001>; ++def FMAXA_D : Float_Reg3_Fmaxa<"fmaxa.d", FGR64Opnd>, R3F<0b011010>; ++def FMINA_S : Float_Reg3_Fmaxa<"fmina.s", FGR32Opnd>, R3F<0b011101>; ++def FMINA_D : Float_Reg3_Fmaxa<"fmina.d", FGR64Opnd>, R3F<0b011110>; ++def FSCALEB_S : Float_Reg3<"fscaleb.s", FGR32Opnd>, R3F<0b100001>; ++def FSCALEB_D : Float_Reg3<"fscaleb.d", FGR64Opnd>, R3F<0b100010>; ++def FCOPYSIGN_S : Float_Reg3<"fcopysign.s", FGR32Opnd, fcopysign>, R3F<0b100101>; ++def FCOPYSIGN_D : Float_Reg3<"fcopysign.d", FGR64Opnd, fcopysign>, R3F<0b100110>; ++/// ++/// R4_IMM21 ++/// ++def FMADD_S : Mul_Reg4<"fmadd.s", FGR32Opnd>, R4MUL<0b0001>; ++def FMADD_D : Mul_Reg4<"fmadd.d", FGR64Opnd>, R4MUL<0b0010>; ++def FMSUB_S : Mul_Reg4<"fmsub.s", FGR32Opnd>, R4MUL<0b0101>; ++def FMSUB_D : Mul_Reg4<"fmsub.d", FGR64Opnd>, R4MUL<0b0110>; ++def FNMADD_S : NMul_Reg4<"fnmadd.s", FGR32Opnd>, R4MUL<0b1001>; ++def FNMADD_D : NMul_Reg4<"fnmadd.d", FGR64Opnd>, R4MUL<0b1010>; ++def FNMSUB_S : NMul_Reg4<"fnmsub.s", FGR32Opnd>, R4MUL<0b1101>; ++def FNMSUB_D : NMul_Reg4<"fnmsub.d", FGR64Opnd>, R4MUL<0b1110>; ++ ++ ++// fmadd: fj * fk + fa ++def : LoongArchPat<(fma FGR64Opnd:$fj, FGR64Opnd:$fk, FGR64Opnd:$fa), ++ (FMADD_D $fj, $fk, $fa)>; ++ ++def : LoongArchPat<(fma FGR32Opnd:$fj, FGR32Opnd:$fk, FGR32Opnd:$fa), ++ (FMADD_S $fj, $fk, $fa)>; ++ ++ ++// fmsub: fj * fk - fa ++def : LoongArchPat<(fma FGR64Opnd:$fj, FGR64Opnd:$fk, (fneg FGR64Opnd:$fa)), ++ (FMSUB_D FGR64Opnd:$fj, FGR64Opnd:$fk, FGR64Opnd:$fa)>; ++ ++def : LoongArchPat<(fma FGR32Opnd:$fj, FGR32Opnd:$fk, (fneg FGR32Opnd:$fa)), ++ (FMSUB_S FGR32Opnd:$fj, FGR32Opnd:$fk, FGR32Opnd:$fa)>; ++ ++ ++// fnmadd: -(fj * fk + fa) ++def : LoongArchPat<(fma (fneg FGR64Opnd:$fj), FGR64Opnd:$fk, (fneg FGR64Opnd:$fa)), ++ (FNMADD_D FGR64Opnd:$fj, FGR64Opnd:$fk, FGR64Opnd:$fa)>; ++ ++def : LoongArchPat<(fma (fneg FGR32Opnd:$fj), FGR32Opnd:$fk, (fneg FGR32Opnd:$fa)), ++ (FNMADD_S FGR32Opnd:$fj, FGR32Opnd:$fk, FGR32Opnd:$fa)>; ++ ++// fnmsub: -(fj * fk - fa) ++def : LoongArchPat<(fma (fneg FGR64Opnd:$fj), FGR64Opnd:$fk, FGR64Opnd:$fa), ++ (FNMSUB_D FGR64Opnd:$fj, FGR64Opnd:$fk, FGR64Opnd:$fa)>; ++ ++def : LoongArchPat<(fma (fneg FGR32Opnd:$fj), FGR32Opnd:$fk, FGR32Opnd:$fa), ++ (FNMSUB_S FGR32Opnd:$fj, FGR32Opnd:$fk, FGR32Opnd:$fa)>; ++ ++let Pattern = [] in { ++defm S : FCMP_COND_M<0b01, "s", FGR32Opnd>; ++defm D : FCMP_COND_M<0b10, "d", FGR64Opnd>; ++} ++// ++//defm S : FCmp_Pats; ++//defm D : FCmp_Pats; ++ ++/// ++/// Float point branching ++/// ++def LoongArch_BRANCH_F : PatLeaf<(i32 0)>; ++def LoongArch_BRANCH_T : PatLeaf<(i32 1)>; ++ ++def BCEQZ : BceqzBr<"bceqz", brtarget, LoongArch_BRANCH_F>, R1_BCEQZ<0>; ++def BCNEZ : BceqzBr<"bcnez", brtarget, LoongArch_BRANCH_T>, R1_BCEQZ<1>; ++ ++/// ++/// FMOV ++/// ++def MOVGR2FCSR : Gpr_2_Fcsr<"movgr2fcsr", GPR64Opnd>, MOVGPR2FCSR; ++def MOVFCSR2GR : Fcsr_2_Gpr<"movfcsr2gr", GPR64Opnd>, MOVFCSR2GPR; ++def MOVFR2CF : Fgr_2_Fcfr<"movfr2cf", FGR64Opnd>, MOVFGR2FCFR; ++def MOVCF2FR : Fcfr_2_Fgr<"movcf2fr", FGR64Opnd>, MOVFCFR2FGR; ++def MOVGR2CF : Gpr_2_Fcfr<"movgr2cf", GPR64Opnd>, MOVGPR2FCFR; ++def MOVCF2GR : Fcfr_2_Gpr<"movcf2gr", GPR64Opnd>, MOVFCFR2GPR; ++ ++let isCodeGenOnly = 1 in { ++ def MOVFR2CF32 : Fgr_2_Fcfr<"movfr2cf", FGR32Opnd>, MOVFGR2FCFR; ++ def MOVCF2FR32 : Fcfr_2_Fgr<"movcf2fr", FGR32Opnd>, MOVFCFR2FGR; ++ def MOVGR2CF32 : Gpr_2_Fcfr<"movgr2cf", GPR32Opnd>, MOVGPR2FCFR; ++ def MOVCF2GR32 : Fcfr_2_Gpr<"movcf2gr", GPR32Opnd>, MOVFCFR2GPR; ++} ++ ++class Sel_Reg4 ++ : InstForm<(outs RO:$fd), (ins FCFROpnd:$ca, RO:$fj, RO:$fk), ++ !strconcat(opstr, "\t$fd, $fj, $fk, $ca"), ++ [(set RO:$fd, (LoongArchFSEL RO:$fj, FCFROpnd:$ca, RO:$fk))], ++ FrmR, opstr>{ ++ let Defs = [FCC0, FCC1, FCC2, FCC3, FCC4, FCC5, FCC6]; ++ let hasFCCRegOperand = 1; ++ } ++ ++def FSEL_T_S : Sel_Reg4<"fsel", FGR32Opnd>, R4SEL; ++let isCodeGenOnly = 1 in { ++ def FSEL_T_D : Sel_Reg4<"fsel", FGR64Opnd>, R4SEL; ++} ++ ++/// ++/// Mem access ++/// ++def FLD_S : FLd<"fld.s", FGR32Opnd, mem, load>, LOAD_STORE<0b1100>; ++def FST_S : FSt<"fst.s", FGR32Opnd, mem, store>, LOAD_STORE<0b1101>; ++def FLD_D : FLd<"fld.d", FGR64Opnd, mem, load>, LOAD_STORE<0b1110>; ++def FST_D : FSt<"fst.d", FGR64Opnd, mem, store>, LOAD_STORE<0b1111>; ++ ++def FLDX_S : FLDX<"fldx.s", FGR32Opnd, load>, R3MF<0b01100000>; ++def FLDX_D : FLDX<"fldx.d", FGR64Opnd, load>, R3MF<0b01101000>; ++def FSTX_S : FSTX<"fstx.s", FGR32Opnd, store>, R3MF<0b01110000>; ++def FSTX_D : FSTX<"fstx.d", FGR64Opnd, store>, R3MF<0b01111000>; ++ ++def FLDGT_S : Float_Int_Reg3<"fldgt.s", FGR32Opnd, GPR64Opnd>, R3MF<0b11101000>; ++def FLDGT_D : Float_Int_Reg3<"fldgt.d", FGR64Opnd, GPR64Opnd>, R3MF<0b11101001>; ++def FLDLE_S : Float_Int_Reg3<"fldle.s", FGR32Opnd, GPR64Opnd>, R3MF<0b11101010>; ++def FLDLE_D : Float_Int_Reg3<"fldle.d", FGR64Opnd, GPR64Opnd>, R3MF<0b11101011>; ++def FSTGT_S : Float_STGT_LE<"fstgt.s", FGR32Opnd, GPR64Opnd>, R3MF<0b11101100>; ++def FSTGT_D : Float_STGT_LE<"fstgt.d", FGR64Opnd, GPR64Opnd>, R3MF<0b11101101>; ++def FSTLE_S : Float_STGT_LE<"fstle.s", FGR32Opnd, GPR64Opnd>, R3MF<0b11101110>; ++def FSTLE_D : Float_STGT_LE<"fstle.d", FGR64Opnd, GPR64Opnd>, R3MF<0b11101111>; ++ ++let isPseudo = 1, isCodeGenOnly = 1 in { ++ def PseudoFFINT_S_W : Float_CVT<"", FGR32Opnd, GPR32Opnd>; ++ def PseudoFFINT_D_W : Float_CVT<"", FGR64Opnd, GPR32Opnd>; ++ def PseudoFFINT_S_L : Float_CVT<"", FGR64Opnd, GPR64Opnd>; ++ def PseudoFFINT_D_L : Float_CVT<"", FGR64Opnd, GPR64Opnd>; ++} ++ ++def : LoongArchPat<(f32 (fpround FGR64Opnd:$src)), ++ (FCVT_S_D FGR64Opnd:$src)>; ++def : LoongArchPat<(f64 (fpextend FGR32Opnd:$src)), ++ (FCVT_D_S FGR32Opnd:$src)>; ++ ++def : LoongArchPat<(f32 (sint_to_fp GPR32Opnd:$src)), ++ (PseudoFFINT_S_W GPR32Opnd:$src)>; ++def : LoongArchPat<(f64 (sint_to_fp GPR32Opnd:$src)), ++ (PseudoFFINT_D_W GPR32Opnd:$src)>; ++def : LoongArchPat<(f32 (sint_to_fp GPR64Opnd:$src)), ++ (EXTRACT_SUBREG (PseudoFFINT_S_L GPR64Opnd:$src), sub_lo)>; ++def : LoongArchPat<(f64 (sint_to_fp GPR64Opnd:$src)), ++ (PseudoFFINT_D_L GPR64Opnd:$src)>; ++ ++def : LoongArchPat<(f32 fpimm0), (MOVGR2FR_W ZERO)>; ++def : LoongArchPat<(f32 fpimm0neg), (FNEG_S (MOVGR2FR_W ZERO))>; ++def : LoongArchPat<(f32 fpimm1), (FFINT_S_W (MOVGR2FR_W (ADDI_W ZERO, 1)))>; ++def : LoongArchPat<(f64 fpimm1), (FFINT_D_L (MOVGR2FR_D (ADDI_D ZERO_64, 1)))>; ++ ++// Patterns for loads/stores with a reg+imm operand. ++let AddedComplexity = 40 in { ++ def : LoadRegImmPat; ++ def : StoreRegImmPat; ++ def : LoadRegImmPat; ++ def : StoreRegImmPat; ++} ++ ++def : LoongArchPat<(LoongArchTruncIntFP FGR32Opnd:$src), ++ (FTINTRZ_W_S FGR32Opnd:$src)>; ++ ++def : LoongArchPat<(LoongArchTruncIntFP FGR64Opnd:$src), ++ (FTINTRZ_L_D FGR64Opnd:$src)>; ++ ++def : LoongArchPat<(LoongArchTruncIntFP FGR32Opnd:$src), ++ (FCVT_D_S (FTINTRZ_W_S FGR32Opnd:$src))>; ++ ++def : LoongArchPat<(f32 (fcopysign FGR32Opnd:$lhs, FGR64Opnd:$rhs)), ++ (FCOPYSIGN_S FGR32Opnd:$lhs, (FCVT_S_D FGR64Opnd:$rhs))>; ++def : LoongArchPat<(f64 (fcopysign FGR64Opnd:$lhs, FGR32Opnd:$rhs)), ++ (FCOPYSIGN_D FGR64Opnd:$lhs, (FCVT_D_S FGR32Opnd:$rhs))>; ++ ++let PrintMethod = "printFCCOperand",EncoderMethod = "getFCMPEncoding" in ++ def condcode : Operand; ++ ++class CEQS_FT : ++ InstForm<(outs), (ins RC:$fj, RC:$fk, condcode:$cond), ++ !strconcat("fcmp.$cond.", typestr, "\t$$fcc0, $fj, $fk"), ++ [(OpNode RC:$fj, RC:$fk, imm:$cond)], FrmFR, ++ !strconcat("fcmp.$cond.", typestr)>, HARDFLOAT { ++ let Defs = [FCC0, FCC1, FCC2, FCC3, FCC4, FCC5, FCC6, FCC7]; ++ let isCodeGenOnly = 1; ++ let hasFCCRegOperand = 1; ++} ++ ++def FCMP_S32 : CEQS_FT<"s", FGR32, LoongArchFPCmp>, CEQS_FM<0b01> { ++ bits<3> cd = 0; ++} ++def FCMP_D64 : CEQS_FT<"d", FGR64, LoongArchFPCmp>, CEQS_FM<0b10>{ ++ bits<3> cd = 0; ++} ++ ++ ++//multiclass FCmp_Pats2 { ++// def : LoongArchPat<(seteq VT:$lhs, VT:$rhs), ++// (!cast("SFCMP_CEQ_"#NAME) VT:$lhs, VT:$rhs)>; ++// def : LoongArchPat<(setgt VT:$lhs, VT:$rhs), ++// (!cast("SFCMP_CLE_"#NAME) VT:$rhs, VT:$lhs)>; ++// def : LoongArchPat<(setge VT:$lhs, VT:$rhs), ++// (!cast("SFCMP_CLT_"#NAME) VT:$rhs, VT:$lhs)>; ++// def : LoongArchPat<(setlt VT:$lhs, VT:$rhs), ++// (!cast("SFCMP_CLT_"#NAME) VT:$lhs, VT:$rhs)>; ++// def : LoongArchPat<(setle VT:$lhs, VT:$rhs), ++// (!cast("SFCMP_CLE_"#NAME) VT:$lhs, VT:$rhs)>; ++// def : LoongArchPat<(setne VT:$lhs, VT:$rhs), ++// (NOROp ++// (!cast("SFCMP_CEQ_"#NAME) VT:$lhs, VT:$rhs), ++// ZEROReg)>; ++// ++// def : LoongArchPat<(seteq VT:$lhs, VT:$rhs), ++// (!cast("DFCMP_CEQ_"#NAME) VT:$lhs, VT:$rhs)>; ++// def : LoongArchPat<(setgt VT:$lhs, VT:$rhs), ++// (!cast("DFCMP_CLE_"#NAME) VT:$rhs, VT:$lhs)>; ++// def : LoongArchPat<(setge VT:$lhs, VT:$rhs), ++// (!cast("DFCMP_CLT_"#NAME) VT:$rhs, VT:$lhs)>; ++// def : LoongArchPat<(setlt VT:$lhs, VT:$rhs), ++// (!cast("DFCMP_CLT_"#NAME) VT:$lhs, VT:$rhs)>; ++// def : LoongArchPat<(setle VT:$lhs, VT:$rhs), ++// (!cast("DFCMP_CLE_"#NAME) VT:$lhs, VT:$rhs)>; ++// def : LoongArchPat<(setne VT:$lhs, VT:$rhs), ++// (NOROp ++// (!cast("DFCMP_CEQ_"#NAME) VT:$lhs, VT:$rhs), ++// ZEROReg)>; ++// } ++// ++//defm S : FCmp_Pats2; ++//defm D : FCmp_Pats2; ++ ++let usesCustomInserter = 1 in { ++ class Select_Pseudo : ++ LoongArchPseudo<(outs RC:$dst), (ins GPR32Opnd:$cond, RC:$T, RC:$F), ++ [(set RC:$dst, (select GPR32Opnd:$cond, RC:$T, RC:$F))]>; ++ ++ class SelectFP_Pseudo_T : ++ LoongArchPseudo<(outs RC:$dst), (ins FCFROpnd:$cond, RC:$T, RC:$F), ++ [(set RC:$dst, (LoongArchCMovFP_T RC:$T, FCFROpnd:$cond, RC:$F))]>; ++ ++ class SelectFP_Pseudo_F : ++ LoongArchPseudo<(outs RC:$dst), (ins FCFROpnd:$cond, RC:$T, RC:$F), ++ [(set RC:$dst, (LoongArchCMovFP_F RC:$T, FCFROpnd:$cond, RC:$F))]>; ++} ++ ++def PseudoSELECT_I : Select_Pseudo; ++def PseudoSELECT_I64 : Select_Pseudo; ++def PseudoSELECT_S : Select_Pseudo; ++def PseudoSELECT_D64 : Select_Pseudo; ++ ++def PseudoSELECTFP_T_I : SelectFP_Pseudo_T; ++def PseudoSELECTFP_T_I64 : SelectFP_Pseudo_T; ++ ++def PseudoSELECTFP_F_I : SelectFP_Pseudo_F; ++def PseudoSELECTFP_F_I64 : SelectFP_Pseudo_F; ++ ++class ABSS_FT : ++ InstForm<(outs DstRC:$fd), (ins SrcRC:$fj), !strconcat(opstr, "\t$fd, $fj"), ++ [(set DstRC:$fd, (OpNode SrcRC:$fj))], FrmFR, opstr>; ++ ++def TRUNC_W_D : ABSS_FT<"ftintrz.w.d", FGR32Opnd, FGR64Opnd>, R2F<0b1010100010>; ++ ++def FTINTRZ_L_S : ABSS_FT<"ftintrz.l.s", FGR64Opnd, FGR32Opnd>, R2F<0b1010101001>; ++ ++def : LoongArchPat<(LoongArchTruncIntFP FGR64Opnd:$src), ++ (TRUNC_W_D FGR64Opnd:$src)>; ++ ++def : LoongArchPat<(LoongArchTruncIntFP FGR32Opnd:$src), ++ (FTINTRZ_L_S FGR32Opnd:$src)>; ++ ++def : Pat<(fcanonicalize FGR32Opnd:$src), (FMAX_S $src, $src)>; ++def : Pat<(fcanonicalize FGR64Opnd:$src), (FMAX_D $src, $src)>; ++ ++def : LoongArchPat<(i64 (sext (i32 (bitconvert FGR32Opnd:$src)))), ++ (MOVFR2GR_DS FGR32Opnd:$src)>; ++ ++let Predicates = [HasFrecipe] in { ++// FP approximate reciprocal operation ++def : Pat<(int_loongarch_frecipe_s FGR32Opnd:$src), (FRECIPE_S FGR32Opnd:$src)>; ++def : Pat<(int_loongarch_frsqrte_s FGR32Opnd:$src), (FRSQRTE_S FGR32Opnd:$src)>; ++def : Pat<(int_loongarch_frecipe_d FGR64Opnd:$src), (FRECIPE_D FGR64Opnd:$src)>; ++def : Pat<(int_loongarch_frsqrte_d FGR64Opnd:$src), (FRSQRTE_D FGR64Opnd:$src)>; ++} +diff --git a/llvm/lib/Target/LoongArch/LoongArchLASXInstrFormats.td b/llvm/lib/Target/LoongArch/LoongArchLASXInstrFormats.td +index ba21d68b9..8e255f857 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchLASXInstrFormats.td ++++ b/llvm/lib/Target/LoongArch/LoongArchLASXInstrFormats.td +@@ -1,459 +1,448 @@ +-// LoongArchLASXInstrFormats.td - LoongArch LASX Instr Formats - tablegen -*-=// ++//===- LoongArchLASXInstrFormats.td - LoongArch LASX Instruction Formats ---*- tablegen -*-===// + // +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// The LLVM Compiler Infrastructure + // +-//===----------------------------------------------------------------------===// +- +-//===----------------------------------------------------------------------===// +-// Describe LoongArch LASX instructions format +-// +-// opcode - operation code. +-// xd/rd/cd - destination register operand. +-// {r/x}{j/k} - source register operand. +-// immN - immediate data operand. ++// This file is distributed under the University of Illinois Open Source ++// License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + +-// 1RI13-type +-// +-class Fmt1RI13_XI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<13> imm13; +- bits<5> xd; ++class LASXInst : InstLA<(outs), (ins), "", [], FrmOther>, ++ EXT_LASX { ++} + +- let Inst{31-0} = op; +- let Inst{17-5} = imm13; +- let Inst{4-0} = xd; ++class LASXCBranch : LASXInst { ++} ++ ++class LASXSpecial : LASXInst { ++} ++ ++class LASXPseudo pattern>: ++ LoongArchPseudo { ++ let Predicates = [HasLASX]; + } + +-// 2R-type +-// +-class Fmt2R_XX op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { ++class LASX_3R op>: LASXInst { ++ bits<5> xk; + bits<5> xj; + bits<5> xd; + +- let Inst{31-0} = op; ++ let Inst{31-15} = op; ++ let Inst{14-10} = xk; + let Inst{9-5} = xj; + let Inst{4-0} = xd; + } + +-// +-class Fmt2R_XR op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<5> rj; ++class LASX_4R op>: LASXInst { ++ bits<5> xa; ++ bits<5> xk; ++ bits<5> xj; + bits<5> xd; + +- let Inst{31-0} = op; +- let Inst{9-5} = rj; ++ let Inst{31-20} = op; ++ let Inst{19-15} = xa; ++ let Inst{14-10} = xk; ++ let Inst{9-5} = xj; + let Inst{4-0} = xd; + } + +-// +-class Fmt2R_CX op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { ++class LASX_XVFCMP op>: LASXInst { ++ bits<5> xd; + bits<5> xj; +- bits<3> cd; ++ bits<5> xk; ++ bits<5> cond; + +- let Inst{31-0} = op; ++ let Inst{31-20} = op; ++ let Inst{19-15} = cond; ++ let Inst{14-10} = xk; + let Inst{9-5} = xj; +- let Inst{2-0} = cd; ++ let Inst{4-0} = xd; + } + +-// 2RI1-type +-// +-class Fmt2RI1_XXI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<1> imm1; +- bits<5> xj; ++class LASX_I12_S op>: LASXInst { + bits<5> xd; ++ bits<17> addr; + +- let Inst{31-0} = op; +- let Inst{10} = imm1; +- let Inst{9-5} = xj; ++ let Inst{31-22} = op; ++ let Inst{21-10} = addr{11-0}; ++ let Inst{9-5} = addr{16-12}; + let Inst{4-0} = xd; + } + +-// 2RI2-type +-// +-class Fmt2RI2_XXI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<2> imm2; +- bits<5> xj; ++class LASX_SI12_S op>: LASXInst { + bits<5> xd; ++ bits<17> addr; + +- let Inst{31-0} = op; +- let Inst{11-10} = imm2; +- let Inst{9-5} = xj; ++ let Inst{31-22} = op; ++ let Inst{21-10} = addr{11-0}; ++ let Inst{9-5} = addr{16-12}; + let Inst{4-0} = xd; + } + +-// +-class Fmt2RI2_XRI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<2> imm2; +- bits<5> rj; ++class LASX_SI11_S op>: LASXInst { + bits<5> xd; ++ bits<16> addr; + +- let Inst{31-0} = op; +- let Inst{11-10} = imm2; +- let Inst{9-5} = rj; ++ let Inst{31-21} = op; ++ let Inst{20-10} = addr{10-0}; ++ let Inst{9-5} = addr{15-11}; + let Inst{4-0} = xd; + } + +-// +-class Fmt2RI2_RXI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<2> imm2; +- bits<5> xj; +- bits<5> rd; ++class LASX_SI10_S op>: LASXInst { ++ bits<5> xd; ++ bits<15> addr; + +- let Inst{31-0} = op; +- let Inst{11-10} = imm2; +- let Inst{9-5} = xj; +- let Inst{4-0} = rd; ++ let Inst{31-20} = op; ++ let Inst{19-10} = addr{9-0}; ++ let Inst{9-5} = addr{14-10}; ++ let Inst{4-0} = xd; + } + +-// 2RI3-type +-// +-class Fmt2RI3_XXI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<3> imm3; +- bits<5> xj; ++class LASX_SI9_S op>: LASXInst { + bits<5> xd; ++ bits<14> addr; + +- let Inst{31-0} = op; +- let Inst{12-10} = imm3; +- let Inst{9-5} = xj; ++ let Inst{31-19} = op; ++ let Inst{18-10} = addr{8-0}; ++ let Inst{9-5} = addr{13-9}; + let Inst{4-0} = xd; + } + +-// +-class Fmt2RI3_XRI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<3> imm3; ++class LASX_SI8_idx5 op>: LASXInst { ++ bits<5> xd; + bits<5> rj; ++ bits<8> si8; ++ bits<5> idx; ++ ++ let Inst{31-23} = op; ++ let Inst{22-18} = idx; ++ let Inst{17-10} = si8; ++ let Inst{9-5} = rj; ++ let Inst{4-0} = xd; ++} ++ ++class LASX_SI8_idx2 op>: LASXInst { + bits<5> xd; ++ bits<5> rj; ++ bits<8> si8; ++ bits<2> idx; + +- let Inst{31-0} = op; +- let Inst{12-10} = imm3; ++ let Inst{31-20} = op; ++ let Inst{19-18} = idx; ++ let Inst{17-10} = si8; + let Inst{9-5} = rj; + let Inst{4-0} = xd; + } + +-// +-class Fmt2RI3_RXI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<3> imm3; +- bits<5> xj; +- bits<5> rd; ++class LASX_SI8_idx3 op>: LASXInst { ++ bits<5> xd; ++ bits<5> rj; ++ bits<8> si8; ++ bits<3> idx; + +- let Inst{31-0} = op; +- let Inst{12-10} = imm3; +- let Inst{9-5} = xj; +- let Inst{4-0} = rd; ++ let Inst{31-21} = op; ++ let Inst{20-18} = idx; ++ let Inst{17-10} = si8; ++ let Inst{9-5} = rj; ++ let Inst{4-0} = xd; + } + +-// 2RI4-type +-// +-class Fmt2RI4_XXI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<4> imm4; +- bits<5> xj; ++class LASX_SI8_idx4 op>: LASXInst { + bits<5> xd; ++ bits<5> rj; ++ bits<8> si8; ++ bits<4> idx; + +- let Inst{31-0} = op; +- let Inst{13-10} = imm4; +- let Inst{9-5} = xj; ++ let Inst{31-22} = op; ++ let Inst{21-18} = idx; ++ let Inst{17-10} = si8; ++ let Inst{9-5} = rj; + let Inst{4-0} = xd; + } + +-// +-class Fmt2RI4_XRI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<4> imm4; ++class LASX_3R_2GP op>: LASXInst { ++ bits<5> rk; + bits<5> rj; + bits<5> xd; + +- let Inst{31-0} = op; +- let Inst{13-10} = imm4; ++ let Inst{31-15} = op; ++ let Inst{14-10} = rk; + let Inst{9-5} = rj; + let Inst{4-0} = xd; + } + +-// +-class Fmt2RI4_RXI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<4> imm4; ++class LASX_3R_1GP op>: LASXInst { ++ bits<5> rk; + bits<5> xj; +- bits<5> rd; ++ bits<5> xd; + +- let Inst{31-0} = op; +- let Inst{13-10} = imm4; ++ let Inst{31-15} = op; ++ let Inst{14-10} = rk; + let Inst{9-5} = xj; +- let Inst{4-0} = rd; ++ let Inst{4-0} = xd; + } + +-// 2RI5-type +-// +-class Fmt2RI5_XXI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<5> imm5; +- bits<5> xj; ++class LASX_I5 op>: LASXInst { + bits<5> xd; ++ bits<5> xj; ++ bits<5> si5; + +- let Inst{31-0} = op; +- let Inst{14-10} = imm5; ++ let Inst{31-15} = op; ++ let Inst{14-10} = si5; + let Inst{9-5} = xj; + let Inst{4-0} = xd; + } + +-// 2RI6-type +-// +-class Fmt2RI6_XXI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<6> imm6; +- bits<5> xj; ++class LASX_I5_U op>: LASXInst { + bits<5> xd; ++ bits<5> xj; ++ bits<5> ui5; + +- let Inst{31-0} = op; +- let Inst{15-10} = imm6; ++ let Inst{31-15} = op; ++ let Inst{14-10} = ui5; + let Inst{9-5} = xj; + let Inst{4-0} = xd; + } + +-// 2RI7-type +-// +-class Fmt2RI7_XXI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<7> imm7; +- bits<5> xj; ++class LASX_I5_mode_U op>: LASXInst { + bits<5> xd; ++ bits<5> mode; ++ bits<5> ui5; + +- let Inst{31-0} = op; +- let Inst{16-10} = imm7; +- let Inst{9-5} = xj; ++ let Inst{31-15} = op; ++ let Inst{14-10} = ui5; ++ let Inst{9-5} = mode; + let Inst{4-0} = xd; + } + +-// 2RI8-type +-// +-class Fmt2RI8_XXI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<8> imm8; ++class LASX_2R op>: LASXInst { + bits<5> xj; + bits<5> xd; + +- let Inst{31-0} = op; +- let Inst{17-10} = imm8; ++ let Inst{31-10} = op; + let Inst{9-5} = xj; + let Inst{4-0} = xd; + } + +-// 2RI8I2-type +-// +-class Fmt2RI8I2_XRII op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<2> imm2; +- bits<8> imm8; ++class LASX_SET op>: LASXInst { ++ bits<5> xj; ++ bits<3> cd; ++ ++ let Inst{31-10} = op; ++ let Inst{9-5} = xj; ++ let Inst{4-3} = 0b00; ++ let Inst{2-0} = cd; ++} ++ ++class LASX_2R_1GP op>: LASXInst { + bits<5> rj; + bits<5> xd; + +- let Inst{31-0} = op; +- let Inst{19-18} = imm2; +- let Inst{17-10} = imm8; ++ let Inst{31-10} = op; + let Inst{9-5} = rj; + let Inst{4-0} = xd; + } + +-// 2RI8I3-type +-// +-class Fmt2RI8I3_XRII op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<3> imm3; +- bits<8> imm8; +- bits<5> rj; ++class LASX_I3_U op>: LASXInst { + bits<5> xd; ++ bits<5> xj; ++ bits<3> ui3; + +- let Inst{31-0} = op; +- let Inst{20-18} = imm3; +- let Inst{17-10} = imm8; +- let Inst{9-5} = rj; ++ let Inst{31-13} = op; ++ let Inst{12-10} = ui3; ++ let Inst{9-5} = xj; + let Inst{4-0} = xd; + } + +-// 2RI8I4-type +-// +-class Fmt2RI8I4_XRII op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<4> imm4; +- bits<8> imm8; +- bits<5> rj; ++class LASX_I4_U op>: LASXInst { + bits<5> xd; ++ bits<5> xj; ++ bits<4> ui4; + +- let Inst{31-0} = op; +- let Inst{21-18} = imm4; +- let Inst{17-10} = imm8; +- let Inst{9-5} = rj; ++ let Inst{31-14} = op; ++ let Inst{13-10} = ui4; ++ let Inst{9-5} = xj; + let Inst{4-0} = xd; + } + +-// 2RI8I5-type +-// +-class Fmt2RI8I5_XRII op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<5> imm5; +- bits<8> imm8; +- bits<5> rj; ++class LASX_I6_U op>: LASXInst { + bits<5> xd; ++ bits<5> xj; ++ bits<6> ui6; + +- let Inst{31-0} = op; +- let Inst{22-18} = imm5; +- let Inst{17-10} = imm8; +- let Inst{9-5} = rj; ++ let Inst{31-16} = op; ++ let Inst{15-10} = ui6; ++ let Inst{9-5} = xj; + let Inst{4-0} = xd; + } + +-// 2RI9-type +-// +-class Fmt2RI9_XRI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<9> imm9; +- bits<5> rj; ++class LASX_I2_R_U op>: LASXInst { + bits<5> xd; ++ bits<5> rj; ++ bits<2> ui2; + +- let Inst{31-0} = op; +- let Inst{18-10} = imm9; ++ let Inst{31-12} = op; ++ let Inst{11-10} = ui2; + let Inst{9-5} = rj; + let Inst{4-0} = xd; + } + +-// 2RI10-type +-// +-class Fmt2RI10_XRI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<10> imm10; +- bits<5> rj; ++class LASX_I3_R_U op>: LASXInst { + bits<5> xd; ++ bits<5> rj; ++ bits<3> ui3; + +- let Inst{31-0} = op; +- let Inst{19-10} = imm10; ++ let Inst{31-13} = op; ++ let Inst{12-10} = ui3; + let Inst{9-5} = rj; + let Inst{4-0} = xd; + } + +-// 2RI11-type +-// +-class Fmt2RI11_XRI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<11> imm11; +- bits<5> rj; ++class LASX_ELM_COPY_U3 op>: LASXInst { ++ bits<5> rd; ++ bits<5> xj; ++ bits<3> ui3; ++ ++ let Inst{31-13} = op; ++ let Inst{12-10} = ui3; ++ let Inst{9-5} = xj; ++ let Inst{4-0} = rd; ++} ++ ++class LASX_ELM_COPY_U2 op>: LASXInst { ++ bits<5> rd; ++ bits<5> xj; ++ bits<2> ui2; ++ ++ let Inst{31-12} = op; ++ let Inst{11-10} = ui2; ++ let Inst{9-5} = xj; ++ let Inst{4-0} = rd; ++} ++ ++class LASX_I1_U op>: LASXInst { + bits<5> xd; ++ bits<5> xj; ++ bits<1> ui1; + +- let Inst{31-0} = op; +- let Inst{20-10} = imm11; +- let Inst{9-5} = rj; ++ let Inst{31-11} = op; ++ let Inst{10} = ui1; ++ let Inst{9-5} = xj; + let Inst{4-0} = xd; + } + +-// 2RI12-type +-// +-class Fmt2RI12_XRI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<12> imm12; +- bits<5> rj; ++class LASX_I2_U op>: LASXInst { + bits<5> xd; ++ bits<5> xj; ++ bits<2> ui2; + +- let Inst{31-0} = op; +- let Inst{21-10} = imm12; +- let Inst{9-5} = rj; ++ let Inst{31-12} = op; ++ let Inst{11-10} = ui2; ++ let Inst{9-5} = xj; + let Inst{4-0} = xd; + } + +-// 3R-type +-// +-class Fmt3R_XXX op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<5> xk; +- bits<5> xj; ++class LASX_I7_U op>: LASXInst { + bits<5> xd; ++ bits<5> xj; ++ bits<7> ui7; + +- let Inst{31-0} = op; +- let Inst{14-10} = xk; ++ let Inst{31-17} = op; ++ let Inst{16-10} = ui7; + let Inst{9-5} = xj; + let Inst{4-0} = xd; + } + +-// +-class Fmt3R_XXR op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<5> rk; +- bits<5> xj; ++class LASX_1R_I13 op>: LASXInst { ++ bits<13> i13; + bits<5> xd; + +- let Inst{31-0} = op; +- let Inst{14-10} = rk; ++ let Inst{31-18} = op; ++ let Inst{17-5} = i13; ++ let Inst{4-0} = xd; ++} ++ ++class LASX_I8_U op>: LASXInst { ++ bits<5> xd; ++ bits<5> xj; ++ bits<8> ui8; ++ ++ let Inst{31-18} = op; ++ let Inst{17-10} = ui8; + let Inst{9-5} = xj; + let Inst{4-0} = xd; + } + +-// +-class Fmt3R_XRR op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<5> rk; ++ ++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ++class LASX_I1_R_U op>: LASXInst { ++ bits<5> xd; + bits<5> rj; ++ bits<1> ui1; ++ ++ let Inst{31-11} = op; ++ let Inst{10} = ui1; ++ let Inst{9-5} = rj; ++ let Inst{4-0} = xd; ++} ++ ++class LASX_I4_R_U op>: LASXInst { + bits<5> xd; ++ bits<5> rj; ++ bits<4> ui4; + +- let Inst{31-0} = op; +- let Inst{14-10} = rk; ++ let Inst{31-14} = op; ++ let Inst{13-10} = ui4; + let Inst{9-5} = rj; + let Inst{4-0} = xd; + } + +-// 4R-type +-// +-class Fmt4R_XXXX op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<5> xa; +- bits<5> xk; ++class LASX_ELM_COPY_B op>: LASXInst { ++ bits<5> rd; + bits<5> xj; +- bits<5> xd; ++ bits<4> ui4; + +- let Inst{31-0} = op; +- let Inst{19-15} = xa; +- let Inst{14-10} = xk; ++ let Inst{31-14} = op; ++ let Inst{13-10} = ui4; ++ let Inst{9-5} = xj; ++ let Inst{4-0} = rd; ++} ++ ++class LASX_ELM_COPY_D op>: LASXInst { ++ bits<5> rd; ++ bits<5> xj; ++ bits<1> ui1; ++ ++ let Inst{31-11} = op; ++ let Inst{10} = ui1; + let Inst{9-5} = xj; ++ let Inst{4-0} = rd; ++} ++ ++class LASX_Addr_SI8_idx1 op>: LASXInst { ++ bits<5> xd; ++ bits<13> addr; ++ bits<1> idx; ++ ++ let Inst{31-19} = op; ++ let Inst{18-11} = addr{7-0}; ++ let Inst{10} = idx; ++ let Inst{9-5} = addr{12-8}; + let Inst{4-0} = xd; + } ++ ++class LASX_1R_I13_I10 op>: LASXInst { ++ bits<10> i10; ++ bits<5> xd; ++ ++ let Inst{31-15} = op; ++ let Inst{14-5} = i10; ++ let Inst{4-0} = xd; ++} ++ ++ ++ ++ ++ ++ +diff --git a/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td +index 3de1fe2b7..609486d98 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td ++++ b/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td +@@ -1,2002 +1,5528 @@ +-//=- LoongArchLASXInstrInfo.td - LoongArch LASX instructions -*- tablegen -*-=// ++//===- LoongArchLASXInstrInfo.td - loongson LASX instructions -*- tablegen ------------*-=// + // +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// The LLVM Compiler Infrastructure ++// ++// This file is distributed under the University of Illinois Open Source ++// License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // +-// This file describes the Advanced SIMD extension instructions. ++// This file describes loongson ASX instructions. + // + //===----------------------------------------------------------------------===// ++def SDT_XVPERMI : SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisInt<0>, ++ SDTCisSameAs<0, 1>, ++ SDTCisVT<2, i32>]>; ++def SDT_XVSHFI : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisVec<0>, ++ SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, ++ SDTCisVT<3, i32>]>; ++def SDT_XVBROADCAST : SDTypeProfile<1, 1, [SDTCisVec<0>]>; ++ ++def SDT_INSVE : SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisSameAs<0, 1>, ++ SDTCisSameAs<1, 2>, ++ SDTCisVT<3, i32>]>; ++ ++def SDT_XVPICKVE : SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisSameAs<0, 1>, ++ SDTCisSameAs<1, 2>, ++ SDTCisVT<3, i32>]>; ++ ++def SDT_XVSHUF4I : SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisInt<0>, ++ SDTCisSameAs<0, 1>, ++ SDTCisSameAs<0, 2>, ++ SDTCisVT<3, i32>]>; ++ ++def LoongArchXVSHUFI : SDNode<"LoongArchISD::XVSHFI", SDT_XVSHFI>; ++ ++def LoongArchXVSELI : SDNode<"LoongArchISD::XVSELI", SDT_XVSHFI>; ++ ++def LoongArchXVPERMI : SDNode<"LoongArchISD::XVPERMI", SDT_XVPERMI>; ++ ++def LoongArchXVBROADCAST : SDNode<"LoongArchISD::XVBROADCAST", SDT_XVBROADCAST, ++ [SDNPHasChain]>; ++ ++def LoongArchINSVE : SDNode<"LoongArchISD::INSVE", SDT_INSVE>; ++ ++def LoongArchXVSHUF4I : SDNode<"LoongArchISD::XVSHUF4I", SDT_XVSHUF4I>; ++ ++def LoongArchXVPICKVE : SDNode<"LoongArchISD::XVPICKVE", SDT_INSVE>; ++ ++def xvbroadcast_v32i8 : PatFrag<(ops node:$v1), ++ (v32i8 (LoongArchXVBROADCAST node:$v1))>; ++def xvbroadcast_v16i16 : PatFrag<(ops node:$v1), ++ (v16i16 (LoongArchXVBROADCAST node:$v1))>; ++def xvbroadcast_v8i32 : PatFrag<(ops node:$v1), ++ (v8i32 (LoongArchXVBROADCAST node:$v1))>; ++def xvbroadcast_v4i64 : PatFrag<(ops node:$v1), ++ (v4i64 (LoongArchXVBROADCAST node:$v1))>; ++ ++ ++def vfseteq_v8f32 : vfsetcc_type; ++def vfseteq_v4f64 : vfsetcc_type; ++def vfsetge_v8f32 : vfsetcc_type; ++def vfsetge_v4f64 : vfsetcc_type; ++def vfsetgt_v8f32 : vfsetcc_type; ++def vfsetgt_v4f64 : vfsetcc_type; ++def vfsetle_v8f32 : vfsetcc_type; ++def vfsetle_v4f64 : vfsetcc_type; ++def vfsetlt_v8f32 : vfsetcc_type; ++def vfsetlt_v4f64 : vfsetcc_type; ++def vfsetne_v8f32 : vfsetcc_type; ++def vfsetne_v4f64 : vfsetcc_type; ++def vfsetoeq_v8f32 : vfsetcc_type; ++def vfsetoeq_v4f64 : vfsetcc_type; ++def vfsetoge_v8f32 : vfsetcc_type; ++def vfsetoge_v4f64 : vfsetcc_type; ++def vfsetogt_v8f32 : vfsetcc_type; ++def vfsetogt_v4f64 : vfsetcc_type; ++def vfsetole_v8f32 : vfsetcc_type; ++def vfsetole_v4f64 : vfsetcc_type; ++def vfsetolt_v8f32 : vfsetcc_type; ++def vfsetolt_v4f64 : vfsetcc_type; ++def vfsetone_v8f32 : vfsetcc_type; ++def vfsetone_v4f64 : vfsetcc_type; ++def vfsetord_v8f32 : vfsetcc_type; ++def vfsetord_v4f64 : vfsetcc_type; ++def vfsetun_v8f32 : vfsetcc_type; ++def vfsetun_v4f64 : vfsetcc_type; ++def vfsetueq_v8f32 : vfsetcc_type; ++def vfsetueq_v4f64 : vfsetcc_type; ++def vfsetuge_v8f32 : vfsetcc_type; ++def vfsetuge_v4f64 : vfsetcc_type; ++def vfsetugt_v8f32 : vfsetcc_type; ++def vfsetugt_v4f64 : vfsetcc_type; ++def vfsetule_v8f32 : vfsetcc_type; ++def vfsetule_v4f64 : vfsetcc_type; ++def vfsetult_v8f32 : vfsetcc_type; ++def vfsetult_v4f64 : vfsetcc_type; ++def vfsetune_v8f32 : vfsetcc_type; ++def vfsetune_v4f64 : vfsetcc_type; ++ ++def xvsplati8 : PatFrag<(ops node:$e0), ++ (v32i8 (build_vector ++ node:$e0, node:$e0, node:$e0, node:$e0, ++ node:$e0, node:$e0, node:$e0, node:$e0, ++ node:$e0, node:$e0, node:$e0, node:$e0, ++ node:$e0, node:$e0, node:$e0, node:$e0, ++ node:$e0, node:$e0, node:$e0, node:$e0, ++ node:$e0, node:$e0, node:$e0, node:$e0, ++ node:$e0, node:$e0, node:$e0, node:$e0, ++ node:$e0, node:$e0, node:$e0, node:$e0))>; ++def xvsplati16 : PatFrag<(ops node:$e0), ++ (v16i16 (build_vector ++ node:$e0, node:$e0, node:$e0, node:$e0, ++ node:$e0, node:$e0, node:$e0, node:$e0, ++ node:$e0, node:$e0, node:$e0, node:$e0, ++ node:$e0, node:$e0, node:$e0, node:$e0))>; ++def xvsplati32 : PatFrag<(ops node:$e0), ++ (v8i32 (build_vector ++ node:$e0, node:$e0, node:$e0, node:$e0, ++ node:$e0, node:$e0, node:$e0, node:$e0))>; ++def xvsplati64 : PatFrag<(ops node:$e0), ++ (v4i64 (build_vector ++ node:$e0, node:$e0, node:$e0, node:$e0))>; ++def xvsplatf32 : PatFrag<(ops node:$e0), ++ (v8f32 (build_vector node:$e0, node:$e0, ++ node:$e0, node:$e0))>; ++def xvsplatf64 : PatFrag<(ops node:$e0), ++ (v4f64 (build_vector node:$e0, node:$e0))>; ++ ++def xvsplati8_uimm3 : SplatComplexPattern; ++def xvsplati16_uimm4 : SplatComplexPattern; ++ ++def xvsplati64_uimm6 : SplatComplexPattern; ++ ++def xvsplati8_simm5 : SplatComplexPattern; ++def xvsplati16_simm5 : SplatComplexPattern; ++def xvsplati32_simm5 : SplatComplexPattern; ++def xvsplati64_simm5 : SplatComplexPattern; ++ ++def xvsplat_imm_eq_1 : PatLeaf<(build_vector), [{ ++ APInt Imm; ++ EVT EltTy = N->getValueType(0).getVectorElementType(); ++ return selectVSplat(N, Imm, EltTy.getSizeInBits()) && ++ Imm.getBitWidth() == EltTy.getSizeInBits() && Imm == 1; ++}]>; ++ ++def xvsplati64_imm_eq_1 : PatLeaf<(bitconvert (v8i32 (build_vector))), [{ ++ APInt Imm; ++ SDNode *BV = N->getOperand(0).getNode(); ++ EVT EltTy = N->getValueType(0).getVectorElementType(); ++ ++ return selectVSplat(BV, Imm, EltTy.getSizeInBits()) && ++ Imm.getBitWidth() == EltTy.getSizeInBits() && Imm == 1; ++}]>; ++ ++def xvbitclr_b : PatFrag<(ops node:$xk, node:$xa), ++ (and node:$xk, (xor (shl vsplat_imm_eq_1, node:$xa), ++ immAllOnesV))>; ++def xvbitclr_h : PatFrag<(ops node:$xk, node:$xa), ++ (and node:$xk, (xor (shl vsplat_imm_eq_1, node:$xa), ++ immAllOnesV))>; ++def xvbitclr_w : PatFrag<(ops node:$xk, node:$xa), ++ (and node:$xk, (xor (shl vsplat_imm_eq_1, node:$xa), ++ immAllOnesV))>; ++def xvbitclr_d : PatFrag<(ops node:$xk, node:$xa), ++ (and node:$xk, (xor (shl (v4i64 vsplati64_imm_eq_1), ++ node:$xa), ++ (bitconvert (v8i32 immAllOnesV))))>; ++ ++ ++ ++def xvsplati8_uimm5 : SplatComplexPattern; ++def xvsplati16_uimm5 : SplatComplexPattern; ++def xvsplati32_uimm5 : SplatComplexPattern; ++def xvsplati64_uimm5 : SplatComplexPattern; ++def xvsplati8_uimm8 : SplatComplexPattern; ++def xvsplati16_uimm8 : SplatComplexPattern; ++def xvsplati32_uimm8 : SplatComplexPattern; ++def xvsplati64_uimm8 : SplatComplexPattern; ++ ++ ++ ++def xvsplati8_uimm4 : SplatComplexPattern; ++def xvsplati16_uimm3 : SplatComplexPattern; ++def xvsplati32_uimm2 : SplatComplexPattern; ++def xvsplati64_uimm1 : SplatComplexPattern; ++ ++ ++// Patterns. ++class LASXPat pred = [HasLASX]> : ++ Pat, Requires; ++ ++class LASX_4RF { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, ROXK:$xk, ROXA:$xa); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $xk, $xa"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, ROXK:$xk, ROXA:$xa))]; ++} + +-def lasxsplati8 +- : PatFrag<(ops node:$e0), +- (v32i8 (build_vector node:$e0, node:$e0, node:$e0, node:$e0, +- node:$e0, node:$e0, node:$e0, node:$e0, +- node:$e0, node:$e0, node:$e0, node:$e0, +- node:$e0, node:$e0, node:$e0, node:$e0, +- node:$e0, node:$e0, node:$e0, node:$e0, +- node:$e0, node:$e0, node:$e0, node:$e0, +- node:$e0, node:$e0, node:$e0, node:$e0, +- node:$e0, node:$e0, node:$e0, node:$e0))>; +-def lasxsplati16 +- : PatFrag<(ops node:$e0), +- (v16i16 (build_vector node:$e0, node:$e0, node:$e0, node:$e0, +- node:$e0, node:$e0, node:$e0, node:$e0, +- node:$e0, node:$e0, node:$e0, node:$e0, +- node:$e0, node:$e0, node:$e0, node:$e0))>; +-def lasxsplati32 +- : PatFrag<(ops node:$e0), +- (v8i32 (build_vector node:$e0, node:$e0, node:$e0, node:$e0, +- node:$e0, node:$e0, node:$e0, node:$e0))>; +-def lasxsplati64 +- : PatFrag<(ops node:$e0), +- (v4i64 (build_vector node:$e0, node:$e0, node:$e0, node:$e0))>; +-def lasxsplatf32 +- : PatFrag<(ops node:$e0), +- (v8f32 (build_vector node:$e0, node:$e0, node:$e0, node:$e0, +- node:$e0, node:$e0, node:$e0, node:$e0))>; +-def lasxsplatf64 +- : PatFrag<(ops node:$e0), +- (v4f64 (build_vector node:$e0, node:$e0, node:$e0, node:$e0))>; ++class LASX_3RF { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, ROXK:$xk); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $xk"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, ROXK:$xk))]; ++} + +-//===----------------------------------------------------------------------===// +-// Instruction class templates +-//===----------------------------------------------------------------------===// ++class LASX_3R_SETCC_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, ROXK:$xk); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $xk"); ++ list Pattern = [(set ROXD:$xd, (VT (vsetcc ROXJ:$xj, ROXK:$xk, CC)))]; ++} + +-class LASX1RI13_XI op, Operand ImmOpnd = simm13> +- : Fmt1RI13_XI; +- +-class LASX2R_XX op> +- : Fmt2R_XX; +- +-class LASX2R_XR op> +- : Fmt2R_XR; +- +-class LASX2R_CX op> +- : Fmt2R_CX; +- +-class LASX2RI1_XXI op, Operand ImmOpnd = uimm1> +- : Fmt2RI1_XXI; +- +-class LASX2RI2_XXI op, Operand ImmOpnd = uimm2> +- : Fmt2RI2_XXI; +- +-class LASX2RI2_RXI op, Operand ImmOpnd = uimm2> +- : Fmt2RI2_RXI; +- +-class LASX2RI3_XXI op, Operand ImmOpnd = uimm3> +- : Fmt2RI3_XXI; +- +-class LASX2RI3_RXI op, Operand ImmOpnd = uimm3> +- : Fmt2RI3_RXI; +- +-class LASX2RI4_XXI op, Operand ImmOpnd = uimm4> +- : Fmt2RI4_XXI; +- +-class LASX2RI4_XRI op, Operand ImmOpnd = uimm4> +- : Fmt2RI4_XRI; +- +-class LASX2RI4_RXI op, Operand ImmOpnd = uimm4> +- : Fmt2RI4_RXI; +- +-class LASX2RI5_XXI op, Operand ImmOpnd = uimm5> +- : Fmt2RI5_XXI; +- +-class LASX2RI6_XXI op, Operand ImmOpnd = uimm6> +- : Fmt2RI6_XXI; +- +-class LASX2RI8_XXI op, Operand ImmOpnd = uimm8> +- : Fmt2RI8_XXI; +- +-class LASX2RI8I2_XRII op, Operand ImmOpnd = simm8, +- Operand IdxOpnd = uimm2> +- : Fmt2RI8I2_XRII; +-class LASX2RI8I3_XRII op, Operand ImmOpnd = simm8, +- Operand IdxOpnd = uimm3> +- : Fmt2RI8I3_XRII; +-class LASX2RI8I4_XRII op, Operand ImmOpnd = simm8, +- Operand IdxOpnd = uimm4> +- : Fmt2RI8I4_XRII; +-class LASX2RI8I5_XRII op, Operand ImmOpnd = simm8, +- Operand IdxOpnd = uimm5> +- : Fmt2RI8I5_XRII; +- +-class LASX3R_XXX op> +- : Fmt3R_XXX; +- +-class LASX3R_XXR op> +- : Fmt3R_XXR; +- +-class LASX4R_XXXX op> +- : Fmt4R_XXXX; +- +-let Constraints = "$xd = $dst" in { +- +-class LASX2RI2_XXXI op, Operand ImmOpnd = uimm2> +- : Fmt2RI2_XXI; +-class LASX2RI3_XXXI op, Operand ImmOpnd = uimm3> +- : Fmt2RI3_XXI; +- +-class LASX2RI2_XXRI op, Operand ImmOpnd = uimm2> +- : Fmt2RI2_XRI; +-class LASX2RI3_XXRI op, Operand ImmOpnd = uimm3> +- : Fmt2RI3_XRI; +- +-class LASX2RI4_XXXI op, Operand ImmOpnd = uimm4> +- : Fmt2RI4_XXI; +-class LASX2RI5_XXXI op, Operand ImmOpnd = uimm5> +- : Fmt2RI5_XXI; +-class LASX2RI6_XXXI op, Operand ImmOpnd = uimm6> +- : Fmt2RI6_XXI; +-class LASX2RI7_XXXI op, Operand ImmOpnd = uimm7> +- : Fmt2RI7_XXI; +- +-class LASX2RI8_XXXI op, Operand ImmOpnd = uimm8> +- : Fmt2RI8_XXI; +- +-class LASX3R_XXXX op> +- : Fmt3R_XXX; +- +-} // Constraints = "$xd = $dst" +- +-class LASX2RI9_Load op, Operand ImmOpnd = simm9_lsl3> +- : Fmt2RI9_XRI; +-class LASX2RI10_Load op, Operand ImmOpnd = simm10_lsl2> +- : Fmt2RI10_XRI; +-class LASX2RI11_Load op, Operand ImmOpnd = simm11_lsl1> +- : Fmt2RI11_XRI; +-class LASX2RI12_Load op, Operand ImmOpnd = simm12> +- : Fmt2RI12_XRI; +-class LASX2RI12_Store op, Operand ImmOpnd = simm12> +- : Fmt2RI12_XRI; +- +-class LASX3R_Load op> +- : Fmt3R_XRR; +-class LASX3R_Store op> +- : Fmt3R_XRR; ++class LASX_LD { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins MemOpnd:$addr); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $addr"); ++ list Pattern = [(set ROXD:$xd, (TyNode (OpNode Addr:$addr)))]; ++ string DecoderMethod = "DecodeLASX256Mem"; ++} + +-//===----------------------------------------------------------------------===// +-// Instructions +-//===----------------------------------------------------------------------===// ++class LASX_ST { ++ dag OutOperandList = (outs); ++ dag InOperandList = (ins ROXD:$xd, MemOpnd:$addr); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $addr"); ++ list Pattern = [(OpNode (TyNode ROXD:$xd), Addr:$addr)]; ++ string DecoderMethod = "DecodeLASX256Mem"; ++} + +-let hasSideEffects = 0, Predicates = [HasExtLASX] in { +- +-let mayLoad = 0, mayStore = 0 in { +-def XVADD_B : LASX3R_XXX<0x740a0000>; +-def XVADD_H : LASX3R_XXX<0x740a8000>; +-def XVADD_W : LASX3R_XXX<0x740b0000>; +-def XVADD_D : LASX3R_XXX<0x740b8000>; +-def XVADD_Q : LASX3R_XXX<0x752d0000>; +- +-def XVSUB_B : LASX3R_XXX<0x740c0000>; +-def XVSUB_H : LASX3R_XXX<0x740c8000>; +-def XVSUB_W : LASX3R_XXX<0x740d0000>; +-def XVSUB_D : LASX3R_XXX<0x740d8000>; +-def XVSUB_Q : LASX3R_XXX<0x752d8000>; +- +-def XVADDI_BU : LASX2RI5_XXI<0x768a0000>; +-def XVADDI_HU : LASX2RI5_XXI<0x768a8000>; +-def XVADDI_WU : LASX2RI5_XXI<0x768b0000>; +-def XVADDI_DU : LASX2RI5_XXI<0x768b8000>; +- +-def XVSUBI_BU : LASX2RI5_XXI<0x768c0000>; +-def XVSUBI_HU : LASX2RI5_XXI<0x768c8000>; +-def XVSUBI_WU : LASX2RI5_XXI<0x768d0000>; +-def XVSUBI_DU : LASX2RI5_XXI<0x768d8000>; +- +-def XVNEG_B : LASX2R_XX<0x769c3000>; +-def XVNEG_H : LASX2R_XX<0x769c3400>; +-def XVNEG_W : LASX2R_XX<0x769c3800>; +-def XVNEG_D : LASX2R_XX<0x769c3c00>; +- +-def XVSADD_B : LASX3R_XXX<0x74460000>; +-def XVSADD_H : LASX3R_XXX<0x74468000>; +-def XVSADD_W : LASX3R_XXX<0x74470000>; +-def XVSADD_D : LASX3R_XXX<0x74478000>; +-def XVSADD_BU : LASX3R_XXX<0x744a0000>; +-def XVSADD_HU : LASX3R_XXX<0x744a8000>; +-def XVSADD_WU : LASX3R_XXX<0x744b0000>; +-def XVSADD_DU : LASX3R_XXX<0x744b8000>; +- +-def XVSSUB_B : LASX3R_XXX<0x74480000>; +-def XVSSUB_H : LASX3R_XXX<0x74488000>; +-def XVSSUB_W : LASX3R_XXX<0x74490000>; +-def XVSSUB_D : LASX3R_XXX<0x74498000>; +-def XVSSUB_BU : LASX3R_XXX<0x744c0000>; +-def XVSSUB_HU : LASX3R_XXX<0x744c8000>; +-def XVSSUB_WU : LASX3R_XXX<0x744d0000>; +-def XVSSUB_DU : LASX3R_XXX<0x744d8000>; +- +-def XVHADDW_H_B : LASX3R_XXX<0x74540000>; +-def XVHADDW_W_H : LASX3R_XXX<0x74548000>; +-def XVHADDW_D_W : LASX3R_XXX<0x74550000>; +-def XVHADDW_Q_D : LASX3R_XXX<0x74558000>; +-def XVHADDW_HU_BU : LASX3R_XXX<0x74580000>; +-def XVHADDW_WU_HU : LASX3R_XXX<0x74588000>; +-def XVHADDW_DU_WU : LASX3R_XXX<0x74590000>; +-def XVHADDW_QU_DU : LASX3R_XXX<0x74598000>; +- +-def XVHSUBW_H_B : LASX3R_XXX<0x74560000>; +-def XVHSUBW_W_H : LASX3R_XXX<0x74568000>; +-def XVHSUBW_D_W : LASX3R_XXX<0x74570000>; +-def XVHSUBW_Q_D : LASX3R_XXX<0x74578000>; +-def XVHSUBW_HU_BU : LASX3R_XXX<0x745a0000>; +-def XVHSUBW_WU_HU : LASX3R_XXX<0x745a8000>; +-def XVHSUBW_DU_WU : LASX3R_XXX<0x745b0000>; +-def XVHSUBW_QU_DU : LASX3R_XXX<0x745b8000>; +- +-def XVADDWEV_H_B : LASX3R_XXX<0x741e0000>; +-def XVADDWEV_W_H : LASX3R_XXX<0x741e8000>; +-def XVADDWEV_D_W : LASX3R_XXX<0x741f0000>; +-def XVADDWEV_Q_D : LASX3R_XXX<0x741f8000>; +-def XVADDWOD_H_B : LASX3R_XXX<0x74220000>; +-def XVADDWOD_W_H : LASX3R_XXX<0x74228000>; +-def XVADDWOD_D_W : LASX3R_XXX<0x74230000>; +-def XVADDWOD_Q_D : LASX3R_XXX<0x74238000>; +- +-def XVSUBWEV_H_B : LASX3R_XXX<0x74200000>; +-def XVSUBWEV_W_H : LASX3R_XXX<0x74208000>; +-def XVSUBWEV_D_W : LASX3R_XXX<0x74210000>; +-def XVSUBWEV_Q_D : LASX3R_XXX<0x74218000>; +-def XVSUBWOD_H_B : LASX3R_XXX<0x74240000>; +-def XVSUBWOD_W_H : LASX3R_XXX<0x74248000>; +-def XVSUBWOD_D_W : LASX3R_XXX<0x74250000>; +-def XVSUBWOD_Q_D : LASX3R_XXX<0x74258000>; +- +-def XVADDWEV_H_BU : LASX3R_XXX<0x742e0000>; +-def XVADDWEV_W_HU : LASX3R_XXX<0x742e8000>; +-def XVADDWEV_D_WU : LASX3R_XXX<0x742f0000>; +-def XVADDWEV_Q_DU : LASX3R_XXX<0x742f8000>; +-def XVADDWOD_H_BU : LASX3R_XXX<0x74320000>; +-def XVADDWOD_W_HU : LASX3R_XXX<0x74328000>; +-def XVADDWOD_D_WU : LASX3R_XXX<0x74330000>; +-def XVADDWOD_Q_DU : LASX3R_XXX<0x74338000>; +- +-def XVSUBWEV_H_BU : LASX3R_XXX<0x74300000>; +-def XVSUBWEV_W_HU : LASX3R_XXX<0x74308000>; +-def XVSUBWEV_D_WU : LASX3R_XXX<0x74310000>; +-def XVSUBWEV_Q_DU : LASX3R_XXX<0x74318000>; +-def XVSUBWOD_H_BU : LASX3R_XXX<0x74340000>; +-def XVSUBWOD_W_HU : LASX3R_XXX<0x74348000>; +-def XVSUBWOD_D_WU : LASX3R_XXX<0x74350000>; +-def XVSUBWOD_Q_DU : LASX3R_XXX<0x74358000>; +- +-def XVADDWEV_H_BU_B : LASX3R_XXX<0x743e0000>; +-def XVADDWEV_W_HU_H : LASX3R_XXX<0x743e8000>; +-def XVADDWEV_D_WU_W : LASX3R_XXX<0x743f0000>; +-def XVADDWEV_Q_DU_D : LASX3R_XXX<0x743f8000>; +-def XVADDWOD_H_BU_B : LASX3R_XXX<0x74400000>; +-def XVADDWOD_W_HU_H : LASX3R_XXX<0x74408000>; +-def XVADDWOD_D_WU_W : LASX3R_XXX<0x74410000>; +-def XVADDWOD_Q_DU_D : LASX3R_XXX<0x74418000>; +- +-def XVAVG_B : LASX3R_XXX<0x74640000>; +-def XVAVG_H : LASX3R_XXX<0x74648000>; +-def XVAVG_W : LASX3R_XXX<0x74650000>; +-def XVAVG_D : LASX3R_XXX<0x74658000>; +-def XVAVG_BU : LASX3R_XXX<0x74660000>; +-def XVAVG_HU : LASX3R_XXX<0x74668000>; +-def XVAVG_WU : LASX3R_XXX<0x74670000>; +-def XVAVG_DU : LASX3R_XXX<0x74678000>; +-def XVAVGR_B : LASX3R_XXX<0x74680000>; +-def XVAVGR_H : LASX3R_XXX<0x74688000>; +-def XVAVGR_W : LASX3R_XXX<0x74690000>; +-def XVAVGR_D : LASX3R_XXX<0x74698000>; +-def XVAVGR_BU : LASX3R_XXX<0x746a0000>; +-def XVAVGR_HU : LASX3R_XXX<0x746a8000>; +-def XVAVGR_WU : LASX3R_XXX<0x746b0000>; +-def XVAVGR_DU : LASX3R_XXX<0x746b8000>; +- +-def XVABSD_B : LASX3R_XXX<0x74600000>; +-def XVABSD_H : LASX3R_XXX<0x74608000>; +-def XVABSD_W : LASX3R_XXX<0x74610000>; +-def XVABSD_D : LASX3R_XXX<0x74618000>; +-def XVABSD_BU : LASX3R_XXX<0x74620000>; +-def XVABSD_HU : LASX3R_XXX<0x74628000>; +-def XVABSD_WU : LASX3R_XXX<0x74630000>; +-def XVABSD_DU : LASX3R_XXX<0x74638000>; +- +-def XVADDA_B : LASX3R_XXX<0x745c0000>; +-def XVADDA_H : LASX3R_XXX<0x745c8000>; +-def XVADDA_W : LASX3R_XXX<0x745d0000>; +-def XVADDA_D : LASX3R_XXX<0x745d8000>; +- +-def XVMAX_B : LASX3R_XXX<0x74700000>; +-def XVMAX_H : LASX3R_XXX<0x74708000>; +-def XVMAX_W : LASX3R_XXX<0x74710000>; +-def XVMAX_D : LASX3R_XXX<0x74718000>; +-def XVMAXI_B : LASX2RI5_XXI<0x76900000, simm5>; +-def XVMAXI_H : LASX2RI5_XXI<0x76908000, simm5>; +-def XVMAXI_W : LASX2RI5_XXI<0x76910000, simm5>; +-def XVMAXI_D : LASX2RI5_XXI<0x76918000, simm5>; +-def XVMAX_BU : LASX3R_XXX<0x74740000>; +-def XVMAX_HU : LASX3R_XXX<0x74748000>; +-def XVMAX_WU : LASX3R_XXX<0x74750000>; +-def XVMAX_DU : LASX3R_XXX<0x74758000>; +-def XVMAXI_BU : LASX2RI5_XXI<0x76940000>; +-def XVMAXI_HU : LASX2RI5_XXI<0x76948000>; +-def XVMAXI_WU : LASX2RI5_XXI<0x76950000>; +-def XVMAXI_DU : LASX2RI5_XXI<0x76958000>; +- +-def XVMIN_B : LASX3R_XXX<0x74720000>; +-def XVMIN_H : LASX3R_XXX<0x74728000>; +-def XVMIN_W : LASX3R_XXX<0x74730000>; +-def XVMIN_D : LASX3R_XXX<0x74738000>; +-def XVMINI_B : LASX2RI5_XXI<0x76920000, simm5>; +-def XVMINI_H : LASX2RI5_XXI<0x76928000, simm5>; +-def XVMINI_W : LASX2RI5_XXI<0x76930000, simm5>; +-def XVMINI_D : LASX2RI5_XXI<0x76938000, simm5>; +-def XVMIN_BU : LASX3R_XXX<0x74760000>; +-def XVMIN_HU : LASX3R_XXX<0x74768000>; +-def XVMIN_WU : LASX3R_XXX<0x74770000>; +-def XVMIN_DU : LASX3R_XXX<0x74778000>; +-def XVMINI_BU : LASX2RI5_XXI<0x76960000>; +-def XVMINI_HU : LASX2RI5_XXI<0x76968000>; +-def XVMINI_WU : LASX2RI5_XXI<0x76970000>; +-def XVMINI_DU : LASX2RI5_XXI<0x76978000>; +- +-def XVMUL_B : LASX3R_XXX<0x74840000>; +-def XVMUL_H : LASX3R_XXX<0x74848000>; +-def XVMUL_W : LASX3R_XXX<0x74850000>; +-def XVMUL_D : LASX3R_XXX<0x74858000>; +- +-def XVMUH_B : LASX3R_XXX<0x74860000>; +-def XVMUH_H : LASX3R_XXX<0x74868000>; +-def XVMUH_W : LASX3R_XXX<0x74870000>; +-def XVMUH_D : LASX3R_XXX<0x74878000>; +-def XVMUH_BU : LASX3R_XXX<0x74880000>; +-def XVMUH_HU : LASX3R_XXX<0x74888000>; +-def XVMUH_WU : LASX3R_XXX<0x74890000>; +-def XVMUH_DU : LASX3R_XXX<0x74898000>; +- +-def XVMULWEV_H_B : LASX3R_XXX<0x74900000>; +-def XVMULWEV_W_H : LASX3R_XXX<0x74908000>; +-def XVMULWEV_D_W : LASX3R_XXX<0x74910000>; +-def XVMULWEV_Q_D : LASX3R_XXX<0x74918000>; +-def XVMULWOD_H_B : LASX3R_XXX<0x74920000>; +-def XVMULWOD_W_H : LASX3R_XXX<0x74928000>; +-def XVMULWOD_D_W : LASX3R_XXX<0x74930000>; +-def XVMULWOD_Q_D : LASX3R_XXX<0x74938000>; +-def XVMULWEV_H_BU : LASX3R_XXX<0x74980000>; +-def XVMULWEV_W_HU : LASX3R_XXX<0x74988000>; +-def XVMULWEV_D_WU : LASX3R_XXX<0x74990000>; +-def XVMULWEV_Q_DU : LASX3R_XXX<0x74998000>; +-def XVMULWOD_H_BU : LASX3R_XXX<0x749a0000>; +-def XVMULWOD_W_HU : LASX3R_XXX<0x749a8000>; +-def XVMULWOD_D_WU : LASX3R_XXX<0x749b0000>; +-def XVMULWOD_Q_DU : LASX3R_XXX<0x749b8000>; +-def XVMULWEV_H_BU_B : LASX3R_XXX<0x74a00000>; +-def XVMULWEV_W_HU_H : LASX3R_XXX<0x74a08000>; +-def XVMULWEV_D_WU_W : LASX3R_XXX<0x74a10000>; +-def XVMULWEV_Q_DU_D : LASX3R_XXX<0x74a18000>; +-def XVMULWOD_H_BU_B : LASX3R_XXX<0x74a20000>; +-def XVMULWOD_W_HU_H : LASX3R_XXX<0x74a28000>; +-def XVMULWOD_D_WU_W : LASX3R_XXX<0x74a30000>; +-def XVMULWOD_Q_DU_D : LASX3R_XXX<0x74a38000>; +- +-def XVMADD_B : LASX3R_XXXX<0x74a80000>; +-def XVMADD_H : LASX3R_XXXX<0x74a88000>; +-def XVMADD_W : LASX3R_XXXX<0x74a90000>; +-def XVMADD_D : LASX3R_XXXX<0x74a98000>; +- +-def XVMSUB_B : LASX3R_XXXX<0x74aa0000>; +-def XVMSUB_H : LASX3R_XXXX<0x74aa8000>; +-def XVMSUB_W : LASX3R_XXXX<0x74ab0000>; +-def XVMSUB_D : LASX3R_XXXX<0x74ab8000>; +- +-def XVMADDWEV_H_B : LASX3R_XXXX<0x74ac0000>; +-def XVMADDWEV_W_H : LASX3R_XXXX<0x74ac8000>; +-def XVMADDWEV_D_W : LASX3R_XXXX<0x74ad0000>; +-def XVMADDWEV_Q_D : LASX3R_XXXX<0x74ad8000>; +-def XVMADDWOD_H_B : LASX3R_XXXX<0x74ae0000>; +-def XVMADDWOD_W_H : LASX3R_XXXX<0x74ae8000>; +-def XVMADDWOD_D_W : LASX3R_XXXX<0x74af0000>; +-def XVMADDWOD_Q_D : LASX3R_XXXX<0x74af8000>; +-def XVMADDWEV_H_BU : LASX3R_XXXX<0x74b40000>; +-def XVMADDWEV_W_HU : LASX3R_XXXX<0x74b48000>; +-def XVMADDWEV_D_WU : LASX3R_XXXX<0x74b50000>; +-def XVMADDWEV_Q_DU : LASX3R_XXXX<0x74b58000>; +-def XVMADDWOD_H_BU : LASX3R_XXXX<0x74b60000>; +-def XVMADDWOD_W_HU : LASX3R_XXXX<0x74b68000>; +-def XVMADDWOD_D_WU : LASX3R_XXXX<0x74b70000>; +-def XVMADDWOD_Q_DU : LASX3R_XXXX<0x74b78000>; +-def XVMADDWEV_H_BU_B : LASX3R_XXXX<0x74bc0000>; +-def XVMADDWEV_W_HU_H : LASX3R_XXXX<0x74bc8000>; +-def XVMADDWEV_D_WU_W : LASX3R_XXXX<0x74bd0000>; +-def XVMADDWEV_Q_DU_D : LASX3R_XXXX<0x74bd8000>; +-def XVMADDWOD_H_BU_B : LASX3R_XXXX<0x74be0000>; +-def XVMADDWOD_W_HU_H : LASX3R_XXXX<0x74be8000>; +-def XVMADDWOD_D_WU_W : LASX3R_XXXX<0x74bf0000>; +-def XVMADDWOD_Q_DU_D : LASX3R_XXXX<0x74bf8000>; +- +-def XVDIV_B : LASX3R_XXX<0x74e00000>; +-def XVDIV_H : LASX3R_XXX<0x74e08000>; +-def XVDIV_W : LASX3R_XXX<0x74e10000>; +-def XVDIV_D : LASX3R_XXX<0x74e18000>; +-def XVDIV_BU : LASX3R_XXX<0x74e40000>; +-def XVDIV_HU : LASX3R_XXX<0x74e48000>; +-def XVDIV_WU : LASX3R_XXX<0x74e50000>; +-def XVDIV_DU : LASX3R_XXX<0x74e58000>; +- +-def XVMOD_B : LASX3R_XXX<0x74e20000>; +-def XVMOD_H : LASX3R_XXX<0x74e28000>; +-def XVMOD_W : LASX3R_XXX<0x74e30000>; +-def XVMOD_D : LASX3R_XXX<0x74e38000>; +-def XVMOD_BU : LASX3R_XXX<0x74e60000>; +-def XVMOD_HU : LASX3R_XXX<0x74e68000>; +-def XVMOD_WU : LASX3R_XXX<0x74e70000>; +-def XVMOD_DU : LASX3R_XXX<0x74e78000>; +- +-def XVSAT_B : LASX2RI3_XXI<0x77242000>; +-def XVSAT_H : LASX2RI4_XXI<0x77244000>; +-def XVSAT_W : LASX2RI5_XXI<0x77248000>; +-def XVSAT_D : LASX2RI6_XXI<0x77250000>; +-def XVSAT_BU : LASX2RI3_XXI<0x77282000>; +-def XVSAT_HU : LASX2RI4_XXI<0x77284000>; +-def XVSAT_WU : LASX2RI5_XXI<0x77288000>; +-def XVSAT_DU : LASX2RI6_XXI<0x77290000>; +- +-def XVEXTH_H_B : LASX2R_XX<0x769ee000>; +-def XVEXTH_W_H : LASX2R_XX<0x769ee400>; +-def XVEXTH_D_W : LASX2R_XX<0x769ee800>; +-def XVEXTH_Q_D : LASX2R_XX<0x769eec00>; +-def XVEXTH_HU_BU : LASX2R_XX<0x769ef000>; +-def XVEXTH_WU_HU : LASX2R_XX<0x769ef400>; +-def XVEXTH_DU_WU : LASX2R_XX<0x769ef800>; +-def XVEXTH_QU_DU : LASX2R_XX<0x769efc00>; +- +-def VEXT2XV_H_B : LASX2R_XX<0x769f1000>; +-def VEXT2XV_W_B : LASX2R_XX<0x769f1400>; +-def VEXT2XV_D_B : LASX2R_XX<0x769f1800>; +-def VEXT2XV_W_H : LASX2R_XX<0x769f1c00>; +-def VEXT2XV_D_H : LASX2R_XX<0x769f2000>; +-def VEXT2XV_D_W : LASX2R_XX<0x769f2400>; +-def VEXT2XV_HU_BU : LASX2R_XX<0x769f2800>; +-def VEXT2XV_WU_BU : LASX2R_XX<0x769f2c00>; +-def VEXT2XV_DU_BU : LASX2R_XX<0x769f3000>; +-def VEXT2XV_WU_HU : LASX2R_XX<0x769f3400>; +-def VEXT2XV_DU_HU : LASX2R_XX<0x769f3800>; +-def VEXT2XV_DU_WU : LASX2R_XX<0x769f3c00>; +- +-def XVHSELI_D : LASX2RI5_XXI<0x769f8000>; +- +-def XVSIGNCOV_B : LASX3R_XXX<0x752e0000>; +-def XVSIGNCOV_H : LASX3R_XXX<0x752e8000>; +-def XVSIGNCOV_W : LASX3R_XXX<0x752f0000>; +-def XVSIGNCOV_D : LASX3R_XXX<0x752f8000>; +- +-def XVMSKLTZ_B : LASX2R_XX<0x769c4000>; +-def XVMSKLTZ_H : LASX2R_XX<0x769c4400>; +-def XVMSKLTZ_W : LASX2R_XX<0x769c4800>; +-def XVMSKLTZ_D : LASX2R_XX<0x769c4c00>; +- +-def XVMSKGEZ_B : LASX2R_XX<0x769c5000>; +- +-def XVMSKNZ_B : LASX2R_XX<0x769c6000>; +- +-def XVLDI : LASX1RI13_XI<0x77e00000>; +- +-def XVAND_V : LASX3R_XXX<0x75260000>; +-def XVOR_V : LASX3R_XXX<0x75268000>; +-def XVXOR_V : LASX3R_XXX<0x75270000>; +-def XVNOR_V : LASX3R_XXX<0x75278000>; +-def XVANDN_V : LASX3R_XXX<0x75280000>; +-def XVORN_V : LASX3R_XXX<0x75288000>; +- +-def XVANDI_B : LASX2RI8_XXI<0x77d00000>; +-def XVORI_B : LASX2RI8_XXI<0x77d40000>; +-def XVXORI_B : LASX2RI8_XXI<0x77d80000>; +-def XVNORI_B : LASX2RI8_XXI<0x77dc0000>; +- +-def XVSLL_B : LASX3R_XXX<0x74e80000>; +-def XVSLL_H : LASX3R_XXX<0x74e88000>; +-def XVSLL_W : LASX3R_XXX<0x74e90000>; +-def XVSLL_D : LASX3R_XXX<0x74e98000>; +-def XVSLLI_B : LASX2RI3_XXI<0x772c2000>; +-def XVSLLI_H : LASX2RI4_XXI<0x772c4000>; +-def XVSLLI_W : LASX2RI5_XXI<0x772c8000>; +-def XVSLLI_D : LASX2RI6_XXI<0x772d0000>; +- +-def XVSRL_B : LASX3R_XXX<0x74ea0000>; +-def XVSRL_H : LASX3R_XXX<0x74ea8000>; +-def XVSRL_W : LASX3R_XXX<0x74eb0000>; +-def XVSRL_D : LASX3R_XXX<0x74eb8000>; +-def XVSRLI_B : LASX2RI3_XXI<0x77302000>; +-def XVSRLI_H : LASX2RI4_XXI<0x77304000>; +-def XVSRLI_W : LASX2RI5_XXI<0x77308000>; +-def XVSRLI_D : LASX2RI6_XXI<0x77310000>; +- +-def XVSRA_B : LASX3R_XXX<0x74ec0000>; +-def XVSRA_H : LASX3R_XXX<0x74ec8000>; +-def XVSRA_W : LASX3R_XXX<0x74ed0000>; +-def XVSRA_D : LASX3R_XXX<0x74ed8000>; +-def XVSRAI_B : LASX2RI3_XXI<0x77342000>; +-def XVSRAI_H : LASX2RI4_XXI<0x77344000>; +-def XVSRAI_W : LASX2RI5_XXI<0x77348000>; +-def XVSRAI_D : LASX2RI6_XXI<0x77350000>; +- +-def XVROTR_B : LASX3R_XXX<0x74ee0000>; +-def XVROTR_H : LASX3R_XXX<0x74ee8000>; +-def XVROTR_W : LASX3R_XXX<0x74ef0000>; +-def XVROTR_D : LASX3R_XXX<0x74ef8000>; +-def XVROTRI_B : LASX2RI3_XXI<0x76a02000>; +-def XVROTRI_H : LASX2RI4_XXI<0x76a04000>; +-def XVROTRI_W : LASX2RI5_XXI<0x76a08000>; +-def XVROTRI_D : LASX2RI6_XXI<0x76a10000>; +- +-def XVSLLWIL_H_B : LASX2RI3_XXI<0x77082000>; +-def XVSLLWIL_W_H : LASX2RI4_XXI<0x77084000>; +-def XVSLLWIL_D_W : LASX2RI5_XXI<0x77088000>; +-def XVEXTL_Q_D : LASX2R_XX<0x77090000>; +-def XVSLLWIL_HU_BU : LASX2RI3_XXI<0x770c2000>; +-def XVSLLWIL_WU_HU : LASX2RI4_XXI<0x770c4000>; +-def XVSLLWIL_DU_WU : LASX2RI5_XXI<0x770c8000>; +-def XVEXTL_QU_DU : LASX2R_XX<0x770d0000>; +- +-def XVSRLR_B : LASX3R_XXX<0x74f00000>; +-def XVSRLR_H : LASX3R_XXX<0x74f08000>; +-def XVSRLR_W : LASX3R_XXX<0x74f10000>; +-def XVSRLR_D : LASX3R_XXX<0x74f18000>; +-def XVSRLRI_B : LASX2RI3_XXI<0x76a42000>; +-def XVSRLRI_H : LASX2RI4_XXI<0x76a44000>; +-def XVSRLRI_W : LASX2RI5_XXI<0x76a48000>; +-def XVSRLRI_D : LASX2RI6_XXI<0x76a50000>; +- +-def XVSRAR_B : LASX3R_XXX<0x74f20000>; +-def XVSRAR_H : LASX3R_XXX<0x74f28000>; +-def XVSRAR_W : LASX3R_XXX<0x74f30000>; +-def XVSRAR_D : LASX3R_XXX<0x74f38000>; +-def XVSRARI_B : LASX2RI3_XXI<0x76a82000>; +-def XVSRARI_H : LASX2RI4_XXI<0x76a84000>; +-def XVSRARI_W : LASX2RI5_XXI<0x76a88000>; +-def XVSRARI_D : LASX2RI6_XXI<0x76a90000>; +- +-def XVSRLN_B_H : LASX3R_XXX<0x74f48000>; +-def XVSRLN_H_W : LASX3R_XXX<0x74f50000>; +-def XVSRLN_W_D : LASX3R_XXX<0x74f58000>; +-def XVSRAN_B_H : LASX3R_XXX<0x74f68000>; +-def XVSRAN_H_W : LASX3R_XXX<0x74f70000>; +-def XVSRAN_W_D : LASX3R_XXX<0x74f78000>; +- +-def XVSRLNI_B_H : LASX2RI4_XXXI<0x77404000>; +-def XVSRLNI_H_W : LASX2RI5_XXXI<0x77408000>; +-def XVSRLNI_W_D : LASX2RI6_XXXI<0x77410000>; +-def XVSRLNI_D_Q : LASX2RI7_XXXI<0x77420000>; +-def XVSRANI_B_H : LASX2RI4_XXXI<0x77584000>; +-def XVSRANI_H_W : LASX2RI5_XXXI<0x77588000>; +-def XVSRANI_W_D : LASX2RI6_XXXI<0x77590000>; +-def XVSRANI_D_Q : LASX2RI7_XXXI<0x775a0000>; +- +-def XVSRLRN_B_H : LASX3R_XXX<0x74f88000>; +-def XVSRLRN_H_W : LASX3R_XXX<0x74f90000>; +-def XVSRLRN_W_D : LASX3R_XXX<0x74f98000>; +-def XVSRARN_B_H : LASX3R_XXX<0x74fa8000>; +-def XVSRARN_H_W : LASX3R_XXX<0x74fb0000>; +-def XVSRARN_W_D : LASX3R_XXX<0x74fb8000>; +- +-def XVSRLRNI_B_H : LASX2RI4_XXXI<0x77444000>; +-def XVSRLRNI_H_W : LASX2RI5_XXXI<0x77448000>; +-def XVSRLRNI_W_D : LASX2RI6_XXXI<0x77450000>; +-def XVSRLRNI_D_Q : LASX2RI7_XXXI<0x77460000>; +-def XVSRARNI_B_H : LASX2RI4_XXXI<0x775c4000>; +-def XVSRARNI_H_W : LASX2RI5_XXXI<0x775c8000>; +-def XVSRARNI_W_D : LASX2RI6_XXXI<0x775d0000>; +-def XVSRARNI_D_Q : LASX2RI7_XXXI<0x775e0000>; +- +-def XVSSRLN_B_H : LASX3R_XXX<0x74fc8000>; +-def XVSSRLN_H_W : LASX3R_XXX<0x74fd0000>; +-def XVSSRLN_W_D : LASX3R_XXX<0x74fd8000>; +-def XVSSRAN_B_H : LASX3R_XXX<0x74fe8000>; +-def XVSSRAN_H_W : LASX3R_XXX<0x74ff0000>; +-def XVSSRAN_W_D : LASX3R_XXX<0x74ff8000>; +-def XVSSRLN_BU_H : LASX3R_XXX<0x75048000>; +-def XVSSRLN_HU_W : LASX3R_XXX<0x75050000>; +-def XVSSRLN_WU_D : LASX3R_XXX<0x75058000>; +-def XVSSRAN_BU_H : LASX3R_XXX<0x75068000>; +-def XVSSRAN_HU_W : LASX3R_XXX<0x75070000>; +-def XVSSRAN_WU_D : LASX3R_XXX<0x75078000>; +- +-def XVSSRLNI_B_H : LASX2RI4_XXXI<0x77484000>; +-def XVSSRLNI_H_W : LASX2RI5_XXXI<0x77488000>; +-def XVSSRLNI_W_D : LASX2RI6_XXXI<0x77490000>; +-def XVSSRLNI_D_Q : LASX2RI7_XXXI<0x774a0000>; +-def XVSSRANI_B_H : LASX2RI4_XXXI<0x77604000>; +-def XVSSRANI_H_W : LASX2RI5_XXXI<0x77608000>; +-def XVSSRANI_W_D : LASX2RI6_XXXI<0x77610000>; +-def XVSSRANI_D_Q : LASX2RI7_XXXI<0x77620000>; +-def XVSSRLNI_BU_H : LASX2RI4_XXXI<0x774c4000>; +-def XVSSRLNI_HU_W : LASX2RI5_XXXI<0x774c8000>; +-def XVSSRLNI_WU_D : LASX2RI6_XXXI<0x774d0000>; +-def XVSSRLNI_DU_Q : LASX2RI7_XXXI<0x774e0000>; +-def XVSSRANI_BU_H : LASX2RI4_XXXI<0x77644000>; +-def XVSSRANI_HU_W : LASX2RI5_XXXI<0x77648000>; +-def XVSSRANI_WU_D : LASX2RI6_XXXI<0x77650000>; +-def XVSSRANI_DU_Q : LASX2RI7_XXXI<0x77660000>; +- +-def XVSSRLRN_B_H : LASX3R_XXX<0x75008000>; +-def XVSSRLRN_H_W : LASX3R_XXX<0x75010000>; +-def XVSSRLRN_W_D : LASX3R_XXX<0x75018000>; +-def XVSSRARN_B_H : LASX3R_XXX<0x75028000>; +-def XVSSRARN_H_W : LASX3R_XXX<0x75030000>; +-def XVSSRARN_W_D : LASX3R_XXX<0x75038000>; +-def XVSSRLRN_BU_H : LASX3R_XXX<0x75088000>; +-def XVSSRLRN_HU_W : LASX3R_XXX<0x75090000>; +-def XVSSRLRN_WU_D : LASX3R_XXX<0x75098000>; +-def XVSSRARN_BU_H : LASX3R_XXX<0x750a8000>; +-def XVSSRARN_HU_W : LASX3R_XXX<0x750b0000>; +-def XVSSRARN_WU_D : LASX3R_XXX<0x750b8000>; +- +-def XVSSRLRNI_B_H : LASX2RI4_XXXI<0x77504000>; +-def XVSSRLRNI_H_W : LASX2RI5_XXXI<0x77508000>; +-def XVSSRLRNI_W_D : LASX2RI6_XXXI<0x77510000>; +-def XVSSRLRNI_D_Q : LASX2RI7_XXXI<0x77520000>; +-def XVSSRARNI_B_H : LASX2RI4_XXXI<0x77684000>; +-def XVSSRARNI_H_W : LASX2RI5_XXXI<0x77688000>; +-def XVSSRARNI_W_D : LASX2RI6_XXXI<0x77690000>; +-def XVSSRARNI_D_Q : LASX2RI7_XXXI<0x776a0000>; +-def XVSSRLRNI_BU_H : LASX2RI4_XXXI<0x77544000>; +-def XVSSRLRNI_HU_W : LASX2RI5_XXXI<0x77548000>; +-def XVSSRLRNI_WU_D : LASX2RI6_XXXI<0x77550000>; +-def XVSSRLRNI_DU_Q : LASX2RI7_XXXI<0x77560000>; +-def XVSSRARNI_BU_H : LASX2RI4_XXXI<0x776c4000>; +-def XVSSRARNI_HU_W : LASX2RI5_XXXI<0x776c8000>; +-def XVSSRARNI_WU_D : LASX2RI6_XXXI<0x776d0000>; +-def XVSSRARNI_DU_Q : LASX2RI7_XXXI<0x776e0000>; +- +-def XVCLO_B : LASX2R_XX<0x769c0000>; +-def XVCLO_H : LASX2R_XX<0x769c0400>; +-def XVCLO_W : LASX2R_XX<0x769c0800>; +-def XVCLO_D : LASX2R_XX<0x769c0c00>; +-def XVCLZ_B : LASX2R_XX<0x769c1000>; +-def XVCLZ_H : LASX2R_XX<0x769c1400>; +-def XVCLZ_W : LASX2R_XX<0x769c1800>; +-def XVCLZ_D : LASX2R_XX<0x769c1c00>; +- +-def XVPCNT_B : LASX2R_XX<0x769c2000>; +-def XVPCNT_H : LASX2R_XX<0x769c2400>; +-def XVPCNT_W : LASX2R_XX<0x769c2800>; +-def XVPCNT_D : LASX2R_XX<0x769c2c00>; +- +-def XVBITCLR_B : LASX3R_XXX<0x750c0000>; +-def XVBITCLR_H : LASX3R_XXX<0x750c8000>; +-def XVBITCLR_W : LASX3R_XXX<0x750d0000>; +-def XVBITCLR_D : LASX3R_XXX<0x750d8000>; +-def XVBITCLRI_B : LASX2RI3_XXI<0x77102000>; +-def XVBITCLRI_H : LASX2RI4_XXI<0x77104000>; +-def XVBITCLRI_W : LASX2RI5_XXI<0x77108000>; +-def XVBITCLRI_D : LASX2RI6_XXI<0x77110000>; +- +-def XVBITSET_B : LASX3R_XXX<0x750e0000>; +-def XVBITSET_H : LASX3R_XXX<0x750e8000>; +-def XVBITSET_W : LASX3R_XXX<0x750f0000>; +-def XVBITSET_D : LASX3R_XXX<0x750f8000>; +-def XVBITSETI_B : LASX2RI3_XXI<0x77142000>; +-def XVBITSETI_H : LASX2RI4_XXI<0x77144000>; +-def XVBITSETI_W : LASX2RI5_XXI<0x77148000>; +-def XVBITSETI_D : LASX2RI6_XXI<0x77150000>; +- +-def XVBITREV_B : LASX3R_XXX<0x75100000>; +-def XVBITREV_H : LASX3R_XXX<0x75108000>; +-def XVBITREV_W : LASX3R_XXX<0x75110000>; +-def XVBITREV_D : LASX3R_XXX<0x75118000>; +-def XVBITREVI_B : LASX2RI3_XXI<0x77182000>; +-def XVBITREVI_H : LASX2RI4_XXI<0x77184000>; +-def XVBITREVI_W : LASX2RI5_XXI<0x77188000>; +-def XVBITREVI_D : LASX2RI6_XXI<0x77190000>; +- +-def XVFRSTP_B : LASX3R_XXXX<0x752b0000>; +-def XVFRSTP_H : LASX3R_XXXX<0x752b8000>; +-def XVFRSTPI_B : LASX2RI5_XXXI<0x769a0000>; +-def XVFRSTPI_H : LASX2RI5_XXXI<0x769a8000>; +- +-def XVFADD_S : LASX3R_XXX<0x75308000>; +-def XVFADD_D : LASX3R_XXX<0x75310000>; +-def XVFSUB_S : LASX3R_XXX<0x75328000>; +-def XVFSUB_D : LASX3R_XXX<0x75330000>; +-def XVFMUL_S : LASX3R_XXX<0x75388000>; +-def XVFMUL_D : LASX3R_XXX<0x75390000>; +-def XVFDIV_S : LASX3R_XXX<0x753a8000>; +-def XVFDIV_D : LASX3R_XXX<0x753b0000>; +- +-def XVFMADD_S : LASX4R_XXXX<0x0a100000>; +-def XVFMADD_D : LASX4R_XXXX<0x0a200000>; +-def XVFMSUB_S : LASX4R_XXXX<0x0a500000>; +-def XVFMSUB_D : LASX4R_XXXX<0x0a600000>; +-def XVFNMADD_S : LASX4R_XXXX<0x0a900000>; +-def XVFNMADD_D : LASX4R_XXXX<0x0aa00000>; +-def XVFNMSUB_S : LASX4R_XXXX<0x0ad00000>; +-def XVFNMSUB_D : LASX4R_XXXX<0x0ae00000>; +- +-def XVFMAX_S : LASX3R_XXX<0x753c8000>; +-def XVFMAX_D : LASX3R_XXX<0x753d0000>; +-def XVFMIN_S : LASX3R_XXX<0x753e8000>; +-def XVFMIN_D : LASX3R_XXX<0x753f0000>; +- +-def XVFMAXA_S : LASX3R_XXX<0x75408000>; +-def XVFMAXA_D : LASX3R_XXX<0x75410000>; +-def XVFMINA_S : LASX3R_XXX<0x75428000>; +-def XVFMINA_D : LASX3R_XXX<0x75430000>; +- +-def XVFLOGB_S : LASX2R_XX<0x769cc400>; +-def XVFLOGB_D : LASX2R_XX<0x769cc800>; +- +-def XVFCLASS_S : LASX2R_XX<0x769cd400>; +-def XVFCLASS_D : LASX2R_XX<0x769cd800>; +- +-def XVFSQRT_S : LASX2R_XX<0x769ce400>; +-def XVFSQRT_D : LASX2R_XX<0x769ce800>; +-def XVFRECIP_S : LASX2R_XX<0x769cf400>; +-def XVFRECIP_D : LASX2R_XX<0x769cf800>; +-def XVFRSQRT_S : LASX2R_XX<0x769d0400>; +-def XVFRSQRT_D : LASX2R_XX<0x769d0800>; +-def XVFRECIPE_S : LASX2R_XX<0x769d1400>; +-def XVFRECIPE_D : LASX2R_XX<0x769d1800>; +-def XVFRSQRTE_S : LASX2R_XX<0x769d2400>; +-def XVFRSQRTE_D : LASX2R_XX<0x769d2800>; +- +-def XVFCVTL_S_H : LASX2R_XX<0x769de800>; +-def XVFCVTH_S_H : LASX2R_XX<0x769dec00>; +-def XVFCVTL_D_S : LASX2R_XX<0x769df000>; +-def XVFCVTH_D_S : LASX2R_XX<0x769df400>; +-def XVFCVT_H_S : LASX3R_XXX<0x75460000>; +-def XVFCVT_S_D : LASX3R_XXX<0x75468000>; +- +-def XVFRINTRNE_S : LASX2R_XX<0x769d7400>; +-def XVFRINTRNE_D : LASX2R_XX<0x769d7800>; +-def XVFRINTRZ_S : LASX2R_XX<0x769d6400>; +-def XVFRINTRZ_D : LASX2R_XX<0x769d6800>; +-def XVFRINTRP_S : LASX2R_XX<0x769d5400>; +-def XVFRINTRP_D : LASX2R_XX<0x769d5800>; +-def XVFRINTRM_S : LASX2R_XX<0x769d4400>; +-def XVFRINTRM_D : LASX2R_XX<0x769d4800>; +-def XVFRINT_S : LASX2R_XX<0x769d3400>; +-def XVFRINT_D : LASX2R_XX<0x769d3800>; +- +-def XVFTINTRNE_W_S : LASX2R_XX<0x769e5000>; +-def XVFTINTRNE_L_D : LASX2R_XX<0x769e5400>; +-def XVFTINTRZ_W_S : LASX2R_XX<0x769e4800>; +-def XVFTINTRZ_L_D : LASX2R_XX<0x769e4c00>; +-def XVFTINTRP_W_S : LASX2R_XX<0x769e4000>; +-def XVFTINTRP_L_D : LASX2R_XX<0x769e4400>; +-def XVFTINTRM_W_S : LASX2R_XX<0x769e3800>; +-def XVFTINTRM_L_D : LASX2R_XX<0x769e3c00>; +-def XVFTINT_W_S : LASX2R_XX<0x769e3000>; +-def XVFTINT_L_D : LASX2R_XX<0x769e3400>; +-def XVFTINTRZ_WU_S : LASX2R_XX<0x769e7000>; +-def XVFTINTRZ_LU_D : LASX2R_XX<0x769e7400>; +-def XVFTINT_WU_S : LASX2R_XX<0x769e5800>; +-def XVFTINT_LU_D : LASX2R_XX<0x769e5c00>; +- +-def XVFTINTRNE_W_D : LASX3R_XXX<0x754b8000>; +-def XVFTINTRZ_W_D : LASX3R_XXX<0x754b0000>; +-def XVFTINTRP_W_D : LASX3R_XXX<0x754a8000>; +-def XVFTINTRM_W_D : LASX3R_XXX<0x754a0000>; +-def XVFTINT_W_D : LASX3R_XXX<0x75498000>; +- +-def XVFTINTRNEL_L_S : LASX2R_XX<0x769ea000>; +-def XVFTINTRNEH_L_S : LASX2R_XX<0x769ea400>; +-def XVFTINTRZL_L_S : LASX2R_XX<0x769e9800>; +-def XVFTINTRZH_L_S : LASX2R_XX<0x769e9c00>; +-def XVFTINTRPL_L_S : LASX2R_XX<0x769e9000>; +-def XVFTINTRPH_L_S : LASX2R_XX<0x769e9400>; +-def XVFTINTRML_L_S : LASX2R_XX<0x769e8800>; +-def XVFTINTRMH_L_S : LASX2R_XX<0x769e8c00>; +-def XVFTINTL_L_S : LASX2R_XX<0x769e8000>; +-def XVFTINTH_L_S : LASX2R_XX<0x769e8400>; +- +-def XVFFINT_S_W : LASX2R_XX<0x769e0000>; +-def XVFFINT_D_L : LASX2R_XX<0x769e0800>; +-def XVFFINT_S_WU : LASX2R_XX<0x769e0400>; +-def XVFFINT_D_LU : LASX2R_XX<0x769e0c00>; +-def XVFFINTL_D_W : LASX2R_XX<0x769e1000>; +-def XVFFINTH_D_W : LASX2R_XX<0x769e1400>; +-def XVFFINT_S_L : LASX3R_XXX<0x75480000>; +- +-def XVSEQ_B : LASX3R_XXX<0x74000000>; +-def XVSEQ_H : LASX3R_XXX<0x74008000>; +-def XVSEQ_W : LASX3R_XXX<0x74010000>; +-def XVSEQ_D : LASX3R_XXX<0x74018000>; +-def XVSEQI_B : LASX2RI5_XXI<0x76800000, simm5>; +-def XVSEQI_H : LASX2RI5_XXI<0x76808000, simm5>; +-def XVSEQI_W : LASX2RI5_XXI<0x76810000, simm5>; +-def XVSEQI_D : LASX2RI5_XXI<0x76818000, simm5>; +- +-def XVSLE_B : LASX3R_XXX<0x74020000>; +-def XVSLE_H : LASX3R_XXX<0x74028000>; +-def XVSLE_W : LASX3R_XXX<0x74030000>; +-def XVSLE_D : LASX3R_XXX<0x74038000>; +-def XVSLEI_B : LASX2RI5_XXI<0x76820000, simm5>; +-def XVSLEI_H : LASX2RI5_XXI<0x76828000, simm5>; +-def XVSLEI_W : LASX2RI5_XXI<0x76830000, simm5>; +-def XVSLEI_D : LASX2RI5_XXI<0x76838000, simm5>; +- +-def XVSLE_BU : LASX3R_XXX<0x74040000>; +-def XVSLE_HU : LASX3R_XXX<0x74048000>; +-def XVSLE_WU : LASX3R_XXX<0x74050000>; +-def XVSLE_DU : LASX3R_XXX<0x74058000>; +-def XVSLEI_BU : LASX2RI5_XXI<0x76840000>; +-def XVSLEI_HU : LASX2RI5_XXI<0x76848000>; +-def XVSLEI_WU : LASX2RI5_XXI<0x76850000>; +-def XVSLEI_DU : LASX2RI5_XXI<0x76858000>; +- +-def XVSLT_B : LASX3R_XXX<0x74060000>; +-def XVSLT_H : LASX3R_XXX<0x74068000>; +-def XVSLT_W : LASX3R_XXX<0x74070000>; +-def XVSLT_D : LASX3R_XXX<0x74078000>; +-def XVSLTI_B : LASX2RI5_XXI<0x76860000, simm5>; +-def XVSLTI_H : LASX2RI5_XXI<0x76868000, simm5>; +-def XVSLTI_W : LASX2RI5_XXI<0x76870000, simm5>; +-def XVSLTI_D : LASX2RI5_XXI<0x76878000, simm5>; +- +-def XVSLT_BU : LASX3R_XXX<0x74080000>; +-def XVSLT_HU : LASX3R_XXX<0x74088000>; +-def XVSLT_WU : LASX3R_XXX<0x74090000>; +-def XVSLT_DU : LASX3R_XXX<0x74098000>; +-def XVSLTI_BU : LASX2RI5_XXI<0x76880000>; +-def XVSLTI_HU : LASX2RI5_XXI<0x76888000>; +-def XVSLTI_WU : LASX2RI5_XXI<0x76890000>; +-def XVSLTI_DU : LASX2RI5_XXI<0x76898000>; +- +-def XVFCMP_CAF_S : LASX3R_XXX<0x0c900000>; +-def XVFCMP_SAF_S : LASX3R_XXX<0x0c908000>; +-def XVFCMP_CLT_S : LASX3R_XXX<0x0c910000>; +-def XVFCMP_SLT_S : LASX3R_XXX<0x0c918000>; +-def XVFCMP_CEQ_S : LASX3R_XXX<0x0c920000>; +-def XVFCMP_SEQ_S : LASX3R_XXX<0x0c928000>; +-def XVFCMP_CLE_S : LASX3R_XXX<0x0c930000>; +-def XVFCMP_SLE_S : LASX3R_XXX<0x0c938000>; +-def XVFCMP_CUN_S : LASX3R_XXX<0x0c940000>; +-def XVFCMP_SUN_S : LASX3R_XXX<0x0c948000>; +-def XVFCMP_CULT_S : LASX3R_XXX<0x0c950000>; +-def XVFCMP_SULT_S : LASX3R_XXX<0x0c958000>; +-def XVFCMP_CUEQ_S : LASX3R_XXX<0x0c960000>; +-def XVFCMP_SUEQ_S : LASX3R_XXX<0x0c968000>; +-def XVFCMP_CULE_S : LASX3R_XXX<0x0c970000>; +-def XVFCMP_SULE_S : LASX3R_XXX<0x0c978000>; +-def XVFCMP_CNE_S : LASX3R_XXX<0x0c980000>; +-def XVFCMP_SNE_S : LASX3R_XXX<0x0c988000>; +-def XVFCMP_COR_S : LASX3R_XXX<0x0c9a0000>; +-def XVFCMP_SOR_S : LASX3R_XXX<0x0c9a8000>; +-def XVFCMP_CUNE_S : LASX3R_XXX<0x0c9c0000>; +-def XVFCMP_SUNE_S : LASX3R_XXX<0x0c9c8000>; +- +-def XVFCMP_CAF_D : LASX3R_XXX<0x0ca00000>; +-def XVFCMP_SAF_D : LASX3R_XXX<0x0ca08000>; +-def XVFCMP_CLT_D : LASX3R_XXX<0x0ca10000>; +-def XVFCMP_SLT_D : LASX3R_XXX<0x0ca18000>; +-def XVFCMP_CEQ_D : LASX3R_XXX<0x0ca20000>; +-def XVFCMP_SEQ_D : LASX3R_XXX<0x0ca28000>; +-def XVFCMP_CLE_D : LASX3R_XXX<0x0ca30000>; +-def XVFCMP_SLE_D : LASX3R_XXX<0x0ca38000>; +-def XVFCMP_CUN_D : LASX3R_XXX<0x0ca40000>; +-def XVFCMP_SUN_D : LASX3R_XXX<0x0ca48000>; +-def XVFCMP_CULT_D : LASX3R_XXX<0x0ca50000>; +-def XVFCMP_SULT_D : LASX3R_XXX<0x0ca58000>; +-def XVFCMP_CUEQ_D : LASX3R_XXX<0x0ca60000>; +-def XVFCMP_SUEQ_D : LASX3R_XXX<0x0ca68000>; +-def XVFCMP_CULE_D : LASX3R_XXX<0x0ca70000>; +-def XVFCMP_SULE_D : LASX3R_XXX<0x0ca78000>; +-def XVFCMP_CNE_D : LASX3R_XXX<0x0ca80000>; +-def XVFCMP_SNE_D : LASX3R_XXX<0x0ca88000>; +-def XVFCMP_COR_D : LASX3R_XXX<0x0caa0000>; +-def XVFCMP_SOR_D : LASX3R_XXX<0x0caa8000>; +-def XVFCMP_CUNE_D : LASX3R_XXX<0x0cac0000>; +-def XVFCMP_SUNE_D : LASX3R_XXX<0x0cac8000>; +- +-def XVBITSEL_V : LASX4R_XXXX<0x0d200000>; +- +-def XVBITSELI_B : LASX2RI8_XXXI<0x77c40000>; +- +-def XVSETEQZ_V : LASX2R_CX<0x769c9800>; +-def XVSETNEZ_V : LASX2R_CX<0x769c9c00>; +-def XVSETANYEQZ_B : LASX2R_CX<0x769ca000>; +-def XVSETANYEQZ_H : LASX2R_CX<0x769ca400>; +-def XVSETANYEQZ_W : LASX2R_CX<0x769ca800>; +-def XVSETANYEQZ_D : LASX2R_CX<0x769cac00>; +-def XVSETALLNEZ_B : LASX2R_CX<0x769cb000>; +-def XVSETALLNEZ_H : LASX2R_CX<0x769cb400>; +-def XVSETALLNEZ_W : LASX2R_CX<0x769cb800>; +-def XVSETALLNEZ_D : LASX2R_CX<0x769cbc00>; +- +-def XVINSGR2VR_W : LASX2RI3_XXRI<0x76ebc000>; +-def XVINSGR2VR_D : LASX2RI2_XXRI<0x76ebe000>; +-def XVPICKVE2GR_W : LASX2RI3_RXI<0x76efc000>; +-def XVPICKVE2GR_D : LASX2RI2_RXI<0x76efe000>; +-def XVPICKVE2GR_WU : LASX2RI3_RXI<0x76f3c000>; +-def XVPICKVE2GR_DU : LASX2RI2_RXI<0x76f3e000>; +- +-def XVREPLGR2VR_B : LASX2R_XR<0x769f0000>; +-def XVREPLGR2VR_H : LASX2R_XR<0x769f0400>; +-def XVREPLGR2VR_W : LASX2R_XR<0x769f0800>; +-def XVREPLGR2VR_D : LASX2R_XR<0x769f0c00>; +- +-def XVREPLVE_B : LASX3R_XXR<0x75220000>; +-def XVREPLVE_H : LASX3R_XXR<0x75228000>; +-def XVREPLVE_W : LASX3R_XXR<0x75230000>; +-def XVREPLVE_D : LASX3R_XXR<0x75238000>; +-def XVREPL128VEI_B : LASX2RI4_XXI<0x76f78000>; +-def XVREPL128VEI_H : LASX2RI3_XXI<0x76f7c000>; +-def XVREPL128VEI_W : LASX2RI2_XXI<0x76f7e000>; +-def XVREPL128VEI_D : LASX2RI1_XXI<0x76f7f000>; +- +-def XVREPLVE0_B : LASX2R_XX<0x77070000>; +-def XVREPLVE0_H : LASX2R_XX<0x77078000>; +-def XVREPLVE0_W : LASX2R_XX<0x7707c000>; +-def XVREPLVE0_D : LASX2R_XX<0x7707e000>; +-def XVREPLVE0_Q : LASX2R_XX<0x7707f000>; +- +-def XVINSVE0_W : LASX2RI3_XXXI<0x76ffc000>; +-def XVINSVE0_D : LASX2RI2_XXXI<0x76ffe000>; +- +-def XVPICKVE_W : LASX2RI3_XXI<0x7703c000>; +-def XVPICKVE_D : LASX2RI2_XXI<0x7703e000>; +- +-def XVBSLL_V : LASX2RI5_XXI<0x768e0000>; +-def XVBSRL_V : LASX2RI5_XXI<0x768e8000>; +- +-def XVPACKEV_B : LASX3R_XXX<0x75160000>; +-def XVPACKEV_H : LASX3R_XXX<0x75168000>; +-def XVPACKEV_W : LASX3R_XXX<0x75170000>; +-def XVPACKEV_D : LASX3R_XXX<0x75178000>; +-def XVPACKOD_B : LASX3R_XXX<0x75180000>; +-def XVPACKOD_H : LASX3R_XXX<0x75188000>; +-def XVPACKOD_W : LASX3R_XXX<0x75190000>; +-def XVPACKOD_D : LASX3R_XXX<0x75198000>; +- +-def XVPICKEV_B : LASX3R_XXX<0x751e0000>; +-def XVPICKEV_H : LASX3R_XXX<0x751e8000>; +-def XVPICKEV_W : LASX3R_XXX<0x751f0000>; +-def XVPICKEV_D : LASX3R_XXX<0x751f8000>; +-def XVPICKOD_B : LASX3R_XXX<0x75200000>; +-def XVPICKOD_H : LASX3R_XXX<0x75208000>; +-def XVPICKOD_W : LASX3R_XXX<0x75210000>; +-def XVPICKOD_D : LASX3R_XXX<0x75218000>; +- +-def XVILVL_B : LASX3R_XXX<0x751a0000>; +-def XVILVL_H : LASX3R_XXX<0x751a8000>; +-def XVILVL_W : LASX3R_XXX<0x751b0000>; +-def XVILVL_D : LASX3R_XXX<0x751b8000>; +-def XVILVH_B : LASX3R_XXX<0x751c0000>; +-def XVILVH_H : LASX3R_XXX<0x751c8000>; +-def XVILVH_W : LASX3R_XXX<0x751d0000>; +-def XVILVH_D : LASX3R_XXX<0x751d8000>; +- +-def XVSHUF_B : LASX4R_XXXX<0x0d600000>; +- +-def XVSHUF_H : LASX3R_XXXX<0x757a8000>; +-def XVSHUF_W : LASX3R_XXXX<0x757b0000>; +-def XVSHUF_D : LASX3R_XXXX<0x757b8000>; +- +-def XVPERM_W : LASX3R_XXX<0x757d0000>; +- +-def XVSHUF4I_B : LASX2RI8_XXI<0x77900000>; +-def XVSHUF4I_H : LASX2RI8_XXI<0x77940000>; +-def XVSHUF4I_W : LASX2RI8_XXI<0x77980000>; +-def XVSHUF4I_D : LASX2RI8_XXXI<0x779c0000>; +- +-def XVPERMI_W : LASX2RI8_XXXI<0x77e40000>; +-def XVPERMI_D : LASX2RI8_XXI<0x77e80000>; +-def XVPERMI_Q : LASX2RI8_XXXI<0x77ec0000>; +- +-def XVEXTRINS_D : LASX2RI8_XXXI<0x77800000>; +-def XVEXTRINS_W : LASX2RI8_XXXI<0x77840000>; +-def XVEXTRINS_H : LASX2RI8_XXXI<0x77880000>; +-def XVEXTRINS_B : LASX2RI8_XXXI<0x778c0000>; +-} // mayLoad = 0, mayStore = 0 +- +-let mayLoad = 1, mayStore = 0 in { +-def XVLD : LASX2RI12_Load<0x2c800000>; +-def XVLDX : LASX3R_Load<0x38480000>; +- +-def XVLDREPL_B : LASX2RI12_Load<0x32800000>; +-def XVLDREPL_H : LASX2RI11_Load<0x32400000>; +-def XVLDREPL_W : LASX2RI10_Load<0x32200000>; +-def XVLDREPL_D : LASX2RI9_Load<0x32100000>; +-} // mayLoad = 1, mayStore = 0 +- +-let mayLoad = 0, mayStore = 1 in { +-def XVST : LASX2RI12_Store<0x2cc00000>; +-def XVSTX : LASX3R_Store<0x384c0000>; +- +-def XVSTELM_B : LASX2RI8I5_XRII<0x33800000>; +-def XVSTELM_H : LASX2RI8I4_XRII<0x33400000, simm8_lsl1>; +-def XVSTELM_W : LASX2RI8I3_XRII<0x33200000, simm8_lsl2>; +-def XVSTELM_D : LASX2RI8I2_XRII<0x33100000, simm8_lsl3>; +-} // mayLoad = 0, mayStore = 1 +- +-} // hasSideEffects = 0, Predicates = [HasExtLASX] +- +-/// Pseudo-instructions +- +-let Predicates = [HasExtLASX] in { +- +-let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0, +- isAsmParserOnly = 1 in { +-def PseudoXVREPLI_B : Pseudo<(outs LASX256:$xd), (ins simm10:$imm), [], +- "xvrepli.b", "$xd, $imm">; +-def PseudoXVREPLI_H : Pseudo<(outs LASX256:$xd), (ins simm10:$imm), [], +- "xvrepli.h", "$xd, $imm">; +-def PseudoXVREPLI_W : Pseudo<(outs LASX256:$xd), (ins simm10:$imm), [], +- "xvrepli.w", "$xd, $imm">; +-def PseudoXVREPLI_D : Pseudo<(outs LASX256:$xd), (ins simm10:$imm), [], +- "xvrepli.d", "$xd, $imm">; +-} +- +-def PseudoXVBNZ_B : VecCond; +-def PseudoXVBNZ_H : VecCond; +-def PseudoXVBNZ_W : VecCond; +-def PseudoXVBNZ_D : VecCond; +-def PseudoXVBNZ : VecCond; +- +-def PseudoXVBZ_B : VecCond; +-def PseudoXVBZ_H : VecCond; +-def PseudoXVBZ_W : VecCond; +-def PseudoXVBZ_D : VecCond; +-def PseudoXVBZ : VecCond; +- +-let usesCustomInserter = 1, Constraints = "$xd = $dst" in { +-def PseudoXVINSGR2VR_B +- : Pseudo<(outs LASX256:$dst), (ins LASX256:$xd, GPR:$rj, uimm5:$imm)>; +-def PseudoXVINSGR2VR_H +- : Pseudo<(outs LASX256:$dst), (ins LASX256:$xd, GPR:$rj, uimm4:$imm)>; +-} // usesCustomInserter = 1, Constraints = "$xd = $dst" +- +-} // Predicates = [HasExtLASX] +- +-multiclass PatXr { +- def : Pat<(v32i8 (OpNode (v32i8 LASX256:$xj))), +- (!cast(Inst#"_B") LASX256:$xj)>; +- def : Pat<(v16i16 (OpNode (v16i16 LASX256:$xj))), +- (!cast(Inst#"_H") LASX256:$xj)>; +- def : Pat<(v8i32 (OpNode (v8i32 LASX256:$xj))), +- (!cast(Inst#"_W") LASX256:$xj)>; +- def : Pat<(v4i64 (OpNode (v4i64 LASX256:$xj))), +- (!cast(Inst#"_D") LASX256:$xj)>; +-} +- +-multiclass PatXrF { +- def : Pat<(v8f32 (OpNode (v8f32 LASX256:$xj))), +- (!cast(Inst#"_S") LASX256:$xj)>; +- def : Pat<(v4f64 (OpNode (v4f64 LASX256:$xj))), +- (!cast(Inst#"_D") LASX256:$xj)>; +-} +- +-multiclass PatXrXr { +- def : Pat<(OpNode (v32i8 LASX256:$xj), (v32i8 LASX256:$xk)), +- (!cast(Inst#"_B") LASX256:$xj, LASX256:$xk)>; +- def : Pat<(OpNode (v16i16 LASX256:$xj), (v16i16 LASX256:$xk)), +- (!cast(Inst#"_H") LASX256:$xj, LASX256:$xk)>; +- def : Pat<(OpNode (v8i32 LASX256:$xj), (v8i32 LASX256:$xk)), +- (!cast(Inst#"_W") LASX256:$xj, LASX256:$xk)>; +- def : Pat<(OpNode (v4i64 LASX256:$xj), (v4i64 LASX256:$xk)), +- (!cast(Inst#"_D") LASX256:$xj, LASX256:$xk)>; +-} +- +-multiclass PatXrXrF { +- def : Pat<(OpNode (v8f32 LASX256:$xj), (v8f32 LASX256:$xk)), +- (!cast(Inst#"_S") LASX256:$xj, LASX256:$xk)>; +- def : Pat<(OpNode (v4f64 LASX256:$xj), (v4f64 LASX256:$xk)), +- (!cast(Inst#"_D") LASX256:$xj, LASX256:$xk)>; +-} +- +-multiclass PatXrXrU { +- def : Pat<(OpNode (v32i8 LASX256:$xj), (v32i8 LASX256:$xk)), +- (!cast(Inst#"_BU") LASX256:$xj, LASX256:$xk)>; +- def : Pat<(OpNode (v16i16 LASX256:$xj), (v16i16 LASX256:$xk)), +- (!cast(Inst#"_HU") LASX256:$xj, LASX256:$xk)>; +- def : Pat<(OpNode (v8i32 LASX256:$xj), (v8i32 LASX256:$xk)), +- (!cast(Inst#"_WU") LASX256:$xj, LASX256:$xk)>; +- def : Pat<(OpNode (v4i64 LASX256:$xj), (v4i64 LASX256:$xk)), +- (!cast(Inst#"_DU") LASX256:$xj, LASX256:$xk)>; +-} +- +-multiclass PatXrSimm5 { +- def : Pat<(OpNode (v32i8 LASX256:$xj), (v32i8 (SplatPat_simm5 simm5:$imm))), +- (!cast(Inst#"_B") LASX256:$xj, simm5:$imm)>; +- def : Pat<(OpNode (v16i16 LASX256:$xj), (v16i16 (SplatPat_simm5 simm5:$imm))), +- (!cast(Inst#"_H") LASX256:$xj, simm5:$imm)>; +- def : Pat<(OpNode (v8i32 LASX256:$xj), (v8i32 (SplatPat_simm5 simm5:$imm))), +- (!cast(Inst#"_W") LASX256:$xj, simm5:$imm)>; +- def : Pat<(OpNode (v4i64 LASX256:$xj), (v4i64 (SplatPat_simm5 simm5:$imm))), +- (!cast(Inst#"_D") LASX256:$xj, simm5:$imm)>; +-} +- +-multiclass PatXrUimm5 { +- def : Pat<(OpNode (v32i8 LASX256:$xj), (v32i8 (SplatPat_uimm5 uimm5:$imm))), +- (!cast(Inst#"_BU") LASX256:$xj, uimm5:$imm)>; +- def : Pat<(OpNode (v16i16 LASX256:$xj), (v16i16 (SplatPat_uimm5 uimm5:$imm))), +- (!cast(Inst#"_HU") LASX256:$xj, uimm5:$imm)>; +- def : Pat<(OpNode (v8i32 LASX256:$xj), (v8i32 (SplatPat_uimm5 uimm5:$imm))), +- (!cast(Inst#"_WU") LASX256:$xj, uimm5:$imm)>; +- def : Pat<(OpNode (v4i64 LASX256:$xj), (v4i64 (SplatPat_uimm5 uimm5:$imm))), +- (!cast(Inst#"_DU") LASX256:$xj, uimm5:$imm)>; +-} +- +-multiclass PatXrXrXr { +- def : Pat<(OpNode (v32i8 LASX256:$xd), (v32i8 LASX256:$xj), +- (v32i8 LASX256:$xk)), +- (!cast(Inst#"_B") LASX256:$xd, LASX256:$xj, LASX256:$xk)>; +- def : Pat<(OpNode (v16i16 LASX256:$xd), (v16i16 LASX256:$xj), +- (v16i16 LASX256:$xk)), +- (!cast(Inst#"_H") LASX256:$xd, LASX256:$xj, LASX256:$xk)>; +- def : Pat<(OpNode (v8i32 LASX256:$xd), (v8i32 LASX256:$xj), +- (v8i32 LASX256:$xk)), +- (!cast(Inst#"_W") LASX256:$xd, LASX256:$xj, LASX256:$xk)>; +- def : Pat<(OpNode (v4i64 LASX256:$xd), (v4i64 LASX256:$xj), +- (v4i64 LASX256:$xk)), +- (!cast(Inst#"_D") LASX256:$xd, LASX256:$xj, LASX256:$xk)>; +-} +- +-multiclass PatShiftXrXr { +- def : Pat<(OpNode (v32i8 LASX256:$xj), (and vsplati8_imm_eq_7, +- (v32i8 LASX256:$xk))), +- (!cast(Inst#"_B") LASX256:$xj, LASX256:$xk)>; +- def : Pat<(OpNode (v16i16 LASX256:$xj), (and vsplati16_imm_eq_15, +- (v16i16 LASX256:$xk))), +- (!cast(Inst#"_H") LASX256:$xj, LASX256:$xk)>; +- def : Pat<(OpNode (v8i32 LASX256:$xj), (and vsplati32_imm_eq_31, +- (v8i32 LASX256:$xk))), +- (!cast(Inst#"_W") LASX256:$xj, LASX256:$xk)>; +- def : Pat<(OpNode (v4i64 LASX256:$xj), (and vsplati64_imm_eq_63, +- (v4i64 LASX256:$xk))), +- (!cast(Inst#"_D") LASX256:$xj, LASX256:$xk)>; +-} +- +-multiclass PatShiftXrUimm { +- def : Pat<(OpNode (v32i8 LASX256:$xj), (v32i8 (SplatPat_uimm3 uimm3:$imm))), +- (!cast(Inst#"_B") LASX256:$xj, uimm3:$imm)>; +- def : Pat<(OpNode (v16i16 LASX256:$xj), (v16i16 (SplatPat_uimm4 uimm4:$imm))), +- (!cast(Inst#"_H") LASX256:$xj, uimm4:$imm)>; +- def : Pat<(OpNode (v8i32 LASX256:$xj), (v8i32 (SplatPat_uimm5 uimm5:$imm))), +- (!cast(Inst#"_W") LASX256:$xj, uimm5:$imm)>; +- def : Pat<(OpNode (v4i64 LASX256:$xj), (v4i64 (SplatPat_uimm6 uimm6:$imm))), +- (!cast(Inst#"_D") LASX256:$xj, uimm6:$imm)>; +-} +- +-multiclass PatCCXrSimm5 { +- def : Pat<(v32i8 (setcc (v32i8 LASX256:$xj), +- (v32i8 (SplatPat_simm5 simm5:$imm)), CC)), +- (!cast(Inst#"_B") LASX256:$xj, simm5:$imm)>; +- def : Pat<(v16i16 (setcc (v16i16 LASX256:$xj), +- (v16i16 (SplatPat_simm5 simm5:$imm)), CC)), +- (!cast(Inst#"_H") LASX256:$xj, simm5:$imm)>; +- def : Pat<(v8i32 (setcc (v8i32 LASX256:$xj), +- (v8i32 (SplatPat_simm5 simm5:$imm)), CC)), +- (!cast(Inst#"_W") LASX256:$xj, simm5:$imm)>; +- def : Pat<(v4i64 (setcc (v4i64 LASX256:$xj), +- (v4i64 (SplatPat_simm5 simm5:$imm)), CC)), +- (!cast(Inst#"_D") LASX256:$xj, simm5:$imm)>; +-} +- +-multiclass PatCCXrUimm5 { +- def : Pat<(v32i8 (setcc (v32i8 LASX256:$xj), +- (v32i8 (SplatPat_uimm5 uimm5:$imm)), CC)), +- (!cast(Inst#"_BU") LASX256:$xj, uimm5:$imm)>; +- def : Pat<(v16i16 (setcc (v16i16 LASX256:$xj), +- (v16i16 (SplatPat_uimm5 uimm5:$imm)), CC)), +- (!cast(Inst#"_HU") LASX256:$xj, uimm5:$imm)>; +- def : Pat<(v8i32 (setcc (v8i32 LASX256:$xj), +- (v8i32 (SplatPat_uimm5 uimm5:$imm)), CC)), +- (!cast(Inst#"_WU") LASX256:$xj, uimm5:$imm)>; +- def : Pat<(v4i64 (setcc (v4i64 LASX256:$xj), +- (v4i64 (SplatPat_uimm5 uimm5:$imm)), CC)), +- (!cast(Inst#"_DU") LASX256:$xj, uimm5:$imm)>; +-} +- +-multiclass PatCCXrXr { +- def : Pat<(v32i8 (setcc (v32i8 LASX256:$xj), (v32i8 LASX256:$xk), CC)), +- (!cast(Inst#"_B") LASX256:$xj, LASX256:$xk)>; +- def : Pat<(v16i16 (setcc (v16i16 LASX256:$xj), (v16i16 LASX256:$xk), CC)), +- (!cast(Inst#"_H") LASX256:$xj, LASX256:$xk)>; +- def : Pat<(v8i32 (setcc (v8i32 LASX256:$xj), (v8i32 LASX256:$xk), CC)), +- (!cast(Inst#"_W") LASX256:$xj, LASX256:$xk)>; +- def : Pat<(v4i64 (setcc (v4i64 LASX256:$xj), (v4i64 LASX256:$xk), CC)), +- (!cast(Inst#"_D") LASX256:$xj, LASX256:$xk)>; +-} +- +-multiclass PatCCXrXrU { +- def : Pat<(v32i8 (setcc (v32i8 LASX256:$xj), (v32i8 LASX256:$xk), CC)), +- (!cast(Inst#"_BU") LASX256:$xj, LASX256:$xk)>; +- def : Pat<(v16i16 (setcc (v16i16 LASX256:$xj), (v16i16 LASX256:$xk), CC)), +- (!cast(Inst#"_HU") LASX256:$xj, LASX256:$xk)>; +- def : Pat<(v8i32 (setcc (v8i32 LASX256:$xj), (v8i32 LASX256:$xk), CC)), +- (!cast(Inst#"_WU") LASX256:$xj, LASX256:$xk)>; +- def : Pat<(v4i64 (setcc (v4i64 LASX256:$xj), (v4i64 LASX256:$xk), CC)), +- (!cast(Inst#"_DU") LASX256:$xj, LASX256:$xk)>; +-} +- +-multiclass PatCCXrXrF { +- def : Pat<(v8i32 (setcc (v8f32 LASX256:$xj), (v8f32 LASX256:$xk), CC)), +- (!cast(Inst#"_S") LASX256:$xj, LASX256:$xk)>; +- def : Pat<(v4i64 (setcc (v4f64 LASX256:$xj), (v4f64 LASX256:$xk), CC)), +- (!cast(Inst#"_D") LASX256:$xj, LASX256:$xk)>; +-} +- +-let Predicates = [HasExtLASX] in { +- +-// XVADD_{B/H/W/D} +-defm : PatXrXr; +-// XVSUB_{B/H/W/D} +-defm : PatXrXr; +- +-// XVADDI_{B/H/W/D}U +-defm : PatXrUimm5; +-// XVSUBI_{B/H/W/D}U +-defm : PatXrUimm5; +- +-// XVNEG_{B/H/W/D} +-def : Pat<(sub immAllZerosV, (v32i8 LASX256:$xj)), (XVNEG_B LASX256:$xj)>; +-def : Pat<(sub immAllZerosV, (v16i16 LASX256:$xj)), (XVNEG_H LASX256:$xj)>; +-def : Pat<(sub immAllZerosV, (v8i32 LASX256:$xj)), (XVNEG_W LASX256:$xj)>; +-def : Pat<(sub immAllZerosV, (v4i64 LASX256:$xj)), (XVNEG_D LASX256:$xj)>; +- +-// XVMAX[I]_{B/H/W/D}[U] +-defm : PatXrXr; +-defm : PatXrXrU; +-defm : PatXrSimm5; +-defm : PatXrUimm5; +- +-// XVMIN[I]_{B/H/W/D}[U] +-defm : PatXrXr; +-defm : PatXrXrU; +-defm : PatXrSimm5; +-defm : PatXrUimm5; +- +-// XVMUL_{B/H/W/D} +-defm : PatXrXr; +- +-// XVMUH_{B/H/W/D}[U] +-defm : PatXrXr; +-defm : PatXrXrU; +- +-// XVMADD_{B/H/W/D} +-defm : PatXrXrXr; +-// XVMSUB_{B/H/W/D} +-defm : PatXrXrXr; +- +-// XVDIV_{B/H/W/D}[U] +-defm : PatXrXr; +-defm : PatXrXrU; +- +-// XVMOD_{B/H/W/D}[U] +-defm : PatXrXr; +-defm : PatXrXrU; +- +-// XVAND_V +-foreach vt = [v32i8, v16i16, v8i32, v4i64] in +-def : Pat<(and (vt LASX256:$xj), (vt LASX256:$xk)), +- (XVAND_V LASX256:$xj, LASX256:$xk)>; +-// XVOR_V +-foreach vt = [v32i8, v16i16, v8i32, v4i64] in +-def : Pat<(or (vt LASX256:$xj), (vt LASX256:$xk)), +- (XVOR_V LASX256:$xj, LASX256:$xk)>; +-// XVXOR_V +-foreach vt = [v32i8, v16i16, v8i32, v4i64] in +-def : Pat<(xor (vt LASX256:$xj), (vt LASX256:$xk)), +- (XVXOR_V LASX256:$xj, LASX256:$xk)>; +-// XVNOR_V +-foreach vt = [v32i8, v16i16, v8i32, v4i64] in +-def : Pat<(vnot (or (vt LASX256:$xj), (vt LASX256:$xk))), +- (XVNOR_V LASX256:$xj, LASX256:$xk)>; +- +-// XVANDI_B +-def : Pat<(and (v32i8 LASX256:$xj), (v32i8 (SplatPat_uimm8 uimm8:$imm))), +- (XVANDI_B LASX256:$xj, uimm8:$imm)>; +-// XVORI_B +-def : Pat<(or (v32i8 LASX256:$xj), (v32i8 (SplatPat_uimm8 uimm8:$imm))), +- (XVORI_B LASX256:$xj, uimm8:$imm)>; +- +-// XVXORI_B +-def : Pat<(xor (v32i8 LASX256:$xj), (v32i8 (SplatPat_uimm8 uimm8:$imm))), +- (XVXORI_B LASX256:$xj, uimm8:$imm)>; +- +-// XVSLL[I]_{B/H/W/D} +-defm : PatXrXr; +-defm : PatShiftXrXr; +-defm : PatShiftXrUimm; +- +-// XVSRL[I]_{B/H/W/D} +-defm : PatXrXr; +-defm : PatShiftXrXr; +-defm : PatShiftXrUimm; +- +-// XVSRA[I]_{B/H/W/D} +-defm : PatXrXr; +-defm : PatShiftXrXr; +-defm : PatShiftXrUimm; +- +-// XVCLZ_{B/H/W/D} +-defm : PatXr; +- +-// XVPCNT_{B/H/W/D} +-defm : PatXr; +- +-// XVBITCLR_{B/H/W/D} +-def : Pat<(and v32i8:$xj, (vnot (shl vsplat_imm_eq_1, v32i8:$xk))), +- (v32i8 (XVBITCLR_B v32i8:$xj, v32i8:$xk))>; +-def : Pat<(and v16i16:$xj, (vnot (shl vsplat_imm_eq_1, v16i16:$xk))), +- (v16i16 (XVBITCLR_H v16i16:$xj, v16i16:$xk))>; +-def : Pat<(and v8i32:$xj, (vnot (shl vsplat_imm_eq_1, v8i32:$xk))), +- (v8i32 (XVBITCLR_W v8i32:$xj, v8i32:$xk))>; +-def : Pat<(and v4i64:$xj, (vnot (shl vsplat_imm_eq_1, v4i64:$xk))), +- (v4i64 (XVBITCLR_D v4i64:$xj, v4i64:$xk))>; +-def : Pat<(and v32i8:$xj, (vnot (shl vsplat_imm_eq_1, +- (vsplati8imm7 v32i8:$xk)))), +- (v32i8 (XVBITCLR_B v32i8:$xj, v32i8:$xk))>; +-def : Pat<(and v16i16:$xj, (vnot (shl vsplat_imm_eq_1, +- (vsplati16imm15 v16i16:$xk)))), +- (v16i16 (XVBITCLR_H v16i16:$xj, v16i16:$xk))>; +-def : Pat<(and v8i32:$xj, (vnot (shl vsplat_imm_eq_1, +- (vsplati32imm31 v8i32:$xk)))), +- (v8i32 (XVBITCLR_W v8i32:$xj, v8i32:$xk))>; +-def : Pat<(and v4i64:$xj, (vnot (shl vsplat_imm_eq_1, +- (vsplati64imm63 v4i64:$xk)))), +- (v4i64 (XVBITCLR_D v4i64:$xj, v4i64:$xk))>; +- +-// XVBITCLRI_{B/H/W/D} +-def : Pat<(and (v32i8 LASX256:$xj), (v32i8 (vsplat_uimm_inv_pow2 uimm3:$imm))), +- (XVBITCLRI_B LASX256:$xj, uimm3:$imm)>; +-def : Pat<(and (v16i16 LASX256:$xj), (v16i16 (vsplat_uimm_inv_pow2 uimm4:$imm))), +- (XVBITCLRI_H LASX256:$xj, uimm4:$imm)>; +-def : Pat<(and (v8i32 LASX256:$xj), (v8i32 (vsplat_uimm_inv_pow2 uimm5:$imm))), +- (XVBITCLRI_W LASX256:$xj, uimm5:$imm)>; +-def : Pat<(and (v4i64 LASX256:$xj), (v4i64 (vsplat_uimm_inv_pow2 uimm6:$imm))), +- (XVBITCLRI_D LASX256:$xj, uimm6:$imm)>; +- +-// XVBITSET_{B/H/W/D} +-def : Pat<(or v32i8:$xj, (shl vsplat_imm_eq_1, v32i8:$xk)), +- (v32i8 (XVBITSET_B v32i8:$xj, v32i8:$xk))>; +-def : Pat<(or v16i16:$xj, (shl vsplat_imm_eq_1, v16i16:$xk)), +- (v16i16 (XVBITSET_H v16i16:$xj, v16i16:$xk))>; +-def : Pat<(or v8i32:$xj, (shl vsplat_imm_eq_1, v8i32:$xk)), +- (v8i32 (XVBITSET_W v8i32:$xj, v8i32:$xk))>; +-def : Pat<(or v4i64:$xj, (shl vsplat_imm_eq_1, v4i64:$xk)), +- (v4i64 (XVBITSET_D v4i64:$xj, v4i64:$xk))>; +-def : Pat<(or v32i8:$xj, (shl vsplat_imm_eq_1, (vsplati8imm7 v32i8:$xk))), +- (v32i8 (XVBITSET_B v32i8:$xj, v32i8:$xk))>; +-def : Pat<(or v16i16:$xj, (shl vsplat_imm_eq_1, (vsplati16imm15 v16i16:$xk))), +- (v16i16 (XVBITSET_H v16i16:$xj, v16i16:$xk))>; +-def : Pat<(or v8i32:$xj, (shl vsplat_imm_eq_1, (vsplati32imm31 v8i32:$xk))), +- (v8i32 (XVBITSET_W v8i32:$xj, v8i32:$xk))>; +-def : Pat<(or v4i64:$xj, (shl vsplat_imm_eq_1, (vsplati64imm63 v4i64:$xk))), +- (v4i64 (XVBITSET_D v4i64:$xj, v4i64:$xk))>; +- +-// XVBITSETI_{B/H/W/D} +-def : Pat<(or (v32i8 LASX256:$xj), (v32i8 (vsplat_uimm_pow2 uimm3:$imm))), +- (XVBITSETI_B LASX256:$xj, uimm3:$imm)>; +-def : Pat<(or (v16i16 LASX256:$xj), (v16i16 (vsplat_uimm_pow2 uimm4:$imm))), +- (XVBITSETI_H LASX256:$xj, uimm4:$imm)>; +-def : Pat<(or (v8i32 LASX256:$xj), (v8i32 (vsplat_uimm_pow2 uimm5:$imm))), +- (XVBITSETI_W LASX256:$xj, uimm5:$imm)>; +-def : Pat<(or (v4i64 LASX256:$xj), (v4i64 (vsplat_uimm_pow2 uimm6:$imm))), +- (XVBITSETI_D LASX256:$xj, uimm6:$imm)>; +- +-// XVBITREV_{B/H/W/D} +-def : Pat<(xor v32i8:$xj, (shl vsplat_imm_eq_1, v32i8:$xk)), +- (v32i8 (XVBITREV_B v32i8:$xj, v32i8:$xk))>; +-def : Pat<(xor v16i16:$xj, (shl vsplat_imm_eq_1, v16i16:$xk)), +- (v16i16 (XVBITREV_H v16i16:$xj, v16i16:$xk))>; +-def : Pat<(xor v8i32:$xj, (shl vsplat_imm_eq_1, v8i32:$xk)), +- (v8i32 (XVBITREV_W v8i32:$xj, v8i32:$xk))>; +-def : Pat<(xor v4i64:$xj, (shl vsplat_imm_eq_1, v4i64:$xk)), +- (v4i64 (XVBITREV_D v4i64:$xj, v4i64:$xk))>; +-def : Pat<(xor v32i8:$xj, (shl vsplat_imm_eq_1, (vsplati8imm7 v32i8:$xk))), +- (v32i8 (XVBITREV_B v32i8:$xj, v32i8:$xk))>; +-def : Pat<(xor v16i16:$xj, (shl vsplat_imm_eq_1, (vsplati16imm15 v16i16:$xk))), +- (v16i16 (XVBITREV_H v16i16:$xj, v16i16:$xk))>; +-def : Pat<(xor v8i32:$xj, (shl vsplat_imm_eq_1, (vsplati32imm31 v8i32:$xk))), +- (v8i32 (XVBITREV_W v8i32:$xj, v8i32:$xk))>; +-def : Pat<(xor v4i64:$xj, (shl vsplat_imm_eq_1, (vsplati64imm63 v4i64:$xk))), +- (v4i64 (XVBITREV_D v4i64:$xj, v4i64:$xk))>; +- +-// XVBITREVI_{B/H/W/D} +-def : Pat<(xor (v32i8 LASX256:$xj), (v32i8 (vsplat_uimm_pow2 uimm3:$imm))), +- (XVBITREVI_B LASX256:$xj, uimm3:$imm)>; +-def : Pat<(xor (v16i16 LASX256:$xj), (v16i16 (vsplat_uimm_pow2 uimm4:$imm))), +- (XVBITREVI_H LASX256:$xj, uimm4:$imm)>; +-def : Pat<(xor (v8i32 LASX256:$xj), (v8i32 (vsplat_uimm_pow2 uimm5:$imm))), +- (XVBITREVI_W LASX256:$xj, uimm5:$imm)>; +-def : Pat<(xor (v4i64 LASX256:$xj), (v4i64 (vsplat_uimm_pow2 uimm6:$imm))), +- (XVBITREVI_D LASX256:$xj, uimm6:$imm)>; +- +-// XVFADD_{S/D} +-defm : PatXrXrF; +- +-// XVFSUB_{S/D} +-defm : PatXrXrF; +- +-// XVFMUL_{S/D} +-defm : PatXrXrF; +- +-// XVFDIV_{S/D} +-defm : PatXrXrF; +- +-// XVFMADD_{S/D} +-def : Pat<(fma v8f32:$xj, v8f32:$xk, v8f32:$xa), +- (XVFMADD_S v8f32:$xj, v8f32:$xk, v8f32:$xa)>; +-def : Pat<(fma v4f64:$xj, v4f64:$xk, v4f64:$xa), +- (XVFMADD_D v4f64:$xj, v4f64:$xk, v4f64:$xa)>; +- +-// XVFMSUB_{S/D} +-def : Pat<(fma v8f32:$xj, v8f32:$xk, (fneg v8f32:$xa)), +- (XVFMSUB_S v8f32:$xj, v8f32:$xk, v8f32:$xa)>; +-def : Pat<(fma v4f64:$xj, v4f64:$xk, (fneg v4f64:$xa)), +- (XVFMSUB_D v4f64:$xj, v4f64:$xk, v4f64:$xa)>; +- +-// XVFNMADD_{S/D} +-def : Pat<(fneg (fma v8f32:$xj, v8f32:$xk, v8f32:$xa)), +- (XVFNMADD_S v8f32:$xj, v8f32:$xk, v8f32:$xa)>; +-def : Pat<(fneg (fma v4f64:$xj, v4f64:$xk, v4f64:$xa)), +- (XVFNMADD_D v4f64:$xj, v4f64:$xk, v4f64:$xa)>; +-def : Pat<(fma_nsz (fneg v8f32:$xj), v8f32:$xk, (fneg v8f32:$xa)), +- (XVFNMADD_S v8f32:$xj, v8f32:$xk, v8f32:$xa)>; +-def : Pat<(fma_nsz (fneg v4f64:$xj), v4f64:$xk, (fneg v4f64:$xa)), +- (XVFNMADD_D v4f64:$xj, v4f64:$xk, v4f64:$xa)>; +- +-// XVFNMSUB_{S/D} +-def : Pat<(fneg (fma v8f32:$xj, v8f32:$xk, (fneg v8f32:$xa))), +- (XVFNMSUB_S v8f32:$xj, v8f32:$xk, v8f32:$xa)>; +-def : Pat<(fneg (fma v4f64:$xj, v4f64:$xk, (fneg v4f64:$xa))), +- (XVFNMSUB_D v4f64:$xj, v4f64:$xk, v4f64:$xa)>; +-def : Pat<(fma_nsz (fneg v8f32:$xj), v8f32:$xk, v8f32:$xa), +- (XVFNMSUB_S v8f32:$xj, v8f32:$xk, v8f32:$xa)>; +-def : Pat<(fma_nsz (fneg v4f64:$xj), v4f64:$xk, v4f64:$xa), +- (XVFNMSUB_D v4f64:$xj, v4f64:$xk, v4f64:$xa)>; +- +-// XVFSQRT_{S/D} +-defm : PatXrF; +- +-// XVRECIP_{S/D} +-def : Pat<(fdiv vsplatf32_fpimm_eq_1, v8f32:$xj), +- (XVFRECIP_S v8f32:$xj)>; +-def : Pat<(fdiv vsplatf64_fpimm_eq_1, v4f64:$xj), +- (XVFRECIP_D v4f64:$xj)>; +- +-// XVFRSQRT_{S/D} +-def : Pat<(fdiv vsplatf32_fpimm_eq_1, (fsqrt v8f32:$xj)), +- (XVFRSQRT_S v8f32:$xj)>; +-def : Pat<(fdiv vsplatf64_fpimm_eq_1, (fsqrt v4f64:$xj)), +- (XVFRSQRT_D v4f64:$xj)>; +- +-// XVSEQ[I]_{B/H/W/D} +-defm : PatCCXrSimm5; +-defm : PatCCXrXr; +- +-// XVSLE[I]_{B/H/W/D}[U] +-defm : PatCCXrSimm5; +-defm : PatCCXrUimm5; +-defm : PatCCXrXr; +-defm : PatCCXrXrU; +- +-// XVSLT[I]_{B/H/W/D}[U] +-defm : PatCCXrSimm5; +-defm : PatCCXrUimm5; +-defm : PatCCXrXr; +-defm : PatCCXrXrU; +- +-// XVFCMP.cond.{S/D} +-defm : PatCCXrXrF; +-defm : PatCCXrXrF; +-defm : PatCCXrXrF; +- +-defm : PatCCXrXrF; +-defm : PatCCXrXrF; +-defm : PatCCXrXrF; +- +-defm : PatCCXrXrF; +-defm : PatCCXrXrF; +-defm : PatCCXrXrF; +- +-defm : PatCCXrXrF; +-defm : PatCCXrXrF; +-defm : PatCCXrXrF; +- +-defm : PatCCXrXrF; +-defm : PatCCXrXrF; +- +-// PseudoXVINSGR2VR_{B/H} +-def : Pat<(vector_insert v32i8:$xd, GRLenVT:$rj, uimm5:$imm), +- (PseudoXVINSGR2VR_B v32i8:$xd, GRLenVT:$rj, uimm5:$imm)>; +-def : Pat<(vector_insert v16i16:$xd, GRLenVT:$rj, uimm4:$imm), +- (PseudoXVINSGR2VR_H v16i16:$xd, GRLenVT:$rj, uimm4:$imm)>; +- +-// XVINSGR2VR_{W/D} +-def : Pat<(vector_insert v8i32:$xd, GRLenVT:$rj, uimm3:$imm), +- (XVINSGR2VR_W v8i32:$xd, GRLenVT:$rj, uimm3:$imm)>; +-def : Pat<(vector_insert v4i64:$xd, GRLenVT:$rj, uimm2:$imm), +- (XVINSGR2VR_D v4i64:$xd, GRLenVT:$rj, uimm2:$imm)>; +- +-def : Pat<(vector_insert v8f32:$vd, FPR32:$fj, uimm3:$imm), +- (XVINSGR2VR_W $vd, (COPY_TO_REGCLASS FPR32:$fj, GPR), uimm3:$imm)>; +-def : Pat<(vector_insert v4f64:$vd, FPR64:$fj, uimm2:$imm), +- (XVINSGR2VR_D $vd, (COPY_TO_REGCLASS FPR64:$fj, GPR), uimm2:$imm)>; +- +-// XVPICKVE2GR_W[U] +-def : Pat<(loongarch_vpick_sext_elt v8i32:$xd, uimm3:$imm, i32), +- (XVPICKVE2GR_W v8i32:$xd, uimm3:$imm)>; +-def : Pat<(loongarch_vpick_zext_elt v8i32:$xd, uimm3:$imm, i32), +- (XVPICKVE2GR_WU v8i32:$xd, uimm3:$imm)>; +- +-// XVREPLGR2VR_{B/H/W/D} +-def : Pat<(lasxsplati8 GPR:$rj), (XVREPLGR2VR_B GPR:$rj)>; +-def : Pat<(lasxsplati16 GPR:$rj), (XVREPLGR2VR_H GPR:$rj)>; +-def : Pat<(lasxsplati32 GPR:$rj), (XVREPLGR2VR_W GPR:$rj)>; +-def : Pat<(lasxsplati64 GPR:$rj), (XVREPLGR2VR_D GPR:$rj)>; +- +-// XVREPLVE_{B/H/W/D} +-def : Pat<(loongarch_vreplve v32i8:$xj, GRLenVT:$rk), +- (XVREPLVE_B v32i8:$xj, GRLenVT:$rk)>; +-def : Pat<(loongarch_vreplve v16i16:$xj, GRLenVT:$rk), +- (XVREPLVE_H v16i16:$xj, GRLenVT:$rk)>; +-def : Pat<(loongarch_vreplve v8i32:$xj, GRLenVT:$rk), +- (XVREPLVE_W v8i32:$xj, GRLenVT:$rk)>; +-def : Pat<(loongarch_vreplve v4i64:$xj, GRLenVT:$rk), +- (XVREPLVE_D v4i64:$xj, GRLenVT:$rk)>; +- +-// XVREPLVE0_{W/D} +-def : Pat<(lasxsplatf32 FPR32:$fj), +- (XVREPLVE0_W (SUBREG_TO_REG (i64 0), FPR32:$fj, sub_32))>; +-def : Pat<(lasxsplatf64 FPR64:$fj), +- (XVREPLVE0_D (SUBREG_TO_REG (i64 0), FPR64:$fj, sub_64))>; +- +-// Loads/Stores +-foreach vt = [v32i8, v16i16, v8i32, v4i64, v8f32, v4f64] in { +- defm : LdPat; +- def : RegRegLdPat; +- defm : StPat; +- def : RegRegStPat; +-} +- +-// Vector extraction with constant index. +-def : Pat<(i64 (vector_extract v32i8:$xj, uimm4:$imm)), +- (VPICKVE2GR_B (EXTRACT_SUBREG v32i8:$xj, sub_128), uimm4:$imm)>; +-def : Pat<(i64 (vector_extract v16i16:$xj, uimm3:$imm)), +- (VPICKVE2GR_H (EXTRACT_SUBREG v16i16:$xj, sub_128), uimm3:$imm)>; +-def : Pat<(i64 (vector_extract v8i32:$xj, uimm3:$imm)), +- (XVPICKVE2GR_W v8i32:$xj, uimm3:$imm)>; +-def : Pat<(i64 (vector_extract v4i64:$xj, uimm2:$imm)), +- (XVPICKVE2GR_D v4i64:$xj, uimm2:$imm)>; +-def : Pat<(f32 (vector_extract v8f32:$xj, uimm3:$imm)), +- (MOVGR2FR_W (XVPICKVE2GR_W v8f32:$xj, uimm3:$imm))>; +-def : Pat<(f64 (vector_extract v4f64:$xj, uimm2:$imm)), +- (MOVGR2FR_D (XVPICKVE2GR_D v4f64:$xj, uimm2:$imm))>; +- +-// vselect +-def : Pat<(v32i8 (vselect LASX256:$xd, (v32i8 (SplatPat_uimm8 uimm8:$imm)), +- LASX256:$xj)), +- (XVBITSELI_B LASX256:$xd, LASX256:$xj, uimm8:$imm)>; +-foreach vt = [v32i8, v16i16, v8i32, v4i64, v8f32, v4f64] in +- def : Pat<(vt (vselect LASX256:$xa, LASX256:$xk, LASX256:$xj)), +- (XVBITSEL_V LASX256:$xj, LASX256:$xk, LASX256:$xa)>; +- +-// fneg +-def : Pat<(fneg (v8f32 LASX256:$xj)), (XVBITREVI_W LASX256:$xj, 31)>; +-def : Pat<(fneg (v4f64 LASX256:$xj)), (XVBITREVI_D LASX256:$xj, 63)>; +- +-// XVFFINT_{S_W/D_L} +-def : Pat<(v8f32 (sint_to_fp v8i32:$vj)), (XVFFINT_S_W v8i32:$vj)>; +-def : Pat<(v4f64 (sint_to_fp v4i64:$vj)), (XVFFINT_D_L v4i64:$vj)>; +-def : Pat<(v4f64 (sint_to_fp v4i32:$vj)), +- (XVFFINT_D_L (VEXT2XV_D_W (SUBREG_TO_REG (i64 0), v4i32:$vj, +- sub_128)))>; +-def : Pat<(v4f32 (sint_to_fp v4i64:$vj)), +- (EXTRACT_SUBREG (XVFCVT_S_D (XVPERMI_D (XVFFINT_D_L v4i64:$vj), 238), +- (XVFFINT_D_L v4i64:$vj)), +- sub_128)>; +- +-// XVFFINT_{S_WU/D_LU} +-def : Pat<(v8f32 (uint_to_fp v8i32:$vj)), (XVFFINT_S_WU v8i32:$vj)>; +-def : Pat<(v4f64 (uint_to_fp v4i64:$vj)), (XVFFINT_D_LU v4i64:$vj)>; +-def : Pat<(v4f64 (uint_to_fp v4i32:$vj)), +- (XVFFINT_D_LU (VEXT2XV_DU_WU (SUBREG_TO_REG (i64 0), v4i32:$vj, +- sub_128)))>; +-def : Pat<(v4f32 (uint_to_fp v4i64:$vj)), +- (EXTRACT_SUBREG (XVFCVT_S_D (XVPERMI_D (XVFFINT_D_LU v4i64:$vj), 238), +- (XVFFINT_D_LU v4i64:$vj)), +- sub_128)>; +- +-// XVFTINTRZ_{W_S/L_D} +-def : Pat<(v8i32 (fp_to_sint v8f32:$vj)), (XVFTINTRZ_W_S v8f32:$vj)>; +-def : Pat<(v4i64 (fp_to_sint v4f64:$vj)), (XVFTINTRZ_L_D v4f64:$vj)>; +-def : Pat<(v4i64 (fp_to_sint v4f32:$vj)), +- (VEXT2XV_D_W (SUBREG_TO_REG (i64 0), (VFTINTRZ_W_S v4f32:$vj), +- sub_128))>; +-def : Pat<(v4i32 (fp_to_sint (v4f64 LASX256:$vj))), +- (EXTRACT_SUBREG (XVFTINTRZ_W_S (XVFCVT_S_D (XVPERMI_D v4f64:$vj, 238), +- v4f64:$vj)), +- sub_128)>; +- +-// XVFTINTRZ_{W_SU/L_DU} +-def : Pat<(v8i32 (fp_to_uint v8f32:$vj)), (XVFTINTRZ_WU_S v8f32:$vj)>; +-def : Pat<(v4i64 (fp_to_uint v4f64:$vj)), (XVFTINTRZ_LU_D v4f64:$vj)>; +-def : Pat<(v4i64 (fp_to_uint v4f32:$vj)), +- (VEXT2XV_DU_WU (SUBREG_TO_REG (i64 0), (VFTINTRZ_WU_S v4f32:$vj), +- sub_128))>; +-def : Pat<(v4i32 (fp_to_uint (v4f64 LASX256:$vj))), +- (EXTRACT_SUBREG (XVFTINTRZ_W_S (XVFCVT_S_D (XVPERMI_D v4f64:$vj, 238), +- v4f64:$vj)), +- sub_128)>; +- +-} // Predicates = [HasExtLASX] +- +-/// Intrinsic pattern +- +-class deriveLASXIntrinsic { +- Intrinsic ret = !cast(!tolower("int_loongarch_lasx_"#Inst)); +-} +- +-let Predicates = [HasExtLASX] in { +- +-// vty: v32i8/v16i16/v8i32/v4i64 +-// Pat<(Intrinsic vty:$xj, vty:$xk), +-// (LAInst vty:$xj, vty:$xk)>; +-foreach Inst = ["XVSADD_B", "XVSADD_BU", "XVSSUB_B", "XVSSUB_BU", +- "XVHADDW_H_B", "XVHADDW_HU_BU", "XVHSUBW_H_B", "XVHSUBW_HU_BU", +- "XVADDWEV_H_B", "XVADDWOD_H_B", "XVSUBWEV_H_B", "XVSUBWOD_H_B", +- "XVADDWEV_H_BU", "XVADDWOD_H_BU", "XVSUBWEV_H_BU", "XVSUBWOD_H_BU", +- "XVADDWEV_H_BU_B", "XVADDWOD_H_BU_B", +- "XVAVG_B", "XVAVG_BU", "XVAVGR_B", "XVAVGR_BU", +- "XVABSD_B", "XVABSD_BU", "XVADDA_B", "XVMUH_B", "XVMUH_BU", +- "XVMULWEV_H_B", "XVMULWOD_H_B", "XVMULWEV_H_BU", "XVMULWOD_H_BU", +- "XVMULWEV_H_BU_B", "XVMULWOD_H_BU_B", "XVSIGNCOV_B", +- "XVANDN_V", "XVORN_V", "XVROTR_B", "XVSRLR_B", "XVSRAR_B", +- "XVSEQ_B", "XVSLE_B", "XVSLE_BU", "XVSLT_B", "XVSLT_BU", +- "XVPACKEV_B", "XVPACKOD_B", "XVPICKEV_B", "XVPICKOD_B", +- "XVILVL_B", "XVILVH_B"] in +- def : Pat<(deriveLASXIntrinsic.ret +- (v32i8 LASX256:$xj), (v32i8 LASX256:$xk)), +- (!cast(Inst) LASX256:$xj, LASX256:$xk)>; +-foreach Inst = ["XVSADD_H", "XVSADD_HU", "XVSSUB_H", "XVSSUB_HU", +- "XVHADDW_W_H", "XVHADDW_WU_HU", "XVHSUBW_W_H", "XVHSUBW_WU_HU", +- "XVADDWEV_W_H", "XVADDWOD_W_H", "XVSUBWEV_W_H", "XVSUBWOD_W_H", +- "XVADDWEV_W_HU", "XVADDWOD_W_HU", "XVSUBWEV_W_HU", "XVSUBWOD_W_HU", +- "XVADDWEV_W_HU_H", "XVADDWOD_W_HU_H", +- "XVAVG_H", "XVAVG_HU", "XVAVGR_H", "XVAVGR_HU", +- "XVABSD_H", "XVABSD_HU", "XVADDA_H", "XVMUH_H", "XVMUH_HU", +- "XVMULWEV_W_H", "XVMULWOD_W_H", "XVMULWEV_W_HU", "XVMULWOD_W_HU", +- "XVMULWEV_W_HU_H", "XVMULWOD_W_HU_H", "XVSIGNCOV_H", "XVROTR_H", +- "XVSRLR_H", "XVSRAR_H", "XVSRLN_B_H", "XVSRAN_B_H", "XVSRLRN_B_H", +- "XVSRARN_B_H", "XVSSRLN_B_H", "XVSSRAN_B_H", "XVSSRLN_BU_H", +- "XVSSRAN_BU_H", "XVSSRLRN_B_H", "XVSSRARN_B_H", "XVSSRLRN_BU_H", +- "XVSSRARN_BU_H", +- "XVSEQ_H", "XVSLE_H", "XVSLE_HU", "XVSLT_H", "XVSLT_HU", +- "XVPACKEV_H", "XVPACKOD_H", "XVPICKEV_H", "XVPICKOD_H", +- "XVILVL_H", "XVILVH_H"] in +- def : Pat<(deriveLASXIntrinsic.ret +- (v16i16 LASX256:$xj), (v16i16 LASX256:$xk)), +- (!cast(Inst) LASX256:$xj, LASX256:$xk)>; +-foreach Inst = ["XVSADD_W", "XVSADD_WU", "XVSSUB_W", "XVSSUB_WU", +- "XVHADDW_D_W", "XVHADDW_DU_WU", "XVHSUBW_D_W", "XVHSUBW_DU_WU", +- "XVADDWEV_D_W", "XVADDWOD_D_W", "XVSUBWEV_D_W", "XVSUBWOD_D_W", +- "XVADDWEV_D_WU", "XVADDWOD_D_WU", "XVSUBWEV_D_WU", "XVSUBWOD_D_WU", +- "XVADDWEV_D_WU_W", "XVADDWOD_D_WU_W", +- "XVAVG_W", "XVAVG_WU", "XVAVGR_W", "XVAVGR_WU", +- "XVABSD_W", "XVABSD_WU", "XVADDA_W", "XVMUH_W", "XVMUH_WU", +- "XVMULWEV_D_W", "XVMULWOD_D_W", "XVMULWEV_D_WU", "XVMULWOD_D_WU", +- "XVMULWEV_D_WU_W", "XVMULWOD_D_WU_W", "XVSIGNCOV_W", "XVROTR_W", +- "XVSRLR_W", "XVSRAR_W", "XVSRLN_H_W", "XVSRAN_H_W", "XVSRLRN_H_W", +- "XVSRARN_H_W", "XVSSRLN_H_W", "XVSSRAN_H_W", "XVSSRLN_HU_W", +- "XVSSRAN_HU_W", "XVSSRLRN_H_W", "XVSSRARN_H_W", "XVSSRLRN_HU_W", +- "XVSSRARN_HU_W", +- "XVSEQ_W", "XVSLE_W", "XVSLE_WU", "XVSLT_W", "XVSLT_WU", +- "XVPACKEV_W", "XVPACKOD_W", "XVPICKEV_W", "XVPICKOD_W", +- "XVILVL_W", "XVILVH_W", "XVPERM_W"] in +- def : Pat<(deriveLASXIntrinsic.ret +- (v8i32 LASX256:$xj), (v8i32 LASX256:$xk)), +- (!cast(Inst) LASX256:$xj, LASX256:$xk)>; +-foreach Inst = ["XVADD_Q", "XVSUB_Q", +- "XVSADD_D", "XVSADD_DU", "XVSSUB_D", "XVSSUB_DU", +- "XVHADDW_Q_D", "XVHADDW_QU_DU", "XVHSUBW_Q_D", "XVHSUBW_QU_DU", +- "XVADDWEV_Q_D", "XVADDWOD_Q_D", "XVSUBWEV_Q_D", "XVSUBWOD_Q_D", +- "XVADDWEV_Q_DU", "XVADDWOD_Q_DU", "XVSUBWEV_Q_DU", "XVSUBWOD_Q_DU", +- "XVADDWEV_Q_DU_D", "XVADDWOD_Q_DU_D", +- "XVAVG_D", "XVAVG_DU", "XVAVGR_D", "XVAVGR_DU", +- "XVABSD_D", "XVABSD_DU", "XVADDA_D", "XVMUH_D", "XVMUH_DU", +- "XVMULWEV_Q_D", "XVMULWOD_Q_D", "XVMULWEV_Q_DU", "XVMULWOD_Q_DU", +- "XVMULWEV_Q_DU_D", "XVMULWOD_Q_DU_D", "XVSIGNCOV_D", "XVROTR_D", +- "XVSRLR_D", "XVSRAR_D", "XVSRLN_W_D", "XVSRAN_W_D", "XVSRLRN_W_D", +- "XVSRARN_W_D", "XVSSRLN_W_D", "XVSSRAN_W_D", "XVSSRLN_WU_D", +- "XVSSRAN_WU_D", "XVSSRLRN_W_D", "XVSSRARN_W_D", "XVSSRLRN_WU_D", +- "XVSSRARN_WU_D", "XVFFINT_S_L", +- "XVSEQ_D", "XVSLE_D", "XVSLE_DU", "XVSLT_D", "XVSLT_DU", +- "XVPACKEV_D", "XVPACKOD_D", "XVPICKEV_D", "XVPICKOD_D", +- "XVILVL_D", "XVILVH_D"] in +- def : Pat<(deriveLASXIntrinsic.ret +- (v4i64 LASX256:$xj), (v4i64 LASX256:$xk)), +- (!cast(Inst) LASX256:$xj, LASX256:$xk)>; +- +-// vty: v32i8/v16i16/v8i32/v4i64 +-// Pat<(Intrinsic vty:$xd, vty:$xj, vty:$xk), +-// (LAInst vty:$xd, vty:$xj, vty:$xk)>; +-foreach Inst = ["XVMADDWEV_H_B", "XVMADDWOD_H_B", "XVMADDWEV_H_BU", +- "XVMADDWOD_H_BU", "XVMADDWEV_H_BU_B", "XVMADDWOD_H_BU_B"] in +- def : Pat<(deriveLASXIntrinsic.ret +- (v16i16 LASX256:$xd), (v32i8 LASX256:$xj), (v32i8 LASX256:$xk)), +- (!cast(Inst) LASX256:$xd, LASX256:$xj, LASX256:$xk)>; +-foreach Inst = ["XVMADDWEV_W_H", "XVMADDWOD_W_H", "XVMADDWEV_W_HU", +- "XVMADDWOD_W_HU", "XVMADDWEV_W_HU_H", "XVMADDWOD_W_HU_H"] in +- def : Pat<(deriveLASXIntrinsic.ret +- (v8i32 LASX256:$xd), (v16i16 LASX256:$xj), (v16i16 LASX256:$xk)), +- (!cast(Inst) LASX256:$xd, LASX256:$xj, LASX256:$xk)>; +-foreach Inst = ["XVMADDWEV_D_W", "XVMADDWOD_D_W", "XVMADDWEV_D_WU", +- "XVMADDWOD_D_WU", "XVMADDWEV_D_WU_W", "XVMADDWOD_D_WU_W"] in +- def : Pat<(deriveLASXIntrinsic.ret +- (v4i64 LASX256:$xd), (v8i32 LASX256:$xj), (v8i32 LASX256:$xk)), +- (!cast(Inst) LASX256:$xd, LASX256:$xj, LASX256:$xk)>; +-foreach Inst = ["XVMADDWEV_Q_D", "XVMADDWOD_Q_D", "XVMADDWEV_Q_DU", +- "XVMADDWOD_Q_DU", "XVMADDWEV_Q_DU_D", "XVMADDWOD_Q_DU_D"] in +- def : Pat<(deriveLASXIntrinsic.ret +- (v4i64 LASX256:$xd), (v4i64 LASX256:$xj), (v4i64 LASX256:$xk)), +- (!cast(Inst) LASX256:$xd, LASX256:$xj, LASX256:$xk)>; +- +-// vty: v32i8/v16i16/v8i32/v4i64 +-// Pat<(Intrinsic vty:$xj), +-// (LAInst vty:$xj)>; +-foreach Inst = ["XVEXTH_H_B", "XVEXTH_HU_BU", +- "XVMSKLTZ_B", "XVMSKGEZ_B", "XVMSKNZ_B", +- "XVCLO_B", "VEXT2XV_H_B", "VEXT2XV_HU_BU", +- "VEXT2XV_W_B", "VEXT2XV_WU_BU", "VEXT2XV_D_B", +- "VEXT2XV_DU_BU", "XVREPLVE0_B", "XVREPLVE0_Q"] in +- def : Pat<(deriveLASXIntrinsic.ret (v32i8 LASX256:$xj)), +- (!cast(Inst) LASX256:$xj)>; +-foreach Inst = ["XVEXTH_W_H", "XVEXTH_WU_HU", "XVMSKLTZ_H", +- "XVCLO_H", "XVFCVTL_S_H", "XVFCVTH_S_H", +- "VEXT2XV_W_H", "VEXT2XV_WU_HU", "VEXT2XV_D_H", +- "VEXT2XV_DU_HU", "XVREPLVE0_H"] in +- def : Pat<(deriveLASXIntrinsic.ret (v16i16 LASX256:$xj)), +- (!cast(Inst) LASX256:$xj)>; +-foreach Inst = ["XVEXTH_D_W", "XVEXTH_DU_WU", "XVMSKLTZ_W", +- "XVCLO_W", "XVFFINT_S_W", "XVFFINT_S_WU", +- "XVFFINTL_D_W", "XVFFINTH_D_W", +- "VEXT2XV_D_W", "VEXT2XV_DU_WU", "XVREPLVE0_W"] in +- def : Pat<(deriveLASXIntrinsic.ret (v8i32 LASX256:$xj)), +- (!cast(Inst) LASX256:$xj)>; +-foreach Inst = ["XVEXTH_Q_D", "XVEXTH_QU_DU", "XVMSKLTZ_D", +- "XVEXTL_Q_D", "XVEXTL_QU_DU", +- "XVCLO_D", "XVFFINT_D_L", "XVFFINT_D_LU", +- "XVREPLVE0_D"] in +- def : Pat<(deriveLASXIntrinsic.ret (v4i64 LASX256:$xj)), +- (!cast(Inst) LASX256:$xj)>; +- +-// Pat<(Intrinsic timm:$imm) +-// (LAInst timm:$imm)>; +-def : Pat<(int_loongarch_lasx_xvldi timm:$imm), +- (XVLDI (to_valid_timm timm:$imm))>; +-foreach Inst = ["XVREPLI_B", "XVREPLI_H", "XVREPLI_W", "XVREPLI_D"] in +- def : Pat<(deriveLASXIntrinsic.ret timm:$imm), +- (!cast("Pseudo"#Inst) (to_valid_timm timm:$imm))>; +- +-// vty: v32i8/v16i16/v8i32/v4i64 +-// Pat<(Intrinsic vty:$xj, timm:$imm) +-// (LAInst vty:$xj, timm:$imm)>; +-foreach Inst = ["XVSAT_B", "XVSAT_BU", "XVNORI_B", "XVROTRI_B", "XVSLLWIL_H_B", +- "XVSLLWIL_HU_BU", "XVSRLRI_B", "XVSRARI_B", +- "XVSEQI_B", "XVSLEI_B", "XVSLEI_BU", "XVSLTI_B", "XVSLTI_BU", +- "XVREPL128VEI_B", "XVBSLL_V", "XVBSRL_V", "XVSHUF4I_B"] in +- def : Pat<(deriveLASXIntrinsic.ret (v32i8 LASX256:$xj), timm:$imm), +- (!cast(Inst) LASX256:$xj, (to_valid_timm timm:$imm))>; +-foreach Inst = ["XVSAT_H", "XVSAT_HU", "XVROTRI_H", "XVSLLWIL_W_H", +- "XVSLLWIL_WU_HU", "XVSRLRI_H", "XVSRARI_H", +- "XVSEQI_H", "XVSLEI_H", "XVSLEI_HU", "XVSLTI_H", "XVSLTI_HU", +- "XVREPL128VEI_H", "XVSHUF4I_H"] in +- def : Pat<(deriveLASXIntrinsic.ret (v16i16 LASX256:$xj), timm:$imm), +- (!cast(Inst) LASX256:$xj, (to_valid_timm timm:$imm))>; +-foreach Inst = ["XVSAT_W", "XVSAT_WU", "XVROTRI_W", "XVSLLWIL_D_W", +- "XVSLLWIL_DU_WU", "XVSRLRI_W", "XVSRARI_W", +- "XVSEQI_W", "XVSLEI_W", "XVSLEI_WU", "XVSLTI_W", "XVSLTI_WU", +- "XVREPL128VEI_W", "XVSHUF4I_W", "XVPICKVE_W"] in +- def : Pat<(deriveLASXIntrinsic.ret (v8i32 LASX256:$xj), timm:$imm), +- (!cast(Inst) LASX256:$xj, (to_valid_timm timm:$imm))>; +-foreach Inst = ["XVSAT_D", "XVSAT_DU", "XVROTRI_D", "XVSRLRI_D", "XVSRARI_D", +- "XVSEQI_D", "XVSLEI_D", "XVSLEI_DU", "XVSLTI_D", "XVSLTI_DU", +- "XVPICKVE2GR_D", "XVPICKVE2GR_DU", +- "XVREPL128VEI_D", "XVPERMI_D", "XVPICKVE_D"] in +- def : Pat<(deriveLASXIntrinsic.ret (v4i64 LASX256:$xj), timm:$imm), +- (!cast(Inst) LASX256:$xj, (to_valid_timm timm:$imm))>; +- +-// vty: v32i8/v16i16/v8i32/v4i64 +-// Pat<(Intrinsic vty:$xd, vty:$xj, timm:$imm) +-// (LAInst vty:$xd, vty:$xj, timm:$imm)>; +-foreach Inst = ["XVSRLNI_B_H", "XVSRANI_B_H", "XVSRLRNI_B_H", "XVSRARNI_B_H", +- "XVSSRLNI_B_H", "XVSSRANI_B_H", "XVSSRLNI_BU_H", "XVSSRANI_BU_H", +- "XVSSRLRNI_B_H", "XVSSRARNI_B_H", "XVSSRLRNI_BU_H", "XVSSRARNI_BU_H", +- "XVFRSTPI_B", "XVBITSELI_B", "XVEXTRINS_B", "XVPERMI_Q"] in +- def : Pat<(deriveLASXIntrinsic.ret +- (v32i8 LASX256:$xd), (v32i8 LASX256:$xj), timm:$imm), +- (!cast(Inst) LASX256:$xd, LASX256:$xj, +- (to_valid_timm timm:$imm))>; +-foreach Inst = ["XVSRLNI_H_W", "XVSRANI_H_W", "XVSRLRNI_H_W", "XVSRARNI_H_W", +- "XVSSRLNI_H_W", "XVSSRANI_H_W", "XVSSRLNI_HU_W", "XVSSRANI_HU_W", +- "XVSSRLRNI_H_W", "XVSSRARNI_H_W", "XVSSRLRNI_HU_W", "XVSSRARNI_HU_W", +- "XVFRSTPI_H", "XVEXTRINS_H"] in +- def : Pat<(deriveLASXIntrinsic.ret +- (v16i16 LASX256:$xd), (v16i16 LASX256:$xj), timm:$imm), +- (!cast(Inst) LASX256:$xd, LASX256:$xj, +- (to_valid_timm timm:$imm))>; +-foreach Inst = ["XVSRLNI_W_D", "XVSRANI_W_D", "XVSRLRNI_W_D", "XVSRARNI_W_D", +- "XVSSRLNI_W_D", "XVSSRANI_W_D", "XVSSRLNI_WU_D", "XVSSRANI_WU_D", +- "XVSSRLRNI_W_D", "XVSSRARNI_W_D", "XVSSRLRNI_WU_D", "XVSSRARNI_WU_D", +- "XVPERMI_W", "XVEXTRINS_W", "XVINSVE0_W"] in +- def : Pat<(deriveLASXIntrinsic.ret +- (v8i32 LASX256:$xd), (v8i32 LASX256:$xj), timm:$imm), +- (!cast(Inst) LASX256:$xd, LASX256:$xj, +- (to_valid_timm timm:$imm))>; +-foreach Inst = ["XVSRLNI_D_Q", "XVSRANI_D_Q", "XVSRLRNI_D_Q", "XVSRARNI_D_Q", +- "XVSSRLNI_D_Q", "XVSSRANI_D_Q", "XVSSRLNI_DU_Q", "XVSSRANI_DU_Q", +- "XVSSRLRNI_D_Q", "XVSSRARNI_D_Q", "XVSSRLRNI_DU_Q", "XVSSRARNI_DU_Q", +- "XVSHUF4I_D", "XVEXTRINS_D", "XVINSVE0_D"] in +- def : Pat<(deriveLASXIntrinsic.ret +- (v4i64 LASX256:$xd), (v4i64 LASX256:$xj), timm:$imm), +- (!cast(Inst) LASX256:$xd, LASX256:$xj, +- (to_valid_timm timm:$imm))>; +- +-// vty: v32i8/v16i16/v8i32/v4i64 +-// Pat<(Intrinsic vty:$xd, vty:$xj, vty:$xk), +-// (LAInst vty:$xd, vty:$xj, vty:$xk)>; +-foreach Inst = ["XVFRSTP_B", "XVBITSEL_V", "XVSHUF_B"] in +- def : Pat<(deriveLASXIntrinsic.ret +- (v32i8 LASX256:$xd), (v32i8 LASX256:$xj), (v32i8 LASX256:$xk)), +- (!cast(Inst) LASX256:$xd, LASX256:$xj, LASX256:$xk)>; +-foreach Inst = ["XVFRSTP_H", "XVSHUF_H"] in +- def : Pat<(deriveLASXIntrinsic.ret +- (v16i16 LASX256:$xd), (v16i16 LASX256:$xj), (v16i16 LASX256:$xk)), +- (!cast(Inst) LASX256:$xd, LASX256:$xj, LASX256:$xk)>; +-def : Pat<(int_loongarch_lasx_xvshuf_w (v8i32 LASX256:$xd), (v8i32 LASX256:$xj), +- (v8i32 LASX256:$xk)), +- (XVSHUF_W LASX256:$xd, LASX256:$xj, LASX256:$xk)>; +-def : Pat<(int_loongarch_lasx_xvshuf_d (v4i64 LASX256:$xd), (v4i64 LASX256:$xj), +- (v4i64 LASX256:$xk)), +- (XVSHUF_D LASX256:$xd, LASX256:$xj, LASX256:$xk)>; +- +-// vty: v8f32/v4f64 +-// Pat<(Intrinsic vty:$xj, vty:$xk, vty:$xa), +-// (LAInst vty:$xj, vty:$xk, vty:$xa)>; +-foreach Inst = ["XVFMSUB_S", "XVFNMADD_S", "XVFNMSUB_S"] in +- def : Pat<(deriveLASXIntrinsic.ret +- (v8f32 LASX256:$xj), (v8f32 LASX256:$xk), (v8f32 LASX256:$xa)), +- (!cast(Inst) LASX256:$xj, LASX256:$xk, LASX256:$xa)>; +-foreach Inst = ["XVFMSUB_D", "XVFNMADD_D", "XVFNMSUB_D"] in +- def : Pat<(deriveLASXIntrinsic.ret +- (v4f64 LASX256:$xj), (v4f64 LASX256:$xk), (v4f64 LASX256:$xa)), +- (!cast(Inst) LASX256:$xj, LASX256:$xk, LASX256:$xa)>; +- +-// vty: v8f32/v4f64 +-// Pat<(Intrinsic vty:$xj, vty:$xk), +-// (LAInst vty:$xj, vty:$xk)>; +-foreach Inst = ["XVFMAX_S", "XVFMIN_S", "XVFMAXA_S", "XVFMINA_S", "XVFCVT_H_S", +- "XVFCMP_CAF_S", "XVFCMP_CUN_S", "XVFCMP_CEQ_S", "XVFCMP_CUEQ_S", +- "XVFCMP_CLT_S", "XVFCMP_CULT_S", "XVFCMP_CLE_S", "XVFCMP_CULE_S", +- "XVFCMP_CNE_S", "XVFCMP_COR_S", "XVFCMP_CUNE_S", +- "XVFCMP_SAF_S", "XVFCMP_SUN_S", "XVFCMP_SEQ_S", "XVFCMP_SUEQ_S", +- "XVFCMP_SLT_S", "XVFCMP_SULT_S", "XVFCMP_SLE_S", "XVFCMP_SULE_S", +- "XVFCMP_SNE_S", "XVFCMP_SOR_S", "XVFCMP_SUNE_S"] in +- def : Pat<(deriveLASXIntrinsic.ret +- (v8f32 LASX256:$xj), (v8f32 LASX256:$xk)), +- (!cast(Inst) LASX256:$xj, LASX256:$xk)>; +-foreach Inst = ["XVFMAX_D", "XVFMIN_D", "XVFMAXA_D", "XVFMINA_D", "XVFCVT_S_D", +- "XVFTINTRNE_W_D", "XVFTINTRZ_W_D", "XVFTINTRP_W_D", "XVFTINTRM_W_D", +- "XVFTINT_W_D", +- "XVFCMP_CAF_D", "XVFCMP_CUN_D", "XVFCMP_CEQ_D", "XVFCMP_CUEQ_D", +- "XVFCMP_CLT_D", "XVFCMP_CULT_D", "XVFCMP_CLE_D", "XVFCMP_CULE_D", +- "XVFCMP_CNE_D", "XVFCMP_COR_D", "XVFCMP_CUNE_D", +- "XVFCMP_SAF_D", "XVFCMP_SUN_D", "XVFCMP_SEQ_D", "XVFCMP_SUEQ_D", +- "XVFCMP_SLT_D", "XVFCMP_SULT_D", "XVFCMP_SLE_D", "XVFCMP_SULE_D", +- "XVFCMP_SNE_D", "XVFCMP_SOR_D", "XVFCMP_SUNE_D"] in +- def : Pat<(deriveLASXIntrinsic.ret +- (v4f64 LASX256:$xj), (v4f64 LASX256:$xk)), +- (!cast(Inst) LASX256:$xj, LASX256:$xk)>; +- +-// vty: v8f32/v4f64 +-// Pat<(Intrinsic vty:$xj), +-// (LAInst vty:$xj)>; +-foreach Inst = ["XVFLOGB_S", "XVFCLASS_S", "XVFSQRT_S", "XVFRECIP_S", "XVFRSQRT_S", +- "XVFRINT_S", "XVFCVTL_D_S", "XVFCVTH_D_S", +- "XVFRINTRNE_S", "XVFRINTRZ_S", "XVFRINTRP_S", "XVFRINTRM_S", +- "XVFTINTRNE_W_S", "XVFTINTRZ_W_S", "XVFTINTRP_W_S", "XVFTINTRM_W_S", +- "XVFTINT_W_S", "XVFTINTRZ_WU_S", "XVFTINT_WU_S", +- "XVFTINTRNEL_L_S", "XVFTINTRNEH_L_S", "XVFTINTRZL_L_S", +- "XVFTINTRZH_L_S", "XVFTINTRPL_L_S", "XVFTINTRPH_L_S", +- "XVFTINTRML_L_S", "XVFTINTRMH_L_S", "XVFTINTL_L_S", +- "XVFTINTH_L_S"] in +- def : Pat<(deriveLASXIntrinsic.ret (v8f32 LASX256:$xj)), +- (!cast(Inst) LASX256:$xj)>; +-foreach Inst = ["XVFLOGB_D", "XVFCLASS_D", "XVFSQRT_D", "XVFRECIP_D", "XVFRSQRT_D", +- "XVFRINT_D", +- "XVFRINTRNE_D", "XVFRINTRZ_D", "XVFRINTRP_D", "XVFRINTRM_D", +- "XVFTINTRNE_L_D", "XVFTINTRZ_L_D", "XVFTINTRP_L_D", "XVFTINTRM_L_D", +- "XVFTINT_L_D", "XVFTINTRZ_LU_D", "XVFTINT_LU_D"] in +- def : Pat<(deriveLASXIntrinsic.ret (v4f64 LASX256:$xj)), +- (!cast(Inst) LASX256:$xj)>; ++class LASX_I8_U5_DESC_BASE { ++ dag OutOperandList = (outs); ++ dag InOperandList = (ins ROXD:$xd, PtrRC:$rj, ImmOp:$si8, uimm5:$idx); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $rj, $si8, $idx"); ++ list Pattern = [(OpNode ROXD:$xd, iPTR:$rj, Imm:$si8, immZExt5:$idx)]; ++ string DecoderMethod = "DecodeLASX256memstl"; ++} + +-// 256-Bit vector FP approximate reciprocal operation +-let Predicates = [HasFrecipe] in { +-foreach Inst = ["XVFRECIPE_S", "XVFRSQRTE_S"] in +- def : Pat<(deriveLASXIntrinsic.ret (v8f32 LASX256:$xj)), +- (!cast(Inst) LASX256:$xj)>; +-foreach Inst = ["XVFRECIPE_D", "XVFRSQRTE_D"] in +- def : Pat<(deriveLASXIntrinsic.ret (v4f64 LASX256:$xj)), +- (!cast(Inst) LASX256:$xj)>; +-} +- +-def : Pat<(int_loongarch_lasx_xvpickve_w_f v8f32:$xj, timm:$imm), +- (XVPICKVE_W v8f32:$xj, (to_valid_timm timm:$imm))>; +-def : Pat<(int_loongarch_lasx_xvpickve_d_f v4f64:$xj, timm:$imm), +- (XVPICKVE_D v4f64:$xj, (to_valid_timm timm:$imm))>; +- +-// load +-def : Pat<(int_loongarch_lasx_xvld GPR:$rj, timm:$imm), +- (XVLD GPR:$rj, (to_valid_timm timm:$imm))>; +-def : Pat<(int_loongarch_lasx_xvldx GPR:$rj, GPR:$rk), +- (XVLDX GPR:$rj, GPR:$rk)>; +- +-def : Pat<(int_loongarch_lasx_xvldrepl_b GPR:$rj, timm:$imm), +- (XVLDREPL_B GPR:$rj, (to_valid_timm timm:$imm))>; +-def : Pat<(int_loongarch_lasx_xvldrepl_h GPR:$rj, timm:$imm), +- (XVLDREPL_H GPR:$rj, (to_valid_timm timm:$imm))>; +-def : Pat<(int_loongarch_lasx_xvldrepl_w GPR:$rj, timm:$imm), +- (XVLDREPL_W GPR:$rj, (to_valid_timm timm:$imm))>; +-def : Pat<(int_loongarch_lasx_xvldrepl_d GPR:$rj, timm:$imm), +- (XVLDREPL_D GPR:$rj, (to_valid_timm timm:$imm))>; +- +-// store +-def : Pat<(int_loongarch_lasx_xvst LASX256:$xd, GPR:$rj, timm:$imm), +- (XVST LASX256:$xd, GPR:$rj, (to_valid_timm timm:$imm))>; +-def : Pat<(int_loongarch_lasx_xvstx LASX256:$xd, GPR:$rj, GPR:$rk), +- (XVSTX LASX256:$xd, GPR:$rj, GPR:$rk)>; +- +-def : Pat<(int_loongarch_lasx_xvstelm_b v32i8:$xd, GPR:$rj, timm:$imm, timm:$idx), +- (XVSTELM_B v32i8:$xd, GPR:$rj, (to_valid_timm timm:$imm), +- (to_valid_timm timm:$idx))>; +-def : Pat<(int_loongarch_lasx_xvstelm_h v16i16:$xd, GPR:$rj, timm:$imm, timm:$idx), +- (XVSTELM_H v16i16:$xd, GPR:$rj, (to_valid_timm timm:$imm), +- (to_valid_timm timm:$idx))>; +-def : Pat<(int_loongarch_lasx_xvstelm_w v8i32:$xd, GPR:$rj, timm:$imm, timm:$idx), +- (XVSTELM_W v8i32:$xd, GPR:$rj, (to_valid_timm timm:$imm), +- (to_valid_timm timm:$idx))>; +-def : Pat<(int_loongarch_lasx_xvstelm_d v4i64:$xd, GPR:$rj, timm:$imm, timm:$idx), +- (XVSTELM_D v4i64:$xd, GPR:$rj, (to_valid_timm timm:$imm), +- (to_valid_timm timm:$idx))>; +- +-} // Predicates = [HasExtLASX] ++class LASX_I8_U2_DESC_BASE { ++ dag OutOperandList = (outs); ++ dag InOperandList = (ins ROXD:$xd, PtrRC:$rj, ImmOp:$si8, uimm2:$idx); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $rj, $si8, $idx"); ++ list Pattern = [(OpNode ROXD:$xd, iPTR:$rj, Imm:$si8, immZExt2:$idx)]; ++ string DecoderMethod = "DecodeLASX256memstl"; ++} ++ ++class LASX_I8_U3_DESC_BASE { ++ dag OutOperandList = (outs); ++ dag InOperandList = (ins ROXD:$xd, PtrRC:$rj, ImmOp:$si8, uimm3:$idx); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $rj, $si8, $idx"); ++ list Pattern = [(OpNode ROXD:$xd, iPTR:$rj, Imm:$si8, immZExt3:$idx)]; ++ string DecoderMethod = "DecodeLASX256memstl"; ++} ++ ++class LASX_I8_U4_DESC_BASE { ++ dag OutOperandList = (outs); ++ dag InOperandList = (ins ROXD:$xd, PtrRC:$rj, ImmOp:$si8, uimm4:$idx); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $rj, $si8, $idx"); ++ list Pattern = [(OpNode ROXD:$xd, iPTR:$rj, Imm:$si8, immZExt4:$idx)]; ++ string DecoderMethod = "DecodeLASX256memstl"; ++} ++ ++class LASX_SDX_LA { ++ dag OutOperandList = (outs); ++ dag InOperandList = (ins ROXD:$xd, PtrRC:$rj, RORK:$rk); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $rj, $rk"); ++ list Pattern = [(OpNode ROXD:$xd, iPTR:$rj, RORK:$rk)]; ++} ++ ++class LASX_3R_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, ROXK:$xk); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $xk"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, ROXK:$xk))]; ++} ++ ++class LASX_LDX_LA { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins PtrRC:$rj, RORK:$rk); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $rj, $rk"); ++ list Pattern = [(set ROXD:$xd, (OpNode iPTR:$rj, RORK:$rk))]; ++} ++ ++class LASX_3R_4R_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXD:$xd_in, ROXJ:$xj, ROXK:$xk); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $xk"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXD:$xd_in, ROXJ:$xj, ++ ROXK:$xk))]; ++ string Constraints = "$xd = $xd_in"; ++} ++ ++ ++class LASX_3R_VREPLVE_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, GPR32Opnd:$rk); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $rk"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, GPR32Opnd:$rk))]; ++} ++ ++ ++class LASX_3R_VREPLVE_DESC_BASE_N { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, GPR64Opnd:$rk); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $rk"); ++ list Pattern = []; ++} ++ ++ ++class LASX_VEC_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, ROXK:$xk); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $xk"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, ROXK:$xk))]; ++} ++ ++ ++ ++class LASX_3RF_DESC_BASE : ++ LASX_3R_DESC_BASE; ++ ++ ++class LASX_3R_DESC_BASE1 { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, ROXK:$xk); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $xk"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, ROXK:$xk))]; ++} ++ ++class LASX_3RF_DESC_BASE1 : ++ LASX_3R_DESC_BASE1; ++ ++ ++ ++class LASX_3R_VSHF_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXD:$xd_in, ROXJ:$xj, ROXK:$xk); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $xk"); ++ list Pattern = [(set ROXD:$xd, (LoongArchVSHF ROXD:$xd_in, ROXJ:$xj, ++ ROXK:$xk))]; ++ string Constraints = "$xd = $xd_in"; ++} ++ ++class LASX_I5_SETCC_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, SplatImm.OpClass:$si5); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $si5"); ++ list Pattern = [(set ROXD:$xd, (VT (vsetcc ROXJ:$xj, SplatImm:$si5, CC)))]; ++} ++ ++class LASX_I5_SETCC_DESC_BASE_Intrinsic { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, ImmOp:$si5); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $si5"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, Imm:$si5))]; ++} ++ ++ ++class LASX_I5_U_SETCC_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, SplatImm.OpClass:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui5"); ++ list Pattern = [(set ROXD:$xd, (VT (vsetcc ROXJ:$xj, SplatImm:$ui5, CC)))]; ++} ++ ++class LASX_I5_U_SETCC_DESC_BASE_Intrinsic { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, ImmOp:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui5"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, Imm:$ui5))]; ++} ++ ++class LASX_VEC_PSEUDO_BASE : ++ LASXPseudo<(outs ROXD:$xd), (ins ROXJ:$xj, ROXK:$xk), ++ [(set ROXD:$xd, (OpNode ROXJ:$xj, ROXK:$xk))]>; ++ ++ ++class LASX_I5_U_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, SplatImm.OpClass:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui5"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, SplatImm:$ui5))]; ++} ++ ++ ++class LASX_I5_U_DESC_BASE_Intrinsic { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, ImmOp:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui5"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, Imm:$ui5))]; ++} ++ ++class LASX_U5_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, uimm5:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui5"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, immZExt5:$ui5))]; ++} ++ ++class LASX_U5N_DESC_BASE : ++ LASX_U5_DESC_BASE; ++ ++class LASX_U5_4R_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXD:$xd_in, ROXJ:$xj, uimm5:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui5"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXD:$xd_in, ROXJ:$xj, immZExt5:$ui5))]; ++ string Constraints = "$xd = $xd_in"; ++} ++ ++class LASX_2R_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj))]; ++} ++ ++class LASX_SET_DESC_BASE { ++ dag OutOperandList = (outs FCFROpnd:$cd); ++ dag InOperandList = (ins ROXD:$xj); ++ string AsmString = !strconcat(instr_asm, "\t$cd, $xj"); ++ list Pattern = []; ++} ++ ++class LASX_FRECIPE_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj"); ++ list Pattern = []; ++} ++ ++class LASX_2RF_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj))]; ++} ++ ++class LASX_I5_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, SplatImm.OpClass:$si5); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $si5"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, SplatImm:$si5))]; ++} ++ ++class LASX_I5_DESC_BASE_Intrinsic { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, ImmOp:$si5); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $si5"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, Imm:$si5))]; ++} ++ ++ ++class LASX_2R_REPL_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROS:$rj); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $rj"); ++ list Pattern = [(set ROXD:$xd, (VT (OpNode ROS:$rj)))]; ++} ++ ++class LASX_XVEXTEND_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj"); ++ list Pattern = [(set ROXD:$xd, (DTy (OpNode (STy ROXJ:$xj))))]; ++} ++ ++class LASX_RORI_U3_DESC_BASE_Intrinsic { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, ImmOp:$ui3); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui3"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, Imm:$ui3))]; ++} ++ ++class LASX_RORI_U4_DESC_BASE_Intrinsic { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, ImmOp:$ui4); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui4"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, Imm:$ui4))]; ++} ++ ++class LASX_RORI_U5_DESC_BASE_Intrinsic { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, ImmOp:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui5"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, Imm:$ui5))]; ++} ++ ++class LASX_RORI_U6_DESC_BASE_Intrinsic { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, ImmOp:$ui6); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui6"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, Imm:$ui6))]; ++} ++ ++class LASX_BIT_3_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, ImmOp:$ui3); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui3"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, Imm:$ui3))]; ++} ++ ++class LASX_BIT_4_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, ImmOp:$ui4); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui4"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, Imm:$ui4))]; ++} ++ ++class LASX_BIT_5_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, ImmOp:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui5"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, Imm:$ui5))]; ++} ++ ++class LASX_BIT_6_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, ImmOp:$ui6); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui6"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, Imm:$ui6))]; ++} ++ ++class LASX_BIT_2_4O_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXD:$xd_in, ROXJ:$xj, ImmOp:$ui2); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui2"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXD:$xd_in, ROXJ:$xj, Imm:$ui2))]; ++ string Constraints = "$xd = $xd_in"; ++} ++ ++class LASX_BIT_2_4ON : ++ LASX_BIT_2_4O_DESC_BASE; ++ ++class LASX_BIT_3_4O_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXD:$xd_in, ROXJ:$xj, ImmOp:$ui3); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui3"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXD:$xd_in, ROXJ:$xj, Imm:$ui3))]; ++ string Constraints = "$xd = $xd_in"; ++} ++ ++class LASX_BIT_3_4ON : ++ LASX_BIT_3_4O_DESC_BASE; ++ ++class LASX_INSERT_U3_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXD:$xd_in, ROS:$rj, ImmOp:$ui3); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $rj, $ui3"); ++ list Pattern = [(set ROXD:$xd, (VTy (insertelt (VTy ROXD:$xd_in), ROS:$rj, Imm:$ui3)))]; ++ string Constraints = "$xd = $xd_in"; ++} ++ ++class LASX_INSERT_U2_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXD:$xd_in, ROS:$rj, ImmOp:$ui2); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $rj, $ui2"); ++ list Pattern = [(set ROXD:$xd, (VTy (insertelt (VTy ROXD:$xd_in), ROS:$rj, Imm:$ui2)))]; ++ string Constraints = "$xd = $xd_in"; ++} ++ ++class LASX_COPY_U2_DESC_BASE { ++ dag OutOperandList = (outs ROD:$rd); ++ dag InOperandList = (ins ROXJ:$xj, ImmOp:$ui2); ++ string AsmString = !strconcat(instr_asm, "\t$rd, $xj, $ui2"); ++ list Pattern = [(set ROD:$rd, (OpNode (VecTy ROXJ:$xj), Imm:$ui2))]; ++} ++ ++class LASX_COPY_U3_DESC_BASE { ++ dag OutOperandList = (outs ROD:$rd); ++ dag InOperandList = (ins ROXJ:$xj, ImmOp:$ui3); ++ string AsmString = !strconcat(instr_asm, "\t$rd, $xj, $ui3"); ++ list Pattern = [(set ROD:$rd, (OpNode (VecTy ROXJ:$xj), Imm:$ui3))]; ++} ++ ++class LASX_ELM_U4_VREPLVE_DESC_BASE_Intrinsic { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, uimm4:$ui4); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui4"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, immZExt4:$ui4))]; ++} ++ ++class LASX_ELM_U3_VREPLVE_DESC_BASE_Intrinsic { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, uimm3:$ui3); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui3"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, immZExt3:$ui3))]; ++} ++ ++class LASX_ELM_U2_VREPLVE_DESC_BASE_Intrinsic { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, uimm2:$ui2); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui2"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, immZExt2:$ui2))]; ++} ++ ++class LASX_ELM_U1_VREPLVE_DESC_BASE_Intrinsic { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, uimm1:$ui1); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui1"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, immZExt1:$ui1))]; ++} ++ ++class LASX_XVBROADCAST_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj"); ++ list Pattern = [(set ROXD:$xd, (OpNode (TyNode ROXJ:$xj)))]; ++} ++ ++class LASX_2R_U3_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, uimm3:$ui3); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui3"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, immZExt3:$ui3))]; ++} ++ ++class LASX_2R_U4_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, uimm4:$ui4); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui4"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, immZExt4:$ui4))]; ++} ++ ++class LASX_2R_U5_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, uimm5:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui5"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, immZExt5:$ui5))]; ++} ++ ++class LASX_2R_U6_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, uimm6:$ui6); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui6"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, immZExt6:$ui6))]; ++} ++ ++class LASX_BIT_U3_VREPLVE_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, SplatImm.OpClass:$ui3); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui3"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, SplatImm:$ui3))]; ++} ++ ++class LASX_BIT_U4_VREPLVE_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, SplatImm.OpClass:$ui4); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui4"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, SplatImm:$ui4))]; ++} ++ ++class LASX_BIT_U5_VREPLVE_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, SplatImm.OpClass:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui5"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, SplatImm:$ui5))]; ++} ++ ++class LASX_BIT_U6_VREPLVE_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, SplatImm.OpClass:$ui6); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui6"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, SplatImm:$ui6))]; ++} ++ ++class LASX_BIT_U3_VREPLVE_DESC_BASE_Intrinsic { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, ImmOp:$ui3); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui3"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, Imm:$ui3))]; ++} ++ ++class LASX_BIT_U4_VREPLVE_DESC_BASE_Intrinsic { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, ImmOp:$ui4); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui4"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, Imm:$ui4))]; ++} ++ ++class LASX_BIT_U5_VREPLVE_DESC_BASE_Intrinsic { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, ImmOp:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui5"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, Imm:$ui5))]; ++} ++ ++class LASX_BIT_U6_VREPLVE_DESC_BASE_Intrinsic { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, ImmOp:$ui6); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui6"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, Imm:$ui6))]; ++} ++ ++class LASX_U4_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXD:$xd_in,ROXJ:$xj, ImmOp:$ui4); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui4"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXD:$xd_in,ROXJ:$xj, Imm:$ui4))]; ++ string Constraints = "$xd = $xd_in"; ++} ++ ++class LASX_N4_U5_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXD:$xd_in, ROXJ:$xj, ImmOp:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui5"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXD:$xd_in, ROXJ:$xj, Imm:$ui5))]; ++ string Constraints = "$xd = $xd_in"; ++} ++ ++class LASX_U6_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXD:$xd_in, ROXJ:$xj, ImmOp:$ui6); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui6"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXD:$xd_in, ROXJ:$xj, Imm:$ui6))]; ++ string Constraints = "$xd = $xd_in"; ++} ++ ++class LASX_D_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXD:$xd_in, ROXJ:$xj, uimm7:$ui7); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui7"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXD:$xd_in, ROXJ:$xj, immZExt7:$ui7))]; ++ string Constraints = "$xd = $xd_in"; ++} ++ ++class LASX_2R_3R_U4_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXD:$xd_in, ROXJ:$xj, uimm4:$ui4); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui4"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXD:$xd_in, ROXJ:$xj, immZExt4:$ui4))]; ++ string Constraints = "$xd = $xd_in"; ++} ++ ++class LASX_2R_3R_U5_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXD:$xd_in, ROXJ:$xj, uimm5:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui5"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXD:$xd_in, ROXJ:$xj, immZExt5:$ui5))]; ++ string Constraints = "$xd = $xd_in"; ++} ++ ++class LASX_2R_3R_U6_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXD:$xd_in, ROXJ:$xj, uimm6:$ui6); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui6"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXD:$xd_in, ROXJ:$xj, immZExt6:$ui6))]; ++ string Constraints = "$xd = $xd_in"; ++} ++ ++class LASX_2R_3R_U7_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXD:$xd_in, ROXJ:$xj, uimm7:$ui7); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui7"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXD:$xd_in, ROXJ:$xj, immZExt7:$ui7))]; ++ string Constraints = "$xd = $xd_in"; ++} ++ ++class LASX_2R_3R_U8_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXD:$xd_in, ROXJ:$xj, uimm8:$ui8); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui8"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXD:$xd_in, ROXJ:$xj, immZExt8:$ui8))]; ++ string Constraints = "$xd = $xd_in"; ++} ++ ++class LASX_2R_3R_U8_SELECT { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXD:$xd_in, ROXJ:$xj, vsplat_uimm8:$ui8); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui8"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXD:$xd_in, xvsplati8_uimm8:$ui8, ROXJ:$xj))]; ++ string Constraints = "$xd = $xd_in"; ++} ++ ++class LASX_I8_O4_SHF_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXD:$xd_in, ROXJ:$xj, uimm8:$ui8); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui8"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXD:$xd_in, ROXJ:$xj, immZExt8:$ui8))]; ++ string Constraints = "$xd = $xd_in"; ++} ++ ++class LASX_I8_SHF_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, uimm8:$ui8); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui8"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, immZExt8:$ui8))]; ++} ++ ++class LASX_2R_U8_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, uimm8:$ui8); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui8"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, immZExt8:$ui8))]; ++} ++ ++class LASX_I13_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins immOp:$i13); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $i13"); ++ list Pattern = [(set ROXD:$xd, (OpNode (Ty simm13:$i13)))]; ++ string DecoderMethod = "DecodeLASX256Mem13"; ++} ++ ++class LASX_I13_DESC_BASE_10 { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ImmOp:$i10); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $i10"); ++ bit hasSideEffects = 0; ++ string DecoderMethod = "DecodeLASX256Mem10"; ++ list Pattern = [(set ROXD:$xd, (OpNode Imm:$i10))]; ++ } ++ ++class LASX_BIT_U8_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXJ:$xj, SplatImm.OpClass:$ui8); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui8"); ++ list Pattern = [(set ROXD:$xd, (OpNode ROXJ:$xj, SplatImm:$ui8))]; ++} ++ ++class LASX_2RN_3R_U8_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins ROXD:$xd_in, ROXJ:$xj, uimm8:$ui8); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $xj, $ui8"); ++ list Pattern = []; ++ string Constraints = "$xd = $xd_in"; ++} ++ ++ ++//encoding ++ ++def XVFMADD_S : LASX_4R<0b000010100001>, ++ LASX_4RF<"xvfmadd.s", int_loongarch_lasx_xvfmadd_s, LASX256WOpnd>; ++ ++def XVFMADD_D : LASX_4R<0b000010100010>, ++ LASX_4RF<"xvfmadd.d", int_loongarch_lasx_xvfmadd_d, LASX256DOpnd>; ++ ++ ++def XVFMSUB_S : LASX_4R<0b000010100101>, ++ LASX_4RF<"xvfmsub.s", int_loongarch_lasx_xvfmsub_s, LASX256WOpnd>; ++ ++def XVFMSUB_D : LASX_4R<0b000010100110>, ++ LASX_4RF<"xvfmsub.d", int_loongarch_lasx_xvfmsub_d, LASX256DOpnd>; ++ ++ ++def XVFNMADD_S : LASX_4R<0b000010101001>, ++ LASX_4RF<"xvfnmadd.s", int_loongarch_lasx_xvfnmadd_s, LASX256WOpnd>; ++ ++def XVFNMADD_D : LASX_4R<0b000010101010>, ++ LASX_4RF<"xvfnmadd.d", int_loongarch_lasx_xvfnmadd_d, LASX256DOpnd>; ++ ++ ++def XVFNMSUB_S : LASX_4R<0b000010101101>, ++ LASX_4RF<"xvfnmsub.s", int_loongarch_lasx_xvfnmsub_s, LASX256WOpnd>; ++ ++def XVFNMSUB_D : LASX_4R<0b000010101110>, ++ LASX_4RF<"xvfnmsub.d", int_loongarch_lasx_xvfnmsub_d, LASX256DOpnd>; ++ ++ ++// xvfmadd: xj * xk + xa ++def : LASXPat<(fma v4f64:$xj, v4f64:$xk, v4f64:$xa), ++ (XVFMADD_D $xj, $xk, $xa)>; ++ ++def : LASXPat<(fma v8f32:$xj, v8f32:$xk, v8f32:$xa), ++ (XVFMADD_S $xj, $xk, $xa)>; ++ ++ ++// xvfmsub: xj * xk - xa ++def : LASXPat<(fma v4f64:$xj, v4f64:$xk, (fneg v4f64:$xa)), ++ (XVFMSUB_D v4f64:$xj, v4f64:$xk, v4f64:$xa)>; ++ ++def : LASXPat<(fma v8f32:$xj, v8f32:$xk, (fneg v8f32:$xa)), ++ (XVFMSUB_S v8f32:$xj, v8f32:$xk, v8f32:$xa)>; ++ ++ ++// xvfnmadd: -(xj * xk + xa) ++def : LASXPat<(fma (fneg v4f64:$xj), v4f64:$xk, (fneg v4f64:$xa)), ++ (XVFNMADD_D v4f64:$xj, v4f64:$xk, v4f64:$xa)>; ++ ++def : LASXPat<(fma (fneg v8f32:$xj), v8f32:$xk, (fneg v8f32:$xa)), ++ (XVFNMADD_S v8f32:$xj, v8f32:$xk, v8f32:$xa)>; ++ ++// xvfnmsub: -(xj * xk - xa) ++def : LASXPat<(fma (fneg v4f64:$xj), v4f64:$xk, v4f64:$xa), ++ (XVFNMSUB_D v4f64:$xj, v4f64:$xk, v4f64:$xa)>; ++ ++def : LASXPat<(fma (fneg v8f32:$xj), v8f32:$xk, v8f32:$xa), ++ (XVFNMSUB_S v8f32:$xj, v8f32:$xk, v8f32:$xa)>; ++ ++ ++def XVFCMP_CAF_S : LASX_XVFCMP<0b000011001001>, ++ LASX_3RF<"xvfcmp.caf.s", int_loongarch_lasx_xvfcmp_caf_s, LASX256WOpnd>{ ++ bits<5> cond=0x0; ++ } ++ ++def XVFCMP_CAF_D : LASX_XVFCMP<0b000011001010>, ++ LASX_3RF<"xvfcmp.caf.d", int_loongarch_lasx_xvfcmp_caf_d, LASX256DOpnd>{ ++ bits<5> cond=0x0; ++ } ++ ++def XVFCMP_COR_S : LASX_XVFCMP<0b000011001001>, ++ LASX_3RF<"xvfcmp.cor.s", vfsetord_v8f32, LASX256WOpnd>{ ++ bits<5> cond=0x14; ++ } ++ ++def XVFCMP_COR_D : LASX_XVFCMP<0b000011001010>, ++ LASX_3RF<"xvfcmp.cor.d", vfsetord_v4f64, LASX256DOpnd>{ ++ bits<5> cond=0x14; ++ } ++ ++def XVFCMP_CUN_S : LASX_XVFCMP<0b000011001001>, ++ LASX_3RF<"xvfcmp.cun.s", vfsetun_v8f32, LASX256WOpnd>{ ++ bits<5> cond=0x8; ++ } ++ ++def XVFCMP_CUN_D : LASX_XVFCMP<0b000011001010>, ++ LASX_3RF<"xvfcmp.cun.d", vfsetun_v4f64, LASX256DOpnd>{ ++ bits<5> cond=0x8; ++ } ++ ++def XVFCMP_CUNE_S : LASX_XVFCMP<0b000011001001>, ++ LASX_3RF<"xvfcmp.cune.s", vfsetune_v8f32, LASX256WOpnd>{ ++ bits<5> cond=0x18; ++ } ++ ++def XVFCMP_CUNE_D : LASX_XVFCMP<0b000011001010>, ++ LASX_3RF<"xvfcmp.cune.d", vfsetune_v4f64, LASX256DOpnd>{ ++ bits<5> cond=0x18; ++ } ++ ++def XVFCMP_CUEQ_S : LASX_XVFCMP<0b000011001001>, ++ LASX_3RF<"xvfcmp.cueq.s", vfsetueq_v8f32, LASX256WOpnd>{ ++ bits<5> cond=0xc; ++ } ++ ++def XVFCMP_CUEQ_D : LASX_XVFCMP<0b000011001010>, ++ LASX_3RF<"xvfcmp.cueq.d", vfsetueq_v4f64, LASX256DOpnd>{ ++ bits<5> cond=0xc; ++ } ++ ++def XVFCMP_CEQ_S : LASX_XVFCMP<0b000011001001>, ++ LASX_3RF<"xvfcmp.ceq.s", vfsetoeq_v8f32, LASX256WOpnd>{ ++ bits<5> cond=0x4; ++ } ++ ++def XVFCMP_CEQ_D : LASX_XVFCMP<0b000011001010>, ++ LASX_3RF<"xvfcmp.ceq.d", vfsetoeq_v4f64, LASX256DOpnd>{ ++ bits<5> cond=0x4; ++ } ++ ++def XVFCMP_CNE_S : LASX_XVFCMP<0b000011001001>, ++ LASX_3RF<"xvfcmp.cne.s", vfsetone_v8f32, LASX256WOpnd>{ ++ bits<5> cond=0x10; ++ } ++ ++def XVFCMP_CNE_D : LASX_XVFCMP<0b000011001010>, ++ LASX_3RF<"xvfcmp.cne.d", vfsetone_v4f64, LASX256DOpnd>{ ++ bits<5> cond=0x10; ++ } ++ ++def XVFCMP_CLT_S : LASX_XVFCMP<0b000011001001>, ++ LASX_3RF<"xvfcmp.clt.s", vfsetolt_v8f32, LASX256WOpnd>{ ++ bits<5> cond=0x2; ++ } ++ ++def XVFCMP_CLT_D : LASX_XVFCMP<0b000011001010>, ++ LASX_3RF<"xvfcmp.clt.d", vfsetolt_v4f64, LASX256DOpnd>{ ++ bits<5> cond=0x2; ++ } ++ ++def XVFCMP_CULT_S : LASX_XVFCMP<0b000011001001>, ++ LASX_3RF<"xvfcmp.cult.s", vfsetult_v8f32, LASX256WOpnd>{ ++ bits<5> cond=0xa; ++ } ++ ++def XVFCMP_CULT_D : LASX_XVFCMP<0b000011001010>, ++ LASX_3RF<"xvfcmp.cult.d", vfsetult_v4f64, LASX256DOpnd>{ ++ bits<5> cond=0xa; ++ } ++ ++def XVFCMP_CLE_S : LASX_XVFCMP<0b000011001001>, ++ LASX_3RF<"xvfcmp.cle.s", vfsetole_v8f32, LASX256WOpnd>{ ++ bits<5> cond=0x6; ++ } ++ ++def XVFCMP_CLE_D : LASX_XVFCMP<0b000011001010>, ++ LASX_3RF<"xvfcmp.cle.d", vfsetole_v4f64, LASX256DOpnd>{ ++ bits<5> cond=0x6; ++ } ++ ++def XVFCMP_CULE_S : LASX_XVFCMP<0b000011001001>, ++ LASX_3RF<"xvfcmp.cule.s", vfsetule_v8f32, LASX256WOpnd>{ ++ bits<5> cond=0xe; ++ } ++ ++def XVFCMP_CULE_D : LASX_XVFCMP<0b000011001010>, ++ LASX_3RF<"xvfcmp.cule.d", vfsetule_v4f64, LASX256DOpnd>{ ++ bits<5> cond=0xe; ++ } ++ ++def XVFCMP_SAF_S : LASX_XVFCMP<0b000011001001>, ++ LASX_3RF<"xvfcmp.saf.s", int_loongarch_lasx_xvfcmp_saf_s, LASX256WOpnd>{ ++ bits<5> cond=0x1; ++ } ++ ++def XVFCMP_SAF_D : LASX_XVFCMP<0b000011001010>, ++ LASX_3RF<"xvfcmp.saf.d", int_loongarch_lasx_xvfcmp_saf_d, LASX256DOpnd>{ ++ bits<5> cond=0x1; ++ } ++ ++def XVFCMP_SOR_S : LASX_XVFCMP<0b000011001001>, ++ LASX_3RF<"xvfcmp.sor.s", int_loongarch_lasx_xvfcmp_sor_s, LASX256WOpnd>{ ++ bits<5> cond=0x15; ++ } ++ ++def XVFCMP_SOR_D : LASX_XVFCMP<0b000011001010>, ++ LASX_3RF<"xvfcmp.sor.d", int_loongarch_lasx_xvfcmp_sor_d, LASX256DOpnd>{ ++ bits<5> cond=0x15; ++ } ++ ++def XVFCMP_SUN_S : LASX_XVFCMP<0b000011001001>, ++ LASX_3RF<"xvfcmp.sun.s", int_loongarch_lasx_xvfcmp_sun_s, LASX256WOpnd>{ ++ bits<5> cond=0x9; ++ } ++ ++def XVFCMP_SUN_D : LASX_XVFCMP<0b000011001010>, ++ LASX_3RF<"xvfcmp.sun.d", int_loongarch_lasx_xvfcmp_sun_d, LASX256DOpnd>{ ++ bits<5> cond=0x9; ++ } ++ ++def XVFCMP_SUNE_S : LASX_XVFCMP<0b000011001001>, ++ LASX_3RF<"xvfcmp.sune.s", int_loongarch_lasx_xvfcmp_sune_s, LASX256WOpnd>{ ++ bits<5> cond=0x19; ++ } ++ ++def XVFCMP_SUNE_D : LASX_XVFCMP<0b000011001010>, ++ LASX_3RF<"xvfcmp.sune.d", int_loongarch_lasx_xvfcmp_sune_d, LASX256DOpnd>{ ++ bits<5> cond=0x19; ++ } ++ ++def XVFCMP_SUEQ_S : LASX_XVFCMP<0b000011001001>, ++ LASX_3RF<"xvfcmp.sueq.s", int_loongarch_lasx_xvfcmp_sueq_s, LASX256WOpnd>{ ++ bits<5> cond=0xd; ++ } ++ ++def XVFCMP_SUEQ_D : LASX_XVFCMP<0b000011001010>, ++ LASX_3RF<"xvfcmp.sueq.d", int_loongarch_lasx_xvfcmp_sueq_d, LASX256DOpnd>{ ++ bits<5> cond=0xd; ++ } ++ ++def XVFCMP_SEQ_S : LASX_XVFCMP<0b000011001001>, ++ LASX_3RF<"xvfcmp.seq.s", int_loongarch_lasx_xvfcmp_seq_s, LASX256WOpnd>{ ++ bits<5> cond=0x5; ++ } ++ ++def XVFCMP_SEQ_D : LASX_XVFCMP<0b000011001010>, ++ LASX_3RF<"xvfcmp.seq.d", int_loongarch_lasx_xvfcmp_seq_d, LASX256DOpnd>{ ++ bits<5> cond=0x5; ++ } ++ ++def XVFCMP_SNE_S : LASX_XVFCMP<0b000011001001>, ++ LASX_3RF<"xvfcmp.sne.s", int_loongarch_lasx_xvfcmp_sne_s, LASX256WOpnd>{ ++ bits<5> cond=0x11; ++ } ++ ++def XVFCMP_SNE_D : LASX_XVFCMP<0b000011001010>, ++ LASX_3RF<"xvfcmp.sne.d", int_loongarch_lasx_xvfcmp_sne_d, LASX256DOpnd>{ ++ bits<5> cond=0x11; ++ } ++ ++def XVFCMP_SLT_S : LASX_XVFCMP<0b000011001001>, ++ LASX_3RF<"xvfcmp.slt.s", int_loongarch_lasx_xvfcmp_slt_s, LASX256WOpnd>{ ++ bits<5> cond=0x3; ++ } ++ ++def XVFCMP_SLT_D : LASX_XVFCMP<0b000011001010>, ++ LASX_3RF<"xvfcmp.slt.d", int_loongarch_lasx_xvfcmp_slt_d, LASX256DOpnd>{ ++ bits<5> cond=0x3; ++ } ++ ++def XVFCMP_SULT_S : LASX_XVFCMP<0b000011001001>, ++ LASX_3RF<"xvfcmp.sult.s", int_loongarch_lasx_xvfcmp_sult_s, LASX256WOpnd>{ ++ bits<5> cond=0xb; ++ } ++ ++def XVFCMP_SULT_D : LASX_XVFCMP<0b000011001010>, ++ LASX_3RF<"xvfcmp.sult.d", int_loongarch_lasx_xvfcmp_sult_d, LASX256DOpnd>{ ++ bits<5> cond=0xb; ++ } ++ ++def XVFCMP_SLE_S : LASX_XVFCMP<0b000011001001>, ++ LASX_3RF<"xvfcmp.sle.s", int_loongarch_lasx_xvfcmp_sle_s, LASX256WOpnd>{ ++ bits<5> cond=0x7; ++ } ++ ++def XVFCMP_SLE_D : LASX_XVFCMP<0b000011001010>, ++ LASX_3RF<"xvfcmp.sle.d", int_loongarch_lasx_xvfcmp_sle_d, LASX256DOpnd>{ ++ bits<5> cond=0x7; ++ } ++ ++def XVFCMP_SULE_S : LASX_XVFCMP<0b000011001001>, ++ LASX_3RF<"xvfcmp.sule.s", int_loongarch_lasx_xvfcmp_sule_s, LASX256WOpnd>{ ++ bits<5> cond=0xf; ++ } ++ ++def XVFCMP_SULE_D : LASX_XVFCMP<0b000011001010>, ++ LASX_3RF<"xvfcmp.sule.d", int_loongarch_lasx_xvfcmp_sule_d, LASX256DOpnd>{ ++ bits<5> cond=0xf; ++ } ++ ++ ++def XVBITSEL_V : LASX_4R<0b000011010010>, ++ LASX_4RF<"xvbitsel.v", int_loongarch_lasx_xvbitsel_v, LASX256BOpnd>; ++ ++class LASX_BSEL_PSEUDO_BASE : ++ LASXPseudo<(outs RO:$xd), (ins RO:$xd_in, RO:$xs, RO:$xt), ++ [(set RO:$xd, (Ty (vselect RO:$xd_in, RO:$xt, RO:$xs)))]>, ++ PseudoInstExpansion<(XVBITSEL_V LASX256BOpnd:$xd, LASX256BOpnd:$xs, ++ LASX256BOpnd:$xt, LASX256BOpnd:$xd_in)> { ++ let Constraints = "$xd_in = $xd"; ++} ++ ++def XBSEL_B_PSEUDO : LASX_BSEL_PSEUDO_BASE; ++def XBSEL_H_PSEUDO : LASX_BSEL_PSEUDO_BASE; ++def XBSEL_W_PSEUDO : LASX_BSEL_PSEUDO_BASE; ++def XBSEL_D_PSEUDO : LASX_BSEL_PSEUDO_BASE; ++def XBSEL_FW_PSEUDO : LASX_BSEL_PSEUDO_BASE; ++def XBSEL_FD_PSEUDO : LASX_BSEL_PSEUDO_BASE; ++ ++ ++ ++def XVSHUF_B : LASX_4R<0b000011010110>, ++ LASX_4RF<"xvshuf.b", int_loongarch_lasx_xvshuf_b, LASX256BOpnd>; ++ ++ ++def XVLD : LASX_I12_S<0b0010110010>, ++ LASX_LD<"xvld", load, v32i8, LASX256BOpnd, mem>; ++ ++def XVST : LASX_I12_S<0b0010110011>, ++ LASX_ST<"xvst", store, v32i8, LASX256BOpnd, mem_simm12>; ++ ++ ++class LASX_LD_DESC_BASE { ++ dag OutOperandList = (outs ROXD:$xd); ++ dag InOperandList = (ins MemOpnd:$addr); ++ string AsmString = !strconcat(instr_asm, "\t$xd, $addr"); ++ list Pattern = [(set ROXD:$xd, (OpNode (iPTR Addr:$addr)))]; ++ string DecoderMethod = "DecodeLASX256memlsl"; ++} ++ ++let mayLoad = 1 in { ++def XVLDREPL_B : LASX_SI12_S<0b0011001010>, ++ LASX_LD_DESC_BASE<"xvldrepl.b", xvbroadcast_v32i8, LASX256BOpnd>; ++ ++def XVLDREPL_H : LASX_SI11_S<0b00110010010>, ++ LASX_LD_DESC_BASE<"xvldrepl.h", xvbroadcast_v16i16, LASX256HOpnd, mem_simm11_lsl1, addrimm11lsl1>; ++ ++def XVLDREPL_W : LASX_SI10_S<0b001100100010>, ++ LASX_LD_DESC_BASE<"xvldrepl.w", xvbroadcast_v8i32, LASX256WOpnd, mem_simm10_lsl2, addrimm10lsl2>; ++ ++def XVLDREPL_D : LASX_SI9_S<0b0011001000010>, ++ LASX_LD_DESC_BASE<"xvldrepl.d", xvbroadcast_v4i64, LASX256DOpnd, mem_simm9_lsl3, addrimm9lsl3>; ++} ++ ++ ++def XVSTELM_B : LASX_SI8_idx5<0b001100111>, ++ LASX_I8_U5_DESC_BASE<"xvstelm.b", int_loongarch_lasx_xvstelm_b, simm8_32, immSExt8, LASX256BOpnd, GPR32Opnd>; ++ ++def XVSTELM_H : LASX_SI8_idx4<0b0011001101>, ++ LASX_I8_U4_DESC_BASE<"xvstelm.h", int_loongarch_lasx_xvstelm_h, immSExt8_1_O, immSExt8, LASX256HOpnd, GPR32Opnd>; ++ ++def XVSTELM_W : LASX_SI8_idx3<0b00110011001>, ++ LASX_I8_U3_DESC_BASE<"xvstelm.w", int_loongarch_lasx_xvstelm_w, immSExt8_2_O, immSExt8, LASX256WOpnd, GPR32Opnd>; ++ ++def XVSTELM_D : LASX_SI8_idx2<0b001100110001>, ++ LASX_I8_U2_DESC_BASE<"xvstelm.d", int_loongarch_lasx_xvstelm_d, immSExt8_3_O, immSExt8, LASX256DOpnd, GPR32Opnd>; ++ ++let mayLoad = 1, canFoldAsLoad = 1 in { ++ def XVLDX : LASX_3R_2GP<0b00111000010010000>, ++ LASX_LDX_LA<"xvldx", int_loongarch_lasx_xvldx, GPR64Opnd, LASX256BOpnd>; ++} ++ ++let mayStore = 1 in{ ++ def XVSTX : LASX_3R_2GP<0b00111000010011000>, ++ LASX_SDX_LA<"xvstx", int_loongarch_lasx_xvstx, GPR64Opnd, LASX256BOpnd>; ++} ++ ++ ++def XVSEQ_B : LASX_3R<0b01110100000000000>, IsCommutable, ++ LASX_3R_SETCC_DESC_BASE<"xvseq.b", SETEQ, v32i8, LASX256BOpnd>; ++ ++def XVSEQ_H : LASX_3R<0b01110100000000001>, IsCommutable, ++ LASX_3R_SETCC_DESC_BASE<"xvseq.h", SETEQ, v16i16, LASX256HOpnd>; ++ ++def XVSEQ_W : LASX_3R<0b01110100000000010>, IsCommutable, ++ LASX_3R_SETCC_DESC_BASE<"xvseq.w", SETEQ, v8i32, LASX256WOpnd> ; ++ ++def XVSEQ_D : LASX_3R<0b01110100000000011>, IsCommutable, ++ LASX_3R_SETCC_DESC_BASE<"xvseq.d", SETEQ, v4i64, LASX256DOpnd>; ++ ++ ++def XVSLE_B : LASX_3R<0b01110100000000100>, ++ LASX_3R_SETCC_DESC_BASE<"xvsle.b", SETLE, v32i8, LASX256BOpnd>; ++ ++def XVSLE_H : LASX_3R<0b01110100000000101>, ++ LASX_3R_SETCC_DESC_BASE<"xvsle.h", SETLE, v16i16, LASX256HOpnd>; ++ ++def XVSLE_W : LASX_3R<0b01110100000000110>, ++ LASX_3R_SETCC_DESC_BASE<"xvsle.w", SETLE, v8i32, LASX256WOpnd>; ++ ++def XVSLE_D : LASX_3R<0b01110100000000111>, ++ LASX_3R_SETCC_DESC_BASE<"xvsle.d", SETLE, v4i64, LASX256DOpnd>; ++ ++ ++def XVSLE_BU : LASX_3R<0b01110100000001000>, ++ LASX_3R_SETCC_DESC_BASE<"xvsle.bu", SETULE, v32i8, LASX256BOpnd>; ++ ++def XVSLE_HU : LASX_3R<0b01110100000001001>, ++ LASX_3R_SETCC_DESC_BASE<"xvsle.hu", SETULE, v16i16, LASX256HOpnd>; ++ ++def XVSLE_WU : LASX_3R<0b01110100000001010>, ++ LASX_3R_SETCC_DESC_BASE<"xvsle.wu", SETULE, v8i32, LASX256WOpnd>; ++ ++def XVSLE_DU : LASX_3R<0b01110100000001011>, ++ LASX_3R_SETCC_DESC_BASE<"xvsle.du", SETULE, v4i64, LASX256DOpnd>; ++ ++ ++def XVSLT_B : LASX_3R<0b01110100000001100>, ++ LASX_3R_SETCC_DESC_BASE<"xvslt.b", SETLT, v32i8, LASX256BOpnd>; ++ ++def XVSLT_H : LASX_3R<0b01110100000001101>, ++ LASX_3R_SETCC_DESC_BASE<"xvslt.h", SETLT, v16i16, LASX256HOpnd>; ++ ++def XVSLT_W : LASX_3R<0b01110100000001110>, ++ LASX_3R_SETCC_DESC_BASE<"xvslt.w", SETLT, v8i32, LASX256WOpnd>; ++ ++def XVSLT_D : LASX_3R<0b01110100000001111>, ++ LASX_3R_SETCC_DESC_BASE<"xvslt.d", SETLT, v4i64, LASX256DOpnd>; ++ ++ ++def XVSLT_BU : LASX_3R<0b01110100000010000>, ++ LASX_3R_SETCC_DESC_BASE<"xvslt.bu", SETULT, v32i8, LASX256BOpnd>; ++ ++def XVSLT_HU : LASX_3R<0b01110100000010001>, ++ LASX_3R_SETCC_DESC_BASE<"xvslt.hu", SETULT, v16i16, LASX256HOpnd>; ++ ++def XVSLT_WU : LASX_3R<0b01110100000010010>, ++ LASX_3R_SETCC_DESC_BASE<"xvslt.wu", SETULT, v8i32, LASX256WOpnd>; ++ ++def XVSLT_DU : LASX_3R<0b01110100000010011>, ++ LASX_3R_SETCC_DESC_BASE<"xvslt.du", SETULT, v4i64, LASX256DOpnd>; ++ ++ ++def XVADD_B : LASX_3R<0b01110100000010100>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvadd.b", add, LASX256BOpnd>; ++ ++def XVADD_H : LASX_3R<0b01110100000010101>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvadd.h", add, LASX256HOpnd>; ++ ++def XVADD_W : LASX_3R<0b01110100000010110>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvadd.w", add, LASX256WOpnd>; ++ ++def XVADD_D : LASX_3R<0b01110100000010111>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvadd.d", add, LASX256DOpnd>; ++ ++ ++def XVSUB_B : LASX_3R<0b01110100000011000>, ++ LASX_3R_DESC_BASE<"xvsub.b", sub, LASX256BOpnd>; ++ ++def XVSUB_H : LASX_3R<0b01110100000011001>, ++ LASX_3R_DESC_BASE<"xvsub.h", sub, LASX256HOpnd>; ++ ++def XVSUB_W : LASX_3R<0b01110100000011010>, ++ LASX_3R_DESC_BASE<"xvsub.w", sub, LASX256WOpnd>; ++ ++def XVSUB_D : LASX_3R<0b01110100000011011>, ++ LASX_3R_DESC_BASE<"xvsub.d", sub, LASX256DOpnd>; ++ ++ ++def XVADDWEV_H_B : LASX_3R<0b01110100000111100>, ++ LASX_3R_DESC_BASE<"xvaddwev.h.b", int_loongarch_lasx_xvaddwev_h_b, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVADDWEV_W_H : LASX_3R<0b01110100000111101>, ++ LASX_3R_DESC_BASE<"xvaddwev.w.h", int_loongarch_lasx_xvaddwev_w_h, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVADDWEV_D_W : LASX_3R<0b01110100000111110>, ++ LASX_3R_DESC_BASE<"xvaddwev.d.w", int_loongarch_lasx_xvaddwev_d_w, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd> ; ++ ++def XVADDWEV_Q_D : LASX_3R<0b01110100000111111>, ++ LASX_3R_DESC_BASE<"xvaddwev.q.d", int_loongarch_lasx_xvaddwev_q_d, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVSUBWEV_H_B : LASX_3R<0b01110100001000000>, ++ LASX_3R_DESC_BASE<"xvsubwev.h.b", int_loongarch_lasx_xvsubwev_h_b, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVSUBWEV_W_H : LASX_3R<0b01110100001000001>, ++ LASX_3R_DESC_BASE<"xvsubwev.w.h", int_loongarch_lasx_xvsubwev_w_h, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVSUBWEV_D_W : LASX_3R<0b01110100001000010>, ++ LASX_3R_DESC_BASE<"xvsubwev.d.w", int_loongarch_lasx_xvsubwev_d_w, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd> ; ++ ++def XVSUBWEV_Q_D : LASX_3R<0b01110100001000011>, ++ LASX_3R_DESC_BASE<"xvsubwev.q.d", int_loongarch_lasx_xvsubwev_q_d, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVADDWOD_H_B : LASX_3R<0b01110100001000100>, ++ LASX_3R_DESC_BASE<"xvaddwod.h.b", int_loongarch_lasx_xvaddwod_h_b, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVADDWOD_W_H : LASX_3R<0b01110100001000101>, ++ LASX_3R_DESC_BASE<"xvaddwod.w.h", int_loongarch_lasx_xvaddwod_w_h, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVADDWOD_D_W : LASX_3R<0b01110100001000110>, ++ LASX_3R_DESC_BASE<"xvaddwod.d.w", int_loongarch_lasx_xvaddwod_d_w, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd> ; ++ ++def XVADDWOD_Q_D : LASX_3R<0b01110100001000111>, ++ LASX_3R_DESC_BASE<"xvaddwod.q.d", int_loongarch_lasx_xvaddwod_q_d, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVSUBWOD_H_B : LASX_3R<0b01110100001001000>, ++ LASX_3R_DESC_BASE<"xvsubwod.h.b", int_loongarch_lasx_xvsubwod_h_b, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVSUBWOD_W_H : LASX_3R<0b01110100001001001>, ++ LASX_3R_DESC_BASE<"xvsubwod.w.h", int_loongarch_lasx_xvsubwod_w_h, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVSUBWOD_D_W : LASX_3R<0b01110100001001010>, ++ LASX_3R_DESC_BASE<"xvsubwod.d.w", int_loongarch_lasx_xvsubwod_d_w, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd> ; ++ ++def XVSUBWOD_Q_D : LASX_3R<0b01110100001001011>, ++ LASX_3R_DESC_BASE<"xvsubwod.q.d", int_loongarch_lasx_xvsubwod_q_d, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVADDWEV_H_BU : LASX_3R<0b01110100001011100>, ++ LASX_3R_DESC_BASE<"xvaddwev.h.bu", int_loongarch_lasx_xvaddwev_h_bu, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVADDWEV_W_HU : LASX_3R<0b01110100001011101>, ++ LASX_3R_DESC_BASE<"xvaddwev.w.hu", int_loongarch_lasx_xvaddwev_w_hu, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVADDWEV_D_WU : LASX_3R<0b01110100001011110>, ++ LASX_3R_DESC_BASE<"xvaddwev.d.wu", int_loongarch_lasx_xvaddwev_d_wu, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd> ; ++ ++def XVADDWEV_Q_DU : LASX_3R<0b01110100001011111>, ++ LASX_3R_DESC_BASE<"xvaddwev.q.du", int_loongarch_lasx_xvaddwev_q_du, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVSUBWEV_H_BU : LASX_3R<0b01110100001100000>, ++ LASX_3R_DESC_BASE<"xvsubwev.h.bu", int_loongarch_lasx_xvsubwev_h_bu, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVSUBWEV_W_HU : LASX_3R<0b01110100001100001>, ++ LASX_3R_DESC_BASE<"xvsubwev.w.hu", int_loongarch_lasx_xvsubwev_w_hu, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVSUBWEV_D_WU : LASX_3R<0b01110100001100010>, ++ LASX_3R_DESC_BASE<"xvsubwev.d.wu", int_loongarch_lasx_xvsubwev_d_wu, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd> ; ++ ++def XVSUBWEV_Q_DU : LASX_3R<0b01110100001100011>, ++ LASX_3R_DESC_BASE<"xvsubwev.q.du", int_loongarch_lasx_xvsubwev_q_du, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVADDWOD_H_BU : LASX_3R<0b01110100001100100>, ++ LASX_3R_DESC_BASE<"xvaddwod.h.bu", int_loongarch_lasx_xvaddwod_h_bu, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVADDWOD_W_HU : LASX_3R<0b01110100001100101>, ++ LASX_3R_DESC_BASE<"xvaddwod.w.hu", int_loongarch_lasx_xvaddwod_w_hu, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVADDWOD_D_WU : LASX_3R<0b01110100001100110>, ++ LASX_3R_DESC_BASE<"xvaddwod.d.wu", int_loongarch_lasx_xvaddwod_d_wu, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd> ; ++ ++def XVADDWOD_Q_DU : LASX_3R<0b01110100001100111>, ++ LASX_3R_DESC_BASE<"xvaddwod.q.du", int_loongarch_lasx_xvaddwod_q_du, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVSUBWOD_H_BU : LASX_3R<0b01110100001101000>, ++ LASX_3R_DESC_BASE<"xvsubwod.h.bu", int_loongarch_lasx_xvsubwod_h_bu, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVSUBWOD_W_HU : LASX_3R<0b01110100001101001>, ++ LASX_3R_DESC_BASE<"xvsubwod.w.hu", int_loongarch_lasx_xvsubwod_w_hu, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVSUBWOD_D_WU : LASX_3R<0b01110100001101010>, ++ LASX_3R_DESC_BASE<"xvsubwod.d.wu", int_loongarch_lasx_xvsubwod_d_wu, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd> ; ++ ++def XVSUBWOD_Q_DU : LASX_3R<0b01110100001101011>, ++ LASX_3R_DESC_BASE<"xvsubwod.q.du", int_loongarch_lasx_xvsubwod_q_du, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVADDWEV_H_BU_B : LASX_3R<0b01110100001111100>, ++ LASX_3R_DESC_BASE<"xvaddwev.h.bu.b", int_loongarch_lasx_xvaddwev_h_bu_b, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVADDWEV_W_HU_H : LASX_3R<0b01110100001111101>, ++ LASX_3R_DESC_BASE<"xvaddwev.w.hu.h", int_loongarch_lasx_xvaddwev_w_hu_h, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVADDWEV_D_WU_W : LASX_3R<0b01110100001111110>, ++ LASX_3R_DESC_BASE<"xvaddwev.d.wu.w", int_loongarch_lasx_xvaddwev_d_wu_w, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd> ; ++ ++def XVADDWEV_Q_DU_D : LASX_3R<0b01110100001111111>, ++ LASX_3R_DESC_BASE<"xvaddwev.q.du.d", int_loongarch_lasx_xvaddwev_q_du_d, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVADDWOD_H_BU_B : LASX_3R<0b01110100010000000>, ++ LASX_3R_DESC_BASE<"xvaddwod.h.bu.b", int_loongarch_lasx_xvaddwod_h_bu_b, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVADDWOD_W_HU_H : LASX_3R<0b01110100010000001>, ++ LASX_3R_DESC_BASE<"xvaddwod.w.hu.h", int_loongarch_lasx_xvaddwod_w_hu_h, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVADDWOD_D_WU_W : LASX_3R<0b01110100010000010>, ++ LASX_3R_DESC_BASE<"xvaddwod.d.wu.w", int_loongarch_lasx_xvaddwod_d_wu_w, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd> ; ++ ++def XVADDWOD_Q_DU_D : LASX_3R<0b01110100010000011>, ++ LASX_3R_DESC_BASE<"xvaddwod.q.du.d", int_loongarch_lasx_xvaddwod_q_du_d, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVSADD_B : LASX_3R<0b01110100010001100>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvsadd.b", saddsat, LASX256BOpnd>; ++ ++def XVSADD_H : LASX_3R<0b01110100010001101>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvsadd.h", saddsat, LASX256HOpnd>; ++ ++def XVSADD_W : LASX_3R<0b01110100010001110>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvsadd.w", saddsat, LASX256WOpnd>; ++ ++def XVSADD_D : LASX_3R<0b01110100010001111>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvsadd.d", saddsat, LASX256DOpnd>; ++ ++ ++def XVSSUB_B : LASX_3R<0b01110100010010000>, ++ LASX_3R_DESC_BASE<"xvssub.b", ssubsat, LASX256BOpnd>; ++ ++def XVSSUB_H : LASX_3R<0b01110100010010001>, ++ LASX_3R_DESC_BASE<"xvssub.h", ssubsat, LASX256HOpnd>; ++ ++def XVSSUB_W : LASX_3R<0b01110100010010010>, ++ LASX_3R_DESC_BASE<"xvssub.w", ssubsat, LASX256WOpnd>; ++ ++def XVSSUB_D : LASX_3R<0b01110100010010011>, ++ LASX_3R_DESC_BASE<"xvssub.d", ssubsat, LASX256DOpnd>; ++ ++ ++def XVSADD_BU : LASX_3R<0b01110100010010100>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvsadd.bu", uaddsat, LASX256BOpnd>; ++ ++def XVSADD_HU : LASX_3R<0b01110100010010101>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvsadd.hu", uaddsat, LASX256HOpnd>; ++ ++def XVSADD_WU : LASX_3R<0b01110100010010110>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvsadd.wu", uaddsat, LASX256WOpnd>; ++ ++def XVSADD_DU : LASX_3R<0b01110100010010111>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvsadd.du", uaddsat, LASX256DOpnd>; ++ ++ ++def XVSSUB_BU : LASX_3R<0b01110100010011000>, ++ LASX_3R_DESC_BASE<"xvssub.bu", usubsat, LASX256BOpnd>; ++ ++def XVSSUB_HU : LASX_3R<0b01110100010011001>, ++ LASX_3R_DESC_BASE<"xvssub.hu", usubsat, LASX256HOpnd>; ++ ++def XVSSUB_WU : LASX_3R<0b01110100010011010>, ++ LASX_3R_DESC_BASE<"xvssub.wu", usubsat, LASX256WOpnd>; ++ ++def XVSSUB_DU : LASX_3R<0b01110100010011011>, ++ LASX_3R_DESC_BASE<"xvssub.du", usubsat, LASX256DOpnd>; ++ ++ ++def XVHADDW_H_B : LASX_3R<0b01110100010101000>, ++ LASX_3R_DESC_BASE<"xvhaddw.h.b", int_loongarch_lasx_xvhaddw_h_b, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVHADDW_W_H : LASX_3R<0b01110100010101001>, ++ LASX_3R_DESC_BASE<"xvhaddw.w.h", int_loongarch_lasx_xvhaddw_w_h, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVHADDW_D_W : LASX_3R<0b01110100010101010>, ++ LASX_3R_DESC_BASE<"xvhaddw.d.w", int_loongarch_lasx_xvhaddw_d_w, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVHADDW_Q_D : LASX_3R<0b01110100010101011>, ++ LASX_3R_DESC_BASE<"xvhaddw.q.d", int_loongarch_lasx_xvhaddw_q_d, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++ ++def XVHSUBW_H_B : LASX_3R<0b01110100010101100>, ++ LASX_3R_DESC_BASE<"xvhsubw.h.b", int_loongarch_lasx_xvhsubw_h_b, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVHSUBW_W_H : LASX_3R<0b01110100010101101>, ++ LASX_3R_DESC_BASE<"xvhsubw.w.h", int_loongarch_lasx_xvhsubw_w_h, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVHSUBW_D_W : LASX_3R<0b01110100010101110>, ++ LASX_3R_DESC_BASE<"xvhsubw.d.w", int_loongarch_lasx_xvhsubw_d_w, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVHSUBW_Q_D : LASX_3R<0b01110100010101111>, ++ LASX_3R_DESC_BASE<"xvhsubw.q.d", int_loongarch_lasx_xvhsubw_q_d, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVHADDW_HU_BU : LASX_3R<0b01110100010110000>, ++ LASX_3R_DESC_BASE<"xvhaddw.hu.bu", int_loongarch_lasx_xvhaddw_hu_bu, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVHADDW_WU_HU : LASX_3R<0b01110100010110001>, ++ LASX_3R_DESC_BASE<"xvhaddw.wu.hu", int_loongarch_lasx_xvhaddw_wu_hu, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVHADDW_DU_WU : LASX_3R<0b01110100010110010>, ++ LASX_3R_DESC_BASE<"xvhaddw.du.wu", int_loongarch_lasx_xvhaddw_du_wu, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVHADDW_QU_DU : LASX_3R<0b01110100010110011>, ++ LASX_3R_DESC_BASE<"xvhaddw.qu.du", int_loongarch_lasx_xvhaddw_qu_du, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++ ++def XVHSUBW_HU_BU : LASX_3R<0b01110100010110100>, ++ LASX_3R_DESC_BASE<"xvhsubw.hu.bu", int_loongarch_lasx_xvhsubw_hu_bu, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVHSUBW_WU_HU : LASX_3R<0b01110100010110101>, ++ LASX_3R_DESC_BASE<"xvhsubw.wu.hu", int_loongarch_lasx_xvhsubw_wu_hu, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVHSUBW_DU_WU : LASX_3R<0b01110100010110110>, ++ LASX_3R_DESC_BASE<"xvhsubw.du.wu", int_loongarch_lasx_xvhsubw_du_wu, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVHSUBW_QU_DU : LASX_3R<0b01110100010110111>, ++ LASX_3R_DESC_BASE<"xvhsubw.qu.du", int_loongarch_lasx_xvhsubw_qu_du, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVADDA_B : LASX_3R<0b01110100010111000>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvadda.b", int_loongarch_lasx_xvadda_b, LASX256BOpnd>; ++ ++def XVADDA_H : LASX_3R<0b01110100010111001>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvadda.h", int_loongarch_lasx_xvadda_h, LASX256HOpnd>; ++ ++def XVADDA_W : LASX_3R<0b01110100010111010>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvadda.w", int_loongarch_lasx_xvadda_w, LASX256WOpnd>; ++ ++def XVADDA_D : LASX_3R<0b01110100010111011>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvadda.d", int_loongarch_lasx_xvadda_d, LASX256DOpnd>; ++ ++ ++def XVABSD_B : LASX_3R<0b01110100011000000>, ++ LASX_3R_DESC_BASE<"xvabsd.b", int_loongarch_lasx_xvabsd_b, LASX256BOpnd>; ++ ++def XVABSD_H : LASX_3R<0b01110100011000001>, ++ LASX_3R_DESC_BASE<"xvabsd.h", int_loongarch_lasx_xvabsd_h, LASX256HOpnd>; ++ ++def XVABSD_W : LASX_3R<0b01110100011000010>, ++ LASX_3R_DESC_BASE<"xvabsd.w", int_loongarch_lasx_xvabsd_w, LASX256WOpnd>; ++ ++def XVABSD_D : LASX_3R<0b01110100011000011>, ++ LASX_3R_DESC_BASE<"xvabsd.d", int_loongarch_lasx_xvabsd_d, LASX256DOpnd>; ++ ++ ++def XVABSD_BU : LASX_3R<0b01110100011000100>, ++ LASX_3R_DESC_BASE<"xvabsd.bu", int_loongarch_lasx_xvabsd_bu, LASX256BOpnd>; ++ ++def XVABSD_HU : LASX_3R<0b01110100011000101>, ++ LASX_3R_DESC_BASE<"xvabsd.hu", int_loongarch_lasx_xvabsd_hu, LASX256HOpnd>; ++ ++def XVABSD_WU : LASX_3R<0b01110100011000110>, ++ LASX_3R_DESC_BASE<"xvabsd.wu", int_loongarch_lasx_xvabsd_wu, LASX256WOpnd>; ++ ++def XVABSD_DU : LASX_3R<0b01110100011000111>, ++ LASX_3R_DESC_BASE<"xvabsd.du", int_loongarch_lasx_xvabsd_du, LASX256DOpnd>; ++ ++ ++def XVAVG_B : LASX_3R<0b01110100011001000>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvavg.b", int_loongarch_lasx_xvavg_b, LASX256BOpnd>; ++ ++def XVAVG_H : LASX_3R<0b01110100011001001>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvavg.h", int_loongarch_lasx_xvavg_h, LASX256HOpnd>; ++ ++def XVAVG_W : LASX_3R<0b01110100011001010>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvavg.w", int_loongarch_lasx_xvavg_w, LASX256WOpnd>; ++ ++def XVAVG_D : LASX_3R<0b01110100011001011>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvavg.d", int_loongarch_lasx_xvavg_d, LASX256DOpnd>; ++ ++ ++def XVAVG_BU : LASX_3R<0b01110100011001100>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvavg.bu", int_loongarch_lasx_xvavg_bu, LASX256BOpnd>; ++ ++def XVAVG_HU : LASX_3R<0b01110100011001101>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvavg.hu", int_loongarch_lasx_xvavg_hu, LASX256HOpnd>; ++ ++def XVAVG_WU : LASX_3R<0b01110100011001110>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvavg.wu", int_loongarch_lasx_xvavg_wu, LASX256WOpnd>; ++ ++def XVAVG_DU : LASX_3R<0b01110100011001111>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvavg.du", int_loongarch_lasx_xvavg_du, LASX256DOpnd>; ++ ++ ++def XVAVGR_B : LASX_3R<0b01110100011010000>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvavgr.b", int_loongarch_lasx_xvavgr_b, LASX256BOpnd>; ++ ++def XVAVGR_H : LASX_3R<0b01110100011010001>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvavgr.h", int_loongarch_lasx_xvavgr_h, LASX256HOpnd>; ++ ++def XVAVGR_W : LASX_3R<0b01110100011010010>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvavgr.w", int_loongarch_lasx_xvavgr_w, LASX256WOpnd>; ++ ++def XVAVGR_D : LASX_3R<0b01110100011010011>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvavgr.d", int_loongarch_lasx_xvavgr_d, LASX256DOpnd>; ++ ++ ++def XVAVGR_BU : LASX_3R<0b01110100011010100>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvavgr.bu", int_loongarch_lasx_xvavgr_bu, LASX256BOpnd>; ++ ++def XVAVGR_HU : LASX_3R<0b01110100011010101>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvavgr.hu", int_loongarch_lasx_xvavgr_hu, LASX256HOpnd>; ++ ++def XVAVGR_WU : LASX_3R<0b01110100011010110>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvavgr.wu", int_loongarch_lasx_xvavgr_wu, LASX256WOpnd>; ++ ++def XVAVGR_DU : LASX_3R<0b01110100011010111>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvavgr.du", int_loongarch_lasx_xvavgr_du, LASX256DOpnd>; ++ ++ ++def XVMAX_B : LASX_3R<0b01110100011100000>, ++ LASX_3R_DESC_BASE<"xvmax.b", smax, LASX256BOpnd>; ++ ++def XVMAX_H : LASX_3R<0b01110100011100001>, ++ LASX_3R_DESC_BASE<"xvmax.h", smax, LASX256HOpnd>; ++ ++def XVMAX_W : LASX_3R<0b01110100011100010>, ++ LASX_3R_DESC_BASE<"xvmax.w", smax, LASX256WOpnd>; ++ ++def XVMAX_D : LASX_3R<0b01110100011100011>, ++ LASX_3R_DESC_BASE<"xvmax.d", smax, LASX256DOpnd>; ++ ++ ++def XVMIN_B : LASX_3R<0b01110100011100100>, ++ LASX_3R_DESC_BASE<"xvmin.b", smin, LASX256BOpnd>; ++ ++def XVMIN_H : LASX_3R<0b01110100011100101>, ++ LASX_3R_DESC_BASE<"xvmin.h", smin, LASX256HOpnd>; ++ ++def XVMIN_W : LASX_3R<0b01110100011100110>, ++ LASX_3R_DESC_BASE<"xvmin.w", smin, LASX256WOpnd>; ++ ++def XVMIN_D : LASX_3R<0b01110100011100111>, ++ LASX_3R_DESC_BASE<"xvmin.d", smin, LASX256DOpnd>; ++ ++ ++def XVMAX_BU : LASX_3R<0b01110100011101000>, ++ LASX_3R_DESC_BASE<"xvmax.bu", umax, LASX256BOpnd>; ++ ++def XVMAX_HU : LASX_3R<0b01110100011101001>, ++ LASX_3R_DESC_BASE<"xvmax.hu", umax, LASX256HOpnd>; ++ ++def XVMAX_WU : LASX_3R<0b01110100011101010>, ++ LASX_3R_DESC_BASE<"xvmax.wu", umax, LASX256WOpnd>; ++ ++def XVMAX_DU : LASX_3R<0b01110100011101011>, ++ LASX_3R_DESC_BASE<"xvmax.du", umax, LASX256DOpnd>; ++ ++ ++def XVMIN_BU : LASX_3R<0b01110100011101100>, ++ LASX_3R_DESC_BASE<"xvmin.bu", umin, LASX256BOpnd>; ++ ++def XVMIN_HU : LASX_3R<0b01110100011101101>, ++ LASX_3R_DESC_BASE<"xvmin.hu", umin, LASX256HOpnd>; ++ ++def XVMIN_WU : LASX_3R<0b01110100011101110>, ++ LASX_3R_DESC_BASE<"xvmin.wu", umin, LASX256WOpnd>; ++ ++def XVMIN_DU : LASX_3R<0b01110100011101111>, ++ LASX_3R_DESC_BASE<"xvmin.du", umin, LASX256DOpnd>; ++ ++ ++def XVMUL_B : LASX_3R<0b01110100100001000>, ++ LASX_3R_DESC_BASE<"xvmul.b", mul, LASX256BOpnd>, IsCommutable; ++ ++def XVMUL_H : LASX_3R<0b01110100100001001>, ++ LASX_3R_DESC_BASE<"xvmul.h", mul, LASX256HOpnd>, IsCommutable; ++ ++def XVMUL_W : LASX_3R<0b01110100100001010>, ++ LASX_3R_DESC_BASE<"xvmul.w", mul, LASX256WOpnd>, IsCommutable; ++ ++def XVMUL_D : LASX_3R<0b01110100100001011>, ++ LASX_3R_DESC_BASE<"xvmul.d", mul, LASX256DOpnd>, IsCommutable; ++ ++ ++def XVMUH_B : LASX_3R<0b01110100100001100>, ++ LASX_3R_DESC_BASE<"xvmuh.b", int_loongarch_lasx_xvmuh_b, LASX256BOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVMUH_H : LASX_3R<0b01110100100001101>, ++ LASX_3R_DESC_BASE<"xvmuh.h", int_loongarch_lasx_xvmuh_h, LASX256HOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVMUH_W : LASX_3R<0b01110100100001110>, ++ LASX_3R_DESC_BASE<"xvmuh.w", int_loongarch_lasx_xvmuh_w, LASX256WOpnd, LASX256WOpnd, LASX256WOpnd> ; ++ ++def XVMUH_D : LASX_3R<0b01110100100001111>, ++ LASX_3R_DESC_BASE<"xvmuh.d", int_loongarch_lasx_xvmuh_d, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVMUH_BU : LASX_3R<0b01110100100010000>, ++ LASX_3R_DESC_BASE<"xvmuh.bu", int_loongarch_lasx_xvmuh_bu, LASX256BOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVMUH_HU : LASX_3R<0b01110100100010001>, ++ LASX_3R_DESC_BASE<"xvmuh.hu", int_loongarch_lasx_xvmuh_hu, LASX256HOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVMUH_WU : LASX_3R<0b01110100100010010>, ++ LASX_3R_DESC_BASE<"xvmuh.wu", int_loongarch_lasx_xvmuh_wu, LASX256WOpnd, LASX256WOpnd, LASX256WOpnd> ; ++ ++def XVMUH_DU : LASX_3R<0b01110100100010011>, ++ LASX_3R_DESC_BASE<"xvmuh.du", int_loongarch_lasx_xvmuh_du, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVMULWEV_H_B : LASX_3R<0b01110100100100000>, ++ LASX_3R_DESC_BASE<"xvmulwev.h.b", int_loongarch_lasx_xvmulwev_h_b, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVMULWEV_W_H : LASX_3R<0b01110100100100001>, ++ LASX_3R_DESC_BASE<"xvmulwev.w.h", int_loongarch_lasx_xvmulwev_w_h, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVMULWEV_D_W : LASX_3R<0b01110100100100010>, ++ LASX_3R_DESC_BASE<"xvmulwev.d.w", int_loongarch_lasx_xvmulwev_d_w, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd> ; ++ ++def XVMULWEV_Q_D : LASX_3R<0b01110100100100011>, ++ LASX_3R_DESC_BASE<"xvmulwev.q.d", int_loongarch_lasx_xvmulwev_q_d, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVMULWOD_H_B : LASX_3R<0b01110100100100100>, ++ LASX_3R_DESC_BASE<"xvmulwod.h.b", int_loongarch_lasx_xvmulwod_h_b, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVMULWOD_W_H : LASX_3R<0b01110100100100101>, ++ LASX_3R_DESC_BASE<"xvmulwod.w.h", int_loongarch_lasx_xvmulwod_w_h, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVMULWOD_D_W : LASX_3R<0b01110100100100110>, ++ LASX_3R_DESC_BASE<"xvmulwod.d.w", int_loongarch_lasx_xvmulwod_d_w, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd> ; ++ ++def XVMULWOD_Q_D : LASX_3R<0b01110100100100111>, ++ LASX_3R_DESC_BASE<"xvmulwod.q.d", int_loongarch_lasx_xvmulwod_q_d, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVMULWEV_H_BU : LASX_3R<0b01110100100110000>, ++ LASX_3R_DESC_BASE<"xvmulwev.h.bu", int_loongarch_lasx_xvmulwev_h_bu, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVMULWEV_W_HU : LASX_3R<0b01110100100110001>, ++ LASX_3R_DESC_BASE<"xvmulwev.w.hu", int_loongarch_lasx_xvmulwev_w_hu, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVMULWEV_D_WU : LASX_3R<0b01110100100110010>, ++ LASX_3R_DESC_BASE<"xvmulwev.d.wu", int_loongarch_lasx_xvmulwev_d_wu, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd> ; ++ ++def XVMULWEV_Q_DU : LASX_3R<0b01110100100110011>, ++ LASX_3R_DESC_BASE<"xvmulwev.q.du", int_loongarch_lasx_xvmulwev_q_du, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVMULWOD_H_BU : LASX_3R<0b01110100100110100>, ++ LASX_3R_DESC_BASE<"xvmulwod.h.bu", int_loongarch_lasx_xvmulwod_h_bu, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVMULWOD_W_HU : LASX_3R<0b01110100100110101>, ++ LASX_3R_DESC_BASE<"xvmulwod.w.hu", int_loongarch_lasx_xvmulwod_w_hu, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVMULWOD_D_WU : LASX_3R<0b01110100100110110>, ++ LASX_3R_DESC_BASE<"xvmulwod.d.wu", int_loongarch_lasx_xvmulwod_d_wu, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd> ; ++ ++def XVMULWOD_Q_DU : LASX_3R<0b01110100100110111>, ++ LASX_3R_DESC_BASE<"xvmulwod.q.du", int_loongarch_lasx_xvmulwod_q_du, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVMULWEV_H_BU_B : LASX_3R<0b01110100101000000>, ++ LASX_3R_DESC_BASE<"xvmulwev.h.bu.b", int_loongarch_lasx_xvmulwev_h_bu_b, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVMULWEV_W_HU_H : LASX_3R<0b01110100101000001>, ++ LASX_3R_DESC_BASE<"xvmulwev.w.hu.h", int_loongarch_lasx_xvmulwev_w_hu_h, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVMULWEV_D_WU_W : LASX_3R<0b01110100101000010>, ++ LASX_3R_DESC_BASE<"xvmulwev.d.wu.w", int_loongarch_lasx_xvmulwev_d_wu_w, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd> ; ++ ++def XVMULWEV_Q_DU_D : LASX_3R<0b01110100101000011>, ++ LASX_3R_DESC_BASE<"xvmulwev.q.du.d", int_loongarch_lasx_xvmulwev_q_du_d, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVMULWOD_H_BU_B : LASX_3R<0b01110100101000100>, ++ LASX_3R_DESC_BASE<"xvmulwod.h.bu.b", int_loongarch_lasx_xvmulwod_h_bu_b, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVMULWOD_W_HU_H : LASX_3R<0b01110100101000101>, ++ LASX_3R_DESC_BASE<"xvmulwod.w.hu.h", int_loongarch_lasx_xvmulwod_w_hu_h, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVMULWOD_D_WU_W : LASX_3R<0b01110100101000110>, ++ LASX_3R_DESC_BASE<"xvmulwod.d.wu.w", int_loongarch_lasx_xvmulwod_d_wu_w, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd> ; ++ ++def XVMULWOD_Q_DU_D : LASX_3R<0b01110100101000111>, ++ LASX_3R_DESC_BASE<"xvmulwod.q.du.d", int_loongarch_lasx_xvmulwod_q_du_d, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVMADD_B : LASX_3R<0b01110100101010000>, ++ LASX_3R_4R_DESC_BASE<"xvmadd.b", muladd, LASX256BOpnd>; ++ ++def XVMADD_H : LASX_3R<0b01110100101010001>, ++ LASX_3R_4R_DESC_BASE<"xvmadd.h", muladd, LASX256HOpnd>; ++ ++def XVMADD_W : LASX_3R<0b01110100101010010>, ++ LASX_3R_4R_DESC_BASE<"xvmadd.w", muladd, LASX256WOpnd>; ++ ++def XVMADD_D : LASX_3R<0b01110100101010011>, ++ LASX_3R_4R_DESC_BASE<"xvmadd.d", muladd, LASX256DOpnd>; ++ ++ ++def XVMSUB_B : LASX_3R<0b01110100101010100>, ++ LASX_3R_4R_DESC_BASE<"xvmsub.b", mulsub, LASX256BOpnd>; ++ ++def XVMSUB_H : LASX_3R<0b01110100101010101>, ++ LASX_3R_4R_DESC_BASE<"xvmsub.h", mulsub, LASX256HOpnd>; ++ ++def XVMSUB_W : LASX_3R<0b01110100101010110>, ++ LASX_3R_4R_DESC_BASE<"xvmsub.w", mulsub, LASX256WOpnd>; ++ ++def XVMSUB_D : LASX_3R<0b01110100101010111>, ++ LASX_3R_4R_DESC_BASE<"xvmsub.d", mulsub, LASX256DOpnd>; ++ ++ ++def XVMADDWEV_H_B : LASX_3R<0b01110100101011000>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwev.h.b", int_loongarch_lasx_xvmaddwev_h_b, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVMADDWEV_W_H : LASX_3R<0b01110100101011001>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwev.w.h", int_loongarch_lasx_xvmaddwev_w_h, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVMADDWEV_D_W : LASX_3R<0b01110100101011010>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwev.d.w", int_loongarch_lasx_xvmaddwev_d_w, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVMADDWEV_Q_D : LASX_3R<0b01110100101011011>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwev.q.d", int_loongarch_lasx_xvmaddwev_q_d, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVMADDWOD_H_B : LASX_3R<0b01110100101011100>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwod.h.b", int_loongarch_lasx_xvmaddwod_h_b, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVMADDWOD_W_H : LASX_3R<0b01110100101011101>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwod.w.h", int_loongarch_lasx_xvmaddwod_w_h, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVMADDWOD_D_W : LASX_3R<0b01110100101011110>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwod.d.w", int_loongarch_lasx_xvmaddwod_d_w, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVMADDWOD_Q_D : LASX_3R<0b01110100101011111>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwod.q.d", int_loongarch_lasx_xvmaddwod_q_d, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVMADDWEV_H_BU : LASX_3R<0b01110100101101000>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwev.h.bu", int_loongarch_lasx_xvmaddwev_h_bu, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVMADDWEV_W_HU : LASX_3R<0b01110100101101001>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwev.w.hu", int_loongarch_lasx_xvmaddwev_w_hu, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVMADDWEV_D_WU : LASX_3R<0b01110100101101010>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwev.d.wu", int_loongarch_lasx_xvmaddwev_d_wu, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVMADDWEV_Q_DU : LASX_3R<0b01110100101101011>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwev.q.du", int_loongarch_lasx_xvmaddwev_q_du, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVMADDWOD_H_BU : LASX_3R<0b01110100101101100>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwod.h.bu", int_loongarch_lasx_xvmaddwod_h_bu, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVMADDWOD_W_HU : LASX_3R<0b01110100101101101>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwod.w.hu", int_loongarch_lasx_xvmaddwod_w_hu, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVMADDWOD_D_WU : LASX_3R<0b01110100101101110>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwod.d.wu", int_loongarch_lasx_xvmaddwod_d_wu, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVMADDWOD_Q_DU : LASX_3R<0b01110100101101111>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwod.q.du", int_loongarch_lasx_xvmaddwod_q_du, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVMADDWEV_H_BU_B : LASX_3R<0b01110100101111000>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwev.h.bu.b", int_loongarch_lasx_xvmaddwev_h_bu_b, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVMADDWEV_W_HU_H : LASX_3R<0b01110100101111001>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwev.w.hu.h", int_loongarch_lasx_xvmaddwev_w_hu_h, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVMADDWEV_D_WU_W : LASX_3R<0b01110100101111010>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwev.d.wu.w", int_loongarch_lasx_xvmaddwev_d_wu_w, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVMADDWEV_Q_DU_D : LASX_3R<0b01110100101111011>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwev.q.du.d", int_loongarch_lasx_xvmaddwev_q_du_d, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVMADDWOD_H_BU_B : LASX_3R<0b01110100101111100>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwod.h.bu.b", int_loongarch_lasx_xvmaddwod_h_bu_b, LASX256HOpnd, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVMADDWOD_W_HU_H : LASX_3R<0b01110100101111101>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwod.w.hu.h", int_loongarch_lasx_xvmaddwod_w_hu_h, LASX256WOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVMADDWOD_D_WU_W : LASX_3R<0b01110100101111110>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwod.d.wu.w", int_loongarch_lasx_xvmaddwod_d_wu_w, LASX256DOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVMADDWOD_Q_DU_D : LASX_3R<0b01110100101111111>, ++ LASX_3R_4R_DESC_BASE<"xvmaddwod.q.du.d", int_loongarch_lasx_xvmaddwod_q_du_d, LASX256DOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVDIV_B : LASX_3R<0b01110100111000000>, ++ LASX_3R_DESC_BASE<"xvdiv.b", sdiv, LASX256BOpnd>; ++ ++def XVDIV_H : LASX_3R<0b01110100111000001>, ++ LASX_3R_DESC_BASE<"xvdiv.h", sdiv, LASX256HOpnd>; ++ ++def XVDIV_W : LASX_3R<0b01110100111000010>, ++ LASX_3R_DESC_BASE<"xvdiv.w", sdiv, LASX256WOpnd>; ++ ++def XVDIV_D : LASX_3R<0b01110100111000011>, ++ LASX_3R_DESC_BASE<"xvdiv.d", sdiv, LASX256DOpnd>; ++ ++ ++def XVMOD_B : LASX_3R<0b01110100111000100>, ++ LASX_3R_DESC_BASE<"xvmod.b", srem, LASX256BOpnd>; ++ ++def XVMOD_H : LASX_3R<0b01110100111000101>, ++ LASX_3R_DESC_BASE<"xvmod.h", srem, LASX256HOpnd>; ++ ++def XVMOD_W : LASX_3R<0b01110100111000110>, ++ LASX_3R_DESC_BASE<"xvmod.w", srem, LASX256WOpnd>; ++ ++def XVMOD_D : LASX_3R<0b01110100111000111>, ++ LASX_3R_DESC_BASE<"xvmod.d", srem, LASX256DOpnd>; ++ ++ ++def XVDIV_BU : LASX_3R<0b01110100111001000>, ++ LASX_3R_DESC_BASE<"xvdiv.bu", udiv, LASX256BOpnd>; ++ ++def XVDIV_HU : LASX_3R<0b01110100111001001>, ++ LASX_3R_DESC_BASE<"xvdiv.hu", udiv, LASX256HOpnd>; ++ ++def XVDIV_WU : LASX_3R<0b01110100111001010>, ++ LASX_3R_DESC_BASE<"xvdiv.wu", udiv, LASX256WOpnd>; ++ ++def XVDIV_DU : LASX_3R<0b01110100111001011>, ++ LASX_3R_DESC_BASE<"xvdiv.du", udiv, LASX256DOpnd>; ++ ++ ++def XVMOD_BU : LASX_3R<0b01110100111001100>, ++ LASX_3R_DESC_BASE<"xvmod.bu", urem, LASX256BOpnd>; ++ ++def XVMOD_HU : LASX_3R<0b01110100111001101>, ++ LASX_3R_DESC_BASE<"xvmod.hu", urem, LASX256HOpnd>; ++ ++def XVMOD_WU : LASX_3R<0b01110100111001110>, ++ LASX_3R_DESC_BASE<"xvmod.wu", urem, LASX256WOpnd>; ++ ++def XVMOD_DU : LASX_3R<0b01110100111001111>, ++ LASX_3R_DESC_BASE<"xvmod.du", urem, LASX256DOpnd>; ++ ++ ++def XVSLL_B : LASX_3R<0b01110100111010000>, ++ LASX_3R_DESC_BASE<"xvsll.b", shl, LASX256BOpnd>; ++ ++def XVSLL_H : LASX_3R<0b01110100111010001>, ++ LASX_3R_DESC_BASE<"xvsll.h", shl, LASX256HOpnd>; ++ ++def XVSLL_W : LASX_3R<0b01110100111010010>, ++ LASX_3R_DESC_BASE<"xvsll.w", shl, LASX256WOpnd>; ++ ++def XVSLL_D : LASX_3R<0b01110100111010011>, ++ LASX_3R_DESC_BASE<"xvsll.d", shl, LASX256DOpnd>; ++ ++ ++def XVSRL_B : LASX_3R<0b01110100111010100>, ++ LASX_3R_DESC_BASE<"xvsrl.b", srl, LASX256BOpnd>; ++ ++def XVSRL_H : LASX_3R<0b01110100111010101>, ++ LASX_3R_DESC_BASE<"xvsrl.h", srl, LASX256HOpnd>; ++ ++def XVSRL_W : LASX_3R<0b01110100111010110>, ++ LASX_3R_DESC_BASE<"xvsrl.w", srl, LASX256WOpnd>; ++ ++def XVSRL_D : LASX_3R<0b01110100111010111>, ++ LASX_3R_DESC_BASE<"xvsrl.d", srl, LASX256DOpnd>; ++ ++ ++def XVSRA_B : LASX_3R<0b01110100111011000>, ++ LASX_3R_DESC_BASE<"xvsra.b", sra, LASX256BOpnd>; ++ ++def XVSRA_H : LASX_3R<0b01110100111011001>, ++ LASX_3R_DESC_BASE<"xvsra.h", sra, LASX256HOpnd>; ++ ++def XVSRA_W : LASX_3R<0b01110100111011010>, ++ LASX_3R_DESC_BASE<"xvsra.w", sra, LASX256WOpnd>; ++ ++def XVSRA_D : LASX_3R<0b01110100111011011>, ++ LASX_3R_DESC_BASE<"xvsra.d", sra, LASX256DOpnd>; ++ ++ ++def XVROTR_B : LASX_3R<0b01110100111011100>, ++ LASX_3R_DESC_BASE<"xvrotr.b", int_loongarch_lasx_xvrotr_b, LASX256BOpnd>; ++ ++def XVROTR_H : LASX_3R<0b01110100111011101>, ++ LASX_3R_DESC_BASE<"xvrotr.h", int_loongarch_lasx_xvrotr_h, LASX256HOpnd>; ++ ++def XVROTR_W : LASX_3R<0b01110100111011110>, ++ LASX_3R_DESC_BASE<"xvrotr.w", int_loongarch_lasx_xvrotr_w, LASX256WOpnd>; ++ ++def XVROTR_D : LASX_3R<0b01110100111011111>, ++ LASX_3R_DESC_BASE<"xvrotr.d", int_loongarch_lasx_xvrotr_d, LASX256DOpnd>; ++ ++ ++def XVSRLR_B : LASX_3R<0b01110100111100000>, ++ LASX_3R_DESC_BASE<"xvsrlr.b", int_loongarch_lasx_xvsrlr_b, LASX256BOpnd>; ++ ++def XVSRLR_H : LASX_3R<0b01110100111100001>, ++ LASX_3R_DESC_BASE<"xvsrlr.h", int_loongarch_lasx_xvsrlr_h, LASX256HOpnd>; ++ ++def XVSRLR_W : LASX_3R<0b01110100111100010>, ++ LASX_3R_DESC_BASE<"xvsrlr.w", int_loongarch_lasx_xvsrlr_w, LASX256WOpnd>; ++ ++def XVSRLR_D : LASX_3R<0b01110100111100011>, ++ LASX_3R_DESC_BASE<"xvsrlr.d", int_loongarch_lasx_xvsrlr_d, LASX256DOpnd>; ++ ++ ++def XVSRAR_B : LASX_3R<0b01110100111100100>, ++ LASX_3R_DESC_BASE<"xvsrar.b", int_loongarch_lasx_xvsrar_b, LASX256BOpnd>; ++ ++def XVSRAR_H : LASX_3R<0b01110100111100101>, ++ LASX_3R_DESC_BASE<"xvsrar.h", int_loongarch_lasx_xvsrar_h, LASX256HOpnd>; ++ ++def XVSRAR_W : LASX_3R<0b01110100111100110>, ++ LASX_3R_DESC_BASE<"xvsrar.w", int_loongarch_lasx_xvsrar_w, LASX256WOpnd>; ++ ++def XVSRAR_D : LASX_3R<0b01110100111100111>, ++ LASX_3R_DESC_BASE<"xvsrar.d", int_loongarch_lasx_xvsrar_d, LASX256DOpnd>; ++ ++ ++def XVSRLN_B_H : LASX_3R<0b01110100111101001>, ++ LASX_3R_DESC_BASE<"xvsrln.b.h", int_loongarch_lasx_xvsrln_b_h, LASX256BOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVSRLN_H_W : LASX_3R<0b01110100111101010>, ++ LASX_3R_DESC_BASE<"xvsrln.h.w", int_loongarch_lasx_xvsrln_h_w, LASX256HOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVSRLN_W_D : LASX_3R<0b01110100111101011>, ++ LASX_3R_DESC_BASE<"xvsrln.w.d", int_loongarch_lasx_xvsrln_w_d, LASX256WOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVSRAN_B_H : LASX_3R<0b01110100111101101>, ++ LASX_3R_DESC_BASE<"xvsran.b.h", int_loongarch_lasx_xvsran_b_h, LASX256BOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVSRAN_H_W : LASX_3R<0b01110100111101110>, ++ LASX_3R_DESC_BASE<"xvsran.h.w", int_loongarch_lasx_xvsran_h_w, LASX256HOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVSRAN_W_D : LASX_3R<0b01110100111101111>, ++ LASX_3R_DESC_BASE<"xvsran.w.d", int_loongarch_lasx_xvsran_w_d, LASX256WOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVSRLRN_B_H : LASX_3R<0b01110100111110001>, ++ LASX_3R_DESC_BASE<"xvsrlrn.b.h", int_loongarch_lasx_xvsrlrn_b_h, LASX256BOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVSRLRN_H_W : LASX_3R<0b01110100111110010>, ++ LASX_3R_DESC_BASE<"xvsrlrn.h.w", int_loongarch_lasx_xvsrlrn_h_w, LASX256HOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVSRLRN_W_D : LASX_3R<0b01110100111110011>, ++ LASX_3R_DESC_BASE<"xvsrlrn.w.d", int_loongarch_lasx_xvsrlrn_w_d, LASX256WOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVSRARN_B_H : LASX_3R<0b01110100111110101>, ++ LASX_3R_DESC_BASE<"xvsrarn.b.h", int_loongarch_lasx_xvsrarn_b_h, LASX256BOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVSRARN_H_W : LASX_3R<0b01110100111110110>, ++ LASX_3R_DESC_BASE<"xvsrarn.h.w", int_loongarch_lasx_xvsrarn_h_w, LASX256HOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVSRARN_W_D : LASX_3R<0b01110100111110111>, ++ LASX_3R_DESC_BASE<"xvsrarn.w.d", int_loongarch_lasx_xvsrarn_w_d, LASX256WOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVSSRLN_B_H : LASX_3R<0b01110100111111001>, ++ LASX_3R_DESC_BASE<"xvssrln.b.h", int_loongarch_lasx_xvssrln_b_h, LASX256BOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVSSRLN_H_W : LASX_3R<0b01110100111111010>, ++ LASX_3R_DESC_BASE<"xvssrln.h.w", int_loongarch_lasx_xvssrln_h_w, LASX256HOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVSSRLN_W_D : LASX_3R<0b01110100111111011>, ++ LASX_3R_DESC_BASE<"xvssrln.w.d", int_loongarch_lasx_xvssrln_w_d, LASX256WOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVSSRAN_B_H : LASX_3R<0b01110100111111101>, ++ LASX_3R_DESC_BASE<"xvssran.b.h", int_loongarch_lasx_xvssran_b_h, LASX256BOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVSSRAN_H_W : LASX_3R<0b01110100111111110>, ++ LASX_3R_DESC_BASE<"xvssran.h.w", int_loongarch_lasx_xvssran_h_w, LASX256HOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVSSRAN_W_D : LASX_3R<0b01110100111111111>, ++ LASX_3R_DESC_BASE<"xvssran.w.d", int_loongarch_lasx_xvssran_w_d, LASX256WOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVSSRLRN_B_H : LASX_3R<0b01110101000000001>, ++ LASX_3R_DESC_BASE<"xvssrlrn.b.h", int_loongarch_lasx_xvssrlrn_b_h, LASX256BOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVSSRLRN_H_W : LASX_3R<0b01110101000000010>, ++ LASX_3R_DESC_BASE<"xvssrlrn.h.w", int_loongarch_lasx_xvssrlrn_h_w, LASX256HOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVSSRLRN_W_D : LASX_3R<0b01110101000000011>, ++ LASX_3R_DESC_BASE<"xvssrlrn.w.d", int_loongarch_lasx_xvssrlrn_w_d, LASX256WOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVSSRARN_B_H : LASX_3R<0b01110101000000101>, ++ LASX_3R_DESC_BASE<"xvssrarn.b.h", int_loongarch_lasx_xvssrarn_b_h, LASX256BOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVSSRARN_H_W : LASX_3R<0b01110101000000110>, ++ LASX_3R_DESC_BASE<"xvssrarn.h.w", int_loongarch_lasx_xvssrarn_h_w, LASX256HOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVSSRARN_W_D : LASX_3R<0b01110101000000111>, ++ LASX_3R_DESC_BASE<"xvssrarn.w.d", int_loongarch_lasx_xvssrarn_w_d, LASX256WOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVSSRLN_BU_H : LASX_3R<0b01110101000001001>, ++ LASX_3R_DESC_BASE<"xvssrln.bu.h", int_loongarch_lasx_xvssrln_bu_h, LASX256BOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVSSRLN_HU_W : LASX_3R<0b01110101000001010>, ++ LASX_3R_DESC_BASE<"xvssrln.hu.w", int_loongarch_lasx_xvssrln_hu_w, LASX256HOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVSSRLN_WU_D : LASX_3R<0b01110101000001011>, ++ LASX_3R_DESC_BASE<"xvssrln.wu.d", int_loongarch_lasx_xvssrln_wu_d, LASX256WOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVSSRAN_BU_H : LASX_3R<0b01110101000001101>, ++ LASX_3R_DESC_BASE<"xvssran.bu.h", int_loongarch_lasx_xvssran_bu_h, LASX256BOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVSSRAN_HU_W : LASX_3R<0b01110101000001110>, ++ LASX_3R_DESC_BASE<"xvssran.hu.w", int_loongarch_lasx_xvssran_hu_w, LASX256HOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVSSRAN_WU_D : LASX_3R<0b01110101000001111>, ++ LASX_3R_DESC_BASE<"xvssran.wu.d", int_loongarch_lasx_xvssran_wu_d, LASX256WOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVSSRLRN_BU_H : LASX_3R<0b01110101000010001>, ++ LASX_3R_DESC_BASE<"xvssrlrn.bu.h", int_loongarch_lasx_xvssrlrn_bu_h, LASX256BOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVSSRLRN_HU_W : LASX_3R<0b01110101000010010>, ++ LASX_3R_DESC_BASE<"xvssrlrn.hu.w", int_loongarch_lasx_xvssrlrn_hu_w, LASX256HOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVSSRLRN_WU_D : LASX_3R<0b01110101000010011>, ++ LASX_3R_DESC_BASE<"xvssrlrn.wu.d", int_loongarch_lasx_xvssrlrn_wu_d, LASX256WOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVSSRARN_BU_H : LASX_3R<0b01110101000010101>, ++ LASX_3R_DESC_BASE<"xvssrarn.bu.h", int_loongarch_lasx_xvssrarn_bu_h, LASX256BOpnd, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVSSRARN_HU_W : LASX_3R<0b01110101000010110>, ++ LASX_3R_DESC_BASE<"xvssrarn.hu.w", int_loongarch_lasx_xvssrarn_hu_w, LASX256HOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVSSRARN_WU_D : LASX_3R<0b01110101000010111>, ++ LASX_3R_DESC_BASE<"xvssrarn.wu.d", int_loongarch_lasx_xvssrarn_wu_d, LASX256WOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVBITCLR_B : LASX_3R<0b01110101000011000>, ++ LASX_3R_DESC_BASE<"xvbitclr.b", xvbitclr_b, LASX256BOpnd>; ++ ++def XVBITCLR_H : LASX_3R<0b01110101000011001>, ++ LASX_3R_DESC_BASE<"xvbitclr.h", xvbitclr_h, LASX256HOpnd>; ++ ++def XVBITCLR_W : LASX_3R<0b01110101000011010>, ++ LASX_3R_DESC_BASE<"xvbitclr.w", xvbitclr_w, LASX256WOpnd>; ++ ++def XVBITCLR_D : LASX_3R<0b01110101000011011>, ++ LASX_3R_DESC_BASE<"xvbitclr.d", xvbitclr_d, LASX256DOpnd>; ++ ++ ++def XVBITSET_B : LASX_3R<0b01110101000011100>, ++ LASX_3R_DESC_BASE<"xvbitset.b", int_loongarch_lasx_xvbitset_b, LASX256BOpnd>; ++ ++def XVBITSET_H : LASX_3R<0b01110101000011101>, ++ LASX_3R_DESC_BASE<"xvbitset.h", int_loongarch_lasx_xvbitset_h, LASX256HOpnd>; ++ ++def XVBITSET_W : LASX_3R<0b01110101000011110>, ++ LASX_3R_DESC_BASE<"xvbitset.w", int_loongarch_lasx_xvbitset_w, LASX256WOpnd>; ++ ++def XVBITSET_D : LASX_3R<0b01110101000011111>, ++ LASX_3R_DESC_BASE<"xvbitset.d", int_loongarch_lasx_xvbitset_d, LASX256DOpnd>; ++ ++ ++def XVBITREV_B : LASX_3R<0b01110101000100000>, ++ LASX_3R_DESC_BASE<"xvbitrev.b", int_loongarch_lasx_xvbitrev_b, LASX256BOpnd>; ++ ++def XVBITREV_H : LASX_3R<0b01110101000100001>, ++ LASX_3R_DESC_BASE<"xvbitrev.h", int_loongarch_lasx_xvbitrev_h, LASX256HOpnd>; ++ ++def XVBITREV_W : LASX_3R<0b01110101000100010>, ++ LASX_3R_DESC_BASE<"xvbitrev.w", int_loongarch_lasx_xvbitrev_w, LASX256WOpnd>; ++ ++def XVBITREV_D : LASX_3R<0b01110101000100011>, ++ LASX_3R_DESC_BASE<"xvbitrev.d", int_loongarch_lasx_xvbitrev_d, LASX256DOpnd>; ++ ++ ++def XVPACKEV_B : LASX_3R<0b01110101000101100>, ++ LASX_3R_DESC_BASE<"xvpackev.b", LoongArchVPACKEV, LASX256BOpnd>; ++ ++def XVPACKEV_H : LASX_3R<0b01110101000101101>, ++ LASX_3R_DESC_BASE<"xvpackev.h", LoongArchVPACKEV, LASX256HOpnd>; ++ ++def XVPACKEV_W : LASX_3R<0b01110101000101110>, ++ LASX_3R_DESC_BASE<"xvpackev.w", LoongArchVPACKEV, LASX256WOpnd>; ++ ++def XVPACKEV_D : LASX_3R<0b01110101000101111>, ++ LASX_3R_DESC_BASE<"xvpackev.d", LoongArchVPACKEV, LASX256DOpnd>; ++ ++ ++def XVPACKOD_B : LASX_3R<0b01110101000110000>, ++ LASX_3R_DESC_BASE<"xvpackod.b", LoongArchVPACKOD, LASX256BOpnd>; ++ ++def XVPACKOD_H : LASX_3R<0b01110101000110001>, ++ LASX_3R_DESC_BASE<"xvpackod.h", LoongArchVPACKOD, LASX256HOpnd>; ++ ++def XVPACKOD_W : LASX_3R<0b01110101000110010>, ++ LASX_3R_DESC_BASE<"xvpackod.w", LoongArchVPACKOD, LASX256WOpnd>; ++ ++def XVPACKOD_D : LASX_3R<0b01110101000110011>, ++ LASX_3R_DESC_BASE<"xvpackod.d", LoongArchVPACKOD, LASX256DOpnd>; ++ ++ ++def XVILVL_B : LASX_3R<0b01110101000110100>, ++ LASX_3R_DESC_BASE<"xvilvl.b", LoongArchVILVL, LASX256BOpnd>; ++ ++def XVILVL_H : LASX_3R<0b01110101000110101>, ++ LASX_3R_DESC_BASE<"xvilvl.h", LoongArchVILVL, LASX256HOpnd>; ++ ++def XVILVL_W : LASX_3R<0b01110101000110110>, ++ LASX_3R_DESC_BASE<"xvilvl.w", LoongArchVILVL, LASX256WOpnd>; ++ ++def XVILVL_D : LASX_3R<0b01110101000110111>, ++ LASX_3R_DESC_BASE<"xvilvl.d", LoongArchVILVL, LASX256DOpnd>; ++ ++ ++def XVILVH_B : LASX_3R<0b01110101000111000>, ++ LASX_3R_DESC_BASE<"xvilvh.b", LoongArchVILVH, LASX256BOpnd>; ++ ++def XVILVH_H : LASX_3R<0b01110101000111001>, ++ LASX_3R_DESC_BASE<"xvilvh.h", LoongArchVILVH, LASX256HOpnd>; ++ ++def XVILVH_W : LASX_3R<0b01110101000111010>, ++ LASX_3R_DESC_BASE<"xvilvh.w", LoongArchVILVH, LASX256WOpnd>; ++ ++def XVILVH_D : LASX_3R<0b01110101000111011>, ++ LASX_3R_DESC_BASE<"xvilvh.d", LoongArchVILVH, LASX256DOpnd>; ++ ++ ++def XVPICKEV_B : LASX_3R<0b01110101000111100>, ++ LASX_3R_DESC_BASE<"xvpickev.b", LoongArchVPICKEV, LASX256BOpnd>; ++ ++def XVPICKEV_H : LASX_3R<0b01110101000111101>, ++ LASX_3R_DESC_BASE<"xvpickev.h", LoongArchVPICKEV, LASX256HOpnd>; ++ ++def XVPICKEV_W : LASX_3R<0b01110101000111110>, ++ LASX_3R_DESC_BASE<"xvpickev.w", LoongArchVPICKEV, LASX256WOpnd>; ++ ++def XVPICKEV_D : LASX_3R<0b01110101000111111>, ++ LASX_3R_DESC_BASE<"xvpickev.d", LoongArchVPICKEV, LASX256DOpnd>; ++ ++ ++def XVPICKOD_B : LASX_3R<0b01110101001000000>, ++ LASX_3R_DESC_BASE<"xvpickod.b", LoongArchVPICKOD, LASX256BOpnd>; ++ ++def XVPICKOD_H : LASX_3R<0b01110101001000001>, ++ LASX_3R_DESC_BASE<"xvpickod.h", LoongArchVPICKOD, LASX256HOpnd>; ++ ++def XVPICKOD_W : LASX_3R<0b01110101001000010>, ++ LASX_3R_DESC_BASE<"xvpickod.w", LoongArchVPICKOD, LASX256WOpnd>; ++ ++def XVPICKOD_D : LASX_3R<0b01110101001000011>, ++ LASX_3R_DESC_BASE<"xvpickod.d", LoongArchVPICKOD, LASX256DOpnd>; ++ ++ ++def XVREPLVE_B : LASX_3R_1GP<0b01110101001000100>, ++ LASX_3R_VREPLVE_DESC_BASE<"xvreplve.b", int_loongarch_lasx_xvreplve_b, LASX256BOpnd>; ++ ++def XVREPLVE_H : LASX_3R_1GP<0b01110101001000101>, ++ LASX_3R_VREPLVE_DESC_BASE<"xvreplve.h", int_loongarch_lasx_xvreplve_h, LASX256HOpnd>; ++ ++def XVREPLVE_W : LASX_3R_1GP<0b01110101001000110>, ++ LASX_3R_VREPLVE_DESC_BASE<"xvreplve.w", int_loongarch_lasx_xvreplve_w, LASX256WOpnd>; ++ ++def XVREPLVE_D : LASX_3R_1GP<0b01110101001000111>, ++ LASX_3R_VREPLVE_DESC_BASE<"xvreplve.d", int_loongarch_lasx_xvreplve_d, LASX256DOpnd>; ++ ++ ++def XVAND_V : LASX_3R<0b01110101001001100>, ++ LASX_VEC_DESC_BASE<"xvand.v", and, LASX256BOpnd>; ++class XAND_V_H_PSEUDO_DESC : LASX_VEC_PSEUDO_BASE; ++class XAND_V_W_PSEUDO_DESC : LASX_VEC_PSEUDO_BASE; ++class XAND_V_D_PSEUDO_DESC : LASX_VEC_PSEUDO_BASE; ++ ++def XAND_V_H_PSEUDO : XAND_V_H_PSEUDO_DESC, ++ PseudoInstExpansion<(XVAND_V LASX256BOpnd:$xd, ++ LASX256BOpnd:$xj, ++ LASX256BOpnd:$xk)>; ++def XAND_V_W_PSEUDO : XAND_V_W_PSEUDO_DESC, ++ PseudoInstExpansion<(XVAND_V LASX256BOpnd:$xd, ++ LASX256BOpnd:$xj, ++ LASX256BOpnd:$xk)>; ++def XAND_V_D_PSEUDO : XAND_V_D_PSEUDO_DESC, ++ PseudoInstExpansion<(XVAND_V LASX256BOpnd:$xd, ++ LASX256BOpnd:$xj, ++ LASX256BOpnd:$xk)>; ++ ++ ++def XVOR_V : LASX_3R<0b01110101001001101>, ++ LASX_VEC_DESC_BASE<"xvor.v", or, LASX256BOpnd>; ++class X_OR_V_H_PSEUDO_DESC : LASX_VEC_PSEUDO_BASE; ++class X_OR_V_W_PSEUDO_DESC : LASX_VEC_PSEUDO_BASE; ++class X_OR_V_D_PSEUDO_DESC : LASX_VEC_PSEUDO_BASE; ++ ++def X_OR_V_H_PSEUDO : X_OR_V_H_PSEUDO_DESC, ++ PseudoInstExpansion<(XVOR_V LASX256BOpnd:$xd, ++ LASX256BOpnd:$xj, ++ LASX256BOpnd:$xk)>; ++def X_OR_V_W_PSEUDO : X_OR_V_W_PSEUDO_DESC, ++ PseudoInstExpansion<(XVOR_V LASX256BOpnd:$xd, ++ LASX256BOpnd:$xj, ++ LASX256BOpnd:$xk)>; ++def X_OR_V_D_PSEUDO : X_OR_V_D_PSEUDO_DESC, ++ PseudoInstExpansion<(XVOR_V LASX256BOpnd:$xd, ++ LASX256BOpnd:$xj, ++ LASX256BOpnd:$xk)>; ++ ++ ++def XVXOR_V : LASX_3R<0b01110101001001110>, ++ LASX_VEC_DESC_BASE<"xvxor.v", xor, LASX256BOpnd>; ++class XXOR_V_H_PSEUDO_DESC : LASX_VEC_PSEUDO_BASE; ++class XXOR_V_W_PSEUDO_DESC : LASX_VEC_PSEUDO_BASE; ++class XXOR_V_D_PSEUDO_DESC : LASX_VEC_PSEUDO_BASE; ++ ++def XXOR_V_H_PSEUDO : XXOR_V_H_PSEUDO_DESC, ++ PseudoInstExpansion<(XVXOR_V LASX256BOpnd:$xd, ++ LASX256BOpnd:$xj, ++ LASX256BOpnd:$xk)>; ++def XXOR_V_W_PSEUDO : XXOR_V_W_PSEUDO_DESC, ++ PseudoInstExpansion<(XVXOR_V LASX256BOpnd:$xd, ++ LASX256BOpnd:$xj, ++ LASX256BOpnd:$xk)>; ++def XXOR_V_D_PSEUDO : XXOR_V_D_PSEUDO_DESC, ++ PseudoInstExpansion<(XVXOR_V LASX256BOpnd:$xd, ++ LASX256BOpnd:$xj, ++ LASX256BOpnd:$xk)>; ++ ++ ++def XVNOR_V : LASX_3R<0b01110101001001111>, ++ LASX_VEC_DESC_BASE<"xvnor.v", LoongArchVNOR, LASX256BOpnd>; ++ ++class XNOR_V_H_PSEUDO_DESC : LASX_VEC_PSEUDO_BASE; ++class XNOR_V_W_PSEUDO_DESC : LASX_VEC_PSEUDO_BASE; ++class XNOR_V_D_PSEUDO_DESC : LASX_VEC_PSEUDO_BASE; ++ ++def XNOR_V_H_PSEUDO : XNOR_V_H_PSEUDO_DESC, ++ PseudoInstExpansion<(XVNOR_V LASX256BOpnd:$xd, ++ LASX256BOpnd:$xj, ++ LASX256BOpnd:$xk)>; ++def XNOR_V_W_PSEUDO : XNOR_V_W_PSEUDO_DESC, ++ PseudoInstExpansion<(XVNOR_V LASX256BOpnd:$xd, ++ LASX256BOpnd:$xj, ++ LASX256BOpnd:$xk)>; ++def XNOR_V_D_PSEUDO : XNOR_V_D_PSEUDO_DESC, ++ PseudoInstExpansion<(XVNOR_V LASX256BOpnd:$xd, ++ LASX256BOpnd:$xj, ++ LASX256BOpnd:$xk)>; ++ ++ ++def XVANDN_V : LASX_3R<0b01110101001010000>, ++ LASX_3R_DESC_BASE<"xvandn.v", int_loongarch_lasx_xvandn_v, LASX256BOpnd>; ++ ++ ++class LASX_ANDN_PSEUDO_BASE : ++ LASXPseudo<(outs RO:$xd), (ins RO:$xj, RO:$xk), ++ []>, ++ PseudoInstExpansion<(XVANDN_V LASX256BOpnd:$xd, ++ LASX256BOpnd:$xj, ++ LASX256BOpnd:$xk)>; ++ ++def XVANDN_H_PSEUDO : LASX_ANDN_PSEUDO_BASE; ++def XVANDN_W_PSEUDO : LASX_ANDN_PSEUDO_BASE; ++def XVANDN_D_PSEUDO : LASX_ANDN_PSEUDO_BASE; ++ ++ ++def XVORN_V : LASX_3R<0b01110101001010001>, ++ LASX_3R_DESC_BASE<"xvorn.v", int_loongarch_lasx_xvorn_v, LASX256BOpnd>; ++ ++ ++class LASX_ORN_PSEUDO_BASE : ++ LASXPseudo<(outs RO:$xd), (ins RO:$xj, RO:$xk), ++ []>, ++ PseudoInstExpansion<(XVORN_V LASX256BOpnd:$xd, ++ LASX256BOpnd:$xj, ++ LASX256BOpnd:$xk)>; ++ ++def XVORN_H_PSEUDO : LASX_ORN_PSEUDO_BASE; ++def XVORN_W_PSEUDO : LASX_ORN_PSEUDO_BASE; ++def XVORN_D_PSEUDO : LASX_ORN_PSEUDO_BASE; ++ ++ ++def XVFRSTP_B : LASX_3R<0b01110101001010110>, ++ LASX_3R_4R_DESC_BASE<"xvfrstp.b", int_loongarch_lasx_xvfrstp_b, LASX256BOpnd>; ++ ++def XVFRSTP_H : LASX_3R<0b01110101001010111>, ++ LASX_3R_4R_DESC_BASE<"xvfrstp.h", int_loongarch_lasx_xvfrstp_h, LASX256HOpnd>; ++ ++ ++def XVADD_Q : LASX_3R<0b01110101001011010>, IsCommutable, ++ LASX_3R_DESC_BASE<"xvadd.q", int_loongarch_lasx_xvadd_q, LASX256DOpnd>; ++ ++def XVSUB_Q : LASX_3R<0b01110101001011011>, ++ LASX_3R_DESC_BASE<"xvsub.q", int_loongarch_lasx_xvsub_q, LASX256DOpnd>; ++ ++ ++def XVSIGNCOV_B : LASX_3R<0b01110101001011100>, ++ LASX_3R_DESC_BASE<"xvsigncov.b", int_loongarch_lasx_xvsigncov_b, LASX256BOpnd>; ++ ++def XVSIGNCOV_H : LASX_3R<0b01110101001011101>, ++ LASX_3R_DESC_BASE<"xvsigncov.h", int_loongarch_lasx_xvsigncov_h, LASX256HOpnd>; ++ ++def XVSIGNCOV_W : LASX_3R<0b01110101001011110>, ++ LASX_3R_DESC_BASE<"xvsigncov.w", int_loongarch_lasx_xvsigncov_w, LASX256WOpnd>; ++ ++def XVSIGNCOV_D : LASX_3R<0b01110101001011111>, ++ LASX_3R_DESC_BASE<"xvsigncov.d", int_loongarch_lasx_xvsigncov_d, LASX256DOpnd>; ++ ++ ++def XVFADD_S : LASX_3R<0b01110101001100001>, IsCommutable, ++ LASX_3RF_DESC_BASE<"xvfadd.s", fadd, LASX256WOpnd>; ++ ++def XVFADD_D : LASX_3R<0b01110101001100010>, IsCommutable, ++ LASX_3RF_DESC_BASE<"xvfadd.d", fadd, LASX256DOpnd>; ++ ++ ++def XVFSUB_S : LASX_3R<0b01110101001100101>, ++ LASX_3RF_DESC_BASE<"xvfsub.s", fsub, LASX256WOpnd>; ++ ++def XVFSUB_D : LASX_3R<0b01110101001100110>, ++ LASX_3RF_DESC_BASE<"xvfsub.d", fsub, LASX256DOpnd>; ++ ++ ++def XVFMUL_S : LASX_3R<0b01110101001110001>, ++ LASX_3RF_DESC_BASE<"xvfmul.s", fmul, LASX256WOpnd>; ++ ++def XVFMUL_D : LASX_3R<0b01110101001110010>, ++ LASX_3RF_DESC_BASE<"xvfmul.d", fmul, LASX256DOpnd>; ++ ++ ++def XVFDIV_S : LASX_3R<0b01110101001110101>, ++ LASX_3RF_DESC_BASE<"xvfdiv.s", fdiv, LASX256WOpnd>; ++ ++def XVFDIV_D : LASX_3R<0b01110101001110110>, ++ LASX_3RF_DESC_BASE<"xvfdiv.d", fdiv, LASX256DOpnd>; ++ ++ ++def XVFMAX_S : LASX_3R<0b01110101001111001>, ++ LASX_3RF_DESC_BASE<"xvfmax.s", int_loongarch_lasx_xvfmax_s, LASX256WOpnd>; ++ ++def XVFMAX_D : LASX_3R<0b01110101001111010>, ++ LASX_3RF_DESC_BASE<"xvfmax.d", int_loongarch_lasx_xvfmax_d, LASX256DOpnd>; ++ ++ ++def XVFMIN_S : LASX_3R<0b01110101001111101>, ++ LASX_3RF_DESC_BASE<"xvfmin.s", int_loongarch_lasx_xvfmin_s, LASX256WOpnd>; ++ ++def XVFMIN_D : LASX_3R<0b01110101001111110>, ++ LASX_3RF_DESC_BASE<"xvfmin.d", int_loongarch_lasx_xvfmin_d, LASX256DOpnd>; ++ ++ ++def XVFMAXA_S : LASX_3R<0b01110101010000001>, ++ LASX_3RF_DESC_BASE<"xvfmaxa.s", int_loongarch_lasx_xvfmaxa_s, LASX256WOpnd>; ++ ++def XVFMAXA_D : LASX_3R<0b01110101010000010>, ++ LASX_3RF_DESC_BASE<"xvfmaxa.d", int_loongarch_lasx_xvfmaxa_d, LASX256DOpnd>; ++ ++ ++def XVFMINA_S : LASX_3R<0b01110101010000101>, ++ LASX_3RF_DESC_BASE<"xvfmina.s", int_loongarch_lasx_xvfmina_s, LASX256WOpnd>; ++ ++def XVFMINA_D : LASX_3R<0b01110101010000110>, ++ LASX_3RF_DESC_BASE<"xvfmina.d", int_loongarch_lasx_xvfmina_d, LASX256DOpnd>; ++ ++ ++def XVFCVT_H_S : LASX_3R<0b01110101010001100>, ++ LASX_3RF_DESC_BASE<"xvfcvt.h.s", int_loongarch_lasx_xvfcvt_h_s, LASX256HOpnd, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVFCVT_S_D : LASX_3R<0b01110101010001101>, ++ LASX_3RF_DESC_BASE1<"xvfcvt.s.d", int_loongarch_lasx_xvfcvt_s_d, LASX256WOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVFFINT_S_L : LASX_3R<0b01110101010010000>, ++ LASX_3RF_DESC_BASE<"xvffint.s.l", int_loongarch_lasx_xvffint_s_l, LASX256WOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++def XVFTINT_W_D : LASX_3R<0b01110101010010011>, ++ LASX_3RF_DESC_BASE<"xvftint.w.d", int_loongarch_lasx_xvftint_w_d, LASX256WOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVFTINTRM_W_D : LASX_3R<0b01110101010010100>, ++ LASX_3RF_DESC_BASE<"xvftintrm.w.d", int_loongarch_lasx_xvftintrm_w_d, LASX256WOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++def XVFTINTRP_W_D : LASX_3R<0b01110101010010101>, ++ LASX_3RF_DESC_BASE<"xvftintrp.w.d", int_loongarch_lasx_xvftintrp_w_d, LASX256WOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++def XVFTINTRZ_W_D : LASX_3R<0b01110101010010110>, ++ LASX_3RF_DESC_BASE<"xvftintrz.w.d", int_loongarch_lasx_xvftintrz_w_d, LASX256WOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++def XVFTINTRNE_W_D : LASX_3R<0b01110101010010111>, ++ LASX_3RF_DESC_BASE<"xvftintrne.w.d", int_loongarch_lasx_xvftintrne_w_d, LASX256WOpnd, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVSHUF_H : LASX_3R<0b01110101011110101>, ++ LASX_3R_VSHF_DESC_BASE<"xvshuf.h", LASX256HOpnd>; ++ ++def XVSHUF_W : LASX_3R<0b01110101011110110>, ++ LASX_3R_VSHF_DESC_BASE<"xvshuf.w", LASX256WOpnd>; ++ ++def XVSHUF_D : LASX_3R<0b01110101011110111>, ++ LASX_3R_VSHF_DESC_BASE<"xvshuf.d", LASX256DOpnd>; ++ ++ ++def XVPERM_W : LASX_3R<0b01110101011111010>, ++ LASX_3R_DESC_BASE<"xvperm.w", int_loongarch_lasx_xvperm_w, LASX256WOpnd>; ++ ++ ++def XVSEQI_B : LASX_I5<0b01110110100000000>, ++ LASX_I5_SETCC_DESC_BASE_Intrinsic<"xvseqi.b", int_loongarch_lasx_xvseqi_b, simm5_32, immSExt5, LASX256BOpnd>; ++ ++def XVSEQI_H : LASX_I5<0b01110110100000001>, ++ LASX_I5_SETCC_DESC_BASE_Intrinsic<"xvseqi.h", int_loongarch_lasx_xvseqi_h, simm5_32, immSExt5, LASX256HOpnd>; ++ ++def XVSEQI_W : LASX_I5<0b01110110100000010>, ++ LASX_I5_SETCC_DESC_BASE_Intrinsic<"xvseqi.w", int_loongarch_lasx_xvseqi_w, simm5_32, immSExt5, LASX256WOpnd>; ++ ++def XVSEQI_D : LASX_I5<0b01110110100000011>, ++ LASX_I5_SETCC_DESC_BASE_Intrinsic<"xvseqi.d", int_loongarch_lasx_xvseqi_d, simm5_32, immSExt5, LASX256DOpnd>; ++ ++ ++def XVSLEI_B : LASX_I5<0b01110110100000100>, ++ LASX_I5_SETCC_DESC_BASE_Intrinsic<"xvslei.b", int_loongarch_lasx_xvslei_b, simm5_32, immSExt5, LASX256BOpnd>; ++ ++def XVSLEI_H : LASX_I5<0b01110110100000101>, ++ LASX_I5_SETCC_DESC_BASE_Intrinsic<"xvslei.h", int_loongarch_lasx_xvslei_h, simm5_32, immSExt5, LASX256HOpnd>; ++ ++def XVSLEI_W : LASX_I5<0b01110110100000110>, ++ LASX_I5_SETCC_DESC_BASE_Intrinsic<"xvslei.w", int_loongarch_lasx_xvslei_w, simm5_32, immSExt5, LASX256WOpnd>; ++ ++def XVSLEI_D : LASX_I5<0b01110110100000111>, ++ LASX_I5_SETCC_DESC_BASE_Intrinsic<"xvslei.d", int_loongarch_lasx_xvslei_d, simm5_32, immSExt5, LASX256DOpnd>; ++ ++ ++def XVSLEI_BU : LASX_I5_U<0b01110110100001000>, ++ LASX_I5_U_SETCC_DESC_BASE_Intrinsic<"xvslei.bu", int_loongarch_lasx_xvslei_bu, uimm5, immZExt5, LASX256BOpnd>; ++ ++def XVSLEI_HU : LASX_I5_U<0b01110110100001001>, ++ LASX_I5_U_SETCC_DESC_BASE_Intrinsic<"xvslei.hu", int_loongarch_lasx_xvslei_hu, uimm5, immZExt5, LASX256HOpnd>; ++ ++def XVSLEI_WU : LASX_I5_U<0b01110110100001010>, ++ LASX_I5_U_SETCC_DESC_BASE_Intrinsic<"xvslei.wu", int_loongarch_lasx_xvslei_wu, uimm5, immZExt5, LASX256WOpnd>; ++ ++def XVSLEI_DU : LASX_I5_U<0b01110110100001011>, ++ LASX_I5_U_SETCC_DESC_BASE_Intrinsic<"xvslei.du", int_loongarch_lasx_xvslei_du, uimm5, immZExt5, LASX256DOpnd>; ++ ++ ++def XVSLTI_B : LASX_I5<0b01110110100001100>, ++ LASX_I5_SETCC_DESC_BASE_Intrinsic<"xvslti.b", int_loongarch_lasx_xvslti_b, simm5_32, immSExt5, LASX256BOpnd>; ++ ++def XVSLTI_H : LASX_I5<0b01110110100001101>, ++ LASX_I5_SETCC_DESC_BASE_Intrinsic<"xvslti.h", int_loongarch_lasx_xvslti_h, simm5_32, immSExt5, LASX256HOpnd>; ++ ++def XVSLTI_W : LASX_I5<0b01110110100001110>, ++ LASX_I5_SETCC_DESC_BASE_Intrinsic<"xvslti.w", int_loongarch_lasx_xvslti_w, simm5_32, immSExt5, LASX256WOpnd>; ++ ++def XVSLTI_D : LASX_I5<0b01110110100001111>, ++ LASX_I5_SETCC_DESC_BASE_Intrinsic<"xvslti.d", int_loongarch_lasx_xvslti_d, simm5_32, immSExt5, LASX256DOpnd>; ++ ++ ++def XVSLTI_BU : LASX_I5_U<0b01110110100010000>, ++ LASX_I5_U_SETCC_DESC_BASE_Intrinsic<"xvslti.bu", int_loongarch_lasx_xvslti_bu, uimm5, immZExt5, LASX256BOpnd>; ++ ++def XVSLTI_HU : LASX_I5_U<0b01110110100010001>, ++ LASX_I5_U_SETCC_DESC_BASE_Intrinsic<"xvslti.hu", int_loongarch_lasx_xvslti_hu, uimm5, immZExt5, LASX256HOpnd>; ++ ++def XVSLTI_WU : LASX_I5_U<0b01110110100010010>, ++ LASX_I5_U_SETCC_DESC_BASE_Intrinsic<"xvslti.wu", int_loongarch_lasx_xvslti_wu, uimm5, immZExt5, LASX256WOpnd>; ++ ++def XVSLTI_DU : LASX_I5_U<0b01110110100010011>, ++ LASX_I5_U_SETCC_DESC_BASE_Intrinsic<"xvslti.du", int_loongarch_lasx_xvslti_du, uimm5, immZExt5, LASX256DOpnd>; ++ ++ ++def XVADDI_BU : LASX_I5_U<0b01110110100010100>, ++ LASX_I5_U_DESC_BASE_Intrinsic<"xvaddi.bu", int_loongarch_lasx_xvaddi_bu, uimm5, immZExt5, LASX256BOpnd>; ++ ++def XVADDI_HU : LASX_I5_U<0b01110110100010101>, ++ LASX_I5_U_DESC_BASE_Intrinsic<"xvaddi.hu", int_loongarch_lasx_xvaddi_hu, uimm5, immZExt5, LASX256HOpnd>; ++ ++def XVADDI_WU : LASX_I5_U<0b01110110100010110>, ++ LASX_I5_U_DESC_BASE_Intrinsic<"xvaddi.wu", int_loongarch_lasx_xvaddi_wu, uimm5, immZExt5, LASX256WOpnd>; ++ ++def XVADDI_DU : LASX_I5_U<0b01110110100010111>, ++ LASX_I5_U_DESC_BASE_Intrinsic<"xvaddi.du", int_loongarch_lasx_xvaddi_du, uimm5, immZExt5, LASX256DOpnd>; ++ ++ ++def XVSUBI_BU : LASX_I5_U<0b01110110100011000>, ++ LASX_I5_U_DESC_BASE_Intrinsic<"xvsubi.bu", int_loongarch_lasx_xvsubi_bu, uimm5, immZExt5, LASX256BOpnd>; ++ ++def XVSUBI_HU : LASX_I5_U<0b01110110100011001>, ++ LASX_I5_U_DESC_BASE_Intrinsic<"xvsubi.hu", int_loongarch_lasx_xvsubi_hu, uimm5, immZExt5, LASX256HOpnd>; ++ ++def XVSUBI_WU : LASX_I5_U<0b01110110100011010>, ++ LASX_I5_U_DESC_BASE_Intrinsic<"xvsubi.wu", int_loongarch_lasx_xvsubi_wu, uimm5, immZExt5, LASX256WOpnd>; ++ ++def XVSUBI_DU : LASX_I5_U<0b01110110100011011>, ++ LASX_I5_U_DESC_BASE_Intrinsic<"xvsubi.du", int_loongarch_lasx_xvsubi_du, uimm5, immZExt5, LASX256DOpnd>; ++ ++ ++def XVBSLL_V : LASX_I5_U<0b01110110100011100>, ++ LASX_U5_DESC_BASE<"xvbsll.v", int_loongarch_lasx_xvbsll_v, LASX256BOpnd>; ++ ++def XVBSRL_V : LASX_I5_U<0b01110110100011101>, ++ LASX_U5_DESC_BASE<"xvbsrl.v", int_loongarch_lasx_xvbsrl_v, LASX256BOpnd>; ++ ++ ++def XVMAXI_B : LASX_I5<0b01110110100100000>, ++ LASX_I5_DESC_BASE_Intrinsic<"xvmaxi.b", int_loongarch_lasx_xvmaxi_b, simm5_32, immSExt5, LASX256BOpnd>; ++ ++def XVMAXI_H : LASX_I5<0b01110110100100001>, ++ LASX_I5_DESC_BASE_Intrinsic<"xvmaxi.h", int_loongarch_lasx_xvmaxi_h, simm5_32, immSExt5, LASX256HOpnd>; ++ ++def XVMAXI_W : LASX_I5<0b01110110100100010>, ++ LASX_I5_DESC_BASE_Intrinsic<"xvmaxi.w", int_loongarch_lasx_xvmaxi_w, simm5_32, immSExt5, LASX256WOpnd>; ++ ++def XVMAXI_D : LASX_I5<0b01110110100100011>, ++ LASX_I5_DESC_BASE_Intrinsic<"xvmaxi.d", int_loongarch_lasx_xvmaxi_d, simm5_32, immSExt5, LASX256DOpnd>; ++ ++ ++def XVMINI_B : LASX_I5<0b01110110100100100>, ++ LASX_I5_DESC_BASE_Intrinsic<"xvmini.b", int_loongarch_lasx_xvmini_b, simm5_32, immSExt5, LASX256BOpnd>; ++ ++def XVMINI_H : LASX_I5<0b01110110100100101>, ++ LASX_I5_DESC_BASE_Intrinsic<"xvmini.h", int_loongarch_lasx_xvmini_h, simm5_32, immSExt5, LASX256HOpnd>; ++ ++def XVMINI_W : LASX_I5<0b01110110100100110>, ++ LASX_I5_DESC_BASE_Intrinsic<"xvmini.w", int_loongarch_lasx_xvmini_w, simm5_32, immSExt5, LASX256WOpnd>; ++ ++def XVMINI_D : LASX_I5<0b01110110100100111>, ++ LASX_I5_DESC_BASE_Intrinsic<"xvmini.d", int_loongarch_lasx_xvmini_d, simm5_32, immSExt5, LASX256DOpnd>; ++ ++ ++def XVMAXI_BU : LASX_I5_U<0b01110110100101000>, ++ LASX_I5_U_DESC_BASE_Intrinsic<"xvmaxi.bu", int_loongarch_lasx_xvmaxi_bu, uimm5, immZExt5, LASX256BOpnd>; ++ ++def XVMAXI_HU : LASX_I5_U<0b01110110100101001>, ++ LASX_I5_U_DESC_BASE_Intrinsic<"xvmaxi.hu", int_loongarch_lasx_xvmaxi_hu, uimm5, immZExt5, LASX256HOpnd>; ++ ++def XVMAXI_WU : LASX_I5_U<0b01110110100101010>, ++ LASX_I5_U_DESC_BASE_Intrinsic<"xvmaxi.wu", int_loongarch_lasx_xvmaxi_wu, uimm5, immZExt5, LASX256WOpnd>; ++ ++def XVMAXI_DU : LASX_I5_U<0b01110110100101011>, ++ LASX_I5_U_DESC_BASE_Intrinsic<"xvmaxi.du", int_loongarch_lasx_xvmaxi_du, uimm5, immZExt5, LASX256DOpnd>; ++ ++ ++def XVMINI_BU : LASX_I5_U<0b01110110100101100>, ++ LASX_I5_U_DESC_BASE_Intrinsic<"xvmini.bu", int_loongarch_lasx_xvmini_bu, uimm5, immZExt5, LASX256BOpnd>; ++ ++def XVMINI_HU : LASX_I5_U<0b01110110100101101>, ++ LASX_I5_U_DESC_BASE_Intrinsic<"xvmini.hu", int_loongarch_lasx_xvmini_hu, uimm5, immZExt5, LASX256HOpnd>; ++ ++def XVMINI_WU : LASX_I5_U<0b01110110100101110>, ++ LASX_I5_U_DESC_BASE_Intrinsic<"xvmini.wu", int_loongarch_lasx_xvmini_wu, uimm5, immZExt5, LASX256WOpnd>; ++ ++def XVMINI_DU : LASX_I5_U<0b01110110100101111>, ++ LASX_I5_U_DESC_BASE_Intrinsic<"xvmini.du", int_loongarch_lasx_xvmini_du, uimm5, immZExt5, LASX256DOpnd>; ++ ++ ++def XVFRSTPI_B : LASX_I5_U<0b01110110100110100>, ++ LASX_U5_4R_DESC_BASE<"xvfrstpi.b", int_loongarch_lasx_xvfrstpi_b, LASX256BOpnd>; ++ ++def XVFRSTPI_H : LASX_I5_U<0b01110110100110101>, ++ LASX_U5_4R_DESC_BASE<"xvfrstpi.h", int_loongarch_lasx_xvfrstpi_h, LASX256HOpnd>; ++ ++ ++def XVCLO_B : LASX_2R<0b0111011010011100000000>, ++ LASX_2R_DESC_BASE<"xvclo.b", int_loongarch_lasx_xvclo_b, LASX256BOpnd>; ++ ++def XVCLO_H : LASX_2R<0b0111011010011100000001>, ++ LASX_2R_DESC_BASE<"xvclo.h", int_loongarch_lasx_xvclo_h, LASX256HOpnd>; ++ ++def XVCLO_W : LASX_2R<0b0111011010011100000010>, ++ LASX_2R_DESC_BASE<"xvclo.w", int_loongarch_lasx_xvclo_w, LASX256WOpnd>; ++ ++def XVCLO_D : LASX_2R<0b0111011010011100000011>, ++ LASX_2R_DESC_BASE<"xvclo.d", int_loongarch_lasx_xvclo_d, LASX256DOpnd>; ++ ++ ++def XVCLZ_B : LASX_2R<0b0111011010011100000100>, ++ LASX_2R_DESC_BASE<"xvclz.b", ctlz, LASX256BOpnd>; ++ ++def XVCLZ_H : LASX_2R<0b0111011010011100000101>, ++ LASX_2R_DESC_BASE<"xvclz.h", ctlz, LASX256HOpnd>; ++ ++def XVCLZ_W : LASX_2R<0b0111011010011100000110>, ++ LASX_2R_DESC_BASE<"xvclz.w", ctlz, LASX256WOpnd>; ++ ++def XVCLZ_D : LASX_2R<0b0111011010011100000111>, ++ LASX_2R_DESC_BASE<"xvclz.d", ctlz, LASX256DOpnd>; ++ ++ ++def XVPCNT_B : LASX_2R<0b0111011010011100001000>, ++ LASX_2R_DESC_BASE<"xvpcnt.b", ctpop, LASX256BOpnd>; ++ ++def XVPCNT_H : LASX_2R<0b0111011010011100001001>, ++ LASX_2R_DESC_BASE<"xvpcnt.h", ctpop, LASX256HOpnd>; ++ ++def XVPCNT_W : LASX_2R<0b0111011010011100001010>, ++ LASX_2R_DESC_BASE<"xvpcnt.w", ctpop, LASX256WOpnd>; ++ ++def XVPCNT_D : LASX_2R<0b0111011010011100001011>, ++ LASX_2R_DESC_BASE<"xvpcnt.d", ctpop, LASX256DOpnd>; ++ ++ ++def XVNEG_B : LASX_2R<0b0111011010011100001100>, ++ LASX_2R_DESC_BASE<"xvneg.b", int_loongarch_lasx_xvneg_b, LASX256BOpnd>; ++ ++def XVNEG_H : LASX_2R<0b0111011010011100001101>, ++ LASX_2R_DESC_BASE<"xvneg.h", int_loongarch_lasx_xvneg_h, LASX256HOpnd>; ++ ++def XVNEG_W : LASX_2R<0b0111011010011100001110>, ++ LASX_2R_DESC_BASE<"xvneg.w", int_loongarch_lasx_xvneg_w, LASX256WOpnd>; ++ ++def XVNEG_D : LASX_2R<0b0111011010011100001111>, ++ LASX_2R_DESC_BASE<"xvneg.d", int_loongarch_lasx_xvneg_d, LASX256DOpnd>; ++ ++ ++def XVMSKLTZ_B : LASX_2R<0b0111011010011100010000>, ++ LASX_2R_DESC_BASE<"xvmskltz.b", int_loongarch_lasx_xvmskltz_b, LASX256BOpnd>; ++ ++def XVMSKLTZ_H : LASX_2R<0b0111011010011100010001>, ++ LASX_2R_DESC_BASE<"xvmskltz.h", int_loongarch_lasx_xvmskltz_h, LASX256HOpnd>; ++ ++def XVMSKLTZ_W : LASX_2R<0b0111011010011100010010>, ++ LASX_2R_DESC_BASE<"xvmskltz.w", int_loongarch_lasx_xvmskltz_w, LASX256WOpnd>; ++ ++def XVMSKLTZ_D : LASX_2R<0b0111011010011100010011>, ++ LASX_2R_DESC_BASE<"xvmskltz.d", int_loongarch_lasx_xvmskltz_d, LASX256DOpnd>; ++ ++ ++def XVMSKGEZ_B : LASX_2R<0b0111011010011100010100>, ++ LASX_2R_DESC_BASE<"xvmskgez.b", int_loongarch_lasx_xvmskgez_b, LASX256BOpnd>; ++ ++def XVMSKNZ_B : LASX_2R<0b0111011010011100011000>, ++ LASX_2R_DESC_BASE<"xvmsknz.b", int_loongarch_lasx_xvmsknz_b, LASX256BOpnd>; ++ ++ ++def XVSETEQZ_V : LASX_SET<0b0111011010011100100110>, ++ LASX_SET_DESC_BASE<"xvseteqz.v", LASX256BOpnd>; ++ ++def XVSETNEZ_V : LASX_SET<0b0111011010011100100111>, ++ LASX_SET_DESC_BASE<"xvsetnez.v", LASX256BOpnd>; ++ ++ ++def XVSETANYEQZ_B : LASX_SET<0b0111011010011100101000>, ++ LASX_SET_DESC_BASE<"xvsetanyeqz.b", LASX256BOpnd>; ++ ++def XVSETANYEQZ_H : LASX_SET<0b0111011010011100101001>, ++ LASX_SET_DESC_BASE<"xvsetanyeqz.h", LASX256HOpnd>; ++ ++def XVSETANYEQZ_W : LASX_SET<0b0111011010011100101010>, ++ LASX_SET_DESC_BASE<"xvsetanyeqz.w", LASX256WOpnd>; ++ ++def XVSETANYEQZ_D : LASX_SET<0b0111011010011100101011>, ++ LASX_SET_DESC_BASE<"xvsetanyeqz.d", LASX256DOpnd>; ++ ++ ++def XVSETALLNEZ_B : LASX_SET<0b0111011010011100101100>, ++ LASX_SET_DESC_BASE<"xvsetallnez.b", LASX256BOpnd>; ++ ++def XVSETALLNEZ_H : LASX_SET<0b0111011010011100101101>, ++ LASX_SET_DESC_BASE<"xvsetallnez.h", LASX256HOpnd>; ++ ++def XVSETALLNEZ_W : LASX_SET<0b0111011010011100101110>, ++ LASX_SET_DESC_BASE<"xvsetallnez.w", LASX256WOpnd>; ++ ++def XVSETALLNEZ_D : LASX_SET<0b0111011010011100101111>, ++ LASX_SET_DESC_BASE<"xvsetallnez.d", LASX256DOpnd>; ++ ++class LASX_CBRANCH_PSEUDO_DESC_BASE : ++ LoongArchPseudo<(outs GPR32:$dst), ++ (ins RCWS:$xj), ++ [(set GPR32:$dst, (OpNode (TyNode RCWS:$xj)))]> { ++ bit usesCustomInserter = 1; ++} ++ ++def XSNZ_B_PSEUDO : LASX_CBRANCH_PSEUDO_DESC_BASE; ++def XSNZ_H_PSEUDO : LASX_CBRANCH_PSEUDO_DESC_BASE; ++def XSNZ_W_PSEUDO : LASX_CBRANCH_PSEUDO_DESC_BASE; ++def XSNZ_D_PSEUDO : LASX_CBRANCH_PSEUDO_DESC_BASE; ++def XSNZ_V_PSEUDO : LASX_CBRANCH_PSEUDO_DESC_BASE; ++ ++def XSZ_B_PSEUDO : LASX_CBRANCH_PSEUDO_DESC_BASE; ++def XSZ_H_PSEUDO : LASX_CBRANCH_PSEUDO_DESC_BASE; ++def XSZ_W_PSEUDO : LASX_CBRANCH_PSEUDO_DESC_BASE; ++def XSZ_D_PSEUDO : LASX_CBRANCH_PSEUDO_DESC_BASE; ++def XSZ_V_PSEUDO : LASX_CBRANCH_PSEUDO_DESC_BASE; ++ ++ ++def XVFLOGB_S : LASX_2R<0b0111011010011100110001>, ++ LASX_2RF_DESC_BASE<"xvflogb.s", int_loongarch_lasx_xvflogb_s, LASX256WOpnd>; ++ ++def XVFLOGB_D : LASX_2R<0b0111011010011100110010>, ++ LASX_2RF_DESC_BASE<"xvflogb.d", int_loongarch_lasx_xvflogb_d, LASX256DOpnd>; ++ ++ ++def XVFCLASS_S : LASX_2R<0b0111011010011100110101>, ++ LASX_2RF_DESC_BASE<"xvfclass.s", int_loongarch_lasx_xvfclass_s, LASX256WOpnd>; ++ ++def XVFCLASS_D : LASX_2R<0b0111011010011100110110>, ++ LASX_2RF_DESC_BASE<"xvfclass.d", int_loongarch_lasx_xvfclass_d, LASX256DOpnd>; ++ ++ ++def XVFSQRT_S : LASX_2R<0b0111011010011100111001>, ++ LASX_2RF_DESC_BASE<"xvfsqrt.s", fsqrt, LASX256WOpnd>; ++ ++def XVFSQRT_D : LASX_2R<0b0111011010011100111010>, ++ LASX_2RF_DESC_BASE<"xvfsqrt.d", fsqrt, LASX256DOpnd>; ++ ++ ++def XVFRECIP_S : LASX_2R<0b0111011010011100111101>, ++ LASX_2RF_DESC_BASE<"xvfrecip.s", int_loongarch_lasx_xvfrecip_s, LASX256WOpnd>; ++ ++def XVFRECIP_D : LASX_2R<0b0111011010011100111110>, ++ LASX_2RF_DESC_BASE<"xvfrecip.d", int_loongarch_lasx_xvfrecip_d, LASX256DOpnd>; ++ ++def XVFRECIPE_S : LASX_2R<0b0111011010011101000101>, ++ LASX_FRECIPE_DESC_BASE<"xvfrecipe.s", LASX256WOpnd>; ++ ++def XVFRECIPE_D : LASX_2R<0b0111011010011101000110>, ++ LASX_FRECIPE_DESC_BASE<"xvfrecipe.d", LASX256DOpnd>; ++ ++def XVFRSQRT_S : LASX_2R<0b0111011010011101000001>, ++ LASX_2RF_DESC_BASE<"xvfrsqrt.s", int_loongarch_lasx_xvfrsqrt_s, LASX256WOpnd>; ++ ++def XVFRSQRT_D : LASX_2R<0b0111011010011101000010>, ++ LASX_2RF_DESC_BASE<"xvfrsqrt.d", int_loongarch_lasx_xvfrsqrt_d, LASX256DOpnd>; ++ ++def XVFRSQRTE_S : LASX_2R<0b0111011010011101001001>, ++ LASX_FRECIPE_DESC_BASE<"xvfrsqrte.s", LASX256WOpnd>; ++ ++def XVFRSQRTE_D : LASX_2R<0b0111011010011101001010>, ++ LASX_FRECIPE_DESC_BASE<"xvfrsqrte.d", LASX256DOpnd>; ++ ++def XVFRINT_S : LASX_2R<0b0111011010011101001101>, ++ LASX_2RF_DESC_BASE<"xvfrint.s", frint, LASX256WOpnd>; ++ ++def XVFRINT_D : LASX_2R<0b0111011010011101001110>, ++ LASX_2RF_DESC_BASE<"xvfrint.d", frint, LASX256DOpnd>; ++ ++ ++def XVFRINTRM_S : LASX_2R<0b0111011010011101010001>, ++ LASX_2RF_DESC_BASE<"xvfrintrm.s", int_loongarch_lasx_xvfrintrm_s, LASX256WOpnd>; ++ ++def XVFRINTRM_D : LASX_2R<0b0111011010011101010010>, ++ LASX_2RF_DESC_BASE<"xvfrintrm.d", int_loongarch_lasx_xvfrintrm_d, LASX256DOpnd>; ++ ++ ++def XVFRINTRP_S : LASX_2R<0b0111011010011101010101>, ++ LASX_2RF_DESC_BASE<"xvfrintrp.s", int_loongarch_lasx_xvfrintrp_s, LASX256WOpnd>; ++ ++def XVFRINTRP_D : LASX_2R<0b0111011010011101010110>, ++ LASX_2RF_DESC_BASE<"xvfrintrp.d", int_loongarch_lasx_xvfrintrp_d, LASX256DOpnd>; ++ ++ ++def XVFRINTRZ_S : LASX_2R<0b0111011010011101011001>, ++ LASX_2RF_DESC_BASE<"xvfrintrz.s", int_loongarch_lasx_xvfrintrz_s, LASX256WOpnd>; ++ ++def XVFRINTRZ_D : LASX_2R<0b0111011010011101011010>, ++ LASX_2RF_DESC_BASE<"xvfrintrz.d", int_loongarch_lasx_xvfrintrz_d, LASX256DOpnd>; ++ ++ ++def XVFRINTRNE_S : LASX_2R<0b0111011010011101011101>, ++ LASX_2RF_DESC_BASE<"xvfrintrne.s", int_loongarch_lasx_xvfrintrne_s, LASX256WOpnd>; ++ ++def XVFRINTRNE_D : LASX_2R<0b0111011010011101011110>, ++ LASX_2RF_DESC_BASE<"xvfrintrne.d", int_loongarch_lasx_xvfrintrne_d, LASX256DOpnd>; ++ ++ ++def XVFCVTL_S_H : LASX_2R<0b0111011010011101111010>, ++ LASX_2RF_DESC_BASE<"xvfcvtl.s.h", int_loongarch_lasx_xvfcvtl_s_h, LASX256WOpnd, LASX256HOpnd>; ++ ++def XVFCVTH_S_H : LASX_2R<0b0111011010011101111011>, ++ LASX_2RF_DESC_BASE<"xvfcvth.s.h", int_loongarch_lasx_xvfcvth_s_h, LASX256WOpnd, LASX256HOpnd>; ++ ++ ++def XVFCVTL_D_S : LASX_2R<0b0111011010011101111100>, ++ LASX_2RF_DESC_BASE<"xvfcvtl.d.s", int_loongarch_lasx_xvfcvtl_d_s, LASX256DOpnd, LASX256WOpnd>; ++ ++def XVFCVTH_D_S : LASX_2R<0b0111011010011101111101>, ++ LASX_2RF_DESC_BASE<"xvfcvth.d.s", int_loongarch_lasx_xvfcvth_d_s, LASX256DOpnd, LASX256WOpnd>; ++ ++ ++def XVFFINT_S_W : LASX_2R<0b0111011010011110000000>, ++ LASX_2RF_DESC_BASE<"xvffint.s.w", sint_to_fp, LASX256WOpnd>; ++ ++def XVFFINT_S_WU : LASX_2R<0b0111011010011110000001>, ++ LASX_2RF_DESC_BASE<"xvffint.s.wu", uint_to_fp, LASX256WOpnd>; ++ ++ ++def XVFFINT_D_L : LASX_2R<0b0111011010011110000010>, ++ LASX_2RF_DESC_BASE<"xvffint.d.l", sint_to_fp, LASX256DOpnd>; ++ ++def XVFFINT_D_LU : LASX_2R<0b0111011010011110000011>, ++ LASX_2RF_DESC_BASE<"xvffint.d.lu", uint_to_fp, LASX256DOpnd>; ++ ++ ++def XVFFINTL_D_W : LASX_2R<0b0111011010011110000100>, ++ LASX_2RF_DESC_BASE<"xvffintl.d.w", int_loongarch_lasx_xvffintl_d_w, LASX256DOpnd, LASX256WOpnd>; ++ ++def XVFFINTH_D_W : LASX_2R<0b0111011010011110000101>, ++ LASX_2RF_DESC_BASE<"xvffinth.d.w", int_loongarch_lasx_xvffinth_d_w, LASX256DOpnd, LASX256WOpnd>; ++ ++ ++def XVFTINT_W_S : LASX_2R<0b0111011010011110001100>, ++ LASX_2RF_DESC_BASE<"xvftint.w.s", int_loongarch_lasx_xvftint_w_s, LASX256WOpnd>; ++ ++def XVFTINT_L_D : LASX_2R<0b0111011010011110001101>, ++ LASX_2RF_DESC_BASE<"xvftint.l.d", int_loongarch_lasx_xvftint_l_d, LASX256DOpnd>; ++ ++ ++def XVFTINTRM_W_S : LASX_2R<0b0111011010011110001110>, ++ LASX_2RF_DESC_BASE<"xvftintrm.w.s", int_loongarch_lasx_xvftintrm_w_s, LASX256WOpnd>; ++ ++def XVFTINTRM_L_D : LASX_2R<0b0111011010011110001111>, ++ LASX_2RF_DESC_BASE<"xvftintrm.l.d", int_loongarch_lasx_xvftintrm_l_d, LASX256DOpnd>; ++ ++ ++def XVFTINTRP_W_S : LASX_2R<0b0111011010011110010000>, ++ LASX_2RF_DESC_BASE<"xvftintrp.w.s", int_loongarch_lasx_xvftintrp_w_s, LASX256WOpnd>; ++ ++def XVFTINTRP_L_D : LASX_2R<0b0111011010011110010001>, ++ LASX_2RF_DESC_BASE<"xvftintrp.l.d", int_loongarch_lasx_xvftintrp_l_d, LASX256DOpnd>; ++ ++ ++def XVFTINTRZ_W_S : LASX_2R<0b0111011010011110010010>, ++ LASX_2RF_DESC_BASE<"xvftintrz.w.s", fp_to_sint, LASX256WOpnd>; ++ ++def XVFTINTRZ_L_D : LASX_2R<0b0111011010011110010011>, ++ LASX_2RF_DESC_BASE<"xvftintrz.l.d", fp_to_sint, LASX256DOpnd>; ++ ++ ++def XVFTINTRNE_W_S : LASX_2R<0b0111011010011110010100>, ++ LASX_2RF_DESC_BASE<"xvftintrne.w.s", int_loongarch_lasx_xvftintrne_w_s, LASX256WOpnd>; ++ ++def XVFTINTRNE_L_D : LASX_2R<0b0111011010011110010101>, ++ LASX_2RF_DESC_BASE<"xvftintrne.l.d", int_loongarch_lasx_xvftintrne_l_d, LASX256DOpnd>; ++ ++ ++def XVFTINT_WU_S : LASX_2R<0b0111011010011110010110>, ++ LASX_2RF_DESC_BASE<"xvftint.wu.s", int_loongarch_lasx_xvftint_wu_s, LASX256WOpnd>; ++ ++def XVFTINT_LU_D : LASX_2R<0b0111011010011110010111>, ++ LASX_2RF_DESC_BASE<"xvftint.lu.d", int_loongarch_lasx_xvftint_lu_d, LASX256DOpnd>; ++ ++ ++def XVFTINTRZ_WU_S : LASX_2R<0b0111011010011110011100>, ++ LASX_2RF_DESC_BASE<"xvftintrz.wu.s", fp_to_uint, LASX256WOpnd>; ++ ++def XVFTINTRZ_LU_D : LASX_2R<0b0111011010011110011101>, ++ LASX_2RF_DESC_BASE<"xvftintrz.lu.d", fp_to_uint, LASX256DOpnd>; ++ ++ ++def XVFTINTL_L_S : LASX_2R<0b0111011010011110100000>, ++ LASX_2RF_DESC_BASE<"xvftintl.l.s", int_loongarch_lasx_xvftintl_l_s, LASX256DOpnd, LASX256WOpnd>; ++ ++def XVFTINTH_L_S : LASX_2R<0b0111011010011110100001>, ++ LASX_2RF_DESC_BASE<"xvftinth.l.s", int_loongarch_lasx_xvftinth_l_s, LASX256DOpnd, LASX256WOpnd>; ++ ++ ++def XVFTINTRML_L_S : LASX_2R<0b0111011010011110100010>, ++ LASX_2RF_DESC_BASE<"xvftintrml.l.s", int_loongarch_lasx_xvftintrml_l_s, LASX256DOpnd, LASX256WOpnd>; ++ ++def XVFTINTRMH_L_S : LASX_2R<0b0111011010011110100011>, ++ LASX_2RF_DESC_BASE<"xvftintrmh.l.s", int_loongarch_lasx_xvftintrmh_l_s, LASX256DOpnd, LASX256WOpnd>; ++ ++ ++def XVFTINTRPL_L_S : LASX_2R<0b0111011010011110100100>, ++ LASX_2RF_DESC_BASE<"xvftintrpl.l.s", int_loongarch_lasx_xvftintrpl_l_s, LASX256DOpnd, LASX256WOpnd>; ++ ++def XVFTINTRPH_L_S : LASX_2R<0b0111011010011110100101>, ++ LASX_2RF_DESC_BASE<"xvftintrph.l.s", int_loongarch_lasx_xvftintrph_l_s, LASX256DOpnd, LASX256WOpnd>; ++ ++ ++def XVFTINTRZL_L_S : LASX_2R<0b0111011010011110100110>, ++ LASX_2RF_DESC_BASE<"xvftintrzl.l.s", int_loongarch_lasx_xvftintrzl_l_s, LASX256DOpnd, LASX256WOpnd>; ++ ++def XVFTINTRZH_L_S : LASX_2R<0b0111011010011110100111>, ++ LASX_2RF_DESC_BASE<"xvftintrzh.l.s", int_loongarch_lasx_xvftintrzh_l_s, LASX256DOpnd, LASX256WOpnd>; ++ ++ ++def XVFTINTRNEL_L_S : LASX_2R<0b0111011010011110101000>, ++ LASX_2RF_DESC_BASE<"xvftintrnel.l.s", int_loongarch_lasx_xvftintrnel_l_s, LASX256DOpnd, LASX256WOpnd>; ++ ++def XVFTINTRNEH_L_S : LASX_2R<0b0111011010011110101001>, ++ LASX_2RF_DESC_BASE<"xvftintrneh.l.s", int_loongarch_lasx_xvftintrneh_l_s, LASX256DOpnd, LASX256WOpnd>; ++ ++ ++def XVEXTH_H_B : LASX_2R<0b0111011010011110111000>, ++ LASX_2R_DESC_BASE<"xvexth.h.b", int_loongarch_lasx_xvexth_h_b, LASX256HOpnd, LASX256BOpnd>; ++ ++def XVEXTH_W_H : LASX_2R<0b0111011010011110111001>, ++ LASX_2R_DESC_BASE<"xvexth.w.h", int_loongarch_lasx_xvexth_w_h, LASX256WOpnd, LASX256HOpnd>; ++ ++def XVEXTH_D_W : LASX_2R<0b0111011010011110111010>, ++ LASX_2R_DESC_BASE<"xvexth.d.w", int_loongarch_lasx_xvexth_d_w, LASX256DOpnd, LASX256WOpnd> ; ++ ++def XVEXTH_Q_D : LASX_2R<0b0111011010011110111011>, ++ LASX_2R_DESC_BASE<"xvexth.q.d", int_loongarch_lasx_xvexth_q_d, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVEXTH_HU_BU : LASX_2R<0b0111011010011110111100>, ++ LASX_2R_DESC_BASE<"xvexth.hu.bu", int_loongarch_lasx_xvexth_hu_bu, LASX256HOpnd, LASX256BOpnd>; ++ ++def XVEXTH_WU_HU : LASX_2R<0b0111011010011110111101>, ++ LASX_2R_DESC_BASE<"xvexth.wu.hu", int_loongarch_lasx_xvexth_wu_hu, LASX256WOpnd, LASX256HOpnd>; ++ ++def XVEXTH_DU_WU : LASX_2R<0b0111011010011110111110>, ++ LASX_2R_DESC_BASE<"xvexth.du.wu", int_loongarch_lasx_xvexth_du_wu, LASX256DOpnd, LASX256WOpnd> ; ++ ++def XVEXTH_QU_DU : LASX_2R<0b0111011010011110111111>, ++ LASX_2R_DESC_BASE<"xvexth.qu.du", int_loongarch_lasx_xvexth_qu_du, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVREPLGR2VR_B : LASX_2R_1GP<0b0111011010011111000000>, ++ LASX_2R_REPL_DESC_BASE<"xvreplgr2vr.b", v32i8, xvsplati8, LASX256BOpnd, GPR32Opnd>; ++ ++def XVREPLGR2VR_H : LASX_2R_1GP<0b0111011010011111000001>, ++ LASX_2R_REPL_DESC_BASE<"xvreplgr2vr.h", v16i16, xvsplati16, LASX256HOpnd, GPR32Opnd>; ++ ++def XVREPLGR2VR_W : LASX_2R_1GP<0b0111011010011111000010>, ++ LASX_2R_REPL_DESC_BASE<"xvreplgr2vr.w", v8i32, xvsplati32, LASX256WOpnd, GPR32Opnd>; ++ ++def XVREPLGR2VR_D : LASX_2R_1GP<0b0111011010011111000011>, ++ LASX_2R_REPL_DESC_BASE<"xvreplgr2vr.d", v4i64, xvsplati64, LASX256DOpnd, GPR64Opnd>; ++ ++ ++def VEXT2XV_H_B : LASX_2R<0b0111011010011111000100>, ++ LASX_XVEXTEND_DESC_BASE<"vext2xv.h.b", int_loongarch_lasx_vext2xv_h_b, v32i8, v16i16, LASX256BOpnd, LASX256HOpnd>; ++ ++def VEXT2XV_W_B : LASX_2R<0b0111011010011111000101>, ++ LASX_XVEXTEND_DESC_BASE<"vext2xv.w.b", int_loongarch_lasx_vext2xv_w_b, v32i8, v8i32, LASX256BOpnd, LASX256WOpnd>; ++ ++def VEXT2XV_D_B : LASX_2R<0b0111011010011111000110>, ++ LASX_XVEXTEND_DESC_BASE<"vext2xv.d.b", int_loongarch_lasx_vext2xv_d_b, v32i8, v4i64, LASX256BOpnd, LASX256DOpnd> ; ++ ++def VEXT2XV_W_H : LASX_2R<0b0111011010011111000111>, ++ LASX_XVEXTEND_DESC_BASE<"vext2xv.w.h", int_loongarch_lasx_vext2xv_w_h, v16i16, v8i32, LASX256HOpnd, LASX256WOpnd>; ++ ++def VEXT2XV_D_H : LASX_2R<0b0111011010011111001000>, ++ LASX_XVEXTEND_DESC_BASE<"vext2xv.d.h", int_loongarch_lasx_vext2xv_d_h, v16i16, v4i64, LASX256HOpnd, LASX256DOpnd> ; ++ ++def VEXT2XV_D_W : LASX_2R<0b0111011010011111001001>, ++ LASX_XVEXTEND_DESC_BASE<"vext2xv.d.w", int_loongarch_lasx_vext2xv_d_w, v8i32, v4i64, LASX256WOpnd, LASX256DOpnd>; ++ ++ ++def VEXT2XV_HU_BU : LASX_2R<0b0111011010011111001010>, ++ LASX_XVEXTEND_DESC_BASE<"vext2xv.hu.bu", int_loongarch_lasx_vext2xv_hu_bu, v32i8, v16i16, LASX256BOpnd, LASX256HOpnd>; ++ ++def VEXT2XV_WU_BU : LASX_2R<0b0111011010011111001011>, ++ LASX_XVEXTEND_DESC_BASE<"vext2xv.wu.bu", int_loongarch_lasx_vext2xv_wu_bu, v32i8, v8i32, LASX256BOpnd, LASX256WOpnd>; ++ ++def VEXT2XV_DU_BU : LASX_2R<0b0111011010011111001100>, ++ LASX_XVEXTEND_DESC_BASE<"vext2xv.du.bu", int_loongarch_lasx_vext2xv_du_bu, v32i8, v4i64, LASX256BOpnd, LASX256DOpnd> ; ++ ++def VEXT2XV_WU_HU : LASX_2R<0b0111011010011111001101>, ++ LASX_XVEXTEND_DESC_BASE<"vext2xv.wu.hu", int_loongarch_lasx_vext2xv_wu_hu, v16i16, v8i32, LASX256HOpnd, LASX256WOpnd>; ++ ++def VEXT2XV_DU_HU : LASX_2R<0b0111011010011111001110>, ++ LASX_XVEXTEND_DESC_BASE<"vext2xv.du.hu", int_loongarch_lasx_vext2xv_du_hu, v16i16, v4i64, LASX256HOpnd, LASX256DOpnd> ; ++ ++def VEXT2XV_DU_WU : LASX_2R<0b0111011010011111001111>, ++ LASX_XVEXTEND_DESC_BASE<"vext2xv.du.wu", int_loongarch_lasx_vext2xv_du_wu, v8i32, v4i64, LASX256WOpnd, LASX256DOpnd>; ++ ++ ++def XVHSELI_D : LASX_I5_U<0b01110110100111111>, ++ LASX_U5N_DESC_BASE<"xvhseli.d", LASX256DOpnd>; ++ ++ ++def XVROTRI_B : LASX_I3_U<0b0111011010100000001>, ++ LASX_RORI_U3_DESC_BASE_Intrinsic<"xvrotri.b", int_loongarch_lasx_xvrotri_b, uimm3, immZExt3, LASX256BOpnd>; ++ ++def XVROTRI_H : LASX_I4_U<0b011101101010000001>, ++ LASX_RORI_U4_DESC_BASE_Intrinsic<"xvrotri.h", int_loongarch_lasx_xvrotri_h, uimm4, immZExt4, LASX256HOpnd>; ++ ++def XVROTRI_W : LASX_I5_U<0b01110110101000001>, ++ LASX_RORI_U5_DESC_BASE_Intrinsic<"xvrotri.w", int_loongarch_lasx_xvrotri_w, uimm5, immZExt5, LASX256WOpnd>; ++ ++def XVROTRI_D : LASX_I6_U<0b0111011010100001>, ++ LASX_RORI_U6_DESC_BASE_Intrinsic<"xvrotri.d", int_loongarch_lasx_xvrotri_d, uimm6, immZExt6, LASX256DOpnd>; ++ ++ ++def XVSRLRI_B : LASX_I3_U<0b0111011010100100001>, ++ LASX_BIT_3_DESC_BASE<"xvsrlri.b", int_loongarch_lasx_xvsrlri_b, uimm3, immZExt3, LASX256BOpnd>; ++ ++def XVSRLRI_H : LASX_I4_U<0b011101101010010001>, ++ LASX_BIT_4_DESC_BASE<"xvsrlri.h", int_loongarch_lasx_xvsrlri_h, uimm4, immZExt4, LASX256HOpnd>; ++ ++def XVSRLRI_W : LASX_I5_U<0b01110110101001001>, ++ LASX_BIT_5_DESC_BASE<"xvsrlri.w", int_loongarch_lasx_xvsrlri_w, uimm5, immZExt5, LASX256WOpnd>; ++ ++def XVSRLRI_D : LASX_I6_U<0b0111011010100101>, ++ LASX_BIT_6_DESC_BASE<"xvsrlri.d", int_loongarch_lasx_xvsrlri_d, uimm6, immZExt6, LASX256DOpnd>; ++ ++ ++def XVSRARI_B : LASX_I3_U<0b0111011010101000001>, ++ LASX_BIT_3_DESC_BASE<"xvsrari.b", int_loongarch_lasx_xvsrari_b, uimm3, immZExt3, LASX256BOpnd>; ++ ++def XVSRARI_H : LASX_I4_U<0b011101101010100001>, ++ LASX_BIT_4_DESC_BASE<"xvsrari.h", int_loongarch_lasx_xvsrari_h, uimm4, immZExt4, LASX256HOpnd>; ++ ++def XVSRARI_W : LASX_I5_U<0b01110110101010001>, ++ LASX_BIT_5_DESC_BASE<"xvsrari.w", int_loongarch_lasx_xvsrari_w, uimm5, immZExt5, LASX256WOpnd>; ++ ++def XVSRARI_D : LASX_I6_U<0b0111011010101001>, ++ LASX_BIT_6_DESC_BASE<"xvsrari.d", int_loongarch_lasx_xvsrari_d, uimm6, immZExt6, LASX256DOpnd>; ++ ++ ++def XVINSGR2VR_W : LASX_I3_R_U<0b0111011011101011110>, ++ LASX_INSERT_U3_DESC_BASE<"xvinsgr2vr.w", v8i32, uimm3_ptr, immZExt3Ptr, LASX256WOpnd, GPR32Opnd>; ++ ++def XVINSGR2VR_D : LASX_I2_R_U<0b01110110111010111110>, ++ LASX_INSERT_U2_DESC_BASE<"xvinsgr2vr.d", v4i64, uimm2_ptr, immZExt2Ptr, LASX256DOpnd, GPR64Opnd>; ++ ++ ++def XVPICKVE2GR_W : LASX_ELM_COPY_U3<0b0111011011101111110>, ++ LASX_COPY_U3_DESC_BASE<"xvpickve2gr.w", vextract_sext_i32, v8i32, uimm3_ptr, immZExt3Ptr, GPR32Opnd, LASX256WOpnd>; ++ ++def XVPICKVE2GR_D : LASX_ELM_COPY_U2<0b01110110111011111110>, ++ LASX_COPY_U2_DESC_BASE<"xvpickve2gr.d", vextract_sext_i64, v4i64, uimm2_ptr, immZExt2Ptr, GPR64Opnd, LASX256DOpnd>; ++ ++ ++def XVPICKVE2GR_WU : LASX_ELM_COPY_U3<0b0111011011110011110>, ++ LASX_COPY_U3_DESC_BASE<"xvpickve2gr.wu", vextract_zext_i32, v8i32, uimm3_ptr, immZExt3Ptr, GPR32Opnd, LASX256WOpnd>; ++ ++def XVPICKVE2GR_DU : LASX_ELM_COPY_U2<0b01110110111100111110>, ++ LASX_COPY_U2_DESC_BASE<"xvpickve2gr.du", vextract_zext_i64, v4i64, uimm2_ptr, immZExt2Ptr, GPR64Opnd, LASX256DOpnd>; ++ ++ ++def XVREPL128VEI_B : LASX_I4_U<0b011101101111011110>, ++ LASX_ELM_U4_VREPLVE_DESC_BASE_Intrinsic<"xvrepl128vei.b", int_loongarch_lasx_xvrepl128vei_b, LASX256BOpnd>; ++ ++def XVREPL128VEI_H : LASX_I3_U<0b0111011011110111110>, ++ LASX_ELM_U3_VREPLVE_DESC_BASE_Intrinsic<"xvrepl128vei.h", int_loongarch_lasx_xvrepl128vei_h, LASX256HOpnd>; ++ ++def XVREPL128VEI_W : LASX_I2_U<0b01110110111101111110>, ++ LASX_ELM_U2_VREPLVE_DESC_BASE_Intrinsic<"xvrepl128vei.w", int_loongarch_lasx_xvrepl128vei_w, LASX256WOpnd>; ++ ++def XVREPL128VEI_D : LASX_I1_U<0b011101101111011111110>, ++ LASX_ELM_U1_VREPLVE_DESC_BASE_Intrinsic<"xvrepl128vei.d", int_loongarch_lasx_xvrepl128vei_d, LASX256DOpnd>; ++ ++ ++def XVINSVE0_W : LASX_I3_U<0b0111011011111111110>, ++ LASX_BIT_3_4O_DESC_BASE<"xvinsve0.w", int_loongarch_lasx_xvinsve0_w, uimm3, immZExt3, LASX256WOpnd>; ++ ++def XVINSVE0_D : LASX_I2_U<0b01110110111111111110>, ++ LASX_BIT_2_4O_DESC_BASE<"xvinsve0.d", int_loongarch_lasx_xvinsve0_d, uimm2, immZExt2, LASX256DOpnd>; ++ ++ ++def XVPICKVE_W : LASX_I3_U<0b0111011100000011110>, ++ LASX_BIT_3_4ON<"xvpickve.w", uimm3, immZExt3, LASX256WOpnd>; ++ ++def XVPICKVE_D : LASX_I2_U<0b01110111000000111110>, ++ LASX_BIT_2_4ON<"xvpickve.d", uimm2, immZExt2, LASX256DOpnd>; ++ ++ ++def XVREPLVE0_B : LASX_2R<0b0111011100000111000000>, ++ LASX_XVBROADCAST_DESC_BASE<"xvreplve0.b", int_loongarch_lasx_xvreplve0_b, v32i8, LASX256BOpnd>; ++ ++def XVREPLVE0_H : LASX_2R<0b0111011100000111100000>, ++ LASX_XVBROADCAST_DESC_BASE<"xvreplve0.h", int_loongarch_lasx_xvreplve0_h, v16i16, LASX256HOpnd>; ++ ++def XVREPLVE0_W : LASX_2R<0b0111011100000111110000>, ++ LASX_XVBROADCAST_DESC_BASE<"xvreplve0.w", int_loongarch_lasx_xvreplve0_w, v8i32, LASX256WOpnd> ; ++ ++def XVREPLVE0_D : LASX_2R<0b0111011100000111111000>, ++ LASX_XVBROADCAST_DESC_BASE<"xvreplve0.d", null_frag, v4i64, LASX256DOpnd>; ++ ++def XVREPLVE0_Q : LASX_2R<0b0111011100000111111100>, ++ LASX_XVBROADCAST_DESC_BASE<"xvreplve0.q", int_loongarch_lasx_xvreplve0_q, v32i8, LASX256BOpnd>; ++ ++ ++def XVSLLWIL_H_B : LASX_I3_U<0b0111011100001000001>, ++ LASX_2R_U3_DESC_BASE<"xvsllwil.h.b", int_loongarch_lasx_xvsllwil_h_b, LASX256HOpnd, LASX256BOpnd>; ++ ++def XVSLLWIL_W_H : LASX_I4_U<0b011101110000100001>, ++ LASX_2R_U4_DESC_BASE<"xvsllwil.w.h", int_loongarch_lasx_xvsllwil_w_h, LASX256WOpnd, LASX256HOpnd>; ++ ++def XVSLLWIL_D_W : LASX_I5_U<0b01110111000010001>, ++ LASX_2R_U5_DESC_BASE<"xvsllwil.d.w", int_loongarch_lasx_xvsllwil_d_w, LASX256DOpnd, LASX256WOpnd> ; ++ ++ ++def XVEXTL_Q_D : LASX_2R<0b0111011100001001000000>, ++ LASX_2R_DESC_BASE<"xvextl.q.d", int_loongarch_lasx_xvextl_q_d, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVSLLWIL_HU_BU : LASX_I3_U<0b0111011100001100001>, ++ LASX_2R_U3_DESC_BASE<"xvsllwil.hu.bu", int_loongarch_lasx_xvsllwil_hu_bu, LASX256HOpnd, LASX256BOpnd>; ++ ++def XVSLLWIL_WU_HU : LASX_I4_U<0b011101110000110001>, ++ LASX_2R_U4_DESC_BASE<"xvsllwil.wu.hu", int_loongarch_lasx_xvsllwil_wu_hu, LASX256WOpnd, LASX256HOpnd>; ++ ++def XVSLLWIL_DU_WU : LASX_I5_U<0b01110111000011001>, ++ LASX_2R_U5_DESC_BASE<"xvsllwil.du.wu", int_loongarch_lasx_xvsllwil_du_wu, LASX256DOpnd, LASX256WOpnd> ; ++ ++ ++def XVEXTL_QU_DU : LASX_2R<0b0111011100001101000000>, ++ LASX_2R_DESC_BASE<"xvextl.qu.du", int_loongarch_lasx_xvextl_qu_du, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVBITCLRI_B : LASX_I3_U<0b0111011100010000001>, ++ LASX_2R_U3_DESC_BASE<"xvbitclri.b", int_loongarch_lasx_xvbitclri_b, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVBITCLRI_H : LASX_I4_U<0b011101110001000001>, ++ LASX_2R_U4_DESC_BASE<"xvbitclri.h", int_loongarch_lasx_xvbitclri_h, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVBITCLRI_W : LASX_I5_U<0b01110111000100001>, ++ LASX_2R_U5_DESC_BASE<"xvbitclri.w", int_loongarch_lasx_xvbitclri_w, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVBITCLRI_D : LASX_I6_U<0b0111011100010001>, ++ LASX_2R_U6_DESC_BASE<"xvbitclri.d", int_loongarch_lasx_xvbitclri_d, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVBITSETI_B : LASX_I3_U<0b0111011100010100001>, ++ LASX_2R_U3_DESC_BASE<"xvbitseti.b", int_loongarch_lasx_xvbitseti_b, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVBITSETI_H : LASX_I4_U<0b011101110001010001>, ++ LASX_2R_U4_DESC_BASE<"xvbitseti.h", int_loongarch_lasx_xvbitseti_h, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVBITSETI_W : LASX_I5_U<0b01110111000101001>, ++ LASX_2R_U5_DESC_BASE<"xvbitseti.w", int_loongarch_lasx_xvbitseti_w, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVBITSETI_D : LASX_I6_U<0b0111011100010101>, ++ LASX_2R_U6_DESC_BASE<"xvbitseti.d", int_loongarch_lasx_xvbitseti_d, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVBITREVI_B : LASX_I3_U<0b0111011100011000001>, ++ LASX_2R_U3_DESC_BASE<"xvbitrevi.b", int_loongarch_lasx_xvbitrevi_b, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVBITREVI_H : LASX_I4_U<0b011101110001100001>, ++ LASX_2R_U4_DESC_BASE<"xvbitrevi.h", int_loongarch_lasx_xvbitrevi_h, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVBITREVI_W : LASX_I5_U<0b01110111000110001>, ++ LASX_2R_U5_DESC_BASE<"xvbitrevi.w", int_loongarch_lasx_xvbitrevi_w, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVBITREVI_D : LASX_I6_U<0b0111011100011001>, ++ LASX_2R_U6_DESC_BASE<"xvbitrevi.d", int_loongarch_lasx_xvbitrevi_d, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVSAT_B : LASX_I3_U<0b0111011100100100001>, ++ LASX_BIT_3_DESC_BASE<"xvsat.b", int_loongarch_lasx_xvsat_b, uimm3, immZExt3, LASX256BOpnd>; ++ ++def XVSAT_H : LASX_I4_U<0b011101110010010001>, ++ LASX_BIT_4_DESC_BASE<"xvsat.h", int_loongarch_lasx_xvsat_h, uimm4, immZExt4, LASX256HOpnd>; ++ ++def XVSAT_W : LASX_I5_U<0b01110111001001001>, ++ LASX_BIT_5_DESC_BASE<"xvsat.w", int_loongarch_lasx_xvsat_w, uimm5, immZExt5, LASX256WOpnd>; ++ ++def XVSAT_D : LASX_I6_U<0b0111011100100101>, ++ LASX_BIT_6_DESC_BASE<"xvsat.d", int_loongarch_lasx_xvsat_d, uimm6, immZExt6, LASX256DOpnd>; ++ ++ ++def XVSAT_BU : LASX_I3_U<0b0111011100101000001>, ++ LASX_BIT_3_DESC_BASE<"xvsat.bu", int_loongarch_lasx_xvsat_bu, uimm3, immZExt3, LASX256BOpnd>; ++ ++def XVSAT_HU : LASX_I4_U<0b011101110010100001>, ++ LASX_BIT_4_DESC_BASE<"xvsat.hu", int_loongarch_lasx_xvsat_hu, uimm4, immZExt4, LASX256HOpnd>; ++ ++def XVSAT_WU : LASX_I5_U<0b01110111001010001>, ++ LASX_BIT_5_DESC_BASE<"xvsat.wu", int_loongarch_lasx_xvsat_wu, uimm5, immZExt5, LASX256WOpnd>; ++ ++def XVSAT_DU : LASX_I6_U<0b0111011100101001>, ++ LASX_BIT_6_DESC_BASE<"xvsat.du", int_loongarch_lasx_xvsat_du, uimm6, immZExt6, LASX256DOpnd>; ++ ++ ++def XVSLLI_B : LASX_I3_U<0b0111011100101100001>, ++ LASX_BIT_U3_VREPLVE_DESC_BASE_Intrinsic<"xvslli.b", int_loongarch_lasx_xvslli_b, uimm3, immZExt3, LASX256BOpnd>; ++ ++def XVSLLI_H : LASX_I4_U<0b011101110010110001>, ++ LASX_BIT_U4_VREPLVE_DESC_BASE_Intrinsic<"xvslli.h", int_loongarch_lasx_xvslli_h, uimm4, immZExt4, LASX256HOpnd>; ++ ++def XVSLLI_W : LASX_I5_U<0b01110111001011001>, ++ LASX_BIT_U5_VREPLVE_DESC_BASE_Intrinsic<"xvslli.w", int_loongarch_lasx_xvslli_w, uimm5, immZExt5, LASX256WOpnd>; ++ ++def XVSLLI_D : LASX_I6_U<0b0111011100101101>, ++ LASX_BIT_U6_VREPLVE_DESC_BASE_Intrinsic<"xvslli.d", int_loongarch_lasx_xvslli_d, uimm6, immZExt6, LASX256DOpnd>; ++ ++ ++def XVSRLI_B : LASX_I3_U<0b0111011100110000001>, ++ LASX_BIT_U3_VREPLVE_DESC_BASE_Intrinsic<"xvsrli.b", int_loongarch_lasx_xvsrli_b, uimm3, immZExt3, LASX256BOpnd>; ++ ++def XVSRLI_H : LASX_I4_U<0b011101110011000001>, ++ LASX_BIT_U4_VREPLVE_DESC_BASE_Intrinsic<"xvsrli.h", int_loongarch_lasx_xvsrli_h, uimm4, immZExt4, LASX256HOpnd>; ++ ++def XVSRLI_W : LASX_I5_U<0b01110111001100001>, ++ LASX_BIT_U5_VREPLVE_DESC_BASE_Intrinsic<"xvsrli.w", int_loongarch_lasx_xvsrli_w, uimm5, immZExt5, LASX256WOpnd>; ++ ++def XVSRLI_D : LASX_I6_U<0b0111011100110001>, ++ LASX_BIT_U6_VREPLVE_DESC_BASE_Intrinsic<"xvsrli.d", int_loongarch_lasx_xvsrli_d, uimm6, immZExt6, LASX256DOpnd>; ++ ++ ++def XVSRAI_B : LASX_I3_U<0b0111011100110100001>, ++ LASX_BIT_U3_VREPLVE_DESC_BASE_Intrinsic<"xvsrai.b", int_loongarch_lasx_xvsrai_b, uimm3, immZExt3, LASX256BOpnd>; ++ ++def XVSRAI_H : LASX_I4_U<0b011101110011010001>, ++ LASX_BIT_U4_VREPLVE_DESC_BASE_Intrinsic<"xvsrai.h", int_loongarch_lasx_xvsrai_h, uimm4, immZExt4, LASX256HOpnd>; ++ ++def XVSRAI_W : LASX_I5_U<0b01110111001101001>, ++ LASX_BIT_U5_VREPLVE_DESC_BASE_Intrinsic<"xvsrai.w", int_loongarch_lasx_xvsrai_w, uimm5, immZExt5, LASX256WOpnd>; ++ ++def XVSRAI_D : LASX_I6_U<0b0111011100110101>, ++ LASX_BIT_U6_VREPLVE_DESC_BASE_Intrinsic<"xvsrai.d", int_loongarch_lasx_xvsrai_d, uimm6, immZExt6, LASX256DOpnd>; ++ ++ ++def XVSRLNI_B_H : LASX_I4_U<0b011101110100000001>, ++ LASX_U4_DESC_BASE<"xvsrlni.b.h", int_loongarch_lasx_xvsrlni_b_h, uimm4, immZExt4, LASX256BOpnd>; ++ ++def XVSRLNI_H_W : LASX_I5_U<0b01110111010000001>, ++ LASX_N4_U5_DESC_BASE<"xvsrlni.h.w", int_loongarch_lasx_xvsrlni_h_w, uimm5, immZExt5, LASX256HOpnd>; ++ ++def XVSRLNI_W_D : LASX_I6_U<0b0111011101000001>, ++ LASX_U6_DESC_BASE<"xvsrlni.w.d", int_loongarch_lasx_xvsrlni_w_d, uimm6, immZExt6, LASX256WOpnd>; ++ ++def XVSRLNI_D_Q : LASX_I7_U<0b011101110100001>, ++ LASX_D_DESC_BASE<"xvsrlni.d.q", int_loongarch_lasx_xvsrlni_d_q, LASX256DOpnd>; ++ ++ ++def XVSRLRNI_B_H : LASX_I4_U<0b011101110100010001>, ++ LASX_U4_DESC_BASE<"xvsrlrni.b.h", int_loongarch_lasx_xvsrlrni_b_h, uimm4, immZExt4, LASX256BOpnd>; ++ ++def XVSRLRNI_H_W : LASX_I5_U<0b01110111010001001>, ++ LASX_N4_U5_DESC_BASE<"xvsrlrni.h.w", int_loongarch_lasx_xvsrlrni_h_w, uimm5, immZExt5, LASX256HOpnd>; ++ ++def XVSRLRNI_W_D : LASX_I6_U<0b0111011101000101>, ++ LASX_U6_DESC_BASE<"xvsrlrni.w.d", int_loongarch_lasx_xvsrlrni_w_d, uimm6, immZExt6, LASX256WOpnd>; ++ ++def XVSRLRNI_D_Q : LASX_I7_U<0b011101110100011>, ++ LASX_D_DESC_BASE<"xvsrlrni.d.q", int_loongarch_lasx_xvsrlrni_d_q, LASX256DOpnd>; ++ ++ ++def XVSSRLNI_B_H : LASX_I4_U<0b011101110100100001>, ++ LASX_U4_DESC_BASE<"xvssrlni.b.h", int_loongarch_lasx_xvssrlni_b_h, uimm4, immZExt4, LASX256BOpnd>; ++ ++def XVSSRLNI_H_W : LASX_I5_U<0b01110111010010001>, ++ LASX_N4_U5_DESC_BASE<"xvssrlni.h.w", int_loongarch_lasx_xvssrlni_h_w, uimm5, immZExt5, LASX256HOpnd>; ++ ++def XVSSRLNI_W_D : LASX_I6_U<0b0111011101001001>, ++ LASX_U6_DESC_BASE<"xvssrlni.w.d", int_loongarch_lasx_xvssrlni_w_d, uimm6, immZExt6, LASX256WOpnd>; ++ ++def XVSSRLNI_D_Q : LASX_I7_U<0b011101110100101>, ++ LASX_D_DESC_BASE<"xvssrlni.d.q", int_loongarch_lasx_xvssrlni_d_q, LASX256DOpnd>; ++ ++ ++def XVSSRLNI_BU_H : LASX_I4_U<0b011101110100110001>, ++ LASX_U4_DESC_BASE<"xvssrlni.bu.h", int_loongarch_lasx_xvssrlni_bu_h, uimm4, immZExt4, LASX256BOpnd>; ++ ++def XVSSRLNI_HU_W : LASX_I5_U<0b01110111010011001>, ++ LASX_N4_U5_DESC_BASE<"xvssrlni.hu.w", int_loongarch_lasx_xvssrlni_hu_w, uimm5, immZExt5, LASX256HOpnd>; ++ ++def XVSSRLNI_WU_D : LASX_I6_U<0b0111011101001101>, ++ LASX_U6_DESC_BASE<"xvssrlni.wu.d", int_loongarch_lasx_xvssrlni_wu_d, uimm6, immZExt6, LASX256WOpnd>; ++ ++def XVSSRLNI_DU_Q : LASX_I7_U<0b011101110100111>, ++ LASX_D_DESC_BASE<"xvssrlni.du.q", int_loongarch_lasx_xvssrlni_du_q, LASX256DOpnd>; ++ ++ ++def XVSSRLRNI_B_H : LASX_I4_U<0b011101110101000001>, ++ LASX_2R_3R_U4_DESC_BASE<"xvssrlrni.b.h", int_loongarch_lasx_xvssrlrni_b_h, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVSSRLRNI_H_W : LASX_I5_U<0b01110111010100001>, ++ LASX_2R_3R_U5_DESC_BASE<"xvssrlrni.h.w", int_loongarch_lasx_xvssrlrni_h_w, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVSSRLRNI_W_D : LASX_I6_U<0b0111011101010001>, ++ LASX_2R_3R_U6_DESC_BASE<"xvssrlrni.w.d", int_loongarch_lasx_xvssrlrni_w_d, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVSSRLRNI_D_Q : LASX_I7_U<0b011101110101001>, ++ LASX_2R_3R_U7_DESC_BASE<"xvssrlrni.d.q", int_loongarch_lasx_xvssrlrni_d_q, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVSSRLRNI_BU_H : LASX_I4_U<0b011101110101010001>, ++ LASX_U4_DESC_BASE<"xvssrlrni.bu.h", int_loongarch_lasx_xvssrlrni_bu_h, uimm4, immZExt4, LASX256BOpnd>; ++ ++def XVSSRLRNI_HU_W : LASX_I5_U<0b01110111010101001>, ++ LASX_N4_U5_DESC_BASE<"xvssrlrni.hu.w", int_loongarch_lasx_xvssrlrni_hu_w, uimm5, immZExt5, LASX256HOpnd>; ++ ++def XVSSRLRNI_WU_D : LASX_I6_U<0b0111011101010101>, ++ LASX_U6_DESC_BASE<"xvssrlrni.wu.d", int_loongarch_lasx_xvssrlrni_wu_d, uimm6, immZExt6, LASX256WOpnd>; ++ ++def XVSSRLRNI_DU_Q : LASX_I7_U<0b011101110101011>, ++ LASX_D_DESC_BASE<"xvssrlrni.du.q", int_loongarch_lasx_xvssrlrni_du_q, LASX256DOpnd>; ++ ++ ++def XVSRANI_B_H : LASX_I4_U<0b011101110101100001>, ++ LASX_2R_3R_U4_DESC_BASE<"xvsrani.b.h", int_loongarch_lasx_xvsrani_b_h, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVSRANI_H_W : LASX_I5_U<0b01110111010110001>, ++ LASX_2R_3R_U5_DESC_BASE<"xvsrani.h.w", int_loongarch_lasx_xvsrani_h_w, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVSRANI_W_D : LASX_I6_U<0b0111011101011001>, ++ LASX_2R_3R_U6_DESC_BASE<"xvsrani.w.d", int_loongarch_lasx_xvsrani_w_d, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVSRANI_D_Q : LASX_I7_U<0b011101110101101>, ++ LASX_2R_3R_U7_DESC_BASE<"xvsrani.d.q", int_loongarch_lasx_xvsrani_d_q, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVSRARNI_B_H : LASX_I4_U<0b011101110101110001>, ++ LASX_U4_DESC_BASE<"xvsrarni.b.h", int_loongarch_lasx_xvsrarni_b_h, uimm4, immZExt4, LASX256BOpnd>; ++ ++def XVSRARNI_H_W : LASX_I5_U<0b01110111010111001>, ++ LASX_N4_U5_DESC_BASE<"xvsrarni.h.w", int_loongarch_lasx_xvsrarni_h_w, uimm5, immZExt5, LASX256HOpnd>; ++ ++def XVSRARNI_W_D : LASX_I6_U<0b0111011101011101>, ++ LASX_U6_DESC_BASE<"xvsrarni.w.d", int_loongarch_lasx_xvsrarni_w_d, uimm6, immZExt6, LASX256WOpnd>; ++ ++def XVSRARNI_D_Q : LASX_I7_U<0b011101110101111>, ++ LASX_D_DESC_BASE<"xvsrarni.d.q", int_loongarch_lasx_xvsrarni_d_q, LASX256DOpnd>; ++ ++ ++def XVSSRANI_B_H : LASX_I4_U<0b011101110110000001>, ++ LASX_U4_DESC_BASE<"xvssrani.b.h", int_loongarch_lasx_xvssrani_b_h, uimm4, immZExt4, LASX256BOpnd>; ++ ++def XVSSRANI_H_W : LASX_I5_U<0b01110111011000001>, ++ LASX_N4_U5_DESC_BASE<"xvssrani.h.w", int_loongarch_lasx_xvssrani_h_w, uimm5, immZExt5, LASX256HOpnd>; ++ ++def XVSSRANI_W_D : LASX_I6_U<0b0111011101100001>, ++ LASX_U6_DESC_BASE<"xvssrani.w.d", int_loongarch_lasx_xvssrani_w_d, uimm6, immZExt6, LASX256WOpnd>; ++ ++def XVSSRANI_D_Q : LASX_I7_U<0b011101110110001>, ++ LASX_D_DESC_BASE<"xvssrani.d.q", int_loongarch_lasx_xvssrani_d_q, LASX256DOpnd>; ++ ++ ++def XVSSRANI_BU_H : LASX_I4_U<0b011101110110010001>, ++ LASX_U4_DESC_BASE<"xvssrani.bu.h", int_loongarch_lasx_xvssrani_bu_h, uimm4, immZExt4, LASX256BOpnd>; ++ ++def XVSSRANI_HU_W : LASX_I5_U<0b01110111011001001>, ++ LASX_N4_U5_DESC_BASE<"xvssrani.hu.w", int_loongarch_lasx_xvssrani_hu_w, uimm5, immZExt5, LASX256HOpnd>; ++ ++def XVSSRANI_WU_D : LASX_I6_U<0b0111011101100101>, ++ LASX_U6_DESC_BASE<"xvssrani.wu.d", int_loongarch_lasx_xvssrani_wu_d, uimm6, immZExt6, LASX256WOpnd>; ++ ++def XVSSRANI_DU_Q : LASX_I7_U<0b011101110110011>, ++ LASX_D_DESC_BASE<"xvssrani.du.q", int_loongarch_lasx_xvssrani_du_q, LASX256DOpnd>; ++ ++ ++def XVSSRARNI_B_H : LASX_I4_U<0b011101110110100001>, ++ LASX_U4_DESC_BASE<"xvssrarni.b.h", int_loongarch_lasx_xvssrarni_b_h, uimm4, immZExt4, LASX256BOpnd>; ++ ++def XVSSRARNI_H_W : LASX_I5_U<0b01110111011010001>, ++ LASX_N4_U5_DESC_BASE<"xvssrarni.h.w", int_loongarch_lasx_xvssrarni_h_w, uimm5, immZExt5, LASX256HOpnd>; ++ ++def XVSSRARNI_W_D : LASX_I6_U<0b0111011101101001>, ++ LASX_U6_DESC_BASE<"xvssrarni.w.d", int_loongarch_lasx_xvssrarni_w_d, uimm6, immZExt6, LASX256WOpnd>; ++ ++def XVSSRARNI_D_Q : LASX_I7_U<0b011101110110101>, ++ LASX_D_DESC_BASE<"xvssrarni.d.q", int_loongarch_lasx_xvssrarni_d_q, LASX256DOpnd>; ++ ++ ++def XVSSRARNI_BU_H : LASX_I4_U<0b011101110110110001>, ++ LASX_U4_DESC_BASE<"xvssrarni.bu.h", int_loongarch_lasx_xvssrarni_bu_h, uimm4, immZExt4, LASX256BOpnd>; ++ ++def XVSSRARNI_HU_W : LASX_I5_U<0b01110111011011001>, ++ LASX_N4_U5_DESC_BASE<"xvssrarni.hu.w", int_loongarch_lasx_xvssrarni_hu_w, uimm5, immZExt5, LASX256HOpnd>; ++ ++def XVSSRARNI_WU_D : LASX_I6_U<0b0111011101101101>, ++ LASX_U6_DESC_BASE<"xvssrarni.wu.d", int_loongarch_lasx_xvssrarni_wu_d, uimm6, immZExt6, LASX256WOpnd>; ++ ++def XVSSRARNI_DU_Q : LASX_I7_U<0b011101110110111>, ++ LASX_D_DESC_BASE<"xvssrarni.du.q", int_loongarch_lasx_xvssrarni_du_q, LASX256DOpnd>; ++ ++ ++def XVEXTRINS_B : LASX_I8_U<0b01110111100011>, ++ LASX_2R_3R_U8_DESC_BASE<"xvextrins.b", int_loongarch_lasx_xvextrins_b, LASX256BOpnd, LASX256BOpnd>; ++ ++def XVEXTRINS_H : LASX_I8_U<0b01110111100010>, ++ LASX_2R_3R_U8_DESC_BASE<"xvextrins.h", int_loongarch_lasx_xvextrins_h, LASX256HOpnd, LASX256HOpnd>; ++ ++def XVEXTRINS_W : LASX_I8_U<0b01110111100001>, ++ LASX_2R_3R_U8_DESC_BASE<"xvextrins.w", int_loongarch_lasx_xvextrins_w, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVEXTRINS_D : LASX_I8_U<0b01110111100000>, ++ LASX_2R_3R_U8_DESC_BASE<"xvextrins.d", int_loongarch_lasx_xvextrins_d, LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVSHUF4I_B : LASX_I8_U<0b01110111100100>, ++ LASX_I8_SHF_DESC_BASE<"xvshuf4i.b", int_loongarch_lasx_xvshuf4i_b, LASX256BOpnd>; ++ ++def XVSHUF4I_H : LASX_I8_U<0b01110111100101>, ++ LASX_I8_SHF_DESC_BASE<"xvshuf4i.h", int_loongarch_lasx_xvshuf4i_h, LASX256HOpnd>; ++ ++def XVSHUF4I_W : LASX_I8_U<0b01110111100110>, ++ LASX_I8_SHF_DESC_BASE<"xvshuf4i.w", int_loongarch_lasx_xvshuf4i_w, LASX256WOpnd>; ++ ++def XVSHUF4I_D : LASX_I8_U<0b01110111100111>, ++ LASX_I8_O4_SHF_DESC_BASE<"xvshuf4i.d", int_loongarch_lasx_xvshuf4i_d, LASX256DOpnd>; ++ ++ ++def XVBITSELI_B : LASX_I8_U<0b01110111110001>, ++ LASX_2R_3R_U8_DESC_BASE<"xvbitseli.b", int_loongarch_lasx_xvbitseli_b, LASX256BOpnd, LASX256BOpnd>; ++ ++ ++def XVANDI_B : LASX_I8_U<0b01110111110100>, ++ LASX_2R_U8_DESC_BASE<"xvandi.b", int_loongarch_lasx_xvandi_b, LASX256BOpnd, LASX256BOpnd>; ++ ++ ++def XVORI_B : LASX_I8_U<0b01110111110101>, ++ LASX_2R_U8_DESC_BASE<"xvori.b", int_loongarch_lasx_xvori_b, LASX256BOpnd, LASX256BOpnd>; ++ ++ ++def XVXORI_B : LASX_I8_U<0b01110111110110>, ++ LASX_2R_U8_DESC_BASE<"xvxori.b", int_loongarch_lasx_xvxori_b, LASX256BOpnd, LASX256BOpnd>; ++ ++ ++def XVNORI_B : LASX_I8_U<0b01110111110111>, ++ LASX_2R_U8_DESC_BASE<"xvnori.b", int_loongarch_lasx_xvnori_b, LASX256BOpnd, LASX256BOpnd>; ++ ++ ++def XVLDI : LASX_1R_I13<0b01110111111000>, ++ LASX_I13_DESC_BASE<"xvldi", int_loongarch_lasx_xvldi, i32, simm13Op, LASX256DOpnd>; ++ ++ ++def XVLDI_B : LASX_1R_I13_I10<0b01110111111000000>, ++ LASX_I13_DESC_BASE_10<"xvldi", int_loongarch_lasx_xvrepli_b, simm10, immZExt10, LASX256BOpnd>; ++ ++def XVLDI_H : LASX_1R_I13_I10<0b01110111111000001>, ++ LASX_I13_DESC_BASE_10<"xvldi", int_loongarch_lasx_xvrepli_h, simm10, immZExt10, LASX256HOpnd>; ++ ++def XVLDI_W : LASX_1R_I13_I10<0b01110111111000010>, ++ LASX_I13_DESC_BASE_10<"xvldi", int_loongarch_lasx_xvrepli_w, simm10, immZExt10, LASX256WOpnd>; ++ ++def XVLDI_D : LASX_1R_I13_I10<0b01110111111000011>, ++ LASX_I13_DESC_BASE_10<"xvldi", int_loongarch_lasx_xvrepli_d, simm10, immZExt10, LASX256DOpnd>; ++ ++ ++def XVPERMI_W : LASX_I8_U<0b01110111111001>, ++ LASX_2R_3R_U8_DESC_BASE<"xvpermi.w", int_loongarch_lasx_xvpermi_w, LASX256WOpnd, LASX256WOpnd>; ++ ++def XVPERMI_D : LASX_I8_U<0b01110111111010>, ++ LASX_2R_U8_DESC_BASE<"xvpermi.d", int_loongarch_lasx_xvpermi_d, LASX256DOpnd, LASX256DOpnd>; ++ ++def XVPERMI_Q : LASX_I8_U<0b01110111111011>, ++ LASX_2R_3R_U8_DESC_BASE<"xvpermi.q", int_loongarch_lasx_xvpermi_q, LASX256BOpnd, LASX256BOpnd>; ++ ++ ++//Pat ++ ++class LASXBitconvertPat preds = [HasLASX]> : ++ LASXPat<(DstVT (bitconvert SrcVT:$src)), ++ (COPY_TO_REGCLASS SrcVT:$src, DstRC), preds>; ++ ++// These are endian-independent because the element size doesnt change ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++ ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++ ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++ ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++ ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++ ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++ ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++def : LASXBitconvertPat; ++ ++class LASX_XINSERT_PSEUDO_BASE : ++ LASXPseudo<(outs ROXD:$xd), (ins ROXD:$xd_in, ImmOp:$n, ROFS:$fs), ++ [(set ROXD:$xd, (OpNode (Ty ROXD:$xd_in), ROFS:$fs, Imm:$n))]> { ++ bit usesCustomInserter = 1; ++ string Constraints = "$xd = $xd_in"; ++} ++ ++class XINSERT_H_PSEUDO_DESC : LASX_XINSERT_PSEUDO_BASE; ++ ++class XINSERT_H64_PSEUDO_DESC : LASX_XINSERT_PSEUDO_BASE; ++ ++def XINSERT_H_PSEUDO : XINSERT_H_PSEUDO_DESC; ++def XINSERT_H64_PSEUDO : XINSERT_H64_PSEUDO_DESC; ++ ++class XINSERT_B_PSEUDO_DESC : LASX_XINSERT_PSEUDO_BASE; ++def XINSERT_B_PSEUDO : XINSERT_B_PSEUDO_DESC; ++ ++ ++class LASX_COPY_PSEUDO_BASE : ++ LASXPseudo<(outs RCD:$xd), (ins RCWS:$xj, ImmOp:$n), ++ [(set RCD:$xd, (OpNode (VecTy RCWS:$xj), Imm:$n))]> { ++ bit usesCustomInserter = 1; ++} ++ ++class XCOPY_FW_PSEUDO_DESC : LASX_COPY_PSEUDO_BASE; ++class XCOPY_FD_PSEUDO_DESC : LASX_COPY_PSEUDO_BASE; ++def XCOPY_FW_PSEUDO : XCOPY_FW_PSEUDO_DESC; ++def XCOPY_FD_PSEUDO : XCOPY_FD_PSEUDO_DESC; ++ ++ ++ ++class LASX_XINSERT_VIDX_PSEUDO_BASE : ++ LASXPseudo<(outs ROXD:$xd), (ins ROXD:$xd_in, ROIdx:$n, ROFS:$fs), ++ [(set ROXD:$xd, (OpNode (Ty ROXD:$xd_in), ROFS:$fs, ROIdx:$n))]> { ++ bit usesCustomInserter = 1; ++ string Constraints = "$xd = $xd_in"; ++} ++ ++ ++class XINSERT_FW_PSEUDO_DESC : LASX_XINSERT_PSEUDO_BASE; ++def XINSERT_FW_PSEUDO : XINSERT_FW_PSEUDO_DESC; ++ ++class XINSERT_FW_VIDX_PSEUDO_DESC : ++ LASX_XINSERT_VIDX_PSEUDO_BASE; ++class XINSERT_FW_VIDX64_PSEUDO_DESC : ++ LASX_XINSERT_VIDX_PSEUDO_BASE; ++ ++def XINSERT_FW_VIDX_PSEUDO : XINSERT_FW_VIDX_PSEUDO_DESC; ++def XINSERT_FW_VIDX64_PSEUDO : XINSERT_FW_VIDX64_PSEUDO_DESC; ++ ++class XINSERT_B_VIDX64_PSEUDO_DESC : ++ LASX_XINSERT_VIDX_PSEUDO_BASE; ++ ++def XINSERT_B_VIDX64_PSEUDO : XINSERT_B_VIDX64_PSEUDO_DESC; ++ ++ ++class XINSERT_B_VIDX_PSEUDO_DESC : ++ LASX_XINSERT_VIDX_PSEUDO_BASE; ++ ++def XINSERT_B_VIDX_PSEUDO : XINSERT_B_VIDX_PSEUDO_DESC; ++ ++ ++class XINSERTPostRA : ++ LoongArchPseudo<(outs RC:$xd), (ins RC:$xd_in, RD:$n, RE:$fs), []> { ++ let mayLoad = 1; ++ let mayStore = 1; ++} ++ ++def XINSERT_B_VIDX_PSEUDO_POSTRA : XINSERTPostRA; ++def XINSERT_B_VIDX64_PSEUDO_POSTRA : XINSERTPostRA; ++def XINSERT_FW_VIDX_PSEUDO_POSTRA : XINSERTPostRA; ++def XINSERT_FW_VIDX64_PSEUDO_POSTRA : XINSERTPostRA; ++ ++class XINSERT_FD_PSEUDO_DESC : LASX_XINSERT_PSEUDO_BASE; ++ ++def XINSERT_FD_PSEUDO : XINSERT_FD_PSEUDO_DESC; ++ ++class LASX_2R_FILL_PSEUDO_BASE : ++ LASXPseudo<(outs RCWD:$xd), (ins RCWS:$fs), ++ [(set RCWD:$xd, (OpNode RCWS:$fs))]> { ++ let usesCustomInserter = 1; ++} ++ ++class XFILL_FW_PSEUDO_DESC : LASX_2R_FILL_PSEUDO_BASE; ++class XFILL_FD_PSEUDO_DESC : LASX_2R_FILL_PSEUDO_BASE; ++def XFILL_FW_PSEUDO : XFILL_FW_PSEUDO_DESC; ++def XFILL_FD_PSEUDO : XFILL_FD_PSEUDO_DESC; ++ ++class LASX_CONCAT_VECTORS_PSEUDO_BASE : ++ LASXPseudo<(outs ROXD:$xd), (ins ROXJ:$xs, ROXK:$xt), ++ [(set ROXD:$xd, (Ty (concat_vectors (SubTy ROXJ:$xs), (SubTy ROXK:$xt))))]> { ++ bit usesCustomInserter = 1; ++} ++ ++class CONCAT_VECTORS_B_PSEUDO_DESC : ++ LASX_CONCAT_VECTORS_PSEUDO_BASE; ++class CONCAT_VECTORS_H_PSEUDO_DESC : ++ LASX_CONCAT_VECTORS_PSEUDO_BASE; ++class CONCAT_VECTORS_W_PSEUDO_DESC : ++ LASX_CONCAT_VECTORS_PSEUDO_BASE; ++class CONCAT_VECTORS_D_PSEUDO_DESC : ++ LASX_CONCAT_VECTORS_PSEUDO_BASE; ++ ++class CONCAT_VECTORS_FW_PSEUDO_DESC : ++ LASX_CONCAT_VECTORS_PSEUDO_BASE; ++class CONCAT_VECTORS_FD_PSEUDO_DESC : ++ LASX_CONCAT_VECTORS_PSEUDO_BASE; ++ ++def CONCAT_VECTORS_B_PSEUDO : CONCAT_VECTORS_B_PSEUDO_DESC; ++def CONCAT_VECTORS_H_PSEUDO : CONCAT_VECTORS_H_PSEUDO_DESC; ++def CONCAT_VECTORS_W_PSEUDO : CONCAT_VECTORS_W_PSEUDO_DESC; ++def CONCAT_VECTORS_D_PSEUDO : CONCAT_VECTORS_D_PSEUDO_DESC; ++def CONCAT_VECTORS_FW_PSEUDO : CONCAT_VECTORS_FW_PSEUDO_DESC; ++def CONCAT_VECTORS_FD_PSEUDO : CONCAT_VECTORS_FD_PSEUDO_DESC; ++ ++ ++class LASX_COPY_GPR_PSEUDO_BASE : ++ LASXPseudo<(outs ROXD:$xd), (ins ROFS:$xj, ROIdx:$n), ++ [(set ROXD:$xd, (OpNode (VecTy ROFS:$xj), ROIdx:$n))]> { ++ bit usesCustomInserter = 1; ++} ++ ++class XCOPY_FW_GPR_PSEUDO_DESC : LASX_COPY_GPR_PSEUDO_BASE; ++def XCOPY_FW_GPR_PSEUDO : XCOPY_FW_GPR_PSEUDO_DESC; ++ ++ ++let isCodeGenOnly = 1 in { ++ ++def XVLD_H : LASX_I12_S<0b0010110010>, ++ LASX_LD<"xvld", load, v16i16, LASX256HOpnd, mem>; ++ ++def XVLD_W : LASX_I12_S<0b0010110010>, ++ LASX_LD<"xvld", load, v8i32, LASX256WOpnd, mem>; ++ ++def XVLD_D : LASX_I12_S<0b0010110010>, ++ LASX_LD<"xvld", load, v4i64, LASX256DOpnd, mem>; ++ ++ ++def XVST_H : LASX_I12_S<0b0010110011>, ++ LASX_ST<"xvst", store, v16i16, LASX256HOpnd, mem_simm12>; ++ ++def XVST_W : LASX_I12_S<0b0010110011>, ++ LASX_ST<"xvst", store, v8i32, LASX256WOpnd, mem_simm12>; ++ ++def XVST_D : LASX_I12_S<0b0010110011>, ++ LASX_ST<"xvst", store, v4i64, LASX256DOpnd, mem_simm12>; ++ ++ ++def XVREPLVE_W_N : LASX_3R_1GP<0b01110101001000110>, ++ LASX_3R_VREPLVE_DESC_BASE_N<"xvreplve.w", LASX256WOpnd>; ++ ++ ++def XVANDI_B_N : LASX_I8_U<0b01110111110100>, ++ LASX_BIT_U8_DESC_BASE<"xvandi.b", and, xvsplati8_uimm8, LASX256BOpnd>; ++ ++ ++def XVXORI_B_N : LASX_I8_U<0b01110111110110>, ++ LASX_BIT_U8_DESC_BASE<"xvxori.b", xor, xvsplati8_uimm8, LASX256BOpnd>; ++ ++ ++def XVSRAI_B_N : LASX_I3_U<0b0111011100110100001>, ++ LASX_BIT_U3_VREPLVE_DESC_BASE<"xvsrai.b", sra, xvsplati8_uimm3, LASX256BOpnd>; ++ ++def XVSRAI_H_N : LASX_I4_U<0b011101110011010001>, ++ LASX_BIT_U4_VREPLVE_DESC_BASE<"xvsrai.h", sra, xvsplati16_uimm4, LASX256HOpnd>; ++ ++def XVSRAI_W_N : LASX_I5_U<0b01110111001101001>, ++ LASX_BIT_U5_VREPLVE_DESC_BASE<"xvsrai.w", sra, xvsplati32_uimm5, LASX256WOpnd>; ++ ++def XVSRAI_D_N : LASX_I6_U<0b0111011100110101>, ++ LASX_BIT_U6_VREPLVE_DESC_BASE<"xvsrai.d", sra, xvsplati64_uimm6, LASX256DOpnd>; ++ ++ ++def XVSLLI_B_N : LASX_I3_U<0b0111011100101100001>, ++ LASX_BIT_U3_VREPLVE_DESC_BASE<"xvslli.b", shl, xvsplati8_uimm3, LASX256BOpnd>; ++ ++def XVSLLI_H_N : LASX_I4_U<0b011101110010110001>, ++ LASX_BIT_U4_VREPLVE_DESC_BASE<"xvslli.h", shl, xvsplati16_uimm4, LASX256HOpnd>; ++ ++def XVSLLI_W_N : LASX_I5_U<0b01110111001011001>, ++ LASX_BIT_U5_VREPLVE_DESC_BASE<"xvslli.w", shl, xvsplati32_uimm5, LASX256WOpnd>; ++ ++def XVSLLI_D_N : LASX_I6_U<0b0111011100101101>, ++ LASX_BIT_U6_VREPLVE_DESC_BASE<"xvslli.d", shl, xvsplati64_uimm6, LASX256DOpnd>; ++ ++ ++def XVSRLI_B_N : LASX_I3_U<0b0111011100110000001>, ++ LASX_BIT_U3_VREPLVE_DESC_BASE<"xvsrli.b", srl, xvsplati8_uimm3, LASX256BOpnd>; ++ ++def XVSRLI_H_N : LASX_I4_U<0b011101110011000001>, ++ LASX_BIT_U4_VREPLVE_DESC_BASE<"xvsrli.h", srl, xvsplati16_uimm4, LASX256HOpnd>; ++ ++def XVSRLI_W_N : LASX_I5_U<0b01110111001100001>, ++ LASX_BIT_U5_VREPLVE_DESC_BASE<"xvsrli.w", srl, xvsplati32_uimm5, LASX256WOpnd>; ++ ++def XVSRLI_D_N : LASX_I6_U<0b0111011100110001>, ++ LASX_BIT_U6_VREPLVE_DESC_BASE<"xvsrli.d", srl, xvsplati64_uimm6, LASX256DOpnd>; ++ ++ ++def XVMAXI_B_N : LASX_I5<0b01110110100100000>, ++ LASX_I5_DESC_BASE<"xvmaxi.b", smax, xvsplati8_simm5, LASX256BOpnd>; ++ ++def XVMAXI_H_N : LASX_I5<0b01110110100100001>, ++ LASX_I5_DESC_BASE<"xvmaxi.h", smax, xvsplati16_simm5, LASX256HOpnd>; ++ ++def XVMAXI_W_N : LASX_I5<0b01110110100100010>, ++ LASX_I5_DESC_BASE<"xvmaxi.w", smax, xvsplati32_simm5, LASX256WOpnd>; ++ ++def XVMAXI_D_N : LASX_I5<0b01110110100100011>, ++ LASX_I5_DESC_BASE<"xvmaxi.d", smax, xvsplati64_simm5, LASX256DOpnd>; ++ ++ ++def XVMINI_B_N : LASX_I5<0b01110110100100100>, ++ LASX_I5_DESC_BASE<"xvmini.b", smin, xvsplati8_simm5, LASX256BOpnd>; ++ ++def XVMINI_H_N : LASX_I5<0b01110110100100101>, ++ LASX_I5_DESC_BASE<"xvmini.h", smin, xvsplati16_simm5, LASX256HOpnd>; ++ ++def XVMINI_W_N : LASX_I5<0b01110110100100110>, ++ LASX_I5_DESC_BASE<"xvmini.w", smin, xvsplati32_simm5, LASX256WOpnd>; ++ ++def XVMINI_D_N : LASX_I5<0b01110110100100111>, ++ LASX_I5_DESC_BASE<"xvmini.d", smin, xvsplati64_simm5, LASX256DOpnd>; ++ ++ ++def XVMAXI_BU_N : LASX_I5_U<0b01110110100101000>, ++ LASX_I5_U_DESC_BASE<"xvmaxi.bu", umax, xvsplati8_uimm5, LASX256BOpnd>; ++ ++def XVMAXI_HU_N : LASX_I5_U<0b01110110100101001>, ++ LASX_I5_U_DESC_BASE<"xvmaxi.hu", umax, xvsplati16_uimm5, LASX256HOpnd>; ++ ++def XVMAXI_WU_N : LASX_I5_U<0b01110110100101010>, ++ LASX_I5_U_DESC_BASE<"xvmaxi.wu", umax, xvsplati32_uimm5, LASX256WOpnd>; ++ ++def XVMAXI_DU_N : LASX_I5_U<0b01110110100101011>, ++ LASX_I5_U_DESC_BASE<"xvmaxi.du", umax, xvsplati64_uimm5, LASX256DOpnd>; ++ ++ ++def XVMINI_BU_N : LASX_I5_U<0b01110110100101100>, ++ LASX_I5_U_DESC_BASE<"xvmini.bu", umin, xvsplati8_uimm5, LASX256BOpnd>; ++ ++def XVMINI_HU_N : LASX_I5_U<0b01110110100101101>, ++ LASX_I5_U_DESC_BASE<"xvmini.hu", umin, xvsplati16_uimm5, LASX256HOpnd>; ++ ++def XVMINI_WU_N : LASX_I5_U<0b01110110100101110>, ++ LASX_I5_U_DESC_BASE<"xvmini.wu", umin, xvsplati32_uimm5, LASX256WOpnd>; ++ ++def XVMINI_DU_N : LASX_I5_U<0b01110110100101111>, ++ LASX_I5_U_DESC_BASE<"xvmini.du", umin, xvsplati64_uimm5, LASX256DOpnd>; ++ ++ ++def XVSEQI_B_N : LASX_I5<0b01110110100000000>, ++ LASX_I5_SETCC_DESC_BASE<"xvseqi.b", SETEQ, v32i8, xvsplati8_simm5, LASX256BOpnd>; ++ ++def XVSEQI_H_N : LASX_I5<0b01110110100000001>, ++ LASX_I5_SETCC_DESC_BASE<"xvseqi.h", SETEQ, v16i16, xvsplati16_simm5, LASX256HOpnd>; ++ ++def XVSEQI_W_N : LASX_I5<0b01110110100000010>, ++ LASX_I5_SETCC_DESC_BASE<"xvseqi.w", SETEQ, v8i32, xvsplati32_simm5, LASX256WOpnd>; ++ ++def XVSEQI_D_N : LASX_I5<0b01110110100000011>, ++ LASX_I5_SETCC_DESC_BASE<"xvseqi.d", SETEQ, v4i64, xvsplati64_simm5, LASX256DOpnd>; ++ ++ ++def XVSLEI_B_N : LASX_I5<0b01110110100000100>, ++ LASX_I5_SETCC_DESC_BASE<"xvslei.b", SETLE, v32i8, xvsplati8_simm5, LASX256BOpnd>; ++ ++def XVSLEI_H_N : LASX_I5<0b01110110100000101>, ++ LASX_I5_SETCC_DESC_BASE<"xvslei.h", SETLE, v16i16, xvsplati16_simm5, LASX256HOpnd>; ++ ++def XVSLEI_W_N : LASX_I5<0b01110110100000110>, ++ LASX_I5_SETCC_DESC_BASE<"xvslei.w", SETLE, v8i32, xvsplati32_simm5, LASX256WOpnd>; ++ ++def XVSLEI_D_N : LASX_I5<0b01110110100000111>, ++ LASX_I5_SETCC_DESC_BASE<"xvslei.d", SETLE, v4i64, xvsplati64_simm5, LASX256DOpnd>; ++ ++ ++def XVSLEI_BU_N : LASX_I5_U<0b01110110100001000>, ++ LASX_I5_U_SETCC_DESC_BASE<"xvslei.bu", SETULE, v32i8, xvsplati8_uimm5, LASX256BOpnd>; ++ ++def XVSLEI_HU_N : LASX_I5_U<0b01110110100001001>, ++ LASX_I5_U_SETCC_DESC_BASE<"xvslei.hu", SETULE, v16i16, xvsplati16_uimm5, LASX256HOpnd>; ++ ++def XVSLEI_WU_N : LASX_I5_U<0b01110110100001010>, ++ LASX_I5_U_SETCC_DESC_BASE<"xvslei.wu", SETULE, v8i32, xvsplati32_uimm5, LASX256WOpnd>; ++ ++def XVSLEI_DU_N : LASX_I5_U<0b01110110100001011>, ++ LASX_I5_U_SETCC_DESC_BASE<"xvslei.du", SETULE, v4i64, xvsplati64_uimm5, LASX256DOpnd>; ++ ++ ++def XVSLTI_B_N : LASX_I5<0b01110110100001100>, ++ LASX_I5_SETCC_DESC_BASE<"xvslti.b", SETLT, v32i8, xvsplati8_simm5, LASX256BOpnd>; ++ ++def XVSLTI_H_N : LASX_I5<0b01110110100001101>, ++ LASX_I5_SETCC_DESC_BASE<"xvslti.h", SETLT, v16i16, xvsplati16_simm5, LASX256HOpnd>; ++ ++def XVSLTI_W_N : LASX_I5<0b01110110100001110>, ++ LASX_I5_SETCC_DESC_BASE<"xvslti.w", SETLT, v8i32, xvsplati32_simm5, LASX256WOpnd>; ++ ++def XVSLTI_D_N : LASX_I5<0b01110110100001111>, ++ LASX_I5_SETCC_DESC_BASE<"xvslti.d", SETLT, v4i64, xvsplati64_simm5, LASX256DOpnd>; ++ ++ ++def XVSLTI_BU_N : LASX_I5_U<0b01110110100010000>, ++ LASX_I5_U_SETCC_DESC_BASE<"xvslti.bu", SETULT, v32i8, xvsplati8_uimm5, LASX256BOpnd>; ++ ++def XVSLTI_HU_N : LASX_I5_U<0b01110110100010001>, ++ LASX_I5_U_SETCC_DESC_BASE<"xvslti.hu", SETULT, v16i16, xvsplati16_uimm5, LASX256HOpnd>; ++ ++def XVSLTI_WU_N : LASX_I5_U<0b01110110100010010>, ++ LASX_I5_U_SETCC_DESC_BASE<"xvslti.wu", SETULT, v8i32, xvsplati32_uimm5, LASX256WOpnd>; ++ ++def XVSLTI_DU_N : LASX_I5_U<0b01110110100010011>, ++ LASX_I5_U_SETCC_DESC_BASE<"xvslti.du", SETULT, v4i64, xvsplati64_uimm5, LASX256DOpnd>; ++ ++ ++def XVADDI_BU_N : LASX_I5_U<0b01110110100010100>, ++ LASX_I5_U_DESC_BASE<"xvaddi.bu", add, xvsplati8_uimm5, LASX256BOpnd>; ++ ++def XVADDI_HU_N : LASX_I5_U<0b01110110100010101>, ++ LASX_I5_U_DESC_BASE<"xvaddi.hu", add, xvsplati16_uimm5, LASX256HOpnd>; ++ ++def XVADDI_WU_N : LASX_I5_U<0b01110110100010110>, ++ LASX_I5_U_DESC_BASE<"xvaddi.wu", add, xvsplati32_uimm5, LASX256WOpnd>; ++ ++def XVADDI_DU_N : LASX_I5_U<0b01110110100010111>, ++ LASX_I5_U_DESC_BASE<"xvaddi.du", add, xvsplati64_uimm5, LASX256DOpnd>; ++ ++ ++def XVSUBI_BU_N : LASX_I5_U<0b01110110100011000>, ++ LASX_I5_U_DESC_BASE<"xvsubi.bu", sub, xvsplati8_uimm5, LASX256BOpnd>; ++ ++def XVSUBI_HU_N : LASX_I5_U<0b01110110100011001>, ++ LASX_I5_U_DESC_BASE<"xvsubi.hu", sub, xvsplati16_uimm5, LASX256HOpnd>; ++ ++def XVSUBI_WU_N : LASX_I5_U<0b01110110100011010>, ++ LASX_I5_U_DESC_BASE<"xvsubi.wu", sub, xvsplati32_uimm5, LASX256WOpnd>; ++ ++def XVSUBI_DU_N : LASX_I5_U<0b01110110100011011>, ++ LASX_I5_U_DESC_BASE<"xvsubi.du", sub, xvsplati64_uimm5, LASX256DOpnd>; ++ ++ ++def XVPERMI_QH : LASX_I8_U<0b01110111111011>, ++ LASX_2RN_3R_U8_DESC_BASE<"xvpermi.q", LASX256HOpnd, LASX256HOpnd>; ++ ++def XVPERMI_QW : LASX_I8_U<0b01110111111011>, ++ LASX_2RN_3R_U8_DESC_BASE<"xvpermi.q", LASX256WOpnd, LASX256WOpnd>; ++ ++def XVPERMI_QD : LASX_I8_U<0b01110111111011>, ++ LASX_2RN_3R_U8_DESC_BASE<"xvpermi.q", LASX256DOpnd, LASX256DOpnd>; ++ ++ ++def XVBITSELI_B_N : LASX_I8_U<0b01110111110001>, ++ LASX_2R_3R_U8_SELECT<"xvbitseli.b", vselect, LASX256BOpnd, LASX256BOpnd>; ++ ++} ++ ++ ++def : LASXPat<(v8f32 (load addrimm12:$addr)), (XVLD_W addrimm12:$addr)>; ++def : LASXPat<(v4f64 (load addrimm12:$addr)), (XVLD_D addrimm12:$addr)>; ++ ++def XVST_FW : LASXPat<(store (v8f32 LASX256W:$xj), addrimm12:$addr), ++ (XVST_W LASX256W:$xj, addrimm12:$addr)>; ++def XVST_FD : LASXPat<(store (v4f64 LASX256D:$xj), addrimm12:$addr), ++ (XVST_D LASX256D:$xj, addrimm12:$addr)>; ++ ++def XVNEG_FW : LASXPat<(fneg (v8f32 LASX256W:$xj)), ++ (XVBITREVI_W LASX256W:$xj, 31)>; ++def XVNEG_FD : LASXPat<(fneg (v4f64 LASX256D:$xj)), ++ (XVBITREVI_D LASX256D:$xj, 63)>; ++ ++ ++def : LASXPat<(v4i64 (LoongArchVABSD v4i64:$xj, v4i64:$xk, (i32 0))), ++ (v4i64 (XVABSD_D $xj, $xk))>; ++ ++def : LASXPat<(v8i32 (LoongArchVABSD v8i32:$xj, v8i32:$xk, (i32 0))), ++ (v8i32 (XVABSD_W $xj, $xk))>; ++ ++def : LASXPat<(v16i16 (LoongArchVABSD v16i16:$xj, v16i16:$xk, (i32 0))), ++ (v16i16 (XVABSD_H $xj, $xk))>; ++ ++def : LASXPat<(v32i8 (LoongArchVABSD v32i8:$xj, v32i8:$xk, (i32 0))), ++ (v32i8 (XVABSD_B $xj, $xk))>; ++ ++def : LASXPat<(v4i64 (LoongArchUVABSD v4i64:$xj, v4i64:$xk, (i32 0))), ++ (v4i64 (XVABSD_DU $xj, $xk))>; ++ ++def : LASXPat<(v8i32 (LoongArchUVABSD v8i32:$xj, v8i32:$xk, (i32 0))), ++ (v8i32 (XVABSD_WU $xj, $xk))>; ++ ++def : LASXPat<(v16i16 (LoongArchUVABSD v16i16:$xj, v16i16:$xk, (i32 0))), ++ (v16i16 (XVABSD_HU $xj, $xk))>; ++ ++def : LASXPat<(v32i8 (LoongArchUVABSD v32i8:$xj, v32i8:$xk, (i32 0))), ++ (v32i8 (XVABSD_BU $xj, $xk))>; ++ ++ ++def : LASXPat<(or v32i8:$vj, (shl vsplat_imm_eq_1, v32i8:$vk)), ++ (XVBITSET_B v32i8:$vj, v32i8:$vk)>; ++def : LASXPat<(or v16i16:$vj, (shl vsplat_imm_eq_1, v16i16:$vk)), ++ (XVBITSET_H v16i16:$vj, v16i16:$vk)>; ++def : LASXPat<(or v8i32:$vj, (shl vsplat_imm_eq_1, v8i32:$vk)), ++ (XVBITSET_W v8i32:$vj, v8i32:$vk)>; ++def : LASXPat<(or v4i64:$vj, (shl vsplat_imm_eq_1, v4i64:$vk)), ++ (XVBITSET_D v4i64:$vj, v4i64:$vk)>; ++ ++def : LASXPat<(xor v32i8:$vj, (shl xvsplat_imm_eq_1, v32i8:$vk)), ++ (XVBITREV_B v32i8:$vj, v32i8:$vk)>; ++def : LASXPat<(xor v16i16:$vj, (shl xvsplat_imm_eq_1, v16i16:$vk)), ++ (XVBITREV_H v16i16:$vj, v16i16:$vk)>; ++def : LASXPat<(xor v8i32:$vj, (shl xvsplat_imm_eq_1, v8i32:$vk)), ++ (XVBITREV_W v8i32:$vj, v8i32:$vk)>; ++def : LASXPat<(xor v4i64:$vj, (shl (v4i64 xvsplati64_imm_eq_1), v4i64:$vk)), ++ (XVBITREV_D v4i64:$vj, v4i64:$vk)>; ++ ++def : LASXPat<(and v32i8:$vj, (xor (shl vsplat_imm_eq_1, v32i8:$vk), immAllOnesV)), ++ (XVBITCLR_B v32i8:$vj, v32i8:$vk)>; ++def : LASXPat<(and v16i16:$vj, (xor (shl vsplat_imm_eq_1, v16i16:$vk), immAllOnesV)), ++ (XVBITCLR_H v16i16:$vj, v16i16:$vk)>; ++def : LASXPat<(and v8i32:$vj, (xor (shl vsplat_imm_eq_1, v8i32:$vk), immAllOnesV)), ++ (XVBITCLR_W v8i32:$vj, v8i32:$vk)>; ++def : LASXPat<(and v4i64:$vj, (xor (shl (v4i64 vsplati64_imm_eq_1), v4i64:$vk), (bitconvert (v8i32 immAllOnesV)))), ++ (XVBITCLR_D v4i64:$vj, v4i64:$vk)>; ++ ++def xvsplati64_imm_eq_63 : PatLeaf<(bitconvert (v8i32 (build_vector))), [{ ++ APInt Imm; ++ SDNode *BV = N->getOperand(0).getNode(); ++ EVT EltTy = N->getValueType(0).getVectorElementType(); ++ ++ return selectVSplat(BV, Imm, EltTy.getSizeInBits()) && ++ Imm.getBitWidth() == EltTy.getSizeInBits() && Imm == 63; ++}]>; ++ ++def xvsplati8imm7 : PatFrag<(ops node:$wt), ++ (and node:$wt, (xvsplati8 immi32Cst7))>; ++def xvsplati16imm15 : PatFrag<(ops node:$wt), ++ (and node:$wt, (xvsplati16 immi32Cst15))>; ++def xvsplati32imm31 : PatFrag<(ops node:$wt), ++ (and node:$wt, (xvsplati32 immi32Cst31))>; ++def xvsplati64imm63 : PatFrag<(ops node:$wt), ++ (and node:$wt, xvsplati64_imm_eq_63)>; ++ ++ ++class LASXShiftPat : ++ LASXPat<(VT (Node VT:$vs, (VT (and VT:$vt, Vec)))), ++ (VT (Insn VT:$vs, VT:$vt))>; ++ ++class LASXBitPat : ++ LASXPat<(VT (Node VT:$vs, (shl vsplat_imm_eq_1, (Frag VT:$vt)))), ++ (VT (Insn VT:$vs, VT:$vt))>; ++ ++multiclass LASXShiftPats { ++ def : LASXShiftPat(Insn#_B), ++ (xvsplati8 immi32Cst7)>; ++ def : LASXShiftPat(Insn#_H), ++ (xvsplati16 immi32Cst15)>; ++ def : LASXShiftPat(Insn#_W), ++ (xvsplati32 immi32Cst31)>; ++ def : LASXPat<(v4i64 (Node v4i64:$vs, (v4i64 (and v4i64:$vt, ++ xvsplati64_imm_eq_63)))), ++ (v4i64 (!cast(Insn#_D) v4i64:$vs, v4i64:$vt))>; ++} ++ ++multiclass LASXBitPats { ++ def : LASXBitPat(Insn#_B), xvsplati8imm7>; ++ def : LASXBitPat(Insn#_H), xvsplati16imm15>; ++ def : LASXBitPat(Insn#_W), xvsplati32imm31>; ++ def : LASXPat<(Node v4i64:$vs, (shl (v4i64 xvsplati64_imm_eq_1), ++ (xvsplati64imm63 v4i64:$vt))), ++ (v4i64 (!cast(Insn#_D) v4i64:$vs, v4i64:$vt))>; ++} ++ ++defm : LASXShiftPats; ++defm : LASXShiftPats; ++defm : LASXShiftPats; ++defm : LASXBitPats; ++defm : LASXBitPats; ++ ++def : LASXPat<(and v32i8:$vs, (xor (shl xvsplat_imm_eq_1, ++ (xvsplati8imm7 v32i8:$vt)), ++ immAllOnesV)), ++ (v32i8 (XVBITCLR_B v32i8:$vs, v32i8:$vt))>; ++def : LASXPat<(and v16i16:$vs, (xor (shl xvsplat_imm_eq_1, ++ (xvsplati16imm15 v16i16:$vt)), ++ immAllOnesV)), ++ (v16i16 (XVBITCLR_H v16i16:$vs, v16i16:$vt))>; ++def : LASXPat<(and v8i32:$vs, (xor (shl xvsplat_imm_eq_1, ++ (xvsplati32imm31 v8i32:$vt)), ++ immAllOnesV)), ++ (v8i32 (XVBITCLR_W v8i32:$vs, v8i32:$vt))>; ++def : LASXPat<(and v4i64:$vs, (xor (shl (v4i64 xvsplati64_imm_eq_1), ++ (xvsplati64imm63 v4i64:$vt)), ++ (bitconvert (v8i32 immAllOnesV)))), ++ (v4i64 (XVBITCLR_D v4i64:$vs, v4i64:$vt))>; ++ ++ ++def : LASXPat<(fdiv (v8f32 (build_vector (f32 fpimm1), (f32 fpimm1), (f32 fpimm1), ++ (f32 fpimm1),(f32 fpimm1), (f32 fpimm1), (f32 fpimm1), (f32 fpimm1))), v8f32:$v), ++ (XVFRECIP_S v8f32:$v)>; ++ ++def : LASXPat<(fdiv (v4f64 (build_vector (f64 fpimm1), (f64 fpimm1), (f64 fpimm1), (f64 fpimm1))), v4f64:$v), ++ (XVFRECIP_D v4f64:$v)>; ++ ++def : LASXPat<(fdiv (v8f32 fpimm1), v8f32:$v), ++ (XVFRECIP_S v8f32:$v)>; ++ ++def : LASXPat<(fdiv (v4f64 fpimm1), v4f64:$v), ++ (XVFRECIP_D v4f64:$v)>; ++ ++// 256-Bit vector FP approximate reciprocal operation ++let Predicates = [HasFrecipe] in { ++def : LASXPat<(int_loongarch_lasx_xvfrecipe_s (v8f32 LASX256W:$xj)), ++ (XVFRECIPE_S LASX256W:$xj)>; ++def : LASXPat<(int_loongarch_lasx_xvfrecipe_d (v4f64 LASX256D:$xj)), ++ (XVFRECIPE_D LASX256D:$xj)>; ++def : LASXPat<(int_loongarch_lasx_xvfrsqrte_s (v8f32 LASX256W:$xj)), ++ (XVFRSQRTE_S LASX256W:$xj)>; ++def : LASXPat<(int_loongarch_lasx_xvfrsqrte_d (v4f64 LASX256D:$xj)), ++ (XVFRSQRTE_D LASX256D:$xj)>; ++} ++ ++def : LASXPat<(fdiv (v8f32 (build_vector (f32 fpimm1), (f32 fpimm1), (f32 fpimm1), (f32 fpimm1), ++ (f32 fpimm1), (f32 fpimm1), (f32 fpimm1), (f32 fpimm1))), (fsqrt v8f32:$v)), ++ (XVFRSQRT_S v8f32:$v)>; ++ ++def : LASXPat<(fdiv (v4f64 (build_vector (f64 fpimm1), (f64 fpimm1), (f64 fpimm1), (f64 fpimm1))), (fsqrt v4f64:$v)), ++ (XVFRSQRT_D v4f64:$v)>; ++ ++def : LASXPat<(fdiv (v8f32 fpimm1), (fsqrt v8f32:$v)), ++ (XVFRSQRT_S v8f32:$v)>; ++ ++def : LASXPat<(fdiv (v4f64 fpimm1), (fsqrt v4f64:$v)), ++ (XVFRSQRT_D v4f64:$v)>; ++ ++ ++def : LASXPat <(extract_subvector v4f64:$vec, (i32 0)), ++ (v2f64 (EXTRACT_SUBREG v4f64:$vec, sub_128))>; ++ ++def : LASXPat <(extract_subvector v8f32:$vec, (i32 0)), ++ (v4f32 (EXTRACT_SUBREG v8f32:$vec, sub_128))>; ++ ++def : LASXPat <(extract_subvector v4i64:$vec, (i32 0)), ++ (v2i64 (EXTRACT_SUBREG v4i64:$vec, sub_128))>; ++ ++def : LASXPat <(extract_subvector v8i32:$vec, (i32 0)), ++ (v4i32 (EXTRACT_SUBREG v8i32:$vec, sub_128))>; ++ ++def : LASXPat <(extract_subvector v16i16:$vec, (i32 0)), ++ (v8i16 (EXTRACT_SUBREG v16i16:$vec, sub_128))>; ++ ++def : LASXPat <(extract_subvector v32i8:$vec, (i32 0)), ++ (v16i8 (EXTRACT_SUBREG v32i8:$vec, sub_128))>; ++ ++ ++ ++def : LASXPat <(extract_subvector v4f64:$vec, (i64 0)), ++ (v2f64 (EXTRACT_SUBREG v4f64:$vec, sub_128))>; ++ ++def : LASXPat <(extract_subvector v8f32:$vec, (i64 0)), ++ (v4f32 (EXTRACT_SUBREG v8f32:$vec, sub_128))>; ++ ++def : LASXPat <(extract_subvector v4i64:$vec, (i64 0)), ++ (v2i64 (EXTRACT_SUBREG v4i64:$vec, sub_128))>; ++ ++def : LASXPat <(extract_subvector v8i32:$vec, (i64 0)), ++ (v4i32 (EXTRACT_SUBREG v8i32:$vec, sub_128))>; ++ ++def : LASXPat <(extract_subvector v16i16:$vec, (i64 0)), ++ (v8i16 (EXTRACT_SUBREG v16i16:$vec, sub_128))>; ++ ++def : LASXPat <(extract_subvector v32i8:$vec, (i64 0)), ++ (v16i8 (EXTRACT_SUBREG v32i8:$vec, sub_128))>; ++ ++ ++def : LASXPat <(extract_subvector v4i64:$vec, (i32 2)), ++ (v2i64 (EXTRACT_SUBREG (v4i64 (XVPERMI_QD v4i64:$vec, v4i64:$vec, (i32 1))), sub_128))>; ++ ++def : LASXPat <(extract_subvector v8i32:$vec, (i32 4)), ++ (v4i32 (EXTRACT_SUBREG (v8i32 (XVPERMI_QW v8i32:$vec, v8i32:$vec, (i32 1))), sub_128))>; ++ ++def : LASXPat <(extract_subvector v16i16:$vec, (i32 8)), ++ (v8i16 (EXTRACT_SUBREG (v16i16 (XVPERMI_QH v16i16:$vec, v16i16:$vec, (i32 1))), sub_128))>; ++ ++def : LASXPat <(extract_subvector v32i8:$vec, (i32 16)), ++ (v16i8 (EXTRACT_SUBREG (v32i8 (XVPERMI_Q v32i8:$vec, v32i8:$vec, (i32 1))), sub_128))>; ++ ++ ++def : LASXPat <(extract_subvector v4i64:$vec, (i64 2)), ++ (v2i64 (EXTRACT_SUBREG (v4i64 (XVPERMI_QD v4i64:$vec, v4i64:$vec, (i32 1))), sub_128))>; ++ ++def : LASXPat <(extract_subvector v8i32:$vec, (i64 4)), ++ (v4i32 (EXTRACT_SUBREG (v8i32 (XVPERMI_QW v8i32:$vec, v8i32:$vec, (i32 1))), sub_128))>; ++ ++def : LASXPat <(extract_subvector v16i16:$vec, (i64 8)), ++ (v8i16 (EXTRACT_SUBREG (v16i16 (XVPERMI_QH v16i16:$vec, v16i16:$vec, (i32 1))), sub_128))>; ++ ++def : LASXPat <(extract_subvector v32i8:$vec, (i64 16)), ++ (v16i8 (EXTRACT_SUBREG (v32i8 (XVPERMI_Q v32i8:$vec, v32i8:$vec, (i32 1))), sub_128))>; ++ ++ ++def : LASXPat<(abs v4i64:$v), ++ (XVMAX_D v4i64:$v, (XVNEG_D v4i64:$v))>; ++ ++def : LASXPat<(abs v8i32:$v), ++ (XVMAX_W v8i32:$v, (XVNEG_W v8i32:$v))>; ++ ++def : LASXPat<(abs v16i16:$v), ++ (XVMAX_H v16i16:$v, (XVNEG_H v16i16:$v))>; ++ ++def : LASXPat<(abs v32i8:$v), ++ (XVMAX_B v32i8:$v, (XVNEG_B v32i8:$v))>; ++ ++ ++def : LASXPat<(sub (v32i8 immAllZerosV), v32i8:$v), ++ (XVNEG_B v32i8:$v)>; ++ ++def : LASXPat<(sub (v16i16 immAllZerosV), v16i16:$v), ++ (XVNEG_H v16i16:$v)>; ++ ++def : LASXPat<(sub (v8i32 immAllZerosV), v8i32:$v), ++ (XVNEG_W v8i32:$v)>; ++ ++def : LASXPat<(sub (v4i64 immAllZerosV), v4i64:$v), ++ (XVNEG_D v4i64:$v)>; ++ ++ ++ ++def : LASXPat<(insert_subvector undef, (v2i64 LSX128D:$src), (i32 0)), ++ (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), LSX128D:$src, sub_128)>; ++ ++def : LASXPat<(insert_subvector undef, (v4i32 LSX128W:$src), (i32 0)), ++ (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), LSX128W:$src, sub_128)>; ++ ++def : LASXPat<(insert_subvector undef, (v8i16 LSX128H:$src), (i32 0)), ++ (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), LSX128H:$src, sub_128)>; ++ ++def : LASXPat<(insert_subvector undef, (v16i8 LSX128B:$src), (i32 0)), ++ (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), LSX128B:$src, sub_128)>; ++ ++ ++def : LASXPat<(insert_subvector undef, (v2i64 LSX128D:$src), (i64 0)), ++ (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), LSX128D:$src, sub_128)>; ++ ++def : LASXPat<(insert_subvector undef, (v4i32 LSX128W:$src), (i64 0)), ++ (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), LSX128W:$src, sub_128)>; ++ ++def : LASXPat<(insert_subvector undef, (v8i16 LSX128H:$src), (i64 0)), ++ (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), LSX128H:$src, sub_128)>; ++ ++def : LASXPat<(insert_subvector undef, (v16i8 LSX128B:$src), (i64 0)), ++ (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), LSX128B:$src, sub_128)>; ++ ++ ++def : LASXPat<(insert_subvector ++ (v4i64 immAllZerosV), (v2i64 LSX128D:$src), (i32 0)), ++ (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), LSX128D:$src, sub_128)>; ++ ++def : LASXPat<(insert_subvector ++ (v8i32 immAllZerosV), (v4i32 LSX128W:$src), (i32 0)), ++ (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), LSX128W:$src, sub_128)>; ++ ++def : LASXPat<(insert_subvector ++ (v16i16 immAllZerosV), (v8i16 LSX128H:$src), (i32 0)), ++ (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), LSX128H:$src, sub_128)>; ++ ++def : LASXPat<(insert_subvector ++ (v32i8 immAllZerosV), (v16i8 LSX128B:$src), (i32 0)), ++ (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), LSX128B:$src, sub_128)>; ++ ++def : LASXPat<(insert_subvector ++ (v4i64 immAllZerosV), (v2i64 LSX128D:$src), (i64 0)), ++ (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), LSX128D:$src, sub_128)>; ++ ++def : LASXPat<(insert_subvector ++ (v8i32 immAllZerosV), (v4i32 LSX128W:$src), (i64 0)), ++ (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), LSX128W:$src, sub_128)>; ++ ++def : LASXPat<(insert_subvector ++ (v16i16 immAllZerosV), (v8i16 LSX128H:$src), (i64 0)), ++ (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), LSX128H:$src, sub_128)>; ++ ++def : LASXPat<(insert_subvector ++ (v32i8 immAllZerosV), (v16i8 LSX128B:$src), (i64 0)), ++ (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), LSX128B:$src, sub_128)>; ++ ++ ++def : LASXPat<(insert_subvector ++ (v4i64 immAllZerosV), (v2i64 LSX128D:$src), (i32 2)), ++ (XVPERMI_QD (v4i64 (XVREPLGR2VR_D ZERO_64)), ++ (v4i64 (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), ++ LSX128D:$src, sub_128)), (i32 32))>; ++ ++def : LASXPat<(insert_subvector (v8i32 immAllZerosV), ++ (v4i32 LSX128W:$src), (i32 4)), ++ (XVPERMI_QW (v8i32 (XVREPLGR2VR_W ZERO)), ++ (v8i32 (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), ++ LSX128W:$src, sub_128)), (i32 32))>; ++ ++def : LASXPat<(insert_subvector ++ (v16i16 immAllZerosV), (v8i16 LSX128H:$src), (i32 8)), ++ (XVPERMI_QH (v16i16 (XVREPLGR2VR_H ZERO)), ++ (v16i16 (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), ++ LSX128H:$src, sub_128)), (i32 32))>; ++ ++def : LASXPat<(insert_subvector ++ (v32i8 immAllZerosV), (v16i8 LSX128B:$src), (i32 16)), ++ (XVPERMI_Q (v32i8 (XVREPLGR2VR_B ZERO)), ++ (v32i8 (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), ++ LSX128B:$src, sub_128)), (i32 32))>; ++ ++ ++def : LASXPat<(insert_subvector ++ (v4i64 immAllZerosV), (v2i64 LSX128D:$src), (i64 2)), ++ (XVPERMI_QD (v4i64 (XVREPLGR2VR_D ZERO_64)), ++ (v4i64 (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), ++ LSX128D:$src, sub_128)), (i32 32))>; ++ ++def : LASXPat<(insert_subvector ++ (v8i32 immAllZerosV), (v4i32 LSX128W:$src), (i64 4)), ++ (XVPERMI_QW (v8i32 (XVREPLGR2VR_W ZERO)), ++ (v8i32 (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), ++ LSX128W:$src, sub_128)), (i32 32))>; ++ ++def : LASXPat<(insert_subvector ++ (v16i16 immAllZerosV), (v8i16 LSX128H:$src), (i64 8)), ++ (XVPERMI_QH (v16i16 (XVREPLGR2VR_H ZERO)), ++ (v16i16 (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), ++ LSX128H:$src, sub_128)), (i32 32))>; ++ ++def : LASXPat<(insert_subvector ++ (v32i8 immAllZerosV), (v16i8 LSX128B:$src), (i64 16)), ++ (XVPERMI_Q (v32i8 (XVREPLGR2VR_B ZERO)), ++ (v32i8 (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), ++ LSX128B:$src, sub_128)), (i32 32))>; ++ ++ ++def : LASXPat<(insert_subvector undef, (v2i64 LSX128D:$src), (i32 2)), ++ (XVPERMI_QD (v4i64 (IMPLICIT_DEF)), ++ (v4i64 (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), ++ LSX128D:$src, sub_128)), (i32 32))>; ++ ++def : LASXPat<(insert_subvector undef, (v4i32 LSX128W:$src), (i32 4)), ++ (XVPERMI_QW (v8i32 (IMPLICIT_DEF)), ++ (v8i32 (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), ++ LSX128W:$src, sub_128)), (i32 32))>; ++ ++def : LASXPat<(insert_subvector undef, (v8i16 LSX128H:$src), (i32 8)), ++ (XVPERMI_QH (v16i16 (IMPLICIT_DEF)), ++ (v16i16 (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), ++ LSX128H:$src, sub_128)), (i32 32))>; ++ ++def : LASXPat<(insert_subvector undef, (v16i8 LSX128B:$src), (i32 16)), ++ (XVPERMI_Q (v32i8 (IMPLICIT_DEF)), ++ (v32i8 (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), ++ LSX128B:$src, sub_128)), (i32 32))>; ++ ++ ++def : LASXPat<(insert_subvector undef, (v2i64 LSX128D:$src), (i64 2)), ++ (XVPERMI_QD (v4i64 (IMPLICIT_DEF)), ++ (v4i64 (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), ++ LSX128D:$src, sub_128)), (i32 32))>; ++ ++def : LASXPat<(insert_subvector undef, (v4i32 LSX128W:$src), (i64 4)), ++ (XVPERMI_QW (v8i32 (IMPLICIT_DEF)), ++ (v8i32 (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), ++ LSX128W:$src, sub_128)), (i32 32))>; ++ ++def : LASXPat<(insert_subvector undef, (v8i16 LSX128H:$src), (i64 8)), ++ (XVPERMI_QH (v16i16 (IMPLICIT_DEF)), ++ (v16i16 (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), ++ LSX128H:$src, sub_128)), (i32 32))>; ++ ++def : LASXPat<(insert_subvector undef, (v16i8 LSX128B:$src), (i64 16)), ++ (XVPERMI_Q (v32i8 (IMPLICIT_DEF)), ++ (v32i8 (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), ++ LSX128B:$src, sub_128)), (i32 32))>; ++ ++ ++def : LASXPat<(sra ++ (v32i8 (add ++ (v32i8 (add LASX256B:$a, LASX256B:$b)), ++ (v32i8 (srl ++ (v32i8 (add LASX256B:$a, LASX256B:$b)), ++ (v32i8 (build_vector (i32 7),(i32 7),(i32 7),(i32 7), ++ (i32 7),(i32 7),(i32 7),(i32 7), ++ (i32 7),(i32 7),(i32 7),(i32 7), ++ (i32 7),(i32 7),(i32 7),(i32 7), ++ (i32 7),(i32 7),(i32 7),(i32 7), ++ (i32 7),(i32 7),(i32 7),(i32 7), ++ (i32 7),(i32 7),(i32 7),(i32 7), ++ (i32 7),(i32 7),(i32 7),(i32 7)) ++ ) ++ ) ++ ) ++ ) ++ ), ++ (v32i8 (build_vector (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1) ++ ))), ++ (XVAVG_B (v32i8 LASX256B:$a), (v32i8 LASX256B:$b))>; ++ ++def : LASXPat<(sra ++ (v16i16 (add ++ (v16i16 (add LASX256H:$a, LASX256H:$b)), ++ (v16i16 (srl ++ (v16i16 (add LASX256H:$a, LASX256H:$b)), ++ (v16i16 (build_vector (i32 15),(i32 15),(i32 15),(i32 15), ++ (i32 15),(i32 15),(i32 15),(i32 15), ++ (i32 15),(i32 15),(i32 15),(i32 15), ++ (i32 15),(i32 15),(i32 15),(i32 15)) ++ ) ++ ) ++ ) ++ ) ++ ), ++ (v16i16 (build_vector (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1) ++ ))), ++ (XVAVG_H (v16i16 LASX256H:$a), (v16i16 LASX256H:$b))>; ++ ++def : LASXPat<(sra ++ (v8i32 (add ++ (v8i32 (add LASX256W:$a, LASX256W:$b)), ++ (v8i32 (srl ++ (v8i32 (add LASX256W:$a, LASX256W:$b)), ++ (v8i32 (build_vector (i32 31),(i32 31),(i32 31),(i32 31), ++ (i32 31),(i32 31),(i32 31),(i32 31)) ++ ) ++ ) ++ ) ++ ) ++ ), ++ (v8i32 (build_vector (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1) ++ ))), ++ (XVAVG_W (v8i32 LASX256W:$a), (v8i32 LASX256W:$b))>; ++ ++def : LASXPat<(sra ++ (v4i64 (add ++ (v4i64 (add LASX256D:$a, LASX256D:$b)), ++ (v4i64 (srl ++ (v4i64 (add LASX256D:$a, LASX256D:$b)), ++ (v4i64 (build_vector (i64 63),(i64 63),(i64 63),(i64 63))) ++ ) ++ ) ++ ) ++ ), ++ (v4i64 (build_vector (i64 1),(i64 1),(i64 1),(i64 1)))), ++ (XVAVG_D (v4i64 LASX256D:$a), (v4i64 LASX256D:$b))>; ++ ++ ++ ++def : LASXPat<(srl ++ (v32i8 (add LASX256B:$a, LASX256B:$b)), ++ (v32i8 (build_vector (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1)) ++ ) ++ ), ++ (XVAVG_BU (v32i8 LASX256B:$a), (v32i8 LASX256B:$b))>; ++ ++def : LASXPat<(srl ++ (v16i16 (add LASX256H:$a, LASX256H:$b)), ++ (v16i16 (build_vector (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1)) ++ ) ++ ), ++ (XVAVG_HU (v16i16 LASX256H:$a), (v16i16 LASX256H:$b))>; ++ ++def : LASXPat<(srl ++ (v8i32 (add LASX256W:$a, LASX256W:$b)), ++ (v8i32 (build_vector (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1)) ++ ) ++ ), ++ (XVAVG_WU (v8i32 LASX256W:$a), (v8i32 LASX256W:$b))>; ++ ++def : LASXPat<(srl ++ (v4i64 (add LASX256D:$a, LASX256D:$b)), ++ (v4i64 (build_vector (i64 1),(i64 1),(i64 1),(i64 1)) ++ ) ++ ), ++ (XVAVG_DU (v4i64 LASX256D:$a), (v4i64 LASX256D:$b))>; ++ ++ ++ ++ ++ ++ ++def : LASXPat<(mulhs LASX256D:$a, LASX256D:$b), ++ (XVMUH_D LASX256D:$a, LASX256D:$b)>; ++ ++def : LASXPat<(mulhs LASX256W:$a, LASX256W:$b), ++ (XVMUH_W LASX256W:$a, LASX256W:$b)>; ++ ++def : LASXPat<(mulhs LASX256H:$a, LASX256H:$b), ++ (XVMUH_H LASX256H:$a, LASX256H:$b)>; ++ ++def : LASXPat<(mulhs LASX256B:$a, LASX256B:$b), ++ (XVMUH_B LASX256B:$a, LASX256B:$b)>; ++ ++ ++def : LASXPat<(mulhu LASX256D:$a, LASX256D:$b), ++ (XVMUH_DU LASX256D:$a, LASX256D:$b)>; ++ ++def : LASXPat<(mulhu LASX256W:$a, LASX256W:$b), ++ (XVMUH_WU LASX256W:$a, LASX256W:$b)>; ++ ++def : LASXPat<(mulhu LASX256H:$a, LASX256H:$b), ++ (XVMUH_HU LASX256H:$a, LASX256H:$b)>; ++ ++def : LASXPat<(mulhu LASX256B:$a, LASX256B:$b), ++ (XVMUH_BU LASX256B:$a, LASX256B:$b)>; ++ ++ ++def : LASXPat<(LoongArchINSVE (v8i32 LASX256W:$a), (v8i32 LASX256W:$b), uimm3:$ui3), ++ (XVINSVE0_W LASX256W:$a, LASX256W:$b, uimm3:$ui3)>; ++ ++def : LASXPat<(LoongArchINSVE (v4i64 LASX256D:$a), (v4i64 LASX256D:$b), uimm2:$ui2), ++ (XVINSVE0_D LASX256D:$a, LASX256D:$b, uimm2:$ui2)>; ++ ++ ++def : LASXPat<(LoongArchXVPICKVE (v8i32 (bitconvert (v32i8 (build_vector ++ (i32 0),(i32 0),(i32 0),(i32 0), ++ (i32 0),(i32 0),(i32 0),(i32 0), ++ (i32 0),(i32 0),(i32 0),(i32 0), ++ (i32 0),(i32 0),(i32 0),(i32 0), ++ (i32 0),(i32 0),(i32 0),(i32 0), ++ (i32 0),(i32 0),(i32 0),(i32 0), ++ (i32 0),(i32 0),(i32 0),(i32 0), ++ (i32 0),(i32 0),(i32 0),(i32 0) ++ )))), (v8i32 LASX256W:$b), uimm3:$ui3), ++ (XVPICKVE_W (v8i32 (IMPLICIT_DEF)), LASX256W:$b, uimm3:$ui3)>; ++ ++def : LASXPat<(LoongArchXVPICKVE (v4i64 (bitconvert (v32i8 (build_vector ++ (i32 0),(i32 0),(i32 0),(i32 0), ++ (i32 0),(i32 0),(i32 0),(i32 0), ++ (i32 0),(i32 0),(i32 0),(i32 0), ++ (i32 0),(i32 0),(i32 0),(i32 0), ++ (i32 0),(i32 0),(i32 0),(i32 0), ++ (i32 0),(i32 0),(i32 0),(i32 0), ++ (i32 0),(i32 0),(i32 0),(i32 0), ++ (i32 0),(i32 0),(i32 0),(i32 0) ++ )))), (v4i64 LASX256D:$b), uimm2:$ui2), ++ (XVPICKVE_D (v4i64 (IMPLICIT_DEF)), LASX256D:$b, uimm2:$ui2)>; ++ ++ ++def : LASXPat<(LoongArchXVPICKVE (v8i32 (build_vector ++ (i32 0),(i32 0),(i32 0),(i32 0), ++ (i32 0),(i32 0),(i32 0),(i32 0) ++ )), (v8i32 LASX256W:$b), uimm3:$ui3), ++ (XVPICKVE_W (v8i32 (IMPLICIT_DEF)), LASX256W:$b, uimm3:$ui3)>; ++ ++def : LASXPat<(LoongArchXVPICKVE (v4i64 (build_vector ++ (i64 0),(i64 0),(i64 0),(i64 0) ++ )), (v4i64 LASX256D:$b), uimm2:$ui2), ++ (XVPICKVE_D (v4i64 (IMPLICIT_DEF)), LASX256D:$b, uimm2:$ui2)>; ++ ++ ++def : LASXPat<(LoongArchXVPICKVE (v8i32 LASX256W:$a), (v8i32 LASX256W:$b), uimm3:$ui3), ++ (XVPICKVE_W LASX256W:$a, LASX256W:$b, uimm3:$ui3)>; ++ ++def : LASXPat<(LoongArchXVPICKVE (v4i64 LASX256D:$a), (v4i64 LASX256D:$b), uimm2:$ui2), ++ (XVPICKVE_D LASX256D:$a, LASX256D:$b, uimm2:$ui2)>; ++ ++ ++def : LASXPat<(LoongArchXVSHUF4I (v4i64 LASX256D:$a), (v4i64 LASX256D:$b), uimm8_32:$ui8), ++ (XVSHUF4I_D LASX256D:$a, LASX256D:$b, uimm8_32:$ui8)>; ++ ++def : LASXPat<(LoongArchXVPERMI (v4i64 LASX256D:$a), uimm8_32:$ui8), ++ (XVPERMI_D LASX256D:$a, uimm8_32:$ui8)>; ++ ++ ++ ++ ++//===----------------------------------------------------------------------===// ++// Intrinsics ++//===----------------------------------------------------------------------===// ++ ++def : LASXPat<(int_loongarch_lasx_xvfcmp_cor_s (v8f32 LASX256W:$xj), (v8f32 LASX256W:$xk)), ++ (XVFCMP_COR_S LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvfcmp_cor_d (v4f64 LASX256D:$xj), (v4f64 LASX256D:$xk)), ++ (XVFCMP_COR_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvfcmp_cun_s (v8f32 LASX256W:$xj), (v8f32 LASX256W:$xk)), ++ (XVFCMP_CUN_S LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvfcmp_cun_d (v4f64 LASX256D:$xj), (v4f64 LASX256D:$xk)), ++ (XVFCMP_CUN_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvfcmp_cune_s (v8f32 LASX256W:$xj), (v8f32 LASX256W:$xk)), ++ (XVFCMP_CUNE_S LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvfcmp_cune_d (v4f64 LASX256D:$xj), (v4f64 LASX256D:$xk)), ++ (XVFCMP_CUNE_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvfcmp_cueq_s (v8f32 LASX256W:$xj), (v8f32 LASX256W:$xk)), ++ (XVFCMP_CUEQ_S LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvfcmp_cueq_d (v4f64 LASX256D:$xj), (v4f64 LASX256D:$xk)), ++ (XVFCMP_CUEQ_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvfcmp_ceq_s (v8f32 LASX256W:$xj), (v8f32 LASX256W:$xk)), ++ (XVFCMP_CEQ_S LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvfcmp_ceq_d (v4f64 LASX256D:$xj), (v4f64 LASX256D:$xk)), ++ (XVFCMP_CEQ_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvfcmp_cne_s (v8f32 LASX256W:$xj), (v8f32 LASX256W:$xk)), ++ (XVFCMP_CNE_S LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvfcmp_cne_d (v4f64 LASX256D:$xj), (v4f64 LASX256D:$xk)), ++ (XVFCMP_CNE_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvfcmp_clt_s (v8f32 LASX256W:$xj), (v8f32 LASX256W:$xk)), ++ (XVFCMP_CLT_S LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvfcmp_clt_d (v4f64 LASX256D:$xj), (v4f64 LASX256D:$xk)), ++ (XVFCMP_CLT_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvfcmp_cult_s (v8f32 LASX256W:$xj), (v8f32 LASX256W:$xk)), ++ (XVFCMP_CULT_S LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvfcmp_cult_d (v4f64 LASX256D:$xj), (v4f64 LASX256D:$xk)), ++ (XVFCMP_CULT_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvfcmp_cle_s (v8f32 LASX256W:$xj), (v8f32 LASX256W:$xk)), ++ (XVFCMP_CLE_S LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvfcmp_cle_d (v4f64 LASX256D:$xj), (v4f64 LASX256D:$xk)), ++ (XVFCMP_CLE_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvfcmp_cule_s (v8f32 LASX256W:$xj), (v8f32 LASX256W:$xk)), ++ (XVFCMP_CULE_S LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvfcmp_cule_d (v4f64 LASX256D:$xj), (v4f64 LASX256D:$xk)), ++ (XVFCMP_CULE_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvseq_b (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVSEQ_B LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvseq_h (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVSEQ_H LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvseq_w (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVSEQ_W LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvseq_d (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVSEQ_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvsle_b (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVSLE_B LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsle_h (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVSLE_H LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsle_w (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVSLE_W LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsle_d (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVSLE_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvsle_bu (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVSLE_BU LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsle_hu (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVSLE_HU LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsle_wu (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVSLE_WU LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsle_du (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVSLE_DU LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvslt_b (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVSLT_B LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvslt_h (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVSLT_H LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvslt_w (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVSLT_W LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvslt_d (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVSLT_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvslt_bu (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVSLT_BU LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvslt_hu (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVSLT_HU LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvslt_wu (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVSLT_WU LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvslt_du (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVSLT_DU LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvadd_b (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVADD_B LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvadd_h (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVADD_H LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvadd_w (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVADD_W LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvadd_d (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVADD_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvsub_b (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVSUB_B LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsub_h (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVSUB_H LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsub_w (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVSUB_W LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsub_d (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVSUB_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvmax_b (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVMAX_B LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmax_h (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVMAX_H LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmax_w (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVMAX_W LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmax_d (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVMAX_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvmin_b (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVMIN_B LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmin_h (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVMIN_H LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmin_w (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVMIN_W LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmin_d (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVMIN_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvmin_bu (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVMIN_BU LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmin_hu (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVMIN_HU LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmin_wu (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVMIN_WU LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmin_du (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVMIN_DU LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvmul_b (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVMUL_B LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmul_h (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVMUL_H LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmul_w (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVMUL_W LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmul_d (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVMUL_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvdiv_bu (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVDIV_BU LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvdiv_hu (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVDIV_HU LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvdiv_wu (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVDIV_WU LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvdiv_du (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVDIV_DU LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvsll_b (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVSLL_B LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsll_h (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVSLL_H LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsll_w (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVSLL_W LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsll_d (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVSLL_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvsrl_b (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVSRL_B LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsrl_h (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVSRL_H LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsrl_w (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVSRL_W LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsrl_d (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVSRL_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvsra_b (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVSRA_B LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsra_h (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVSRA_H LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsra_w (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVSRA_W LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsra_d (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVSRA_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvfadd_s (v8f32 LASX256W:$xj), (v8f32 LASX256W:$xk)), ++ (XVFADD_S LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvfadd_d (v4f64 LASX256D:$xj), (v4f64 LASX256D:$xk)), ++ (XVFADD_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvfsub_s (v8f32 LASX256W:$xj), (v8f32 LASX256W:$xk)), ++ (XVFSUB_S LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvfsub_d (v4f64 LASX256D:$xj), (v4f64 LASX256D:$xk)), ++ (XVFSUB_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvfmul_s (v8f32 LASX256W:$xj), (v8f32 LASX256W:$xk)), ++ (XVFMUL_S LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvfmul_d (v4f64 LASX256D:$xj), (v4f64 LASX256D:$xk)), ++ (XVFMUL_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvfdiv_s (v8f32 LASX256W:$xj), (v8f32 LASX256W:$xk)), ++ (XVFDIV_S LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvfdiv_d (v4f64 LASX256D:$xj), (v4f64 LASX256D:$xk)), ++ (XVFDIV_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvfsqrt_s (v8f32 LASX256W:$xj)), ++ (XVFSQRT_S LASX256W:$xj)>; ++def : LASXPat<(int_loongarch_lasx_xvfsqrt_d (v4f64 LASX256D:$xj)), ++ (XVFSQRT_D LASX256D:$xj)>; ++ ++def : LASXPat<(v8f32 (int_loongarch_lasx_xvffint_s_w (v8i32 LASX256W:$xj))), ++ (XVFFINT_S_W (v8i32 LASX256W:$xj))>; ++def : LASXPat<(v8f32 (int_loongarch_lasx_xvffint_s_wu (v8i32 LASX256W:$xj))), ++ (XVFFINT_S_WU (v8i32 LASX256W:$xj))>; ++ ++def : LASXPat<(v4f64 (int_loongarch_lasx_xvffint_d_l (v4i64 LASX256D:$xj))), ++ (XVFFINT_D_L (v4i64 LASX256D:$xj))>; ++def : LASXPat<(v4f64 (int_loongarch_lasx_xvffint_d_lu (v4i64 LASX256D:$xj))), ++ (XVFFINT_D_LU (v4i64 LASX256D:$xj))>; ++ ++def : LASXPat<(int_loongarch_lasx_xvreplgr2vr_b GPR32Opnd:$rj), ++ (XVREPLGR2VR_B GPR32Opnd:$rj)>; ++def : LASXPat<(int_loongarch_lasx_xvreplgr2vr_h GPR32Opnd:$rj), ++ (XVREPLGR2VR_H GPR32Opnd:$rj)>; ++def : LASXPat<(int_loongarch_lasx_xvreplgr2vr_w GPR32Opnd:$rj), ++ (XVREPLGR2VR_W GPR32Opnd:$rj)>; ++def : LASXPat<(int_loongarch_lasx_xvreplgr2vr_d GPR64Opnd:$rj), ++ (XVREPLGR2VR_D GPR64Opnd:$rj)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvpickve2gr_w (v8i32 LASX256W:$xj), (immZExt3:$ui3)), ++ (XVPICKVE2GR_W LASX256W:$xj, uimm3:$ui3)>; ++def : LASXPat<(int_loongarch_lasx_xvpickve2gr_d (v4i64 LASX256D:$xj), (immZExt2:$ui2)), ++ (XVPICKVE2GR_D LASX256D:$xj, uimm2:$ui2)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvpickve2gr_wu (v8i32 LASX256W:$xj), (immZExt3:$ui3)), ++ (XVPICKVE2GR_WU LASX256W:$xj, uimm3:$ui3)>; ++def : LASXPat<(int_loongarch_lasx_xvpickve2gr_du (v4i64 LASX256D:$xj), (immZExt2:$ui2)), ++ (XVPICKVE2GR_DU LASX256D:$xj, uimm2:$ui2)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvreplve0_d (v4i64 LASX256D:$xj)), ++ (XVREPLVE0_D (v4i64 LASX256D:$xj))>; ++ ++def : LASXPat<(int_loongarch_lasx_xvinsgr2vr_w (v8i32 LASX256W:$xj), GPR32Opnd:$rj, (immZExt3:$ui3)), ++ (XVINSGR2VR_W LASX256W:$xj, GPR32Opnd:$rj, uimm3:$ui3)>; ++def : LASXPat<(int_loongarch_lasx_xvinsgr2vr_d (v4i64 LASX256D:$xj), GPR64Opnd:$rj, (immZExt2:$ui2)), ++ (XVINSGR2VR_D LASX256D:$xj, GPR64Opnd:$rj, uimm2:$ui2)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvpickve_w (v8i32 LASX256W:$xj), (immZExt3:$ui3)), ++ (XVPICKVE_W (v8i32 (IMPLICIT_DEF)), LASX256W:$xj, uimm3:$ui3)>; ++def : LASXPat<(int_loongarch_lasx_xvpickve_d (v4i64 LASX256D:$xj), (immZExt2:$ui2)), ++ (XVPICKVE_D (v4i64 (IMPLICIT_DEF)), LASX256D:$xj, uimm2:$ui2)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvpickve_w_f (v8f32 LASX256W:$xj), (immZExt3:$ui3)), ++ (XVPICKVE_W (v8f32 (IMPLICIT_DEF)), LASX256W:$xj, uimm3:$ui3)>; ++def : LASXPat<(int_loongarch_lasx_xvpickve_d_f (v4f64 LASX256D:$xj), (immZExt2:$ui2)), ++ (XVPICKVE_D (v4f64 (IMPLICIT_DEF)), LASX256D:$xj, uimm2:$ui2)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvdiv_b (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVDIV_B LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvdiv_h (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVDIV_H LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvdiv_w (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVDIV_W LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvdiv_d (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVDIV_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvmod_bu (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVMOD_BU LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmod_hu (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVMOD_HU LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmod_wu (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVMOD_WU LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmod_du (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVMOD_DU LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvmod_b (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVMOD_B LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmod_h (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVMOD_H LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmod_w (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVMOD_W LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmod_d (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVMOD_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvmax_bu (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVMAX_BU LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmax_hu (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVMAX_HU LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmax_wu (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVMAX_WU LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmax_du (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVMAX_DU LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvfrint_s (v8f32 LASX256W:$xj)), ++ (XVFRINT_S LASX256W:$xj)>; ++def : LASXPat<(int_loongarch_lasx_xvfrint_d (v4f64 LASX256D:$xj)), ++ (XVFRINT_D LASX256D:$xj)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvpackod_b (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVPACKOD_B LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvpackod_h (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVPACKOD_H LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvpackod_w (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVPACKOD_W LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvpackod_d (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVPACKOD_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvpackev_b (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVPACKEV_B LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvpackev_h (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVPACKEV_H LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvpackev_w (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVPACKEV_W LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvpackev_d (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVPACKEV_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvilvh_b (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVILVH_B LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvilvh_h (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVILVH_H LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvilvh_w (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVILVH_W LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvilvh_d (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVILVH_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvilvl_b (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVILVL_B LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvilvl_h (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVILVL_H LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvilvl_w (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVILVL_W LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvilvl_d (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVILVL_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvpickev_b (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVPICKEV_B LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvpickev_h (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVPICKEV_H LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvpickev_w (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVPICKEV_W LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvpickev_d (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVPICKEV_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvpickod_b (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVPICKOD_B LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvpickod_h (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVPICKOD_H LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvpickod_w (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVPICKOD_W LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvpickod_d (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVPICKOD_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvsadd_b (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVSADD_B LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsadd_h (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVSADD_H LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsadd_w (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVSADD_W LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsadd_d (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVSADD_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvssub_b (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVSSUB_B LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvssub_h (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVSSUB_H LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvssub_w (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVSSUB_W LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvssub_d (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVSSUB_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvsadd_bu (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVSADD_BU LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsadd_hu (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVSADD_HU LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsadd_wu (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVSADD_WU LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvsadd_du (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVSADD_DU LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvssub_bu (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVSSUB_BU LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvssub_hu (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVSSUB_HU LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvssub_wu (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVSSUB_WU LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvssub_du (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVSSUB_DU LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvmadd_b (v32i8 LASX256B:$xd_in), (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVMADD_B LASX256B:$xd_in, LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmadd_h (v16i16 LASX256H:$xd_in), (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVMADD_H LASX256H:$xd_in, LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmadd_w (v8i32 LASX256W:$xd_in), (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVMADD_W LASX256W:$xd_in, LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmadd_d (v4i64 LASX256D:$xd_in), (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVMADD_D LASX256D:$xd_in, LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvmsub_b (v32i8 LASX256B:$xd_in), (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVMSUB_B LASX256B:$xd_in, LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmsub_h (v16i16 LASX256H:$xd_in), (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVMSUB_H LASX256H:$xd_in, LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmsub_w (v8i32 LASX256W:$xd_in), (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVMSUB_W LASX256W:$xd_in, LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvmsub_d (v4i64 LASX256D:$xd_in), (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVMSUB_D LASX256D:$xd_in, LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(v8i32 (int_loongarch_lasx_xvftintrz_wu_s (v8f32 LASX256W:$xj))), ++ (XVFTINTRZ_WU_S (v8f32 LASX256W:$xj))>; ++def : LASXPat<(v4i64 (int_loongarch_lasx_xvftintrz_lu_d (v4f64 LASX256D:$xj))), ++ (XVFTINTRZ_LU_D (v4f64 LASX256D:$xj))>; ++ ++def : LASXPat<(v8i32 (int_loongarch_lasx_xvftintrz_w_s (v8f32 LASX256W:$xj))), ++ (XVFTINTRZ_W_S (v8f32 LASX256W:$xj))>; ++def : LASXPat<(v4i64 (int_loongarch_lasx_xvftintrz_l_d (v4f64 LASX256D:$xj))), ++ (XVFTINTRZ_L_D (v4f64 LASX256D:$xj))>; ++ ++def : LASXPat<(int_loongarch_lasx_xvbitclr_b (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk)), ++ (XVBITCLR_B LASX256B:$xj, LASX256B:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvbitclr_h (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk)), ++ (XVBITCLR_H LASX256H:$xj, LASX256H:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvbitclr_w (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk)), ++ (XVBITCLR_W LASX256W:$xj, LASX256W:$xk)>; ++def : LASXPat<(int_loongarch_lasx_xvbitclr_d (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk)), ++ (XVBITCLR_D LASX256D:$xj, LASX256D:$xk)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvclz_b (v32i8 LASX256B:$xj)), ++ (XVCLZ_B LASX256B:$xj)>; ++def : LASXPat<(int_loongarch_lasx_xvclz_h (v16i16 LASX256H:$xj)), ++ (XVCLZ_H LASX256H:$xj)>; ++def : LASXPat<(int_loongarch_lasx_xvclz_w (v8i32 LASX256W:$xj)), ++ (XVCLZ_W LASX256W:$xj)>; ++def : LASXPat<(int_loongarch_lasx_xvclz_d (v4i64 LASX256D:$xj)), ++ (XVCLZ_D LASX256D:$xj)>; ++ ++def : LASXPat<(int_loongarch_lasx_xvpcnt_b (v32i8 LASX256B:$xj)), ++ (XVPCNT_B LASX256B:$xj)>; ++def : LASXPat<(int_loongarch_lasx_xvpcnt_h (v16i16 LASX256H:$xj)), ++ (XVPCNT_H LASX256H:$xj)>; ++def : LASXPat<(int_loongarch_lasx_xvpcnt_w (v8i32 LASX256W:$xj)), ++ (XVPCNT_W LASX256W:$xj)>; ++def : LASXPat<(int_loongarch_lasx_xvpcnt_d (v4i64 LASX256D:$xj)), ++ (XVPCNT_D LASX256D:$xj)>; ++ ++ ++def : LASXPat<(v32i8 (load (add iPTR:$xj, iPTR:$xk))), ++ (XVLDX PtrRC:$xj, PtrRC:$xk)>; ++ ++def : LASXPat<(store (v32i8 LASX256B:$xd), (add iPTR:$xj, iPTR:$xk)), ++ (XVSTX LASX256B:$xd, PtrRC:$xj, PtrRC:$xk)>; ++ ++ ++def : LASXPat<(v4i64 (sext_invec (v8i32 LASX256W:$xj))), ++ (VEXT2XV_D_W LASX256W:$xj)>; ++def : LASXPat<(v8i32 (sext_invec (v16i16 LASX256H:$xj))), ++ (VEXT2XV_W_H LASX256H:$xj)>; ++def : LASXPat<(v16i16 (sext_invec (v32i8 LASX256B:$xj))), ++ (VEXT2XV_H_B LASX256B:$xj)>; ++ ++ ++def : LASXPat<(v4i64 (zext_invec (v8i32 LASX256W:$xj))), ++ (VEXT2XV_DU_WU LASX256W:$xj)>; ++def : LASXPat<(v8i32 (zext_invec (v16i16 LASX256H:$xj))), ++ (VEXT2XV_WU_HU LASX256H:$xj)>; ++def : LASXPat<(v16i16 (zext_invec (v32i8 LASX256B:$xj))), ++ (VEXT2XV_HU_BU LASX256B:$xj)>; ++ ++ ++def : LASXPat<(v4i64 (sext_invec (v16i16 LASX256H:$xj))), ++ (VEXT2XV_D_H LASX256H:$xj)>; ++def : LASXPat<(v4i64 (sext_invec (v32i8 LASX256B:$xj))), ++ (VEXT2XV_D_B LASX256B:$xj)>; ++def : LASXPat<(v8i32 (sext_invec (v32i8 LASX256B:$xj))), ++ (VEXT2XV_W_B LASX256B:$xj)>; ++ ++ ++def : LASXPat<(v4i64 (zext_invec (v16i16 LASX256H:$xj))), ++ (VEXT2XV_DU_HU LASX256H:$xj)>; ++def : LASXPat<(v4i64 (zext_invec (v32i8 LASX256B:$xj))), ++ (VEXT2XV_DU_BU LASX256B:$xj)>; ++def : LASXPat<(v8i32 (zext_invec (v32i8 LASX256B:$xj))), ++ (VEXT2XV_WU_BU LASX256B:$xj)>; ++ ++ ++def : LASXPat<(v4i64 (sext_invec (v16i16 LASX256H:$xj))), ++ (VEXT2XV_D_H LASX256H:$xj)>; ++def : LASXPat<(v4i64 (sext_invec (v32i8 LASX256B:$xj))), ++ (VEXT2XV_D_B LASX256B:$xj)>; ++def : LASXPat<(v8i32 (sext_invec (v32i8 LASX256B:$xj))), ++ (VEXT2XV_W_B LASX256B:$xj)>; ++ ++def : LASXPat<(v4i64 (zext_invec (v16i16 LASX256H:$xj))), ++ (VEXT2XV_DU_HU LASX256H:$xj)>; ++def : LASXPat<(v4i64 (zext_invec (v32i8 LASX256B:$xj))), ++ (VEXT2XV_DU_BU LASX256B:$xj)>; ++def : LASXPat<(v8i32 (zext_invec (v32i8 LASX256B:$xj))), ++ (VEXT2XV_WU_BU LASX256B:$xj)>; ++ ++ ++def : LASXPat<(v16i16 (sext (v16i8 LSX128B:$vj))), ++ (VEXT2XV_H_B ++ (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), LSX128B:$vj, sub_128))>; ++ ++def : LASXPat<(v8i32 (sext (v8i16 LSX128H:$vj))), ++ (VEXT2XV_W_H ++ (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), LSX128H:$vj, sub_128))>; ++ ++def : LASXPat<(v4i64 (sext (v4i32 LSX128W:$vj))), ++ (VEXT2XV_D_W ++ (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), LSX128W:$vj, sub_128))>; ++ ++def : LASXPat<(v16i16 (zext (v16i8 LSX128B:$vj))), ++ (VEXT2XV_HU_BU ++ (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), LSX128B:$vj, sub_128))>; ++ ++def : LASXPat<(v8i32 (zext (v8i16 LSX128H:$vj))), ++ (VEXT2XV_WU_HU ++ (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), LSX128H:$vj, sub_128))>; ++ ++def : LASXPat<(v4i64 (zext (v4i32 LSX128W:$vj))), ++ (VEXT2XV_DU_WU ++ (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), LSX128W:$vj, sub_128))>; ++ ++ ++def : LASXPat<(xor ++ (v16i16 LASX256H:$xj), (xvsplati16 imm_mask) ++ ), ++ (XNOR_V_H_PSEUDO (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xj))>; ++ ++def : LASXPat<(xor ++ (v8i32 LASX256W:$xj), (xvsplati32 imm_mask) ++ ), ++ (XNOR_V_W_PSEUDO (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xj))>; ++ ++def : LASXPat<(xor ++ (v4i64 LASX256D:$xj), (xvsplati64 imm_mask_64) ++ ), ++ (XNOR_V_D_PSEUDO (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xj))>; ++ ++ ++def : LASXPat<(and ++ (v32i8 (xor (v32i8 LASX256B:$xj), (xvsplati8 imm_mask))), ++ (v32i8 LASX256B:$xk) ++ ), ++ (XVANDN_V (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk))>; ++ ++def : LASXPat<(and ++ (v16i16 (xor (v16i16 LASX256H:$xj), (xvsplati16 imm_mask))), ++ (v16i16 LASX256H:$xk) ++ ), ++ (XVANDN_H_PSEUDO (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk))>; ++ ++def : LASXPat<(and ++ (v8i32 (xor (v8i32 LASX256W:$xj), (xvsplati32 imm_mask))), ++ (v8i32 LASX256W:$xk) ++ ), ++ (XVANDN_W_PSEUDO (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk))>; ++ ++def : LASXPat<(and ++ (v4i64 (xor (v4i64 LASX256D:$xj), (xvsplati64 imm_mask_64))), ++ (v4i64 LASX256D:$xk) ++ ), ++ (XVANDN_D_PSEUDO (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk))>; ++ ++ ++def : LASXPat<(or ++ (v32i8 LASX256B:$xj), ++ (v32i8 (xor (v32i8 LASX256B:$xk), (xvsplati8 imm_mask))) ++ ), ++ (XVORN_V (v32i8 LASX256B:$xj), (v32i8 LASX256B:$xk))>; ++ ++def : LASXPat<(or ++ (v16i16 LASX256H:$xj), ++ (v16i16 (xor (v16i16 LASX256H:$xk), (xvsplati16 imm_mask))) ++ ), ++ (XVORN_H_PSEUDO (v16i16 LASX256H:$xj), (v16i16 LASX256H:$xk))>; ++ ++def : LASXPat<(or ++ (v8i32 LASX256W:$xj), ++ (v8i32 (xor (v8i32 LASX256W:$xk), (xvsplati32 imm_mask))) ++ ), ++ (XVORN_W_PSEUDO (v8i32 LASX256W:$xj), (v8i32 LASX256W:$xk))>; ++ ++def : LASXPat<(or ++ (v4i64 LASX256D:$xj), ++ (v4i64 (xor (v4i64 LASX256D:$xk), (xvsplati64 imm_mask_64))) ++ ), ++ (XVORN_D_PSEUDO (v4i64 LASX256D:$xj), (v4i64 LASX256D:$xk))>; ++ ++ ++def : LASXPat<(add (v4i64 (abs LASX256D:$a)), (v4i64 (abs LASX256D:$b))), ++ (XVADDA_D (v4i64 LASX256D:$a),(v4i64 LASX256D:$b))>; ++ ++def : LASXPat<(add (v8i32 (abs LASX256W:$a)), (v8i32 (abs LASX256W:$b))), ++ (XVADDA_W (v8i32 LASX256W:$a),(v8i32 LASX256W:$b))>; ++ ++def : LASXPat<(add (v16i16 (abs LASX256H:$a)), (v16i16 (abs LASX256H:$b))), ++ (XVADDA_H (v16i16 LASX256H:$a),(v16i16 LASX256H:$b))>; ++ ++def : LASXPat<(add (v32i8 (abs LASX256B:$a)), (v32i8 (abs LASX256B:$b))), ++ (XVADDA_B (v32i8 LASX256B:$a),(v32i8 LASX256B:$b))>; ++ ++ ++def : LASXPat<(and v32i8:$xj, (xor (shl xvsplat_imm_eq_1, v32i8:$xk), ++ (xvsplati8 imm_mask))), ++ (XVBITCLR_B v32i8:$xj, v32i8:$xk)>; ++ ++def : LASXPat<(and v16i16:$xj, (xor (shl xvsplat_imm_eq_1, v16i16:$xk), ++ (xvsplati16 imm_mask))), ++ (XVBITCLR_H v16i16:$xj, v16i16:$xk)>; ++ ++def : LASXPat<(and v8i32:$xj, (xor (shl xvsplat_imm_eq_1, v8i32:$xk), ++ (xvsplati32 imm_mask))), ++ (XVBITCLR_W v8i32:$xj, v8i32:$xk)>; ++ ++def : LASXPat<(and v4i64:$xj, (xor (shl xvsplat_imm_eq_1, v4i64:$xk), ++ (xvsplati64 imm_mask_64))), ++ (XVBITCLR_D v4i64:$xj, v4i64:$xk)>; ++ ++ ++def : LASXPat<(insert_subvector (v32i8 LASX256B:$dst), ++ (v16i8 LSX128B:$src), (i64 0)), ++ (XVPERMI_Q (v32i8 LASX256B:$dst), ++ (v32i8 (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), ++ LSX128B:$src, sub_128)), ++ (i32 48))>; ++ ++def : LASXPat<(insert_subvector (v16i16 LASX256H:$dst), ++ (v8i16 LSX128H:$src), (i64 0)), ++ (XVPERMI_QH (v16i16 LASX256H:$dst), ++ (v16i16 (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), ++ LSX128H:$src, sub_128)), ++ (i32 48))>; ++ ++def : LASXPat<(insert_subvector (v8i32 LASX256W:$dst), ++ (v4i32 LSX128W:$src), (i64 0)), ++ (XVPERMI_QW (v8i32 LASX256W:$dst), ++ (v8i32 (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), ++ LSX128W:$src, sub_128)), ++ (i32 48))>; ++ ++def : LASXPat<(insert_subvector (v4i64 LASX256D:$dst), ++ (v2i64 LSX128D:$src), (i64 0)), ++ (XVPERMI_QD (v4i64 LASX256D:$dst), ++ (v4i64 (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), ++ LSX128D:$src, sub_128)), ++ (i32 48))>; ++ ++def : LASXPat<(insert_subvector (v4i64 LASX256D:$dst), ++ (v2i64 LSX128D:$src), (i64 2)), ++ (XVPERMI_QD (v4i64 LASX256D:$dst), ++ (v4i64 (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), ++ LSX128D:$src, sub_128)), (i32 32))>; ++ ++def : LASXPat<(insert_subvector (v8i32 LASX256W:$dst), ++ (v4i32 LSX128W:$src), (i64 4)), ++ (XVPERMI_QW (v8i32 LASX256W:$dst), ++ (v8i32 (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), ++ LSX128W:$src, sub_128)), (i32 32))>; ++ ++def : LASXPat<(insert_subvector (v16i16 LASX256H:$dst), ++ (v8i16 LSX128H:$src), (i64 8)), ++ (XVPERMI_QH (v16i16 LASX256H:$dst), ++ (v16i16 (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), ++ LSX128H:$src, sub_128)), (i32 32))>; ++ ++def : LASXPat<(insert_subvector (v32i8 LASX256B:$dst), ++ (v16i8 LSX128B:$src), (i64 16)), ++ (XVPERMI_Q (v32i8 LASX256B:$dst), ++ (v32i8 (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), ++ LSX128B:$src, sub_128)), (i32 32))>; +diff --git a/llvm/lib/Target/LoongArch/LoongArchLBTInstrFormats.td b/llvm/lib/Target/LoongArch/LoongArchLBTInstrFormats.td +deleted file mode 100644 +index 2faee056e..000000000 +--- a/llvm/lib/Target/LoongArch/LoongArchLBTInstrFormats.td ++++ /dev/null +@@ -1,256 +0,0 @@ +-// LoongArchLBTInstrFormats.td - LoongArch LBT Instr Formats -*- tablegen -*-=// +-// +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +-// +-//===----------------------------------------------------------------------===// +- +-//===----------------------------------------------------------------------===// +-// Describe LoongArch LBT instructions format +-// +-// opcode - operation code. +-// rd/sd - destination register operand. +-// rj/rk/sj - source register operand. +-// immN/ptr - immediate data operand. +-// +-// Note: The definition of "NoDstFmt..." conveys the meaning of no explicit +-// output operand. In other words, there will be no output operand in the +-// assembly notation of these instructions. In fact, they always manipulate +-// the "EFLAGS" register. +-// Since these instructions are currently not used for code generation, +-// we do not need to add `let Defs/Uses = [EFLAGS]`. +-//===----------------------------------------------------------------------===// +- +-// 1R-type (no outs) +-// +-class NoDstFmt1R op> +- : LAInst<(outs), (ins GPR:$rj), +- deriveInsnMnemonic.ret, "$rj"> { +- bits<5> rj; +- +- let Inst{31-0} = op; +- let Inst{9-5} = rj; +-} +- +-// 1RI3-type (no outs) +-// +-class NoDstFmt1RI3 op> +- : LAInst<(outs), (ins GPR:$rj, uimm3:$imm3), +- deriveInsnMnemonic.ret, "$rj, $imm3"> { +- bits<3> imm3; +- bits<5> rj; +- +- let Inst{31-0} = op; +- let Inst{12-10} = imm3; +- let Inst{9-5} = rj; +-} +- +-// 1RI4-type (no outs) +-// +-class NoDstFmt1RI4 op> +- : LAInst<(outs), (ins GPR:$rj, uimm4:$imm4), +- deriveInsnMnemonic.ret, "$rj, $imm4"> { +- bits<4> imm4; +- bits<5> rj; +- +- let Inst{31-0} = op; +- let Inst{13-10} = imm4; +- let Inst{9-5} = rj; +-} +- +-// 1RI4-type +-// +-class Fmt1RI4 op> +- : LAInst<(outs GPR:$rd), (ins uimm4:$imm4), +- deriveInsnMnemonic.ret, "$rd, $imm4"> { +- bits<4> imm4; +- bits<5> rd; +- +- let Inst{31-0} = op; +- let Inst{13-10} = imm4; +- let Inst{4-0} = rd; +-} +- +-// 1RI5-type (no outs) +-// +-class NoDstFmt1RI5 op> +- : LAInst<(outs), (ins GPR:$rj, uimm5:$imm5), +- deriveInsnMnemonic.ret, "$rj, $imm5"> { +- bits<5> imm5; +- bits<5> rj; +- +- let Inst{31-0} = op; +- let Inst{14-10} = imm5; +- let Inst{9-5} = rj; +-} +- +-// 1RI5I4-type (no outs) +-// +-class NoDstFmt1RI5I4 op> +- : LAInst<(outs), (ins GPR:$rj, uimm5:$imm5, uimm4:$imm4), +- deriveInsnMnemonic.ret, "$rj, $imm5, $imm4"> { +- bits<5> imm5; +- bits<5> rj; +- bits<4> imm4; +- +- let Inst{31-0} = op; +- let Inst{14-10} = imm5; +- let Inst{9-5} = rj; +- let Inst{3-0} = imm4; +-} +- +-// 1RI5I8-type +-// +-class Fmt1RI5I8 op> +- : LAInst<(outs GPR:$rd), (ins uimm5:$imm5, uimm8:$imm8), +- deriveInsnMnemonic.ret, "$rd, $imm5, $imm8"> { +- bits<8> imm8; +- bits<5> imm5; +- bits<5> rd; +- +- let Inst{31-0} = op; +- let Inst{17-10} = imm8; +- let Inst{9-5} = imm5; +- let Inst{4-0} = rd; +-} +- +-// 1RI6-type (no outs) +-// +-class NoDstFmt1RI6 op> +- : LAInst<(outs), (ins GPR:$rj, uimm6:$imm6), +- deriveInsnMnemonic.ret, "$rj, $imm6"> { +- bits<6> imm6; +- bits<5> rj; +- +- let Inst{31-0} = op; +- let Inst{15-10} = imm6; +- let Inst{9-5} = rj; +-} +- +-// 1RI8-type +-// +-class Fmt1RI8 op> +- : LAInst<(outs GPR:$rd), (ins uimm8:$imm8), +- deriveInsnMnemonic.ret, "$rd, $imm8"> { +- bits<8> imm8; +- bits<5> rd; +- +- let Inst{31-0} = op; +- let Inst{17-10} = imm8; +- let Inst{4-0} = rd; +-} +- +-// 2R-type (no outs) +-// +-class NoDstFmt2R op> +- : LAInst<(outs), (ins GPR:$rj, GPR:$rk), +- deriveInsnMnemonic.ret, "$rj, $rk"> { +- bits<5> rk; +- bits<5> rj; +- +- let Inst{31-0} = op; +- let Inst{14-10} = rk; +- let Inst{9-5} = rj; +-} +- +-// 2RI4-type (no outs) +-// +-class NoDstFmt2RI4 op> +- : LAInst<(outs), (ins GPR:$rj, GPR:$rk, uimm4:$imm4), +- deriveInsnMnemonic.ret, "$rj, $rk, $imm4"> { +- bits<4> imm4; +- bits<5> rk; +- bits<5> rj; +- +- let Inst{31-0} = op; +- let Inst{14-10} = rk; +- let Inst{9-5} = rj; +- let Inst{3-0} = imm4; +-} +- +-// 2RI3-type +-// +-class Fmt2RI3 op> +- : LAInst<(outs GPR:$rd), (ins GPR:$rj, uimm3:$imm3), +- deriveInsnMnemonic.ret, "$rd, $rj, $imm3"> { +- bits<3> imm3; +- bits<5> rj; +- bits<5> rd; +- +- let Inst{31-0} = op; +- let Inst{12-10} = imm3; +- let Inst{9-5} = rj; +- let Inst{4-0} = rd; +-} +- +-// 2RI4-type +-// +-class Fmt2RI4 op> +- : LAInst<(outs GPR:$rd), (ins GPR:$rj, uimm4:$imm4), +- deriveInsnMnemonic.ret, "$rd, $rj, $imm4"> { +- bits<4> imm4; +- bits<5> rj; +- bits<5> rd; +- +- let Inst{31-0} = op; +- let Inst{13-10} = imm4; +- let Inst{9-5} = rj; +- let Inst{4-0} = rd; +-} +- +-// +-class FmtGR2SCR op> +- : LAInst<(outs SCR:$sd), (ins GPR:$rj), deriveInsnMnemonic.ret, +- "$sd, $rj"> { +- bits<5> rj; +- bits<2> sd; +- +- let Inst{31-0} = op; +- let Inst{9-5} = rj; +- let Inst{1-0} = sd; +-} +- +-// +-class FmtSCR2GR op> +- : LAInst<(outs GPR:$rd), (ins SCR:$sj), deriveInsnMnemonic.ret, +- "$rd, $sj"> { +- bits<2> sj; +- bits<5> rd; +- +- let Inst{31-0} = op; +- let Inst{6-5} = sj; +- let Inst{4-0} = rd; +-} +- +-// +-class FmtJISCR op> +- : LAInst<(outs), (ins simm21_lsl2:$imm21), deriveInsnMnemonic.ret, +- "$imm21"> { +- bits<21> imm21; +- bits<5> rj; +- +- let Inst{31-0} = op; +- let Inst{25-10} = imm21{15-0}; +- let Inst{4-0} = imm21{20-16}; +-} +- +-// +-class FmtMFTOP op> +- : LAInst<(outs GPR:$rd), (ins), deriveInsnMnemonic.ret, +- "$rd"> { +- bits<5> rd; +- +- let Inst{31-0} = op; +- let Inst{4-0} = rd; +-} +- +-// +-class FmtMTTOP op> +- : LAInst<(outs), (ins uimm3:$ptr), deriveInsnMnemonic.ret, +- "$ptr"> { +- bits<3> ptr; +- +- let Inst{31-0} = op; +- let Inst{7-5} = ptr; +-} +diff --git a/llvm/lib/Target/LoongArch/LoongArchLBTInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchLBTInstrInfo.td +deleted file mode 100644 +index 76e927016..000000000 +--- a/llvm/lib/Target/LoongArch/LoongArchLBTInstrInfo.td ++++ /dev/null +@@ -1,241 +0,0 @@ +-//===- LoongArchLBTInstrInfo.td - LoongArch LBT instructions -*- tablegen -*-=// +-// +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +-// +-//===----------------------------------------------------------------------===// +-// +-// This file describes the LBT extension instructions. +-// +-//===----------------------------------------------------------------------===// +- +-//===----------------------------------------------------------------------===// +-// Instructions +-//===----------------------------------------------------------------------===// +- +-let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Predicates = [HasExtLBT] in { +- +-def MOVGR2SCR : FmtGR2SCR<0x00000800>; +-def MOVSCR2GR : FmtSCR2GR<0x00000c00>; +- +-def JISCR0 : FmtJISCR<0x48000200>; +-def JISCR1 : FmtJISCR<0x48000300>; +- +-def ADDU12I_W : ALU_2RI5<0x00290000, simm5>; +- +-def ADC_B : ALU_3R<0x00300000>; +-def ADC_H : ALU_3R<0x00308000>; +-def ADC_W : ALU_3R<0x00310000>; +- +-def SBC_B : ALU_3R<0x00320000>; +-def SBC_H : ALU_3R<0x00328000>; +-def SBC_W : ALU_3R<0x00330000>; +- +-def ROTR_B : ALU_3R<0x001a0000>; +-def ROTR_H : ALU_3R<0x001a8000>; +- +-def ROTRI_B : Fmt2RI3<0x004c2000>; +-def ROTRI_H : Fmt2RI4<0x004c4000>; +- +-def RCR_B : ALU_3R<0x00340000>; +-def RCR_H : ALU_3R<0x00348000>; +-def RCR_W : ALU_3R<0x00350000>; +- +-def RCRI_B : Fmt2RI3<0x00502000>; +-def RCRI_H : Fmt2RI4<0x00504000>; +-def RCRI_W : ALU_2RI5<0x00508000, uimm5>; +- +-def FCVT_UD_D : FP_CONV<0x0114e400>; +-def FCVT_LD_D : FP_CONV<0x0114e000>; +-def FCVT_D_LD : FP_ALU_3R<0x01150000>; +- +-let mayLoad = 1 in { +-def LDL_W : LOAD_2RI12<0x2e000000>; +-def LDR_W : LOAD_2RI12<0x2e400000>; +-} // mayLoad = 1 +- +-let mayStore = 1 in { +-def STL_W : STORE_2RI12<0x2f000000>; +-def STR_W : STORE_2RI12<0x2f400000>; +-} // mayStore = 1 +- +-def X86ADC_B : NoDstFmt2R<0x003f000c>; +-def X86ADC_H : NoDstFmt2R<0x003f000d>; +-def X86ADC_W : NoDstFmt2R<0x003f000e>; +-def X86ADD_B : NoDstFmt2R<0x003f0004>; +-def X86ADD_H : NoDstFmt2R<0x003f0005>; +-def X86ADD_W : NoDstFmt2R<0x003f0006>; +- +-def X86INC_B : NoDstFmt1R<0x00008000>; +-def X86INC_H : NoDstFmt1R<0x00008001>; +-def X86INC_W : NoDstFmt1R<0x00008002>; +- +-def X86SBC_B : NoDstFmt2R<0x003f0010>; +-def X86SBC_H : NoDstFmt2R<0x003f0011>; +-def X86SBC_W : NoDstFmt2R<0x003f0012>; +-def X86SUB_B : NoDstFmt2R<0x003f0008>; +-def X86SUB_H : NoDstFmt2R<0x003f0009>; +-def X86SUB_W : NoDstFmt2R<0x003f000a>; +- +-def X86DEC_B : NoDstFmt1R<0x00008004>; +-def X86DEC_H : NoDstFmt1R<0x00008005>; +-def X86DEC_W : NoDstFmt1R<0x00008006>; +- +-def X86AND_B : NoDstFmt2R<0x003f8010>; +-def X86AND_H : NoDstFmt2R<0x003f8011>; +-def X86AND_W : NoDstFmt2R<0x003f8012>; +- +-def X86OR_B : NoDstFmt2R<0x003f8014>; +-def X86OR_H : NoDstFmt2R<0x003f8015>; +-def X86OR_W : NoDstFmt2R<0x003f8016>; +- +-def X86XOR_B : NoDstFmt2R<0x003f8018>; +-def X86XOR_H : NoDstFmt2R<0x003f8019>; +-def X86XOR_W : NoDstFmt2R<0x003f801a>; +- +-def X86MUL_B : NoDstFmt2R<0x003e8000>; +-def X86MUL_H : NoDstFmt2R<0x003e8001>; +-def X86MUL_W : NoDstFmt2R<0x003e8002>; +-def X86MUL_BU : NoDstFmt2R<0x003e8004>; +-def X86MUL_HU : NoDstFmt2R<0x003e8005>; +- +-def X86RCL_B : NoDstFmt2R<0x003f800c>; +-def X86RCL_H : NoDstFmt2R<0x003f800d>; +-def X86RCL_W : NoDstFmt2R<0x003f800e>; +-def X86RCLI_B : NoDstFmt1RI3<0x00542018>; +-def X86RCLI_H : NoDstFmt1RI4<0x00544019>; +-def X86RCLI_W : NoDstFmt1RI5<0x0054801a>; +- +-def X86RCR_B : NoDstFmt2R<0x003f8008>; +-def X86RCR_H : NoDstFmt2R<0x003f8009>; +-def X86RCR_W : NoDstFmt2R<0x003f800a>; +-def X86RCRI_B : NoDstFmt1RI3<0x00542010>; +-def X86RCRI_H : NoDstFmt1RI4<0x00544011>; +-def X86RCRI_W : NoDstFmt1RI5<0x00548012>; +- +-def X86ROTL_B : NoDstFmt2R<0x003f8004>; +-def X86ROTL_H : NoDstFmt2R<0x003f8005>; +-def X86ROTL_W : NoDstFmt2R<0x003f8006>; +-def X86ROTLI_B : NoDstFmt1RI3<0x00542014>; +-def X86ROTLI_H : NoDstFmt1RI4<0x00544015>; +-def X86ROTLI_W : NoDstFmt1RI5<0x00548016>; +- +-def X86ROTR_B : NoDstFmt2R<0x003f8000>; +-def X86ROTR_H : NoDstFmt2R<0x003f8001>; +-def X86ROTR_W : NoDstFmt2R<0x003f8003>; +-def X86ROTRI_B : NoDstFmt1RI3<0x0054200c>; +-def X86ROTRI_H : NoDstFmt1RI4<0x0054400d>; +-def X86ROTRI_W : NoDstFmt1RI5<0x0054800e>; +- +-def X86SLL_B : NoDstFmt2R<0x003f0014>; +-def X86SLL_H : NoDstFmt2R<0x003f0015>; +-def X86SLL_W : NoDstFmt2R<0x003f0016>; +-def X86SLLI_B : NoDstFmt1RI3<0x00542000>; +-def X86SLLI_H : NoDstFmt1RI4<0x00544001>; +-def X86SLLI_W : NoDstFmt1RI5<0x00548002>; +- +-def X86SRL_B : NoDstFmt2R<0x003f0018>; +-def X86SRL_H : NoDstFmt2R<0x003f0019>; +-def X86SRL_W : NoDstFmt2R<0x003f001a>; +-def X86SRLI_B : NoDstFmt1RI3<0x00542004>; +-def X86SRLI_H : NoDstFmt1RI4<0x00544005>; +-def X86SRLI_W : NoDstFmt1RI5<0x00548006>; +- +-def X86SRA_B : NoDstFmt2R<0x003f001c>; +-def X86SRA_H : NoDstFmt2R<0x003f001d>; +-def X86SRA_W : NoDstFmt2R<0x003f001e>; +-def X86SRAI_B : NoDstFmt1RI3<0x00542008>; +-def X86SRAI_H : NoDstFmt1RI4<0x00544009>; +-def X86SRAI_W : NoDstFmt1RI5<0x0054800a>; +- +-def SETX86J : Fmt1RI4<0x00368000>; +-def SETX86LOOPE : ALU_2R<0x00007800>; +-def SETX86LOOPNE : ALU_2R<0x00007c00>; +-def X86MFFLAG : Fmt1RI8<0x005c0000>; +-def X86MTFLAG : Fmt1RI8<0x005c0020>; +-def X86MFTOP : FmtMFTOP<0x00007400>; +-def X86MTTOP : FmtMTTOP<0x00007000>; +- +-def X86INCTOP : FmtI32<0x00008009>; +-def X86DECTOP : FmtI32<0x00008029>; +-def X86SETTM : FmtI32<0x00008008>; +-def X86CLRTM : FmtI32<0x00008028>; +-def X86SETTAG : Fmt1RI5I8<0x00580000>; +- +-def ARMADD_W : NoDstFmt2RI4<0x00370010>; +-def ARMSUB_W : NoDstFmt2RI4<0x00378010>; +-def ARMADC_W : NoDstFmt2RI4<0x00380010>; +-def ARMSBC_W : NoDstFmt2RI4<0x00388010>; +-def ARMAND_W : NoDstFmt2RI4<0x00390010>; +-def ARMOR_W : NoDstFmt2RI4<0x00398010>; +-def ARMXOR_W : NoDstFmt2RI4<0x003a0010>; +-def ARMNOT_W : NoDstFmt1RI4<0x003fc01c>; +-def ARMSLL_W : NoDstFmt2RI4<0x003a8010>; +-def ARMSRL_W : NoDstFmt2RI4<0x003b0010>; +-def ARMSRA_W : NoDstFmt2RI4<0x003b8010>; +-def ARMROTR_W : NoDstFmt2RI4<0x003c0010>; +-def ARMSLLI_W : NoDstFmt1RI5I4<0x003c8010>; +-def ARMSRLI_W : NoDstFmt1RI5I4<0x003d0010>; +-def ARMSRAI_W : NoDstFmt1RI5I4<0x003d8010>; +-def ARMROTRI_W : NoDstFmt1RI5I4<0x003e0010>; +-def ARMRRX_W : NoDstFmt1RI4<0x003fc01f>; +-def ARMMOVE : Fmt2RI4<0x00364000>; +-def ARMMOV_W : NoDstFmt1RI4<0x003fc01d>; +- +-def ARMMFFLAG : Fmt1RI8<0x005c0040>; +-def ARMMTFLAG : Fmt1RI8<0x005c0060>; +-def SETARMJ : Fmt1RI4<0x0036c000>; +- +-let Predicates = [IsLA64] in { +-def ADDU12I_D : ALU_2RI5<0x00298000, simm5>; +-def ADC_D : ALU_3R<0x00318000>; +-def SBC_D : ALU_3R<0x00338000>; +-def RCR_D : ALU_3R<0x00358000>; +-def RCRI_D : ALU_2RI6<0x00510000, uimm6>; +- +-// mayLoad = 1 +-let mayLoad = 1 in { +-def LDL_D : LOAD_2RI12<0x2e800000>; +-def LDR_D : LOAD_2RI12<0x2ec00000>; +-} // mayLoad = 1 +- +-let mayStore = 1 in { +-def STL_D : STORE_2RI12<0x2f800000>; +-def STR_D : STORE_2RI12<0x2fc00000>; +-} // mayStore = 1 +- +-def X86ADC_D : NoDstFmt2R<0x003f000f>; +-def X86ADD_D : NoDstFmt2R<0x003f0007>; +-def X86ADD_WU : NoDstFmt2R<0x003f0000>; +-def X86ADD_DU : NoDstFmt2R<0x003f0001>; +-def X86INC_D : NoDstFmt1R<0x00008003>; +-def X86SBC_D : NoDstFmt2R<0x003f0013>; +-def X86SUB_WU : NoDstFmt2R<0x003f0002>; +-def X86SUB_D : NoDstFmt2R<0x003f000b>; +-def X86SUB_DU : NoDstFmt2R<0x003f0003>; +-def X86DEC_D : NoDstFmt1R<0x00008007>; +-def X86AND_D : NoDstFmt2R<0x003f8013>; +-def X86OR_D : NoDstFmt2R<0x003f8017>; +-def X86XOR_D : NoDstFmt2R<0x003f801b>; +-def X86MUL_D : NoDstFmt2R<0x003e8003>; +-def X86MUL_WU : NoDstFmt2R<0x003e8006>; +-def X86MUL_DU : NoDstFmt2R<0x003e8007>; +-def X86RCL_D : NoDstFmt2R<0x003f800f>; +-def X86RCLI_D : NoDstFmt1RI6<0x0055001b>; +-def X86RCR_D : NoDstFmt2R<0x003f800b>; +-def X86RCRI_D : NoDstFmt1RI6<0x00550013>; +-def X86ROTL_D : NoDstFmt2R<0x003f8007>; +-def X86ROTLI_D : NoDstFmt1RI6<0x00550017>; +-def X86ROTR_D : NoDstFmt2R<0x003f8002>; +-def X86ROTRI_D : NoDstFmt1RI6<0x0055000f>; +-def X86SLL_D : NoDstFmt2R<0x003f0017>; +-def X86SLLI_D : NoDstFmt1RI6<0x00550003>; +-def X86SRL_D : NoDstFmt2R<0x003f001b>; +-def X86SRLI_D : NoDstFmt1RI6<0x00550007>; +-def X86SRA_D : NoDstFmt2R<0x003f001f>; +-def X86SRAI_D : NoDstFmt1RI6<0x0055000b>; +-def ARMMOV_D : NoDstFmt1RI4<0x003fc01e>; +- +-} // Predicates = [IsLA64] +-} // hasSideEffects = 0, mayLoad = 0, mayStore = 0, Predicates = [HasExtLBT] +diff --git a/llvm/lib/Target/LoongArch/LoongArchLSXInstrFormats.td b/llvm/lib/Target/LoongArch/LoongArchLSXInstrFormats.td +index 843f9cbd9..50df4d724 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchLSXInstrFormats.td ++++ b/llvm/lib/Target/LoongArch/LoongArchLSXInstrFormats.td +@@ -1,486 +1,449 @@ +-// LoongArchLSXInstrFormats.td - LoongArch LSX Instr Formats -*- tablegen -*-=// ++//===- LoongArchLSXInstrFormats.td - LoongArch LSX Instruction Formats ---*- tablegen -*-===// + // +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// The LLVM Compiler Infrastructure + // +-//===----------------------------------------------------------------------===// +- +-//===----------------------------------------------------------------------===// +-// Describe LoongArch LSX instructions format +-// +-// opcode - operation code. +-// vd/rd/cd - destination register operand. +-// {r/v}{j/k} - source register operand. +-// immN - immediate data operand. ++// This file is distributed under the University of Illinois Open Source ++// License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + +-// 1RI13-type +-// +-class Fmt1RI13_VI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<13> imm13; ++class LSXInst : InstLA<(outs), (ins), "", [], FrmOther>, ++ EXT_LSX { ++} ++ ++class LSXCBranch : LSXInst { ++} ++ ++class LSXSpecial : LSXInst { ++} ++ ++class LSXPseudo pattern>: ++ LoongArchPseudo { ++ let Predicates = [HasLSX]; ++} ++ ++class LSX_3R op>: LSXInst { ++ bits<5> vk; ++ bits<5> vj; + bits<5> vd; + +- let Inst{31-0} = op; +- let Inst{17-5} = imm13; ++ let Inst{31-15} = op; ++ let Inst{14-10} = vk; ++ let Inst{9-5} = vj; + let Inst{4-0} = vd; + } + +-// 2R-type +-// +-class Fmt2R_VV op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { ++class LSX_3R_1GP op>: LSXInst { ++ bits<5> rk; + bits<5> vj; + bits<5> vd; + +- let Inst{31-0} = op; ++ let Inst{31-15} = op; ++ let Inst{14-10} = rk; + let Inst{9-5} = vj; + let Inst{4-0} = vd; + } + +-// +-class Fmt2R_VR op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<5> rj; ++class LSX_I5 op>: LSXInst { + bits<5> vd; ++ bits<5> vj; ++ bits<5> si5; + +- let Inst{31-0} = op; +- let Inst{9-5} = rj; ++ let Inst{31-15} = op; ++ let Inst{14-10} = si5; ++ let Inst{9-5} = vj; + let Inst{4-0} = vd; + } + +-// +-class Fmt2R_CV op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { ++class LSX_I5_U op>: LSXInst { ++ bits<5> vd; + bits<5> vj; +- bits<3> cd; ++ bits<5> ui5; + +- let Inst{31-0} = op; ++ let Inst{31-15} = op; ++ let Inst{14-10} = ui5; + let Inst{9-5} = vj; +- let Inst{2-0} = cd; ++ let Inst{4-0} = vd; + } + +-// 2RI1-type +-// +-class Fmt2RI1_VVI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<1> imm1; ++class LSX_2R op>: LSXInst { + bits<5> vj; + bits<5> vd; + +- let Inst{31-0} = op; +- let Inst{10} = imm1; ++ let Inst{31-10} = op; + let Inst{9-5} = vj; + let Inst{4-0} = vd; + } + +-// +-class Fmt2RI1_VRI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<1> imm1; ++class LSX_2R_1GP op>: LSXInst { + bits<5> rj; + bits<5> vd; + +- let Inst{31-0} = op; +- let Inst{10} = imm1; ++ let Inst{31-10} = op; + let Inst{9-5} = rj; + let Inst{4-0} = vd; + } + +-// +-class Fmt2RI1_RVI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<1> imm1; ++class LSX_I1_U op>: LSXInst { ++ bits<5> vd; + bits<5> vj; +- bits<5> rd; ++ bits<1> ui1; + +- let Inst{31-0} = op; +- let Inst{10} = imm1; ++ let Inst{31-11} = op; ++ let Inst{10} = ui1; + let Inst{9-5} = vj; +- let Inst{4-0} = rd; ++ let Inst{4-0} = vd; + } + +-// 2RI2-type +-// +-class Fmt2RI2_VVI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<2> imm2; +- bits<5> vj; ++class LSX_I2_U op>: LSXInst { + bits<5> vd; ++ bits<5> vj; ++ bits<2> ui2; + +- let Inst{31-0} = op; +- let Inst{11-10} = imm2; ++ let Inst{31-12} = op; ++ let Inst{11-10} = ui2; + let Inst{9-5} = vj; + let Inst{4-0} = vd; + } + +-// +-class Fmt2RI2_VRI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<2> imm2; +- bits<5> rj; ++class LSX_I3_U op>: LSXInst { + bits<5> vd; ++ bits<5> vj; ++ bits<3> ui3; + +- let Inst{31-0} = op; +- let Inst{11-10} = imm2; +- let Inst{9-5} = rj; ++ let Inst{31-13} = op; ++ let Inst{12-10} = ui3; ++ let Inst{9-5} = vj; + let Inst{4-0} = vd; + } + +-// +-class Fmt2RI2_RVI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<2> imm2; ++class LSX_I4_U op>: LSXInst { ++ bits<5> vd; + bits<5> vj; +- bits<5> rd; ++ bits<4> ui4; + +- let Inst{31-0} = op; +- let Inst{11-10} = imm2; ++ let Inst{31-14} = op; ++ let Inst{13-10} = ui4; + let Inst{9-5} = vj; +- let Inst{4-0} = rd; ++ let Inst{4-0} = vd; + } + +-// 2RI3-type +-// +-class Fmt2RI3_VVI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<3> imm3; +- bits<5> vj; ++class LSX_I6_U op>: LSXInst { + bits<5> vd; ++ bits<5> vj; ++ bits<6> ui6; + +- let Inst{31-0} = op; +- let Inst{12-10} = imm3; ++ let Inst{31-16} = op; ++ let Inst{15-10} = ui6; + let Inst{9-5} = vj; + let Inst{4-0} = vd; + } + +-// +-class Fmt2RI3_VRI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<3> imm3; +- bits<5> rj; ++class LSX_I1_R_U op>: LSXInst { + bits<5> vd; ++ bits<5> rj; ++ bits<1> ui1; + +- let Inst{31-0} = op; +- let Inst{12-10} = imm3; ++ let Inst{31-11} = op; ++ let Inst{10} = ui1; + let Inst{9-5} = rj; + let Inst{4-0} = vd; + } + +-// +-class Fmt2RI3_RVI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<3> imm3; +- bits<5> vj; +- bits<5> rd; ++class LSX_I2_R_U op>: LSXInst { ++ bits<5> vd; ++ bits<5> rj; ++ bits<2> ui2; + +- let Inst{31-0} = op; +- let Inst{12-10} = imm3; +- let Inst{9-5} = vj; +- let Inst{4-0} = rd; ++ let Inst{31-12} = op; ++ let Inst{11-10} = ui2; ++ let Inst{9-5} = rj; ++ let Inst{4-0} = vd; + } + +-// 2RI4-type +-// +-class Fmt2RI4_VVI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<4> imm4; +- bits<5> vj; ++class LSX_I3_R_U op>: LSXInst { + bits<5> vd; ++ bits<5> rj; ++ bits<3> ui3; + +- let Inst{31-0} = op; +- let Inst{13-10} = imm4; +- let Inst{9-5} = vj; ++ let Inst{31-13} = op; ++ let Inst{12-10} = ui3; ++ let Inst{9-5} = rj; + let Inst{4-0} = vd; + } + +-// +-class Fmt2RI4_VRI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<4> imm4; +- bits<5> rj; ++class LSX_I4_R_U op>: LSXInst { + bits<5> vd; ++ bits<5> rj; ++ bits<4> ui4; + +- let Inst{31-0} = op; +- let Inst{13-10} = imm4; ++ let Inst{31-14} = op; ++ let Inst{13-10} = ui4; + let Inst{9-5} = rj; + let Inst{4-0} = vd; + } + +-// +-class Fmt2RI4_RVI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<4> imm4; ++class LSX_ELM_COPY_B op>: LSXInst { ++ bits<5> rd; + bits<5> vj; ++ bits<4> ui4; ++ ++ let Inst{31-14} = op; ++ let Inst{13-10} = ui4; ++ let Inst{9-5} = vj; ++ let Inst{4-0} = rd; ++} ++ ++class LSX_ELM_COPY_H op>: LSXInst { + bits<5> rd; ++ bits<5> vj; ++ bits<3> ui3; + +- let Inst{31-0} = op; +- let Inst{13-10} = imm4; ++ let Inst{31-13} = op; ++ let Inst{12-10} = ui3; + let Inst{9-5} = vj; + let Inst{4-0} = rd; + } + +-// 2RI5-type +-// +-class Fmt2RI5_VVI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<5> imm5; ++class LSX_ELM_COPY_W op>: LSXInst { ++ bits<5> rd; + bits<5> vj; +- bits<5> vd; ++ bits<2> ui2; + +- let Inst{31-0} = op; +- let Inst{14-10} = imm5; ++ let Inst{31-12} = op; ++ let Inst{11-10} = ui2; + let Inst{9-5} = vj; +- let Inst{4-0} = vd; ++ let Inst{4-0} = rd; + } + +-// 2RI6-type +-// +-class Fmt2RI6_VVI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<6> imm6; ++class LSX_ELM_COPY_D op>: LSXInst { ++ bits<5> rd; + bits<5> vj; ++ bits<1> ui1; ++ ++ let Inst{31-11} = op; ++ let Inst{10} = ui1; ++ let Inst{9-5} = vj; ++ let Inst{4-0} = rd; ++} ++ ++class LSX_I8_U op>: LSXInst { + bits<5> vd; ++ bits<5> vj; ++ bits<8> ui8; + +- let Inst{31-0} = op; +- let Inst{15-10} = imm6; ++ let Inst{31-18} = op; ++ let Inst{17-10} = ui8; + let Inst{9-5} = vj; + let Inst{4-0} = vd; + } + +-// 2RI7-type +-// +-class Fmt2RI7_VVI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<7> imm7; +- bits<5> vj; ++class LSX_I7_U op>: LSXInst { + bits<5> vd; ++ bits<5> vj; ++ bits<7> ui7; + +- let Inst{31-0} = op; +- let Inst{16-10} = imm7; ++ let Inst{31-17} = op; ++ let Inst{16-10} = ui7; + let Inst{9-5} = vj; + let Inst{4-0} = vd; + } + +-// 2RI8-type +-// +-class Fmt2RI8_VVI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<8> imm8; +- bits<5> vj; ++class LSX_I12_S op>: LSXInst { + bits<5> vd; ++// bits<5> rj; ++// bits<12> si12; ++ bits<17> addr; + +- let Inst{31-0} = op; +- let Inst{17-10} = imm8; +- let Inst{9-5} = vj; ++ let Inst{31-22} = op; ++ let Inst{21-10} = addr{11-0}; ++ let Inst{9-5} = addr{16-12}; + let Inst{4-0} = vd; + } + +-// 2RI8I1-type +-// +-class Fmt2RI8I1_VRII op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<1> imm1; +- bits<8> imm8; +- bits<5> rj; ++class LSX_SI12_S op>: LSXInst { + bits<5> vd; ++ bits<17> addr; + +- let Inst{31-0} = op; +- let Inst{18} = imm1; +- let Inst{17-10} = imm8; +- let Inst{9-5} = rj; ++ let Inst{31-22} = op; ++ let Inst{21-10} = addr{11-0}; ++ let Inst{9-5} = addr{16-12}; + let Inst{4-0} = vd; + } + +-// 2RI8I2-type +-// +-class Fmt2RI8I2_VRII op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<2> imm2; +- bits<8> imm8; +- bits<5> rj; ++class LSX_SI11_S op>: LSXInst { + bits<5> vd; ++ bits<16> addr; + +- let Inst{31-0} = op; +- let Inst{19-18} = imm2; +- let Inst{17-10} = imm8; +- let Inst{9-5} = rj; ++ let Inst{31-21} = op; ++ let Inst{20-10} = addr{10-0}; ++ let Inst{9-5} = addr{15-11}; + let Inst{4-0} = vd; + } + +-// 2RI8I3-type +-// +-class Fmt2RI8I3_VRII op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<3> imm3; +- bits<8> imm8; +- bits<5> rj; ++class LSX_SI10_S op>: LSXInst { + bits<5> vd; ++ bits<15> addr; + +- let Inst{31-0} = op; +- let Inst{20-18} = imm3; +- let Inst{17-10} = imm8; +- let Inst{9-5} = rj; ++ let Inst{31-20} = op; ++ let Inst{19-10} = addr{9-0}; ++ let Inst{9-5} = addr{14-10}; + let Inst{4-0} = vd; + } + +-// 2RI8I4-type +-// +-class Fmt2RI8I4_VRII op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<4> imm4; +- bits<8> imm8; +- bits<5> rj; ++class LSX_SI9_S op>: LSXInst { + bits<5> vd; ++ bits<14> addr; + +- let Inst{31-0} = op; +- let Inst{21-18} = imm4; +- let Inst{17-10} = imm8; +- let Inst{9-5} = rj; ++ let Inst{31-19} = op; ++ let Inst{18-10} = addr{8-0}; ++ let Inst{9-5} = addr{13-9}; + let Inst{4-0} = vd; + } +-// 2RI9-type +-// +-class Fmt2RI9_VRI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<9> imm9; +- bits<5> rj; ++ ++class LSX_SET op>: LSXInst { ++ bits<5> vj; ++ bits<3> cd; ++ ++ let Inst{31-10} = op; ++ let Inst{9-5} = vj; ++ let Inst{4-3} = 0b00; ++ let Inst{2-0} = cd; ++} ++ ++class LSX_VR4MUL op>: LSXInst { + bits<5> vd; ++ bits<5> vj; ++ bits<5> vk; ++ bits<5> va; + +- let Inst{31-0} = op; +- let Inst{18-10} = imm9; +- let Inst{9-5} = rj; ++ let Inst{31-20} = op; ++ let Inst{19-15} = va; ++ let Inst{14-10} = vk; ++ let Inst{9-5} = vj; + let Inst{4-0} = vd; + } + +-// 2RI10-type +-// +-class Fmt2RI10_VRI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<10> imm10; +- bits<5> rj; ++class LSX_VFCMP op>: LSXInst { + bits<5> vd; ++ bits<5> vj; ++ bits<5> vk; ++ bits<5> cond; + +- let Inst{31-0} = op; +- let Inst{19-10} = imm10; +- let Inst{9-5} = rj; ++ let Inst{31-20} = op; ++ let Inst{19-15} = cond; ++ let Inst{14-10} = vk; ++ let Inst{9-5} = vj; + let Inst{4-0} = vd; + } + +-// 2RI11-type +-// +-class Fmt2RI11_VRI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<11> imm11; +- bits<5> rj; ++class LSX_Addr_SI8_idx1 op>: LSXInst { + bits<5> vd; ++ bits<13> addr; ++ bits<1> idx; + +- let Inst{31-0} = op; +- let Inst{20-10} = imm11; +- let Inst{9-5} = rj; ++ let Inst{31-19} = op; ++ let Inst{18-11} = addr{7-0}; ++ let Inst{10} = idx; ++ let Inst{9-5} = addr{12-8}; + let Inst{4-0} = vd; + } + +-// 2RI12-type +-// +-class Fmt2RI12_VRI op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<12> imm12; ++class LSX_SI8_idx1 op>: LSXInst { ++ bits<5> vd; + bits<5> rj; ++ bits<8> si8; ++ bits<1> idx; ++ ++ let Inst{31-19} = op; ++ let Inst{18} = idx; ++ let Inst{17-10} = si8; ++ let Inst{9-5} = rj; ++ let Inst{4-0} = vd; ++} ++ ++class LSX_SI8_idx2 op>: LSXInst { + bits<5> vd; ++ bits<5> rj; ++ bits<8> si8; ++ bits<2> idx; + +- let Inst{31-0} = op; +- let Inst{21-10} = imm12; ++ let Inst{31-20} = op; ++ let Inst{19-18} = idx; ++ let Inst{17-10} = si8; + let Inst{9-5} = rj; + let Inst{4-0} = vd; + } + +-// 3R-type +-// +-class Fmt3R_VVV op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<5> vk; +- bits<5> vj; ++class LSX_SI8_idx3 op>: LSXInst { + bits<5> vd; ++ bits<5> rj; ++ bits<8> si8; ++ bits<3> idx; + +- let Inst{31-0} = op; +- let Inst{14-10} = vk; +- let Inst{9-5} = vj; ++ let Inst{31-21} = op; ++ let Inst{20-18} = idx; ++ let Inst{17-10} = si8; ++ let Inst{9-5} = rj; + let Inst{4-0} = vd; + } + +-// +-class Fmt3R_VVR op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<5> rk; +- bits<5> vj; ++class LSX_SI8_idx4 op>: LSXInst { + bits<5> vd; ++ bits<5> rj; ++ bits<8> si8; ++ bits<4> idx; + +- let Inst{31-0} = op; +- let Inst{14-10} = rk; +- let Inst{9-5} = vj; ++ let Inst{31-22} = op; ++ let Inst{21-18} = idx; ++ let Inst{17-10} = si8; ++ let Inst{9-5} = rj; + let Inst{4-0} = vd; + } + +-// +-class Fmt3R_VRR op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { ++class LSX_3R_2GP op>: LSXInst { + bits<5> rk; + bits<5> rj; + bits<5> vd; + +- let Inst{31-0} = op; ++ let Inst{31-15} = op; + let Inst{14-10} = rk; + let Inst{9-5} = rj; + let Inst{4-0} = vd; + } + +-// 4R-type +-// +-class Fmt4R_VVVV op, dag outs, dag ins, string opnstr, +- list pattern = []> +- : LAInst.ret, opnstr, pattern> { +- bits<5> va; +- bits<5> vk; +- bits<5> vj; ++class LSX_I5_mode_U op>: LSXInst { + bits<5> vd; ++ bits<5> mode; ++ bits<5> ui5; + +- let Inst{31-0} = op; +- let Inst{19-15} = va; +- let Inst{14-10} = vk; +- let Inst{9-5} = vj; ++ let Inst{31-15} = op; ++ let Inst{14-10} = ui5; ++ let Inst{9-5} = mode; ++ let Inst{4-0} = vd; ++} ++ ++class LSX_1R_I13 op>: LSXInst { ++ bits<13> i13; ++ bits<5> vd; ++ ++ let Inst{31-18} = op; ++ let Inst{17-5} = i13; + let Inst{4-0} = vd; + } ++ ++class LSX_1R_I13_I10 op>: LSXInst { ++ bits<10> i10; ++ bits<5> vd; ++ ++ let Inst{31-15} = op; ++ let Inst{14-5} = i10; ++ let Inst{4-0} = vd; ++} ++ ++ ++ ++ ++ ++ ++ +diff --git a/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td +index 39ee861cd..56fa82391 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td ++++ b/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td +@@ -1,145 +1,770 @@ +-//===- LoongArchLSXInstrInfo.td - LoongArch LSX instructions -*- tablegen -*-=// ++//===- LoongArchLSXInstrInfo.td - LSX instructions -*- tablegen ------------*-=// + // +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// The LLVM Compiler Infrastructure ++// ++// This file is distributed under the University of Illinois Open Source ++// License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // +-// This file describes the SIMD extension instructions. ++// This file describes LoongArch LSX instructions. + // + //===----------------------------------------------------------------------===// + +-def SDT_LoongArchVreplve : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisVec<0>, +- SDTCisInt<1>, SDTCisVec<1>, +- SDTCisSameAs<0, 1>, SDTCisInt<2>]>; + def SDT_LoongArchVecCond : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisVec<1>]>; ++def SDT_VSetCC : SDTypeProfile<1, 3, [SDTCisInt<0>, ++ SDTCisInt<1>, ++ SDTCisSameAs<1, 2>, ++ SDTCisVT<3, OtherVT>]>; ++def SDT_VFSetCC : SDTypeProfile<1, 3, [SDTCisInt<0>, ++ SDTCisFP<1>, ++ SDTCisSameAs<1, 2>, ++ SDTCisVT<3, OtherVT>]>; ++def SDT_VSHF : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisVec<0>, ++ SDTCisInt<1>, SDTCisVec<1>, ++ SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>]>; ++def SDT_SHF : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisVec<0>, ++ SDTCisVT<1, i32>, SDTCisSameAs<0, 2>]>; ++def SDT_ILV : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisVec<0>, ++ SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>]>; ++def SDTVABSD : SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisSameAs<0, 1>, ++ SDTCisSameAs<0, 2>, SDTCisVT<3, i32>]>; ++ ++def SDT_VBROADCAST : SDTypeProfile<1, 1, [SDTCisVec<0>]>; ++def LoongArchVBROADCAST : SDNode<"LoongArchISD::VBROADCAST", SDT_VBROADCAST, ++ [SDNPHasChain]>; ++ ++def LoongArchVAllNonZero : SDNode<"LoongArchISD::VALL_NONZERO", SDT_LoongArchVecCond>; ++def LoongArchVAnyNonZero : SDNode<"LoongArchISD::VANY_NONZERO", SDT_LoongArchVecCond>; ++def LoongArchVAllZero : SDNode<"LoongArchISD::VALL_ZERO", SDT_LoongArchVecCond>; ++def LoongArchVAnyZero : SDNode<"LoongArchISD::VANY_ZERO", SDT_LoongArchVecCond>; ++def LoongArchVNOR : SDNode<"LoongArchISD::VNOR", SDTIntBinOp, ++ [SDNPCommutative, SDNPAssociative]>; ++def LoongArchVSHF : SDNode<"LoongArchISD::VSHF", SDT_VSHF>; ++def LoongArchSHF : SDNode<"LoongArchISD::SHF", SDT_SHF>; ++def LoongArchVPACKEV : SDNode<"LoongArchISD::VPACKEV", SDT_ILV>; ++def LoongArchVPACKOD : SDNode<"LoongArchISD::VPACKOD", SDT_ILV>; ++def LoongArchVILVH : SDNode<"LoongArchISD::VILVH", SDT_ILV>; ++def LoongArchVILVL : SDNode<"LoongArchISD::VILVL", SDT_ILV>; ++def LoongArchVPICKEV : SDNode<"LoongArchISD::VPICKEV", SDT_ILV>; ++def LoongArchVPICKOD : SDNode<"LoongArchISD::VPICKOD", SDT_ILV>; ++def LoongArchVABSD : SDNode<"LoongArchISD::VABSD", SDTVABSD>; ++def LoongArchUVABSD : SDNode<"LoongArchISD::UVABSD", SDTVABSD>; ++ ++def vsetcc : SDNode<"ISD::SETCC", SDT_VSetCC>; ++def vfsetcc : SDNode<"ISD::SETCC", SDT_VFSetCC>; ++ ++def LoongArchVExtractSExt : SDNode<"LoongArchISD::VEXTRACT_SEXT_ELT", ++ SDTypeProfile<1, 3, [SDTCisPtrTy<2>]>, []>; ++def LoongArchVExtractZExt : SDNode<"LoongArchISD::VEXTRACT_ZEXT_ELT", ++ SDTypeProfile<1, 3, [SDTCisPtrTy<2>]>, []>; ++ ++def immZExt1Ptr : ImmLeaf(Imm);}]>; ++def immZExt2Ptr : ImmLeaf(Imm);}]>; ++def immZExt3Ptr : ImmLeaf(Imm);}]>; ++def immZExt4Ptr : ImmLeaf(Imm);}]>; ++def immZExt5Ptr : ImmLeaf(Imm);}]>; ++def immZExt10 : ImmLeaf(Imm);}]>; ++def immZExt8 : ImmLeaf(Imm);}]>; ++def immZExt7 : PatLeaf<(imm), [{ return isUInt<7>(N->getZExtValue()); }]>; ++def immZExt6 : ImmLeaf; ++def immZExt4 : ImmLeaf(Imm);}]>; ++def immZExt3 : ImmLeaf(Imm);}]>; ++def immZExt2 : ImmLeaf(Imm);}]>; ++def immZExt1 : ImmLeaf(Imm);}]>; ++def immSExt12_l : ImmLeaf(Imm);}]>; ++def immSExt11Ptr : ImmLeaf(Imm);}]>; ++ ++def immSExt11_1 : ImmLeaf(Imm<<1);}]>; ++def immSExt10Ptr : ImmLeaf(Imm);}]>; ++def immSExt10_2 : ImmLeaf(Imm<<2);}]>; ++def immSExt9Ptr : ImmLeaf(Imm);}]>; ++def immSExt9_3 : ImmLeaf(Imm<<3);}]>; ++def immSExt8 : ImmLeaf(Imm);}]>; ++def immSExt5 : ImmLeaf(Imm);}]>; ++def immSExt8_1 : ImmLeaf(Imm<<1);}]>; ++def immSExt8_2 : ImmLeaf(Imm<<2);}]>; ++def immSExt8_3 : ImmLeaf(Imm<<3);}]>; ++ ++def addrimm10 : ComplexPattern; ++def addrimm10lsl2 : ComplexPattern; ++def addrimm9lsl3 : ComplexPattern; ++def addrimm11lsl1 : ComplexPattern; ++ ++ ++class SimmLslAsmOperandClass Supers = [], ++ int Shift = 0> : AsmOperandClass { ++ let Name = "Simm" # Bits # "_Lsl" # Shift; ++ let RenderMethod = "addImmOperands"; ++ let PredicateMethod = "isScaledSImm<" # Bits # ", " # Shift # ">"; ++ let SuperClasses = Supers; ++ let DiagnosticType = "SImm" # Bits # "_Lsl" # Shift; ++} + +-// Target nodes. +-def loongarch_vreplve : SDNode<"LoongArchISD::VREPLVE", SDT_LoongArchVreplve>; +-def loongarch_vall_nonzero : SDNode<"LoongArchISD::VALL_NONZERO", +- SDT_LoongArchVecCond>; +-def loongarch_vany_nonzero : SDNode<"LoongArchISD::VANY_NONZERO", +- SDT_LoongArchVecCond>; +-def loongarch_vall_zero : SDNode<"LoongArchISD::VALL_ZERO", +- SDT_LoongArchVecCond>; +-def loongarch_vany_zero : SDNode<"LoongArchISD::VANY_ZERO", +- SDT_LoongArchVecCond>; +- +-def loongarch_vpick_sext_elt : SDNode<"LoongArchISD::VPICK_SEXT_ELT", +- SDTypeProfile<1, 3, [SDTCisPtrTy<2>]>>; +-def loongarch_vpick_zext_elt : SDNode<"LoongArchISD::VPICK_ZEXT_ELT", +- SDTypeProfile<1, 3, [SDTCisPtrTy<2>]>>; +- +-class VecCond +- : Pseudo<(outs GPR:$rd), (ins RC:$vj), +- [(set GPR:$rd, (OpNode (TyNode RC:$vj)))]> { +- let hasSideEffects = 0; +- let mayLoad = 0; +- let mayStore = 0; +- let usesCustomInserter = 1; ++def Simm11Lsl1AsmOperand ++ : SimmLslAsmOperandClass<11, [], 1>; ++ ++def immSExt11_1_O : Operand { ++ let EncoderMethod = "getSImm11Lsl1Encoding"; ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<2>"; ++ let ParserMatchClass = Simm11Lsl1AsmOperand; + } + +-def vsplat_imm_eq_1 : PatFrags<(ops), [(build_vector), +- (bitconvert (v4i32 (build_vector)))], [{ +- APInt Imm; +- EVT EltTy = N->getValueType(0).getVectorElementType(); ++def Simm10Lsl2AsmOperand ++ : SimmLslAsmOperandClass<10, [], 2>; + +- if (N->getOpcode() == ISD::BITCAST) +- N = N->getOperand(0).getNode(); ++def immSExt10_2_O : Operand { ++ let EncoderMethod = "getSImm10Lsl2Encoding"; ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<4>"; ++ let ParserMatchClass = Simm10Lsl2AsmOperand; ++} + +- return selectVSplat(N, Imm, EltTy.getSizeInBits()) && +- Imm.getBitWidth() == EltTy.getSizeInBits() && Imm == 1; +-}]>; ++def Simm9Lsl3AsmOperand ++ : SimmLslAsmOperandClass<9, [], 3>; + +-def vsplati8_imm_eq_7 : PatFrags<(ops), [(build_vector)], [{ +- APInt Imm; +- EVT EltTy = N->getValueType(0).getVectorElementType(); ++def immSExt9_3_O : Operand { ++ let EncoderMethod = "getSImm9Lsl3Encoding"; ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<8>"; ++ let ParserMatchClass = Simm9Lsl3AsmOperand; ++} + +- if (N->getOpcode() == ISD::BITCAST) +- N = N->getOperand(0).getNode(); ++def Simm8Lsl3AsmOperand ++ : SimmLslAsmOperandClass<8, [], 3>; + +- return selectVSplat(N, Imm, EltTy.getSizeInBits()) && +- Imm.getBitWidth() == EltTy.getSizeInBits() && Imm == 7; +-}]>; +-def vsplati16_imm_eq_15 : PatFrags<(ops), [(build_vector)], [{ +- APInt Imm; +- EVT EltTy = N->getValueType(0).getVectorElementType(); ++def immSExt8_3_O : Operand { ++ let EncoderMethod = "getSImm8Lsl3Encoding"; ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<8>"; ++ let ParserMatchClass = Simm8Lsl3AsmOperand; ++} + +- if (N->getOpcode() == ISD::BITCAST) +- N = N->getOperand(0).getNode(); ++def Simm8Lsl2AsmOperand ++ : SimmLslAsmOperandClass<8, [], 2>; + +- return selectVSplat(N, Imm, EltTy.getSizeInBits()) && +- Imm.getBitWidth() == EltTy.getSizeInBits() && Imm == 15; +-}]>; +-def vsplati32_imm_eq_31 : PatFrags<(ops), [(build_vector)], [{ +- APInt Imm; +- EVT EltTy = N->getValueType(0).getVectorElementType(); ++def immSExt8_2_O : Operand { ++ let EncoderMethod = "getSImm8Lsl2Encoding"; ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<4>"; ++ let ParserMatchClass = Simm8Lsl2AsmOperand; ++} + +- if (N->getOpcode() == ISD::BITCAST) +- N = N->getOperand(0).getNode(); ++def Simm8Lsl1AsmOperand ++ : SimmLslAsmOperandClass<8, [], 1>; + +- return selectVSplat(N, Imm, EltTy.getSizeInBits()) && +- Imm.getBitWidth() == EltTy.getSizeInBits() && Imm == 31; +-}]>; +-def vsplati64_imm_eq_63 : PatFrags<(ops), [(build_vector), +- (bitconvert (v4i32 (build_vector)))], [{ +- APInt Imm; +- EVT EltTy = N->getValueType(0).getVectorElementType(); ++def immSExt8_1_O : Operand { ++ let EncoderMethod = "getSImm8Lsl1Encoding"; ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<2>"; ++ let ParserMatchClass = Simm8Lsl1AsmOperand; ++} + +- if (N->getOpcode() == ISD::BITCAST) +- N = N->getOperand(0).getNode(); + +- return selectVSplat(N, Imm, EltTy.getSizeInBits()) && +- Imm.getBitWidth() == EltTy.getSizeInBits() && Imm == 63; +-}]>; ++class ConstantSImmAsmOperandClass Supers = [], ++ int Offset = 0> : AsmOperandClass { ++ let Name = "ConstantSImm" # Bits # "_" # Offset; ++ let RenderMethod = "addConstantSImmOperands<" # Bits # ", " # Offset # ">"; ++ let PredicateMethod = "isConstantSImm<" # Bits # ", " # Offset # ">"; ++ let SuperClasses = Supers; ++ let DiagnosticType = "SImm" # Bits # "_" # Offset; ++} + +-def vsplatf32_fpimm_eq_1 +- : PatFrags<(ops), [(bitconvert (v4i32 (build_vector))), +- (bitconvert (v8i32 (build_vector)))], [{ +- APInt Imm; +- EVT EltTy = N->getValueType(0).getVectorElementType(); +- N = N->getOperand(0).getNode(); ++class ConstantUImmRangeAsmOperandClass Supers = []> ++ : AsmOperandClass { ++ let Name = "ConstantUImmRange" # Bottom # "_" # Top; ++ let RenderMethod = "addImmOperands"; ++ let PredicateMethod = "isConstantUImmRange<" # Bottom # ", " # Top # ">"; ++ let SuperClasses = Supers; ++ let DiagnosticType = "UImmRange" # Bottom # "_" # Top; ++} + +- return selectVSplat(N, Imm, EltTy.getSizeInBits()) && +- Imm.getBitWidth() == EltTy.getSizeInBits() && +- Imm == APFloat(+1.0f).bitcastToAPInt(); +-}]>; +-def vsplatf64_fpimm_eq_1 +- : PatFrags<(ops), [(bitconvert (v2i64 (build_vector))), +- (bitconvert (v4i64 (build_vector)))], [{ ++def SImm16RelaxedAsmOperandClass ++ : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> { ++ let Name = "SImm16_Relaxed"; ++ let PredicateMethod = "isAnyImm<16>"; ++ let DiagnosticType = "SImm16_Relaxed"; ++} ++ ++def ConstantSImm11Lsl1AsmOperandClass : AsmOperandClass { ++ let Name = "SImm11Lsl1"; ++ let RenderMethod = "addImmOperands"; ++ let PredicateMethod = "isScaledSImm<11, 1>"; ++ let SuperClasses = [SImm12Operand]; ++ let DiagnosticType = "SImm11_Lsl1"; ++} ++ ++def ConstantSImm9Lsl3AsmOperandClass : AsmOperandClass { ++ let Name = "SImm9Lsl3"; ++ let RenderMethod = "addImmOperands"; ++ let PredicateMethod = "isScaledSImm<9, 3>"; ++ let SuperClasses = [SImm12Operand]; ++ let DiagnosticType = "SImm9_Lsl3"; ++} ++ ++def ConstantSImm10Lsl2AsmOperandClass : AsmOperandClass { ++ let Name = "SImm10Lsl2"; ++ let RenderMethod = "addImmOperands"; ++ let PredicateMethod = "isScaledSImm<10, 2>"; ++ let SuperClasses = [SImm12Operand]; ++ let DiagnosticType = "SImm10_Lsl2"; ++} ++def ConstantSImm11AsmOperandClass ++ : ConstantSImmAsmOperandClass<11, [ConstantSImm10Lsl2AsmOperandClass]>; ++def ConstantSImm10Lsl1AsmOperandClass : AsmOperandClass { ++ let Name = "SImm10Lsl1"; ++ let RenderMethod = "addImmOperands"; ++ let PredicateMethod = "isScaledSImm<10, 1>"; ++ let SuperClasses = [ConstantSImm11AsmOperandClass]; ++ let DiagnosticType = "SImm10_Lsl1"; ++} ++def ConstantUImm10AsmOperandClass ++ : ConstantUImmAsmOperandClass<10, [ConstantSImm10Lsl1AsmOperandClass]>; ++def ConstantSImm10AsmOperandClass ++ : ConstantSImmAsmOperandClass<10, [ConstantUImm10AsmOperandClass]>; ++def ConstantSImm9AsmOperandClass ++ : ConstantSImmAsmOperandClass<9, [ConstantSImm10AsmOperandClass]>; ++def ConstantSImm7Lsl2AsmOperandClass : AsmOperandClass { ++ let Name = "SImm7Lsl2"; ++ let RenderMethod = "addImmOperands"; ++ let PredicateMethod = "isScaledSImm<7, 2>"; ++ let SuperClasses = [ConstantSImm9AsmOperandClass]; ++ let DiagnosticType = "SImm7_Lsl2"; ++} ++def ConstantUImm8AsmOperandClass ++ : ConstantUImmAsmOperandClass<8, [ConstantSImm7Lsl2AsmOperandClass]>; ++def ConstantUImm7Sub1AsmOperandClass ++ : ConstantUImmAsmOperandClass<7, [ConstantUImm8AsmOperandClass], -1> { ++ // Specify the names since the -1 offset causes invalid identifiers otherwise. ++ let Name = "UImm7_N1"; ++ let DiagnosticType = "UImm7_N1"; ++} ++def ConstantUImm7AsmOperandClass ++ : ConstantUImmAsmOperandClass<7, [ConstantUImm7Sub1AsmOperandClass]>; ++def ConstantUImm6Lsl2AsmOperandClass : AsmOperandClass { ++ let Name = "UImm6Lsl2"; ++ let RenderMethod = "addImmOperands"; ++ let PredicateMethod = "isScaledUImm<6, 2>"; ++ let SuperClasses = [ConstantUImm7AsmOperandClass]; ++ let DiagnosticType = "UImm6_Lsl2"; ++} ++def ConstantUImm6AsmOperandClass ++ : ConstantUImmAsmOperandClass<6, [ConstantUImm6Lsl2AsmOperandClass]>; ++def ConstantSImm6AsmOperandClass ++ : ConstantSImmAsmOperandClass<6, [ConstantUImm6AsmOperandClass]>; ++def ConstantUImm5Lsl2AsmOperandClass : AsmOperandClass { ++ let Name = "UImm5Lsl2"; ++ let RenderMethod = "addImmOperands"; ++ let PredicateMethod = "isScaledUImm<5, 2>"; ++ let SuperClasses = [ConstantSImm6AsmOperandClass]; ++ let DiagnosticType = "UImm5_Lsl2"; ++} ++def ConstantUImm5_Range2_64AsmOperandClass ++ : ConstantUImmRangeAsmOperandClass<2, 64, [ConstantUImm5Lsl2AsmOperandClass]>; ++def ConstantUImm5Plus33AsmOperandClass ++ : ConstantUImmAsmOperandClass<5, [ConstantUImm5_Range2_64AsmOperandClass], ++ 33>; ++def ConstantUImm5ReportUImm6AsmOperandClass ++ : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus33AsmOperandClass]> { ++ let Name = "ConstantUImm5_0_Report_UImm6"; ++ let DiagnosticType = "UImm5_0_Report_UImm6"; ++} ++def ConstantUImm5Plus32AsmOperandClass ++ : ConstantUImmAsmOperandClass< ++ 5, [ConstantUImm5ReportUImm6AsmOperandClass], 32>; ++def ConstantUImm5Plus32NormalizeAsmOperandClass ++ : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus32AsmOperandClass], 32> { ++ let Name = "ConstantUImm5_32_Norm"; ++ // We must also subtract 32 when we render the operand. ++ let RenderMethod = "addConstantUImmOperands<5, 32, -32>"; ++} ++def ConstantUImm5Plus1ReportUImm6AsmOperandClass ++ : ConstantUImmAsmOperandClass< ++ 5, [ConstantUImm5Plus32NormalizeAsmOperandClass], 1>{ ++ let Name = "ConstantUImm5_Plus1_Report_UImm6"; ++} ++def ConstantUImm5Plus1AsmOperandClass ++ : ConstantUImmAsmOperandClass< ++ 5, [ConstantUImm5Plus1ReportUImm6AsmOperandClass], 1>; ++def ConstantUImm5AsmOperandClass ++ : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus1AsmOperandClass]>; ++def ConstantSImm5AsmOperandClass ++ : ConstantSImmAsmOperandClass<5, [ConstantUImm5AsmOperandClass]>; ++def ConstantUImm4AsmOperandClass ++ : ConstantUImmAsmOperandClass<4, [ConstantSImm5AsmOperandClass]>; ++def ConstantSImm4AsmOperandClass ++ : ConstantSImmAsmOperandClass<4, [ConstantUImm4AsmOperandClass]>; ++def ConstantUImm3AsmOperandClass ++ : ConstantUImmAsmOperandClass<3, [ConstantSImm4AsmOperandClass]>; ++def ConstantUImm2AsmOperandClass ++ : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass]>; ++def ConstantUImm1AsmOperandClass ++ : ConstantUImmAsmOperandClass<1, [ConstantUImm2AsmOperandClass]>; ++def ConstantImmzAsmOperandClass : AsmOperandClass { ++ let Name = "ConstantImmz"; ++ let RenderMethod = "addConstantUImmOperands<1>"; ++ let PredicateMethod = "isConstantImmz"; ++ let SuperClasses = [ConstantUImm1AsmOperandClass]; ++ let DiagnosticType = "Immz"; ++} ++ ++foreach I = {1, 2, 3, 4, 5, 6, 8} in ++ def vsplat_uimm # I : Operand { ++ let PrintMethod = "printUImm<" # I # ">"; ++ let ParserMatchClass = ++ !cast("ConstantUImm" # I # "AsmOperandClass"); ++ } ++ ++foreach I = {5, 10} in ++ def vsplat_simm # I : Operand { ++ let ParserMatchClass = ++ !cast("ConstantSImm" # I # "AsmOperandClass"); ++ } ++ ++foreach I = {1, 4, 7, 8, 10, 20, 26} in ++ def uimm # I : Operand { ++ let PrintMethod = "printUImm<" # I # ">"; ++ let ParserMatchClass = ++ !cast("ConstantUImm" # I # "AsmOperandClass"); ++ } ++ ++foreach I = {1, 2, 3, 4, 5, 6, 7, 8} in ++ def uimm # I # _ptr : Operand { ++ let PrintMethod = "printUImm<" # I # ">"; ++ let ParserMatchClass = ++ !cast("ConstantUImm" # I # "AsmOperandClass"); ++ } ++ ++ ++def addrimm12 : ComplexPattern; ++ ++ ++def LoongArchMemSimm12AsmOperand : AsmOperandClass { ++ let Name = "MemOffsetSimm12"; ++ let SuperClasses = [LoongArchMemAsmOperand]; ++ let RenderMethod = "addMemOperands"; ++ let ParserMethod = "parseMemOperand"; ++ let PredicateMethod = "isMemWithSimmOffset<12>"; ++ let DiagnosticType = "MemSImm12"; ++} ++ ++def mem_simm12 : mem_generic { ++ let MIOperandInfo = (ops ptr_rc, simm12); ++ let EncoderMethod = "getMemEncoding"; ++ let ParserMatchClass = LoongArchMemSimm12AsmOperand; ++} ++ ++foreach I = {4, 6, 9, 10, 11} in ++ def simm # I : Operand { ++ let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">"; ++ let ParserMatchClass = ++ !cast("ConstantSImm" # I # "AsmOperandClass"); ++ } ++ ++def LoongArchMemSimm9AsmOperand : AsmOperandClass { ++ let Name = "MemOffsetSimm9"; ++ let SuperClasses = [LoongArchMemAsmOperand]; ++ let RenderMethod = "addMemOperands"; ++ let ParserMethod = "parseMemOperand"; ++ let PredicateMethod = "isMemWithSimmOffset<9>"; ++ let DiagnosticType = "MemSImm9"; ++} ++ ++def LoongArchMemSimm10AsmOperand : AsmOperandClass { ++ let Name = "MemOffsetSimm10"; ++ let SuperClasses = [LoongArchMemAsmOperand]; ++ let RenderMethod = "addMemOperands"; ++ let ParserMethod = "parseMemOperand"; ++ let PredicateMethod = "isMemWithSimmOffset<10>"; ++ let DiagnosticType = "MemSImm10"; ++} ++ ++def LoongArchMemSimm11AsmOperand : AsmOperandClass { ++ let Name = "MemOffsetSimm11"; ++ let SuperClasses = [LoongArchMemAsmOperand]; ++ let RenderMethod = "addMemOperands"; ++ let ParserMethod = "parseMemOperand"; ++ let PredicateMethod = "isMemWithSimmOffset<11>"; ++ let DiagnosticType = "MemSImm11"; ++} ++ ++def simm13 : PatLeaf<(imm), [{ return isInt<13>(N->getSExtValue()); }]>; ++ ++def simm10Op : Operand { ++ let DecoderMethod = "DecodeSIMM10"; ++} ++ ++def simm13Op : Operand { ++ let DecoderMethod = "DecodeSIMM13"; ++} ++ ++def LoongArchMemSimm10Lsl2AsmOperand : AsmOperandClass { ++ let Name = "MemOffsetSimm10_2"; ++ let SuperClasses = [LoongArchMemAsmOperand]; ++ let RenderMethod = "addMemOperands"; ++ let ParserMethod = "parseMemOperand"; ++ let PredicateMethod = "isMemWithSimmOffset<10, 2>"; ++ let DiagnosticType = "MemSImm10Lsl2"; ++} ++ ++ ++def simm10_lsl2 : Operand { ++// let DecoderMethod = "DecodeSImmWithOffsetAndScale<10, 2>"; ++ let ParserMatchClass = ++ !cast("ConstantSImm10Lsl2AsmOperandClass"); ++} ++ ++def mem_simm10_lsl2 : mem_generic { ++ let MIOperandInfo = (ops ptr_rc, !cast("simm10_lsl2")); ++ let EncoderMethod = "getMemEncoding10l2"; ++ let ParserMatchClass = ++ !cast("LoongArchMemSimm10Lsl2AsmOperand"); ++} ++ ++ ++def LoongArchMemSimm11Lsl1AsmOperand : AsmOperandClass { ++ let Name = "MemOffsetSimm11_1"; ++ let SuperClasses = [LoongArchMemAsmOperand]; ++ let RenderMethod = "addMemOperands"; ++ let ParserMethod = "parseMemOperand"; ++ let PredicateMethod = "isMemWithSimmOffset<11, 1>"; ++ let DiagnosticType = "MemSImm11Lsl1"; ++} ++ ++ ++def simm11_lsl1 : Operand { ++ // let DecoderMethod = "DecodeSImmWithOffsetAndScale<11, 1>"; ++ let ParserMatchClass = ++ !cast("ConstantSImm11Lsl1AsmOperandClass"); ++} ++ ++def mem_simm11_lsl1 : mem_generic { ++ let MIOperandInfo = (ops ptr_rc, !cast("simm11_lsl1")); ++ let EncoderMethod = "getMemEncoding11l1"; ++ let ParserMatchClass = ++ !cast("LoongArchMemSimm11Lsl1AsmOperand"); ++} ++ ++def LoongArchMemSimm9Lsl3AsmOperand : AsmOperandClass { ++ let Name = "MemOffsetSimm9_3"; ++ let SuperClasses = [LoongArchMemAsmOperand]; ++ let RenderMethod = "addMemOperands"; ++ let ParserMethod = "parseMemOperand"; ++ let PredicateMethod = "isMemWithSimmOffset<9, 3>"; ++ let DiagnosticType = "MemSImm9Lsl3"; ++} ++ ++ ++def simm9_lsl3 : Operand { ++ // let DecoderMethod = "DecodeSImmWithOffsetAndScale<9, 3>"; ++ let ParserMatchClass = ++ !cast("ConstantSImm9Lsl3AsmOperandClass"); ++} ++ ++def mem_simm9_lsl3 : mem_generic { ++ let MIOperandInfo = (ops ptr_rc, !cast("simm9_lsl3")); ++ let EncoderMethod = "getMemEncoding9l3"; ++ let ParserMatchClass = ++ !cast("LoongArchMemSimm9Lsl3AsmOperand"); ++} ++ ++ ++ ++ ++// Operands ++ ++def immZExt2Lsa : ImmLeaf(Imm - 1);}]>; ++ ++// Pattern fragments ++def vextract_sext_i8 : PatFrag<(ops node:$vec, node:$idx), ++ (LoongArchVExtractSExt node:$vec, node:$idx, i8)>; ++def vextract_sext_i16 : PatFrag<(ops node:$vec, node:$idx), ++ (LoongArchVExtractSExt node:$vec, node:$idx, i16)>; ++def vextract_sext_i32 : PatFrag<(ops node:$vec, node:$idx), ++ (LoongArchVExtractSExt node:$vec, node:$idx, i32)>; ++def vextract_sext_i64 : PatFrag<(ops node:$vec, node:$idx), ++ (LoongArchVExtractSExt node:$vec, node:$idx, i64)>; ++ ++def vextract_zext_i8 : PatFrag<(ops node:$vec, node:$idx), ++ (LoongArchVExtractZExt node:$vec, node:$idx, i8)>; ++def vextract_zext_i16 : PatFrag<(ops node:$vec, node:$idx), ++ (LoongArchVExtractZExt node:$vec, node:$idx, i16)>; ++def vextract_zext_i32 : PatFrag<(ops node:$vec, node:$idx), ++ (LoongArchVExtractZExt node:$vec, node:$idx, i32)>; ++def vextract_zext_i64 : PatFrag<(ops node:$vec, node:$idx), ++ (LoongArchVExtractZExt node:$vec, node:$idx, i64)>; ++ ++def vldrepl_v16i8 : PatFrag<(ops node:$v1), ++ (v16i8 (LoongArchVBROADCAST node:$v1))>; ++def vldrepl_v8i16 : PatFrag<(ops node:$v1), ++ (v8i16 (LoongArchVBROADCAST node:$v1))>; ++def vldrepl_v4i32 : PatFrag<(ops node:$v1), ++ (v4i32 (LoongArchVBROADCAST node:$v1))>; ++def vldrepl_v2i64 : PatFrag<(ops node:$v1), ++ (v2i64 (LoongArchVBROADCAST node:$v1))>; ++ ++def vinsert_v16i8 : PatFrag<(ops node:$vec, node:$val, node:$idx), ++ (v16i8 (vector_insert node:$vec, node:$val, node:$idx))>; ++def vinsert_v8i16 : PatFrag<(ops node:$vec, node:$val, node:$idx), ++ (v8i16 (vector_insert node:$vec, node:$val, node:$idx))>; ++def vinsert_v4i32 : PatFrag<(ops node:$vec, node:$val, node:$idx), ++ (v4i32 (vector_insert node:$vec, node:$val, node:$idx))>; ++def vinsert_v2i64 : PatFrag<(ops node:$vec, node:$val, node:$idx), ++ (v2i64 (vector_insert node:$vec, node:$val, node:$idx))>; ++ ++class vfsetcc_type : ++ PatFrag<(ops node:$lhs, node:$rhs), ++ (ResTy (vfsetcc (OpTy node:$lhs), (OpTy node:$rhs), CC))>; ++ ++// ISD::SETFALSE cannot occur ++def vfseteq_v4f32 : vfsetcc_type; ++def vfseteq_v2f64 : vfsetcc_type; ++def vfsetge_v4f32 : vfsetcc_type; ++def vfsetge_v2f64 : vfsetcc_type; ++def vfsetgt_v4f32 : vfsetcc_type; ++def vfsetgt_v2f64 : vfsetcc_type; ++def vfsetle_v4f32 : vfsetcc_type; ++def vfsetle_v2f64 : vfsetcc_type; ++def vfsetlt_v4f32 : vfsetcc_type; ++def vfsetlt_v2f64 : vfsetcc_type; ++def vfsetne_v4f32 : vfsetcc_type; ++def vfsetne_v2f64 : vfsetcc_type; ++def vfsetoeq_v4f32 : vfsetcc_type; ++def vfsetoeq_v2f64 : vfsetcc_type; ++def vfsetoge_v4f32 : vfsetcc_type; ++def vfsetoge_v2f64 : vfsetcc_type; ++def vfsetogt_v4f32 : vfsetcc_type; ++def vfsetogt_v2f64 : vfsetcc_type; ++def vfsetole_v4f32 : vfsetcc_type; ++def vfsetole_v2f64 : vfsetcc_type; ++def vfsetolt_v4f32 : vfsetcc_type; ++def vfsetolt_v2f64 : vfsetcc_type; ++def vfsetone_v4f32 : vfsetcc_type; ++def vfsetone_v2f64 : vfsetcc_type; ++def vfsetord_v4f32 : vfsetcc_type; ++def vfsetord_v2f64 : vfsetcc_type; ++def vfsetun_v4f32 : vfsetcc_type; ++def vfsetun_v2f64 : vfsetcc_type; ++def vfsetueq_v4f32 : vfsetcc_type; ++def vfsetueq_v2f64 : vfsetcc_type; ++def vfsetuge_v4f32 : vfsetcc_type; ++def vfsetuge_v2f64 : vfsetcc_type; ++def vfsetugt_v4f32 : vfsetcc_type; ++def vfsetugt_v2f64 : vfsetcc_type; ++def vfsetule_v4f32 : vfsetcc_type; ++def vfsetule_v2f64 : vfsetcc_type; ++def vfsetult_v4f32 : vfsetcc_type; ++def vfsetult_v2f64 : vfsetcc_type; ++def vfsetune_v4f32 : vfsetcc_type; ++def vfsetune_v2f64 : vfsetcc_type; ++ ++ ++ ++// ISD::SETTRUE cannot occur ++// ISD::SETFALSE2 cannot occur ++// ISD::SETTRUE2 cannot occur ++ ++class vsetcc_type : ++ PatFrag<(ops node:$lhs, node:$rhs), ++ (ResTy (vsetcc node:$lhs, node:$rhs, CC))>; ++ ++def vseteq_v16i8 : vsetcc_type; ++def vseteq_v8i16 : vsetcc_type; ++def vseteq_v4i32 : vsetcc_type; ++def vseteq_v2i64 : vsetcc_type; ++def vsetle_v16i8 : vsetcc_type; ++def vsetle_v8i16 : vsetcc_type; ++def vsetle_v4i32 : vsetcc_type; ++def vsetle_v2i64 : vsetcc_type; ++def vsetlt_v16i8 : vsetcc_type; ++def vsetlt_v8i16 : vsetcc_type; ++def vsetlt_v4i32 : vsetcc_type; ++def vsetlt_v2i64 : vsetcc_type; ++def vsetule_v16i8 : vsetcc_type; ++def vsetule_v8i16 : vsetcc_type; ++def vsetule_v4i32 : vsetcc_type; ++def vsetule_v2i64 : vsetcc_type; ++def vsetult_v16i8 : vsetcc_type; ++def vsetult_v8i16 : vsetcc_type; ++def vsetult_v4i32 : vsetcc_type; ++def vsetult_v2i64 : vsetcc_type; ++ ++def vsplati8 : PatFrag<(ops node:$e0), ++ (v16i8 (build_vector node:$e0, node:$e0, ++ node:$e0, node:$e0, ++ node:$e0, node:$e0, ++ node:$e0, node:$e0, ++ node:$e0, node:$e0, ++ node:$e0, node:$e0, ++ node:$e0, node:$e0, ++ node:$e0, node:$e0))>; ++def vsplati16 : PatFrag<(ops node:$e0), ++ (v8i16 (build_vector node:$e0, node:$e0, ++ node:$e0, node:$e0, ++ node:$e0, node:$e0, ++ node:$e0, node:$e0))>; ++def vsplati32 : PatFrag<(ops node:$e0), ++ (v4i32 (build_vector node:$e0, node:$e0, ++ node:$e0, node:$e0))>; ++ ++def vsplati64_imm_eq_1 : PatLeaf<(bitconvert (v4i32 (build_vector))), [{ + APInt Imm; ++ SDNode *BV = N->getOperand(0).getNode(); + EVT EltTy = N->getValueType(0).getVectorElementType(); +- N = N->getOperand(0).getNode(); + +- return selectVSplat(N, Imm, EltTy.getSizeInBits()) && +- Imm.getBitWidth() == EltTy.getSizeInBits() && +- Imm == APFloat(+1.0).bitcastToAPInt(); ++ return selectVSplat(BV, Imm, EltTy.getSizeInBits()) && ++ Imm.getBitWidth() == EltTy.getSizeInBits() && Imm == 1; + }]>; + +-def vsplati8imm7 : PatFrag<(ops node:$reg), +- (and node:$reg, vsplati8_imm_eq_7)>; +-def vsplati16imm15 : PatFrag<(ops node:$reg), +- (and node:$reg, vsplati16_imm_eq_15)>; +-def vsplati32imm31 : PatFrag<(ops node:$reg), +- (and node:$reg, vsplati32_imm_eq_31)>; +-def vsplati64imm63 : PatFrag<(ops node:$reg), +- (and node:$reg, vsplati64_imm_eq_63)>; ++def vsplati64 : PatFrag<(ops node:$e0), ++ (v2i64 (build_vector node:$e0, node:$e0))>; ++ ++def vsplati64_splat_d : PatFrag<(ops node:$e0), ++ (v2i64 (bitconvert ++ (v4i32 (and ++ (v4i32 (build_vector node:$e0, ++ node:$e0, ++ node:$e0, ++ node:$e0)), ++ vsplati64_imm_eq_1))))>; ++ ++def vsplatf32 : PatFrag<(ops node:$e0), ++ (v4f32 (build_vector node:$e0, node:$e0, ++ node:$e0, node:$e0))>; ++def vsplatf64 : PatFrag<(ops node:$e0), ++ (v2f64 (build_vector node:$e0, node:$e0))>; ++ ++def vsplati8_elt : PatFrag<(ops node:$v, node:$i), ++ (LoongArchVSHF (vsplati8 node:$i), node:$v, node:$v)>; ++def vsplati16_elt : PatFrag<(ops node:$v, node:$i), ++ (LoongArchVSHF (vsplati16 node:$i), node:$v, node:$v)>; ++def vsplati32_elt : PatFrag<(ops node:$v, node:$i), ++ (LoongArchVSHF (vsplati32 node:$i), node:$v, node:$v)>; ++def vsplati64_elt : PatFrag<(ops node:$v, node:$i), ++ (LoongArchVSHF (vsplati64_splat_d node:$i),node:$v, node:$v)>; ++ ++class SplatPatLeaf ++ : PatLeaf { ++ Operand OpClass = opclass; ++} ++ ++class SplatComplexPattern roots = [], ++ list props = []> : ++ ComplexPattern { ++ Operand OpClass = opclass; ++} ++ ++def vsplati8_uimm3 : SplatComplexPattern; ++ ++def vsplati8_uimm4 : SplatComplexPattern; ++ ++def vsplati8_uimm5 : SplatComplexPattern; ++ ++def vsplati8_uimm8 : SplatComplexPattern; ++ ++def vsplati8_simm5 : SplatComplexPattern; ++ ++def vsplati16_uimm3 : SplatComplexPattern; ++ ++def vsplati16_uimm4 : SplatComplexPattern; ++ ++def vsplati16_uimm5 : SplatComplexPattern; ++ ++def vsplati16_simm5 : SplatComplexPattern; + +-foreach N = [3, 4, 5, 6, 8] in +- def SplatPat_uimm#N : ComplexPattern", +- [build_vector, bitconvert], [], 2>; ++def vsplati32_uimm2 : SplatComplexPattern; ++ ++def vsplati32_uimm5 : SplatComplexPattern; ++ ++def vsplati32_simm5 : SplatComplexPattern; ++ ++def vsplati64_uimm1 : SplatComplexPattern; ++ ++def vsplati64_uimm5 : SplatComplexPattern; + +-foreach N = [5] in +- def SplatPat_simm#N : ComplexPattern", +- [build_vector, bitconvert]>; ++def vsplati64_uimm6 : SplatComplexPattern; + +-def vsplat_uimm_inv_pow2 : ComplexPattern; + +-def vsplat_uimm_pow2 : ComplexPattern; ++ ++// Any build_vector that is a constant splat with a value that equals 1 ++// FIXME: These should be a ComplexPattern but we can't use them because the ++// ISel generator requires the uses to have a name, but providing a name ++// causes other errors ("used in pattern but not operand list") ++def vsplat_imm_eq_1 : PatLeaf<(build_vector), [{ ++ APInt Imm; ++ EVT EltTy = N->getValueType(0).getVectorElementType(); ++ ++ return selectVSplat(N, Imm, EltTy.getSizeInBits()) && ++ Imm.getBitWidth() == EltTy.getSizeInBits() && Imm == 1; ++}]>; ++ ++def vbitclr_b : PatFrag<(ops node:$vj, node:$vk), ++ (and node:$vj, (xor (shl vsplat_imm_eq_1, node:$vk), ++ immAllOnesV))>; ++def vbitclr_h : PatFrag<(ops node:$vj, node:$vk), ++ (and node:$vj, (xor (shl vsplat_imm_eq_1, node:$vk), ++ immAllOnesV))>; ++def vbitclr_w : PatFrag<(ops node:$vj, node:$vk), ++ (and node:$vj, (xor (shl vsplat_imm_eq_1, node:$vk), ++ immAllOnesV))>; ++def vbitclr_d : PatFrag<(ops node:$vj, node:$vk), ++ (and node:$vj, (xor (shl (v2i64 vsplati64_imm_eq_1), ++ node:$vk), ++ (bitconvert (v4i32 immAllOnesV))))>; ++ ++def vbneg_b : PatFrag<(ops node:$vj, node:$vk), ++ (xor node:$vj, (shl vsplat_imm_eq_1, node:$vk))>; ++def vbneg_h : PatFrag<(ops node:$vj, node:$vk), ++ (xor node:$vj, (shl vsplat_imm_eq_1, node:$vk))>; ++def vbneg_w : PatFrag<(ops node:$vj, node:$vk), ++ (xor node:$vj, (shl vsplat_imm_eq_1, node:$vk))>; ++def vbneg_d : PatFrag<(ops node:$vj, node:$vk), ++ (xor node:$vj, (shl (v2i64 vsplati64_imm_eq_1), ++ node:$vk))>; ++ ++def vbset_b : PatFrag<(ops node:$vj, node:$vk), ++ (or node:$vj, (shl vsplat_imm_eq_1, node:$vk))>; ++def vbset_h : PatFrag<(ops node:$vj, node:$vk), ++ (or node:$vj, (shl vsplat_imm_eq_1, node:$vk))>; ++def vbset_w : PatFrag<(ops node:$vj, node:$vk), ++ (or node:$vj, (shl vsplat_imm_eq_1, node:$vk))>; ++def vbset_d : PatFrag<(ops node:$vj, node:$vk), ++ (or node:$vj, (shl (v2i64 vsplati64_imm_eq_1), ++ node:$vk))>; + + def muladd : PatFrag<(ops node:$vd, node:$vj, node:$vk), + (add node:$vd, (mul node:$vj, node:$vk))>; +@@ -147,1948 +772,5000 @@ def muladd : PatFrag<(ops node:$vd, node:$vj, node:$vk), + def mulsub : PatFrag<(ops node:$vd, node:$vj, node:$vk), + (sub node:$vd, (mul node:$vj, node:$vk))>; + +-def lsxsplati8 : PatFrag<(ops node:$e0), +- (v16i8 (build_vector node:$e0, node:$e0, +- node:$e0, node:$e0, +- node:$e0, node:$e0, +- node:$e0, node:$e0, +- node:$e0, node:$e0, +- node:$e0, node:$e0, +- node:$e0, node:$e0, +- node:$e0, node:$e0))>; +-def lsxsplati16 : PatFrag<(ops node:$e0), +- (v8i16 (build_vector node:$e0, node:$e0, +- node:$e0, node:$e0, +- node:$e0, node:$e0, +- node:$e0, node:$e0))>; +-def lsxsplati32 : PatFrag<(ops node:$e0), +- (v4i32 (build_vector node:$e0, node:$e0, +- node:$e0, node:$e0))>; +-def lsxsplati64 : PatFrag<(ops node:$e0), +- (v2i64 (build_vector node:$e0, node:$e0))>; +-def lsxsplatf32 : PatFrag<(ops node:$e0), +- (v4f32 (build_vector node:$e0, node:$e0, +- node:$e0, node:$e0))>; +-def lsxsplatf64 : PatFrag<(ops node:$e0), +- (v2f64 (build_vector node:$e0, node:$e0))>; +- +-def to_valid_timm : SDNodeXForm(N); +- return CurDAG->getTargetConstant(CN->getSExtValue(), SDLoc(N), Subtarget->getGRLenVT()); +-}]>; ++class IsCommutable { ++ bit isCommutable = 1; ++} + +-//===----------------------------------------------------------------------===// +-// Instruction class templates +-//===----------------------------------------------------------------------===// + +-class LSX1RI13_VI op, Operand ImmOpnd = simm13> +- : Fmt1RI13_VI; +- +-class LSX2R_VV op> +- : Fmt2R_VV; +- +-class LSX2R_VR op> +- : Fmt2R_VR; +- +-class LSX2R_CV op> +- : Fmt2R_CV; +- +-class LSX2RI1_VVI op, Operand ImmOpnd = uimm1> +- : Fmt2RI1_VVI; +- +-class LSX2RI1_RVI op, Operand ImmOpnd = uimm1> +- : Fmt2RI1_RVI; +- +-class LSX2RI2_VVI op, Operand ImmOpnd = uimm2> +- : Fmt2RI2_VVI; +- +-class LSX2RI2_RVI op, Operand ImmOpnd = uimm2> +- : Fmt2RI2_RVI; +- +-class LSX2RI3_VVI op, Operand ImmOpnd = uimm3> +- : Fmt2RI3_VVI; +- +-class LSX2RI3_RVI op, Operand ImmOpnd = uimm3> +- : Fmt2RI3_RVI; +- +-class LSX2RI4_VVI op, Operand ImmOpnd = uimm4> +- : Fmt2RI4_VVI; +- +-class LSX2RI4_RVI op, Operand ImmOpnd = uimm4> +- : Fmt2RI4_RVI; +- +-class LSX2RI5_VVI op, Operand ImmOpnd = uimm5> +- : Fmt2RI5_VVI; +- +-class LSX2RI6_VVI op, Operand ImmOpnd = uimm6> +- : Fmt2RI6_VVI; +- +-class LSX2RI8_VVI op, Operand ImmOpnd = uimm8> +- : Fmt2RI8_VVI; +- +-class LSX2RI8I1_VRII op, Operand ImmOpnd = simm8, +- Operand IdxOpnd = uimm1> +- : Fmt2RI8I1_VRII; +-class LSX2RI8I2_VRII op, Operand ImmOpnd = simm8, +- Operand IdxOpnd = uimm2> +- : Fmt2RI8I2_VRII; +-class LSX2RI8I3_VRII op, Operand ImmOpnd = simm8, +- Operand IdxOpnd = uimm3> +- : Fmt2RI8I3_VRII; +-class LSX2RI8I4_VRII op, Operand ImmOpnd = simm8, +- Operand IdxOpnd = uimm4> +- : Fmt2RI8I4_VRII; +- +-class LSX3R_VVV op> +- : Fmt3R_VVV; +- +-class LSX3R_VVR op> +- : Fmt3R_VVR; +- +-class LSX4R_VVVV op> +- : Fmt4R_VVVV; +- +-let Constraints = "$vd = $dst" in { +- +-class LSX2RI1_VVRI op, Operand ImmOpnd = uimm1> +- : Fmt2RI1_VRI; +-class LSX2RI2_VVRI op, Operand ImmOpnd = uimm2> +- : Fmt2RI2_VRI; +-class LSX2RI3_VVRI op, Operand ImmOpnd = uimm3> +- : Fmt2RI3_VRI; +-class LSX2RI4_VVRI op, Operand ImmOpnd = uimm4> +- : Fmt2RI4_VRI; +- +-class LSX2RI4_VVVI op, Operand ImmOpnd = uimm4> +- : Fmt2RI4_VVI; +-class LSX2RI5_VVVI op, Operand ImmOpnd = uimm5> +- : Fmt2RI5_VVI; +-class LSX2RI6_VVVI op, Operand ImmOpnd = uimm6> +- : Fmt2RI6_VVI; +-class LSX2RI7_VVVI op, Operand ImmOpnd = uimm7> +- : Fmt2RI7_VVI; +- +-class LSX2RI8_VVVI op, Operand ImmOpnd = uimm8> +- : Fmt2RI8_VVI; +- +-class LSX3R_VVVV op> +- : Fmt3R_VVV; +- +-} // Constraints = "$vd = $dst" +- +-class LSX2RI9_Load op, Operand ImmOpnd = simm9_lsl3> +- : Fmt2RI9_VRI; +-class LSX2RI10_Load op, Operand ImmOpnd = simm10_lsl2> +- : Fmt2RI10_VRI; +-class LSX2RI11_Load op, Operand ImmOpnd = simm11_lsl1> +- : Fmt2RI11_VRI; +-class LSX2RI12_Load op, Operand ImmOpnd = simm12> +- : Fmt2RI12_VRI; +-class LSX2RI12_Store op, Operand ImmOpnd = simm12> +- : Fmt2RI12_VRI; +- +-class LSX3R_Load op> +- : Fmt3R_VRR; +-class LSX3R_Store op> +- : Fmt3R_VRR; + +-//===----------------------------------------------------------------------===// +-// Instructions +-//===----------------------------------------------------------------------===// ++//class ++class LSX_3R_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, ROVK:$vk); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $vk"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, ROVK:$vk))]; ++} + +-let hasSideEffects = 0, Predicates = [HasExtLSX] in { +- +-let mayLoad = 0, mayStore = 0 in { +- +-def VADD_B : LSX3R_VVV<0x700a0000>; +-def VADD_H : LSX3R_VVV<0x700a8000>; +-def VADD_W : LSX3R_VVV<0x700b0000>; +-def VADD_D : LSX3R_VVV<0x700b8000>; +-def VADD_Q : LSX3R_VVV<0x712d0000>; +- +-def VSUB_B : LSX3R_VVV<0x700c0000>; +-def VSUB_H : LSX3R_VVV<0x700c8000>; +-def VSUB_W : LSX3R_VVV<0x700d0000>; +-def VSUB_D : LSX3R_VVV<0x700d8000>; +-def VSUB_Q : LSX3R_VVV<0x712d8000>; +- +-def VADDI_BU : LSX2RI5_VVI<0x728a0000>; +-def VADDI_HU : LSX2RI5_VVI<0x728a8000>; +-def VADDI_WU : LSX2RI5_VVI<0x728b0000>; +-def VADDI_DU : LSX2RI5_VVI<0x728b8000>; +- +-def VSUBI_BU : LSX2RI5_VVI<0x728c0000>; +-def VSUBI_HU : LSX2RI5_VVI<0x728c8000>; +-def VSUBI_WU : LSX2RI5_VVI<0x728d0000>; +-def VSUBI_DU : LSX2RI5_VVI<0x728d8000>; +- +-def VNEG_B : LSX2R_VV<0x729c3000>; +-def VNEG_H : LSX2R_VV<0x729c3400>; +-def VNEG_W : LSX2R_VV<0x729c3800>; +-def VNEG_D : LSX2R_VV<0x729c3c00>; +- +-def VSADD_B : LSX3R_VVV<0x70460000>; +-def VSADD_H : LSX3R_VVV<0x70468000>; +-def VSADD_W : LSX3R_VVV<0x70470000>; +-def VSADD_D : LSX3R_VVV<0x70478000>; +-def VSADD_BU : LSX3R_VVV<0x704a0000>; +-def VSADD_HU : LSX3R_VVV<0x704a8000>; +-def VSADD_WU : LSX3R_VVV<0x704b0000>; +-def VSADD_DU : LSX3R_VVV<0x704b8000>; +- +-def VSSUB_B : LSX3R_VVV<0x70480000>; +-def VSSUB_H : LSX3R_VVV<0x70488000>; +-def VSSUB_W : LSX3R_VVV<0x70490000>; +-def VSSUB_D : LSX3R_VVV<0x70498000>; +-def VSSUB_BU : LSX3R_VVV<0x704c0000>; +-def VSSUB_HU : LSX3R_VVV<0x704c8000>; +-def VSSUB_WU : LSX3R_VVV<0x704d0000>; +-def VSSUB_DU : LSX3R_VVV<0x704d8000>; +- +-def VHADDW_H_B : LSX3R_VVV<0x70540000>; +-def VHADDW_W_H : LSX3R_VVV<0x70548000>; +-def VHADDW_D_W : LSX3R_VVV<0x70550000>; +-def VHADDW_Q_D : LSX3R_VVV<0x70558000>; +-def VHADDW_HU_BU : LSX3R_VVV<0x70580000>; +-def VHADDW_WU_HU : LSX3R_VVV<0x70588000>; +-def VHADDW_DU_WU : LSX3R_VVV<0x70590000>; +-def VHADDW_QU_DU : LSX3R_VVV<0x70598000>; +- +-def VHSUBW_H_B : LSX3R_VVV<0x70560000>; +-def VHSUBW_W_H : LSX3R_VVV<0x70568000>; +-def VHSUBW_D_W : LSX3R_VVV<0x70570000>; +-def VHSUBW_Q_D : LSX3R_VVV<0x70578000>; +-def VHSUBW_HU_BU : LSX3R_VVV<0x705a0000>; +-def VHSUBW_WU_HU : LSX3R_VVV<0x705a8000>; +-def VHSUBW_DU_WU : LSX3R_VVV<0x705b0000>; +-def VHSUBW_QU_DU : LSX3R_VVV<0x705b8000>; +- +-def VADDWEV_H_B : LSX3R_VVV<0x701e0000>; +-def VADDWEV_W_H : LSX3R_VVV<0x701e8000>; +-def VADDWEV_D_W : LSX3R_VVV<0x701f0000>; +-def VADDWEV_Q_D : LSX3R_VVV<0x701f8000>; +-def VADDWOD_H_B : LSX3R_VVV<0x70220000>; +-def VADDWOD_W_H : LSX3R_VVV<0x70228000>; +-def VADDWOD_D_W : LSX3R_VVV<0x70230000>; +-def VADDWOD_Q_D : LSX3R_VVV<0x70238000>; +- +-def VSUBWEV_H_B : LSX3R_VVV<0x70200000>; +-def VSUBWEV_W_H : LSX3R_VVV<0x70208000>; +-def VSUBWEV_D_W : LSX3R_VVV<0x70210000>; +-def VSUBWEV_Q_D : LSX3R_VVV<0x70218000>; +-def VSUBWOD_H_B : LSX3R_VVV<0x70240000>; +-def VSUBWOD_W_H : LSX3R_VVV<0x70248000>; +-def VSUBWOD_D_W : LSX3R_VVV<0x70250000>; +-def VSUBWOD_Q_D : LSX3R_VVV<0x70258000>; +- +-def VADDWEV_H_BU : LSX3R_VVV<0x702e0000>; +-def VADDWEV_W_HU : LSX3R_VVV<0x702e8000>; +-def VADDWEV_D_WU : LSX3R_VVV<0x702f0000>; +-def VADDWEV_Q_DU : LSX3R_VVV<0x702f8000>; +-def VADDWOD_H_BU : LSX3R_VVV<0x70320000>; +-def VADDWOD_W_HU : LSX3R_VVV<0x70328000>; +-def VADDWOD_D_WU : LSX3R_VVV<0x70330000>; +-def VADDWOD_Q_DU : LSX3R_VVV<0x70338000>; +- +-def VSUBWEV_H_BU : LSX3R_VVV<0x70300000>; +-def VSUBWEV_W_HU : LSX3R_VVV<0x70308000>; +-def VSUBWEV_D_WU : LSX3R_VVV<0x70310000>; +-def VSUBWEV_Q_DU : LSX3R_VVV<0x70318000>; +-def VSUBWOD_H_BU : LSX3R_VVV<0x70340000>; +-def VSUBWOD_W_HU : LSX3R_VVV<0x70348000>; +-def VSUBWOD_D_WU : LSX3R_VVV<0x70350000>; +-def VSUBWOD_Q_DU : LSX3R_VVV<0x70358000>; +- +-def VADDWEV_H_BU_B : LSX3R_VVV<0x703e0000>; +-def VADDWEV_W_HU_H : LSX3R_VVV<0x703e8000>; +-def VADDWEV_D_WU_W : LSX3R_VVV<0x703f0000>; +-def VADDWEV_Q_DU_D : LSX3R_VVV<0x703f8000>; +-def VADDWOD_H_BU_B : LSX3R_VVV<0x70400000>; +-def VADDWOD_W_HU_H : LSX3R_VVV<0x70408000>; +-def VADDWOD_D_WU_W : LSX3R_VVV<0x70410000>; +-def VADDWOD_Q_DU_D : LSX3R_VVV<0x70418000>; +- +-def VAVG_B : LSX3R_VVV<0x70640000>; +-def VAVG_H : LSX3R_VVV<0x70648000>; +-def VAVG_W : LSX3R_VVV<0x70650000>; +-def VAVG_D : LSX3R_VVV<0x70658000>; +-def VAVG_BU : LSX3R_VVV<0x70660000>; +-def VAVG_HU : LSX3R_VVV<0x70668000>; +-def VAVG_WU : LSX3R_VVV<0x70670000>; +-def VAVG_DU : LSX3R_VVV<0x70678000>; +-def VAVGR_B : LSX3R_VVV<0x70680000>; +-def VAVGR_H : LSX3R_VVV<0x70688000>; +-def VAVGR_W : LSX3R_VVV<0x70690000>; +-def VAVGR_D : LSX3R_VVV<0x70698000>; +-def VAVGR_BU : LSX3R_VVV<0x706a0000>; +-def VAVGR_HU : LSX3R_VVV<0x706a8000>; +-def VAVGR_WU : LSX3R_VVV<0x706b0000>; +-def VAVGR_DU : LSX3R_VVV<0x706b8000>; +- +-def VABSD_B : LSX3R_VVV<0x70600000>; +-def VABSD_H : LSX3R_VVV<0x70608000>; +-def VABSD_W : LSX3R_VVV<0x70610000>; +-def VABSD_D : LSX3R_VVV<0x70618000>; +-def VABSD_BU : LSX3R_VVV<0x70620000>; +-def VABSD_HU : LSX3R_VVV<0x70628000>; +-def VABSD_WU : LSX3R_VVV<0x70630000>; +-def VABSD_DU : LSX3R_VVV<0x70638000>; +- +-def VADDA_B : LSX3R_VVV<0x705c0000>; +-def VADDA_H : LSX3R_VVV<0x705c8000>; +-def VADDA_W : LSX3R_VVV<0x705d0000>; +-def VADDA_D : LSX3R_VVV<0x705d8000>; +- +-def VMAX_B : LSX3R_VVV<0x70700000>; +-def VMAX_H : LSX3R_VVV<0x70708000>; +-def VMAX_W : LSX3R_VVV<0x70710000>; +-def VMAX_D : LSX3R_VVV<0x70718000>; +-def VMAXI_B : LSX2RI5_VVI<0x72900000, simm5>; +-def VMAXI_H : LSX2RI5_VVI<0x72908000, simm5>; +-def VMAXI_W : LSX2RI5_VVI<0x72910000, simm5>; +-def VMAXI_D : LSX2RI5_VVI<0x72918000, simm5>; +-def VMAX_BU : LSX3R_VVV<0x70740000>; +-def VMAX_HU : LSX3R_VVV<0x70748000>; +-def VMAX_WU : LSX3R_VVV<0x70750000>; +-def VMAX_DU : LSX3R_VVV<0x70758000>; +-def VMAXI_BU : LSX2RI5_VVI<0x72940000>; +-def VMAXI_HU : LSX2RI5_VVI<0x72948000>; +-def VMAXI_WU : LSX2RI5_VVI<0x72950000>; +-def VMAXI_DU : LSX2RI5_VVI<0x72958000>; +- +-def VMIN_B : LSX3R_VVV<0x70720000>; +-def VMIN_H : LSX3R_VVV<0x70728000>; +-def VMIN_W : LSX3R_VVV<0x70730000>; +-def VMIN_D : LSX3R_VVV<0x70738000>; +-def VMINI_B : LSX2RI5_VVI<0x72920000, simm5>; +-def VMINI_H : LSX2RI5_VVI<0x72928000, simm5>; +-def VMINI_W : LSX2RI5_VVI<0x72930000, simm5>; +-def VMINI_D : LSX2RI5_VVI<0x72938000, simm5>; +-def VMIN_BU : LSX3R_VVV<0x70760000>; +-def VMIN_HU : LSX3R_VVV<0x70768000>; +-def VMIN_WU : LSX3R_VVV<0x70770000>; +-def VMIN_DU : LSX3R_VVV<0x70778000>; +-def VMINI_BU : LSX2RI5_VVI<0x72960000>; +-def VMINI_HU : LSX2RI5_VVI<0x72968000>; +-def VMINI_WU : LSX2RI5_VVI<0x72970000>; +-def VMINI_DU : LSX2RI5_VVI<0x72978000>; +- +-def VMUL_B : LSX3R_VVV<0x70840000>; +-def VMUL_H : LSX3R_VVV<0x70848000>; +-def VMUL_W : LSX3R_VVV<0x70850000>; +-def VMUL_D : LSX3R_VVV<0x70858000>; +- +-def VMUH_B : LSX3R_VVV<0x70860000>; +-def VMUH_H : LSX3R_VVV<0x70868000>; +-def VMUH_W : LSX3R_VVV<0x70870000>; +-def VMUH_D : LSX3R_VVV<0x70878000>; +-def VMUH_BU : LSX3R_VVV<0x70880000>; +-def VMUH_HU : LSX3R_VVV<0x70888000>; +-def VMUH_WU : LSX3R_VVV<0x70890000>; +-def VMUH_DU : LSX3R_VVV<0x70898000>; +- +-def VMULWEV_H_B : LSX3R_VVV<0x70900000>; +-def VMULWEV_W_H : LSX3R_VVV<0x70908000>; +-def VMULWEV_D_W : LSX3R_VVV<0x70910000>; +-def VMULWEV_Q_D : LSX3R_VVV<0x70918000>; +-def VMULWOD_H_B : LSX3R_VVV<0x70920000>; +-def VMULWOD_W_H : LSX3R_VVV<0x70928000>; +-def VMULWOD_D_W : LSX3R_VVV<0x70930000>; +-def VMULWOD_Q_D : LSX3R_VVV<0x70938000>; +-def VMULWEV_H_BU : LSX3R_VVV<0x70980000>; +-def VMULWEV_W_HU : LSX3R_VVV<0x70988000>; +-def VMULWEV_D_WU : LSX3R_VVV<0x70990000>; +-def VMULWEV_Q_DU : LSX3R_VVV<0x70998000>; +-def VMULWOD_H_BU : LSX3R_VVV<0x709a0000>; +-def VMULWOD_W_HU : LSX3R_VVV<0x709a8000>; +-def VMULWOD_D_WU : LSX3R_VVV<0x709b0000>; +-def VMULWOD_Q_DU : LSX3R_VVV<0x709b8000>; +-def VMULWEV_H_BU_B : LSX3R_VVV<0x70a00000>; +-def VMULWEV_W_HU_H : LSX3R_VVV<0x70a08000>; +-def VMULWEV_D_WU_W : LSX3R_VVV<0x70a10000>; +-def VMULWEV_Q_DU_D : LSX3R_VVV<0x70a18000>; +-def VMULWOD_H_BU_B : LSX3R_VVV<0x70a20000>; +-def VMULWOD_W_HU_H : LSX3R_VVV<0x70a28000>; +-def VMULWOD_D_WU_W : LSX3R_VVV<0x70a30000>; +-def VMULWOD_Q_DU_D : LSX3R_VVV<0x70a38000>; +- +-def VMADD_B : LSX3R_VVVV<0x70a80000>; +-def VMADD_H : LSX3R_VVVV<0x70a88000>; +-def VMADD_W : LSX3R_VVVV<0x70a90000>; +-def VMADD_D : LSX3R_VVVV<0x70a98000>; +- +-def VMSUB_B : LSX3R_VVVV<0x70aa0000>; +-def VMSUB_H : LSX3R_VVVV<0x70aa8000>; +-def VMSUB_W : LSX3R_VVVV<0x70ab0000>; +-def VMSUB_D : LSX3R_VVVV<0x70ab8000>; +- +-def VMADDWEV_H_B : LSX3R_VVVV<0x70ac0000>; +-def VMADDWEV_W_H : LSX3R_VVVV<0x70ac8000>; +-def VMADDWEV_D_W : LSX3R_VVVV<0x70ad0000>; +-def VMADDWEV_Q_D : LSX3R_VVVV<0x70ad8000>; +-def VMADDWOD_H_B : LSX3R_VVVV<0x70ae0000>; +-def VMADDWOD_W_H : LSX3R_VVVV<0x70ae8000>; +-def VMADDWOD_D_W : LSX3R_VVVV<0x70af0000>; +-def VMADDWOD_Q_D : LSX3R_VVVV<0x70af8000>; +-def VMADDWEV_H_BU : LSX3R_VVVV<0x70b40000>; +-def VMADDWEV_W_HU : LSX3R_VVVV<0x70b48000>; +-def VMADDWEV_D_WU : LSX3R_VVVV<0x70b50000>; +-def VMADDWEV_Q_DU : LSX3R_VVVV<0x70b58000>; +-def VMADDWOD_H_BU : LSX3R_VVVV<0x70b60000>; +-def VMADDWOD_W_HU : LSX3R_VVVV<0x70b68000>; +-def VMADDWOD_D_WU : LSX3R_VVVV<0x70b70000>; +-def VMADDWOD_Q_DU : LSX3R_VVVV<0x70b78000>; +-def VMADDWEV_H_BU_B : LSX3R_VVVV<0x70bc0000>; +-def VMADDWEV_W_HU_H : LSX3R_VVVV<0x70bc8000>; +-def VMADDWEV_D_WU_W : LSX3R_VVVV<0x70bd0000>; +-def VMADDWEV_Q_DU_D : LSX3R_VVVV<0x70bd8000>; +-def VMADDWOD_H_BU_B : LSX3R_VVVV<0x70be0000>; +-def VMADDWOD_W_HU_H : LSX3R_VVVV<0x70be8000>; +-def VMADDWOD_D_WU_W : LSX3R_VVVV<0x70bf0000>; +-def VMADDWOD_Q_DU_D : LSX3R_VVVV<0x70bf8000>; +- +-def VDIV_B : LSX3R_VVV<0x70e00000>; +-def VDIV_H : LSX3R_VVV<0x70e08000>; +-def VDIV_W : LSX3R_VVV<0x70e10000>; +-def VDIV_D : LSX3R_VVV<0x70e18000>; +-def VDIV_BU : LSX3R_VVV<0x70e40000>; +-def VDIV_HU : LSX3R_VVV<0x70e48000>; +-def VDIV_WU : LSX3R_VVV<0x70e50000>; +-def VDIV_DU : LSX3R_VVV<0x70e58000>; +- +-def VMOD_B : LSX3R_VVV<0x70e20000>; +-def VMOD_H : LSX3R_VVV<0x70e28000>; +-def VMOD_W : LSX3R_VVV<0x70e30000>; +-def VMOD_D : LSX3R_VVV<0x70e38000>; +-def VMOD_BU : LSX3R_VVV<0x70e60000>; +-def VMOD_HU : LSX3R_VVV<0x70e68000>; +-def VMOD_WU : LSX3R_VVV<0x70e70000>; +-def VMOD_DU : LSX3R_VVV<0x70e78000>; +- +-def VSAT_B : LSX2RI3_VVI<0x73242000>; +-def VSAT_H : LSX2RI4_VVI<0x73244000>; +-def VSAT_W : LSX2RI5_VVI<0x73248000>; +-def VSAT_D : LSX2RI6_VVI<0x73250000>; +-def VSAT_BU : LSX2RI3_VVI<0x73282000>; +-def VSAT_HU : LSX2RI4_VVI<0x73284000>; +-def VSAT_WU : LSX2RI5_VVI<0x73288000>; +-def VSAT_DU : LSX2RI6_VVI<0x73290000>; +- +-def VEXTH_H_B : LSX2R_VV<0x729ee000>; +-def VEXTH_W_H : LSX2R_VV<0x729ee400>; +-def VEXTH_D_W : LSX2R_VV<0x729ee800>; +-def VEXTH_Q_D : LSX2R_VV<0x729eec00>; +-def VEXTH_HU_BU : LSX2R_VV<0x729ef000>; +-def VEXTH_WU_HU : LSX2R_VV<0x729ef400>; +-def VEXTH_DU_WU : LSX2R_VV<0x729ef800>; +-def VEXTH_QU_DU : LSX2R_VV<0x729efc00>; +- +-def VSIGNCOV_B : LSX3R_VVV<0x712e0000>; +-def VSIGNCOV_H : LSX3R_VVV<0x712e8000>; +-def VSIGNCOV_W : LSX3R_VVV<0x712f0000>; +-def VSIGNCOV_D : LSX3R_VVV<0x712f8000>; +- +-def VMSKLTZ_B : LSX2R_VV<0x729c4000>; +-def VMSKLTZ_H : LSX2R_VV<0x729c4400>; +-def VMSKLTZ_W : LSX2R_VV<0x729c4800>; +-def VMSKLTZ_D : LSX2R_VV<0x729c4c00>; +- +-def VMSKGEZ_B : LSX2R_VV<0x729c5000>; +- +-def VMSKNZ_B : LSX2R_VV<0x729c6000>; +- +-def VLDI : LSX1RI13_VI<0x73e00000>; +- +-def VAND_V : LSX3R_VVV<0x71260000>; +-def VOR_V : LSX3R_VVV<0x71268000>; +-def VXOR_V : LSX3R_VVV<0x71270000>; +-def VNOR_V : LSX3R_VVV<0x71278000>; +-def VANDN_V : LSX3R_VVV<0x71280000>; +-def VORN_V : LSX3R_VVV<0x71288000>; +- +-def VANDI_B : LSX2RI8_VVI<0x73d00000>; +-def VORI_B : LSX2RI8_VVI<0x73d40000>; +-def VXORI_B : LSX2RI8_VVI<0x73d80000>; +-def VNORI_B : LSX2RI8_VVI<0x73dc0000>; +- +-def VSLL_B : LSX3R_VVV<0x70e80000>; +-def VSLL_H : LSX3R_VVV<0x70e88000>; +-def VSLL_W : LSX3R_VVV<0x70e90000>; +-def VSLL_D : LSX3R_VVV<0x70e98000>; +-def VSLLI_B : LSX2RI3_VVI<0x732c2000>; +-def VSLLI_H : LSX2RI4_VVI<0x732c4000>; +-def VSLLI_W : LSX2RI5_VVI<0x732c8000>; +-def VSLLI_D : LSX2RI6_VVI<0x732d0000>; +- +-def VSRL_B : LSX3R_VVV<0x70ea0000>; +-def VSRL_H : LSX3R_VVV<0x70ea8000>; +-def VSRL_W : LSX3R_VVV<0x70eb0000>; +-def VSRL_D : LSX3R_VVV<0x70eb8000>; +-def VSRLI_B : LSX2RI3_VVI<0x73302000>; +-def VSRLI_H : LSX2RI4_VVI<0x73304000>; +-def VSRLI_W : LSX2RI5_VVI<0x73308000>; +-def VSRLI_D : LSX2RI6_VVI<0x73310000>; +- +-def VSRA_B : LSX3R_VVV<0x70ec0000>; +-def VSRA_H : LSX3R_VVV<0x70ec8000>; +-def VSRA_W : LSX3R_VVV<0x70ed0000>; +-def VSRA_D : LSX3R_VVV<0x70ed8000>; +-def VSRAI_B : LSX2RI3_VVI<0x73342000>; +-def VSRAI_H : LSX2RI4_VVI<0x73344000>; +-def VSRAI_W : LSX2RI5_VVI<0x73348000>; +-def VSRAI_D : LSX2RI6_VVI<0x73350000>; +- +-def VROTR_B : LSX3R_VVV<0x70ee0000>; +-def VROTR_H : LSX3R_VVV<0x70ee8000>; +-def VROTR_W : LSX3R_VVV<0x70ef0000>; +-def VROTR_D : LSX3R_VVV<0x70ef8000>; +-def VROTRI_B : LSX2RI3_VVI<0x72a02000>; +-def VROTRI_H : LSX2RI4_VVI<0x72a04000>; +-def VROTRI_W : LSX2RI5_VVI<0x72a08000>; +-def VROTRI_D : LSX2RI6_VVI<0x72a10000>; +- +-def VSLLWIL_H_B : LSX2RI3_VVI<0x73082000>; +-def VSLLWIL_W_H : LSX2RI4_VVI<0x73084000>; +-def VSLLWIL_D_W : LSX2RI5_VVI<0x73088000>; +-def VEXTL_Q_D : LSX2R_VV<0x73090000>; +-def VSLLWIL_HU_BU : LSX2RI3_VVI<0x730c2000>; +-def VSLLWIL_WU_HU : LSX2RI4_VVI<0x730c4000>; +-def VSLLWIL_DU_WU : LSX2RI5_VVI<0x730c8000>; +-def VEXTL_QU_DU : LSX2R_VV<0x730d0000>; +- +-def VSRLR_B : LSX3R_VVV<0x70f00000>; +-def VSRLR_H : LSX3R_VVV<0x70f08000>; +-def VSRLR_W : LSX3R_VVV<0x70f10000>; +-def VSRLR_D : LSX3R_VVV<0x70f18000>; +-def VSRLRI_B : LSX2RI3_VVI<0x72a42000>; +-def VSRLRI_H : LSX2RI4_VVI<0x72a44000>; +-def VSRLRI_W : LSX2RI5_VVI<0x72a48000>; +-def VSRLRI_D : LSX2RI6_VVI<0x72a50000>; +- +-def VSRAR_B : LSX3R_VVV<0x70f20000>; +-def VSRAR_H : LSX3R_VVV<0x70f28000>; +-def VSRAR_W : LSX3R_VVV<0x70f30000>; +-def VSRAR_D : LSX3R_VVV<0x70f38000>; +-def VSRARI_B : LSX2RI3_VVI<0x72a82000>; +-def VSRARI_H : LSX2RI4_VVI<0x72a84000>; +-def VSRARI_W : LSX2RI5_VVI<0x72a88000>; +-def VSRARI_D : LSX2RI6_VVI<0x72a90000>; +- +-def VSRLN_B_H : LSX3R_VVV<0x70f48000>; +-def VSRLN_H_W : LSX3R_VVV<0x70f50000>; +-def VSRLN_W_D : LSX3R_VVV<0x70f58000>; +-def VSRAN_B_H : LSX3R_VVV<0x70f68000>; +-def VSRAN_H_W : LSX3R_VVV<0x70f70000>; +-def VSRAN_W_D : LSX3R_VVV<0x70f78000>; +- +-def VSRLNI_B_H : LSX2RI4_VVVI<0x73404000>; +-def VSRLNI_H_W : LSX2RI5_VVVI<0x73408000>; +-def VSRLNI_W_D : LSX2RI6_VVVI<0x73410000>; +-def VSRLNI_D_Q : LSX2RI7_VVVI<0x73420000>; +-def VSRANI_B_H : LSX2RI4_VVVI<0x73584000>; +-def VSRANI_H_W : LSX2RI5_VVVI<0x73588000>; +-def VSRANI_W_D : LSX2RI6_VVVI<0x73590000>; +-def VSRANI_D_Q : LSX2RI7_VVVI<0x735a0000>; +- +-def VSRLRN_B_H : LSX3R_VVV<0x70f88000>; +-def VSRLRN_H_W : LSX3R_VVV<0x70f90000>; +-def VSRLRN_W_D : LSX3R_VVV<0x70f98000>; +-def VSRARN_B_H : LSX3R_VVV<0x70fa8000>; +-def VSRARN_H_W : LSX3R_VVV<0x70fb0000>; +-def VSRARN_W_D : LSX3R_VVV<0x70fb8000>; +- +-def VSRLRNI_B_H : LSX2RI4_VVVI<0x73444000>; +-def VSRLRNI_H_W : LSX2RI5_VVVI<0x73448000>; +-def VSRLRNI_W_D : LSX2RI6_VVVI<0x73450000>; +-def VSRLRNI_D_Q : LSX2RI7_VVVI<0x73460000>; +-def VSRARNI_B_H : LSX2RI4_VVVI<0x735c4000>; +-def VSRARNI_H_W : LSX2RI5_VVVI<0x735c8000>; +-def VSRARNI_W_D : LSX2RI6_VVVI<0x735d0000>; +-def VSRARNI_D_Q : LSX2RI7_VVVI<0x735e0000>; +- +-def VSSRLN_B_H : LSX3R_VVV<0x70fc8000>; +-def VSSRLN_H_W : LSX3R_VVV<0x70fd0000>; +-def VSSRLN_W_D : LSX3R_VVV<0x70fd8000>; +-def VSSRAN_B_H : LSX3R_VVV<0x70fe8000>; +-def VSSRAN_H_W : LSX3R_VVV<0x70ff0000>; +-def VSSRAN_W_D : LSX3R_VVV<0x70ff8000>; +-def VSSRLN_BU_H : LSX3R_VVV<0x71048000>; +-def VSSRLN_HU_W : LSX3R_VVV<0x71050000>; +-def VSSRLN_WU_D : LSX3R_VVV<0x71058000>; +-def VSSRAN_BU_H : LSX3R_VVV<0x71068000>; +-def VSSRAN_HU_W : LSX3R_VVV<0x71070000>; +-def VSSRAN_WU_D : LSX3R_VVV<0x71078000>; +- +-def VSSRLNI_B_H : LSX2RI4_VVVI<0x73484000>; +-def VSSRLNI_H_W : LSX2RI5_VVVI<0x73488000>; +-def VSSRLNI_W_D : LSX2RI6_VVVI<0x73490000>; +-def VSSRLNI_D_Q : LSX2RI7_VVVI<0x734a0000>; +-def VSSRANI_B_H : LSX2RI4_VVVI<0x73604000>; +-def VSSRANI_H_W : LSX2RI5_VVVI<0x73608000>; +-def VSSRANI_W_D : LSX2RI6_VVVI<0x73610000>; +-def VSSRANI_D_Q : LSX2RI7_VVVI<0x73620000>; +-def VSSRLNI_BU_H : LSX2RI4_VVVI<0x734c4000>; +-def VSSRLNI_HU_W : LSX2RI5_VVVI<0x734c8000>; +-def VSSRLNI_WU_D : LSX2RI6_VVVI<0x734d0000>; +-def VSSRLNI_DU_Q : LSX2RI7_VVVI<0x734e0000>; +-def VSSRANI_BU_H : LSX2RI4_VVVI<0x73644000>; +-def VSSRANI_HU_W : LSX2RI5_VVVI<0x73648000>; +-def VSSRANI_WU_D : LSX2RI6_VVVI<0x73650000>; +-def VSSRANI_DU_Q : LSX2RI7_VVVI<0x73660000>; +- +-def VSSRLRN_B_H : LSX3R_VVV<0x71008000>; +-def VSSRLRN_H_W : LSX3R_VVV<0x71010000>; +-def VSSRLRN_W_D : LSX3R_VVV<0x71018000>; +-def VSSRARN_B_H : LSX3R_VVV<0x71028000>; +-def VSSRARN_H_W : LSX3R_VVV<0x71030000>; +-def VSSRARN_W_D : LSX3R_VVV<0x71038000>; +-def VSSRLRN_BU_H : LSX3R_VVV<0x71088000>; +-def VSSRLRN_HU_W : LSX3R_VVV<0x71090000>; +-def VSSRLRN_WU_D : LSX3R_VVV<0x71098000>; +-def VSSRARN_BU_H : LSX3R_VVV<0x710a8000>; +-def VSSRARN_HU_W : LSX3R_VVV<0x710b0000>; +-def VSSRARN_WU_D : LSX3R_VVV<0x710b8000>; +- +-def VSSRLRNI_B_H : LSX2RI4_VVVI<0x73504000>; +-def VSSRLRNI_H_W : LSX2RI5_VVVI<0x73508000>; +-def VSSRLRNI_W_D : LSX2RI6_VVVI<0x73510000>; +-def VSSRLRNI_D_Q : LSX2RI7_VVVI<0x73520000>; +-def VSSRARNI_B_H : LSX2RI4_VVVI<0x73684000>; +-def VSSRARNI_H_W : LSX2RI5_VVVI<0x73688000>; +-def VSSRARNI_W_D : LSX2RI6_VVVI<0x73690000>; +-def VSSRARNI_D_Q : LSX2RI7_VVVI<0x736a0000>; +-def VSSRLRNI_BU_H : LSX2RI4_VVVI<0x73544000>; +-def VSSRLRNI_HU_W : LSX2RI5_VVVI<0x73548000>; +-def VSSRLRNI_WU_D : LSX2RI6_VVVI<0x73550000>; +-def VSSRLRNI_DU_Q : LSX2RI7_VVVI<0x73560000>; +-def VSSRARNI_BU_H : LSX2RI4_VVVI<0x736c4000>; +-def VSSRARNI_HU_W : LSX2RI5_VVVI<0x736c8000>; +-def VSSRARNI_WU_D : LSX2RI6_VVVI<0x736d0000>; +-def VSSRARNI_DU_Q : LSX2RI7_VVVI<0x736e0000>; +- +-def VCLO_B : LSX2R_VV<0x729c0000>; +-def VCLO_H : LSX2R_VV<0x729c0400>; +-def VCLO_W : LSX2R_VV<0x729c0800>; +-def VCLO_D : LSX2R_VV<0x729c0c00>; +-def VCLZ_B : LSX2R_VV<0x729c1000>; +-def VCLZ_H : LSX2R_VV<0x729c1400>; +-def VCLZ_W : LSX2R_VV<0x729c1800>; +-def VCLZ_D : LSX2R_VV<0x729c1c00>; +- +-def VPCNT_B : LSX2R_VV<0x729c2000>; +-def VPCNT_H : LSX2R_VV<0x729c2400>; +-def VPCNT_W : LSX2R_VV<0x729c2800>; +-def VPCNT_D : LSX2R_VV<0x729c2c00>; +- +-def VBITCLR_B : LSX3R_VVV<0x710c0000>; +-def VBITCLR_H : LSX3R_VVV<0x710c8000>; +-def VBITCLR_W : LSX3R_VVV<0x710d0000>; +-def VBITCLR_D : LSX3R_VVV<0x710d8000>; +-def VBITCLRI_B : LSX2RI3_VVI<0x73102000>; +-def VBITCLRI_H : LSX2RI4_VVI<0x73104000>; +-def VBITCLRI_W : LSX2RI5_VVI<0x73108000>; +-def VBITCLRI_D : LSX2RI6_VVI<0x73110000>; +- +-def VBITSET_B : LSX3R_VVV<0x710e0000>; +-def VBITSET_H : LSX3R_VVV<0x710e8000>; +-def VBITSET_W : LSX3R_VVV<0x710f0000>; +-def VBITSET_D : LSX3R_VVV<0x710f8000>; +-def VBITSETI_B : LSX2RI3_VVI<0x73142000>; +-def VBITSETI_H : LSX2RI4_VVI<0x73144000>; +-def VBITSETI_W : LSX2RI5_VVI<0x73148000>; +-def VBITSETI_D : LSX2RI6_VVI<0x73150000>; +- +-def VBITREV_B : LSX3R_VVV<0x71100000>; +-def VBITREV_H : LSX3R_VVV<0x71108000>; +-def VBITREV_W : LSX3R_VVV<0x71110000>; +-def VBITREV_D : LSX3R_VVV<0x71118000>; +-def VBITREVI_B : LSX2RI3_VVI<0x73182000>; +-def VBITREVI_H : LSX2RI4_VVI<0x73184000>; +-def VBITREVI_W : LSX2RI5_VVI<0x73188000>; +-def VBITREVI_D : LSX2RI6_VVI<0x73190000>; +- +-def VFRSTP_B : LSX3R_VVVV<0x712b0000>; +-def VFRSTP_H : LSX3R_VVVV<0x712b8000>; +-def VFRSTPI_B : LSX2RI5_VVVI<0x729a0000>; +-def VFRSTPI_H : LSX2RI5_VVVI<0x729a8000>; +- +-def VFADD_S : LSX3R_VVV<0x71308000>; +-def VFADD_D : LSX3R_VVV<0x71310000>; +-def VFSUB_S : LSX3R_VVV<0x71328000>; +-def VFSUB_D : LSX3R_VVV<0x71330000>; +-def VFMUL_S : LSX3R_VVV<0x71388000>; +-def VFMUL_D : LSX3R_VVV<0x71390000>; +-def VFDIV_S : LSX3R_VVV<0x713a8000>; +-def VFDIV_D : LSX3R_VVV<0x713b0000>; +- +-def VFMADD_S : LSX4R_VVVV<0x09100000>; +-def VFMADD_D : LSX4R_VVVV<0x09200000>; +-def VFMSUB_S : LSX4R_VVVV<0x09500000>; +-def VFMSUB_D : LSX4R_VVVV<0x09600000>; +-def VFNMADD_S : LSX4R_VVVV<0x09900000>; +-def VFNMADD_D : LSX4R_VVVV<0x09a00000>; +-def VFNMSUB_S : LSX4R_VVVV<0x09d00000>; +-def VFNMSUB_D : LSX4R_VVVV<0x09e00000>; +- +-def VFMAX_S : LSX3R_VVV<0x713c8000>; +-def VFMAX_D : LSX3R_VVV<0x713d0000>; +-def VFMIN_S : LSX3R_VVV<0x713e8000>; +-def VFMIN_D : LSX3R_VVV<0x713f0000>; +- +-def VFMAXA_S : LSX3R_VVV<0x71408000>; +-def VFMAXA_D : LSX3R_VVV<0x71410000>; +-def VFMINA_S : LSX3R_VVV<0x71428000>; +-def VFMINA_D : LSX3R_VVV<0x71430000>; +- +-def VFLOGB_S : LSX2R_VV<0x729cc400>; +-def VFLOGB_D : LSX2R_VV<0x729cc800>; +- +-def VFCLASS_S : LSX2R_VV<0x729cd400>; +-def VFCLASS_D : LSX2R_VV<0x729cd800>; +- +-def VFSQRT_S : LSX2R_VV<0x729ce400>; +-def VFSQRT_D : LSX2R_VV<0x729ce800>; +-def VFRECIP_S : LSX2R_VV<0x729cf400>; +-def VFRECIP_D : LSX2R_VV<0x729cf800>; +-def VFRSQRT_S : LSX2R_VV<0x729d0400>; +-def VFRSQRT_D : LSX2R_VV<0x729d0800>; +-def VFRECIPE_S : LSX2R_VV<0x729d1400>; +-def VFRECIPE_D : LSX2R_VV<0x729d1800>; +-def VFRSQRTE_S : LSX2R_VV<0x729d2400>; +-def VFRSQRTE_D : LSX2R_VV<0x729d2800>; +- +-def VFCVTL_S_H : LSX2R_VV<0x729de800>; +-def VFCVTH_S_H : LSX2R_VV<0x729dec00>; +-def VFCVTL_D_S : LSX2R_VV<0x729df000>; +-def VFCVTH_D_S : LSX2R_VV<0x729df400>; +-def VFCVT_H_S : LSX3R_VVV<0x71460000>; +-def VFCVT_S_D : LSX3R_VVV<0x71468000>; +- +-def VFRINTRNE_S : LSX2R_VV<0x729d7400>; +-def VFRINTRNE_D : LSX2R_VV<0x729d7800>; +-def VFRINTRZ_S : LSX2R_VV<0x729d6400>; +-def VFRINTRZ_D : LSX2R_VV<0x729d6800>; +-def VFRINTRP_S : LSX2R_VV<0x729d5400>; +-def VFRINTRP_D : LSX2R_VV<0x729d5800>; +-def VFRINTRM_S : LSX2R_VV<0x729d4400>; +-def VFRINTRM_D : LSX2R_VV<0x729d4800>; +-def VFRINT_S : LSX2R_VV<0x729d3400>; +-def VFRINT_D : LSX2R_VV<0x729d3800>; +- +-def VFTINTRNE_W_S : LSX2R_VV<0x729e5000>; +-def VFTINTRNE_L_D : LSX2R_VV<0x729e5400>; +-def VFTINTRZ_W_S : LSX2R_VV<0x729e4800>; +-def VFTINTRZ_L_D : LSX2R_VV<0x729e4c00>; +-def VFTINTRP_W_S : LSX2R_VV<0x729e4000>; +-def VFTINTRP_L_D : LSX2R_VV<0x729e4400>; +-def VFTINTRM_W_S : LSX2R_VV<0x729e3800>; +-def VFTINTRM_L_D : LSX2R_VV<0x729e3c00>; +-def VFTINT_W_S : LSX2R_VV<0x729e3000>; +-def VFTINT_L_D : LSX2R_VV<0x729e3400>; +-def VFTINTRZ_WU_S : LSX2R_VV<0x729e7000>; +-def VFTINTRZ_LU_D : LSX2R_VV<0x729e7400>; +-def VFTINT_WU_S : LSX2R_VV<0x729e5800>; +-def VFTINT_LU_D : LSX2R_VV<0x729e5c00>; +- +-def VFTINTRNE_W_D : LSX3R_VVV<0x714b8000>; +-def VFTINTRZ_W_D : LSX3R_VVV<0x714b0000>; +-def VFTINTRP_W_D : LSX3R_VVV<0x714a8000>; +-def VFTINTRM_W_D : LSX3R_VVV<0x714a0000>; +-def VFTINT_W_D : LSX3R_VVV<0x71498000>; +- +-def VFTINTRNEL_L_S : LSX2R_VV<0x729ea000>; +-def VFTINTRNEH_L_S : LSX2R_VV<0x729ea400>; +-def VFTINTRZL_L_S : LSX2R_VV<0x729e9800>; +-def VFTINTRZH_L_S : LSX2R_VV<0x729e9c00>; +-def VFTINTRPL_L_S : LSX2R_VV<0x729e9000>; +-def VFTINTRPH_L_S : LSX2R_VV<0x729e9400>; +-def VFTINTRML_L_S : LSX2R_VV<0x729e8800>; +-def VFTINTRMH_L_S : LSX2R_VV<0x729e8c00>; +-def VFTINTL_L_S : LSX2R_VV<0x729e8000>; +-def VFTINTH_L_S : LSX2R_VV<0x729e8400>; +- +-def VFFINT_S_W : LSX2R_VV<0x729e0000>; +-def VFFINT_D_L : LSX2R_VV<0x729e0800>; +-def VFFINT_S_WU : LSX2R_VV<0x729e0400>; +-def VFFINT_D_LU : LSX2R_VV<0x729e0c00>; +-def VFFINTL_D_W : LSX2R_VV<0x729e1000>; +-def VFFINTH_D_W : LSX2R_VV<0x729e1400>; +-def VFFINT_S_L : LSX3R_VVV<0x71480000>; +- +-def VSEQ_B : LSX3R_VVV<0x70000000>; +-def VSEQ_H : LSX3R_VVV<0x70008000>; +-def VSEQ_W : LSX3R_VVV<0x70010000>; +-def VSEQ_D : LSX3R_VVV<0x70018000>; +-def VSEQI_B : LSX2RI5_VVI<0x72800000, simm5>; +-def VSEQI_H : LSX2RI5_VVI<0x72808000, simm5>; +-def VSEQI_W : LSX2RI5_VVI<0x72810000, simm5>; +-def VSEQI_D : LSX2RI5_VVI<0x72818000, simm5>; +- +-def VSLE_B : LSX3R_VVV<0x70020000>; +-def VSLE_H : LSX3R_VVV<0x70028000>; +-def VSLE_W : LSX3R_VVV<0x70030000>; +-def VSLE_D : LSX3R_VVV<0x70038000>; +-def VSLEI_B : LSX2RI5_VVI<0x72820000, simm5>; +-def VSLEI_H : LSX2RI5_VVI<0x72828000, simm5>; +-def VSLEI_W : LSX2RI5_VVI<0x72830000, simm5>; +-def VSLEI_D : LSX2RI5_VVI<0x72838000, simm5>; +- +-def VSLE_BU : LSX3R_VVV<0x70040000>; +-def VSLE_HU : LSX3R_VVV<0x70048000>; +-def VSLE_WU : LSX3R_VVV<0x70050000>; +-def VSLE_DU : LSX3R_VVV<0x70058000>; +-def VSLEI_BU : LSX2RI5_VVI<0x72840000>; +-def VSLEI_HU : LSX2RI5_VVI<0x72848000>; +-def VSLEI_WU : LSX2RI5_VVI<0x72850000>; +-def VSLEI_DU : LSX2RI5_VVI<0x72858000>; +- +-def VSLT_B : LSX3R_VVV<0x70060000>; +-def VSLT_H : LSX3R_VVV<0x70068000>; +-def VSLT_W : LSX3R_VVV<0x70070000>; +-def VSLT_D : LSX3R_VVV<0x70078000>; +-def VSLTI_B : LSX2RI5_VVI<0x72860000, simm5>; +-def VSLTI_H : LSX2RI5_VVI<0x72868000, simm5>; +-def VSLTI_W : LSX2RI5_VVI<0x72870000, simm5>; +-def VSLTI_D : LSX2RI5_VVI<0x72878000, simm5>; +- +-def VSLT_BU : LSX3R_VVV<0x70080000>; +-def VSLT_HU : LSX3R_VVV<0x70088000>; +-def VSLT_WU : LSX3R_VVV<0x70090000>; +-def VSLT_DU : LSX3R_VVV<0x70098000>; +-def VSLTI_BU : LSX2RI5_VVI<0x72880000>; +-def VSLTI_HU : LSX2RI5_VVI<0x72888000>; +-def VSLTI_WU : LSX2RI5_VVI<0x72890000>; +-def VSLTI_DU : LSX2RI5_VVI<0x72898000>; +- +-def VFCMP_CAF_S : LSX3R_VVV<0x0c500000>; +-def VFCMP_SAF_S : LSX3R_VVV<0x0c508000>; +-def VFCMP_CLT_S : LSX3R_VVV<0x0c510000>; +-def VFCMP_SLT_S : LSX3R_VVV<0x0c518000>; +-def VFCMP_CEQ_S : LSX3R_VVV<0x0c520000>; +-def VFCMP_SEQ_S : LSX3R_VVV<0x0c528000>; +-def VFCMP_CLE_S : LSX3R_VVV<0x0c530000>; +-def VFCMP_SLE_S : LSX3R_VVV<0x0c538000>; +-def VFCMP_CUN_S : LSX3R_VVV<0x0c540000>; +-def VFCMP_SUN_S : LSX3R_VVV<0x0c548000>; +-def VFCMP_CULT_S : LSX3R_VVV<0x0c550000>; +-def VFCMP_SULT_S : LSX3R_VVV<0x0c558000>; +-def VFCMP_CUEQ_S : LSX3R_VVV<0x0c560000>; +-def VFCMP_SUEQ_S : LSX3R_VVV<0x0c568000>; +-def VFCMP_CULE_S : LSX3R_VVV<0x0c570000>; +-def VFCMP_SULE_S : LSX3R_VVV<0x0c578000>; +-def VFCMP_CNE_S : LSX3R_VVV<0x0c580000>; +-def VFCMP_SNE_S : LSX3R_VVV<0x0c588000>; +-def VFCMP_COR_S : LSX3R_VVV<0x0c5a0000>; +-def VFCMP_SOR_S : LSX3R_VVV<0x0c5a8000>; +-def VFCMP_CUNE_S : LSX3R_VVV<0x0c5c0000>; +-def VFCMP_SUNE_S : LSX3R_VVV<0x0c5c8000>; +- +-def VFCMP_CAF_D : LSX3R_VVV<0x0c600000>; +-def VFCMP_SAF_D : LSX3R_VVV<0x0c608000>; +-def VFCMP_CLT_D : LSX3R_VVV<0x0c610000>; +-def VFCMP_SLT_D : LSX3R_VVV<0x0c618000>; +-def VFCMP_CEQ_D : LSX3R_VVV<0x0c620000>; +-def VFCMP_SEQ_D : LSX3R_VVV<0x0c628000>; +-def VFCMP_CLE_D : LSX3R_VVV<0x0c630000>; +-def VFCMP_SLE_D : LSX3R_VVV<0x0c638000>; +-def VFCMP_CUN_D : LSX3R_VVV<0x0c640000>; +-def VFCMP_SUN_D : LSX3R_VVV<0x0c648000>; +-def VFCMP_CULT_D : LSX3R_VVV<0x0c650000>; +-def VFCMP_SULT_D : LSX3R_VVV<0x0c658000>; +-def VFCMP_CUEQ_D : LSX3R_VVV<0x0c660000>; +-def VFCMP_SUEQ_D : LSX3R_VVV<0x0c668000>; +-def VFCMP_CULE_D : LSX3R_VVV<0x0c670000>; +-def VFCMP_SULE_D : LSX3R_VVV<0x0c678000>; +-def VFCMP_CNE_D : LSX3R_VVV<0x0c680000>; +-def VFCMP_SNE_D : LSX3R_VVV<0x0c688000>; +-def VFCMP_COR_D : LSX3R_VVV<0x0c6a0000>; +-def VFCMP_SOR_D : LSX3R_VVV<0x0c6a8000>; +-def VFCMP_CUNE_D : LSX3R_VVV<0x0c6c0000>; +-def VFCMP_SUNE_D : LSX3R_VVV<0x0c6c8000>; +- +-def VBITSEL_V : LSX4R_VVVV<0x0d100000>; +- +-def VBITSELI_B : LSX2RI8_VVVI<0x73c40000>; +- +-def VSETEQZ_V : LSX2R_CV<0x729c9800>; +-def VSETNEZ_V : LSX2R_CV<0x729c9c00>; +-def VSETANYEQZ_B : LSX2R_CV<0x729ca000>; +-def VSETANYEQZ_H : LSX2R_CV<0x729ca400>; +-def VSETANYEQZ_W : LSX2R_CV<0x729ca800>; +-def VSETANYEQZ_D : LSX2R_CV<0x729cac00>; +-def VSETALLNEZ_B : LSX2R_CV<0x729cb000>; +-def VSETALLNEZ_H : LSX2R_CV<0x729cb400>; +-def VSETALLNEZ_W : LSX2R_CV<0x729cb800>; +-def VSETALLNEZ_D : LSX2R_CV<0x729cbc00>; +- +-def VINSGR2VR_B : LSX2RI4_VVRI<0x72eb8000>; +-def VINSGR2VR_H : LSX2RI3_VVRI<0x72ebc000>; +-def VINSGR2VR_W : LSX2RI2_VVRI<0x72ebe000>; +-def VINSGR2VR_D : LSX2RI1_VVRI<0x72ebf000>; +-def VPICKVE2GR_B : LSX2RI4_RVI<0x72ef8000>; +-def VPICKVE2GR_H : LSX2RI3_RVI<0x72efc000>; +-def VPICKVE2GR_W : LSX2RI2_RVI<0x72efe000>; +-def VPICKVE2GR_D : LSX2RI1_RVI<0x72eff000>; +-def VPICKVE2GR_BU : LSX2RI4_RVI<0x72f38000>; +-def VPICKVE2GR_HU : LSX2RI3_RVI<0x72f3c000>; +-def VPICKVE2GR_WU : LSX2RI2_RVI<0x72f3e000>; +-def VPICKVE2GR_DU : LSX2RI1_RVI<0x72f3f000>; +- +-def VREPLGR2VR_B : LSX2R_VR<0x729f0000>; +-def VREPLGR2VR_H : LSX2R_VR<0x729f0400>; +-def VREPLGR2VR_W : LSX2R_VR<0x729f0800>; +-def VREPLGR2VR_D : LSX2R_VR<0x729f0c00>; +- +-def VREPLVE_B : LSX3R_VVR<0x71220000>; +-def VREPLVE_H : LSX3R_VVR<0x71228000>; +-def VREPLVE_W : LSX3R_VVR<0x71230000>; +-def VREPLVE_D : LSX3R_VVR<0x71238000>; +-def VREPLVEI_B : LSX2RI4_VVI<0x72f78000>; +-def VREPLVEI_H : LSX2RI3_VVI<0x72f7c000>; +-def VREPLVEI_W : LSX2RI2_VVI<0x72f7e000>; +-def VREPLVEI_D : LSX2RI1_VVI<0x72f7f000>; +- +-def VBSLL_V : LSX2RI5_VVI<0x728e0000>; +-def VBSRL_V : LSX2RI5_VVI<0x728e8000>; +- +-def VPACKEV_B : LSX3R_VVV<0x71160000>; +-def VPACKEV_H : LSX3R_VVV<0x71168000>; +-def VPACKEV_W : LSX3R_VVV<0x71170000>; +-def VPACKEV_D : LSX3R_VVV<0x71178000>; +-def VPACKOD_B : LSX3R_VVV<0x71180000>; +-def VPACKOD_H : LSX3R_VVV<0x71188000>; +-def VPACKOD_W : LSX3R_VVV<0x71190000>; +-def VPACKOD_D : LSX3R_VVV<0x71198000>; +- +-def VPICKEV_B : LSX3R_VVV<0x711e0000>; +-def VPICKEV_H : LSX3R_VVV<0x711e8000>; +-def VPICKEV_W : LSX3R_VVV<0x711f0000>; +-def VPICKEV_D : LSX3R_VVV<0x711f8000>; +-def VPICKOD_B : LSX3R_VVV<0x71200000>; +-def VPICKOD_H : LSX3R_VVV<0x71208000>; +-def VPICKOD_W : LSX3R_VVV<0x71210000>; +-def VPICKOD_D : LSX3R_VVV<0x71218000>; +- +-def VILVL_B : LSX3R_VVV<0x711a0000>; +-def VILVL_H : LSX3R_VVV<0x711a8000>; +-def VILVL_W : LSX3R_VVV<0x711b0000>; +-def VILVL_D : LSX3R_VVV<0x711b8000>; +-def VILVH_B : LSX3R_VVV<0x711c0000>; +-def VILVH_H : LSX3R_VVV<0x711c8000>; +-def VILVH_W : LSX3R_VVV<0x711d0000>; +-def VILVH_D : LSX3R_VVV<0x711d8000>; +- +-def VSHUF_B : LSX4R_VVVV<0x0d500000>; +- +-def VSHUF_H : LSX3R_VVVV<0x717a8000>; +-def VSHUF_W : LSX3R_VVVV<0x717b0000>; +-def VSHUF_D : LSX3R_VVVV<0x717b8000>; +- +-def VSHUF4I_B : LSX2RI8_VVI<0x73900000>; +-def VSHUF4I_H : LSX2RI8_VVI<0x73940000>; +-def VSHUF4I_W : LSX2RI8_VVI<0x73980000>; +-def VSHUF4I_D : LSX2RI8_VVVI<0x739c0000>; +- +-def VPERMI_W : LSX2RI8_VVVI<0x73e40000>; +- +-def VEXTRINS_D : LSX2RI8_VVVI<0x73800000>; +-def VEXTRINS_W : LSX2RI8_VVVI<0x73840000>; +-def VEXTRINS_H : LSX2RI8_VVVI<0x73880000>; +-def VEXTRINS_B : LSX2RI8_VVVI<0x738c0000>; +-} // mayLoad = 0, mayStore = 0 +- +-let mayLoad = 1, mayStore = 0 in { +-def VLD : LSX2RI12_Load<0x2c000000>; +-def VLDX : LSX3R_Load<0x38400000>; +- +-def VLDREPL_B : LSX2RI12_Load<0x30800000>; +-def VLDREPL_H : LSX2RI11_Load<0x30400000>; +-def VLDREPL_W : LSX2RI10_Load<0x30200000>; +-def VLDREPL_D : LSX2RI9_Load<0x30100000>; +-} // mayLoad = 1, mayStore = 0 +- +-let mayLoad = 0, mayStore = 1 in { +-def VST : LSX2RI12_Store<0x2c400000>; +-def VSTX : LSX3R_Store<0x38440000>; +- +-def VSTELM_B : LSX2RI8I4_VRII<0x31800000>; +-def VSTELM_H : LSX2RI8I3_VRII<0x31400000, simm8_lsl1>; +-def VSTELM_W : LSX2RI8I2_VRII<0x31200000, simm8_lsl2>; +-def VSTELM_D : LSX2RI8I1_VRII<0x31100000, simm8_lsl3>; +-} // mayLoad = 0, mayStore = 1 +- +-} // hasSideEffects = 0, Predicates = [HasExtLSX] +- +-/// Pseudo-instructions +- +-let Predicates = [HasExtLSX] in { +- +-let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0, +- isAsmParserOnly = 1 in { +-def PseudoVREPLI_B : Pseudo<(outs LSX128:$vd), (ins simm10:$imm), [], +- "vrepli.b", "$vd, $imm">; +-def PseudoVREPLI_H : Pseudo<(outs LSX128:$vd), (ins simm10:$imm), [], +- "vrepli.h", "$vd, $imm">; +-def PseudoVREPLI_W : Pseudo<(outs LSX128:$vd), (ins simm10:$imm), [], +- "vrepli.w", "$vd, $imm">; +-def PseudoVREPLI_D : Pseudo<(outs LSX128:$vd), (ins simm10:$imm), [], +- "vrepli.d", "$vd, $imm">; +-} +- +-def PseudoVBNZ_B : VecCond; +-def PseudoVBNZ_H : VecCond; +-def PseudoVBNZ_W : VecCond; +-def PseudoVBNZ_D : VecCond; +-def PseudoVBNZ : VecCond; +- +-def PseudoVBZ_B : VecCond; +-def PseudoVBZ_H : VecCond; +-def PseudoVBZ_W : VecCond; +-def PseudoVBZ_D : VecCond; +-def PseudoVBZ : VecCond; +- +-} // Predicates = [HasExtLSX] +- +-multiclass PatVr { +- def : Pat<(v16i8 (OpNode (v16i8 LSX128:$vj))), +- (!cast(Inst#"_B") LSX128:$vj)>; +- def : Pat<(v8i16 (OpNode (v8i16 LSX128:$vj))), +- (!cast(Inst#"_H") LSX128:$vj)>; +- def : Pat<(v4i32 (OpNode (v4i32 LSX128:$vj))), +- (!cast(Inst#"_W") LSX128:$vj)>; +- def : Pat<(v2i64 (OpNode (v2i64 LSX128:$vj))), +- (!cast(Inst#"_D") LSX128:$vj)>; +-} +- +-multiclass PatVrF { +- def : Pat<(v4f32 (OpNode (v4f32 LSX128:$vj))), +- (!cast(Inst#"_S") LSX128:$vj)>; +- def : Pat<(v2f64 (OpNode (v2f64 LSX128:$vj))), +- (!cast(Inst#"_D") LSX128:$vj)>; +-} +- +-multiclass PatVrVr { +- def : Pat<(OpNode (v16i8 LSX128:$vj), (v16i8 LSX128:$vk)), +- (!cast(Inst#"_B") LSX128:$vj, LSX128:$vk)>; +- def : Pat<(OpNode (v8i16 LSX128:$vj), (v8i16 LSX128:$vk)), +- (!cast(Inst#"_H") LSX128:$vj, LSX128:$vk)>; +- def : Pat<(OpNode (v4i32 LSX128:$vj), (v4i32 LSX128:$vk)), +- (!cast(Inst#"_W") LSX128:$vj, LSX128:$vk)>; +- def : Pat<(OpNode (v2i64 LSX128:$vj), (v2i64 LSX128:$vk)), +- (!cast(Inst#"_D") LSX128:$vj, LSX128:$vk)>; +-} +- +-multiclass PatVrVrF { +- def : Pat<(OpNode (v4f32 LSX128:$vj), (v4f32 LSX128:$vk)), +- (!cast(Inst#"_S") LSX128:$vj, LSX128:$vk)>; +- def : Pat<(OpNode (v2f64 LSX128:$vj), (v2f64 LSX128:$vk)), +- (!cast(Inst#"_D") LSX128:$vj, LSX128:$vk)>; +-} +- +-multiclass PatVrVrU { +- def : Pat<(OpNode (v16i8 LSX128:$vj), (v16i8 LSX128:$vk)), +- (!cast(Inst#"_BU") LSX128:$vj, LSX128:$vk)>; +- def : Pat<(OpNode (v8i16 LSX128:$vj), (v8i16 LSX128:$vk)), +- (!cast(Inst#"_HU") LSX128:$vj, LSX128:$vk)>; +- def : Pat<(OpNode (v4i32 LSX128:$vj), (v4i32 LSX128:$vk)), +- (!cast(Inst#"_WU") LSX128:$vj, LSX128:$vk)>; +- def : Pat<(OpNode (v2i64 LSX128:$vj), (v2i64 LSX128:$vk)), +- (!cast(Inst#"_DU") LSX128:$vj, LSX128:$vk)>; +-} +- +-multiclass PatVrSimm5 { +- def : Pat<(OpNode (v16i8 LSX128:$vj), (v16i8 (SplatPat_simm5 simm5:$imm))), +- (!cast(Inst#"_B") LSX128:$vj, simm5:$imm)>; +- def : Pat<(OpNode (v8i16 LSX128:$vj), (v8i16 (SplatPat_simm5 simm5:$imm))), +- (!cast(Inst#"_H") LSX128:$vj, simm5:$imm)>; +- def : Pat<(OpNode (v4i32 LSX128:$vj), (v4i32 (SplatPat_simm5 simm5:$imm))), +- (!cast(Inst#"_W") LSX128:$vj, simm5:$imm)>; +- def : Pat<(OpNode (v2i64 LSX128:$vj), (v2i64 (SplatPat_simm5 simm5:$imm))), +- (!cast(Inst#"_D") LSX128:$vj, simm5:$imm)>; +-} +- +-multiclass PatVrUimm5 { +- def : Pat<(OpNode (v16i8 LSX128:$vj), (v16i8 (SplatPat_uimm5 uimm5:$imm))), +- (!cast(Inst#"_BU") LSX128:$vj, uimm5:$imm)>; +- def : Pat<(OpNode (v8i16 LSX128:$vj), (v8i16 (SplatPat_uimm5 uimm5:$imm))), +- (!cast(Inst#"_HU") LSX128:$vj, uimm5:$imm)>; +- def : Pat<(OpNode (v4i32 LSX128:$vj), (v4i32 (SplatPat_uimm5 uimm5:$imm))), +- (!cast(Inst#"_WU") LSX128:$vj, uimm5:$imm)>; +- def : Pat<(OpNode (v2i64 LSX128:$vj), (v2i64 (SplatPat_uimm5 uimm5:$imm))), +- (!cast(Inst#"_DU") LSX128:$vj, uimm5:$imm)>; +-} +- +-multiclass PatVrVrVr { +- def : Pat<(OpNode (v16i8 LSX128:$vd), (v16i8 LSX128:$vj), (v16i8 LSX128:$vk)), +- (!cast(Inst#"_B") LSX128:$vd, LSX128:$vj, LSX128:$vk)>; +- def : Pat<(OpNode (v8i16 LSX128:$vd), (v8i16 LSX128:$vj), (v8i16 LSX128:$vk)), +- (!cast(Inst#"_H") LSX128:$vd, LSX128:$vj, LSX128:$vk)>; +- def : Pat<(OpNode (v4i32 LSX128:$vd), (v4i32 LSX128:$vj), (v4i32 LSX128:$vk)), +- (!cast(Inst#"_W") LSX128:$vd, LSX128:$vj, LSX128:$vk)>; +- def : Pat<(OpNode (v2i64 LSX128:$vd), (v2i64 LSX128:$vj), (v2i64 LSX128:$vk)), +- (!cast(Inst#"_D") LSX128:$vd, LSX128:$vj, LSX128:$vk)>; +-} +- +-multiclass PatShiftVrVr { +- def : Pat<(OpNode (v16i8 LSX128:$vj), (and vsplati8_imm_eq_7, +- (v16i8 LSX128:$vk))), +- (!cast(Inst#"_B") LSX128:$vj, LSX128:$vk)>; +- def : Pat<(OpNode (v8i16 LSX128:$vj), (and vsplati16_imm_eq_15, +- (v8i16 LSX128:$vk))), +- (!cast(Inst#"_H") LSX128:$vj, LSX128:$vk)>; +- def : Pat<(OpNode (v4i32 LSX128:$vj), (and vsplati32_imm_eq_31, +- (v4i32 LSX128:$vk))), +- (!cast(Inst#"_W") LSX128:$vj, LSX128:$vk)>; +- def : Pat<(OpNode (v2i64 LSX128:$vj), (and vsplati64_imm_eq_63, +- (v2i64 LSX128:$vk))), +- (!cast(Inst#"_D") LSX128:$vj, LSX128:$vk)>; +-} +- +-multiclass PatShiftVrUimm { +- def : Pat<(OpNode (v16i8 LSX128:$vj), (v16i8 (SplatPat_uimm3 uimm3:$imm))), +- (!cast(Inst#"_B") LSX128:$vj, uimm3:$imm)>; +- def : Pat<(OpNode (v8i16 LSX128:$vj), (v8i16 (SplatPat_uimm4 uimm4:$imm))), +- (!cast(Inst#"_H") LSX128:$vj, uimm4:$imm)>; +- def : Pat<(OpNode (v4i32 LSX128:$vj), (v4i32 (SplatPat_uimm5 uimm5:$imm))), +- (!cast(Inst#"_W") LSX128:$vj, uimm5:$imm)>; +- def : Pat<(OpNode (v2i64 LSX128:$vj), (v2i64 (SplatPat_uimm6 uimm6:$imm))), +- (!cast(Inst#"_D") LSX128:$vj, uimm6:$imm)>; +-} +- +-multiclass PatCCVrSimm5 { +- def : Pat<(v16i8 (setcc (v16i8 LSX128:$vj), +- (v16i8 (SplatPat_simm5 simm5:$imm)), CC)), +- (!cast(Inst#"_B") LSX128:$vj, simm5:$imm)>; +- def : Pat<(v8i16 (setcc (v8i16 LSX128:$vj), +- (v8i16 (SplatPat_simm5 simm5:$imm)), CC)), +- (!cast(Inst#"_H") LSX128:$vj, simm5:$imm)>; +- def : Pat<(v4i32 (setcc (v4i32 LSX128:$vj), +- (v4i32 (SplatPat_simm5 simm5:$imm)), CC)), +- (!cast(Inst#"_W") LSX128:$vj, simm5:$imm)>; +- def : Pat<(v2i64 (setcc (v2i64 LSX128:$vj), +- (v2i64 (SplatPat_simm5 simm5:$imm)), CC)), +- (!cast(Inst#"_D") LSX128:$vj, simm5:$imm)>; +-} +- +-multiclass PatCCVrUimm5 { +- def : Pat<(v16i8 (setcc (v16i8 LSX128:$vj), +- (v16i8 (SplatPat_uimm5 uimm5:$imm)), CC)), +- (!cast(Inst#"_BU") LSX128:$vj, uimm5:$imm)>; +- def : Pat<(v8i16 (setcc (v8i16 LSX128:$vj), +- (v8i16 (SplatPat_uimm5 uimm5:$imm)), CC)), +- (!cast(Inst#"_HU") LSX128:$vj, uimm5:$imm)>; +- def : Pat<(v4i32 (setcc (v4i32 LSX128:$vj), +- (v4i32 (SplatPat_uimm5 uimm5:$imm)), CC)), +- (!cast(Inst#"_WU") LSX128:$vj, uimm5:$imm)>; +- def : Pat<(v2i64 (setcc (v2i64 LSX128:$vj), +- (v2i64 (SplatPat_uimm5 uimm5:$imm)), CC)), +- (!cast(Inst#"_DU") LSX128:$vj, uimm5:$imm)>; +-} +- +-multiclass PatCCVrVr { +- def : Pat<(v16i8 (setcc (v16i8 LSX128:$vj), (v16i8 LSX128:$vk), CC)), +- (!cast(Inst#"_B") LSX128:$vj, LSX128:$vk)>; +- def : Pat<(v8i16 (setcc (v8i16 LSX128:$vj), (v8i16 LSX128:$vk), CC)), +- (!cast(Inst#"_H") LSX128:$vj, LSX128:$vk)>; +- def : Pat<(v4i32 (setcc (v4i32 LSX128:$vj), (v4i32 LSX128:$vk), CC)), +- (!cast(Inst#"_W") LSX128:$vj, LSX128:$vk)>; +- def : Pat<(v2i64 (setcc (v2i64 LSX128:$vj), (v2i64 LSX128:$vk), CC)), +- (!cast(Inst#"_D") LSX128:$vj, LSX128:$vk)>; +-} +- +-multiclass PatCCVrVrU { +- def : Pat<(v16i8 (setcc (v16i8 LSX128:$vj), (v16i8 LSX128:$vk), CC)), +- (!cast(Inst#"_BU") LSX128:$vj, LSX128:$vk)>; +- def : Pat<(v8i16 (setcc (v8i16 LSX128:$vj), (v8i16 LSX128:$vk), CC)), +- (!cast(Inst#"_HU") LSX128:$vj, LSX128:$vk)>; +- def : Pat<(v4i32 (setcc (v4i32 LSX128:$vj), (v4i32 LSX128:$vk), CC)), +- (!cast(Inst#"_WU") LSX128:$vj, LSX128:$vk)>; +- def : Pat<(v2i64 (setcc (v2i64 LSX128:$vj), (v2i64 LSX128:$vk), CC)), +- (!cast(Inst#"_DU") LSX128:$vj, LSX128:$vk)>; +-} +- +-multiclass PatCCVrVrF { +- def : Pat<(v4i32 (setcc (v4f32 LSX128:$vj), (v4f32 LSX128:$vk), CC)), +- (!cast(Inst#"_S") LSX128:$vj, LSX128:$vk)>; +- def : Pat<(v2i64 (setcc (v2f64 LSX128:$vj), (v2f64 LSX128:$vk), CC)), +- (!cast(Inst#"_D") LSX128:$vj, LSX128:$vk)>; +-} +- +-let Predicates = [HasExtLSX] in { +- +-// VADD_{B/H/W/D} +-defm : PatVrVr; +-// VSUB_{B/H/W/D} +-defm : PatVrVr; +- +-// VADDI_{B/H/W/D}U +-defm : PatVrUimm5; +-// VSUBI_{B/H/W/D}U +-defm : PatVrUimm5; +- +-// VNEG_{B/H/W/D} +-def : Pat<(sub immAllZerosV, (v16i8 LSX128:$vj)), (VNEG_B LSX128:$vj)>; +-def : Pat<(sub immAllZerosV, (v8i16 LSX128:$vj)), (VNEG_H LSX128:$vj)>; +-def : Pat<(sub immAllZerosV, (v4i32 LSX128:$vj)), (VNEG_W LSX128:$vj)>; +-def : Pat<(sub immAllZerosV, (v2i64 LSX128:$vj)), (VNEG_D LSX128:$vj)>; +- +-// VMAX[I]_{B/H/W/D}[U] +-defm : PatVrVr; +-defm : PatVrVrU; +-defm : PatVrSimm5; +-defm : PatVrUimm5; +- +-// VMIN[I]_{B/H/W/D}[U] +-defm : PatVrVr; +-defm : PatVrVrU; +-defm : PatVrSimm5; +-defm : PatVrUimm5; +- +-// VMUL_{B/H/W/D} +-defm : PatVrVr; +- +-// VMUH_{B/H/W/D}[U] +-defm : PatVrVr; +-defm : PatVrVrU; +- +-// VMADD_{B/H/W/D} +-defm : PatVrVrVr; +-// VMSUB_{B/H/W/D} +-defm : PatVrVrVr; +- +-// VDIV_{B/H/W/D}[U] +-defm : PatVrVr; +-defm : PatVrVrU; +- +-// VMOD_{B/H/W/D}[U] +-defm : PatVrVr; +-defm : PatVrVrU; +- +-// VAND_V +-foreach vt = [v16i8, v8i16, v4i32, v2i64] in +-def : Pat<(and (vt LSX128:$vj), (vt LSX128:$vk)), +- (VAND_V LSX128:$vj, LSX128:$vk)>; +-// VOR_V +-foreach vt = [v16i8, v8i16, v4i32, v2i64] in +-def : Pat<(or (vt LSX128:$vj), (vt LSX128:$vk)), +- (VOR_V LSX128:$vj, LSX128:$vk)>; +-// VXOR_V +-foreach vt = [v16i8, v8i16, v4i32, v2i64] in +-def : Pat<(xor (vt LSX128:$vj), (vt LSX128:$vk)), +- (VXOR_V LSX128:$vj, LSX128:$vk)>; +-// VNOR_V +-foreach vt = [v16i8, v8i16, v4i32, v2i64] in +-def : Pat<(vnot (or (vt LSX128:$vj), (vt LSX128:$vk))), +- (VNOR_V LSX128:$vj, LSX128:$vk)>; +- +-// VANDI_B +-def : Pat<(and (v16i8 LSX128:$vj), (v16i8 (SplatPat_uimm8 uimm8:$imm))), +- (VANDI_B LSX128:$vj, uimm8:$imm)>; +-// VORI_B +-def : Pat<(or (v16i8 LSX128:$vj), (v16i8 (SplatPat_uimm8 uimm8:$imm))), +- (VORI_B LSX128:$vj, uimm8:$imm)>; +- +-// VXORI_B +-def : Pat<(xor (v16i8 LSX128:$vj), (v16i8 (SplatPat_uimm8 uimm8:$imm))), +- (VXORI_B LSX128:$vj, uimm8:$imm)>; +- +-// VSLL[I]_{B/H/W/D} +-defm : PatVrVr; +-defm : PatShiftVrVr; +-defm : PatShiftVrUimm; +- +-// VSRL[I]_{B/H/W/D} +-defm : PatVrVr; +-defm : PatShiftVrVr; +-defm : PatShiftVrUimm; +- +-// VSRA[I]_{B/H/W/D} +-defm : PatVrVr; +-defm : PatShiftVrVr; +-defm : PatShiftVrUimm; +- +-// VCLZ_{B/H/W/D} +-defm : PatVr; +- +-// VPCNT_{B/H/W/D} +-defm : PatVr; +- +-// VBITCLR_{B/H/W/D} +-def : Pat<(and v16i8:$vj, (vnot (shl vsplat_imm_eq_1, v16i8:$vk))), +- (v16i8 (VBITCLR_B v16i8:$vj, v16i8:$vk))>; +-def : Pat<(and v8i16:$vj, (vnot (shl vsplat_imm_eq_1, v8i16:$vk))), +- (v8i16 (VBITCLR_H v8i16:$vj, v8i16:$vk))>; +-def : Pat<(and v4i32:$vj, (vnot (shl vsplat_imm_eq_1, v4i32:$vk))), +- (v4i32 (VBITCLR_W v4i32:$vj, v4i32:$vk))>; +-def : Pat<(and v2i64:$vj, (vnot (shl vsplat_imm_eq_1, v2i64:$vk))), +- (v2i64 (VBITCLR_D v2i64:$vj, v2i64:$vk))>; +-def : Pat<(and v16i8:$vj, (vnot (shl vsplat_imm_eq_1, +- (vsplati8imm7 v16i8:$vk)))), +- (v16i8 (VBITCLR_B v16i8:$vj, v16i8:$vk))>; +-def : Pat<(and v8i16:$vj, (vnot (shl vsplat_imm_eq_1, +- (vsplati16imm15 v8i16:$vk)))), +- (v8i16 (VBITCLR_H v8i16:$vj, v8i16:$vk))>; +-def : Pat<(and v4i32:$vj, (vnot (shl vsplat_imm_eq_1, +- (vsplati32imm31 v4i32:$vk)))), +- (v4i32 (VBITCLR_W v4i32:$vj, v4i32:$vk))>; +-def : Pat<(and v2i64:$vj, (vnot (shl vsplat_imm_eq_1, +- (vsplati64imm63 v2i64:$vk)))), +- (v2i64 (VBITCLR_D v2i64:$vj, v2i64:$vk))>; +- +-// VBITCLRI_{B/H/W/D} +-def : Pat<(and (v16i8 LSX128:$vj), (v16i8 (vsplat_uimm_inv_pow2 uimm3:$imm))), +- (VBITCLRI_B LSX128:$vj, uimm3:$imm)>; +-def : Pat<(and (v8i16 LSX128:$vj), (v8i16 (vsplat_uimm_inv_pow2 uimm4:$imm))), +- (VBITCLRI_H LSX128:$vj, uimm4:$imm)>; +-def : Pat<(and (v4i32 LSX128:$vj), (v4i32 (vsplat_uimm_inv_pow2 uimm5:$imm))), +- (VBITCLRI_W LSX128:$vj, uimm5:$imm)>; +-def : Pat<(and (v2i64 LSX128:$vj), (v2i64 (vsplat_uimm_inv_pow2 uimm6:$imm))), +- (VBITCLRI_D LSX128:$vj, uimm6:$imm)>; +- +-// VBITSET_{B/H/W/D} +-def : Pat<(or v16i8:$vj, (shl vsplat_imm_eq_1, v16i8:$vk)), +- (v16i8 (VBITSET_B v16i8:$vj, v16i8:$vk))>; +-def : Pat<(or v8i16:$vj, (shl vsplat_imm_eq_1, v8i16:$vk)), +- (v8i16 (VBITSET_H v8i16:$vj, v8i16:$vk))>; +-def : Pat<(or v4i32:$vj, (shl vsplat_imm_eq_1, v4i32:$vk)), +- (v4i32 (VBITSET_W v4i32:$vj, v4i32:$vk))>; +-def : Pat<(or v2i64:$vj, (shl vsplat_imm_eq_1, v2i64:$vk)), +- (v2i64 (VBITSET_D v2i64:$vj, v2i64:$vk))>; +-def : Pat<(or v16i8:$vj, (shl vsplat_imm_eq_1, (vsplati8imm7 v16i8:$vk))), +- (v16i8 (VBITSET_B v16i8:$vj, v16i8:$vk))>; +-def : Pat<(or v8i16:$vj, (shl vsplat_imm_eq_1, (vsplati16imm15 v8i16:$vk))), +- (v8i16 (VBITSET_H v8i16:$vj, v8i16:$vk))>; +-def : Pat<(or v4i32:$vj, (shl vsplat_imm_eq_1, (vsplati32imm31 v4i32:$vk))), +- (v4i32 (VBITSET_W v4i32:$vj, v4i32:$vk))>; +-def : Pat<(or v2i64:$vj, (shl vsplat_imm_eq_1, (vsplati64imm63 v2i64:$vk))), +- (v2i64 (VBITSET_D v2i64:$vj, v2i64:$vk))>; +- +-// VBITSETI_{B/H/W/D} +-def : Pat<(or (v16i8 LSX128:$vj), (v16i8 (vsplat_uimm_pow2 uimm3:$imm))), +- (VBITSETI_B LSX128:$vj, uimm3:$imm)>; +-def : Pat<(or (v8i16 LSX128:$vj), (v8i16 (vsplat_uimm_pow2 uimm4:$imm))), +- (VBITSETI_H LSX128:$vj, uimm4:$imm)>; +-def : Pat<(or (v4i32 LSX128:$vj), (v4i32 (vsplat_uimm_pow2 uimm5:$imm))), +- (VBITSETI_W LSX128:$vj, uimm5:$imm)>; +-def : Pat<(or (v2i64 LSX128:$vj), (v2i64 (vsplat_uimm_pow2 uimm6:$imm))), +- (VBITSETI_D LSX128:$vj, uimm6:$imm)>; +- +-// VBITREV_{B/H/W/D} +-def : Pat<(xor v16i8:$vj, (shl vsplat_imm_eq_1, v16i8:$vk)), +- (v16i8 (VBITREV_B v16i8:$vj, v16i8:$vk))>; +-def : Pat<(xor v8i16:$vj, (shl vsplat_imm_eq_1, v8i16:$vk)), +- (v8i16 (VBITREV_H v8i16:$vj, v8i16:$vk))>; +-def : Pat<(xor v4i32:$vj, (shl vsplat_imm_eq_1, v4i32:$vk)), +- (v4i32 (VBITREV_W v4i32:$vj, v4i32:$vk))>; +-def : Pat<(xor v2i64:$vj, (shl vsplat_imm_eq_1, v2i64:$vk)), +- (v2i64 (VBITREV_D v2i64:$vj, v2i64:$vk))>; +-def : Pat<(xor v16i8:$vj, (shl vsplat_imm_eq_1, (vsplati8imm7 v16i8:$vk))), +- (v16i8 (VBITREV_B v16i8:$vj, v16i8:$vk))>; +-def : Pat<(xor v8i16:$vj, (shl vsplat_imm_eq_1, (vsplati16imm15 v8i16:$vk))), +- (v8i16 (VBITREV_H v8i16:$vj, v8i16:$vk))>; +-def : Pat<(xor v4i32:$vj, (shl vsplat_imm_eq_1, (vsplati32imm31 v4i32:$vk))), +- (v4i32 (VBITREV_W v4i32:$vj, v4i32:$vk))>; +-def : Pat<(xor v2i64:$vj, (shl vsplat_imm_eq_1, (vsplati64imm63 v2i64:$vk))), +- (v2i64 (VBITREV_D v2i64:$vj, v2i64:$vk))>; +- +-// VBITREVI_{B/H/W/D} +-def : Pat<(xor (v16i8 LSX128:$vj), (v16i8 (vsplat_uimm_pow2 uimm3:$imm))), +- (VBITREVI_B LSX128:$vj, uimm3:$imm)>; +-def : Pat<(xor (v8i16 LSX128:$vj), (v8i16 (vsplat_uimm_pow2 uimm4:$imm))), +- (VBITREVI_H LSX128:$vj, uimm4:$imm)>; +-def : Pat<(xor (v4i32 LSX128:$vj), (v4i32 (vsplat_uimm_pow2 uimm5:$imm))), +- (VBITREVI_W LSX128:$vj, uimm5:$imm)>; +-def : Pat<(xor (v2i64 LSX128:$vj), (v2i64 (vsplat_uimm_pow2 uimm6:$imm))), +- (VBITREVI_D LSX128:$vj, uimm6:$imm)>; +- +-// VFADD_{S/D} +-defm : PatVrVrF; +- +-// VFSUB_{S/D} +-defm : PatVrVrF; +- +-// VFMUL_{S/D} +-defm : PatVrVrF; +- +-// VFDIV_{S/D} +-defm : PatVrVrF; +- +-// VFMADD_{S/D} +-def : Pat<(fma v4f32:$vj, v4f32:$vk, v4f32:$va), +- (VFMADD_S v4f32:$vj, v4f32:$vk, v4f32:$va)>; +-def : Pat<(fma v2f64:$vj, v2f64:$vk, v2f64:$va), +- (VFMADD_D v2f64:$vj, v2f64:$vk, v2f64:$va)>; +- +-// VFMSUB_{S/D} +-def : Pat<(fma v4f32:$vj, v4f32:$vk, (fneg v4f32:$va)), +- (VFMSUB_S v4f32:$vj, v4f32:$vk, v4f32:$va)>; +-def : Pat<(fma v2f64:$vj, v2f64:$vk, (fneg v2f64:$va)), +- (VFMSUB_D v2f64:$vj, v2f64:$vk, v2f64:$va)>; +- +-// VFNMADD_{S/D} +-def : Pat<(fneg (fma v4f32:$vj, v4f32:$vk, v4f32:$va)), +- (VFNMADD_S v4f32:$vj, v4f32:$vk, v4f32:$va)>; +-def : Pat<(fneg (fma v2f64:$vj, v2f64:$vk, v2f64:$va)), +- (VFNMADD_D v2f64:$vj, v2f64:$vk, v2f64:$va)>; +-def : Pat<(fma_nsz (fneg v4f32:$vj), v4f32:$vk, (fneg v4f32:$va)), +- (VFNMADD_S v4f32:$vj, v4f32:$vk, v4f32:$va)>; +-def : Pat<(fma_nsz (fneg v2f64:$vj), v2f64:$vk, (fneg v2f64:$va)), +- (VFNMADD_D v2f64:$vj, v2f64:$vk, v2f64:$va)>; +- +-// VFNMSUB_{S/D} +-def : Pat<(fneg (fma v4f32:$vj, v4f32:$vk, (fneg v4f32:$va))), +- (VFNMSUB_S v4f32:$vj, v4f32:$vk, v4f32:$va)>; +-def : Pat<(fneg (fma v2f64:$vj, v2f64:$vk, (fneg v2f64:$va))), +- (VFNMSUB_D v2f64:$vj, v2f64:$vk, v2f64:$va)>; +-def : Pat<(fma_nsz (fneg v4f32:$vj), v4f32:$vk, v4f32:$va), +- (VFNMSUB_S v4f32:$vj, v4f32:$vk, v4f32:$va)>; +-def : Pat<(fma_nsz (fneg v2f64:$vj), v2f64:$vk, v2f64:$va), +- (VFNMSUB_D v2f64:$vj, v2f64:$vk, v2f64:$va)>; +- +-// VFSQRT_{S/D} +-defm : PatVrF; +- +-// VFRECIP_{S/D} +-def : Pat<(fdiv vsplatf32_fpimm_eq_1, v4f32:$vj), +- (VFRECIP_S v4f32:$vj)>; +-def : Pat<(fdiv vsplatf64_fpimm_eq_1, v2f64:$vj), +- (VFRECIP_D v2f64:$vj)>; +- +-// VFRSQRT_{S/D} +-def : Pat<(fdiv vsplatf32_fpimm_eq_1, (fsqrt v4f32:$vj)), +- (VFRSQRT_S v4f32:$vj)>; +-def : Pat<(fdiv vsplatf64_fpimm_eq_1, (fsqrt v2f64:$vj)), +- (VFRSQRT_D v2f64:$vj)>; +- +-// VSEQ[I]_{B/H/W/D} +-defm : PatCCVrSimm5; +-defm : PatCCVrVr; +- +-// VSLE[I]_{B/H/W/D}[U] +-defm : PatCCVrSimm5; +-defm : PatCCVrUimm5; +-defm : PatCCVrVr; +-defm : PatCCVrVrU; +- +-// VSLT[I]_{B/H/W/D}[U] +-defm : PatCCVrSimm5; +-defm : PatCCVrUimm5; +-defm : PatCCVrVr; +-defm : PatCCVrVrU; +- +-// VFCMP.cond.{S/D} +-defm : PatCCVrVrF; +-defm : PatCCVrVrF; +-defm : PatCCVrVrF; +- +-defm : PatCCVrVrF; +-defm : PatCCVrVrF; +-defm : PatCCVrVrF; +- +-defm : PatCCVrVrF; +-defm : PatCCVrVrF; +-defm : PatCCVrVrF; +- +-defm : PatCCVrVrF; +-defm : PatCCVrVrF; +-defm : PatCCVrVrF; +- +-defm : PatCCVrVrF; +-defm : PatCCVrVrF; +- +-// VINSGR2VR_{B/H/W/D} +-def : Pat<(vector_insert v16i8:$vd, GRLenVT:$rj, uimm4:$imm), +- (VINSGR2VR_B v16i8:$vd, GRLenVT:$rj, uimm4:$imm)>; +-def : Pat<(vector_insert v8i16:$vd, GRLenVT:$rj, uimm3:$imm), +- (VINSGR2VR_H v8i16:$vd, GRLenVT:$rj, uimm3:$imm)>; +-def : Pat<(vector_insert v4i32:$vd, GRLenVT:$rj, uimm2:$imm), +- (VINSGR2VR_W v4i32:$vd, GRLenVT:$rj, uimm2:$imm)>; +-def : Pat<(vector_insert v2i64:$vd, GRLenVT:$rj, uimm1:$imm), +- (VINSGR2VR_D v2i64:$vd, GRLenVT:$rj, uimm1:$imm)>; +- +-def : Pat<(vector_insert v4f32:$vd, FPR32:$fj, uimm2:$imm), +- (VINSGR2VR_W $vd, (COPY_TO_REGCLASS FPR32:$fj, GPR), uimm2:$imm)>; +-def : Pat<(vector_insert v2f64:$vd, FPR64:$fj, uimm1:$imm), +- (VINSGR2VR_D $vd, (COPY_TO_REGCLASS FPR64:$fj, GPR), uimm1:$imm)>; +- +-// VPICKVE2GR_{B/H/W}[U] +-def : Pat<(loongarch_vpick_sext_elt v16i8:$vd, uimm4:$imm, i8), +- (VPICKVE2GR_B v16i8:$vd, uimm4:$imm)>; +-def : Pat<(loongarch_vpick_sext_elt v8i16:$vd, uimm3:$imm, i16), +- (VPICKVE2GR_H v8i16:$vd, uimm3:$imm)>; +-def : Pat<(loongarch_vpick_sext_elt v4i32:$vd, uimm2:$imm, i32), +- (VPICKVE2GR_W v4i32:$vd, uimm2:$imm)>; +- +-def : Pat<(loongarch_vpick_zext_elt v16i8:$vd, uimm4:$imm, i8), +- (VPICKVE2GR_BU v16i8:$vd, uimm4:$imm)>; +-def : Pat<(loongarch_vpick_zext_elt v8i16:$vd, uimm3:$imm, i16), +- (VPICKVE2GR_HU v8i16:$vd, uimm3:$imm)>; +-def : Pat<(loongarch_vpick_zext_elt v4i32:$vd, uimm2:$imm, i32), +- (VPICKVE2GR_WU v4i32:$vd, uimm2:$imm)>; +- +-// VREPLGR2VR_{B/H/W/D} +-def : Pat<(lsxsplati8 GPR:$rj), (VREPLGR2VR_B GPR:$rj)>; +-def : Pat<(lsxsplati16 GPR:$rj), (VREPLGR2VR_H GPR:$rj)>; +-def : Pat<(lsxsplati32 GPR:$rj), (VREPLGR2VR_W GPR:$rj)>; +-def : Pat<(lsxsplati64 GPR:$rj), (VREPLGR2VR_D GPR:$rj)>; +- +-// VREPLVE_{B/H/W/D} +-def : Pat<(loongarch_vreplve v16i8:$vj, GRLenVT:$rk), +- (VREPLVE_B v16i8:$vj, GRLenVT:$rk)>; +-def : Pat<(loongarch_vreplve v8i16:$vj, GRLenVT:$rk), +- (VREPLVE_H v8i16:$vj, GRLenVT:$rk)>; +-def : Pat<(loongarch_vreplve v4i32:$vj, GRLenVT:$rk), +- (VREPLVE_W v4i32:$vj, GRLenVT:$rk)>; +-def : Pat<(loongarch_vreplve v2i64:$vj, GRLenVT:$rk), +- (VREPLVE_D v2i64:$vj, GRLenVT:$rk)>; +- +-// VREPLVEI_{W/D} +-def : Pat<(lsxsplatf32 FPR32:$fj), +- (VREPLVEI_W (SUBREG_TO_REG (i64 0), FPR32:$fj, sub_32), 0)>; +-def : Pat<(lsxsplatf64 FPR64:$fj), +- (VREPLVEI_D (SUBREG_TO_REG (i64 0), FPR64:$fj, sub_64), 0)>; +- +-// Loads/Stores +-foreach vt = [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64] in { +- defm : LdPat; +- def : RegRegLdPat; +- defm : StPat; +- def : RegRegStPat; +-} +- +-// Vector extraction with constant index. +-def : Pat<(i64 (vector_extract v16i8:$vj, uimm4:$imm)), +- (VPICKVE2GR_B v16i8:$vj, uimm4:$imm)>; +-def : Pat<(i64 (vector_extract v8i16:$vj, uimm3:$imm)), +- (VPICKVE2GR_H v8i16:$vj, uimm3:$imm)>; +-def : Pat<(i64 (vector_extract v4i32:$vj, uimm2:$imm)), +- (VPICKVE2GR_W v4i32:$vj, uimm2:$imm)>; +-def : Pat<(i64 (vector_extract v2i64:$vj, uimm1:$imm)), +- (VPICKVE2GR_D v2i64:$vj, uimm1:$imm)>; +-def : Pat<(f32 (vector_extract v4f32:$vj, uimm2:$imm)), +- (f32 (EXTRACT_SUBREG (VREPLVEI_W v4f32:$vj, uimm2:$imm), sub_32))>; +-def : Pat<(f64 (vector_extract v2f64:$vj, uimm1:$imm)), +- (f64 (EXTRACT_SUBREG (VREPLVEI_D v2f64:$vj, uimm1:$imm), sub_64))>; +- +-// Vector extraction with variable index. +-def : Pat<(i64 (vector_extract v16i8:$vj, i64:$rk)), +- (SRAI_W (COPY_TO_REGCLASS (f32 (EXTRACT_SUBREG (VREPLVE_B v16i8:$vj, +- i64:$rk), +- sub_32)), +- GPR), (i64 24))>; +-def : Pat<(i64 (vector_extract v8i16:$vj, i64:$rk)), +- (SRAI_W (COPY_TO_REGCLASS (f32 (EXTRACT_SUBREG (VREPLVE_H v8i16:$vj, +- i64:$rk), +- sub_32)), +- GPR), (i64 16))>; +-def : Pat<(i64 (vector_extract v4i32:$vj, i64:$rk)), +- (COPY_TO_REGCLASS (f32 (EXTRACT_SUBREG (VREPLVE_W v4i32:$vj, i64:$rk), +- sub_32)), +- GPR)>; +-def : Pat<(i64 (vector_extract v2i64:$vj, i64:$rk)), +- (COPY_TO_REGCLASS (f64 (EXTRACT_SUBREG (VREPLVE_D v2i64:$vj, i64:$rk), +- sub_64)), +- GPR)>; +-def : Pat<(f32 (vector_extract v4f32:$vj, i64:$rk)), +- (f32 (EXTRACT_SUBREG (VREPLVE_W v4f32:$vj, i64:$rk), sub_32))>; +-def : Pat<(f64 (vector_extract v2f64:$vj, i64:$rk)), +- (f64 (EXTRACT_SUBREG (VREPLVE_D v2f64:$vj, i64:$rk), sub_64))>; +- +-// vselect +-def : Pat<(v16i8 (vselect LSX128:$vd, (v16i8 (SplatPat_uimm8 uimm8:$imm)), +- LSX128:$vj)), +- (VBITSELI_B LSX128:$vd, LSX128:$vj, uimm8:$imm)>; +-foreach vt = [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64] in +- def : Pat<(vt (vselect LSX128:$va, LSX128:$vk, LSX128:$vj)), +- (VBITSEL_V LSX128:$vj, LSX128:$vk, LSX128:$va)>; +- +-// fneg +-def : Pat<(fneg (v4f32 LSX128:$vj)), (VBITREVI_W LSX128:$vj, 31)>; +-def : Pat<(fneg (v2f64 LSX128:$vj)), (VBITREVI_D LSX128:$vj, 63)>; +- +-// VFFINT_{S_W/D_L} +-def : Pat<(v4f32 (sint_to_fp v4i32:$vj)), (VFFINT_S_W v4i32:$vj)>; +-def : Pat<(v2f64 (sint_to_fp v2i64:$vj)), (VFFINT_D_L v2i64:$vj)>; +- +-// VFFINT_{S_WU/D_LU} +-def : Pat<(v4f32 (uint_to_fp v4i32:$vj)), (VFFINT_S_WU v4i32:$vj)>; +-def : Pat<(v2f64 (uint_to_fp v2i64:$vj)), (VFFINT_D_LU v2i64:$vj)>; +- +-// VFTINTRZ_{W_S/L_D} +-def : Pat<(v4i32 (fp_to_sint v4f32:$vj)), (VFTINTRZ_W_S v4f32:$vj)>; +-def : Pat<(v2i64 (fp_to_sint v2f64:$vj)), (VFTINTRZ_L_D v2f64:$vj)>; +- +-// VFTINTRZ_{W_SU/L_DU} +-def : Pat<(v4i32 (fp_to_uint v4f32:$vj)), (VFTINTRZ_WU_S v4f32:$vj)>; +-def : Pat<(v2i64 (fp_to_uint v2f64:$vj)), (VFTINTRZ_LU_D v2f64:$vj)>; +- +-} // Predicates = [HasExtLSX] +- +-/// Intrinsic pattern +- +-class deriveLSXIntrinsic { +- Intrinsic ret = !cast(!tolower("int_loongarch_lsx_"#Inst)); +-} +- +-let Predicates = [HasExtLSX] in { +- +-// vty: v16i8/v8i16/v4i32/v2i64 +-// Pat<(Intrinsic vty:$vj, vty:$vk), +-// (LAInst vty:$vj, vty:$vk)>; +-foreach Inst = ["VSADD_B", "VSADD_BU", "VSSUB_B", "VSSUB_BU", +- "VHADDW_H_B", "VHADDW_HU_BU", "VHSUBW_H_B", "VHSUBW_HU_BU", +- "VADDWEV_H_B", "VADDWOD_H_B", "VSUBWEV_H_B", "VSUBWOD_H_B", +- "VADDWEV_H_BU", "VADDWOD_H_BU", "VSUBWEV_H_BU", "VSUBWOD_H_BU", +- "VADDWEV_H_BU_B", "VADDWOD_H_BU_B", +- "VAVG_B", "VAVG_BU", "VAVGR_B", "VAVGR_BU", +- "VABSD_B", "VABSD_BU", "VADDA_B", "VMUH_B", "VMUH_BU", +- "VMULWEV_H_B", "VMULWOD_H_B", "VMULWEV_H_BU", "VMULWOD_H_BU", +- "VMULWEV_H_BU_B", "VMULWOD_H_BU_B", "VSIGNCOV_B", +- "VANDN_V", "VORN_V", "VROTR_B", "VSRLR_B", "VSRAR_B", +- "VSEQ_B", "VSLE_B", "VSLE_BU", "VSLT_B", "VSLT_BU", +- "VPACKEV_B", "VPACKOD_B", "VPICKEV_B", "VPICKOD_B", +- "VILVL_B", "VILVH_B"] in +- def : Pat<(deriveLSXIntrinsic.ret +- (v16i8 LSX128:$vj), (v16i8 LSX128:$vk)), +- (!cast(Inst) LSX128:$vj, LSX128:$vk)>; +-foreach Inst = ["VSADD_H", "VSADD_HU", "VSSUB_H", "VSSUB_HU", +- "VHADDW_W_H", "VHADDW_WU_HU", "VHSUBW_W_H", "VHSUBW_WU_HU", +- "VADDWEV_W_H", "VADDWOD_W_H", "VSUBWEV_W_H", "VSUBWOD_W_H", +- "VADDWEV_W_HU", "VADDWOD_W_HU", "VSUBWEV_W_HU", "VSUBWOD_W_HU", +- "VADDWEV_W_HU_H", "VADDWOD_W_HU_H", +- "VAVG_H", "VAVG_HU", "VAVGR_H", "VAVGR_HU", +- "VABSD_H", "VABSD_HU", "VADDA_H", "VMUH_H", "VMUH_HU", +- "VMULWEV_W_H", "VMULWOD_W_H", "VMULWEV_W_HU", "VMULWOD_W_HU", +- "VMULWEV_W_HU_H", "VMULWOD_W_HU_H", "VSIGNCOV_H", "VROTR_H", +- "VSRLR_H", "VSRAR_H", "VSRLN_B_H", "VSRAN_B_H", "VSRLRN_B_H", +- "VSRARN_B_H", "VSSRLN_B_H", "VSSRAN_B_H", "VSSRLN_BU_H", +- "VSSRAN_BU_H", "VSSRLRN_B_H", "VSSRARN_B_H", "VSSRLRN_BU_H", +- "VSSRARN_BU_H", +- "VSEQ_H", "VSLE_H", "VSLE_HU", "VSLT_H", "VSLT_HU", +- "VPACKEV_H", "VPACKOD_H", "VPICKEV_H", "VPICKOD_H", +- "VILVL_H", "VILVH_H"] in +- def : Pat<(deriveLSXIntrinsic.ret +- (v8i16 LSX128:$vj), (v8i16 LSX128:$vk)), +- (!cast(Inst) LSX128:$vj, LSX128:$vk)>; +-foreach Inst = ["VSADD_W", "VSADD_WU", "VSSUB_W", "VSSUB_WU", +- "VHADDW_D_W", "VHADDW_DU_WU", "VHSUBW_D_W", "VHSUBW_DU_WU", +- "VADDWEV_D_W", "VADDWOD_D_W", "VSUBWEV_D_W", "VSUBWOD_D_W", +- "VADDWEV_D_WU", "VADDWOD_D_WU", "VSUBWEV_D_WU", "VSUBWOD_D_WU", +- "VADDWEV_D_WU_W", "VADDWOD_D_WU_W", +- "VAVG_W", "VAVG_WU", "VAVGR_W", "VAVGR_WU", +- "VABSD_W", "VABSD_WU", "VADDA_W", "VMUH_W", "VMUH_WU", +- "VMULWEV_D_W", "VMULWOD_D_W", "VMULWEV_D_WU", "VMULWOD_D_WU", +- "VMULWEV_D_WU_W", "VMULWOD_D_WU_W", "VSIGNCOV_W", "VROTR_W", +- "VSRLR_W", "VSRAR_W", "VSRLN_H_W", "VSRAN_H_W", "VSRLRN_H_W", +- "VSRARN_H_W", "VSSRLN_H_W", "VSSRAN_H_W", "VSSRLN_HU_W", +- "VSSRAN_HU_W", "VSSRLRN_H_W", "VSSRARN_H_W", "VSSRLRN_HU_W", +- "VSSRARN_HU_W", +- "VSEQ_W", "VSLE_W", "VSLE_WU", "VSLT_W", "VSLT_WU", +- "VPACKEV_W", "VPACKOD_W", "VPICKEV_W", "VPICKOD_W", +- "VILVL_W", "VILVH_W"] in +- def : Pat<(deriveLSXIntrinsic.ret +- (v4i32 LSX128:$vj), (v4i32 LSX128:$vk)), +- (!cast(Inst) LSX128:$vj, LSX128:$vk)>; +-foreach Inst = ["VADD_Q", "VSUB_Q", +- "VSADD_D", "VSADD_DU", "VSSUB_D", "VSSUB_DU", +- "VHADDW_Q_D", "VHADDW_QU_DU", "VHSUBW_Q_D", "VHSUBW_QU_DU", +- "VADDWEV_Q_D", "VADDWOD_Q_D", "VSUBWEV_Q_D", "VSUBWOD_Q_D", +- "VADDWEV_Q_DU", "VADDWOD_Q_DU", "VSUBWEV_Q_DU", "VSUBWOD_Q_DU", +- "VADDWEV_Q_DU_D", "VADDWOD_Q_DU_D", +- "VAVG_D", "VAVG_DU", "VAVGR_D", "VAVGR_DU", +- "VABSD_D", "VABSD_DU", "VADDA_D", "VMUH_D", "VMUH_DU", +- "VMULWEV_Q_D", "VMULWOD_Q_D", "VMULWEV_Q_DU", "VMULWOD_Q_DU", +- "VMULWEV_Q_DU_D", "VMULWOD_Q_DU_D", "VSIGNCOV_D", "VROTR_D", +- "VSRLR_D", "VSRAR_D", "VSRLN_W_D", "VSRAN_W_D", "VSRLRN_W_D", +- "VSRARN_W_D", "VSSRLN_W_D", "VSSRAN_W_D", "VSSRLN_WU_D", +- "VSSRAN_WU_D", "VSSRLRN_W_D", "VSSRARN_W_D", "VSSRLRN_WU_D", +- "VSSRARN_WU_D", "VFFINT_S_L", +- "VSEQ_D", "VSLE_D", "VSLE_DU", "VSLT_D", "VSLT_DU", +- "VPACKEV_D", "VPACKOD_D", "VPICKEV_D", "VPICKOD_D", +- "VILVL_D", "VILVH_D"] in +- def : Pat<(deriveLSXIntrinsic.ret +- (v2i64 LSX128:$vj), (v2i64 LSX128:$vk)), +- (!cast(Inst) LSX128:$vj, LSX128:$vk)>; +- +-// vty: v16i8/v8i16/v4i32/v2i64 +-// Pat<(Intrinsic vty:$vd, vty:$vj, vty:$vk), +-// (LAInst vty:$vd, vty:$vj, vty:$vk)>; +-foreach Inst = ["VMADDWEV_H_B", "VMADDWOD_H_B", "VMADDWEV_H_BU", +- "VMADDWOD_H_BU", "VMADDWEV_H_BU_B", "VMADDWOD_H_BU_B"] in +- def : Pat<(deriveLSXIntrinsic.ret +- (v8i16 LSX128:$vd), (v16i8 LSX128:$vj), (v16i8 LSX128:$vk)), +- (!cast(Inst) LSX128:$vd, LSX128:$vj, LSX128:$vk)>; +-foreach Inst = ["VMADDWEV_W_H", "VMADDWOD_W_H", "VMADDWEV_W_HU", +- "VMADDWOD_W_HU", "VMADDWEV_W_HU_H", "VMADDWOD_W_HU_H"] in +- def : Pat<(deriveLSXIntrinsic.ret +- (v4i32 LSX128:$vd), (v8i16 LSX128:$vj), (v8i16 LSX128:$vk)), +- (!cast(Inst) LSX128:$vd, LSX128:$vj, LSX128:$vk)>; +-foreach Inst = ["VMADDWEV_D_W", "VMADDWOD_D_W", "VMADDWEV_D_WU", +- "VMADDWOD_D_WU", "VMADDWEV_D_WU_W", "VMADDWOD_D_WU_W"] in +- def : Pat<(deriveLSXIntrinsic.ret +- (v2i64 LSX128:$vd), (v4i32 LSX128:$vj), (v4i32 LSX128:$vk)), +- (!cast(Inst) LSX128:$vd, LSX128:$vj, LSX128:$vk)>; +-foreach Inst = ["VMADDWEV_Q_D", "VMADDWOD_Q_D", "VMADDWEV_Q_DU", +- "VMADDWOD_Q_DU", "VMADDWEV_Q_DU_D", "VMADDWOD_Q_DU_D"] in +- def : Pat<(deriveLSXIntrinsic.ret +- (v2i64 LSX128:$vd), (v2i64 LSX128:$vj), (v2i64 LSX128:$vk)), +- (!cast(Inst) LSX128:$vd, LSX128:$vj, LSX128:$vk)>; +- +-// vty: v16i8/v8i16/v4i32/v2i64 +-// Pat<(Intrinsic vty:$vj), +-// (LAInst vty:$vj)>; +-foreach Inst = ["VEXTH_H_B", "VEXTH_HU_BU", +- "VMSKLTZ_B", "VMSKGEZ_B", "VMSKNZ_B", +- "VCLO_B"] in +- def : Pat<(deriveLSXIntrinsic.ret (v16i8 LSX128:$vj)), +- (!cast(Inst) LSX128:$vj)>; +-foreach Inst = ["VEXTH_W_H", "VEXTH_WU_HU", "VMSKLTZ_H", +- "VCLO_H", "VFCVTL_S_H", "VFCVTH_S_H"] in +- def : Pat<(deriveLSXIntrinsic.ret (v8i16 LSX128:$vj)), +- (!cast(Inst) LSX128:$vj)>; +-foreach Inst = ["VEXTH_D_W", "VEXTH_DU_WU", "VMSKLTZ_W", +- "VCLO_W", "VFFINT_S_W", "VFFINT_S_WU", +- "VFFINTL_D_W", "VFFINTH_D_W"] in +- def : Pat<(deriveLSXIntrinsic.ret (v4i32 LSX128:$vj)), +- (!cast(Inst) LSX128:$vj)>; +-foreach Inst = ["VEXTH_Q_D", "VEXTH_QU_DU", "VMSKLTZ_D", +- "VEXTL_Q_D", "VEXTL_QU_DU", +- "VCLO_D", "VFFINT_D_L", "VFFINT_D_LU"] in +- def : Pat<(deriveLSXIntrinsic.ret (v2i64 LSX128:$vj)), +- (!cast(Inst) LSX128:$vj)>; +- +-// Pat<(Intrinsic timm:$imm) +-// (LAInst timm:$imm)>; +-def : Pat<(int_loongarch_lsx_vldi timm:$imm), +- (VLDI (to_valid_timm timm:$imm))>; +-foreach Inst = ["VREPLI_B", "VREPLI_H", "VREPLI_W", "VREPLI_D"] in +- def : Pat<(deriveLSXIntrinsic.ret timm:$imm), +- (!cast("Pseudo"#Inst) (to_valid_timm timm:$imm))>; +- +-// vty: v16i8/v8i16/v4i32/v2i64 +-// Pat<(Intrinsic vty:$vj, timm:$imm) +-// (LAInst vty:$vj, timm:$imm)>; +-foreach Inst = ["VSAT_B", "VSAT_BU", "VNORI_B", "VROTRI_B", "VSLLWIL_H_B", +- "VSLLWIL_HU_BU", "VSRLRI_B", "VSRARI_B", +- "VSEQI_B", "VSLEI_B", "VSLEI_BU", "VSLTI_B", "VSLTI_BU", +- "VREPLVEI_B", "VBSLL_V", "VBSRL_V", "VSHUF4I_B"] in +- def : Pat<(deriveLSXIntrinsic.ret (v16i8 LSX128:$vj), timm:$imm), +- (!cast(Inst) LSX128:$vj, (to_valid_timm timm:$imm))>; +-foreach Inst = ["VSAT_H", "VSAT_HU", "VROTRI_H", "VSLLWIL_W_H", +- "VSLLWIL_WU_HU", "VSRLRI_H", "VSRARI_H", +- "VSEQI_H", "VSLEI_H", "VSLEI_HU", "VSLTI_H", "VSLTI_HU", +- "VREPLVEI_H", "VSHUF4I_H"] in +- def : Pat<(deriveLSXIntrinsic.ret (v8i16 LSX128:$vj), timm:$imm), +- (!cast(Inst) LSX128:$vj, (to_valid_timm timm:$imm))>; +-foreach Inst = ["VSAT_W", "VSAT_WU", "VROTRI_W", "VSLLWIL_D_W", +- "VSLLWIL_DU_WU", "VSRLRI_W", "VSRARI_W", +- "VSEQI_W", "VSLEI_W", "VSLEI_WU", "VSLTI_W", "VSLTI_WU", +- "VREPLVEI_W", "VSHUF4I_W"] in +- def : Pat<(deriveLSXIntrinsic.ret (v4i32 LSX128:$vj), timm:$imm), +- (!cast(Inst) LSX128:$vj, (to_valid_timm timm:$imm))>; +-foreach Inst = ["VSAT_D", "VSAT_DU", "VROTRI_D", "VSRLRI_D", "VSRARI_D", +- "VSEQI_D", "VSLEI_D", "VSLEI_DU", "VSLTI_D", "VSLTI_DU", +- "VPICKVE2GR_D", "VPICKVE2GR_DU", +- "VREPLVEI_D"] in +- def : Pat<(deriveLSXIntrinsic.ret (v2i64 LSX128:$vj), timm:$imm), +- (!cast(Inst) LSX128:$vj, (to_valid_timm timm:$imm))>; +- +-// vty: v16i8/v8i16/v4i32/v2i64 +-// Pat<(Intrinsic vty:$vd, vty:$vj, timm:$imm) +-// (LAInst vty:$vd, vty:$vj, timm:$imm)>; +-foreach Inst = ["VSRLNI_B_H", "VSRANI_B_H", "VSRLRNI_B_H", "VSRARNI_B_H", +- "VSSRLNI_B_H", "VSSRANI_B_H", "VSSRLNI_BU_H", "VSSRANI_BU_H", +- "VSSRLRNI_B_H", "VSSRARNI_B_H", "VSSRLRNI_BU_H", "VSSRARNI_BU_H", +- "VFRSTPI_B", "VBITSELI_B", "VEXTRINS_B"] in +- def : Pat<(deriveLSXIntrinsic.ret +- (v16i8 LSX128:$vd), (v16i8 LSX128:$vj), timm:$imm), +- (!cast(Inst) LSX128:$vd, LSX128:$vj, +- (to_valid_timm timm:$imm))>; +-foreach Inst = ["VSRLNI_H_W", "VSRANI_H_W", "VSRLRNI_H_W", "VSRARNI_H_W", +- "VSSRLNI_H_W", "VSSRANI_H_W", "VSSRLNI_HU_W", "VSSRANI_HU_W", +- "VSSRLRNI_H_W", "VSSRARNI_H_W", "VSSRLRNI_HU_W", "VSSRARNI_HU_W", +- "VFRSTPI_H", "VEXTRINS_H"] in +- def : Pat<(deriveLSXIntrinsic.ret +- (v8i16 LSX128:$vd), (v8i16 LSX128:$vj), timm:$imm), +- (!cast(Inst) LSX128:$vd, LSX128:$vj, +- (to_valid_timm timm:$imm))>; +-foreach Inst = ["VSRLNI_W_D", "VSRANI_W_D", "VSRLRNI_W_D", "VSRARNI_W_D", +- "VSSRLNI_W_D", "VSSRANI_W_D", "VSSRLNI_WU_D", "VSSRANI_WU_D", +- "VSSRLRNI_W_D", "VSSRARNI_W_D", "VSSRLRNI_WU_D", "VSSRARNI_WU_D", +- "VPERMI_W", "VEXTRINS_W"] in +- def : Pat<(deriveLSXIntrinsic.ret +- (v4i32 LSX128:$vd), (v4i32 LSX128:$vj), timm:$imm), +- (!cast(Inst) LSX128:$vd, LSX128:$vj, +- (to_valid_timm timm:$imm))>; +-foreach Inst = ["VSRLNI_D_Q", "VSRANI_D_Q", "VSRLRNI_D_Q", "VSRARNI_D_Q", +- "VSSRLNI_D_Q", "VSSRANI_D_Q", "VSSRLNI_DU_Q", "VSSRANI_DU_Q", +- "VSSRLRNI_D_Q", "VSSRARNI_D_Q", "VSSRLRNI_DU_Q", "VSSRARNI_DU_Q", +- "VSHUF4I_D", "VEXTRINS_D"] in +- def : Pat<(deriveLSXIntrinsic.ret +- (v2i64 LSX128:$vd), (v2i64 LSX128:$vj), timm:$imm), +- (!cast(Inst) LSX128:$vd, LSX128:$vj, +- (to_valid_timm timm:$imm))>; +- +-// vty: v16i8/v8i16/v4i32/v2i64 +-// Pat<(Intrinsic vty:$vd, vty:$vj, vty:$vk), +-// (LAInst vty:$vd, vty:$vj, vty:$vk)>; +-foreach Inst = ["VFRSTP_B", "VBITSEL_V", "VSHUF_B"] in +- def : Pat<(deriveLSXIntrinsic.ret +- (v16i8 LSX128:$vd), (v16i8 LSX128:$vj), (v16i8 LSX128:$vk)), +- (!cast(Inst) LSX128:$vd, LSX128:$vj, LSX128:$vk)>; +-foreach Inst = ["VFRSTP_H", "VSHUF_H"] in +- def : Pat<(deriveLSXIntrinsic.ret +- (v8i16 LSX128:$vd), (v8i16 LSX128:$vj), (v8i16 LSX128:$vk)), +- (!cast(Inst) LSX128:$vd, LSX128:$vj, LSX128:$vk)>; +-def : Pat<(int_loongarch_lsx_vshuf_w (v4i32 LSX128:$vd), (v4i32 LSX128:$vj), +- (v4i32 LSX128:$vk)), +- (VSHUF_W LSX128:$vd, LSX128:$vj, LSX128:$vk)>; +-def : Pat<(int_loongarch_lsx_vshuf_d (v2i64 LSX128:$vd), (v2i64 LSX128:$vj), +- (v2i64 LSX128:$vk)), +- (VSHUF_D LSX128:$vd, LSX128:$vj, LSX128:$vk)>; +- +-// vty: v4f32/v2f64 +-// Pat<(Intrinsic vty:$vj, vty:$vk, vty:$va), +-// (LAInst vty:$vj, vty:$vk, vty:$va)>; +-foreach Inst = ["VFMSUB_S", "VFNMADD_S", "VFNMSUB_S"] in +- def : Pat<(deriveLSXIntrinsic.ret +- (v4f32 LSX128:$vj), (v4f32 LSX128:$vk), (v4f32 LSX128:$va)), +- (!cast(Inst) LSX128:$vj, LSX128:$vk, LSX128:$va)>; +-foreach Inst = ["VFMSUB_D", "VFNMADD_D", "VFNMSUB_D"] in +- def : Pat<(deriveLSXIntrinsic.ret +- (v2f64 LSX128:$vj), (v2f64 LSX128:$vk), (v2f64 LSX128:$va)), +- (!cast(Inst) LSX128:$vj, LSX128:$vk, LSX128:$va)>; +- +-// vty: v4f32/v2f64 +-// Pat<(Intrinsic vty:$vj, vty:$vk), +-// (LAInst vty:$vj, vty:$vk)>; +-foreach Inst = ["VFMAX_S", "VFMIN_S", "VFMAXA_S", "VFMINA_S", "VFCVT_H_S", +- "VFCMP_CAF_S", "VFCMP_CUN_S", "VFCMP_CEQ_S", "VFCMP_CUEQ_S", +- "VFCMP_CLT_S", "VFCMP_CULT_S", "VFCMP_CLE_S", "VFCMP_CULE_S", +- "VFCMP_CNE_S", "VFCMP_COR_S", "VFCMP_CUNE_S", +- "VFCMP_SAF_S", "VFCMP_SUN_S", "VFCMP_SEQ_S", "VFCMP_SUEQ_S", +- "VFCMP_SLT_S", "VFCMP_SULT_S", "VFCMP_SLE_S", "VFCMP_SULE_S", +- "VFCMP_SNE_S", "VFCMP_SOR_S", "VFCMP_SUNE_S"] in +- def : Pat<(deriveLSXIntrinsic.ret +- (v4f32 LSX128:$vj), (v4f32 LSX128:$vk)), +- (!cast(Inst) LSX128:$vj, LSX128:$vk)>; +-foreach Inst = ["VFMAX_D", "VFMIN_D", "VFMAXA_D", "VFMINA_D", "VFCVT_S_D", +- "VFTINTRNE_W_D", "VFTINTRZ_W_D", "VFTINTRP_W_D", "VFTINTRM_W_D", +- "VFTINT_W_D", +- "VFCMP_CAF_D", "VFCMP_CUN_D", "VFCMP_CEQ_D", "VFCMP_CUEQ_D", +- "VFCMP_CLT_D", "VFCMP_CULT_D", "VFCMP_CLE_D", "VFCMP_CULE_D", +- "VFCMP_CNE_D", "VFCMP_COR_D", "VFCMP_CUNE_D", +- "VFCMP_SAF_D", "VFCMP_SUN_D", "VFCMP_SEQ_D", "VFCMP_SUEQ_D", +- "VFCMP_SLT_D", "VFCMP_SULT_D", "VFCMP_SLE_D", "VFCMP_SULE_D", +- "VFCMP_SNE_D", "VFCMP_SOR_D", "VFCMP_SUNE_D"] in +- def : Pat<(deriveLSXIntrinsic.ret +- (v2f64 LSX128:$vj), (v2f64 LSX128:$vk)), +- (!cast(Inst) LSX128:$vj, LSX128:$vk)>; +- +-// vty: v4f32/v2f64 +-// Pat<(Intrinsic vty:$vj), +-// (LAInst vty:$vj)>; +-foreach Inst = ["VFLOGB_S", "VFCLASS_S", "VFSQRT_S", "VFRECIP_S", "VFRSQRT_S", +- "VFRINT_S", "VFCVTL_D_S", "VFCVTH_D_S", +- "VFRINTRNE_S", "VFRINTRZ_S", "VFRINTRP_S", "VFRINTRM_S", +- "VFTINTRNE_W_S", "VFTINTRZ_W_S", "VFTINTRP_W_S", "VFTINTRM_W_S", +- "VFTINT_W_S", "VFTINTRZ_WU_S", "VFTINT_WU_S", +- "VFTINTRNEL_L_S", "VFTINTRNEH_L_S", "VFTINTRZL_L_S", +- "VFTINTRZH_L_S", "VFTINTRPL_L_S", "VFTINTRPH_L_S", +- "VFTINTRML_L_S", "VFTINTRMH_L_S", "VFTINTL_L_S", +- "VFTINTH_L_S"] in +- def : Pat<(deriveLSXIntrinsic.ret (v4f32 LSX128:$vj)), +- (!cast(Inst) LSX128:$vj)>; +-foreach Inst = ["VFLOGB_D", "VFCLASS_D", "VFSQRT_D", "VFRECIP_D", "VFRSQRT_D", +- "VFRINT_D", +- "VFRINTRNE_D", "VFRINTRZ_D", "VFRINTRP_D", "VFRINTRM_D", +- "VFTINTRNE_L_D", "VFTINTRZ_L_D", "VFTINTRP_L_D", "VFTINTRM_L_D", +- "VFTINT_L_D", "VFTINTRZ_LU_D", "VFTINT_LU_D"] in +- def : Pat<(deriveLSXIntrinsic.ret (v2f64 LSX128:$vj)), +- (!cast(Inst) LSX128:$vj)>; ++class LSX_3RN_DESC_BASE : ++ LSX_3R_DESC_BASE; ++ ++class LSX_3R_4R_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVD:$vd_in, ROVJ:$vj, ROVK:$vk); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $vk"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVD:$vd_in, ROVJ:$vj, ++ ROVK:$vk))]; ++ string Constraints = "$vd = $vd_in"; ++} + +-// 128-Bit vector FP approximate reciprocal operation +-let Predicates = [HasFrecipe] in { +-foreach Inst = ["VFRECIPE_S", "VFRSQRTE_S"] in +- def : Pat<(deriveLSXIntrinsic.ret (v4f32 LSX128:$vj)), +- (!cast(Inst) LSX128:$vj)>; +-foreach Inst = ["VFRECIPE_D", "VFRSQRTE_D"] in +- def : Pat<(deriveLSXIntrinsic.ret (v2f64 LSX128:$vj)), +- (!cast(Inst) LSX128:$vj)>; +-} +- +-// load +-def : Pat<(int_loongarch_lsx_vld GPR:$rj, timm:$imm), +- (VLD GPR:$rj, (to_valid_timm timm:$imm))>; +-def : Pat<(int_loongarch_lsx_vldx GPR:$rj, GPR:$rk), +- (VLDX GPR:$rj, GPR:$rk)>; +- +-def : Pat<(int_loongarch_lsx_vldrepl_b GPR:$rj, timm:$imm), +- (VLDREPL_B GPR:$rj, (to_valid_timm timm:$imm))>; +-def : Pat<(int_loongarch_lsx_vldrepl_h GPR:$rj, timm:$imm), +- (VLDREPL_H GPR:$rj, (to_valid_timm timm:$imm))>; +-def : Pat<(int_loongarch_lsx_vldrepl_w GPR:$rj, timm:$imm), +- (VLDREPL_W GPR:$rj, (to_valid_timm timm:$imm))>; +-def : Pat<(int_loongarch_lsx_vldrepl_d GPR:$rj, timm:$imm), +- (VLDREPL_D GPR:$rj, (to_valid_timm timm:$imm))>; +- +-// store +-def : Pat<(int_loongarch_lsx_vst LSX128:$vd, GPR:$rj, timm:$imm), +- (VST LSX128:$vd, GPR:$rj, (to_valid_timm timm:$imm))>; +-def : Pat<(int_loongarch_lsx_vstx LSX128:$vd, GPR:$rj, GPR:$rk), +- (VSTX LSX128:$vd, GPR:$rj, GPR:$rk)>; +- +-def : Pat<(int_loongarch_lsx_vstelm_b v16i8:$vd, GPR:$rj, timm:$imm, timm:$idx), +- (VSTELM_B v16i8:$vd, GPR:$rj, (to_valid_timm timm:$imm), +- (to_valid_timm timm:$idx))>; +-def : Pat<(int_loongarch_lsx_vstelm_h v8i16:$vd, GPR:$rj, timm:$imm, timm:$idx), +- (VSTELM_H v8i16:$vd, GPR:$rj, (to_valid_timm timm:$imm), +- (to_valid_timm timm:$idx))>; +-def : Pat<(int_loongarch_lsx_vstelm_w v4i32:$vd, GPR:$rj, timm:$imm, timm:$idx), +- (VSTELM_W v4i32:$vd, GPR:$rj, (to_valid_timm timm:$imm), +- (to_valid_timm timm:$idx))>; +-def : Pat<(int_loongarch_lsx_vstelm_d v2i64:$vd, GPR:$rj, timm:$imm, timm:$idx), +- (VSTELM_D v2i64:$vd, GPR:$rj, (to_valid_timm timm:$imm), +- (to_valid_timm timm:$idx))>; +- +-} // Predicates = [HasExtLSX] ++class LSX_3R_VREPLVE_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, GPR32Opnd:$rk); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $rk"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, GPR32Opnd:$rk))]; ++} ++ ++class LSX_VEC_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, ROVK:$vk); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $vk"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, ROVK:$vk))]; ++} ++ ++class LSX_VEC_PSEUDO_BASE : ++ LSXPseudo<(outs ROVD:$vd), (ins ROVJ:$vj, ROVK:$vk), ++ [(set ROVD:$vd, (OpNode ROVJ:$vj, ROVK:$vk))]>; ++ ++class LSX_3RF_DESC_BASE : ++ LSX_3R_DESC_BASE; ++ ++class LSX_3RFN_DESC_BASE : ++ LSX_3R_DESC_BASE; ++ ++class LSX_3R_DESC_BASE1 { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, ROVK:$vk); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $vk"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, ROVK:$vk))]; ++} ++ ++class LSX_3RF_DESC_BASE1 : ++ LSX_3R_DESC_BASE1; ++ ++class LSX_3R_VSHF_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVD:$vd_in, ROVJ:$vj, ROVK:$vk); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $vk"); ++ list Pattern = [(set ROVD:$vd, (LoongArchVSHF ROVD:$vd_in, ROVJ:$vj, ++ ROVK:$vk))]; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++class LSX_3R_4R_VSHF_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, ROVK:$vk, ROVD:$va); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $vk, $va"); ++ list Pattern = [(set ROVD:$vd, (LoongArchVSHF ROVD:$va, ROVJ:$vj, ++ ROVK:$vk))]; ++} ++ ++class LSX_I5_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, SplatImm.OpClass:$si5); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $si5"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, SplatImm:$si5))]; ++} ++ ++class LSX_I5_U_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, SplatImm.OpClass:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui5"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, SplatImm:$ui5))]; ++} ++ ++class LSX_BIT_3_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, ImmOp:$ui3); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui3"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, Imm:$ui3))]; ++} ++ ++class LSX_BIT_3N_DESC_BASE : ++ LSX_BIT_3_DESC_BASE; ++ ++class LSX_BIT_4_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, ImmOp:$ui4); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui4"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, Imm:$ui4))]; ++} ++ ++class LSX_BIT_4N_DESC_BASE : ++ LSX_BIT_4_DESC_BASE; ++ ++class LSX_BIT_5_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, ImmOp:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui5"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, Imm:$ui5))]; ++} ++ ++class LSX_BIT_5N_DESC_BASE : ++ LSX_BIT_5_DESC_BASE; ++ ++class LSX_BIT_6_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, ImmOp:$ui6); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui6"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, Imm:$ui6))]; ++} ++ ++class LSX_BIT_6N_DESC_BASE : ++ LSX_BIT_6_DESC_BASE; ++ ++class LSX_2R_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj))]; ++} ++ ++class LSX_2RN_DESC_BASE : ++ LSX_2R_DESC_BASE; ++ ++class LSX_2RF_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj))]; ++} ++ ++class LSX_2RFN_DESC_BASE : ++ LSX_2R_DESC_BASE; ++ ++class LSX_2RF_DESC_BASE_CVT { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj))]; ++} ++ ++class LSX_2RFN_DESC_BASE_CVT : ++ LSX_2RF_DESC_BASE_CVT; ++ ++class LSX_2RF_DESC_BASE_tmp { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj"); ++ list Pattern = []; ++} ++ ++class LSX_2R_REPL_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROS:$rj); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $rj"); ++ list Pattern = [(set ROVD:$vd, (VT (OpNode ROS:$rj)))]; ++} ++ ++class LSX_INSERT_U4_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVD:$vd_in, ROVJ:$rj, ImmOp:$ui4); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $rj, $ui4"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVD:$vd_in, ROVJ:$rj, Imm:$ui4))]; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++class LSX_INSERT_U4N_DESC_BASE : ++ LSX_INSERT_U4_DESC_BASE; ++ ++class LSX_INSERT_U3_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVD:$vd_in, ROS:$rj, ImmOp:$ui3); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $rj, $ui3"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVD:$vd_in, ROS:$rj, Imm:$ui3))]; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++class LSX_INSERT_U3N_DESC_BASE : ++ LSX_INSERT_U3_DESC_BASE; ++ ++class LSX_INSERT_U2_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVD:$vd_in, ROS:$rj, ImmOp:$ui2); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $rj, $ui2"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVD:$vd_in, ROS:$rj, Imm:$ui2))]; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++class LSX_INSERT_U2N_DESC_BASE : ++ LSX_INSERT_U2_DESC_BASE; ++ ++class LSX_INSERT_U1_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVD:$vd_in, ROS:$rj, ImmOp:$ui1); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $rj, $ui1"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVD:$vd_in, ROS:$rj, Imm:$ui1))]; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++class LSX_INSERT_U1N_DESC_BASE : ++ LSX_INSERT_U1_DESC_BASE; ++ ++class LSX_PICK_U1_DESC_BASE { ++ dag OutOperandList = (outs ROD:$rd); ++ dag InOperandList = (ins ROVJ:$vj, ImmOp:$ui1); ++ string AsmString = !strconcat(instr_asm, "\t$rd, $vj, $ui1"); ++ list Pattern = [(set ROD:$rd, (OpNode (VecTy ROVJ:$vj), Imm:$ui1))]; ++} ++ ++class LSX_PICK_U2_DESC_BASE { ++ dag OutOperandList = (outs ROD:$rd); ++ dag InOperandList = (ins ROVJ:$vj, ImmOp:$ui2); ++ string AsmString = !strconcat(instr_asm, "\t$rd, $vj, $ui2"); ++ list Pattern = [(set ROD:$rd, (OpNode (VecTy ROVJ:$vj), Imm:$ui2))]; ++} ++ ++class LSX_PICK_U3_DESC_BASE { ++ dag OutOperandList = (outs ROD:$rd); ++ dag InOperandList = (ins ROVJ:$vj, ImmOp:$ui3); ++ string AsmString = !strconcat(instr_asm, "\t$rd, $vj, $ui3"); ++ list Pattern = [(set ROD:$rd, (OpNode (VecTy ROVJ:$vj), Imm:$ui3))]; ++} ++ ++class LSX_PICK_U4_DESC_BASE { ++ dag OutOperandList = (outs ROD:$rd); ++ dag InOperandList = (ins ROVJ:$vj, ImmOp:$ui4); ++ string AsmString = !strconcat(instr_asm, "\t$rd, $vj, $ui4"); ++ list Pattern = [(set ROD:$rd, (OpNode (VecTy ROVJ:$vj), Imm:$ui4))]; ++} ++ ++class LSX_ELM_U3_VREPLVE_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, SplatImm.OpClass:$ui3); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui3"); ++ list Pattern = [(set ROVD:$vd, (LoongArchVSHF SplatImm:$ui3, ROVJ:$vj, ++ ROVJ:$vj))]; ++} ++ ++class LSX_ELM_U2_VREPLVE_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, SplatImm.OpClass:$ui2); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui2"); ++ list Pattern = [(set ROVD:$vd, (LoongArchVSHF SplatImm:$ui2, ROVJ:$vj, ++ ROVJ:$vj))]; ++} ++ ++class LSX_ELM_U1_VREPLVE_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, SplatImm.OpClass:$ui1); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui1"); ++ list Pattern = [(set ROVD:$vd, (LoongArchVSHF SplatImm:$ui1, ROVJ:$vj, ++ ROVJ:$vj))]; ++} ++ ++class LSX_ELM_U4_VREPLVE_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, SplatImm.OpClass:$ui4); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui4"); ++ list Pattern = [(set ROVD:$vd, (LoongArchVSHF SplatImm:$ui4, ROVJ:$vj, ++ ROVJ:$vj))]; ++} ++ ++class LSX_ELM_U4_SLD_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVD:$vd_in, ROVJ:$vj, ImmOp:$ui4); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui4"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVD:$vd_in, ROVJ:$vj, ++ Imm:$ui4))]; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++class LSX_ELM_U3_SLD_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVD:$vd_in, ROVJ:$vj, ImmOp:$ui3); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui3"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVD:$vd_in, ROVJ:$vj, ++ Imm:$ui3))]; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++class LSX_ELM_U2_SLD_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVD:$vd_in, ROVJ:$vj, ImmOp:$ui2); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui2"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVD:$vd_in, ROVJ:$vj, ++ Imm:$ui2))]; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++class LSX_ELM_U1_SLD_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVD:$vd_in, ROVJ:$vj, ImmOp:$ui1); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui1"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVD:$vd_in, ROVJ:$vj, ++ Imm:$ui1))]; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++class LSX_BIT_U3_VREPLVE_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, SplatImm.OpClass:$ui3); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui3"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, SplatImm:$ui3))]; ++} ++ ++class LSX_BIT_U4_VREPLVE_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, SplatImm.OpClass:$ui4); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui4"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, SplatImm:$ui4))]; ++} ++ ++class LSX_BIT_U5_VREPLVE_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, SplatImm.OpClass:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui5"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, SplatImm:$ui5))]; ++} ++ ++class LSX_BIT_U6_VREPLVE_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, SplatImm.OpClass:$ui6); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui6"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, SplatImm:$ui6))]; ++} ++ ++class LSX_BIT_U6_VREPLVE_DESC_BASE_Intrinsic { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, uimm6:$ui6); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui6"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, immZExt6:$ui6))]; ++} ++ ++class LSX_BIT_U3_VREPLVE_DESC_BASE_Intrinsic { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, uimm3:$ui3); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui3"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, immZExt3:$ui3))]; ++} ++ ++class LSX_BIT_U4_VREPLVE_DESC_BASE_Intrinsic { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, uimm4:$ui4); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui4"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, immZExt4:$ui4))]; ++} ++ ++class LSX_BIT_U5_VREPLVE_DESC_BASE_Intrinsic { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, uimm5:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui5"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, immZExt5:$ui5))]; ++} ++ ++class LSX_I8_SHF_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, uimm8:$ui8); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui8"); ++ list Pattern = [(set ROVD:$vd, (LoongArchSHF immZExt8:$ui8, ROVJ:$vj))]; ++} ++ ++class LSX_I8_SHUF_DESC_BASE_D { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVD:$vd_in, ROVJ:$vj, uimm8:$ui8); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui8"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVD:$vd_in, ROVJ:$vj, immZExt8:$ui8))]; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++def LoongArchSelect : SDNode<"LoongArchISD::VSELECT" ,SDTSelect>; ++def LoongArchVROR : SDNode<"LoongArchISD::VROR", ++ SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisInt<0>, ++ SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>]>, []>; ++def LoongArchVRORI : SDNode<"LoongArchISD::VRORI", ++ SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisInt<0>, ++ SDTCisSameAs<0, 1>, SDTCisVT<2, i32>]>, []>; ++ ++class LSX2_RORI_U3_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, ImmOp:$ui3); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui3"); ++ list Pattern = [(set ROVD:$vd, (LoongArchVRORI ROVJ:$vj, Imm:$ui3))]; ++} ++ ++class LSX2_RORI_U4_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, ImmOp:$ui4); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui4"); ++ list Pattern = [(set ROVD:$vd, (LoongArchVRORI ROVJ:$vj, Imm:$ui4))]; ++} ++ ++class LSX2_RORI_U5_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, ImmOp:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui5"); ++ list Pattern = [(set ROVD:$vd, (LoongArchVRORI ROVJ:$vj, Imm:$ui5))]; ++} ++ ++class LSX2_RORI_U6_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, ImmOp:$ui6); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui6"); ++ list Pattern = [(set ROVD:$vd, (LoongArchVRORI ROVJ:$vj, Imm:$ui6))]; ++} ++ ++class LSX_BIND_U4_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVD:$vd_in, ROVJ:$vj, ImmOp:$ui4); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui4"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVD:$vd_in, ROVJ:$vj, Imm:$ui4))]; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++class LSX_BIND_U4N_DESC_BASE : ++ LSX_BIND_U4_DESC_BASE; ++ ++class LSX_BIND_U5_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVD:$vd_in, ROVJ:$vj, ImmOp:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui5"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVD:$vd_in, ROVJ:$vj, Imm:$ui5))]; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++class LSX_BIND_U5N_DESC_BASE : ++ LSX_BIND_U5_DESC_BASE; ++ ++class LSX_BIND_U6_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVD:$vd_in, ROVJ:$vj, ImmOp:$ui6); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui6"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVD:$vd_in, ROVJ:$vj, Imm:$ui6))]; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++class LSX_BIND_U6N_DESC_BASE : ++ LSX_BIND_U6_DESC_BASE; ++ ++class LSX_BIND_U7_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVD:$vd_in, ROVJ:$vj, uimm7:$ui7); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui7"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVD:$vd_in, ROVJ:$vj, immZExt7:$ui7))]; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++class LSX_BIND_U7N_DESC_BASE : ++ LSX_BIND_U7_DESC_BASE; ++ ++ ++class LD_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins MemOpnd:$addr); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $addr"); ++ list Pattern = [(set ROVD:$vd, (TyNode (OpNode Addr:$addr)))]; ++ string DecoderMethod = "DecodeLSX128Mem"; ++} ++ ++class ST_DESC_BASE { ++ dag OutOperandList = (outs); ++ dag InOperandList = (ins ROVD:$vd, MemOpnd:$addr); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $addr"); ++ list Pattern = [(OpNode (TyNode ROVD:$vd), Addr:$addr)]; ++ string DecoderMethod = "DecodeLSX128Mem"; ++} ++ ++class LSX_VEC_ADDR_PSEUDO_BASE : ++ LSXPseudo<(outs), (ins ROVD:$vd, MemOpnd:$addr), ++ [(OpNode (TyNode ROVD:$vd), MemOpnd:$addr)]>; ++ ++ ++class LSX_SET_DESC_BASE { ++ dag OutOperandList = (outs FCFROpnd:$cd); ++ dag InOperandList = (ins ROVD:$vj); ++ string AsmString = !strconcat(instr_asm, "\t$cd, $vj"); ++ list Pattern = []; ++} ++ ++class LSX_SET_DESC_BASE_tmp { ++ dag OutOperandList = (outs FCFROpnd:$cd); ++ dag InOperandList = (ins ROVD:$vj); ++ string AsmString = !strconcat(instr_asm, "\t$cd, $vj"); ++ list Pattern = []; ++} ++ ++class LSX_VMul_Reg4 { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, ROVK:$vk, ROVA:$va); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $vk, $va"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, ROVK:$vk, ROVA:$va))]; ++} ++ ++class LSX_4RF { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, ROVK:$vk, ROVA:$va); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $vk, $va"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, ROVK:$vk, ROVA:$va))]; ++} ++ ++ ++class LSX_VFCMP_Reg3 { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, ROVK:$vk); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $vk"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, ROVK:$vk))]; ++} ++ ++class LSX_I12_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins PtrRC:$rj, ImmOp:$si12); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $rj, $si12"); ++ list Pattern = [(set ROVD:$vd, (OpNode iPTR:$rj, Imm:$si12))]; ++} ++ ++class LSX_I11_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins PtrRC:$rj, ImmOp:$si11); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $rj, $si11"); ++ list Pattern = [(set ROVD:$vd, (OpNode iPTR:$rj, Imm:$si11))]; ++} ++ ++class LSX_I10_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins PtrRC:$rj, ImmOp:$si10); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $rj, $si10"); ++ list Pattern = [(set ROVD:$vd, (OpNode iPTR:$rj, Imm:$si10))]; ++} ++ ++class LSX_I9_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins PtrRC:$rj, ImmOp:$si9); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $rj, $si9"); ++ list Pattern = [(set ROVD:$vd, (OpNode iPTR:$rj, Imm:$si9))]; ++} ++ ++ ++class LSX_I8_U1_DESC_BASE { ++ dag OutOperandList = (outs); ++ dag InOperandList = (ins ROVD:$vd, PtrRC:$rj, ImmOp:$si8, uimm1:$idx); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $rj, $si8, $idx"); ++ list Pattern = [(OpNode ROVD:$vd, iPTR:$rj, Imm:$si8, immZExt1:$idx)]; ++ string DecoderMethod = "DecodeLSX128memstl"; ++} ++ ++ ++class LSX_I8_U2_DESC_BASE { ++ dag OutOperandList = (outs); ++ dag InOperandList = (ins ROVD:$vd, PtrRC:$rj, ImmOp:$si8, uimm2:$idx); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $rj, $si8, $idx"); ++ list Pattern = [(OpNode ROVD:$vd, iPTR:$rj, Imm:$si8, immZExt2:$idx)]; ++ string DecoderMethod = "DecodeLSX128memstl"; ++} ++ ++class LSX_I8_U3_DESC_BASE { ++ dag OutOperandList = (outs); ++ dag InOperandList = (ins ROVD:$vd, PtrRC:$rj, ImmOp:$si8, uimm3:$idx); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $rj, $si8, $idx"); ++ list Pattern = [(OpNode ROVD:$vd, iPTR:$rj, Imm:$si8, immZExt3:$idx)]; ++ string DecoderMethod = "DecodeLSX128memstl"; ++} ++ ++class LSX_I8_U4_DESC_BASE { ++ dag OutOperandList = (outs); ++ dag InOperandList = (ins ROVD:$vd, PtrRC:$rj, ImmOp:$si8, uimm4:$idx); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $rj, $si8, $idx"); ++ list Pattern = [(OpNode ROVD:$vd, iPTR:$rj, Imm:$si8, immZExt4:$idx)]; ++ string DecoderMethod = "DecodeLSX128memstl"; ++} ++ ++class LSX_I5_U_DESC_BASE_Intrinsic { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, ImmOp:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui5"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, Imm:$ui5))]; ++} ++ ++class LSX_I5_DESC_BASE_Intrinsic { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, ImmOp:$si5); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $si5"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, Imm:$si5))]; ++} ++ ++class LSX_LDX_LA { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins PtrRC:$rj, RORK:$rk); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $rj, $rk"); ++ list Pattern = [(set ROVD:$vd, (OpNode iPTR:$rj, RORK:$rk))]; ++} ++ ++class LSX_SDX_LA { ++ dag OutOperandList = (outs); ++ dag InOperandList = (ins ROVD:$vd, PtrRC:$rj, RORK:$rk); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $rj, $rk"); ++ list Pattern = [(OpNode ROVD:$vd, iPTR:$rj, RORK:$rk)]; ++} ++ ++class LSX_U5_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, uimm5:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui5"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, immZExt5:$ui5))]; ++} ++ ++class LSX_U5_4R_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVD:$vd_in, ROVJ:$vj, uimm5:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui5"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVD:$vd_in, ROVJ:$vj, immZExt5:$ui5))]; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++class LSX_2R_U3_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, uimm3:$ui3); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui3"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, immZExt3:$ui3))]; ++} ++ ++class LSX_2R_U4_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, uimm4:$ui4); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui4"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, immZExt4:$ui4))]; ++} ++ ++class LSX_2R_U5_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, uimm5:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui5"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, immZExt5:$ui5))]; ++} ++ ++class LSX_2R_U6_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, uimm6:$ui6); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui6"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, immZExt6:$ui6))]; ++} ++ ++class LSX_2R_3R_U4_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVD:$vd_in, ROVJ:$vj, uimm4:$ui4); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui4"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVD:$vd_in, ROVJ:$vj, immZExt4:$ui4))]; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++class LSX_2R_3R_U5_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVD:$vd_in, ROVJ:$vj, uimm5:$ui5); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui5"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVD:$vd_in, ROVJ:$vj, immZExt5:$ui5))]; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++class LSX_2R_3R_U6_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVD:$vd_in, ROVJ:$vj, uimm6:$ui6); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui6"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVD:$vd_in, ROVJ:$vj, immZExt6:$ui6))]; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++class LSX_2R_3R_U7_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVD:$vd_in, ROVJ:$vj, uimm7:$ui7); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui7"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVD:$vd_in, ROVJ:$vj, immZExt7:$ui7))]; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++class LSX_2R_3R_U8_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVD:$vd_in, ROVJ:$vj, uimm8:$ui8); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui8"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVD:$vd_in, ROVJ:$vj, immZExt8:$ui8))]; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++class LSX_2R_3R_SELECT { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVD:$vd_in, ROVJ:$vj, vsplat_uimm8:$ui8); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui8"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVD:$vd_in, vsplati8_uimm8:$ui8, ROVJ:$vj))]; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++class LSX_2R_U8_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, uimm8:$ui8); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui8"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, immZExt8:$ui8))]; ++} ++ ++class LSX_I13_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins immOp:$i13); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $i13"); ++ list Pattern = [(set ROVD:$vd, (OpNode (Ty simm13:$i13)))]; ++ string DecoderMethod = "DecodeLSX128Mem13"; ++} ++ ++class LSX_I13_DESC_BASE_10 { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ImmOp:$i10); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $i10"); ++ list Pattern = [(set ROVD:$vd, (OpNode Imm:$i10))]; ++ bit hasSideEffects = 0; ++ string DecoderMethod = "DecodeLSX128Mem10"; ++} ++ ++class LSX_BIT_U8_VREPLVE_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins ROVJ:$vj, SplatImm.OpClass:$ui8); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $vj, $ui8"); ++ list Pattern = [(set ROVD:$vd, (OpNode ROVJ:$vj, SplatImm:$ui8))]; ++} ++ ++ ++class LSXPat pred = [HasLSX]> : ++ Pat, Requires; ++ ++// Instruction encoding. ++ ++ ++def VSADD_B : LSX_3R<0b01110000010001100>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vsadd.b", LSX128BOpnd>; ++ ++def VSADD_H : LSX_3R<0b01110000010001101>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vsadd.h", LSX128HOpnd>; ++ ++def VSADD_W : LSX_3R<0b01110000010001110>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vsadd.w", LSX128WOpnd>; ++ ++def VSADD_D : LSX_3R<0b01110000010001111>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vsadd.d", LSX128DOpnd>; ++ ++ ++def VSSUB_B : LSX_3R<0b01110000010010000>, ++ LSX_3RN_DESC_BASE<"vssub.b", LSX128BOpnd>; ++ ++def VSSUB_H : LSX_3R<0b01110000010010001>, ++ LSX_3RN_DESC_BASE<"vssub.h", LSX128HOpnd>; ++ ++def VSSUB_W : LSX_3R<0b01110000010010010>, ++ LSX_3RN_DESC_BASE<"vssub.w", LSX128WOpnd>; ++ ++def VSSUB_D : LSX_3R<0b01110000010010011>, ++ LSX_3RN_DESC_BASE<"vssub.d", LSX128DOpnd>; ++ ++ ++def VSADD_BU : LSX_3R<0b01110000010010100>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vsadd.bu", LSX128BOpnd>; ++ ++def VSADD_HU : LSX_3R<0b01110000010010101>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vsadd.hu", LSX128HOpnd>; ++ ++def VSADD_WU : LSX_3R<0b01110000010010110>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vsadd.wu", LSX128WOpnd>; ++ ++def VSADD_DU : LSX_3R<0b01110000010010111>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vsadd.du", LSX128DOpnd>; ++ ++ ++def VSSUB_BU : LSX_3R<0b01110000010011000>, ++ LSX_3RN_DESC_BASE<"vssub.bu", LSX128BOpnd>; ++ ++def VSSUB_HU : LSX_3R<0b01110000010011001>, ++ LSX_3RN_DESC_BASE<"vssub.hu", LSX128HOpnd>; ++ ++def VSSUB_WU : LSX_3R<0b01110000010011010>, ++ LSX_3RN_DESC_BASE<"vssub.wu", LSX128WOpnd>; ++ ++def VSSUB_DU : LSX_3R<0b01110000010011011>, ++ LSX_3RN_DESC_BASE<"vssub.du", LSX128DOpnd>; ++ ++ ++def VHADDW_H_B : LSX_3R<0b01110000010101000>, ++ LSX_3RN_DESC_BASE<"vhaddw.h.b", LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VHADDW_W_H : LSX_3R<0b01110000010101001>, ++ LSX_3RN_DESC_BASE<"vhaddw.w.h", LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VHADDW_D_W : LSX_3R<0b01110000010101010>, ++ LSX_3RN_DESC_BASE<"vhaddw.d.w", LSX128DOpnd, LSX128WOpnd, LSX128WOpnd>; ++ ++ ++def VHSUBW_H_B : LSX_3R<0b01110000010101100>, ++ LSX_3RN_DESC_BASE<"vhsubw.h.b", LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VHSUBW_W_H : LSX_3R<0b01110000010101101>, ++ LSX_3RN_DESC_BASE<"vhsubw.w.h", LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VHSUBW_D_W : LSX_3R<0b01110000010101110>, ++ LSX_3RN_DESC_BASE<"vhsubw.d.w", LSX128DOpnd, LSX128WOpnd, LSX128WOpnd>; ++ ++ ++def VHADDW_HU_BU : LSX_3R<0b01110000010110000>, ++ LSX_3RN_DESC_BASE<"vhaddw.hu.bu", LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VHADDW_WU_HU : LSX_3R<0b01110000010110001>, ++ LSX_3RN_DESC_BASE<"vhaddw.wu.hu", LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VHADDW_DU_WU : LSX_3R<0b01110000010110010>, ++ LSX_3RN_DESC_BASE<"vhaddw.du.wu", LSX128DOpnd, LSX128WOpnd, LSX128WOpnd>; ++ ++ ++def VHSUBW_HU_BU : LSX_3R<0b01110000010110100>, ++ LSX_3RN_DESC_BASE<"vhsubw.hu.bu", LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VHSUBW_WU_HU : LSX_3R<0b01110000010110101>, ++ LSX_3RN_DESC_BASE<"vhsubw.wu.hu", LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VHSUBW_DU_WU : LSX_3R<0b01110000010110110>, ++ LSX_3RN_DESC_BASE<"vhsubw.du.wu", LSX128DOpnd, LSX128WOpnd, LSX128WOpnd>; ++ ++ ++def VADDA_B : LSX_3R<0b01110000010111000>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vadda.b", LSX128BOpnd>; ++ ++def VADDA_H : LSX_3R<0b01110000010111001>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vadda.h", LSX128HOpnd>; ++ ++def VADDA_W : LSX_3R<0b01110000010111010>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vadda.w", LSX128WOpnd>; ++ ++def VADDA_D : LSX_3R<0b01110000010111011>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vadda.d", LSX128DOpnd>; ++ ++ ++def VABSD_B : LSX_3R<0b01110000011000000>, ++ LSX_3RN_DESC_BASE<"vabsd.b", LSX128BOpnd>; ++ ++def VABSD_H : LSX_3R<0b01110000011000001>, ++ LSX_3RN_DESC_BASE<"vabsd.h", LSX128HOpnd>; ++ ++def VABSD_W : LSX_3R<0b01110000011000010>, ++ LSX_3RN_DESC_BASE<"vabsd.w", LSX128WOpnd>; ++ ++def VABSD_D : LSX_3R<0b01110000011000011>, ++ LSX_3RN_DESC_BASE<"vabsd.d", LSX128DOpnd>; ++ ++ ++def VABSD_BU : LSX_3R<0b01110000011000100>, ++ LSX_3RN_DESC_BASE<"vabsd.bu", LSX128BOpnd>; ++ ++def VABSD_HU : LSX_3R<0b01110000011000101>, ++ LSX_3RN_DESC_BASE<"vabsd.hu", LSX128HOpnd>; ++ ++def VABSD_WU : LSX_3R<0b01110000011000110>, ++ LSX_3RN_DESC_BASE<"vabsd.wu", LSX128WOpnd>; ++ ++def VABSD_DU : LSX_3R<0b01110000011000111>, ++ LSX_3RN_DESC_BASE<"vabsd.du", LSX128DOpnd>; ++ ++ ++def VAVG_B : LSX_3R<0b01110000011001000>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vavg.b", LSX128BOpnd>; ++ ++def VAVG_H : LSX_3R<0b01110000011001001>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vavg.h", LSX128HOpnd>; ++ ++def VAVG_W : LSX_3R<0b01110000011001010>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vavg.w", LSX128WOpnd>; ++ ++def VAVG_D : LSX_3R<0b01110000011001011>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vavg.d", LSX128DOpnd>; ++ ++ ++def VAVG_BU : LSX_3R<0b01110000011001100>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vavg.bu", LSX128BOpnd>; ++ ++def VAVG_HU : LSX_3R<0b01110000011001101>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vavg.hu", LSX128HOpnd>; ++ ++def VAVG_WU : LSX_3R<0b01110000011001110>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vavg.wu", LSX128WOpnd>; ++ ++def VAVG_DU : LSX_3R<0b01110000011001111>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vavg.du", LSX128DOpnd>; ++ ++ ++def VAVGR_B : LSX_3R<0b01110000011010000>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vavgr.b", LSX128BOpnd>; ++ ++def VAVGR_H : LSX_3R<0b01110000011010001>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vavgr.h", LSX128HOpnd>; ++ ++def VAVGR_W : LSX_3R<0b01110000011010010>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vavgr.w", LSX128WOpnd>; ++ ++def VAVGR_D : LSX_3R<0b01110000011010011>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vavgr.d", LSX128DOpnd>; ++ ++ ++def VAVGR_BU : LSX_3R<0b01110000011010100>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vavgr.bu", LSX128BOpnd>; ++ ++def VAVGR_HU : LSX_3R<0b01110000011010101>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vavgr.hu", LSX128HOpnd>; ++ ++def VAVGR_WU : LSX_3R<0b01110000011010110>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vavgr.wu", LSX128WOpnd>; ++ ++def VAVGR_DU : LSX_3R<0b01110000011010111>, IsCommutable, ++ LSX_3RN_DESC_BASE<"vavgr.du", LSX128DOpnd>; ++ ++ ++def VMAX_B : LSX_3R<0b01110000011100000>, ++ LSX_3R_DESC_BASE<"vmax.b", smax, LSX128BOpnd>; ++ ++def VMAX_H : LSX_3R<0b01110000011100001>, ++ LSX_3R_DESC_BASE<"vmax.h", smax, LSX128HOpnd>; ++ ++def VMAX_W : LSX_3R<0b01110000011100010>, ++ LSX_3R_DESC_BASE<"vmax.w", smax, LSX128WOpnd>; ++ ++def VMAX_D : LSX_3R<0b01110000011100011>, ++ LSX_3R_DESC_BASE<"vmax.d", smax, LSX128DOpnd>; ++ ++ ++def VMIN_B : LSX_3R<0b01110000011100100>, ++ LSX_3R_DESC_BASE<"vmin.b", smin, LSX128BOpnd>; ++ ++def VMIN_H : LSX_3R<0b01110000011100101>, ++ LSX_3R_DESC_BASE<"vmin.h", smin, LSX128HOpnd>; ++ ++def VMIN_W : LSX_3R<0b01110000011100110>, ++ LSX_3R_DESC_BASE<"vmin.w", smin, LSX128WOpnd>; ++ ++def VMIN_D : LSX_3R<0b01110000011100111>, ++ LSX_3R_DESC_BASE<"vmin.d", smin, LSX128DOpnd>; ++ ++ ++def VMAX_BU : LSX_3R<0b01110000011101000>, ++ LSX_3R_DESC_BASE<"vmax.bu", umax, LSX128BOpnd>; ++ ++def VMAX_HU : LSX_3R<0b01110000011101001>, ++ LSX_3R_DESC_BASE<"vmax.hu", umax, LSX128HOpnd>; ++ ++def VMAX_WU : LSX_3R<0b01110000011101010>, ++ LSX_3R_DESC_BASE<"vmax.wu", umax, LSX128WOpnd>; ++ ++def VMAX_DU : LSX_3R<0b01110000011101011>, ++ LSX_3R_DESC_BASE<"vmax.du", umax, LSX128DOpnd>; ++ ++ ++def VMIN_BU : LSX_3R<0b01110000011101100>, ++ LSX_3R_DESC_BASE<"vmin.bu", umin, LSX128BOpnd>; ++ ++def VMIN_HU : LSX_3R<0b01110000011101101>, ++ LSX_3R_DESC_BASE<"vmin.hu", umin, LSX128HOpnd>; ++ ++def VMIN_WU : LSX_3R<0b01110000011101110>, ++ LSX_3R_DESC_BASE<"vmin.wu", umin, LSX128WOpnd>; ++ ++def VMIN_DU : LSX_3R<0b01110000011101111>, ++ LSX_3R_DESC_BASE<"vmin.du", umin, LSX128DOpnd>; ++ ++ ++def VMUL_B : LSX_3R<0b01110000100001000>, ++ LSX_3R_DESC_BASE<"vmul.b", mul, LSX128BOpnd>; ++ ++def VMUL_H : LSX_3R<0b01110000100001001>, ++ LSX_3R_DESC_BASE<"vmul.h", mul, LSX128HOpnd>; ++ ++def VMUL_W : LSX_3R<0b01110000100001010>, ++ LSX_3R_DESC_BASE<"vmul.w", mul, LSX128WOpnd>; ++ ++def VMUL_D : LSX_3R<0b01110000100001011>, ++ LSX_3R_DESC_BASE<"vmul.d", mul, LSX128DOpnd>; ++ ++ ++def VMADD_B : LSX_3R<0b01110000101010000>, ++ LSX_3R_4R_DESC_BASE<"vmadd.b", muladd, LSX128BOpnd>; ++ ++def VMADD_H : LSX_3R<0b01110000101010001>, ++ LSX_3R_4R_DESC_BASE<"vmadd.h", muladd, LSX128HOpnd>; ++ ++def VMADD_W : LSX_3R<0b01110000101010010>, ++ LSX_3R_4R_DESC_BASE<"vmadd.w", muladd, LSX128WOpnd>; ++ ++def VMADD_D : LSX_3R<0b01110000101010011>, ++ LSX_3R_4R_DESC_BASE<"vmadd.d", muladd, LSX128DOpnd>; ++ ++ ++def VMSUB_B : LSX_3R<0b01110000101010100>, ++ LSX_3R_4R_DESC_BASE<"vmsub.b", mulsub, LSX128BOpnd>; ++ ++def VMSUB_H : LSX_3R<0b01110000101010101>, ++ LSX_3R_4R_DESC_BASE<"vmsub.h", mulsub, LSX128HOpnd>; ++ ++def VMSUB_W : LSX_3R<0b01110000101010110>, ++ LSX_3R_4R_DESC_BASE<"vmsub.w", mulsub, LSX128WOpnd>; ++ ++def VMSUB_D : LSX_3R<0b01110000101010111>, ++ LSX_3R_4R_DESC_BASE<"vmsub.d", mulsub, LSX128DOpnd>; ++ ++ ++def VDIV_B : LSX_3R<0b01110000111000000>, ++ LSX_3R_DESC_BASE<"vdiv.b", sdiv, LSX128BOpnd>; ++ ++def VDIV_H : LSX_3R<0b01110000111000001>, ++ LSX_3R_DESC_BASE<"vdiv.h", sdiv, LSX128HOpnd>; ++ ++def VDIV_W : LSX_3R<0b01110000111000010>, ++ LSX_3R_DESC_BASE<"vdiv.w", sdiv, LSX128WOpnd>; ++ ++def VDIV_D : LSX_3R<0b01110000111000011>, ++ LSX_3R_DESC_BASE<"vdiv.d", sdiv, LSX128DOpnd>; ++ ++ ++def VMOD_B : LSX_3R<0b01110000111000100>, ++ LSX_3R_DESC_BASE<"vmod.b", srem, LSX128BOpnd>; ++ ++def VMOD_H : LSX_3R<0b01110000111000101>, ++ LSX_3R_DESC_BASE<"vmod.h", srem, LSX128HOpnd>; ++ ++def VMOD_W : LSX_3R<0b01110000111000110>, ++ LSX_3R_DESC_BASE<"vmod.w", srem, LSX128WOpnd>; ++ ++def VMOD_D : LSX_3R<0b01110000111000111>, ++ LSX_3R_DESC_BASE<"vmod.d", srem, LSX128DOpnd>; ++ ++ ++def VDIV_BU : LSX_3R<0b01110000111001000>, ++ LSX_3R_DESC_BASE<"vdiv.bu", udiv, LSX128BOpnd>; ++ ++def VDIV_HU : LSX_3R<0b01110000111001001>, ++ LSX_3R_DESC_BASE<"vdiv.hu", udiv, LSX128HOpnd>; ++ ++def VDIV_WU : LSX_3R<0b01110000111001010>, ++ LSX_3R_DESC_BASE<"vdiv.wu", udiv, LSX128WOpnd>; ++ ++def VDIV_DU : LSX_3R<0b01110000111001011>, ++ LSX_3R_DESC_BASE<"vdiv.du", udiv, LSX128DOpnd>; ++ ++ ++def VMOD_BU : LSX_3R<0b01110000111001100>, ++ LSX_3R_DESC_BASE<"vmod.bu", urem, LSX128BOpnd>; ++ ++def VMOD_HU : LSX_3R<0b01110000111001101>, ++ LSX_3R_DESC_BASE<"vmod.hu", urem, LSX128HOpnd>; ++ ++def VMOD_WU : LSX_3R<0b01110000111001110>, ++ LSX_3R_DESC_BASE<"vmod.wu", urem, LSX128WOpnd>; ++ ++def VMOD_DU : LSX_3R<0b01110000111001111>, ++ LSX_3R_DESC_BASE<"vmod.du", urem, LSX128DOpnd>; ++ ++ ++def VSLL_B : LSX_3R<0b01110000111010000>, ++ LSX_3R_DESC_BASE<"vsll.b", shl, LSX128BOpnd>; ++ ++def VSLL_H : LSX_3R<0b01110000111010001>, ++ LSX_3R_DESC_BASE<"vsll.h", shl, LSX128HOpnd>; ++ ++def VSLL_W : LSX_3R<0b01110000111010010>, ++ LSX_3R_DESC_BASE<"vsll.w", shl, LSX128WOpnd>; ++ ++def VSLL_D : LSX_3R<0b01110000111010011>, ++ LSX_3R_DESC_BASE<"vsll.d", shl, LSX128DOpnd>; ++ ++ ++def VSRL_B : LSX_3R<0b01110000111010100>, ++ LSX_3R_DESC_BASE<"vsrl.b", srl, LSX128BOpnd>; ++ ++def VSRL_H : LSX_3R<0b01110000111010101>, ++ LSX_3R_DESC_BASE<"vsrl.h", srl, LSX128HOpnd>; ++ ++def VSRL_W : LSX_3R<0b01110000111010110>, ++ LSX_3R_DESC_BASE<"vsrl.w", srl, LSX128WOpnd>; ++ ++def VSRL_D : LSX_3R<0b01110000111010111>, ++ LSX_3R_DESC_BASE<"vsrl.d", srl, LSX128DOpnd>; ++ ++ ++def VSRA_B : LSX_3R<0b01110000111011000>, ++ LSX_3R_DESC_BASE<"vsra.b", sra, LSX128BOpnd>; ++ ++def VSRA_H : LSX_3R<0b01110000111011001>, ++ LSX_3R_DESC_BASE<"vsra.h", sra, LSX128HOpnd>; ++ ++def VSRA_W : LSX_3R<0b01110000111011010>, ++ LSX_3R_DESC_BASE<"vsra.w", sra, LSX128WOpnd>; ++ ++def VSRA_D : LSX_3R<0b01110000111011011>, ++ LSX_3R_DESC_BASE<"vsra.d", sra, LSX128DOpnd>; ++ ++ ++def VSRLR_B : LSX_3R<0b01110000111100000>, ++ LSX_3RN_DESC_BASE<"vsrlr.b", LSX128BOpnd>; ++ ++def VSRLR_H : LSX_3R<0b01110000111100001>, ++ LSX_3RN_DESC_BASE<"vsrlr.h", LSX128HOpnd>; ++ ++def VSRLR_W : LSX_3R<0b01110000111100010>, ++ LSX_3RN_DESC_BASE<"vsrlr.w", LSX128WOpnd>; ++ ++def VSRLR_D : LSX_3R<0b01110000111100011>, ++ LSX_3RN_DESC_BASE<"vsrlr.d", LSX128DOpnd>; ++ ++ ++def VSRAR_B : LSX_3R<0b01110000111100100>, ++ LSX_3RN_DESC_BASE<"vsrar.b", LSX128BOpnd>; ++ ++def VSRAR_H : LSX_3R<0b01110000111100101>, ++ LSX_3RN_DESC_BASE<"vsrar.h", LSX128HOpnd>; ++ ++def VSRAR_W : LSX_3R<0b01110000111100110>, ++ LSX_3RN_DESC_BASE<"vsrar.w", LSX128WOpnd>; ++ ++def VSRAR_D : LSX_3R<0b01110000111100111>, ++ LSX_3RN_DESC_BASE<"vsrar.d", LSX128DOpnd>; ++ ++ ++def VBITCLR_B : LSX_3R<0b01110001000011000>, ++ LSX_3R_DESC_BASE<"vbitclr.b", vbitclr_b, LSX128BOpnd>; ++ ++def VBITCLR_H : LSX_3R<0b01110001000011001>, ++ LSX_3R_DESC_BASE<"vbitclr.h", vbitclr_h, LSX128HOpnd>; ++ ++def VBITCLR_W : LSX_3R<0b01110001000011010>, ++ LSX_3R_DESC_BASE<"vbitclr.w", vbitclr_w, LSX128WOpnd>; ++ ++def VBITCLR_D : LSX_3R<0b01110001000011011>, ++ LSX_3R_DESC_BASE<"vbitclr.d", vbitclr_d, LSX128DOpnd>; ++ ++ ++def VBITSET_B : LSX_3R<0b01110001000011100>, ++ LSX_3RN_DESC_BASE<"vbitset.b", LSX128BOpnd>; ++ ++def VBITSET_H : LSX_3R<0b01110001000011101>, ++ LSX_3RN_DESC_BASE<"vbitset.h", LSX128HOpnd>; ++ ++def VBITSET_W : LSX_3R<0b01110001000011110>, ++ LSX_3RN_DESC_BASE<"vbitset.w", LSX128WOpnd>; ++ ++def VBITSET_D : LSX_3R<0b01110001000011111>, ++ LSX_3RN_DESC_BASE<"vbitset.d", LSX128DOpnd>; ++ ++ ++def VBITREV_B : LSX_3R<0b01110001000100000>, ++ LSX_3RN_DESC_BASE<"vbitrev.b", LSX128BOpnd>; ++ ++def VBITREV_H : LSX_3R<0b01110001000100001>, ++ LSX_3RN_DESC_BASE<"vbitrev.h", LSX128HOpnd>; ++ ++def VBITREV_W : LSX_3R<0b01110001000100010>, ++ LSX_3RN_DESC_BASE<"vbitrev.w", LSX128WOpnd>; ++ ++def VBITREV_D : LSX_3R<0b01110001000100011>, ++ LSX_3RN_DESC_BASE<"vbitrev.d", LSX128DOpnd>; ++ ++ ++def VPACKEV_B : LSX_3R<0b01110001000101100>, ++ LSX_3R_DESC_BASE<"vpackev.b", LoongArchVPACKEV, LSX128BOpnd>; ++ ++def VPACKEV_H : LSX_3R<0b01110001000101101>, ++ LSX_3R_DESC_BASE<"vpackev.h", LoongArchVPACKEV, LSX128HOpnd>; ++ ++def VPACKEV_W : LSX_3R<0b01110001000101110>, ++ LSX_3R_DESC_BASE<"vpackev.w", LoongArchVPACKEV, LSX128WOpnd>; ++ ++def VPACKEV_D : LSX_3R<0b01110001000101111>, ++ LSX_3R_DESC_BASE<"vpackev.d", LoongArchVPACKEV, LSX128DOpnd>; ++ ++ ++def VPACKOD_B : LSX_3R<0b01110001000110000>, ++ LSX_3R_DESC_BASE<"vpackod.b", LoongArchVPACKOD, LSX128BOpnd>; ++ ++def VPACKOD_H : LSX_3R<0b01110001000110001>, ++ LSX_3R_DESC_BASE<"vpackod.h", LoongArchVPACKOD, LSX128HOpnd>; ++ ++def VPACKOD_W : LSX_3R<0b01110001000110010>, ++ LSX_3R_DESC_BASE<"vpackod.w", LoongArchVPACKOD, LSX128WOpnd>; ++ ++def VPACKOD_D : LSX_3R<0b01110001000110011>, ++ LSX_3R_DESC_BASE<"vpackod.d", LoongArchVPACKOD, LSX128DOpnd>; ++ ++ ++def VILVL_B : LSX_3R<0b01110001000110100>, ++ LSX_3R_DESC_BASE<"vilvl.b", LoongArchVILVL, LSX128BOpnd>; ++ ++def VILVL_H : LSX_3R<0b01110001000110101>, ++ LSX_3R_DESC_BASE<"vilvl.h", LoongArchVILVL, LSX128HOpnd>; ++ ++def VILVL_W : LSX_3R<0b01110001000110110>, ++ LSX_3R_DESC_BASE<"vilvl.w", LoongArchVILVL, LSX128WOpnd>; ++ ++def VILVL_D : LSX_3R<0b01110001000110111>, ++ LSX_3R_DESC_BASE<"vilvl.d", LoongArchVILVL, LSX128DOpnd>; ++ ++ ++def VILVH_B : LSX_3R<0b01110001000111000>, ++ LSX_3R_DESC_BASE<"vilvh.b", LoongArchVILVH, LSX128BOpnd>; ++ ++def VILVH_H : LSX_3R<0b01110001000111001>, ++ LSX_3R_DESC_BASE<"vilvh.h", LoongArchVILVH, LSX128HOpnd>; ++ ++def VILVH_W : LSX_3R<0b01110001000111010>, ++ LSX_3R_DESC_BASE<"vilvh.w", LoongArchVILVH, LSX128WOpnd>; ++ ++def VILVH_D : LSX_3R<0b01110001000111011>, ++ LSX_3R_DESC_BASE<"vilvh.d", LoongArchVILVH, LSX128DOpnd>; ++ ++ ++def VPICKEV_B : LSX_3R<0b01110001000111100>, ++ LSX_3R_DESC_BASE<"vpickev.b", LoongArchVPICKEV, LSX128BOpnd>; ++ ++def VPICKEV_H : LSX_3R<0b01110001000111101>, ++ LSX_3R_DESC_BASE<"vpickev.h", LoongArchVPICKEV, LSX128HOpnd>; ++ ++def VPICKEV_W : LSX_3R<0b01110001000111110>, ++ LSX_3R_DESC_BASE<"vpickev.w", LoongArchVPICKEV, LSX128WOpnd>; ++ ++def VPICKEV_D : LSX_3R<0b01110001000111111>, ++ LSX_3R_DESC_BASE<"vpickev.d", LoongArchVPICKEV, LSX128DOpnd>; ++ ++ ++def VPICKOD_B : LSX_3R<0b01110001001000000>, ++ LSX_3R_DESC_BASE<"vpickod.b", LoongArchVPICKOD, LSX128BOpnd>; ++ ++def VPICKOD_H : LSX_3R<0b01110001001000001>, ++ LSX_3R_DESC_BASE<"vpickod.h", LoongArchVPICKOD, LSX128HOpnd>; ++ ++def VPICKOD_W : LSX_3R<0b01110001001000010>, ++ LSX_3R_DESC_BASE<"vpickod.w", LoongArchVPICKOD, LSX128WOpnd>; ++ ++def VPICKOD_D : LSX_3R<0b01110001001000011>, ++ LSX_3R_DESC_BASE<"vpickod.d", LoongArchVPICKOD, LSX128DOpnd>; ++ ++ ++def VREPLVE_B : LSX_3R_1GP<0b01110001001000100>, ++ LSX_3R_VREPLVE_DESC_BASE<"vreplve.b", vsplati8_elt, LSX128BOpnd>; ++ ++def VREPLVE_H : LSX_3R_1GP<0b01110001001000101>, ++ LSX_3R_VREPLVE_DESC_BASE<"vreplve.h", vsplati16_elt, LSX128HOpnd>; ++ ++def VREPLVE_W : LSX_3R_1GP<0b01110001001000110>, ++ LSX_3R_VREPLVE_DESC_BASE<"vreplve.w", vsplati32_elt, LSX128WOpnd>; ++ ++def VREPLVE_D : LSX_3R_1GP<0b01110001001000111>, ++ LSX_3R_VREPLVE_DESC_BASE<"vreplve.d", vsplati64_elt, LSX128DOpnd>; ++ ++ ++def VAND_V : LSX_3R<0b01110001001001100>, ++ LSX_VEC_DESC_BASE<"vand.v", and, LSX128BOpnd>; ++class AND_V_H_PSEUDO_DESC : LSX_VEC_PSEUDO_BASE; ++class AND_V_W_PSEUDO_DESC : LSX_VEC_PSEUDO_BASE; ++class AND_V_D_PSEUDO_DESC : LSX_VEC_PSEUDO_BASE; ++ ++def AND_V_H_PSEUDO : AND_V_H_PSEUDO_DESC, ++ PseudoInstExpansion<(VAND_V LSX128BOpnd:$vd, ++ LSX128BOpnd:$vj, ++ LSX128BOpnd:$vk)>; ++def AND_V_W_PSEUDO : AND_V_W_PSEUDO_DESC, ++ PseudoInstExpansion<(VAND_V LSX128BOpnd:$vd, ++ LSX128BOpnd:$vj, ++ LSX128BOpnd:$vk)>; ++def AND_V_D_PSEUDO : AND_V_D_PSEUDO_DESC, ++ PseudoInstExpansion<(VAND_V LSX128BOpnd:$vd, ++ LSX128BOpnd:$vj, ++ LSX128BOpnd:$vk)>; ++ ++ ++def VOR_V : LSX_3R<0b01110001001001101>, ++ LSX_VEC_DESC_BASE<"vor.v", or, LSX128BOpnd>; ++class OR_V_H_PSEUDO_DESC : LSX_VEC_PSEUDO_BASE; ++class OR_V_W_PSEUDO_DESC : LSX_VEC_PSEUDO_BASE; ++class OR_V_D_PSEUDO_DESC : LSX_VEC_PSEUDO_BASE; ++ ++def OR_V_H_PSEUDO : OR_V_H_PSEUDO_DESC, ++ PseudoInstExpansion<(VOR_V LSX128BOpnd:$vd, ++ LSX128BOpnd:$vj, ++ LSX128BOpnd:$vk)>; ++def OR_V_W_PSEUDO : OR_V_W_PSEUDO_DESC, ++ PseudoInstExpansion<(VOR_V LSX128BOpnd:$vd, ++ LSX128BOpnd:$vj, ++ LSX128BOpnd:$vk)>; ++def OR_V_D_PSEUDO : OR_V_D_PSEUDO_DESC, ++ PseudoInstExpansion<(VOR_V LSX128BOpnd:$vd, ++ LSX128BOpnd:$vj, ++ LSX128BOpnd:$vk)>; ++ ++ ++def VXOR_V : LSX_3R<0b01110001001001110>, ++ LSX_VEC_DESC_BASE<"vxor.v", xor, LSX128BOpnd>; ++class XOR_V_H_PSEUDO_DESC : LSX_VEC_PSEUDO_BASE; ++class XOR_V_W_PSEUDO_DESC : LSX_VEC_PSEUDO_BASE; ++class XOR_V_D_PSEUDO_DESC : LSX_VEC_PSEUDO_BASE; ++ ++def XOR_V_H_PSEUDO : XOR_V_H_PSEUDO_DESC, ++ PseudoInstExpansion<(VXOR_V LSX128BOpnd:$vd, ++ LSX128BOpnd:$vj, ++ LSX128BOpnd:$vk)>; ++def XOR_V_W_PSEUDO : XOR_V_W_PSEUDO_DESC, ++ PseudoInstExpansion<(VXOR_V LSX128BOpnd:$vd, ++ LSX128BOpnd:$vj, ++ LSX128BOpnd:$vk)>; ++def XOR_V_D_PSEUDO : XOR_V_D_PSEUDO_DESC, ++ PseudoInstExpansion<(VXOR_V LSX128BOpnd:$vd, ++ LSX128BOpnd:$vj, ++ LSX128BOpnd:$vk)>; ++ ++ ++def VNOR_V : LSX_3R<0b01110001001001111>, ++ LSX_VEC_DESC_BASE<"vnor.v", LoongArchVNOR, LSX128BOpnd>; ++class NOR_V_H_PSEUDO_DESC : LSX_VEC_PSEUDO_BASE; ++class NOR_V_W_PSEUDO_DESC : LSX_VEC_PSEUDO_BASE; ++class NOR_V_D_PSEUDO_DESC : LSX_VEC_PSEUDO_BASE; ++ ++def NOR_V_H_PSEUDO : NOR_V_H_PSEUDO_DESC, ++ PseudoInstExpansion<(VNOR_V LSX128BOpnd:$vd, ++ LSX128BOpnd:$vj, ++ LSX128BOpnd:$vk)>; ++def NOR_V_W_PSEUDO : NOR_V_W_PSEUDO_DESC, ++ PseudoInstExpansion<(VNOR_V LSX128BOpnd:$vd, ++ LSX128BOpnd:$vj, ++ LSX128BOpnd:$vk)>; ++def NOR_V_D_PSEUDO : NOR_V_D_PSEUDO_DESC, ++ PseudoInstExpansion<(VNOR_V LSX128BOpnd:$vd, ++ LSX128BOpnd:$vj, ++ LSX128BOpnd:$vk)>; ++ ++ ++def VFADD_S : LSX_3R<0b01110001001100001>, IsCommutable, ++ LSX_3RF_DESC_BASE<"vfadd.s", fadd, LSX128WOpnd>; ++ ++def VFADD_D : LSX_3R<0b01110001001100010>, IsCommutable, ++ LSX_3RF_DESC_BASE<"vfadd.d", fadd, LSX128DOpnd>; ++ ++ ++def VFSUB_S : LSX_3R<0b01110001001100101>, ++ LSX_3RF_DESC_BASE<"vfsub.s", fsub, LSX128WOpnd>; ++ ++def VFSUB_D : LSX_3R<0b01110001001100110>, ++ LSX_3RF_DESC_BASE<"vfsub.d", fsub, LSX128DOpnd>; ++ ++ ++def VFMUL_S : LSX_3R<0b01110001001110001>, ++ LSX_3RF_DESC_BASE<"vfmul.s", fmul, LSX128WOpnd>; ++ ++def VFMUL_D : LSX_3R<0b01110001001110010>, ++ LSX_3RF_DESC_BASE<"vfmul.d", fmul, LSX128DOpnd>; ++ ++ ++def VFDIV_S : LSX_3R<0b01110001001110101>, ++ LSX_3RF_DESC_BASE<"vfdiv.s", fdiv, LSX128WOpnd>; ++ ++def VFDIV_D : LSX_3R<0b01110001001110110>, ++ LSX_3RF_DESC_BASE<"vfdiv.d", fdiv, LSX128DOpnd>; ++ ++ ++def VFMAX_S : LSX_3R<0b01110001001111001>, ++ LSX_3RFN_DESC_BASE<"vfmax.s", LSX128WOpnd>; ++ ++def VFMAX_D : LSX_3R<0b01110001001111010>, ++ LSX_3RFN_DESC_BASE<"vfmax.d", LSX128DOpnd>; ++ ++ ++def VFMIN_S : LSX_3R<0b01110001001111101>, ++ LSX_3RFN_DESC_BASE<"vfmin.s", LSX128WOpnd>; ++ ++def VFMIN_D : LSX_3R<0b01110001001111110>, ++ LSX_3RFN_DESC_BASE<"vfmin.d", LSX128DOpnd>; ++ ++ ++def VFMAXA_S : LSX_3R<0b01110001010000001>, ++ LSX_3RFN_DESC_BASE<"vfmaxa.s", LSX128WOpnd>; ++ ++def VFMAXA_D : LSX_3R<0b01110001010000010>, ++ LSX_3RFN_DESC_BASE<"vfmaxa.d", LSX128DOpnd>; ++ ++ ++def VFMINA_S : LSX_3R<0b01110001010000101>, ++ LSX_3RFN_DESC_BASE<"vfmina.s", LSX128WOpnd>; ++ ++def VFMINA_D : LSX_3R<0b01110001010000110>, ++ LSX_3RFN_DESC_BASE<"vfmina.d", LSX128DOpnd>; ++ ++ ++def VSHUF_H : LSX_3R<0b01110001011110101>, ++ LSX_3R_VSHF_DESC_BASE<"vshuf.h", LSX128HOpnd>; ++ ++def VSHUF_W : LSX_3R<0b01110001011110110>, ++ LSX_3R_VSHF_DESC_BASE<"vshuf.w", LSX128WOpnd>; ++ ++def VSHUF_D : LSX_3R<0b01110001011110111>, ++ LSX_3R_VSHF_DESC_BASE<"vshuf.d", LSX128DOpnd>; ++ ++ ++def VSEQI_B : LSX_I5<0b01110010100000000>, ++ LSX_I5_DESC_BASE_Intrinsic<"vseqi.b", int_loongarch_lsx_vseqi_b, simm5_32, immSExt5, LSX128BOpnd>; ++ ++def VSEQI_H : LSX_I5<0b01110010100000001>, ++ LSX_I5_DESC_BASE_Intrinsic<"vseqi.h", int_loongarch_lsx_vseqi_h, simm5_32, immSExt5, LSX128HOpnd>; ++ ++def VSEQI_W : LSX_I5<0b01110010100000010>, ++ LSX_I5_DESC_BASE_Intrinsic<"vseqi.w", int_loongarch_lsx_vseqi_w, simm5_32, immSExt5, LSX128WOpnd>; ++ ++def VSEQI_D : LSX_I5<0b01110010100000011>, ++ LSX_I5_DESC_BASE_Intrinsic<"vseqi.d", int_loongarch_lsx_vseqi_d, simm5_32, immSExt5, LSX128DOpnd>; ++ ++ ++def VSLEI_B : LSX_I5<0b01110010100000100>, ++ LSX_I5_DESC_BASE_Intrinsic<"vslei.b", int_loongarch_lsx_vslei_b, simm5_32, immSExt5, LSX128BOpnd>; ++ ++def VSLEI_H : LSX_I5<0b01110010100000101>, ++ LSX_I5_DESC_BASE_Intrinsic<"vslei.h", int_loongarch_lsx_vslei_h, simm5_32, immSExt5, LSX128HOpnd>; ++ ++def VSLEI_W : LSX_I5<0b01110010100000110>, ++ LSX_I5_DESC_BASE_Intrinsic<"vslei.w", int_loongarch_lsx_vslei_w, simm5_32, immSExt5, LSX128WOpnd>; ++ ++def VSLEI_D : LSX_I5<0b01110010100000111>, ++ LSX_I5_DESC_BASE_Intrinsic<"vslei.d", int_loongarch_lsx_vslei_d, simm5_32, immSExt5, LSX128DOpnd>; ++ ++ ++def VSLEI_BU : LSX_I5_U<0b01110010100001000>, ++ LSX_I5_U_DESC_BASE_Intrinsic<"vslei.bu", int_loongarch_lsx_vslei_bu, uimm5, immZExt5, LSX128BOpnd>; ++ ++def VSLEI_HU : LSX_I5_U<0b01110010100001001>, ++ LSX_I5_U_DESC_BASE_Intrinsic<"vslei.hu", int_loongarch_lsx_vslei_hu, uimm5, immZExt5, LSX128HOpnd>; ++ ++def VSLEI_WU : LSX_I5_U<0b01110010100001010>, ++ LSX_I5_U_DESC_BASE_Intrinsic<"vslei.wu", int_loongarch_lsx_vslei_wu, uimm5, immZExt5, LSX128WOpnd>; ++ ++def VSLEI_DU : LSX_I5_U<0b01110010100001011>, ++ LSX_I5_U_DESC_BASE_Intrinsic<"vslei.du", int_loongarch_lsx_vslei_du, uimm5, immZExt5, LSX128DOpnd>; ++ ++ ++def VSLTI_B : LSX_I5<0b01110010100001100>, ++ LSX_I5_DESC_BASE_Intrinsic<"vslti.b", int_loongarch_lsx_vslti_b, simm5_32, immSExt5, LSX128BOpnd>; ++ ++def VSLTI_H : LSX_I5<0b01110010100001101>, ++ LSX_I5_DESC_BASE_Intrinsic<"vslti.h", int_loongarch_lsx_vslti_h, simm5_32, immSExt5, LSX128HOpnd>; ++ ++def VSLTI_W : LSX_I5<0b01110010100001110>, ++ LSX_I5_DESC_BASE_Intrinsic<"vslti.w", int_loongarch_lsx_vslti_w, simm5_32, immSExt5, LSX128WOpnd>; ++ ++def VSLTI_D : LSX_I5<0b01110010100001111>, ++ LSX_I5_DESC_BASE_Intrinsic<"vslti.d", int_loongarch_lsx_vslti_d, simm5_32, immSExt5, LSX128DOpnd>; ++ ++ ++def VSLTI_BU : LSX_I5_U<0b01110010100010000>, ++ LSX_I5_U_DESC_BASE_Intrinsic<"vslti.bu", int_loongarch_lsx_vslti_bu, uimm5, immZExt5, LSX128BOpnd>; ++ ++def VSLTI_HU : LSX_I5_U<0b01110010100010001>, ++ LSX_I5_U_DESC_BASE_Intrinsic<"vslti.hu", int_loongarch_lsx_vslti_hu, uimm5, immZExt5, LSX128HOpnd>; ++ ++def VSLTI_WU : LSX_I5_U<0b01110010100010010>, ++ LSX_I5_U_DESC_BASE_Intrinsic<"vslti.wu", int_loongarch_lsx_vslti_wu, uimm5, immZExt5, LSX128WOpnd>; ++ ++def VSLTI_DU : LSX_I5_U<0b01110010100010011>, ++ LSX_I5_U_DESC_BASE_Intrinsic<"vslti.du", int_loongarch_lsx_vslti_du, uimm5, immZExt5, LSX128DOpnd>; ++ ++ ++def VADDI_BU : LSX_I5_U<0b01110010100010100>, ++ LSX_I5_U_DESC_BASE<"vaddi.bu", add, vsplati8_uimm5, LSX128BOpnd>; ++ ++def VADDI_HU : LSX_I5_U<0b01110010100010101>, ++ LSX_I5_U_DESC_BASE<"vaddi.hu", add, vsplati16_uimm5, LSX128HOpnd>; ++ ++def VADDI_WU : LSX_I5_U<0b01110010100010110>, ++ LSX_I5_U_DESC_BASE<"vaddi.wu", add, vsplati32_uimm5, LSX128WOpnd>; ++ ++def VADDI_DU : LSX_I5_U<0b01110010100010111>, ++ LSX_I5_U_DESC_BASE<"vaddi.du", add, vsplati64_uimm5, LSX128DOpnd>; ++ ++ ++def VSUBI_BU : LSX_I5_U<0b01110010100011000>, ++ LSX_I5_U_DESC_BASE<"vsubi.bu", sub, vsplati8_uimm5, LSX128BOpnd>; ++ ++def VSUBI_HU : LSX_I5_U<0b01110010100011001>, ++ LSX_I5_U_DESC_BASE<"vsubi.hu", sub, vsplati16_uimm5, LSX128HOpnd>; ++ ++def VSUBI_WU : LSX_I5_U<0b01110010100011010>, ++ LSX_I5_U_DESC_BASE<"vsubi.wu", sub, vsplati32_uimm5, LSX128WOpnd>; ++ ++def VSUBI_DU : LSX_I5_U<0b01110010100011011>, ++ LSX_I5_U_DESC_BASE<"vsubi.du", sub, vsplati64_uimm5, LSX128DOpnd>; ++ ++ ++def VMAXI_B : LSX_I5<0b01110010100100000>, ++ LSX_I5_DESC_BASE_Intrinsic<"vmaxi.b", int_loongarch_lsx_vmaxi_b, simm5_32, immSExt5, LSX128BOpnd>; ++ ++def VMAXI_H : LSX_I5<0b01110010100100001>, ++ LSX_I5_DESC_BASE_Intrinsic<"vmaxi.h", int_loongarch_lsx_vmaxi_h, simm5_32, immSExt5, LSX128HOpnd>; ++ ++def VMAXI_W : LSX_I5<0b01110010100100010>, ++ LSX_I5_DESC_BASE_Intrinsic<"vmaxi.w", int_loongarch_lsx_vmaxi_w, simm5_32, immSExt5, LSX128WOpnd>; ++ ++def VMAXI_D : LSX_I5<0b01110010100100011>, ++ LSX_I5_DESC_BASE_Intrinsic<"vmaxi.d", int_loongarch_lsx_vmaxi_d, simm5_32, immSExt5, LSX128DOpnd>; ++ ++ ++def VMINI_B : LSX_I5<0b01110010100100100>, ++ LSX_I5_DESC_BASE_Intrinsic<"vmini.b", int_loongarch_lsx_vmini_b, simm5_32, immSExt5, LSX128BOpnd>; ++ ++def VMINI_H : LSX_I5<0b01110010100100101>, ++ LSX_I5_DESC_BASE_Intrinsic<"vmini.h", int_loongarch_lsx_vmini_h, simm5_32, immSExt5, LSX128HOpnd>; ++ ++def VMINI_W : LSX_I5<0b01110010100100110>, ++ LSX_I5_DESC_BASE_Intrinsic<"vmini.w", int_loongarch_lsx_vmini_w, simm5_32, immSExt5, LSX128WOpnd>; ++ ++def VMINI_D : LSX_I5<0b01110010100100111>, ++ LSX_I5_DESC_BASE_Intrinsic<"vmini.d", int_loongarch_lsx_vmini_d, simm5_32, immSExt5, LSX128DOpnd>; ++ ++ ++def VMAXI_BU : LSX_I5_U<0b01110010100101000>, ++ LSX_I5_U_DESC_BASE_Intrinsic<"vmaxi.bu", int_loongarch_lsx_vmaxi_bu, uimm5, immZExt5, LSX128BOpnd>; ++ ++def VMAXI_HU : LSX_I5_U<0b01110010100101001>, ++ LSX_I5_U_DESC_BASE_Intrinsic<"vmaxi.hu", int_loongarch_lsx_vmaxi_hu, uimm5, immZExt5, LSX128HOpnd>; ++ ++def VMAXI_WU : LSX_I5_U<0b01110010100101010>, ++ LSX_I5_U_DESC_BASE_Intrinsic<"vmaxi.wu", int_loongarch_lsx_vmaxi_wu, uimm5, immZExt5, LSX128WOpnd>; ++ ++def VMAXI_DU : LSX_I5_U<0b01110010100101011>, ++ LSX_I5_U_DESC_BASE_Intrinsic<"vmaxi.du", int_loongarch_lsx_vmaxi_du, uimm5, immZExt5, LSX128DOpnd>; ++ ++ ++def VMINI_BU : LSX_I5_U<0b01110010100101100>, ++ LSX_I5_U_DESC_BASE<"vmini.bu", umin, vsplati8_uimm5, LSX128BOpnd>; ++ ++def VMINI_HU : LSX_I5_U<0b01110010100101101>, ++ LSX_I5_U_DESC_BASE<"vmini.hu", umin, vsplati16_uimm5, LSX128HOpnd>; ++ ++def VMINI_WU : LSX_I5_U<0b01110010100101110>, ++ LSX_I5_U_DESC_BASE<"vmini.wu", umin, vsplati32_uimm5, LSX128WOpnd>; ++ ++def VMINI_DU : LSX_I5_U<0b01110010100101111>, ++ LSX_I5_U_DESC_BASE<"vmini.du", umin, vsplati64_uimm5, LSX128DOpnd>; ++ ++ ++def VCLO_B : LSX_2R<0b0111001010011100000000>, ++ LSX_2RN_DESC_BASE<"vclo.b", LSX128BOpnd>; ++ ++def VCLO_H : LSX_2R<0b0111001010011100000001>, ++ LSX_2RN_DESC_BASE<"vclo.h", LSX128HOpnd>; ++ ++def VCLO_W : LSX_2R<0b0111001010011100000010>, ++ LSX_2RN_DESC_BASE<"vclo.w", LSX128WOpnd>; ++ ++def VCLO_D : LSX_2R<0b0111001010011100000011>, ++ LSX_2RN_DESC_BASE<"vclo.d", LSX128DOpnd>; ++ ++ ++def VCLZ_B : LSX_2R<0b0111001010011100000100>, ++ LSX_2R_DESC_BASE<"vclz.b", ctlz, LSX128BOpnd>; ++ ++def VCLZ_H : LSX_2R<0b0111001010011100000101>, ++ LSX_2R_DESC_BASE<"vclz.h", ctlz, LSX128HOpnd>; ++ ++def VCLZ_W : LSX_2R<0b0111001010011100000110>, ++ LSX_2R_DESC_BASE<"vclz.w", ctlz, LSX128WOpnd>; ++ ++def VCLZ_D : LSX_2R<0b0111001010011100000111>, ++ LSX_2R_DESC_BASE<"vclz.d", ctlz, LSX128DOpnd>; ++ ++ ++def VPCNT_B : LSX_2R<0b0111001010011100001000>, ++ LSX_2R_DESC_BASE<"vpcnt.b", ctpop, LSX128BOpnd>; ++ ++def VPCNT_H : LSX_2R<0b0111001010011100001001>, ++ LSX_2R_DESC_BASE<"vpcnt.h", ctpop, LSX128HOpnd>; ++ ++def VPCNT_W : LSX_2R<0b0111001010011100001010>, ++ LSX_2R_DESC_BASE<"vpcnt.w", ctpop, LSX128WOpnd>; ++ ++def VPCNT_D : LSX_2R<0b0111001010011100001011>, ++ LSX_2R_DESC_BASE<"vpcnt.d", ctpop, LSX128DOpnd>; ++ ++ ++def VFLOGB_S : LSX_2R<0b0111001010011100110001>, ++ LSX_2RFN_DESC_BASE<"vflogb.s", LSX128WOpnd>; ++ ++def VFLOGB_D : LSX_2R<0b0111001010011100110010>, ++ LSX_2RFN_DESC_BASE<"vflogb.d", LSX128DOpnd>; ++ ++ ++def VFCLASS_S : LSX_2R<0b0111001010011100110101>, ++ LSX_2RFN_DESC_BASE<"vfclass.s", LSX128WOpnd>; ++ ++def VFCLASS_D : LSX_2R<0b0111001010011100110110>, ++ LSX_2RFN_DESC_BASE<"vfclass.d", LSX128DOpnd>; ++ ++ ++def VFSQRT_S : LSX_2R<0b0111001010011100111001>, ++ LSX_2RF_DESC_BASE<"vfsqrt.s", fsqrt, LSX128WOpnd>; ++ ++def VFSQRT_D : LSX_2R<0b0111001010011100111010>, ++ LSX_2RF_DESC_BASE<"vfsqrt.d", fsqrt, LSX128DOpnd>; ++ ++ ++def VFRECIP_S : LSX_2R<0b0111001010011100111101>, ++ LSX_2RFN_DESC_BASE<"vfrecip.s", LSX128WOpnd>; ++ ++def VFRECIP_D : LSX_2R<0b0111001010011100111110>, ++ LSX_2RFN_DESC_BASE<"vfrecip.d", LSX128DOpnd>; ++ ++def VFRECIPE_S : LSX_2R<0b0111001010011101000101>, ++ LSX_2RFN_DESC_BASE<"vfrecipe.s", LSX128WOpnd>; ++ ++def VFRECIPE_D : LSX_2R<0b0111001010011101000110>, ++ LSX_2RFN_DESC_BASE<"vfrecipe.d", LSX128DOpnd>; ++ ++def VFRSQRT_S : LSX_2R<0b0111001010011101000001>, ++ LSX_2RFN_DESC_BASE<"vfrsqrt.s", LSX128WOpnd>; ++ ++def VFRSQRT_D : LSX_2R<0b0111001010011101000010>, ++ LSX_2RFN_DESC_BASE<"vfrsqrt.d", LSX128DOpnd>; ++ ++def VFRSQRTE_S : LSX_2R<0b0111001010011101001001>, ++ LSX_2RFN_DESC_BASE<"vfrsqrte.s", LSX128WOpnd>; ++ ++def VFRSQRTE_D : LSX_2R<0b0111001010011101001010>, ++ LSX_2RFN_DESC_BASE<"vfrsqrte.d", LSX128DOpnd>; ++ ++def VFRINT_S : LSX_2R<0b0111001010011101001101>, ++ LSX_2RF_DESC_BASE<"vfrint.s", frint, LSX128WOpnd>; ++ ++def VFRINT_D : LSX_2R<0b0111001010011101001110>, ++ LSX_2RF_DESC_BASE<"vfrint.d", frint, LSX128DOpnd>; ++ ++ ++def VFCVTL_S_H : LSX_2R<0b0111001010011101111010>, ++ LSX_2RFN_DESC_BASE_CVT<"vfcvtl.s.h", LSX128WOpnd, LSX128HOpnd>; ++ ++def VFCVTH_S_H : LSX_2R<0b0111001010011101111011>, ++ LSX_2RFN_DESC_BASE_CVT<"vfcvth.s.h", LSX128WOpnd, LSX128HOpnd>; ++ ++ ++def VFCVTL_D_S : LSX_2R<0b0111001010011101111100>, ++ LSX_2RFN_DESC_BASE_CVT<"vfcvtl.d.s", LSX128DOpnd, LSX128WOpnd>; ++ ++def VFCVTH_D_S : LSX_2R<0b0111001010011101111101>, ++ LSX_2RFN_DESC_BASE_CVT<"vfcvth.d.s", LSX128DOpnd, LSX128WOpnd>; ++ ++ ++def VFFINT_S_W : LSX_2R<0b0111001010011110000000>, ++ LSX_2RF_DESC_BASE<"vffint.s.w", sint_to_fp, LSX128WOpnd>; ++ ++def VFFINT_S_WU : LSX_2R<0b0111001010011110000001>, ++ LSX_2RF_DESC_BASE<"vffint.s.wu", uint_to_fp, LSX128WOpnd>; ++ ++ ++def VFFINT_D_L : LSX_2R<0b0111001010011110000010>, ++ LSX_2RF_DESC_BASE<"vffint.d.l", sint_to_fp, LSX128DOpnd>; ++ ++def VFFINT_D_LU : LSX_2R<0b0111001010011110000011>, ++ LSX_2RF_DESC_BASE<"vffint.d.lu", uint_to_fp, LSX128DOpnd>; ++ ++ ++def VFTINT_W_S : LSX_2R<0b0111001010011110001100>, ++ LSX_2RFN_DESC_BASE<"vftint.w.s", LSX128WOpnd>; ++ ++def VFTINT_L_D : LSX_2R<0b0111001010011110001101>, ++ LSX_2RFN_DESC_BASE<"vftint.l.d", LSX128DOpnd>; ++ ++ ++def VFTINT_WU_S : LSX_2R<0b0111001010011110010110>, ++ LSX_2RFN_DESC_BASE<"vftint.wu.s", LSX128WOpnd>; ++ ++def VFTINT_LU_D : LSX_2R<0b0111001010011110010111>, ++ LSX_2RFN_DESC_BASE<"vftint.lu.d", LSX128DOpnd>; ++ ++ ++def VFTINTRZ_WU_S : LSX_2R<0b0111001010011110011100>, ++ LSX_2RF_DESC_BASE<"vftintrz.wu.s", fp_to_uint, LSX128WOpnd>; ++ ++def VFTINTRZ_LU_D : LSX_2R<0b0111001010011110011101>, ++ LSX_2RF_DESC_BASE<"vftintrz.lu.d", fp_to_uint, LSX128DOpnd>; ++ ++ ++def VREPLGR2VR_B : LSX_2R_1GP<0b0111001010011111000000>, ++ LSX_2R_REPL_DESC_BASE<"vreplgr2vr.b", v16i8, vsplati8, LSX128BOpnd, GPR32Opnd>; ++ ++def VREPLGR2VR_H : LSX_2R_1GP<0b0111001010011111000001>, ++ LSX_2R_REPL_DESC_BASE<"vreplgr2vr.h", v8i16, vsplati16, LSX128HOpnd, GPR32Opnd>; ++ ++def VREPLGR2VR_W : LSX_2R_1GP<0b0111001010011111000010>, ++ LSX_2R_REPL_DESC_BASE<"vreplgr2vr.w", v4i32, vsplati32, LSX128WOpnd, GPR32Opnd>; ++ ++def VREPLGR2VR_D : LSX_2R_1GP<0b0111001010011111000011>, ++ LSX_2R_REPL_DESC_BASE<"vreplgr2vr.d", v2i64, vsplati64, LSX128DOpnd, GPR64Opnd>; ++ ++ ++class LSX_2R_FILL_PSEUDO_BASE : ++ LSXPseudo<(outs RCVD:$vd), (ins RCVS:$fs), ++ [(set RCVD:$vd, (OpNode RCVS:$fs))]> { ++ let usesCustomInserter = 1; ++} ++ ++class FILL_FW_PSEUDO_DESC : LSX_2R_FILL_PSEUDO_BASE; ++class FILL_FD_PSEUDO_DESC : LSX_2R_FILL_PSEUDO_BASE; ++ ++def FILL_FW_PSEUDO : FILL_FW_PSEUDO_DESC; ++def FILL_FD_PSEUDO : FILL_FD_PSEUDO_DESC; ++ ++ ++def VSRLRI_B : LSX_I3_U<0b0111001010100100001>, ++ LSX_BIT_3N_DESC_BASE<"vsrlri.b", uimm3, immZExt3, LSX128BOpnd>; ++ ++def VSRLRI_H : LSX_I4_U<0b011100101010010001>, ++ LSX_BIT_4N_DESC_BASE<"vsrlri.h", uimm4, immZExt4, LSX128HOpnd>; ++ ++def VSRLRI_W : LSX_I5_U<0b01110010101001001>, ++ LSX_BIT_5N_DESC_BASE<"vsrlri.w", uimm5, immZExt5, LSX128WOpnd>; ++ ++def VSRLRI_D : LSX_I6_U<0b0111001010100101>, ++ LSX_BIT_6N_DESC_BASE<"vsrlri.d", uimm6, immZExt6, LSX128DOpnd>; ++ ++ ++def VSRARI_B : LSX_I3_U<0b0111001010101000001>, ++ LSX_BIT_3N_DESC_BASE<"vsrari.b", uimm3, immZExt3, LSX128BOpnd>; ++ ++def VSRARI_H : LSX_I4_U<0b011100101010100001>, ++ LSX_BIT_4N_DESC_BASE<"vsrari.h", uimm4, immZExt4, LSX128HOpnd>; ++ ++def VSRARI_W : LSX_I5_U<0b01110010101010001>, ++ LSX_BIT_5N_DESC_BASE<"vsrari.w", uimm5, immZExt5, LSX128WOpnd>; ++ ++def VSRARI_D : LSX_I6_U<0b0111001010101001>, ++ LSX_BIT_6N_DESC_BASE<"vsrari.d", uimm6, immZExt6, LSX128DOpnd>; ++ ++ ++def VINSGR2VR_B : LSX_I4_R_U<0b011100101110101110>, ++ LSX_INSERT_U4_DESC_BASE<"vinsgr2vr.b", vinsert_v16i8, uimm4, immZExt4Ptr, LSX128BOpnd, GPR32Opnd>; ++ ++def VINSGR2VR_H : LSX_I3_R_U<0b0111001011101011110>, ++ LSX_INSERT_U3_DESC_BASE<"vinsgr2vr.h", vinsert_v8i16, uimm3, immZExt3Ptr, LSX128HOpnd, GPR32Opnd>; ++ ++def VINSGR2VR_W : LSX_I2_R_U<0b01110010111010111110>, ++ LSX_INSERT_U2_DESC_BASE<"vinsgr2vr.w", vinsert_v4i32, uimm2, immZExt2Ptr, LSX128WOpnd, GPR32Opnd>; ++ ++def VINSGR2VR_D : LSX_I1_R_U<0b011100101110101111110>, ++ LSX_INSERT_U1_DESC_BASE<"vinsgr2vr.d", vinsert_v2i64, uimm1, immZExt1Ptr, LSX128DOpnd, GPR64Opnd>; ++ ++ ++def VPICKVE2GR_B : LSX_ELM_COPY_B<0b011100101110111110>, ++ LSX_PICK_U4_DESC_BASE<"vpickve2gr.b", vextract_sext_i8, v16i8, uimm4_ptr, immZExt4Ptr, GPR32Opnd, LSX128BOpnd>; ++ ++def VPICKVE2GR_H : LSX_ELM_COPY_H<0b0111001011101111110>, ++ LSX_PICK_U3_DESC_BASE<"vpickve2gr.h", vextract_sext_i16, v8i16, uimm3_ptr, immZExt3Ptr, GPR32Opnd, LSX128HOpnd>; ++ ++def VPICKVE2GR_W : LSX_ELM_COPY_W<0b01110010111011111110>, ++ LSX_PICK_U2_DESC_BASE<"vpickve2gr.w", vextract_sext_i32, v4i32, uimm2_ptr, immZExt2Ptr, GPR32Opnd, LSX128WOpnd>; ++ ++def VPICKVE2GR_D : LSX_ELM_COPY_D<0b011100101110111111110>, ++ LSX_PICK_U1_DESC_BASE<"vpickve2gr.d", vextract_sext_i64, v2i64, uimm1_ptr, immZExt1Ptr, GPR64Opnd, LSX128DOpnd>; ++ ++ ++def VPICKVE2GR_BU : LSX_ELM_COPY_B<0b011100101111001110>, ++ LSX_PICK_U4_DESC_BASE<"vpickve2gr.bu", vextract_zext_i8, v16i8, uimm4_ptr, immZExt4Ptr, GPR32Opnd, LSX128BOpnd>; ++ ++def VPICKVE2GR_HU : LSX_ELM_COPY_H<0b0111001011110011110>, ++ LSX_PICK_U3_DESC_BASE<"vpickve2gr.hu", vextract_zext_i16, v8i16, uimm3_ptr, immZExt3Ptr, GPR32Opnd, LSX128HOpnd>; ++ ++def VPICKVE2GR_WU : LSX_ELM_COPY_W<0b01110010111100111110>, ++ LSX_PICK_U2_DESC_BASE<"vpickve2gr.wu", vextract_zext_i32, v4i32, uimm2_ptr, immZExt2Ptr, GPR32Opnd, LSX128WOpnd>; ++ ++def VPICKVE2GR_DU : LSX_ELM_COPY_D<0b011100101111001111110>, ++ LSX_PICK_U1_DESC_BASE<"vpickve2gr.du", int_loongarch_lsx_vpickve2gr_du, v2i64, uimm1, immZExt1, GPR64Opnd, LSX128DOpnd>; ++ ++ ++def : LSXPat<(vextract_zext_i64 (v2i64 LSX128D:$vj), immZExt1Ptr:$idx), ++ (VPICKVE2GR_D LSX128D:$vj, immZExt1:$idx)>; ++def : LSXPat<(vextract_zext_i64 (v2f64 LSX128D:$vj), immZExt1Ptr:$idx), ++ (VPICKVE2GR_D LSX128D:$vj, immZExt1:$idx)>; ++ ++ ++def VREPLVEI_B : LSX_I4_U<0b011100101111011110>, ++ LSX_ELM_U4_VREPLVE_DESC_BASE<"vreplvei.b", vsplati8_uimm4, LSX128BOpnd>; ++ ++def VREPLVEI_H : LSX_I3_U<0b0111001011110111110>, ++ LSX_ELM_U3_VREPLVE_DESC_BASE<"vreplvei.h", vsplati16_uimm3, LSX128HOpnd>; ++ ++def VREPLVEI_W : LSX_I2_U<0b01110010111101111110>, ++ LSX_ELM_U2_VREPLVE_DESC_BASE<"vreplvei.w", vsplati32_uimm2, LSX128WOpnd>; ++ ++def VREPLVEI_D : LSX_I1_U<0b011100101111011111110>, ++ LSX_ELM_U1_VREPLVE_DESC_BASE<"vreplvei.d", vsplati64_uimm1, LSX128DOpnd>; ++ ++ ++def VSAT_B : LSX_I3_U<0b0111001100100100001>, ++ LSX_BIT_3N_DESC_BASE<"vsat.b", uimm3, immZExt3, LSX128BOpnd>; ++ ++def VSAT_H : LSX_I4_U<0b011100110010010001>, ++ LSX_BIT_4N_DESC_BASE<"vsat.h", uimm4, immZExt4, LSX128HOpnd>; ++ ++def VSAT_W : LSX_I5_U<0b01110011001001001>, ++ LSX_BIT_5N_DESC_BASE<"vsat.w", uimm5, immZExt5, LSX128WOpnd>; ++ ++def VSAT_D : LSX_I6_U<0b0111001100100101>, ++ LSX_BIT_6N_DESC_BASE<"vsat.d", uimm6, immZExt6, LSX128DOpnd>; ++ ++ ++def VSAT_BU : LSX_I3_U<0b0111001100101000001>, ++ LSX_BIT_3N_DESC_BASE<"vsat.bu", uimm3, immZExt3, LSX128BOpnd>; ++ ++def VSAT_HU : LSX_I4_U<0b011100110010100001>, ++ LSX_BIT_4N_DESC_BASE<"vsat.hu", uimm4, immZExt4, LSX128HOpnd>; ++ ++def VSAT_WU : LSX_I5_U<0b01110011001010001>, ++ LSX_BIT_5N_DESC_BASE<"vsat.wu", uimm5, immZExt5, LSX128WOpnd>; ++ ++def VSAT_DU : LSX_I6_U<0b0111001100101001>, ++ LSX_BIT_6N_DESC_BASE<"vsat.du", uimm6, immZExt6, LSX128DOpnd>; ++ ++ ++def VSLLI_B : LSX_I3_U<0b0111001100101100001>, ++ LSX_BIT_U3_VREPLVE_DESC_BASE<"vslli.b", shl, vsplati8_uimm3, LSX128BOpnd>; ++ ++def VSLLI_H : LSX_I4_U<0b011100110010110001>, ++ LSX_BIT_U4_VREPLVE_DESC_BASE<"vslli.h", shl, vsplati16_uimm4, LSX128HOpnd>; ++ ++def VSLLI_W : LSX_I5_U<0b01110011001011001>, ++ LSX_BIT_U5_VREPLVE_DESC_BASE<"vslli.w", shl, vsplati32_uimm5, LSX128WOpnd>; ++ ++def VSLLI_D : LSX_I6_U<0b0111001100101101>, ++ LSX_BIT_U6_VREPLVE_DESC_BASE<"vslli.d", shl, vsplati64_uimm6, LSX128DOpnd>; ++ ++ ++def VSRLI_B : LSX_I3_U<0b0111001100110000001>, ++ LSX_BIT_U3_VREPLVE_DESC_BASE<"vsrli.b", srl, vsplati8_uimm3, LSX128BOpnd>; ++ ++def VSRLI_H : LSX_I4_U<0b011100110011000001>, ++ LSX_BIT_U4_VREPLVE_DESC_BASE<"vsrli.h", srl, vsplati16_uimm4, LSX128HOpnd>; ++ ++def VSRLI_W : LSX_I5_U<0b01110011001100001>, ++ LSX_BIT_U5_VREPLVE_DESC_BASE<"vsrli.w", srl, vsplati32_uimm5, LSX128WOpnd>; ++ ++def VSRLI_D : LSX_I6_U<0b0111001100110001>, ++ LSX_BIT_U6_VREPLVE_DESC_BASE<"vsrli.d", srl, vsplati64_uimm6, LSX128DOpnd>; ++ ++ ++def VSRAI_B : LSX_I3_U<0b0111001100110100001>, ++ LSX_BIT_U3_VREPLVE_DESC_BASE_Intrinsic<"vsrai.b", int_loongarch_lsx_vsrai_b, LSX128BOpnd>; ++ ++def VSRAI_H : LSX_I4_U<0b011100110011010001>, ++ LSX_BIT_U4_VREPLVE_DESC_BASE_Intrinsic<"vsrai.h", int_loongarch_lsx_vsrai_h, LSX128HOpnd>; ++ ++def VSRAI_W : LSX_I5_U<0b01110011001101001>, ++ LSX_BIT_U5_VREPLVE_DESC_BASE_Intrinsic<"vsrai.w", int_loongarch_lsx_vsrai_w, LSX128WOpnd>; ++ ++def VSRAI_D : LSX_I6_U<0b0111001100110101>, ++ LSX_BIT_U6_VREPLVE_DESC_BASE_Intrinsic<"vsrai.d", int_loongarch_lsx_vsrai_d, LSX128DOpnd>; ++ ++ ++def VSHUF4I_B : LSX_I8_U<0b01110011100100>, ++ LSX_I8_SHF_DESC_BASE<"vshuf4i.b", LSX128BOpnd>; ++ ++def VSHUF4I_H : LSX_I8_U<0b01110011100101>, ++ LSX_I8_SHF_DESC_BASE<"vshuf4i.h", LSX128HOpnd>; ++ ++def VSHUF4I_W : LSX_I8_U<0b01110011100110>, ++ LSX_I8_SHF_DESC_BASE<"vshuf4i.w", LSX128WOpnd>; ++ ++def VSHUF4I_D : LSX_I8_U<0b01110011100111>, ++ LSX_I8_SHUF_DESC_BASE_D<"vshuf4i.d", int_loongarch_lsx_vshuf4i_d, LSX128DOpnd>; ++ ++ ++def VROTR_B : LSX_3R<0b01110000111011100>, ++ LSX_3R_DESC_BASE<"vrotr.b", LoongArchVROR, LSX128BOpnd>; ++ ++def VROTR_H : LSX_3R<0b01110000111011101>, ++ LSX_3R_DESC_BASE<"vrotr.h", LoongArchVROR, LSX128HOpnd>; ++ ++def VROTR_W : LSX_3R<0b01110000111011110>, ++ LSX_3R_DESC_BASE<"vrotr.w", LoongArchVROR, LSX128WOpnd>; ++ ++def VROTR_D : LSX_3R<0b01110000111011111>, ++ LSX_3R_DESC_BASE<"vrotr.d", LoongArchVROR, LSX128DOpnd>; ++ ++ ++def VMSKLTZ_B : LSX_2R<0b0111001010011100010000>, ++ LSX_2RN_DESC_BASE<"vmskltz.b", LSX128BOpnd>; ++ ++def VMSKLTZ_H : LSX_2R<0b0111001010011100010001>, ++ LSX_2RN_DESC_BASE<"vmskltz.h", LSX128HOpnd>; ++ ++def VMSKLTZ_W : LSX_2R<0b0111001010011100010010>, ++ LSX_2RN_DESC_BASE<"vmskltz.w", LSX128WOpnd>; ++ ++def VMSKLTZ_D : LSX_2R<0b0111001010011100010011>, ++ LSX_2RN_DESC_BASE<"vmskltz.d", LSX128DOpnd>; ++ ++ ++def VROTRI_B : LSX_I3_U<0b0111001010100000001>, ++ LSX2_RORI_U3_DESC_BASE<"vrotri.b", uimm3, immZExt3, LSX128BOpnd>; ++ ++def VROTRI_H : LSX_I4_U<0b011100101010000001>, ++ LSX2_RORI_U4_DESC_BASE<"vrotri.h", uimm4, immZExt4, LSX128HOpnd>; ++ ++def VROTRI_W : LSX_I5_U<0b01110010101000001>, ++ LSX2_RORI_U5_DESC_BASE<"vrotri.w", uimm5, immZExt5, LSX128WOpnd>; ++ ++def VROTRI_D : LSX_I6_U<0b0111001010100001>, ++ LSX2_RORI_U6_DESC_BASE<"vrotri.d", uimm6, immZExt6, LSX128DOpnd>; ++ ++ ++def VSRLNI_B_H : LSX_I4_U<0b011100110100000001>, ++ LSX_BIND_U4N_DESC_BASE<"vsrlni.b.h", uimm4, immZExt4, LSX128BOpnd>; ++ ++def VSRLNI_H_W : LSX_I5_U<0b01110011010000001>, ++ LSX_BIND_U5N_DESC_BASE<"vsrlni.h.w", uimm5, immZExt5, LSX128HOpnd>; ++ ++def VSRLNI_W_D : LSX_I6_U<0b0111001101000001>, ++ LSX_BIND_U6N_DESC_BASE<"vsrlni.w.d", uimm6, immZExt6, LSX128WOpnd>; ++ ++def VSRLNI_D_Q : LSX_I7_U<0b011100110100001>, ++ LSX_BIND_U7N_DESC_BASE<"vsrlni.d.q", LSX128DOpnd>; ++ ++ ++def VSRLRNI_B_H : LSX_I4_U<0b011100110100010001>, ++ LSX_BIND_U4_DESC_BASE<"vsrlrni.b.h", int_loongarch_lsx_vsrlrni_b_h, uimm4, immZExt4, LSX128BOpnd>; ++ ++def VSRLRNI_H_W : LSX_I5_U<0b01110011010001001>, ++ LSX_BIND_U5_DESC_BASE<"vsrlrni.h.w", int_loongarch_lsx_vsrlrni_h_w, uimm5, immZExt5, LSX128HOpnd>; ++ ++def VSRLRNI_W_D : LSX_I6_U<0b0111001101000101>, ++ LSX_BIND_U6_DESC_BASE<"vsrlrni.w.d", int_loongarch_lsx_vsrlrni_w_d, uimm6, immZExt6, LSX128WOpnd>; ++ ++def VSRLRNI_D_Q : LSX_I7_U<0b011100110100011>, ++ LSX_BIND_U7_DESC_BASE<"vsrlrni.d.q", int_loongarch_lsx_vsrlrni_d_q, LSX128DOpnd>; ++ ++ ++def VSSRLNI_B_H : LSX_I4_U<0b011100110100100001>, ++ LSX_BIND_U4N_DESC_BASE<"vssrlni.b.h", uimm4, immZExt4, LSX128BOpnd>; ++ ++def VSSRLNI_H_W : LSX_I5_U<0b01110011010010001>, ++ LSX_BIND_U5N_DESC_BASE<"vssrlni.h.w", uimm5, immZExt5, LSX128HOpnd>; ++ ++def VSSRLNI_W_D : LSX_I6_U<0b0111001101001001>, ++ LSX_BIND_U6N_DESC_BASE<"vssrlni.w.d", uimm6, immZExt6, LSX128WOpnd>; ++ ++def VSSRLNI_D_Q : LSX_I7_U<0b011100110100101>, ++ LSX_BIND_U7N_DESC_BASE<"vssrlni.d.q", LSX128DOpnd>; ++ ++ ++def VSSRLNI_BU_H : LSX_I4_U<0b011100110100110001>, ++ LSX_BIND_U4N_DESC_BASE<"vssrlni.bu.h", uimm4, immZExt4, LSX128BOpnd> ; ++ ++def VSSRLNI_HU_W : LSX_I5_U<0b01110011010011001>, ++ LSX_BIND_U5N_DESC_BASE<"vssrlni.hu.w", uimm5, immZExt5, LSX128HOpnd>; ++ ++def VSSRLNI_WU_D : LSX_I6_U<0b0111001101001101>, ++ LSX_BIND_U6N_DESC_BASE<"vssrlni.wu.d", uimm6, immZExt6, LSX128WOpnd>; ++ ++def VSSRLNI_DU_Q : LSX_I7_U<0b011100110100111>, ++ LSX_BIND_U7N_DESC_BASE<"vssrlni.du.q", LSX128DOpnd>; ++ ++ ++def VSSRLRNI_BU_H : LSX_I4_U<0b011100110101010001>, ++ LSX_BIND_U4N_DESC_BASE<"vssrlrni.bu.h", uimm4, immZExt4, LSX128BOpnd>; ++ ++def VSSRLRNI_HU_W : LSX_I5_U<0b01110011010101001>, ++ LSX_BIND_U5N_DESC_BASE<"vssrlrni.hu.w", uimm5, immZExt5, LSX128HOpnd>; ++ ++def VSSRLRNI_WU_D : LSX_I6_U<0b0111001101010101>, ++ LSX_BIND_U6N_DESC_BASE<"vssrlrni.wu.d", uimm6, immZExt6, LSX128WOpnd>; ++ ++def VSSRLRNI_DU_Q : LSX_I7_U<0b011100110101011>, ++ LSX_BIND_U7N_DESC_BASE<"vssrlrni.du.q", LSX128DOpnd>; ++ ++ ++def VSRARNI_B_H : LSX_I4_U<0b011100110101110001>, ++ LSX_BIND_U4N_DESC_BASE<"vsrarni.b.h", uimm4, immZExt4, LSX128BOpnd>; ++ ++def VSRARNI_H_W : LSX_I5_U<0b01110011010111001>, ++ LSX_BIND_U5N_DESC_BASE<"vsrarni.h.w", uimm5, immZExt5, LSX128HOpnd>; ++ ++def VSRARNI_W_D : LSX_I6_U<0b0111001101011101>, ++ LSX_BIND_U6N_DESC_BASE<"vsrarni.w.d", uimm6, immZExt6, LSX128WOpnd>; ++ ++def VSRARNI_D_Q : LSX_I7_U<0b011100110101111>, ++ LSX_BIND_U7N_DESC_BASE<"vsrarni.d.q", LSX128DOpnd>; ++ ++ ++def VSSRANI_B_H : LSX_I4_U<0b011100110110000001>, ++ LSX_BIND_U4N_DESC_BASE<"vssrani.b.h", uimm4, immZExt4, LSX128BOpnd>; ++ ++def VSSRANI_H_W : LSX_I5_U<0b01110011011000001>, ++ LSX_BIND_U5N_DESC_BASE<"vssrani.h.w", uimm5, immZExt5, LSX128HOpnd>; ++ ++def VSSRANI_W_D : LSX_I6_U<0b0111001101100001>, ++ LSX_BIND_U6N_DESC_BASE<"vssrani.w.d", uimm6, immZExt6, LSX128WOpnd>; ++ ++def VSSRANI_D_Q : LSX_I7_U<0b011100110110001>, ++ LSX_BIND_U7N_DESC_BASE<"vssrani.d.q", LSX128DOpnd>; ++ ++ ++def VSSRANI_BU_H : LSX_I4_U<0b011100110110010001>, ++ LSX_BIND_U4N_DESC_BASE<"vssrani.bu.h", uimm4, immZExt4, LSX128BOpnd>; ++ ++def VSSRANI_HU_W : LSX_I5_U<0b01110011011001001>, ++ LSX_BIND_U5N_DESC_BASE<"vssrani.hu.w", uimm5, immZExt5, LSX128HOpnd>; ++ ++def VSSRANI_WU_D : LSX_I6_U<0b0111001101100101>, ++ LSX_BIND_U6N_DESC_BASE<"vssrani.wu.d", uimm6, immZExt6, LSX128WOpnd>; ++ ++def VSSRANI_DU_Q : LSX_I7_U<0b011100110110011>, ++ LSX_BIND_U7N_DESC_BASE<"vssrani.du.q", LSX128DOpnd>; ++ ++ ++def VSSRARNI_B_H : LSX_I4_U<0b011100110110100001>, ++ LSX_BIND_U4N_DESC_BASE<"vssrarni.b.h", uimm4, immZExt4, LSX128BOpnd>; ++ ++def VSSRARNI_H_W : LSX_I5_U<0b01110011011010001>, ++ LSX_BIND_U5N_DESC_BASE<"vssrarni.h.w", uimm5, immZExt5, LSX128HOpnd>; ++ ++def VSSRARNI_W_D : LSX_I6_U<0b0111001101101001>, ++ LSX_BIND_U6N_DESC_BASE<"vssrarni.w.d", uimm6, immZExt6, LSX128WOpnd>; ++ ++def VSSRARNI_D_Q : LSX_I7_U<0b011100110110101>, ++ LSX_BIND_U7N_DESC_BASE<"vssrarni.d.q", LSX128DOpnd>; ++ ++ ++def VSSRARNI_BU_H : LSX_I4_U<0b011100110110110001>, ++ LSX_BIND_U4N_DESC_BASE<"vssrarni.bu.h", uimm4, immZExt4, LSX128BOpnd>; ++ ++def VSSRARNI_HU_W : LSX_I5_U<0b01110011011011001>, ++ LSX_BIND_U5N_DESC_BASE<"vssrarni.hu.w", uimm5, immZExt5, LSX128HOpnd>; ++ ++def VSSRARNI_WU_D : LSX_I6_U<0b0111001101101101>, ++ LSX_BIND_U6N_DESC_BASE<"vssrarni.wu.d", uimm6, immZExt6, LSX128WOpnd>; ++ ++def VSSRARNI_DU_Q : LSX_I7_U<0b011100110110111>, ++ LSX_BIND_U7N_DESC_BASE<"vssrarni.du.q", LSX128DOpnd>; ++ ++ ++ ++def VLD : LSX_I12_S<0b0010110000>, ++ LD_DESC_BASE<"vld", load, v16i8, LSX128BOpnd, mem>; ++ ++def VST : LSX_I12_S<0b0010110001>, ++ ST_DESC_BASE<"vst", store, v16i8, LSX128BOpnd, mem_simm12>; ++ ++ ++def VSETEQZ_V : LSX_SET<0b0111001010011100100110>, ++ LSX_SET_DESC_BASE<"vseteqz.v", LSX128BOpnd>; ++ ++def VSETNEZ_V : LSX_SET<0b0111001010011100100111>, ++ LSX_SET_DESC_BASE<"vsetnez.v", LSX128BOpnd>; ++ ++ ++def VSETANYEQZ_B : LSX_SET<0b0111001010011100101000>, ++ LSX_SET_DESC_BASE<"vsetanyeqz.b", LSX128BOpnd>; ++ ++def VSETANYEQZ_H : LSX_SET<0b0111001010011100101001>, ++ LSX_SET_DESC_BASE<"vsetanyeqz.h", LSX128HOpnd>; ++ ++def VSETANYEQZ_W : LSX_SET<0b0111001010011100101010>, ++ LSX_SET_DESC_BASE<"vsetanyeqz.w", LSX128WOpnd>; ++ ++def VSETANYEQZ_D : LSX_SET<0b0111001010011100101011>, ++ LSX_SET_DESC_BASE<"vsetanyeqz.d", LSX128DOpnd>; ++ ++ ++def VSETALLNEZ_B : LSX_SET<0b0111001010011100101100>, ++ LSX_SET_DESC_BASE<"vsetallnez.b", LSX128BOpnd>; ++ ++def VSETALLNEZ_H : LSX_SET<0b0111001010011100101101>, ++ LSX_SET_DESC_BASE<"vsetallnez.h", LSX128HOpnd>; ++ ++def VSETALLNEZ_W : LSX_SET<0b0111001010011100101110>, ++ LSX_SET_DESC_BASE<"vsetallnez.w", LSX128WOpnd>; ++ ++def VSETALLNEZ_D : LSX_SET<0b0111001010011100101111>, ++ LSX_SET_DESC_BASE<"vsetallnez.d", LSX128DOpnd>; ++ ++class LSX_CBRANCH_PSEUDO_DESC_BASE : ++ LoongArchPseudo<(outs GPR32Opnd:$rd), ++ (ins RCVS:$vj), ++ [(set GPR32Opnd:$rd, (OpNode (TyNode RCVS:$vj)))]> { ++ bit usesCustomInserter = 1; ++} ++ ++def SNZ_B_PSEUDO : LSX_CBRANCH_PSEUDO_DESC_BASE; ++def SNZ_H_PSEUDO : LSX_CBRANCH_PSEUDO_DESC_BASE; ++def SNZ_W_PSEUDO : LSX_CBRANCH_PSEUDO_DESC_BASE; ++def SNZ_D_PSEUDO : LSX_CBRANCH_PSEUDO_DESC_BASE; ++def SNZ_V_PSEUDO : LSX_CBRANCH_PSEUDO_DESC_BASE; ++ ++def SZ_B_PSEUDO : LSX_CBRANCH_PSEUDO_DESC_BASE; ++def SZ_H_PSEUDO : LSX_CBRANCH_PSEUDO_DESC_BASE; ++def SZ_W_PSEUDO : LSX_CBRANCH_PSEUDO_DESC_BASE; ++def SZ_D_PSEUDO : LSX_CBRANCH_PSEUDO_DESC_BASE; ++def SZ_V_PSEUDO : LSX_CBRANCH_PSEUDO_DESC_BASE; ++ ++ ++def VFMADD_S : LSX_VR4MUL<0b000010010001>, ++ LSX_4RF<"vfmadd.s", int_loongarch_lsx_vfmadd_s, LSX128WOpnd>; ++ ++def VFMADD_D : LSX_VR4MUL<0b000010010010>, ++ LSX_4RF<"vfmadd.d", int_loongarch_lsx_vfmadd_d, LSX128DOpnd>; ++ ++def VFMSUB_S : LSX_VR4MUL<0b000010010101>, ++ LSX_4RF<"vfmsub.s", int_loongarch_lsx_vfmsub_s, LSX128WOpnd>; ++ ++def VFMSUB_D : LSX_VR4MUL<0b000010010110>, ++ LSX_4RF<"vfmsub.d", int_loongarch_lsx_vfmsub_d, LSX128DOpnd>; ++ ++def VFNMADD_S : LSX_VR4MUL<0b000010011001>, ++ LSX_4RF<"vfnmadd.s", int_loongarch_lsx_vfnmadd_s, LSX128WOpnd>; ++ ++def VFNMADD_D : LSX_VR4MUL<0b000010011010>, ++ LSX_4RF<"vfnmadd.d", int_loongarch_lsx_vfnmadd_d, LSX128DOpnd>; ++ ++def VFNMSUB_S : LSX_VR4MUL<0b000010011101>, ++ LSX_4RF<"vfnmsub.s", int_loongarch_lsx_vfnmsub_s, LSX128WOpnd>; ++ ++def VFNMSUB_D : LSX_VR4MUL<0b000010011110>, ++ LSX_4RF<"vfnmsub.d", int_loongarch_lsx_vfnmsub_d, LSX128DOpnd>; ++ ++ ++// vfmadd: vj * vk + va ++def : LSXPat<(fma v2f64:$vj, v2f64:$vk, v2f64:$va), ++ (VFMADD_D $vj, $vk, $va)>; ++ ++def : LSXPat<(fma v4f32:$vj, v4f32:$vk, v4f32:$va), ++ (VFMADD_S $vj, $vk, $va)>; ++ ++ ++// vfmsub: vj * vk - va ++def : LSXPat<(fma v2f64:$vj, v2f64:$vk, (fneg v2f64:$va)), ++ (VFMSUB_D v2f64:$vj, v2f64:$vk, v2f64:$va)>; ++ ++def : LSXPat<(fma v4f32:$vj, v4f32:$vk, (fneg v4f32:$va)), ++ (VFMSUB_S v4f32:$vj, v4f32:$vk, v4f32:$va)>; ++ ++ ++// vfnmadd: -(vj * vk + va) ++def : LSXPat<(fma (fneg v2f64:$vj), v2f64:$vk, (fneg v2f64:$va)), ++ (VFNMADD_D v2f64:$vj, v2f64:$vk, v2f64:$va)>; ++ ++def : LSXPat<(fma (fneg v4f32:$vj), v4f32:$vk, (fneg v4f32:$va)), ++ (VFNMADD_S v4f32:$vj, v4f32:$vk, v4f32:$va)>; ++ ++// vfnmsub: -(vj * vk - va) ++def : LSXPat<(fma (fneg v2f64:$vj), v2f64:$vk, v2f64:$va), ++ (VFNMSUB_D v2f64:$vj, v2f64:$vk, v2f64:$va)>; ++ ++def : LSXPat<(fma (fneg v4f32:$vj), v4f32:$vk, v4f32:$va), ++ (VFNMSUB_S v4f32:$vj, v4f32:$vk, v4f32:$va)>; ++ ++ ++def VFCMP_CAF_S : LSX_VFCMP<0b000011000101>, ++ LSX_VFCMP_Reg3<"vfcmp.caf.s", LSX128WOpnd, LSX128WOpnd, LSX128WOpnd, int_loongarch_lsx_vfcmp_caf_s>{ ++ bits<5> cond=0x0; ++ } ++ ++def VFCMP_CAF_D : LSX_VFCMP<0b000011000110>, ++ LSX_VFCMP_Reg3<"vfcmp.caf.d", LSX128DOpnd, LSX128DOpnd, LSX128DOpnd, int_loongarch_lsx_vfcmp_caf_d>{ ++ bits<5> cond=0x0; ++ } ++ ++ ++def VFCMP_COR_S : LSX_VFCMP<0b000011000101>, ++ LSX_VFCMP_Reg3<"vfcmp.cor.s", LSX128WOpnd, LSX128WOpnd, LSX128WOpnd, vfsetord_v4f32>{ ++ bits<5> cond=0x14; ++ } ++ ++def VFCMP_COR_D : LSX_VFCMP<0b000011000110>, ++ LSX_VFCMP_Reg3<"vfcmp.cor.d", LSX128DOpnd, LSX128DOpnd, LSX128DOpnd, vfsetord_v2f64>{ ++ bits<5> cond=0x14; ++ } ++ ++ ++def VFCMP_CUN_S : LSX_VFCMP<0b000011000101>, ++ LSX_VFCMP_Reg3<"vfcmp.cun.s", LSX128WOpnd, LSX128WOpnd, LSX128WOpnd, vfsetun_v4f32>{ ++ bits<5> cond=0x8; ++ } ++ ++def VFCMP_CUN_D : LSX_VFCMP<0b000011000110>, ++ LSX_VFCMP_Reg3<"vfcmp.cun.d", LSX128DOpnd, LSX128DOpnd, LSX128DOpnd, vfsetun_v2f64>{ ++ bits<5> cond=0x8; ++ } ++ ++ ++def VFCMP_CUNE_S : LSX_VFCMP<0b000011000101>, ++ LSX_VFCMP_Reg3<"vfcmp.cune.s", LSX128WOpnd, LSX128WOpnd, LSX128WOpnd, vfsetune_v4f32>{ ++ bits<5> cond=0x18; ++ } ++ ++def VFCMP_CUNE_D : LSX_VFCMP<0b000011000110>, ++ LSX_VFCMP_Reg3<"vfcmp.cune.d", LSX128DOpnd, LSX128DOpnd, LSX128DOpnd, vfsetune_v2f64>{ ++ bits<5> cond=0x18; ++ } ++ ++ ++def VFCMP_CUEQ_S : LSX_VFCMP<0b000011000101>, ++ LSX_VFCMP_Reg3<"vfcmp.cueq.s", LSX128WOpnd, LSX128WOpnd, LSX128WOpnd, vfsetueq_v4f32>{ ++ bits<5> cond=0xc; ++ } ++ ++def VFCMP_CUEQ_D : LSX_VFCMP<0b000011000110>, ++ LSX_VFCMP_Reg3<"vfcmp.cueq.d", LSX128DOpnd, LSX128DOpnd, LSX128DOpnd, vfsetueq_v2f64>{ ++ bits<5> cond=0xc; ++ } ++ ++def VFCMP_CEQ_S : LSX_VFCMP<0b000011000101>, ++ LSX_VFCMP_Reg3<"vfcmp.ceq.s", LSX128WOpnd, LSX128WOpnd, LSX128WOpnd, vfsetoeq_v4f32>{ ++ bits<5> cond=0x4; ++ } ++ ++def VFCMP_CEQ_D : LSX_VFCMP<0b000011000110>, ++ LSX_VFCMP_Reg3<"vfcmp.ceq.d", LSX128DOpnd, LSX128DOpnd, LSX128DOpnd, vfsetoeq_v2f64>{ ++ bits<5> cond=0x4; ++ } ++ ++ ++def VFCMP_CNE_S : LSX_VFCMP<0b000011000101>, ++ LSX_VFCMP_Reg3<"vfcmp.cne.s", LSX128WOpnd, LSX128WOpnd, LSX128WOpnd, vfsetone_v4f32>{ ++ bits<5> cond=0x10; ++ } ++ ++def VFCMP_CNE_D : LSX_VFCMP<0b000011000110>, ++ LSX_VFCMP_Reg3<"vfcmp.cne.d", LSX128DOpnd, LSX128DOpnd, LSX128DOpnd, vfsetone_v2f64>{ ++ bits<5> cond=0x10; ++ } ++ ++ ++def VFCMP_CLT_S : LSX_VFCMP<0b000011000101>, ++ LSX_VFCMP_Reg3<"vfcmp.clt.s", LSX128WOpnd, LSX128WOpnd, LSX128WOpnd, vfsetolt_v4f32>{ ++ bits<5> cond=0x2; ++ } ++ ++def VFCMP_CLT_D : LSX_VFCMP<0b000011000110>, ++ LSX_VFCMP_Reg3<"vfcmp.clt.d", LSX128DOpnd, LSX128DOpnd, LSX128DOpnd, vfsetolt_v2f64>{ ++ bits<5> cond=0x2; ++ } ++ ++ ++def VFCMP_CULT_S : LSX_VFCMP<0b000011000101>, ++ LSX_VFCMP_Reg3<"vfcmp.cult.s", LSX128WOpnd, LSX128WOpnd, LSX128WOpnd, vfsetult_v4f32>{ ++ bits<5> cond=0xa; ++ } ++ ++def VFCMP_CULT_D : LSX_VFCMP<0b000011000110>, ++ LSX_VFCMP_Reg3<"vfcmp.cult.d", LSX128DOpnd, LSX128DOpnd, LSX128DOpnd, vfsetult_v2f64>{ ++ bits<5> cond=0xa; ++ } ++ ++ ++def VFCMP_CLE_S : LSX_VFCMP<0b000011000101>, ++ LSX_VFCMP_Reg3<"vfcmp.cle.s", LSX128WOpnd, LSX128WOpnd, LSX128WOpnd, vfsetole_v4f32>{ ++ bits<5> cond=0x6; ++ } ++ ++def VFCMP_CLE_D : LSX_VFCMP<0b000011000110>, ++ LSX_VFCMP_Reg3<"vfcmp.cle.d", LSX128DOpnd, LSX128DOpnd, LSX128DOpnd, vfsetole_v2f64>{ ++ bits<5> cond=0x6; ++ } ++ ++ ++def VFCMP_CULE_S : LSX_VFCMP<0b000011000101>, ++ LSX_VFCMP_Reg3<"vfcmp.cule.s", LSX128WOpnd, LSX128WOpnd, LSX128WOpnd, vfsetule_v4f32>{ ++ bits<5> cond=0xe; ++ } ++ ++def VFCMP_CULE_D : LSX_VFCMP<0b000011000110>, ++ LSX_VFCMP_Reg3<"vfcmp.cule.d", LSX128DOpnd, LSX128DOpnd, LSX128DOpnd, vfsetule_v2f64>{ ++ bits<5> cond=0xe; ++ } ++ ++ ++def VFCMP_SAF_S : LSX_VFCMP<0b000011000101>, ++ LSX_VFCMP_Reg3<"vfcmp.saf.s", LSX128WOpnd, LSX128WOpnd, LSX128WOpnd, int_loongarch_lsx_vfcmp_saf_s>{ ++ bits<5> cond=0x1; ++ } ++ ++def VFCMP_SAF_D : LSX_VFCMP<0b000011000110>, ++ LSX_VFCMP_Reg3<"vfcmp.saf.d", LSX128DOpnd, LSX128DOpnd, LSX128DOpnd, int_loongarch_lsx_vfcmp_saf_d>{ ++ bits<5> cond=0x1; ++ } ++ ++def VFCMP_SOR_S : LSX_VFCMP<0b000011000101>, ++ LSX_VFCMP_Reg3<"vfcmp.sor.s", LSX128WOpnd, LSX128WOpnd, LSX128WOpnd, int_loongarch_lsx_vfcmp_sor_s>{ ++ bits<5> cond=0x15; ++ } ++ ++def VFCMP_SOR_D : LSX_VFCMP<0b000011000110>, ++ LSX_VFCMP_Reg3<"vfcmp.sor.d", LSX128DOpnd, LSX128DOpnd, LSX128DOpnd, int_loongarch_lsx_vfcmp_sor_d>{ ++ bits<5> cond=0x15; ++ } ++ ++def VFCMP_SUN_S : LSX_VFCMP<0b000011000101>, ++ LSX_VFCMP_Reg3<"vfcmp.sun.s", LSX128WOpnd, LSX128WOpnd, LSX128WOpnd, int_loongarch_lsx_vfcmp_sun_s>{ ++ bits<5> cond=0x9; ++ } ++ ++def VFCMP_SUN_D : LSX_VFCMP<0b000011000110>, ++ LSX_VFCMP_Reg3<"vfcmp.sun.d", LSX128DOpnd, LSX128DOpnd, LSX128DOpnd, int_loongarch_lsx_vfcmp_sun_d>{ ++ bits<5> cond=0x9; ++ } ++ ++def VFCMP_SUNE_S : LSX_VFCMP<0b000011000101>, ++ LSX_VFCMP_Reg3<"vfcmp.sune.s", LSX128WOpnd, LSX128WOpnd, LSX128WOpnd, int_loongarch_lsx_vfcmp_sune_s>{ ++ bits<5> cond=0x19; ++ } ++ ++def VFCMP_SUNE_D : LSX_VFCMP<0b000011000110>, ++ LSX_VFCMP_Reg3<"vfcmp.sune.d", LSX128DOpnd, LSX128DOpnd, LSX128DOpnd, int_loongarch_lsx_vfcmp_sune_d>{ ++ bits<5> cond=0x19; ++ } ++ ++def VFCMP_SUEQ_S : LSX_VFCMP<0b000011000101>, ++ LSX_VFCMP_Reg3<"vfcmp.sueq.s", LSX128WOpnd, LSX128WOpnd, LSX128WOpnd, int_loongarch_lsx_vfcmp_sueq_s>{ ++ bits<5> cond=0xd; ++ } ++ ++def VFCMP_SUEQ_D : LSX_VFCMP<0b000011000110>, ++ LSX_VFCMP_Reg3<"vfcmp.sueq.d", LSX128DOpnd, LSX128DOpnd, LSX128DOpnd, int_loongarch_lsx_vfcmp_sueq_d>{ ++ bits<5> cond=0xd; ++ } ++ ++def VFCMP_SEQ_S : LSX_VFCMP<0b000011000101>, ++ LSX_VFCMP_Reg3<"vfcmp.seq.s", LSX128WOpnd, LSX128WOpnd, LSX128WOpnd, int_loongarch_lsx_vfcmp_seq_s>{ ++ bits<5> cond=0x5; ++ } ++ ++def VFCMP_SEQ_D : LSX_VFCMP<0b000011000110>, ++ LSX_VFCMP_Reg3<"vfcmp.seq.d", LSX128DOpnd, LSX128DOpnd, LSX128DOpnd, int_loongarch_lsx_vfcmp_seq_d>{ ++ bits<5> cond=0x5; ++ } ++ ++def VFCMP_SNE_S : LSX_VFCMP<0b000011000101>, ++ LSX_VFCMP_Reg3<"vfcmp.sne.s", LSX128WOpnd, LSX128WOpnd, LSX128WOpnd, int_loongarch_lsx_vfcmp_sne_s>{ ++ bits<5> cond=0x11; ++ } ++ ++def VFCMP_SNE_D : LSX_VFCMP<0b000011000110>, ++ LSX_VFCMP_Reg3<"vfcmp.sne.d", LSX128DOpnd, LSX128DOpnd, LSX128DOpnd, int_loongarch_lsx_vfcmp_sne_d>{ ++ bits<5> cond=0x11; ++ } ++ ++def VFCMP_SLT_S : LSX_VFCMP<0b000011000101>, ++ LSX_VFCMP_Reg3<"vfcmp.slt.s", LSX128WOpnd, LSX128WOpnd, LSX128WOpnd, int_loongarch_lsx_vfcmp_slt_s>{ ++ bits<5> cond=0x3; ++ } ++ ++def VFCMP_SLT_D : LSX_VFCMP<0b000011000110>, ++ LSX_VFCMP_Reg3<"vfcmp.slt.d", LSX128DOpnd, LSX128DOpnd, LSX128DOpnd, int_loongarch_lsx_vfcmp_slt_d>{ ++ bits<5> cond=0x3; ++ } ++ ++def VFCMP_SULT_S : LSX_VFCMP<0b000011000101>, ++ LSX_VFCMP_Reg3<"vfcmp.sult.s", LSX128WOpnd, LSX128WOpnd, LSX128WOpnd, int_loongarch_lsx_vfcmp_sult_s>{ ++ bits<5> cond=0xb; ++ } ++ ++def VFCMP_SULT_D : LSX_VFCMP<0b000011000110>, ++ LSX_VFCMP_Reg3<"vfcmp.sult.d", LSX128DOpnd, LSX128DOpnd, LSX128DOpnd, int_loongarch_lsx_vfcmp_sult_d>{ ++ bits<5> cond=0xb; ++ } ++ ++def VFCMP_SLE_S : LSX_VFCMP<0b000011000101>, ++ LSX_VFCMP_Reg3<"vfcmp.sle.s", LSX128WOpnd, LSX128WOpnd, LSX128WOpnd, int_loongarch_lsx_vfcmp_sle_s>{ ++ bits<5> cond=0x7; ++ } ++ ++def VFCMP_SLE_D : LSX_VFCMP<0b000011000110>, ++ LSX_VFCMP_Reg3<"vfcmp.sle.d", LSX128DOpnd, LSX128DOpnd, LSX128DOpnd, int_loongarch_lsx_vfcmp_sle_d>{ ++ bits<5> cond=0x7; ++ } ++ ++def VFCMP_SULE_S : LSX_VFCMP<0b000011000101>, ++ LSX_VFCMP_Reg3<"vfcmp.sule.s", LSX128WOpnd, LSX128WOpnd, LSX128WOpnd, int_loongarch_lsx_vfcmp_sule_s>{ ++ bits<5> cond=0xf; ++ } ++ ++def VFCMP_SULE_D : LSX_VFCMP<0b000011000110>, ++ LSX_VFCMP_Reg3<"vfcmp.sule.d", LSX128DOpnd, LSX128DOpnd, LSX128DOpnd, int_loongarch_lsx_vfcmp_sule_d>{ ++ bits<5> cond=0xf; ++ } ++ ++def VBITSEL_V : LSX_VR4MUL<0b000011010001>, ++ LSX_VMul_Reg4<"vbitsel.v", LSX128BOpnd, LSX128BOpnd, LSX128BOpnd, LSX128BOpnd, int_loongarch_lsx_vbitsel_v>; ++ ++def VSHUF_B : LSX_VR4MUL<0b000011010101>, ++ LSX_3R_4R_VSHF_DESC_BASE<"vshuf.b", LSX128BOpnd>; ++ ++ ++class LSX_BSEL_PSEUDO_BASE : ++ LSXPseudo<(outs RO:$vd), (ins RO:$vd_in, RO:$vs, RO:$vt), ++ [(set RO:$vd, (Ty (vselect RO:$vd_in, RO:$vt, RO:$vs)))]>, ++ PseudoInstExpansion<(VBITSEL_V LSX128BOpnd:$vd, LSX128BOpnd:$vs, ++ LSX128BOpnd:$vt, LSX128BOpnd:$vd_in)> { ++ let Constraints = "$vd_in = $vd"; ++} ++ ++def BSEL_B_PSEUDO : LSX_BSEL_PSEUDO_BASE; ++def BSEL_H_PSEUDO : LSX_BSEL_PSEUDO_BASE; ++def BSEL_W_PSEUDO : LSX_BSEL_PSEUDO_BASE; ++def BSEL_D_PSEUDO : LSX_BSEL_PSEUDO_BASE; ++def BSEL_FW_PSEUDO : LSX_BSEL_PSEUDO_BASE; ++def BSEL_FD_PSEUDO : LSX_BSEL_PSEUDO_BASE; ++ ++ ++class LSX_LD_DESC_BASE { ++ dag OutOperandList = (outs ROVD:$vd); ++ dag InOperandList = (ins MemOpnd:$addr); ++ string AsmString = !strconcat(instr_asm, "\t$vd, $addr"); ++ list Pattern = [(set ROVD:$vd, (OpNode (iPTR Addr:$addr)))]; ++ string DecoderMethod = "DecodeLSX128memlsl"; ++} ++ ++let mayLoad = 1 in { ++def VLDREPL_B : LSX_SI12_S<0b0011000010>, ++ LSX_LD_DESC_BASE<"vldrepl.b", vldrepl_v16i8, LSX128BOpnd>; ++ ++def VLDREPL_H : LSX_SI11_S<0b00110000010>, ++ LSX_LD_DESC_BASE<"vldrepl.h", vldrepl_v8i16, LSX128HOpnd, mem_simm11_lsl1, addrimm11lsl1>; ++ ++def VLDREPL_W : LSX_SI10_S<0b001100000010>, ++ LSX_LD_DESC_BASE<"vldrepl.w", vldrepl_v4i32, LSX128WOpnd, mem_simm10_lsl2, addrimm10lsl2>; ++ ++def VLDREPL_D : LSX_SI9_S<0b0011000000010>, ++ LSX_LD_DESC_BASE<"vldrepl.d", vldrepl_v2i64, LSX128DOpnd, mem_simm9_lsl3, addrimm9lsl3>; ++} ++ ++ ++def VSTELM_B : LSX_SI8_idx4<0b0011000110>, ++ LSX_I8_U4_DESC_BASE<"vstelm.b", int_loongarch_lsx_vstelm_b, simm8_32, immSExt8, LSX128BOpnd>; ++ ++def VSTELM_H : LSX_SI8_idx3<0b00110001010>, ++ LSX_I8_U3_DESC_BASE<"vstelm.h", int_loongarch_lsx_vstelm_h, immSExt8_1_O, immSExt8, LSX128HOpnd>; ++ ++def VSTELM_W : LSX_SI8_idx2<0b001100010010>, ++ LSX_I8_U2_DESC_BASE<"vstelm.w", int_loongarch_lsx_vstelm_w, immSExt8_2_O, immSExt8, LSX128WOpnd>; ++ ++def VSTELM_D : LSX_SI8_idx1<0b0011000100010>, ++ LSX_I8_U1_DESC_BASE<"vstelm.d", int_loongarch_lsx_vstelm_d, immSExt8_3_O, immSExt8, LSX128DOpnd>; ++ ++ ++let mayLoad = 1, canFoldAsLoad = 1 in { ++ def VLDX : LSX_3R_2GP<0b00111000010000000>, ++ LSX_LDX_LA<"vldx", int_loongarch_lsx_vldx, GPR64Opnd, LSX128BOpnd>; ++} ++ ++let mayStore = 1 in{ ++ def VSTX : LSX_3R_2GP<0b00111000010001000>, ++ LSX_SDX_LA<"vstx", int_loongarch_lsx_vstx, GPR64Opnd, LSX128BOpnd>; ++} ++ ++ ++def VADDWEV_H_B : LSX_3R<0b01110000000111100>, ++ LSX_3R_DESC_BASE<"vaddwev.h.b", int_loongarch_lsx_vaddwev_h_b, LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VADDWEV_W_H : LSX_3R<0b01110000000111101>, ++ LSX_3R_DESC_BASE<"vaddwev.w.h", int_loongarch_lsx_vaddwev_w_h, LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VADDWEV_D_W : LSX_3R<0b01110000000111110>, ++ LSX_3R_DESC_BASE<"vaddwev.d.w", int_loongarch_lsx_vaddwev_d_w, LSX128DOpnd, LSX128WOpnd, LSX128WOpnd> ; ++ ++def VADDWEV_Q_D : LSX_3R<0b01110000000111111>, ++ LSX_3R_DESC_BASE<"vaddwev.q.d", int_loongarch_lsx_vaddwev_q_d, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VSUBWEV_H_B : LSX_3R<0b01110000001000000>, ++ LSX_3R_DESC_BASE<"vsubwev.h.b", int_loongarch_lsx_vsubwev_h_b, LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VSUBWEV_W_H : LSX_3R<0b01110000001000001>, ++ LSX_3R_DESC_BASE<"vsubwev.w.h", int_loongarch_lsx_vsubwev_w_h, LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VSUBWEV_D_W : LSX_3R<0b01110000001000010>, ++ LSX_3R_DESC_BASE<"vsubwev.d.w", int_loongarch_lsx_vsubwev_d_w, LSX128DOpnd, LSX128WOpnd, LSX128WOpnd> ; ++ ++def VSUBWEV_Q_D : LSX_3R<0b01110000001000011>, ++ LSX_3R_DESC_BASE<"vsubwev.q.d", int_loongarch_lsx_vsubwev_q_d, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VADDWOD_H_B : LSX_3R<0b01110000001000100>, ++ LSX_3R_DESC_BASE<"vaddwod.h.b", int_loongarch_lsx_vaddwod_h_b, LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VADDWOD_W_H : LSX_3R<0b01110000001000101>, ++ LSX_3R_DESC_BASE<"vaddwod.w.h", int_loongarch_lsx_vaddwod_w_h, LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VADDWOD_D_W : LSX_3R<0b01110000001000110>, ++ LSX_3R_DESC_BASE<"vaddwod.d.w", int_loongarch_lsx_vaddwod_d_w, LSX128DOpnd, LSX128WOpnd, LSX128WOpnd> ; ++ ++def VADDWOD_Q_D : LSX_3R<0b01110000001000111>, ++ LSX_3R_DESC_BASE<"vaddwod.q.d", int_loongarch_lsx_vaddwod_q_d, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VSUBWOD_H_B : LSX_3R<0b01110000001001000>, ++ LSX_3R_DESC_BASE<"vsubwod.h.b", int_loongarch_lsx_vsubwod_h_b, LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VSUBWOD_W_H : LSX_3R<0b01110000001001001>, ++ LSX_3R_DESC_BASE<"vsubwod.w.h", int_loongarch_lsx_vsubwod_w_h, LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VSUBWOD_D_W : LSX_3R<0b01110000001001010>, ++ LSX_3R_DESC_BASE<"vsubwod.d.w", int_loongarch_lsx_vsubwod_d_w, LSX128DOpnd, LSX128WOpnd, LSX128WOpnd> ; ++ ++def VSUBWOD_Q_D : LSX_3R<0b01110000001001011>, ++ LSX_3R_DESC_BASE<"vsubwod.q.d", int_loongarch_lsx_vsubwod_q_d, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VADDWEV_H_BU : LSX_3R<0b01110000001011100>, ++ LSX_3R_DESC_BASE<"vaddwev.h.bu", int_loongarch_lsx_vaddwev_h_bu, LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VADDWEV_W_HU : LSX_3R<0b01110000001011101>, ++ LSX_3R_DESC_BASE<"vaddwev.w.hu", int_loongarch_lsx_vaddwev_w_hu, LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VADDWEV_D_WU : LSX_3R<0b01110000001011110>, ++ LSX_3R_DESC_BASE<"vaddwev.d.wu", int_loongarch_lsx_vaddwev_d_wu, LSX128DOpnd, LSX128WOpnd, LSX128WOpnd> ; ++ ++def VADDWEV_Q_DU : LSX_3R<0b01110000001011111>, ++ LSX_3R_DESC_BASE<"vaddwev.q.du", int_loongarch_lsx_vaddwev_q_du, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VSUBWEV_H_BU : LSX_3R<0b01110000001100000>, ++ LSX_3R_DESC_BASE<"vsubwev.h.bu", int_loongarch_lsx_vsubwev_h_bu, LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VSUBWEV_W_HU : LSX_3R<0b01110000001100001>, ++ LSX_3R_DESC_BASE<"vsubwev.w.hu", int_loongarch_lsx_vsubwev_w_hu, LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VSUBWEV_D_WU : LSX_3R<0b01110000001100010>, ++ LSX_3R_DESC_BASE<"vsubwev.d.wu", int_loongarch_lsx_vsubwev_d_wu, LSX128DOpnd, LSX128WOpnd, LSX128WOpnd> ; ++ ++def VSUBWEV_Q_DU : LSX_3R<0b01110000001100011>, ++ LSX_3R_DESC_BASE<"vsubwev.q.du", int_loongarch_lsx_vsubwev_q_du, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VADDWOD_H_BU : LSX_3R<0b01110000001100100>, ++ LSX_3R_DESC_BASE<"vaddwod.h.bu", int_loongarch_lsx_vaddwod_h_bu, LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VADDWOD_W_HU : LSX_3R<0b01110000001100101>, ++ LSX_3R_DESC_BASE<"vaddwod.w.hu", int_loongarch_lsx_vaddwod_w_hu, LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VADDWOD_D_WU : LSX_3R<0b01110000001100110>, ++ LSX_3R_DESC_BASE<"vaddwod.d.wu", int_loongarch_lsx_vaddwod_d_wu, LSX128DOpnd, LSX128WOpnd, LSX128WOpnd> ; ++ ++def VADDWOD_Q_DU : LSX_3R<0b01110000001100111>, ++ LSX_3R_DESC_BASE<"vaddwod.q.du", int_loongarch_lsx_vaddwod_q_du, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VSUBWOD_H_BU : LSX_3R<0b01110000001101000>, ++ LSX_3R_DESC_BASE<"vsubwod.h.bu", int_loongarch_lsx_vsubwod_h_bu, LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VSUBWOD_W_HU : LSX_3R<0b01110000001101001>, ++ LSX_3R_DESC_BASE<"vsubwod.w.hu", int_loongarch_lsx_vsubwod_w_hu, LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VSUBWOD_D_WU : LSX_3R<0b01110000001101010>, ++ LSX_3R_DESC_BASE<"vsubwod.d.wu", int_loongarch_lsx_vsubwod_d_wu, LSX128DOpnd, LSX128WOpnd, LSX128WOpnd> ; ++ ++def VSUBWOD_Q_DU : LSX_3R<0b01110000001101011>, ++ LSX_3R_DESC_BASE<"vsubwod.q.du", int_loongarch_lsx_vsubwod_q_du, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VADDWEV_H_BU_B : LSX_3R<0b01110000001111100>, ++ LSX_3R_DESC_BASE<"vaddwev.h.bu.b", int_loongarch_lsx_vaddwev_h_bu_b, LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VADDWEV_W_HU_H : LSX_3R<0b01110000001111101>, ++ LSX_3R_DESC_BASE<"vaddwev.w.hu.h", int_loongarch_lsx_vaddwev_w_hu_h, LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VADDWEV_D_WU_W : LSX_3R<0b01110000001111110>, ++ LSX_3R_DESC_BASE<"vaddwev.d.wu.w", int_loongarch_lsx_vaddwev_d_wu_w, LSX128DOpnd, LSX128WOpnd, LSX128WOpnd> ; ++ ++def VADDWEV_Q_DU_D : LSX_3R<0b01110000001111111>, ++ LSX_3R_DESC_BASE<"vaddwev.q.du.d", int_loongarch_lsx_vaddwev_q_du_d, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VADDWOD_H_BU_B : LSX_3R<0b01110000010000000>, ++ LSX_3R_DESC_BASE<"vaddwod.h.bu.b", int_loongarch_lsx_vaddwod_h_bu_b, LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VADDWOD_W_HU_H : LSX_3R<0b01110000010000001>, ++ LSX_3R_DESC_BASE<"vaddwod.w.hu.h", int_loongarch_lsx_vaddwod_w_hu_h, LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VADDWOD_D_WU_W : LSX_3R<0b01110000010000010>, ++ LSX_3R_DESC_BASE<"vaddwod.d.wu.w", int_loongarch_lsx_vaddwod_d_wu_w, LSX128DOpnd, LSX128WOpnd, LSX128WOpnd> ; ++ ++def VADDWOD_Q_DU_D : LSX_3R<0b01110000010000011>, ++ LSX_3R_DESC_BASE<"vaddwod.q.du.d", int_loongarch_lsx_vaddwod_q_du_d, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VHADDW_Q_D : LSX_3R<0b01110000010101011>, ++ LSX_3R_DESC_BASE<"vhaddw.q.d", int_loongarch_lsx_vhaddw_q_d, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++def VHSUBW_Q_D : LSX_3R<0b01110000010101111>, ++ LSX_3R_DESC_BASE<"vhsubw.q.d", int_loongarch_lsx_vhsubw_q_d, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VHADDW_QU_DU : LSX_3R<0b01110000010110011>, ++ LSX_3R_DESC_BASE<"vhaddw.qu.du", int_loongarch_lsx_vhaddw_qu_du, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++def VHSUBW_QU_DU : LSX_3R<0b01110000010110111>, ++ LSX_3R_DESC_BASE<"vhsubw.qu.du", int_loongarch_lsx_vhsubw_qu_du, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VMUH_B : LSX_3R<0b01110000100001100>, ++ LSX_3R_DESC_BASE<"vmuh.b", int_loongarch_lsx_vmuh_b, LSX128BOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VMUH_H : LSX_3R<0b01110000100001101>, ++ LSX_3R_DESC_BASE<"vmuh.h", int_loongarch_lsx_vmuh_h, LSX128HOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VMUH_W : LSX_3R<0b01110000100001110>, ++ LSX_3R_DESC_BASE<"vmuh.w", int_loongarch_lsx_vmuh_w, LSX128WOpnd, LSX128WOpnd, LSX128WOpnd> ; ++ ++def VMUH_D : LSX_3R<0b01110000100001111>, ++ LSX_3R_DESC_BASE<"vmuh.d", int_loongarch_lsx_vmuh_d, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VMUH_BU : LSX_3R<0b01110000100010000>, ++ LSX_3R_DESC_BASE<"vmuh.bu", int_loongarch_lsx_vmuh_bu, LSX128BOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VMUH_HU : LSX_3R<0b01110000100010001>, ++ LSX_3R_DESC_BASE<"vmuh.hu", int_loongarch_lsx_vmuh_hu, LSX128HOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VMUH_WU : LSX_3R<0b01110000100010010>, ++ LSX_3R_DESC_BASE<"vmuh.wu", int_loongarch_lsx_vmuh_wu, LSX128WOpnd, LSX128WOpnd, LSX128WOpnd> ; ++ ++def VMUH_DU : LSX_3R<0b01110000100010011>, ++ LSX_3R_DESC_BASE<"vmuh.du", int_loongarch_lsx_vmuh_du, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VMULWEV_H_B : LSX_3R<0b01110000100100000>, ++ LSX_3R_DESC_BASE<"vmulwev.h.b", int_loongarch_lsx_vmulwev_h_b, LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VMULWEV_W_H : LSX_3R<0b01110000100100001>, ++ LSX_3R_DESC_BASE<"vmulwev.w.h", int_loongarch_lsx_vmulwev_w_h, LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VMULWEV_D_W : LSX_3R<0b01110000100100010>, ++ LSX_3R_DESC_BASE<"vmulwev.d.w", int_loongarch_lsx_vmulwev_d_w, LSX128DOpnd, LSX128WOpnd, LSX128WOpnd> ; ++ ++def VMULWEV_Q_D : LSX_3R<0b01110000100100011>, ++ LSX_3R_DESC_BASE<"vmulwev.q.d", int_loongarch_lsx_vmulwev_q_d, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VMULWOD_H_B : LSX_3R<0b01110000100100100>, ++ LSX_3R_DESC_BASE<"vmulwod.h.b", int_loongarch_lsx_vmulwod_h_b, LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VMULWOD_W_H : LSX_3R<0b01110000100100101>, ++ LSX_3R_DESC_BASE<"vmulwod.w.h", int_loongarch_lsx_vmulwod_w_h, LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VMULWOD_D_W : LSX_3R<0b01110000100100110>, ++ LSX_3R_DESC_BASE<"vmulwod.d.w", int_loongarch_lsx_vmulwod_d_w, LSX128DOpnd, LSX128WOpnd, LSX128WOpnd> ; ++ ++def VMULWOD_Q_D : LSX_3R<0b01110000100100111>, ++ LSX_3R_DESC_BASE<"vmulwod.q.d", int_loongarch_lsx_vmulwod_q_d, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VMULWEV_H_BU : LSX_3R<0b01110000100110000>, ++ LSX_3R_DESC_BASE<"vmulwev.h.bu", int_loongarch_lsx_vmulwev_h_bu, LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VMULWEV_W_HU : LSX_3R<0b01110000100110001>, ++ LSX_3R_DESC_BASE<"vmulwev.w.hu", int_loongarch_lsx_vmulwev_w_hu, LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VMULWEV_D_WU : LSX_3R<0b01110000100110010>, ++ LSX_3R_DESC_BASE<"vmulwev.d.wu", int_loongarch_lsx_vmulwev_d_wu, LSX128DOpnd, LSX128WOpnd, LSX128WOpnd> ; ++ ++def VMULWEV_Q_DU : LSX_3R<0b01110000100110011>, ++ LSX_3R_DESC_BASE<"vmulwev.q.du", int_loongarch_lsx_vmulwev_q_du, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VMULWOD_H_BU : LSX_3R<0b01110000100110100>, ++ LSX_3R_DESC_BASE<"vmulwod.h.bu", int_loongarch_lsx_vmulwod_h_bu, LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VMULWOD_W_HU : LSX_3R<0b01110000100110101>, ++ LSX_3R_DESC_BASE<"vmulwod.w.hu", int_loongarch_lsx_vmulwod_w_hu, LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VMULWOD_D_WU : LSX_3R<0b01110000100110110>, ++ LSX_3R_DESC_BASE<"vmulwod.d.wu", int_loongarch_lsx_vmulwod_d_wu, LSX128DOpnd, LSX128WOpnd, LSX128WOpnd> ; ++ ++def VMULWOD_Q_DU : LSX_3R<0b01110000100110111>, ++ LSX_3R_DESC_BASE<"vmulwod.q.du", int_loongarch_lsx_vmulwod_q_du, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VMULWEV_H_BU_B : LSX_3R<0b01110000101000000>, ++ LSX_3R_DESC_BASE<"vmulwev.h.bu.b", int_loongarch_lsx_vmulwev_h_bu_b, LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VMULWEV_W_HU_H : LSX_3R<0b01110000101000001>, ++ LSX_3R_DESC_BASE<"vmulwev.w.hu.h", int_loongarch_lsx_vmulwev_w_hu_h, LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VMULWEV_D_WU_W : LSX_3R<0b01110000101000010>, ++ LSX_3R_DESC_BASE<"vmulwev.d.wu.w", int_loongarch_lsx_vmulwev_d_wu_w, LSX128DOpnd, LSX128WOpnd, LSX128WOpnd> ; ++ ++def VMULWEV_Q_DU_D : LSX_3R<0b01110000101000011>, ++ LSX_3R_DESC_BASE<"vmulwev.q.du.d", int_loongarch_lsx_vmulwev_q_du_d, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VMULWOD_H_BU_B : LSX_3R<0b01110000101000100>, ++ LSX_3R_DESC_BASE<"vmulwod.h.bu.b", int_loongarch_lsx_vmulwod_h_bu_b, LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VMULWOD_W_HU_H : LSX_3R<0b01110000101000101>, ++ LSX_3R_DESC_BASE<"vmulwod.w.hu.h", int_loongarch_lsx_vmulwod_w_hu_h, LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VMULWOD_D_WU_W : LSX_3R<0b01110000101000110>, ++ LSX_3R_DESC_BASE<"vmulwod.d.wu.w", int_loongarch_lsx_vmulwod_d_wu_w, LSX128DOpnd, LSX128WOpnd, LSX128WOpnd> ; ++ ++def VMULWOD_Q_DU_D : LSX_3R<0b01110000101000111>, ++ LSX_3R_DESC_BASE<"vmulwod.q.du.d", int_loongarch_lsx_vmulwod_q_du_d, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VMADDWEV_H_B : LSX_3R<0b01110000101011000>, ++ LSX_3R_4R_DESC_BASE<"vmaddwev.h.b", int_loongarch_lsx_vmaddwev_h_b, LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VMADDWEV_W_H : LSX_3R<0b01110000101011001>, ++ LSX_3R_4R_DESC_BASE<"vmaddwev.w.h", int_loongarch_lsx_vmaddwev_w_h, LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VMADDWEV_D_W : LSX_3R<0b01110000101011010>, ++ LSX_3R_4R_DESC_BASE<"vmaddwev.d.w", int_loongarch_lsx_vmaddwev_d_w, LSX128DOpnd, LSX128WOpnd, LSX128WOpnd>; ++ ++def VMADDWEV_Q_D : LSX_3R<0b01110000101011011>, ++ LSX_3R_4R_DESC_BASE<"vmaddwev.q.d", int_loongarch_lsx_vmaddwev_q_d, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VMADDWOD_H_B : LSX_3R<0b01110000101011100>, ++ LSX_3R_4R_DESC_BASE<"vmaddwod.h.b", int_loongarch_lsx_vmaddwod_h_b, LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VMADDWOD_W_H : LSX_3R<0b01110000101011101>, ++ LSX_3R_4R_DESC_BASE<"vmaddwod.w.h", int_loongarch_lsx_vmaddwod_w_h, LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VMADDWOD_D_W : LSX_3R<0b01110000101011110>, ++ LSX_3R_4R_DESC_BASE<"vmaddwod.d.w", int_loongarch_lsx_vmaddwod_d_w, LSX128DOpnd, LSX128WOpnd, LSX128WOpnd>; ++ ++def VMADDWOD_Q_D : LSX_3R<0b01110000101011111>, ++ LSX_3R_4R_DESC_BASE<"vmaddwod.q.d", int_loongarch_lsx_vmaddwod_q_d, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VMADDWEV_H_BU : LSX_3R<0b01110000101101000>, ++ LSX_3R_4R_DESC_BASE<"vmaddwev.h.bu", int_loongarch_lsx_vmaddwev_h_bu, LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VMADDWEV_W_HU : LSX_3R<0b01110000101101001>, ++ LSX_3R_4R_DESC_BASE<"vmaddwev.w.hu", int_loongarch_lsx_vmaddwev_w_hu, LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VMADDWEV_D_WU : LSX_3R<0b01110000101101010>, ++ LSX_3R_4R_DESC_BASE<"vmaddwev.d.wu", int_loongarch_lsx_vmaddwev_d_wu, LSX128DOpnd, LSX128WOpnd, LSX128WOpnd>; ++ ++def VMADDWEV_Q_DU : LSX_3R<0b01110000101101011>, ++ LSX_3R_4R_DESC_BASE<"vmaddwev.q.du", int_loongarch_lsx_vmaddwev_q_du, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VMADDWOD_H_BU : LSX_3R<0b01110000101101100>, ++ LSX_3R_4R_DESC_BASE<"vmaddwod.h.bu", int_loongarch_lsx_vmaddwod_h_bu, LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VMADDWOD_W_HU : LSX_3R<0b01110000101101101>, ++ LSX_3R_4R_DESC_BASE<"vmaddwod.w.hu", int_loongarch_lsx_vmaddwod_w_hu, LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VMADDWOD_D_WU : LSX_3R<0b01110000101101110>, ++ LSX_3R_4R_DESC_BASE<"vmaddwod.d.wu", int_loongarch_lsx_vmaddwod_d_wu, LSX128DOpnd, LSX128WOpnd, LSX128WOpnd>; ++ ++def VMADDWOD_Q_DU : LSX_3R<0b01110000101101111>, ++ LSX_3R_4R_DESC_BASE<"vmaddwod.q.du", int_loongarch_lsx_vmaddwod_q_du, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VMADDWEV_H_BU_B : LSX_3R<0b01110000101111000>, ++ LSX_3R_4R_DESC_BASE<"vmaddwev.h.bu.b", int_loongarch_lsx_vmaddwev_h_bu_b, LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VMADDWEV_W_HU_H : LSX_3R<0b01110000101111001>, ++ LSX_3R_4R_DESC_BASE<"vmaddwev.w.hu.h", int_loongarch_lsx_vmaddwev_w_hu_h, LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VMADDWEV_D_WU_W : LSX_3R<0b01110000101111010>, ++ LSX_3R_4R_DESC_BASE<"vmaddwev.d.wu.w", int_loongarch_lsx_vmaddwev_d_wu_w, LSX128DOpnd, LSX128WOpnd, LSX128WOpnd> ; ++ ++def VMADDWEV_Q_DU_D : LSX_3R<0b01110000101111011>, ++ LSX_3R_4R_DESC_BASE<"vmaddwev.q.du.d", int_loongarch_lsx_vmaddwev_q_du_d, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VMADDWOD_H_BU_B : LSX_3R<0b01110000101111100>, ++ LSX_3R_4R_DESC_BASE<"vmaddwod.h.bu.b", int_loongarch_lsx_vmaddwod_h_bu_b, LSX128HOpnd, LSX128BOpnd, LSX128BOpnd>; ++ ++def VMADDWOD_W_HU_H : LSX_3R<0b01110000101111101>, ++ LSX_3R_4R_DESC_BASE<"vmaddwod.w.hu.h", int_loongarch_lsx_vmaddwod_w_hu_h, LSX128WOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VMADDWOD_D_WU_W : LSX_3R<0b01110000101111110>, ++ LSX_3R_4R_DESC_BASE<"vmaddwod.d.wu.w", int_loongarch_lsx_vmaddwod_d_wu_w, LSX128DOpnd, LSX128WOpnd, LSX128WOpnd> ; ++ ++def VMADDWOD_Q_DU_D : LSX_3R<0b01110000101111111>, ++ LSX_3R_4R_DESC_BASE<"vmaddwod.q.du.d", int_loongarch_lsx_vmaddwod_q_du_d, LSX128DOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VSRLN_B_H : LSX_3R<0b01110000111101001>, ++ LSX_3R_DESC_BASE<"vsrln.b.h", int_loongarch_lsx_vsrln_b_h, LSX128BOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VSRLN_H_W : LSX_3R<0b01110000111101010>, ++ LSX_3R_DESC_BASE<"vsrln.h.w", int_loongarch_lsx_vsrln_h_w, LSX128HOpnd, LSX128WOpnd, LSX128WOpnd>; ++ ++def VSRLN_W_D : LSX_3R<0b01110000111101011>, ++ LSX_3R_DESC_BASE<"vsrln.w.d", int_loongarch_lsx_vsrln_w_d, LSX128WOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VSRAN_B_H : LSX_3R<0b01110000111101101>, ++ LSX_3R_DESC_BASE<"vsran.b.h", int_loongarch_lsx_vsran_b_h, LSX128BOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VSRAN_H_W : LSX_3R<0b01110000111101110>, ++ LSX_3R_DESC_BASE<"vsran.h.w", int_loongarch_lsx_vsran_h_w, LSX128HOpnd, LSX128WOpnd, LSX128WOpnd>; ++ ++def VSRAN_W_D : LSX_3R<0b01110000111101111>, ++ LSX_3R_DESC_BASE<"vsran.w.d", int_loongarch_lsx_vsran_w_d, LSX128WOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VSRLRN_B_H : LSX_3R<0b01110000111110001>, ++ LSX_3R_DESC_BASE<"vsrlrn.b.h", int_loongarch_lsx_vsrlrn_b_h, LSX128BOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VSRLRN_H_W : LSX_3R<0b01110000111110010>, ++ LSX_3R_DESC_BASE<"vsrlrn.h.w", int_loongarch_lsx_vsrlrn_h_w, LSX128HOpnd, LSX128WOpnd, LSX128WOpnd>; ++ ++def VSRLRN_W_D : LSX_3R<0b01110000111110011>, ++ LSX_3R_DESC_BASE<"vsrlrn.w.d", int_loongarch_lsx_vsrlrn_w_d, LSX128WOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VSRARN_B_H : LSX_3R<0b01110000111110101>, ++ LSX_3R_DESC_BASE<"vsrarn.b.h", int_loongarch_lsx_vsrarn_b_h, LSX128BOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VSRARN_H_W : LSX_3R<0b01110000111110110>, ++ LSX_3R_DESC_BASE<"vsrarn.h.w", int_loongarch_lsx_vsrarn_h_w, LSX128HOpnd, LSX128WOpnd, LSX128WOpnd>; ++ ++def VSRARN_W_D : LSX_3R<0b01110000111110111>, ++ LSX_3R_DESC_BASE<"vsrarn.w.d", int_loongarch_lsx_vsrarn_w_d, LSX128WOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VSSRLN_B_H : LSX_3R<0b01110000111111001>, ++ LSX_3R_DESC_BASE<"vssrln.b.h", int_loongarch_lsx_vssrln_b_h, LSX128BOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VSSRLN_H_W : LSX_3R<0b01110000111111010>, ++ LSX_3R_DESC_BASE<"vssrln.h.w", int_loongarch_lsx_vssrln_h_w, LSX128HOpnd, LSX128WOpnd, LSX128WOpnd>; ++ ++def VSSRLN_W_D : LSX_3R<0b01110000111111011>, ++ LSX_3R_DESC_BASE<"vssrln.w.d", int_loongarch_lsx_vssrln_w_d, LSX128WOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VSSRAN_B_H : LSX_3R<0b01110000111111101>, ++ LSX_3R_DESC_BASE<"vssran.b.h", int_loongarch_lsx_vssran_b_h, LSX128BOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VSSRAN_H_W : LSX_3R<0b01110000111111110>, ++ LSX_3R_DESC_BASE<"vssran.h.w", int_loongarch_lsx_vssran_h_w, LSX128HOpnd, LSX128WOpnd, LSX128WOpnd>; ++ ++def VSSRAN_W_D : LSX_3R<0b01110000111111111>, ++ LSX_3R_DESC_BASE<"vssran.w.d", int_loongarch_lsx_vssran_w_d, LSX128WOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VSSRLRN_B_H : LSX_3R<0b01110001000000001>, ++ LSX_3R_DESC_BASE<"vssrlrn.b.h", int_loongarch_lsx_vssrlrn_b_h, LSX128BOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VSSRLRN_H_W : LSX_3R<0b01110001000000010>, ++ LSX_3R_DESC_BASE<"vssrlrn.h.w", int_loongarch_lsx_vssrlrn_h_w, LSX128HOpnd, LSX128WOpnd, LSX128WOpnd>; ++ ++def VSSRLRN_W_D : LSX_3R<0b01110001000000011>, ++ LSX_3R_DESC_BASE<"vssrlrn.w.d", int_loongarch_lsx_vssrlrn_w_d, LSX128WOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VSSRARN_B_H : LSX_3R<0b01110001000000101>, ++ LSX_3R_DESC_BASE<"vssrarn.b.h", int_loongarch_lsx_vssrarn_b_h, LSX128BOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VSSRARN_H_W : LSX_3R<0b01110001000000110>, ++ LSX_3R_DESC_BASE<"vssrarn.h.w", int_loongarch_lsx_vssrarn_h_w, LSX128HOpnd, LSX128WOpnd, LSX128WOpnd>; ++ ++def VSSRARN_W_D : LSX_3R<0b01110001000000111>, ++ LSX_3R_DESC_BASE<"vssrarn.w.d", int_loongarch_lsx_vssrarn_w_d, LSX128WOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VSSRLN_BU_H : LSX_3R<0b01110001000001001>, ++ LSX_3R_DESC_BASE<"vssrln.bu.h", int_loongarch_lsx_vssrln_bu_h, LSX128BOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VSSRLN_HU_W : LSX_3R<0b01110001000001010>, ++ LSX_3R_DESC_BASE<"vssrln.hu.w", int_loongarch_lsx_vssrln_hu_w, LSX128HOpnd, LSX128WOpnd, LSX128WOpnd>; ++ ++def VSSRLN_WU_D : LSX_3R<0b01110001000001011>, ++ LSX_3R_DESC_BASE<"vssrln.wu.d", int_loongarch_lsx_vssrln_wu_d, LSX128WOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VSSRAN_BU_H : LSX_3R<0b01110001000001101>, ++ LSX_3R_DESC_BASE<"vssran.bu.h", int_loongarch_lsx_vssran_bu_h, LSX128BOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VSSRAN_HU_W : LSX_3R<0b01110001000001110>, ++ LSX_3R_DESC_BASE<"vssran.hu.w", int_loongarch_lsx_vssran_hu_w, LSX128HOpnd, LSX128WOpnd, LSX128WOpnd>; ++ ++def VSSRAN_WU_D : LSX_3R<0b01110001000001111>, ++ LSX_3R_DESC_BASE<"vssran.wu.d", int_loongarch_lsx_vssran_wu_d, LSX128WOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VSSRLRN_BU_H : LSX_3R<0b01110001000010001>, ++ LSX_3R_DESC_BASE<"vssrlrn.bu.h", int_loongarch_lsx_vssrlrn_bu_h, LSX128BOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VSSRLRN_HU_W : LSX_3R<0b01110001000010010>, ++ LSX_3R_DESC_BASE<"vssrlrn.hu.w", int_loongarch_lsx_vssrlrn_hu_w, LSX128HOpnd, LSX128WOpnd, LSX128WOpnd>; ++ ++def VSSRLRN_WU_D : LSX_3R<0b01110001000010011>, ++ LSX_3R_DESC_BASE<"vssrlrn.wu.d", int_loongarch_lsx_vssrlrn_wu_d, LSX128WOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VSSRARN_BU_H : LSX_3R<0b01110001000010101>, ++ LSX_3R_DESC_BASE<"vssrarn.bu.h", int_loongarch_lsx_vssrarn_bu_h, LSX128BOpnd, LSX128HOpnd, LSX128HOpnd>; ++ ++def VSSRARN_HU_W : LSX_3R<0b01110001000010110>, ++ LSX_3R_DESC_BASE<"vssrarn.hu.w", int_loongarch_lsx_vssrarn_hu_w, LSX128HOpnd, LSX128WOpnd, LSX128WOpnd>; ++ ++def VSSRARN_WU_D : LSX_3R<0b01110001000010111>, ++ LSX_3R_DESC_BASE<"vssrarn.wu.d", int_loongarch_lsx_vssrarn_wu_d, LSX128WOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VANDN_V : LSX_3R<0b01110001001010000>, ++ LSX_3R_DESC_BASE<"vandn.v", int_loongarch_lsx_vandn_v, LSX128BOpnd>; ++ ++ ++class LSX_VANDN_PSEUDO_BASE : ++ LSXPseudo<(outs RO:$vd), (ins RO:$vj, RO:$vk), ++ []>, ++ PseudoInstExpansion<(VANDN_V LSX128BOpnd:$vd, ++ LSX128BOpnd:$vj, ++ LSX128BOpnd:$vk)>; ++ ++def VANDN_H_PSEUDO : LSX_VANDN_PSEUDO_BASE; ++def VANDN_W_PSEUDO : LSX_VANDN_PSEUDO_BASE; ++def VANDN_D_PSEUDO : LSX_VANDN_PSEUDO_BASE; ++ ++ ++ ++def VORN_V : LSX_3R<0b01110001001010001>, ++ LSX_3R_DESC_BASE<"vorn.v", int_loongarch_lsx_vorn_v, LSX128BOpnd>; ++ ++ ++class LSX_VORN_PSEUDO_BASE : ++ LSXPseudo<(outs RO:$vd), (ins RO:$vj, RO:$vk), ++ []>, ++ PseudoInstExpansion<(VORN_V LSX128BOpnd:$vd, ++ LSX128BOpnd:$vj, ++ LSX128BOpnd:$vk)>; ++ ++def VORN_H_PSEUDO : LSX_VORN_PSEUDO_BASE; ++def VORN_W_PSEUDO : LSX_VORN_PSEUDO_BASE; ++def VORN_D_PSEUDO : LSX_VORN_PSEUDO_BASE; ++ ++ ++def VFRSTP_B : LSX_3R<0b01110001001010110>, ++ LSX_3R_4R_DESC_BASE<"vfrstp.b", int_loongarch_lsx_vfrstp_b, LSX128BOpnd>; ++ ++def VFRSTP_H : LSX_3R<0b01110001001010111>, ++ LSX_3R_4R_DESC_BASE<"vfrstp.h", int_loongarch_lsx_vfrstp_h, LSX128HOpnd>; ++ ++ ++def VADD_Q : LSX_3R<0b01110001001011010>, IsCommutable, ++ LSX_3R_DESC_BASE<"vadd.q", int_loongarch_lsx_vadd_q, LSX128DOpnd>; ++ ++def VSUB_Q : LSX_3R<0b01110001001011011>, ++ LSX_3R_DESC_BASE<"vsub.q", int_loongarch_lsx_vsub_q, LSX128DOpnd>; ++ ++ ++def VSIGNCOV_B : LSX_3R<0b01110001001011100>, ++ LSX_3R_DESC_BASE<"vsigncov.b", int_loongarch_lsx_vsigncov_b, LSX128BOpnd>; ++ ++def VSIGNCOV_H : LSX_3R<0b01110001001011101>, ++ LSX_3R_DESC_BASE<"vsigncov.h", int_loongarch_lsx_vsigncov_h, LSX128HOpnd>; ++ ++def VSIGNCOV_W : LSX_3R<0b01110001001011110>, ++ LSX_3R_DESC_BASE<"vsigncov.w", int_loongarch_lsx_vsigncov_w, LSX128WOpnd>; ++ ++def VSIGNCOV_D : LSX_3R<0b01110001001011111>, ++ LSX_3R_DESC_BASE<"vsigncov.d", int_loongarch_lsx_vsigncov_d, LSX128DOpnd>; ++ ++ ++def VFCVT_H_S : LSX_3R<0b01110001010001100>, ++ LSX_3RF_DESC_BASE<"vfcvt.h.s", int_loongarch_lsx_vfcvt_h_s, LSX128HOpnd, LSX128WOpnd, LSX128WOpnd>; ++ ++def VFCVT_S_D : LSX_3R<0b01110001010001101>, ++ LSX_3RF_DESC_BASE1<"vfcvt.s.d", int_loongarch_lsx_vfcvt_s_d, LSX128WOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VFFINT_S_L : LSX_3R<0b01110001010010000>, ++ LSX_3RF_DESC_BASE<"vffint.s.l", int_loongarch_lsx_vffint_s_l, LSX128WOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++def VFTINT_W_D : LSX_3R<0b01110001010010011>, ++ LSX_3RF_DESC_BASE<"vftint.w.d", int_loongarch_lsx_vftint_w_d, LSX128WOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VFTINTRZ_W_D : LSX_3R<0b01110001010010110>, ++ LSX_3RF_DESC_BASE<"vftintrz.w.d", int_loongarch_lsx_vftintrz_w_d, LSX128WOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++def VFTINTRP_W_D : LSX_3R<0b01110001010010101>, ++ LSX_3RF_DESC_BASE<"vftintrp.w.d", int_loongarch_lsx_vftintrp_w_d, LSX128WOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++def VFTINTRM_W_D : LSX_3R<0b01110001010010100>, ++ LSX_3RF_DESC_BASE<"vftintrm.w.d", int_loongarch_lsx_vftintrm_w_d, LSX128WOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++def VFTINTRNE_W_D : LSX_3R<0b01110001010010111>, ++ LSX_3RF_DESC_BASE<"vftintrne.w.d", int_loongarch_lsx_vftintrne_w_d, LSX128WOpnd, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VBSRL_V : LSX_I5_U<0b01110010100011101>, ++ LSX_U5_DESC_BASE<"vbsrl.v", int_loongarch_lsx_vbsrl_v, LSX128BOpnd>; ++ ++def VBSLL_V : LSX_I5_U<0b01110010100011100>, ++ LSX_U5_DESC_BASE<"vbsll.v", int_loongarch_lsx_vbsll_v, LSX128BOpnd>; ++ ++ ++def VFRSTPI_B : LSX_I5_U<0b01110010100110100>, ++ LSX_U5_4R_DESC_BASE<"vfrstpi.b", int_loongarch_lsx_vfrstpi_b, LSX128BOpnd>; ++ ++def VFRSTPI_H : LSX_I5_U<0b01110010100110101>, ++ LSX_U5_4R_DESC_BASE<"vfrstpi.h", int_loongarch_lsx_vfrstpi_h, LSX128HOpnd>; ++ ++ ++def VNEG_B : LSX_2R<0b0111001010011100001100>, ++ LSX_2R_DESC_BASE<"vneg.b", int_loongarch_lsx_vneg_b, LSX128BOpnd>; ++ ++def VNEG_H : LSX_2R<0b0111001010011100001101>, ++ LSX_2R_DESC_BASE<"vneg.h", int_loongarch_lsx_vneg_h, LSX128HOpnd>; ++ ++def VNEG_W : LSX_2R<0b0111001010011100001110>, ++ LSX_2R_DESC_BASE<"vneg.w", int_loongarch_lsx_vneg_w, LSX128WOpnd>; ++ ++def VNEG_D : LSX_2R<0b0111001010011100001111>, ++ LSX_2R_DESC_BASE<"vneg.d", int_loongarch_lsx_vneg_d, LSX128DOpnd>; ++ ++ ++def VMSKGEZ_B : LSX_2R<0b0111001010011100010100>, ++ LSX_2R_DESC_BASE<"vmskgez.b", int_loongarch_lsx_vmskgez_b, LSX128BOpnd>; ++ ++def VMSKNZ_B : LSX_2R<0b0111001010011100011000>, ++ LSX_2R_DESC_BASE<"vmsknz.b", int_loongarch_lsx_vmsknz_b, LSX128BOpnd>; ++ ++ ++def VFRINTRM_S : LSX_2R<0b0111001010011101010001>, ++ LSX_2RF_DESC_BASE<"vfrintrm.s", int_loongarch_lsx_vfrintrm_s, LSX128WOpnd>; ++ ++def VFRINTRM_D : LSX_2R<0b0111001010011101010010>, ++ LSX_2RF_DESC_BASE<"vfrintrm.d", int_loongarch_lsx_vfrintrm_d, LSX128DOpnd>; ++ ++ ++def VFRINTRP_S : LSX_2R<0b0111001010011101010101>, ++ LSX_2RF_DESC_BASE<"vfrintrp.s", int_loongarch_lsx_vfrintrp_s, LSX128WOpnd>; ++ ++def VFRINTRP_D : LSX_2R<0b0111001010011101010110>, ++ LSX_2RF_DESC_BASE<"vfrintrp.d", int_loongarch_lsx_vfrintrp_d, LSX128DOpnd>; ++ ++ ++def VFRINTRZ_S : LSX_2R<0b0111001010011101011001>, ++ LSX_2RF_DESC_BASE<"vfrintrz.s", int_loongarch_lsx_vfrintrz_s, LSX128WOpnd>; ++ ++def VFRINTRZ_D : LSX_2R<0b0111001010011101011010>, ++ LSX_2RF_DESC_BASE<"vfrintrz.d", int_loongarch_lsx_vfrintrz_d, LSX128DOpnd>; ++ ++ ++def VFRINTRNE_S : LSX_2R<0b0111001010011101011101>, ++ LSX_2RF_DESC_BASE<"vfrintrne.s", int_loongarch_lsx_vfrintrne_s, LSX128WOpnd>; ++ ++def VFRINTRNE_D : LSX_2R<0b0111001010011101011110>, ++ LSX_2RF_DESC_BASE<"vfrintrne.d", int_loongarch_lsx_vfrintrne_d, LSX128DOpnd>; ++ ++ ++def VFFINTL_D_W : LSX_2R<0b0111001010011110000100>, ++ LSX_2RF_DESC_BASE<"vffintl.d.w", int_loongarch_lsx_vffintl_d_w, LSX128DOpnd, LSX128WOpnd>; ++ ++def VFFINTH_D_W : LSX_2R<0b0111001010011110000101>, ++ LSX_2RF_DESC_BASE<"vffinth.d.w", int_loongarch_lsx_vffinth_d_w, LSX128DOpnd, LSX128WOpnd>; ++ ++ ++def VFTINTRM_W_S : LSX_2R<0b0111001010011110001110>, ++ LSX_2RF_DESC_BASE<"vftintrm.w.s", int_loongarch_lsx_vftintrm_w_s, LSX128WOpnd>; ++ ++def VFTINTRM_L_D : LSX_2R<0b0111001010011110001111>, ++ LSX_2RF_DESC_BASE<"vftintrm.l.d", int_loongarch_lsx_vftintrm_l_d, LSX128DOpnd>; ++ ++ ++def VFTINTRP_W_S : LSX_2R<0b0111001010011110010000>, ++ LSX_2RF_DESC_BASE<"vftintrp.w.s", int_loongarch_lsx_vftintrp_w_s, LSX128WOpnd>; ++ ++def VFTINTRP_L_D : LSX_2R<0b0111001010011110010001>, ++ LSX_2RF_DESC_BASE<"vftintrp.l.d", int_loongarch_lsx_vftintrp_l_d, LSX128DOpnd>; ++ ++ ++def VFTINTRZ_W_S : LSX_2R<0b0111001010011110010010>, ++ LSX_2RF_DESC_BASE<"vftintrz.w.s", fp_to_sint, LSX128WOpnd>; ++ ++def VFTINTRZ_L_D : LSX_2R<0b0111001010011110010011>, ++ LSX_2RF_DESC_BASE<"vftintrz.l.d", fp_to_sint, LSX128DOpnd>; ++ ++ ++def VFTINTRNE_W_S : LSX_2R<0b0111001010011110010100>, ++ LSX_2RF_DESC_BASE<"vftintrne.w.s", int_loongarch_lsx_vftintrne_w_s, LSX128WOpnd>; ++ ++def VFTINTRNE_L_D : LSX_2R<0b0111001010011110010101>, ++ LSX_2RF_DESC_BASE<"vftintrne.l.d", int_loongarch_lsx_vftintrne_l_d, LSX128DOpnd>; ++ ++ ++def VFTINTL_L_S : LSX_2R<0b0111001010011110100000>, ++ LSX_2RF_DESC_BASE<"vftintl.l.s", int_loongarch_lsx_vftintl_l_s, LSX128DOpnd, LSX128WOpnd>; ++ ++def VFTINTH_L_S : LSX_2R<0b0111001010011110100001>, ++ LSX_2RF_DESC_BASE<"vftinth.l.s", int_loongarch_lsx_vftinth_l_s, LSX128DOpnd, LSX128WOpnd>; ++ ++ ++def VFTINTRML_L_S : LSX_2R<0b0111001010011110100010>, ++ LSX_2RF_DESC_BASE<"vftintrml.l.s", int_loongarch_lsx_vftintrml_l_s, LSX128DOpnd, LSX128WOpnd>; ++ ++def VFTINTRMH_L_S : LSX_2R<0b0111001010011110100011>, ++ LSX_2RF_DESC_BASE<"vftintrmh.l.s", int_loongarch_lsx_vftintrmh_l_s, LSX128DOpnd, LSX128WOpnd>; ++ ++ ++def VFTINTRPL_L_S : LSX_2R<0b0111001010011110100100>, ++ LSX_2RF_DESC_BASE<"vftintrpl.l.s", int_loongarch_lsx_vftintrpl_l_s, LSX128DOpnd, LSX128WOpnd>; ++ ++def VFTINTRPH_L_S : LSX_2R<0b0111001010011110100101>, ++ LSX_2RF_DESC_BASE<"vftintrph.l.s", int_loongarch_lsx_vftintrph_l_s, LSX128DOpnd, LSX128WOpnd>; ++ ++ ++def VFTINTRZL_L_S : LSX_2R<0b0111001010011110100110>, ++ LSX_2RF_DESC_BASE<"vftintrzl.l.s", int_loongarch_lsx_vftintrzl_l_s, LSX128DOpnd, LSX128WOpnd>; ++ ++def VFTINTRZH_L_S : LSX_2R<0b0111001010011110100111>, ++ LSX_2RF_DESC_BASE<"vftintrzh.l.s", int_loongarch_lsx_vftintrzh_l_s, LSX128DOpnd, LSX128WOpnd>; ++ ++ ++def VFTINTRNEL_L_S : LSX_2R<0b0111001010011110101000>, ++ LSX_2RF_DESC_BASE<"vftintrnel.l.s", int_loongarch_lsx_vftintrnel_l_s, LSX128DOpnd, LSX128WOpnd>; ++ ++def VFTINTRNEH_L_S : LSX_2R<0b0111001010011110101001>, ++ LSX_2RF_DESC_BASE<"vftintrneh.l.s", int_loongarch_lsx_vftintrneh_l_s, LSX128DOpnd, LSX128WOpnd>; ++ ++ ++def VEXTH_H_B : LSX_2R<0b0111001010011110111000>, ++ LSX_2R_DESC_BASE<"vexth.h.b", int_loongarch_lsx_vexth_h_b, LSX128HOpnd, LSX128BOpnd>; ++ ++def VEXTH_W_H : LSX_2R<0b0111001010011110111001>, ++ LSX_2R_DESC_BASE<"vexth.w.h", int_loongarch_lsx_vexth_w_h, LSX128WOpnd, LSX128HOpnd>; ++ ++def VEXTH_D_W : LSX_2R<0b0111001010011110111010>, ++ LSX_2R_DESC_BASE<"vexth.d.w", int_loongarch_lsx_vexth_d_w, LSX128DOpnd, LSX128WOpnd> ; ++ ++def VEXTH_Q_D : LSX_2R<0b0111001010011110111011>, ++ LSX_2R_DESC_BASE<"vexth.q.d", int_loongarch_lsx_vexth_q_d, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VEXTH_HU_BU : LSX_2R<0b0111001010011110111100>, ++ LSX_2R_DESC_BASE<"vexth.hu.bu", int_loongarch_lsx_vexth_hu_bu, LSX128HOpnd, LSX128BOpnd>; ++ ++def VEXTH_WU_HU : LSX_2R<0b0111001010011110111101>, ++ LSX_2R_DESC_BASE<"vexth.wu.hu", int_loongarch_lsx_vexth_wu_hu, LSX128WOpnd, LSX128HOpnd>; ++ ++def VEXTH_DU_WU : LSX_2R<0b0111001010011110111110>, ++ LSX_2R_DESC_BASE<"vexth.du.wu", int_loongarch_lsx_vexth_du_wu, LSX128DOpnd, LSX128WOpnd> ; ++ ++def VEXTH_QU_DU : LSX_2R<0b0111001010011110111111>, ++ LSX_2R_DESC_BASE<"vexth.qu.du", int_loongarch_lsx_vexth_qu_du, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VSLLWIL_H_B : LSX_I3_U<0b0111001100001000001>, ++ LSX_2R_U3_DESC_BASE<"vsllwil.h.b", int_loongarch_lsx_vsllwil_h_b, LSX128HOpnd, LSX128BOpnd>; ++ ++def VSLLWIL_W_H : LSX_I4_U<0b011100110000100001>, ++ LSX_2R_U4_DESC_BASE<"vsllwil.w.h", int_loongarch_lsx_vsllwil_w_h, LSX128WOpnd, LSX128HOpnd>; ++ ++def VSLLWIL_D_W : LSX_I5_U<0b01110011000010001>, ++ LSX_2R_U5_DESC_BASE<"vsllwil.d.w", int_loongarch_lsx_vsllwil_d_w, LSX128DOpnd, LSX128WOpnd> ; ++ ++ ++def VEXTL_Q_D : LSX_2R<0b0111001100001001000000>, ++ LSX_2R_DESC_BASE<"vextl.q.d", int_loongarch_lsx_vextl_q_d, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VSLLWIL_HU_BU : LSX_I3_U<0b0111001100001100001>, ++ LSX_2R_U3_DESC_BASE<"vsllwil.hu.bu", int_loongarch_lsx_vsllwil_hu_bu, LSX128HOpnd, LSX128BOpnd>; ++ ++def VSLLWIL_WU_HU : LSX_I4_U<0b011100110000110001>, ++ LSX_2R_U4_DESC_BASE<"vsllwil.wu.hu", int_loongarch_lsx_vsllwil_wu_hu, LSX128WOpnd, LSX128HOpnd>; ++ ++def VSLLWIL_DU_WU : LSX_I5_U<0b01110011000011001>, ++ LSX_2R_U5_DESC_BASE<"vsllwil.du.wu", int_loongarch_lsx_vsllwil_du_wu, LSX128DOpnd, LSX128WOpnd> ; ++ ++ ++def VEXTL_QU_DU : LSX_2R<0b0111001100001101000000>, ++ LSX_2R_DESC_BASE<"vextl.qu.du", int_loongarch_lsx_vextl_qu_du, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VBITCLRI_B : LSX_I3_U<0b0111001100010000001>, ++ LSX_2R_U3_DESC_BASE<"vbitclri.b", int_loongarch_lsx_vbitclri_b, LSX128BOpnd, LSX128BOpnd>; ++ ++def VBITCLRI_H : LSX_I4_U<0b011100110001000001>, ++ LSX_2R_U4_DESC_BASE<"vbitclri.h", int_loongarch_lsx_vbitclri_h, LSX128HOpnd, LSX128HOpnd>; ++ ++def VBITCLRI_W : LSX_I5_U<0b01110011000100001>, ++ LSX_2R_U5_DESC_BASE<"vbitclri.w", int_loongarch_lsx_vbitclri_w, LSX128WOpnd, LSX128WOpnd>; ++ ++def VBITCLRI_D : LSX_I6_U<0b0111001100010001>, ++ LSX_2R_U6_DESC_BASE<"vbitclri.d", int_loongarch_lsx_vbitclri_d, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VBITSETI_B : LSX_I3_U<0b0111001100010100001>, ++ LSX_2R_U3_DESC_BASE<"vbitseti.b", int_loongarch_lsx_vbitseti_b, LSX128BOpnd, LSX128BOpnd>; ++ ++def VBITSETI_H : LSX_I4_U<0b011100110001010001>, ++ LSX_2R_U4_DESC_BASE<"vbitseti.h", int_loongarch_lsx_vbitseti_h, LSX128HOpnd, LSX128HOpnd>; ++ ++def VBITSETI_W : LSX_I5_U<0b01110011000101001>, ++ LSX_2R_U5_DESC_BASE<"vbitseti.w", int_loongarch_lsx_vbitseti_w, LSX128WOpnd, LSX128WOpnd>; ++ ++def VBITSETI_D : LSX_I6_U<0b0111001100010101>, ++ LSX_2R_U6_DESC_BASE<"vbitseti.d", int_loongarch_lsx_vbitseti_d, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VBITREVI_B : LSX_I3_U<0b0111001100011000001>, ++ LSX_2R_U3_DESC_BASE<"vbitrevi.b", int_loongarch_lsx_vbitrevi_b, LSX128BOpnd, LSX128BOpnd>; ++ ++def VBITREVI_H : LSX_I4_U<0b011100110001100001>, ++ LSX_2R_U4_DESC_BASE<"vbitrevi.h", int_loongarch_lsx_vbitrevi_h, LSX128HOpnd, LSX128HOpnd>; ++ ++def VBITREVI_W : LSX_I5_U<0b01110011000110001>, ++ LSX_2R_U5_DESC_BASE<"vbitrevi.w", int_loongarch_lsx_vbitrevi_w, LSX128WOpnd, LSX128WOpnd>; ++ ++def VBITREVI_D : LSX_I6_U<0b0111001100011001>, ++ LSX_2R_U6_DESC_BASE<"vbitrevi.d", int_loongarch_lsx_vbitrevi_d, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VSSRLRNI_B_H : LSX_I4_U<0b011100110101000001>, ++ LSX_2R_3R_U4_DESC_BASE<"vssrlrni.b.h", int_loongarch_lsx_vssrlrni_b_h, LSX128BOpnd, LSX128BOpnd>; ++ ++def VSSRLRNI_H_W : LSX_I5_U<0b01110011010100001>, ++ LSX_2R_3R_U5_DESC_BASE<"vssrlrni.h.w", int_loongarch_lsx_vssrlrni_h_w, LSX128HOpnd, LSX128HOpnd>; ++ ++def VSSRLRNI_W_D : LSX_I6_U<0b0111001101010001>, ++ LSX_2R_3R_U6_DESC_BASE<"vssrlrni.w.d", int_loongarch_lsx_vssrlrni_w_d, LSX128WOpnd, LSX128WOpnd>; ++ ++def VSSRLRNI_D_Q : LSX_I7_U<0b011100110101001>, ++ LSX_2R_3R_U7_DESC_BASE<"vssrlrni.d.q", int_loongarch_lsx_vssrlrni_d_q, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VSRANI_B_H : LSX_I4_U<0b011100110101100001>, ++ LSX_2R_3R_U4_DESC_BASE<"vsrani.b.h", int_loongarch_lsx_vsrani_b_h, LSX128BOpnd, LSX128BOpnd>; ++ ++def VSRANI_H_W : LSX_I5_U<0b01110011010110001>, ++ LSX_2R_3R_U5_DESC_BASE<"vsrani.h.w", int_loongarch_lsx_vsrani_h_w, LSX128HOpnd, LSX128HOpnd>; ++ ++def VSRANI_W_D : LSX_I6_U<0b0111001101011001>, ++ LSX_2R_3R_U6_DESC_BASE<"vsrani.w.d", int_loongarch_lsx_vsrani_w_d, LSX128WOpnd, LSX128WOpnd>; ++ ++def VSRANI_D_Q : LSX_I7_U<0b011100110101101>, ++ LSX_2R_3R_U7_DESC_BASE<"vsrani.d.q", int_loongarch_lsx_vsrani_d_q, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VEXTRINS_B : LSX_I8_U<0b01110011100011>, ++ LSX_2R_3R_U8_DESC_BASE<"vextrins.b", int_loongarch_lsx_vextrins_b, LSX128BOpnd, LSX128BOpnd>; ++ ++def VEXTRINS_H : LSX_I8_U<0b01110011100010>, ++ LSX_2R_3R_U8_DESC_BASE<"vextrins.h", int_loongarch_lsx_vextrins_h, LSX128HOpnd, LSX128HOpnd>; ++ ++def VEXTRINS_W : LSX_I8_U<0b01110011100001>, ++ LSX_2R_3R_U8_DESC_BASE<"vextrins.w", int_loongarch_lsx_vextrins_w, LSX128WOpnd, LSX128WOpnd>; ++ ++def VEXTRINS_D : LSX_I8_U<0b01110011100000>, ++ LSX_2R_3R_U8_DESC_BASE<"vextrins.d", int_loongarch_lsx_vextrins_d, LSX128DOpnd, LSX128DOpnd>; ++ ++ ++def VBITSELI_B : LSX_I8_U<0b01110011110001>, ++ LSX_2R_3R_U8_DESC_BASE<"vbitseli.b", int_loongarch_lsx_vbitseli_b, LSX128BOpnd, LSX128BOpnd>; ++ ++ ++def VANDI_B : LSX_I8_U<0b01110011110100>, ++ LSX_2R_U8_DESC_BASE<"vandi.b", int_loongarch_lsx_vandi_b, LSX128BOpnd, LSX128BOpnd>; ++ ++ ++def VORI_B : LSX_I8_U<0b01110011110101>, ++ LSX_2R_U8_DESC_BASE<"vori.b", int_loongarch_lsx_vori_b, LSX128BOpnd, LSX128BOpnd>; ++ ++ ++def VXORI_B : LSX_I8_U<0b01110011110110>, ++ LSX_2R_U8_DESC_BASE<"vxori.b", int_loongarch_lsx_vxori_b, LSX128BOpnd, LSX128BOpnd>; ++ ++ ++def VNORI_B : LSX_I8_U<0b01110011110111>, ++ LSX_2R_U8_DESC_BASE<"vnori.b", int_loongarch_lsx_vnori_b, LSX128BOpnd, LSX128BOpnd>; ++ ++ ++def VLDI : LSX_1R_I13<0b01110011111000>, ++ LSX_I13_DESC_BASE<"vldi", int_loongarch_lsx_vldi, i32, simm13Op, LSX128DOpnd>; ++ ++def VLDI_B : LSX_1R_I13_I10<0b01110011111000000>, ++ LSX_I13_DESC_BASE_10<"vldi", int_loongarch_lsx_vrepli_b, simm10, immZExt10, LSX128BOpnd>; ++ ++def VLDI_H : LSX_1R_I13_I10<0b01110011111000001>, ++ LSX_I13_DESC_BASE_10<"vldi", int_loongarch_lsx_vrepli_h, simm10, immZExt10, LSX128HOpnd>; ++ ++def VLDI_W : LSX_1R_I13_I10<0b01110011111000010>, ++ LSX_I13_DESC_BASE_10<"vldi", int_loongarch_lsx_vrepli_w, simm10, immZExt10, LSX128WOpnd>; ++ ++def VLDI_D : LSX_1R_I13_I10<0b01110011111000011>, ++ LSX_I13_DESC_BASE_10<"vldi", int_loongarch_lsx_vrepli_d, simm10, immZExt10, LSX128DOpnd>; ++ ++def VPERMI_W : LSX_I8_U<0b01110011111001>, ++ LSX_2R_3R_U8_DESC_BASE<"vpermi.w", int_loongarch_lsx_vpermi_w, LSX128WOpnd, LSX128WOpnd>; ++ ++ ++def VSEQ_B : LSX_3R<0b01110000000000000>, IsCommutable, ++ LSX_3R_DESC_BASE<"vseq.b", vseteq_v16i8, LSX128BOpnd>; ++ ++def VSEQ_H : LSX_3R<0b01110000000000001>, IsCommutable, ++ LSX_3R_DESC_BASE<"vseq.h", vseteq_v8i16, LSX128HOpnd>; ++ ++def VSEQ_W : LSX_3R<0b01110000000000010>, IsCommutable, ++ LSX_3R_DESC_BASE<"vseq.w", vseteq_v4i32, LSX128WOpnd> ; ++ ++def VSEQ_D : LSX_3R<0b01110000000000011>, IsCommutable, ++ LSX_3R_DESC_BASE<"vseq.d", vseteq_v2i64, LSX128DOpnd>; ++ ++ ++def VSLE_B : LSX_3R<0b01110000000000100>, ++ LSX_3R_DESC_BASE<"vsle.b", vsetle_v16i8, LSX128BOpnd>; ++ ++def VSLE_H : LSX_3R<0b01110000000000101>, ++ LSX_3R_DESC_BASE<"vsle.h", vsetle_v8i16, LSX128HOpnd>; ++ ++def VSLE_W : LSX_3R<0b01110000000000110>, ++ LSX_3R_DESC_BASE<"vsle.w", vsetle_v4i32, LSX128WOpnd>; ++ ++def VSLE_D : LSX_3R<0b01110000000000111>, ++ LSX_3R_DESC_BASE<"vsle.d", vsetle_v2i64, LSX128DOpnd>; ++ ++ ++def VSLE_BU : LSX_3R<0b01110000000001000>, ++ LSX_3R_DESC_BASE<"vsle.bu", vsetule_v16i8, LSX128BOpnd>; ++ ++def VSLE_HU : LSX_3R<0b01110000000001001>, ++ LSX_3R_DESC_BASE<"vsle.hu", vsetule_v8i16, LSX128HOpnd>; ++ ++def VSLE_WU : LSX_3R<0b01110000000001010>, ++ LSX_3R_DESC_BASE<"vsle.wu", vsetule_v4i32, LSX128WOpnd>; ++ ++def VSLE_DU : LSX_3R<0b01110000000001011>, ++ LSX_3R_DESC_BASE<"vsle.du", vsetule_v2i64, LSX128DOpnd>; ++ ++ ++def VSLT_B : LSX_3R<0b01110000000001100>, ++ LSX_3R_DESC_BASE<"vslt.b", vsetlt_v16i8, LSX128BOpnd>; ++ ++def VSLT_H : LSX_3R<0b01110000000001101>, ++ LSX_3R_DESC_BASE<"vslt.h", vsetlt_v8i16, LSX128HOpnd>; ++ ++def VSLT_W : LSX_3R<0b01110000000001110>, ++ LSX_3R_DESC_BASE<"vslt.w", vsetlt_v4i32, LSX128WOpnd>; ++ ++def VSLT_D : LSX_3R<0b01110000000001111>, ++ LSX_3R_DESC_BASE<"vslt.d", vsetlt_v2i64, LSX128DOpnd>; ++ ++ ++def VSLT_BU : LSX_3R<0b01110000000010000>, ++ LSX_3R_DESC_BASE<"vslt.bu", vsetult_v16i8, LSX128BOpnd>; ++ ++def VSLT_HU : LSX_3R<0b01110000000010001>, ++ LSX_3R_DESC_BASE<"vslt.hu", vsetult_v8i16, LSX128HOpnd>; ++ ++def VSLT_WU : LSX_3R<0b01110000000010010>, ++ LSX_3R_DESC_BASE<"vslt.wu", vsetult_v4i32, LSX128WOpnd>; ++ ++def VSLT_DU : LSX_3R<0b01110000000010011>, ++ LSX_3R_DESC_BASE<"vslt.du", vsetult_v2i64, LSX128DOpnd>; ++ ++ ++def VADD_B : LSX_3R<0b01110000000010100>, IsCommutable, ++ LSX_3R_DESC_BASE<"vadd.b", add, LSX128BOpnd>; ++ ++def VADD_H : LSX_3R<0b01110000000010101>, IsCommutable, ++ LSX_3R_DESC_BASE<"vadd.h", add, LSX128HOpnd>; ++ ++def VADD_W : LSX_3R<0b01110000000010110>, IsCommutable, ++ LSX_3R_DESC_BASE<"vadd.w", add, LSX128WOpnd>; ++ ++def VADD_D : LSX_3R<0b01110000000010111>, IsCommutable, ++ LSX_3R_DESC_BASE<"vadd.d", add, LSX128DOpnd>; ++ ++ ++def VSUB_B : LSX_3R<0b01110000000011000>, ++ LSX_3R_DESC_BASE<"vsub.b", sub, LSX128BOpnd>; ++ ++def VSUB_H : LSX_3R<0b01110000000011001>, ++ LSX_3R_DESC_BASE<"vsub.h", sub, LSX128HOpnd>; ++ ++def VSUB_W : LSX_3R<0b01110000000011010>, ++ LSX_3R_DESC_BASE<"vsub.w", sub, LSX128WOpnd>; ++ ++def VSUB_D : LSX_3R<0b01110000000011011>, ++ LSX_3R_DESC_BASE<"vsub.d", sub, LSX128DOpnd>; ++ ++ ++ ++//Pat ++class LSXBitconvertPat preds = [HasLSX]> : ++ LSXPat<(DstVT (bitconvert SrcVT:$src)), ++ (COPY_TO_REGCLASS SrcVT:$src, DstRC), preds>; ++ ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++ ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++ ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++ ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++ ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++ ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++ ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++def : LSXBitconvertPat; ++ ++ ++ ++ ++def : LSXPat<(i32 (vextract_sext_i8 v16i8:$vj, i32:$idx)), ++ (SRAI_W (COPY_TO_REGCLASS (i32 (EXTRACT_SUBREG (VREPLVE_B v16i8:$vj, ++ i32:$idx), ++ sub_lo)), ++ GPR32), (i32 24))>; ++def : LSXPat<(i32 (vextract_sext_i16 v8i16:$vj, i32:$idx)), ++ (SRAI_W (COPY_TO_REGCLASS (i32 (EXTRACT_SUBREG (VREPLVE_H v8i16:$vj, ++ i32:$idx), ++ sub_lo)), ++ GPR32), (i32 16))>; ++def : LSXPat<(i32 (vextract_sext_i32 v4i32:$vj, i32:$idx)), ++ (COPY_TO_REGCLASS (i32 (EXTRACT_SUBREG (VREPLVE_W v4i32:$vj, ++ i32:$idx), ++ sub_lo)), ++ GPR32)>; ++def : LSXPat<(i64 (vextract_sext_i64 v2i64:$vj, i32:$idx)), ++ (COPY_TO_REGCLASS (i64 (EXTRACT_SUBREG (VREPLVE_D v2i64:$vj, ++ i32:$idx), ++ sub_64)), ++ GPR64)>; ++ ++def : LSXPat<(i32 (vextract_zext_i8 v16i8:$vj, i32:$idx)), ++ (SRLI_W (COPY_TO_REGCLASS (i32 (EXTRACT_SUBREG (VREPLVE_B v16i8:$vj, ++ i32:$idx), ++ sub_lo)), ++ GPR32), (i32 24))>; ++def : LSXPat<(i32 (vextract_zext_i16 v8i16:$vj, i32:$idx)), ++ (SRLI_W (COPY_TO_REGCLASS (i32 (EXTRACT_SUBREG (VREPLVE_H v8i16:$vj, ++ i32:$idx), ++ sub_lo)), ++ GPR32), (i32 16))>; ++def : LSXPat<(i32 (vextract_zext_i32 v4i32:$vj, i32:$idx)), ++ (COPY_TO_REGCLASS (i32 (EXTRACT_SUBREG (VREPLVE_W v4i32:$vj, ++ i32:$idx), ++ sub_lo)), ++ GPR32)>; ++ ++def : LSXPat<(i64 (vextract_zext_i64 v2i64:$vj, i32:$idx)), ++ (COPY_TO_REGCLASS (i64 (EXTRACT_SUBREG (VREPLVE_D v2i64:$vj, ++ i32:$idx), ++ sub_64)), ++ GPR64)>; ++ ++def : LSXPat<(f32 (vector_extract v4f32:$vj, i32:$idx)), ++ (f32 (EXTRACT_SUBREG (VREPLVE_W v4f32:$vj, ++ i32:$idx), ++ sub_lo))>; ++def : LSXPat<(f64 (vector_extract v2f64:$vj, i32:$idx)), ++ (f64 (EXTRACT_SUBREG (VREPLVE_D v2f64:$vj, ++ i32:$idx), ++ sub_64))>; ++ ++def : LSXPat< ++ (i32 (vextract_sext_i8 v16i8:$vj, i64:$idx)), ++ (SRAI_W (COPY_TO_REGCLASS ++ (i32 (EXTRACT_SUBREG ++ (VREPLVE_B v16i8:$vj, ++ (COPY_TO_REGCLASS ++ (i32 (EXTRACT_SUBREG i64:$idx, sub_32)), GPR32)), ++ sub_lo)), ++ GPR32), ++ (i32 24))>; ++def : LSXPat< ++ (i32 (vextract_sext_i16 v8i16:$vj, i64:$idx)), ++ (SRAI_W (COPY_TO_REGCLASS ++ (i32 (EXTRACT_SUBREG ++ (VREPLVE_H v8i16:$vj, ++ (COPY_TO_REGCLASS ++ (i32 (EXTRACT_SUBREG i64:$idx, sub_32)), GPR32)), ++ sub_lo)), ++ GPR32), ++ (i32 16))>; ++ ++def : LSXPat< ++ (i32 (vextract_sext_i32 v4i32:$vj, i64:$idx)), ++ (COPY_TO_REGCLASS ++ (i32 (EXTRACT_SUBREG ++ (VREPLVE_W v4i32:$vj, ++ (COPY_TO_REGCLASS ++ (i32 (EXTRACT_SUBREG i64:$idx, sub_32)), GPR32)), ++ sub_lo)), ++ GPR32)>; ++ ++def : LSXPat< ++ (i64 (vextract_sext_i64 v2i64:$vj, i64:$idx)), ++ (COPY_TO_REGCLASS ++ (i64 (EXTRACT_SUBREG ++ (VREPLVE_D v2i64:$vj, ++ (COPY_TO_REGCLASS (i32 (EXTRACT_SUBREG i64:$idx, sub_32)), GPR32)), ++ sub_64)), ++ GPR64)>; ++ ++def : LSXPat< ++ (i32 (vextract_zext_i8 v16i8:$vj, i64:$idx)), ++ (SRLI_W (COPY_TO_REGCLASS ++ (i32 (EXTRACT_SUBREG ++ (VREPLVE_B v16i8:$vj, ++ (COPY_TO_REGCLASS ++ (i32 (EXTRACT_SUBREG i64:$idx, sub_32)), GPR32)), ++ sub_lo)), ++ GPR32), ++ (i32 24))>; ++def : LSXPat< ++ (i32 (vextract_zext_i16 v8i16:$vj, i64:$idx)), ++ (SRLI_W (COPY_TO_REGCLASS ++ (i32 (EXTRACT_SUBREG ++ (VREPLVE_H v8i16:$vj, ++ (COPY_TO_REGCLASS ++ (i32 (EXTRACT_SUBREG i64:$idx, sub_32)), GPR32)), ++ sub_lo)), ++ GPR32), ++ (i32 16))>; ++def : LSXPat< ++ (i32 (vextract_zext_i32 v4i32:$vj, i64:$idx)), ++ (COPY_TO_REGCLASS ++ (i32 (EXTRACT_SUBREG ++ (VREPLVE_W v4i32:$vj, ++ (COPY_TO_REGCLASS (i32 (EXTRACT_SUBREG i64:$idx, sub_32)), GPR32)), ++ sub_lo)), ++ GPR32)>; ++def : LSXPat< ++ (i64 (vextract_zext_i64 v2i64:$vj, i64:$idx)), ++ (COPY_TO_REGCLASS ++ (i64 (EXTRACT_SUBREG ++ (VREPLVE_D v2i64:$vj, ++ (COPY_TO_REGCLASS (i32 (EXTRACT_SUBREG i64:$idx, sub_32)), GPR32)), ++ sub_64)), ++ GPR64)>; ++ ++ def : LSXPat< ++ (f32 (vector_extract v4f32:$vj, i64:$idx)), ++ (f32 (EXTRACT_SUBREG ++ (VREPLVE_W v4f32:$vj, ++ (COPY_TO_REGCLASS (i32 (EXTRACT_SUBREG i64:$idx, sub_32)), GPR32)), ++ sub_lo))>; ++def : LSXPat< ++ (f64 (vector_extract v2f64:$vj, i64:$idx)), ++ (f64 (EXTRACT_SUBREG ++ (VREPLVE_D v2f64:$vj, ++ (COPY_TO_REGCLASS (i32 (EXTRACT_SUBREG i64:$idx, sub_32)), GPR32)), ++ sub_64))>; ++ ++ ++def : LSXPat<(vfseteq_v4f32 LSX128WOpnd:$a, LSX128WOpnd:$b), ++ (VFCMP_CEQ_S LSX128WOpnd:$a, LSX128WOpnd:$b)>; ++ ++def : LSXPat<(vfseteq_v2f64 LSX128DOpnd:$a, LSX128DOpnd:$b), ++ (VFCMP_CEQ_D LSX128DOpnd:$a, LSX128DOpnd:$b)>; ++ ++def : LSXPat<(vfsetle_v4f32 LSX128WOpnd:$a, LSX128WOpnd:$b), ++ (VFCMP_CLE_S LSX128WOpnd:$a, LSX128WOpnd:$b)>; ++ ++def : LSXPat<(vfsetle_v2f64 LSX128DOpnd:$a, LSX128DOpnd:$b), ++ (VFCMP_CLE_D LSX128DOpnd:$a, LSX128DOpnd:$b)>; ++ ++def : LSXPat<(vfsetlt_v4f32 LSX128WOpnd:$a, LSX128WOpnd:$b), ++ (VFCMP_CLT_S LSX128WOpnd:$a, LSX128WOpnd:$b)>; ++ ++def : LSXPat<(vfsetlt_v2f64 LSX128DOpnd:$a, LSX128DOpnd:$b), ++ (VFCMP_CLT_D LSX128DOpnd:$a, LSX128DOpnd:$b)>; ++ ++def : LSXPat<(vfsetne_v4f32 LSX128WOpnd:$a, LSX128WOpnd:$b), ++ (VFCMP_CNE_S LSX128WOpnd:$a, LSX128WOpnd:$b)>; ++ ++def : LSXPat<(vfsetne_v2f64 LSX128DOpnd:$a, LSX128DOpnd:$b), ++ (VFCMP_CNE_D LSX128DOpnd:$a, LSX128DOpnd:$b)>; ++ ++ ++class LSX_INSERT_PSEUDO_BASE : ++ LSXPseudo<(outs ROVD:$vd), (ins ROVD:$vd_in, ImmOp:$n, ROFS:$fs), ++ [(set ROVD:$vd, (OpNode (Ty ROVD:$vd_in), ROFS:$fs, Imm:$n))]> { ++ bit usesCustomInserter = 1; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++ ++class INSERT_FW_PSEUDO_DESC : LSX_INSERT_PSEUDO_BASE; ++class INSERT_FD_PSEUDO_DESC : LSX_INSERT_PSEUDO_BASE; ++ ++def INSERT_FW_PSEUDO : INSERT_FW_PSEUDO_DESC; ++def INSERT_FD_PSEUDO : INSERT_FD_PSEUDO_DESC; ++ ++ ++class LSX_INSERT_VIDX_PSEUDO_BASE : ++ LSXPseudo<(outs ROVD:$vd), (ins ROVD:$vd_in, ROIdx:$n, ROFS:$fs), ++ [(set ROVD:$vd, (OpNode (Ty ROVD:$vd_in), ROFS:$fs, ++ ROIdx:$n))]> { ++ bit usesCustomInserter = 1; ++ string Constraints = "$vd = $vd_in"; ++} ++ ++class INSERT_H_VIDX64_PSEUDO_DESC : ++ LSX_INSERT_VIDX_PSEUDO_BASE; ++def INSERT_H_VIDX64_PSEUDO : INSERT_H_VIDX64_PSEUDO_DESC; ++ ++class INSERTPostRA : ++ LoongArchPseudo<(outs RC:$xd), (ins RC:$xd_in, RD:$n, RE:$fs), []> { ++ let mayLoad = 1; ++ let mayStore = 1; ++} ++ ++def INSERT_H_VIDX64_PSEUDO_POSTRA : INSERTPostRA; ++ ++class LSX_COPY_PSEUDO_BASE : ++ LSXPseudo<(outs RCD:$vd), (ins RCVS:$vj, ImmOp:$n), ++ [(set RCD:$vd, (OpNode (VecTy RCVS:$vj), Imm:$n))]> { ++ bit usesCustomInserter = 1; ++} ++ ++ ++class COPY_FW_PSEUDO_DESC : LSX_COPY_PSEUDO_BASE; ++class COPY_FD_PSEUDO_DESC : LSX_COPY_PSEUDO_BASE; ++def COPY_FW_PSEUDO : COPY_FW_PSEUDO_DESC; ++def COPY_FD_PSEUDO : COPY_FD_PSEUDO_DESC; ++ ++ ++let isCodeGenOnly = 1 in { ++ ++def VST_H : LSX_I12_S<0b0010110001>, ++ ST_DESC_BASE<"vst", store, v8i16, LSX128HOpnd, mem_simm12>; ++def VST_W : LSX_I12_S<0b0010110001>, ++ ST_DESC_BASE<"vst", store, v4i32, LSX128WOpnd, mem_simm12>; ++def VST_D : LSX_I12_S<0b0010110001>, ++ ST_DESC_BASE<"vst", store, v2i64, LSX128DOpnd, mem_simm12>; ++ ++ ++def VLD_H : LSX_I12_S<0b0010110000>, ++ LD_DESC_BASE<"vld", load, v8i16, LSX128HOpnd, mem_simm12>; ++def VLD_W : LSX_I12_S<0b0010110000>, ++ LD_DESC_BASE<"vld", load, v4i32, LSX128WOpnd, mem_simm12>; ++def VLD_D : LSX_I12_S<0b0010110000>, ++ LD_DESC_BASE<"vld", load, v2i64, LSX128DOpnd, mem_simm12>; ++ ++ ++ ++def VANDI_B_N : LSX_I8_U<0b01110011110100>, ++ LSX_BIT_U8_VREPLVE_DESC_BASE<"vandi.b", and, vsplati8_uimm8, LSX128BOpnd>; ++ ++ ++def VXORI_B_N : LSX_I8_U<0b01110011110110>, ++ LSX_BIT_U8_VREPLVE_DESC_BASE<"vxori.b", xor, vsplati8_uimm8, LSX128BOpnd>; ++ ++ ++def VSRAI_B_N : LSX_I3_U<0b0111001100110100001>, ++ LSX_BIT_U3_VREPLVE_DESC_BASE<"vsrai.b", sra, vsplati8_uimm3, LSX128BOpnd>; ++ ++def VSRAI_H_N : LSX_I4_U<0b011100110011010001>, ++ LSX_BIT_U4_VREPLVE_DESC_BASE<"vsrai.h", sra, vsplati16_uimm4, LSX128HOpnd>; ++ ++def VSRAI_W_N : LSX_I5_U<0b01110011001101001>, ++ LSX_BIT_U5_VREPLVE_DESC_BASE<"vsrai.w", sra, vsplati32_uimm5, LSX128WOpnd>; ++ ++def VSRAI_D_N : LSX_I6_U<0b0111001100110101>, ++ LSX_BIT_U6_VREPLVE_DESC_BASE<"vsrai.d", sra, vsplati64_uimm6, LSX128DOpnd>; ++ ++ ++def VMAXI_BU_N : LSX_I5_U<0b01110010100101000>, ++ LSX_I5_U_DESC_BASE<"vmaxi.bu", umax, vsplati8_uimm5, LSX128BOpnd>; ++ ++def VMAXI_HU_N : LSX_I5_U<0b01110010100101001>, ++ LSX_I5_U_DESC_BASE<"vmaxi.hu", umax, vsplati16_uimm5, LSX128HOpnd>; ++ ++def VMAXI_WU_N : LSX_I5_U<0b01110010100101010>, ++ LSX_I5_U_DESC_BASE<"vmaxi.wu", umax, vsplati32_uimm5, LSX128WOpnd>; ++ ++def VMAXI_DU_N : LSX_I5_U<0b01110010100101011>, ++ LSX_I5_U_DESC_BASE<"vmaxi.du", umax, vsplati64_uimm5, LSX128DOpnd>; ++ ++ ++def VMINI_B_N : LSX_I5<0b01110010100100100>, ++ LSX_I5_DESC_BASE<"vmini.b", smin, vsplati8_simm5, LSX128BOpnd>; ++ ++def VMINI_H_N : LSX_I5<0b01110010100100101>, ++ LSX_I5_DESC_BASE<"vmini.h", smin, vsplati16_simm5, LSX128HOpnd>; ++ ++def VMINI_W_N : LSX_I5<0b01110010100100110>, ++ LSX_I5_DESC_BASE<"vmini.w", smin, vsplati32_simm5, LSX128WOpnd>; ++ ++def VMINI_D_N : LSX_I5<0b01110010100100111>, ++ LSX_I5_DESC_BASE<"vmini.d", smin, vsplati64_simm5, LSX128DOpnd>; ++ ++ ++def VMAXI_B_N : LSX_I5<0b01110010100100000>, ++ LSX_I5_DESC_BASE<"vmaxi.b", smax, vsplati8_simm5, LSX128BOpnd>; ++ ++def VMAXI_H_N : LSX_I5<0b01110010100100001>, ++ LSX_I5_DESC_BASE<"vmaxi.h", smax, vsplati16_simm5, LSX128HOpnd>; ++ ++def VMAXI_W_N : LSX_I5<0b01110010100100010>, ++ LSX_I5_DESC_BASE<"vmaxi.w", smax, vsplati32_simm5, LSX128WOpnd>; ++ ++def VMAXI_D_N : LSX_I5<0b01110010100100011>, ++ LSX_I5_DESC_BASE<"vmaxi.d", smax, vsplati64_simm5, LSX128DOpnd>; ++ ++ ++def VSEQI_B_N : LSX_I5<0b01110010100000000>, ++ LSX_I5_DESC_BASE<"vseqi.b", vseteq_v16i8, vsplati8_simm5, LSX128BOpnd>; ++ ++def VSEQI_H_N : LSX_I5<0b01110010100000001>, ++ LSX_I5_DESC_BASE<"vseqi.h", vseteq_v8i16, vsplati16_simm5, LSX128HOpnd>; ++ ++def VSEQI_W_N : LSX_I5<0b01110010100000010>, ++ LSX_I5_DESC_BASE<"vseqi.w", vseteq_v4i32, vsplati32_simm5, LSX128WOpnd>; ++ ++def VSEQI_D_N : LSX_I5<0b01110010100000011>, ++ LSX_I5_DESC_BASE<"vseqi.d", vseteq_v2i64, vsplati64_simm5, LSX128DOpnd>; ++ ++ ++def VSLEI_B_N : LSX_I5<0b01110010100000100>, ++ LSX_I5_DESC_BASE<"vslei.b", vsetle_v16i8, vsplati8_simm5, LSX128BOpnd>; ++ ++def VSLEI_H_N : LSX_I5<0b01110010100000101>, ++ LSX_I5_DESC_BASE<"vslei.h", vsetle_v8i16, vsplati16_simm5, LSX128HOpnd>; ++ ++def VSLEI_W_N : LSX_I5<0b01110010100000110>, ++ LSX_I5_DESC_BASE<"vslei.w", vsetle_v4i32, vsplati32_simm5, LSX128WOpnd>; ++ ++def VSLEI_D_N : LSX_I5<0b01110010100000111>, ++ LSX_I5_DESC_BASE<"vslei.d", vsetle_v2i64, vsplati64_simm5, LSX128DOpnd>; ++ ++def VSLEI_BU_N : LSX_I5_U<0b01110010100001000>, ++ LSX_I5_U_DESC_BASE<"vslei.bu", vsetule_v16i8, vsplati8_uimm5, LSX128BOpnd>; ++ ++def VSLEI_HU_N : LSX_I5_U<0b01110010100001001>, ++ LSX_I5_U_DESC_BASE<"vslei.hu", vsetule_v8i16, vsplati16_uimm5, LSX128HOpnd>; ++ ++def VSLEI_WU_N : LSX_I5_U<0b01110010100001010>, ++ LSX_I5_U_DESC_BASE<"vslei.wu", vsetule_v4i32, vsplati32_uimm5, LSX128WOpnd>; ++ ++def VSLEI_DU_N : LSX_I5_U<0b01110010100001011>, ++ LSX_I5_U_DESC_BASE<"vslei.du", vsetule_v2i64, vsplati64_uimm5, LSX128DOpnd>; ++ ++ ++def VSLTI_B_N : LSX_I5<0b01110010100001100>, ++ LSX_I5_DESC_BASE<"vslti.b", vsetlt_v16i8, vsplati8_simm5, LSX128BOpnd>; ++ ++def VSLTI_H_N : LSX_I5<0b01110010100001101>, ++ LSX_I5_DESC_BASE<"vslti.h", vsetlt_v8i16, vsplati16_simm5, LSX128HOpnd>; ++ ++def VSLTI_W_N : LSX_I5<0b01110010100001110>, ++ LSX_I5_DESC_BASE<"vslti.w", vsetlt_v4i32, vsplati32_simm5, LSX128WOpnd>; ++ ++def VSLTI_D_N : LSX_I5<0b01110010100001111>, ++ LSX_I5_DESC_BASE<"vslti.d", vsetlt_v2i64, vsplati64_simm5, LSX128DOpnd>; ++ ++ ++def VSLTI_BU_N : LSX_I5_U<0b01110010100010000>, ++ LSX_I5_U_DESC_BASE<"vslti.bu", vsetult_v16i8, vsplati8_uimm5, LSX128BOpnd>; ++ ++def VSLTI_HU_N : LSX_I5_U<0b01110010100010001>, ++ LSX_I5_U_DESC_BASE<"vslti.hu", vsetult_v8i16, vsplati16_uimm5, LSX128HOpnd>; ++ ++def VSLTI_WU_N : LSX_I5_U<0b01110010100010010>, ++ LSX_I5_U_DESC_BASE<"vslti.wu", vsetult_v4i32, vsplati32_uimm5, LSX128WOpnd>; ++ ++def VSLTI_DU_N : LSX_I5_U<0b01110010100010011>, ++ LSX_I5_U_DESC_BASE<"vslti.du", vsetult_v2i64, vsplati64_uimm5, LSX128DOpnd>; ++ ++ ++def VBITSELI_B_N : LSX_I8_U<0b01110011110001>, ++ LSX_2R_3R_SELECT<"vbitseli.b", vselect, LSX128BOpnd, LSX128BOpnd>; ++ ++} ++ ++ ++def : LSXPat<(v4f32 (load addrimm12:$addr)), (VLD_W addrimm12:$addr)>; ++def : LSXPat<(v2f64 (load addrimm12:$addr)), (VLD_D addrimm12:$addr)>; ++ ++def VST_FW : LSXPat<(store (v4f32 LSX128W:$vj), addrimm12:$addr), ++ (VST_W LSX128W:$vj, addrimm12:$addr)>; ++def VST_FD : LSXPat<(store (v2f64 LSX128D:$vj), addrimm12:$addr), ++ (VST_D LSX128D:$vj, addrimm12:$addr)>; ++ ++def VNEG_FW : LSXPat<(fneg (v4f32 LSX128W:$vj)), ++ (VBITREVI_W LSX128W:$vj, 31)>; ++def VNEG_FD : LSXPat<(fneg (v2f64 LSX128D:$vj)), ++ (VBITREVI_D LSX128D:$vj, 63)>; ++ ++ ++def : LSXPat<(v2i64 (LoongArchVABSD v2i64:$vj, v2i64:$vk, (i32 0))), ++ (v2i64 (VABSD_D $vj, $vk))>; ++ ++def : LSXPat<(v4i32 (LoongArchVABSD v4i32:$vj, v4i32:$vk, (i32 0))), ++ (v4i32 (VABSD_W $vj, $vk))>; ++ ++def : LSXPat<(v8i16 (LoongArchVABSD v8i16:$vj, v8i16:$vk, (i32 0))), ++ (v8i16 (VABSD_H $vj, $vk))>; ++ ++def : LSXPat<(v16i8 (LoongArchVABSD v16i8:$vj, v16i8:$vk, (i32 0))), ++ (v16i8 (VABSD_B $vj, $vk))>; ++ ++def : LSXPat<(v2i64 (LoongArchUVABSD v2i64:$vj, v2i64:$vk, (i32 0))), ++ (v2i64 (VABSD_DU $vj, $vk))>; ++ ++def : LSXPat<(v4i32 (LoongArchUVABSD v4i32:$vj, v4i32:$vk, (i32 0))), ++ (v4i32 (VABSD_WU $vj, $vk))>; ++ ++def : LSXPat<(v8i16 (LoongArchUVABSD v8i16:$vj, v8i16:$vk, (i32 0))), ++ (v8i16 (VABSD_HU $vj, $vk))>; ++ ++def : LSXPat<(v16i8 (LoongArchUVABSD v16i8:$vj, v16i8:$vk, (i32 0))), ++ (v16i8 (VABSD_BU $vj, $vk))>; ++ ++ ++def : LSXPat<(or v16i8:$vj, (shl vsplat_imm_eq_1, v16i8:$vk)), ++ (VBITSET_B v16i8:$vj, v16i8:$vk)>; ++def : LSXPat<(or v8i16:$vj, (shl vsplat_imm_eq_1, v8i16:$vk)), ++ (VBITSET_H v8i16:$vj, v8i16:$vk)>; ++def : LSXPat<(or v4i32:$vj, (shl vsplat_imm_eq_1, v4i32:$vk)), ++ (VBITSET_W v4i32:$vj, v4i32:$vk)>; ++def : LSXPat<(or v2i64:$vj, (shl vsplat_imm_eq_1, v2i64:$vk)), ++ (VBITSET_D v2i64:$vj, v2i64:$vk)>; ++ ++def : LSXPat<(xor v16i8:$vj, (shl vsplat_imm_eq_1, v16i8:$vk)), ++ (VBITREV_B v16i8:$vj, v16i8:$vk)>; ++def : LSXPat<(xor v8i16:$vj, (shl vsplat_imm_eq_1, v8i16:$vk)), ++ (VBITREV_H v8i16:$vj, v8i16:$vk)>; ++def : LSXPat<(xor v4i32:$vj, (shl vsplat_imm_eq_1, v4i32:$vk)), ++ (VBITREV_W v4i32:$vj, v4i32:$vk)>; ++def : LSXPat<(xor v2i64:$vj, (shl (v2i64 vsplati64_imm_eq_1), v2i64:$vk)), ++ (VBITREV_D v2i64:$vj, v2i64:$vk)>; ++ ++def : LSXPat<(and v16i8:$vj, (xor (shl vsplat_imm_eq_1, v16i8:$vk), immAllOnesV)), ++ (VBITCLR_B v16i8:$vj, v16i8:$vk)>; ++def : LSXPat<(and v8i16:$vj, (xor (shl vsplat_imm_eq_1, v8i16:$vk), immAllOnesV)), ++ (VBITCLR_H v8i16:$vj, v8i16:$vk)>; ++def : LSXPat<(and v4i32:$vj, (xor (shl vsplat_imm_eq_1, v4i32:$vk), immAllOnesV)), ++ (VBITCLR_W v4i32:$vj, v4i32:$vk)>; ++def : LSXPat<(and v2i64:$vj, (xor (shl (v2i64 vsplati64_imm_eq_1), v2i64:$vk), (bitconvert (v4i32 immAllOnesV)))), ++ (VBITCLR_D v2i64:$vj, v2i64:$vk)>; ++def vsplati64_imm_eq_63 : PatLeaf<(bitconvert (v4i32 (build_vector))), [{ ++ APInt Imm; ++ SDNode *BV = N->getOperand(0).getNode(); ++ EVT EltTy = N->getValueType(0).getVectorElementType(); ++ ++ return selectVSplat(BV, Imm, EltTy.getSizeInBits()) && ++ Imm.getBitWidth() == EltTy.getSizeInBits() && Imm == 63; ++}]>; ++ ++def immi32Cst7 : ImmLeaf(Imm) && Imm == 7;}]>; ++def immi32Cst15 : ImmLeaf(Imm) && Imm == 15;}]>; ++def immi32Cst31 : ImmLeaf(Imm) && Imm == 31;}]>; ++ ++def vsplati8imm7 : PatFrag<(ops node:$vt), ++ (and node:$vt, (vsplati8 immi32Cst7))>; ++def vsplati16imm15 : PatFrag<(ops node:$vt), ++ (and node:$vt, (vsplati16 immi32Cst15))>; ++def vsplati32imm31 : PatFrag<(ops node:$vt), ++ (and node:$vt, (vsplati32 immi32Cst31))>; ++def vsplati64imm63 : PatFrag<(ops node:$vt), ++ (and node:$vt, vsplati64_imm_eq_63)>; ++ ++class LSXShiftPat : ++ LSXPat<(VT (Node VT:$vs, (VT (and VT:$vt, Vec)))), ++ (VT (Insn VT:$vs, VT:$vt))>; ++ ++class LSXBitPat : ++ LSXPat<(VT (Node VT:$vs, (shl vsplat_imm_eq_1, (Frag VT:$vt)))), ++ (VT (Insn VT:$vs, VT:$vt))>; ++ ++multiclass LSXShiftPats { ++ def : LSXShiftPat(Insn#_B), ++ (vsplati8 immi32Cst7)>; ++ def : LSXShiftPat(Insn#_H), ++ (vsplati16 immi32Cst15)>; ++ def : LSXShiftPat(Insn#_W), ++ (vsplati32 immi32Cst31)>; ++ def : LSXPat<(v2i64 (Node v2i64:$vs, (v2i64 (and v2i64:$vt, ++ vsplati64_imm_eq_63)))), ++ (v2i64 (!cast(Insn#_D) v2i64:$vs, v2i64:$vt))>; ++} ++ ++multiclass LSXBitPats { ++ def : LSXBitPat(Insn#_B), vsplati8imm7>; ++ def : LSXBitPat(Insn#_H), vsplati16imm15>; ++ def : LSXBitPat(Insn#_W), vsplati32imm31>; ++ def : LSXPat<(Node v2i64:$vs, (shl (v2i64 vsplati64_imm_eq_1), ++ (vsplati64imm63 v2i64:$vt))), ++ (v2i64 (!cast(Insn#_D) v2i64:$vs, v2i64:$vt))>; ++} ++ ++defm : LSXShiftPats; ++defm : LSXShiftPats; ++defm : LSXShiftPats; ++defm : LSXBitPats; ++defm : LSXBitPats; ++ ++def : LSXPat<(and v16i8:$vs, (xor (shl vsplat_imm_eq_1, ++ (vsplati8imm7 v16i8:$vt)), ++ immAllOnesV)), ++ (v16i8 (VBITCLR_B v16i8:$vs, v16i8:$vt))>; ++def : LSXPat<(and v8i16:$vs, (xor (shl vsplat_imm_eq_1, ++ (vsplati16imm15 v8i16:$vt)), ++ immAllOnesV)), ++ (v8i16 (VBITCLR_H v8i16:$vs, v8i16:$vt))>; ++def : LSXPat<(and v4i32:$vs, (xor (shl vsplat_imm_eq_1, ++ (vsplati32imm31 v4i32:$vt)), ++ immAllOnesV)), ++ (v4i32 (VBITCLR_W v4i32:$vs, v4i32:$vt))>; ++def : LSXPat<(and v2i64:$vs, (xor (shl (v2i64 vsplati64_imm_eq_1), ++ (vsplati64imm63 v2i64:$vt)), ++ (bitconvert (v4i32 immAllOnesV)))), ++ (v2i64 (VBITCLR_D v2i64:$vs, v2i64:$vt))>; ++ ++ ++def : LSXPat<(fdiv (v4f32 (build_vector (f32 fpimm1), (f32 fpimm1), (f32 fpimm1), (f32 fpimm1))), v4f32:$v), ++ (VFRECIP_S v4f32:$v)>; ++ ++def : LSXPat<(fdiv (v2f64 (build_vector (f64 fpimm1), (f64 fpimm1))), v2f64:$v), ++ (VFRECIP_D v2f64:$v)>; ++ ++def : LSXPat<(fdiv (v4f32 fpimm1), v4f32:$v), ++ (VFRECIP_S v4f32:$v)>; ++ ++def : LSXPat<(fdiv (v2f64 fpimm1), v2f64:$v), ++ (VFRECIP_D v2f64:$v)>; ++ ++// 128-Bit vector FP approximate reciprocal operation ++let Predicates = [HasFrecipe] in { ++def : LSXPat<(int_loongarch_lsx_vfrecipe_s (v4f32 LSX128W:$vj)), ++ (VFRECIPE_S LSX128W:$vj)>; ++def : LSXPat<(int_loongarch_lsx_vfrecipe_d (v2f64 LSX128D:$vj)), ++ (VFRECIPE_D LSX128D:$vj)>; ++def : LSXPat<(int_loongarch_lsx_vfrsqrte_s (v4f32 LSX128W:$vj)), ++ (VFRSQRTE_S LSX128W:$vj)>; ++def : LSXPat<(int_loongarch_lsx_vfrsqrte_d (v2f64 LSX128D:$vj)), ++ (VFRSQRTE_D LSX128D:$vj)>; ++} ++ ++ ++def : LSXPat<(fdiv (v4f32 (build_vector (f32 fpimm1), (f32 fpimm1), (f32 fpimm1), (f32 fpimm1))), (fsqrt v4f32:$v)), ++ (VFRSQRT_S v4f32:$v)>; ++ ++def : LSXPat<(fdiv (v2f64 (build_vector (f64 fpimm1), (f64 fpimm1))), (fsqrt v2f64:$v)), ++ (VFRSQRT_D v2f64:$v)>; ++ ++def : LSXPat<(fdiv (v4f32 fpimm1), (fsqrt v4f32:$v)), ++ (VFRSQRT_S v4f32:$v)>; ++ ++def : LSXPat<(fdiv (v2f64 fpimm1), (fsqrt v2f64:$v)), ++ (VFRSQRT_D v2f64:$v)>; ++ ++ ++def : LSXPat<(abs v2i64:$v), ++ (VMAX_D v2i64:$v, (VNEG_D v2i64:$v))>; ++ ++def : LSXPat<(abs v4i32:$v), ++ (VMAX_W v4i32:$v, (VNEG_W v4i32:$v))>; ++ ++def : LSXPat<(abs v8i16:$v), ++ (VMAX_H v8i16:$v, (VNEG_H v8i16:$v))>; ++ ++def : LSXPat<(abs v16i8:$v), ++ (VMAX_B v16i8:$v, (VNEG_B v16i8:$v))>; ++ ++ ++def : LSXPat<(sub (v16i8 immAllZerosV), v16i8:$v), ++ (VNEG_B v16i8:$v)>; ++ ++def : LSXPat<(sub (v8i16 immAllZerosV), v8i16:$v), ++ (VNEG_H v8i16:$v)>; ++ ++def : LSXPat<(sub (v4i32 immAllZerosV), v4i32:$v), ++ (VNEG_W v4i32:$v)>; ++ ++def : LSXPat<(sub (v2i64 immAllZerosV), v2i64:$v), ++ (VNEG_D v2i64:$v)>; ++ ++ ++def : LSXPat<(sra ++ (v16i8 (add ++ (v16i8 (add LSX128B:$a, LSX128B:$b)), ++ (v16i8 (srl ++ (v16i8 (add LSX128B:$a, LSX128B:$b)), ++ (v16i8 (build_vector (i32 7),(i32 7),(i32 7),(i32 7), ++ (i32 7),(i32 7),(i32 7),(i32 7), ++ (i32 7),(i32 7),(i32 7),(i32 7), ++ (i32 7),(i32 7),(i32 7),(i32 7)) ++ ) ++ ) ++ ) ++ ) ++ ), ++ (v16i8 (build_vector (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1) ++ ))), ++ (VAVG_B (v16i8 LSX128B:$a), (v16i8 LSX128B:$b))>; ++ ++def : LSXPat<(sra ++ (v8i16 (add ++ (v8i16 (add LSX128H:$a, LSX128H:$b)), ++ (v8i16 (srl ++ (v8i16 (add LSX128H:$a, LSX128H:$b)), ++ (v8i16 (build_vector (i32 15),(i32 15),(i32 15),(i32 15), ++ (i32 15),(i32 15),(i32 15),(i32 15)) ++ ) ++ ) ++ ) ++ ) ++ ), ++ (v8i16 (build_vector (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1) ++ ))), ++ (VAVG_H (v8i16 LSX128H:$a), (v8i16 LSX128H:$b))>; ++ ++def : LSXPat<(sra ++ (v4i32 (add ++ (v4i32 (add LSX128W:$a, LSX128W:$b)), ++ (v4i32 (srl ++ (v4i32 (add LSX128W:$a, LSX128W:$b)), ++ (v4i32 (build_vector (i32 31),(i32 31),(i32 31),(i32 31)) ++ ) ++ ) ++ ) ++ ) ++ ), ++ (v4i32 (build_vector (i32 1),(i32 1),(i32 1),(i32 1)))), ++ (VAVG_W (v4i32 LSX128W:$a), (v4i32 LSX128W:$b))>; ++ ++def : LSXPat<(sra ++ (v2i64 (add ++ (v2i64 (add LSX128D:$a, LSX128D:$b)), ++ (v2i64 (srl ++ (v2i64 (add LSX128D:$a, LSX128D:$b)), ++ (v2i64 (build_vector (i64 63),(i64 63))) ++ ) ++ ) ++ ) ++ ), ++ (v2i64 (build_vector (i64 1),(i64 1)))), ++ (VAVG_D (v2i64 LSX128D:$a), (v2i64 LSX128D:$b))>; ++ ++ ++ ++def : LSXPat<(srl ++ (v16i8 (add LSX128B:$a, LSX128B:$b)), ++ (v16i8 (build_vector (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1)) ++ ) ++ ), ++ (VAVG_BU (v16i8 LSX128B:$a), (v16i8 LSX128B:$b))>; ++ ++def : LSXPat<(srl ++ (v8i16 (add LSX128H:$a, LSX128H:$b)), ++ (v8i16 (build_vector (i32 1),(i32 1),(i32 1),(i32 1), ++ (i32 1),(i32 1),(i32 1),(i32 1)) ++ ) ++ ), ++ (VAVG_HU (v8i16 LSX128H:$a), (v8i16 LSX128H:$b))>; ++ ++def : LSXPat<(srl ++ (v4i32 (add LSX128W:$a, LSX128W:$b)), ++ (v4i32 (build_vector (i32 1),(i32 1),(i32 1),(i32 1)) ++ ) ++ ), ++ (VAVG_WU (v4i32 LSX128W:$a), (v4i32 LSX128W:$b))>; ++ ++def : LSXPat<(srl ++ (v2i64 (add LSX128D:$a, LSX128D:$b)), ++ (v2i64 (build_vector (i64 1),(i64 1)) ++ ) ++ ), ++ (VAVG_DU (v2i64 LSX128D:$a), (v2i64 LSX128D:$b))>; ++ ++ ++ ++ ++ ++ ++def : LSXPat<(mulhs LSX128D:$a, LSX128D:$b), ++ (VMUH_D LSX128D:$a, LSX128D:$b)>; ++ ++def : LSXPat<(mulhs LSX128W:$a, LSX128W:$b), ++ (VMUH_W LSX128W:$a, LSX128W:$b)>; ++ ++def : LSXPat<(mulhs LSX128H:$a, LSX128H:$b), ++ (VMUH_H LSX128H:$a, LSX128H:$b)>; ++ ++def : LSXPat<(mulhs LSX128B:$a, LSX128B:$b), ++ (VMUH_B LSX128B:$a, LSX128B:$b)>; ++ ++ ++def : LSXPat<(mulhu LSX128D:$a, LSX128D:$b), ++ (VMUH_DU LSX128D:$a, LSX128D:$b)>; ++ ++def : LSXPat<(mulhu LSX128W:$a, LSX128W:$b), ++ (VMUH_WU LSX128W:$a, LSX128W:$b)>; ++ ++def : LSXPat<(mulhu LSX128H:$a, LSX128H:$b), ++ (VMUH_HU LSX128H:$a, LSX128H:$b)>; ++ ++def : LSXPat<(mulhu LSX128B:$a, LSX128B:$b), ++ (VMUH_BU LSX128B:$a, LSX128B:$b)>; ++ ++ ++ ++//===----------------------------------------------------------------------===// ++// Intrinsics ++//===----------------------------------------------------------------------===// ++ ++def : LSXPat<(int_loongarch_lsx_vseq_b (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VSEQ_B LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vseq_h (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VSEQ_H LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vseq_w (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VSEQ_W LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vseq_d (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk)), ++ (VSEQ_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vsle_b (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VSLE_B LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vsle_h (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VSLE_H LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vsle_w (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VSLE_W LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vsle_d (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk)), ++ (VSLE_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vsle_bu (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VSLE_BU LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vsle_hu (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VSLE_HU LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vsle_wu (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VSLE_WU LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vsle_du (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk)), ++ (VSLE_DU LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vslt_b (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VSLT_B LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vslt_h (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VSLT_H LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vslt_w (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VSLT_W LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vslt_d (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk)), ++ (VSLT_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vslt_bu (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VSLT_BU LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vslt_hu (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VSLT_HU LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vslt_wu (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VSLT_WU LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vslt_du (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk)), ++ (VSLT_DU LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vadd_b (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VADD_B LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vadd_h (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VADD_H LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vadd_w (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VADD_W LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vadd_d (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk)), ++ (VADD_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vsub_b (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VSUB_B LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vsub_h (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VSUB_H LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vsub_w (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VSUB_W LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vsub_d (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk)), ++ (VSUB_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vsadd_b (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VSADD_B LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vsadd_h (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VSADD_H LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vsadd_w (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VSADD_W LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vsadd_d (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk)), ++ (VSADD_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vssub_b (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VSSUB_B LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vssub_h (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VSSUB_H LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vssub_w (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VSSUB_W LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vssub_d (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk)), ++ (VSSUB_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vsadd_bu (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VSADD_BU LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vsadd_hu (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VSADD_HU LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vsadd_wu (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VSADD_WU LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vsadd_du (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk)), ++ (VSADD_DU LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vssub_bu (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VSSUB_BU LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vssub_hu (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VSSUB_HU LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vssub_wu (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VSSUB_WU LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vssub_du (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk)), ++ (VSSUB_DU LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vhaddw_h_b (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VHADDW_H_B LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vhaddw_w_h (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VHADDW_W_H LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vhaddw_d_w (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VHADDW_D_W LSX128W:$vj, LSX128W:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vhsubw_h_b (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VHSUBW_H_B LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vhsubw_w_h (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VHSUBW_W_H LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vhsubw_d_w (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VHSUBW_D_W LSX128W:$vj, LSX128W:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vhaddw_hu_bu (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VHADDW_HU_BU LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vhaddw_wu_hu (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VHADDW_WU_HU LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vhaddw_du_wu (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VHADDW_DU_WU LSX128W:$vj, LSX128W:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vhsubw_hu_bu (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VHSUBW_HU_BU LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vhsubw_wu_hu (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VHSUBW_WU_HU LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vhsubw_du_wu (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VHSUBW_DU_WU LSX128W:$vj, LSX128W:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vadda_b (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VADDA_B LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vadda_h (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VADDA_H LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vadda_w (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VADDA_W LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vadda_d (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk)), ++ (VADDA_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vabsd_b (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VABSD_B LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vabsd_h (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VABSD_H LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vabsd_w (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VABSD_W LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vabsd_d (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk)), ++ (VABSD_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vabsd_bu (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VABSD_BU LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vabsd_hu (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VABSD_HU LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vabsd_wu (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VABSD_WU LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vabsd_du (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk)), ++ (VABSD_DU LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vavg_b (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VAVG_B LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vavg_h (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VAVG_H LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vavg_w (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VAVG_W LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vavg_d (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk)), ++ (VAVG_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vavg_bu (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VAVG_BU LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vavg_hu (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VAVG_HU LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vavg_wu (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VAVG_WU LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vavg_du (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk)), ++ (VAVG_DU LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vavgr_b (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VAVGR_B LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vavgr_h (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VAVGR_H LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vavgr_w (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VAVGR_W LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vavgr_d (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk)), ++ (VAVGR_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vavgr_bu (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VAVGR_BU LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vavgr_hu (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VAVGR_HU LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vavgr_wu (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VAVGR_WU LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vavgr_du (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk)), ++ (VAVGR_DU LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vsrlr_b (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VSRLR_B LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vsrlr_h (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VSRLR_H LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vsrlr_w (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VSRLR_W LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vsrlr_d (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk)), ++ (VSRLR_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vsrar_b (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VSRAR_B LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vsrar_h (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VSRAR_H LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vsrar_w (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VSRAR_W LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vsrar_d (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk)), ++ (VSRAR_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vbitset_b (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VBITSET_B LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vbitset_h (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VBITSET_H LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vbitset_w (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VBITSET_W LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vbitset_d (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk)), ++ (VBITSET_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vbitrev_b (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk)), ++ (VBITREV_B LSX128B:$vj, LSX128B:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vbitrev_h (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk)), ++ (VBITREV_H LSX128H:$vj, LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vbitrev_w (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk)), ++ (VBITREV_W LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vbitrev_d (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk)), ++ (VBITREV_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vfadd_s (v4f32 LSX128W:$vj), (v4f32 LSX128W:$vk)), ++ (VFADD_S LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vfadd_d (v2f64 LSX128D:$vj), (v2f64 LSX128D:$vk)), ++ (VFADD_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vfsub_s (v4f32 LSX128W:$vj), (v4f32 LSX128W:$vk)), ++ (VFSUB_S LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vfsub_d (v2f64 LSX128D:$vj), (v2f64 LSX128D:$vk)), ++ (VFSUB_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vfmax_s (v4f32 LSX128W:$vj), (v4f32 LSX128W:$vk)), ++ (VFMAX_S LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vfmax_d (v2f64 LSX128D:$vj), (v2f64 LSX128D:$vk)), ++ (VFMAX_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vfmin_s (v4f32 LSX128W:$vj), (v4f32 LSX128W:$vk)), ++ (VFMIN_S LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vfmin_d (v2f64 LSX128D:$vj), (v2f64 LSX128D:$vk)), ++ (VFMIN_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vfmaxa_s (v4f32 LSX128W:$vj), (v4f32 LSX128W:$vk)), ++ (VFMAXA_S LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vfmaxa_d (v2f64 LSX128D:$vj), (v2f64 LSX128D:$vk)), ++ (VFMAXA_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vfmina_s (v4f32 LSX128W:$vj), (v4f32 LSX128W:$vk)), ++ (VFMINA_S LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vfmina_d (v2f64 LSX128D:$vj), (v2f64 LSX128D:$vk)), ++ (VFMINA_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vclo_b (v16i8 LSX128B:$vj)), ++ (VCLO_B LSX128B:$vj)>; ++def : LSXPat<(int_loongarch_lsx_vclo_h (v8i16 LSX128H:$vj)), ++ (VCLO_H LSX128H:$vj)>; ++def : LSXPat<(int_loongarch_lsx_vclo_w (v4i32 LSX128W:$vj)), ++ (VCLO_W LSX128W:$vj)>; ++def : LSXPat<(int_loongarch_lsx_vclo_d (v2i64 LSX128D:$vj)), ++ (VCLO_D LSX128D:$vj)>; ++ ++def : LSXPat<(int_loongarch_lsx_vflogb_s (v4f32 LSX128W:$vj)), ++ (VFLOGB_S LSX128W:$vj)>; ++def : LSXPat<(int_loongarch_lsx_vflogb_d (v2f64 LSX128D:$vj)), ++ (VFLOGB_D LSX128D:$vj)>; ++ ++def : LSXPat<(int_loongarch_lsx_vfclass_s (v4f32 LSX128W:$vj)), ++ (VFCLASS_S LSX128W:$vj)>; ++def : LSXPat<(int_loongarch_lsx_vfclass_d (v2f64 LSX128D:$vj)), ++ (VFCLASS_D LSX128D:$vj)>; ++ ++def : LSXPat<(int_loongarch_lsx_vfrecip_s (v4f32 LSX128W:$vj)), ++ (VFRECIP_S LSX128W:$vj)>; ++def : LSXPat<(int_loongarch_lsx_vfrecip_d (v2f64 LSX128D:$vj)), ++ (VFRECIP_D LSX128D:$vj)>; ++ ++def : LSXPat<(int_loongarch_lsx_vfrsqrt_s (v4f32 LSX128W:$vj)), ++ (VFRSQRT_S LSX128W:$vj)>; ++def : LSXPat<(int_loongarch_lsx_vfrsqrt_d (v2f64 LSX128D:$vj)), ++ (VFRSQRT_D LSX128D:$vj)>; ++ ++def : LSXPat<(int_loongarch_lsx_vfcvtl_s_h (v8i16 LSX128H:$vk)), ++ (VFCVTL_S_H LSX128H:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vfcvth_s_h (v8i16 LSX128H:$vk)), ++ (VFCVTH_S_H LSX128H:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vfcvtl_d_s (v4f32 LSX128W:$vj)), ++ (VFCVTL_D_S LSX128W:$vj)>; ++def : LSXPat<(int_loongarch_lsx_vfcvth_d_s (v4f32 LSX128W:$vj)), ++ (VFCVTH_D_S LSX128W:$vj)>; ++ ++def : LSXPat<(int_loongarch_lsx_vftint_w_s (v4f32 LSX128W:$vj)), ++ (VFTINT_W_S LSX128W:$vj)>; ++def : LSXPat<(int_loongarch_lsx_vftint_l_d (v2f64 LSX128D:$vj)), ++ (VFTINT_L_D LSX128D:$vj)>; ++ ++def : LSXPat<(int_loongarch_lsx_vftint_wu_s (v4f32 LSX128W:$vj)), ++ (VFTINT_WU_S LSX128W:$vj)>; ++def : LSXPat<(int_loongarch_lsx_vftint_lu_d (v2f64 LSX128D:$vj)), ++ (VFTINT_LU_D LSX128D:$vj)>; ++ ++def : LSXPat<(int_loongarch_lsx_vreplgr2vr_b GPR32Opnd:$rj), ++ (VREPLGR2VR_B GPR32Opnd:$rj)>; ++def : LSXPat<(int_loongarch_lsx_vreplgr2vr_h GPR32Opnd:$rj), ++ (VREPLGR2VR_H GPR32Opnd:$rj)>; ++def : LSXPat<(int_loongarch_lsx_vreplgr2vr_w GPR32Opnd:$rj), ++ (VREPLGR2VR_W GPR32Opnd:$rj)>; ++def : LSXPat<(int_loongarch_lsx_vreplgr2vr_d GPR64Opnd:$rj), ++ (VREPLGR2VR_D GPR64Opnd:$rj)>; ++ ++def : LSXPat<(int_loongarch_lsx_vsrlri_b (v16i8 LSX128B:$vj), (immZExt3:$ui3)), ++ (VSRLRI_B LSX128B:$vj, uimm3:$ui3)>; ++def : LSXPat<(int_loongarch_lsx_vsrlri_h (v8i16 LSX128H:$vj), (immZExt4:$ui4)), ++ (VSRLRI_H LSX128H:$vj, uimm4i:$ui4)>; ++def : LSXPat<(int_loongarch_lsx_vsrlri_w (v4i32 LSX128W:$vj), (immZExt5:$ui5)), ++ (VSRLRI_W LSX128W:$vj, uimm5:$ui5)>; ++def : LSXPat<(int_loongarch_lsx_vsrlri_d (v2i64 LSX128D:$vj), (immZExt6:$ui6)), ++ (VSRLRI_D LSX128D:$vj, uimm6:$ui6)>; ++ ++def : LSXPat<(int_loongarch_lsx_vsrari_b (v16i8 LSX128B:$vj), (immZExt3:$ui3)), ++ (VSRARI_B LSX128B:$vj, uimm3:$ui3)>; ++def : LSXPat<(int_loongarch_lsx_vsrari_h (v8i16 LSX128H:$vj), (immZExt4:$ui4)), ++ (VSRARI_H LSX128H:$vj, uimm4i:$ui4)>; ++def : LSXPat<(int_loongarch_lsx_vsrari_w (v4i32 LSX128W:$vj), (immZExt5:$ui5)), ++ (VSRARI_W LSX128W:$vj, uimm5:$ui5)>; ++def : LSXPat<(int_loongarch_lsx_vsrari_d (v2i64 LSX128D:$vj), (immZExt6:$ui6)), ++ (VSRARI_D LSX128D:$vj, uimm6:$ui6)>; ++ ++def : LSXPat<(int_loongarch_lsx_vinsgr2vr_b (v16i8 LSX128B:$vj), GPR32Opnd:$rj, (immZExt4:$ui4)), ++ (VINSGR2VR_B LSX128B:$vj, GPR32Opnd:$rj, (uimm4i:$ui4))>; ++def : LSXPat<(int_loongarch_lsx_vinsgr2vr_h (v8i16 LSX128H:$vj), GPR32Opnd:$rj, (immZExt3:$ui3)), ++ (VINSGR2VR_H LSX128H:$vj, GPR32Opnd:$rj, uimm3:$ui3)>; ++def : LSXPat<(int_loongarch_lsx_vinsgr2vr_w (v4i32 LSX128W:$vj), GPR32Opnd:$rj, (immZExt2:$ui2)), ++ (VINSGR2VR_W LSX128W:$vj, GPR32Opnd:$rj, uimm2:$ui2)>; ++def : LSXPat<(int_loongarch_lsx_vinsgr2vr_d (v2i64 LSX128D:$vj), GPR64Opnd:$rj, (immZExt1:$ui1)), ++ (VINSGR2VR_D LSX128D:$vj, GPR64Opnd:$rj, uimm1i:$ui1)>; ++ ++def : LSXPat<(int_loongarch_lsx_vpickve2gr_b (v16i8 LSX128B:$vj), (immZExt4:$ui4)), ++ (VPICKVE2GR_B LSX128B:$vj, (uimm4i:$ui4))>; ++def : LSXPat<(int_loongarch_lsx_vpickve2gr_h (v8i16 LSX128H:$vj), (immZExt3:$ui3)), ++ (VPICKVE2GR_H LSX128H:$vj, uimm3:$ui3)>; ++def : LSXPat<(int_loongarch_lsx_vpickve2gr_w (v4i32 LSX128W:$vj), (immZExt2:$ui2)), ++ (VPICKVE2GR_W LSX128W:$vj, uimm2:$ui2)>; ++def : LSXPat<(int_loongarch_lsx_vpickve2gr_d (v2i64 LSX128D:$vj), (immZExt1:$ui1)), ++ (VPICKVE2GR_D LSX128D:$vj, uimm1i:$ui1)>; ++ ++def : LSXPat<(int_loongarch_lsx_vpickve2gr_bu (v16i8 LSX128B:$vj), (immZExt4:$ui4)), ++ (VPICKVE2GR_BU LSX128B:$vj, (uimm4i:$ui4))>; ++def : LSXPat<(int_loongarch_lsx_vpickve2gr_hu (v8i16 LSX128H:$vj), (immZExt3:$ui3)), ++ (VPICKVE2GR_HU LSX128H:$vj, uimm3:$ui3)>; ++def : LSXPat<(int_loongarch_lsx_vpickve2gr_wu (v4i32 LSX128W:$vj), (immZExt2:$ui2)), ++ (VPICKVE2GR_WU LSX128W:$vj, uimm2:$ui2)>; ++ ++def : LSXPat<(int_loongarch_lsx_vsat_b (v16i8 LSX128B:$vj), (immZExt3:$ui3)), ++ (VSAT_B LSX128B:$vj, uimm3:$ui3)>; ++def : LSXPat<(int_loongarch_lsx_vsat_h (v8i16 LSX128H:$vj), (immZExt4:$ui4)), ++ (VSAT_H LSX128H:$vj, uimm4i:$ui4)>; ++def : LSXPat<(int_loongarch_lsx_vsat_w (v4i32 LSX128W:$vj), (immZExt5:$ui5)), ++ (VSAT_W LSX128W:$vj, uimm5:$ui5)>; ++def : LSXPat<(int_loongarch_lsx_vsat_d (v2i64 LSX128D:$vj), (immZExt6:$ui6)), ++ (VSAT_D LSX128D:$vj, uimm6:$ui6)>; ++ ++def : LSXPat<(int_loongarch_lsx_vsat_bu (v16i8 LSX128B:$vj), (immZExt3:$ui3)), ++ (VSAT_BU LSX128B:$vj, uimm3:$ui3)>; ++def : LSXPat<(int_loongarch_lsx_vsat_hu (v8i16 LSX128H:$vj), (immZExt4:$ui4)), ++ (VSAT_HU LSX128H:$vj, uimm4i:$ui4)>; ++def : LSXPat<(int_loongarch_lsx_vsat_wu (v4i32 LSX128W:$vj), (immZExt5:$ui5)), ++ (VSAT_WU LSX128W:$vj, uimm5:$ui5)>; ++def : LSXPat<(int_loongarch_lsx_vsat_du (v2i64 LSX128D:$vj), (immZExt6:$ui6)), ++ (VSAT_DU LSX128D:$vj, uimm6:$ui6)>; ++ ++def : LSXPat<(int_loongarch_lsx_vmskltz_b (v16i8 LSX128B:$vj)), ++ (VMSKLTZ_B LSX128B:$vj)>; ++def : LSXPat<(int_loongarch_lsx_vmskltz_h (v8i16 LSX128H:$vj)), ++ (VMSKLTZ_H LSX128H:$vj)>; ++def : LSXPat<(int_loongarch_lsx_vmskltz_w (v4i32 LSX128W:$vj)), ++ (VMSKLTZ_W LSX128W:$vj)>; ++def : LSXPat<(int_loongarch_lsx_vmskltz_d (v2i64 LSX128D:$vj)), ++ (VMSKLTZ_D LSX128D:$vj)>; ++ ++def : LSXPat<(int_loongarch_lsx_vsrlni_b_h (v16i8 LSX128B:$vd_in), (v16i8 LSX128B:$vj), (immZExt4:$ui4)), ++ (VSRLNI_B_H LSX128B:$vd_in, LSX128B:$vj, uimm4i:$ui4)>; ++def : LSXPat<(int_loongarch_lsx_vsrlni_h_w (v8i16 LSX128H:$vd_in), (v8i16 LSX128H:$vj), (immZExt5:$ui5)), ++ (VSRLNI_H_W LSX128H:$vd_in, LSX128H:$vj, uimm5:$ui5)>; ++def : LSXPat<(int_loongarch_lsx_vsrlni_w_d (v4i32 LSX128W:$vd_in), (v4i32 LSX128W:$vj), (immZExt6:$ui6)), ++ (VSRLNI_W_D LSX128W:$vd_in, LSX128W:$vj, uimm6:$ui6)>; ++def : LSXPat<(int_loongarch_lsx_vsrlni_d_q (v2i64 LSX128D:$vd_in), (v2i64 LSX128D:$vj), (immZExt7:$ui7)), ++ (VSRLNI_D_Q LSX128D:$vd_in, LSX128D:$vj, uimm7i:$ui7)>; ++ ++def : LSXPat<(int_loongarch_lsx_vssrlni_b_h (v16i8 LSX128B:$vd_in), (v16i8 LSX128B:$vj), (immZExt4:$ui4)), ++ (VSSRLNI_B_H LSX128B:$vd_in, LSX128B:$vj, uimm4i:$ui4)>; ++def : LSXPat<(int_loongarch_lsx_vssrlni_h_w (v8i16 LSX128H:$vd_in), (v8i16 LSX128H:$vj), (immZExt5:$ui5)), ++ (VSSRLNI_H_W LSX128H:$vd_in, LSX128H:$vj, uimm5:$ui5)>; ++def : LSXPat<(int_loongarch_lsx_vssrlni_w_d (v4i32 LSX128W:$vd_in), (v4i32 LSX128W:$vj), (immZExt6:$ui6)), ++ (VSSRLNI_W_D LSX128W:$vd_in, LSX128W:$vj, uimm6:$ui6)>; ++def : LSXPat<(int_loongarch_lsx_vssrlni_d_q (v2i64 LSX128D:$vd_in), (v2i64 LSX128D:$vj), (immZExt7:$ui7)), ++ (VSSRLNI_D_Q LSX128D:$vd_in, LSX128D:$vj, uimm7i:$ui7)>; ++ ++def : LSXPat<(int_loongarch_lsx_vssrlni_bu_h (v16i8 LSX128B:$vd_in), (v16i8 LSX128B:$vj), (immZExt4:$ui4)), ++ (VSSRLNI_BU_H LSX128B:$vd_in, LSX128B:$vj, uimm4i:$ui4)>; ++def : LSXPat<(int_loongarch_lsx_vssrlni_hu_w (v8i16 LSX128H:$vd_in), (v8i16 LSX128H:$vj), (immZExt5:$ui5)), ++ (VSSRLNI_HU_W LSX128H:$vd_in, LSX128H:$vj, uimm5:$ui5)>; ++def : LSXPat<(int_loongarch_lsx_vssrlni_wu_d (v4i32 LSX128W:$vd_in), (v4i32 LSX128W:$vj), (immZExt6:$ui6)), ++ (VSSRLNI_WU_D LSX128W:$vd_in, LSX128W:$vj, uimm6:$ui6)>; ++def : LSXPat<(int_loongarch_lsx_vssrlni_du_q (v2i64 LSX128D:$vd_in), (v2i64 LSX128D:$vj), (immZExt7:$ui7)), ++ (VSSRLNI_DU_Q LSX128D:$vd_in, LSX128D:$vj, uimm7i:$ui7)>; ++ ++def : LSXPat<(int_loongarch_lsx_vssrlrni_bu_h (v16i8 LSX128B:$vd_in), (v16i8 LSX128B:$vj), (immZExt4:$ui4)), ++ (VSSRLRNI_BU_H LSX128B:$vd_in, LSX128B:$vj, uimm4i:$ui4)>; ++def : LSXPat<(int_loongarch_lsx_vssrlrni_hu_w (v8i16 LSX128H:$vd_in), (v8i16 LSX128H:$vj), (immZExt5:$ui5)), ++ (VSSRLRNI_HU_W LSX128H:$vd_in, LSX128H:$vj, uimm5:$ui5)>; ++def : LSXPat<(int_loongarch_lsx_vssrlrni_wu_d (v4i32 LSX128W:$vd_in), (v4i32 LSX128W:$vj), (immZExt6:$ui6)), ++ (VSSRLRNI_WU_D LSX128W:$vd_in, LSX128W:$vj, uimm6:$ui6)>; ++def : LSXPat<(int_loongarch_lsx_vssrlrni_du_q (v2i64 LSX128D:$vd_in), (v2i64 LSX128D:$vj), (immZExt7:$ui7)), ++ (VSSRLRNI_DU_Q LSX128D:$vd_in, LSX128D:$vj, uimm7i:$ui7)>; ++ ++def : LSXPat<(int_loongarch_lsx_vsrarni_b_h (v16i8 LSX128B:$vd_in), (v16i8 LSX128B:$vj), (immZExt4:$ui4)), ++ (VSRARNI_B_H LSX128B:$vd_in, LSX128B:$vj, uimm4i:$ui4)>; ++def : LSXPat<(int_loongarch_lsx_vsrarni_h_w (v8i16 LSX128H:$vd_in), (v8i16 LSX128H:$vj), (immZExt5:$ui5)), ++ (VSRARNI_H_W LSX128H:$vd_in, LSX128H:$vj, uimm5:$ui5)>; ++def : LSXPat<(int_loongarch_lsx_vsrarni_w_d (v4i32 LSX128W:$vd_in), (v4i32 LSX128W:$vj), (immZExt6:$ui6)), ++ (VSRARNI_W_D LSX128W:$vd_in, LSX128W:$vj, uimm6:$ui6)>; ++def : LSXPat<(int_loongarch_lsx_vsrarni_d_q (v2i64 LSX128D:$vd_in), (v2i64 LSX128D:$vj), (immZExt7:$ui7)), ++ (VSRARNI_D_Q LSX128D:$vd_in, LSX128D:$vj, uimm7i:$ui7)>; ++ ++def : LSXPat<(int_loongarch_lsx_vssrani_b_h (v16i8 LSX128B:$vd_in), (v16i8 LSX128B:$vj), (immZExt4:$ui4)), ++ (VSSRANI_B_H LSX128B:$vd_in, LSX128B:$vj, uimm4i:$ui4)>; ++def : LSXPat<(int_loongarch_lsx_vssrani_h_w (v8i16 LSX128H:$vd_in), (v8i16 LSX128H:$vj), (immZExt5:$ui5)), ++ (VSSRANI_H_W LSX128H:$vd_in, LSX128H:$vj, uimm5:$ui5)>; ++def : LSXPat<(int_loongarch_lsx_vssrani_w_d (v4i32 LSX128W:$vd_in), (v4i32 LSX128W:$vj), (immZExt6:$ui6)), ++ (VSSRANI_W_D LSX128W:$vd_in, LSX128W:$vj, uimm6:$ui6)>; ++def : LSXPat<(int_loongarch_lsx_vssrani_d_q (v2i64 LSX128D:$vd_in), (v2i64 LSX128D:$vj), (immZExt7:$ui7)), ++ (VSSRANI_D_Q LSX128D:$vd_in, LSX128D:$vj, uimm7i:$ui7)>; ++ ++def : LSXPat<(int_loongarch_lsx_vssrani_bu_h (v16i8 LSX128B:$vd_in), (v16i8 LSX128B:$vj), (immZExt4:$ui4)), ++ (VSSRANI_BU_H LSX128B:$vd_in, LSX128B:$vj, uimm4i:$ui4)>; ++def : LSXPat<(int_loongarch_lsx_vssrani_hu_w (v8i16 LSX128H:$vd_in), (v8i16 LSX128H:$vj), (immZExt5:$ui5)), ++ (VSSRANI_HU_W LSX128H:$vd_in, LSX128H:$vj, uimm5:$ui5)>; ++def : LSXPat<(int_loongarch_lsx_vssrani_wu_d (v4i32 LSX128W:$vd_in), (v4i32 LSX128W:$vj), (immZExt6:$ui6)), ++ (VSSRANI_WU_D LSX128W:$vd_in, LSX128W:$vj, uimm6:$ui6)>; ++def : LSXPat<(int_loongarch_lsx_vssrani_du_q (v2i64 LSX128D:$vd_in), (v2i64 LSX128D:$vj), (immZExt7:$ui7)), ++ (VSSRANI_DU_Q LSX128D:$vd_in, LSX128D:$vj, uimm7i:$ui7)>; ++ ++def : LSXPat<(int_loongarch_lsx_vssrarni_b_h (v16i8 LSX128B:$vd_in), (v16i8 LSX128B:$vj), (immZExt4:$ui4)), ++ (VSSRARNI_B_H LSX128B:$vd_in, LSX128B:$vj, uimm4i:$ui4)>; ++def : LSXPat<(int_loongarch_lsx_vssrarni_h_w (v8i16 LSX128H:$vd_in), (v8i16 LSX128H:$vj), (immZExt5:$ui5)), ++ (VSSRARNI_H_W LSX128H:$vd_in, LSX128H:$vj, uimm5:$ui5)>; ++def : LSXPat<(int_loongarch_lsx_vssrarni_w_d (v4i32 LSX128W:$vd_in), (v4i32 LSX128W:$vj), (immZExt6:$ui6)), ++ (VSSRARNI_W_D LSX128W:$vd_in, LSX128W:$vj, uimm6:$ui6)>; ++def : LSXPat<(int_loongarch_lsx_vssrarni_d_q (v2i64 LSX128D:$vd_in), (v2i64 LSX128D:$vj), (immZExt7:$ui7)), ++ (VSSRARNI_D_Q LSX128D:$vd_in, LSX128D:$vj, uimm7i:$ui7)>; ++ ++def : LSXPat<(int_loongarch_lsx_vssrarni_bu_h (v16i8 LSX128B:$vd_in), (v16i8 LSX128B:$vj), (immZExt4:$ui4)), ++ (VSSRARNI_BU_H LSX128B:$vd_in, LSX128B:$vj, uimm4i:$ui4)>; ++def : LSXPat<(int_loongarch_lsx_vssrarni_hu_w (v8i16 LSX128H:$vd_in), (v8i16 LSX128H:$vj), (immZExt5:$ui5)), ++ (VSSRARNI_HU_W LSX128H:$vd_in, LSX128H:$vj, uimm5:$ui5)>; ++def : LSXPat<(int_loongarch_lsx_vssrarni_wu_d (v4i32 LSX128W:$vd_in), (v4i32 LSX128W:$vj), (immZExt6:$ui6)), ++ (VSSRARNI_WU_D LSX128W:$vd_in, LSX128W:$vj, uimm6:$ui6)>; ++def : LSXPat<(int_loongarch_lsx_vssrarni_du_q (v2i64 LSX128D:$vd_in), (v2i64 LSX128D:$vj), (immZExt7:$ui7)), ++ (VSSRARNI_DU_Q LSX128D:$vd_in, LSX128D:$vj, uimm7i:$ui7)>; ++ ++def : LSXPat<(load (add iPTR:$vj, GPR64Opnd:$vk)), ++ (VLDX PtrRC:$vj, GPR64Opnd:$vk)>; ++ ++def : LSXPat<(store (v16i8 LSX128B:$vd), (add iPTR:$vj, GPR64Opnd:$vk)), ++ (VSTX LSX128B:$vd, PtrRC:$vj, GPR64Opnd:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vshuf_b (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk), (v16i8 LSX128B:$va)), ++ (VSHUF_B LSX128B:$vj, LSX128B:$vk, LSX128B:$va)>; ++ ++def : LSXPat<(int_loongarch_lsx_vfcmp_ceq_s (v4f32 LSX128W:$vj), (v4f32 LSX128W:$vk)), ++ (VFCMP_CEQ_S LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vfcmp_ceq_d (v2f64 LSX128D:$vj), (v2f64 LSX128D:$vk)), ++ (VFCMP_CEQ_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vfcmp_cor_s (v4f32 LSX128W:$vj), (v4f32 LSX128W:$vk)), ++ (VFCMP_COR_S LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vfcmp_cor_d (v2f64 LSX128D:$vj), (v2f64 LSX128D:$vk)), ++ (VFCMP_COR_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vfcmp_cun_s (v4f32 LSX128W:$vj), (v4f32 LSX128W:$vk)), ++ (VFCMP_CUN_S LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vfcmp_cun_d (v2f64 LSX128D:$vj), (v2f64 LSX128D:$vk)), ++ (VFCMP_CUN_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vfcmp_cune_s (v4f32 LSX128W:$vj), (v4f32 LSX128W:$vk)), ++ (VFCMP_CUNE_S LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vfcmp_cune_d (v2f64 LSX128D:$vj), (v2f64 LSX128D:$vk)), ++ (VFCMP_CUNE_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vfcmp_cueq_s (v4f32 LSX128W:$vj), (v4f32 LSX128W:$vk)), ++ (VFCMP_CUEQ_S LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vfcmp_cueq_d (v2f64 LSX128D:$vj), (v2f64 LSX128D:$vk)), ++ (VFCMP_CUEQ_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vfcmp_cne_s (v4f32 LSX128W:$vj), (v4f32 LSX128W:$vk)), ++ (VFCMP_CNE_S LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vfcmp_cne_d (v2f64 LSX128D:$vj), (v2f64 LSX128D:$vk)), ++ (VFCMP_CNE_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vfcmp_clt_s (v4f32 LSX128W:$vj), (v4f32 LSX128W:$vk)), ++ (VFCMP_CLT_S LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vfcmp_clt_d (v2f64 LSX128D:$vj), (v2f64 LSX128D:$vk)), ++ (VFCMP_CLT_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vfcmp_cult_s (v4f32 LSX128W:$vj), (v4f32 LSX128W:$vk)), ++ (VFCMP_CULT_S LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vfcmp_cult_d (v2f64 LSX128D:$vj), (v2f64 LSX128D:$vk)), ++ (VFCMP_CULT_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vfcmp_cle_s (v4f32 LSX128W:$vj), (v4f32 LSX128W:$vk)), ++ (VFCMP_CLE_S LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vfcmp_cle_d (v2f64 LSX128D:$vj), (v2f64 LSX128D:$vk)), ++ (VFCMP_CLE_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vfcmp_cule_s (v4f32 LSX128W:$vj), (v4f32 LSX128W:$vk)), ++ (VFCMP_CULE_S LSX128W:$vj, LSX128W:$vk)>; ++def : LSXPat<(int_loongarch_lsx_vfcmp_cule_d (v2f64 LSX128D:$vj), (v2f64 LSX128D:$vk)), ++ (VFCMP_CULE_D LSX128D:$vj, LSX128D:$vk)>; ++ ++def : LSXPat<(int_loongarch_lsx_vftintrz_w_s (v4f32 LSX128W:$vj)), ++ (VFTINTRZ_W_S LSX128W:$vj)>; ++def : LSXPat<(int_loongarch_lsx_vftintrz_l_d (v2f64 LSX128D:$vj)), ++ (VFTINTRZ_L_D LSX128D:$vj)>; ++ ++ ++def imm_mask : ImmLeaf(Imm) && Imm == -1;}]>; ++def imm_mask_64 : ImmLeaf(Imm) && Imm == -1;}]>; ++ ++ ++def : LSXPat<(xor (v8i16 LSX128H:$vj), (vsplati16 imm_mask)), ++ (NOR_V_H_PSEUDO (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vj))>; ++ ++def : LSXPat<(xor (v4i32 LSX128W:$vj), (vsplati32 imm_mask)), ++ (NOR_V_W_PSEUDO (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vj))>; ++ ++def : LSXPat<(xor (v2i64 LSX128D:$vj), (vsplati64 imm_mask_64)), ++ (NOR_V_D_PSEUDO (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vj))>; ++ ++ ++def : LSXPat<(and ++ (v16i8 (xor (v16i8 LSX128B:$vj),(vsplati8 imm_mask))), ++ (v16i8 LSX128B:$vk) ++ ), ++ (VANDN_V (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk))>; ++ ++def : LSXPat<(and ++ (v8i16 (xor (v8i16 LSX128H:$vj), (vsplati16 imm_mask))), ++ (v8i16 LSX128H:$vk) ++ ), ++ (VANDN_H_PSEUDO (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk))>; ++ ++def : LSXPat<(and ++ (v4i32 (xor (v4i32 LSX128W:$vj), (vsplati32 imm_mask))), ++ (v4i32 LSX128W:$vk) ++ ), ++ (VANDN_W_PSEUDO (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk))>; ++ ++def : LSXPat<(and ++ (v2i64 (xor (v2i64 LSX128D:$vj), (vsplati64 imm_mask_64))), ++ (v2i64 LSX128D:$vk) ++ ), ++ (VANDN_D_PSEUDO (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk))>; ++ ++ ++def : LSXPat<(or ++ (v16i8 LSX128B:$vj), ++ (v16i8 (xor (v16i8 LSX128B:$vk), (vsplati8 imm_mask))) ++ ), ++ (VORN_V (v16i8 LSX128B:$vj), (v16i8 LSX128B:$vk))>; ++ ++def : LSXPat<(or ++ (v8i16 LSX128H:$vj), ++ (v8i16 (xor (v8i16 LSX128H:$vk), (vsplati16 imm_mask))) ++ ), ++ (VORN_H_PSEUDO (v8i16 LSX128H:$vj), (v8i16 LSX128H:$vk))>; ++ ++def : LSXPat<(or ++ (v4i32 LSX128W:$vj), ++ (v4i32 (xor (v4i32 LSX128W:$vk), (vsplati32 imm_mask))) ++ ), ++ (VORN_W_PSEUDO (v4i32 LSX128W:$vj), (v4i32 LSX128W:$vk))>; ++ ++def : LSXPat<(or ++ (v2i64 LSX128D:$vj), ++ (v2i64 (xor (v2i64 LSX128D:$vk), (vsplati64 imm_mask_64))) ++ ), ++ (VORN_D_PSEUDO (v2i64 LSX128D:$vj), (v2i64 LSX128D:$vk))>; ++ ++ ++def : LSXPat<(add (v2i64 (abs LSX128D:$a)), (v2i64 (abs LSX128D:$b))), ++ (VADDA_D (v2i64 LSX128D:$a),(v2i64 LSX128D:$b))>; ++ ++def : LSXPat<(add (v4i32 (abs LSX128W:$a)), (v4i32 (abs LSX128W:$b))), ++ (VADDA_W (v4i32 LSX128W:$a),(v4i32 LSX128W:$b))>; ++ ++def : LSXPat<(add (v8i16 (abs LSX128H:$a)), (v8i16 (abs LSX128H:$b))), ++ (VADDA_H (v8i16 LSX128H:$a),(v8i16 LSX128H:$b))>; ++ ++def : LSXPat<(add (v16i8 (abs LSX128B:$a)), (v16i8 (abs LSX128B:$b))), ++ (VADDA_B (v16i8 LSX128B:$a),(v16i8 LSX128B:$b))>; ++ ++ ++def : LSXPat<(and v16i8:$vj, (xor (shl vsplat_imm_eq_1, v16i8:$vk), ++ (vsplati8 imm_mask))), ++ (VBITCLR_B v16i8:$vj, v16i8:$vk)>; ++ ++def : LSXPat<(and v8i16:$vj, (xor (shl vsplat_imm_eq_1, v8i16:$vk), ++ (vsplati16 imm_mask))), ++ (VBITCLR_H v8i16:$vj, v8i16:$vk)>; ++ ++def : LSXPat<(and v4i32:$vj, (xor (shl vsplat_imm_eq_1, v4i32:$vk), ++ (vsplati32 imm_mask))), ++ (VBITCLR_W v4i32:$vj, v4i32:$vk)>; ++ ++def : LSXPat<(and v2i64:$vj, (xor (shl vsplat_imm_eq_1, v2i64:$vk), ++ (vsplati64 imm_mask_64))), ++ (VBITCLR_D v2i64:$vj, v2i64:$vk)>; +diff --git a/llvm/lib/Target/LoongArch/LoongArchLVZInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchLVZInstrInfo.td +deleted file mode 100644 +index 50a16e2dd..000000000 +--- a/llvm/lib/Target/LoongArch/LoongArchLVZInstrInfo.td ++++ /dev/null +@@ -1,33 +0,0 @@ +-//===- LoongArchLVZInstrInfo.td - LoongArch LVZ instructions -*- tablegen -*-=// +-// +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +-// +-//===----------------------------------------------------------------------===// +-// +-// This file describes the LVZ extension instructions. +-// +-//===----------------------------------------------------------------------===// +- +-//===----------------------------------------------------------------------===// +-// Instructions +-//===----------------------------------------------------------------------===// +- +-let hasSideEffects = 1, mayLoad = 0, mayStore = 0, Predicates = [HasExtLVZ] in { +- +-def GCSRRD : FmtCSR<0x05000000, (outs GPR:$rd), (ins uimm14:$csr_num), +- "$rd, $csr_num">; +- +-let Constraints = "$rd = $dst" in { +-def GCSRWR : FmtCSR<0x05000020, (outs GPR:$dst), +- (ins GPR:$rd, uimm14:$csr_num), "$rd, $csr_num">; +-def GCSRXCHG : FmtCSRXCHG<0x05000000, (outs GPR:$dst), +- (ins GPR:$rd, GPR:$rj, uimm14:$csr_num), +- "$rd, $rj, $csr_num">; +-} // Constraints = "$rd = $dst" +- +-def GTLBFLUSH : FmtI32<0x06482401>; +-def HVCL : MISC_I15<0x002b8000>; +- +-} // hasSideEffects = 1, mayLoad = 0, mayStore = 0, Predicates = [HasExtLVZ] +diff --git a/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp b/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp +index 98ad49f25..bf70b09d4 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp ++++ b/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp +@@ -1,4 +1,4 @@ +-//=- LoongArchMCInstLower.cpp - Convert LoongArch MachineInstr to an MCInst -=// ++//===- LoongArchMCInstLower.cpp - Convert LoongArch MachineInstr to MCInst ----------===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -6,164 +6,337 @@ + // + //===----------------------------------------------------------------------===// + // +-// This file contains code to lower LoongArch MachineInstrs to their +-// corresponding MCInst records. ++// This file contains code to lower LoongArch MachineInstrs to their corresponding ++// MCInst records. + // + //===----------------------------------------------------------------------===// + +-#include "LoongArch.h" +-#include "LoongArchSubtarget.h" ++#include "LoongArchMCInstLower.h" + #include "MCTargetDesc/LoongArchBaseInfo.h" + #include "MCTargetDesc/LoongArchMCExpr.h" +-#include "llvm/CodeGen/AsmPrinter.h" ++#include "LoongArchAsmPrinter.h" + #include "llvm/CodeGen/MachineBasicBlock.h" + #include "llvm/CodeGen/MachineInstr.h" +-#include "llvm/MC/MCAsmInfo.h" +-#include "llvm/MC/MCContext.h" +-#include "llvm/Support/raw_ostream.h" ++#include "llvm/CodeGen/MachineOperand.h" ++#include "llvm/MC/MCExpr.h" ++#include "llvm/MC/MCInst.h" ++#include "llvm/Support/ErrorHandling.h" ++#include + + using namespace llvm; + +-static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym, +- const AsmPrinter &AP) { +- MCContext &Ctx = AP.OutContext; +- LoongArchMCExpr::VariantKind Kind; ++LoongArchMCInstLower::LoongArchMCInstLower(LoongArchAsmPrinter &asmprinter) ++ : AsmPrinter(asmprinter) {} + +- switch (MO.getTargetFlags()) { ++void LoongArchMCInstLower::Initialize(MCContext *C) { ++ Ctx = C; ++} ++ ++MCOperand LoongArchMCInstLower::LowerSymbolOperand(const MachineOperand &MO, ++ MachineOperandType MOTy, ++ unsigned Offset) const { ++ MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None; ++ LoongArchMCExpr::LoongArchExprKind TargetKind = LoongArchMCExpr::MEK_None; ++ const MCSymbol *Symbol; ++ ++ switch(MO.getTargetFlags()) { + default: +- llvm_unreachable("Unknown target flag on GV operand"); +- case LoongArchII::MO_None: +- Kind = LoongArchMCExpr::VK_LoongArch_None; ++ llvm_unreachable("Invalid target flag!"); ++ case LoongArchII::MO_NO_FLAG: ++ break; ++ case LoongArchII::MO_GOT_HI: ++ TargetKind = LoongArchMCExpr::MEK_GOT_HI; ++ break; ++ case LoongArchII::MO_GOT_LO: ++ TargetKind = LoongArchMCExpr::MEK_GOT_LO; ++ break; ++ case LoongArchII::MO_GOT_RRHI: ++ TargetKind = LoongArchMCExpr::MEK_GOT_RRHI; + break; +- case LoongArchII::MO_CALL: +- Kind = LoongArchMCExpr::VK_LoongArch_CALL; ++ case LoongArchII::MO_GOT_RRHIGHER: ++ TargetKind = LoongArchMCExpr::MEK_GOT_RRHIGHER; + break; +- case LoongArchII::MO_CALL_PLT: +- Kind = LoongArchMCExpr::VK_LoongArch_CALL_PLT; ++ case LoongArchII::MO_GOT_RRHIGHEST: ++ TargetKind = LoongArchMCExpr::MEK_GOT_RRHIGHEST; ++ break; ++ case LoongArchII::MO_GOT_RRLO: ++ TargetKind = LoongArchMCExpr::MEK_GOT_RRLO; + break; + case LoongArchII::MO_PCREL_HI: +- Kind = LoongArchMCExpr::VK_LoongArch_PCALA_HI20; ++ TargetKind = LoongArchMCExpr::MEK_PCREL_HI; + break; + case LoongArchII::MO_PCREL_LO: +- Kind = LoongArchMCExpr::VK_LoongArch_PCALA_LO12; ++ TargetKind = LoongArchMCExpr::MEK_PCREL_LO; ++ break; ++ case LoongArchII::MO_PCREL_RRHI: ++ TargetKind = LoongArchMCExpr::MEK_PCREL_RRHI; ++ break; ++ case LoongArchII::MO_PCREL_RRHIGHER: ++ TargetKind = LoongArchMCExpr::MEK_PCREL_RRHIGHER; ++ break; ++ case LoongArchII::MO_PCREL_RRHIGHEST: ++ TargetKind = LoongArchMCExpr::MEK_PCREL_RRHIGHEST; ++ break; ++ case LoongArchII::MO_PCREL_RRLO: ++ TargetKind = LoongArchMCExpr::MEK_PCREL_RRLO; + break; +- case LoongArchII::MO_PCREL64_LO: +- Kind = LoongArchMCExpr::VK_LoongArch_PCALA64_LO20; ++ case LoongArchII::MO_TLSIE_HI: ++ TargetKind = LoongArchMCExpr::MEK_TLSIE_HI; + break; +- case LoongArchII::MO_PCREL64_HI: +- Kind = LoongArchMCExpr::VK_LoongArch_PCALA64_HI12; ++ case LoongArchII::MO_TLSIE_LO: ++ TargetKind = LoongArchMCExpr::MEK_TLSIE_LO; + break; +- case LoongArchII::MO_GOT_PC_HI: +- Kind = LoongArchMCExpr::VK_LoongArch_GOT_PC_HI20; ++ case LoongArchII::MO_TLSIE_RRHI: ++ TargetKind = LoongArchMCExpr::MEK_TLSIE_RRHI; + break; +- case LoongArchII::MO_GOT_PC_LO: +- Kind = LoongArchMCExpr::VK_LoongArch_GOT_PC_LO12; ++ case LoongArchII::MO_TLSIE_RRHIGHER: ++ TargetKind = LoongArchMCExpr::MEK_TLSIE_RRHIGHER; + break; +- case LoongArchII::MO_GOT_PC64_LO: +- Kind = LoongArchMCExpr::VK_LoongArch_GOT64_PC_LO20; ++ case LoongArchII::MO_TLSIE_RRHIGHEST: ++ TargetKind = LoongArchMCExpr::MEK_TLSIE_RRHIGHEST; + break; +- case LoongArchII::MO_GOT_PC64_HI: +- Kind = LoongArchMCExpr::VK_LoongArch_GOT64_PC_HI12; ++ case LoongArchII::MO_TLSIE_RRLO: ++ TargetKind = LoongArchMCExpr::MEK_TLSIE_RRLO; + break; +- case LoongArchII::MO_LE_HI: +- Kind = LoongArchMCExpr::VK_LoongArch_TLS_LE_HI20; ++ case LoongArchII::MO_TLSLE_HI: ++ TargetKind = LoongArchMCExpr::MEK_TLSLE_HI; + break; +- case LoongArchII::MO_LE_LO: +- Kind = LoongArchMCExpr::VK_LoongArch_TLS_LE_LO12; ++ case LoongArchII::MO_TLSLE_HIGHER: ++ TargetKind = LoongArchMCExpr::MEK_TLSLE_HIGHER; + break; +- case LoongArchII::MO_LE64_LO: +- Kind = LoongArchMCExpr::VK_LoongArch_TLS_LE64_LO20; ++ case LoongArchII::MO_TLSLE_HIGHEST: ++ TargetKind = LoongArchMCExpr::MEK_TLSLE_HIGHEST; + break; +- case LoongArchII::MO_LE64_HI: +- Kind = LoongArchMCExpr::VK_LoongArch_TLS_LE64_HI12; ++ case LoongArchII::MO_TLSLE_LO: ++ TargetKind = LoongArchMCExpr::MEK_TLSLE_LO; + break; +- case LoongArchII::MO_IE_PC_HI: +- Kind = LoongArchMCExpr::VK_LoongArch_TLS_IE_PC_HI20; ++ case LoongArchII::MO_TLSGD_HI: ++ TargetKind = LoongArchMCExpr::MEK_TLSGD_HI; + break; +- case LoongArchII::MO_IE_PC_LO: +- Kind = LoongArchMCExpr::VK_LoongArch_TLS_IE_PC_LO12; ++ case LoongArchII::MO_TLSGD_LO: ++ TargetKind = LoongArchMCExpr::MEK_TLSGD_LO; + break; +- case LoongArchII::MO_IE_PC64_LO: +- Kind = LoongArchMCExpr::VK_LoongArch_TLS_IE64_PC_LO20; ++ case LoongArchII::MO_TLSGD_RRHI: ++ TargetKind = LoongArchMCExpr::MEK_TLSGD_RRHI; + break; +- case LoongArchII::MO_IE_PC64_HI: +- Kind = LoongArchMCExpr::VK_LoongArch_TLS_IE64_PC_HI12; ++ case LoongArchII::MO_TLSGD_RRHIGHER: ++ TargetKind = LoongArchMCExpr::MEK_TLSGD_RRHIGHER; + break; +- case LoongArchII::MO_LD_PC_HI: +- Kind = LoongArchMCExpr::VK_LoongArch_TLS_LD_PC_HI20; ++ case LoongArchII::MO_TLSGD_RRHIGHEST: ++ TargetKind = LoongArchMCExpr::MEK_TLSGD_RRHIGHEST; + break; +- case LoongArchII::MO_GD_PC_HI: +- Kind = LoongArchMCExpr::VK_LoongArch_TLS_GD_PC_HI20; ++ case LoongArchII::MO_TLSGD_RRLO: ++ TargetKind = LoongArchMCExpr::MEK_TLSGD_RRLO; + break; +- case LoongArchII::MO_CALL36: +- Kind = LoongArchMCExpr::VK_LoongArch_CALL36; ++ case LoongArchII::MO_ABS_HI: ++ TargetKind = LoongArchMCExpr::MEK_ABS_HI; ++ break; ++ case LoongArchII::MO_ABS_HIGHER: ++ TargetKind = LoongArchMCExpr::MEK_ABS_HIGHER; ++ break; ++ case LoongArchII::MO_ABS_HIGHEST: ++ TargetKind = LoongArchMCExpr::MEK_ABS_HIGHEST; ++ break; ++ case LoongArchII::MO_ABS_LO: ++ TargetKind = LoongArchMCExpr::MEK_ABS_LO; ++ break; ++ case LoongArchII::MO_CALL_HI: ++ TargetKind = LoongArchMCExpr::MEK_CALL_HI; ++ break; ++ case LoongArchII::MO_CALL_LO: ++ TargetKind = LoongArchMCExpr::MEK_CALL_LO; + break; +- // TODO: Handle more target-flags. + } + +- const MCExpr *ME = +- MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx); ++ switch (MOTy) { ++ case MachineOperand::MO_MachineBasicBlock: ++ Symbol = MO.getMBB()->getSymbol(); ++ break; + +- if (!MO.isJTI() && !MO.isMBB() && MO.getOffset()) +- ME = MCBinaryExpr::createAdd( +- ME, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); ++ case MachineOperand::MO_GlobalAddress: ++ Symbol = AsmPrinter.getSymbol(MO.getGlobal()); ++ Offset += MO.getOffset(); ++ break; + +- if (Kind != LoongArchMCExpr::VK_LoongArch_None) +- ME = LoongArchMCExpr::create(ME, Kind, Ctx); +- return MCOperand::createExpr(ME); +-} ++ case MachineOperand::MO_BlockAddress: ++ Symbol = AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress()); ++ Offset += MO.getOffset(); ++ break; ++ ++ case MachineOperand::MO_ExternalSymbol: ++ Symbol = AsmPrinter.GetExternalSymbolSymbol(MO.getSymbolName()); ++ Offset += MO.getOffset(); ++ break; ++ ++ case MachineOperand::MO_MCSymbol: ++ Symbol = MO.getMCSymbol(); ++ Offset += MO.getOffset(); ++ break; ++ ++ case MachineOperand::MO_JumpTableIndex: ++ Symbol = AsmPrinter.GetJTISymbol(MO.getIndex()); ++ break; ++ ++ case MachineOperand::MO_ConstantPoolIndex: ++ Symbol = AsmPrinter.GetCPISymbol(MO.getIndex()); ++ Offset += MO.getOffset(); ++ break; + +-bool llvm::lowerLoongArchMachineOperandToMCOperand(const MachineOperand &MO, +- MCOperand &MCOp, +- const AsmPrinter &AP) { +- switch (MO.getType()) { + default: +- report_fatal_error( +- "lowerLoongArchMachineOperandToMCOperand: unknown operand type"); ++ llvm_unreachable(""); ++ } ++ ++ const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, Kind, *Ctx); ++ ++ if (Offset) { ++ // Assume offset is never negative. ++ assert(Offset > 0); ++ ++ Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(Offset, *Ctx), ++ *Ctx); ++ } ++ ++ if (TargetKind != LoongArchMCExpr::MEK_None) ++ Expr = LoongArchMCExpr::create(TargetKind, Expr, *Ctx); ++ ++ return MCOperand::createExpr(Expr); ++} ++ ++MCOperand LoongArchMCInstLower::LowerOperand(const MachineOperand &MO, ++ unsigned offset) const { ++ MachineOperandType MOTy = MO.getType(); ++ ++ switch (MOTy) { ++ default: llvm_unreachable("unknown operand type"); + case MachineOperand::MO_Register: + // Ignore all implicit register operands. +- if (MO.isImplicit()) +- return false; +- MCOp = MCOperand::createReg(MO.getReg()); +- break; +- case MachineOperand::MO_RegisterMask: +- // Regmasks are like implicit defs. +- return false; ++ if (MO.isImplicit()) break; ++ return MCOperand::createReg(MO.getReg()); + case MachineOperand::MO_Immediate: +- MCOp = MCOperand::createImm(MO.getImm()); +- break; ++ return MCOperand::createImm(MO.getImm() + offset); ++ case MachineOperand::MO_MachineBasicBlock: ++ case MachineOperand::MO_GlobalAddress: ++ case MachineOperand::MO_ExternalSymbol: ++ case MachineOperand::MO_MCSymbol: ++ case MachineOperand::MO_JumpTableIndex: + case MachineOperand::MO_ConstantPoolIndex: +- MCOp = lowerSymbolOperand(MO, AP.GetCPISymbol(MO.getIndex()), AP); ++ case MachineOperand::MO_BlockAddress: ++ return LowerSymbolOperand(MO, MOTy, offset); ++ case MachineOperand::MO_RegisterMask: + break; +- case MachineOperand::MO_GlobalAddress: +- MCOp = lowerSymbolOperand(MO, AP.getSymbolPreferLocal(*MO.getGlobal()), AP); ++ } ++ ++ return MCOperand(); ++} ++ ++MCOperand LoongArchMCInstLower::createSub(MachineBasicBlock *BB1, ++ MachineBasicBlock *BB2, ++ LoongArchMCExpr::LoongArchExprKind Kind) const { ++ const MCSymbolRefExpr *Sym1 = MCSymbolRefExpr::create(BB1->getSymbol(), *Ctx); ++ const MCSymbolRefExpr *Sym2 = MCSymbolRefExpr::create(BB2->getSymbol(), *Ctx); ++ const MCBinaryExpr *Sub = MCBinaryExpr::createSub(Sym1, Sym2, *Ctx); ++ ++ return MCOperand::createExpr(LoongArchMCExpr::create(Kind, Sub, *Ctx)); ++} ++ ++void LoongArchMCInstLower::lowerLongBranchADDI(const MachineInstr *MI, ++ MCInst &OutMI, int Opcode) const { ++ OutMI.setOpcode(Opcode); ++ ++ LoongArchMCExpr::LoongArchExprKind Kind; ++ unsigned TargetFlags = MI->getOperand(2).getTargetFlags(); ++ switch (TargetFlags) { ++ case LoongArchII::MO_ABS_HIGHEST: ++ Kind = LoongArchMCExpr::MEK_ABS_HIGHEST; + break; +- case MachineOperand::MO_MachineBasicBlock: +- MCOp = lowerSymbolOperand(MO, MO.getMBB()->getSymbol(), AP); ++ case LoongArchII::MO_ABS_HIGHER: ++ Kind = LoongArchMCExpr::MEK_ABS_HIGHER; + break; +- case MachineOperand::MO_ExternalSymbol: +- MCOp = lowerSymbolOperand( +- MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), AP); ++ case LoongArchII::MO_ABS_HI: ++ Kind = LoongArchMCExpr::MEK_ABS_HI; + break; +- case MachineOperand::MO_BlockAddress: +- MCOp = lowerSymbolOperand( +- MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP); ++ case LoongArchII::MO_ABS_LO: ++ Kind = LoongArchMCExpr::MEK_ABS_LO; + break; +- case MachineOperand::MO_JumpTableIndex: +- MCOp = lowerSymbolOperand(MO, AP.GetJTISymbol(MO.getIndex()), AP); ++ default: ++ report_fatal_error("Unexpected flags for lowerLongBranchADDI"); ++ } ++ ++ // Lower two register operands. ++ for (unsigned I = 0, E = 2; I != E; ++I) { ++ const MachineOperand &MO = MI->getOperand(I); ++ OutMI.addOperand(LowerOperand(MO)); ++ } ++ ++ if (MI->getNumOperands() == 3) { ++ // Lower register operand. ++ const MCExpr *Expr = ++ MCSymbolRefExpr::create(MI->getOperand(2).getMBB()->getSymbol(), *Ctx); ++ const LoongArchMCExpr *LoongArchExpr = LoongArchMCExpr::create(Kind, Expr, *Ctx); ++ OutMI.addOperand(MCOperand::createExpr(LoongArchExpr)); ++ } else if (MI->getNumOperands() == 4) { ++ // Create %lo($tgt-$baltgt) or %hi($tgt-$baltgt). ++ OutMI.addOperand(createSub(MI->getOperand(2).getMBB(), ++ MI->getOperand(3).getMBB(), Kind)); ++ } ++} ++ ++void LoongArchMCInstLower::lowerLongBranchPCADDU12I(const MachineInstr *MI, ++ MCInst &OutMI, int Opcode) const { ++ OutMI.setOpcode(Opcode); ++ ++ LoongArchMCExpr::LoongArchExprKind Kind; ++ unsigned TargetFlags = MI->getOperand(1).getTargetFlags(); ++ switch (TargetFlags) { ++ case LoongArchII::MO_PCREL_HI: ++ Kind = LoongArchMCExpr::MEK_PCREL_HI; + break; ++ case LoongArchII::MO_PCREL_LO: ++ Kind = LoongArchMCExpr::MEK_PCREL_LO; ++ break; ++ default: ++ report_fatal_error("Unexpected flags for lowerLongBranchADDI"); ++ } ++ ++ // Lower one register operands. ++ const MachineOperand &MO = MI->getOperand(0); ++ OutMI.addOperand(LowerOperand(MO)); ++ ++ const MCExpr *Expr = ++ MCSymbolRefExpr::create(MI->getOperand(1).getMBB()->getSymbol(), *Ctx); ++ const LoongArchMCExpr *LoongArchExpr = LoongArchMCExpr::create(Kind, Expr, *Ctx); ++ OutMI.addOperand(MCOperand::createExpr(LoongArchExpr)); ++} ++bool LoongArchMCInstLower::lowerLongBranch(const MachineInstr *MI, ++ MCInst &OutMI) const { ++ switch (MI->getOpcode()) { ++ default: ++ return false; ++ case LoongArch::LONG_BRANCH_ADDIW: ++ case LoongArch::LONG_BRANCH_ADDIW2Op: ++ lowerLongBranchADDI(MI, OutMI, LoongArch::ADDI_W); ++ return true; ++ case LoongArch::LONG_BRANCH_ADDID: ++ case LoongArch::LONG_BRANCH_ADDID2Op: ++ lowerLongBranchADDI(MI, OutMI, LoongArch::ADDI_D); ++ return true; ++ case LoongArch::LONG_BRANCH_PCADDU12I: ++ lowerLongBranchPCADDU12I(MI, OutMI, LoongArch::PCADDU12I); ++ return true; + } +- return true; + } + +-bool llvm::lowerLoongArchMachineInstrToMCInst(const MachineInstr *MI, +- MCInst &OutMI, AsmPrinter &AP) { ++void LoongArchMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { ++ if (lowerLongBranch(MI, OutMI)) ++ return; ++ + OutMI.setOpcode(MI->getOpcode()); + +- for (const MachineOperand &MO : MI->operands()) { +- MCOperand MCOp; +- if (lowerLoongArchMachineOperandToMCOperand(MO, MCOp, AP)) ++ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { ++ const MachineOperand &MO = MI->getOperand(i); ++ MCOperand MCOp = LowerOperand(MO); ++ ++ if (MCOp.isValid()) + OutMI.addOperand(MCOp); + } +- return false; + } +diff --git a/llvm/lib/Target/LoongArch/LoongArchMCInstLower.h b/llvm/lib/Target/LoongArch/LoongArchMCInstLower.h +new file mode 100644 +index 000000000..6463a7b64 +--- /dev/null ++++ b/llvm/lib/Target/LoongArch/LoongArchMCInstLower.h +@@ -0,0 +1,55 @@ ++//===- LoongArchMCInstLower.h - Lower MachineInstr to MCInst --------*- C++ -*--===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHMCINSTLOWER_H ++#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHMCINSTLOWER_H ++ ++#include "MCTargetDesc/LoongArchMCExpr.h" ++#include "llvm/CodeGen/MachineOperand.h" ++#include "llvm/Support/Compiler.h" ++ ++namespace llvm { ++ ++class MachineBasicBlock; ++class MachineInstr; ++class MCContext; ++class MCInst; ++class MCOperand; ++class LoongArchAsmPrinter; ++ ++/// LoongArchMCInstLower - This class is used to lower an MachineInstr into an ++/// MCInst. ++class LLVM_LIBRARY_VISIBILITY LoongArchMCInstLower { ++ using MachineOperandType = MachineOperand::MachineOperandType; ++ ++ MCContext *Ctx; ++ LoongArchAsmPrinter &AsmPrinter; ++ ++public: ++ LoongArchMCInstLower(LoongArchAsmPrinter &asmprinter); ++ ++ void Initialize(MCContext *C); ++ void Lower(const MachineInstr *MI, MCInst &OutMI) const; ++ MCOperand LowerOperand(const MachineOperand& MO, unsigned offset = 0) const; ++ ++private: ++ MCOperand LowerSymbolOperand(const MachineOperand &MO, ++ MachineOperandType MOTy, unsigned Offset) const; ++ MCOperand createSub(MachineBasicBlock *BB1, MachineBasicBlock *BB2, ++ LoongArchMCExpr::LoongArchExprKind Kind) const; ++ void lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI) const; ++ void lowerLongBranchADDI(const MachineInstr *MI, MCInst &OutMI, ++ int Opcode) const; ++ void lowerLongBranchPCADDU12I(const MachineInstr *MI, MCInst &OutMI, ++ int Opcode) const; ++ bool lowerLongBranch(const MachineInstr *MI, MCInst &OutMI) const; ++}; ++ ++} // end namespace llvm ++ ++#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHMCINSTLOWER_H +diff --git a/llvm/lib/Target/LoongArch/LoongArchMachineFunction.cpp b/llvm/lib/Target/LoongArch/LoongArchMachineFunction.cpp +new file mode 100644 +index 000000000..0326cc889 +--- /dev/null ++++ b/llvm/lib/Target/LoongArch/LoongArchMachineFunction.cpp +@@ -0,0 +1,66 @@ ++//===-- LoongArchMachineFunctionInfo.cpp - Private data used for LoongArch ----------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++#include "LoongArchMachineFunction.h" ++#include "MCTargetDesc/LoongArchABIInfo.h" ++#include "LoongArchSubtarget.h" ++#include "LoongArchTargetMachine.h" ++#include "llvm/CodeGen/MachineFrameInfo.h" ++#include "llvm/CodeGen/MachineRegisterInfo.h" ++#include "llvm/CodeGen/PseudoSourceValue.h" ++#include "llvm/CodeGen/PseudoSourceValueManager.h" ++#include "llvm/CodeGen/TargetRegisterInfo.h" ++#include "llvm/Support/CommandLine.h" ++ ++using namespace llvm; ++ ++MachineFunctionInfo * ++LoongArchFunctionInfo::clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, ++ const DenseMap ++ &Src2DstMBB) const { ++ return DestMF.cloneInfo(*this); ++} ++ ++LoongArchFunctionInfo::~LoongArchFunctionInfo() = default; ++ ++void LoongArchFunctionInfo::createEhDataRegsFI(MachineFunction &MF) { ++ const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); ++ for (int I = 0; I < 4; ++I) { ++ const TargetRegisterClass &RC = ++ static_cast(MF.getTarget()).getABI().IsLP64() ++ ? LoongArch::GPR64RegClass ++ : LoongArch::GPR32RegClass; ++ ++ EhDataRegFI[I] = MF.getFrameInfo().CreateStackObject(TRI.getSpillSize(RC), ++ TRI.getSpillAlign(RC), false); ++ } ++} ++ ++bool LoongArchFunctionInfo::isEhDataRegFI(int FI) const { ++ return CallsEhReturn && (FI == EhDataRegFI[0] || FI == EhDataRegFI[1] ++ || FI == EhDataRegFI[2] || FI == EhDataRegFI[3]); ++} ++ ++MachinePointerInfo LoongArchFunctionInfo::callPtrInfo(MachineFunction &MF, const char *ES) { ++ return MachinePointerInfo(MF.getPSVManager().getExternalSymbolCallEntry(ES)); ++} ++ ++MachinePointerInfo LoongArchFunctionInfo::callPtrInfo(MachineFunction &MF, const GlobalValue *GV) { ++ return MachinePointerInfo(MF.getPSVManager().getGlobalValueCallEntry(GV)); ++} ++ ++int LoongArchFunctionInfo::getMoveF64ViaSpillFI(MachineFunction &MF, const TargetRegisterClass *RC) { ++ const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); ++ if (MoveF64ViaSpillFI == -1) { ++ MoveF64ViaSpillFI = MF.getFrameInfo().CreateStackObject( ++ TRI.getSpillSize(*RC), TRI.getSpillAlign(*RC), false); ++ } ++ return MoveF64ViaSpillFI; ++} ++ ++void LoongArchFunctionInfo::anchor() {} +diff --git a/llvm/lib/Target/LoongArch/LoongArchMachineFunction.h b/llvm/lib/Target/LoongArch/LoongArchMachineFunction.h +new file mode 100644 +index 000000000..2f04ddadc +--- /dev/null ++++ b/llvm/lib/Target/LoongArch/LoongArchMachineFunction.h +@@ -0,0 +1,106 @@ ++//===- LoongArchMachineFunctionInfo.h - Private data used for LoongArch ---*- C++ -*-===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++// ++// This file declares the LoongArch specific subclass of MachineFunctionInfo. ++// ++//===----------------------------------------------------------------------===// ++ ++#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHMACHINEFUNCTION_H ++#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHMACHINEFUNCTION_H ++ ++#include "llvm/CodeGen/MachineFunction.h" ++#include "llvm/CodeGen/MachineMemOperand.h" ++#include ++ ++namespace llvm { ++ ++/// LoongArchFunctionInfo - This class is derived from MachineFunction private ++/// LoongArch target-specific information for each MachineFunction. ++class LoongArchFunctionInfo : public MachineFunctionInfo { ++public: ++ LoongArchFunctionInfo(const Function &F, const TargetSubtargetInfo *STI) {} ++ ++ MachineFunctionInfo * ++ clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, ++ const DenseMap &Src2DstMBB) ++ const override; ++ ++ ~LoongArchFunctionInfo() override; ++ ++ unsigned getSRetReturnReg() const { return SRetReturnReg; } ++ void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; } ++ ++ int getVarArgsFrameIndex() const { return VarArgsFrameIndex; } ++ void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; } ++ ++ unsigned getVarArgsSaveSize() const { return VarArgsSaveSize; } ++ void setVarArgsSaveSize(int Size) { VarArgsSaveSize = Size; } ++ ++ bool hasByvalArg() const { return HasByvalArg; } ++ void setFormalArgInfo(unsigned Size, bool HasByval) { ++ IncomingArgSize = Size; ++ HasByvalArg = HasByval; ++ } ++ ++ unsigned getIncomingArgSize() const { return IncomingArgSize; } ++ ++ bool callsEhReturn() const { return CallsEhReturn; } ++ void setCallsEhReturn() { CallsEhReturn = true; } ++ ++ void createEhDataRegsFI(MachineFunction &MF); ++ int getEhDataRegFI(unsigned Reg) const { return EhDataRegFI[Reg]; } ++ bool isEhDataRegFI(int FI) const; ++ ++ /// Create a MachinePointerInfo that has an ExternalSymbolPseudoSourceValue ++ /// object representing a GOT entry for an external function. ++ MachinePointerInfo callPtrInfo(MachineFunction &MF, const char *ES); ++ ++ /// Create a MachinePointerInfo that has a GlobalValuePseudoSourceValue object ++ /// representing a GOT entry for a global function. ++ MachinePointerInfo callPtrInfo(MachineFunction &MF, const GlobalValue *GV); ++ ++ void setSaveS2() { SaveS2 = true; } ++ bool hasSaveS2() const { return SaveS2; } ++ ++ int getMoveF64ViaSpillFI(MachineFunction &MF, const TargetRegisterClass *RC); ++ ++private: ++ virtual void anchor(); ++ ++ /// SRetReturnReg - Some subtargets require that sret lowering includes ++ /// returning the value of the returned struct in a register. This field ++ /// holds the virtual register into which the sret argument is passed. ++ Register SRetReturnReg; ++ ++ /// VarArgsFrameIndex - FrameIndex for start of varargs area. ++ int VarArgsFrameIndex = 0; ++ int VarArgsSaveSize = 0; ++ ++ /// True if function has a byval argument. ++ bool HasByvalArg; ++ ++ /// Size of incoming argument area. ++ unsigned IncomingArgSize; ++ ++ /// CallsEhReturn - Whether the function calls llvm.eh.return. ++ bool CallsEhReturn = false; ++ ++ /// Frame objects for spilling eh data registers. ++ int EhDataRegFI[4]; ++ ++ // saveS2 ++ bool SaveS2 = false; ++ ++ /// FrameIndex for expanding BuildPairF64 nodes to spill and reload when the ++ /// LP32 FPXX ABI is enabled. -1 is used to denote invalid index. ++ int MoveF64ViaSpillFI = -1; ++}; ++ ++} // end namespace llvm ++ ++#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHMACHINEFUNCTION_H +diff --git a/llvm/lib/Target/LoongArch/LoongArchMachineFunctionInfo.h b/llvm/lib/Target/LoongArch/LoongArchMachineFunctionInfo.h +deleted file mode 100644 +index 0d819154a..000000000 +--- a/llvm/lib/Target/LoongArch/LoongArchMachineFunctionInfo.h ++++ /dev/null +@@ -1,69 +0,0 @@ +-//=- LoongArchMachineFunctionInfo.h - LoongArch machine function info -----===// +-// +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +-// +-//===----------------------------------------------------------------------===// +-// +-// This file declares LoongArch-specific per-machine-function information. +-// +-//===----------------------------------------------------------------------===// +- +-#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHMACHINEFUNCTIONINFO_H +-#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHMACHINEFUNCTIONINFO_H +- +-#include "LoongArchSubtarget.h" +-#include "llvm/CodeGen/MachineFrameInfo.h" +-#include "llvm/CodeGen/MachineFunction.h" +- +-namespace llvm { +- +-/// LoongArchMachineFunctionInfo - This class is derived from +-/// MachineFunctionInfo and contains private LoongArch-specific information for +-/// each MachineFunction. +-class LoongArchMachineFunctionInfo : public MachineFunctionInfo { +-private: +- /// FrameIndex for start of varargs area +- int VarArgsFrameIndex = 0; +- /// Size of the save area used for varargs +- int VarArgsSaveSize = 0; +- +- /// Size of stack frame to save callee saved registers +- unsigned CalleeSavedStackSize = 0; +- +- /// FrameIndex of the spill slot when there is no scavenged register in +- /// insertIndirectBranch. +- int BranchRelaxationSpillFrameIndex = -1; +- +-public: +- LoongArchMachineFunctionInfo(const Function &F, +- const TargetSubtargetInfo *STI) {} +- +- MachineFunctionInfo * +- clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, +- const DenseMap &Src2DstMBB) +- const override { +- return DestMF.cloneInfo(*this); +- } +- +- int getVarArgsFrameIndex() const { return VarArgsFrameIndex; } +- void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; } +- +- unsigned getVarArgsSaveSize() const { return VarArgsSaveSize; } +- void setVarArgsSaveSize(int Size) { VarArgsSaveSize = Size; } +- +- unsigned getCalleeSavedStackSize() const { return CalleeSavedStackSize; } +- void setCalleeSavedStackSize(unsigned Size) { CalleeSavedStackSize = Size; } +- +- int getBranchRelaxationSpillFrameIndex() { +- return BranchRelaxationSpillFrameIndex; +- } +- void setBranchRelaxationSpillFrameIndex(int Index) { +- BranchRelaxationSpillFrameIndex = Index; +- } +-}; +- +-} // end namespace llvm +- +-#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHMACHINEFUNCTIONINFO_H +diff --git a/llvm/lib/Target/LoongArch/LoongArchModuleISelDAGToDAG.cpp b/llvm/lib/Target/LoongArch/LoongArchModuleISelDAGToDAG.cpp +new file mode 100644 +index 000000000..8dbf30f21 +--- /dev/null ++++ b/llvm/lib/Target/LoongArch/LoongArchModuleISelDAGToDAG.cpp +@@ -0,0 +1,53 @@ ++//===----------------------------------------------------------------------===// ++// Instruction Selector Subtarget Control ++//===----------------------------------------------------------------------===// ++ ++//===----------------------------------------------------------------------===// ++// This file defines a pass used to change the subtarget for the ++// LoongArch Instruction selector. ++// ++//===----------------------------------------------------------------------===// ++ ++#include "LoongArch.h" ++#include "LoongArchTargetMachine.h" ++#include "llvm/CodeGen/TargetPassConfig.h" ++#include "llvm/CodeGen/StackProtector.h" ++#include "llvm/Support/Debug.h" ++#include "llvm/Support/raw_ostream.h" ++ ++using namespace llvm; ++ ++#define DEBUG_TYPE "loongarch-isel" ++ ++namespace { ++ class LoongArchModuleDAGToDAGISel : public MachineFunctionPass { ++ public: ++ static char ID; ++ ++ LoongArchModuleDAGToDAGISel() : MachineFunctionPass(ID) {} ++ ++ // Pass Name ++ StringRef getPassName() const override { ++ return "LoongArch DAG->DAG Pattern Instruction Selection"; ++ } ++ ++ void getAnalysisUsage(AnalysisUsage &AU) const override { ++ AU.addRequired(); ++ AU.addPreserved(); ++ MachineFunctionPass::getAnalysisUsage(AU); ++ } ++ ++ bool runOnMachineFunction(MachineFunction &MF) override; ++ }; ++ ++ char LoongArchModuleDAGToDAGISel::ID = 0; ++} ++ ++bool LoongArchModuleDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { ++ LLVM_DEBUG(errs() << "In LoongArchModuleDAGToDAGISel::runMachineFunction\n"); ++ return false; ++} ++ ++llvm::FunctionPass *llvm::createLoongArchModuleISelDagPass() { ++ return new LoongArchModuleDAGToDAGISel(); ++} +diff --git a/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.cpp b/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.cpp +index 092b5f1fb..f3dcf9f4b 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.cpp ++++ b/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.cpp +@@ -1,4 +1,4 @@ +-//===- LoongArchRegisterInfo.cpp - LoongArch Register Information -*- C++ -*-=// ++//===- LoongArchRegisterInfo.cpp - LoongArch Register Information -------------------===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -6,214 +6,355 @@ + // + //===----------------------------------------------------------------------===// + // +-// This file contains the LoongArch implementation of the TargetRegisterInfo +-// class. ++// This file contains the LoongArch implementation of the TargetRegisterInfo class. + // + //===----------------------------------------------------------------------===// + + #include "LoongArchRegisterInfo.h" ++#include "MCTargetDesc/LoongArchABIInfo.h" + #include "LoongArch.h" +-#include "LoongArchInstrInfo.h" ++#include "LoongArchMachineFunction.h" + #include "LoongArchSubtarget.h" +-#include "MCTargetDesc/LoongArchBaseInfo.h" +-#include "MCTargetDesc/LoongArchMCTargetDesc.h" ++#include "LoongArchTargetMachine.h" ++#include "llvm/ADT/BitVector.h" ++#include "llvm/ADT/STLExtras.h" + #include "llvm/CodeGen/MachineFrameInfo.h" + #include "llvm/CodeGen/MachineFunction.h" +-#include "llvm/CodeGen/MachineInstrBuilder.h" +-#include "llvm/CodeGen/RegisterScavenging.h" ++#include "llvm/CodeGen/MachineInstr.h" ++#include "llvm/CodeGen/MachineRegisterInfo.h" + #include "llvm/CodeGen/TargetFrameLowering.h" +-#include "llvm/CodeGen/TargetInstrInfo.h" ++#include "llvm/CodeGen/TargetRegisterInfo.h" ++#include "llvm/CodeGen/TargetSubtargetInfo.h" ++#include "llvm/IR/Function.h" ++#include "llvm/MC/MCRegisterInfo.h" ++#include "llvm/Support/Debug.h" + #include "llvm/Support/ErrorHandling.h" ++#include "llvm/Support/raw_ostream.h" ++#include + + using namespace llvm; + ++#define DEBUG_TYPE "loongarch-reg-info" ++ + #define GET_REGINFO_TARGET_DESC + #include "LoongArchGenRegisterInfo.inc" + +-LoongArchRegisterInfo::LoongArchRegisterInfo(unsigned HwMode) +- : LoongArchGenRegisterInfo(LoongArch::R1, /*DwarfFlavour*/ 0, +- /*EHFlavor*/ 0, +- /*PC*/ 0, HwMode) {} ++LoongArchRegisterInfo::LoongArchRegisterInfo() : LoongArchGenRegisterInfo(LoongArch::RA) {} + +-const MCPhysReg * +-LoongArchRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { +- auto &Subtarget = MF->getSubtarget(); ++unsigned LoongArchRegisterInfo::getPICCallReg() { return LoongArch::T8; } ++ ++const TargetRegisterClass * ++LoongArchRegisterInfo::getPointerRegClass(const MachineFunction &MF, ++ unsigned Kind) const { ++ LoongArchABIInfo ABI = MF.getSubtarget().getABI(); ++ LoongArchPtrClass PtrClassKind = static_cast(Kind); ++ ++ switch (PtrClassKind) { ++ case LoongArchPtrClass::Default: ++ return ABI.ArePtrs64bit() ? &LoongArch::GPR64RegClass : &LoongArch::GPR32RegClass; ++ case LoongArchPtrClass::StackPointer: ++ return ABI.ArePtrs64bit() ? &LoongArch::SP64RegClass : &LoongArch::SP32RegClass; ++ } ++ ++ llvm_unreachable("Unknown pointer kind"); ++} + +- if (MF->getFunction().getCallingConv() == CallingConv::GHC) +- return CSR_NoRegs_SaveList; +- switch (Subtarget.getTargetABI()) { ++unsigned ++LoongArchRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC, ++ MachineFunction &MF) const { ++ switch (RC->getID()) { + default: +- llvm_unreachable("Unrecognized ABI"); +- case LoongArchABI::ABI_ILP32S: +- case LoongArchABI::ABI_LP64S: +- return CSR_ILP32S_LP64S_SaveList; +- case LoongArchABI::ABI_ILP32F: +- case LoongArchABI::ABI_LP64F: +- return CSR_ILP32F_LP64F_SaveList; +- case LoongArchABI::ABI_ILP32D: +- case LoongArchABI::ABI_LP64D: +- return CSR_ILP32D_LP64D_SaveList; ++ return 0; ++ case LoongArch::GPR32RegClassID: ++ case LoongArch::GPR64RegClassID: ++ { ++ const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); ++ return 28 - TFI->hasFP(MF); ++ } ++ case LoongArch::FGR32RegClassID: ++ return 32; ++ case LoongArch::FGR64RegClassID: ++ return 32; + } + } + ++//===----------------------------------------------------------------------===// ++// Callee Saved Registers methods ++//===----------------------------------------------------------------------===// ++ ++/// LoongArch Callee Saved Registers ++const MCPhysReg * ++LoongArchRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { ++ const LoongArchSubtarget &Subtarget = MF->getSubtarget(); ++ ++ if (Subtarget.isSingleFloat()) ++ return CSR_SingleFloatOnly_SaveList; ++ ++ if (Subtarget.isABI_LP64()) ++ return CSR_LP64_SaveList; ++ ++ if (Subtarget.isABI_LPX32()) ++ return CSR_LPX32_SaveList; ++ ++ return CSR_LP32_SaveList; ++} ++ + const uint32_t * + LoongArchRegisterInfo::getCallPreservedMask(const MachineFunction &MF, +- CallingConv::ID CC) const { +- auto &Subtarget = MF.getSubtarget(); ++ CallingConv::ID) const { ++ const LoongArchSubtarget &Subtarget = MF.getSubtarget(); + +- if (CC == CallingConv::GHC) +- return CSR_NoRegs_RegMask; +- switch (Subtarget.getTargetABI()) { +- default: +- llvm_unreachable("Unrecognized ABI"); +- case LoongArchABI::ABI_ILP32S: +- case LoongArchABI::ABI_LP64S: +- return CSR_ILP32S_LP64S_RegMask; +- case LoongArchABI::ABI_ILP32F: +- case LoongArchABI::ABI_LP64F: +- return CSR_ILP32F_LP64F_RegMask; +- case LoongArchABI::ABI_ILP32D: +- case LoongArchABI::ABI_LP64D: +- return CSR_ILP32D_LP64D_RegMask; +- } +-} ++ if (Subtarget.isSingleFloat()) ++ return CSR_SingleFloatOnly_RegMask; ++ ++ if (Subtarget.isABI_LP64()) ++ return CSR_LP64_RegMask; + +-const uint32_t *LoongArchRegisterInfo::getNoPreservedMask() const { +- return CSR_NoRegs_RegMask; ++ return CSR_LP32_RegMask; + } + +-BitVector +-LoongArchRegisterInfo::getReservedRegs(const MachineFunction &MF) const { +- const LoongArchFrameLowering *TFI = getFrameLowering(MF); ++BitVector LoongArchRegisterInfo:: ++getReservedRegs(const MachineFunction &MF) const { ++ static const MCPhysReg ReservedGPR32[] = { ++ LoongArch::ZERO, LoongArch::SP, LoongArch::TP, LoongArch::T9 ++ }; ++ ++ static const MCPhysReg ReservedGPR64[] = { ++ LoongArch::ZERO_64, LoongArch::SP_64, LoongArch::TP_64, LoongArch::T9_64 ++ }; ++ + BitVector Reserved(getNumRegs()); ++ const LoongArchSubtarget &Subtarget = MF.getSubtarget(); ++ ++ for (unsigned I = 0; I < std::size(ReservedGPR32); ++I) ++ Reserved.set(ReservedGPR32[I]); ++ ++ for (unsigned I = 0; I < std::size(ReservedGPR64); ++I) ++ Reserved.set(ReservedGPR64[I]); ++ ++ // Reserve FP if this function should have a dedicated frame pointer register. ++ if (Subtarget.getFrameLowering()->hasFP(MF)) { ++ Reserved.set(LoongArch::FP); ++ Reserved.set(LoongArch::FP_64); ++ ++ // Reserve the base register if we need to both realign the stack and ++ // allocate variable-sized objects at runtime. This should test the ++ // same conditions as LoongArchFrameLowering::hasBP(). ++ if (hasStackRealignment(MF) && MF.getFrameInfo().hasVarSizedObjects()) { ++ Reserved.set(LoongArch::S7); ++ Reserved.set(LoongArch::S7_64); ++ } ++ } + +- // Use markSuperRegs to ensure any register aliases are also reserved +- markSuperRegs(Reserved, LoongArch::R0); // zero +- markSuperRegs(Reserved, LoongArch::R2); // tp +- markSuperRegs(Reserved, LoongArch::R3); // sp +- markSuperRegs(Reserved, LoongArch::R21); // non-allocatable +- if (TFI->hasFP(MF)) +- markSuperRegs(Reserved, LoongArch::R22); // fp +- // Reserve the base register if we need to realign the stack and allocate +- // variable-sized objects at runtime. +- if (TFI->hasBP(MF)) +- markSuperRegs(Reserved, LoongArchABI::getBPReg()); // bp +- +- assert(checkAllSuperRegsMarked(Reserved)); + return Reserved; + } + +-Register +-LoongArchRegisterInfo::getFrameRegister(const MachineFunction &MF) const { +- const TargetFrameLowering *TFI = getFrameLowering(MF); +- return TFI->hasFP(MF) ? LoongArch::R22 : LoongArch::R3; ++bool ++LoongArchRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const { ++ return true; ++} ++ ++bool LoongArchRegisterInfo:: ++requiresFrameIndexScavenging(const MachineFunction &MF) const { ++ return true; ++} ++ ++bool ++LoongArchRegisterInfo::trackLivenessAfterRegAlloc(const MachineFunction &MF) const { ++ return true; + } + ++/// Get the size of the offset supported by the given load/store/inline asm. ++/// The result includes the effects of any scale factors applied to the ++/// instruction immediate. ++static inline unsigned getLoadStoreOffsetSizeInBits(const unsigned Opcode, ++ MachineOperand MO) { ++ switch (Opcode) { ++ case LoongArch::LDPTR_W: ++ case LoongArch::LDPTR_W32: ++ case LoongArch::LDPTR_D: ++ case LoongArch::STPTR_W: ++ case LoongArch::STPTR_W32: ++ case LoongArch::STPTR_D: ++ case LoongArch::LL_W: ++ case LoongArch::LL_D: ++ case LoongArch::SC_W: ++ case LoongArch::SC_D: ++ return 14 + 2 /* scale factor */; ++ case LoongArch::INLINEASM: { ++ const InlineAsm::Flag F(MO.getImm()); ++ switch (F.getMemoryConstraintID()) { ++ case InlineAsm::ConstraintCode::ZC: { ++ return 14 + 2 /* scale factor */; ++ } ++ default: ++ return 12; ++ } ++ } ++ default: ++ return 12; ++ } ++} ++ ++/// Get the scale factor applied to the immediate in the given load/store. ++static inline unsigned getLoadStoreOffsetAlign(const unsigned Opcode) { ++ switch (Opcode) { ++ case LoongArch::LDPTR_W: ++ case LoongArch::LDPTR_W32: ++ case LoongArch::LDPTR_D: ++ case LoongArch::STPTR_W: ++ case LoongArch::STPTR_W32: ++ case LoongArch::STPTR_D: ++ case LoongArch::LL_W: ++ case LoongArch::LL_D: ++ case LoongArch::SC_W: ++ case LoongArch::SC_D: ++ return 4; ++ default: ++ return 1; ++ } ++} ++ ++// FrameIndex represent objects inside a abstract stack. ++// We must replace FrameIndex with an stack/frame pointer ++// direct reference. + bool LoongArchRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, + int SPAdj, + unsigned FIOperandNum, + RegScavenger *RS) const { +- // TODO: this implementation is a temporary placeholder which does just +- // enough to allow other aspects of code generation to be tested. +- +- assert(SPAdj == 0 && "Unexpected non-zero SPAdj value"); +- + MachineInstr &MI = *II; +- assert(MI.getOperand(FIOperandNum + 1).isImm() && +- "Unexpected FI-consuming insn"); +- +- MachineBasicBlock &MBB = *MI.getParent(); + MachineFunction &MF = *MI.getParent()->getParent(); +- MachineRegisterInfo &MRI = MF.getRegInfo(); +- const LoongArchSubtarget &STI = MF.getSubtarget(); +- const LoongArchInstrInfo *TII = STI.getInstrInfo(); +- const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); +- DebugLoc DL = MI.getDebugLoc(); +- bool IsLA64 = STI.is64Bit(); +- unsigned MIOpc = MI.getOpcode(); ++ const LoongArchFrameLowering *TFI = getFrameLowering(MF); ++ ++ LLVM_DEBUG(errs() << "\nFunction : " << MF.getName() << "\n"; ++ errs() << "<--------->\n" ++ << MI); + + int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); ++ uint64_t stackSize = MF.getFrameInfo().getStackSize(); ++ int64_t spOffset = MF.getFrameInfo().getObjectOffset(FrameIndex); ++ ++ LLVM_DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n" ++ << "spOffset : " << spOffset << "\n" ++ << "stackSize : " << stackSize << "\n" ++ << "SPAdj : " << SPAdj << "\n" ++ << "alignment : " ++ << DebugStr(MF.getFrameInfo().getObjectAlign(FrameIndex)) ++ << "\n"); ++ ++ LoongArchABIInfo ABI = ++ static_cast(MF.getTarget()).getABI(); ++ ++ // Everything else is referenced relative to whatever register ++ // getFrameIndexReference() returns. + Register FrameReg; + StackOffset Offset = + TFI->getFrameIndexReference(MF, FrameIndex, FrameReg) + + StackOffset::getFixed(MI.getOperand(FIOperandNum + 1).getImm()); + +- bool FrameRegIsKill = false; ++ LLVM_DEBUG(errs() << "Location : " ++ << "FrameReg<" << FrameReg << "> + " << Offset.getFixed() ++ << "\n<--------->\n"); + +- if (!isInt<12>(Offset.getFixed())) { +- unsigned Addi = IsLA64 ? LoongArch::ADDI_D : LoongArch::ADDI_W; +- unsigned Add = IsLA64 ? LoongArch::ADD_D : LoongArch::ADD_W; ++ MachineBasicBlock &MBB = *MI.getParent(); ++ DebugLoc DL = II->getDebugLoc(); ++ bool IsKill = false; + +- // The offset won't fit in an immediate, so use a scratch register instead. +- // Modify Offset and FrameReg appropriately. +- Register ScratchReg = MRI.createVirtualRegister(&LoongArch::GPRRegClass); +- TII->movImm(MBB, II, DL, ScratchReg, Offset.getFixed()); +- if (MIOpc == Addi) { +- BuildMI(MBB, II, DL, TII->get(Add), MI.getOperand(0).getReg()) ++ if (!MI.isDebugValue()) { ++ // Make sure Offset fits within the field available. ++ // For ldptr/stptr/ll/sc instructions, this is a 14-bit signed immediate ++ // (scaled by 2), otherwise it is a 12-bit signed immediate. ++ unsigned OffsetBitSize = getLoadStoreOffsetSizeInBits( ++ MI.getOpcode(), MI.getOperand(FIOperandNum - 1)); ++ const Align OffsetAlign(getLoadStoreOffsetAlign(MI.getOpcode())); ++ ++ if (OffsetBitSize == 16 && isInt<12>(Offset.getFixed()) && ++ !isAligned(OffsetAlign, Offset.getFixed())) { ++ // If we have an offset that needs to fit into a signed n-bit immediate ++ // (where n == 16) and doesn't aligned and does fit into 12-bits ++ // then use an ADDI ++ const TargetRegisterClass *PtrRC = ABI.ArePtrs64bit() ++ ? &LoongArch::GPR64RegClass ++ : &LoongArch::GPR32RegClass; ++ MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo(); ++ unsigned Reg = RegInfo.createVirtualRegister(PtrRC); ++ const LoongArchInstrInfo &TII = *static_cast( ++ MBB.getParent()->getSubtarget().getInstrInfo()); ++ BuildMI(MBB, II, DL, TII.get(ABI.GetPtrAddiOp()), Reg) + .addReg(FrameReg) +- .addReg(ScratchReg, RegState::Kill); +- MI.eraseFromParent(); +- return true; +- } +- BuildMI(MBB, II, DL, TII->get(Add), ScratchReg) +- .addReg(FrameReg) +- .addReg(ScratchReg, RegState::Kill); +- Offset = StackOffset::getFixed(0); +- FrameReg = ScratchReg; +- FrameRegIsKill = true; +- } ++ .addImm(Offset.getFixed()); + +- // Spill CFRs. +- if (MIOpc == LoongArch::PseudoST_CFR) { +- Register ScratchReg = MRI.createVirtualRegister(&LoongArch::GPRRegClass); +- BuildMI(MBB, II, DL, TII->get(LoongArch::MOVCF2GR), ScratchReg) +- .add(MI.getOperand(0)); +- BuildMI(MBB, II, DL, TII->get(IsLA64 ? LoongArch::ST_D : LoongArch::ST_W)) +- .addReg(ScratchReg, RegState::Kill) +- .addReg(FrameReg) +- .addImm(Offset.getFixed()); +- MI.eraseFromParent(); +- return true; +- } ++ FrameReg = Reg; ++ Offset = StackOffset::getFixed(0); ++ IsKill = true; ++ } else if (!isInt<12>(Offset.getFixed())) { ++ // Otherwise split the offset into several pieces and add it in multiple ++ // instructions. ++ const LoongArchInstrInfo &TII = *static_cast( ++ MBB.getParent()->getSubtarget().getInstrInfo()); ++ unsigned Reg = TII.loadImmediate(Offset.getFixed(), MBB, II, DL); ++ BuildMI(MBB, II, DL, TII.get(ABI.GetPtrAddOp()), Reg) ++ .addReg(FrameReg) ++ .addReg(Reg, RegState::Kill); + +- // Reload CFRs. +- if (MIOpc == LoongArch::PseudoLD_CFR) { +- Register ScratchReg = MRI.createVirtualRegister(&LoongArch::GPRRegClass); +- BuildMI(MBB, II, DL, TII->get(IsLA64 ? LoongArch::LD_D : LoongArch::LD_W), +- ScratchReg) +- .addReg(FrameReg) +- .addImm(Offset.getFixed()); +- BuildMI(MBB, II, DL, TII->get(LoongArch::MOVGR2CF)) +- .add(MI.getOperand(0)) +- .addReg(ScratchReg, RegState::Kill); +- MI.eraseFromParent(); +- return true; ++ FrameReg = Reg; ++ Offset = StackOffset::getFixed(0); ++ IsKill = true; ++ } + } + +- MI.getOperand(FIOperandNum) +- .ChangeToRegister(FrameReg, false, false, FrameRegIsKill); ++ MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false, false, IsKill); + MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset.getFixed()); ++ // Todo: Fixme + return false; + } + ++Register LoongArchRegisterInfo:: ++getFrameRegister(const MachineFunction &MF) const { ++ const LoongArchSubtarget &Subtarget = MF.getSubtarget(); ++ const TargetFrameLowering *TFI = Subtarget.getFrameLowering(); ++ bool IsLP64 = ++ static_cast(MF.getTarget()).getABI().IsLP64(); ++ ++ return TFI->hasFP(MF) ? (IsLP64 ? LoongArch::FP_64 : LoongArch::FP) : ++ (IsLP64 ? LoongArch::SP_64 : LoongArch::SP); ++} ++ ++const TargetRegisterClass * ++LoongArchRegisterInfo::intRegClass(unsigned Size) const { ++ if (Size == 4) ++ return &LoongArch::GPR32RegClass; ++ ++ assert(Size == 8); ++ return &LoongArch::GPR64RegClass; ++} ++ + bool LoongArchRegisterInfo::canRealignStack(const MachineFunction &MF) const { ++ // Avoid realigning functions that explicitly do not want to be realigned. ++ // Normally, we should report an error when a function should be dynamically ++ // realigned but also has the attribute no-realign-stack. Unfortunately, ++ // with this attribute, MachineFrameInfo clamps each new object's alignment ++ // to that of the stack's alignment as specified by the ABI. As a result, ++ // the information of whether we have objects with larger alignment ++ // requirement than the stack's alignment is already lost at this point. + if (!TargetRegisterInfo::canRealignStack(MF)) + return false; + +- const MachineRegisterInfo *MRI = &MF.getRegInfo(); +- const LoongArchFrameLowering *TFI = getFrameLowering(MF); ++ const LoongArchSubtarget &Subtarget = MF.getSubtarget(); ++ unsigned FP = Subtarget.is64Bit() ? LoongArch::FP_64 : LoongArch::FP; ++ unsigned BP = Subtarget.is64Bit() ? LoongArch::S7_64 : LoongArch::S7; + +- // Stack realignment requires a frame pointer. If we already started +- // register allocation with frame pointer elimination, it is too late now. +- if (!MRI->canReserveReg(LoongArch::R22)) ++ // We can't perform dynamic stack realignment if we can't reserve the ++ // frame pointer register. ++ if (!MF.getRegInfo().canReserveReg(FP)) + return false; + +- // We may also need a base pointer if there are dynamic allocas or stack +- // pointer adjustments around calls. +- if (TFI->hasReservedCallFrame(MF)) ++ // We can realign the stack if we know the maximum call frame size and we ++ // don't have variable sized objects. ++ if (Subtarget.getFrameLowering()->hasReservedCallFrame(MF)) + return true; + +- // A base pointer is required and allowed. Check that it isn't too late to +- // reserve it. +- return MRI->canReserveReg(LoongArchABI::getBPReg()); ++ // We have to reserve the base pointer register in the presence of variable ++ // sized objects. ++ return MF.getRegInfo().canReserveReg(BP); + } +diff --git a/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.h b/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.h +index d1e40254c..044ce418f 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.h ++++ b/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.h +@@ -1,4 +1,4 @@ +-//= LoongArchRegisterInfo.h - LoongArch Register Information Impl -*- C++ -*-=// ++//===- LoongArchRegisterInfo.h - LoongArch Register Information Impl ------*- C++ -*-===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -6,53 +6,75 @@ + // + //===----------------------------------------------------------------------===// + // +-// This file contains the LoongArch implementation of the TargetRegisterInfo +-// class. ++// This file contains the LoongArch implementation of the TargetRegisterInfo class. + // + //===----------------------------------------------------------------------===// + + #ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHREGISTERINFO_H + #define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHREGISTERINFO_H + +-#include "llvm/CodeGen/TargetRegisterInfo.h" ++#include "LoongArch.h" ++#include "llvm/CodeGen/MachineBasicBlock.h" ++#include + + #define GET_REGINFO_HEADER + #include "LoongArchGenRegisterInfo.inc" + + namespace llvm { + +-struct LoongArchRegisterInfo : public LoongArchGenRegisterInfo { ++class TargetRegisterClass; + +- LoongArchRegisterInfo(unsigned HwMode); ++class LoongArchRegisterInfo : public LoongArchGenRegisterInfo { ++public: ++ enum class LoongArchPtrClass { ++ /// The default register class for integer values. ++ Default = 0, ++ /// The stack pointer only. ++ StackPointer = 1, ++ }; + ++ LoongArchRegisterInfo(); ++ ++ /// Get PIC indirect call register ++ static unsigned getPICCallReg(); ++ ++ /// Code Generation virtual methods... ++ const TargetRegisterClass *getPointerRegClass(const MachineFunction &MF, ++ unsigned Kind) const override; ++ ++ unsigned getRegPressureLimit(const TargetRegisterClass *RC, ++ MachineFunction &MF) const override; + const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override; + const uint32_t *getCallPreservedMask(const MachineFunction &MF, + CallingConv::ID) const override; +- const uint32_t *getNoPreservedMask() const override; +- + BitVector getReservedRegs(const MachineFunction &MF) const override; + +- const TargetRegisterClass * +- getPointerRegClass(const MachineFunction &MF, +- unsigned Kind = 0) const override { +- return &LoongArch::GPRRegClass; +- } ++ bool requiresRegisterScavenging(const MachineFunction &MF) const override; ++ ++ bool requiresFrameIndexScavenging(const MachineFunction &MF) const override; + ++ bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const override; ++ ++ /// Stack Frame Processing Methods + bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, + unsigned FIOperandNum, + RegScavenger *RS = nullptr) const override; + ++ // Stack realignment queries. ++ bool canRealignStack(const MachineFunction &MF) const override; ++ ++ /// Debug information queries. + Register getFrameRegister(const MachineFunction &MF) const override; + +- bool requiresRegisterScavenging(const MachineFunction &MF) const override { +- return true; +- } ++ /// Return GPR register class. ++ const TargetRegisterClass *intRegClass(unsigned Size) const; + +- bool requiresFrameIndexScavenging(const MachineFunction &MF) const override { +- return true; +- } +- bool canRealignStack(const MachineFunction &MF) const override; ++private: ++ void eliminateFI(MachineBasicBlock::iterator II, unsigned OpNo, ++ int FrameIndex, uint64_t StackSize, ++ int SPAdj, int64_t SPOffset) const; + }; ++ + } // end namespace llvm + + #endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHREGISTERINFO_H +diff --git a/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td b/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td +index fbca110fd..96569e075 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td ++++ b/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td +@@ -1,4 +1,4 @@ +-//===-- LoongArchRegisterInfo.td - LoongArch Register defs -*- tablegen -*-===// ++//===-- LoongArchRegisterInfo.td - LoongArch Register defs -----------*- tablegen -*-===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -7,210 +7,367 @@ + //===----------------------------------------------------------------------===// + + //===----------------------------------------------------------------------===// +-// Declarations that describe the LoongArch register files ++// Declarations that describe the LoongArch register file + //===----------------------------------------------------------------------===// +- + let Namespace = "LoongArch" in { +-class LoongArchReg Enc, string n, list alt = []> +- : Register { +- let HWEncoding = Enc; +- let AltNames = alt; ++def sub_32 : SubRegIndex<32>; ++def sub_64 : SubRegIndex<64>; ++def sub_128 : SubRegIndex<128>; ++def sub_fcsr1 : SubRegIndex<5>; ++def sub_fcsr2 : SubRegIndex<13, 16>; ++def sub_fcsr3 : SubRegIndex<2, 8>; ++def sub_lo : SubRegIndex<32>; ++def sub_hi : SubRegIndex<32, 32>; ++def PC : Register<"pc">; + } + +-class LoongArchRegWithSubRegs Enc, string n, list subregs, +- list alt = []> +- : RegisterWithSubRegs { ++class Unallocatable { ++ bit isAllocatable = 0; ++} ++ ++/// We have banks of registers each. ++class LoongArchReg Enc, string n> : Register { + let HWEncoding = Enc; +- let AltNames = alt; ++ let Namespace = "LoongArch"; + } + +-class LoongArchReg32 Enc, string n, list alt = []> +- : Register { ++class LoongArchRegWithSubRegs Enc, string n, list subregs> ++ : RegisterWithSubRegs { + let HWEncoding = Enc; +- let AltNames = alt; ++ let Namespace = "LoongArch"; + } + +-def sub_32 : SubRegIndex<32>; +-class LoongArchReg64 +- : LoongArchRegWithSubRegs { ++/// LoongArch 32-bit CPU Registers. ++class LoongArch32GPR Enc, string n> : LoongArchReg; ++ ++/// LoongArch 64-bit CPU Registers. ++class LoongArch64GPR Enc, string n, list subregs> ++ : LoongArchRegWithSubRegs { + let SubRegIndices = [sub_32]; + } + +-def sub_64 : SubRegIndex<64>; +-class LoongArchReg128 +- : LoongArchRegWithSubRegs { ++/// LoongArch 64-bit Floating-point Registers ++class FGR32 Enc, string n> : LoongArchReg; ++class FGR64 Enc, string n, list subregs> ++ : LoongArchRegWithSubRegs { ++ let SubRegIndices = [sub_lo]; ++} ++ ++// LoongArch 128-bit (aliased) LSX Registers ++class LSX128 Enc, string n, list subregs> ++ : LoongArchRegWithSubRegs { + let SubRegIndices = [sub_64]; + } + +-def sub_128 : SubRegIndex<128>; +-class LoongArchReg256 +- : LoongArchRegWithSubRegs { ++// LoongArch 256-bit (aliased) LASX Registers ++class LASX256 Enc, string n, list subregs> ++ : LoongArchRegWithSubRegs { + let SubRegIndices = [sub_128]; + } + +-let FallbackRegAltNameIndex = NoRegAltName in +-def RegAliasName : RegAltNameIndex; +-} // Namespace = "LoongArch" +- +-// Integer registers +- +-let RegAltNameIndices = [RegAliasName] in { +- let isConstant = true in +- def R0 : LoongArchReg<0, "r0", ["zero"]>, DwarfRegNum<[0]>; +- def R1 : LoongArchReg<1, "r1", ["ra"]>, DwarfRegNum<[1]>; +- def R2 : LoongArchReg<2, "r2", ["tp"]>, DwarfRegNum<[2]>; +- def R3 : LoongArchReg<3, "r3", ["sp"]>, DwarfRegNum<[3]>; +- def R4 : LoongArchReg<4, "r4", ["a0"]>, DwarfRegNum<[4]>; +- def R5 : LoongArchReg<5, "r5", ["a1"]>, DwarfRegNum<[5]>; +- def R6 : LoongArchReg<6, "r6", ["a2"]>, DwarfRegNum<[6]>; +- def R7 : LoongArchReg<7, "r7", ["a3"]>, DwarfRegNum<[7]>; +- def R8 : LoongArchReg<8, "r8", ["a4"]>, DwarfRegNum<[8]>; +- def R9 : LoongArchReg<9, "r9", ["a5"]>, DwarfRegNum<[9]>; +- def R10 : LoongArchReg<10, "r10", ["a6"]>, DwarfRegNum<[10]>; +- def R11 : LoongArchReg<11, "r11", ["a7"]>, DwarfRegNum<[11]>; +- def R12 : LoongArchReg<12, "r12", ["t0"]>, DwarfRegNum<[12]>; +- def R13 : LoongArchReg<13, "r13", ["t1"]>, DwarfRegNum<[13]>; +- def R14 : LoongArchReg<14, "r14", ["t2"]>, DwarfRegNum<[14]>; +- def R15 : LoongArchReg<15, "r15", ["t3"]>, DwarfRegNum<[15]>; +- def R16 : LoongArchReg<16, "r16", ["t4"]>, DwarfRegNum<[16]>; +- def R17 : LoongArchReg<17, "r17", ["t5"]>, DwarfRegNum<[17]>; +- def R18 : LoongArchReg<18, "r18", ["t6"]>, DwarfRegNum<[18]>; +- def R19 : LoongArchReg<19, "r19", ["t7"]>, DwarfRegNum<[19]>; +- def R20 : LoongArchReg<20, "r20", ["t8"]>, DwarfRegNum<[20]>; +- def R21 : LoongArchReg<21, "r21", [""]>, DwarfRegNum<[21]>; +- def R22 : LoongArchReg<22, "r22", ["fp", "s9"]>, DwarfRegNum<[22]>; +- def R23 : LoongArchReg<23, "r23", ["s0"]>, DwarfRegNum<[23]>; +- def R24 : LoongArchReg<24, "r24", ["s1"]>, DwarfRegNum<[24]>; +- def R25 : LoongArchReg<25, "r25", ["s2"]>, DwarfRegNum<[25]>; +- def R26 : LoongArchReg<26, "r26", ["s3"]>, DwarfRegNum<[26]>; +- def R27 : LoongArchReg<27, "r27", ["s4"]>, DwarfRegNum<[27]>; +- def R28 : LoongArchReg<28, "r28", ["s5"]>, DwarfRegNum<[28]>; +- def R29 : LoongArchReg<29, "r29", ["s6"]>, DwarfRegNum<[29]>; +- def R30 : LoongArchReg<30, "r30", ["s7"]>, DwarfRegNum<[30]>; +- def R31 : LoongArchReg<31, "r31", ["s8"]>, DwarfRegNum<[31]>; +-} // RegAltNameIndices = [RegAliasName] +- +-def GRLenVT : ValueTypeByHwMode<[LA32, LA64], +- [i32, i64]>; +-def GRLenRI : RegInfoByHwMode< +- [LA32, LA64], +- [RegInfo<32,32,32>, RegInfo<64,64,64>]>; +- +-// The order of registers represents the preferred allocation sequence. +-// Registers are listed in the order caller-save, callee-save, specials. +-def GPR : RegisterClass<"LoongArch", [GRLenVT], 32, (add +- // Argument registers (a0...a7) +- (sequence "R%u", 4, 11), +- // Temporary registers (t0...t8) +- (sequence "R%u", 12, 20), +- // Static register (s9/fp, s0...s8) +- (sequence "R%u", 22, 31), +- // Specials (r0, ra, tp, sp) +- (sequence "R%u", 0, 3), +- // Reserved (Non-allocatable) +- R21 +- )> { +- let RegInfos = GRLenRI; +-} +- +-// GPR for indirect tail calls. We can't use callee-saved registers, as they are +-// restored to the saved value before the tail call, which would clobber a call +-// address. +-def GPRT : RegisterClass<"LoongArch", [GRLenVT], 32, (add +- // a0...a7, t0...t8 +- (sequence "R%u", 4, 20) +- )> { +- let RegInfos = GRLenRI; +-} +- +-// Floating point registers +- +-let RegAltNameIndices = [RegAliasName] in { +- def F0 : LoongArchReg32<0, "f0", ["fa0"]>, DwarfRegNum<[32]>; +- def F1 : LoongArchReg32<1, "f1", ["fa1"]>, DwarfRegNum<[33]>; +- def F2 : LoongArchReg32<2, "f2", ["fa2"]>, DwarfRegNum<[34]>; +- def F3 : LoongArchReg32<3, "f3", ["fa3"]>, DwarfRegNum<[35]>; +- def F4 : LoongArchReg32<4, "f4", ["fa4"]>, DwarfRegNum<[36]>; +- def F5 : LoongArchReg32<5, "f5", ["fa5"]>, DwarfRegNum<[37]>; +- def F6 : LoongArchReg32<6, "f6", ["fa6"]>, DwarfRegNum<[38]>; +- def F7 : LoongArchReg32<7, "f7", ["fa7"]>, DwarfRegNum<[39]>; +- def F8 : LoongArchReg32<8, "f8", ["ft0"]>, DwarfRegNum<[40]>; +- def F9 : LoongArchReg32<9, "f9", ["ft1"]>, DwarfRegNum<[41]>; +- def F10 : LoongArchReg32<10,"f10", ["ft2"]>, DwarfRegNum<[42]>; +- def F11 : LoongArchReg32<11,"f11", ["ft3"]>, DwarfRegNum<[43]>; +- def F12 : LoongArchReg32<12,"f12", ["ft4"]>, DwarfRegNum<[44]>; +- def F13 : LoongArchReg32<13,"f13", ["ft5"]>, DwarfRegNum<[45]>; +- def F14 : LoongArchReg32<14,"f14", ["ft6"]>, DwarfRegNum<[46]>; +- def F15 : LoongArchReg32<15,"f15", ["ft7"]>, DwarfRegNum<[47]>; +- def F16 : LoongArchReg32<16,"f16", ["ft8"]>, DwarfRegNum<[48]>; +- def F17 : LoongArchReg32<17,"f17", ["ft9"]>, DwarfRegNum<[49]>; +- def F18 : LoongArchReg32<18,"f18", ["ft10"]>, DwarfRegNum<[50]>; +- def F19 : LoongArchReg32<19,"f19", ["ft11"]>, DwarfRegNum<[51]>; +- def F20 : LoongArchReg32<20,"f20", ["ft12"]>, DwarfRegNum<[52]>; +- def F21 : LoongArchReg32<21,"f21", ["ft13"]>, DwarfRegNum<[53]>; +- def F22 : LoongArchReg32<22,"f22", ["ft14"]>, DwarfRegNum<[54]>; +- def F23 : LoongArchReg32<23,"f23", ["ft15"]>, DwarfRegNum<[55]>; +- def F24 : LoongArchReg32<24,"f24", ["fs0"]>, DwarfRegNum<[56]>; +- def F25 : LoongArchReg32<25,"f25", ["fs1"]>, DwarfRegNum<[57]>; +- def F26 : LoongArchReg32<26,"f26", ["fs2"]>, DwarfRegNum<[58]>; +- def F27 : LoongArchReg32<27,"f27", ["fs3"]>, DwarfRegNum<[59]>; +- def F28 : LoongArchReg32<28,"f28", ["fs4"]>, DwarfRegNum<[60]>; +- def F29 : LoongArchReg32<29,"f29", ["fs5"]>, DwarfRegNum<[61]>; +- def F30 : LoongArchReg32<30,"f30", ["fs6"]>, DwarfRegNum<[62]>; +- def F31 : LoongArchReg32<31,"f31", ["fs7"]>, DwarfRegNum<[63]>; +- +- foreach I = 0-31 in { +- def F#I#_64 : LoongArchReg64("F"#I)>, +- DwarfRegNum<[!add(I, 32)]>; +- } +-} +- +-// The order of registers represents the preferred allocation sequence. +-def FPR32 : RegisterClass<"LoongArch", [f32], 32, (sequence "F%u", 0, 31)>; +-def FPR64 : RegisterClass<"LoongArch", [f64], 64, (sequence "F%u_64", 0, 31)>; +- +-// Condition flag registers ++//===----------------------------------------------------------------------===// ++// Registers ++//===----------------------------------------------------------------------===// + ++/// General Purpose 32-bit Registers ++def ZERO : LoongArch32GPR<0, "zero">, ++ DwarfRegNum<[0]>; ++def RA : LoongArch32GPR<1, "ra">, DwarfRegNum<[1]>; ++def TP : LoongArch32GPR<2, "tp">, DwarfRegNum<[2]>; ++def SP : LoongArch32GPR<3, "sp">, DwarfRegNum<[3]>; ++def A0 : LoongArch32GPR<4, "r4">, DwarfRegNum<[4]>; ++def A1 : LoongArch32GPR<5, "r5">, DwarfRegNum<[5]>; ++def A2 : LoongArch32GPR<6, "r6">, DwarfRegNum<[6]>; ++def A3 : LoongArch32GPR<7, "r7">, DwarfRegNum<[7]>; ++def A4 : LoongArch32GPR<8, "r8">, DwarfRegNum<[8]>; ++def A5 : LoongArch32GPR<9, "r9">, DwarfRegNum<[9]>; ++def A6 : LoongArch32GPR<10, "r10">, DwarfRegNum<[10]>; ++def A7 : LoongArch32GPR<11, "r11">, DwarfRegNum<[11]>; ++def T0 : LoongArch32GPR<12, "r12">, DwarfRegNum<[12]>; ++def T1 : LoongArch32GPR<13, "r13">, DwarfRegNum<[13]>; ++def T2 : LoongArch32GPR<14, "r14">, DwarfRegNum<[14]>; ++def T3 : LoongArch32GPR<15, "r15">, DwarfRegNum<[15]>; ++def T4 : LoongArch32GPR<16, "r16">, DwarfRegNum<[16]>; ++def T5 : LoongArch32GPR<17, "r17">, DwarfRegNum<[17]>; ++def T6 : LoongArch32GPR<18, "r18">, DwarfRegNum<[18]>; ++def T7 : LoongArch32GPR<19, "r19">, DwarfRegNum<[19]>; ++def T8 : LoongArch32GPR<20, "r20">, DwarfRegNum<[20]>; ++def T9 : LoongArch32GPR<21, "r21">, DwarfRegNum<[21]>; ++def FP : LoongArch32GPR<22, "r22">, DwarfRegNum<[22]>; ++def S0 : LoongArch32GPR<23, "r23">, DwarfRegNum<[23]>; ++def S1 : LoongArch32GPR<24, "r24">, DwarfRegNum<[24]>; ++def S2 : LoongArch32GPR<25, "r25">, DwarfRegNum<[25]>; ++def S3 : LoongArch32GPR<26, "r26">, DwarfRegNum<[26]>; ++def S4 : LoongArch32GPR<27, "r27">, DwarfRegNum<[27]>; ++def S5 : LoongArch32GPR<28, "r28">, DwarfRegNum<[28]>; ++def S6 : LoongArch32GPR<29, "r29">, DwarfRegNum<[29]>; ++def S7 : LoongArch32GPR<30, "r30">, DwarfRegNum<[30]>; ++def S8 : LoongArch32GPR<31, "r31">, DwarfRegNum<[31]>; ++ ++let SubRegIndices = [sub_32] in { ++def V0 : LoongArchRegWithSubRegs<4, "r4", [A0]>, DwarfRegNum<[4]>; ++def V1 : LoongArchRegWithSubRegs<5, "r5", [A1]>, DwarfRegNum<[5]>; ++} ++ ++/// General Purpose 64-bit Registers ++def ZERO_64 : LoongArch64GPR<0, "zero", [ZERO]>, DwarfRegNum<[0]>; ++def RA_64 : LoongArch64GPR<1, "ra", [RA]>, DwarfRegNum<[1]>; ++def TP_64 : LoongArch64GPR<2, "tp", [TP]>, DwarfRegNum<[2]>; ++def SP_64 : LoongArch64GPR<3, "sp", [SP]>, DwarfRegNum<[3]>; ++def A0_64 : LoongArch64GPR<4, "r4", [A0]>, DwarfRegNum<[4]>; ++def A1_64 : LoongArch64GPR<5, "r5", [A1]>, DwarfRegNum<[5]>; ++def A2_64 : LoongArch64GPR<6, "r6", [A2]>, DwarfRegNum<[6]>; ++def A3_64 : LoongArch64GPR<7, "r7", [A3]>, DwarfRegNum<[7]>; ++def A4_64 : LoongArch64GPR<8, "r8", [A4]>, DwarfRegNum<[8]>; ++def A5_64 : LoongArch64GPR<9, "r9", [A5]>, DwarfRegNum<[9]>; ++def A6_64 : LoongArch64GPR<10, "r10", [A6]>, DwarfRegNum<[10]>; ++def A7_64 : LoongArch64GPR<11, "r11", [A7]>, DwarfRegNum<[11]>; ++def T0_64 : LoongArch64GPR<12, "r12", [T0]>, DwarfRegNum<[12]>; ++def T1_64 : LoongArch64GPR<13, "r13", [T1]>, DwarfRegNum<[13]>; ++def T2_64 : LoongArch64GPR<14, "r14", [T2]>, DwarfRegNum<[14]>; ++def T3_64 : LoongArch64GPR<15, "r15", [T3]>, DwarfRegNum<[15]>; ++def T4_64 : LoongArch64GPR<16, "r16", [T4]>, DwarfRegNum<[16]>; ++def T5_64 : LoongArch64GPR<17, "r17", [T5]>, DwarfRegNum<[17]>; ++def T6_64 : LoongArch64GPR<18, "r18", [T6]>, DwarfRegNum<[18]>; ++def T7_64 : LoongArch64GPR<19, "r19", [T7]>, DwarfRegNum<[19]>; ++def T8_64 : LoongArch64GPR<20, "r20", [T8]>, DwarfRegNum<[20]>; ++def T9_64 : LoongArch64GPR<21, "r21", [T9]>, DwarfRegNum<[21]>; ++def FP_64 : LoongArch64GPR<22, "r22", [FP]>, DwarfRegNum<[22]>; ++def S0_64 : LoongArch64GPR<23, "r23", [S0]>, DwarfRegNum<[23]>; ++def S1_64 : LoongArch64GPR<24, "r24", [S1]>, DwarfRegNum<[24]>; ++def S2_64 : LoongArch64GPR<25, "r25", [S2]>, DwarfRegNum<[25]>; ++def S3_64 : LoongArch64GPR<26, "r26", [S3]>, DwarfRegNum<[26]>; ++def S4_64 : LoongArch64GPR<27, "r27", [S4]>, DwarfRegNum<[27]>; ++def S5_64 : LoongArch64GPR<28, "r28", [S5]>, DwarfRegNum<[28]>; ++def S6_64 : LoongArch64GPR<29, "r29", [S6]>, DwarfRegNum<[29]>; ++def S7_64 : LoongArch64GPR<30, "r30", [S7]>, DwarfRegNum<[30]>; ++def S8_64 : LoongArch64GPR<31, "r31", [S8]>, DwarfRegNum<[31]>; ++ ++let SubRegIndices = [sub_64] in { ++def V0_64 : LoongArch64GPR<4, "r4", [A0_64]>, DwarfRegNum<[4]>; ++def V1_64 : LoongArch64GPR<5, "r5", [A1_64]>, DwarfRegNum<[5]>; ++} ++ ++/// FP registers ++foreach I = 0-31 in ++def F#I : FGR32, DwarfRegNum<[!add(I, 32)]>; ++ ++foreach I = 0-31 in ++def F#I#_64 : FGR64("F"#I)]>, DwarfRegNum<[!add(I, 32)]>; ++ ++/// FP Condition Flag 0~7 + foreach I = 0-7 in + def FCC#I : LoongArchReg; + +-def CFR : RegisterClass<"LoongArch", [GRLenVT], 32, (sequence "FCC%u", 0, 7)> { +- let RegInfos = GRLenRI; ++/// FP Control and Status Registers, FCSR 1~3 ++foreach I = 1-3 in ++def FCSR#I : LoongArchReg; ++ ++class FCSRReg Enc, string n, list subregs> : ++ RegisterWithSubRegs { ++// field bits<2> chan_encoding = 0; ++ let Namespace = "LoongArch"; ++ let SubRegIndices = [sub_fcsr1, sub_fcsr2, sub_fcsr3]; ++// let HWEncoding{8-0} = encoding{8-0}; ++// let HWEncoding{10-9} = chan_encoding; + } + +-// Control and status registers ++def FCSR0 : FCSRReg<0, "fcsr0", [FCSR1, FCSR2, FCSR3]>; + +-foreach I = 0-3 in +-def FCSR#I : LoongArchReg; ++/// PC register ++//let NameSpace = "LoongArch" in ++//def PC : Register<"pc">; + +-let isAllocatable = false in +-def FCSR : RegisterClass<"LoongArch", [i32], 32, (sequence "FCSR%u", 0, 3)>; ++//===----------------------------------------------------------------------===// ++// Register Classes ++//===----------------------------------------------------------------------===// + +-// LSX registers ++def GPR32 : RegisterClass<"LoongArch", [i32], 32, (add ++ // Reserved ++ ZERO, ++ // Return Values and Arguments ++ A0, A1, A2, A3, A4, A5, A6, A7, ++ // Not preserved across procedure calls ++ T0, T1, T2, T3, T4, T5, T6, T7, T8, ++ // Callee save ++ S0, S1, S2, S3, S4, S5, S6, S7, S8, ++ // Reserved ++ RA, TP, SP, ++ // Reserved ++ T9, FP)>; ++ ++def GPR64 : RegisterClass<"LoongArch", [i64], 64, (add ++ // Reserved ++ ZERO_64, ++ // Return Values and Arguments ++ A0_64, A1_64, A2_64, A3_64, A4_64, A5_64, A6_64, A7_64, ++ // Not preserved across procedure calls ++ T0_64, T1_64, T2_64, T3_64, T4_64, T5_64, T6_64, T7_64, T8_64, ++ // Callee save ++ S0_64, S1_64, S2_64, S3_64, S4_64, S5_64, S6_64, S7_64, S8_64, ++ // Reserved ++ RA_64, TP_64, SP_64, ++ // Reserved ++ T9_64, FP_64)>; ++ ++def GPRTC64 : RegisterClass<"LoongArch", [i64], 64, (add ++ // Return Values and Arguments ++ A0_64, A1_64, A2_64, A3_64, A4_64, A5_64, A6_64, A7_64, ++ // Not preserved across procedure calls ++ T0_64, T1_64, T2_64, T3_64, T4_64, T5_64, T6_64, T7_64, T8_64)>; ++ ++/// FP Registers. ++def FGR64 : RegisterClass<"LoongArch", [f64], 64, (sequence "F%u_64", 0, 31)>; ++def FGR32 : RegisterClass<"LoongArch", [f32], 64, (sequence "F%u", 0, 31)>; ++ ++/// FP condition Flag registers. ++def FCFR : RegisterClass<"LoongArch", [i32], 32, (sequence "FCC%u", 0, 7)>, ++ Unallocatable; ++ ++def SP32 : RegisterClass<"LoongArch", [i32], 32, (add SP)>, Unallocatable; ++def SP64 : RegisterClass<"LoongArch", [i64], 64, (add SP_64)>, Unallocatable; ++def TP32 : RegisterClass<"LoongArch", [i32], 32, (add TP)>, Unallocatable; ++def TP64 : RegisterClass<"LoongArch", [i64], 64, (add TP_64)>, Unallocatable; ++ ++/// FP control and Status registers. ++def FCSR : RegisterClass<"LoongArch", [i32], 4, (sequence "FCSR%u", 0, 3)>, ++ Unallocatable; ++ ++//LSX ++foreach I = 0-31 in ++def VR#I : LSX128("F"#I#"_64")]>, ++ DwarfRegNum<[!add(I, 32)]>; + ++//LASX + foreach I = 0-31 in +-def VR#I : LoongArchReg128("F"#I#"_64"), "vr"#I>, +- DwarfRegAlias("F"#I#"_64")>; ++def XR#I : LASX256("VR"#I)]>, ++ DwarfRegNum<[!add(I, 32)]>; + +-def LSX128 : RegisterClass<"LoongArch", +- [v4f32, v2f64, v16i8, v8i16, v4i32, v2i64], +- 128, (sequence "VR%u", 0, 31)>; ++def LSX128B: RegisterClass<"LoongArch", [v16i8], 128, ++ (sequence "VR%u", 0, 31)>; + +-// LASX registers ++def LSX128H: RegisterClass<"LoongArch", [v8i16], 128, ++ (sequence "VR%u", 0, 31)>; + +-foreach I = 0-31 in +-def XR#I : LoongArchReg256("VR"#I), "xr"#I>, +- DwarfRegAlias("VR"#I)>; ++def LSX128W: RegisterClass<"LoongArch", [v4i32, v4f32], 128, ++ (sequence "VR%u", 0, 31)>; ++ ++def LSX128D: RegisterClass<"LoongArch", [v2i64, v2f64], 128, ++ (sequence "VR%u", 0, 31)>; ++ ++def LASX256B: RegisterClass<"LoongArch", [v32i8], 256, ++ (sequence "XR%u", 0, 31)>; ++def LASX256H: RegisterClass<"LoongArch", [v16i16], 256, ++ (sequence "XR%u", 0, 31)>; ++def LASX256W: RegisterClass<"LoongArch", [v8i32, v8f32], 256, ++ (sequence "XR%u", 0, 31)>; ++def LASX256D: RegisterClass<"LoongArch", [v4i64, v4f64], 256, ++ (sequence "XR%u", 0, 31)>; ++ ++//===----------------------------------------------------------------------===// ++// Register Operands. ++//===----------------------------------------------------------------------===// + +-def LASX256 : RegisterClass<"LoongArch", +- [v8f32, v4f64, v32i8, v16i16, v8i32, v4i64], +- 256, (sequence "XR%u", 0, 31)>; ++class LoongArchAsmRegOperand : AsmOperandClass { ++ let ParserMethod = "parseAnyRegister"; ++} + +-// Scratchpad registers ++def GPR32AsmOperand : LoongArchAsmRegOperand { ++ let Name = "GPR32AsmReg"; ++ let PredicateMethod = "isGPRAsmReg"; ++} + +-foreach I = 0-3 in +-def SCR#I : LoongArchReg; ++def GPR64AsmOperand : LoongArchAsmRegOperand { ++ let Name = "GPR64AsmReg"; ++ let PredicateMethod = "isGPRAsmReg"; ++} + +-let isAllocatable = false, RegInfos = GRLenRI in +-def SCR : RegisterClass<"LoongArch", [GRLenVT], 32, (sequence "SCR%u", 0, 3)>; ++def FGR32AsmOperand : LoongArchAsmRegOperand { ++ let Name = "FGR32AsmReg"; ++ let PredicateMethod = "isFGRAsmReg"; ++} ++ ++def FGR64AsmOperand : LoongArchAsmRegOperand { ++ let Name = "FGR64AsmReg"; ++ let PredicateMethod = "isFGRAsmReg"; ++} ++ ++def FCSRAsmOperand : LoongArchAsmRegOperand { ++ let Name = "FCSRAsmReg"; ++} ++ ++def FCFRAsmOperand : LoongArchAsmRegOperand { ++ let Name = "FCFRAsmReg"; ++} ++ ++//LSX ++def LSX128AsmOperand : LoongArchAsmRegOperand { ++ let Name = "LSX128AsmReg"; ++} ++ ++//LASX ++def LASX256AsmOperand : LoongArchAsmRegOperand { ++ let Name = "LASX256AsmReg"; ++} ++ ++def GPR32Opnd : RegisterOperand { ++ let ParserMatchClass = GPR32AsmOperand; ++} ++ ++def GPR64Opnd : RegisterOperand { ++ let ParserMatchClass = GPR64AsmOperand; ++} ++ ++def GPRTC64Opnd : RegisterOperand { ++ let ParserMatchClass = GPR64AsmOperand; ++} ++ ++def FGR32Opnd : RegisterOperand { ++ let ParserMatchClass = FGR32AsmOperand; ++} ++ ++def FGR64Opnd : RegisterOperand { ++ let ParserMatchClass = FGR64AsmOperand; ++} ++ ++def FCSROpnd : RegisterOperand { ++ let ParserMatchClass = FCSRAsmOperand; ++} ++ ++def FCFROpnd : RegisterOperand { ++ let ParserMatchClass = FCFRAsmOperand; ++} ++ ++//LSX ++def LSX128BOpnd : RegisterOperand { ++ let ParserMatchClass = LSX128AsmOperand; ++} ++ ++def LSX128HOpnd : RegisterOperand { ++ let ParserMatchClass = LSX128AsmOperand; ++} ++ ++def LSX128WOpnd : RegisterOperand { ++ let ParserMatchClass = LSX128AsmOperand; ++} ++ ++def LSX128DOpnd : RegisterOperand { ++ let ParserMatchClass = LSX128AsmOperand; ++} ++ ++//LASX ++def LASX256BOpnd : RegisterOperand { ++ let ParserMatchClass = LASX256AsmOperand; ++} ++ ++def LASX256HOpnd : RegisterOperand { ++ let ParserMatchClass = LASX256AsmOperand; ++} ++ ++def LASX256WOpnd : RegisterOperand { ++ let ParserMatchClass = LASX256AsmOperand; ++} ++ ++def LASX256DOpnd : RegisterOperand { ++ let ParserMatchClass = LASX256AsmOperand; ++} +diff --git a/llvm/lib/Target/LoongArch/LoongArchSubtarget.cpp b/llvm/lib/Target/LoongArch/LoongArchSubtarget.cpp +index ffcde7dd1..29c6c973a 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchSubtarget.cpp ++++ b/llvm/lib/Target/LoongArch/LoongArchSubtarget.cpp +@@ -1,4 +1,4 @@ +-//===-- LoongArchSubtarget.cpp - LoongArch Subtarget Information -*- C++ -*--=// ++//===-- LoongArchSubtarget.cpp - LoongArch Subtarget Information --------------------===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -11,8 +11,16 @@ + //===----------------------------------------------------------------------===// + + #include "LoongArchSubtarget.h" +-#include "LoongArchFrameLowering.h" +-#include "MCTargetDesc/LoongArchBaseInfo.h" ++#include "LoongArch.h" ++#include "LoongArchMachineFunction.h" ++#include "LoongArchRegisterInfo.h" ++#include "LoongArchTargetMachine.h" ++#include "llvm/IR/Attributes.h" ++#include "llvm/IR/Function.h" ++#include "llvm/Support/CommandLine.h" ++#include "llvm/Support/Debug.h" ++#include "llvm/MC/TargetRegistry.h" ++#include "llvm/Support/raw_ostream.h" + + using namespace llvm; + +@@ -24,68 +32,74 @@ using namespace llvm; + + void LoongArchSubtarget::anchor() {} + +-LoongArchSubtarget &LoongArchSubtarget::initializeSubtargetDependencies( +- const Triple &TT, StringRef CPU, StringRef TuneCPU, StringRef FS, +- StringRef ABIName) { +- bool Is64Bit = TT.isArch64Bit(); +- if (CPU.empty() || CPU == "generic") +- CPU = Is64Bit ? "generic-la64" : "generic-la32"; +- +- if (TuneCPU.empty()) +- TuneCPU = CPU; +- +- ParseSubtargetFeatures(CPU, TuneCPU, FS); +- initializeProperties(TuneCPU); +- if (Is64Bit) { +- GRLenVT = MVT::i64; +- GRLen = 64; +- } ++LoongArchSubtarget::LoongArchSubtarget(const Triple &TT, StringRef CPU, ++ StringRef FS, ++ const LoongArchTargetMachine &TM, ++ MaybeAlign StackAlignOverride) ++ : LoongArchGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS), HasLA64(false), ++ IsSoftFloat(false), IsSingleFloat(false), IsFP64bit(false), HasLSX(false), ++ HasLASX(false), UnalignedAccess(false), HasFrecipe(false), ++ StackAlignOverride(StackAlignOverride), TM(TM), TargetTriple(TT), ++ TSInfo(), InstrInfo(initializeSubtargetDependencies(CPU, FS, TM)), ++ FrameLowering(*this), TLInfo(TM, *this) { ++ ++ // Check if Architecture and ABI are compatible. ++ assert(((!is64Bit() && isABI_LP32()) || ++ (is64Bit() && (isABI_LPX32() || isABI_LP64()))) && ++ "Invalid Arch & ABI pair."); ++ ++ if (hasLSX() && !isFP64bit()) ++ report_fatal_error("LSX requires 64-bit floating point register." ++ "See -mattr=+fp64.", ++ false); ++ ++ assert(isFP64bit()); ++} + +- if (HasLA32 == HasLA64) +- report_fatal_error("Please use one feature of 32bit and 64bit."); ++bool LoongArchSubtarget::isPositionIndependent() const { ++ return TM.isPositionIndependent(); ++} + +- if (Is64Bit && HasLA32) +- report_fatal_error("Feature 32bit should be used for loongarch32 target."); ++/// This overrides the PostRAScheduler bit in the SchedModel for any CPU. ++bool LoongArchSubtarget::enablePostRAScheduler() const { return true; } + +- if (!Is64Bit && HasLA64) +- report_fatal_error("Feature 64bit should be used for loongarch64 target."); ++void LoongArchSubtarget::getCriticalPathRCs(RegClassVector &CriticalPathRCs) const { ++ CriticalPathRCs.clear(); ++ CriticalPathRCs.push_back(is64Bit() ? &LoongArch::GPR64RegClass ++ : &LoongArch::GPR32RegClass); ++} + +- TargetABI = LoongArchABI::computeTargetABI(TT, ABIName); ++CodeGenOptLevel LoongArchSubtarget::getOptLevelToEnablePostRAScheduler() const { ++ return CodeGenOptLevel::Aggressive; ++} ++ ++LoongArchSubtarget & ++LoongArchSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS, ++ const TargetMachine &TM) { ++ StringRef CPUName = LoongArch_MC::selectLoongArchCPU(TM.getTargetTriple(), CPU); ++ ++ // Parse features string. ++ ParseSubtargetFeatures(CPUName, /*TuneCPU*/ CPUName, FS); ++ // Initialize scheduling itinerary for the specified CPU. ++ InstrItins = getInstrItineraryForCPU(CPUName); ++ ++ if (StackAlignOverride) ++ stackAlignment = *StackAlignOverride; ++ else if (isABI_LPX32() || isABI_LP64()) ++ stackAlignment = Align(16); ++ else { ++ assert(isABI_LP32() && "Unknown ABI for stack alignment!"); ++ stackAlignment = Align(8); ++ } + + return *this; + } + +-void LoongArchSubtarget::initializeProperties(StringRef TuneCPU) { +- // Initialize CPU specific properties. We should add a tablegen feature for +- // this in the future so we can specify it together with the subtarget +- // features. +- +- // TODO: Check TuneCPU and override defaults (that are for LA464) once we +- // support optimizing for more uarchs. +- +- // Default to the alignment settings empirically confirmed to perform best +- // on LA464, with 4-wide instruction fetch and decode stages. These settings +- // can also be overridden in initializeProperties. +- // +- // We default to such higher-than-minimum alignments because we assume that: +- // +- // * these settings should benefit most existing uarchs/users, +- // * future general-purpose LoongArch cores are likely to have issue widths +- // equal to or wider than 4, +- // * instruction sequences best for LA464 should not pessimize other future +- // uarchs, and +- // * narrower cores would not suffer much (aside from slightly increased +- // ICache footprint maybe), compared to the gains everywhere else. +- PrefFunctionAlignment = Align(32); +- PrefLoopAlignment = Align(16); +- MaxBytesForAlignment = 16; ++Reloc::Model LoongArchSubtarget::getRelocationModel() const { ++ return TM.getRelocationModel(); + } + +-LoongArchSubtarget::LoongArchSubtarget(const Triple &TT, StringRef CPU, +- StringRef TuneCPU, StringRef FS, +- StringRef ABIName, +- const TargetMachine &TM) +- : LoongArchGenSubtargetInfo(TT, CPU, TuneCPU, FS), +- FrameLowering( +- initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)), +- InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) {} ++bool LoongArchSubtarget::isABI_LP64() const { return getABI().IsLP64(); } ++bool LoongArchSubtarget::isABI_LPX32() const { return getABI().IsLPX32(); } ++bool LoongArchSubtarget::isABI_LP32() const { return getABI().IsLP32(); } ++const LoongArchABIInfo &LoongArchSubtarget::getABI() const { return TM.getABI(); } +diff --git a/llvm/lib/Target/LoongArch/LoongArchSubtarget.h b/llvm/lib/Target/LoongArch/LoongArchSubtarget.h +index 11c0b39e1..6a9c5593d 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchSubtarget.h ++++ b/llvm/lib/Target/LoongArch/LoongArchSubtarget.h +@@ -1,4 +1,4 @@ +-//===- LoongArchSubtarget.h - Define Subtarget for the LoongArch -*- C++ -*-==// ++//===-- LoongArchSubtarget.h - Define Subtarget for the LoongArch ---------*- C++ -*-===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -13,15 +13,15 @@ + #ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHSUBTARGET_H + #define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHSUBTARGET_H + ++#include "MCTargetDesc/LoongArchABIInfo.h" + #include "LoongArchFrameLowering.h" + #include "LoongArchISelLowering.h" + #include "LoongArchInstrInfo.h" +-#include "LoongArchRegisterInfo.h" +-#include "MCTargetDesc/LoongArchBaseInfo.h" + #include "llvm/CodeGen/SelectionDAGTargetInfo.h" + #include "llvm/CodeGen/TargetSubtargetInfo.h" + #include "llvm/IR/DataLayout.h" +-#include "llvm/Target/TargetMachine.h" ++#include "llvm/MC/MCInstrItineraries.h" ++#include "llvm/Support/ErrorHandling.h" + + #define GET_SUBTARGETINFO_HEADER + #include "LoongArchGenSubtargetInfo.inc" +@@ -29,91 +29,119 @@ + namespace llvm { + class StringRef; + ++class LoongArchTargetMachine; ++ + class LoongArchSubtarget : public LoongArchGenSubtargetInfo { + virtual void anchor(); +- bool HasLA32 = false; +- bool HasLA64 = false; +- bool HasBasicF = false; +- bool HasBasicD = false; +- bool HasExtLSX = false; +- bool HasExtLASX = false; +- bool HasExtLVZ = false; +- bool HasExtLBT = false; +- bool HasLaGlobalWithPcrel = false; +- bool HasLaGlobalWithAbs = false; +- bool HasLaLocalWithAbs = false; +- bool HasUAL = false; +- bool HasLinkerRelax = false; +- bool HasExpAutoVec = false; +- bool HasFrecipe = false; +- unsigned GRLen = 32; +- MVT GRLenVT = MVT::i32; +- LoongArchABI::ABI TargetABI = LoongArchABI::ABI_Unknown; +- LoongArchFrameLowering FrameLowering; +- LoongArchInstrInfo InstrInfo; +- LoongArchRegisterInfo RegInfo; +- LoongArchTargetLowering TLInfo; +- SelectionDAGTargetInfo TSInfo; +- +- Align PrefFunctionAlignment; +- Align PrefLoopAlignment; +- unsigned MaxBytesForAlignment; +- +- /// Initializes using the passed in CPU and feature strings so that we can +- /// use initializer lists for subtarget initialization. +- LoongArchSubtarget &initializeSubtargetDependencies(const Triple &TT, +- StringRef CPU, +- StringRef TuneCPU, +- StringRef FS, +- StringRef ABIName); +- +- /// Initialize properties based on the selected processor family. +- void initializeProperties(StringRef TuneCPU); ++ ++ // HasLA64 - The target processor has LA64 ISA support. ++ bool HasLA64; ++ ++ // IsSoftFloat - The target does not support any floating point instructions. ++ bool IsSoftFloat; ++ ++ // IsSingleFloat - The target only supports single precision float ++ // point operations. This enable the target to use all 32 32-bit ++ // floating point registers instead of only using even ones. ++ bool IsSingleFloat; ++ ++ // IsFP64bit - The target processor has 64-bit floating point registers. ++ bool IsFP64bit; ++ ++ /// Features related to the presence of specific instructions. ++ ++ // HasLSX - Supports LSX. ++ bool HasLSX; ++ ++ // HasLASX - Supports LASX. ++ bool HasLASX; ++ ++ /// The minimum alignment known to hold of the stack frame on ++ /// entry to the function and which must be maintained by every function. ++ Align stackAlignment; ++ ++ // Allow unaligned memory accesses. ++ bool UnalignedAccess; ++ ++ // HasFrecipe - Support FP approximation reciprocal instructions. ++ bool HasFrecipe; ++ ++ /// The overridden stack alignment. ++ MaybeAlign StackAlignOverride; ++ ++ InstrItineraryData InstrItins; ++ ++ const LoongArchTargetMachine &TM; ++ ++ Triple TargetTriple; ++ ++ const SelectionDAGTargetInfo TSInfo; ++ const LoongArchInstrInfo InstrInfo; ++ const LoongArchFrameLowering FrameLowering; ++ const LoongArchTargetLowering TLInfo; + + public: +- // Initializes the data members to match that of the specified triple. +- LoongArchSubtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU, +- StringRef FS, StringRef ABIName, const TargetMachine &TM); ++ bool isPositionIndependent() const; ++ /// This overrides the PostRAScheduler bit in the SchedModel for each CPU. ++ bool enablePostRAScheduler() const override; ++ void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const override; ++ CodeGenOptLevel getOptLevelToEnablePostRAScheduler() const override; ++ ++ bool isABI_LP64() const; ++ bool isABI_LPX32() const; ++ bool isABI_LP32() const; ++ const LoongArchABIInfo &getABI() const; ++ ++ /// This constructor initializes the data members to match that ++ /// of the specified triple. ++ LoongArchSubtarget(const Triple &TT, StringRef CPU, StringRef FS, ++ const LoongArchTargetMachine &TM, MaybeAlign StackAlignOverride); + +- // Parses features string setting specified subtarget options. The +- // definition of this function is auto-generated by tblgen. ++ /// ParseSubtargetFeatures - Parses features string setting specified ++ /// subtarget options. Definition of function is auto generated by tblgen. + void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); + +- const LoongArchFrameLowering *getFrameLowering() const override { ++ bool is64Bit() const { return HasLA64; } ++ bool isFP64bit() const { return IsFP64bit; } ++ unsigned getGPRSizeInBytes() const { return is64Bit() ? 8 : 4; } ++ bool isSingleFloat() const { return IsSingleFloat; } ++ bool hasLSX() const { return HasLSX; } ++ bool hasLASX() const { return HasLASX; } ++ bool useSoftFloat() const { return IsSoftFloat; } ++ ++ bool allowUnalignedAccess() const { return UnalignedAccess; } ++ ++ bool hasFrecipe() const { return HasFrecipe; } ++ ++ bool isXRaySupported() const override { return true; } ++ ++ Align getStackAlignment() const { return stackAlignment; } ++ ++ // Grab relocation model ++ Reloc::Model getRelocationModel() const; ++ ++ LoongArchSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS, ++ const TargetMachine &TM); ++ ++ const SelectionDAGTargetInfo *getSelectionDAGInfo() const override { ++ return &TSInfo; ++ } ++ const LoongArchInstrInfo *getInstrInfo() const override { ++ return &InstrInfo; ++ } ++ const TargetFrameLowering *getFrameLowering() const override { + return &FrameLowering; + } +- const LoongArchInstrInfo *getInstrInfo() const override { return &InstrInfo; } + const LoongArchRegisterInfo *getRegisterInfo() const override { +- return &RegInfo; ++ return &InstrInfo.getRegisterInfo(); + } + const LoongArchTargetLowering *getTargetLowering() const override { + return &TLInfo; + } +- const SelectionDAGTargetInfo *getSelectionDAGInfo() const override { +- return &TSInfo; ++ const InstrItineraryData *getInstrItineraryData() const override { ++ return &InstrItins; + } +- bool is64Bit() const { return HasLA64; } +- bool hasBasicF() const { return HasBasicF; } +- bool hasBasicD() const { return HasBasicD; } +- bool hasExtLSX() const { return HasExtLSX; } +- bool hasExtLASX() const { return HasExtLASX; } +- bool hasExtLVZ() const { return HasExtLVZ; } +- bool hasExtLBT() const { return HasExtLBT; } +- bool hasLaGlobalWithPcrel() const { return HasLaGlobalWithPcrel; } +- bool hasLaGlobalWithAbs() const { return HasLaGlobalWithAbs; } +- bool hasLaLocalWithAbs() const { return HasLaLocalWithAbs; } +- bool hasUAL() const { return HasUAL; } +- bool hasLinkerRelax() const { return HasLinkerRelax; } +- bool hasExpAutoVec() const { return HasExpAutoVec; } +- bool hasFrecipe() const { return HasFrecipe; } +- MVT getGRLenVT() const { return GRLenVT; } +- unsigned getGRLen() const { return GRLen; } +- LoongArchABI::ABI getTargetABI() const { return TargetABI; } +- bool isXRaySupported() const override { return is64Bit(); } +- Align getPrefFunctionAlignment() const { return PrefFunctionAlignment; } +- Align getPrefLoopAlignment() const { return PrefLoopAlignment; } +- unsigned getMaxBytesForAlignment() const { return MaxBytesForAlignment; } + }; +-} // end namespace llvm ++} // End llvm namespace + +-#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHSUBTARGET_H ++#endif +diff --git a/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp b/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp +index 62ae1dea0..db743a02f 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp ++++ b/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp +@@ -1,4 +1,4 @@ +-//===-- LoongArchTargetMachine.cpp - Define TargetMachine for LoongArch ---===// ++//===-- LoongArchTargetMachine.cpp - Define TargetMachine for LoongArch -------------===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -12,18 +12,29 @@ + + #include "LoongArchTargetMachine.h" + #include "LoongArch.h" +-#include "LoongArchMachineFunctionInfo.h" ++#include "LoongArchISelDAGToDAG.h" ++#include "LoongArchMachineFunction.h" ++#include "LoongArchSubtarget.h" ++#include "LoongArchTargetObjectFile.h" + #include "LoongArchTargetTransformInfo.h" +-#include "MCTargetDesc/LoongArchBaseInfo.h" +-#include "TargetInfo/LoongArchTargetInfo.h" ++#include "MCTargetDesc/LoongArchABIInfo.h" ++#include "MCTargetDesc/LoongArchMCTargetDesc.h" ++#include "llvm/ADT/STLExtras.h" ++#include "llvm/ADT/StringRef.h" + #include "llvm/Analysis/TargetTransformInfo.h" ++#include "llvm/CodeGen/BasicTTIImpl.h" ++#include "llvm/CodeGen/MachineFunction.h" + #include "llvm/CodeGen/Passes.h" +-#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" + #include "llvm/CodeGen/TargetPassConfig.h" ++#include "llvm/IR/Attributes.h" ++#include "llvm/IR/Function.h" + #include "llvm/MC/TargetRegistry.h" + #include "llvm/Support/CodeGen.h" +-#include "llvm/Transforms/Scalar.h" +-#include ++#include "llvm/Support/Debug.h" ++#include "llvm/Support/raw_ostream.h" ++#include "llvm/Target/TargetOptions.h" ++#include ++#include + + using namespace llvm; + +@@ -32,57 +43,63 @@ using namespace llvm; + extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchTarget() { + // Register the target. + RegisterTargetMachine X(getTheLoongArch32Target()); +- RegisterTargetMachine Y(getTheLoongArch64Target()); +- auto *PR = PassRegistry::getPassRegistry(); +- initializeLoongArchPreRAExpandPseudoPass(*PR); +- initializeLoongArchDAGToDAGISelPass(*PR); ++ RegisterTargetMachine A(getTheLoongArch64Target()); + } + +-static cl::opt +- EnableLoopDataPrefetch("loongarch-enable-loop-data-prefetch", cl::Hidden, +- cl::desc("Enable the loop data prefetch pass"), +- cl::init(false)); ++static std::string computeDataLayout(const Triple &TT, StringRef CPU, ++ const TargetOptions &Options) { ++ std::string Ret; ++ LoongArchABIInfo ABI = LoongArchABIInfo::computeTargetABI(TT, CPU, Options.MCOptions); + +-static std::string computeDataLayout(const Triple &TT) { +- if (TT.isArch64Bit()) +- return "e-m:e-p:64:64-i64:64-i128:128-n64-S128"; +- assert(TT.isArch32Bit() && "only LA32 and LA64 are currently supported"); +- return "e-m:e-p:32:32-i64:64-n32-S128"; +-} ++ Ret += "e"; + +-static Reloc::Model getEffectiveRelocModel(const Triple &TT, +- std::optional RM) { +- return RM.value_or(Reloc::Static); ++ if (ABI.IsLP32()) ++ Ret += "-m:m"; ++ else ++ Ret += "-m:e"; ++ ++ // Pointers are 32 bit on some ABIs. ++ if (!ABI.IsLP64()) ++ Ret += "-p:32:32"; ++ ++ // 8 and 16 bit integers only need to have natural alignment, but try to ++ // align them to 32 bits. 64 bit integers have natural alignment. ++ Ret += "-i8:8:32-i16:16:32-i64:64"; ++ ++ // 32 bit registers are always available and the stack is at least 64 bit ++ // aligned. On LP64 64 bit registers are also available and the stack is ++ // 128 bit aligned. ++ if (ABI.IsLP64() || ABI.IsLPX32()) ++ Ret += "-n32:64-S128"; ++ else ++ Ret += "-n32-S64"; ++ ++ return Ret; + } + +-static CodeModel::Model +-getEffectiveLoongArchCodeModel(const Triple &TT, +- std::optional CM) { +- if (!CM) +- return CodeModel::Small; +- +- switch (*CM) { +- case CodeModel::Small: +- return *CM; +- case CodeModel::Medium: +- case CodeModel::Large: +- if (!TT.isArch64Bit()) +- report_fatal_error("Medium/Large code model requires LA64"); +- return *CM; +- default: +- report_fatal_error( +- "Only small, medium and large code models are allowed on LoongArch"); +- } ++static Reloc::Model getEffectiveRelocModel(bool JIT, ++ std::optional RM) { ++ if (!RM || JIT) ++ return Reloc::Static; ++ return *RM; + } + +-LoongArchTargetMachine::LoongArchTargetMachine( +- const Target &T, const Triple &TT, StringRef CPU, StringRef FS, +- const TargetOptions &Options, std::optional RM, +- std::optional CM, CodeGenOptLevel OL, bool JIT) +- : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, +- getEffectiveRelocModel(TT, RM), +- getEffectiveLoongArchCodeModel(TT, CM), OL), +- TLOF(std::make_unique()) { ++// On function prologue, the stack is created by decrementing ++// its pointer. Once decremented, all references are done with positive ++// offset from the stack/frame pointer, using StackGrowsUp enables ++// an easier handling. ++// Using CodeModel::Large enables different CALL behavior. ++LoongArchTargetMachine::LoongArchTargetMachine(const Target &T, const Triple &TT, ++ StringRef CPU, StringRef FS, ++ const TargetOptions &Options, ++ std::optional RM, ++ std::optional CM, ++ CodeGenOptLevel OL, bool JIT) ++ : LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options), TT, ++ CPU, FS, Options, getEffectiveRelocModel(JIT, RM), ++ getEffectiveCodeModel(CM, CodeModel::Small), OL), ++ TLOF(std::make_unique()), ++ ABI(LoongArchABIInfo::computeTargetABI(TT, CPU, Options.MCOptions)) { + initAsmInfo(); + } + +@@ -91,51 +108,45 @@ LoongArchTargetMachine::~LoongArchTargetMachine() = default; + const LoongArchSubtarget * + LoongArchTargetMachine::getSubtargetImpl(const Function &F) const { + Attribute CPUAttr = F.getFnAttribute("target-cpu"); +- Attribute TuneAttr = F.getFnAttribute("tune-cpu"); + Attribute FSAttr = F.getFnAttribute("target-features"); + +- std::string CPU = +- CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU; +- std::string TuneCPU = +- TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU; +- std::string FS = +- FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS; ++ std::string CPU = !CPUAttr.hasAttribute(Attribute::None) ++ ? CPUAttr.getValueAsString().str() ++ : TargetCPU; ++ std::string FS = !FSAttr.hasAttribute(Attribute::None) ++ ? FSAttr.getValueAsString().str() ++ : TargetFS; ++ ++ // FIXME: This is related to the code below to reset the target options, ++ // we need to know whether or not the soft float flag is set on the ++ // function, so we can enable it as a subtarget feature. ++ bool softFloat = ++ F.hasFnAttribute("use-soft-float") && ++ F.getFnAttribute("use-soft-float").getValueAsString() == "true"; + +- std::string Key = CPU + TuneCPU + FS; +- auto &I = SubtargetMap[Key]; ++ if (softFloat) ++ FS += FS.empty() ? "+soft-float" : ",+soft-float"; ++ ++ auto &I = SubtargetMap[CPU + FS]; + if (!I) { + // This needs to be done before we create a new subtarget since any + // creation will depend on the TM and the code generation flags on the + // function that reside in TargetOptions. + resetTargetOptions(F); +- auto ABIName = Options.MCOptions.getABIName(); +- if (const MDString *ModuleTargetABI = dyn_cast_or_null( +- F.getParent()->getModuleFlag("target-abi"))) { +- auto TargetABI = LoongArchABI::getTargetABI(ABIName); +- if (TargetABI != LoongArchABI::ABI_Unknown && +- ModuleTargetABI->getString() != ABIName) { +- report_fatal_error("-target-abi option != target-abi module flag"); +- } +- ABIName = ModuleTargetABI->getString(); +- } +- I = std::make_unique(TargetTriple, CPU, TuneCPU, FS, +- ABIName, *this); ++ I = std::make_unique(TargetTriple, CPU, FS, *this, ++ MaybeAlign(F.getParent()->getOverrideStackAlignment())); + } + return I.get(); + } + +-MachineFunctionInfo *LoongArchTargetMachine::createMachineFunctionInfo( +- BumpPtrAllocator &Allocator, const Function &F, +- const TargetSubtargetInfo *STI) const { +- return LoongArchMachineFunctionInfo::create( +- Allocator, F, STI); +-} +- + namespace { ++ ++/// LoongArch Code Generator Pass Configuration Options. + class LoongArchPassConfig : public TargetPassConfig { + public: + LoongArchPassConfig(LoongArchTargetMachine &TM, PassManagerBase &PM) +- : TargetPassConfig(TM, PM) {} ++ : TargetPassConfig(TM, PM) { ++ } + + LoongArchTargetMachine &getLoongArchTargetMachine() const { + return getTM(); +@@ -144,49 +155,47 @@ public: + void addIRPasses() override; + bool addInstSelector() override; + void addPreEmitPass() override; +- void addPreEmitPass2() override; +- void addPreRegAlloc() override; + }; +-} // end namespace + +-TargetPassConfig * +-LoongArchTargetMachine::createPassConfig(PassManagerBase &PM) { ++} // end anonymous namespace ++ ++TargetPassConfig *LoongArchTargetMachine::createPassConfig(PassManagerBase &PM) { + return new LoongArchPassConfig(*this, PM); + } + + void LoongArchPassConfig::addIRPasses() { +- // Run LoopDataPrefetch +- // +- // Run this before LSR to remove the multiplies involved in computing the +- // pointer values N iterations ahead. +- if (TM->getOptLevel() != CodeGenOptLevel::None && EnableLoopDataPrefetch) +- addPass(createLoopDataPrefetchPass()); +- addPass(createAtomicExpandPass()); +- + TargetPassConfig::addIRPasses(); ++ addPass(createAtomicExpandPass()); + } +- ++// Install an instruction selector pass using ++// the ISelDag to gen LoongArch code. + bool LoongArchPassConfig::addInstSelector() { +- addPass(createLoongArchISelDag(getLoongArchTargetMachine())); +- ++ addPass(createLoongArchModuleISelDagPass()); ++ addPass(createLoongArchISelDag(getLoongArchTargetMachine(), getOptLevel())); + return false; + } + + TargetTransformInfo + LoongArchTargetMachine::getTargetTransformInfo(const Function &F) const { +- return TargetTransformInfo(LoongArchTTIImpl(this, F)); ++ LLVM_DEBUG(errs() << "Target Transform Info Pass Added\n"); ++ return TargetTransformInfo(BasicTTIImpl(this, F)); + } + +-void LoongArchPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); } ++MachineFunctionInfo *LoongArchTargetMachine::createMachineFunctionInfo( ++ BumpPtrAllocator &Allocator, const Function &F, ++ const TargetSubtargetInfo *STI) const { ++ return LoongArchFunctionInfo::create(Allocator, F, STI); ++} + +-void LoongArchPassConfig::addPreEmitPass2() { ++// Implemented by targets that want to run passes immediately before ++// machine code is emitted. return true if -print-machineinstrs should ++// print out the code after the passes. ++void LoongArchPassConfig::addPreEmitPass() { ++ // Expand pseudo instructions that are sensitive to register allocation. + addPass(createLoongArchExpandPseudoPass()); +- // Schedule the expansion of AtomicPseudos at the last possible moment, +- // avoiding the possibility for other passes to break the requirements for +- // forward progress in the LL/SC block. +- addPass(createLoongArchExpandAtomicPseudoPass()); +-} + +-void LoongArchPassConfig::addPreRegAlloc() { +- addPass(createLoongArchPreRAExpandPseudoPass()); ++ // Relax conditional branch instructions if they're otherwise out of ++ // range of their destination. ++ // This pass must be run after any pseudo instruction expansion ++ addPass(&BranchRelaxationPassID); + } +diff --git a/llvm/lib/Target/LoongArch/LoongArchTargetMachine.h b/llvm/lib/Target/LoongArch/LoongArchTargetMachine.h +index fa9bc7608..46f9d1cd6 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchTargetMachine.h ++++ b/llvm/lib/Target/LoongArch/LoongArchTargetMachine.h +@@ -1,4 +1,4 @@ +-//=- LoongArchTargetMachine.h - Define TargetMachine for LoongArch -*- C++ -*-// ++//===- LoongArchTargetMachine.h - Define TargetMachine for LoongArch ------*- C++ -*-===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -13,27 +13,32 @@ + #ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHTARGETMACHINE_H + #define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHTARGETMACHINE_H + ++#include "MCTargetDesc/LoongArchABIInfo.h" + #include "LoongArchSubtarget.h" ++#include "llvm/ADT/StringMap.h" ++#include "llvm/ADT/StringRef.h" ++#include "llvm/Support/CodeGen.h" + #include "llvm/Target/TargetMachine.h" +-#include ++#include + + namespace llvm { + + class LoongArchTargetMachine : public LLVMTargetMachine { + std::unique_ptr TLOF; ++ // Selected ABI ++ LoongArchABIInfo ABI; ++ + mutable StringMap> SubtargetMap; + + public: + LoongArchTargetMachine(const Target &T, const Triple &TT, StringRef CPU, +- StringRef FS, const TargetOptions &Options, +- std::optional RM, +- std::optional CM, CodeGenOptLevel OL, +- bool JIT); ++ StringRef FS, const TargetOptions &Options, ++ std::optional RM, std::optional CM, ++ CodeGenOptLevel OL, bool JIT); + ~LoongArchTargetMachine() override; + + TargetTransformInfo getTargetTransformInfo(const Function &F) const override; + const LoongArchSubtarget *getSubtargetImpl(const Function &F) const override; +- const LoongArchSubtarget *getSubtargetImpl() const = delete; + + // Pass Pipeline Configuration + TargetPassConfig *createPassConfig(PassManagerBase &PM) override; +@@ -46,9 +51,18 @@ public: + createMachineFunctionInfo(BumpPtrAllocator &Allocator, const Function &F, + const TargetSubtargetInfo *STI) const override; + +- // Addrspacecasts are always noops. ++ /// Returns true if a cast between SrcAS and DestAS is a noop. + bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override { +- return true; ++ // Mips doesn't have any special address spaces so we just reserve ++ // the first 256 for software use (e.g. OpenCL) and treat casts ++ // between them as noops. ++ return SrcAS < 256 && DestAS < 256; ++ } ++ ++ const LoongArchABIInfo &getABI() const { return ABI; } ++ ++ bool isMachineVerifierClean() const override { ++ return false; + } + }; + +diff --git a/llvm/lib/Target/LoongArch/LoongArchTargetObjectFile.cpp b/llvm/lib/Target/LoongArch/LoongArchTargetObjectFile.cpp +new file mode 100644 +index 000000000..9c6250d28 +--- /dev/null ++++ b/llvm/lib/Target/LoongArch/LoongArchTargetObjectFile.cpp +@@ -0,0 +1,26 @@ ++//===-- LoongArchTargetObjectFile.cpp - LoongArch Object Files ----------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++#include "LoongArchTargetObjectFile.h" ++#include "LoongArchSubtarget.h" ++#include "LoongArchTargetMachine.h" ++#include "MCTargetDesc/LoongArchMCExpr.h" ++#include "llvm/BinaryFormat/ELF.h" ++#include "llvm/IR/DataLayout.h" ++#include "llvm/IR/DerivedTypes.h" ++#include "llvm/IR/GlobalVariable.h" ++#include "llvm/MC/MCContext.h" ++#include "llvm/MC/MCSectionELF.h" ++#include "llvm/Support/CommandLine.h" ++#include "llvm/Target/TargetMachine.h" ++using namespace llvm; ++ ++void LoongArchTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){ ++ TargetLoweringObjectFileELF::Initialize(Ctx, TM); ++ InitializeELF(TM.Options.UseInitArray); ++} +diff --git a/llvm/lib/Target/LoongArch/LoongArchTargetObjectFile.h b/llvm/lib/Target/LoongArch/LoongArchTargetObjectFile.h +new file mode 100644 +index 000000000..a50c57171 +--- /dev/null ++++ b/llvm/lib/Target/LoongArch/LoongArchTargetObjectFile.h +@@ -0,0 +1,24 @@ ++//===-- llvm/Target/LoongArchTargetObjectFile.h - LoongArch Object Info ---*- C++ -*-===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHTARGETOBJECTFILE_H ++#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHTARGETOBJECTFILE_H ++ ++#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" ++ ++namespace llvm { ++class LoongArchTargetMachine; ++ class LoongArchTargetObjectFile : public TargetLoweringObjectFileELF { ++ ++ public: ++ ++ void Initialize(MCContext &Ctx, const TargetMachine &TM) override; ++ }; ++} // end namespace llvm ++ ++#endif +diff --git a/llvm/lib/Target/LoongArch/LoongArchTargetStreamer.h b/llvm/lib/Target/LoongArch/LoongArchTargetStreamer.h +new file mode 100644 +index 000000000..f99681866 +--- /dev/null ++++ b/llvm/lib/Target/LoongArch/LoongArchTargetStreamer.h +@@ -0,0 +1,129 @@ ++//===-- LoongArchTargetStreamer.h - LoongArch Target Streamer ------------*- C++ -*--===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHTARGETSTREAMER_H ++#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHTARGETSTREAMER_H ++ ++#include "MCTargetDesc/LoongArchABIInfo.h" ++#include "llvm/ADT/STLExtras.h" ++#include "llvm/MC/MCELFStreamer.h" ++#include "llvm/MC/MCRegisterInfo.h" ++#include "llvm/MC/MCStreamer.h" ++ ++namespace llvm { ++ ++class formatted_raw_ostream; ++ ++struct LoongArchFPABIInfo; ++ ++class LoongArchTargetStreamer : public MCTargetStreamer { ++public: ++ LoongArchTargetStreamer(MCStreamer &S); ++ ++ virtual void setPic(bool Value) {} ++ ++ virtual void emitDirectiveOptionPic0(); ++ virtual void emitDirectiveOptionPic2(); ++ ++ virtual void emitDirectiveSetArch(StringRef Arch); ++ virtual void emitDirectiveSetLoongArch32(); ++ virtual void emitDirectiveSetloongarch64(); ++ ++ void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc, ++ const MCSubtargetInfo *STI); ++ void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, ++ const MCSubtargetInfo *STI); ++ void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc, ++ const MCSubtargetInfo *STI); ++ void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc, ++ const MCSubtargetInfo *STI); ++ void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc, ++ const MCSubtargetInfo *STI); ++ void emitRXX(unsigned Opcode, unsigned Reg0, MCOperand Op1, MCOperand Op2, ++ SMLoc IDLoc, const MCSubtargetInfo *STI); ++ void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2, ++ SMLoc IDLoc, const MCSubtargetInfo *STI); ++ void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2, ++ SMLoc IDLoc, const MCSubtargetInfo *STI); ++ void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int32_t Imm, ++ SMLoc IDLoc, const MCSubtargetInfo *STI); ++ void emitRRXX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2, ++ MCOperand Op3, SMLoc IDLoc, const MCSubtargetInfo *STI); ++ void emitRRIII(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm0, ++ int16_t Imm1, int16_t Imm2, SMLoc IDLoc, ++ const MCSubtargetInfo *STI); ++ void emitAdd(unsigned DstReg, unsigned SrcReg, unsigned TrgReg, bool Is64Bit, ++ const MCSubtargetInfo *STI); ++ void emitDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount, ++ SMLoc IDLoc, const MCSubtargetInfo *STI); ++ void emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI); ++ ++ void forbidModuleDirective() { ModuleDirectiveAllowed = false; } ++ void reallowModuleDirective() { ModuleDirectiveAllowed = true; } ++ bool isModuleDirectiveAllowed() { return ModuleDirectiveAllowed; } ++ ++ template ++ void updateABIInfo(const PredicateLibrary &P) { ++ ABI = P.getABI(); ++ } ++ ++ const LoongArchABIInfo &getABI() const { ++ assert(ABI && "ABI hasn't been set!"); ++ return *ABI; ++ } ++ ++protected: ++ std::optional ABI; ++ ++ bool GPRInfoSet; ++ ++ bool FPRInfoSet; ++ ++ bool FrameInfoSet; ++ int FrameOffset; ++ unsigned FrameReg; ++ unsigned ReturnReg; ++ ++private: ++ bool ModuleDirectiveAllowed; ++}; ++ ++// This part is for ascii assembly output ++class LoongArchTargetAsmStreamer : public LoongArchTargetStreamer { ++ formatted_raw_ostream &OS; ++ ++public: ++ LoongArchTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS); ++ ++ void emitDirectiveOptionPic0() override; ++ void emitDirectiveOptionPic2() override; ++ ++ void emitDirectiveSetArch(StringRef Arch) override; ++ void emitDirectiveSetLoongArch32() override; ++ void emitDirectiveSetloongarch64() override; ++}; ++ ++// This part is for ELF object output ++class LoongArchTargetELFStreamer : public LoongArchTargetStreamer { ++ const MCSubtargetInfo &STI; ++ bool Pic; ++ ++public: ++ MCELFStreamer &getStreamer(); ++ LoongArchTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI); ++ ++ void setPic(bool Value) override { Pic = Value; } ++ ++ void emitLabel(MCSymbol *Symbol) override; ++ void finish() override; ++ ++ void emitDirectiveOptionPic0() override; ++ void emitDirectiveOptionPic2() override; ++}; ++} ++#endif +diff --git a/llvm/lib/Target/LoongArch/LoongArchTargetTransformInfo.cpp b/llvm/lib/Target/LoongArch/LoongArchTargetTransformInfo.cpp +index d47dded9e..23abb402c 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchTargetTransformInfo.cpp ++++ b/llvm/lib/Target/LoongArch/LoongArchTargetTransformInfo.cpp +@@ -1,8 +1,10 @@ +-//===-- LoongArchTargetTransformInfo.cpp - LoongArch specific TTI ---------===// ++//===-- LoongArchTargetTransformInfo.cpp - LoongArch specific TTI pass ++//----------------===// + // +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// The LLVM Compiler Infrastructure ++// ++// This file is distributed under the University of Illinois Open Source ++// License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + /// \file +@@ -14,30 +16,311 @@ + //===----------------------------------------------------------------------===// + + #include "LoongArchTargetTransformInfo.h" ++#include "llvm/Analysis/TargetTransformInfo.h" ++#include "llvm/CodeGen/BasicTTIImpl.h" ++#include "llvm/CodeGen/CostTable.h" ++#include "llvm/CodeGen/TargetLowering.h" ++#include "llvm/IR/IntrinsicInst.h" ++#include "llvm/Support/Debug.h" + + using namespace llvm; + +-#define DEBUG_TYPE "loongarchtti" +- +-TypeSize LoongArchTTIImpl::getRegisterBitWidth( +- TargetTransformInfo::RegisterKind K) const { +- TypeSize DefSize = TargetTransformInfoImplBase::getRegisterBitWidth(K); +- switch (K) { +- case TargetTransformInfo::RGK_Scalar: +- return TypeSize::getFixed(ST->is64Bit() ? 64 : 32); +- case TargetTransformInfo::RGK_FixedWidthVector: +- if (!ST->hasExpAutoVec()) +- return DefSize; +- if (ST->hasExtLASX()) +- return TypeSize::getFixed(256); +- if (ST->hasExtLSX()) +- return TypeSize::getFixed(128); +- [[fallthrough]]; +- case TargetTransformInfo::RGK_ScalableVector: +- return DefSize; ++#define DEBUG_TYPE "LoongArchtti" ++ ++//===----------------------------------------------------------------------===// ++// ++// LoongArch cost model. ++// ++//===----------------------------------------------------------------------===// ++ ++bool LoongArchTTIImpl::areInlineCompatible(const Function *Caller, ++ const Function *Callee) const { ++ const TargetMachine &TM = getTLI()->getTargetMachine(); ++ ++ const FeatureBitset &CallerBits = ++ TM.getSubtargetImpl(*Caller)->getFeatureBits(); ++ const FeatureBitset &CalleeBits = ++ TM.getSubtargetImpl(*Callee)->getFeatureBits(); ++ ++ // Inline a callee if its target-features are a subset of the callers ++ // target-features. ++ return (CallerBits & CalleeBits) == CalleeBits; ++} ++ ++TargetTransformInfo::PopcntSupportKind ++LoongArchTTIImpl::getPopcntSupport(unsigned TyWidth) { ++ assert(isPowerOf2_32(TyWidth) && "Ty width must be power of 2"); ++ if (TyWidth == 32 || TyWidth == 64) ++ return TTI::PSK_FastHardware; ++ return TTI::PSK_Software; ++} ++ ++unsigned LoongArchTTIImpl::getNumberOfRegisters(bool Vector) { ++ if (Vector && !ST->hasLSX()) ++ return 0; ++ ++ return 32; ++} ++ ++unsigned LoongArchTTIImpl::getRegisterBitWidth(bool Vector) const { ++ if (Vector) { ++ if (ST->hasLASX()) ++ return 256; ++ ++ if (ST->hasLSX()) ++ return 128; ++ ++ return 0; + } ++ return 64; ++} + +- llvm_unreachable("Unsupported register kind"); ++unsigned LoongArchTTIImpl::getMaxInterleaveFactor(unsigned VF) { ++ if (VF == 1) ++ return 1; ++ return 2; + } + +-// TODO: Implement more hooks to provide TTI machinery for LoongArch. ++InstructionCost LoongArchTTIImpl::getArithmeticInstrCost( ++ unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, ++ TTI::OperandValueInfo Op1Info, TTI::OperandValueInfo Op2Info, ++ ArrayRef Args, const Instruction *CxtI) { ++ ++ std::pair LT = getTypeLegalizationCost(Ty); ++ ++ int ISD = TLI->InstructionOpcodeToISD(Opcode); ++ assert(ISD && "Invalid opcode"); ++ ++ static const CostTblEntry LASXCostTable[] = { ++ ++ {ISD::SHL, MVT::v32i8, 1}, ++ {ISD::SHL, MVT::v16i16, 1}, ++ {ISD::SHL, MVT::v8i32, 1}, ++ {ISD::SHL, MVT::v4i64, 1}, ++ ++ {ISD::SRL, MVT::v32i8, 1}, ++ {ISD::SRL, MVT::v16i16, 1}, ++ {ISD::SRL, MVT::v8i32, 1}, ++ {ISD::SRL, MVT::v4i64, 1}, ++ ++ {ISD::SRA, MVT::v32i8, 1}, ++ {ISD::SRA, MVT::v16i16, 1}, ++ {ISD::SRA, MVT::v8i32, 1}, ++ {ISD::SRA, MVT::v4i64, 1}, ++ ++ {ISD::SUB, MVT::v32i8, 1}, ++ {ISD::SUB, MVT::v16i16, 1}, ++ {ISD::SUB, MVT::v8i32, 1}, ++ {ISD::SUB, MVT::v4i64, 1}, ++ ++ {ISD::ADD, MVT::v32i8, 1}, ++ {ISD::ADD, MVT::v16i16, 1}, ++ {ISD::ADD, MVT::v8i32, 1}, ++ {ISD::ADD, MVT::v4i64, 1}, ++ ++ {ISD::MUL, MVT::v32i8, 1}, ++ {ISD::MUL, MVT::v16i16, 1}, ++ {ISD::MUL, MVT::v8i32, 1}, ++ {ISD::MUL, MVT::v4i64, 1}, ++ ++ {ISD::SDIV, MVT::v32i8, 29}, ++ {ISD::SDIV, MVT::v16i16, 19}, ++ {ISD::SDIV, MVT::v8i32, 14}, ++ {ISD::SDIV, MVT::v4i64, 13}, ++ ++ {ISD::UDIV, MVT::v32i8, 29}, ++ {ISD::UDIV, MVT::v16i16, 19}, ++ {ISD::UDIV, MVT::v8i32, 14}, ++ {ISD::UDIV, MVT::v4i64, 13}, ++ ++ {ISD::SREM, MVT::v32i8, 33}, ++ {ISD::SREM, MVT::v16i16, 21}, ++ {ISD::SREM, MVT::v8i32, 15}, ++ {ISD::SREM, MVT::v4i64, 13}, ++ ++ {ISD::UREM, MVT::v32i8, 29}, ++ {ISD::UREM, MVT::v16i16, 19}, ++ {ISD::UREM, MVT::v8i32, 14}, ++ {ISD::UREM, MVT::v4i64, 13}, ++ ++ {ISD::FADD, MVT::f64, 1}, ++ {ISD::FADD, MVT::f32, 1}, ++ {ISD::FADD, MVT::v4f64, 1}, ++ {ISD::FADD, MVT::v8f32, 1}, ++ ++ {ISD::FSUB, MVT::f64, 1}, ++ {ISD::FSUB, MVT::f32, 1}, ++ {ISD::FSUB, MVT::v4f64, 1}, ++ {ISD::FSUB, MVT::v8f32, 1}, ++ ++ {ISD::FMUL, MVT::f64, 1}, ++ {ISD::FMUL, MVT::f32, 1}, ++ {ISD::FMUL, MVT::v4f64, 1}, ++ {ISD::FMUL, MVT::v8f32, 1}, ++ ++ {ISD::FDIV, MVT::f32, 12}, ++ {ISD::FDIV, MVT::f64, 10}, ++ {ISD::FDIV, MVT::v8f32, 12}, ++ {ISD::FDIV, MVT::v4f64, 10} ++ ++ }; ++ ++ if (ST->hasLASX()) ++ if (const auto *Entry = CostTableLookup(LASXCostTable, ISD, LT.second)) ++ return LT.first * Entry->Cost; ++ ++ static const CostTblEntry LSXCostTable[] = { ++ ++ {ISD::SHL, MVT::v16i8, 1}, ++ {ISD::SHL, MVT::v8i16, 1}, ++ {ISD::SHL, MVT::v4i32, 1}, ++ {ISD::SHL, MVT::v2i64, 1}, ++ ++ {ISD::SRL, MVT::v16i8, 1}, ++ {ISD::SRL, MVT::v8i16, 1}, ++ {ISD::SRL, MVT::v4i32, 1}, ++ {ISD::SRL, MVT::v2i64, 1}, ++ ++ {ISD::SRA, MVT::v16i8, 1}, ++ {ISD::SRA, MVT::v8i16, 1}, ++ {ISD::SRA, MVT::v4i32, 1}, ++ {ISD::SRA, MVT::v2i64, 1}, ++ ++ {ISD::SUB, MVT::v16i8, 1}, ++ {ISD::SUB, MVT::v8i16, 1}, ++ {ISD::SUB, MVT::v4i32, 1}, ++ {ISD::SUB, MVT::v2i64, 1}, ++ ++ {ISD::ADD, MVT::v16i8, 1}, ++ {ISD::ADD, MVT::v8i16, 1}, ++ {ISD::ADD, MVT::v4i32, 1}, ++ {ISD::ADD, MVT::v2i64, 1}, ++ ++ {ISD::MUL, MVT::v16i8, 1}, ++ {ISD::MUL, MVT::v8i16, 1}, ++ {ISD::MUL, MVT::v4i32, 1}, ++ {ISD::MUL, MVT::v2i64, 1}, ++ ++ {ISD::SDIV, MVT::v16i8, 29}, ++ {ISD::SDIV, MVT::v8i16, 19}, ++ {ISD::SDIV, MVT::v4i32, 14}, ++ {ISD::SDIV, MVT::v2i64, 13}, ++ ++ {ISD::UDIV, MVT::v16i8, 29}, ++ {ISD::UDIV, MVT::v8i16, 19}, ++ {ISD::UDIV, MVT::v4i32, 14}, ++ {ISD::UDIV, MVT::v2i64, 13}, ++ ++ {ISD::SREM, MVT::v16i8, 33}, ++ {ISD::SREM, MVT::v8i16, 21}, ++ {ISD::SREM, MVT::v4i32, 15}, ++ {ISD::SREM, MVT::v2i64, 13}, ++ ++ {ISD::UREM, MVT::v16i8, 29}, ++ {ISD::UREM, MVT::v8i16, 19}, ++ {ISD::UREM, MVT::v4i32, 14}, ++ {ISD::UREM, MVT::v2i64, 13}, ++ ++ {ISD::FADD, MVT::f64, 1}, ++ {ISD::FADD, MVT::f32, 1}, ++ {ISD::FADD, MVT::v2f64, 1}, ++ {ISD::FADD, MVT::v4f32, 1}, ++ ++ {ISD::FSUB, MVT::f64, 1}, ++ {ISD::FSUB, MVT::f32, 1}, ++ {ISD::FSUB, MVT::v2f64, 1}, ++ {ISD::FSUB, MVT::v4f32, 1}, ++ ++ {ISD::FMUL, MVT::f64, 1}, ++ {ISD::FMUL, MVT::f32, 1}, ++ {ISD::FMUL, MVT::v2f64, 1}, ++ {ISD::FMUL, MVT::v4f32, 1}, ++ ++ {ISD::FDIV, MVT::f32, 12}, ++ {ISD::FDIV, MVT::f64, 10}, ++ {ISD::FDIV, MVT::v4f32, 12}, ++ {ISD::FDIV, MVT::v2f64, 10} ++ ++ }; ++ ++ if (ST->hasLSX()) ++ if (const auto *Entry = CostTableLookup(LSXCostTable, ISD, LT.second)) ++ return LT.first * Entry->Cost; ++ ++ // Fallback to the default implementation. ++ return BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind, Op1Info, Op2Info, ++ Args, CxtI); ++} ++ ++InstructionCost LoongArchTTIImpl::getVectorInstrCost(unsigned Opcode, Type *Val, ++ TTI::TargetCostKind CostKind, ++ unsigned Index, Value *Op0, ++ Value *Op1) { ++ assert(Val->isVectorTy() && "This must be a vector type"); ++ ++ Type *ScalarType = Val->getScalarType(); ++ ++ if (Index != -1U) { ++ // Legalize the type. ++ std::pair LT = getTypeLegalizationCost(Val); ++ ++ // This type is legalized to a scalar type. ++ if (!LT.second.isVector()) ++ return 0; ++ ++ // The type may be split. Normalize the index to the new type. ++ unsigned Width = LT.second.getVectorNumElements(); ++ Index = Index % Width; ++ ++ // The element at index zero is already inside the vector. ++ if (Index == 0) // if (ScalarType->isFloatingPointTy() && Index == 0) ++ return 0; ++ } ++ ++ // Add to the base cost if we know that the extracted element of a vector is ++ // destined to be moved to and used in the integer register file. ++ int RegisterFileMoveCost = 0; ++ if (Opcode == Instruction::ExtractElement && ScalarType->isPointerTy()) ++ RegisterFileMoveCost = 1; ++ ++ return BaseT::getVectorInstrCost(Opcode, Val, CostKind, Index, Op0, Op1) + RegisterFileMoveCost; ++} ++ ++unsigned LoongArchTTIImpl::getLoadStoreVecRegBitWidth(unsigned) const { ++ return getRegisterBitWidth(true); ++} ++ ++InstructionCost LoongArchTTIImpl::getCastInstrCost(unsigned Opcode, Type *Dst, ++ Type *Src, ++ TTI::CastContextHint CCH, ++ TTI::TargetCostKind CostKind, ++ const Instruction *I) { ++ int ISD = TLI->InstructionOpcodeToISD(Opcode); ++ assert(ISD && "Invalid opcode"); ++ ++ static const TypeConversionCostTblEntry LASXConversionTbl[] = { ++ ++ // TODO:The cost requires more granular testing ++ {ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, 3}, ++ {ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, 3}, ++ {ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, 3}, ++ {ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, 3}, ++ {ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, 3}, ++ {ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, 3}, ++ ++ }; ++ ++ EVT SrcTy = TLI->getValueType(DL, Src); ++ EVT DstTy = TLI->getValueType(DL, Dst); ++ ++ if (!SrcTy.isSimple() || !DstTy.isSimple()) ++ return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I); ++ ++ if (ST->hasLASX()) { ++ if (const auto *Entry = ConvertCostTableLookup( ++ LASXConversionTbl, ISD, DstTy.getSimpleVT(), SrcTy.getSimpleVT())) ++ return Entry->Cost; ++ } ++ ++ return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I); ++} +diff --git a/llvm/lib/Target/LoongArch/LoongArchTargetTransformInfo.h b/llvm/lib/Target/LoongArch/LoongArchTargetTransformInfo.h +index d296c9ed5..a88bdc295 100644 +--- a/llvm/lib/Target/LoongArch/LoongArchTargetTransformInfo.h ++++ b/llvm/lib/Target/LoongArch/LoongArchTargetTransformInfo.h +@@ -1,25 +1,29 @@ +-//===- LoongArchTargetTransformInfo.h - LoongArch specific TTI --*- C++ -*-===// ++//===-- LoongArchTargetTransformInfo.h - LoongArch specific TTI -------------*- ++// C++ -*-===// + // +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// The LLVM Compiler Infrastructure ++// ++// This file is distributed under the University of Illinois Open Source ++// License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// +-/// \file +-/// This file a TargetTransformInfo::Concept conforming object specific to the +-/// LoongArch target machine. It uses the target's detailed information to +-/// provide more precise answers to certain TTI queries, while letting the +-/// target independent and default TTI implementations handle the rest. +-/// ++// \file ++// This file a TargetTransformInfo::Concept conforming object specific to the ++// LoongArch target machine. It uses the target's detailed information to ++// provide more precise answers to certain TTI queries, while letting the ++// target independent and default TTI implementations handle the rest. ++// + //===----------------------------------------------------------------------===// + +-#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHTARGETTRANSFORMINFO_H +-#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHTARGETTRANSFORMINFO_H ++#ifndef LLVM_LIB_TARGET_LoongArch_LoongArchTARGETTRANSFORMINFO_H ++#define LLVM_LIB_TARGET_LoongArch_LoongArchTARGETTRANSFORMINFO_H + ++#include "LoongArch.h" + #include "LoongArchSubtarget.h" + #include "LoongArchTargetMachine.h" + #include "llvm/Analysis/TargetTransformInfo.h" + #include "llvm/CodeGen/BasicTTIImpl.h" ++#include "llvm/CodeGen/TargetLowering.h" + + namespace llvm { + +@@ -39,11 +43,49 @@ public: + : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)), + TLI(ST->getTargetLowering()) {} + +- TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const; ++ bool areInlineCompatible(const Function *Caller, ++ const Function *Callee) const; ++ ++ /// \name Scalar TTI Implementations ++ // /// @{ ++ ++ TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth); ++ ++ /// @} ++ ++ /// \name Vector TTI Implementations ++ /// @{ ++ ++ bool enableInterleavedAccessVectorization() { return true; } ++ ++ unsigned getNumberOfRegisters(bool Vector); ++ ++ unsigned getRegisterBitWidth(bool Vector) const; ++ ++ unsigned getMaxInterleaveFactor(unsigned VF); ++ ++ using BaseT::getVectorInstrCost; ++ InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, ++ TTI::TargetCostKind CostKind, ++ unsigned Index, Value *Op0, Value *Op1); ++ ++ InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, ++ TTI::CastContextHint CCH, ++ TTI::TargetCostKind CostKind, ++ const Instruction *I = nullptr); ++ ++ unsigned getLoadStoreVecRegBitWidth(unsigned AS) const; ++ ++ InstructionCost getArithmeticInstrCost( ++ unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, ++ TTI::OperandValueInfo Op1Info = {TTI::OK_AnyValue, TTI::OP_None}, ++ TTI::OperandValueInfo Op2Info = {TTI::OK_AnyValue, TTI::OP_None}, ++ ArrayRef Args = ArrayRef(), ++ const Instruction *CxtI = nullptr); + +- // TODO: Implement more hooks to provide TTI machinery for LoongArch. ++ /// @} + }; + + } // end namespace llvm + +-#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHTARGETTRANSFORMINFO_H ++#endif +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/LoongArch/MCTargetDesc/CMakeLists.txt +index 796e50b5c..927fa7d5b 100644 +--- a/llvm/lib/Target/LoongArch/MCTargetDesc/CMakeLists.txt ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/CMakeLists.txt +@@ -1,6 +1,7 @@ +-add_llvm_component_library(LLVMLoongArchDesc ++ add_llvm_component_library(LLVMLoongArchDesc ++ LoongArchABIInfo.cpp ++ LoongArchAnalyzeImmediate.cpp + LoongArchAsmBackend.cpp +- LoongArchBaseInfo.cpp + LoongArchELFObjectWriter.cpp + LoongArchELFStreamer.cpp + LoongArchInstPrinter.cpp +@@ -8,14 +9,12 @@ add_llvm_component_library(LLVMLoongArchDesc + LoongArchMCCodeEmitter.cpp + LoongArchMCExpr.cpp + LoongArchMCTargetDesc.cpp +- LoongArchMatInt.cpp + LoongArchTargetStreamer.cpp + + LINK_COMPONENTS + MC + LoongArchInfo + Support +- TargetParser + + ADD_TO_COMPONENT + LoongArch +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchABIInfo.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchABIInfo.cpp +new file mode 100644 +index 000000000..00b67d45d +--- /dev/null ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchABIInfo.cpp +@@ -0,0 +1,106 @@ ++//===---- LoongArchABIInfo.cpp - Information about LoongArch ABI's ------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++#include "LoongArchABIInfo.h" ++#include "LoongArchRegisterInfo.h" ++#include "llvm/ADT/StringRef.h" ++#include "llvm/ADT/StringSwitch.h" ++#include "llvm/MC/MCTargetOptions.h" ++ ++using namespace llvm; ++ ++namespace { ++static const MCPhysReg LP32IntRegs[4] = {LoongArch::A0, LoongArch::A1, LoongArch::A2, LoongArch::A3}; ++ ++static const MCPhysReg LoongArch64IntRegs[8] = { ++ LoongArch::A0_64, LoongArch::A1_64, LoongArch::A2_64, LoongArch::A3_64, ++ LoongArch::A4_64, LoongArch::A5_64, LoongArch::A6_64, LoongArch::A7_64}; ++} ++ ++ArrayRef LoongArchABIInfo::GetByValArgRegs() const { ++ if (IsLP32()) ++ return ArrayRef(LP32IntRegs); ++ if (IsLPX32() || IsLP64()) ++ return ArrayRef(LoongArch64IntRegs); ++ llvm_unreachable("Unhandled ABI"); ++} ++ ++ArrayRef LoongArchABIInfo::GetVarArgRegs() const { ++ if (IsLP32()) ++ return ArrayRef(LP32IntRegs); ++ if (IsLPX32() || IsLP64()) ++ return ArrayRef(LoongArch64IntRegs); ++ llvm_unreachable("Unhandled ABI"); ++} ++ ++LoongArchABIInfo LoongArchABIInfo::computeTargetABI(const Triple &TT, StringRef CPU, ++ const MCTargetOptions &Options) { ++ if (Options.getABIName().starts_with("lp32")) ++ return LoongArchABIInfo::LP32(); ++ if (Options.getABIName().starts_with("lpx32")) ++ return LoongArchABIInfo::LPX32(); ++ if (Options.getABIName().starts_with("lp64")) ++ return LoongArchABIInfo::LP64(); ++ assert(Options.getABIName().empty() && "Unknown ABI option for LoongArch"); ++ ++ if (TT.isLoongArch64()) ++ return LoongArchABIInfo::LP64(); ++ return LoongArchABIInfo::LP32(); ++} ++ ++unsigned LoongArchABIInfo::GetStackPtr() const { ++ return ArePtrs64bit() ? LoongArch::SP_64 : LoongArch::SP; ++} ++ ++unsigned LoongArchABIInfo::GetFramePtr() const { ++ return ArePtrs64bit() ? LoongArch::FP_64 : LoongArch::FP; ++} ++ ++unsigned LoongArchABIInfo::GetBasePtr() const { ++ return ArePtrs64bit() ? LoongArch::S7_64 : LoongArch::S7; ++} ++ ++unsigned LoongArchABIInfo::GetNullPtr() const { ++ return ArePtrs64bit() ? LoongArch::ZERO_64 : LoongArch::ZERO; ++} ++ ++unsigned LoongArchABIInfo::GetZeroReg() const { ++ return AreGprs64bit() ? LoongArch::ZERO_64 : LoongArch::ZERO; ++} ++ ++unsigned LoongArchABIInfo::GetPtrAddOp() const { ++ return ArePtrs64bit() ? LoongArch::ADD_D : LoongArch::ADD_W; ++} ++ ++unsigned LoongArchABIInfo::GetPtrAddiOp() const { ++ return ArePtrs64bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W; ++} ++ ++unsigned LoongArchABIInfo::GetPtrSubOp() const { ++ return ArePtrs64bit() ? LoongArch::SUB_D : LoongArch::SUB_W; ++} ++ ++unsigned LoongArchABIInfo::GetPtrAndOp() const { ++ return ArePtrs64bit() ? LoongArch::AND : LoongArch::AND32; ++} ++ ++unsigned LoongArchABIInfo::GetGPRMoveOp() const { ++ return ArePtrs64bit() ? LoongArch::OR : LoongArch::OR32; ++} ++ ++unsigned LoongArchABIInfo::GetEhDataReg(unsigned I) const { ++ static const unsigned EhDataReg[] = { ++ LoongArch::A0, LoongArch::A1, LoongArch::A2, LoongArch::A3 ++ }; ++ static const unsigned EhDataReg64[] = { ++ LoongArch::A0_64, LoongArch::A1_64, LoongArch::A2_64, LoongArch::A3_64 ++ }; ++ ++ return IsLP64() ? EhDataReg64[I] : EhDataReg[I]; ++} ++ +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchABIInfo.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchABIInfo.h +new file mode 100644 +index 000000000..351ec7646 +--- /dev/null ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchABIInfo.h +@@ -0,0 +1,76 @@ ++//===---- LoongArchABIInfo.h - Information about LoongArch ABI's --------------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++#ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHABIINFO_H ++#define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHABIINFO_H ++ ++#include "llvm/IR/CallingConv.h" ++#include "llvm/MC/MCRegisterInfo.h" ++#include "llvm/TargetParser/Triple.h" ++ ++namespace llvm { ++ ++template class ArrayRef; ++class MCTargetOptions; ++class StringRef; ++class TargetRegisterClass; ++ ++class LoongArchABIInfo { ++public: ++ enum class ABI { Unknown, LP32, LPX32, LP64 }; ++ ++protected: ++ ABI ThisABI; ++ ++public: ++ LoongArchABIInfo(ABI ThisABI) : ThisABI(ThisABI) {} ++ ++ static LoongArchABIInfo Unknown() { return LoongArchABIInfo(ABI::Unknown); } ++ static LoongArchABIInfo LP32() { return LoongArchABIInfo(ABI::LP32); } ++ static LoongArchABIInfo LPX32() { return LoongArchABIInfo(ABI::LPX32); } ++ static LoongArchABIInfo LP64() { return LoongArchABIInfo(ABI::LP64); } ++ static LoongArchABIInfo computeTargetABI(const Triple &TT, StringRef CPU, ++ const MCTargetOptions &Options); ++ ++ bool IsKnown() const { return ThisABI != ABI::Unknown; } ++ bool IsLP32() const { return ThisABI == ABI::LP32; } ++ bool IsLPX32() const { return ThisABI == ABI::LPX32; } ++ bool IsLP64() const { return ThisABI == ABI::LP64; } ++ ABI GetEnumValue() const { return ThisABI; } ++ ++ /// The registers to use for byval arguments. ++ ArrayRef GetByValArgRegs() const; ++ ++ /// The registers to use for the variable argument list. ++ ArrayRef GetVarArgRegs() const; ++ ++ /// Ordering of ABI's ++ /// LoongArchGenSubtargetInfo.inc will use this to resolve conflicts when given ++ /// multiple ABI options. ++ bool operator<(const LoongArchABIInfo Other) const { ++ return ThisABI < Other.GetEnumValue(); ++ } ++ ++ unsigned GetStackPtr() const; ++ unsigned GetFramePtr() const; ++ unsigned GetBasePtr() const; ++ unsigned GetNullPtr() const; ++ unsigned GetZeroReg() const; ++ unsigned GetPtrAddOp() const; ++ unsigned GetPtrAddiOp() const; ++ unsigned GetPtrSubOp() const; ++ unsigned GetPtrAndOp() const; ++ unsigned GetGPRMoveOp() const; ++ inline bool ArePtrs64bit() const { return IsLP64(); } ++ inline bool AreGprs64bit() const { return IsLPX32() || IsLP64(); } ++ ++ unsigned GetEhDataReg(unsigned I) const; ++}; ++} ++ ++#endif +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAnalyzeImmediate.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAnalyzeImmediate.cpp +new file mode 100644 +index 000000000..96e43b2d3 +--- /dev/null ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAnalyzeImmediate.cpp +@@ -0,0 +1,64 @@ ++//===- LoongArchAnalyzeImmediate.cpp - Analyze Immediates -----------------===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++ ++#include "LoongArchAnalyzeImmediate.h" ++#include "LoongArch.h" ++#include "MCTargetDesc/LoongArchMCTargetDesc.h" ++#include "llvm/Support/MathExtras.h" ++ ++using namespace llvm; ++ ++LoongArchAnalyzeImmediate::InstSeq ++LoongArchAnalyzeImmediate::generateInstSeq(int64_t Val, bool Is64Bit) { ++ // Val: ++ // | hi32 | lo32 | ++ // +------------+------------------+------------------+-----------+ ++ // | Bits_52_63 | Bits_32_51 | Bits_12_31 | Bits_0_11 | ++ // +------------+------------------+------------------+-----------+ ++ // 63 52 51 32 31 12 11 0 ++ unsigned ORIOp = Is64Bit ? LoongArch::ORI : LoongArch::ORI32; ++ unsigned LU12IOp = Is64Bit ? LoongArch::LU12I_W : LoongArch::LU12I_W32; ++ unsigned ADDIOp = Is64Bit ? LoongArch::ADDI_W64 : LoongArch::ADDI_W; ++ unsigned LU32IOp = LoongArch::LU32I_D_R2; ++ unsigned LU52IOp = LoongArch::LU52I_D; ++ ++ int64_t Bits_52_63 = Val >> 52 & 0xFFF; ++ int64_t Bits_32_51 = Val >> 32 & 0xFFFFF; ++ int64_t Bits_12_31 = Val >> 12 & 0xFFFFF; ++ int64_t Bits_0_11 = Val & 0xFFF; ++ ++ InstSeq Insts; ++ ++ if (isInt<12>(Val) && Is64Bit) { ++ Insts.push_back(Inst(LoongArch::ADDI_D, SignExtend64<12>(Bits_0_11))); ++ return Insts; ++ } ++ ++ if (Bits_52_63 != 0 && SignExtend64<52>(Val) == 0) { ++ Insts.push_back(Inst(LU52IOp, SignExtend64<12>(Bits_52_63))); ++ return Insts; ++ } ++ ++ if (Bits_12_31 == 0) ++ Insts.push_back(Inst(ORIOp, Bits_0_11)); ++ else if (SignExtend32<1>(Bits_0_11 >> 11) == SignExtend32<20>(Bits_12_31)) ++ Insts.push_back(Inst(ADDIOp, SignExtend64<12>(Bits_0_11))); ++ else { ++ Insts.push_back(Inst(LU12IOp, SignExtend64<20>(Bits_12_31))); ++ if (Bits_0_11 != 0) ++ Insts.push_back(Inst(ORIOp, Bits_0_11)); ++ } ++ ++ if (SignExtend32<1>(Bits_12_31 >> 19) != SignExtend32<20>(Bits_32_51)) ++ Insts.push_back(Inst(LU32IOp, SignExtend64<20>(Bits_32_51))); ++ ++ if (SignExtend32<1>(Bits_32_51 >> 19) != SignExtend32<12>(Bits_52_63)) ++ Insts.push_back(Inst(LU52IOp, SignExtend64<12>(Bits_52_63))); ++ ++ return Insts; ++} +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMatInt.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAnalyzeImmediate.h +similarity index 62% +rename from llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMatInt.h +rename to llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAnalyzeImmediate.h +index be1b42589..3ff00f254 100644 +--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMatInt.h ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAnalyzeImmediate.h +@@ -1,4 +1,4 @@ +-//===- LoongArchMatInt.h - Immediate materialisation - --------*- C++ -*--===// ++//===- LoongArchAnalyzeImmediate.h - Analyze Immediates --------*- C++ -*--===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -6,14 +6,13 @@ + // + //===----------------------------------------------------------------------===// + +-#ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_MATINT_H +-#define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_MATINT_H ++#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHANALYZEIMMEDIATE_H ++#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHANALYZEIMMEDIATE_H + + #include "llvm/ADT/SmallVector.h" +-#include + + namespace llvm { +-namespace LoongArchMatInt { ++namespace LoongArchAnalyzeImmediate { + struct Inst { + unsigned Opc; + int64_t Imm; +@@ -23,8 +22,8 @@ using InstSeq = SmallVector; + + // Helper to generate an instruction sequence that will materialise the given + // immediate value into a register. +-InstSeq generateInstSeq(int64_t Val); +-} // end namespace LoongArchMatInt ++InstSeq generateInstSeq(int64_t Val, bool Is64Bit); ++} // end namespace LoongArchAnalyzeImmediate + } // end namespace llvm + +-#endif ++#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHANALYZEIMMEDIATE_H +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp +index de492f2b1..50efb35ef 100644 +--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp +@@ -1,4 +1,4 @@ +-//===-- LoongArchAsmBackend.cpp - LoongArch Assembler Backend -*- C++ -*---===// ++//===-- LoongArchAsmBackend.cpp - LoongArch Asm Backend ----------------------------===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -9,68 +9,151 @@ + // This file implements the LoongArchAsmBackend class. + // + //===----------------------------------------------------------------------===// ++// + +-#include "LoongArchAsmBackend.h" +-#include "LoongArchFixupKinds.h" +-#include "llvm/MC/MCAsmInfo.h" +-#include "llvm/MC/MCAsmLayout.h" ++#include "MCTargetDesc/LoongArchAsmBackend.h" ++#include "MCTargetDesc/LoongArchABIInfo.h" ++#include "MCTargetDesc/LoongArchFixupKinds.h" ++#include "MCTargetDesc/LoongArchMCExpr.h" ++#include "MCTargetDesc/LoongArchMCTargetDesc.h" ++#include "llvm/ADT/STLExtras.h" ++#include "llvm/MC/MCAsmBackend.h" + #include "llvm/MC/MCAssembler.h" + #include "llvm/MC/MCContext.h" ++#include "llvm/MC/MCDirectives.h" + #include "llvm/MC/MCELFObjectWriter.h" +-#include "llvm/MC/MCExpr.h" +-#include "llvm/MC/MCSection.h" ++#include "llvm/MC/MCFixupKindInfo.h" ++#include "llvm/MC/MCObjectWriter.h" ++#include "llvm/MC/MCSubtargetInfo.h" ++#include "llvm/MC/MCTargetOptions.h" + #include "llvm/MC/MCValue.h" + #include "llvm/Support/EndianStream.h" +-#include "llvm/Support/LEB128.h" ++#include "llvm/Support/ErrorHandling.h" ++#include "llvm/Support/Format.h" + #include "llvm/Support/MathExtras.h" +- +-#define DEBUG_TYPE "loongarch-asmbackend" ++#include "llvm/Support/raw_ostream.h" + + using namespace llvm; + ++std::unique_ptr ++LoongArchAsmBackend::createObjectTargetWriter() const { ++ return createLoongArchELFObjectWriter(TheTriple, IsLPX32); ++} ++ ++/// ApplyFixup - Apply the \p Value for given \p Fixup into the provided ++/// data fragment, at the offset specified by the fixup and following the ++/// fixup kind as appropriate. ++void LoongArchAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, ++ const MCValue &Target, ++ MutableArrayRef Data, uint64_t Value, ++ bool IsResolved, ++ const MCSubtargetInfo *STI) const { ++ MCFixupKind Kind = Fixup.getKind(); ++ if (Kind > FirstTargetFixupKind) ++ return; ++ ++ if (!Value) ++ return; // Doesn't change encoding. ++ ++ // Where do we start in the object ++ unsigned Offset = Fixup.getOffset(); ++ // Number of bytes we need to fixup ++ unsigned NumBytes = (getFixupKindInfo(Kind).TargetSize + 7) / 8; ++ ++ ++ // Grab current value, if any, from bits. ++ uint64_t CurVal = 0; ++ ++ for (unsigned i = 0; i != NumBytes; ++i) ++ CurVal |= (uint64_t)((uint8_t)Data[Offset + i]) << (i*8); ++ ++ uint64_t Mask = ((uint64_t)(-1) >> ++ (64 - getFixupKindInfo(Kind).TargetSize)); ++ CurVal |= Value & Mask; ++ ++ // Write out the fixed up bytes back to the code/data bits. ++ for (unsigned i = 0; i != NumBytes; ++i) ++ Data[Offset + i] = (uint8_t)((CurVal >> (i*8)) & 0xff); ++} ++ + std::optional + LoongArchAsmBackend::getFixupKind(StringRef Name) const { + if (STI.getTargetTriple().isOSBinFormatELF()) { +- auto Type = llvm::StringSwitch(Name) ++ unsigned Type = llvm::StringSwitch(Name) + #define ELF_RELOC(X, Y) .Case(#X, Y) + #include "llvm/BinaryFormat/ELFRelocs/LoongArch.def" + #undef ELF_RELOC +- .Case("BFD_RELOC_NONE", ELF::R_LARCH_NONE) +- .Case("BFD_RELOC_32", ELF::R_LARCH_32) +- .Case("BFD_RELOC_64", ELF::R_LARCH_64) +- .Default(-1u); ++ .Case("BFD_RELOC_NONE", ELF::R_LARCH_NONE) ++ .Case("BFD_RELOC_32", ELF::R_LARCH_32) ++ .Case("BFD_RELOC_64", ELF::R_LARCH_64) ++ .Default(-1u); + if (Type != -1u) + return static_cast(FirstLiteralRelocationKind + Type); + } + return std::nullopt; + } + +-const MCFixupKindInfo & +-LoongArchAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { ++const MCFixupKindInfo &LoongArchAsmBackend:: ++getFixupKindInfo(MCFixupKind Kind) const { + const static MCFixupKindInfo Infos[] = { +- // This table *must* be in the order that the fixup_* kinds are defined in +- // LoongArchFixupKinds.h. +- // +- // {name, offset, bits, flags} +- {"fixup_loongarch_b16", 10, 16, MCFixupKindInfo::FKF_IsPCRel}, +- {"fixup_loongarch_b21", 0, 26, MCFixupKindInfo::FKF_IsPCRel}, +- {"fixup_loongarch_b26", 0, 26, MCFixupKindInfo::FKF_IsPCRel}, +- {"fixup_loongarch_abs_hi20", 5, 20, 0}, +- {"fixup_loongarch_abs_lo12", 10, 12, 0}, +- {"fixup_loongarch_abs64_lo20", 5, 20, 0}, +- {"fixup_loongarch_abs64_hi12", 10, 12, 0}, +- {"fixup_loongarch_tls_le_hi20", 5, 20, 0}, +- {"fixup_loongarch_tls_le_lo12", 10, 12, 0}, +- {"fixup_loongarch_tls_le64_lo20", 5, 20, 0}, +- {"fixup_loongarch_tls_le64_hi12", 10, 12, 0}, +- // TODO: Add more fixup kinds. ++ // This table *must* be in same the order of fixup_* kinds in ++ // LoongArchFixupKinds.h. ++ // ++ // name offset bits flags ++ { "fixup_LARCH_NONE", 0, 0, 0 }, ++ { "fixup_LARCH_SOP_PUSH_ABSOLUTE", 0, 0, 0}, ++ { "fixup_LARCH_SOP_PUSH_PCREL", 0, 0, 0}, ++ { "fixup_LARCH_SOP_PUSH_GPREL", 0, 0, 0}, ++ { "fixup_LARCH_SOP_PUSH_TLS_TPREL", 0, 0, 0}, ++ { "fixup_LARCH_SOP_PUSH_TLS_GOT", 0, 0, 0}, ++ { "fixup_LARCH_SOP_PUSH_TLS_GD", 0, 0, 0}, ++ { "fixup_LARCH_SOP_PUSH_PLT_PCREL", 0, 0, 0}, ++ { "fixup_LARCH_32", 0, 0, 0}, ++ { "fixup_LARCH_64", 0, 0, 0}, ++ { "fixup_LARCH_RELATIVE", 0, 0, 0}, ++ { "fixup_LARCH_COPY", 0, 0, 0}, ++ { "fixup_LARCH_JUMP_SLOT", 0, 0, 0}, ++ { "fixup_LARCH_TLS_DTPMOD32", 0, 0, 0}, ++ { "fixup_LARCH_TLS_DTPMOD64", 0, 0, 0}, ++ { "fixup_LARCH_TLS_DTPREL32", 0, 0, 0}, ++ { "fixup_LARCH_TLS_DTPREL64", 0, 0, 0}, ++ { "fixup_LARCH_TLS_TPREL32", 0, 0, 0}, ++ { "fixup_LARCH_TLS_TPREL64", 0, 0, 0}, ++ { "fixup_LARCH_IRELATIVE", 0, 0, 0}, ++ { "fixup_LARCH_MARK_LA", 0, 0, 0}, ++ { "fixup_LARCH_MARK_PCREL", 0, 0, 0}, ++ { "fixup_LARCH_SOP_PUSH_DUP", 0, 0, 0}, ++ { "fixup_LARCH_SOP_ASSERT", 0, 0, 0}, ++ { "fixup_LARCH_SOP_NOT", 0, 0, 0}, ++ { "fixup_LARCH_SOP_SUB", 0, 0, 0}, ++ { "fixup_LARCH_SOP_SL", 0, 0, 0}, ++ { "fixup_LARCH_SOP_SR", 0, 0, 0}, ++ { "fixup_LARCH_SOP_ADD", 0, 0, 0}, ++ { "fixup_LARCH_SOP_AND", 0, 0, 0}, ++ { "fixup_LARCH_SOP_IF_ELSE", 0, 0, 0}, ++ { "fixup_LARCH_SOP_POP_32_S_10_5", 0, 0, 0}, ++ { "fixup_LARCH_SOP_POP_32_U_10_12", 0, 0, 0}, ++ { "fixup_LARCH_SOP_POP_32_S_10_12", 0, 0, 0}, ++ { "fixup_LARCH_SOP_POP_32_S_10_16", 0, 0, 0}, ++ { "fixup_LARCH_SOP_POP_32_S_10_16_S2", 0, 0, 0}, ++ { "fixup_LARCH_SOP_POP_32_S_5_20", 0, 0, 0}, ++ { "fixup_LARCH_SOP_POP_32_S_0_5_10_16_S2", 0, 0, 0}, ++ { "fixup_LARCH_SOP_POP_32_S_0_10_10_16_S2", 0, 0, 0}, ++ { "fixup_LARCH_SOP_POP_32_U", 0, 0, 0}, ++ { "fixup_LARCH_ADD8", 0, 0, 0}, ++ { "fixup_LARCH_ADD16", 0, 0, 0}, ++ { "fixup_LARCH_ADD24", 0, 0, 0}, ++ { "fixup_LARCH_ADD32", 0, 0, 0}, ++ { "fixup_LARCH_ADD64", 0, 0, 0}, ++ { "fixup_LARCH_SUB8", 0, 0, 0}, ++ { "fixup_LARCH_SUB16", 0, 0, 0}, ++ { "fixup_LARCH_SUB24", 0, 0, 0}, ++ { "fixup_LARCH_SUB32", 0, 0, 0}, ++ { "fixup_LARCH_SUB64", 0, 0, 0}, + }; + +- static_assert((std::size(Infos)) == LoongArch::NumTargetFixupKinds, +- "Not all fixup kinds added to Infos array"); +- +- // Fixup kinds from .reloc directive are like R_LARCH_NONE. They +- // do not require any extra processing. ++ // Fixup kinds from .reloc directive are like R_LARCH_NONE. They do not ++ // require any extra processing. + if (Kind >= FirstLiteralRelocationKind) + return MCAsmBackend::getFixupKindInfo(FK_NONE); + +@@ -78,443 +161,73 @@ LoongArchAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { + return MCAsmBackend::getFixupKindInfo(Kind); + + assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && +- "Invalid kind!"); +- return Infos[Kind - FirstTargetFixupKind]; +-} ++ "Invalid kind!"); + +-static void reportOutOfRangeError(MCContext &Ctx, SMLoc Loc, unsigned N) { +- Ctx.reportError(Loc, "fixup value out of range [" + Twine(llvm::minIntN(N)) + +- ", " + Twine(llvm::maxIntN(N)) + "]"); +-} +- +-static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value, +- MCContext &Ctx) { +- switch (Fixup.getTargetKind()) { +- default: +- llvm_unreachable("Unknown fixup kind"); +- case FK_Data_1: +- case FK_Data_2: +- case FK_Data_4: +- case FK_Data_8: +- case FK_Data_leb128: +- return Value; +- case LoongArch::fixup_loongarch_b16: { +- if (!isInt<18>(Value)) +- reportOutOfRangeError(Ctx, Fixup.getLoc(), 18); +- if (Value % 4) +- Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned"); +- return (Value >> 2) & 0xffff; +- } +- case LoongArch::fixup_loongarch_b21: { +- if (!isInt<23>(Value)) +- reportOutOfRangeError(Ctx, Fixup.getLoc(), 23); +- if (Value % 4) +- Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned"); +- return ((Value & 0x3fffc) << 8) | ((Value >> 18) & 0x1f); +- } +- case LoongArch::fixup_loongarch_b26: { +- if (!isInt<28>(Value)) +- reportOutOfRangeError(Ctx, Fixup.getLoc(), 28); +- if (Value % 4) +- Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned"); +- return ((Value & 0x3fffc) << 8) | ((Value >> 18) & 0x3ff); +- } +- case LoongArch::fixup_loongarch_abs_hi20: +- case LoongArch::fixup_loongarch_tls_le_hi20: +- return (Value >> 12) & 0xfffff; +- case LoongArch::fixup_loongarch_abs_lo12: +- case LoongArch::fixup_loongarch_tls_le_lo12: +- return Value & 0xfff; +- case LoongArch::fixup_loongarch_abs64_lo20: +- case LoongArch::fixup_loongarch_tls_le64_lo20: +- return (Value >> 32) & 0xfffff; +- case LoongArch::fixup_loongarch_abs64_hi12: +- case LoongArch::fixup_loongarch_tls_le64_hi12: +- return (Value >> 52) & 0xfff; +- } +-} +- +-static void fixupLeb128(MCContext &Ctx, const MCFixup &Fixup, +- MutableArrayRef Data, uint64_t Value) { +- unsigned I; +- for (I = 0; I != Data.size() && Value; ++I, Value >>= 7) +- Data[I] |= uint8_t(Value & 0x7f); +- if (Value) +- Ctx.reportError(Fixup.getLoc(), "Invalid uleb128 value!"); +-} +- +-void LoongArchAsmBackend::applyFixup(const MCAssembler &Asm, +- const MCFixup &Fixup, +- const MCValue &Target, +- MutableArrayRef Data, uint64_t Value, +- bool IsResolved, +- const MCSubtargetInfo *STI) const { +- if (!Value) +- return; // Doesn't change encoding. +- +- MCFixupKind Kind = Fixup.getKind(); +- if (Kind >= FirstLiteralRelocationKind) +- return; +- MCFixupKindInfo Info = getFixupKindInfo(Kind); +- MCContext &Ctx = Asm.getContext(); +- +- // Fixup leb128 separately. +- if (Fixup.getTargetKind() == FK_Data_leb128) +- return fixupLeb128(Ctx, Fixup, Data, Value); +- +- // Apply any target-specific value adjustments. +- Value = adjustFixupValue(Fixup, Value, Ctx); +- +- // Shift the value into position. +- Value <<= Info.TargetOffset; +- +- unsigned Offset = Fixup.getOffset(); +- unsigned NumBytes = alignTo(Info.TargetSize + Info.TargetOffset, 8) / 8; +- +- assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!"); +- // For each byte of the fragment that the fixup touches, mask in the +- // bits from the fixup value. +- for (unsigned I = 0; I != NumBytes; ++I) { +- Data[Offset + I] |= uint8_t((Value >> (I * 8)) & 0xff); +- } +-} +- +-// Linker relaxation may change code size. We have to insert Nops +-// for .align directive when linker relaxation enabled. So then Linker +-// could satisfy alignment by removing Nops. +-// The function returns the total Nops Size we need to insert. +-bool LoongArchAsmBackend::shouldInsertExtraNopBytesForCodeAlign( +- const MCAlignFragment &AF, unsigned &Size) { +- // Calculate Nops Size only when linker relaxation enabled. +- if (!AF.getSubtargetInfo()->hasFeature(LoongArch::FeatureRelax)) +- return false; +- +- // Ignore alignment if MaxBytesToEmit is less than the minimum Nop size. +- const unsigned MinNopLen = 4; +- if (AF.getMaxBytesToEmit() < MinNopLen) +- return false; +- Size = AF.getAlignment().value() - MinNopLen; +- return AF.getAlignment() > MinNopLen; ++ return Infos[Kind - FirstTargetFixupKind]; + } + +-// We need to insert R_LARCH_ALIGN relocation type to indicate the +-// position of Nops and the total bytes of the Nops have been inserted +-// when linker relaxation enabled. +-// The function inserts fixup_loongarch_align fixup which eventually will +-// transfer to R_LARCH_ALIGN relocation type. +-// The improved R_LARCH_ALIGN requires symbol index. The lowest 8 bits of +-// addend represent alignment and the other bits of addend represent the +-// maximum number of bytes to emit. The maximum number of bytes is zero +-// means ignore the emit limit. +-bool LoongArchAsmBackend::shouldInsertFixupForCodeAlign( +- MCAssembler &Asm, const MCAsmLayout &Layout, MCAlignFragment &AF) { +- // Insert the fixup only when linker relaxation enabled. +- if (!AF.getSubtargetInfo()->hasFeature(LoongArch::FeatureRelax)) +- return false; +- +- // Calculate total Nops we need to insert. If there are none to insert +- // then simply return. +- unsigned Count; +- if (!shouldInsertExtraNopBytesForCodeAlign(AF, Count)) ++/// WriteNopData - Write an (optimal) nop sequence of Count bytes ++/// to the given output. If the target cannot generate such a sequence, ++/// it should return an error. ++/// ++/// \return - True on success. ++bool LoongArchAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count, ++ const MCSubtargetInfo *STI) const { ++ // Check for a less than instruction size number of bytes ++ if ((Count % 4) != 0) + return false; + +- MCSection *Sec = AF.getParent(); +- MCContext &Ctx = Asm.getContext(); +- const MCExpr *Dummy = MCConstantExpr::create(0, Ctx); +- // Create fixup_loongarch_align fixup. +- MCFixup Fixup = +- MCFixup::create(0, Dummy, MCFixupKind(LoongArch::fixup_loongarch_align)); +- const MCSymbolRefExpr *MCSym = getSecToAlignSym()[Sec]; +- if (MCSym == nullptr) { +- // Create a symbol and make the value of symbol is zero. +- MCSymbol *Sym = Ctx.createNamedTempSymbol("la-relax-align"); +- Sym->setFragment(&*Sec->getBeginSymbol()->getFragment()); +- Asm.registerSymbol(*Sym); +- MCSym = MCSymbolRefExpr::create(Sym, Ctx); +- getSecToAlignSym()[Sec] = MCSym; +- } +- +- uint64_t FixedValue = 0; +- unsigned Lo = Log2_64(Count) + 1; +- unsigned Hi = AF.getMaxBytesToEmit() >= Count ? 0 : AF.getMaxBytesToEmit(); +- MCValue Value = MCValue::get(MCSym, nullptr, Hi << 8 | Lo); +- Asm.getWriter().recordRelocation(Asm, Layout, &AF, Fixup, Value, FixedValue); ++ // The nop on LoongArch is andi r0, r0, 0. ++ for (; Count >= 4; Count -= 4) ++ support::endian::write(OS, 0x03400000, llvm::endianness::little); + + return true; + } + + bool LoongArchAsmBackend::shouldForceRelocation(const MCAssembler &Asm, +- const MCFixup &Fixup, +- const MCValue &Target, +- const MCSubtargetInfo *STI) { ++ const MCFixup &Fixup, ++ const MCValue &Target, ++ const MCSubtargetInfo *STI) { ++ // .reloc directive should force relocation. + if (Fixup.getKind() >= FirstLiteralRelocationKind) + return true; +- switch (Fixup.getTargetKind()) { +- default: +- return STI->hasFeature(LoongArch::FeatureRelax); +- case FK_Data_1: +- case FK_Data_2: +- case FK_Data_4: +- case FK_Data_8: +- case FK_Data_leb128: +- return !Target.isAbsolute(); +- } +-} + +-static inline std::pair +-getRelocPairForSize(unsigned Size) { +- switch (Size) { ++ const unsigned FixupKind = Fixup.getKind(); ++ switch (FixupKind) { + default: +- llvm_unreachable("unsupported fixup size"); +- case 6: +- return std::make_pair( +- MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_ADD6), +- MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_SUB6)); +- case 8: +- return std::make_pair( +- MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_ADD8), +- MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_SUB8)); +- case 16: +- return std::make_pair( +- MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_ADD16), +- MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_SUB16)); +- case 32: +- return std::make_pair( +- MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_ADD32), +- MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_SUB32)); +- case 64: +- return std::make_pair( +- MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_ADD64), +- MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_SUB64)); +- case 128: +- return std::make_pair( +- MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_ADD_ULEB128), +- MCFixupKind(FirstLiteralRelocationKind + ELF::R_LARCH_SUB_ULEB128)); +- } +-} +- +-std::pair LoongArchAsmBackend::relaxLEB128(MCLEBFragment &LF, +- MCAsmLayout &Layout, +- int64_t &Value) const { +- const MCExpr &Expr = LF.getValue(); +- if (LF.isSigned() || !Expr.evaluateKnownAbsolute(Value, Layout)) +- return std::make_pair(false, false); +- LF.getFixups().push_back( +- MCFixup::create(0, &Expr, FK_Data_leb128, Expr.getLoc())); +- return std::make_pair(true, true); +-} +- +-bool LoongArchAsmBackend::relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF, +- MCAsmLayout &Layout, +- bool &WasRelaxed) const { +- MCContext &C = Layout.getAssembler().getContext(); +- +- int64_t LineDelta = DF.getLineDelta(); +- const MCExpr &AddrDelta = DF.getAddrDelta(); +- SmallVectorImpl &Data = DF.getContents(); +- SmallVectorImpl &Fixups = DF.getFixups(); +- size_t OldSize = Data.size(); +- +- int64_t Value; +- if (AddrDelta.evaluateAsAbsolute(Value, Layout)) + return false; +- bool IsAbsolute = AddrDelta.evaluateKnownAbsolute(Value, Layout); +- assert(IsAbsolute && "CFA with invalid expression"); +- (void)IsAbsolute; +- +- Data.clear(); +- Fixups.clear(); +- raw_svector_ostream OS(Data); +- +- // INT64_MAX is a signal that this is actually a DW_LNE_end_sequence. +- if (LineDelta != INT64_MAX) { +- OS << uint8_t(dwarf::DW_LNS_advance_line); +- encodeSLEB128(LineDelta, OS); +- } +- +- unsigned Offset; +- std::pair FK; +- +- // According to the DWARF specification, the `DW_LNS_fixed_advance_pc` opcode +- // takes a single unsigned half (unencoded) operand. The maximum encodable +- // value is therefore 65535. Set a conservative upper bound for relaxation. +- if (Value > 60000) { +- unsigned PtrSize = C.getAsmInfo()->getCodePointerSize(); +- +- OS << uint8_t(dwarf::DW_LNS_extended_op); +- encodeULEB128(PtrSize + 1, OS); +- +- OS << uint8_t(dwarf::DW_LNE_set_address); +- Offset = OS.tell(); +- assert((PtrSize == 4 || PtrSize == 8) && "Unexpected pointer size"); +- FK = getRelocPairForSize(PtrSize == 4 ? 32 : 64); +- OS.write_zeros(PtrSize); +- } else { +- OS << uint8_t(dwarf::DW_LNS_fixed_advance_pc); +- Offset = OS.tell(); +- FK = getRelocPairForSize(16); +- support::endian::write(OS, 0, llvm::endianness::little); +- } +- +- const MCBinaryExpr &MBE = cast(AddrDelta); +- Fixups.push_back(MCFixup::create(Offset, MBE.getLHS(), std::get<0>(FK))); +- Fixups.push_back(MCFixup::create(Offset, MBE.getRHS(), std::get<1>(FK))); +- +- if (LineDelta == INT64_MAX) { +- OS << uint8_t(dwarf::DW_LNS_extended_op); +- OS << uint8_t(1); +- OS << uint8_t(dwarf::DW_LNE_end_sequence); +- } else { +- OS << uint8_t(dwarf::DW_LNS_copy); +- } +- +- WasRelaxed = OldSize != Data.size(); +- return true; +-} +- +-bool LoongArchAsmBackend::relaxDwarfCFA(MCDwarfCallFrameFragment &DF, +- MCAsmLayout &Layout, +- bool &WasRelaxed) const { +- const MCExpr &AddrDelta = DF.getAddrDelta(); +- SmallVectorImpl &Data = DF.getContents(); +- SmallVectorImpl &Fixups = DF.getFixups(); +- size_t OldSize = Data.size(); +- +- int64_t Value; +- if (AddrDelta.evaluateAsAbsolute(Value, Layout)) +- return false; +- bool IsAbsolute = AddrDelta.evaluateKnownAbsolute(Value, Layout); +- assert(IsAbsolute && "CFA with invalid expression"); +- (void)IsAbsolute; +- +- Data.clear(); +- Fixups.clear(); +- raw_svector_ostream OS(Data); +- +- assert( +- Layout.getAssembler().getContext().getAsmInfo()->getMinInstAlignment() == +- 1 && +- "expected 1-byte alignment"); +- if (Value == 0) { +- WasRelaxed = OldSize != Data.size(); ++ // All these relocations require special processing ++ // at linking time. Delegate this work to a linker. ++ case LoongArch::fixup_LARCH_SOP_PUSH_PLT_PCREL: ++ case LoongArch::fixup_LARCH_SOP_PUSH_PCREL: ++ case LoongArch::fixup_LARCH_SOP_PUSH_GPREL: ++ case LoongArch::fixup_LARCH_SOP_PUSH_TLS_GD: ++ case LoongArch::fixup_LARCH_SOP_PUSH_TLS_GOT: ++ case LoongArch::fixup_LARCH_SOP_PUSH_TLS_TPREL: ++ case LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE: ++ case LoongArch::fixup_LARCH_SOP_IF_ELSE: ++ case LoongArch::fixup_LARCH_SOP_ADD: ++ case LoongArch::fixup_LARCH_SOP_SUB: ++ case LoongArch::fixup_LARCH_SOP_AND: ++ case LoongArch::fixup_LARCH_SOP_SL: ++ case LoongArch::fixup_LARCH_SOP_SR: ++ case LoongArch::fixup_LARCH_SOP_POP_32_S_10_5: ++ case LoongArch::fixup_LARCH_SOP_POP_32_S_5_20: ++ case LoongArch::fixup_LARCH_SOP_POP_32_S_10_12: ++ case LoongArch::fixup_LARCH_SOP_POP_32_U_10_12: ++ case LoongArch::fixup_LARCH_SOP_POP_32_S_10_16_S2: ++ case LoongArch::fixup_LARCH_SOP_POP_32_S_0_5_10_16_S2: ++ case LoongArch::fixup_LARCH_SOP_POP_32_S_0_10_10_16_S2: + return true; + } +- +- auto AddFixups = [&Fixups, +- &AddrDelta](unsigned Offset, +- std::pair FK) { +- const MCBinaryExpr &MBE = cast(AddrDelta); +- Fixups.push_back(MCFixup::create(Offset, MBE.getLHS(), std::get<0>(FK))); +- Fixups.push_back(MCFixup::create(Offset, MBE.getRHS(), std::get<1>(FK))); +- }; +- +- if (isUIntN(6, Value)) { +- OS << uint8_t(dwarf::DW_CFA_advance_loc); +- AddFixups(0, getRelocPairForSize(6)); +- } else if (isUInt<8>(Value)) { +- OS << uint8_t(dwarf::DW_CFA_advance_loc1); +- support::endian::write(OS, 0, llvm::endianness::little); +- AddFixups(1, getRelocPairForSize(8)); +- } else if (isUInt<16>(Value)) { +- OS << uint8_t(dwarf::DW_CFA_advance_loc2); +- support::endian::write(OS, 0, llvm::endianness::little); +- AddFixups(1, getRelocPairForSize(16)); +- } else if (isUInt<32>(Value)) { +- OS << uint8_t(dwarf::DW_CFA_advance_loc4); +- support::endian::write(OS, 0, llvm::endianness::little); +- AddFixups(1, getRelocPairForSize(32)); +- } else { +- llvm_unreachable("unsupported CFA encoding"); +- } +- +- WasRelaxed = OldSize != Data.size(); +- return true; +-} +- +-bool LoongArchAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count, +- const MCSubtargetInfo *STI) const { +- // We mostly follow binutils' convention here: align to 4-byte boundary with a +- // 0-fill padding. +- OS.write_zeros(Count % 4); +- +- // The remainder is now padded with 4-byte nops. +- // nop: andi r0, r0, 0 +- for (; Count >= 4; Count -= 4) +- OS.write("\0\0\x40\x03", 4); +- +- return true; +-} +- +-bool LoongArchAsmBackend::handleAddSubRelocations(const MCAsmLayout &Layout, +- const MCFragment &F, +- const MCFixup &Fixup, +- const MCValue &Target, +- uint64_t &FixedValue) const { +- std::pair FK; +- uint64_t FixedValueA, FixedValueB; +- const MCSymbol &SA = Target.getSymA()->getSymbol(); +- const MCSymbol &SB = Target.getSymB()->getSymbol(); +- +- bool force = !SA.isInSection() || !SB.isInSection(); +- if (!force) { +- const MCSection &SecA = SA.getSection(); +- const MCSection &SecB = SB.getSection(); +- +- // We need record relocation if SecA != SecB. Usually SecB is same as the +- // section of Fixup, which will be record the relocation as PCRel. If SecB +- // is not same as the section of Fixup, it will report error. Just return +- // false and then this work can be finished by handleFixup. +- if (&SecA != &SecB) +- return false; +- +- // In SecA == SecB case. If the linker relaxation is enabled, we need record +- // the ADD, SUB relocations. Otherwise the FixedValue has already been calc- +- // ulated out in evaluateFixup, return true and avoid record relocations. +- if (!STI.hasFeature(LoongArch::FeatureRelax)) +- return true; +- } +- +- switch (Fixup.getKind()) { +- case llvm::FK_Data_1: +- FK = getRelocPairForSize(8); +- break; +- case llvm::FK_Data_2: +- FK = getRelocPairForSize(16); +- break; +- case llvm::FK_Data_4: +- FK = getRelocPairForSize(32); +- break; +- case llvm::FK_Data_8: +- FK = getRelocPairForSize(64); +- break; +- case llvm::FK_Data_leb128: +- FK = getRelocPairForSize(128); +- break; +- default: +- llvm_unreachable("unsupported fixup size"); +- } +- MCValue A = MCValue::get(Target.getSymA(), nullptr, Target.getConstant()); +- MCValue B = MCValue::get(Target.getSymB()); +- auto FA = MCFixup::create(Fixup.getOffset(), nullptr, std::get<0>(FK)); +- auto FB = MCFixup::create(Fixup.getOffset(), nullptr, std::get<1>(FK)); +- auto &Asm = Layout.getAssembler(); +- Asm.getWriter().recordRelocation(Asm, Layout, &F, FA, A, FixedValueA); +- Asm.getWriter().recordRelocation(Asm, Layout, &F, FB, B, FixedValueB); +- FixedValue = FixedValueA - FixedValueB; +- return true; +-} +- +-std::unique_ptr +-LoongArchAsmBackend::createObjectTargetWriter() const { +- return createLoongArchELFObjectWriter( +- OSABI, Is64Bit, STI.hasFeature(LoongArch::FeatureRelax)); + } + + MCAsmBackend *llvm::createLoongArchAsmBackend(const Target &T, + const MCSubtargetInfo &STI, + const MCRegisterInfo &MRI, + const MCTargetOptions &Options) { +- const Triple &TT = STI.getTargetTriple(); +- uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS()); +- return new LoongArchAsmBackend(STI, OSABI, TT.isArch64Bit(), Options); ++ LoongArchABIInfo ABI = LoongArchABIInfo::computeTargetABI( ++ STI.getTargetTriple(), STI.getCPU(), Options); ++ return new LoongArchAsmBackend(STI, T, MRI, STI.getTargetTriple(), ++ STI.getCPU(), ABI.IsLPX32()); + } +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h +index 9d81781fc..aa56b9a25 100644 +--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h +@@ -1,4 +1,4 @@ +-//===-- LoongArchAsmBackend.h - LoongArch Assembler Backend ---*- C++ -*---===// ++//===-- LoongArchAsmBackend.h - LoongArch Asm Backend ------------------------------===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -9,93 +9,85 @@ + // This file defines the LoongArchAsmBackend class. + // + //===----------------------------------------------------------------------===// ++// + + #ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHASMBACKEND_H + #define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHASMBACKEND_H + +-#include "MCTargetDesc/LoongArchBaseInfo.h" + #include "MCTargetDesc/LoongArchFixupKinds.h" +-#include "MCTargetDesc/LoongArchMCTargetDesc.h" + #include "llvm/MC/MCAsmBackend.h" +-#include "llvm/MC/MCExpr.h" +-#include "llvm/MC/MCFixupKindInfo.h" +-#include "llvm/MC/MCSection.h" +-#include "llvm/MC/MCSubtargetInfo.h" ++#include "llvm/TargetParser/Triple.h" + + namespace llvm { + ++class MCAssembler; ++struct MCFixupKindInfo; ++class MCObjectWriter; ++class MCRegisterInfo; ++class MCSymbolELF; ++class Target; ++ + class LoongArchAsmBackend : public MCAsmBackend { + const MCSubtargetInfo &STI; +- uint8_t OSABI; +- bool Is64Bit; +- const MCTargetOptions &TargetOptions; +- DenseMap SecToAlignSym; ++ Triple TheTriple; ++ bool IsLPX32; + + public: +- LoongArchAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit, +- const MCTargetOptions &Options) +- : MCAsmBackend(llvm::endianness::little, +- LoongArch::fixup_loongarch_relax), +- STI(STI), OSABI(OSABI), Is64Bit(Is64Bit), TargetOptions(Options) {} +- ~LoongArchAsmBackend() override {} ++ LoongArchAsmBackend(const MCSubtargetInfo &STI, const Target &T, ++ const MCRegisterInfo &MRI, const Triple &TT, ++ StringRef CPU, bool LPX32) ++ : MCAsmBackend(llvm::endianness::little), STI(STI), TheTriple(TT), IsLPX32(LPX32) { ++ assert(TT.isLittleEndian()); ++ } + +- bool handleAddSubRelocations(const MCAsmLayout &Layout, const MCFragment &F, +- const MCFixup &Fixup, const MCValue &Target, +- uint64_t &FixedValue) const override; ++ std::unique_ptr ++ createObjectTargetWriter() const override; + + void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, + const MCValue &Target, MutableArrayRef Data, + uint64_t Value, bool IsResolved, + const MCSubtargetInfo *STI) const override; + +- // Return Size with extra Nop Bytes for alignment directive in code section. +- bool shouldInsertExtraNopBytesForCodeAlign(const MCAlignFragment &AF, +- unsigned &Size) override; +- +- // Insert target specific fixup type for alignment directive in code section. +- bool shouldInsertFixupForCodeAlign(MCAssembler &Asm, +- const MCAsmLayout &Layout, +- MCAlignFragment &AF) override; +- +- bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, +- const MCValue &Target, +- const MCSubtargetInfo *STI) override; +- +- bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, +- const MCRelaxableFragment *DF, +- const MCAsmLayout &Layout) const override { +- return false; +- } ++ std::optional getFixupKind(StringRef Name) const override; ++ const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; + + unsigned getNumFixupKinds() const override { + return LoongArch::NumTargetFixupKinds; + } + +- std::optional getFixupKind(StringRef Name) const override; +- +- const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; ++ /// @name Target Relaxation Interfaces ++ /// @{ + +- void relaxInstruction(MCInst &Inst, +- const MCSubtargetInfo &STI) const override {} ++ /// MayNeedRelaxation - Check whether the given instruction may need ++ /// relaxation. ++ /// ++ /// \param Inst - The instruction to test. ++ bool mayNeedRelaxation(const MCInst &Inst, ++ const MCSubtargetInfo &STI) const override { ++ return false; ++ } + +- std::pair relaxLEB128(MCLEBFragment &LF, MCAsmLayout &Layout, +- int64_t &Value) const override; ++ /// fixupNeedsRelaxation - Target specific predicate for whether a given ++ /// fixup requires the associated instruction to be relaxed. ++ bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, ++ const MCRelaxableFragment *DF, ++ const MCAsmLayout &Layout) const override { ++ // FIXME. ++ llvm_unreachable("RelaxInstruction() unimplemented"); ++ return false; ++ } + +- bool relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF, MCAsmLayout &Layout, +- bool &WasRelaxed) const override; +- bool relaxDwarfCFA(MCDwarfCallFrameFragment &DF, MCAsmLayout &Layout, +- bool &WasRelaxed) const override; ++ /// @} + + bool writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const override; + +- std::unique_ptr +- createObjectTargetWriter() const override; +- const MCTargetOptions &getTargetOptions() const { return TargetOptions; } +- DenseMap &getSecToAlignSym() { +- return SecToAlignSym; +- } +-}; +-} // end namespace llvm ++ bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, ++ const MCValue &Target, ++ const MCSubtargetInfo *STI) override; ++ ++}; // class LoongArchAsmBackend ++ ++} // namespace + +-#endif // LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHASMBACKEND_H ++#endif +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.cpp +deleted file mode 100644 +index 928adb03f..000000000 +--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.cpp ++++ /dev/null +@@ -1,102 +0,0 @@ +-//= LoongArchBaseInfo.cpp - Top level definitions for LoongArch MC -*- C++ -*-// +-// +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +-// +-//===----------------------------------------------------------------------===// +-// +-// This file implements helper functions for the LoongArch target useful for the +-// compiler back-end and the MC libraries. +-// +-//===----------------------------------------------------------------------===// +- +-#include "LoongArchBaseInfo.h" +-#include "llvm/ADT/ArrayRef.h" +-#include "llvm/MC/MCSubtargetInfo.h" +-#include "llvm/Support/raw_ostream.h" +-#include "llvm/TargetParser/Triple.h" +- +-namespace llvm { +- +-namespace LoongArchABI { +- +-ABI computeTargetABI(const Triple &TT, StringRef ABIName) { +- ABI ArgProvidedABI = getTargetABI(ABIName); +- bool Is64Bit = TT.isArch64Bit(); +- ABI TripleABI; +- +- // Figure out the ABI explicitly requested via the triple's environment type. +- switch (TT.getEnvironment()) { +- case llvm::Triple::EnvironmentType::GNUSF: +- TripleABI = Is64Bit ? LoongArchABI::ABI_LP64S : LoongArchABI::ABI_ILP32S; +- break; +- case llvm::Triple::EnvironmentType::GNUF32: +- TripleABI = Is64Bit ? LoongArchABI::ABI_LP64F : LoongArchABI::ABI_ILP32F; +- break; +- +- // Let the fallback case behave like {ILP32,LP64}D. +- case llvm::Triple::EnvironmentType::GNUF64: +- default: +- TripleABI = Is64Bit ? LoongArchABI::ABI_LP64D : LoongArchABI::ABI_ILP32D; +- break; +- } +- +- switch (ArgProvidedABI) { +- case LoongArchABI::ABI_Unknown: +- // Fallback to the triple-implied ABI if ABI name is not specified or +- // invalid. +- if (!ABIName.empty()) +- errs() << "'" << ABIName +- << "' is not a recognized ABI for this target, ignoring and using " +- "triple-implied ABI\n"; +- return TripleABI; +- +- case LoongArchABI::ABI_ILP32S: +- case LoongArchABI::ABI_ILP32F: +- case LoongArchABI::ABI_ILP32D: +- if (Is64Bit) { +- errs() << "32-bit ABIs are not supported for 64-bit targets, ignoring " +- "target-abi and using triple-implied ABI\n"; +- return TripleABI; +- } +- break; +- +- case LoongArchABI::ABI_LP64S: +- case LoongArchABI::ABI_LP64F: +- case LoongArchABI::ABI_LP64D: +- if (!Is64Bit) { +- errs() << "64-bit ABIs are not supported for 32-bit targets, ignoring " +- "target-abi and using triple-implied ABI\n"; +- return TripleABI; +- } +- break; +- } +- +- if (!ABIName.empty() && TT.hasEnvironment() && ArgProvidedABI != TripleABI) +- errs() << "warning: triple-implied ABI conflicts with provided target-abi '" +- << ABIName << "', using target-abi\n"; +- +- return ArgProvidedABI; +-} +- +-ABI getTargetABI(StringRef ABIName) { +- auto TargetABI = StringSwitch(ABIName) +- .Case("ilp32s", ABI_ILP32S) +- .Case("ilp32f", ABI_ILP32F) +- .Case("ilp32d", ABI_ILP32D) +- .Case("lp64s", ABI_LP64S) +- .Case("lp64f", ABI_LP64F) +- .Case("lp64d", ABI_LP64D) +- .Default(ABI_Unknown); +- return TargetABI; +-} +- +-// To avoid the BP value clobbered by a function call, we need to choose a +-// callee saved register to save the value. The `last` `S` register (s9) is +-// used for FP. So we choose the previous (s8) as BP. +-MCRegister getBPReg() { return LoongArch::R31; } +- +-} // end namespace LoongArchABI +- +-} // end namespace llvm +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h +index 0692cb92b..707333c18 100644 +--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h +@@ -1,4 +1,4 @@ +-//=- LoongArchBaseInfo.h - Top level definitions for LoongArch MC -*- C++ -*-=// ++//===-- LoongArchBaseInfo.h - Top level definitions for LoongArch MC ------*- C++ -*-===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -6,70 +6,123 @@ + // + //===----------------------------------------------------------------------===// + // +-// This file contains small standalone enum definitions and helper function +-// definitions for the LoongArch target useful for the compiler back-end and the +-// MC libraries. ++// This file contains small standalone helper functions and enum definitions for ++// the LoongArch target useful for the compiler back-end and the MC libraries. + // + //===----------------------------------------------------------------------===// + #ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHBASEINFO_H + #define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHBASEINFO_H + +-#include "MCTargetDesc/LoongArchMCTargetDesc.h" +-#include "llvm/ADT/StringRef.h" +-#include "llvm/ADT/StringSwitch.h" +-#include "llvm/MC/MCInstrDesc.h" +-#include "llvm/TargetParser/SubtargetFeature.h" ++#include "LoongArchFixupKinds.h" ++#include "LoongArchMCTargetDesc.h" ++#include "llvm/MC/MCExpr.h" ++#include "llvm/Support/DataTypes.h" ++#include "llvm/Support/ErrorHandling.h" + + namespace llvm { + +-// This namespace holds all of the target specific flags that instruction info +-// tracks. ++/// LoongArchII - This namespace holds all of the target specific flags that ++/// instruction info tracks. ++/// + namespace LoongArchII { +-enum { +- MO_None, +- MO_CALL, +- MO_CALL_PLT, +- MO_PCREL_HI, +- MO_PCREL_LO, +- MO_PCREL64_LO, +- MO_PCREL64_HI, +- MO_GOT_PC_HI, +- MO_GOT_PC_LO, +- MO_GOT_PC64_LO, +- MO_GOT_PC64_HI, +- MO_LE_HI, +- MO_LE_LO, +- MO_LE64_LO, +- MO_LE64_HI, +- MO_IE_PC_HI, +- MO_IE_PC_LO, +- MO_IE_PC64_LO, +- MO_IE_PC64_HI, +- MO_LD_PC_HI, +- MO_GD_PC_HI, +- MO_CALL36 +- // TODO: Add more flags. +-}; +-} // end namespace LoongArchII +- +-namespace LoongArchABI { +-enum ABI { +- ABI_ILP32S, +- ABI_ILP32F, +- ABI_ILP32D, +- ABI_LP64S, +- ABI_LP64F, +- ABI_LP64D, +- ABI_Unknown +-}; +- +-ABI computeTargetABI(const Triple &TT, StringRef ABIName); +-ABI getTargetABI(StringRef ABIName); +- +-// Returns the register used to hold the stack pointer after realignment. +-MCRegister getBPReg(); +-} // end namespace LoongArchABI +- +-} // end namespace llvm +- +-#endif // LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHBASEINFO_H ++ /// Target Operand Flag enum. ++ enum TOF { ++ //===------------------------------------------------------------------===// ++ // LoongArch Specific MachineOperand flags. ++ ++ MO_NO_FLAG, ++ ++ /// MO_ABS_XXX - Represents the hi or low part of an absolute symbol ++ /// address. ++ MO_ABS_HI, ++ MO_ABS_LO, ++ MO_ABS_HIGHER, ++ MO_ABS_HIGHEST, ++ ++ /// MO_PCREL_XXX - Represents the hi or low part of an pc relative symbol ++ /// address. ++ MO_PCREL_HI, ++ MO_PCREL_LO, ++ // with tmp reg ++ MO_PCREL_RRHI, ++ MO_PCREL_RRLO, ++ MO_PCREL_RRHIGHER, ++ MO_PCREL_RRHIGHEST, ++ ++ // LArch Tls gd and ld ++ MO_TLSGD_HI, ++ MO_TLSGD_LO, ++ // with tmp reg ++ MO_TLSGD_RRHI, ++ MO_TLSGD_RRLO, ++ MO_TLSGD_RRHIGHER, ++ MO_TLSGD_RRHIGHEST, ++ ++ // LArch thread tprel (ie/le) ++ // LArch Tls ie ++ MO_TLSIE_HI, ++ MO_TLSIE_LO, ++ // with tmp reg ++ MO_TLSIE_RRHI, ++ MO_TLSIE_RRLO, ++ MO_TLSIE_RRHIGHER, ++ MO_TLSIE_RRHIGHEST, ++ // LArch Tls le ++ MO_TLSLE_HI, ++ MO_TLSLE_LO, ++ MO_TLSLE_HIGHER, ++ MO_TLSLE_HIGHEST, ++ ++ // Loongarch got ++ MO_GOT_HI, ++ MO_GOT_LO, ++ // with tmp reg ++ MO_GOT_RRHI, ++ MO_GOT_RRLO, ++ MO_GOT_RRHIGHER, ++ MO_GOT_RRHIGHEST, ++ ++ MO_CALL_HI, ++ MO_CALL_LO, ++ }; ++ ++ enum { ++ //===------------------------------------------------------------------===// ++ // Instruction encodings. These are the standard/most common forms for ++ // LoongArch instructions. ++ // ++ ++ // Pseudo - This represents an instruction that is a pseudo instruction ++ // or one that has not been implemented yet. It is illegal to code generate ++ // it, but tolerated for intermediate implementation stages. ++ Pseudo = 0, ++ ++ /// FrmR - This form is for instructions of the format R. ++ FrmR = 1, ++ /// FrmI - This form is for instructions of the format I. ++ FrmI = 2, ++ /// FrmJ - This form is for instructions of the format J. ++ FrmJ = 3, ++ /// FrmFR - This form is for instructions of the format FR. ++ FrmFR = 4, ++ /// FrmFI - This form is for instructions of the format FI. ++ FrmFI = 5, ++ /// FrmOther - This form is for instructions that have no specific format. ++ FrmOther = 6, ++ ++ FormMask = 15, ++ /// IsCTI - Instruction is a Control Transfer Instruction. ++ IsCTI = 1 << 4, ++ /// HasForbiddenSlot - Instruction has a forbidden slot. ++ HasForbiddenSlot = 1 << 5, ++ /// IsPCRelativeLoad - A Load instruction with implicit source register ++ /// ($pc) with explicit offset and destination register ++ IsPCRelativeLoad = 1 << 6, ++ /// HasFCCRegOperand - Instruction uses an $fcc register. ++ HasFCCRegOperand = 1 << 7 ++ ++ }; ++} ++} ++ ++#endif +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp +index 1dec816f3..59dc7a4fd 100644 +--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp +@@ -1,4 +1,4 @@ +-//===-- LoongArchELFObjectWriter.cpp - LoongArch ELF Writer ---*- C++ -*---===// ++//===-- LoongArchELFObjectWriter.cpp - LoongArch ELF Writer -------------------------===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -8,95 +8,182 @@ + + #include "MCTargetDesc/LoongArchFixupKinds.h" + #include "MCTargetDesc/LoongArchMCTargetDesc.h" ++#include "llvm/ADT/STLExtras.h" + #include "llvm/BinaryFormat/ELF.h" + #include "llvm/MC/MCContext.h" + #include "llvm/MC/MCELFObjectWriter.h" + #include "llvm/MC/MCFixup.h" + #include "llvm/MC/MCObjectWriter.h" ++#include "llvm/MC/MCSymbolELF.h" ++#include "llvm/Support/Casting.h" ++#include "llvm/Support/Compiler.h" ++#include "llvm/Support/Debug.h" + #include "llvm/Support/ErrorHandling.h" ++#include "llvm/Support/MathExtras.h" ++#include "llvm/Support/raw_ostream.h" ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DEBUG_TYPE "loongarch-elf-object-writer" + + using namespace llvm; + + namespace { ++ + class LoongArchELFObjectWriter : public MCELFObjectTargetWriter { + public: +- LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit, bool EnableRelax); ++ LoongArchELFObjectWriter(uint8_t OSABI, bool HasRelocationAddend, bool Is64); + +- ~LoongArchELFObjectWriter() override; ++ ~LoongArchELFObjectWriter() override = default; + ++ unsigned getRelocType(MCContext &Ctx, const MCValue &Target, ++ const MCFixup &Fixup, bool IsPCRel) const override; + bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym, + unsigned Type) const override { +- return EnableRelax; ++ return true; + } +- +-protected: +- unsigned getRelocType(MCContext &Ctx, const MCValue &Target, +- const MCFixup &Fixup, bool IsPCRel) const override; +- bool EnableRelax; + }; +-} // end namespace + +-LoongArchELFObjectWriter::LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit, +- bool EnableRelax) +- : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_LOONGARCH, +- /*HasRelocationAddend=*/true), +- EnableRelax(EnableRelax) {} ++} // end anonymous namespace + +-LoongArchELFObjectWriter::~LoongArchELFObjectWriter() {} ++LoongArchELFObjectWriter::LoongArchELFObjectWriter(uint8_t OSABI, ++ bool HasRelocationAddend, bool Is64) ++ : MCELFObjectTargetWriter(Is64, OSABI, ELF::EM_LOONGARCH, HasRelocationAddend) {} + + unsigned LoongArchELFObjectWriter::getRelocType(MCContext &Ctx, +- const MCValue &Target, +- const MCFixup &Fixup, +- bool IsPCRel) const { +- // Determine the type of the relocation +- unsigned Kind = Fixup.getTargetKind(); ++ const MCValue &Target, ++ const MCFixup &Fixup, ++ bool IsPCRel) const { ++ // Determine the type of the relocation. ++ ///XXX:Reloc ++ unsigned Kind = (unsigned)Fixup.getKind(); + + if (Kind >= FirstLiteralRelocationKind) + return Kind - FirstLiteralRelocationKind; + + switch (Kind) { +- default: +- Ctx.reportError(Fixup.getLoc(), "Unsupported relocation type"); +- return ELF::R_LARCH_NONE; +- case FK_Data_1: +- Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported"); +- return ELF::R_LARCH_NONE; +- case FK_Data_2: +- Ctx.reportError(Fixup.getLoc(), "2-byte data relocations not supported"); +- return ELF::R_LARCH_NONE; +- case FK_Data_4: +- return IsPCRel ? ELF::R_LARCH_32_PCREL : ELF::R_LARCH_32; +- case FK_Data_8: +- return IsPCRel ? ELF::R_LARCH_64_PCREL : ELF::R_LARCH_64; +- case LoongArch::fixup_loongarch_b16: +- return ELF::R_LARCH_B16; +- case LoongArch::fixup_loongarch_b21: +- return ELF::R_LARCH_B21; +- case LoongArch::fixup_loongarch_b26: +- return ELF::R_LARCH_B26; +- case LoongArch::fixup_loongarch_abs_hi20: +- return ELF::R_LARCH_ABS_HI20; +- case LoongArch::fixup_loongarch_abs_lo12: +- return ELF::R_LARCH_ABS_LO12; +- case LoongArch::fixup_loongarch_abs64_lo20: +- return ELF::R_LARCH_ABS64_LO20; +- case LoongArch::fixup_loongarch_abs64_hi12: +- return ELF::R_LARCH_ABS64_HI12; +- case LoongArch::fixup_loongarch_tls_le_hi20: +- return ELF::R_LARCH_TLS_LE_HI20; +- case LoongArch::fixup_loongarch_tls_le_lo12: +- return ELF::R_LARCH_TLS_LE_LO12; +- case LoongArch::fixup_loongarch_tls_le64_lo20: +- return ELF::R_LARCH_TLS_LE64_LO20; +- case LoongArch::fixup_loongarch_tls_le64_hi12: +- return ELF::R_LARCH_TLS_LE64_HI12; +- case LoongArch::fixup_loongarch_call36: +- return ELF::R_LARCH_CALL36; +- // TODO: Handle more fixup-kinds. ++ default: ++ return ELF::R_LARCH_NONE; ++ //llvm_unreachable("invalid fixup kind!"); ++ case FK_Data_4: ++ case LoongArch::fixup_LARCH_32: ++ return ELF::R_LARCH_32; ++ case FK_GPRel_4: ++ case FK_Data_8: ++ case LoongArch::fixup_LARCH_64: ++ return ELF::R_LARCH_64; ++ case LoongArch::fixup_LARCH_NONE: ++ return ELF::R_LARCH_NONE; ++ case LoongArch::fixup_LARCH_RELATIVE: ++ return ELF::R_LARCH_RELATIVE; ++ case LoongArch::fixup_LARCH_COPY: ++ return ELF::R_LARCH_COPY; ++ case LoongArch::fixup_LARCH_JUMP_SLOT: ++ return ELF::R_LARCH_JUMP_SLOT; ++ case LoongArch::fixup_LARCH_TLS_DTPMOD32: ++ return ELF::R_LARCH_TLS_DTPMOD32; ++ case LoongArch::fixup_LARCH_TLS_DTPMOD64: ++ return ELF::R_LARCH_TLS_DTPMOD64; ++ case LoongArch::fixup_LARCH_TLS_DTPREL32: ++ return ELF::R_LARCH_TLS_DTPREL32; ++ case LoongArch::fixup_LARCH_TLS_DTPREL64: ++ return ELF::R_LARCH_TLS_DTPREL64; ++ case LoongArch::fixup_LARCH_TLS_TPREL32: ++ return ELF::R_LARCH_TLS_TPREL32; ++ case LoongArch::fixup_LARCH_TLS_TPREL64: ++ return ELF::R_LARCH_TLS_TPREL64; ++ case LoongArch::fixup_LARCH_IRELATIVE: ++ return ELF::R_LARCH_IRELATIVE; ++ case LoongArch::fixup_LARCH_MARK_LA: ++ return ELF::R_LARCH_MARK_LA; ++ case LoongArch::fixup_LARCH_MARK_PCREL: ++ return ELF::R_LARCH_MARK_PCREL; ++ case LoongArch::fixup_LARCH_SOP_PUSH_PCREL: ++ return ELF::R_LARCH_SOP_PUSH_PCREL; ++ case LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE: ++ return ELF::R_LARCH_SOP_PUSH_ABSOLUTE; ++ case LoongArch::fixup_LARCH_SOP_PUSH_DUP: ++ return ELF::R_LARCH_SOP_PUSH_DUP; ++ case LoongArch::fixup_LARCH_SOP_PUSH_GPREL: ++ return ELF::R_LARCH_SOP_PUSH_GPREL; ++ case LoongArch::fixup_LARCH_SOP_PUSH_TLS_TPREL: ++ return ELF::R_LARCH_SOP_PUSH_TLS_TPREL; ++ case LoongArch::fixup_LARCH_SOP_PUSH_TLS_GOT: ++ return ELF::R_LARCH_SOP_PUSH_TLS_GOT; ++ case LoongArch::fixup_LARCH_SOP_PUSH_TLS_GD: ++ return ELF::R_LARCH_SOP_PUSH_TLS_GD; ++ case LoongArch::fixup_LARCH_SOP_PUSH_PLT_PCREL: ++ return ELF::R_LARCH_SOP_PUSH_PLT_PCREL; ++ case LoongArch::fixup_LARCH_SOP_ASSERT: ++ return ELF::R_LARCH_SOP_ASSERT; ++ case LoongArch::fixup_LARCH_SOP_NOT: ++ return ELF::R_LARCH_SOP_NOT; ++ case LoongArch::fixup_LARCH_SOP_SUB: ++ return ELF::R_LARCH_SOP_SUB; ++ case LoongArch::fixup_LARCH_SOP_SL: ++ return ELF::R_LARCH_SOP_SL; ++ case LoongArch::fixup_LARCH_SOP_SR: ++ return ELF::R_LARCH_SOP_SR; ++ case LoongArch::fixup_LARCH_SOP_ADD: ++ return ELF::R_LARCH_SOP_ADD; ++ case LoongArch::fixup_LARCH_SOP_AND: ++ return ELF::R_LARCH_SOP_AND; ++ case LoongArch::fixup_LARCH_SOP_IF_ELSE: ++ return ELF::R_LARCH_SOP_IF_ELSE; ++ case LoongArch::fixup_LARCH_SOP_POP_32_S_10_5: ++ return ELF::R_LARCH_SOP_POP_32_S_10_5; ++ case LoongArch::fixup_LARCH_SOP_POP_32_U_10_12: ++ return ELF::R_LARCH_SOP_POP_32_U_10_12; ++ case LoongArch::fixup_LARCH_SOP_POP_32_S_10_12: ++ return ELF::R_LARCH_SOP_POP_32_S_10_12; ++ case LoongArch::fixup_LARCH_SOP_POP_32_S_10_16: ++ return ELF::R_LARCH_SOP_POP_32_S_10_16; ++ case LoongArch::fixup_LARCH_SOP_POP_32_S_10_16_S2: ++ return ELF::R_LARCH_SOP_POP_32_S_10_16_S2; ++ case LoongArch::fixup_LARCH_SOP_POP_32_S_5_20: ++ return ELF::R_LARCH_SOP_POP_32_S_5_20; ++ case LoongArch::fixup_LARCH_SOP_POP_32_S_0_5_10_16_S2: ++ return ELF::R_LARCH_SOP_POP_32_S_0_5_10_16_S2; ++ case LoongArch::fixup_LARCH_SOP_POP_32_S_0_10_10_16_S2: ++ return ELF::R_LARCH_SOP_POP_32_S_0_10_10_16_S2; ++ case LoongArch::fixup_LARCH_SOP_POP_32_U: ++ return ELF::R_LARCH_SOP_POP_32_U; ++ case LoongArch::fixup_LARCH_ADD8: ++ return ELF::R_LARCH_ADD8; ++ case LoongArch::fixup_LARCH_ADD16: ++ return ELF::R_LARCH_ADD16; ++ case LoongArch::fixup_LARCH_ADD24: ++ return ELF::R_LARCH_ADD24; ++ case LoongArch::fixup_LARCH_ADD32: ++ return ELF::R_LARCH_ADD32; ++ case LoongArch::fixup_LARCH_ADD64: ++ return ELF::R_LARCH_ADD64; ++ case LoongArch::fixup_LARCH_SUB8: ++ return ELF::R_LARCH_SUB8; ++ case LoongArch::fixup_LARCH_SUB16: ++ return ELF::R_LARCH_SUB16; ++ case LoongArch::fixup_LARCH_SUB24: ++ return ELF::R_LARCH_SUB24; ++ case LoongArch::fixup_LARCH_SUB32: ++ return ELF::R_LARCH_SUB32; ++ case LoongArch::fixup_LARCH_SUB64: ++ return ELF::R_LARCH_SUB64; ++ case LoongArch::fixup_LARCH_GNU_VTINHERIT: ++ return ELF::R_LARCH_GNU_VTINHERIT; ++ case LoongArch::fixup_LARCH_GNU_VTENTRY: ++ return ELF::R_LARCH_GNU_VTENTRY; + } + } + + std::unique_ptr +-llvm::createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit, bool Relax) { +- return std::make_unique(OSABI, Is64Bit, Relax); ++llvm::createLoongArchELFObjectWriter(const Triple &TT, bool IsLPX32) { ++ uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS()); ++ bool IsLP64 = TT.isArch64Bit() && !IsLPX32; ++ bool HasRelocationAddend = TT.isArch64Bit(); ++ return std::make_unique(OSABI, HasRelocationAddend, ++ IsLP64); + } +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFStreamer.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFStreamer.cpp +index a6e15e094..a74fee3f8 100644 +--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFStreamer.cpp ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFStreamer.cpp +@@ -1,92 +1,138 @@ +-//===-- LoongArchELFStreamer.cpp - LoongArch ELF Target Streamer Methods --===// ++//===-------- LoongArchELFStreamer.cpp - ELF Object Output ---------------------===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. + // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + // + //===----------------------------------------------------------------------===// +-// +-// This file provides LoongArch specific target streamer methods. +-// +-//===----------------------------------------------------------------------===// + + #include "LoongArchELFStreamer.h" +-#include "LoongArchAsmBackend.h" +-#include "LoongArchBaseInfo.h" ++#include "LoongArchFixupKinds.h" ++#include "LoongArchTargetStreamer.h" + #include "llvm/BinaryFormat/ELF.h" ++#include "llvm/MC/MCAsmBackend.h" + #include "llvm/MC/MCAssembler.h" + #include "llvm/MC/MCCodeEmitter.h" ++#include "llvm/MC/MCContext.h" ++#include "llvm/MC/MCDwarf.h" ++#include "llvm/MC/MCInst.h" + #include "llvm/MC/MCObjectWriter.h" ++#include "llvm/MC/MCSymbolELF.h" ++#include "llvm/MC/MCValue.h" ++#include "llvm/Support/Casting.h" + + using namespace llvm; + +-// This part is for ELF object output. +-LoongArchTargetELFStreamer::LoongArchTargetELFStreamer( +- MCStreamer &S, const MCSubtargetInfo &STI) +- : LoongArchTargetStreamer(S) { +- auto &MAB = static_cast( +- getStreamer().getAssembler().getBackend()); +- setTargetABI(LoongArchABI::computeTargetABI( +- STI.getTargetTriple(), MAB.getTargetOptions().getABIName())); ++static std::pair getRelocPairForSize(unsigned Size) { ++ switch (Size) { ++ default: ++ llvm_unreachable("unsupported fixup size"); ++ case 1: ++ return std::make_pair(LoongArch::fixup_LARCH_ADD8, ++ LoongArch::fixup_LARCH_SUB8); ++ case 2: ++ return std::make_pair(LoongArch::fixup_LARCH_ADD16, ++ LoongArch::fixup_LARCH_SUB16); ++ case 4: ++ return std::make_pair(LoongArch::fixup_LARCH_ADD32, ++ LoongArch::fixup_LARCH_SUB32); ++ case 8: ++ return std::make_pair(LoongArch::fixup_LARCH_ADD64, ++ LoongArch::fixup_LARCH_SUB64); ++ } + } + +-MCELFStreamer &LoongArchTargetELFStreamer::getStreamer() { +- return static_cast(Streamer); ++static bool requiresFixups(MCContext &C, const MCExpr *Value, ++ const MCExpr *&LHS, const MCExpr *&RHS, ++ LoongArchELFStreamer *MCS) { ++ const auto *MBE = dyn_cast(Value); ++ if (MBE == nullptr) ++ return false; ++ ++ MCValue E; ++ if (!Value->evaluateAsRelocatable(E, nullptr, nullptr)) ++ return false; ++ if (E.getSymA() == nullptr || E.getSymB() == nullptr) ++ return false; ++ ++ const auto &A = E.getSymA()->getSymbol(); ++ const auto &B = E.getSymB()->getSymbol(); ++ ++ if (A.getName().empty() && B.getName().empty()) ++ return false; ++ ++ if (!A.isInSection() && !B.isInSection() && ++ !A.getName().empty() && !B.getName().empty()) ++ return false; ++ ++ LHS = ++ MCBinaryExpr::create(MCBinaryExpr::Add, MCSymbolRefExpr::create(&A, C), ++ MCConstantExpr::create(E.getConstant(), C), C); ++ RHS = E.getSymB(); ++ ++ bool isCheckInstr = ++ StringSwitch(MCS->getCurrentSectionOnly()->getName()) ++ .Case(".debug_aranges", true) ++ .Default(false); ++ ++ return (A.isInSection() ++ ? (isCheckInstr ? A.getSection().hasInstructions() : true) ++ : !A.getName().empty()) || ++ (B.isInSection() ? B.getSection().hasInstructions() ++ : !B.getName().empty()); + } + +-void LoongArchTargetELFStreamer::finish() { +- LoongArchTargetStreamer::finish(); +- MCAssembler &MCA = getStreamer().getAssembler(); +- LoongArchABI::ABI ABI = getTargetABI(); +- +- // Figure out the e_flags. +- // +- // Bitness is already represented with the EI_CLASS byte in the current spec, +- // so here we only record the base ABI modifier. Also set the object file ABI +- // version to v1, as upstream LLVM cannot handle the previous stack-machine- +- // based relocs from day one. +- // +- // Refer to LoongArch ELF psABI v2.01 for details. +- unsigned EFlags = MCA.getELFHeaderEFlags(); +- EFlags |= ELF::EF_LOONGARCH_OBJABI_V1; +- switch (ABI) { +- case LoongArchABI::ABI_ILP32S: +- case LoongArchABI::ABI_LP64S: +- EFlags |= ELF::EF_LOONGARCH_ABI_SOFT_FLOAT; +- break; +- case LoongArchABI::ABI_ILP32F: +- case LoongArchABI::ABI_LP64F: +- EFlags |= ELF::EF_LOONGARCH_ABI_SINGLE_FLOAT; +- break; +- case LoongArchABI::ABI_ILP32D: +- case LoongArchABI::ABI_LP64D: +- EFlags |= ELF::EF_LOONGARCH_ABI_DOUBLE_FLOAT; +- break; +- case LoongArchABI::ABI_Unknown: +- llvm_unreachable("Improperly initialized target ABI"); ++LoongArchELFStreamer::LoongArchELFStreamer(MCContext &Context, ++ std::unique_ptr MAB, ++ std::unique_ptr OW, ++ std::unique_ptr Emitter) ++ : MCELFStreamer(Context, std::move(MAB), std::move(OW), ++ std::move(Emitter)) { + } +- MCA.setELFHeaderEFlags(EFlags); ++ ++void LoongArchELFStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { ++ Frame.Begin = getContext().createTempSymbol(); ++ MCELFStreamer::emitLabel(Frame.Begin); ++} ++ ++MCSymbol *LoongArchELFStreamer::emitCFILabel() { ++ MCSymbol *Label = getContext().createTempSymbol("cfi", true); ++ MCELFStreamer::emitLabel(Label); ++ return Label; ++} ++ ++void LoongArchELFStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { ++ Frame.End = getContext().createTempSymbol(); ++ MCELFStreamer::emitLabel(Frame.End); ++} ++ ++void LoongArchELFStreamer::emitValueImpl(const MCExpr *Value, unsigned Size, ++ SMLoc Loc) { ++ const MCExpr *A, *B; ++ if (!requiresFixups(getContext(), Value, A, B, this)) ++ return MCELFStreamer::emitValueImpl(Value, Size, Loc); ++ ++ MCStreamer::emitValueImpl(Value, Size, Loc); ++ ++ MCDataFragment *DF = getOrCreateDataFragment(); ++ flushPendingLabels(DF, DF->getContents().size()); ++ MCDwarfLineEntry::make(this, getCurrentSectionOnly()); ++ ++ unsigned Add, Sub; ++ std::tie(Add, Sub) = getRelocPairForSize(Size); ++ ++ DF->getFixups().push_back(MCFixup::create( ++ DF->getContents().size(), A, static_cast(Add), Loc)); ++ DF->getFixups().push_back(MCFixup::create( ++ DF->getContents().size(), B, static_cast(Sub), Loc)); ++ ++ DF->getContents().resize(DF->getContents().size() + Size, 0); + } + +-namespace { +-class LoongArchELFStreamer : public MCELFStreamer { +-public: +- LoongArchELFStreamer(MCContext &C, std::unique_ptr MAB, +- std::unique_ptr MOW, +- std::unique_ptr MCE) +- : MCELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE)) {} +-}; +-} // end namespace +- +-namespace llvm { +-MCELFStreamer *createLoongArchELFStreamer(MCContext &C, +- std::unique_ptr MAB, +- std::unique_ptr MOW, +- std::unique_ptr MCE, +- bool RelaxAll) { +- LoongArchELFStreamer *S = new LoongArchELFStreamer( +- C, std::move(MAB), std::move(MOW), std::move(MCE)); +- S->getAssembler().setRelaxAll(RelaxAll); +- return S; ++MCELFStreamer *llvm::createLoongArchELFStreamer( ++ MCContext &Context, std::unique_ptr MAB, ++ std::unique_ptr OW, std::unique_ptr Emitter, ++ bool RelaxAll) { ++ return new LoongArchELFStreamer(Context, std::move(MAB), std::move(OW), ++ std::move(Emitter)); + } +-} // end namespace llvm +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFStreamer.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFStreamer.h +index 220b54092..875cebcb7 100644 +--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFStreamer.h ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFStreamer.h +@@ -1,31 +1,53 @@ +-//==-- LoongArchELFStreamer.h - LoongArch ELF Target Streamer --*- C++ -*--===// ++//===- LoongArchELFStreamer.h - ELF Object Output --------------------*- C++ -*-===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. + // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + // + //===----------------------------------------------------------------------===// ++// ++// This is a custom MCELFStreamer which allows us to insert some hooks before ++// emitting data into an actual object file. ++// ++//===----------------------------------------------------------------------===// + + #ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHELFSTREAMER_H + #define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHELFSTREAMER_H + +-#include "LoongArchTargetStreamer.h" ++#include "llvm/ADT/SmallVector.h" + #include "llvm/MC/MCELFStreamer.h" ++#include + + namespace llvm { + +-class LoongArchTargetELFStreamer : public LoongArchTargetStreamer { ++class MCAsmBackend; ++class MCCodeEmitter; ++class MCContext; ++class MCSubtargetInfo; ++struct MCDwarfFrameInfo; ++ ++class LoongArchELFStreamer : public MCELFStreamer { ++ + public: +- MCELFStreamer &getStreamer(); +- LoongArchTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI); ++ LoongArchELFStreamer(MCContext &Context, std::unique_ptr MAB, ++ std::unique_ptr OW, ++ std::unique_ptr Emitter); ++ ++ /// Overriding these functions allows us to dismiss all labels. ++ void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override; + +- void finish() override; ++ // Overriding these functions allows us to avoid recording of these labels ++ // in emitLabel. ++ void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override; ++ void emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override; ++ MCSymbol *emitCFILabel() override; + }; + +-MCELFStreamer *createLoongArchELFStreamer(MCContext &C, +- std::unique_ptr MAB, +- std::unique_ptr MOW, +- std::unique_ptr MCE, +- bool RelaxAll); ++MCELFStreamer *createLoongArchELFStreamer(MCContext &Context, ++ std::unique_ptr MAB, ++ std::unique_ptr OW, ++ std::unique_ptr Emitter, ++ bool RelaxAll); + } // end namespace llvm +-#endif ++ ++#endif // LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHELFSTREAMER_H +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchFixupKinds.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchFixupKinds.h +index 0d19d2b0f..e0e1200d8 100644 +--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchFixupKinds.h ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchFixupKinds.h +@@ -1,4 +1,4 @@ +-//===- LoongArchFixupKinds.h - LoongArch Specific Fixup Entries -*- C++ -*-===// ++//===-- LoongArchFixupKinds.h - LoongArch Specific Fixup Entries ----------*- C++ -*-===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -9,113 +9,82 @@ + #ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHFIXUPKINDS_H + #define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHFIXUPKINDS_H + +-#include "llvm/BinaryFormat/ELF.h" + #include "llvm/MC/MCFixup.h" + +-#undef LoongArch +- + namespace llvm { + namespace LoongArch { +-// +-// This table *must* be in the same order of +-// MCFixupKindInfo Infos[LoongArch::NumTargetFixupKinds] in +-// LoongArchAsmBackend.cpp. +-// +-enum Fixups { +- // Define fixups can be handled by LoongArchAsmBackend::applyFixup. +- // 16-bit fixup corresponding to %b16(foo) for instructions like bne. +- fixup_loongarch_b16 = FirstTargetFixupKind, +- // 21-bit fixup corresponding to %b21(foo) for instructions like bnez. +- fixup_loongarch_b21, +- // 26-bit fixup corresponding to %b26(foo)/%plt(foo) for instructions b/bl. +- fixup_loongarch_b26, +- // 20-bit fixup corresponding to %abs_hi20(foo) for instruction lu12i.w. +- fixup_loongarch_abs_hi20, +- // 12-bit fixup corresponding to %abs_lo12(foo) for instruction ori. +- fixup_loongarch_abs_lo12, +- // 20-bit fixup corresponding to %abs64_lo20(foo) for instruction lu32i.d. +- fixup_loongarch_abs64_lo20, +- // 12-bit fixup corresponding to %abs_hi12(foo) for instruction lu52i.d. +- fixup_loongarch_abs64_hi12, +- // 20-bit fixup corresponding to %le_hi20(foo) for instruction lu12i.w. +- fixup_loongarch_tls_le_hi20, +- // 12-bit fixup corresponding to %le_lo12(foo) for instruction ori. +- fixup_loongarch_tls_le_lo12, +- // 20-bit fixup corresponding to %le64_lo20(foo) for instruction lu32i.d. +- fixup_loongarch_tls_le64_lo20, +- // 12-bit fixup corresponding to %le64_hi12(foo) for instruction lu52i.d. +- fixup_loongarch_tls_le64_hi12, +- // TODO: Add more fixup kind. ++ // Although most of the current fixup types reflect a unique relocation ++ // one can have multiple fixup types for a given relocation and thus need ++ // to be uniquely named. ++ // ++ // This table *must* be in the same order of ++ // MCFixupKindInfo Infos[LoongArch::NumTargetFixupKinds] ++ // in LoongArchAsmBackend.cpp. ++ // ++ enum Fixups { ++ // R_LARCH_NONE. ++ fixup_LARCH_NONE = FirstTargetFixupKind, ++ ++ // reloc_hint ++ fixup_LARCH_SOP_PUSH_ABSOLUTE, ++ fixup_LARCH_SOP_PUSH_PCREL, ++ fixup_LARCH_SOP_PUSH_GPREL, ++ fixup_LARCH_SOP_PUSH_TLS_TPREL, ++ fixup_LARCH_SOP_PUSH_TLS_GOT, ++ fixup_LARCH_SOP_PUSH_TLS_GD, ++ fixup_LARCH_SOP_PUSH_PLT_PCREL, ++ // fixup methods ++ fixup_LARCH_32, ++ fixup_LARCH_64, ++ fixup_LARCH_RELATIVE, ++ fixup_LARCH_COPY, ++ fixup_LARCH_JUMP_SLOT, ++ fixup_LARCH_TLS_DTPMOD32, ++ fixup_LARCH_TLS_DTPMOD64, ++ fixup_LARCH_TLS_DTPREL32, ++ fixup_LARCH_TLS_DTPREL64, ++ fixup_LARCH_TLS_TPREL32, ++ fixup_LARCH_TLS_TPREL64, ++ fixup_LARCH_IRELATIVE, ++ fixup_LARCH_MARK_LA, ++ fixup_LARCH_MARK_PCREL, ++ fixup_LARCH_SOP_PUSH_DUP, ++ fixup_LARCH_SOP_ASSERT, ++ fixup_LARCH_SOP_NOT, ++ fixup_LARCH_SOP_SUB, ++ fixup_LARCH_SOP_SL, ++ fixup_LARCH_SOP_SR, ++ fixup_LARCH_SOP_ADD, ++ fixup_LARCH_SOP_AND, ++ fixup_LARCH_SOP_IF_ELSE, ++ fixup_LARCH_SOP_POP_32_S_10_5, ++ fixup_LARCH_SOP_POP_32_U_10_12, ++ fixup_LARCH_SOP_POP_32_S_10_12, ++ fixup_LARCH_SOP_POP_32_S_10_16, ++ fixup_LARCH_SOP_POP_32_S_10_16_S2, ++ fixup_LARCH_SOP_POP_32_S_5_20, ++ fixup_LARCH_SOP_POP_32_S_0_5_10_16_S2, ++ fixup_LARCH_SOP_POP_32_S_0_10_10_16_S2, ++ fixup_LARCH_SOP_POP_32_U, ++ fixup_LARCH_ADD8, ++ fixup_LARCH_ADD16, ++ fixup_LARCH_ADD24, ++ fixup_LARCH_ADD32, ++ fixup_LARCH_ADD64, ++ fixup_LARCH_SUB8, ++ fixup_LARCH_SUB16, ++ fixup_LARCH_SUB24, ++ fixup_LARCH_SUB32, ++ fixup_LARCH_SUB64, ++ fixup_LARCH_GNU_VTINHERIT, ++ fixup_LARCH_GNU_VTENTRY, + +- // Used as a sentinel, must be the last of the fixup which can be handled by +- // LoongArchAsmBackend::applyFixup. +- fixup_loongarch_invalid, +- NumTargetFixupKinds = fixup_loongarch_invalid - FirstTargetFixupKind, ++ // Marker ++ LastTargetFixupKind, ++ NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind ++ }; ++} // namespace LoongArch ++} // namespace llvm + +- // Define fixups for force relocation as FirstLiteralRelocationKind+V +- // represents the relocation type with number V. +- // 20-bit fixup corresponding to %pc_hi20(foo) for instruction pcalau12i. +- fixup_loongarch_pcala_hi20 = +- FirstLiteralRelocationKind + ELF::R_LARCH_PCALA_HI20, +- // 12-bit fixup corresponding to %pc_lo12(foo) for instructions like addi.w/d. +- fixup_loongarch_pcala_lo12, +- // 20-bit fixup corresponding to %pc64_lo20(foo) for instruction lu32i.d. +- fixup_loongarch_pcala64_lo20, +- // 12-bit fixup corresponding to %pc64_hi12(foo) for instruction lu52i.d. +- fixup_loongarch_pcala64_hi12, +- // 20-bit fixup corresponding to %got_pc_hi20(foo) for instruction pcalau12i. +- fixup_loongarch_got_pc_hi20, +- // 12-bit fixup corresponding to %got_pc_lo12(foo) for instructions +- // ld.w/ld.d/add.d. +- fixup_loongarch_got_pc_lo12, +- // 20-bit fixup corresponding to %got64_pc_lo20(foo) for instruction lu32i.d. +- fixup_loongarch_got64_pc_lo20, +- // 12-bit fixup corresponding to %got64_pc_hi12(foo) for instruction lu52i.d. +- fixup_loongarch_got64_pc_hi12, +- // 20-bit fixup corresponding to %got_hi20(foo) for instruction lu12i.w. +- fixup_loongarch_got_hi20, +- // 12-bit fixup corresponding to %got_lo12(foo) for instruction ori. +- fixup_loongarch_got_lo12, +- // 20-bit fixup corresponding to %got64_lo20(foo) for instruction lu32i.d. +- fixup_loongarch_got64_lo20, +- // 12-bit fixup corresponding to %got64_hi12(foo) for instruction lu52i.d. +- fixup_loongarch_got64_hi12, +- // Skip R_LARCH_TLS_LE_*. +- // 20-bit fixup corresponding to %ie_pc_hi20(foo) for instruction pcalau12i. +- fixup_loongarch_tls_ie_pc_hi20 = +- FirstLiteralRelocationKind + ELF::R_LARCH_TLS_IE_PC_HI20, +- // 12-bit fixup corresponding to %ie_pc_lo12(foo) for instructions +- // ld.w/ld.d/add.d. +- fixup_loongarch_tls_ie_pc_lo12, +- // 20-bit fixup corresponding to %ie64_pc_lo20(foo) for instruction lu32i.d. +- fixup_loongarch_tls_ie64_pc_lo20, +- // 12-bit fixup corresponding to %ie64_pc_hi12(foo) for instruction lu52i.d. +- fixup_loongarch_tls_ie64_pc_hi12, +- // 20-bit fixup corresponding to %ie_hi20(foo) for instruction lu12i.w. +- fixup_loongarch_tls_ie_hi20, +- // 12-bit fixup corresponding to %ie_lo12(foo) for instruction ori. +- fixup_loongarch_tls_ie_lo12, +- // 20-bit fixup corresponding to %ie64_lo20(foo) for instruction lu32i.d. +- fixup_loongarch_tls_ie64_lo20, +- // 12-bit fixup corresponding to %ie64_hi12(foo) for instruction lu52i.d. +- fixup_loongarch_tls_ie64_hi12, +- // 20-bit fixup corresponding to %ld_pc_hi20(foo) for instruction pcalau12i. +- fixup_loongarch_tls_ld_pc_hi20, +- // 20-bit fixup corresponding to %ld_hi20(foo) for instruction lu12i.w. +- fixup_loongarch_tls_ld_hi20, +- // 20-bit fixup corresponding to %gd_pc_hi20(foo) for instruction pcalau12i. +- fixup_loongarch_tls_gd_pc_hi20, +- // 20-bit fixup corresponding to %gd_hi20(foo) for instruction lu12i.w. +- fixup_loongarch_tls_gd_hi20, +- // Generate an R_LARCH_RELAX which indicates the linker may relax here. +- fixup_loongarch_relax = FirstLiteralRelocationKind + ELF::R_LARCH_RELAX, +- // Generate an R_LARCH_ALIGN which indicates the linker may fixup align here. +- fixup_loongarch_align = FirstLiteralRelocationKind + ELF::R_LARCH_ALIGN, +- // 36-bit fixup corresponding to %call36(foo) for a pair instructions: +- // pcaddu18i+jirl. +- fixup_loongarch_call36 = FirstLiteralRelocationKind + ELF::R_LARCH_CALL36, +-}; +-} // end namespace LoongArch +-} // end namespace llvm + + #endif +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.cpp +index cb2521db5..90716a646 100644 +--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.cpp ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.cpp +@@ -1,4 +1,4 @@ +-//===- LoongArchInstPrinter.cpp - Convert LoongArch MCInst to asm syntax --===// ++//===-- LoongArchInstPrinter.cpp - Convert LoongArch MCInst to assembly syntax ------===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -11,84 +11,266 @@ + //===----------------------------------------------------------------------===// + + #include "LoongArchInstPrinter.h" +-#include "LoongArchBaseInfo.h" +-#include "LoongArchMCTargetDesc.h" +-#include "llvm/MC/MCAsmInfo.h" ++#include "MCTargetDesc/LoongArchMCExpr.h" ++#include "LoongArchInstrInfo.h" ++#include "MCTargetDesc/LoongArchMCTargetDesc.h" ++#include "llvm/ADT/StringExtras.h" ++#include "llvm/MC/MCExpr.h" + #include "llvm/MC/MCInst.h" +-#include "llvm/MC/MCRegisterInfo.h" +-#include "llvm/MC/MCSubtargetInfo.h" ++#include "llvm/MC/MCInstrInfo.h" + #include "llvm/MC/MCSymbol.h" +-#include "llvm/Support/CommandLine.h" ++#include "llvm/Support/ErrorHandling.h" ++#include "llvm/Support/raw_ostream.h" + using namespace llvm; + +-#define DEBUG_TYPE "loongarch-asm-printer" ++#define DEBUG_TYPE "asm-printer" + +-// Include the auto-generated portion of the assembly writer. + #define PRINT_ALIAS_INSTR + #include "LoongArchGenAsmWriter.inc" + +-static cl::opt +- NumericReg("loongarch-numeric-reg", +- cl::desc("Print numeric register names rather than the ABI " +- "names (such as $r0 instead of $zero)"), +- cl::init(false), cl::Hidden); +- +-// The command-line flag above is used by llvm-mc and llc. It can be used by +-// `llvm-objdump`, but we override the value here to handle options passed to +-// `llvm-objdump` with `-M` (which matches GNU objdump). There did not seem to +-// be an easier way to allow these options in all these tools, without doing it +-// this way. +-bool LoongArchInstPrinter::applyTargetSpecificCLOption(StringRef Opt) { +- if (Opt == "numeric") { +- NumericReg = true; +- return true; ++template ++static bool isReg(const MCInst &MI, unsigned OpNo) { ++ assert(MI.getOperand(OpNo).isReg() && "Register operand expected."); ++ return MI.getOperand(OpNo).getReg() == R; ++} ++ ++const char* LoongArch::LoongArchFCCToString(LoongArch::CondCode CC) { ++ switch (CC) { ++ case FCOND_T: ++ case FCOND_F: return "caf"; ++ case FCOND_OR: ++ case FCOND_UN: return "cun"; ++ case FCOND_UNE: ++ case FCOND_OEQ: return "ceq"; ++ case FCOND_ONE: ++ case FCOND_UEQ: return "cueq"; ++ case FCOND_UGE: ++ case FCOND_OLT: return "clt"; ++ case FCOND_OGE: ++ case FCOND_ULT: return "cult"; ++ case FCOND_UGT: ++ case FCOND_OLE: return "cle"; ++ case FCOND_OGT: ++ case FCOND_ULE: return "cule"; ++ case FCOND_ST: ++ case FCOND_SF: return "saf"; ++ case FCOND_GLE: ++ case FCOND_NGLE:return "sun"; ++ case FCOND_SEQ: return "seq"; ++ case FCOND_SNE: return "sne"; ++ case FCOND_GL: ++ case FCOND_NGL: return "sueq"; ++ case FCOND_NLT: ++ case FCOND_LT: return "slt"; ++ case FCOND_GE: ++ case FCOND_NGE: return "sult"; ++ case FCOND_NLE: ++ case FCOND_LE: return "sle"; ++ case FCOND_GT: ++ case FCOND_NGT: return "sule"; ++ case FCOND_CNE: return "cne"; ++ case FCOND_COR: return "cor"; ++ case FCOND_SOR: return "sor"; ++ case FCOND_CUNE: return "cune"; ++ case FCOND_SUNE: return "sune"; + } ++ llvm_unreachable("Impossible condition code!"); ++} + +- return false; ++void LoongArchInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) const { ++ OS << '$' << StringRef(getRegisterName(Reg)).lower(); + } + + void LoongArchInstPrinter::printInst(const MCInst *MI, uint64_t Address, + StringRef Annot, + const MCSubtargetInfo &STI, + raw_ostream &O) { +- if (!printAliasInstr(MI, Address, STI, O)) +- printInstruction(MI, Address, STI, O); +- printAnnotation(O, Annot); +-} ++ switch (MI->getOpcode()) { ++ default: ++ break; ++ case LoongArch::PCADDU12I_ri: ++ case LoongArch::PCADDU12I_rii: ++ case LoongArch::LU12I_W_ri: ++ printLoadAddr(MI, O); ++ return; ++ case LoongArch::PCADDU12I_ri_large: ++ printLoadAddrLarge(MI, O); ++ return; ++ case LoongArch::ADD_D_rrr: ++ case LoongArch::LDX_D_rrr: ++ case LoongArch::ADDI_D_rri: ++ case LoongArch::ADDI_D_rrii: ++ case LoongArch::LD_D_rri: ++ case LoongArch::LD_D_rrii: ++ case LoongArch::ORI_rri: ++ case LoongArch::ORI_rrii: ++ case LoongArch::LU32I_D_ri: ++ case LoongArch::LU32I_D_rii: ++ case LoongArch::LU52I_D_rri: ++ case LoongArch::LU52I_D_rrii: ++ O << "\t# la expanded slot"; ++ return; ++ } + +-void LoongArchInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) const { +- O << '$' << getRegisterName(Reg); ++ // Try to print any aliases first. ++ if (!printAliasInstr(MI, Address, O) && !printAlias(*MI, O)) ++ printInstruction(MI, Address, O); ++ printAnnotation(O, Annot); + } + + void LoongArchInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, +- const MCSubtargetInfo &STI, +- raw_ostream &O) { +- const MCOperand &MO = MI->getOperand(OpNo); ++ raw_ostream &O) { ++ const MCOperand &Op = MI->getOperand(OpNo); ++ if (Op.isReg()) { ++ printRegName(O, Op.getReg()); ++ return; ++ } + +- if (MO.isReg()) { +- printRegName(O, MO.getReg()); ++ if (Op.isImm()) { ++ O << formatImm(Op.getImm()); + return; + } + ++ assert(Op.isExpr() && "unknown operand kind in printOperand"); ++ Op.getExpr()->print(O, &MAI, true); ++} ++ ++template ++void LoongArchInstPrinter::printUImm(const MCInst *MI, int opNum, raw_ostream &O) { ++ const MCOperand &MO = MI->getOperand(opNum); + if (MO.isImm()) { +- O << MO.getImm(); ++ uint64_t Imm = MO.getImm(); ++ Imm -= Offset; ++ Imm &= (1 << Bits) - 1; ++ Imm += Offset; ++ O << formatImm(Imm); + return; + } + +- assert(MO.isExpr() && "Unknown operand kind in printOperand"); +- MO.getExpr()->print(O, &MAI); ++ printOperand(MI, opNum, O); + } + +-void LoongArchInstPrinter::printAtomicMemOp(const MCInst *MI, unsigned OpNo, +- const MCSubtargetInfo &STI, ++void LoongArchInstPrinter:: ++printMemOperand(const MCInst *MI, int opNum, raw_ostream &O) { ++ // Load/Store memory operands -- $reg, imm ++ printOperand(MI, opNum, O); ++ O << ", "; ++ printOperand(MI, opNum+1, O); ++} ++ ++void LoongArchInstPrinter::printAMemOperand(const MCInst *MI, int opNum, + raw_ostream &O) { +- const MCOperand &MO = MI->getOperand(OpNo); +- assert(MO.isReg() && "printAtomicMemOp can only print register operands"); +- printRegName(O, MO.getReg()); ++ // AM* instruction memory operand: "rj, 0" ++ printRegName(O, MI->getOperand(opNum).getReg()); ++ O << ", 0"; ++} ++ ++void LoongArchInstPrinter:: ++printMemOperandEA(const MCInst *MI, int opNum, raw_ostream &O) { ++ // when using stack locations for not load/store instructions ++ // print the same way as all normal 3 operand instructions. ++ printOperand(MI, opNum, O); ++ O << ", "; ++ printOperand(MI, opNum+1, O); + } + +-const char *LoongArchInstPrinter::getRegisterName(MCRegister Reg) { +- // Default print reg alias name +- return getRegisterName(Reg, NumericReg ? LoongArch::NoRegAltName +- : LoongArch::RegAliasName); ++void LoongArchInstPrinter:: ++printFCCOperand(const MCInst *MI, int opNum, raw_ostream &O) { ++ const MCOperand& MO = MI->getOperand(opNum); ++ O << LoongArchFCCToString((LoongArch::CondCode)MO.getImm()); ++} ++ ++bool LoongArchInstPrinter::printAlias(const char *Str, const MCInst &MI, ++ unsigned OpNo, raw_ostream &OS) { ++ OS << "\t" << Str << "\t"; ++ if(MI.getOpcode() == LoongArch::JIRL) { ++ printOperand(&MI, OpNo, OS); ++ OS << "@plt"; ++ }else ++ printOperand(&MI, OpNo, OS); ++ return true; ++} ++ ++bool LoongArchInstPrinter::printAlias(const char *Str, const MCInst &MI, ++ unsigned OpNo0, unsigned OpNo1, ++ raw_ostream &OS) { ++ printAlias(Str, MI, OpNo0, OS); ++ OS << ", "; ++ printOperand(&MI, OpNo1, OS); ++ return true; ++} ++ ++bool LoongArchInstPrinter::printAlias(const MCInst &MI, raw_ostream &OS) { ++ switch (MI.getOpcode()) { ++ case LoongArch::OR: ++ // or $r0, $r1, $zero => move $r0, $r1 ++ return isReg(MI, 2) && printAlias("move", MI, 0, 1, OS); ++ default: return false; ++ } ++} ++ ++void LoongArchInstPrinter:: ++printRegisterList(const MCInst *MI, int opNum, raw_ostream &O) { ++ // - 2 because register List is always first operand of instruction and it is ++ // always followed by memory operand (base + offset). ++ for (int i = opNum, e = MI->getNumOperands() - 2; i != e; ++i) { ++ if (i != opNum) ++ O << ", "; ++ printRegName(O, MI->getOperand(i).getReg()); ++ } ++} ++ ++void LoongArchInstPrinter:: ++printLoadAddr(const MCInst *MI, raw_ostream &O) { ++ const MCOperand &Op = MI->getOperand(1); ++ const MCExpr *Expr = Op.getExpr(); ++ const LoongArchMCExpr *LoongArchExpr = cast(Expr); ++ switch (LoongArchExpr->getKind()) { ++ default: ++ llvm_unreachable("invalid handled!"); ++ return; ++ case LoongArchMCExpr::MEK_ABS_HI: ++ O << "\tla.abs\t"; ++ break; ++ case LoongArchMCExpr::MEK_GOT_HI: ++ O << "\tla.got\t"; ++ break; ++ case LoongArchMCExpr::MEK_PCREL_HI: ++ O << "\tla.pcrel\t"; ++ break; ++ case LoongArchMCExpr::MEK_TLSGD_HI: ++ O << "\tla.tls.gd\t"; ++ break; ++ case LoongArchMCExpr::MEK_TLSIE_HI: ++ O << "\tla.tls.ie\t"; ++ break; ++ case LoongArchMCExpr::MEK_TLSLE_HI: ++ O << "\tla.tls.le\t"; ++ break; ++ } ++ printRegName(O, MI->getOperand(0).getReg()); ++ O << ", "; ++ Expr->print(O, nullptr); ++ return; ++} ++ ++void LoongArchInstPrinter::printLoadAddrLarge(const MCInst *MI, ++ raw_ostream &O) { ++ const MCOperand &Op = MI->getOperand(2); ++ const MCExpr *Expr = Op.getExpr(); ++ const LoongArchMCExpr *LoongArchExpr = cast(Expr); ++ switch (LoongArchExpr->getKind()) { ++ default: ++ llvm_unreachable("invalid handled!"); ++ return; ++ case LoongArchMCExpr::MEK_PCREL_RRHI: ++ O << "\tla.local\t"; ++ break; ++ } ++ printRegName(O, MI->getOperand(0).getReg()); ++ O << ", "; ++ printRegName(O, MI->getOperand(1).getReg()); ++ O << ", "; ++ Expr->print(O, nullptr); ++ return; + } +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.h +index 4e6092bfc..c294fecfa 100644 +--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.h ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.h +@@ -1,4 +1,4 @@ +-//===-- LoongArchInstPrinter.h - Convert LoongArch MCInst to asm syntax ---===// ++//=== LoongArchInstPrinter.h - Convert LoongArch MCInst to assembly syntax -*- C++ -*-==// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -10,44 +10,111 @@ + // + //===----------------------------------------------------------------------===// + +-#ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHINSTPRINTER_H +-#define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHINSTPRINTER_H +- +-#include "MCTargetDesc/LoongArchMCTargetDesc.h" ++#ifndef LLVM_LIB_TARGET_LOONGARCH_INSTPRINTER_LOONGARCHINSTPRINTER_H ++#define LLVM_LIB_TARGET_LOONGARCH_INSTPRINTER_LOONGARCHINSTPRINTER_H + #include "llvm/MC/MCInstPrinter.h" + + namespace llvm { + ++namespace LoongArch { ++// LoongArch Branch Codes ++enum FPBranchCode { ++ BRANCH_F, ++ BRANCH_T, ++ BRANCH_INVALID ++}; ++ ++// LoongArch Condition Codes ++enum CondCode { ++ FCOND_F = 0x0, ++ FCOND_SF, ++ FCOND_OLT, ++ FCOND_LT, ++ FCOND_OEQ, ++ FCOND_SEQ, ++ FCOND_OLE, ++ FCOND_LE, ++ FCOND_UN, ++ FCOND_NGLE, ++ FCOND_ULT, ++ FCOND_NGE, ++ FCOND_UEQ, ++ FCOND_NGL, ++ FCOND_ULE, ++ FCOND_NGT, ++ FCOND_CNE, ++ FCOND_SNE, ++ FCOND_COR = 0x14, ++ FCOND_SOR = 0x15, ++ FCOND_CUNE = 0x18, ++ FCOND_SUNE = 0x19, ++ ++ // To be used with float branch False ++ // This conditions have the same mnemonic as the ++ // above ones, but are used with a branch False; ++ FCOND_T, ++ FCOND_UNE, ++ FCOND_ST, ++ FCOND_UGE, ++ FCOND_NLT, ++ FCOND_UGT, ++ FCOND_NLE, ++ FCOND_OR, ++ FCOND_GLE, ++ FCOND_OGE, ++ FCOND_GE, ++ FCOND_ONE, ++ FCOND_GL, ++ FCOND_OGT, ++ FCOND_GT ++}; ++ ++const char *LoongArchFCCToString(LoongArch::CondCode CC); ++} // end namespace LoongArch ++ + class LoongArchInstPrinter : public MCInstPrinter { + public: + LoongArchInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, +- const MCRegisterInfo &MRI) +- : MCInstPrinter(MAI, MII, MRI) {} ++ const MCRegisterInfo &MRI) ++ : MCInstPrinter(MAI, MII, MRI) {} + +- bool applyTargetSpecificCLOption(StringRef Opt) override; ++ // Autogenerated by tblgen. ++ std::pair getMnemonic(const MCInst *MI) override; ++ void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); ++ static const char *getRegisterName(MCRegister Reg); + ++ void printRegName(raw_ostream &OS, MCRegister Reg) const override; + void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, + const MCSubtargetInfo &STI, raw_ostream &O) override; +- void printRegName(raw_ostream &O, MCRegister Reg) const override; +- void printAtomicMemOp(const MCInst *MI, unsigned OpNo, +- const MCSubtargetInfo &STI, raw_ostream &O); + +- // Autogenerated by tblgen. +- std::pair getMnemonic(const MCInst *MI) override; +- void printInstruction(const MCInst *MI, uint64_t Address, +- const MCSubtargetInfo &STI, raw_ostream &O); +- bool printAliasInstr(const MCInst *MI, uint64_t Address, +- const MCSubtargetInfo &STI, raw_ostream &O); ++ bool printAliasInstr(const MCInst *MI, uint64_t Address, raw_ostream &OS); + void printCustomAliasOperand(const MCInst *MI, uint64_t Address, + unsigned OpIdx, unsigned PrintMethodIdx, +- const MCSubtargetInfo &STI, raw_ostream &O); +- static const char *getRegisterName(MCRegister Reg); +- static const char *getRegisterName(MCRegister Reg, unsigned AltIdx); ++ raw_ostream &O); + + private: +- void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, +- raw_ostream &O); ++ void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); ++ void printOperand(const MCInst *MI, uint64_t /*Address*/, unsigned OpNum, ++ raw_ostream &O) { ++ printOperand(MI, OpNum, O); ++ } ++ template ++ void printUImm(const MCInst *MI, int opNum, raw_ostream &O); ++ void printMemOperand(const MCInst *MI, int opNum, raw_ostream &O); ++ void printAMemOperand(const MCInst *MI, int opNum, raw_ostream &O); ++ void printMemOperandEA(const MCInst *MI, int opNum, raw_ostream &O); ++ void printFCCOperand(const MCInst *MI, int opNum, raw_ostream &O); ++ ++ bool printAlias(const char *Str, const MCInst &MI, unsigned OpNo, ++ raw_ostream &OS); ++ bool printAlias(const char *Str, const MCInst &MI, unsigned OpNo0, ++ unsigned OpNo1, raw_ostream &OS); ++ bool printAlias(const MCInst &MI, raw_ostream &OS); ++ void printSaveRestore(const MCInst *MI, raw_ostream &O); ++ void printRegisterList(const MCInst *MI, int opNum, raw_ostream &O); ++ void printLoadAddr(const MCInst *MI, raw_ostream &O); ++ void printLoadAddrLarge(const MCInst *MI, raw_ostream &O); + }; + } // end namespace llvm + +-#endif // LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHINSTPRINTER_H ++#endif +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp +index 9b7fccd00..df58ed247 100644 +--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp +@@ -1,4 +1,4 @@ +-//===-- LoongArchMCAsmInfo.cpp - LoongArch Asm properties ------*- C++ -*--===// ++//===-- LoongArchMCAsmInfo.cpp - LoongArch Asm Properties ---------------------------===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -11,24 +11,29 @@ + //===----------------------------------------------------------------------===// + + #include "LoongArchMCAsmInfo.h" +-#include "llvm/BinaryFormat/Dwarf.h" +-#include "llvm/MC/MCStreamer.h" + #include "llvm/TargetParser/Triple.h" + + using namespace llvm; + +-void LoongArchMCAsmInfo::anchor() {} ++void LoongArchMCAsmInfo::anchor() { } + +-LoongArchMCAsmInfo::LoongArchMCAsmInfo(const Triple &TT) { +- CodePointerSize = CalleeSaveStackSlotSize = TT.isArch64Bit() ? 8 : 4; +- AlignmentIsInBytes = false; +- Data8bitsDirective = "\t.byte\t"; +- Data16bitsDirective = "\t.half\t"; +- Data32bitsDirective = "\t.word\t"; +- Data64bitsDirective = "\t.dword\t"; +- ZeroDirective = "\t.space\t"; +- CommentString = "#"; ++LoongArchMCAsmInfo::LoongArchMCAsmInfo(const Triple &TheTriple, ++ const MCTargetOptions &Options) { ++ ++ if (TheTriple.isLoongArch64() ++ && TheTriple.getEnvironment() != Triple::GNUABILPX32) ++ CodePointerSize = CalleeSaveStackSlotSize = 8; ++ ++ AlignmentIsInBytes = false; ++ Data16bitsDirective = "\t.half\t"; ++ Data32bitsDirective = "\t.word\t"; ++ Data64bitsDirective = "\t.dword\t"; ++ CommentString = "#"; ++ ZeroDirective = "\t.space\t"; + SupportsDebugInformation = true; +- DwarfRegNumForCFI = true; + ExceptionsType = ExceptionHandling::DwarfCFI; ++ DwarfRegNumForCFI = true; ++ //HasLoongArchExpressions = true; ++ UseIntegratedAssembler = true; ++ UsesELFSectionDirectiveForBSS = true; + } +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.h +index ed1abbf46..244db58db 100644 +--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.h ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.h +@@ -1,4 +1,4 @@ +-//===-- LoongArchMCAsmInfo.h - LoongArch Asm Info --------------*- C++ -*--===// ++//===-- LoongArchMCAsmInfo.h - LoongArch Asm Info ------------------------*- C++ -*--===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -22,9 +22,10 @@ class LoongArchMCAsmInfo : public MCAsmInfoELF { + void anchor() override; + + public: +- explicit LoongArchMCAsmInfo(const Triple &TargetTriple); ++ explicit LoongArchMCAsmInfo(const Triple &TheTriple, ++ const MCTargetOptions &Options); + }; + +-} // end namespace llvm ++} // namespace llvm + +-#endif // LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCASMINFO_H ++#endif +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp +index 9ac0128f2..c141be386 100644 +--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp +@@ -1,4 +1,4 @@ +-//=- LoongArchMCCodeEmitter.cpp - Convert LoongArch code to machine code --===// ++//===-- LoongArchMCCodeEmitter.cpp - Convert LoongArch Code to Machine Code ---------===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -10,348 +10,1420 @@ + // + //===----------------------------------------------------------------------===// + +-#include "LoongArchFixupKinds.h" +-#include "MCTargetDesc/LoongArchBaseInfo.h" ++#include "LoongArchMCCodeEmitter.h" ++#include "MCTargetDesc/LoongArchFixupKinds.h" + #include "MCTargetDesc/LoongArchMCExpr.h" + #include "MCTargetDesc/LoongArchMCTargetDesc.h" +-#include "llvm/MC/MCCodeEmitter.h" ++#include "MCTargetDesc/LoongArchInstPrinter.h" ++#include "llvm/ADT/APFloat.h" ++#include "llvm/ADT/APInt.h" ++#include "llvm/ADT/SmallVector.h" + #include "llvm/MC/MCContext.h" +-#include "llvm/MC/MCInstBuilder.h" ++#include "llvm/MC/MCExpr.h" ++#include "llvm/MC/MCFixup.h" ++#include "llvm/MC/MCInst.h" ++#include "llvm/MC/MCInstrDesc.h" + #include "llvm/MC/MCInstrInfo.h" + #include "llvm/MC/MCRegisterInfo.h" + #include "llvm/MC/MCSubtargetInfo.h" + #include "llvm/Support/Casting.h" + #include "llvm/Support/EndianStream.h" ++#include "llvm/Support/ErrorHandling.h" ++#include "llvm/Support/raw_ostream.h" ++#include ++#include + + using namespace llvm; + + #define DEBUG_TYPE "mccodeemitter" + +-namespace { +-class LoongArchMCCodeEmitter : public MCCodeEmitter { +- LoongArchMCCodeEmitter(const LoongArchMCCodeEmitter &) = delete; +- void operator=(const LoongArchMCCodeEmitter &) = delete; +- MCContext &Ctx; +- MCInstrInfo const &MCII; +- +-public: +- LoongArchMCCodeEmitter(MCContext &ctx, MCInstrInfo const &MCII) +- : Ctx(ctx), MCII(MCII) {} +- +- ~LoongArchMCCodeEmitter() override {} +- +- void encodeInstruction(const MCInst &MI, SmallVectorImpl &CB, +- SmallVectorImpl &Fixups, +- const MCSubtargetInfo &STI) const override; +- +- template +- void expandToVectorLDI(const MCInst &MI, SmallVectorImpl &CB, +- SmallVectorImpl &Fixups, +- const MCSubtargetInfo &STI) const; +- +- /// TableGen'erated function for getting the binary encoding for an +- /// instruction. +- uint64_t getBinaryCodeForInstr(const MCInst &MI, +- SmallVectorImpl &Fixups, +- const MCSubtargetInfo &STI) const; +- +- /// Return binary encoding of operand. If the machine operand requires +- /// relocation, record the relocation and return zero. +- unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, +- SmallVectorImpl &Fixups, +- const MCSubtargetInfo &STI) const; +- +- /// Return binary encoding of an immediate operand specified by OpNo. +- /// The value returned is the value of the immediate minus 1. +- /// Note that this function is dedicated to specific immediate types, +- /// e.g. uimm2_plus1. +- unsigned getImmOpValueSub1(const MCInst &MI, unsigned OpNo, +- SmallVectorImpl &Fixups, +- const MCSubtargetInfo &STI) const; +- +- /// Return binary encoding of an immediate operand specified by OpNo. +- /// The value returned is the value of the immediate shifted right +- // arithmetically by N. +- /// Note that this function is dedicated to specific immediate types, +- /// e.g. simm14_lsl2, simm16_lsl2, simm21_lsl2 and simm26_lsl2. +- template +- unsigned getImmOpValueAsr(const MCInst &MI, unsigned OpNo, +- SmallVectorImpl &Fixups, +- const MCSubtargetInfo &STI) const { +- const MCOperand &MO = MI.getOperand(OpNo); +- if (MO.isImm()) { +- unsigned Res = MI.getOperand(OpNo).getImm(); +- assert((Res & ((1U << N) - 1U)) == 0 && "lowest N bits are non-zero"); +- return Res >> N; +- } +- return getExprOpValue(MI, MO, Fixups, STI); +- } ++#define GET_INSTRMAP_INFO ++#include "LoongArchGenInstrInfo.inc" ++#undef GET_INSTRMAP_INFO + +- unsigned getExprOpValue(const MCInst &MI, const MCOperand &MO, +- SmallVectorImpl &Fixups, +- const MCSubtargetInfo &STI) const; +-}; +-} // end namespace ++namespace llvm { + +-unsigned +-LoongArchMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO, +- SmallVectorImpl &Fixups, +- const MCSubtargetInfo &STI) const { ++MCCodeEmitter *createLoongArchMCCodeEmitter(const MCInstrInfo &MCII, ++ MCContext &Ctx) { ++ return new LoongArchMCCodeEmitter(MCII, Ctx); ++} + +- if (MO.isReg()) +- return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); ++} // end namespace llvm + +- if (MO.isImm()) +- return static_cast(MO.getImm()); ++void LoongArchMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const { ++ OS << (char)C; ++} + +- // MO must be an Expr. +- assert(MO.isExpr()); +- return getExprOpValue(MI, MO, Fixups, STI); ++/// encodeInstruction - Emit the instruction. ++/// Size the instruction with Desc.getSize(). ++void LoongArchMCCodeEmitter:: ++encodeInstruction(const MCInst &MI, ++ SmallVectorImpl &CB, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const ++{ ++ const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); ++ ++ // Get byte count of instruction ++ unsigned Size = Desc.getSize(); ++ if (!Size) ++ llvm_unreachable("Desc.getSize() returns 0"); ++ ++ switch (Size) { ++ default: ++ llvm_unreachable("Unhandled encodeInstruction length!"); ++ case 4: { ++ uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); ++ support::endian::write(CB, Bits, llvm::endianness::little); ++ ++ break; ++ } ++ } + } + +-unsigned +-LoongArchMCCodeEmitter::getImmOpValueSub1(const MCInst &MI, unsigned OpNo, +- SmallVectorImpl &Fixups, +- const MCSubtargetInfo &STI) const { +- return MI.getOperand(OpNo).getImm() - 1; ++/// getBranchTargetOpValue - Return binary encoding of the branch ++/// target operand. If the machine operand requires relocation, ++/// record the relocation and return zero. ++unsigned LoongArchMCCodeEmitter:: ++getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const { ++ const MCOperand &MO = MI.getOperand(OpNo); ++ ++ // If the destination is an immediate, divide by 4. ++ if (MO.isImm()) return MO.getImm() >> 2; ++ ++ assert(MO.isExpr() && ++ "getBranchTargetOpValue expects only expressions or immediates"); ++ ++ // XXX: brtarget reloc EncoderMethod. ++ const MCExpr *Expr = MO.getExpr(); ++ int64_t Value = 0x0; ++ const MCConstantExpr *tmpExpr = MCConstantExpr::create(Value, Ctx); ++ Fixups.push_back(MCFixup::create(0, Expr, ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_PCREL))); ++ switch (MI.getOpcode()) { ++ default: ++ llvm_unreachable("Unhandled reloc instruction!"); ++ break; ++ case LoongArch::BEQZ: ++ case LoongArch::BEQZ32: ++ case LoongArch::BNEZ: ++ case LoongArch::BNEZ32: ++ case LoongArch::BCEQZ: ++ case LoongArch::BCNEZ: ++ Fixups.push_back(MCFixup::create(0, tmpExpr, ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_0_5_10_16_S2))); ++ break; ++ case LoongArch::BEQ: ++ case LoongArch::BEQ32: ++ case LoongArch::BNE: ++ case LoongArch::BNE32: ++ case LoongArch::BLT: ++ case LoongArch::BLT32: ++ case LoongArch::BGE: ++ case LoongArch::BGE32: ++ case LoongArch::BLTU: ++ case LoongArch::BLTU32: ++ case LoongArch::BGEU: ++ case LoongArch::BGEU32: ++ Fixups.push_back(MCFixup::create(0, tmpExpr, ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_10_16_S2))); ++ break; ++ } ++ return 0; + } + +-unsigned +-LoongArchMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCOperand &MO, +- SmallVectorImpl &Fixups, +- const MCSubtargetInfo &STI) const { +- assert(MO.isExpr() && "getExprOpValue expects only expressions"); +- bool RelaxCandidate = false; +- bool EnableRelax = STI.hasFeature(LoongArch::FeatureRelax); ++/// getJumpTargetOpValue - Return binary encoding of the jump ++/// target operand. If the machine operand requires relocation, ++/// record the relocation and return zero. ++unsigned LoongArchMCCodeEmitter:: ++getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const { ++ const MCOperand &MO = MI.getOperand(OpNo); ++ // If the destination is an immediate, divide by 4. ++ if (MO.isImm()) return MO.getImm()>>2; ++ ++ assert(MO.isExpr() && ++ "getJumpTargetOpValue expects only expressions or an immediate"); ++ + const MCExpr *Expr = MO.getExpr(); ++ int64_t Value = 0x0; ++ const MCConstantExpr *tmpExpr = MCConstantExpr::create(Value, Ctx); ++ Fixups.push_back(MCFixup::create(0, Expr, ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_PLT_PCREL))); ++ if (MI.getOpcode() == LoongArch::JIRL) ++ Fixups.push_back(MCFixup::create(0, tmpExpr, ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_10_16_S2))); ++ else // B or BL ++ Fixups.push_back(MCFixup::create(0, tmpExpr, ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_0_10_10_16_S2))); ++ return 0; ++} ++ ++unsigned LoongArchMCCodeEmitter:: ++getSImm11Lsl1Encoding(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const { ++ const MCOperand &MO = MI.getOperand(OpNo); ++ if (MO.isImm()) { ++ unsigned Value = MO.getImm(); ++ return Value >> 1; ++ } ++ ++ return 0; ++} ++ ++unsigned LoongArchMCCodeEmitter:: ++getSImm10Lsl2Encoding(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const { ++ const MCOperand &MO = MI.getOperand(OpNo); ++ if (MO.isImm()) { ++ unsigned Value = MO.getImm(); ++ return Value >> 2; ++ } ++ ++ return 0; ++} ++ ++unsigned LoongArchMCCodeEmitter:: ++getSImm9Lsl3Encoding(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const { ++ const MCOperand &MO = MI.getOperand(OpNo); ++ if (MO.isImm()) { ++ unsigned Value = MO.getImm(); ++ return Value >> 3; ++ } ++ ++ return 0; ++} ++ ++unsigned LoongArchMCCodeEmitter:: ++getSImm8Lsl1Encoding(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const { ++ const MCOperand &MO = MI.getOperand(OpNo); ++ if (MO.isImm()) { ++ unsigned Value = MO.getImm(); ++ return Value >> 1; ++ } ++ ++ return 0; ++} ++ ++unsigned LoongArchMCCodeEmitter:: ++getSImm8Lsl2Encoding(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const { ++ const MCOperand &MO = MI.getOperand(OpNo); ++ if (MO.isImm()) { ++ unsigned Value = MO.getImm(); ++ return Value >> 2; ++ } ++ ++ return 0; ++} ++ ++unsigned LoongArchMCCodeEmitter:: ++getSImm8Lsl3Encoding(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const { ++ const MCOperand &MO = MI.getOperand(OpNo); ++ if (MO.isImm()) { ++ unsigned Value = MO.getImm(); ++ return Value >> 3; ++ } ++ ++ return 0; ++} ++ ++unsigned LoongArchMCCodeEmitter:: ++getExprOpValue(const MCInst &MI, const MCExpr *Expr, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const { ++ int64_t Res; ++ ++ if (Expr->evaluateAsAbsolute(Res)) ++ return Res; ++ + MCExpr::ExprKind Kind = Expr->getKind(); +- LoongArch::Fixups FixupKind = LoongArch::fixup_loongarch_invalid; ++ if (Kind == MCExpr::Constant) { ++ return cast(Expr)->getValue(); ++ } ++ ++ if (Kind == MCExpr::Binary) { ++ unsigned Res = getExprOpValue(MI, cast(Expr)->getLHS(), Fixups, STI); ++ Res += getExprOpValue(MI, cast(Expr)->getRHS(), Fixups, STI); ++ return Res; ++ } ++ + if (Kind == MCExpr::Target) { +- const LoongArchMCExpr *LAExpr = cast(Expr); ++ int64_t Value = 0x0; ++ const LoongArchMCExpr *LoongArchExpr = cast(Expr); ++ const MCExpr *BinExpr = nullptr; ++ const MCExpr *GOTExpr = nullptr; ++ const MCSymbol *GOTSymbol = Ctx.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); + +- RelaxCandidate = LAExpr->getRelaxHint(); +- switch (LAExpr->getKind()) { +- case LoongArchMCExpr::VK_LoongArch_None: +- case LoongArchMCExpr::VK_LoongArch_Invalid: ++ LoongArch::Fixups FixupKind = LoongArch::Fixups(0); ++ switch (LoongArchExpr->getKind()) { ++ case LoongArchMCExpr::MEK_None: ++ case LoongArchMCExpr::MEK_Special: + llvm_unreachable("Unhandled fixup kind!"); +- case LoongArchMCExpr::VK_LoongArch_B16: +- FixupKind = LoongArch::fixup_loongarch_b16; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); + break; +- case LoongArchMCExpr::VK_LoongArch_B21: +- FixupKind = LoongArch::fixup_loongarch_b21; ++ case LoongArchMCExpr::MEK_PLT: ++ Value = 0x0; ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PLT_PCREL; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ if (MI.getOpcode() == LoongArch::JIRL) ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_10_16_S2))); ++ else // B or BL ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_0_10_10_16_S2))); + break; +- case LoongArchMCExpr::VK_LoongArch_B26: +- case LoongArchMCExpr::VK_LoongArch_CALL: +- case LoongArchMCExpr::VK_LoongArch_CALL_PLT: +- FixupKind = LoongArch::fixup_loongarch_b26; ++ case LoongArchMCExpr::MEK_CALL_HI: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PLT_PCREL; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ ++ Value = 0x20000; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ Value = 0x12; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_5_20))); ++ + break; +- case LoongArchMCExpr::VK_LoongArch_ABS_HI20: +- FixupKind = LoongArch::fixup_loongarch_abs_hi20; ++ case LoongArchMCExpr::MEK_CALL_LO: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PLT_PCREL; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ ++ Value = 0x4; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x20004; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ Value = 0x12; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x12; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SUB))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_10_16_S2))); + break; +- case LoongArchMCExpr::VK_LoongArch_ABS_LO12: +- FixupKind = LoongArch::fixup_loongarch_abs_lo12; ++ case LoongArchMCExpr::MEK_GOT_HI: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ GOTExpr = MCSymbolRefExpr::create(GOTSymbol, ++ MCSymbolRefExpr::VK_None, Ctx); ++ Value = 0x800; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_GPREL; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ Value = 0xc; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_5_20))); + break; +- case LoongArchMCExpr::VK_LoongArch_ABS64_LO20: +- FixupKind = LoongArch::fixup_loongarch_abs64_lo20; ++ case LoongArchMCExpr::MEK_GOT_LO: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ GOTExpr = MCSymbolRefExpr::create(GOTSymbol, ++ MCSymbolRefExpr::VK_None, Ctx); ++ Value = 0x4; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_GPREL; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ Value = 0x804; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_GPREL; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ Value = 0xc; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0xc; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SUB))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_10_12))); + break; +- case LoongArchMCExpr::VK_LoongArch_ABS64_HI12: +- FixupKind = LoongArch::fixup_loongarch_abs64_hi12; ++ case LoongArchMCExpr::MEK_GOT_RRHI: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ GOTExpr = MCSymbolRefExpr::create(GOTSymbol, ++ MCSymbolRefExpr::VK_None, Ctx); ++ Fixups.push_back(MCFixup::create(0, GOTExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_GPREL; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ Value = 0x80000000; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_GPREL; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ Value = 0x20; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x20; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SUB))); ++ Value = 0x20; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x2c; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_5_20))); + break; +- case LoongArchMCExpr::VK_LoongArch_PCALA_HI20: +- FixupKind = LoongArch::fixup_loongarch_pcala_hi20; ++ case LoongArchMCExpr::MEK_GOT_RRLO: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ GOTExpr = MCSymbolRefExpr::create(GOTSymbol, ++ MCSymbolRefExpr::VK_None, Ctx); ++ Value = 0x4; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_GPREL; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ Value = 0x80000004; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_GPREL; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ Value = 0x20; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x20; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SUB))); ++ Value = 0xfff; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_AND))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_U_10_12))); + break; +- case LoongArchMCExpr::VK_LoongArch_PCALA_LO12: +- FixupKind = LoongArch::fixup_loongarch_pcala_lo12; ++ case LoongArchMCExpr::MEK_GOT_RRHIGHER: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ GOTExpr = MCSymbolRefExpr::create(GOTSymbol, ++ MCSymbolRefExpr::VK_None, Ctx); ++ Value = 0x80000008; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_GPREL; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ Value = 0xc; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x2c; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_5_20))); + break; +- case LoongArchMCExpr::VK_LoongArch_PCALA64_LO20: +- FixupKind = LoongArch::fixup_loongarch_pcala64_lo20; ++ case LoongArchMCExpr::MEK_GOT_RRHIGHEST: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ GOTExpr = MCSymbolRefExpr::create(GOTSymbol, ++ MCSymbolRefExpr::VK_None, Ctx); ++ Value = 0x8000000c; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_GPREL; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ Value = 0x34; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_10_12))); + break; +- case LoongArchMCExpr::VK_LoongArch_PCALA64_HI12: +- FixupKind = LoongArch::fixup_loongarch_pcala64_hi12; ++ case LoongArchMCExpr::MEK_ABS_HI: ++ FixupKind = LoongArch::fixup_LARCH_MARK_LA; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x20; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x2c; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_5_20))); + break; +- case LoongArchMCExpr::VK_LoongArch_GOT_PC_HI20: +- FixupKind = LoongArch::fixup_loongarch_got_pc_hi20; ++ case LoongArchMCExpr::MEK_ABS_LO: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0xfff; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_AND))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_U_10_12))); + break; +- case LoongArchMCExpr::VK_LoongArch_GOT_PC_LO12: +- FixupKind = LoongArch::fixup_loongarch_got_pc_lo12; ++ case LoongArchMCExpr::MEK_ABS_HIGHER: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0xc; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x2c; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_5_20))); + break; +- case LoongArchMCExpr::VK_LoongArch_GOT64_PC_LO20: +- FixupKind = LoongArch::fixup_loongarch_got64_pc_lo20; ++ case LoongArchMCExpr::MEK_ABS_HIGHEST: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x34; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_10_12))); + break; +- case LoongArchMCExpr::VK_LoongArch_GOT64_PC_HI12: +- FixupKind = LoongArch::fixup_loongarch_got64_pc_hi12; ++ case LoongArchMCExpr::MEK_PCREL_HI: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ Value = 0x800; ++ BinExpr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ Value = 0xc; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_5_20))); + break; +- case LoongArchMCExpr::VK_LoongArch_GOT_HI20: +- FixupKind = LoongArch::fixup_loongarch_got_hi20; ++ case LoongArchMCExpr::MEK_PCREL_LO: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ Value = 0x4; ++ BinExpr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ Value = 0x804; ++ BinExpr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ Value = 0xc; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0xc; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SUB))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_10_12))); + break; +- case LoongArchMCExpr::VK_LoongArch_GOT_LO12: +- FixupKind = LoongArch::fixup_loongarch_got_lo12; ++ case LoongArchMCExpr::MEK_PCREL_RRHI: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ Value = 0x80000000; ++ BinExpr = MCBinaryExpr::createAdd(LoongArchExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ Value = 0x20; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x20; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SUB))); ++ Value = 0x20; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x2c; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_5_20))); + break; +- case LoongArchMCExpr::VK_LoongArch_GOT64_LO20: +- FixupKind = LoongArch::fixup_loongarch_got64_lo20; ++ case LoongArchMCExpr::MEK_PCREL_RRLO: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ Value = 0x4; ++ BinExpr = MCBinaryExpr::createAdd(LoongArchExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ Value = 0x80000004; ++ BinExpr = MCBinaryExpr::createAdd(LoongArchExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ Value = 0x20; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x20; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SUB))); ++ Value = 0xfff; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_AND))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_U_10_12))); + break; +- case LoongArchMCExpr::VK_LoongArch_GOT64_HI12: +- FixupKind = LoongArch::fixup_loongarch_got64_hi12; ++ case LoongArchMCExpr::MEK_PCREL_RRHIGHER: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ Value = 0x80000008; ++ BinExpr = MCBinaryExpr::createAdd(LoongArchExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ Value = 0xc; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x2c; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_5_20))); + break; +- case LoongArchMCExpr::VK_LoongArch_TLS_LE_HI20: +- FixupKind = LoongArch::fixup_loongarch_tls_le_hi20; ++ case LoongArchMCExpr::MEK_PCREL_RRHIGHEST: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ Value = 0x8000000c; ++ BinExpr = MCBinaryExpr::createAdd(LoongArchExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ Value = 0x34; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_10_12))); + break; +- case LoongArchMCExpr::VK_LoongArch_TLS_LE_LO12: +- FixupKind = LoongArch::fixup_loongarch_tls_le_lo12; ++ case LoongArchMCExpr::MEK_TLSGD_HI: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ GOTExpr = MCSymbolRefExpr::create(GOTSymbol, ++ MCSymbolRefExpr::VK_None, Ctx); ++ Value = 0x800; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_TLS_GD; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ Value = 0xc; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_5_20))); + break; +- case LoongArchMCExpr::VK_LoongArch_TLS_LE64_LO20: +- FixupKind = LoongArch::fixup_loongarch_tls_le64_lo20; ++ case LoongArchMCExpr::MEK_TLSGD_LO: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ GOTExpr = MCSymbolRefExpr::create(GOTSymbol, ++ MCSymbolRefExpr::VK_None, Ctx); ++ Value = 0x4; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_TLS_GD; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ Value = 0x804; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_TLS_GD; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ Value = 0xc; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0xc; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SUB))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_10_12))); + break; +- case LoongArchMCExpr::VK_LoongArch_TLS_LE64_HI12: +- FixupKind = LoongArch::fixup_loongarch_tls_le64_hi12; ++ case LoongArchMCExpr::MEK_TLSGD_RRHI: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ GOTExpr = MCSymbolRefExpr::create(GOTSymbol, ++ MCSymbolRefExpr::VK_None, Ctx); ++ Fixups.push_back(MCFixup::create(0, GOTExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_TLS_GD; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ Value = 0x80000000; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_TLS_GD; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ Value = 0x20; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x20; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SUB))); ++ Value = 0x20; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x2c; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_5_20))); + break; +- case LoongArchMCExpr::VK_LoongArch_TLS_IE_PC_HI20: +- FixupKind = LoongArch::fixup_loongarch_tls_ie_pc_hi20; ++ case LoongArchMCExpr::MEK_TLSGD_RRLO: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ GOTExpr = MCSymbolRefExpr::create(GOTSymbol, ++ MCSymbolRefExpr::VK_None, Ctx); ++ Value = 0x4; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_TLS_GD; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ Value = 0x80000004; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_TLS_GD; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ Value = 0x20; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x20; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SUB))); ++ Value = 0xfff; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_AND))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_U_10_12))); + break; +- case LoongArchMCExpr::VK_LoongArch_TLS_IE_PC_LO12: +- FixupKind = LoongArch::fixup_loongarch_tls_ie_pc_lo12; ++ case LoongArchMCExpr::MEK_TLSGD_RRHIGHER: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ GOTExpr = MCSymbolRefExpr::create(GOTSymbol, ++ MCSymbolRefExpr::VK_None, Ctx); ++ Value = 0x80000008; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_TLS_GD; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ Value = 0xc; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x2c; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_5_20))); + break; +- case LoongArchMCExpr::VK_LoongArch_TLS_IE64_PC_LO20: +- FixupKind = LoongArch::fixup_loongarch_tls_ie64_pc_lo20; ++ case LoongArchMCExpr::MEK_TLSGD_RRHIGHEST: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ GOTExpr = MCSymbolRefExpr::create(GOTSymbol, ++ MCSymbolRefExpr::VK_None, Ctx); ++ Value = 0x8000000c; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_TLS_GD; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ Value = 0x34; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_10_12))); + break; +- case LoongArchMCExpr::VK_LoongArch_TLS_IE64_PC_HI12: +- FixupKind = LoongArch::fixup_loongarch_tls_ie64_pc_hi12; ++ case LoongArchMCExpr::MEK_TLSIE_HI: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ GOTExpr = MCSymbolRefExpr::create(GOTSymbol, ++ MCSymbolRefExpr::VK_None, Ctx); ++ Value = 0x800; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_TLS_GOT; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ Value = 0xc; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_5_20))); + break; +- case LoongArchMCExpr::VK_LoongArch_TLS_IE_HI20: +- FixupKind = LoongArch::fixup_loongarch_tls_ie_hi20; ++ case LoongArchMCExpr::MEK_TLSIE_LO: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ GOTExpr = MCSymbolRefExpr::create(GOTSymbol, ++ MCSymbolRefExpr::VK_None, Ctx); ++ Value = 0x4; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_TLS_GOT; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ Value = 0x804; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_TLS_GOT; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ Value = 0xc; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0xc; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SUB))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_10_12))); + break; +- case LoongArchMCExpr::VK_LoongArch_TLS_IE_LO12: +- FixupKind = LoongArch::fixup_loongarch_tls_ie_lo12; ++ case LoongArchMCExpr::MEK_TLSIE_RRHI: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ GOTExpr = MCSymbolRefExpr::create(GOTSymbol, ++ MCSymbolRefExpr::VK_None, Ctx); ++ Fixups.push_back(MCFixup::create(0, GOTExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_TLS_GOT; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ Value = 0x80000000; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_TLS_GOT; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ Value = 0x20; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x20; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SUB))); ++ Value = 0x20; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x2c; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_5_20))); + break; +- case LoongArchMCExpr::VK_LoongArch_TLS_IE64_LO20: +- FixupKind = LoongArch::fixup_loongarch_tls_ie64_lo20; ++ case LoongArchMCExpr::MEK_TLSIE_RRLO: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ GOTExpr = MCSymbolRefExpr::create(GOTSymbol, ++ MCSymbolRefExpr::VK_None, Ctx); ++ Value = 0x4; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_TLS_GOT; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ Value = 0x80000004; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_TLS_GOT; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ Value = 0x20; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x20; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SUB))); ++ Value = 0xfff; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_AND))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_U_10_12))); + break; +- case LoongArchMCExpr::VK_LoongArch_TLS_IE64_HI12: +- FixupKind = LoongArch::fixup_loongarch_tls_ie64_hi12; ++ case LoongArchMCExpr::MEK_TLSIE_RRHIGHER: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ GOTExpr = MCSymbolRefExpr::create(GOTSymbol, ++ MCSymbolRefExpr::VK_None, Ctx); ++ Value = 0x80000008; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_TLS_GOT; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ Value = 0xc; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x2c; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_5_20))); + break; +- case LoongArchMCExpr::VK_LoongArch_TLS_LD_PC_HI20: +- FixupKind = LoongArch::fixup_loongarch_tls_ld_pc_hi20; ++ case LoongArchMCExpr::MEK_TLSIE_RRHIGHEST: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_PCREL; ++ GOTExpr = MCSymbolRefExpr::create(GOTSymbol, ++ MCSymbolRefExpr::VK_None, Ctx); ++ Value = 0x8000000c; ++ BinExpr = MCBinaryExpr::createAdd(GOTExpr, MCConstantExpr::create(Value, Ctx), Ctx); ++ Fixups.push_back(MCFixup::create(0, BinExpr, MCFixupKind(FixupKind))); ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_TLS_GOT; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_ADD))); ++ Value = 0x34; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_10_12))); + break; +- case LoongArchMCExpr::VK_LoongArch_TLS_LD_HI20: +- FixupKind = LoongArch::fixup_loongarch_tls_ld_hi20; ++ case LoongArchMCExpr::MEK_TLSLE_HI: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_TLS_TPREL; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ ++ Value = 0x20; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x2c; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_5_20))); + break; +- case LoongArchMCExpr::VK_LoongArch_TLS_GD_PC_HI20: +- FixupKind = LoongArch::fixup_loongarch_tls_gd_pc_hi20; ++ case LoongArchMCExpr::MEK_TLSLE_LO: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_TLS_TPREL; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0xfff; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_AND))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_U_10_12))); + break; +- case LoongArchMCExpr::VK_LoongArch_TLS_GD_HI20: +- FixupKind = LoongArch::fixup_loongarch_tls_gd_hi20; ++ case LoongArchMCExpr::MEK_TLSLE_HIGHER: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_TLS_TPREL; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0xc; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SL))); ++ Value = 0x2c; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_5_20))); + break; +- case LoongArchMCExpr::VK_LoongArch_CALL36: +- FixupKind = LoongArch::fixup_loongarch_call36; ++ case LoongArchMCExpr::MEK_TLSLE_HIGHEST: ++ FixupKind = LoongArch::fixup_LARCH_SOP_PUSH_TLS_TPREL; ++ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); ++ Value = 0x34; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_PUSH_ABSOLUTE))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_SR))); ++ Value = 0x0; ++ Fixups.push_back(MCFixup::create(0, MCConstantExpr::create(Value, Ctx), ++ MCFixupKind(LoongArch::fixup_LARCH_SOP_POP_32_S_10_12))); + break; + } +- } else if (Kind == MCExpr::SymbolRef && +- cast(Expr)->getKind() == +- MCSymbolRefExpr::VK_None) { +- switch (MI.getOpcode()) { +- default: +- break; +- case LoongArch::BEQ: +- case LoongArch::BNE: +- case LoongArch::BLT: +- case LoongArch::BGE: +- case LoongArch::BLTU: +- case LoongArch::BGEU: +- FixupKind = LoongArch::fixup_loongarch_b16; +- break; +- case LoongArch::BEQZ: +- case LoongArch::BNEZ: +- case LoongArch::BCEQZ: +- case LoongArch::BCNEZ: +- FixupKind = LoongArch::fixup_loongarch_b21; +- break; +- case LoongArch::B: +- case LoongArch::BL: +- FixupKind = LoongArch::fixup_loongarch_b26; ++ return 0; ++ } ++ ++ if (Kind == MCExpr::SymbolRef) { ++ LoongArch::Fixups FixupKind = LoongArch::Fixups(0); ++ ++ switch(cast(Expr)->getKind()) { ++ default: llvm_unreachable("Unknown fixup kind!"); + break; + } ++ Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); ++ return 0; + } ++ return 0; ++} + +- assert(FixupKind != LoongArch::fixup_loongarch_invalid && +- "Unhandled expression!"); ++/// getMachineOpValue - Return binary encoding of operand. If the machine ++/// operand requires relocation, record the relocation and return zero. ++unsigned LoongArchMCCodeEmitter:: ++getMachineOpValue(const MCInst &MI, const MCOperand &MO, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const { ++ if (MO.isReg()) { ++ unsigned Reg = MO.getReg(); ++ unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); ++ return RegNo; ++ } else if (MO.isImm()) { ++ return static_cast(MO.getImm()); ++ } else if (MO.isDFPImm()) { ++ return static_cast(bit_cast(MO.getDFPImm())); ++ } ++ // MO must be an Expr. ++ assert(MO.isExpr()); ++ return getExprOpValue(MI, MO.getExpr(),Fixups, STI); ++} + +- Fixups.push_back( +- MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc())); ++/// Return binary encoding of memory related operand. ++/// If the offset operand requires relocation, record the relocation. ++template ++unsigned LoongArchMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const { ++ // Base register is encoded in bits 16-12, offset is encoded in bits 11-0. ++ assert(MI.getOperand(OpNo).isReg()); ++ unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 12; ++ unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); + +- // Emit an R_LARCH_RELAX if linker relaxation is enabled and LAExpr has relax +- // hint. +- if (EnableRelax && RelaxCandidate) { +- const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx); +- Fixups.push_back(MCFixup::create( +- 0, Dummy, MCFixupKind(LoongArch::fixup_loongarch_relax), MI.getLoc())); +- } ++ // Apply the scale factor if there is one. ++ OffBits >>= ShiftAmount; + +- return 0; ++ return (OffBits & 0xFFF) | RegBits; + } + +-template +-void LoongArchMCCodeEmitter::expandToVectorLDI( +- const MCInst &MI, SmallVectorImpl &CB, +- SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const { +- int64_t Imm = MI.getOperand(1).getImm() & 0x3FF; +- switch (MI.getOpcode()) { +- case LoongArch::PseudoVREPLI_B: +- case LoongArch::PseudoXVREPLI_B: +- break; +- case LoongArch::PseudoVREPLI_H: +- case LoongArch::PseudoXVREPLI_H: +- Imm |= 0x400; +- break; +- case LoongArch::PseudoVREPLI_W: +- case LoongArch::PseudoXVREPLI_W: +- Imm |= 0x800; +- break; +- case LoongArch::PseudoVREPLI_D: +- case LoongArch::PseudoXVREPLI_D: +- Imm |= 0xC00; +- break; +- } +- MCInst TmpInst = MCInstBuilder(Opc).addOperand(MI.getOperand(0)).addImm(Imm); +- uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); +- support::endian::write(CB, Binary, llvm::endianness::little); ++/// Return binary encoding of AM* memory related operand. ++unsigned ++LoongArchMCCodeEmitter::getAMemEncoding(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const { ++ // Base register is encoded in bits 16-12, bits 11-0 are not used. ++ assert(MI.getOperand(OpNo).isReg()); ++ unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) ++ << 12; ++ return RegBits; + } + +-void LoongArchMCCodeEmitter::encodeInstruction( +- const MCInst &MI, SmallVectorImpl &CB, +- SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const { +- const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); +- // Get byte count of instruction. +- unsigned Size = Desc.getSize(); ++unsigned LoongArchMCCodeEmitter::getMemEncoding10l2(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const { ++ // Base register is encoded in bits 16-12, offset is encoded in bits 11-0. ++ assert(MI.getOperand(OpNo).isReg()); ++ unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 10; ++ unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); + +- switch (MI.getOpcode()) { +- default: +- break; +- case LoongArch::PseudoVREPLI_B: +- case LoongArch::PseudoVREPLI_H: +- case LoongArch::PseudoVREPLI_W: +- case LoongArch::PseudoVREPLI_D: +- return expandToVectorLDI(MI, CB, Fixups, STI); +- case LoongArch::PseudoXVREPLI_B: +- case LoongArch::PseudoXVREPLI_H: +- case LoongArch::PseudoXVREPLI_W: +- case LoongArch::PseudoXVREPLI_D: +- return expandToVectorLDI(MI, CB, Fixups, STI); +- } ++ // Apply the scale factor if there is one. ++ OffBits >>= 2; + +- switch (Size) { ++ return (OffBits & 0x3FF) | RegBits; ++} ++ ++unsigned LoongArchMCCodeEmitter::getMemEncoding11l1(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const { ++ // Base register is encoded in bits 16-12, offset is encoded in bits 11-0. ++ assert(MI.getOperand(OpNo).isReg()); ++ unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 11; ++ unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); ++ ++ // Apply the scale factor if there is one. ++ OffBits >>= 1; ++ ++ return (OffBits & 0x7FF) | RegBits; ++} ++ ++unsigned LoongArchMCCodeEmitter::getMemEncoding9l3(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const { ++ // Base register is encoded in bits 16-12, offset is encoded in bits 11-0. ++ assert(MI.getOperand(OpNo).isReg()); ++ unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 9; ++ unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); ++ ++ // Apply the scale factor if there is one. ++ OffBits >>= 3; ++ ++ return (OffBits & 0x1FF) | RegBits; ++} ++ ++/// Return binary encoding of simm14 memory related operand. Such as LL/SC instructions. ++/// If the offset operand requires relocation, record the relocation. ++template ++unsigned LoongArchMCCodeEmitter::getSimm14MemEncoding(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const { ++ // Base register is encoded in bits 18-14, offset is encoded in bits 13-0. ++ assert(MI.getOperand(OpNo).isReg()); ++ unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 14; ++ unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); ++ ++ // Apply the scale factor if there is one. ++ OffBits >>= ShiftAmount; ++ ++ return (OffBits & 0x3FFF) | RegBits; ++} ++ ++unsigned ++LoongArchMCCodeEmitter::getFCMPEncoding(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const { ++ const MCOperand& MO = MI.getOperand(OpNo); ++ switch((LoongArch::CondCode)MO.getImm()){ ++ case LoongArch::FCOND_T: ++ return 0x0; ++ case LoongArch::FCOND_OR: ++ return 0x8; ++ case LoongArch::FCOND_UNE: ++ return 0x4; ++ case LoongArch::FCOND_ONE: ++ return 0xC; ++ case LoongArch::FCOND_UGE: ++ return 0x2; ++ case LoongArch::FCOND_OGE: ++ return 0xA; ++ case LoongArch::FCOND_UGT: ++ return 0x6; ++ case LoongArch::FCOND_OGT: ++ return 0xE; ++ case LoongArch::FCOND_ST: ++ return 0x1; ++ case LoongArch::FCOND_GLE: ++ return 0x9; ++ case LoongArch::FCOND_GL: ++ return 0xD; ++ case LoongArch::FCOND_NLT: ++ return 0x3; ++ case LoongArch::FCOND_GE: ++ return 0xB; ++ case LoongArch::FCOND_NLE: ++ return 0x7; ++ case LoongArch::FCOND_GT: ++ return 0xF; + default: +- llvm_unreachable("Unhandled encodeInstruction length!"); +- case 4: { +- uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); +- support::endian::write(CB, Bits, llvm::endianness::little); +- break; +- } ++ return MO.getImm(); + } + } + +-MCCodeEmitter *llvm::createLoongArchMCCodeEmitter(const MCInstrInfo &MCII, +- MCContext &Ctx) { +- return new LoongArchMCCodeEmitter(Ctx, MCII); ++template ++unsigned ++LoongArchMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const { ++ assert(MI.getOperand(OpNo).isImm()); ++ unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); ++ Value -= Offset; ++ return Value; + } + + #include "LoongArchGenMCCodeEmitter.inc" +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.h +new file mode 100644 +index 000000000..ee8865ec7 +--- /dev/null ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.h +@@ -0,0 +1,143 @@ ++//===- LoongArchMCCodeEmitter.h - Convert LoongArch Code to Machine Code --*- C++ -*-===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++// ++// This file defines the LoongArchMCCodeEmitter class. ++// ++//===----------------------------------------------------------------------===// ++ ++#ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCCODEEMITTER_H ++#define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCCODEEMITTER_H ++ ++#include "llvm/MC/MCCodeEmitter.h" ++#include "llvm/ADT/StringRef.h" ++#include ++#include ++ ++namespace llvm { ++ ++class MCContext; ++class MCExpr; ++class MCFixup; ++class MCInst; ++class MCInstrInfo; ++class MCOperand; ++class MCSubtargetInfo; ++class raw_ostream; ++ ++class LoongArchMCCodeEmitter : public MCCodeEmitter { ++ const MCInstrInfo &MCII; ++ MCContext &Ctx; ++ ++public: ++ LoongArchMCCodeEmitter(const MCInstrInfo &mcii, MCContext &Ctx_) ++ : MCII(mcii), Ctx(Ctx_) {} ++ LoongArchMCCodeEmitter(const LoongArchMCCodeEmitter &) = delete; ++ LoongArchMCCodeEmitter &operator=(const LoongArchMCCodeEmitter &) = delete; ++ ~LoongArchMCCodeEmitter() override = default; ++ ++ void EmitByte(unsigned char C, raw_ostream &OS) const; ++ ++ void encodeInstruction(const MCInst &MI, SmallVectorImpl &CB, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const override; ++ ++ // getBinaryCodeForInstr - TableGen'erated function for getting the ++ // binary encoding for an instruction. ++ uint64_t getBinaryCodeForInstr(const MCInst &MI, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const; ++ ++ // getJumpTargetOpValue - Return binary encoding of the jump ++ // target operand. If the machine operand requires relocation, ++ // record the relocation and return zero. ++ unsigned getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const; ++ ++ // getBranchTargetOpValue - Return binary encoding of the branch ++ // target operand. If the machine operand requires relocation, ++ // record the relocation and return zero. ++ unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const; ++ ++ // getMachineOpValue - Return binary encoding of operand. If the machin ++ // operand requires relocation, record the relocation and return zero. ++ unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const; ++ ++ template ++ unsigned getMemEncoding(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const; ++ ++ unsigned getAMemEncoding(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const; ++ ++ unsigned getMemEncoding10l2(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const; ++ ++ unsigned getMemEncoding11l1(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const; ++ ++ unsigned getMemEncoding9l3(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const; ++ ++ template ++ unsigned getSimm14MemEncoding(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const; ++ ++ unsigned getFCMPEncoding(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const; ++ ++ /// Subtract Offset then encode as a N-bit unsigned integer. ++ template ++ unsigned getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const; ++ ++ unsigned getExprOpValue(const MCInst &MI, const MCExpr *Expr, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const; ++ ++ unsigned getSImm11Lsl1Encoding(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const; ++ ++ unsigned getSImm10Lsl2Encoding(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const; ++ ++ unsigned getSImm9Lsl3Encoding(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const; ++ ++ unsigned getSImm8Lsl1Encoding(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const; ++ ++ unsigned getSImm8Lsl2Encoding(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const; ++ ++ unsigned getSImm8Lsl3Encoding(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl &Fixups, ++ const MCSubtargetInfo &STI) const; ++ ++}; ++ ++} // end namespace llvm ++ ++#endif // LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCCODEEMITTER_H +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp +index 8ca8876a1..7f5b06962 100644 +--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp +@@ -1,201 +1,86 @@ +-//===-- LoongArchMCExpr.cpp - LoongArch specific MC expression classes ----===// ++//===-- LoongArchMCExpr.cpp - LoongArch specific MC expression classes --------------===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. + // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + // + //===----------------------------------------------------------------------===// +-// +-// This file contains the implementation of the assembly expression modifiers +-// accepted by the LoongArch architecture. +-// +-//===----------------------------------------------------------------------===// + + #include "LoongArchMCExpr.h" +-#include "LoongArchAsmBackend.h" +-#include "LoongArchFixupKinds.h" ++#include "llvm/BinaryFormat/ELF.h" ++#include "llvm/MC/MCAsmInfo.h" ++#include "llvm/MC/MCAssembler.h" + #include "llvm/MC/MCContext.h" + #include "llvm/MC/MCStreamer.h" + #include "llvm/MC/MCSymbolELF.h" + #include "llvm/MC/MCValue.h" + #include "llvm/Support/Casting.h" + #include "llvm/Support/ErrorHandling.h" ++#include "llvm/Support/MathExtras.h" ++#include "llvm/Support/raw_ostream.h" ++#include + + using namespace llvm; + +-#define DEBUG_TYPE "loongarch-mcexpr" ++#define DEBUG_TYPE "loongarchmcexpr" + +-const LoongArchMCExpr *LoongArchMCExpr::create(const MCExpr *Expr, +- VariantKind Kind, MCContext &Ctx, +- bool Hint) { +- return new (Ctx) LoongArchMCExpr(Expr, Kind, Hint); ++const LoongArchMCExpr *LoongArchMCExpr::create(LoongArchMCExpr::LoongArchExprKind Kind, ++ const MCExpr *Expr, MCContext &Ctx) { ++ return new (Ctx) LoongArchMCExpr(Kind, Expr); + } + + void LoongArchMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const { +- VariantKind Kind = getKind(); +- bool HasVariant = +- ((Kind != VK_LoongArch_None) && (Kind != VK_LoongArch_CALL)); +- +- if (HasVariant) +- OS << '%' << getVariantKindName(getKind()) << '('; +- Expr->print(OS, MAI); +- if (HasVariant) +- OS << ')'; ++ int64_t AbsVal; ++ if (Expr->evaluateAsAbsolute(AbsVal)) ++ OS << AbsVal; ++ else ++ Expr->print(OS, MAI, true); + } + +-bool LoongArchMCExpr::evaluateAsRelocatableImpl(MCValue &Res, +- const MCAsmLayout *Layout, +- const MCFixup *Fixup) const { +- // Explicitly drop the layout and assembler to prevent any symbolic folding in +- // the expression handling. This is required to preserve symbolic difference +- // expressions to emit the paired relocations. +- if (!getSubExpr()->evaluateAsRelocatable(Res, nullptr, nullptr)) ++bool ++LoongArchMCExpr::evaluateAsRelocatableImpl(MCValue &Res, ++ const MCAsmLayout *Layout, ++ const MCFixup *Fixup) const { ++ if (!getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup)) + return false; + +- Res = +- MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), getKind()); +- // Custom fixup types are not valid with symbol difference expressions. +- return Res.getSymB() ? getKind() == VK_LoongArch_None : true; +-} +- +-void LoongArchMCExpr::visitUsedExpr(MCStreamer &Streamer) const { +- Streamer.visitUsedExpr(*getSubExpr()); +-} ++ if (Res.getRefKind() != MCSymbolRefExpr::VK_None) ++ return false; + +-StringRef LoongArchMCExpr::getVariantKindName(VariantKind Kind) { +- switch (Kind) { +- default: +- llvm_unreachable("Invalid ELF symbol kind"); +- case VK_LoongArch_CALL_PLT: +- return "plt"; +- case VK_LoongArch_B16: +- return "b16"; +- case VK_LoongArch_B21: +- return "b21"; +- case VK_LoongArch_B26: +- return "b21"; +- case VK_LoongArch_ABS_HI20: +- return "abs_hi20"; +- case VK_LoongArch_ABS_LO12: +- return "abs_lo12"; +- case VK_LoongArch_ABS64_LO20: +- return "abs64_lo20"; +- case VK_LoongArch_ABS64_HI12: +- return "abs64_hi12"; +- case VK_LoongArch_PCALA_HI20: +- return "pc_hi20"; +- case VK_LoongArch_PCALA_LO12: +- return "pc_lo12"; +- case VK_LoongArch_PCALA64_LO20: +- return "pc64_lo20"; +- case VK_LoongArch_PCALA64_HI12: +- return "pc64_hi12"; +- case VK_LoongArch_GOT_PC_HI20: +- return "got_pc_hi20"; +- case VK_LoongArch_GOT_PC_LO12: +- return "got_pc_lo12"; +- case VK_LoongArch_GOT64_PC_LO20: +- return "got64_pc_lo20"; +- case VK_LoongArch_GOT64_PC_HI12: +- return "got64_pc_hi12"; +- case VK_LoongArch_GOT_HI20: +- return "got_hi20"; +- case VK_LoongArch_GOT_LO12: +- return "got_lo12"; +- case VK_LoongArch_GOT64_LO20: +- return "got64_lo20"; +- case VK_LoongArch_GOT64_HI12: +- return "got64_hi12"; +- case VK_LoongArch_TLS_LE_HI20: +- return "le_hi20"; +- case VK_LoongArch_TLS_LE_LO12: +- return "le_lo12"; +- case VK_LoongArch_TLS_LE64_LO20: +- return "le64_lo20"; +- case VK_LoongArch_TLS_LE64_HI12: +- return "le64_hi12"; +- case VK_LoongArch_TLS_IE_PC_HI20: +- return "ie_pc_hi20"; +- case VK_LoongArch_TLS_IE_PC_LO12: +- return "ie_pc_lo12"; +- case VK_LoongArch_TLS_IE64_PC_LO20: +- return "ie64_pc_lo20"; +- case VK_LoongArch_TLS_IE64_PC_HI12: +- return "ie64_pc_hi12"; +- case VK_LoongArch_TLS_IE_HI20: +- return "ie_hi20"; +- case VK_LoongArch_TLS_IE_LO12: +- return "ie_lo12"; +- case VK_LoongArch_TLS_IE64_LO20: +- return "ie64_lo20"; +- case VK_LoongArch_TLS_IE64_HI12: +- return "ie64_hi12"; +- case VK_LoongArch_TLS_LD_PC_HI20: +- return "ld_pc_hi20"; +- case VK_LoongArch_TLS_LD_HI20: +- return "ld_hi20"; +- case VK_LoongArch_TLS_GD_PC_HI20: +- return "gd_pc_hi20"; +- case VK_LoongArch_TLS_GD_HI20: +- return "gd_hi20"; +- case VK_LoongArch_CALL36: +- return "call36"; ++ // evaluateAsAbsolute() and evaluateAsValue() require that we evaluate the ++ // %hi/%lo/etc. here. Fixup is a null pointer when either of these is the ++ // caller. ++ if (Res.isAbsolute() && Fixup == nullptr) { ++ int64_t AbsVal = Res.getConstant(); ++ switch (Kind) { ++ default: ++ break; ++ case MEK_None: ++ case MEK_Special: ++ llvm_unreachable("MEK_None and MEK_Special are invalid"); ++ } ++ Res = MCValue::get(AbsVal); ++ return true; + } ++ ++ // We want to defer it for relocatable expressions since the constant is ++ // applied to the whole symbol value. ++ Res = MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant()); ++ ++ return true; + } + +-LoongArchMCExpr::VariantKind +-LoongArchMCExpr::getVariantKindForName(StringRef name) { +- return StringSwitch(name) +- .Case("plt", VK_LoongArch_CALL_PLT) +- .Case("b16", VK_LoongArch_B16) +- .Case("b21", VK_LoongArch_B21) +- .Case("b26", VK_LoongArch_B26) +- .Case("abs_hi20", VK_LoongArch_ABS_HI20) +- .Case("abs_lo12", VK_LoongArch_ABS_LO12) +- .Case("abs64_lo20", VK_LoongArch_ABS64_LO20) +- .Case("abs64_hi12", VK_LoongArch_ABS64_HI12) +- .Case("pc_hi20", VK_LoongArch_PCALA_HI20) +- .Case("pc_lo12", VK_LoongArch_PCALA_LO12) +- .Case("pc64_lo20", VK_LoongArch_PCALA64_LO20) +- .Case("pc64_hi12", VK_LoongArch_PCALA64_HI12) +- .Case("got_pc_hi20", VK_LoongArch_GOT_PC_HI20) +- .Case("got_pc_lo12", VK_LoongArch_GOT_PC_LO12) +- .Case("got64_pc_lo20", VK_LoongArch_GOT64_PC_LO20) +- .Case("got64_pc_hi12", VK_LoongArch_GOT64_PC_HI12) +- .Case("got_hi20", VK_LoongArch_GOT_HI20) +- .Case("got_lo12", VK_LoongArch_GOT_LO12) +- .Case("got64_lo20", VK_LoongArch_GOT64_LO20) +- .Case("got64_hi12", VK_LoongArch_GOT64_HI12) +- .Case("le_hi20", VK_LoongArch_TLS_LE_HI20) +- .Case("le_lo12", VK_LoongArch_TLS_LE_LO12) +- .Case("le64_lo20", VK_LoongArch_TLS_LE64_LO20) +- .Case("le64_hi12", VK_LoongArch_TLS_LE64_HI12) +- .Case("ie_pc_hi20", VK_LoongArch_TLS_IE_PC_HI20) +- .Case("ie_pc_lo12", VK_LoongArch_TLS_IE_PC_LO12) +- .Case("ie64_pc_lo20", VK_LoongArch_TLS_IE64_PC_LO20) +- .Case("ie64_pc_hi12", VK_LoongArch_TLS_IE64_PC_HI12) +- .Case("ie_hi20", VK_LoongArch_TLS_IE_HI20) +- .Case("ie_lo12", VK_LoongArch_TLS_IE_LO12) +- .Case("ie64_lo20", VK_LoongArch_TLS_IE64_LO20) +- .Case("ie64_hi12", VK_LoongArch_TLS_IE64_HI12) +- .Case("ld_pc_hi20", VK_LoongArch_TLS_LD_PC_HI20) +- .Case("ld_hi20", VK_LoongArch_TLS_LD_HI20) +- .Case("gd_pc_hi20", VK_LoongArch_TLS_GD_PC_HI20) +- .Case("gd_hi20", VK_LoongArch_TLS_GD_HI20) +- .Case("call36", VK_LoongArch_CALL36) +- .Default(VK_LoongArch_Invalid); ++void LoongArchMCExpr::visitUsedExpr(MCStreamer &Streamer) const { ++ Streamer.visitUsedExpr(*getSubExpr()); + } + + static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) { + switch (Expr->getKind()) { + case MCExpr::Target: +- llvm_unreachable("Can't handle nested target expression"); ++ fixELFSymbolsInTLSFixupsImpl(cast(Expr)->getSubExpr(), Asm); + break; + case MCExpr::Constant: + break; +- case MCExpr::Unary: +- fixELFSymbolsInTLSFixupsImpl(cast(Expr)->getSubExpr(), Asm); +- break; + case MCExpr::Binary: { + const MCBinaryExpr *BE = cast(Expr); + fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm); +@@ -209,21 +94,61 @@ static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) { + cast(SymRef.getSymbol()).setType(ELF::STT_TLS); + break; + } ++ case MCExpr::Unary: ++ fixELFSymbolsInTLSFixupsImpl(cast(Expr)->getSubExpr(), Asm); ++ break; + } + } + + void LoongArchMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { + switch (getKind()) { + default: +- return; +- case VK_LoongArch_TLS_LE_HI20: +- case VK_LoongArch_TLS_IE_PC_HI20: +- case VK_LoongArch_TLS_IE_HI20: +- case VK_LoongArch_TLS_LD_PC_HI20: +- case VK_LoongArch_TLS_LD_HI20: +- case VK_LoongArch_TLS_GD_PC_HI20: +- case VK_LoongArch_TLS_GD_HI20: ++ break; ++ case MEK_None: ++ case MEK_Special: ++ llvm_unreachable("MEK_None and MEK_Special are invalid"); ++ break; ++ case MEK_CALL_HI: ++ case MEK_CALL_LO: ++ case MEK_GOT_HI: ++ case MEK_GOT_LO: ++ case MEK_GOT_RRHI: ++ case MEK_GOT_RRLO: ++ case MEK_GOT_RRHIGHER: ++ case MEK_GOT_RRHIGHEST: ++ case MEK_ABS_HI: ++ case MEK_ABS_LO: ++ case MEK_ABS_HIGHER: ++ case MEK_ABS_HIGHEST: ++ case MEK_PCREL_HI: ++ case MEK_PCREL_LO: ++ case MEK_PCREL_RRHI: ++ case MEK_PCREL_RRHIGHER: ++ case MEK_PCREL_RRHIGHEST: ++ case MEK_PCREL_RRLO: ++ case MEK_PLT: ++ // If we do have nested target-specific expressions, they will be in ++ // a consecutive chain. ++ if (const LoongArchMCExpr *E = dyn_cast(getSubExpr())) ++ E->fixELFSymbolsInTLSFixups(Asm); ++ break; ++ case MEK_TLSGD_HI: ++ case MEK_TLSGD_LO: ++ case MEK_TLSGD_RRHI: ++ case MEK_TLSGD_RRHIGHER: ++ case MEK_TLSGD_RRHIGHEST: ++ case MEK_TLSGD_RRLO: ++ case MEK_TLSLE_HI: ++ case MEK_TLSLE_HIGHER: ++ case MEK_TLSLE_HIGHEST: ++ case MEK_TLSLE_LO: ++ case MEK_TLSIE_HI: ++ case MEK_TLSIE_LO: ++ case MEK_TLSIE_RRHI: ++ case MEK_TLSIE_RRHIGHER: ++ case MEK_TLSIE_RRHIGHEST: ++ case MEK_TLSIE_RRLO: ++ fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm); + break; + } +- fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm); + } +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h +index bd828116d..7851d478e 100644 +--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h +@@ -1,90 +1,86 @@ +-//= LoongArchMCExpr.h - LoongArch specific MC expression classes -*- C++ -*-==// ++//===- LoongArchMCExpr.h - LoongArch specific MC expression classes -------*- C++ -*-===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. + // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + // + //===----------------------------------------------------------------------===// +-// +-// This file describes LoongArch-specific MCExprs, used for modifiers like +-// "%pc_hi20" or "%pc_lo12" etc. +-// +-//===----------------------------------------------------------------------===// + + #ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCEXPR_H + #define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCEXPR_H + ++#include "llvm/MC/MCAsmLayout.h" + #include "llvm/MC/MCExpr.h" ++#include "llvm/MC/MCValue.h" + + namespace llvm { + +-class StringRef; +- + class LoongArchMCExpr : public MCTargetExpr { + public: +- enum VariantKind { +- VK_LoongArch_None, +- VK_LoongArch_CALL, +- VK_LoongArch_CALL_PLT, +- VK_LoongArch_B16, +- VK_LoongArch_B21, +- VK_LoongArch_B26, +- VK_LoongArch_ABS_HI20, +- VK_LoongArch_ABS_LO12, +- VK_LoongArch_ABS64_LO20, +- VK_LoongArch_ABS64_HI12, +- VK_LoongArch_PCALA_HI20, +- VK_LoongArch_PCALA_LO12, +- VK_LoongArch_PCALA64_LO20, +- VK_LoongArch_PCALA64_HI12, +- VK_LoongArch_GOT_PC_HI20, +- VK_LoongArch_GOT_PC_LO12, +- VK_LoongArch_GOT64_PC_LO20, +- VK_LoongArch_GOT64_PC_HI12, +- VK_LoongArch_GOT_HI20, +- VK_LoongArch_GOT_LO12, +- VK_LoongArch_GOT64_LO20, +- VK_LoongArch_GOT64_HI12, +- VK_LoongArch_TLS_LE_HI20, +- VK_LoongArch_TLS_LE_LO12, +- VK_LoongArch_TLS_LE64_LO20, +- VK_LoongArch_TLS_LE64_HI12, +- VK_LoongArch_TLS_IE_PC_HI20, +- VK_LoongArch_TLS_IE_PC_LO12, +- VK_LoongArch_TLS_IE64_PC_LO20, +- VK_LoongArch_TLS_IE64_PC_HI12, +- VK_LoongArch_TLS_IE_HI20, +- VK_LoongArch_TLS_IE_LO12, +- VK_LoongArch_TLS_IE64_LO20, +- VK_LoongArch_TLS_IE64_HI12, +- VK_LoongArch_TLS_LD_PC_HI20, +- VK_LoongArch_TLS_LD_HI20, +- VK_LoongArch_TLS_GD_PC_HI20, +- VK_LoongArch_TLS_GD_HI20, +- VK_LoongArch_CALL36, +- VK_LoongArch_Invalid // Must be the last item. ++ enum LoongArchExprKind { ++ MEK_None, ++ MEK_CALL_HI, ++ MEK_CALL_LO, ++ MEK_GOT_HI, ++ MEK_GOT_LO, ++ MEK_GOT_RRHI, ++ MEK_GOT_RRHIGHER, ++ MEK_GOT_RRHIGHEST, ++ MEK_GOT_RRLO, ++ MEK_ABS_HI, ++ MEK_ABS_HIGHER, ++ MEK_ABS_HIGHEST, ++ MEK_ABS_LO, ++ MEK_PCREL_HI, ++ MEK_PCREL_LO, ++ MEK_PCREL_RRHI, ++ MEK_PCREL_RRHIGHER, ++ MEK_PCREL_RRHIGHEST, ++ MEK_PCREL_RRLO, ++ MEK_TLSLE_HI, ++ MEK_TLSLE_HIGHER, ++ MEK_TLSLE_HIGHEST, ++ MEK_TLSLE_LO, ++ MEK_TLSIE_HI, ++ MEK_TLSIE_LO, ++ MEK_TLSIE_RRHI, ++ MEK_TLSIE_RRHIGHER, ++ MEK_TLSIE_RRHIGHEST, ++ MEK_TLSIE_RRLO, ++ MEK_TLSGD_HI, ++ MEK_TLSGD_LO, ++ MEK_TLSGD_RRHI, ++ MEK_TLSGD_RRHIGHER, ++ MEK_TLSGD_RRHIGHEST, ++ MEK_TLSGD_RRLO, ++ MEK_PLT, ++ MEK_Special, + }; + + private: ++ const LoongArchExprKind Kind; + const MCExpr *Expr; +- const VariantKind Kind; +- const bool RelaxHint; + +- explicit LoongArchMCExpr(const MCExpr *Expr, VariantKind Kind, bool Hint) +- : Expr(Expr), Kind(Kind), RelaxHint(Hint) {} ++ explicit LoongArchMCExpr(LoongArchExprKind Kind, const MCExpr *Expr) ++ : Kind(Kind), Expr(Expr) {} + + public: +- static const LoongArchMCExpr *create(const MCExpr *Expr, VariantKind Kind, +- MCContext &Ctx, bool Hint = false); ++ static const LoongArchMCExpr *create(LoongArchExprKind Kind, const MCExpr *Expr, ++ MCContext &Ctx); ++ static const LoongArchMCExpr *createGpOff(LoongArchExprKind Kind, const MCExpr *Expr, ++ MCContext &Ctx); + +- VariantKind getKind() const { return Kind; } ++ /// Get the kind of this expression. ++ LoongArchExprKind getKind() const { return Kind; } ++ ++ /// Get the child of this expression. + const MCExpr *getSubExpr() const { return Expr; } +- bool getRelaxHint() const { return RelaxHint; } + + void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override; + bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, + const MCFixup *Fixup) const override; + void visitUsedExpr(MCStreamer &Streamer) const override; ++ + MCFragment *findAssociatedFragment() const override { + return getSubExpr()->findAssociatedFragment(); + } +@@ -94,11 +90,8 @@ public: + static bool classof(const MCExpr *E) { + return E->getKind() == MCExpr::Target; + } +- +- static StringRef getVariantKindName(VariantKind Kind); +- static VariantKind getVariantKindForName(StringRef name); + }; + + } // end namespace llvm + +-#endif ++#endif // LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCEXPR_H +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.cpp +index a4e6a0986..5582948fc 100644 +--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.cpp ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.cpp +@@ -1,4 +1,4 @@ +-//===-- LoongArchMCTargetDesc.cpp - LoongArch Target Descriptions ---------===// ++//===-- LoongArchMCTargetDesc.cpp - LoongArch Target Descriptions -------------------===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -11,39 +11,47 @@ + //===----------------------------------------------------------------------===// + + #include "LoongArchMCTargetDesc.h" +-#include "LoongArchBaseInfo.h" +-#include "LoongArchELFStreamer.h" +-#include "LoongArchInstPrinter.h" +-#include "LoongArchMCAsmInfo.h" ++#include "LoongArchTargetStreamer.h" ++#include "MCTargetDesc/LoongArchAsmBackend.h" ++#include "MCTargetDesc/LoongArchELFStreamer.h" ++#include "MCTargetDesc/LoongArchInstPrinter.h" ++#include "MCTargetDesc/LoongArchMCAsmInfo.h" + #include "TargetInfo/LoongArchTargetInfo.h" +-#include "llvm/MC/MCAsmBackend.h" +-#include "llvm/MC/MCAsmInfo.h" + #include "llvm/MC/MCCodeEmitter.h" +-#include "llvm/MC/MCDwarf.h" ++#include "llvm/MC/MCELFStreamer.h" + #include "llvm/MC/MCInstrAnalysis.h" + #include "llvm/MC/MCInstrInfo.h" + #include "llvm/MC/MCObjectWriter.h" + #include "llvm/MC/MCRegisterInfo.h" + #include "llvm/MC/MCSubtargetInfo.h" ++#include "llvm/MC/MCSymbol.h" ++#include "llvm/MC/MachineLocation.h" ++#include "llvm/Support/ErrorHandling.h" ++#include "llvm/Support/FormattedStream.h" + #include "llvm/MC/TargetRegistry.h" +-#include "llvm/Support/Compiler.h" ++#include "llvm/TargetParser/Triple.h" ++ ++using namespace llvm; + + #define GET_INSTRINFO_MC_DESC +-#define ENABLE_INSTR_PREDICATE_VERIFIER + #include "LoongArchGenInstrInfo.inc" + +-#define GET_REGINFO_MC_DESC +-#include "LoongArchGenRegisterInfo.inc" +- + #define GET_SUBTARGETINFO_MC_DESC + #include "LoongArchGenSubtargetInfo.inc" + +-using namespace llvm; ++#define GET_REGINFO_MC_DESC ++#include "LoongArchGenRegisterInfo.inc" + +-static MCRegisterInfo *createLoongArchMCRegisterInfo(const Triple &TT) { +- MCRegisterInfo *X = new MCRegisterInfo(); +- InitLoongArchMCRegisterInfo(X, LoongArch::R1); +- return X; ++/// Select the LoongArch CPU for the given triple and cpu name. ++/// FIXME: Merge with the copy in LoongArchSubtarget.cpp ++StringRef LoongArch_MC::selectLoongArchCPU(const Triple &TT, StringRef CPU) { ++ if (CPU.empty() || CPU == "generic") { ++ if (TT.isLoongArch32()) ++ CPU = "loongarch32"; //FIXME ++ else ++ CPU = "loongarch64"; ++ } ++ return CPU; + } + + static MCInstrInfo *createLoongArchMCInstrInfo() { +@@ -52,20 +60,24 @@ static MCInstrInfo *createLoongArchMCInstrInfo() { + return X; + } + +-static MCSubtargetInfo * +-createLoongArchMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) { +- if (CPU.empty() || CPU == "generic") +- CPU = TT.isArch64Bit() ? "la464" : "generic-la32"; ++static MCRegisterInfo *createLoongArchMCRegisterInfo(const Triple &TT) { ++ MCRegisterInfo *X = new MCRegisterInfo(); ++ InitLoongArchMCRegisterInfo(X, LoongArch::RA); ++ return X; ++} ++ ++static MCSubtargetInfo *createLoongArchMCSubtargetInfo(const Triple &TT, ++ StringRef CPU, StringRef FS) { ++ CPU = LoongArch_MC::selectLoongArchCPU(TT, CPU); + return createLoongArchMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS); + } + + static MCAsmInfo *createLoongArchMCAsmInfo(const MCRegisterInfo &MRI, + const Triple &TT, + const MCTargetOptions &Options) { +- MCAsmInfo *MAI = new LoongArchMCAsmInfo(TT); ++ MCAsmInfo *MAI = new LoongArchMCAsmInfo(TT, Options); + +- // Initial state of the frame pointer is sp(r3). +- MCRegister SP = MRI.getDwarfRegNum(LoongArch::R3, true); ++ unsigned SP = MRI.getDwarfRegNum(LoongArch::SP, true); + MCCFIInstruction Inst = MCCFIInstruction::cfiDefCfa(nullptr, SP, 0); + MAI->addInitialFrameState(Inst); + +@@ -80,138 +92,96 @@ static MCInstPrinter *createLoongArchMCInstPrinter(const Triple &T, + return new LoongArchInstPrinter(MAI, MII, MRI); + } + ++static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context, ++ std::unique_ptr &&MAB, ++ std::unique_ptr &&OW, ++ std::unique_ptr &&Emitter, ++ bool RelaxAll) { ++ MCStreamer *S; ++ S = createLoongArchELFStreamer(Context, std::move(MAB), std::move(OW), ++ std::move(Emitter), RelaxAll); ++ return S; ++} ++ ++static MCTargetStreamer *createLoongArchAsmTargetStreamer(MCStreamer &S, ++ formatted_raw_ostream &OS, ++ MCInstPrinter *InstPrint, ++ bool isVerboseAsm) { ++ return new LoongArchTargetAsmStreamer(S, OS); ++} ++ ++static MCTargetStreamer *createLoongArchNullTargetStreamer(MCStreamer &S) { ++ return new LoongArchTargetStreamer(S); ++} ++ + static MCTargetStreamer * + createLoongArchObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { +- return STI.getTargetTriple().isOSBinFormatELF() +- ? new LoongArchTargetELFStreamer(S, STI) +- : nullptr; ++ return new LoongArchTargetELFStreamer(S, STI); + } + + namespace { + + class LoongArchMCInstrAnalysis : public MCInstrAnalysis { + public: +- explicit LoongArchMCInstrAnalysis(const MCInstrInfo *Info) +- : MCInstrAnalysis(Info) {} ++ LoongArchMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {} + + bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size, + uint64_t &Target) const override { + unsigned NumOps = Inst.getNumOperands(); +- if ((isBranch(Inst) && !isIndirectBranch(Inst)) || +- Inst.getOpcode() == LoongArch::BL) { +- Target = Addr + Inst.getOperand(NumOps - 1).getImm(); +- return true; +- } +- +- return false; +- } +- +- bool isTerminator(const MCInst &Inst) const override { +- if (MCInstrAnalysis::isTerminator(Inst)) +- return true; +- +- switch (Inst.getOpcode()) { +- default: +- return false; +- case LoongArch::JIRL: +- return Inst.getOperand(0).getReg() == LoongArch::R0; +- } +- } +- +- bool isCall(const MCInst &Inst) const override { +- if (MCInstrAnalysis::isCall(Inst)) +- return true; +- +- switch (Inst.getOpcode()) { +- default: ++ if (NumOps == 0) + return false; +- case LoongArch::JIRL: +- return Inst.getOperand(0).getReg() != LoongArch::R0; +- } +- } +- +- bool isReturn(const MCInst &Inst) const override { +- if (MCInstrAnalysis::isReturn(Inst)) ++ if (Info->get(Inst.getOpcode()).isBranch() || Inst.getOpcode() == LoongArch::BL) { ++ // just not jirl ++ Target = Addr + Inst.getOperand(NumOps - 1).getImm(); + return true; +- +- switch (Inst.getOpcode()) { +- default: ++ } else { + return false; +- case LoongArch::JIRL: +- return Inst.getOperand(0).getReg() == LoongArch::R0 && +- Inst.getOperand(1).getReg() == LoongArch::R1; + } + } ++}; ++} + +- bool isBranch(const MCInst &Inst) const override { +- if (MCInstrAnalysis::isBranch(Inst)) +- return true; ++static MCInstrAnalysis *createLoongArchMCInstrAnalysis(const MCInstrInfo *Info) { ++ return new LoongArchMCInstrAnalysis(Info); ++} + +- switch (Inst.getOpcode()) { +- default: +- return false; +- case LoongArch::JIRL: +- return Inst.getOperand(0).getReg() == LoongArch::R0 && +- Inst.getOperand(1).getReg() != LoongArch::R1; +- } +- } ++extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchTargetMC() { ++ for (Target *T : {&getTheLoongArch32Target(), &getTheLoongArch64Target()}) { ++ // Register the MC asm info. ++ RegisterMCAsmInfoFn X(*T, createLoongArchMCAsmInfo); + +- bool isUnconditionalBranch(const MCInst &Inst) const override { +- if (MCInstrAnalysis::isUnconditionalBranch(Inst)) +- return true; ++ // Register the MC instruction info. ++ TargetRegistry::RegisterMCInstrInfo(*T, createLoongArchMCInstrInfo); + +- switch (Inst.getOpcode()) { +- default: +- return false; +- case LoongArch::JIRL: +- return Inst.getOperand(0).getReg() == LoongArch::R0 && +- Inst.getOperand(1).getReg() != LoongArch::R1; +- } +- } ++ // Register the MC register info. ++ TargetRegistry::RegisterMCRegInfo(*T, createLoongArchMCRegisterInfo); + +- bool isIndirectBranch(const MCInst &Inst) const override { +- if (MCInstrAnalysis::isIndirectBranch(Inst)) +- return true; ++ // Register the elf streamer. ++ TargetRegistry::RegisterELFStreamer(*T, createMCStreamer); + +- switch (Inst.getOpcode()) { +- default: +- return false; +- case LoongArch::JIRL: +- return Inst.getOperand(0).getReg() == LoongArch::R0 && +- Inst.getOperand(1).getReg() != LoongArch::R1; +- } +- } +-}; ++ // Register the asm target streamer. ++ TargetRegistry::RegisterAsmTargetStreamer(*T, createLoongArchAsmTargetStreamer); + +-} // end namespace ++ TargetRegistry::RegisterNullTargetStreamer(*T, ++ createLoongArchNullTargetStreamer); + +-static MCInstrAnalysis *createLoongArchInstrAnalysis(const MCInstrInfo *Info) { +- return new LoongArchMCInstrAnalysis(Info); +-} ++ // Register the MC subtarget info. ++ TargetRegistry::RegisterMCSubtargetInfo(*T, createLoongArchMCSubtargetInfo); + +-namespace { +-MCStreamer *createLoongArchELFStreamer(const Triple &T, MCContext &Context, +- std::unique_ptr &&MAB, +- std::unique_ptr &&MOW, +- std::unique_ptr &&MCE, +- bool RelaxAll) { +- return createLoongArchELFStreamer(Context, std::move(MAB), std::move(MOW), +- std::move(MCE), RelaxAll); +-} +-} // end namespace ++ // Register the MC instruction analyzer. ++ TargetRegistry::RegisterMCInstrAnalysis(*T, createLoongArchMCInstrAnalysis); + +-extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchTargetMC() { +- for (Target *T : {&getTheLoongArch32Target(), &getTheLoongArch64Target()}) { +- TargetRegistry::RegisterMCRegInfo(*T, createLoongArchMCRegisterInfo); +- TargetRegistry::RegisterMCInstrInfo(*T, createLoongArchMCInstrInfo); +- TargetRegistry::RegisterMCSubtargetInfo(*T, createLoongArchMCSubtargetInfo); +- TargetRegistry::RegisterMCAsmInfo(*T, createLoongArchMCAsmInfo); +- TargetRegistry::RegisterMCCodeEmitter(*T, createLoongArchMCCodeEmitter); +- TargetRegistry::RegisterMCAsmBackend(*T, createLoongArchAsmBackend); ++ // Register the MCInstPrinter. + TargetRegistry::RegisterMCInstPrinter(*T, createLoongArchMCInstPrinter); +- TargetRegistry::RegisterMCInstrAnalysis(*T, createLoongArchInstrAnalysis); +- TargetRegistry::RegisterELFStreamer(*T, createLoongArchELFStreamer); ++ + TargetRegistry::RegisterObjectTargetStreamer( + *T, createLoongArchObjectTargetStreamer); ++ ++ // Register the asm backend. ++ TargetRegistry::RegisterMCAsmBackend(*T, createLoongArchAsmBackend); + } ++ ++ // Register the MC Code Emitter ++ for (Target *T : {&getTheLoongArch32Target(), &getTheLoongArch64Target()}) ++ TargetRegistry::RegisterMCCodeEmitter(*T, createLoongArchMCCodeEmitter); + } +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h +index bb05baa9b..04a5c79e6 100644 +--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h +@@ -1,4 +1,4 @@ +-//===- LoongArchMCTargetDesc.h - LoongArch Target Descriptions --*- C++ -*-===// ++//===-- LoongArchMCTargetDesc.h - LoongArch Target Descriptions -----------*- C++ -*-===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -13,8 +13,8 @@ + #ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCTARGETDESC_H + #define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCTARGETDESC_H + +-#include "llvm/MC/MCTargetOptions.h" + #include "llvm/Support/DataTypes.h" ++ + #include + + namespace llvm { +@@ -25,7 +25,15 @@ class MCInstrInfo; + class MCObjectTargetWriter; + class MCRegisterInfo; + class MCSubtargetInfo; ++class MCTargetOptions; ++class StringRef; + class Target; ++class Triple; ++class raw_ostream; ++class raw_pwrite_stream; ++ ++Target &getTheLoongArch32Target(); ++Target &getTheLoongArch64Target(); + + MCCodeEmitter *createLoongArchMCCodeEmitter(const MCInstrInfo &MCII, + MCContext &Ctx); +@@ -36,20 +44,24 @@ MCAsmBackend *createLoongArchAsmBackend(const Target &T, + const MCTargetOptions &Options); + + std::unique_ptr +-createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit, bool Relax); ++createLoongArchELFObjectWriter(const Triple &TT, bool IsLPX32); ++ ++namespace LoongArch_MC { ++StringRef selectLoongArchCPU(const Triple &TT, StringRef CPU); ++} + +-} // end namespace llvm ++} // End llvm namespace + +-// Defines symbolic names for LoongArch registers. ++// Defines symbolic names for LoongArch registers. This defines a mapping from ++// register name to register number. + #define GET_REGINFO_ENUM + #include "LoongArchGenRegisterInfo.inc" + +-// Defines symbolic names for LoongArch instructions. ++// Defines symbolic names for the LoongArch instructions. + #define GET_INSTRINFO_ENUM +-#define GET_INSTRINFO_MC_HELPER_DECLS + #include "LoongArchGenInstrInfo.inc" + + #define GET_SUBTARGETINFO_ENUM + #include "LoongArchGenSubtargetInfo.inc" + +-#endif // LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCTARGETDESC_H ++#endif +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMatInt.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMatInt.cpp +deleted file mode 100644 +index 1509c436c..000000000 +--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMatInt.cpp ++++ /dev/null +@@ -1,51 +0,0 @@ +-//===- LoongArchMatInt.cpp - Immediate materialisation ---------*- C++ -*--===// +-// +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +-// +-//===----------------------------------------------------------------------===// +- +-#include "LoongArchMatInt.h" +-#include "MCTargetDesc/LoongArchMCTargetDesc.h" +-#include "llvm/Support/MathExtras.h" +- +-using namespace llvm; +- +-LoongArchMatInt::InstSeq LoongArchMatInt::generateInstSeq(int64_t Val) { +- // Val: +- // | hi32 | lo32 | +- // +-----------+------------------+------------------+-----------+ +- // | Highest12 | Higher20 | Hi20 | Lo12 | +- // +-----------+------------------+------------------+-----------+ +- // 63 52 51 32 31 12 11 0 +- // +- const int64_t Highest12 = Val >> 52 & 0xFFF; +- const int64_t Higher20 = Val >> 32 & 0xFFFFF; +- const int64_t Hi20 = Val >> 12 & 0xFFFFF; +- const int64_t Lo12 = Val & 0xFFF; +- InstSeq Insts; +- +- if (Highest12 != 0 && SignExtend64<52>(Val) == 0) { +- Insts.push_back(Inst(LoongArch::LU52I_D, SignExtend64<12>(Highest12))); +- return Insts; +- } +- +- if (Hi20 == 0) +- Insts.push_back(Inst(LoongArch::ORI, Lo12)); +- else if (SignExtend32<1>(Lo12 >> 11) == SignExtend32<20>(Hi20)) +- Insts.push_back(Inst(LoongArch::ADDI_W, SignExtend64<12>(Lo12))); +- else { +- Insts.push_back(Inst(LoongArch::LU12I_W, SignExtend64<20>(Hi20))); +- if (Lo12 != 0) +- Insts.push_back(Inst(LoongArch::ORI, Lo12)); +- } +- +- if (SignExtend32<1>(Hi20 >> 19) != SignExtend32<20>(Higher20)) +- Insts.push_back(Inst(LoongArch::LU32I_D, SignExtend64<20>(Higher20))); +- +- if (SignExtend32<1>(Higher20 >> 19) != SignExtend32<12>(Highest12)) +- Insts.push_back(Inst(LoongArch::LU52I_D, SignExtend64<12>(Highest12))); +- +- return Insts; +-} +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchTargetStreamer.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchTargetStreamer.cpp +index 571178442..9bf8504d3 100644 +--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchTargetStreamer.cpp ++++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchTargetStreamer.cpp +@@ -1,4 +1,4 @@ +-//===-- LoongArchTargetStreamer.cpp - LoongArch Target Streamer Methods ---===// ++//===-- LoongArchTargetStreamer.cpp - LoongArch Target Streamer Methods -------------===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -10,15 +10,319 @@ + // + //===----------------------------------------------------------------------===// + ++#include "LoongArchABIInfo.h" ++#include "LoongArchELFStreamer.h" ++#include "LoongArchInstPrinter.h" ++#include "LoongArchMCExpr.h" ++#include "LoongArchMCTargetDesc.h" ++#include "LoongArchTargetObjectFile.h" + #include "LoongArchTargetStreamer.h" ++#include "llvm/BinaryFormat/ELF.h" ++#include "llvm/MC/MCAssembler.h" ++#include "llvm/MC/MCContext.h" ++#include "llvm/MC/MCSectionELF.h" ++#include "llvm/MC/MCSubtargetInfo.h" ++#include "llvm/MC/MCSymbolELF.h" ++#include "llvm/Support/Casting.h" ++#include "llvm/Support/CommandLine.h" ++#include "llvm/Support/ErrorHandling.h" ++#include "llvm/Support/FormattedStream.h" + + using namespace llvm; + ++namespace { ++static cl::opt RoundSectionSizes( ++ "loongarch-round-section-sizes", cl::init(false), ++ cl::desc("Round section sizes up to the section alignment"), cl::Hidden); ++} // end anonymous namespace ++ + LoongArchTargetStreamer::LoongArchTargetStreamer(MCStreamer &S) +- : MCTargetStreamer(S) {} ++ : MCTargetStreamer(S), ModuleDirectiveAllowed(true) { ++ GPRInfoSet = FPRInfoSet = FrameInfoSet = false; ++} ++void LoongArchTargetStreamer::emitDirectiveOptionPic0() {} ++void LoongArchTargetStreamer::emitDirectiveOptionPic2() {} ++void LoongArchTargetStreamer::emitDirectiveSetArch(StringRef Arch) { ++ forbidModuleDirective(); ++} ++void LoongArchTargetStreamer::emitDirectiveSetLoongArch32() { forbidModuleDirective(); } ++void LoongArchTargetStreamer::emitDirectiveSetloongarch64() { forbidModuleDirective(); } ++ ++void LoongArchTargetStreamer::emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc, ++ const MCSubtargetInfo *STI) { ++ MCInst TmpInst; ++ TmpInst.setOpcode(Opcode); ++ TmpInst.addOperand(MCOperand::createReg(Reg0)); ++ TmpInst.setLoc(IDLoc); ++ getStreamer().emitInstruction(TmpInst, *STI); ++} ++ ++void LoongArchTargetStreamer::emitRXX(unsigned Opcode, unsigned Reg0, MCOperand Op1, ++ MCOperand Op2, SMLoc IDLoc, const MCSubtargetInfo *STI) { ++ MCInst TmpInst; ++ TmpInst.setOpcode(Opcode); ++ TmpInst.addOperand(MCOperand::createReg(Reg0)); ++ TmpInst.addOperand(Op1); ++ TmpInst.addOperand(Op2); ++ TmpInst.setLoc(IDLoc); ++ getStreamer().emitInstruction(TmpInst, *STI); ++} ++ ++void LoongArchTargetStreamer::emitRRXX(unsigned Opcode, unsigned Reg0, unsigned Reg1, ++ MCOperand Op2, MCOperand Op3, SMLoc IDLoc, ++ const MCSubtargetInfo *STI) { ++ MCInst TmpInst; ++ TmpInst.setOpcode(Opcode); ++ TmpInst.addOperand(MCOperand::createReg(Reg0)); ++ TmpInst.addOperand(MCOperand::createReg(Reg1)); ++ TmpInst.addOperand(Op2); ++ TmpInst.addOperand(Op3); ++ TmpInst.setLoc(IDLoc); ++ getStreamer().emitInstruction(TmpInst, *STI); ++} ++ ++void LoongArchTargetStreamer::emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, ++ SMLoc IDLoc, const MCSubtargetInfo *STI) { ++ MCInst TmpInst; ++ TmpInst.setOpcode(Opcode); ++ TmpInst.addOperand(MCOperand::createReg(Reg0)); ++ TmpInst.addOperand(Op1); ++ TmpInst.setLoc(IDLoc); ++ getStreamer().emitInstruction(TmpInst, *STI); ++} ++ ++void LoongArchTargetStreamer::emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, ++ SMLoc IDLoc, const MCSubtargetInfo *STI) { ++ emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, STI); ++} ++ ++void LoongArchTargetStreamer::emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, ++ SMLoc IDLoc, const MCSubtargetInfo *STI) { ++ emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, STI); ++} ++ ++void LoongArchTargetStreamer::emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, ++ SMLoc IDLoc, const MCSubtargetInfo *STI) { ++ MCInst TmpInst; ++ TmpInst.setOpcode(Opcode); ++ TmpInst.addOperand(MCOperand::createImm(Imm1)); ++ TmpInst.addOperand(MCOperand::createImm(Imm2)); ++ TmpInst.setLoc(IDLoc); ++ getStreamer().emitInstruction(TmpInst, *STI); ++} ++ ++void LoongArchTargetStreamer::emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, ++ MCOperand Op2, SMLoc IDLoc, ++ const MCSubtargetInfo *STI) { ++ MCInst TmpInst; ++ TmpInst.setOpcode(Opcode); ++ TmpInst.addOperand(MCOperand::createReg(Reg0)); ++ TmpInst.addOperand(MCOperand::createReg(Reg1)); ++ TmpInst.addOperand(Op2); ++ TmpInst.setLoc(IDLoc); ++ getStreamer().emitInstruction(TmpInst, *STI); ++} ++ ++void LoongArchTargetStreamer::emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, ++ unsigned Reg2, SMLoc IDLoc, ++ const MCSubtargetInfo *STI) { ++ emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc, STI); ++} ++ ++void LoongArchTargetStreamer::emitRRI(unsigned Opcode, unsigned Reg0, ++ unsigned Reg1, int32_t Imm, SMLoc IDLoc, ++ const MCSubtargetInfo *STI) { ++ emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc, STI); ++} ++ ++void LoongArchTargetStreamer::emitRRIII(unsigned Opcode, unsigned Reg0, ++ unsigned Reg1, int16_t Imm0, int16_t Imm1, ++ int16_t Imm2, SMLoc IDLoc, ++ const MCSubtargetInfo *STI) { ++ MCInst TmpInst; ++ TmpInst.setOpcode(Opcode); ++ TmpInst.addOperand(MCOperand::createReg(Reg0)); ++ TmpInst.addOperand(MCOperand::createReg(Reg1)); ++ TmpInst.addOperand(MCOperand::createImm(Imm0)); ++ TmpInst.addOperand(MCOperand::createImm(Imm1)); ++ TmpInst.addOperand(MCOperand::createImm(Imm2)); ++ TmpInst.setLoc(IDLoc); ++ getStreamer().emitInstruction(TmpInst, *STI); ++} ++ ++void LoongArchTargetStreamer::emitAdd(unsigned DstReg, unsigned SrcReg, ++ unsigned TrgReg, bool Is64Bit, ++ const MCSubtargetInfo *STI) { ++ emitRRR(Is64Bit ? LoongArch::ADD_D : LoongArch::ADD_W, DstReg, SrcReg, TrgReg, SMLoc(), ++ STI); ++} ++ ++void LoongArchTargetStreamer::emitDSLL(unsigned DstReg, unsigned SrcReg, ++ int16_t ShiftAmount, SMLoc IDLoc, ++ const MCSubtargetInfo *STI) { ++ if (ShiftAmount >= 32) { ++ emitRRI(LoongArch::SLLI_D, DstReg, SrcReg, ShiftAmount - 32, IDLoc, STI); ++ return; ++ } ++ ++ emitRRI(LoongArch::SLLI_D, DstReg, SrcReg, ShiftAmount, IDLoc, STI); ++} ++ ++void LoongArchTargetStreamer::emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI) { ++ emitRRI(LoongArch::ANDI, LoongArch::ZERO, LoongArch::ZERO, 0, IDLoc, STI); ++} ++ ++LoongArchTargetAsmStreamer::LoongArchTargetAsmStreamer(MCStreamer &S, ++ formatted_raw_ostream &OS) ++ : LoongArchTargetStreamer(S), OS(OS) {} ++ ++void LoongArchTargetAsmStreamer::emitDirectiveOptionPic0() { ++ OS << "\t.option\tpic0\n"; ++} ++ ++void LoongArchTargetAsmStreamer::emitDirectiveOptionPic2() { ++ OS << "\t.option\tpic2\n"; ++} ++ ++void LoongArchTargetAsmStreamer::emitDirectiveSetArch(StringRef Arch) { ++ OS << "\t.set arch=" << Arch << "\n"; ++ LoongArchTargetStreamer::emitDirectiveSetArch(Arch); ++} ++ ++void LoongArchTargetAsmStreamer::emitDirectiveSetLoongArch32() { ++ //OS << "\t.set\tloongarch32\n"; ++ LoongArchTargetStreamer::emitDirectiveSetLoongArch32(); ++} ++ ++void LoongArchTargetAsmStreamer::emitDirectiveSetloongarch64() { ++ //OS << "\t.set\tloongarch64\n"; ++ LoongArchTargetStreamer::emitDirectiveSetloongarch64(); ++} ++ ++// This part is for ELF object output. ++LoongArchTargetELFStreamer::LoongArchTargetELFStreamer(MCStreamer &S, ++ const MCSubtargetInfo &STI) ++ : LoongArchTargetStreamer(S), STI(STI) { ++ MCAssembler &MCA = getStreamer().getAssembler(); ++ ++ // It's possible that MCObjectFileInfo isn't fully initialized at this point ++ // due to an initialization order problem where LLVMTargetMachine creates the ++ // target streamer before TargetLoweringObjectFile calls ++ // InitializeMCObjectFileInfo. There doesn't seem to be a single place that ++ // covers all cases so this statement covers most cases and direct object ++ // emission must call setPic() once MCObjectFileInfo has been initialized. The ++ // cases we don't handle here are covered by LoongArchAsmPrinter. ++ Pic = MCA.getContext().getObjectFileInfo()->isPositionIndependent(); ++ ++ // Set the header flags that we can in the constructor. ++ // FIXME: This is a fairly terrible hack. We set the rest ++ // of these in the destructor. The problem here is two-fold: ++ // ++ // a: Some of the eflags can be set/reset by directives. ++ // b: There aren't any usage paths that initialize the ABI ++ // pointer until after we initialize either an assembler ++ // or the target machine. ++ // We can fix this by making the target streamer construct ++ // the ABI, but this is fraught with wide ranging dependency ++ // issues as well. ++ unsigned EFlags = MCA.getELFHeaderEFlags(); ++ ++ // FIXME: Fix a dependency issue by instantiating the ABI object to some ++ // default based off the triple. The triple doesn't describe the target ++ // fully, but any external user of the API that uses the MCTargetStreamer ++ // would otherwise crash on assertion failure. ++ ++ ABI = LoongArchABIInfo( ++ STI.getTargetTriple().getArch() == Triple::ArchType::loongarch32 ++ ? LoongArchABIInfo::LP32() ++ : LoongArchABIInfo::LP64()); ++ ++ EFlags |= ELF::EF_LARCH_ABI; ++ MCA.setELFHeaderEFlags(EFlags); ++} ++ ++void LoongArchTargetELFStreamer::emitLabel(MCSymbol *S) { ++ auto *Symbol = cast(S); ++ getStreamer().getAssembler().registerSymbol(*Symbol); ++ uint8_t Type = Symbol->getType(); ++ if (Type != ELF::STT_FUNC) ++ return; ++ ++} ++ ++void LoongArchTargetELFStreamer::finish() { ++ MCAssembler &MCA = getStreamer().getAssembler(); ++ const MCObjectFileInfo &OFI = *MCA.getContext().getObjectFileInfo(); ++ ++ // .bss, .text and .data are always at least 16-byte aligned. ++ MCSection &TextSection = *OFI.getTextSection(); ++ MCA.registerSection(TextSection); ++ MCSection &DataSection = *OFI.getDataSection(); ++ MCA.registerSection(DataSection); ++ MCSection &BSSSection = *OFI.getBSSSection(); ++ MCA.registerSection(BSSSection); ++ ++ TextSection.setAlignment(std::max(Align(16), TextSection.getAlign())); ++ DataSection.setAlignment(std::max(Align(16), DataSection.getAlign())); ++ BSSSection.setAlignment(std::max(Align(16), BSSSection.getAlign())); ++ ++ if (RoundSectionSizes) { ++ // Make sections sizes a multiple of the alignment. This is useful for ++ // verifying the output of IAS against the output of other assemblers but ++ // it's not necessary to produce a correct object and increases section ++ // size. ++ MCStreamer &OS = getStreamer(); ++ for (MCSection &S : MCA) { ++ MCSectionELF &Section = static_cast(S); ++ ++ Align Alignment = Section.getAlign(); ++ OS.switchSection(&Section); ++ if (Section.useCodeAlign()) ++ OS.emitCodeAlignment(Alignment, &STI, Alignment.value()); ++ else ++ OS.emitValueToAlignment(Alignment, 0, 1, Alignment.value()); ++ } ++ } ++ ++ // Update e_header flags. See the FIXME and comment above in ++ // the constructor for a full rundown on this. ++ unsigned EFlags = MCA.getELFHeaderEFlags(); ++ ++ // ABI ++ // LP64 does not require any ABI bits. ++ if (getABI().IsLP32()) ++ EFlags |= ELF::EF_LARCH_ABI_LP32; ++ else if (getABI().IsLPX32()) ++ EFlags |= ELF::EF_LARCH_ABI_LPX32; ++ else ++ EFlags |= ELF::EF_LARCH_ABI_LP64; ++ ++ MCA.setELFHeaderEFlags(EFlags); ++} ++ ++MCELFStreamer &LoongArchTargetELFStreamer::getStreamer() { ++ return static_cast(Streamer); ++} ++ ++void LoongArchTargetELFStreamer::emitDirectiveOptionPic0() { ++ MCAssembler &MCA = getStreamer().getAssembler(); ++ unsigned Flags = MCA.getELFHeaderEFlags(); ++ // This option overrides other PIC options like -KPIC. ++ Pic = false; ++ ///XXX:Reloc no this flags ++ //Flags &= ~ELF::EF_LOONGARCH_PIC; ++ MCA.setELFHeaderEFlags(Flags); ++} + +-void LoongArchTargetStreamer::setTargetABI(LoongArchABI::ABI ABI) { +- assert(ABI != LoongArchABI::ABI_Unknown && +- "Improperly initialized target ABI"); +- TargetABI = ABI; ++void LoongArchTargetELFStreamer::emitDirectiveOptionPic2() { ++ MCAssembler &MCA = getStreamer().getAssembler(); ++ unsigned Flags = MCA.getELFHeaderEFlags(); ++ Pic = true; ++ // NOTE: We are following the GAS behaviour here which means the directive ++ // 'pic2' also sets the CPIC bit in the ELF header. This is different from ++ // what is stated in the SYSV ABI which consider the bits EF_LOONGARCH_PIC and ++ // EF_LOONGARCH_CPIC to be mutually exclusive. ++ ///XXX:Reloc no this flags ++ //Flags |= ELF::EF_LOONGARCH_PIC | ELF::EF_LOONGARCH_CPIC; ++ MCA.setELFHeaderEFlags(Flags); + } +diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchTargetStreamer.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchTargetStreamer.h +deleted file mode 100644 +index d4b1b2a3e..000000000 +--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchTargetStreamer.h ++++ /dev/null +@@ -1,27 +0,0 @@ +-//===-- LoongArchTargetStreamer.h - LoongArch Target Streamer --*- C++ -*--===// +-// +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +-// +-//===----------------------------------------------------------------------===// +- +-#ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHTARGETSTREAMER_H +-#define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHTARGETSTREAMER_H +- +-#include "LoongArch.h" +-#include "llvm/MC/MCStreamer.h" +-#include "llvm/MC/MCSubtargetInfo.h" +- +-namespace llvm { +-class LoongArchTargetStreamer : public MCTargetStreamer { +- LoongArchABI::ABI TargetABI = LoongArchABI::ABI_Unknown; +- +-public: +- LoongArchTargetStreamer(MCStreamer &S); +- void setTargetABI(LoongArchABI::ABI ABI); +- LoongArchABI::ABI getTargetABI() const { return TargetABI; } +-}; +- +-} // end namespace llvm +-#endif +diff --git a/llvm/lib/Target/LoongArch/TargetInfo/CMakeLists.txt b/llvm/lib/Target/LoongArch/TargetInfo/CMakeLists.txt +index e14360ff5..f53ddba40 100644 +--- a/llvm/lib/Target/LoongArch/TargetInfo/CMakeLists.txt ++++ b/llvm/lib/Target/LoongArch/TargetInfo/CMakeLists.txt +@@ -2,7 +2,6 @@ add_llvm_component_library(LLVMLoongArchInfo + LoongArchTargetInfo.cpp + + LINK_COMPONENTS +- MC + Support + + ADD_TO_COMPONENT +diff --git a/llvm/lib/Target/LoongArch/TargetInfo/LoongArchTargetInfo.cpp b/llvm/lib/Target/LoongArch/TargetInfo/LoongArchTargetInfo.cpp +index 1d6be4069..e6b845180 100644 +--- a/llvm/lib/Target/LoongArch/TargetInfo/LoongArchTargetInfo.cpp ++++ b/llvm/lib/Target/LoongArch/TargetInfo/LoongArchTargetInfo.cpp +@@ -1,4 +1,4 @@ +-//===-- LoongArchTargetInfo.cpp - LoongArch Target Implementation ---------===// ++//===-- LoongArchTargetInfo.cpp - LoongArch Target Implementation -------------------===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -21,10 +21,14 @@ Target &llvm::getTheLoongArch64Target() { + } + + extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchTargetInfo() { +- RegisterTarget X( +- getTheLoongArch32Target(), "loongarch32", "32-bit LoongArch", +- "LoongArch"); +- RegisterTarget Y( +- getTheLoongArch64Target(), "loongarch64", "64-bit LoongArch", +- "LoongArch"); ++#if 0 ++ //TODO: support it in futrue ++ RegisterTarget ++ X(getTheLoongArch32Target(), "loongarch32", "LoongArch (32-bit)", "LoongArch"); ++#endif ++ RegisterTarget ++ A(getTheLoongArch64Target(), "loongarch64", "LoongArch (64-bit)", ++ "LoongArch"); + } +diff --git a/llvm/lib/Target/LoongArch/TargetInfo/LoongArchTargetInfo.h b/llvm/lib/Target/LoongArch/TargetInfo/LoongArchTargetInfo.h +index b24cf8795..7dce2497f 100644 +--- a/llvm/lib/Target/LoongArch/TargetInfo/LoongArchTargetInfo.h ++++ b/llvm/lib/Target/LoongArch/TargetInfo/LoongArchTargetInfo.h +@@ -1,4 +1,4 @@ +-//===-- LoongArchTargetInfo.h - LoongArch Target Implementation -*- C++ -*-===// ++//===-- LoongArchTargetInfo.h - LoongArch Target Implementation -----------*- C++ -*-===// + // + // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + // See https://llvm.org/LICENSE.txt for license information. +@@ -16,6 +16,6 @@ class Target; + Target &getTheLoongArch32Target(); + Target &getTheLoongArch64Target(); + +-} // end namespace llvm ++} // namespace llvm + + #endif // LLVM_LIB_TARGET_LOONGARCH_TARGETINFO_LOONGARCHTARGETINFO_H +diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td +index c0e7eef8d..4c8b4287f 100644 +--- a/llvm/lib/Target/Mips/Mips64InstrInfo.td ++++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td +@@ -414,12 +414,10 @@ let isCodeGenOnly = 1, AdditionalPredicates = [NotInMicroMips] in { + let isCodeGenOnly = 1, rs = 0, shamt = 0 in { + def DSLL64_32 : FR<0x00, 0x3c, (outs GPR64:$rd), (ins GPR32:$rt), + "dsll\t$rd, $rt, 32", [], II_DSLL>, GPR_64; +- let isMoveReg = 1 in { +- def SLL64_32 : FR<0x0, 0x00, (outs GPR64:$rd), (ins GPR32:$rt), +- "sll\t$rd, $rt, 0", [], II_SLL>, GPR_64; +- def SLL64_64 : FR<0x0, 0x00, (outs GPR64:$rd), (ins GPR64:$rt), +- "sll\t$rd, $rt, 0", [], II_SLL>, GPR_64; +- } ++ def SLL64_32 : FR<0x0, 0x00, (outs GPR64:$rd), (ins GPR32:$rt), ++ "sll\t$rd, $rt, 0", [], II_SLL>, GPR_64; ++ def SLL64_64 : FR<0x0, 0x00, (outs GPR64:$rd), (ins GPR64:$rt), ++ "sll\t$rd, $rt, 0", [], II_SLL>, GPR_64; + } + + // We need the following pseudo instruction to avoid offset calculation for +diff --git a/llvm/lib/Target/Mips/MipsExpandPseudo.cpp b/llvm/lib/Target/Mips/MipsExpandPseudo.cpp +index 2c2554b5b..87acef0ec 100644 +--- a/llvm/lib/Target/Mips/MipsExpandPseudo.cpp ++++ b/llvm/lib/Target/Mips/MipsExpandPseudo.cpp +@@ -27,6 +27,12 @@ + + using namespace llvm; + ++static cl::opt ++EnableLoongson3FixLLSC("mips-fix-loongson3-llsc", cl::Hidden, ++ cl::desc("Work around loongson3 llsc erratum"), ++ cl::init(true)); ++ ++ + #define DEBUG_TYPE "mips-pseudo" + + namespace { +@@ -188,6 +194,21 @@ bool MipsExpandPseudo::expandAtomicCmpSwapSubword( + .addImm(ShiftImm); + } + ++ if (EnableLoongson3FixLLSC) { ++ bool Has_sync = false; ++ for (MachineBasicBlock::iterator MBBb = sinkMBB->begin(), MBBe = sinkMBB->end(); ++ MBBb != MBBe; ++MBBb) { ++ Has_sync |= MBBb->getOpcode() == Mips::SYNC ? true : false; ++ if (MBBb->mayLoad() || MBBb->mayStore()) ++ break; ++ } ++ ++ if (!Has_sync) { ++ MachineBasicBlock::iterator Pos = sinkMBB->begin(); ++ BuildMI(*sinkMBB, Pos, DL, TII->get(Mips::SYNC)).addImm(0); ++ } ++ } ++ + LivePhysRegs LiveRegs; + computeAndAddLiveIns(LiveRegs, *loop1MBB); + computeAndAddLiveIns(LiveRegs, *loop2MBB); +@@ -289,6 +310,20 @@ bool MipsExpandPseudo::expandAtomicCmpSwap(MachineBasicBlock &BB, + BuildMI(loop2MBB, DL, TII->get(BEQ)) + .addReg(Scratch, RegState::Kill).addReg(ZERO).addMBB(loop1MBB); + ++ if (EnableLoongson3FixLLSC) { ++ bool Has_sync = false; ++ for (MachineBasicBlock::iterator MBBb = exitMBB->begin(), MBBe = exitMBB->end(); ++ MBBb != MBBe; ++MBBb) { ++ Has_sync |= MBBb->getOpcode() == Mips::SYNC ? true : false; ++ if (MBBb->mayLoad() || MBBb->mayStore()) ++ break; ++ } ++ if (!Has_sync) { ++ MachineBasicBlock::iterator Pos = exitMBB->begin(); ++ BuildMI(*exitMBB, Pos, DL, TII->get(Mips::SYNC)).addImm(0); ++ } ++ } ++ + LivePhysRegs LiveRegs; + computeAndAddLiveIns(LiveRegs, *loop1MBB); + computeAndAddLiveIns(LiveRegs, *loop2MBB); +diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +index bd49875c9..ae362ae3b 100644 +--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp ++++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +@@ -336,17 +336,16 @@ bool RISCVAsmBackend::relaxDwarfCFA(MCDwarfCallFrameFragment &DF, + return true; + } + +-std::pair RISCVAsmBackend::relaxLEB128(MCLEBFragment &LF, +- MCAsmLayout &Layout, +- int64_t &Value) const { ++bool RISCVAsmBackend::relaxLEB128(MCLEBFragment &LF, MCAsmLayout &Layout, ++ int64_t &Value) const { + if (LF.isSigned()) +- return std::make_pair(false, false); ++ return false; + const MCExpr &Expr = LF.getValue(); + if (ULEB128Reloc) { + LF.getFixups().push_back( + MCFixup::create(0, &Expr, FK_Data_leb128, Expr.getLoc())); + } +- return std::make_pair(Expr.evaluateKnownAbsolute(Value, Layout), false); ++ return Expr.evaluateKnownAbsolute(Value, Layout); + } + + // Given a compressed control flow instruction this function returns +diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h +index 902b44bba..2ad6534ac 100644 +--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h ++++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h +@@ -100,8 +100,8 @@ public: + bool &WasRelaxed) const override; + bool relaxDwarfCFA(MCDwarfCallFrameFragment &DF, MCAsmLayout &Layout, + bool &WasRelaxed) const override; +- std::pair relaxLEB128(MCLEBFragment &LF, MCAsmLayout &Layout, +- int64_t &Value) const override; ++ bool relaxLEB128(MCLEBFragment &LF, MCAsmLayout &Layout, ++ int64_t &Value) const override; + + bool writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const override; +diff --git a/llvm/lib/TargetParser/CMakeLists.txt b/llvm/lib/TargetParser/CMakeLists.txt +index da1e352b0..2204b7098 100644 +--- a/llvm/lib/TargetParser/CMakeLists.txt ++++ b/llvm/lib/TargetParser/CMakeLists.txt +@@ -19,7 +19,6 @@ add_llvm_component_library(LLVMTargetParser + ARMTargetParser.cpp + CSKYTargetParser.cpp + Host.cpp +- LoongArchTargetParser.cpp + RISCVTargetParser.cpp + SubtargetFeature.cpp + TargetParser.cpp +diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp +index 848b531dd..3430aeda2 100644 +--- a/llvm/lib/TargetParser/Host.cpp ++++ b/llvm/lib/TargetParser/Host.cpp +@@ -1434,6 +1434,51 @@ StringRef sys::getHostCPUName() { + StringRef Content = P ? P->getBuffer() : ""; + return detail::getHostCPUNameForS390x(Content); + } ++#elif defined(__linux__) && defined(__loongarch__) ++// Reference to prid register definitions in arch/loongarch/include/asm/cpu.h ++// from kernel/linux-5.10 version. ++// loongarch prid register ++// +----------------+----------------+-----------+---------------------+ ++// | Reserved | Company ID | Series ID | Product ID | ++// +----------------+----------------+-----------+---------------------+ ++// 31 24 23 16 15 12 11 0 ++ ++#define PRID_COMP_MASK 0xff0000 ++#define PRID_COMP_LOONGSON 0x140000 ++#define PRID_IMP_MASK 0xff00 ++ ++#define PRID_SERIES_LA132 0x8000 /* Loongson 32bit */ ++#define PRID_SERIES_LA264 0xa000 /* Loongson 64bit, 2-issue */ ++#define PRID_SERIES_LA364 0xb000 /* Loongson 64bit, 3-issue */ ++#define PRID_SERIES_LA464 0xc000 /* Loongson 64bit, 4-issue */ ++#define PRID_SERIES_LA664 0xd000 /* Loongson 64bit, 6-issue */ ++ ++StringRef sys::getHostCPUName() { ++ // use prid to detect cpu name ++ unsigned CPUCFG_NUM = 0; // prid ++ unsigned prid; ++ ++ __asm__("cpucfg %[prid], %[CPUCFG_NUM]\n\t" ++ :[prid]"=r"(prid) ++ :[CPUCFG_NUM]"r"(CPUCFG_NUM)); ++ ++ if ((prid & PRID_COMP_MASK) == PRID_COMP_LOONGSON) {// for Loongson ++ switch (prid & PRID_IMP_MASK) { ++ case PRID_SERIES_LA132: // not support ++ return "loongarch32"; ++ case PRID_SERIES_LA264: ++ return "la264"; ++ case PRID_SERIES_LA364: ++ return "la364"; ++ case PRID_SERIES_LA464: ++ return "la464"; ++ case PRID_SERIES_LA664: ++ return "la664"; ++ } ++ } ++ ++ return "generic"; ++} + #elif defined(__MVS__) + StringRef sys::getHostCPUName() { + // Get pointer to Communications Vector Table (CVT). +@@ -1529,21 +1574,6 @@ StringRef sys::getHostCPUName() { + return "generic"; + } + } +-#elif defined(__loongarch__) +-StringRef sys::getHostCPUName() { +- // Use processor id to detect cpu name. +- uint32_t processor_id; +- __asm__("cpucfg %[prid], $zero\n\t" : [prid] "=r"(processor_id)); +- // Refer PRID_SERIES_MASK in linux kernel: arch/loongarch/include/asm/cpu.h. +- switch (processor_id & 0xf000) { +- case 0xc000: // Loongson 64bit, 4-issue +- return "la464"; +- // TODO: Others. +- default: +- break; +- } +- return "generic"; +-} + #elif defined(__riscv) + StringRef sys::getHostCPUName() { + #if defined(__linux__) +@@ -1955,23 +1985,6 @@ bool sys::getHostCPUFeatures(StringMap &Features) { + + return true; + } +-#elif defined(__linux__) && defined(__loongarch__) +-#include +-bool sys::getHostCPUFeatures(StringMap &Features) { +- unsigned long hwcap = getauxval(AT_HWCAP); +- bool HasFPU = hwcap & (1UL << 3); // HWCAP_LOONGARCH_FPU +- uint32_t cpucfg2 = 0x2; +- __asm__("cpucfg %[cpucfg2], %[cpucfg2]\n\t" : [cpucfg2] "+r"(cpucfg2)); +- +- Features["f"] = HasFPU && (cpucfg2 & (1U << 1)); // CPUCFG.2.FP_SP +- Features["d"] = HasFPU && (cpucfg2 & (1U << 2)); // CPUCFG.2.FP_DP +- +- Features["lsx"] = hwcap & (1UL << 4); // HWCAP_LOONGARCH_LSX +- Features["lasx"] = hwcap & (1UL << 5); // HWCAP_LOONGARCH_LASX +- Features["lvz"] = hwcap & (1UL << 9); // HWCAP_LOONGARCH_LVZ +- +- return true; +-} + #else + bool sys::getHostCPUFeatures(StringMap &Features) { return false; } + #endif +diff --git a/llvm/lib/TargetParser/LoongArchTargetParser.cpp b/llvm/lib/TargetParser/LoongArchTargetParser.cpp +deleted file mode 100644 +index 772d24c5c..000000000 +--- a/llvm/lib/TargetParser/LoongArchTargetParser.cpp ++++ /dev/null +@@ -1,60 +0,0 @@ +-//===-- LoongArchTargetParser - Parser for LoongArch features --*- C++ -*-====// +-// +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +-// +-//===----------------------------------------------------------------------===// +-// +-// This file implements a target parser to recognise LoongArch hardware features +-// such as CPU/ARCH and extension names. +-// +-//===----------------------------------------------------------------------===// +- +-#include "llvm/TargetParser/LoongArchTargetParser.h" +- +-using namespace llvm; +-using namespace llvm::LoongArch; +- +-const FeatureInfo AllFeatures[] = { +-#define LOONGARCH_FEATURE(NAME, KIND) {NAME, KIND}, +-#include "llvm/TargetParser/LoongArchTargetParser.def" +-}; +- +-const ArchInfo AllArchs[] = { +-#define LOONGARCH_ARCH(NAME, KIND, FEATURES) \ +- {NAME, LoongArch::ArchKind::KIND, FEATURES}, +-#include "llvm/TargetParser/LoongArchTargetParser.def" +-}; +- +-bool LoongArch::isValidArchName(StringRef Arch) { +- for (const auto A : AllArchs) +- if (A.Name == Arch) +- return true; +- return false; +-} +- +-bool LoongArch::getArchFeatures(StringRef Arch, +- std::vector &Features) { +- for (const auto A : AllArchs) { +- if (A.Name == Arch) { +- for (const auto F : AllFeatures) +- if ((A.Features & F.Kind) == F.Kind) +- Features.push_back(F.Name); +- return true; +- } +- } +- return false; +-} +- +-bool LoongArch::isValidCPUName(StringRef Name) { return isValidArchName(Name); } +- +-void LoongArch::fillValidCPUList(SmallVectorImpl &Values) { +- for (const auto A : AllArchs) +- Values.emplace_back(A.Name); +-} +- +-StringRef LoongArch::getDefaultArch(bool Is64Bit) { +- // TODO: use a real 32-bit arch name. +- return Is64Bit ? "loongarch64" : ""; +-} +diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp +index 0bbe8a3ce..737743d82 100644 +--- a/llvm/lib/TargetParser/Triple.cpp ++++ b/llvm/lib/TargetParser/Triple.cpp +@@ -293,11 +293,9 @@ StringRef Triple::getEnvironmentTypeName(EnvironmentType Kind) { + case GNU: return "gnu"; + case GNUABI64: return "gnuabi64"; + case GNUABIN32: return "gnuabin32"; ++ case GNUABILPX32: return "gnuabilpx32"; + case GNUEABI: return "gnueabi"; + case GNUEABIHF: return "gnueabihf"; +- case GNUF32: return "gnuf32"; +- case GNUF64: return "gnuf64"; +- case GNUSF: return "gnusf"; + case GNUX32: return "gnux32"; + case GNUILP32: return "gnu_ilp32"; + case Itanium: return "itanium"; +@@ -655,13 +653,11 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { + return StringSwitch(EnvironmentName) + .StartsWith("eabihf", Triple::EABIHF) + .StartsWith("eabi", Triple::EABI) ++ .StartsWith("gnuabilpx32", Triple::GNUABILPX32) + .StartsWith("gnuabin32", Triple::GNUABIN32) + .StartsWith("gnuabi64", Triple::GNUABI64) + .StartsWith("gnueabihf", Triple::GNUEABIHF) + .StartsWith("gnueabi", Triple::GNUEABI) +- .StartsWith("gnuf32", Triple::GNUF32) +- .StartsWith("gnuf64", Triple::GNUF64) +- .StartsWith("gnusf", Triple::GNUSF) + .StartsWith("gnux32", Triple::GNUX32) + .StartsWith("gnu_ilp32", Triple::GNUILP32) + .StartsWith("code16", Triple::CODE16) +diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp +index 633fcb331..69282f0e6 100644 +--- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp ++++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp +@@ -1203,7 +1203,7 @@ static const unsigned kARMJumpTableEntrySize = 4; + static const unsigned kARMBTIJumpTableEntrySize = 8; + static const unsigned kARMv6MJumpTableEntrySize = 16; + static const unsigned kRISCVJumpTableEntrySize = 8; +-static const unsigned kLOONGARCH64JumpTableEntrySize = 8; ++static const unsigned kLOONGARCH64JumpTableEntrySize = 4; + + bool LowerTypeTestsModule::hasBranchTargetEnforcement() { + if (HasBranchTargetEnforcement == -1) { +@@ -1311,8 +1311,8 @@ void LowerTypeTestsModule::createJumpTableEntry( + JumpTableArch == Triple::riscv64) { + AsmOS << "tail $" << ArgIndex << "@plt\n"; + } else if (JumpTableArch == Triple::loongarch64) { +- AsmOS << "pcalau12i $$t0, %pc_hi20($" << ArgIndex << ")\n" +- << "jirl $$r0, $$t0, %pc_lo12($" << ArgIndex << ")\n"; ++ // FIXME: use large code model insn seq: pcaddu18i+jirl. ++ AsmOS << "b $" << ArgIndex << "\n"; + } else { + report_fatal_error("Unsupported architecture for jump tables"); + } +diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +index caab98c73..b2b1b8cba 100644 +--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp ++++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +@@ -105,8 +105,8 @@ static const uint64_t kSystemZ_ShadowOffset64 = 1ULL << 52; + static const uint64_t kMIPS_ShadowOffsetN32 = 1ULL << 29; + static const uint64_t kMIPS32_ShadowOffset32 = 0x0aaa0000; + static const uint64_t kMIPS64_ShadowOffset64 = 1ULL << 37; ++static const uint64_t kLoongArch64_ShadowOffset64 = 1ULL << 37; + static const uint64_t kAArch64_ShadowOffset64 = 1ULL << 36; +-static const uint64_t kLoongArch64_ShadowOffset64 = 1ULL << 46; + static const uint64_t kRISCV64_ShadowOffset64 = 0xd55550000; + static const uint64_t kFreeBSD_ShadowOffset32 = 1ULL << 30; + static const uint64_t kFreeBSD_ShadowOffset64 = 1ULL << 46; +@@ -491,10 +491,10 @@ static ShadowMapping getShadowMapping(const Triple &TargetTriple, int LongSize, + bool IsMIPSN32ABI = TargetTriple.getEnvironment() == Triple::GNUABIN32; + bool IsMIPS32 = TargetTriple.isMIPS32(); + bool IsMIPS64 = TargetTriple.isMIPS64(); ++ bool IsLoongArch64 = TargetTriple.isLoongArch64(); + bool IsArmOrThumb = TargetTriple.isARM() || TargetTriple.isThumb(); + bool IsAArch64 = TargetTriple.getArch() == Triple::aarch64 || + TargetTriple.getArch() == Triple::aarch64_be; +- bool IsLoongArch64 = TargetTriple.isLoongArch64(); + bool IsRISCV64 = TargetTriple.getArch() == Triple::riscv64; + bool IsWindows = TargetTriple.isOSWindows(); + bool IsFuchsia = TargetTriple.isOSFuchsia(); +@@ -560,14 +560,14 @@ static ShadowMapping getShadowMapping(const Triple &TargetTriple, int LongSize, + Mapping.Offset = kWindowsShadowOffset64; + } else if (IsMIPS64) + Mapping.Offset = kMIPS64_ShadowOffset64; +- else if (IsIOS) ++ else if (IsLoongArch64) { ++ Mapping.Offset = kLoongArch64_ShadowOffset64; ++ } else if (IsIOS) + Mapping.Offset = kDynamicShadowSentinel; + else if (IsMacOS && IsAArch64) + Mapping.Offset = kDynamicShadowSentinel; + else if (IsAArch64) + Mapping.Offset = kAArch64_ShadowOffset64; +- else if (IsLoongArch64) +- Mapping.Offset = kLoongArch64_ShadowOffset64; + else if (IsRISCV64) + Mapping.Offset = kRISCV64_ShadowOffset64; + else if (IsAMDGPU) +@@ -586,12 +586,12 @@ static ShadowMapping getShadowMapping(const Triple &TargetTriple, int LongSize, + } + + // OR-ing shadow offset if more efficient (at least on x86) if the offset +- // is a power of two, but on ppc64 and loongarch64 we have to use add since +- // the shadow offset is not necessarily 1/8-th of the address space. On +- // SystemZ, we could OR the constant in a single instruction, but it's more ++ // is a power of two, but on ppc64 we have to use add since the shadow ++ // offset is not necessary 1/8-th of the address space. On SystemZ, ++ // we could OR the constant in a single instruction, but it's more + // efficient to load it once and use indexed addressing. + Mapping.OrShadowOffset = !IsAArch64 && !IsPPC64 && !IsSystemZ && !IsPS && +- !IsRISCV64 && !IsLoongArch64 && ++ !IsRISCV64 && + !(Mapping.Offset & (Mapping.Offset - 1)) && + Mapping.Offset != kDynamicShadowSentinel; + bool IsAndroidWithIfuncSupport = +diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +index 2ba127bba..b85b5e863 100644 +--- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp ++++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +@@ -305,14 +305,6 @@ const MemoryMapParams Linux_X86_64_MemoryMapParams = { + }; + // NOLINTEND(readability-identifier-naming) + +-// loongarch64 Linux +-const MemoryMapParams Linux_LoongArch64_MemoryMapParams = { +- 0, // AndMask (not used) +- 0x500000000000, // XorMask +- 0, // ShadowBase (not used) +- 0x100000000000, // OriginBase +-}; +- + namespace { + + class DFSanABIList { +@@ -1136,9 +1128,6 @@ bool DataFlowSanitizer::initializeModule(Module &M) { + case Triple::x86_64: + MapParams = &Linux_X86_64_MemoryMapParams; + break; +- case Triple::loongarch64: +- MapParams = &Linux_LoongArch64_MemoryMapParams; +- break; + default: + report_fatal_error("unsupported architecture"); + } +diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +index 15bca5388..8934b2a65 100644 +--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp ++++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +@@ -406,6 +406,14 @@ static const MemoryMapParams Linux_X86_64_MemoryMapParams = { + 0x100000000000, // OriginBase + }; + ++// loongarch64 Linux ++static const MemoryMapParams Linux_LOONGARCH64_MemoryMapParams = { ++ 0, // AndMask (not used) ++ 0x008000000000, // XorMask ++ 0, // ShadowBase (not used) ++ 0x002000000000, // OriginBase ++}; ++ + // mips64 Linux + static const MemoryMapParams Linux_MIPS64_MemoryMapParams = { + 0, // AndMask (not used) +@@ -438,14 +446,6 @@ static const MemoryMapParams Linux_AArch64_MemoryMapParams = { + 0x0200000000000, // OriginBase + }; + +-// loongarch64 Linux +-static const MemoryMapParams Linux_LoongArch64_MemoryMapParams = { +- 0, // AndMask (not used) +- 0x500000000000, // XorMask +- 0, // ShadowBase (not used) +- 0x100000000000, // OriginBase +-}; +- + // aarch64 FreeBSD + static const MemoryMapParams FreeBSD_AArch64_MemoryMapParams = { + 0x1800000000000, // AndMask +@@ -483,6 +483,11 @@ static const PlatformMemoryMapParams Linux_X86_MemoryMapParams = { + &Linux_X86_64_MemoryMapParams, + }; + ++static const PlatformMemoryMapParams Linux_LOONGARCH_MemoryMapParams = { ++ nullptr, ++ &Linux_LOONGARCH64_MemoryMapParams, ++}; ++ + static const PlatformMemoryMapParams Linux_MIPS_MemoryMapParams = { + nullptr, + &Linux_MIPS64_MemoryMapParams, +@@ -503,11 +508,6 @@ static const PlatformMemoryMapParams Linux_ARM_MemoryMapParams = { + &Linux_AArch64_MemoryMapParams, + }; + +-static const PlatformMemoryMapParams Linux_LoongArch_MemoryMapParams = { +- nullptr, +- &Linux_LoongArch64_MemoryMapParams, +-}; +- + static const PlatformMemoryMapParams FreeBSD_ARM_MemoryMapParams = { + nullptr, + &FreeBSD_AArch64_MemoryMapParams, +@@ -551,6 +551,7 @@ private: + friend struct MemorySanitizerVisitor; + friend struct VarArgHelperBase; + friend struct VarArgAMD64Helper; ++ friend struct VarArgLoongArch64Helper; + friend struct VarArgMIPS64Helper; + friend struct VarArgAArch64Helper; + friend struct VarArgPowerPC64Helper; +@@ -1010,6 +1011,9 @@ void MemorySanitizer::initializeModule(Module &M) { + case Triple::x86: + MapParams = Linux_X86_MemoryMapParams.bits32; + break; ++ case Triple::loongarch64: ++ MapParams = Linux_LOONGARCH_MemoryMapParams.bits64; ++ break; + case Triple::mips64: + case Triple::mips64el: + MapParams = Linux_MIPS_MemoryMapParams.bits64; +@@ -1025,9 +1029,6 @@ void MemorySanitizer::initializeModule(Module &M) { + case Triple::aarch64_be: + MapParams = Linux_ARM_MemoryMapParams.bits64; + break; +- case Triple::loongarch64: +- MapParams = Linux_LoongArch_MemoryMapParams.bits64; +- break; + default: + report_fatal_error("unsupported architecture"); + } +@@ -4977,8 +4978,84 @@ struct VarArgAMD64Helper : public VarArgHelperBase { + } + }; + ++/// LoongArch64-specific implementation of VarArgHelper. ++struct VarArgLoongArch64Helper : public VarArgHelperBase { ++ AllocaInst *VAArgTLSCopy = nullptr; ++ Value *VAArgSize = nullptr; ++ ++ VarArgLoongArch64Helper(Function &F, MemorySanitizer &MS, ++ MemorySanitizerVisitor &MSV) ++ : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/8) {} ++ ++ void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override { ++ unsigned VAArgOffset = 0; ++ const DataLayout &DL = F.getParent()->getDataLayout(); ++ for (Value *A : ++ llvm::drop_begin(CB.args(), CB.getFunctionType()->getNumParams())) { ++ Triple TargetTriple(F.getParent()->getTargetTriple()); ++ Value *Base; ++ uint64_t ArgSize = DL.getTypeAllocSize(A->getType()); ++ Base = getShadowPtrForVAArgument(A->getType(), IRB, VAArgOffset, ArgSize); ++ VAArgOffset += ArgSize; ++ VAArgOffset = alignTo(VAArgOffset, 8); ++ if (!Base) ++ continue; ++ IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment); ++ } ++ ++ Constant *TotalVAArgSize = ConstantInt::get(IRB.getInt64Ty(), VAArgOffset); ++ // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of ++ // a new class member i.e. it is the total size of all VarArgs. ++ IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS); ++ } ++ ++ void finalizeInstrumentation() override { ++ assert(!VAArgSize && !VAArgTLSCopy && ++ "finalizeInstrumentation called twice"); ++ IRBuilder<> IRB(MSV.FnPrologueEnd); ++ VAArgSize = IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS); ++ Value *CopySize = ++ IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, 0), VAArgSize); ++ ++ if (!VAStartInstrumentationList.empty()) { ++ // If there is a va_start in this function, make a backup copy of ++ // va_arg_tls somewhere in the function entry block. ++ VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize); ++ VAArgTLSCopy->setAlignment(kShadowTLSAlignment); ++ IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()), ++ CopySize, kShadowTLSAlignment, false); ++ ++ Value *SrcSize = IRB.CreateBinaryIntrinsic( ++ Intrinsic::umin, CopySize, ++ ConstantInt::get(MS.IntptrTy, kParamTLSSize)); ++ IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS, ++ kShadowTLSAlignment, SrcSize); ++ } ++ ++ // Instrument va_start. ++ // Copy va_list shadow from the backup copy of the TLS contents. ++ for (size_t i = 0, n = VAStartInstrumentationList.size(); i < n; i++) { ++ CallInst *OrigInst = VAStartInstrumentationList[i]; ++ NextNodeIRBuilder IRB(OrigInst); ++ Value *VAListTag = OrigInst->getArgOperand(0); ++ Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C); // i64* ++ Value *RegSaveAreaPtrPtr = ++ IRB.CreateIntToPtr(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy), ++ PointerType::get(RegSaveAreaPtrTy, 0)); ++ Value *RegSaveAreaPtr = ++ IRB.CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr); ++ Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr; ++ const Align Alignment = Align(8); ++ std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) = ++ MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(), ++ Alignment, /*isStore*/ true); ++ IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment, ++ CopySize); ++ } ++ } ++}; ++ + /// MIPS64-specific implementation of VarArgHelper. +-/// NOTE: This is also used for LoongArch64. + struct VarArgMIPS64Helper : public VarArgHelperBase { + AllocaInst *VAArgTLSCopy = nullptr; + Value *VAArgSize = nullptr; +@@ -5734,10 +5811,6 @@ struct VarArgSystemZHelper : public VarArgHelperBase { + } + }; + +-// Loongarch64 is not a MIPS, but the current vargs calling convention matches +-// the MIPS. +-using VarArgLoongArch64Helper = VarArgMIPS64Helper; +- + /// A no-op implementation of VarArgHelper. + struct VarArgNoOpHelper : public VarArgHelper { + VarArgNoOpHelper(Function &F, MemorySanitizer &MS, +@@ -5770,7 +5843,7 @@ static VarArgHelper *CreateVarArgHelper(Function &Func, MemorySanitizer &Msan, + return new VarArgPowerPC64Helper(Func, Msan, Visitor); + else if (TargetTriple.getArch() == Triple::systemz) + return new VarArgSystemZHelper(Func, Msan, Visitor); +- else if (TargetTriple.isLoongArch64()) ++ else if (TargetTriple.getArch() == Triple::loongarch64) + return new VarArgLoongArch64Helper(Func, Msan, Visitor); + else + return new VarArgNoOpHelper(Func, Msan, Visitor); +diff --git a/llvm/lib/XRay/InstrumentationMap.cpp b/llvm/lib/XRay/InstrumentationMap.cpp +index 800f0a0f4..639e029a6 100644 +--- a/llvm/lib/XRay/InstrumentationMap.cpp ++++ b/llvm/lib/XRay/InstrumentationMap.cpp +@@ -60,8 +60,8 @@ loadObj(StringRef Filename, object::OwningBinary &ObjFile, + // Find the section named "xray_instr_map". + if ((!ObjFile.getBinary()->isELF() && !ObjFile.getBinary()->isMachO()) || + !(ObjFile.getBinary()->getArch() == Triple::x86_64 || +- ObjFile.getBinary()->getArch() == Triple::loongarch64 || + ObjFile.getBinary()->getArch() == Triple::ppc64le || ++ ObjFile.getBinary()->getArch() == Triple::loongarch64 || + ObjFile.getBinary()->getArch() == Triple::arm || + ObjFile.getBinary()->getArch() == Triple::aarch64)) + return make_error( +diff --git a/llvm/test/CodeGen/LoongArch/O0-pipeline.ll b/llvm/test/CodeGen/LoongArch/O0-pipeline.ll +deleted file mode 100644 +index 84d235d78..000000000 +--- a/llvm/test/CodeGen/LoongArch/O0-pipeline.ll ++++ /dev/null +@@ -1,77 +0,0 @@ +-;; When EXPENSIVE_CHECKS are enabled, the machine verifier appears between each +-;; pass. Ignore it with 'grep -v'. +-; RUN: llc --mtriple=loongarch32 -O0 --debug-pass=Structure %s -o /dev/null 2>&1 | \ +-; RUN: grep -v "Verify generated machine code" | FileCheck %s +-; RUN: llc --mtriple=loongarch64 -O0 --debug-pass=Structure %s -o /dev/null 2>&1 | \ +-; RUN: grep -v "Verify generated machine code" | FileCheck %s +- +-; REQUIRES: asserts +- +-; CHECK-LABEL: Pass Arguments: +-; CHECK-NEXT: Target Library Information +-; CHECK-NEXT: Target Pass Configuration +-; CHECK-NEXT: Machine Module Information +-; CHECK-NEXT: Target Transform Information +-; CHECK-NEXT: Create Garbage Collector Module Metadata +-; CHECK-NEXT: Assumption Cache Tracker +-; CHECK-NEXT: Profile summary info +-; CHECK-NEXT: Machine Branch Probability Analysis +-; CHECK-NEXT: ModulePass Manager +-; CHECK-NEXT: Pre-ISel Intrinsic Lowering +-; CHECK-NEXT: FunctionPass Manager +-; CHECK-NEXT: Expand large div/rem +-; CHECK-NEXT: Expand large fp convert +-; CHECK-NEXT: Expand Atomic instructions +-; CHECK-NEXT: Module Verifier +-; CHECK-NEXT: Lower Garbage Collection Instructions +-; CHECK-NEXT: Shadow Stack GC Lowering +-; CHECK-NEXT: Lower constant intrinsics +-; CHECK-NEXT: Remove unreachable blocks from the CFG +-; CHECK-NEXT: Expand vector predication intrinsics +-; CHECK-NEXT: Scalarize Masked Memory Intrinsics +-; CHECK-NEXT: Expand reduction intrinsics +-; CHECK-NEXT: Exception handling preparation +-; CHECK-NEXT: Prepare callbr +-; CHECK-NEXT: Safe Stack instrumentation pass +-; CHECK-NEXT: Insert stack protectors +-; CHECK-NEXT: Module Verifier +-; CHECK-NEXT: Dominator Tree Construction +-; CHECK-NEXT: Basic Alias Analysis (stateless AA impl) +-; CHECK-NEXT: Function Alias Analysis Results +-; CHECK-NEXT: Natural Loop Information +-; CHECK-NEXT: Post-Dominator Tree Construction +-; CHECK-NEXT: Branch Probability Analysis +-; CHECK-NEXT: Assignment Tracking Analysis +-; CHECK-NEXT: Lazy Branch Probability Analysis +-; CHECK-NEXT: Lazy Block Frequency Analysis +-; CHECK-NEXT: LoongArch DAG->DAG Pattern Instruction Selection +-; CHECK-NEXT: Finalize ISel and expand pseudo-instructions +-; CHECK-NEXT: Local Stack Slot Allocation +-; CHECK-NEXT: LoongArch Pre-RA pseudo instruction expansion pass +-; CHECK-NEXT: Eliminate PHI nodes for register allocation +-; CHECK-NEXT: Two-Address instruction pass +-; CHECK-NEXT: Fast Register Allocator +-; CHECK-NEXT: Remove Redundant DEBUG_VALUE analysis +-; CHECK-NEXT: Fixup Statepoint Caller Saved +-; CHECK-NEXT: Lazy Machine Block Frequency Analysis +-; CHECK-NEXT: Machine Optimization Remark Emitter +-; CHECK-NEXT: Prologue/Epilogue Insertion & Frame Finalization +-; CHECK-NEXT: Post-RA pseudo instruction expansion pass +-; CHECK-NEXT: Analyze Machine Code For Garbage Collection +-; CHECK-NEXT: Insert fentry calls +-; CHECK-NEXT: Insert XRay ops +-; CHECK-NEXT: Implement the 'patchable-function' attribute +-; CHECK-NEXT: Branch relaxation pass +-; CHECK-NEXT: Contiguously Lay Out Funclets +-; CHECK-NEXT: StackMap Liveness Analysis +-; CHECK-NEXT: Live DEBUG_VALUE analysis +-; CHECK-NEXT: Machine Sanitizer Binary Metadata +-; CHECK-NEXT: Lazy Machine Block Frequency Analysis +-; CHECK-NEXT: Machine Optimization Remark Emitter +-; CHECK-NEXT: Stack Frame Layout Analysis +-; CHECK-NEXT: LoongArch pseudo instruction expansion pass +-; CHECK-NEXT: LoongArch atomic pseudo instruction expansion pass +-; CHECK-NEXT: Lazy Machine Block Frequency Analysis +-; CHECK-NEXT: Machine Optimization Remark Emitter +-; CHECK-NEXT: LoongArch Assembly Printer +-; CHECK-NEXT: Free MachineFunction +diff --git a/llvm/test/CodeGen/LoongArch/addrspacecast.ll b/llvm/test/CodeGen/LoongArch/addrspacecast.ll +deleted file mode 100644 +index 787556233..000000000 +--- a/llvm/test/CodeGen/LoongArch/addrspacecast.ll ++++ /dev/null +@@ -1,47 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --verify-machineinstrs < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s | FileCheck %s --check-prefix=LA64 +- +-define void @cast0(ptr addrspace(1) %ptr) { +-; LA32-LABEL: cast0: +-; LA32: # %bb.0: +-; LA32-NEXT: st.w $zero, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: cast0: +-; LA64: # %bb.0: +-; LA64-NEXT: st.w $zero, $a0, 0 +-; LA64-NEXT: ret +- %ptr0 = addrspacecast ptr addrspace(1) %ptr to ptr addrspace(0) +- store i32 0, ptr %ptr0 +- ret void +-} +- +-define void @cast1(ptr %ptr) { +-; LA32-LABEL: cast1: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: bl %plt(foo) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: cast1: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: .cfi_def_cfa_offset 16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: bl %plt(foo) +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %castptr = addrspacecast ptr %ptr to ptr addrspace(10) +- call void @foo(ptr addrspace(10) %castptr) +- ret void +-} +- +-declare void @foo(ptr addrspace(10)) +diff --git a/llvm/test/CodeGen/LoongArch/align.ll b/llvm/test/CodeGen/LoongArch/align.ll +new file mode 100644 +index 000000000..c5b08dbd4 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/align.ll +@@ -0,0 +1,8 @@ ++; RUN: llc -mtriple=loongarch64 %s -o - | FileCheck %s ++ ++define void @foo() { ++;CHECK: .p2align 2 ++;CHECK: foo: ++entry: ++ ret void ++} +diff --git a/llvm/test/CodeGen/LoongArch/alloca.ll b/llvm/test/CodeGen/LoongArch/alloca.ll +deleted file mode 100644 +index d766be6aa..000000000 +--- a/llvm/test/CodeGen/LoongArch/alloca.ll ++++ /dev/null +@@ -1,185 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --verify-machineinstrs < %s \ +-; RUN: | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s \ +-; RUN: | FileCheck %s --check-prefix=LA64 +- +-declare void @notdead(ptr) +- +-;; These tests must ensure the stack pointer is restored using the frame +-;; pointer +- +-define void @simple_alloca(i32 %n) nounwind { +-; LA32-LABEL: simple_alloca: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: st.w $fp, $sp, 8 # 4-byte Folded Spill +-; LA32-NEXT: addi.w $fp, $sp, 16 +-; LA32-NEXT: addi.w $a0, $a0, 15 +-; LA32-NEXT: bstrins.w $a0, $zero, 3, 0 +-; LA32-NEXT: sub.w $a0, $sp, $a0 +-; LA32-NEXT: move $sp, $a0 +-; LA32-NEXT: bl %plt(notdead) +-; LA32-NEXT: addi.w $sp, $fp, -16 +-; LA32-NEXT: ld.w $fp, $sp, 8 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: simple_alloca: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: st.d $fp, $sp, 0 # 8-byte Folded Spill +-; LA64-NEXT: addi.d $fp, $sp, 16 +-; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 +-; LA64-NEXT: addi.d $a0, $a0, 15 +-; LA64-NEXT: bstrpick.d $a0, $a0, 32, 4 +-; LA64-NEXT: slli.d $a0, $a0, 4 +-; LA64-NEXT: sub.d $a0, $sp, $a0 +-; LA64-NEXT: move $sp, $a0 +-; LA64-NEXT: bl %plt(notdead) +-; LA64-NEXT: addi.d $sp, $fp, -16 +-; LA64-NEXT: ld.d $fp, $sp, 0 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %1 = alloca i8, i32 %n +- call void @notdead(ptr %1) +- ret void +-} +- +-declare ptr @llvm.stacksave() +-declare void @llvm.stackrestore(ptr) +- +-define void @scoped_alloca(i32 %n) nounwind { +-; LA32-LABEL: scoped_alloca: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: st.w $fp, $sp, 8 # 4-byte Folded Spill +-; LA32-NEXT: st.w $s0, $sp, 4 # 4-byte Folded Spill +-; LA32-NEXT: addi.w $fp, $sp, 16 +-; LA32-NEXT: move $s0, $sp +-; LA32-NEXT: addi.w $a0, $a0, 15 +-; LA32-NEXT: bstrins.w $a0, $zero, 3, 0 +-; LA32-NEXT: sub.w $a0, $sp, $a0 +-; LA32-NEXT: move $sp, $a0 +-; LA32-NEXT: bl %plt(notdead) +-; LA32-NEXT: move $sp, $s0 +-; LA32-NEXT: addi.w $sp, $fp, -16 +-; LA32-NEXT: ld.w $s0, $sp, 4 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $fp, $sp, 8 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: scoped_alloca: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -32 +-; LA64-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill +-; LA64-NEXT: st.d $fp, $sp, 16 # 8-byte Folded Spill +-; LA64-NEXT: st.d $s0, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: addi.d $fp, $sp, 32 +-; LA64-NEXT: move $s0, $sp +-; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 +-; LA64-NEXT: addi.d $a0, $a0, 15 +-; LA64-NEXT: bstrpick.d $a0, $a0, 32, 4 +-; LA64-NEXT: slli.d $a0, $a0, 4 +-; LA64-NEXT: sub.d $a0, $sp, $a0 +-; LA64-NEXT: move $sp, $a0 +-; LA64-NEXT: bl %plt(notdead) +-; LA64-NEXT: move $sp, $s0 +-; LA64-NEXT: addi.d $sp, $fp, -32 +-; LA64-NEXT: ld.d $s0, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $fp, $sp, 16 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 32 +-; LA64-NEXT: ret +- %sp = call ptr @llvm.stacksave() +- %addr = alloca i8, i32 %n +- call void @notdead(ptr %addr) +- call void @llvm.stackrestore(ptr %sp) +- ret void +-} +- +-declare void @func(ptr, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) +- +-;; Check that outgoing arguments passed on the stack do not corrupt a +-;; variable-sized stack object. +-define void @alloca_callframe(i32 %n) nounwind { +-; LA32-LABEL: alloca_callframe: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: st.w $fp, $sp, 8 # 4-byte Folded Spill +-; LA32-NEXT: addi.w $fp, $sp, 16 +-; LA32-NEXT: addi.w $a0, $a0, 15 +-; LA32-NEXT: bstrins.w $a0, $zero, 3, 0 +-; LA32-NEXT: sub.w $a0, $sp, $a0 +-; LA32-NEXT: move $sp, $a0 +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: ori $a1, $zero, 12 +-; LA32-NEXT: st.w $a1, $sp, 12 +-; LA32-NEXT: ori $a1, $zero, 11 +-; LA32-NEXT: st.w $a1, $sp, 8 +-; LA32-NEXT: ori $a1, $zero, 10 +-; LA32-NEXT: st.w $a1, $sp, 4 +-; LA32-NEXT: ori $a1, $zero, 9 +-; LA32-NEXT: st.w $a1, $sp, 0 +-; LA32-NEXT: ori $a1, $zero, 2 +-; LA32-NEXT: ori $a2, $zero, 3 +-; LA32-NEXT: ori $a3, $zero, 4 +-; LA32-NEXT: ori $a4, $zero, 5 +-; LA32-NEXT: ori $a5, $zero, 6 +-; LA32-NEXT: ori $a6, $zero, 7 +-; LA32-NEXT: ori $a7, $zero, 8 +-; LA32-NEXT: bl %plt(func) +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: addi.w $sp, $fp, -16 +-; LA32-NEXT: ld.w $fp, $sp, 8 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: alloca_callframe: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: st.d $fp, $sp, 0 # 8-byte Folded Spill +-; LA64-NEXT: addi.d $fp, $sp, 16 +-; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 +-; LA64-NEXT: addi.d $a0, $a0, 15 +-; LA64-NEXT: bstrpick.d $a0, $a0, 32, 4 +-; LA64-NEXT: slli.d $a0, $a0, 4 +-; LA64-NEXT: sub.d $a0, $sp, $a0 +-; LA64-NEXT: move $sp, $a0 +-; LA64-NEXT: addi.d $sp, $sp, -32 +-; LA64-NEXT: ori $a1, $zero, 12 +-; LA64-NEXT: st.d $a1, $sp, 24 +-; LA64-NEXT: ori $a1, $zero, 11 +-; LA64-NEXT: st.d $a1, $sp, 16 +-; LA64-NEXT: ori $a1, $zero, 10 +-; LA64-NEXT: st.d $a1, $sp, 8 +-; LA64-NEXT: ori $a1, $zero, 9 +-; LA64-NEXT: st.d $a1, $sp, 0 +-; LA64-NEXT: ori $a1, $zero, 2 +-; LA64-NEXT: ori $a2, $zero, 3 +-; LA64-NEXT: ori $a3, $zero, 4 +-; LA64-NEXT: ori $a4, $zero, 5 +-; LA64-NEXT: ori $a5, $zero, 6 +-; LA64-NEXT: ori $a6, $zero, 7 +-; LA64-NEXT: ori $a7, $zero, 8 +-; LA64-NEXT: bl %plt(func) +-; LA64-NEXT: addi.d $sp, $sp, 32 +-; LA64-NEXT: addi.d $sp, $fp, -16 +-; LA64-NEXT: ld.d $fp, $sp, 0 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %1 = alloca i8, i32 %n +- call void @func(ptr %1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, +- i32 9, i32 10, i32 11, i32 12) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/alsl.ll b/llvm/test/CodeGen/LoongArch/alsl.ll +deleted file mode 100644 +index 650f504dc..000000000 +--- a/llvm/test/CodeGen/LoongArch/alsl.ll ++++ /dev/null +@@ -1,363 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-define i8 @alsl_i8(i8 signext %a, i8 signext %b) nounwind { +-; LA32-LABEL: alsl_i8: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: alsl.w $a0, $a0, $a1, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: alsl_i8: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: alsl.d $a0, $a0, $a1, 1 +-; LA64-NEXT: ret +-entry: +- %mul = mul nsw i8 %a, 2 +- %add = add nsw i8 %b, %mul +- ret i8 %add +-} +- +-define i16 @alsl_i16(i16 signext %a, i16 signext %b) nounwind { +-; LA32-LABEL: alsl_i16: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: alsl.w $a0, $a0, $a1, 2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: alsl_i16: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: alsl.d $a0, $a0, $a1, 2 +-; LA64-NEXT: ret +-entry: +- %mul = mul nsw i16 %a, 4 +- %add = add nsw i16 %b, %mul +- ret i16 %add +-} +- +-define i32 @alsl_i32(i32 signext %a, i32 signext %b) nounwind { +-; LA32-LABEL: alsl_i32: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: alsl.w $a0, $a0, $a1, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: alsl_i32: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: alsl.d $a0, $a0, $a1, 3 +-; LA64-NEXT: ret +-entry: +- %mul = mul nsw i32 %a, 8 +- %add = add nsw i32 %b, %mul +- ret i32 %add +-} +- +-define i64 @alsl_i64(i64 signext %a, i64 signext %b) nounwind { +-; LA32-LABEL: alsl_i64: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: slli.w $a1, $a1, 4 +-; LA32-NEXT: srli.w $a4, $a0, 28 +-; LA32-NEXT: or $a1, $a1, $a4 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: alsl.w $a0, $a0, $a2, 4 +-; LA32-NEXT: sltu $a2, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a1, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: alsl_i64: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: alsl.d $a0, $a0, $a1, 4 +-; LA64-NEXT: ret +-entry: +- %mul = mul nsw i64 %a, 16 +- %add = add nsw i64 %b, %mul +- ret i64 %add +-} +- +-define i32 @alsl_zext_i8(i8 signext %a, i8 signext %b) nounwind { +-; LA32-LABEL: alsl_zext_i8: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: alsl.w $a0, $a0, $a1, 1 +-; LA32-NEXT: andi $a0, $a0, 255 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: alsl_zext_i8: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: alsl.d $a0, $a0, $a1, 1 +-; LA64-NEXT: andi $a0, $a0, 255 +-; LA64-NEXT: ret +-entry: +- %mul = mul nsw i8 %a, 2 +- %add = add nsw i8 %b, %mul +- %zext = zext i8 %add to i32 +- ret i32 %zext +-} +- +-define i32 @alsl_zext_i16(i16 signext %a, i16 signext %b) nounwind { +-; LA32-LABEL: alsl_zext_i16: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: alsl.w $a0, $a0, $a1, 2 +-; LA32-NEXT: bstrpick.w $a0, $a0, 15, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: alsl_zext_i16: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: alsl.d $a0, $a0, $a1, 2 +-; LA64-NEXT: bstrpick.d $a0, $a0, 15, 0 +-; LA64-NEXT: ret +-entry: +- %mul = mul nsw i16 %a, 4 +- %add = add nsw i16 %b, %mul +- %zext = zext i16 %add to i32 +- ret i32 %zext +-} +- +-define i64 @alsl_zext_i32(i32 signext %a, i32 signext %b) nounwind { +-; LA32-LABEL: alsl_zext_i32: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: alsl.w $a0, $a0, $a1, 3 +-; LA32-NEXT: move $a1, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: alsl_zext_i32: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: alsl.wu $a0, $a0, $a1, 3 +-; LA64-NEXT: ret +-entry: +- %mul = mul nsw i32 %a, 8 +- %add = add nsw i32 %b, %mul +- %zext = zext i32 %add to i64 +- ret i64 %zext +-} +- +-define i8 @mul_add_i8(i8 signext %a, i8 signext %b) nounwind { +-; LA32-LABEL: mul_add_i8: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 1 +-; LA32-NEXT: add.w $a0, $a1, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_add_i8: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 1 +-; LA64-NEXT: add.d $a0, $a1, $a0 +-; LA64-NEXT: ret +-entry: +- %mul = mul nsw i8 %a, 3 +- %add = add nsw i8 %b, %mul +- ret i8 %add +-} +- +-define i16 @mul_add_i16(i16 signext %a, i16 signext %b) nounwind { +-; LA32-LABEL: mul_add_i16: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: alsl.w $a0, $a0, $a2, 1 +-; LA32-NEXT: add.w $a0, $a1, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_add_i16: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: alsl.d $a0, $a0, $a2, 1 +-; LA64-NEXT: add.d $a0, $a1, $a0 +-; LA64-NEXT: ret +-entry: +- %mul = mul nsw i16 %a, 10 +- %add = add nsw i16 %b, %mul +- ret i16 %add +-} +- +-define i32 @mul_add_i32(i32 signext %a, i32 signext %b) nounwind { +-; LA32-LABEL: mul_add_i32: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: alsl.w $a0, $a0, $a2, 2 +-; LA32-NEXT: add.w $a0, $a1, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_add_i32: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: alsl.d $a0, $a0, $a2, 2 +-; LA64-NEXT: add.d $a0, $a1, $a0 +-; LA64-NEXT: ret +-entry: +- %mul = mul nsw i32 %a, 12 +- %add = add nsw i32 %b, %mul +- ret i32 %add +-} +- +-define i64 @mul_add_i64(i64 signext %a, i64 signext %b) nounwind { +-; LA32-LABEL: mul_add_i64: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: slli.w $a4, $a1, 4 +-; LA32-NEXT: sub.w $a1, $a4, $a1 +-; LA32-NEXT: ori $a4, $zero, 15 +-; LA32-NEXT: mulh.wu $a4, $a0, $a4 +-; LA32-NEXT: add.w $a1, $a4, $a1 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: slli.w $a3, $a0, 4 +-; LA32-NEXT: sub.w $a0, $a3, $a0 +-; LA32-NEXT: add.w $a0, $a2, $a0 +-; LA32-NEXT: sltu $a2, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a1, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_add_i64: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: slli.d $a2, $a0, 4 +-; LA64-NEXT: sub.d $a0, $a2, $a0 +-; LA64-NEXT: add.d $a0, $a1, $a0 +-; LA64-NEXT: ret +-entry: +- %mul = mul nsw i64 %a, 15 +- %add = add nsw i64 %b, %mul +- ret i64 %add +-} +- +-define i32 @mul_add_zext_i8(i8 signext %a, i8 signext %b) nounwind { +-; LA32-LABEL: mul_add_zext_i8: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 2 +-; LA32-NEXT: add.w $a0, $a1, $a0 +-; LA32-NEXT: andi $a0, $a0, 255 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_add_zext_i8: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 2 +-; LA64-NEXT: add.d $a0, $a1, $a0 +-; LA64-NEXT: andi $a0, $a0, 255 +-; LA64-NEXT: ret +-entry: +- %mul = mul nsw i8 %a, 5 +- %add = add nsw i8 %b, %mul +- %zext = zext i8 %add to i32 +- ret i32 %zext +-} +- +-define i32 @mul_add_zext_i16(i16 signext %a, i16 signext %b) nounwind { +-; LA32-LABEL: mul_add_zext_i16: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: slli.w $a2, $a0, 4 +-; LA32-NEXT: sub.w $a0, $a2, $a0 +-; LA32-NEXT: add.w $a0, $a1, $a0 +-; LA32-NEXT: bstrpick.w $a0, $a0, 15, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_add_zext_i16: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: slli.d $a2, $a0, 4 +-; LA64-NEXT: sub.d $a0, $a2, $a0 +-; LA64-NEXT: add.d $a0, $a1, $a0 +-; LA64-NEXT: bstrpick.d $a0, $a0, 15, 0 +-; LA64-NEXT: ret +-entry: +- %mul = mul nsw i16 %a, 15 +- %add = add nsw i16 %b, %mul +- %zext = zext i16 %add to i32 +- ret i32 %zext +-} +- +-define i64 @mul_add_zext_i32(i32 signext %a, i32 signext %b) nounwind { +-; LA32-LABEL: mul_add_zext_i32: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 2 +-; LA32-NEXT: add.w $a0, $a1, $a0 +-; LA32-NEXT: move $a1, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_add_zext_i32: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 2 +-; LA64-NEXT: add.d $a0, $a1, $a0 +-; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 +-; LA64-NEXT: ret +-entry: +- %mul = mul nsw i32 %a, 5 +- %add = add nsw i32 %b, %mul +- %zext = zext i32 %add to i64 +- ret i64 %zext +-} +- +-define i8 @alsl_neg_i8(i8 signext %a, i8 signext %b) nounwind { +-; LA32-LABEL: alsl_neg_i8: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 1 +-; LA32-NEXT: sub.w $a0, $a1, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: alsl_neg_i8: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 1 +-; LA64-NEXT: sub.d $a0, $a1, $a0 +-; LA64-NEXT: ret +-entry: +- %mul = mul nsw i8 %a, -3 +- %add = add nsw i8 %b, %mul +- ret i8 %add +-} +- +-define i16 @alsl_neg_i16(i16 signext %a, i16 signext %b) nounwind { +-; LA32-LABEL: alsl_neg_i16: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 2 +-; LA32-NEXT: sub.w $a0, $a1, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: alsl_neg_i16: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 2 +-; LA64-NEXT: sub.d $a0, $a1, $a0 +-; LA64-NEXT: ret +-entry: +- %mul = mul nsw i16 %a, -5 +- %add = add nsw i16 %b, %mul +- ret i16 %add +-} +- +-define i32 @alsl_neg_i32(i32 signext %a, i32 signext %b) nounwind { +-; LA32-LABEL: alsl_neg_i32: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 3 +-; LA32-NEXT: sub.w $a0, $a1, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: alsl_neg_i32: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 3 +-; LA64-NEXT: sub.d $a0, $a1, $a0 +-; LA64-NEXT: ret +-entry: +- %mul = mul nsw i32 %a, -9 +- %add = add nsw i32 %b, %mul +- ret i32 %add +-} +- +-define i64 @mul_add_neg_i64(i64 signext %a, i64 signext %b) nounwind { +-; LA32-LABEL: mul_add_neg_i64: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: slli.w $a4, $a1, 4 +-; LA32-NEXT: sub.w $a1, $a1, $a4 +-; LA32-NEXT: addi.w $a4, $zero, -15 +-; LA32-NEXT: mulh.wu $a4, $a0, $a4 +-; LA32-NEXT: sub.w $a4, $a4, $a0 +-; LA32-NEXT: add.w $a1, $a4, $a1 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: slli.w $a3, $a0, 4 +-; LA32-NEXT: sub.w $a0, $a0, $a3 +-; LA32-NEXT: add.w $a0, $a2, $a0 +-; LA32-NEXT: sltu $a2, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a1, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_add_neg_i64: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: slli.d $a2, $a0, 4 +-; LA64-NEXT: sub.d $a0, $a0, $a2 +-; LA64-NEXT: add.d $a0, $a1, $a0 +-; LA64-NEXT: ret +-entry: +- %mul = mul nsw i64 %a, -15 +- %add = add nsw i64 %b, %mul +- ret i64 %add +-} +diff --git a/llvm/test/CodeGen/LoongArch/analyze-branch.ll b/llvm/test/CodeGen/LoongArch/analyze-branch.ll +deleted file mode 100644 +index fb89964af..000000000 +--- a/llvm/test/CodeGen/LoongArch/analyze-branch.ll ++++ /dev/null +@@ -1,76 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s +- +-;; This test checks that LLVM can do basic stripping and reapplying of branches +-;; to basic blocks. +- +-declare void @test_true() +-declare void @test_false() +- +-;; !0 corresponds to a branch being taken, !1 to not being taken. +-!0 = !{!"branch_weights", i32 64, i32 4} +-!1 = !{!"branch_weights", i32 4, i32 64} +- +-define void @test_bcc_fallthrough_taken(i64 %in) nounwind { +-; CHECK-LABEL: test_bcc_fallthrough_taken: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; CHECK-NEXT: ori $a1, $zero, 42 +-; CHECK-NEXT: bne $a0, $a1, .LBB0_3 +-; CHECK-NEXT: # %bb.1: # %true +-; CHECK-NEXT: bl %plt(test_true) +-; CHECK-NEXT: .LBB0_2: # %true +-; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +-; CHECK-NEXT: .LBB0_3: # %false +-; CHECK-NEXT: bl %plt(test_false) +-; CHECK-NEXT: b .LBB0_2 +- %tst = icmp eq i64 %in, 42 +- br i1 %tst, label %true, label %false, !prof !0 +- +-;; Expected layout order is: Entry, TrueBlock, FalseBlock +-;; Entry->TrueBlock is the common path, which should be taken whenever the +-;; conditional branch is false. +- +-true: +- call void @test_true() +- ret void +- +-false: +- call void @test_false() +- ret void +-} +- +-define void @test_bcc_fallthrough_nottaken(i64 %in) nounwind { +-; CHECK-LABEL: test_bcc_fallthrough_nottaken: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; CHECK-NEXT: ori $a1, $zero, 42 +-; CHECK-NEXT: beq $a0, $a1, .LBB1_3 +-; CHECK-NEXT: # %bb.1: # %false +-; CHECK-NEXT: bl %plt(test_false) +-; CHECK-NEXT: .LBB1_2: # %true +-; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +-; CHECK-NEXT: .LBB1_3: # %true +-; CHECK-NEXT: bl %plt(test_true) +-; CHECK-NEXT: b .LBB1_2 +- %tst = icmp eq i64 %in, 42 +- br i1 %tst, label %true, label %false, !prof !1 +- +-;; Expected layout order is: Entry, FalseBlock, TrueBlock +-;; Entry->FalseBlock is the common path, which should be taken whenever the +-;; conditional branch is false. +- +-true: +- call void @test_true() +- ret void +- +-false: +- call void @test_false() +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/andn-icmp.ll b/llvm/test/CodeGen/LoongArch/andn-icmp.ll +deleted file mode 100644 +index ff6935e2e..000000000 +--- a/llvm/test/CodeGen/LoongArch/andn-icmp.ll ++++ /dev/null +@@ -1,143 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-define i1 @andn_icmp_eq_i8(i8 signext %a, i8 signext %b) nounwind { +-; LA32-LABEL: andn_icmp_eq_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: andn $a0, $a1, $a0 +-; LA32-NEXT: sltui $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: andn_icmp_eq_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: andn $a0, $a1, $a0 +-; LA64-NEXT: sltui $a0, $a0, 1 +-; LA64-NEXT: ret +- %and = and i8 %a, %b +- %cmpeq = icmp eq i8 %and, %b +- ret i1 %cmpeq +-} +- +-define i1 @andn_icmp_eq_i16(i16 signext %a, i16 signext %b) nounwind { +-; LA32-LABEL: andn_icmp_eq_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: andn $a0, $a1, $a0 +-; LA32-NEXT: sltui $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: andn_icmp_eq_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: andn $a0, $a1, $a0 +-; LA64-NEXT: sltui $a0, $a0, 1 +-; LA64-NEXT: ret +- %and = and i16 %a, %b +- %cmpeq = icmp eq i16 %and, %b +- ret i1 %cmpeq +-} +- +-define i1 @andn_icmp_eq_i32(i32 signext %a, i32 signext %b) nounwind { +-; LA32-LABEL: andn_icmp_eq_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: andn $a0, $a1, $a0 +-; LA32-NEXT: sltui $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: andn_icmp_eq_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: andn $a0, $a1, $a0 +-; LA64-NEXT: sltui $a0, $a0, 1 +-; LA64-NEXT: ret +- %and = and i32 %a, %b +- %cmpeq = icmp eq i32 %and, %b +- ret i1 %cmpeq +-} +- +-define i1 @andn_icmp_eq_i64(i64 %a, i64 %b) nounwind { +-; LA32-LABEL: andn_icmp_eq_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: andn $a1, $a3, $a1 +-; LA32-NEXT: andn $a0, $a2, $a0 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: sltui $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: andn_icmp_eq_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: andn $a0, $a1, $a0 +-; LA64-NEXT: sltui $a0, $a0, 1 +-; LA64-NEXT: ret +- %and = and i64 %a, %b +- %cmpeq = icmp eq i64 %and, %b +- ret i1 %cmpeq +-} +- +-define i1 @andn_icmp_ne_i8(i8 signext %a, i8 signext %b) nounwind { +-; LA32-LABEL: andn_icmp_ne_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: andn $a0, $a1, $a0 +-; LA32-NEXT: sltu $a0, $zero, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: andn_icmp_ne_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: andn $a0, $a1, $a0 +-; LA64-NEXT: sltu $a0, $zero, $a0 +-; LA64-NEXT: ret +- %and = and i8 %a, %b +- %cmpne = icmp ne i8 %and, %b +- ret i1 %cmpne +-} +- +-define i1 @andn_icmp_ne_i16(i16 signext %a, i16 signext %b) nounwind { +-; LA32-LABEL: andn_icmp_ne_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: andn $a0, $a1, $a0 +-; LA32-NEXT: sltu $a0, $zero, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: andn_icmp_ne_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: andn $a0, $a1, $a0 +-; LA64-NEXT: sltu $a0, $zero, $a0 +-; LA64-NEXT: ret +- %and = and i16 %a, %b +- %cmpne = icmp ne i16 %and, %b +- ret i1 %cmpne +-} +- +-define i1 @andn_icmp_ne_i32(i32 signext %a, i32 signext %b) nounwind { +-; LA32-LABEL: andn_icmp_ne_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: andn $a0, $a1, $a0 +-; LA32-NEXT: sltu $a0, $zero, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: andn_icmp_ne_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: andn $a0, $a1, $a0 +-; LA64-NEXT: sltu $a0, $zero, $a0 +-; LA64-NEXT: ret +- %and = and i32 %a, %b +- %cmpne = icmp ne i32 %and, %b +- ret i1 %cmpne +-} +- +-define i1 @andn_icmp_ne_i64(i64 %a, i64 %b) nounwind { +-; LA32-LABEL: andn_icmp_ne_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: andn $a1, $a3, $a1 +-; LA32-NEXT: andn $a0, $a2, $a0 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: sltu $a0, $zero, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: andn_icmp_ne_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: andn $a0, $a1, $a0 +-; LA64-NEXT: sltu $a0, $zero, $a0 +-; LA64-NEXT: ret +- %and = and i64 %a, %b +- %cmpne = icmp ne i64 %and, %b +- ret i1 %cmpne +-} +diff --git a/llvm/test/CodeGen/LoongArch/atomic-cmpxchg.ll b/llvm/test/CodeGen/LoongArch/atomic-cmpxchg.ll +new file mode 100644 +index 000000000..795b5c6b2 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/atomic-cmpxchg.ll +@@ -0,0 +1,902 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 ++ ++define void @cmpxchg_i8_acquire_acquire(i8* %ptr, i8 %cmp, i8 %val) nounwind { ++; LA64-LABEL: cmpxchg_i8_acquire_acquire: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r5, $r5, 0 ++; LA64-NEXT: addi.d $r7, $zero, -4 ++; LA64-NEXT: and $r7, $r4, $r7 ++; LA64-NEXT: andi $r4, $r4, 3 ++; LA64-NEXT: slli.w $r4, $r4, 3 ++; LA64-NEXT: ori $r8, $zero, 255 ++; LA64-NEXT: sll.w $r8, $r8, $r4 ++; LA64-NEXT: nor $r9, $zero, $r8 ++; LA64-NEXT: andi $r5, $r5, 255 ++; LA64-NEXT: sll.w $r5, $r5, $r4 ++; LA64-NEXT: andi $r6, $r6, 255 ++; LA64-NEXT: sll.w $r6, $r6, $r4 ++; LA64-NEXT: .LBB0_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r11, $r7, 0 ++; LA64-NEXT: and $r12, $r11, $r8 ++; LA64-NEXT: bne $r12, $r5, .LBB0_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB0_1 Depth=1 ++; LA64-NEXT: and $r11, $r11, $r9 ++; LA64-NEXT: or $r11, $r11, $r6 ++; LA64-NEXT: sc.w $r11, $r7, 0 ++; LA64-NEXT: beq $r11, $zero, .LBB0_1 ++; LA64-NEXT: .LBB0_3: ++; LA64-NEXT: dbar 20 ++; LA64-NEXT: srl.w $r10, $r12, $r4 ++; LA64-NEXT: ext.w.b $r10, $r10 ++; LA64-NEXT: # %bb.4: ++; LA64-NEXT: jr $ra ++ %res = cmpxchg i8* %ptr, i8 %cmp, i8 %val acquire acquire ++ ret void ++} ++ ++define void @cmpxchg_i8_release_acquire(i8* %ptr, i8 %cmp, i8 %val) nounwind { ++; LA64-LABEL: cmpxchg_i8_release_acquire: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r5, $r5, 0 ++; LA64-NEXT: addi.d $r7, $zero, -4 ++; LA64-NEXT: and $r7, $r4, $r7 ++; LA64-NEXT: andi $r4, $r4, 3 ++; LA64-NEXT: slli.w $r4, $r4, 3 ++; LA64-NEXT: ori $r8, $zero, 255 ++; LA64-NEXT: sll.w $r8, $r8, $r4 ++; LA64-NEXT: nor $r9, $zero, $r8 ++; LA64-NEXT: andi $r5, $r5, 255 ++; LA64-NEXT: sll.w $r5, $r5, $r4 ++; LA64-NEXT: andi $r6, $r6, 255 ++; LA64-NEXT: sll.w $r6, $r6, $r4 ++; LA64-NEXT: .LBB1_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r11, $r7, 0 ++; LA64-NEXT: and $r12, $r11, $r8 ++; LA64-NEXT: bne $r12, $r5, .LBB1_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB1_1 Depth=1 ++; LA64-NEXT: and $r11, $r11, $r9 ++; LA64-NEXT: or $r11, $r11, $r6 ++; LA64-NEXT: sc.w $r11, $r7, 0 ++; LA64-NEXT: beq $r11, $zero, .LBB1_1 ++; LA64-NEXT: .LBB1_3: ++; LA64-NEXT: dbar 20 ++; LA64-NEXT: srl.w $r10, $r12, $r4 ++; LA64-NEXT: ext.w.b $r10, $r10 ++; LA64-NEXT: # %bb.4: ++; LA64-NEXT: jr $ra ++ %res = cmpxchg i8* %ptr, i8 %cmp, i8 %val release acquire ++ ret void ++} ++ ++;; Check that only the failure ordering is taken care. ++define void @cmpxchg_i8_acquire_monotonic(i8* %ptr, i8 %cmp, i8 %val) nounwind { ++; LA64-LABEL: cmpxchg_i8_acquire_monotonic: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r5, $r5, 0 ++; LA64-NEXT: addi.d $r7, $zero, -4 ++; LA64-NEXT: and $r7, $r4, $r7 ++; LA64-NEXT: andi $r4, $r4, 3 ++; LA64-NEXT: slli.w $r4, $r4, 3 ++; LA64-NEXT: ori $r8, $zero, 255 ++; LA64-NEXT: sll.w $r8, $r8, $r4 ++; LA64-NEXT: nor $r9, $zero, $r8 ++; LA64-NEXT: andi $r5, $r5, 255 ++; LA64-NEXT: sll.w $r5, $r5, $r4 ++; LA64-NEXT: andi $r6, $r6, 255 ++; LA64-NEXT: sll.w $r6, $r6, $r4 ++; LA64-NEXT: .LBB2_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r11, $r7, 0 ++; LA64-NEXT: and $r12, $r11, $r8 ++; LA64-NEXT: bne $r12, $r5, .LBB2_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB2_1 Depth=1 ++; LA64-NEXT: and $r11, $r11, $r9 ++; LA64-NEXT: or $r11, $r11, $r6 ++; LA64-NEXT: sc.w $r11, $r7, 0 ++; LA64-NEXT: beq $r11, $zero, .LBB2_1 ++; LA64-NEXT: .LBB2_3: ++; LA64-NEXT: dbar 1792 ++; LA64-NEXT: srl.w $r10, $r12, $r4 ++; LA64-NEXT: ext.w.b $r10, $r10 ++; LA64-NEXT: # %bb.4: ++; LA64-NEXT: jr $ra ++ %res = cmpxchg i8* %ptr, i8 %cmp, i8 %val acquire monotonic ++ ret void ++} ++ ++define void @cmpxchg_i16_acquire_acquire(i16* %ptr, i16 %cmp, i16 %val) nounwind { ++; LA64-LABEL: cmpxchg_i16_acquire_acquire: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r5, $r5, 0 ++; LA64-NEXT: addi.d $r7, $zero, -4 ++; LA64-NEXT: and $r7, $r4, $r7 ++; LA64-NEXT: andi $r4, $r4, 3 ++; LA64-NEXT: slli.w $r4, $r4, 3 ++; LA64-NEXT: lu12i.w $r8, 15 ++; LA64-NEXT: ori $r8, $r8, 4095 ++; LA64-NEXT: sll.w $r9, $r8, $r4 ++; LA64-NEXT: nor $r10, $zero, $r9 ++; LA64-NEXT: and $r5, $r5, $r8 ++; LA64-NEXT: sll.w $r5, $r5, $r4 ++; LA64-NEXT: and $r6, $r6, $r8 ++; LA64-NEXT: sll.w $r6, $r6, $r4 ++; LA64-NEXT: .LBB3_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r11, $r7, 0 ++; LA64-NEXT: and $r12, $r11, $r9 ++; LA64-NEXT: bne $r12, $r5, .LBB3_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB3_1 Depth=1 ++; LA64-NEXT: and $r11, $r11, $r10 ++; LA64-NEXT: or $r11, $r11, $r6 ++; LA64-NEXT: sc.w $r11, $r7, 0 ++; LA64-NEXT: beq $r11, $zero, .LBB3_1 ++; LA64-NEXT: .LBB3_3: ++; LA64-NEXT: dbar 20 ++; LA64-NEXT: srl.w $r8, $r12, $r4 ++; LA64-NEXT: ext.w.h $r8, $r8 ++; LA64-NEXT: # %bb.4: ++; LA64-NEXT: jr $ra ++ %res = cmpxchg i16* %ptr, i16 %cmp, i16 %val acquire acquire ++ ret void ++} ++ ++define void @cmpxchg_i16_release_acquire(i16* %ptr, i16 %cmp, i16 %val) nounwind { ++; LA64-LABEL: cmpxchg_i16_release_acquire: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r5, $r5, 0 ++; LA64-NEXT: addi.d $r7, $zero, -4 ++; LA64-NEXT: and $r7, $r4, $r7 ++; LA64-NEXT: andi $r4, $r4, 3 ++; LA64-NEXT: slli.w $r4, $r4, 3 ++; LA64-NEXT: lu12i.w $r8, 15 ++; LA64-NEXT: ori $r8, $r8, 4095 ++; LA64-NEXT: sll.w $r9, $r8, $r4 ++; LA64-NEXT: nor $r10, $zero, $r9 ++; LA64-NEXT: and $r5, $r5, $r8 ++; LA64-NEXT: sll.w $r5, $r5, $r4 ++; LA64-NEXT: and $r6, $r6, $r8 ++; LA64-NEXT: sll.w $r6, $r6, $r4 ++; LA64-NEXT: .LBB4_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r11, $r7, 0 ++; LA64-NEXT: and $r12, $r11, $r9 ++; LA64-NEXT: bne $r12, $r5, .LBB4_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB4_1 Depth=1 ++; LA64-NEXT: and $r11, $r11, $r10 ++; LA64-NEXT: or $r11, $r11, $r6 ++; LA64-NEXT: sc.w $r11, $r7, 0 ++; LA64-NEXT: beq $r11, $zero, .LBB4_1 ++; LA64-NEXT: .LBB4_3: ++; LA64-NEXT: dbar 20 ++; LA64-NEXT: srl.w $r8, $r12, $r4 ++; LA64-NEXT: ext.w.h $r8, $r8 ++; LA64-NEXT: # %bb.4: ++; LA64-NEXT: jr $ra ++ %res = cmpxchg i16* %ptr, i16 %cmp, i16 %val release acquire ++ ret void ++} ++ ++;; Check that only the failure ordering is taken care. ++define void @cmpxchg_i16_acquire_monotonic(i16* %ptr, i16 %cmp, i16 %val) nounwind { ++; LA64-LABEL: cmpxchg_i16_acquire_monotonic: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r5, $r5, 0 ++; LA64-NEXT: addi.d $r7, $zero, -4 ++; LA64-NEXT: and $r7, $r4, $r7 ++; LA64-NEXT: andi $r4, $r4, 3 ++; LA64-NEXT: slli.w $r4, $r4, 3 ++; LA64-NEXT: lu12i.w $r8, 15 ++; LA64-NEXT: ori $r8, $r8, 4095 ++; LA64-NEXT: sll.w $r9, $r8, $r4 ++; LA64-NEXT: nor $r10, $zero, $r9 ++; LA64-NEXT: and $r5, $r5, $r8 ++; LA64-NEXT: sll.w $r5, $r5, $r4 ++; LA64-NEXT: and $r6, $r6, $r8 ++; LA64-NEXT: sll.w $r6, $r6, $r4 ++; LA64-NEXT: .LBB5_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r11, $r7, 0 ++; LA64-NEXT: and $r12, $r11, $r9 ++; LA64-NEXT: bne $r12, $r5, .LBB5_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB5_1 Depth=1 ++; LA64-NEXT: and $r11, $r11, $r10 ++; LA64-NEXT: or $r11, $r11, $r6 ++; LA64-NEXT: sc.w $r11, $r7, 0 ++; LA64-NEXT: beq $r11, $zero, .LBB5_1 ++; LA64-NEXT: .LBB5_3: ++; LA64-NEXT: dbar 1792 ++; LA64-NEXT: srl.w $r8, $r12, $r4 ++; LA64-NEXT: ext.w.h $r8, $r8 ++; LA64-NEXT: # %bb.4: ++; LA64-NEXT: jr $ra ++ %res = cmpxchg i16* %ptr, i16 %cmp, i16 %val acquire monotonic ++ ret void ++} ++ ++define void @cmpxchg_i32_acquire_acquire(i32* %ptr, i32 %cmp, i32 %val) nounwind { ++; LA64-LABEL: cmpxchg_i32_acquire_acquire: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r5, $r5, 0 ++; LA64-NEXT: .LBB6_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r7, $r4, 0 ++; LA64-NEXT: bne $r7, $r5, .LBB6_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB6_1 Depth=1 ++; LA64-NEXT: move $r8, $r6 ++; LA64-NEXT: sc.w $r8, $r4, 0 ++; LA64-NEXT: beq $r8, $zero, .LBB6_1 ++; LA64-NEXT: .LBB6_3: ++; LA64-NEXT: dbar 0 ++; LA64-NEXT: jr $ra ++ %res = cmpxchg i32* %ptr, i32 %cmp, i32 %val acquire acquire ++ ret void ++} ++ ++define void @cmpxchg_i32_release_acquire(i32* %ptr, i32 %cmp, i32 %val) nounwind { ++; LA64-LABEL: cmpxchg_i32_release_acquire: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r5, $r5, 0 ++; LA64-NEXT: .LBB7_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r7, $r4, 0 ++; LA64-NEXT: bne $r7, $r5, .LBB7_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB7_1 Depth=1 ++; LA64-NEXT: move $r8, $r6 ++; LA64-NEXT: sc.w $r8, $r4, 0 ++; LA64-NEXT: beq $r8, $zero, .LBB7_1 ++; LA64-NEXT: .LBB7_3: ++; LA64-NEXT: dbar 0 ++; LA64-NEXT: jr $ra ++ %res = cmpxchg i32* %ptr, i32 %cmp, i32 %val release acquire ++ ret void ++} ++ ++;; Check that only the failure ordering is taken care. ++define void @cmpxchg_i32_acquire_monotonic(i32* %ptr, i32 %cmp, i32 %val) nounwind { ++; LA64-LABEL: cmpxchg_i32_acquire_monotonic: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r5, $r5, 0 ++; LA64-NEXT: .LBB8_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r7, $r4, 0 ++; LA64-NEXT: bne $r7, $r5, .LBB8_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB8_1 Depth=1 ++; LA64-NEXT: move $r8, $r6 ++; LA64-NEXT: sc.w $r8, $r4, 0 ++; LA64-NEXT: beq $r8, $zero, .LBB8_1 ++; LA64-NEXT: .LBB8_3: ++; LA64-NEXT: dbar 1792 ++; LA64-NEXT: jr $ra ++ %res = cmpxchg i32* %ptr, i32 %cmp, i32 %val acquire monotonic ++ ret void ++} ++ ++define void @cmpxchg_i64_acquire_acquire(i64* %ptr, i64 %cmp, i64 %val) nounwind { ++; LA64-LABEL: cmpxchg_i64_acquire_acquire: ++; LA64: # %bb.0: ++; LA64-NEXT: .LBB9_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.d $r7, $r4, 0 ++; LA64-NEXT: bne $r7, $r5, .LBB9_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB9_1 Depth=1 ++; LA64-NEXT: move $r8, $r6 ++; LA64-NEXT: sc.d $r8, $r4, 0 ++; LA64-NEXT: beq $r8, $zero, .LBB9_1 ++; LA64-NEXT: .LBB9_3: ++; LA64-NEXT: dbar 0 ++; LA64-NEXT: jr $ra ++ %res = cmpxchg i64* %ptr, i64 %cmp, i64 %val acquire acquire ++ ret void ++} ++ ++define void @cmpxchg_i64_release_acquire(i64* %ptr, i64 %cmp, i64 %val) nounwind { ++; LA64-LABEL: cmpxchg_i64_release_acquire: ++; LA64: # %bb.0: ++; LA64-NEXT: .LBB10_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.d $r7, $r4, 0 ++; LA64-NEXT: bne $r7, $r5, .LBB10_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB10_1 Depth=1 ++; LA64-NEXT: move $r8, $r6 ++; LA64-NEXT: sc.d $r8, $r4, 0 ++; LA64-NEXT: beq $r8, $zero, .LBB10_1 ++; LA64-NEXT: .LBB10_3: ++; LA64-NEXT: dbar 0 ++; LA64-NEXT: jr $ra ++ %res = cmpxchg i64* %ptr, i64 %cmp, i64 %val release acquire ++ ret void ++} ++ ++;; Check that only the failure ordering is taken care. ++define void @cmpxchg_i64_acquire_monotonic(i64* %ptr, i64 %cmp, i64 %val) nounwind { ++; LA64-LABEL: cmpxchg_i64_acquire_monotonic: ++; LA64: # %bb.0: ++; LA64-NEXT: .LBB11_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.d $r7, $r4, 0 ++; LA64-NEXT: bne $r7, $r5, .LBB11_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB11_1 Depth=1 ++; LA64-NEXT: move $r8, $r6 ++; LA64-NEXT: sc.d $r8, $r4, 0 ++; LA64-NEXT: beq $r8, $zero, .LBB11_1 ++; LA64-NEXT: .LBB11_3: ++; LA64-NEXT: dbar 1792 ++; LA64-NEXT: jr $ra ++ %res = cmpxchg i64* %ptr, i64 %cmp, i64 %val acquire monotonic ++ ret void ++} ++ ++define i8 @cmpxchg_i8_acquire_acquire_reti8(i8* %ptr, i8 %cmp, i8 %val) nounwind { ++; LA64-LABEL: cmpxchg_i8_acquire_acquire_reti8: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r5, $r5, 0 ++; LA64-NEXT: addi.d $r7, $zero, -4 ++; LA64-NEXT: and $r7, $r4, $r7 ++; LA64-NEXT: andi $r4, $r4, 3 ++; LA64-NEXT: slli.w $r8, $r4, 3 ++; LA64-NEXT: ori $r4, $zero, 255 ++; LA64-NEXT: sll.w $r9, $r4, $r8 ++; LA64-NEXT: nor $r10, $zero, $r9 ++; LA64-NEXT: andi $r4, $r5, 255 ++; LA64-NEXT: sll.w $r5, $r4, $r8 ++; LA64-NEXT: andi $r4, $r6, 255 ++; LA64-NEXT: sll.w $r6, $r4, $r8 ++; LA64-NEXT: .LBB12_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r11, $r7, 0 ++; LA64-NEXT: and $r12, $r11, $r9 ++; LA64-NEXT: bne $r12, $r5, .LBB12_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB12_1 Depth=1 ++; LA64-NEXT: and $r11, $r11, $r10 ++; LA64-NEXT: or $r11, $r11, $r6 ++; LA64-NEXT: sc.w $r11, $r7, 0 ++; LA64-NEXT: beq $r11, $zero, .LBB12_1 ++; LA64-NEXT: .LBB12_3: ++; LA64-NEXT: dbar 20 ++; LA64-NEXT: srl.w $r4, $r12, $r8 ++; LA64-NEXT: ext.w.b $r4, $r4 ++; LA64-NEXT: # %bb.4: ++; LA64-NEXT: jr $ra ++ %tmp = cmpxchg i8* %ptr, i8 %cmp, i8 %val acquire acquire ++ %res = extractvalue { i8, i1 } %tmp, 0 ++ ret i8 %res ++} ++ ++define i16 @cmpxchg_i16_acquire_acquire_reti16(i16* %ptr, i16 %cmp, i16 %val) nounwind { ++; LA64-LABEL: cmpxchg_i16_acquire_acquire_reti16: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r5, $r5, 0 ++; LA64-NEXT: addi.d $r7, $zero, -4 ++; LA64-NEXT: and $r7, $r4, $r7 ++; LA64-NEXT: andi $r4, $r4, 3 ++; LA64-NEXT: slli.w $r8, $r4, 3 ++; LA64-NEXT: lu12i.w $r4, 15 ++; LA64-NEXT: ori $r4, $r4, 4095 ++; LA64-NEXT: sll.w $r9, $r4, $r8 ++; LA64-NEXT: nor $r10, $zero, $r9 ++; LA64-NEXT: and $r5, $r5, $r4 ++; LA64-NEXT: sll.w $r5, $r5, $r8 ++; LA64-NEXT: and $r4, $r6, $r4 ++; LA64-NEXT: sll.w $r6, $r4, $r8 ++; LA64-NEXT: .LBB13_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r11, $r7, 0 ++; LA64-NEXT: and $r12, $r11, $r9 ++; LA64-NEXT: bne $r12, $r5, .LBB13_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB13_1 Depth=1 ++; LA64-NEXT: and $r11, $r11, $r10 ++; LA64-NEXT: or $r11, $r11, $r6 ++; LA64-NEXT: sc.w $r11, $r7, 0 ++; LA64-NEXT: beq $r11, $zero, .LBB13_1 ++; LA64-NEXT: .LBB13_3: ++; LA64-NEXT: dbar 20 ++; LA64-NEXT: srl.w $r4, $r12, $r8 ++; LA64-NEXT: ext.w.h $r4, $r4 ++; LA64-NEXT: # %bb.4: ++; LA64-NEXT: jr $ra ++ %tmp = cmpxchg i16* %ptr, i16 %cmp, i16 %val acquire acquire ++ %res = extractvalue { i16, i1 } %tmp, 0 ++ ret i16 %res ++} ++ ++define i32 @cmpxchg_i32_acquire_acquire_reti32(i32* %ptr, i32 %cmp, i32 %val) nounwind { ++; LA64-LABEL: cmpxchg_i32_acquire_acquire_reti32: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r7, $r5, 0 ++; LA64-NEXT: .LBB14_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r5, $r4, 0 ++; LA64-NEXT: bne $r5, $r7, .LBB14_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB14_1 Depth=1 ++; LA64-NEXT: move $r8, $r6 ++; LA64-NEXT: sc.w $r8, $r4, 0 ++; LA64-NEXT: beq $r8, $zero, .LBB14_1 ++; LA64-NEXT: .LBB14_3: ++; LA64-NEXT: dbar 0 ++; LA64-NEXT: move $r4, $r5 ++; LA64-NEXT: jr $ra ++ %tmp = cmpxchg i32* %ptr, i32 %cmp, i32 %val acquire acquire ++ %res = extractvalue { i32, i1 } %tmp, 0 ++ ret i32 %res ++} ++ ++define i64 @cmpxchg_i64_acquire_acquire_reti64(i64* %ptr, i64 %cmp, i64 %val) nounwind { ++; LA64-LABEL: cmpxchg_i64_acquire_acquire_reti64: ++; LA64: # %bb.0: ++; LA64-NEXT: .LBB15_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.d $r7, $r4, 0 ++; LA64-NEXT: bne $r7, $r5, .LBB15_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1 ++; LA64-NEXT: move $r8, $r6 ++; LA64-NEXT: sc.d $r8, $r4, 0 ++; LA64-NEXT: beq $r8, $zero, .LBB15_1 ++; LA64-NEXT: .LBB15_3: ++; LA64-NEXT: dbar 0 ++; LA64-NEXT: move $r4, $r7 ++; LA64-NEXT: jr $ra ++ %tmp = cmpxchg i64* %ptr, i64 %cmp, i64 %val acquire acquire ++ %res = extractvalue { i64, i1 } %tmp, 0 ++ ret i64 %res ++} ++ ++define i1 @cmpxchg_i8_acquire_acquire_reti1(i8* %ptr, i8 %cmp, i8 %val) nounwind { ++; LA64-LABEL: cmpxchg_i8_acquire_acquire_reti1: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r5, $r5, 0 ++; LA64-NEXT: addi.d $r7, $zero, -4 ++; LA64-NEXT: and $r7, $r4, $r7 ++; LA64-NEXT: andi $r4, $r4, 3 ++; LA64-NEXT: slli.w $r8, $r4, 3 ++; LA64-NEXT: ori $r4, $zero, 255 ++; LA64-NEXT: sll.w $r9, $r4, $r8 ++; LA64-NEXT: nor $r10, $zero, $r9 ++; LA64-NEXT: andi $r4, $r5, 255 ++; LA64-NEXT: sll.w $r11, $r4, $r8 ++; LA64-NEXT: andi $r4, $r6, 255 ++; LA64-NEXT: sll.w $r6, $r4, $r8 ++; LA64-NEXT: .LBB16_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r12, $r7, 0 ++; LA64-NEXT: and $r13, $r12, $r9 ++; LA64-NEXT: bne $r13, $r11, .LBB16_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB16_1 Depth=1 ++; LA64-NEXT: and $r12, $r12, $r10 ++; LA64-NEXT: or $r12, $r12, $r6 ++; LA64-NEXT: sc.w $r12, $r7, 0 ++; LA64-NEXT: beq $r12, $zero, .LBB16_1 ++; LA64-NEXT: .LBB16_3: ++; LA64-NEXT: dbar 20 ++; LA64-NEXT: srl.w $r4, $r13, $r8 ++; LA64-NEXT: ext.w.b $r4, $r4 ++; LA64-NEXT: # %bb.4: ++; LA64-NEXT: ext.w.b $r5, $r5 ++; LA64-NEXT: xor $r4, $r4, $r5 ++; LA64-NEXT: sltui $r4, $r4, 1 ++; LA64-NEXT: jr $ra ++ %tmp = cmpxchg i8* %ptr, i8 %cmp, i8 %val acquire acquire ++ %res = extractvalue { i8, i1 } %tmp, 1 ++ ret i1 %res ++} ++ ++define i1 @cmpxchg_i16_acquire_acquire_reti1(i16* %ptr, i16 %cmp, i16 %val) nounwind { ++; LA64-LABEL: cmpxchg_i16_acquire_acquire_reti1: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r5, $r5, 0 ++; LA64-NEXT: addi.d $r7, $zero, -4 ++; LA64-NEXT: and $r7, $r4, $r7 ++; LA64-NEXT: andi $r4, $r4, 3 ++; LA64-NEXT: slli.w $r8, $r4, 3 ++; LA64-NEXT: lu12i.w $r4, 15 ++; LA64-NEXT: ori $r4, $r4, 4095 ++; LA64-NEXT: sll.w $r9, $r4, $r8 ++; LA64-NEXT: nor $r10, $zero, $r9 ++; LA64-NEXT: and $r11, $r5, $r4 ++; LA64-NEXT: sll.w $r11, $r11, $r8 ++; LA64-NEXT: and $r4, $r6, $r4 ++; LA64-NEXT: sll.w $r6, $r4, $r8 ++; LA64-NEXT: .LBB17_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r12, $r7, 0 ++; LA64-NEXT: and $r13, $r12, $r9 ++; LA64-NEXT: bne $r13, $r11, .LBB17_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB17_1 Depth=1 ++; LA64-NEXT: and $r12, $r12, $r10 ++; LA64-NEXT: or $r12, $r12, $r6 ++; LA64-NEXT: sc.w $r12, $r7, 0 ++; LA64-NEXT: beq $r12, $zero, .LBB17_1 ++; LA64-NEXT: .LBB17_3: ++; LA64-NEXT: dbar 20 ++; LA64-NEXT: srl.w $r4, $r13, $r8 ++; LA64-NEXT: ext.w.h $r4, $r4 ++; LA64-NEXT: # %bb.4: ++; LA64-NEXT: ext.w.h $r5, $r5 ++; LA64-NEXT: xor $r4, $r4, $r5 ++; LA64-NEXT: sltui $r4, $r4, 1 ++; LA64-NEXT: jr $ra ++ %tmp = cmpxchg i16* %ptr, i16 %cmp, i16 %val acquire acquire ++ %res = extractvalue { i16, i1 } %tmp, 1 ++ ret i1 %res ++} ++ ++define i1 @cmpxchg_i32_acquire_acquire_reti1(i32* %ptr, i32 %cmp, i32 %val) nounwind { ++; LA64-LABEL: cmpxchg_i32_acquire_acquire_reti1: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r5, $r5, 0 ++; LA64-NEXT: .LBB18_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r7, $r4, 0 ++; LA64-NEXT: bne $r7, $r5, .LBB18_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB18_1 Depth=1 ++; LA64-NEXT: move $r8, $r6 ++; LA64-NEXT: sc.w $r8, $r4, 0 ++; LA64-NEXT: beq $r8, $zero, .LBB18_1 ++; LA64-NEXT: .LBB18_3: ++; LA64-NEXT: dbar 0 ++; LA64-NEXT: xor $r4, $r7, $r5 ++; LA64-NEXT: sltui $r4, $r4, 1 ++; LA64-NEXT: jr $ra ++ %tmp = cmpxchg i32* %ptr, i32 %cmp, i32 %val acquire acquire ++ %res = extractvalue { i32, i1 } %tmp, 1 ++ ret i1 %res ++} ++ ++define i1 @cmpxchg_i64_acquire_acquire_reti1(i64* %ptr, i64 %cmp, i64 %val) nounwind { ++; LA64-LABEL: cmpxchg_i64_acquire_acquire_reti1: ++; LA64: # %bb.0: ++; LA64-NEXT: .LBB19_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.d $r7, $r4, 0 ++; LA64-NEXT: bne $r7, $r5, .LBB19_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB19_1 Depth=1 ++; LA64-NEXT: move $r8, $r6 ++; LA64-NEXT: sc.d $r8, $r4, 0 ++; LA64-NEXT: beq $r8, $zero, .LBB19_1 ++; LA64-NEXT: .LBB19_3: ++; LA64-NEXT: dbar 0 ++; LA64-NEXT: xor $r4, $r7, $r5 ++; LA64-NEXT: sltui $r4, $r4, 1 ++; LA64-NEXT: jr $ra ++ %tmp = cmpxchg i64* %ptr, i64 %cmp, i64 %val acquire acquire ++ %res = extractvalue { i64, i1 } %tmp, 1 ++ ret i1 %res ++} ++ ++define void @cmpxchg_i8_monotonic_monotonic(i8* %ptr, i8 %cmp, i8 %val) nounwind { ++; LA64-LABEL: cmpxchg_i8_monotonic_monotonic: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r5, $r5, 0 ++; LA64-NEXT: addi.d $r7, $zero, -4 ++; LA64-NEXT: and $r7, $r4, $r7 ++; LA64-NEXT: andi $r4, $r4, 3 ++; LA64-NEXT: slli.w $r4, $r4, 3 ++; LA64-NEXT: ori $r8, $zero, 255 ++; LA64-NEXT: sll.w $r8, $r8, $r4 ++; LA64-NEXT: nor $r9, $zero, $r8 ++; LA64-NEXT: andi $r5, $r5, 255 ++; LA64-NEXT: sll.w $r5, $r5, $r4 ++; LA64-NEXT: andi $r6, $r6, 255 ++; LA64-NEXT: sll.w $r6, $r6, $r4 ++; LA64-NEXT: .LBB20_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r11, $r7, 0 ++; LA64-NEXT: and $r12, $r11, $r8 ++; LA64-NEXT: bne $r12, $r5, .LBB20_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB20_1 Depth=1 ++; LA64-NEXT: and $r11, $r11, $r9 ++; LA64-NEXT: or $r11, $r11, $r6 ++; LA64-NEXT: sc.w $r11, $r7, 0 ++; LA64-NEXT: beq $r11, $zero, .LBB20_1 ++; LA64-NEXT: .LBB20_3: ++; LA64-NEXT: dbar 1792 ++; LA64-NEXT: srl.w $r10, $r12, $r4 ++; LA64-NEXT: ext.w.b $r10, $r10 ++; LA64-NEXT: # %bb.4: ++; LA64-NEXT: jr $ra ++ %res = cmpxchg i8* %ptr, i8 %cmp, i8 %val monotonic monotonic ++ ret void ++} ++ ++define void @cmpxchg_i16_monotonic_monotonic(i16* %ptr, i16 %cmp, i16 %val) nounwind { ++; LA64-LABEL: cmpxchg_i16_monotonic_monotonic: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r5, $r5, 0 ++; LA64-NEXT: addi.d $r7, $zero, -4 ++; LA64-NEXT: and $r7, $r4, $r7 ++; LA64-NEXT: andi $r4, $r4, 3 ++; LA64-NEXT: slli.w $r4, $r4, 3 ++; LA64-NEXT: lu12i.w $r8, 15 ++; LA64-NEXT: ori $r8, $r8, 4095 ++; LA64-NEXT: sll.w $r9, $r8, $r4 ++; LA64-NEXT: nor $r10, $zero, $r9 ++; LA64-NEXT: and $r5, $r5, $r8 ++; LA64-NEXT: sll.w $r5, $r5, $r4 ++; LA64-NEXT: and $r6, $r6, $r8 ++; LA64-NEXT: sll.w $r6, $r6, $r4 ++; LA64-NEXT: .LBB21_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r11, $r7, 0 ++; LA64-NEXT: and $r12, $r11, $r9 ++; LA64-NEXT: bne $r12, $r5, .LBB21_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB21_1 Depth=1 ++; LA64-NEXT: and $r11, $r11, $r10 ++; LA64-NEXT: or $r11, $r11, $r6 ++; LA64-NEXT: sc.w $r11, $r7, 0 ++; LA64-NEXT: beq $r11, $zero, .LBB21_1 ++; LA64-NEXT: .LBB21_3: ++; LA64-NEXT: dbar 1792 ++; LA64-NEXT: srl.w $r8, $r12, $r4 ++; LA64-NEXT: ext.w.h $r8, $r8 ++; LA64-NEXT: # %bb.4: ++; LA64-NEXT: jr $ra ++ %res = cmpxchg i16* %ptr, i16 %cmp, i16 %val monotonic monotonic ++ ret void ++} ++ ++define void @cmpxchg_i32_monotonic_monotonic(i32* %ptr, i32 %cmp, i32 %val) nounwind { ++; LA64-LABEL: cmpxchg_i32_monotonic_monotonic: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r5, $r5, 0 ++; LA64-NEXT: .LBB22_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r7, $r4, 0 ++; LA64-NEXT: bne $r7, $r5, .LBB22_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB22_1 Depth=1 ++; LA64-NEXT: move $r8, $r6 ++; LA64-NEXT: sc.w $r8, $r4, 0 ++; LA64-NEXT: beq $r8, $zero, .LBB22_1 ++; LA64-NEXT: .LBB22_3: ++; LA64-NEXT: dbar 1792 ++; LA64-NEXT: jr $ra ++ %res = cmpxchg i32* %ptr, i32 %cmp, i32 %val monotonic monotonic ++ ret void ++} ++ ++define void @cmpxchg_i64_monotonic_monotonic(i64* %ptr, i64 %cmp, i64 %val) nounwind { ++; LA64-LABEL: cmpxchg_i64_monotonic_monotonic: ++; LA64: # %bb.0: ++; LA64-NEXT: .LBB23_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.d $r7, $r4, 0 ++; LA64-NEXT: bne $r7, $r5, .LBB23_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB23_1 Depth=1 ++; LA64-NEXT: move $r8, $r6 ++; LA64-NEXT: sc.d $r8, $r4, 0 ++; LA64-NEXT: beq $r8, $zero, .LBB23_1 ++; LA64-NEXT: .LBB23_3: ++; LA64-NEXT: dbar 1792 ++; LA64-NEXT: jr $ra ++ %res = cmpxchg i64* %ptr, i64 %cmp, i64 %val monotonic monotonic ++ ret void ++} ++ ++define i8 @cmpxchg_i8_monotonic_monotonic_reti8(i8* %ptr, i8 %cmp, i8 %val) nounwind { ++; LA64-LABEL: cmpxchg_i8_monotonic_monotonic_reti8: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r5, $r5, 0 ++; LA64-NEXT: addi.d $r7, $zero, -4 ++; LA64-NEXT: and $r7, $r4, $r7 ++; LA64-NEXT: andi $r4, $r4, 3 ++; LA64-NEXT: slli.w $r8, $r4, 3 ++; LA64-NEXT: ori $r4, $zero, 255 ++; LA64-NEXT: sll.w $r9, $r4, $r8 ++; LA64-NEXT: nor $r10, $zero, $r9 ++; LA64-NEXT: andi $r4, $r5, 255 ++; LA64-NEXT: sll.w $r5, $r4, $r8 ++; LA64-NEXT: andi $r4, $r6, 255 ++; LA64-NEXT: sll.w $r6, $r4, $r8 ++; LA64-NEXT: .LBB24_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r11, $r7, 0 ++; LA64-NEXT: and $r12, $r11, $r9 ++; LA64-NEXT: bne $r12, $r5, .LBB24_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB24_1 Depth=1 ++; LA64-NEXT: and $r11, $r11, $r10 ++; LA64-NEXT: or $r11, $r11, $r6 ++; LA64-NEXT: sc.w $r11, $r7, 0 ++; LA64-NEXT: beq $r11, $zero, .LBB24_1 ++; LA64-NEXT: .LBB24_3: ++; LA64-NEXT: dbar 1792 ++; LA64-NEXT: srl.w $r4, $r12, $r8 ++; LA64-NEXT: ext.w.b $r4, $r4 ++; LA64-NEXT: # %bb.4: ++; LA64-NEXT: jr $ra ++ %tmp = cmpxchg i8* %ptr, i8 %cmp, i8 %val monotonic monotonic ++ %res = extractvalue { i8, i1 } %tmp, 0 ++ ret i8 %res ++} ++ ++define i16 @cmpxchg_i16_monotonic_monotonic_reti16(i16* %ptr, i16 %cmp, i16 %val) nounwind { ++; LA64-LABEL: cmpxchg_i16_monotonic_monotonic_reti16: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r5, $r5, 0 ++; LA64-NEXT: addi.d $r7, $zero, -4 ++; LA64-NEXT: and $r7, $r4, $r7 ++; LA64-NEXT: andi $r4, $r4, 3 ++; LA64-NEXT: slli.w $r8, $r4, 3 ++; LA64-NEXT: lu12i.w $r4, 15 ++; LA64-NEXT: ori $r4, $r4, 4095 ++; LA64-NEXT: sll.w $r9, $r4, $r8 ++; LA64-NEXT: nor $r10, $zero, $r9 ++; LA64-NEXT: and $r5, $r5, $r4 ++; LA64-NEXT: sll.w $r5, $r5, $r8 ++; LA64-NEXT: and $r4, $r6, $r4 ++; LA64-NEXT: sll.w $r6, $r4, $r8 ++; LA64-NEXT: .LBB25_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r11, $r7, 0 ++; LA64-NEXT: and $r12, $r11, $r9 ++; LA64-NEXT: bne $r12, $r5, .LBB25_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB25_1 Depth=1 ++; LA64-NEXT: and $r11, $r11, $r10 ++; LA64-NEXT: or $r11, $r11, $r6 ++; LA64-NEXT: sc.w $r11, $r7, 0 ++; LA64-NEXT: beq $r11, $zero, .LBB25_1 ++; LA64-NEXT: .LBB25_3: ++; LA64-NEXT: dbar 1792 ++; LA64-NEXT: srl.w $r4, $r12, $r8 ++; LA64-NEXT: ext.w.h $r4, $r4 ++; LA64-NEXT: # %bb.4: ++; LA64-NEXT: jr $ra ++ %tmp = cmpxchg i16* %ptr, i16 %cmp, i16 %val monotonic monotonic ++ %res = extractvalue { i16, i1 } %tmp, 0 ++ ret i16 %res ++} ++ ++define i32 @cmpxchg_i32_monotonic_monotonic_reti32(i32* %ptr, i32 %cmp, i32 %val) nounwind { ++; LA64-LABEL: cmpxchg_i32_monotonic_monotonic_reti32: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r7, $r5, 0 ++; LA64-NEXT: .LBB26_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r5, $r4, 0 ++; LA64-NEXT: bne $r5, $r7, .LBB26_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB26_1 Depth=1 ++; LA64-NEXT: move $r8, $r6 ++; LA64-NEXT: sc.w $r8, $r4, 0 ++; LA64-NEXT: beq $r8, $zero, .LBB26_1 ++; LA64-NEXT: .LBB26_3: ++; LA64-NEXT: dbar 1792 ++; LA64-NEXT: move $r4, $r5 ++; LA64-NEXT: jr $ra ++ %tmp = cmpxchg i32* %ptr, i32 %cmp, i32 %val monotonic monotonic ++ %res = extractvalue { i32, i1 } %tmp, 0 ++ ret i32 %res ++} ++ ++define i64 @cmpxchg_i64_monotonic_monotonic_reti64(i64* %ptr, i64 %cmp, i64 %val) nounwind { ++; LA64-LABEL: cmpxchg_i64_monotonic_monotonic_reti64: ++; LA64: # %bb.0: ++; LA64-NEXT: .LBB27_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.d $r7, $r4, 0 ++; LA64-NEXT: bne $r7, $r5, .LBB27_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB27_1 Depth=1 ++; LA64-NEXT: move $r8, $r6 ++; LA64-NEXT: sc.d $r8, $r4, 0 ++; LA64-NEXT: beq $r8, $zero, .LBB27_1 ++; LA64-NEXT: .LBB27_3: ++; LA64-NEXT: dbar 1792 ++; LA64-NEXT: move $r4, $r7 ++; LA64-NEXT: jr $ra ++ %tmp = cmpxchg i64* %ptr, i64 %cmp, i64 %val monotonic monotonic ++ %res = extractvalue { i64, i1 } %tmp, 0 ++ ret i64 %res ++} ++ ++define i1 @cmpxchg_i8_monotonic_monotonic_reti1(i8* %ptr, i8 %cmp, i8 %val) nounwind { ++; LA64-LABEL: cmpxchg_i8_monotonic_monotonic_reti1: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r5, $r5, 0 ++; LA64-NEXT: addi.d $r7, $zero, -4 ++; LA64-NEXT: and $r7, $r4, $r7 ++; LA64-NEXT: andi $r4, $r4, 3 ++; LA64-NEXT: slli.w $r8, $r4, 3 ++; LA64-NEXT: ori $r4, $zero, 255 ++; LA64-NEXT: sll.w $r9, $r4, $r8 ++; LA64-NEXT: nor $r10, $zero, $r9 ++; LA64-NEXT: andi $r4, $r5, 255 ++; LA64-NEXT: sll.w $r11, $r4, $r8 ++; LA64-NEXT: andi $r4, $r6, 255 ++; LA64-NEXT: sll.w $r6, $r4, $r8 ++; LA64-NEXT: .LBB28_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r12, $r7, 0 ++; LA64-NEXT: and $r13, $r12, $r9 ++; LA64-NEXT: bne $r13, $r11, .LBB28_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB28_1 Depth=1 ++; LA64-NEXT: and $r12, $r12, $r10 ++; LA64-NEXT: or $r12, $r12, $r6 ++; LA64-NEXT: sc.w $r12, $r7, 0 ++; LA64-NEXT: beq $r12, $zero, .LBB28_1 ++; LA64-NEXT: .LBB28_3: ++; LA64-NEXT: dbar 1792 ++; LA64-NEXT: srl.w $r4, $r13, $r8 ++; LA64-NEXT: ext.w.b $r4, $r4 ++; LA64-NEXT: # %bb.4: ++; LA64-NEXT: ext.w.b $r5, $r5 ++; LA64-NEXT: xor $r4, $r4, $r5 ++; LA64-NEXT: sltui $r4, $r4, 1 ++; LA64-NEXT: jr $ra ++ %tmp = cmpxchg i8* %ptr, i8 %cmp, i8 %val monotonic monotonic ++ %res = extractvalue { i8, i1 } %tmp, 1 ++ ret i1 %res ++} ++ ++define i1 @cmpxchg_i16_monotonic_monotonic_reti1(i16* %ptr, i16 %cmp, i16 %val) nounwind { ++; LA64-LABEL: cmpxchg_i16_monotonic_monotonic_reti1: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r5, $r5, 0 ++; LA64-NEXT: addi.d $r7, $zero, -4 ++; LA64-NEXT: and $r7, $r4, $r7 ++; LA64-NEXT: andi $r4, $r4, 3 ++; LA64-NEXT: slli.w $r8, $r4, 3 ++; LA64-NEXT: lu12i.w $r4, 15 ++; LA64-NEXT: ori $r4, $r4, 4095 ++; LA64-NEXT: sll.w $r9, $r4, $r8 ++; LA64-NEXT: nor $r10, $zero, $r9 ++; LA64-NEXT: and $r11, $r5, $r4 ++; LA64-NEXT: sll.w $r11, $r11, $r8 ++; LA64-NEXT: and $r4, $r6, $r4 ++; LA64-NEXT: sll.w $r6, $r4, $r8 ++; LA64-NEXT: .LBB29_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r12, $r7, 0 ++; LA64-NEXT: and $r13, $r12, $r9 ++; LA64-NEXT: bne $r13, $r11, .LBB29_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB29_1 Depth=1 ++; LA64-NEXT: and $r12, $r12, $r10 ++; LA64-NEXT: or $r12, $r12, $r6 ++; LA64-NEXT: sc.w $r12, $r7, 0 ++; LA64-NEXT: beq $r12, $zero, .LBB29_1 ++; LA64-NEXT: .LBB29_3: ++; LA64-NEXT: dbar 1792 ++; LA64-NEXT: srl.w $r4, $r13, $r8 ++; LA64-NEXT: ext.w.h $r4, $r4 ++; LA64-NEXT: # %bb.4: ++; LA64-NEXT: ext.w.h $r5, $r5 ++; LA64-NEXT: xor $r4, $r4, $r5 ++; LA64-NEXT: sltui $r4, $r4, 1 ++; LA64-NEXT: jr $ra ++ %tmp = cmpxchg i16* %ptr, i16 %cmp, i16 %val monotonic monotonic ++ %res = extractvalue { i16, i1 } %tmp, 1 ++ ret i1 %res ++} ++ ++define i1 @cmpxchg_i32_monotonic_monotonic_reti1(i32* %ptr, i32 %cmp, i32 %val) nounwind { ++; LA64-LABEL: cmpxchg_i32_monotonic_monotonic_reti1: ++; LA64: # %bb.0: ++; LA64-NEXT: slli.w $r6, $r6, 0 ++; LA64-NEXT: slli.w $r5, $r5, 0 ++; LA64-NEXT: .LBB30_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.w $r7, $r4, 0 ++; LA64-NEXT: bne $r7, $r5, .LBB30_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB30_1 Depth=1 ++; LA64-NEXT: move $r8, $r6 ++; LA64-NEXT: sc.w $r8, $r4, 0 ++; LA64-NEXT: beq $r8, $zero, .LBB30_1 ++; LA64-NEXT: .LBB30_3: ++; LA64-NEXT: dbar 1792 ++; LA64-NEXT: xor $r4, $r7, $r5 ++; LA64-NEXT: sltui $r4, $r4, 1 ++; LA64-NEXT: jr $ra ++ %tmp = cmpxchg i32* %ptr, i32 %cmp, i32 %val monotonic monotonic ++ %res = extractvalue { i32, i1 } %tmp, 1 ++ ret i1 %res ++} ++ ++define i1 @cmpxchg_i64_monotonic_monotonic_reti1(i64* %ptr, i64 %cmp, i64 %val) nounwind { ++; LA64-LABEL: cmpxchg_i64_monotonic_monotonic_reti1: ++; LA64: # %bb.0: ++; LA64-NEXT: .LBB31_1: # =>This Inner Loop Header: Depth=1 ++; LA64-NEXT: ll.d $r7, $r4, 0 ++; LA64-NEXT: bne $r7, $r5, .LBB31_3 ++; LA64-NEXT: # %bb.2: # in Loop: Header=BB31_1 Depth=1 ++; LA64-NEXT: move $r8, $r6 ++; LA64-NEXT: sc.d $r8, $r4, 0 ++; LA64-NEXT: beq $r8, $zero, .LBB31_1 ++; LA64-NEXT: .LBB31_3: ++; LA64-NEXT: dbar 1792 ++; LA64-NEXT: xor $r4, $r7, $r5 ++; LA64-NEXT: sltui $r4, $r4, 1 ++; LA64-NEXT: jr $ra ++ %tmp = cmpxchg i64* %ptr, i64 %cmp, i64 %val monotonic monotonic ++ %res = extractvalue { i64, i1 } %tmp, 1 ++ ret i1 %res ++} +diff --git a/llvm/test/CodeGen/LoongArch/atomic-operand-imm0.ll b/llvm/test/CodeGen/LoongArch/atomic-operand-imm0.ll +new file mode 100644 +index 000000000..d1d0c0bc4 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/atomic-operand-imm0.ll +@@ -0,0 +1,17 @@ ++; Test that the last immediate 0 operand of amtomic instruction is printed ++ ++; RUN: llc -march=loongarch64 -o - %s | FileCheck %s ++ ++define void @test_i32(i32* %dst, i32 %val) { ++; CHECK: ammax_db.wu $r[[REG1:[0-9]+]], $r[[REG2:[0-9]+]], $r[[REG3:[0-9]+]], 0 ++entry: ++ %a = atomicrmw umax i32* %dst, i32 %val monotonic ++ ret void ++} ++ ++define void @test_i64(i64* %dst, i64 %val) { ++; CHECK: ammax_db.du $r[[REG1:[0-9]+]], $r[[REG2:[0-9]+]], $r[[REG3:[0-9]+]], 0 ++entry: ++ %a = atomicrmw umax i64* %dst, i64 %val monotonic ++ ret void ++} +diff --git a/llvm/test/CodeGen/LoongArch/atomic_16_8.ll b/llvm/test/CodeGen/LoongArch/atomic_16_8.ll +new file mode 100644 +index 000000000..ba454ab40 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/atomic_16_8.ll +@@ -0,0 +1,785 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -mtriple=loongarch64 -o - %s | FileCheck %s ++ ++ ++define void @umax_8(i8* %ptr) { ++; CHECK-LABEL: umax_8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: ori $r7, $zero, 255 ++; CHECK-NEXT: sll.w $r7, $r7, $r4 ++; CHECK-NEXT: nor $r8, $zero, $r7 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB0_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r7 ++; CHECK-NEXT: and $r5, $r5, $r7 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r8 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB0_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r9, $r10, $r7 ++; CHECK-NEXT: srl.w $r9, $r9, $r4 ++; CHECK-NEXT: ext.w.b $r9, $r9 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw umax i8* %ptr, i8 100 seq_cst ++ ret void ++} ++ ++define void @umax_16(i16* %ptr) { ++; CHECK-LABEL: umax_16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: lu12i.w $r7, 15 ++; CHECK-NEXT: ori $r7, $r7, 4095 ++; CHECK-NEXT: sll.w $r7, $r7, $r4 ++; CHECK-NEXT: nor $r8, $zero, $r7 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB1_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r7 ++; CHECK-NEXT: and $r5, $r5, $r7 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r8 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB1_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r9, $r10, $r7 ++; CHECK-NEXT: srl.w $r9, $r9, $r4 ++; CHECK-NEXT: ext.w.h $r9, $r9 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw umax i16* %ptr, i16 100 seq_cst ++ ret void ++} ++ ++define void @max_8(i8* %ptr) { ++; CHECK-LABEL: max_8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: ori $r7, $zero, 255 ++; CHECK-NEXT: sll.w $r7, $r7, $r4 ++; CHECK-NEXT: nor $r8, $zero, $r7 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB2_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r7 ++; CHECK-NEXT: and $r5, $r5, $r7 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r8 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB2_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r9, $r10, $r7 ++; CHECK-NEXT: srl.w $r9, $r9, $r4 ++; CHECK-NEXT: ext.w.b $r9, $r9 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw max i8* %ptr, i8 100 seq_cst ++ ret void ++} ++ ++define void @max_16(i16* %ptr) { ++; CHECK-LABEL: max_16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: lu12i.w $r7, 15 ++; CHECK-NEXT: ori $r7, $r7, 4095 ++; CHECK-NEXT: sll.w $r7, $r7, $r4 ++; CHECK-NEXT: nor $r8, $zero, $r7 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB3_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r7 ++; CHECK-NEXT: and $r5, $r5, $r7 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r8 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB3_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r9, $r10, $r7 ++; CHECK-NEXT: srl.w $r9, $r9, $r4 ++; CHECK-NEXT: ext.w.h $r9, $r9 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw max i16* %ptr, i16 100 seq_cst ++ ret void ++} ++ ++ ++define void @umin_8(i8* %ptr) { ++; CHECK-LABEL: umin_8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: ori $r7, $zero, 255 ++; CHECK-NEXT: sll.w $r7, $r7, $r4 ++; CHECK-NEXT: nor $r8, $zero, $r7 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB4_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r7 ++; CHECK-NEXT: and $r5, $r5, $r7 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r8 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB4_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r9, $r10, $r7 ++; CHECK-NEXT: srl.w $r9, $r9, $r4 ++; CHECK-NEXT: ext.w.b $r9, $r9 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw umin i8* %ptr, i8 100 seq_cst ++ ret void ++} ++ ++define void @umin_16(i16* %ptr) { ++; CHECK-LABEL: umin_16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: lu12i.w $r7, 15 ++; CHECK-NEXT: ori $r7, $r7, 4095 ++; CHECK-NEXT: sll.w $r7, $r7, $r4 ++; CHECK-NEXT: nor $r8, $zero, $r7 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB5_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r7 ++; CHECK-NEXT: and $r5, $r5, $r7 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r8 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB5_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r9, $r10, $r7 ++; CHECK-NEXT: srl.w $r9, $r9, $r4 ++; CHECK-NEXT: ext.w.h $r9, $r9 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw umin i16* %ptr, i16 100 seq_cst ++ ret void ++} ++ ++define void @min_8(i8* %ptr) { ++; CHECK-LABEL: min_8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: ori $r7, $zero, 255 ++; CHECK-NEXT: sll.w $r7, $r7, $r4 ++; CHECK-NEXT: nor $r8, $zero, $r7 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB6_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r7 ++; CHECK-NEXT: and $r5, $r5, $r7 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r8 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB6_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r9, $r10, $r7 ++; CHECK-NEXT: srl.w $r9, $r9, $r4 ++; CHECK-NEXT: ext.w.b $r9, $r9 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw min i8* %ptr, i8 100 seq_cst ++ ret void ++} ++ ++define void @min_16(i16* %ptr) { ++; CHECK-LABEL: min_16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: lu12i.w $r7, 15 ++; CHECK-NEXT: ori $r7, $r7, 4095 ++; CHECK-NEXT: sll.w $r7, $r7, $r4 ++; CHECK-NEXT: nor $r8, $zero, $r7 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB7_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r7 ++; CHECK-NEXT: and $r5, $r5, $r7 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r8 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB7_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r9, $r10, $r7 ++; CHECK-NEXT: srl.w $r9, $r9, $r4 ++; CHECK-NEXT: ext.w.h $r9, $r9 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw min i16* %ptr, i16 100 seq_cst ++ ret void ++} ++ ++ ++define void @or_8(i8* %ptr) { ++; CHECK-LABEL: or_8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: ori $r7, $zero, 255 ++; CHECK-NEXT: sll.w $r7, $r7, $r4 ++; CHECK-NEXT: nor $r8, $zero, $r7 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB8_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: or $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r7 ++; CHECK-NEXT: and $r12, $r10, $r8 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB8_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r9, $r10, $r7 ++; CHECK-NEXT: srl.w $r9, $r9, $r4 ++; CHECK-NEXT: ext.w.b $r9, $r9 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw or i8* %ptr, i8 100 seq_cst ++ ret void ++} ++ ++define void @or_16(i16* %ptr) { ++; CHECK-LABEL: or_16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: lu12i.w $r7, 15 ++; CHECK-NEXT: ori $r7, $r7, 4095 ++; CHECK-NEXT: sll.w $r7, $r7, $r4 ++; CHECK-NEXT: nor $r8, $zero, $r7 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB9_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: or $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r7 ++; CHECK-NEXT: and $r12, $r10, $r8 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB9_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r9, $r10, $r7 ++; CHECK-NEXT: srl.w $r9, $r9, $r4 ++; CHECK-NEXT: ext.w.h $r9, $r9 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw or i16* %ptr, i16 100 seq_cst ++ ret void ++} ++ ++ ++define void @add_8(i8* %ptr) { ++; CHECK-LABEL: add_8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: ori $r7, $zero, 255 ++; CHECK-NEXT: sll.w $r7, $r7, $r4 ++; CHECK-NEXT: nor $r8, $zero, $r7 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB10_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: add.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r7 ++; CHECK-NEXT: and $r12, $r10, $r8 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB10_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r9, $r10, $r7 ++; CHECK-NEXT: srl.w $r9, $r9, $r4 ++; CHECK-NEXT: ext.w.b $r9, $r9 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw add i8* %ptr, i8 100 seq_cst ++ ret void ++} ++ ++define void @add_16(i16* %ptr) { ++; CHECK-LABEL: add_16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: lu12i.w $r7, 15 ++; CHECK-NEXT: ori $r7, $r7, 4095 ++; CHECK-NEXT: sll.w $r7, $r7, $r4 ++; CHECK-NEXT: nor $r8, $zero, $r7 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB11_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: add.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r7 ++; CHECK-NEXT: and $r12, $r10, $r8 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB11_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r9, $r10, $r7 ++; CHECK-NEXT: srl.w $r9, $r9, $r4 ++; CHECK-NEXT: ext.w.h $r9, $r9 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw add i16* %ptr, i16 100 seq_cst ++ ret void ++} ++ ++ ++define void @sub_8(i8* %ptr) { ++; CHECK-LABEL: sub_8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: ori $r7, $zero, 255 ++; CHECK-NEXT: sll.w $r7, $r7, $r4 ++; CHECK-NEXT: nor $r8, $zero, $r7 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB12_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: sub.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r7 ++; CHECK-NEXT: and $r12, $r10, $r8 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB12_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r9, $r10, $r7 ++; CHECK-NEXT: srl.w $r9, $r9, $r4 ++; CHECK-NEXT: ext.w.b $r9, $r9 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw sub i8* %ptr, i8 100 seq_cst ++ ret void ++} ++ ++define void @sub_16(i16* %ptr) { ++; CHECK-LABEL: sub_16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: lu12i.w $r7, 15 ++; CHECK-NEXT: ori $r7, $r7, 4095 ++; CHECK-NEXT: sll.w $r7, $r7, $r4 ++; CHECK-NEXT: nor $r8, $zero, $r7 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB13_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: sub.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r7 ++; CHECK-NEXT: and $r12, $r10, $r8 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB13_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r9, $r10, $r7 ++; CHECK-NEXT: srl.w $r9, $r9, $r4 ++; CHECK-NEXT: ext.w.h $r9, $r9 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw sub i16* %ptr, i16 100 seq_cst ++ ret void ++} ++ ++ ++define void @and_8(i8* %ptr) { ++; CHECK-LABEL: and_8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: ori $r7, $zero, 255 ++; CHECK-NEXT: sll.w $r7, $r7, $r4 ++; CHECK-NEXT: nor $r8, $zero, $r7 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB14_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r7 ++; CHECK-NEXT: and $r12, $r10, $r8 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB14_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r9, $r10, $r7 ++; CHECK-NEXT: srl.w $r9, $r9, $r4 ++; CHECK-NEXT: ext.w.b $r9, $r9 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw and i8* %ptr, i8 100 seq_cst ++ ret void ++} ++ ++define void @and_16(i16* %ptr) { ++; CHECK-LABEL: and_16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: lu12i.w $r7, 15 ++; CHECK-NEXT: ori $r7, $r7, 4095 ++; CHECK-NEXT: sll.w $r7, $r7, $r4 ++; CHECK-NEXT: nor $r8, $zero, $r7 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB15_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r7 ++; CHECK-NEXT: and $r12, $r10, $r8 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB15_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r9, $r10, $r7 ++; CHECK-NEXT: srl.w $r9, $r9, $r4 ++; CHECK-NEXT: ext.w.h $r9, $r9 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw and i16* %ptr, i16 100 seq_cst ++ ret void ++} ++ ++ ++define void @nand_8(i8* %ptr) { ++; CHECK-LABEL: nand_8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: ori $r7, $zero, 255 ++; CHECK-NEXT: sll.w $r7, $r7, $r4 ++; CHECK-NEXT: nor $r8, $zero, $r7 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB16_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: nor $r11, $zero, $r11 ++; CHECK-NEXT: and $r11, $r11, $r7 ++; CHECK-NEXT: and $r12, $r10, $r8 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB16_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r9, $r10, $r7 ++; CHECK-NEXT: srl.w $r9, $r9, $r4 ++; CHECK-NEXT: ext.w.b $r9, $r9 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw nand i8* %ptr, i8 100 seq_cst ++ ret void ++} ++ ++define void @nand_16(i16* %ptr) { ++; CHECK-LABEL: nand_16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: lu12i.w $r7, 15 ++; CHECK-NEXT: ori $r7, $r7, 4095 ++; CHECK-NEXT: sll.w $r7, $r7, $r4 ++; CHECK-NEXT: nor $r8, $zero, $r7 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB17_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: nor $r11, $zero, $r11 ++; CHECK-NEXT: and $r11, $r11, $r7 ++; CHECK-NEXT: and $r12, $r10, $r8 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB17_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r9, $r10, $r7 ++; CHECK-NEXT: srl.w $r9, $r9, $r4 ++; CHECK-NEXT: ext.w.h $r9, $r9 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw nand i16* %ptr, i16 100 seq_cst ++ ret void ++} ++ ++ ++define void @xor_8(i8* %ptr) { ++; CHECK-LABEL: xor_8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: ori $r7, $zero, 255 ++; CHECK-NEXT: sll.w $r7, $r7, $r4 ++; CHECK-NEXT: nor $r8, $zero, $r7 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB18_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: xor $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r7 ++; CHECK-NEXT: and $r12, $r10, $r8 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB18_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r9, $r10, $r7 ++; CHECK-NEXT: srl.w $r9, $r9, $r4 ++; CHECK-NEXT: ext.w.b $r9, $r9 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw xor i8* %ptr, i8 100 seq_cst ++ ret void ++} ++ ++define void @xor_16(i16* %ptr) { ++; CHECK-LABEL: xor_16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: lu12i.w $r7, 15 ++; CHECK-NEXT: ori $r7, $r7, 4095 ++; CHECK-NEXT: sll.w $r7, $r7, $r4 ++; CHECK-NEXT: nor $r8, $zero, $r7 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB19_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: xor $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r7 ++; CHECK-NEXT: and $r12, $r10, $r8 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB19_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r9, $r10, $r7 ++; CHECK-NEXT: srl.w $r9, $r9, $r4 ++; CHECK-NEXT: ext.w.h $r9, $r9 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw xor i16* %ptr, i16 100 seq_cst ++ ret void ++} ++ ++ ++define void @xchg_8(i8* %ptr) { ++; CHECK-LABEL: xchg_8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: ori $r7, $zero, 255 ++; CHECK-NEXT: sll.w $r7, $r7, $r4 ++; CHECK-NEXT: nor $r8, $zero, $r7 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB20_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r7 ++; CHECK-NEXT: and $r12, $r10, $r8 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB20_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r9, $r10, $r7 ++; CHECK-NEXT: srl.w $r9, $r9, $r4 ++; CHECK-NEXT: ext.w.b $r9, $r9 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw xchg i8* %ptr, i8 100 seq_cst ++ ret void ++} ++ ++define void @xchg_16(i16* %ptr) { ++; CHECK-LABEL: xchg_16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: lu12i.w $r7, 15 ++; CHECK-NEXT: ori $r7, $r7, 4095 ++; CHECK-NEXT: sll.w $r7, $r7, $r4 ++; CHECK-NEXT: nor $r8, $zero, $r7 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB21_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r7 ++; CHECK-NEXT: and $r12, $r10, $r8 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB21_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r9, $r10, $r7 ++; CHECK-NEXT: srl.w $r9, $r9, $r4 ++; CHECK-NEXT: ext.w.h $r9, $r9 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw xchg i16* %ptr, i16 100 seq_cst ++ ret void ++} ++ ++define void @cmpxchg_8(i8* %ptr) { ++; CHECK-LABEL: cmpxchg_8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 1 ++; CHECK-NEXT: ori $r6, $zero, 100 ++; CHECK-NEXT: addi.d $r7, $zero, -4 ++; CHECK-NEXT: and $r7, $r4, $r7 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: ori $r8, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r8, $r4 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: andi $r6, $r6, 255 ++; CHECK-NEXT: sll.w $r6, $r6, $r4 ++; CHECK-NEXT: andi $r5, $r5, 255 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB22_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r11, $r7, 0 ++; CHECK-NEXT: and $r12, $r11, $r8 ++; CHECK-NEXT: bne $r12, $r6, .LBB22_3 ++; CHECK-NEXT: # %bb.2: # in Loop: Header=BB22_1 Depth=1 ++; CHECK-NEXT: and $r11, $r11, $r9 ++; CHECK-NEXT: or $r11, $r11, $r5 ++; CHECK-NEXT: sc.w $r11, $r7, 0 ++; CHECK-NEXT: beq $r11, $zero, .LBB22_1 ++; CHECK-NEXT: .LBB22_3: ++; CHECK-NEXT: dbar 20 ++; CHECK-NEXT: srl.w $r10, $r12, $r4 ++; CHECK-NEXT: ext.w.b $r10, $r10 ++; CHECK-NEXT: # %bb.4: ++; CHECK-NEXT: jr $ra ++ %ret = cmpxchg i8* %ptr, i8 100, i8 1 seq_cst seq_cst ++ ret void ++} ++ ++define void @cmpxchg_16(i16* %ptr) { ++; CHECK-LABEL: cmpxchg_16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 1 ++; CHECK-NEXT: ori $r6, $zero, 100 ++; CHECK-NEXT: addi.d $r7, $zero, -4 ++; CHECK-NEXT: and $r7, $r4, $r7 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r4, $r4, 3 ++; CHECK-NEXT: lu12i.w $r8, 15 ++; CHECK-NEXT: ori $r8, $r8, 4095 ++; CHECK-NEXT: sll.w $r9, $r8, $r4 ++; CHECK-NEXT: nor $r10, $zero, $r9 ++; CHECK-NEXT: and $r6, $r6, $r8 ++; CHECK-NEXT: sll.w $r6, $r6, $r4 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r4 ++; CHECK-NEXT: .LBB23_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r11, $r7, 0 ++; CHECK-NEXT: and $r12, $r11, $r9 ++; CHECK-NEXT: bne $r12, $r6, .LBB23_3 ++; CHECK-NEXT: # %bb.2: # in Loop: Header=BB23_1 Depth=1 ++; CHECK-NEXT: and $r11, $r11, $r10 ++; CHECK-NEXT: or $r11, $r11, $r5 ++; CHECK-NEXT: sc.w $r11, $r7, 0 ++; CHECK-NEXT: beq $r11, $zero, .LBB23_1 ++; CHECK-NEXT: .LBB23_3: ++; CHECK-NEXT: dbar 20 ++; CHECK-NEXT: srl.w $r8, $r12, $r4 ++; CHECK-NEXT: ext.w.h $r8, $r8 ++; CHECK-NEXT: # %bb.4: ++; CHECK-NEXT: jr $ra ++ %ret = cmpxchg i16* %ptr, i16 100, i16 1 seq_cst seq_cst ++ ret void ++} +diff --git a/llvm/test/CodeGen/LoongArch/atomic_64_32.ll b/llvm/test/CodeGen/LoongArch/atomic_64_32.ll +new file mode 100644 +index 000000000..61a24cd5d +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/atomic_64_32.ll +@@ -0,0 +1,323 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -mtriple=loongarch64 --verify-machineinstrs -o - %s | FileCheck %s ++ ++ ++define void @umax_32(i32* %ptr) { ++; CHECK-LABEL: umax_32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.wu $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw umax i32* %ptr, i32 100 seq_cst ++ ret void ++} ++ ++define void @umax_64(i64* %ptr) { ++; CHECK-LABEL: umax_64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $r5, $zero, 100 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.du $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw umax i64* %ptr, i64 100 seq_cst ++ ret void ++} ++ ++define void @max_32(i32* %ptr) { ++; CHECK-LABEL: max_32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.w $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw max i32* %ptr, i32 100 seq_cst ++ ret void ++} ++ ++define void @max_64(i64* %ptr) { ++; CHECK-LABEL: max_64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $r5, $zero, 100 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw max i64* %ptr, i64 100 seq_cst ++ ret void ++} ++ ++ ++define void @umin_32(i32* %ptr) { ++; CHECK-LABEL: umin_32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.wu $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw umin i32* %ptr, i32 100 seq_cst ++ ret void ++} ++ ++define void @umin_64(i64* %ptr) { ++; CHECK-LABEL: umin_64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $r5, $zero, 100 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.du $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw umin i64* %ptr, i64 100 seq_cst ++ ret void ++} ++ ++define void @min_32(i32* %ptr) { ++; CHECK-LABEL: min_32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.w $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw min i32* %ptr, i32 100 seq_cst ++ ret void ++} ++ ++define void @min_64(i64* %ptr) { ++; CHECK-LABEL: min_64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $r5, $zero, 100 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw min i64* %ptr, i64 100 seq_cst ++ ret void ++} ++ ++ ++define void @or_32(i32* %ptr) { ++; CHECK-LABEL: or_32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amor_db.w $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw or i32* %ptr, i32 100 seq_cst ++ ret void ++} ++ ++define void @or_64(i64* %ptr) { ++; CHECK-LABEL: or_64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $r5, $zero, 100 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amor_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw or i64* %ptr, i64 100 seq_cst ++ ret void ++} ++ ++ ++define void @add_32(i32* %ptr) { ++; CHECK-LABEL: add_32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amadd_db.w $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw add i32* %ptr, i32 100 seq_cst ++ ret void ++} ++ ++define void @add_64(i64* %ptr) { ++; CHECK-LABEL: add_64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $r5, $zero, 100 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amadd_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw add i64* %ptr, i64 100 seq_cst ++ ret void ++} ++ ++ ++define void @sub_32(i32* %ptr) { ++; CHECK-LABEL: sub_32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: sub.w $r7, $zero, $r5 ++; CHECK-NEXT: amadd_db.w $r6, $r7, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw sub i32* %ptr, i32 100 seq_cst ++ ret void ++} ++ ++define void @sub_64(i64* %ptr) { ++; CHECK-LABEL: sub_64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $r5, $zero, 100 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: sub.d $r7, $zero, $r5 ++; CHECK-NEXT: amadd_db.d $r6, $r7, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw sub i64* %ptr, i64 100 seq_cst ++ ret void ++} ++ ++ ++define void @and_32(i32* %ptr) { ++; CHECK-LABEL: and_32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amand_db.w $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw and i32* %ptr, i32 100 seq_cst ++ ret void ++} ++ ++define void @and_64(i64* %ptr) { ++; CHECK-LABEL: and_64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $r5, $zero, 100 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amand_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw and i64* %ptr, i64 100 seq_cst ++ ret void ++} ++ ++ ++define void @nand_32(i32* %ptr) { ++; CHECK-LABEL: nand_32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: .LBB16_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r6, $r4, 0 ++; CHECK-NEXT: and $r7, $r6, $r5 ++; CHECK-NEXT: nor $r7, $zero, $r7 ++; CHECK-NEXT: sc.w $r7, $r4, 0 ++; CHECK-NEXT: beq $r7, $zero, .LBB16_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw nand i32* %ptr, i32 100 seq_cst ++ ret void ++} ++ ++define void @nand_64(i64* %ptr) { ++; CHECK-LABEL: nand_64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $r5, $zero, 100 ++; CHECK-NEXT: .LBB17_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.d $r6, $r4, 0 ++; CHECK-NEXT: and $r7, $r6, $r5 ++; CHECK-NEXT: nor $r7, $zero, $r7 ++; CHECK-NEXT: sc.d $r7, $r4, 0 ++; CHECK-NEXT: beq $r7, $zero, .LBB17_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw nand i64* %ptr, i64 100 seq_cst ++ ret void ++} ++ ++ ++define void @xor_32(i32* %ptr) { ++; CHECK-LABEL: xor_32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amxor_db.w $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw xor i32* %ptr, i32 100 seq_cst ++ ret void ++} ++ ++define void @xor_64(i64* %ptr) { ++; CHECK-LABEL: xor_64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $r5, $zero, 100 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amxor_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw xor i64* %ptr, i64 100 seq_cst ++ ret void ++} ++ ++ ++define void @xchg_32(i32* %ptr) { ++; CHECK-LABEL: xchg_32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 100 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amswap_db.w $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw xchg i32* %ptr, i32 100 seq_cst ++ ret void ++} ++ ++define void @xchg_64(i64* %ptr) { ++; CHECK-LABEL: xchg_64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $r5, $zero, 100 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amswap_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: jr $ra ++ %ret = atomicrmw xchg i64* %ptr, i64 100 seq_cst ++ ret void ++} ++ ++define void @cmpxchg_32(i32* %ptr) { ++; CHECK-LABEL: cmpxchg_32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 1 ++; CHECK-NEXT: ori $r6, $zero, 100 ++; CHECK-NEXT: .LBB22_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r7, $r4, 0 ++; CHECK-NEXT: bne $r7, $r6, .LBB22_3 ++; CHECK-NEXT: # %bb.2: # in Loop: Header=BB22_1 Depth=1 ++; CHECK-NEXT: move $r8, $r5 ++; CHECK-NEXT: sc.w $r8, $r4, 0 ++; CHECK-NEXT: beq $r8, $zero, .LBB22_1 ++; CHECK-NEXT: .LBB22_3: ++; CHECK-NEXT: dbar 0 ++; CHECK-NEXT: jr $ra ++ %ret = cmpxchg i32* %ptr, i32 100, i32 1 seq_cst seq_cst ++ ret void ++} ++ ++define void @cmpxchg_64(i64* %ptr) { ++; CHECK-LABEL: cmpxchg_64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $r5, $zero, 1 ++; CHECK-NEXT: addi.d $r6, $zero, 100 ++; CHECK-NEXT: .LBB23_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.d $r7, $r4, 0 ++; CHECK-NEXT: bne $r7, $r6, .LBB23_3 ++; CHECK-NEXT: # %bb.2: # in Loop: Header=BB23_1 Depth=1 ++; CHECK-NEXT: move $r8, $r5 ++; CHECK-NEXT: sc.d $r8, $r4, 0 ++; CHECK-NEXT: beq $r8, $zero, .LBB23_1 ++; CHECK-NEXT: .LBB23_3: ++; CHECK-NEXT: dbar 0 ++; CHECK-NEXT: jr $ra ++ %ret = cmpxchg i64* %ptr, i64 100, i64 1 seq_cst seq_cst ++ ret void ++} +diff --git a/llvm/test/CodeGen/LoongArch/atomicrmw-fp.ll b/llvm/test/CodeGen/LoongArch/atomicrmw-fp.ll +new file mode 100644 +index 000000000..7ef963cc6 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/atomicrmw-fp.ll +@@ -0,0 +1,1776 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s ++ ++define float @float_fadd_acquire(ptr %p) nounwind { ++; CHECK-LABEL: float_fadd_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fld.s $f0, $r4, 0 ++; CHECK-NEXT: addi.w $r5, $zero, 1 ++; CHECK-NEXT: movgr2fr.w $f1, $r5 ++; CHECK-NEXT: ffint.s.w $f1, $f1 ++; CHECK-NEXT: .LBB0_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Loop Header: Depth=1 ++; CHECK-NEXT: # Child Loop BB0_2 Depth 2 ++; CHECK-NEXT: fadd.s $f2, $f0, $f1 ++; CHECK-NEXT: movfr2gr.s $r5, $f2 ++; CHECK-NEXT: movfr2gr.s $r6, $f0 ++; CHECK-NEXT: .LBB0_2: # %atomicrmw.start ++; CHECK-NEXT: # Parent Loop BB0_1 Depth=1 ++; CHECK-NEXT: # => This Inner Loop Header: Depth=2 ++; CHECK-NEXT: ll.w $r7, $r4, 0 ++; CHECK-NEXT: bne $r7, $r6, .LBB0_4 ++; CHECK-NEXT: # %bb.3: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB0_2 Depth=2 ++; CHECK-NEXT: move $r8, $r5 ++; CHECK-NEXT: sc.w $r8, $r4, 0 ++; CHECK-NEXT: beq $r8, $zero, .LBB0_2 ++; CHECK-NEXT: .LBB0_4: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1 ++; CHECK-NEXT: dbar 0 ++; CHECK-NEXT: movgr2fr.w $f0, $r7 ++; CHECK-NEXT: bne $r7, $r6, .LBB0_1 ++; CHECK-NEXT: # %bb.5: # %atomicrmw.end ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fadd ptr %p, float 1.0 acquire, align 4 ++ ret float %v ++} ++ ++define float @float_fsub_acquire(ptr %p) nounwind { ++; CHECK-LABEL: float_fsub_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fld.s $f0, $r4, 0 ++; CHECK-NEXT: .LBB1_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Loop Header: Depth=1 ++; CHECK-NEXT: # Child Loop BB1_2 Depth 2 ++; CHECK-NEXT: lu12i.w $r5, .LCPI1_0 ++; CHECK-NEXT: ori $r5, $r5, .LCPI1_0 ++; CHECK-NEXT: lu32i.d $r5, .LCPI1_0 ++; CHECK-NEXT: lu52i.d $r5, $r5, .LCPI1_0 ++; CHECK-NEXT: fld.s $f1, $r5, 0 ++; CHECK-NEXT: fadd.s $f1, $f0, $f1 ++; CHECK-NEXT: movfr2gr.s $r5, $f1 ++; CHECK-NEXT: movfr2gr.s $r6, $f0 ++; CHECK-NEXT: .LBB1_2: # %atomicrmw.start ++; CHECK-NEXT: # Parent Loop BB1_1 Depth=1 ++; CHECK-NEXT: # => This Inner Loop Header: Depth=2 ++; CHECK-NEXT: ll.w $r7, $r4, 0 ++; CHECK-NEXT: bne $r7, $r6, .LBB1_4 ++; CHECK-NEXT: # %bb.3: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB1_2 Depth=2 ++; CHECK-NEXT: move $r8, $r5 ++; CHECK-NEXT: sc.w $r8, $r4, 0 ++; CHECK-NEXT: beq $r8, $zero, .LBB1_2 ++; CHECK-NEXT: .LBB1_4: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB1_1 Depth=1 ++; CHECK-NEXT: dbar 0 ++; CHECK-NEXT: movgr2fr.w $f0, $r7 ++; CHECK-NEXT: bne $r7, $r6, .LBB1_1 ++; CHECK-NEXT: # %bb.5: # %atomicrmw.end ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fsub ptr %p, float 1.0 acquire, align 4 ++ ret float %v ++} ++ ++define float @float_fmin_acquire(ptr %p) nounwind { ++; CHECK-LABEL: float_fmin_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fld.s $f0, $r4, 0 ++; CHECK-NEXT: addi.w $r5, $zero, 1 ++; CHECK-NEXT: movgr2fr.w $f1, $r5 ++; CHECK-NEXT: ffint.s.w $f1, $f1 ++; CHECK-NEXT: .LBB2_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Loop Header: Depth=1 ++; CHECK-NEXT: # Child Loop BB2_2 Depth 2 ++; CHECK-NEXT: fmax.s $f2, $f0, $f0 ++; CHECK-NEXT: fmin.s $f2, $f2, $f1 ++; CHECK-NEXT: movfr2gr.s $r5, $f2 ++; CHECK-NEXT: movfr2gr.s $r6, $f0 ++; CHECK-NEXT: .LBB2_2: # %atomicrmw.start ++; CHECK-NEXT: # Parent Loop BB2_1 Depth=1 ++; CHECK-NEXT: # => This Inner Loop Header: Depth=2 ++; CHECK-NEXT: ll.w $r7, $r4, 0 ++; CHECK-NEXT: bne $r7, $r6, .LBB2_4 ++; CHECK-NEXT: # %bb.3: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB2_2 Depth=2 ++; CHECK-NEXT: move $r8, $r5 ++; CHECK-NEXT: sc.w $r8, $r4, 0 ++; CHECK-NEXT: beq $r8, $zero, .LBB2_2 ++; CHECK-NEXT: .LBB2_4: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB2_1 Depth=1 ++; CHECK-NEXT: dbar 0 ++; CHECK-NEXT: movgr2fr.w $f0, $r7 ++; CHECK-NEXT: bne $r7, $r6, .LBB2_1 ++; CHECK-NEXT: # %bb.5: # %atomicrmw.end ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fmin ptr %p, float 1.0 acquire, align 4 ++ ret float %v ++} ++ ++define float @float_fmax_acquire(ptr %p) nounwind { ++; CHECK-LABEL: float_fmax_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fld.s $f0, $r4, 0 ++; CHECK-NEXT: addi.w $r5, $zero, 1 ++; CHECK-NEXT: movgr2fr.w $f1, $r5 ++; CHECK-NEXT: ffint.s.w $f1, $f1 ++; CHECK-NEXT: .LBB3_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Loop Header: Depth=1 ++; CHECK-NEXT: # Child Loop BB3_2 Depth 2 ++; CHECK-NEXT: fmax.s $f2, $f0, $f0 ++; CHECK-NEXT: fmax.s $f2, $f2, $f1 ++; CHECK-NEXT: movfr2gr.s $r5, $f2 ++; CHECK-NEXT: movfr2gr.s $r6, $f0 ++; CHECK-NEXT: .LBB3_2: # %atomicrmw.start ++; CHECK-NEXT: # Parent Loop BB3_1 Depth=1 ++; CHECK-NEXT: # => This Inner Loop Header: Depth=2 ++; CHECK-NEXT: ll.w $r7, $r4, 0 ++; CHECK-NEXT: bne $r7, $r6, .LBB3_4 ++; CHECK-NEXT: # %bb.3: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB3_2 Depth=2 ++; CHECK-NEXT: move $r8, $r5 ++; CHECK-NEXT: sc.w $r8, $r4, 0 ++; CHECK-NEXT: beq $r8, $zero, .LBB3_2 ++; CHECK-NEXT: .LBB3_4: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB3_1 Depth=1 ++; CHECK-NEXT: dbar 0 ++; CHECK-NEXT: movgr2fr.w $f0, $r7 ++; CHECK-NEXT: bne $r7, $r6, .LBB3_1 ++; CHECK-NEXT: # %bb.5: # %atomicrmw.end ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fmax ptr %p, float 1.0 acquire, align 4 ++ ret float %v ++} ++ ++define double @double_fadd_acquire(ptr %p) nounwind { ++; CHECK-LABEL: double_fadd_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -80 ++; CHECK-NEXT: fst.d $f24, $sp, 72 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $ra, $sp, 64 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r27, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r26, $sp, 48 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r25, $sp, 40 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r24, $sp, 32 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r23, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: move $r23, $r4 ++; CHECK-NEXT: fld.d $f0, $r4, 0 ++; CHECK-NEXT: addi.d $r4, $zero, 1 ++; CHECK-NEXT: movgr2fr.d $f1, $r4 ++; CHECK-NEXT: ffint.d.l $f24, $f1 ++; CHECK-NEXT: addi.d $r24, $zero, 8 ++; CHECK-NEXT: addi.d $r25, $sp, 16 ++; CHECK-NEXT: addi.d $r26, $sp, 8 ++; CHECK-NEXT: addi.d $r27, $zero, 2 ++; CHECK-NEXT: .LBB4_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: fst.d $f0, $sp, 16 ++; CHECK-NEXT: fadd.d $f0, $f0, $f24 ++; CHECK-NEXT: fst.d $f0, $sp, 8 ++; CHECK-NEXT: move $r4, $r24 ++; CHECK-NEXT: move $r5, $r23 ++; CHECK-NEXT: move $r6, $r25 ++; CHECK-NEXT: move $r7, $r26 ++; CHECK-NEXT: move $r8, $r27 ++; CHECK-NEXT: move $r9, $r27 ++; CHECK-NEXT: lu12i.w $ra, __atomic_compare_exchange ++; CHECK-NEXT: ori $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu32i.d $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu52i.d $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: jirl $ra, $ra, 0 ++; CHECK-NEXT: fld.d $f0, $sp, 16 ++; CHECK-NEXT: beqz $r4, .LBB4_1 ++; CHECK-NEXT: # %bb.2: # %atomicrmw.end ++; CHECK-NEXT: ld.d $r23, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r24, $sp, 32 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r25, $sp, 40 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r26, $sp, 48 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r27, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 64 # 8-byte Folded Reload ++; CHECK-NEXT: fld.d $f24, $sp, 72 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 80 ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fadd ptr %p, double 1.0 acquire, align 4 ++ ret double %v ++} ++ ++define double @double_fsub_acquire(ptr %p) nounwind { ++; CHECK-LABEL: double_fsub_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -64 ++; CHECK-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r27, $sp, 48 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r26, $sp, 40 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r25, $sp, 32 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r24, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r23, $sp, 16 # 8-byte Folded Spill ++; CHECK-NEXT: move $r23, $r4 ++; CHECK-NEXT: fld.d $f0, $r4, 0 ++; CHECK-NEXT: addi.d $r24, $zero, 8 ++; CHECK-NEXT: addi.d $r25, $sp, 8 ++; CHECK-NEXT: addi.d $r26, $sp, 0 ++; CHECK-NEXT: addi.d $r27, $zero, 2 ++; CHECK-NEXT: .LBB5_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: fst.d $f0, $sp, 8 ++; CHECK-NEXT: lu12i.w $r4, .LCPI5_0 ++; CHECK-NEXT: ori $r4, $r4, .LCPI5_0 ++; CHECK-NEXT: lu32i.d $r4, .LCPI5_0 ++; CHECK-NEXT: lu52i.d $r4, $r4, .LCPI5_0 ++; CHECK-NEXT: fld.d $f1, $r4, 0 ++; CHECK-NEXT: fadd.d $f0, $f0, $f1 ++; CHECK-NEXT: fst.d $f0, $sp, 0 ++; CHECK-NEXT: move $r4, $r24 ++; CHECK-NEXT: move $r5, $r23 ++; CHECK-NEXT: move $r6, $r25 ++; CHECK-NEXT: move $r7, $r26 ++; CHECK-NEXT: move $r8, $r27 ++; CHECK-NEXT: move $r9, $r27 ++; CHECK-NEXT: lu12i.w $ra, __atomic_compare_exchange ++; CHECK-NEXT: ori $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu32i.d $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu52i.d $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: jirl $ra, $ra, 0 ++; CHECK-NEXT: fld.d $f0, $sp, 8 ++; CHECK-NEXT: beqz $r4, .LBB5_1 ++; CHECK-NEXT: # %bb.2: # %atomicrmw.end ++; CHECK-NEXT: ld.d $r23, $sp, 16 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r24, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r25, $sp, 32 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r26, $sp, 40 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r27, $sp, 48 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 64 ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fsub ptr %p, double 1.0 acquire, align 4 ++ ret double %v ++} ++ ++define double @double_fmin_acquire(ptr %p) nounwind { ++; CHECK-LABEL: double_fmin_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -80 ++; CHECK-NEXT: fst.d $f24, $sp, 72 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $ra, $sp, 64 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r27, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r26, $sp, 48 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r25, $sp, 40 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r24, $sp, 32 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r23, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: move $r23, $r4 ++; CHECK-NEXT: fld.d $f0, $r4, 0 ++; CHECK-NEXT: addi.d $r4, $zero, 1 ++; CHECK-NEXT: movgr2fr.d $f1, $r4 ++; CHECK-NEXT: ffint.d.l $f24, $f1 ++; CHECK-NEXT: addi.d $r24, $zero, 8 ++; CHECK-NEXT: addi.d $r25, $sp, 16 ++; CHECK-NEXT: addi.d $r26, $sp, 8 ++; CHECK-NEXT: addi.d $r27, $zero, 2 ++; CHECK-NEXT: .LBB6_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: fst.d $f0, $sp, 16 ++; CHECK-NEXT: fmax.d $f0, $f0, $f0 ++; CHECK-NEXT: fmin.d $f0, $f0, $f24 ++; CHECK-NEXT: fst.d $f0, $sp, 8 ++; CHECK-NEXT: move $r4, $r24 ++; CHECK-NEXT: move $r5, $r23 ++; CHECK-NEXT: move $r6, $r25 ++; CHECK-NEXT: move $r7, $r26 ++; CHECK-NEXT: move $r8, $r27 ++; CHECK-NEXT: move $r9, $r27 ++; CHECK-NEXT: lu12i.w $ra, __atomic_compare_exchange ++; CHECK-NEXT: ori $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu32i.d $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu52i.d $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: jirl $ra, $ra, 0 ++; CHECK-NEXT: fld.d $f0, $sp, 16 ++; CHECK-NEXT: beqz $r4, .LBB6_1 ++; CHECK-NEXT: # %bb.2: # %atomicrmw.end ++; CHECK-NEXT: ld.d $r23, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r24, $sp, 32 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r25, $sp, 40 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r26, $sp, 48 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r27, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 64 # 8-byte Folded Reload ++; CHECK-NEXT: fld.d $f24, $sp, 72 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 80 ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fmin ptr %p, double 1.0 acquire, align 4 ++ ret double %v ++} ++ ++define double @double_fmax_acquire(ptr %p) nounwind { ++; CHECK-LABEL: double_fmax_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -80 ++; CHECK-NEXT: fst.d $f24, $sp, 72 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $ra, $sp, 64 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r27, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r26, $sp, 48 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r25, $sp, 40 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r24, $sp, 32 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r23, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: move $r23, $r4 ++; CHECK-NEXT: fld.d $f0, $r4, 0 ++; CHECK-NEXT: addi.d $r4, $zero, 1 ++; CHECK-NEXT: movgr2fr.d $f1, $r4 ++; CHECK-NEXT: ffint.d.l $f24, $f1 ++; CHECK-NEXT: addi.d $r24, $zero, 8 ++; CHECK-NEXT: addi.d $r25, $sp, 16 ++; CHECK-NEXT: addi.d $r26, $sp, 8 ++; CHECK-NEXT: addi.d $r27, $zero, 2 ++; CHECK-NEXT: .LBB7_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: fst.d $f0, $sp, 16 ++; CHECK-NEXT: fmax.d $f0, $f0, $f0 ++; CHECK-NEXT: fmax.d $f0, $f0, $f24 ++; CHECK-NEXT: fst.d $f0, $sp, 8 ++; CHECK-NEXT: move $r4, $r24 ++; CHECK-NEXT: move $r5, $r23 ++; CHECK-NEXT: move $r6, $r25 ++; CHECK-NEXT: move $r7, $r26 ++; CHECK-NEXT: move $r8, $r27 ++; CHECK-NEXT: move $r9, $r27 ++; CHECK-NEXT: lu12i.w $ra, __atomic_compare_exchange ++; CHECK-NEXT: ori $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu32i.d $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu52i.d $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: jirl $ra, $ra, 0 ++; CHECK-NEXT: fld.d $f0, $sp, 16 ++; CHECK-NEXT: beqz $r4, .LBB7_1 ++; CHECK-NEXT: # %bb.2: # %atomicrmw.end ++; CHECK-NEXT: ld.d $r23, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r24, $sp, 32 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r25, $sp, 40 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r26, $sp, 48 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r27, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 64 # 8-byte Folded Reload ++; CHECK-NEXT: fld.d $f24, $sp, 72 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 80 ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fmax ptr %p, double 1.0 acquire, align 4 ++ ret double %v ++} ++ ++define float @float_fadd_release(ptr %p) nounwind { ++; CHECK-LABEL: float_fadd_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fld.s $f0, $r4, 0 ++; CHECK-NEXT: addi.w $r5, $zero, 1 ++; CHECK-NEXT: movgr2fr.w $f1, $r5 ++; CHECK-NEXT: ffint.s.w $f1, $f1 ++; CHECK-NEXT: .LBB8_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Loop Header: Depth=1 ++; CHECK-NEXT: # Child Loop BB8_2 Depth 2 ++; CHECK-NEXT: fadd.s $f2, $f0, $f1 ++; CHECK-NEXT: movfr2gr.s $r5, $f2 ++; CHECK-NEXT: movfr2gr.s $r6, $f0 ++; CHECK-NEXT: .LBB8_2: # %atomicrmw.start ++; CHECK-NEXT: # Parent Loop BB8_1 Depth=1 ++; CHECK-NEXT: # => This Inner Loop Header: Depth=2 ++; CHECK-NEXT: ll.w $r7, $r4, 0 ++; CHECK-NEXT: bne $r7, $r6, .LBB8_4 ++; CHECK-NEXT: # %bb.3: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB8_2 Depth=2 ++; CHECK-NEXT: move $r8, $r5 ++; CHECK-NEXT: sc.w $r8, $r4, 0 ++; CHECK-NEXT: beq $r8, $zero, .LBB8_2 ++; CHECK-NEXT: .LBB8_4: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB8_1 Depth=1 ++; CHECK-NEXT: dbar 1792 ++; CHECK-NEXT: movgr2fr.w $f0, $r7 ++; CHECK-NEXT: bne $r7, $r6, .LBB8_1 ++; CHECK-NEXT: # %bb.5: # %atomicrmw.end ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fadd ptr %p, float 1.0 release, align 4 ++ ret float %v ++} ++ ++define float @float_fsub_release(ptr %p) nounwind { ++; CHECK-LABEL: float_fsub_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fld.s $f0, $r4, 0 ++; CHECK-NEXT: .LBB9_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Loop Header: Depth=1 ++; CHECK-NEXT: # Child Loop BB9_2 Depth 2 ++; CHECK-NEXT: lu12i.w $r5, .LCPI9_0 ++; CHECK-NEXT: ori $r5, $r5, .LCPI9_0 ++; CHECK-NEXT: lu32i.d $r5, .LCPI9_0 ++; CHECK-NEXT: lu52i.d $r5, $r5, .LCPI9_0 ++; CHECK-NEXT: fld.s $f1, $r5, 0 ++; CHECK-NEXT: fadd.s $f1, $f0, $f1 ++; CHECK-NEXT: movfr2gr.s $r5, $f1 ++; CHECK-NEXT: movfr2gr.s $r6, $f0 ++; CHECK-NEXT: .LBB9_2: # %atomicrmw.start ++; CHECK-NEXT: # Parent Loop BB9_1 Depth=1 ++; CHECK-NEXT: # => This Inner Loop Header: Depth=2 ++; CHECK-NEXT: ll.w $r7, $r4, 0 ++; CHECK-NEXT: bne $r7, $r6, .LBB9_4 ++; CHECK-NEXT: # %bb.3: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB9_2 Depth=2 ++; CHECK-NEXT: move $r8, $r5 ++; CHECK-NEXT: sc.w $r8, $r4, 0 ++; CHECK-NEXT: beq $r8, $zero, .LBB9_2 ++; CHECK-NEXT: .LBB9_4: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB9_1 Depth=1 ++; CHECK-NEXT: dbar 1792 ++; CHECK-NEXT: movgr2fr.w $f0, $r7 ++; CHECK-NEXT: bne $r7, $r6, .LBB9_1 ++; CHECK-NEXT: # %bb.5: # %atomicrmw.end ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fsub ptr %p, float 1.0 release, align 4 ++ ret float %v ++} ++ ++define float @float_fmin_release(ptr %p) nounwind { ++; CHECK-LABEL: float_fmin_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fld.s $f0, $r4, 0 ++; CHECK-NEXT: addi.w $r5, $zero, 1 ++; CHECK-NEXT: movgr2fr.w $f1, $r5 ++; CHECK-NEXT: ffint.s.w $f1, $f1 ++; CHECK-NEXT: .LBB10_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Loop Header: Depth=1 ++; CHECK-NEXT: # Child Loop BB10_2 Depth 2 ++; CHECK-NEXT: fmax.s $f2, $f0, $f0 ++; CHECK-NEXT: fmin.s $f2, $f2, $f1 ++; CHECK-NEXT: movfr2gr.s $r5, $f2 ++; CHECK-NEXT: movfr2gr.s $r6, $f0 ++; CHECK-NEXT: .LBB10_2: # %atomicrmw.start ++; CHECK-NEXT: # Parent Loop BB10_1 Depth=1 ++; CHECK-NEXT: # => This Inner Loop Header: Depth=2 ++; CHECK-NEXT: ll.w $r7, $r4, 0 ++; CHECK-NEXT: bne $r7, $r6, .LBB10_4 ++; CHECK-NEXT: # %bb.3: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB10_2 Depth=2 ++; CHECK-NEXT: move $r8, $r5 ++; CHECK-NEXT: sc.w $r8, $r4, 0 ++; CHECK-NEXT: beq $r8, $zero, .LBB10_2 ++; CHECK-NEXT: .LBB10_4: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB10_1 Depth=1 ++; CHECK-NEXT: dbar 1792 ++; CHECK-NEXT: movgr2fr.w $f0, $r7 ++; CHECK-NEXT: bne $r7, $r6, .LBB10_1 ++; CHECK-NEXT: # %bb.5: # %atomicrmw.end ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fmin ptr %p, float 1.0 release, align 4 ++ ret float %v ++} ++ ++define float @float_fmax_release(ptr %p) nounwind { ++; CHECK-LABEL: float_fmax_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fld.s $f0, $r4, 0 ++; CHECK-NEXT: addi.w $r5, $zero, 1 ++; CHECK-NEXT: movgr2fr.w $f1, $r5 ++; CHECK-NEXT: ffint.s.w $f1, $f1 ++; CHECK-NEXT: .LBB11_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Loop Header: Depth=1 ++; CHECK-NEXT: # Child Loop BB11_2 Depth 2 ++; CHECK-NEXT: fmax.s $f2, $f0, $f0 ++; CHECK-NEXT: fmax.s $f2, $f2, $f1 ++; CHECK-NEXT: movfr2gr.s $r5, $f2 ++; CHECK-NEXT: movfr2gr.s $r6, $f0 ++; CHECK-NEXT: .LBB11_2: # %atomicrmw.start ++; CHECK-NEXT: # Parent Loop BB11_1 Depth=1 ++; CHECK-NEXT: # => This Inner Loop Header: Depth=2 ++; CHECK-NEXT: ll.w $r7, $r4, 0 ++; CHECK-NEXT: bne $r7, $r6, .LBB11_4 ++; CHECK-NEXT: # %bb.3: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB11_2 Depth=2 ++; CHECK-NEXT: move $r8, $r5 ++; CHECK-NEXT: sc.w $r8, $r4, 0 ++; CHECK-NEXT: beq $r8, $zero, .LBB11_2 ++; CHECK-NEXT: .LBB11_4: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB11_1 Depth=1 ++; CHECK-NEXT: dbar 1792 ++; CHECK-NEXT: movgr2fr.w $f0, $r7 ++; CHECK-NEXT: bne $r7, $r6, .LBB11_1 ++; CHECK-NEXT: # %bb.5: # %atomicrmw.end ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fmax ptr %p, float 1.0 release, align 4 ++ ret float %v ++} ++ ++define double @double_fadd_release(ptr %p) nounwind { ++; CHECK-LABEL: double_fadd_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -80 ++; CHECK-NEXT: fst.d $f24, $sp, 72 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $ra, $sp, 64 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r28, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r27, $sp, 48 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r26, $sp, 40 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r25, $sp, 32 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r24, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r23, $sp, 16 # 8-byte Folded Spill ++; CHECK-NEXT: move $r23, $r4 ++; CHECK-NEXT: fld.d $f0, $r4, 0 ++; CHECK-NEXT: addi.d $r4, $zero, 1 ++; CHECK-NEXT: movgr2fr.d $f1, $r4 ++; CHECK-NEXT: ffint.d.l $f24, $f1 ++; CHECK-NEXT: addi.d $r24, $zero, 8 ++; CHECK-NEXT: addi.d $r25, $sp, 8 ++; CHECK-NEXT: addi.d $r26, $sp, 0 ++; CHECK-NEXT: addi.d $r27, $zero, 3 ++; CHECK-NEXT: addi.d $r28, $zero, 0 ++; CHECK-NEXT: .LBB12_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: fst.d $f0, $sp, 8 ++; CHECK-NEXT: fadd.d $f0, $f0, $f24 ++; CHECK-NEXT: fst.d $f0, $sp, 0 ++; CHECK-NEXT: move $r4, $r24 ++; CHECK-NEXT: move $r5, $r23 ++; CHECK-NEXT: move $r6, $r25 ++; CHECK-NEXT: move $r7, $r26 ++; CHECK-NEXT: move $r8, $r27 ++; CHECK-NEXT: move $r9, $r28 ++; CHECK-NEXT: lu12i.w $ra, __atomic_compare_exchange ++; CHECK-NEXT: ori $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu32i.d $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu52i.d $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: jirl $ra, $ra, 0 ++; CHECK-NEXT: fld.d $f0, $sp, 8 ++; CHECK-NEXT: beqz $r4, .LBB12_1 ++; CHECK-NEXT: # %bb.2: # %atomicrmw.end ++; CHECK-NEXT: ld.d $r23, $sp, 16 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r24, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r25, $sp, 32 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r26, $sp, 40 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r27, $sp, 48 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r28, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 64 # 8-byte Folded Reload ++; CHECK-NEXT: fld.d $f24, $sp, 72 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 80 ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fadd ptr %p, double 1.0 release, align 4 ++ ret double %v ++} ++ ++define double @double_fsub_release(ptr %p) nounwind { ++; CHECK-LABEL: double_fsub_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -80 ++; CHECK-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r28, $sp, 64 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r27, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r26, $sp, 48 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r25, $sp, 40 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r24, $sp, 32 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r23, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: move $r23, $r4 ++; CHECK-NEXT: fld.d $f0, $r4, 0 ++; CHECK-NEXT: addi.d $r24, $zero, 8 ++; CHECK-NEXT: addi.d $r25, $sp, 16 ++; CHECK-NEXT: addi.d $r26, $sp, 8 ++; CHECK-NEXT: addi.d $r27, $zero, 3 ++; CHECK-NEXT: addi.d $r28, $zero, 0 ++; CHECK-NEXT: .LBB13_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: fst.d $f0, $sp, 16 ++; CHECK-NEXT: lu12i.w $r4, .LCPI13_0 ++; CHECK-NEXT: ori $r4, $r4, .LCPI13_0 ++; CHECK-NEXT: lu32i.d $r4, .LCPI13_0 ++; CHECK-NEXT: lu52i.d $r4, $r4, .LCPI13_0 ++; CHECK-NEXT: fld.d $f1, $r4, 0 ++; CHECK-NEXT: fadd.d $f0, $f0, $f1 ++; CHECK-NEXT: fst.d $f0, $sp, 8 ++; CHECK-NEXT: move $r4, $r24 ++; CHECK-NEXT: move $r5, $r23 ++; CHECK-NEXT: move $r6, $r25 ++; CHECK-NEXT: move $r7, $r26 ++; CHECK-NEXT: move $r8, $r27 ++; CHECK-NEXT: move $r9, $r28 ++; CHECK-NEXT: lu12i.w $ra, __atomic_compare_exchange ++; CHECK-NEXT: ori $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu32i.d $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu52i.d $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: jirl $ra, $ra, 0 ++; CHECK-NEXT: fld.d $f0, $sp, 16 ++; CHECK-NEXT: beqz $r4, .LBB13_1 ++; CHECK-NEXT: # %bb.2: # %atomicrmw.end ++; CHECK-NEXT: ld.d $r23, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r24, $sp, 32 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r25, $sp, 40 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r26, $sp, 48 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r27, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r28, $sp, 64 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 80 ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fsub ptr %p, double 1.0 release, align 4 ++ ret double %v ++} ++ ++define double @double_fmin_release(ptr %p) nounwind { ++; CHECK-LABEL: double_fmin_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -80 ++; CHECK-NEXT: fst.d $f24, $sp, 72 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $ra, $sp, 64 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r28, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r27, $sp, 48 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r26, $sp, 40 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r25, $sp, 32 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r24, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r23, $sp, 16 # 8-byte Folded Spill ++; CHECK-NEXT: move $r23, $r4 ++; CHECK-NEXT: fld.d $f0, $r4, 0 ++; CHECK-NEXT: addi.d $r4, $zero, 1 ++; CHECK-NEXT: movgr2fr.d $f1, $r4 ++; CHECK-NEXT: ffint.d.l $f24, $f1 ++; CHECK-NEXT: addi.d $r24, $zero, 8 ++; CHECK-NEXT: addi.d $r25, $sp, 8 ++; CHECK-NEXT: addi.d $r26, $sp, 0 ++; CHECK-NEXT: addi.d $r27, $zero, 3 ++; CHECK-NEXT: addi.d $r28, $zero, 0 ++; CHECK-NEXT: .LBB14_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: fst.d $f0, $sp, 8 ++; CHECK-NEXT: fmax.d $f0, $f0, $f0 ++; CHECK-NEXT: fmin.d $f0, $f0, $f24 ++; CHECK-NEXT: fst.d $f0, $sp, 0 ++; CHECK-NEXT: move $r4, $r24 ++; CHECK-NEXT: move $r5, $r23 ++; CHECK-NEXT: move $r6, $r25 ++; CHECK-NEXT: move $r7, $r26 ++; CHECK-NEXT: move $r8, $r27 ++; CHECK-NEXT: move $r9, $r28 ++; CHECK-NEXT: lu12i.w $ra, __atomic_compare_exchange ++; CHECK-NEXT: ori $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu32i.d $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu52i.d $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: jirl $ra, $ra, 0 ++; CHECK-NEXT: fld.d $f0, $sp, 8 ++; CHECK-NEXT: beqz $r4, .LBB14_1 ++; CHECK-NEXT: # %bb.2: # %atomicrmw.end ++; CHECK-NEXT: ld.d $r23, $sp, 16 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r24, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r25, $sp, 32 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r26, $sp, 40 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r27, $sp, 48 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r28, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 64 # 8-byte Folded Reload ++; CHECK-NEXT: fld.d $f24, $sp, 72 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 80 ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fmin ptr %p, double 1.0 release, align 4 ++ ret double %v ++} ++ ++define double @double_fmax_release(ptr %p) nounwind { ++; CHECK-LABEL: double_fmax_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -80 ++; CHECK-NEXT: fst.d $f24, $sp, 72 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $ra, $sp, 64 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r28, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r27, $sp, 48 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r26, $sp, 40 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r25, $sp, 32 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r24, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r23, $sp, 16 # 8-byte Folded Spill ++; CHECK-NEXT: move $r23, $r4 ++; CHECK-NEXT: fld.d $f0, $r4, 0 ++; CHECK-NEXT: addi.d $r4, $zero, 1 ++; CHECK-NEXT: movgr2fr.d $f1, $r4 ++; CHECK-NEXT: ffint.d.l $f24, $f1 ++; CHECK-NEXT: addi.d $r24, $zero, 8 ++; CHECK-NEXT: addi.d $r25, $sp, 8 ++; CHECK-NEXT: addi.d $r26, $sp, 0 ++; CHECK-NEXT: addi.d $r27, $zero, 3 ++; CHECK-NEXT: addi.d $r28, $zero, 0 ++; CHECK-NEXT: .LBB15_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: fst.d $f0, $sp, 8 ++; CHECK-NEXT: fmax.d $f0, $f0, $f0 ++; CHECK-NEXT: fmax.d $f0, $f0, $f24 ++; CHECK-NEXT: fst.d $f0, $sp, 0 ++; CHECK-NEXT: move $r4, $r24 ++; CHECK-NEXT: move $r5, $r23 ++; CHECK-NEXT: move $r6, $r25 ++; CHECK-NEXT: move $r7, $r26 ++; CHECK-NEXT: move $r8, $r27 ++; CHECK-NEXT: move $r9, $r28 ++; CHECK-NEXT: lu12i.w $ra, __atomic_compare_exchange ++; CHECK-NEXT: ori $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu32i.d $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu52i.d $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: jirl $ra, $ra, 0 ++; CHECK-NEXT: fld.d $f0, $sp, 8 ++; CHECK-NEXT: beqz $r4, .LBB15_1 ++; CHECK-NEXT: # %bb.2: # %atomicrmw.end ++; CHECK-NEXT: ld.d $r23, $sp, 16 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r24, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r25, $sp, 32 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r26, $sp, 40 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r27, $sp, 48 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r28, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 64 # 8-byte Folded Reload ++; CHECK-NEXT: fld.d $f24, $sp, 72 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 80 ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fmax ptr %p, double 1.0 release, align 4 ++ ret double %v ++} ++ ++define float @float_fadd_acq_rel(ptr %p) nounwind { ++; CHECK-LABEL: float_fadd_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fld.s $f0, $r4, 0 ++; CHECK-NEXT: addi.w $r5, $zero, 1 ++; CHECK-NEXT: movgr2fr.w $f1, $r5 ++; CHECK-NEXT: ffint.s.w $f1, $f1 ++; CHECK-NEXT: .LBB16_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Loop Header: Depth=1 ++; CHECK-NEXT: # Child Loop BB16_2 Depth 2 ++; CHECK-NEXT: fadd.s $f2, $f0, $f1 ++; CHECK-NEXT: movfr2gr.s $r5, $f2 ++; CHECK-NEXT: movfr2gr.s $r6, $f0 ++; CHECK-NEXT: .LBB16_2: # %atomicrmw.start ++; CHECK-NEXT: # Parent Loop BB16_1 Depth=1 ++; CHECK-NEXT: # => This Inner Loop Header: Depth=2 ++; CHECK-NEXT: ll.w $r7, $r4, 0 ++; CHECK-NEXT: bne $r7, $r6, .LBB16_4 ++; CHECK-NEXT: # %bb.3: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB16_2 Depth=2 ++; CHECK-NEXT: move $r8, $r5 ++; CHECK-NEXT: sc.w $r8, $r4, 0 ++; CHECK-NEXT: beq $r8, $zero, .LBB16_2 ++; CHECK-NEXT: .LBB16_4: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB16_1 Depth=1 ++; CHECK-NEXT: dbar 0 ++; CHECK-NEXT: movgr2fr.w $f0, $r7 ++; CHECK-NEXT: bne $r7, $r6, .LBB16_1 ++; CHECK-NEXT: # %bb.5: # %atomicrmw.end ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fadd ptr %p, float 1.0 acq_rel, align 4 ++ ret float %v ++} ++ ++define float @float_fsub_acq_rel(ptr %p) nounwind { ++; CHECK-LABEL: float_fsub_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fld.s $f0, $r4, 0 ++; CHECK-NEXT: .LBB17_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Loop Header: Depth=1 ++; CHECK-NEXT: # Child Loop BB17_2 Depth 2 ++; CHECK-NEXT: lu12i.w $r5, .LCPI17_0 ++; CHECK-NEXT: ori $r5, $r5, .LCPI17_0 ++; CHECK-NEXT: lu32i.d $r5, .LCPI17_0 ++; CHECK-NEXT: lu52i.d $r5, $r5, .LCPI17_0 ++; CHECK-NEXT: fld.s $f1, $r5, 0 ++; CHECK-NEXT: fadd.s $f1, $f0, $f1 ++; CHECK-NEXT: movfr2gr.s $r5, $f1 ++; CHECK-NEXT: movfr2gr.s $r6, $f0 ++; CHECK-NEXT: .LBB17_2: # %atomicrmw.start ++; CHECK-NEXT: # Parent Loop BB17_1 Depth=1 ++; CHECK-NEXT: # => This Inner Loop Header: Depth=2 ++; CHECK-NEXT: ll.w $r7, $r4, 0 ++; CHECK-NEXT: bne $r7, $r6, .LBB17_4 ++; CHECK-NEXT: # %bb.3: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB17_2 Depth=2 ++; CHECK-NEXT: move $r8, $r5 ++; CHECK-NEXT: sc.w $r8, $r4, 0 ++; CHECK-NEXT: beq $r8, $zero, .LBB17_2 ++; CHECK-NEXT: .LBB17_4: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB17_1 Depth=1 ++; CHECK-NEXT: dbar 0 ++; CHECK-NEXT: movgr2fr.w $f0, $r7 ++; CHECK-NEXT: bne $r7, $r6, .LBB17_1 ++; CHECK-NEXT: # %bb.5: # %atomicrmw.end ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fsub ptr %p, float 1.0 acq_rel, align 4 ++ ret float %v ++} ++ ++define float @float_fmin_acq_rel(ptr %p) nounwind { ++; CHECK-LABEL: float_fmin_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fld.s $f0, $r4, 0 ++; CHECK-NEXT: addi.w $r5, $zero, 1 ++; CHECK-NEXT: movgr2fr.w $f1, $r5 ++; CHECK-NEXT: ffint.s.w $f1, $f1 ++; CHECK-NEXT: .LBB18_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Loop Header: Depth=1 ++; CHECK-NEXT: # Child Loop BB18_2 Depth 2 ++; CHECK-NEXT: fmax.s $f2, $f0, $f0 ++; CHECK-NEXT: fmin.s $f2, $f2, $f1 ++; CHECK-NEXT: movfr2gr.s $r5, $f2 ++; CHECK-NEXT: movfr2gr.s $r6, $f0 ++; CHECK-NEXT: .LBB18_2: # %atomicrmw.start ++; CHECK-NEXT: # Parent Loop BB18_1 Depth=1 ++; CHECK-NEXT: # => This Inner Loop Header: Depth=2 ++; CHECK-NEXT: ll.w $r7, $r4, 0 ++; CHECK-NEXT: bne $r7, $r6, .LBB18_4 ++; CHECK-NEXT: # %bb.3: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB18_2 Depth=2 ++; CHECK-NEXT: move $r8, $r5 ++; CHECK-NEXT: sc.w $r8, $r4, 0 ++; CHECK-NEXT: beq $r8, $zero, .LBB18_2 ++; CHECK-NEXT: .LBB18_4: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB18_1 Depth=1 ++; CHECK-NEXT: dbar 0 ++; CHECK-NEXT: movgr2fr.w $f0, $r7 ++; CHECK-NEXT: bne $r7, $r6, .LBB18_1 ++; CHECK-NEXT: # %bb.5: # %atomicrmw.end ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fmin ptr %p, float 1.0 acq_rel, align 4 ++ ret float %v ++} ++ ++define float @float_fmax_acq_rel(ptr %p) nounwind { ++; CHECK-LABEL: float_fmax_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fld.s $f0, $r4, 0 ++; CHECK-NEXT: addi.w $r5, $zero, 1 ++; CHECK-NEXT: movgr2fr.w $f1, $r5 ++; CHECK-NEXT: ffint.s.w $f1, $f1 ++; CHECK-NEXT: .LBB19_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Loop Header: Depth=1 ++; CHECK-NEXT: # Child Loop BB19_2 Depth 2 ++; CHECK-NEXT: fmax.s $f2, $f0, $f0 ++; CHECK-NEXT: fmax.s $f2, $f2, $f1 ++; CHECK-NEXT: movfr2gr.s $r5, $f2 ++; CHECK-NEXT: movfr2gr.s $r6, $f0 ++; CHECK-NEXT: .LBB19_2: # %atomicrmw.start ++; CHECK-NEXT: # Parent Loop BB19_1 Depth=1 ++; CHECK-NEXT: # => This Inner Loop Header: Depth=2 ++; CHECK-NEXT: ll.w $r7, $r4, 0 ++; CHECK-NEXT: bne $r7, $r6, .LBB19_4 ++; CHECK-NEXT: # %bb.3: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB19_2 Depth=2 ++; CHECK-NEXT: move $r8, $r5 ++; CHECK-NEXT: sc.w $r8, $r4, 0 ++; CHECK-NEXT: beq $r8, $zero, .LBB19_2 ++; CHECK-NEXT: .LBB19_4: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB19_1 Depth=1 ++; CHECK-NEXT: dbar 0 ++; CHECK-NEXT: movgr2fr.w $f0, $r7 ++; CHECK-NEXT: bne $r7, $r6, .LBB19_1 ++; CHECK-NEXT: # %bb.5: # %atomicrmw.end ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fmax ptr %p, float 1.0 acq_rel, align 4 ++ ret float %v ++} ++ ++define double @double_fadd_acq_rel(ptr %p) nounwind { ++; CHECK-LABEL: double_fadd_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -80 ++; CHECK-NEXT: fst.d $f24, $sp, 72 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $ra, $sp, 64 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r28, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r27, $sp, 48 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r26, $sp, 40 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r25, $sp, 32 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r24, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r23, $sp, 16 # 8-byte Folded Spill ++; CHECK-NEXT: move $r23, $r4 ++; CHECK-NEXT: fld.d $f0, $r4, 0 ++; CHECK-NEXT: addi.d $r4, $zero, 1 ++; CHECK-NEXT: movgr2fr.d $f1, $r4 ++; CHECK-NEXT: ffint.d.l $f24, $f1 ++; CHECK-NEXT: addi.d $r24, $zero, 8 ++; CHECK-NEXT: addi.d $r25, $sp, 8 ++; CHECK-NEXT: addi.d $r26, $sp, 0 ++; CHECK-NEXT: addi.d $r27, $zero, 4 ++; CHECK-NEXT: addi.d $r28, $zero, 2 ++; CHECK-NEXT: .LBB20_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: fst.d $f0, $sp, 8 ++; CHECK-NEXT: fadd.d $f0, $f0, $f24 ++; CHECK-NEXT: fst.d $f0, $sp, 0 ++; CHECK-NEXT: move $r4, $r24 ++; CHECK-NEXT: move $r5, $r23 ++; CHECK-NEXT: move $r6, $r25 ++; CHECK-NEXT: move $r7, $r26 ++; CHECK-NEXT: move $r8, $r27 ++; CHECK-NEXT: move $r9, $r28 ++; CHECK-NEXT: lu12i.w $ra, __atomic_compare_exchange ++; CHECK-NEXT: ori $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu32i.d $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu52i.d $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: jirl $ra, $ra, 0 ++; CHECK-NEXT: fld.d $f0, $sp, 8 ++; CHECK-NEXT: beqz $r4, .LBB20_1 ++; CHECK-NEXT: # %bb.2: # %atomicrmw.end ++; CHECK-NEXT: ld.d $r23, $sp, 16 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r24, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r25, $sp, 32 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r26, $sp, 40 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r27, $sp, 48 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r28, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 64 # 8-byte Folded Reload ++; CHECK-NEXT: fld.d $f24, $sp, 72 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 80 ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fadd ptr %p, double 1.0 acq_rel, align 4 ++ ret double %v ++} ++ ++define double @double_fsub_acq_rel(ptr %p) nounwind { ++; CHECK-LABEL: double_fsub_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -80 ++; CHECK-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r28, $sp, 64 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r27, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r26, $sp, 48 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r25, $sp, 40 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r24, $sp, 32 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r23, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: move $r23, $r4 ++; CHECK-NEXT: fld.d $f0, $r4, 0 ++; CHECK-NEXT: addi.d $r24, $zero, 8 ++; CHECK-NEXT: addi.d $r25, $sp, 16 ++; CHECK-NEXT: addi.d $r26, $sp, 8 ++; CHECK-NEXT: addi.d $r27, $zero, 4 ++; CHECK-NEXT: addi.d $r28, $zero, 2 ++; CHECK-NEXT: .LBB21_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: fst.d $f0, $sp, 16 ++; CHECK-NEXT: lu12i.w $r4, .LCPI21_0 ++; CHECK-NEXT: ori $r4, $r4, .LCPI21_0 ++; CHECK-NEXT: lu32i.d $r4, .LCPI21_0 ++; CHECK-NEXT: lu52i.d $r4, $r4, .LCPI21_0 ++; CHECK-NEXT: fld.d $f1, $r4, 0 ++; CHECK-NEXT: fadd.d $f0, $f0, $f1 ++; CHECK-NEXT: fst.d $f0, $sp, 8 ++; CHECK-NEXT: move $r4, $r24 ++; CHECK-NEXT: move $r5, $r23 ++; CHECK-NEXT: move $r6, $r25 ++; CHECK-NEXT: move $r7, $r26 ++; CHECK-NEXT: move $r8, $r27 ++; CHECK-NEXT: move $r9, $r28 ++; CHECK-NEXT: lu12i.w $ra, __atomic_compare_exchange ++; CHECK-NEXT: ori $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu32i.d $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu52i.d $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: jirl $ra, $ra, 0 ++; CHECK-NEXT: fld.d $f0, $sp, 16 ++; CHECK-NEXT: beqz $r4, .LBB21_1 ++; CHECK-NEXT: # %bb.2: # %atomicrmw.end ++; CHECK-NEXT: ld.d $r23, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r24, $sp, 32 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r25, $sp, 40 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r26, $sp, 48 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r27, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r28, $sp, 64 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 80 ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fsub ptr %p, double 1.0 acq_rel, align 4 ++ ret double %v ++} ++ ++define double @double_fmin_acq_rel(ptr %p) nounwind { ++; CHECK-LABEL: double_fmin_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -80 ++; CHECK-NEXT: fst.d $f24, $sp, 72 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $ra, $sp, 64 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r28, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r27, $sp, 48 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r26, $sp, 40 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r25, $sp, 32 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r24, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r23, $sp, 16 # 8-byte Folded Spill ++; CHECK-NEXT: move $r23, $r4 ++; CHECK-NEXT: fld.d $f0, $r4, 0 ++; CHECK-NEXT: addi.d $r4, $zero, 1 ++; CHECK-NEXT: movgr2fr.d $f1, $r4 ++; CHECK-NEXT: ffint.d.l $f24, $f1 ++; CHECK-NEXT: addi.d $r24, $zero, 8 ++; CHECK-NEXT: addi.d $r25, $sp, 8 ++; CHECK-NEXT: addi.d $r26, $sp, 0 ++; CHECK-NEXT: addi.d $r27, $zero, 4 ++; CHECK-NEXT: addi.d $r28, $zero, 2 ++; CHECK-NEXT: .LBB22_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: fst.d $f0, $sp, 8 ++; CHECK-NEXT: fmax.d $f0, $f0, $f0 ++; CHECK-NEXT: fmin.d $f0, $f0, $f24 ++; CHECK-NEXT: fst.d $f0, $sp, 0 ++; CHECK-NEXT: move $r4, $r24 ++; CHECK-NEXT: move $r5, $r23 ++; CHECK-NEXT: move $r6, $r25 ++; CHECK-NEXT: move $r7, $r26 ++; CHECK-NEXT: move $r8, $r27 ++; CHECK-NEXT: move $r9, $r28 ++; CHECK-NEXT: lu12i.w $ra, __atomic_compare_exchange ++; CHECK-NEXT: ori $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu32i.d $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu52i.d $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: jirl $ra, $ra, 0 ++; CHECK-NEXT: fld.d $f0, $sp, 8 ++; CHECK-NEXT: beqz $r4, .LBB22_1 ++; CHECK-NEXT: # %bb.2: # %atomicrmw.end ++; CHECK-NEXT: ld.d $r23, $sp, 16 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r24, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r25, $sp, 32 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r26, $sp, 40 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r27, $sp, 48 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r28, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 64 # 8-byte Folded Reload ++; CHECK-NEXT: fld.d $f24, $sp, 72 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 80 ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fmin ptr %p, double 1.0 acq_rel, align 4 ++ ret double %v ++} ++ ++define double @double_fmax_acq_rel(ptr %p) nounwind { ++; CHECK-LABEL: double_fmax_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -80 ++; CHECK-NEXT: fst.d $f24, $sp, 72 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $ra, $sp, 64 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r28, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r27, $sp, 48 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r26, $sp, 40 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r25, $sp, 32 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r24, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r23, $sp, 16 # 8-byte Folded Spill ++; CHECK-NEXT: move $r23, $r4 ++; CHECK-NEXT: fld.d $f0, $r4, 0 ++; CHECK-NEXT: addi.d $r4, $zero, 1 ++; CHECK-NEXT: movgr2fr.d $f1, $r4 ++; CHECK-NEXT: ffint.d.l $f24, $f1 ++; CHECK-NEXT: addi.d $r24, $zero, 8 ++; CHECK-NEXT: addi.d $r25, $sp, 8 ++; CHECK-NEXT: addi.d $r26, $sp, 0 ++; CHECK-NEXT: addi.d $r27, $zero, 4 ++; CHECK-NEXT: addi.d $r28, $zero, 2 ++; CHECK-NEXT: .LBB23_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: fst.d $f0, $sp, 8 ++; CHECK-NEXT: fmax.d $f0, $f0, $f0 ++; CHECK-NEXT: fmax.d $f0, $f0, $f24 ++; CHECK-NEXT: fst.d $f0, $sp, 0 ++; CHECK-NEXT: move $r4, $r24 ++; CHECK-NEXT: move $r5, $r23 ++; CHECK-NEXT: move $r6, $r25 ++; CHECK-NEXT: move $r7, $r26 ++; CHECK-NEXT: move $r8, $r27 ++; CHECK-NEXT: move $r9, $r28 ++; CHECK-NEXT: lu12i.w $ra, __atomic_compare_exchange ++; CHECK-NEXT: ori $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu32i.d $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu52i.d $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: jirl $ra, $ra, 0 ++; CHECK-NEXT: fld.d $f0, $sp, 8 ++; CHECK-NEXT: beqz $r4, .LBB23_1 ++; CHECK-NEXT: # %bb.2: # %atomicrmw.end ++; CHECK-NEXT: ld.d $r23, $sp, 16 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r24, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r25, $sp, 32 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r26, $sp, 40 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r27, $sp, 48 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r28, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 64 # 8-byte Folded Reload ++; CHECK-NEXT: fld.d $f24, $sp, 72 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 80 ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fmax ptr %p, double 1.0 acq_rel, align 4 ++ ret double %v ++} ++ ++define float @float_fadd_seq_cst(ptr %p) nounwind { ++; CHECK-LABEL: float_fadd_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fld.s $f0, $r4, 0 ++; CHECK-NEXT: addi.w $r5, $zero, 1 ++; CHECK-NEXT: movgr2fr.w $f1, $r5 ++; CHECK-NEXT: ffint.s.w $f1, $f1 ++; CHECK-NEXT: .LBB24_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Loop Header: Depth=1 ++; CHECK-NEXT: # Child Loop BB24_2 Depth 2 ++; CHECK-NEXT: fadd.s $f2, $f0, $f1 ++; CHECK-NEXT: movfr2gr.s $r5, $f2 ++; CHECK-NEXT: movfr2gr.s $r6, $f0 ++; CHECK-NEXT: .LBB24_2: # %atomicrmw.start ++; CHECK-NEXT: # Parent Loop BB24_1 Depth=1 ++; CHECK-NEXT: # => This Inner Loop Header: Depth=2 ++; CHECK-NEXT: ll.w $r7, $r4, 0 ++; CHECK-NEXT: bne $r7, $r6, .LBB24_4 ++; CHECK-NEXT: # %bb.3: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB24_2 Depth=2 ++; CHECK-NEXT: move $r8, $r5 ++; CHECK-NEXT: sc.w $r8, $r4, 0 ++; CHECK-NEXT: beq $r8, $zero, .LBB24_2 ++; CHECK-NEXT: .LBB24_4: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB24_1 Depth=1 ++; CHECK-NEXT: dbar 0 ++; CHECK-NEXT: movgr2fr.w $f0, $r7 ++; CHECK-NEXT: bne $r7, $r6, .LBB24_1 ++; CHECK-NEXT: # %bb.5: # %atomicrmw.end ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fadd ptr %p, float 1.0 seq_cst, align 4 ++ ret float %v ++} ++ ++define float @float_fsub_seq_cst(ptr %p) nounwind { ++; CHECK-LABEL: float_fsub_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fld.s $f0, $r4, 0 ++; CHECK-NEXT: .LBB25_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Loop Header: Depth=1 ++; CHECK-NEXT: # Child Loop BB25_2 Depth 2 ++; CHECK-NEXT: lu12i.w $r5, .LCPI25_0 ++; CHECK-NEXT: ori $r5, $r5, .LCPI25_0 ++; CHECK-NEXT: lu32i.d $r5, .LCPI25_0 ++; CHECK-NEXT: lu52i.d $r5, $r5, .LCPI25_0 ++; CHECK-NEXT: fld.s $f1, $r5, 0 ++; CHECK-NEXT: fadd.s $f1, $f0, $f1 ++; CHECK-NEXT: movfr2gr.s $r5, $f1 ++; CHECK-NEXT: movfr2gr.s $r6, $f0 ++; CHECK-NEXT: .LBB25_2: # %atomicrmw.start ++; CHECK-NEXT: # Parent Loop BB25_1 Depth=1 ++; CHECK-NEXT: # => This Inner Loop Header: Depth=2 ++; CHECK-NEXT: ll.w $r7, $r4, 0 ++; CHECK-NEXT: bne $r7, $r6, .LBB25_4 ++; CHECK-NEXT: # %bb.3: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB25_2 Depth=2 ++; CHECK-NEXT: move $r8, $r5 ++; CHECK-NEXT: sc.w $r8, $r4, 0 ++; CHECK-NEXT: beq $r8, $zero, .LBB25_2 ++; CHECK-NEXT: .LBB25_4: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB25_1 Depth=1 ++; CHECK-NEXT: dbar 0 ++; CHECK-NEXT: movgr2fr.w $f0, $r7 ++; CHECK-NEXT: bne $r7, $r6, .LBB25_1 ++; CHECK-NEXT: # %bb.5: # %atomicrmw.end ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fsub ptr %p, float 1.0 seq_cst, align 4 ++ ret float %v ++} ++ ++define float @float_fmin_seq_cst(ptr %p) nounwind { ++; CHECK-LABEL: float_fmin_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fld.s $f0, $r4, 0 ++; CHECK-NEXT: addi.w $r5, $zero, 1 ++; CHECK-NEXT: movgr2fr.w $f1, $r5 ++; CHECK-NEXT: ffint.s.w $f1, $f1 ++; CHECK-NEXT: .LBB26_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Loop Header: Depth=1 ++; CHECK-NEXT: # Child Loop BB26_2 Depth 2 ++; CHECK-NEXT: fmax.s $f2, $f0, $f0 ++; CHECK-NEXT: fmin.s $f2, $f2, $f1 ++; CHECK-NEXT: movfr2gr.s $r5, $f2 ++; CHECK-NEXT: movfr2gr.s $r6, $f0 ++; CHECK-NEXT: .LBB26_2: # %atomicrmw.start ++; CHECK-NEXT: # Parent Loop BB26_1 Depth=1 ++; CHECK-NEXT: # => This Inner Loop Header: Depth=2 ++; CHECK-NEXT: ll.w $r7, $r4, 0 ++; CHECK-NEXT: bne $r7, $r6, .LBB26_4 ++; CHECK-NEXT: # %bb.3: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB26_2 Depth=2 ++; CHECK-NEXT: move $r8, $r5 ++; CHECK-NEXT: sc.w $r8, $r4, 0 ++; CHECK-NEXT: beq $r8, $zero, .LBB26_2 ++; CHECK-NEXT: .LBB26_4: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB26_1 Depth=1 ++; CHECK-NEXT: dbar 0 ++; CHECK-NEXT: movgr2fr.w $f0, $r7 ++; CHECK-NEXT: bne $r7, $r6, .LBB26_1 ++; CHECK-NEXT: # %bb.5: # %atomicrmw.end ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fmin ptr %p, float 1.0 seq_cst, align 4 ++ ret float %v ++} ++ ++define float @float_fmax_seq_cst(ptr %p) nounwind { ++; CHECK-LABEL: float_fmax_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fld.s $f0, $r4, 0 ++; CHECK-NEXT: addi.w $r5, $zero, 1 ++; CHECK-NEXT: movgr2fr.w $f1, $r5 ++; CHECK-NEXT: ffint.s.w $f1, $f1 ++; CHECK-NEXT: .LBB27_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Loop Header: Depth=1 ++; CHECK-NEXT: # Child Loop BB27_2 Depth 2 ++; CHECK-NEXT: fmax.s $f2, $f0, $f0 ++; CHECK-NEXT: fmax.s $f2, $f2, $f1 ++; CHECK-NEXT: movfr2gr.s $r5, $f2 ++; CHECK-NEXT: movfr2gr.s $r6, $f0 ++; CHECK-NEXT: .LBB27_2: # %atomicrmw.start ++; CHECK-NEXT: # Parent Loop BB27_1 Depth=1 ++; CHECK-NEXT: # => This Inner Loop Header: Depth=2 ++; CHECK-NEXT: ll.w $r7, $r4, 0 ++; CHECK-NEXT: bne $r7, $r6, .LBB27_4 ++; CHECK-NEXT: # %bb.3: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB27_2 Depth=2 ++; CHECK-NEXT: move $r8, $r5 ++; CHECK-NEXT: sc.w $r8, $r4, 0 ++; CHECK-NEXT: beq $r8, $zero, .LBB27_2 ++; CHECK-NEXT: .LBB27_4: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB27_1 Depth=1 ++; CHECK-NEXT: dbar 0 ++; CHECK-NEXT: movgr2fr.w $f0, $r7 ++; CHECK-NEXT: bne $r7, $r6, .LBB27_1 ++; CHECK-NEXT: # %bb.5: # %atomicrmw.end ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fmax ptr %p, float 1.0 seq_cst, align 4 ++ ret float %v ++} ++ ++define double @double_fadd_seq_cst(ptr %p) nounwind { ++; CHECK-LABEL: double_fadd_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -80 ++; CHECK-NEXT: fst.d $f24, $sp, 72 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $ra, $sp, 64 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r27, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r26, $sp, 48 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r25, $sp, 40 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r24, $sp, 32 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r23, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: move $r23, $r4 ++; CHECK-NEXT: fld.d $f0, $r4, 0 ++; CHECK-NEXT: addi.d $r4, $zero, 1 ++; CHECK-NEXT: movgr2fr.d $f1, $r4 ++; CHECK-NEXT: ffint.d.l $f24, $f1 ++; CHECK-NEXT: addi.d $r24, $zero, 8 ++; CHECK-NEXT: addi.d $r25, $sp, 16 ++; CHECK-NEXT: addi.d $r26, $sp, 8 ++; CHECK-NEXT: addi.d $r27, $zero, 5 ++; CHECK-NEXT: .LBB28_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: fst.d $f0, $sp, 16 ++; CHECK-NEXT: fadd.d $f0, $f0, $f24 ++; CHECK-NEXT: fst.d $f0, $sp, 8 ++; CHECK-NEXT: move $r4, $r24 ++; CHECK-NEXT: move $r5, $r23 ++; CHECK-NEXT: move $r6, $r25 ++; CHECK-NEXT: move $r7, $r26 ++; CHECK-NEXT: move $r8, $r27 ++; CHECK-NEXT: move $r9, $r27 ++; CHECK-NEXT: lu12i.w $ra, __atomic_compare_exchange ++; CHECK-NEXT: ori $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu32i.d $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu52i.d $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: jirl $ra, $ra, 0 ++; CHECK-NEXT: fld.d $f0, $sp, 16 ++; CHECK-NEXT: beqz $r4, .LBB28_1 ++; CHECK-NEXT: # %bb.2: # %atomicrmw.end ++; CHECK-NEXT: ld.d $r23, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r24, $sp, 32 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r25, $sp, 40 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r26, $sp, 48 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r27, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 64 # 8-byte Folded Reload ++; CHECK-NEXT: fld.d $f24, $sp, 72 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 80 ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fadd ptr %p, double 1.0 seq_cst, align 4 ++ ret double %v ++} ++ ++define double @double_fsub_seq_cst(ptr %p) nounwind { ++; CHECK-LABEL: double_fsub_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -64 ++; CHECK-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r27, $sp, 48 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r26, $sp, 40 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r25, $sp, 32 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r24, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r23, $sp, 16 # 8-byte Folded Spill ++; CHECK-NEXT: move $r23, $r4 ++; CHECK-NEXT: fld.d $f0, $r4, 0 ++; CHECK-NEXT: addi.d $r24, $zero, 8 ++; CHECK-NEXT: addi.d $r25, $sp, 8 ++; CHECK-NEXT: addi.d $r26, $sp, 0 ++; CHECK-NEXT: addi.d $r27, $zero, 5 ++; CHECK-NEXT: .LBB29_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: fst.d $f0, $sp, 8 ++; CHECK-NEXT: lu12i.w $r4, .LCPI29_0 ++; CHECK-NEXT: ori $r4, $r4, .LCPI29_0 ++; CHECK-NEXT: lu32i.d $r4, .LCPI29_0 ++; CHECK-NEXT: lu52i.d $r4, $r4, .LCPI29_0 ++; CHECK-NEXT: fld.d $f1, $r4, 0 ++; CHECK-NEXT: fadd.d $f0, $f0, $f1 ++; CHECK-NEXT: fst.d $f0, $sp, 0 ++; CHECK-NEXT: move $r4, $r24 ++; CHECK-NEXT: move $r5, $r23 ++; CHECK-NEXT: move $r6, $r25 ++; CHECK-NEXT: move $r7, $r26 ++; CHECK-NEXT: move $r8, $r27 ++; CHECK-NEXT: move $r9, $r27 ++; CHECK-NEXT: lu12i.w $ra, __atomic_compare_exchange ++; CHECK-NEXT: ori $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu32i.d $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu52i.d $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: jirl $ra, $ra, 0 ++; CHECK-NEXT: fld.d $f0, $sp, 8 ++; CHECK-NEXT: beqz $r4, .LBB29_1 ++; CHECK-NEXT: # %bb.2: # %atomicrmw.end ++; CHECK-NEXT: ld.d $r23, $sp, 16 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r24, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r25, $sp, 32 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r26, $sp, 40 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r27, $sp, 48 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 64 ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fsub ptr %p, double 1.0 seq_cst, align 4 ++ ret double %v ++} ++ ++define double @double_fmin_seq_cst(ptr %p) nounwind { ++; CHECK-LABEL: double_fmin_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -80 ++; CHECK-NEXT: fst.d $f24, $sp, 72 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $ra, $sp, 64 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r27, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r26, $sp, 48 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r25, $sp, 40 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r24, $sp, 32 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r23, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: move $r23, $r4 ++; CHECK-NEXT: fld.d $f0, $r4, 0 ++; CHECK-NEXT: addi.d $r4, $zero, 1 ++; CHECK-NEXT: movgr2fr.d $f1, $r4 ++; CHECK-NEXT: ffint.d.l $f24, $f1 ++; CHECK-NEXT: addi.d $r24, $zero, 8 ++; CHECK-NEXT: addi.d $r25, $sp, 16 ++; CHECK-NEXT: addi.d $r26, $sp, 8 ++; CHECK-NEXT: addi.d $r27, $zero, 5 ++; CHECK-NEXT: .LBB30_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: fst.d $f0, $sp, 16 ++; CHECK-NEXT: fmax.d $f0, $f0, $f0 ++; CHECK-NEXT: fmin.d $f0, $f0, $f24 ++; CHECK-NEXT: fst.d $f0, $sp, 8 ++; CHECK-NEXT: move $r4, $r24 ++; CHECK-NEXT: move $r5, $r23 ++; CHECK-NEXT: move $r6, $r25 ++; CHECK-NEXT: move $r7, $r26 ++; CHECK-NEXT: move $r8, $r27 ++; CHECK-NEXT: move $r9, $r27 ++; CHECK-NEXT: lu12i.w $ra, __atomic_compare_exchange ++; CHECK-NEXT: ori $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu32i.d $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu52i.d $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: jirl $ra, $ra, 0 ++; CHECK-NEXT: fld.d $f0, $sp, 16 ++; CHECK-NEXT: beqz $r4, .LBB30_1 ++; CHECK-NEXT: # %bb.2: # %atomicrmw.end ++; CHECK-NEXT: ld.d $r23, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r24, $sp, 32 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r25, $sp, 40 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r26, $sp, 48 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r27, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 64 # 8-byte Folded Reload ++; CHECK-NEXT: fld.d $f24, $sp, 72 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 80 ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fmin ptr %p, double 1.0 seq_cst, align 4 ++ ret double %v ++} ++ ++define double @double_fmax_seq_cst(ptr %p) nounwind { ++; CHECK-LABEL: double_fmax_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -80 ++; CHECK-NEXT: fst.d $f24, $sp, 72 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $ra, $sp, 64 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r27, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r26, $sp, 48 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r25, $sp, 40 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r24, $sp, 32 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r23, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: move $r23, $r4 ++; CHECK-NEXT: fld.d $f0, $r4, 0 ++; CHECK-NEXT: addi.d $r4, $zero, 1 ++; CHECK-NEXT: movgr2fr.d $f1, $r4 ++; CHECK-NEXT: ffint.d.l $f24, $f1 ++; CHECK-NEXT: addi.d $r24, $zero, 8 ++; CHECK-NEXT: addi.d $r25, $sp, 16 ++; CHECK-NEXT: addi.d $r26, $sp, 8 ++; CHECK-NEXT: addi.d $r27, $zero, 5 ++; CHECK-NEXT: .LBB31_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: fst.d $f0, $sp, 16 ++; CHECK-NEXT: fmax.d $f0, $f0, $f0 ++; CHECK-NEXT: fmax.d $f0, $f0, $f24 ++; CHECK-NEXT: fst.d $f0, $sp, 8 ++; CHECK-NEXT: move $r4, $r24 ++; CHECK-NEXT: move $r5, $r23 ++; CHECK-NEXT: move $r6, $r25 ++; CHECK-NEXT: move $r7, $r26 ++; CHECK-NEXT: move $r8, $r27 ++; CHECK-NEXT: move $r9, $r27 ++; CHECK-NEXT: lu12i.w $ra, __atomic_compare_exchange ++; CHECK-NEXT: ori $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu32i.d $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu52i.d $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: jirl $ra, $ra, 0 ++; CHECK-NEXT: fld.d $f0, $sp, 16 ++; CHECK-NEXT: beqz $r4, .LBB31_1 ++; CHECK-NEXT: # %bb.2: # %atomicrmw.end ++; CHECK-NEXT: ld.d $r23, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r24, $sp, 32 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r25, $sp, 40 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r26, $sp, 48 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r27, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 64 # 8-byte Folded Reload ++; CHECK-NEXT: fld.d $f24, $sp, 72 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 80 ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fmax ptr %p, double 1.0 seq_cst, align 4 ++ ret double %v ++} ++ ++define float @float_fadd_monotonic(ptr %p) nounwind { ++; CHECK-LABEL: float_fadd_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fld.s $f0, $r4, 0 ++; CHECK-NEXT: addi.w $r5, $zero, 1 ++; CHECK-NEXT: movgr2fr.w $f1, $r5 ++; CHECK-NEXT: ffint.s.w $f1, $f1 ++; CHECK-NEXT: .LBB32_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Loop Header: Depth=1 ++; CHECK-NEXT: # Child Loop BB32_2 Depth 2 ++; CHECK-NEXT: fadd.s $f2, $f0, $f1 ++; CHECK-NEXT: movfr2gr.s $r5, $f2 ++; CHECK-NEXT: movfr2gr.s $r6, $f0 ++; CHECK-NEXT: .LBB32_2: # %atomicrmw.start ++; CHECK-NEXT: # Parent Loop BB32_1 Depth=1 ++; CHECK-NEXT: # => This Inner Loop Header: Depth=2 ++; CHECK-NEXT: ll.w $r7, $r4, 0 ++; CHECK-NEXT: bne $r7, $r6, .LBB32_4 ++; CHECK-NEXT: # %bb.3: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB32_2 Depth=2 ++; CHECK-NEXT: move $r8, $r5 ++; CHECK-NEXT: sc.w $r8, $r4, 0 ++; CHECK-NEXT: beq $r8, $zero, .LBB32_2 ++; CHECK-NEXT: .LBB32_4: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB32_1 Depth=1 ++; CHECK-NEXT: dbar 1792 ++; CHECK-NEXT: movgr2fr.w $f0, $r7 ++; CHECK-NEXT: bne $r7, $r6, .LBB32_1 ++; CHECK-NEXT: # %bb.5: # %atomicrmw.end ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fadd ptr %p, float 1.0 monotonic, align 4 ++ ret float %v ++} ++ ++define float @float_fsub_monotonic(ptr %p) nounwind { ++; CHECK-LABEL: float_fsub_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fld.s $f0, $r4, 0 ++; CHECK-NEXT: .LBB33_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Loop Header: Depth=1 ++; CHECK-NEXT: # Child Loop BB33_2 Depth 2 ++; CHECK-NEXT: lu12i.w $r5, .LCPI33_0 ++; CHECK-NEXT: ori $r5, $r5, .LCPI33_0 ++; CHECK-NEXT: lu32i.d $r5, .LCPI33_0 ++; CHECK-NEXT: lu52i.d $r5, $r5, .LCPI33_0 ++; CHECK-NEXT: fld.s $f1, $r5, 0 ++; CHECK-NEXT: fadd.s $f1, $f0, $f1 ++; CHECK-NEXT: movfr2gr.s $r5, $f1 ++; CHECK-NEXT: movfr2gr.s $r6, $f0 ++; CHECK-NEXT: .LBB33_2: # %atomicrmw.start ++; CHECK-NEXT: # Parent Loop BB33_1 Depth=1 ++; CHECK-NEXT: # => This Inner Loop Header: Depth=2 ++; CHECK-NEXT: ll.w $r7, $r4, 0 ++; CHECK-NEXT: bne $r7, $r6, .LBB33_4 ++; CHECK-NEXT: # %bb.3: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB33_2 Depth=2 ++; CHECK-NEXT: move $r8, $r5 ++; CHECK-NEXT: sc.w $r8, $r4, 0 ++; CHECK-NEXT: beq $r8, $zero, .LBB33_2 ++; CHECK-NEXT: .LBB33_4: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB33_1 Depth=1 ++; CHECK-NEXT: dbar 1792 ++; CHECK-NEXT: movgr2fr.w $f0, $r7 ++; CHECK-NEXT: bne $r7, $r6, .LBB33_1 ++; CHECK-NEXT: # %bb.5: # %atomicrmw.end ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fsub ptr %p, float 1.0 monotonic, align 4 ++ ret float %v ++} ++ ++define float @float_fmin_monotonic(ptr %p) nounwind { ++; CHECK-LABEL: float_fmin_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fld.s $f0, $r4, 0 ++; CHECK-NEXT: addi.w $r5, $zero, 1 ++; CHECK-NEXT: movgr2fr.w $f1, $r5 ++; CHECK-NEXT: ffint.s.w $f1, $f1 ++; CHECK-NEXT: .LBB34_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Loop Header: Depth=1 ++; CHECK-NEXT: # Child Loop BB34_2 Depth 2 ++; CHECK-NEXT: fmax.s $f2, $f0, $f0 ++; CHECK-NEXT: fmin.s $f2, $f2, $f1 ++; CHECK-NEXT: movfr2gr.s $r5, $f2 ++; CHECK-NEXT: movfr2gr.s $r6, $f0 ++; CHECK-NEXT: .LBB34_2: # %atomicrmw.start ++; CHECK-NEXT: # Parent Loop BB34_1 Depth=1 ++; CHECK-NEXT: # => This Inner Loop Header: Depth=2 ++; CHECK-NEXT: ll.w $r7, $r4, 0 ++; CHECK-NEXT: bne $r7, $r6, .LBB34_4 ++; CHECK-NEXT: # %bb.3: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB34_2 Depth=2 ++; CHECK-NEXT: move $r8, $r5 ++; CHECK-NEXT: sc.w $r8, $r4, 0 ++; CHECK-NEXT: beq $r8, $zero, .LBB34_2 ++; CHECK-NEXT: .LBB34_4: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB34_1 Depth=1 ++; CHECK-NEXT: dbar 1792 ++; CHECK-NEXT: movgr2fr.w $f0, $r7 ++; CHECK-NEXT: bne $r7, $r6, .LBB34_1 ++; CHECK-NEXT: # %bb.5: # %atomicrmw.end ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fmin ptr %p, float 1.0 monotonic, align 4 ++ ret float %v ++} ++ ++define float @float_fmax_monotonic(ptr %p) nounwind { ++; CHECK-LABEL: float_fmax_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fld.s $f0, $r4, 0 ++; CHECK-NEXT: addi.w $r5, $zero, 1 ++; CHECK-NEXT: movgr2fr.w $f1, $r5 ++; CHECK-NEXT: ffint.s.w $f1, $f1 ++; CHECK-NEXT: .LBB35_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Loop Header: Depth=1 ++; CHECK-NEXT: # Child Loop BB35_2 Depth 2 ++; CHECK-NEXT: fmax.s $f2, $f0, $f0 ++; CHECK-NEXT: fmax.s $f2, $f2, $f1 ++; CHECK-NEXT: movfr2gr.s $r5, $f2 ++; CHECK-NEXT: movfr2gr.s $r6, $f0 ++; CHECK-NEXT: .LBB35_2: # %atomicrmw.start ++; CHECK-NEXT: # Parent Loop BB35_1 Depth=1 ++; CHECK-NEXT: # => This Inner Loop Header: Depth=2 ++; CHECK-NEXT: ll.w $r7, $r4, 0 ++; CHECK-NEXT: bne $r7, $r6, .LBB35_4 ++; CHECK-NEXT: # %bb.3: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB35_2 Depth=2 ++; CHECK-NEXT: move $r8, $r5 ++; CHECK-NEXT: sc.w $r8, $r4, 0 ++; CHECK-NEXT: beq $r8, $zero, .LBB35_2 ++; CHECK-NEXT: .LBB35_4: # %atomicrmw.start ++; CHECK-NEXT: # in Loop: Header=BB35_1 Depth=1 ++; CHECK-NEXT: dbar 1792 ++; CHECK-NEXT: movgr2fr.w $f0, $r7 ++; CHECK-NEXT: bne $r7, $r6, .LBB35_1 ++; CHECK-NEXT: # %bb.5: # %atomicrmw.end ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fmax ptr %p, float 1.0 monotonic, align 4 ++ ret float %v ++} ++ ++define double @double_fadd_monotonic(ptr %p) nounwind { ++; CHECK-LABEL: double_fadd_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -80 ++; CHECK-NEXT: fst.d $f24, $sp, 72 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $ra, $sp, 64 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r27, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r26, $sp, 48 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r25, $sp, 40 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r24, $sp, 32 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r23, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: move $r23, $r4 ++; CHECK-NEXT: fld.d $f0, $r4, 0 ++; CHECK-NEXT: addi.d $r4, $zero, 1 ++; CHECK-NEXT: movgr2fr.d $f1, $r4 ++; CHECK-NEXT: ffint.d.l $f24, $f1 ++; CHECK-NEXT: addi.d $r24, $zero, 8 ++; CHECK-NEXT: addi.d $r25, $sp, 16 ++; CHECK-NEXT: addi.d $r26, $sp, 8 ++; CHECK-NEXT: addi.d $r27, $zero, 0 ++; CHECK-NEXT: .LBB36_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: fst.d $f0, $sp, 16 ++; CHECK-NEXT: fadd.d $f0, $f0, $f24 ++; CHECK-NEXT: fst.d $f0, $sp, 8 ++; CHECK-NEXT: move $r4, $r24 ++; CHECK-NEXT: move $r5, $r23 ++; CHECK-NEXT: move $r6, $r25 ++; CHECK-NEXT: move $r7, $r26 ++; CHECK-NEXT: move $r8, $r27 ++; CHECK-NEXT: move $r9, $r27 ++; CHECK-NEXT: lu12i.w $ra, __atomic_compare_exchange ++; CHECK-NEXT: ori $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu32i.d $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu52i.d $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: jirl $ra, $ra, 0 ++; CHECK-NEXT: fld.d $f0, $sp, 16 ++; CHECK-NEXT: beqz $r4, .LBB36_1 ++; CHECK-NEXT: # %bb.2: # %atomicrmw.end ++; CHECK-NEXT: ld.d $r23, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r24, $sp, 32 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r25, $sp, 40 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r26, $sp, 48 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r27, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 64 # 8-byte Folded Reload ++; CHECK-NEXT: fld.d $f24, $sp, 72 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 80 ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fadd ptr %p, double 1.0 monotonic, align 4 ++ ret double %v ++} ++ ++define double @double_fsub_monotonic(ptr %p) nounwind { ++; CHECK-LABEL: double_fsub_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -64 ++; CHECK-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r27, $sp, 48 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r26, $sp, 40 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r25, $sp, 32 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r24, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r23, $sp, 16 # 8-byte Folded Spill ++; CHECK-NEXT: move $r23, $r4 ++; CHECK-NEXT: fld.d $f0, $r4, 0 ++; CHECK-NEXT: addi.d $r24, $zero, 8 ++; CHECK-NEXT: addi.d $r25, $sp, 8 ++; CHECK-NEXT: addi.d $r26, $sp, 0 ++; CHECK-NEXT: addi.d $r27, $zero, 0 ++; CHECK-NEXT: .LBB37_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: fst.d $f0, $sp, 8 ++; CHECK-NEXT: lu12i.w $r4, .LCPI37_0 ++; CHECK-NEXT: ori $r4, $r4, .LCPI37_0 ++; CHECK-NEXT: lu32i.d $r4, .LCPI37_0 ++; CHECK-NEXT: lu52i.d $r4, $r4, .LCPI37_0 ++; CHECK-NEXT: fld.d $f1, $r4, 0 ++; CHECK-NEXT: fadd.d $f0, $f0, $f1 ++; CHECK-NEXT: fst.d $f0, $sp, 0 ++; CHECK-NEXT: move $r4, $r24 ++; CHECK-NEXT: move $r5, $r23 ++; CHECK-NEXT: move $r6, $r25 ++; CHECK-NEXT: move $r7, $r26 ++; CHECK-NEXT: move $r8, $r27 ++; CHECK-NEXT: move $r9, $r27 ++; CHECK-NEXT: lu12i.w $ra, __atomic_compare_exchange ++; CHECK-NEXT: ori $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu32i.d $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu52i.d $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: jirl $ra, $ra, 0 ++; CHECK-NEXT: fld.d $f0, $sp, 8 ++; CHECK-NEXT: beqz $r4, .LBB37_1 ++; CHECK-NEXT: # %bb.2: # %atomicrmw.end ++; CHECK-NEXT: ld.d $r23, $sp, 16 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r24, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r25, $sp, 32 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r26, $sp, 40 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r27, $sp, 48 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 64 ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fsub ptr %p, double 1.0 monotonic, align 4 ++ ret double %v ++} ++ ++define double @double_fmin_monotonic(ptr %p) nounwind { ++; CHECK-LABEL: double_fmin_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -80 ++; CHECK-NEXT: fst.d $f24, $sp, 72 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $ra, $sp, 64 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r27, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r26, $sp, 48 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r25, $sp, 40 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r24, $sp, 32 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r23, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: move $r23, $r4 ++; CHECK-NEXT: fld.d $f0, $r4, 0 ++; CHECK-NEXT: addi.d $r4, $zero, 1 ++; CHECK-NEXT: movgr2fr.d $f1, $r4 ++; CHECK-NEXT: ffint.d.l $f24, $f1 ++; CHECK-NEXT: addi.d $r24, $zero, 8 ++; CHECK-NEXT: addi.d $r25, $sp, 16 ++; CHECK-NEXT: addi.d $r26, $sp, 8 ++; CHECK-NEXT: addi.d $r27, $zero, 0 ++; CHECK-NEXT: .LBB38_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: fst.d $f0, $sp, 16 ++; CHECK-NEXT: fmax.d $f0, $f0, $f0 ++; CHECK-NEXT: fmin.d $f0, $f0, $f24 ++; CHECK-NEXT: fst.d $f0, $sp, 8 ++; CHECK-NEXT: move $r4, $r24 ++; CHECK-NEXT: move $r5, $r23 ++; CHECK-NEXT: move $r6, $r25 ++; CHECK-NEXT: move $r7, $r26 ++; CHECK-NEXT: move $r8, $r27 ++; CHECK-NEXT: move $r9, $r27 ++; CHECK-NEXT: lu12i.w $ra, __atomic_compare_exchange ++; CHECK-NEXT: ori $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu32i.d $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu52i.d $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: jirl $ra, $ra, 0 ++; CHECK-NEXT: fld.d $f0, $sp, 16 ++; CHECK-NEXT: beqz $r4, .LBB38_1 ++; CHECK-NEXT: # %bb.2: # %atomicrmw.end ++; CHECK-NEXT: ld.d $r23, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r24, $sp, 32 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r25, $sp, 40 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r26, $sp, 48 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r27, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 64 # 8-byte Folded Reload ++; CHECK-NEXT: fld.d $f24, $sp, 72 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 80 ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fmin ptr %p, double 1.0 monotonic, align 4 ++ ret double %v ++} ++ ++define double @double_fmax_monotonic(ptr %p) nounwind { ++; CHECK-LABEL: double_fmax_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -80 ++; CHECK-NEXT: fst.d $f24, $sp, 72 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $ra, $sp, 64 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r27, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r26, $sp, 48 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r25, $sp, 40 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r24, $sp, 32 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r23, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: move $r23, $r4 ++; CHECK-NEXT: fld.d $f0, $r4, 0 ++; CHECK-NEXT: addi.d $r4, $zero, 1 ++; CHECK-NEXT: movgr2fr.d $f1, $r4 ++; CHECK-NEXT: ffint.d.l $f24, $f1 ++; CHECK-NEXT: addi.d $r24, $zero, 8 ++; CHECK-NEXT: addi.d $r25, $sp, 16 ++; CHECK-NEXT: addi.d $r26, $sp, 8 ++; CHECK-NEXT: addi.d $r27, $zero, 0 ++; CHECK-NEXT: .LBB39_1: # %atomicrmw.start ++; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: fst.d $f0, $sp, 16 ++; CHECK-NEXT: fmax.d $f0, $f0, $f0 ++; CHECK-NEXT: fmax.d $f0, $f0, $f24 ++; CHECK-NEXT: fst.d $f0, $sp, 8 ++; CHECK-NEXT: move $r4, $r24 ++; CHECK-NEXT: move $r5, $r23 ++; CHECK-NEXT: move $r6, $r25 ++; CHECK-NEXT: move $r7, $r26 ++; CHECK-NEXT: move $r8, $r27 ++; CHECK-NEXT: move $r9, $r27 ++; CHECK-NEXT: lu12i.w $ra, __atomic_compare_exchange ++; CHECK-NEXT: ori $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu32i.d $ra, __atomic_compare_exchange ++; CHECK-NEXT: lu52i.d $ra, $ra, __atomic_compare_exchange ++; CHECK-NEXT: jirl $ra, $ra, 0 ++; CHECK-NEXT: fld.d $f0, $sp, 16 ++; CHECK-NEXT: beqz $r4, .LBB39_1 ++; CHECK-NEXT: # %bb.2: # %atomicrmw.end ++; CHECK-NEXT: ld.d $r23, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r24, $sp, 32 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r25, $sp, 40 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r26, $sp, 48 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $r27, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 64 # 8-byte Folded Reload ++; CHECK-NEXT: fld.d $f24, $sp, 72 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 80 ++; CHECK-NEXT: jr $ra ++ %v = atomicrmw fmax ptr %p, double 1.0 monotonic, align 4 ++ ret double %v ++} +diff --git a/llvm/test/CodeGen/LoongArch/atomicrmw-minmax.ll b/llvm/test/CodeGen/LoongArch/atomicrmw-minmax.ll +new file mode 100644 +index 000000000..3e04fc53c +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/atomicrmw-minmax.ll +@@ -0,0 +1,1882 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s | FileCheck %s ++ ++define i8 @atomicrmw_umax_i8_acquire(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umax_i8_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB0_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB0_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umax ptr %a, i8 %b acquire ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_umax_i16_acquire(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umax_i16_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB1_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB1_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umax ptr %a, i16 %b acquire ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_umax_i32_acquire(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umax_i32_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.wu $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umax ptr %a, i32 %b acquire ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_umax_i64_acquire(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umax_i64_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.du $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umax ptr %a, i64 %b acquire ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_umin_i8_acquire(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umin_i8_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB4_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB4_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umin ptr %a, i8 %b acquire ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_umin_i16_acquire(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umin_i16_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB5_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB5_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umin ptr %a, i16 %b acquire ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_umin_i32_acquire(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umin_i32_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.wu $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umin ptr %a, i32 %b acquire ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_umin_i64_acquire(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umin_i64_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.du $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umin ptr %a, i64 %b acquire ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_max_i8_acquire(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_max_i8_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB8_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB8_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw max ptr %a, i8 %b acquire ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_max_i16_acquire(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_max_i16_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB9_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB9_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw max ptr %a, i16 %b acquire ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_max_i32_acquire(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_max_i32_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw max ptr %a, i32 %b acquire ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_max_i64_acquire(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_max_i64_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw max ptr %a, i64 %b acquire ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_min_i8_acquire(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_min_i8_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB12_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB12_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw min ptr %a, i8 %b acquire ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_min_i16_acquire(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_min_i16_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB13_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB13_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw min ptr %a, i16 %b acquire ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_min_i32_acquire(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_min_i32_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw min ptr %a, i32 %b acquire ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_min_i64_acquire(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_min_i64_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw min ptr %a, i64 %b acquire ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_umax_i8_release(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umax_i8_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB16_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB16_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umax ptr %a, i8 %b release ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_umax_i16_release(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umax_i16_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB17_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB17_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umax ptr %a, i16 %b release ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_umax_i32_release(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umax_i32_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.wu $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umax ptr %a, i32 %b release ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_umax_i64_release(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umax_i64_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.du $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umax ptr %a, i64 %b release ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_umin_i8_release(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umin_i8_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB20_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB20_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umin ptr %a, i8 %b release ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_umin_i16_release(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umin_i16_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB21_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB21_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umin ptr %a, i16 %b release ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_umin_i32_release(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umin_i32_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.wu $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umin ptr %a, i32 %b release ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_umin_i64_release(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umin_i64_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.du $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umin ptr %a, i64 %b release ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_max_i8_release(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_max_i8_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB24_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB24_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw max ptr %a, i8 %b release ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_max_i16_release(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_max_i16_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB25_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB25_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw max ptr %a, i16 %b release ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_max_i32_release(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_max_i32_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw max ptr %a, i32 %b release ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_max_i64_release(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_max_i64_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw max ptr %a, i64 %b release ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_min_i8_release(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_min_i8_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB28_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB28_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw min ptr %a, i8 %b release ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_min_i16_release(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_min_i16_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB29_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB29_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw min ptr %a, i16 %b release ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_min_i32_release(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_min_i32_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw min ptr %a, i32 %b release ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_min_i64_release(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_min_i64_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw min ptr %a, i64 %b release ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_umax_i8_acq_rel(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umax_i8_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB32_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB32_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umax ptr %a, i8 %b acq_rel ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_umax_i16_acq_rel(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umax_i16_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB33_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB33_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umax ptr %a, i16 %b acq_rel ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_umax_i32_acq_rel(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umax_i32_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.wu $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umax ptr %a, i32 %b acq_rel ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_umax_i64_acq_rel(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umax_i64_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.du $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umax ptr %a, i64 %b acq_rel ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_umin_i8_acq_rel(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umin_i8_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB36_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB36_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umin ptr %a, i8 %b acq_rel ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_umin_i16_acq_rel(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umin_i16_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB37_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB37_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umin ptr %a, i16 %b acq_rel ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_umin_i32_acq_rel(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umin_i32_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.wu $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umin ptr %a, i32 %b acq_rel ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_umin_i64_acq_rel(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umin_i64_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.du $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umin ptr %a, i64 %b acq_rel ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_max_i8_acq_rel(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_max_i8_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB40_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB40_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw max ptr %a, i8 %b acq_rel ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_max_i16_acq_rel(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_max_i16_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB41_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB41_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw max ptr %a, i16 %b acq_rel ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_max_i32_acq_rel(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_max_i32_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw max ptr %a, i32 %b acq_rel ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_max_i64_acq_rel(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_max_i64_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw max ptr %a, i64 %b acq_rel ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_min_i8_acq_rel(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_min_i8_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB44_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB44_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw min ptr %a, i8 %b acq_rel ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_min_i16_acq_rel(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_min_i16_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB45_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB45_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw min ptr %a, i16 %b acq_rel ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_min_i32_acq_rel(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_min_i32_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw min ptr %a, i32 %b acq_rel ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_min_i64_acq_rel(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_min_i64_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw min ptr %a, i64 %b acq_rel ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_umax_i8_seq_cst(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umax_i8_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB48_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB48_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umax ptr %a, i8 %b seq_cst ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_umax_i16_seq_cst(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umax_i16_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB49_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB49_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umax ptr %a, i16 %b seq_cst ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_umax_i32_seq_cst(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umax_i32_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.wu $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umax ptr %a, i32 %b seq_cst ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_umax_i64_seq_cst(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umax_i64_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.du $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umax ptr %a, i64 %b seq_cst ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_umin_i8_seq_cst(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umin_i8_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB52_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB52_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umin ptr %a, i8 %b seq_cst ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_umin_i16_seq_cst(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umin_i16_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB53_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB53_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umin ptr %a, i16 %b seq_cst ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_umin_i32_seq_cst(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umin_i32_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.wu $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umin ptr %a, i32 %b seq_cst ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_umin_i64_seq_cst(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umin_i64_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.du $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umin ptr %a, i64 %b seq_cst ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_max_i8_seq_cst(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_max_i8_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB56_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB56_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw max ptr %a, i8 %b seq_cst ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_max_i16_seq_cst(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_max_i16_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB57_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB57_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw max ptr %a, i16 %b seq_cst ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_max_i32_seq_cst(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_max_i32_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw max ptr %a, i32 %b seq_cst ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_max_i64_seq_cst(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_max_i64_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw max ptr %a, i64 %b seq_cst ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_min_i8_seq_cst(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_min_i8_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB60_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB60_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw min ptr %a, i8 %b seq_cst ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_min_i16_seq_cst(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_min_i16_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB61_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB61_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw min ptr %a, i16 %b seq_cst ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_min_i32_seq_cst(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_min_i32_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw min ptr %a, i32 %b seq_cst ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_min_i64_seq_cst(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_min_i64_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw min ptr %a, i64 %b seq_cst ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_umax_i8_monotonic(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umax_i8_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB64_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB64_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umax ptr %a, i8 %b monotonic ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_umax_i16_monotonic(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umax_i16_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB65_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB65_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umax ptr %a, i16 %b monotonic ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_umax_i32_monotonic(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umax_i32_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.wu $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umax ptr %a, i32 %b monotonic ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_umax_i64_monotonic(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umax_i64_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.du $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umax ptr %a, i64 %b monotonic ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_umin_i8_monotonic(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umin_i8_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB68_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB68_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umin ptr %a, i8 %b monotonic ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_umin_i16_monotonic(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umin_i16_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB69_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: sltu $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB69_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umin ptr %a, i16 %b monotonic ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_umin_i32_monotonic(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umin_i32_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.wu $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umin ptr %a, i32 %b monotonic ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_umin_i64_monotonic(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_umin_i64_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.du $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw umin ptr %a, i64 %b monotonic ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_max_i8_monotonic(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_max_i8_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB72_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB72_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw max ptr %a, i8 %b monotonic ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_max_i16_monotonic(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_max_i16_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB73_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: masknez $r11, $r14, $r13 ++; CHECK-NEXT: maskeqz $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB73_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw max ptr %a, i16 %b monotonic ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_max_i32_monotonic(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_max_i32_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw max ptr %a, i32 %b monotonic ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_max_i64_monotonic(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_max_i64_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammax_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw max ptr %a, i64 %b monotonic ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_min_i8_monotonic(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_min_i8_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB76_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB76_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw min ptr %a, i8 %b monotonic ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_min_i16_monotonic(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_min_i16_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB77_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r14, $r10, $r8 ++; CHECK-NEXT: and $r5, $r5, $r8 ++; CHECK-NEXT: slt $r13, $r14, $r5 ++; CHECK-NEXT: maskeqz $r11, $r14, $r13 ++; CHECK-NEXT: masknez $r13, $r5, $r13 ++; CHECK-NEXT: or $r11, $r11, $r13 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB77_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw min ptr %a, i16 %b monotonic ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_min_i32_monotonic(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_min_i32_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw min ptr %a, i32 %b monotonic ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_min_i64_monotonic(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_min_i64_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: ammin_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw min ptr %a, i64 %b monotonic ++ ret i64 %1 ++} +diff --git a/llvm/test/CodeGen/LoongArch/atomicrmw-uinc-udec-wrap.ll b/llvm/test/CodeGen/LoongArch/atomicrmw-uinc-udec-wrap.ll +deleted file mode 100644 +index b84c1093e..000000000 +--- a/llvm/test/CodeGen/LoongArch/atomicrmw-uinc-udec-wrap.ll ++++ /dev/null +@@ -1,374 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck --check-prefix=LA64 %s +- +-define i8 @atomicrmw_uinc_wrap_i8(ptr %ptr, i8 %val) { +-; LA64-LABEL: atomicrmw_uinc_wrap_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: ld.w $a2, $a0, 0 +-; LA64-NEXT: ori $a4, $zero, 255 +-; LA64-NEXT: sll.w $a4, $a4, $a3 +-; LA64-NEXT: andi $a3, $a3, 24 +-; LA64-NEXT: nor $a4, $a4, $zero +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: .p2align 4, , 16 +-; LA64-NEXT: .LBB0_1: # %atomicrmw.start +-; LA64-NEXT: # =>This Loop Header: Depth=1 +-; LA64-NEXT: # Child Loop BB0_3 Depth 2 +-; LA64-NEXT: srl.w $a5, $a2, $a3 +-; LA64-NEXT: andi $a6, $a5, 255 +-; LA64-NEXT: sltu $a6, $a6, $a1 +-; LA64-NEXT: addi.d $a5, $a5, 1 +-; LA64-NEXT: xori $a6, $a6, 1 +-; LA64-NEXT: masknez $a5, $a5, $a6 +-; LA64-NEXT: andi $a5, $a5, 255 +-; LA64-NEXT: sll.w $a5, $a5, $a3 +-; LA64-NEXT: and $a6, $a2, $a4 +-; LA64-NEXT: or $a5, $a6, $a5 +-; LA64-NEXT: addi.w $a6, $a2, 0 +-; LA64-NEXT: .LBB0_3: # %atomicrmw.start +-; LA64-NEXT: # Parent Loop BB0_1 Depth=1 +-; LA64-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64-NEXT: ll.w $a2, $a0, 0 +-; LA64-NEXT: bne $a2, $a6, .LBB0_5 +-; LA64-NEXT: # %bb.4: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB0_3 Depth=2 +-; LA64-NEXT: move $a7, $a5 +-; LA64-NEXT: sc.w $a7, $a0, 0 +-; LA64-NEXT: beqz $a7, .LBB0_3 +-; LA64-NEXT: b .LBB0_6 +-; LA64-NEXT: .LBB0_5: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB0_1 Depth=1 +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: .LBB0_6: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB0_1 Depth=1 +-; LA64-NEXT: bne $a2, $a6, .LBB0_1 +-; LA64-NEXT: # %bb.2: # %atomicrmw.end +-; LA64-NEXT: srl.w $a0, $a2, $a3 +-; LA64-NEXT: ret +- %result = atomicrmw uinc_wrap ptr %ptr, i8 %val seq_cst +- ret i8 %result +-} +- +-define i16 @atomicrmw_uinc_wrap_i16(ptr %ptr, i16 %val) { +-; LA64-LABEL: atomicrmw_uinc_wrap_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: ld.w $a2, $a0, 0 +-; LA64-NEXT: lu12i.w $a4, 15 +-; LA64-NEXT: ori $a4, $a4, 4095 +-; LA64-NEXT: sll.w $a4, $a4, $a3 +-; LA64-NEXT: andi $a3, $a3, 24 +-; LA64-NEXT: nor $a4, $a4, $zero +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: .p2align 4, , 16 +-; LA64-NEXT: .LBB1_1: # %atomicrmw.start +-; LA64-NEXT: # =>This Loop Header: Depth=1 +-; LA64-NEXT: # Child Loop BB1_3 Depth 2 +-; LA64-NEXT: srl.w $a5, $a2, $a3 +-; LA64-NEXT: bstrpick.d $a6, $a5, 15, 0 +-; LA64-NEXT: sltu $a6, $a6, $a1 +-; LA64-NEXT: addi.d $a5, $a5, 1 +-; LA64-NEXT: xori $a6, $a6, 1 +-; LA64-NEXT: masknez $a5, $a5, $a6 +-; LA64-NEXT: bstrpick.d $a5, $a5, 15, 0 +-; LA64-NEXT: sll.w $a5, $a5, $a3 +-; LA64-NEXT: and $a6, $a2, $a4 +-; LA64-NEXT: or $a5, $a6, $a5 +-; LA64-NEXT: addi.w $a6, $a2, 0 +-; LA64-NEXT: .LBB1_3: # %atomicrmw.start +-; LA64-NEXT: # Parent Loop BB1_1 Depth=1 +-; LA64-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64-NEXT: ll.w $a2, $a0, 0 +-; LA64-NEXT: bne $a2, $a6, .LBB1_5 +-; LA64-NEXT: # %bb.4: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB1_3 Depth=2 +-; LA64-NEXT: move $a7, $a5 +-; LA64-NEXT: sc.w $a7, $a0, 0 +-; LA64-NEXT: beqz $a7, .LBB1_3 +-; LA64-NEXT: b .LBB1_6 +-; LA64-NEXT: .LBB1_5: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB1_1 Depth=1 +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: .LBB1_6: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB1_1 Depth=1 +-; LA64-NEXT: bne $a2, $a6, .LBB1_1 +-; LA64-NEXT: # %bb.2: # %atomicrmw.end +-; LA64-NEXT: srl.w $a0, $a2, $a3 +-; LA64-NEXT: ret +- %result = atomicrmw uinc_wrap ptr %ptr, i16 %val seq_cst +- ret i16 %result +-} +- +-define i32 @atomicrmw_uinc_wrap_i32(ptr %ptr, i32 %val) { +-; LA64-LABEL: atomicrmw_uinc_wrap_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.w $a2, $a0, 0 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: .p2align 4, , 16 +-; LA64-NEXT: .LBB2_1: # %atomicrmw.start +-; LA64-NEXT: # =>This Loop Header: Depth=1 +-; LA64-NEXT: # Child Loop BB2_3 Depth 2 +-; LA64-NEXT: addi.w $a3, $a2, 0 +-; LA64-NEXT: sltu $a4, $a3, $a1 +-; LA64-NEXT: xori $a4, $a4, 1 +-; LA64-NEXT: addi.d $a2, $a2, 1 +-; LA64-NEXT: masknez $a4, $a2, $a4 +-; LA64-NEXT: .LBB2_3: # %atomicrmw.start +-; LA64-NEXT: # Parent Loop BB2_1 Depth=1 +-; LA64-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64-NEXT: ll.w $a2, $a0, 0 +-; LA64-NEXT: bne $a2, $a3, .LBB2_5 +-; LA64-NEXT: # %bb.4: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB2_3 Depth=2 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB2_3 +-; LA64-NEXT: b .LBB2_6 +-; LA64-NEXT: .LBB2_5: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB2_1 Depth=1 +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: .LBB2_6: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB2_1 Depth=1 +-; LA64-NEXT: bne $a2, $a3, .LBB2_1 +-; LA64-NEXT: # %bb.2: # %atomicrmw.end +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %result = atomicrmw uinc_wrap ptr %ptr, i32 %val seq_cst +- ret i32 %result +-} +- +-define i64 @atomicrmw_uinc_wrap_i64(ptr %ptr, i64 %val) { +-; LA64-LABEL: atomicrmw_uinc_wrap_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.d $a2, $a0, 0 +-; LA64-NEXT: .p2align 4, , 16 +-; LA64-NEXT: .LBB3_1: # %atomicrmw.start +-; LA64-NEXT: # =>This Loop Header: Depth=1 +-; LA64-NEXT: # Child Loop BB3_3 Depth 2 +-; LA64-NEXT: move $a3, $a2 +-; LA64-NEXT: sltu $a2, $a2, $a1 +-; LA64-NEXT: xori $a2, $a2, 1 +-; LA64-NEXT: addi.d $a4, $a3, 1 +-; LA64-NEXT: masknez $a4, $a4, $a2 +-; LA64-NEXT: .LBB3_3: # %atomicrmw.start +-; LA64-NEXT: # Parent Loop BB3_1 Depth=1 +-; LA64-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64-NEXT: ll.d $a2, $a0, 0 +-; LA64-NEXT: bne $a2, $a3, .LBB3_5 +-; LA64-NEXT: # %bb.4: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB3_3 Depth=2 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: sc.d $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB3_3 +-; LA64-NEXT: b .LBB3_6 +-; LA64-NEXT: .LBB3_5: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB3_1 Depth=1 +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: .LBB3_6: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB3_1 Depth=1 +-; LA64-NEXT: bne $a2, $a3, .LBB3_1 +-; LA64-NEXT: # %bb.2: # %atomicrmw.end +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %result = atomicrmw uinc_wrap ptr %ptr, i64 %val seq_cst +- ret i64 %result +-} +- +-define i8 @atomicrmw_udec_wrap_i8(ptr %ptr, i8 %val) { +-; LA64-LABEL: atomicrmw_udec_wrap_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: ld.w $a2, $a0, 0 +-; LA64-NEXT: ori $a4, $zero, 255 +-; LA64-NEXT: sll.w $a4, $a4, $a3 +-; LA64-NEXT: andi $a3, $a3, 24 +-; LA64-NEXT: nor $a4, $a4, $zero +-; LA64-NEXT: andi $a5, $a1, 255 +-; LA64-NEXT: .p2align 4, , 16 +-; LA64-NEXT: .LBB4_1: # %atomicrmw.start +-; LA64-NEXT: # =>This Loop Header: Depth=1 +-; LA64-NEXT: # Child Loop BB4_3 Depth 2 +-; LA64-NEXT: srl.w $a6, $a2, $a3 +-; LA64-NEXT: andi $a7, $a6, 255 +-; LA64-NEXT: sltu $t0, $a5, $a7 +-; LA64-NEXT: addi.d $a6, $a6, -1 +-; LA64-NEXT: masknez $a6, $a6, $t0 +-; LA64-NEXT: maskeqz $t0, $a1, $t0 +-; LA64-NEXT: or $a6, $t0, $a6 +-; LA64-NEXT: sltui $a7, $a7, 1 +-; LA64-NEXT: masknez $a6, $a6, $a7 +-; LA64-NEXT: maskeqz $a7, $a1, $a7 +-; LA64-NEXT: or $a6, $a7, $a6 +-; LA64-NEXT: andi $a6, $a6, 255 +-; LA64-NEXT: sll.w $a6, $a6, $a3 +-; LA64-NEXT: and $a7, $a2, $a4 +-; LA64-NEXT: or $a6, $a7, $a6 +-; LA64-NEXT: addi.w $a7, $a2, 0 +-; LA64-NEXT: .LBB4_3: # %atomicrmw.start +-; LA64-NEXT: # Parent Loop BB4_1 Depth=1 +-; LA64-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64-NEXT: ll.w $a2, $a0, 0 +-; LA64-NEXT: bne $a2, $a7, .LBB4_5 +-; LA64-NEXT: # %bb.4: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB4_3 Depth=2 +-; LA64-NEXT: move $t0, $a6 +-; LA64-NEXT: sc.w $t0, $a0, 0 +-; LA64-NEXT: beqz $t0, .LBB4_3 +-; LA64-NEXT: b .LBB4_6 +-; LA64-NEXT: .LBB4_5: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB4_1 Depth=1 +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: .LBB4_6: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB4_1 Depth=1 +-; LA64-NEXT: bne $a2, $a7, .LBB4_1 +-; LA64-NEXT: # %bb.2: # %atomicrmw.end +-; LA64-NEXT: srl.w $a0, $a2, $a3 +-; LA64-NEXT: ret +- %result = atomicrmw udec_wrap ptr %ptr, i8 %val seq_cst +- ret i8 %result +-} +- +-define i16 @atomicrmw_udec_wrap_i16(ptr %ptr, i16 %val) { +-; LA64-LABEL: atomicrmw_udec_wrap_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: ld.w $a2, $a0, 0 +-; LA64-NEXT: lu12i.w $a4, 15 +-; LA64-NEXT: ori $a4, $a4, 4095 +-; LA64-NEXT: sll.w $a4, $a4, $a3 +-; LA64-NEXT: andi $a3, $a3, 24 +-; LA64-NEXT: nor $a4, $a4, $zero +-; LA64-NEXT: bstrpick.d $a5, $a1, 15, 0 +-; LA64-NEXT: .p2align 4, , 16 +-; LA64-NEXT: .LBB5_1: # %atomicrmw.start +-; LA64-NEXT: # =>This Loop Header: Depth=1 +-; LA64-NEXT: # Child Loop BB5_3 Depth 2 +-; LA64-NEXT: srl.w $a6, $a2, $a3 +-; LA64-NEXT: bstrpick.d $a7, $a6, 15, 0 +-; LA64-NEXT: sltu $t0, $a5, $a7 +-; LA64-NEXT: addi.d $a6, $a6, -1 +-; LA64-NEXT: masknez $a6, $a6, $t0 +-; LA64-NEXT: maskeqz $t0, $a1, $t0 +-; LA64-NEXT: or $a6, $t0, $a6 +-; LA64-NEXT: sltui $a7, $a7, 1 +-; LA64-NEXT: masknez $a6, $a6, $a7 +-; LA64-NEXT: maskeqz $a7, $a1, $a7 +-; LA64-NEXT: or $a6, $a7, $a6 +-; LA64-NEXT: bstrpick.d $a6, $a6, 15, 0 +-; LA64-NEXT: sll.w $a6, $a6, $a3 +-; LA64-NEXT: and $a7, $a2, $a4 +-; LA64-NEXT: or $a6, $a7, $a6 +-; LA64-NEXT: addi.w $a7, $a2, 0 +-; LA64-NEXT: .LBB5_3: # %atomicrmw.start +-; LA64-NEXT: # Parent Loop BB5_1 Depth=1 +-; LA64-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64-NEXT: ll.w $a2, $a0, 0 +-; LA64-NEXT: bne $a2, $a7, .LBB5_5 +-; LA64-NEXT: # %bb.4: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB5_3 Depth=2 +-; LA64-NEXT: move $t0, $a6 +-; LA64-NEXT: sc.w $t0, $a0, 0 +-; LA64-NEXT: beqz $t0, .LBB5_3 +-; LA64-NEXT: b .LBB5_6 +-; LA64-NEXT: .LBB5_5: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB5_1 Depth=1 +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: .LBB5_6: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB5_1 Depth=1 +-; LA64-NEXT: bne $a2, $a7, .LBB5_1 +-; LA64-NEXT: # %bb.2: # %atomicrmw.end +-; LA64-NEXT: srl.w $a0, $a2, $a3 +-; LA64-NEXT: ret +- %result = atomicrmw udec_wrap ptr %ptr, i16 %val seq_cst +- ret i16 %result +-} +- +-define i32 @atomicrmw_udec_wrap_i32(ptr %ptr, i32 %val) { +-; LA64-LABEL: atomicrmw_udec_wrap_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.w $a2, $a0, 0 +-; LA64-NEXT: addi.w $a3, $a1, 0 +-; LA64-NEXT: .p2align 4, , 16 +-; LA64-NEXT: .LBB6_1: # %atomicrmw.start +-; LA64-NEXT: # =>This Loop Header: Depth=1 +-; LA64-NEXT: # Child Loop BB6_3 Depth 2 +-; LA64-NEXT: addi.w $a4, $a2, 0 +-; LA64-NEXT: sltu $a5, $a3, $a4 +-; LA64-NEXT: addi.d $a2, $a2, -1 +-; LA64-NEXT: masknez $a2, $a2, $a5 +-; LA64-NEXT: maskeqz $a5, $a1, $a5 +-; LA64-NEXT: or $a2, $a5, $a2 +-; LA64-NEXT: sltui $a5, $a4, 1 +-; LA64-NEXT: masknez $a2, $a2, $a5 +-; LA64-NEXT: maskeqz $a5, $a1, $a5 +-; LA64-NEXT: or $a5, $a5, $a2 +-; LA64-NEXT: .LBB6_3: # %atomicrmw.start +-; LA64-NEXT: # Parent Loop BB6_1 Depth=1 +-; LA64-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64-NEXT: ll.w $a2, $a0, 0 +-; LA64-NEXT: bne $a2, $a4, .LBB6_5 +-; LA64-NEXT: # %bb.4: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB6_3 Depth=2 +-; LA64-NEXT: move $a6, $a5 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB6_3 +-; LA64-NEXT: b .LBB6_6 +-; LA64-NEXT: .LBB6_5: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB6_1 Depth=1 +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: .LBB6_6: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB6_1 Depth=1 +-; LA64-NEXT: bne $a2, $a4, .LBB6_1 +-; LA64-NEXT: # %bb.2: # %atomicrmw.end +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %result = atomicrmw udec_wrap ptr %ptr, i32 %val seq_cst +- ret i32 %result +-} +- +-define i64 @atomicrmw_udec_wrap_i64(ptr %ptr, i64 %val) { +-; LA64-LABEL: atomicrmw_udec_wrap_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.d $a2, $a0, 0 +-; LA64-NEXT: .p2align 4, , 16 +-; LA64-NEXT: .LBB7_1: # %atomicrmw.start +-; LA64-NEXT: # =>This Loop Header: Depth=1 +-; LA64-NEXT: # Child Loop BB7_3 Depth 2 +-; LA64-NEXT: move $a3, $a2 +-; LA64-NEXT: sltu $a2, $a1, $a2 +-; LA64-NEXT: addi.d $a4, $a3, -1 +-; LA64-NEXT: masknez $a4, $a4, $a2 +-; LA64-NEXT: maskeqz $a2, $a1, $a2 +-; LA64-NEXT: or $a2, $a2, $a4 +-; LA64-NEXT: sltui $a4, $a3, 1 +-; LA64-NEXT: masknez $a2, $a2, $a4 +-; LA64-NEXT: maskeqz $a4, $a1, $a4 +-; LA64-NEXT: or $a4, $a4, $a2 +-; LA64-NEXT: .LBB7_3: # %atomicrmw.start +-; LA64-NEXT: # Parent Loop BB7_1 Depth=1 +-; LA64-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64-NEXT: ll.d $a2, $a0, 0 +-; LA64-NEXT: bne $a2, $a3, .LBB7_5 +-; LA64-NEXT: # %bb.4: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB7_3 Depth=2 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: sc.d $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB7_3 +-; LA64-NEXT: b .LBB7_6 +-; LA64-NEXT: .LBB7_5: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB7_1 Depth=1 +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: .LBB7_6: # %atomicrmw.start +-; LA64-NEXT: # in Loop: Header=BB7_1 Depth=1 +-; LA64-NEXT: bne $a2, $a3, .LBB7_1 +-; LA64-NEXT: # %bb.2: # %atomicrmw.end +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %result = atomicrmw udec_wrap ptr %ptr, i64 %val seq_cst +- ret i64 %result +-} +diff --git a/llvm/test/CodeGen/LoongArch/atomicrmw.ll b/llvm/test/CodeGen/LoongArch/atomicrmw.ll +new file mode 100644 +index 000000000..4732ec0fa +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/atomicrmw.ll +@@ -0,0 +1,3652 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s ++ ++define i8 @atomicrmw_xchg_i8_acquire(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_i8_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB0_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB0_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i8 %b acquire ++ ret i8 %1 ++} ++ ++define i8 @atomicrmw_xchg_0_i8_acquire(ptr %a) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_0_i8_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB1_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB1_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i8 0 acquire ++ ret i8 %1 ++} ++ ++define i8 @atomicrmw_xchg_minus_1_i8_acquire(ptr %a) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_minus_1_i8_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r5, $zero, -1 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB2_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB2_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i8 -1 acquire ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_xchg_i16_acquire(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_i16_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB3_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB3_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i16 %b acquire ++ ret i16 %1 ++} ++ ++define i16 @atomicrmw_xchg_0_i16_acquire(ptr %a) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_0_i16_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB4_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB4_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i16 0 acquire ++ ret i16 %1 ++} ++ ++define i16 @atomicrmw_xchg_minus_1_i16_acquire(ptr %a) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_minus_1_i16_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r5, $zero, -1 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB5_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB5_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i16 -1 acquire ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_xchg_i32_acquire(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_i32_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amswap_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i32 %b acquire ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_xchg_i64_acquire(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_i64_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amswap_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i64 %b acquire ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_add_i8_acquire(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_add_i8_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB8_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: add.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB8_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw add ptr %a, i8 %b acquire ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_add_i16_acquire(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_add_i16_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB9_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: add.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB9_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw add ptr %a, i16 %b acquire ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_add_i32_acquire(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_add_i32_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amadd_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw add ptr %a, i32 %b acquire ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_add_i64_acquire(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_add_i64_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amadd_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw add ptr %a, i64 %b acquire ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_sub_i8_acquire(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_sub_i8_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB12_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: sub.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB12_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw sub ptr %a, i8 %b acquire ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_sub_i16_acquire(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_sub_i16_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB13_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: sub.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB13_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw sub ptr %a, i16 %b acquire ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_sub_i32_acquire(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_sub_i32_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: sub.w $r7, $zero, $r6 ++; CHECK-NEXT: amadd_db.w $r5, $r7, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw sub ptr %a, i32 %b acquire ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_sub_i64_acquire(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_sub_i64_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: sub.d $r7, $zero, $r5 ++; CHECK-NEXT: amadd_db.d $r6, $r7, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw sub ptr %a, i64 %b acquire ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_nand_i8_acquire(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_nand_i8_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB16_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: nor $r11, $zero, $r11 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB16_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw nand ptr %a, i8 %b acquire ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_nand_i16_acquire(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_nand_i16_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB17_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: nor $r11, $zero, $r11 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB17_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw nand ptr %a, i16 %b acquire ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_nand_i32_acquire(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_nand_i32_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: .LBB18_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r5, $r4, 0 ++; CHECK-NEXT: and $r7, $r5, $r6 ++; CHECK-NEXT: nor $r7, $zero, $r7 ++; CHECK-NEXT: sc.w $r7, $r4, 0 ++; CHECK-NEXT: beq $r7, $zero, .LBB18_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw nand ptr %a, i32 %b acquire ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_nand_i64_acquire(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_nand_i64_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: .LBB19_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.d $r6, $r4, 0 ++; CHECK-NEXT: and $r7, $r6, $r5 ++; CHECK-NEXT: nor $r7, $zero, $r7 ++; CHECK-NEXT: sc.d $r7, $r4, 0 ++; CHECK-NEXT: beq $r7, $zero, .LBB19_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw nand ptr %a, i64 %b acquire ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_and_i8_acquire(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_and_i8_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB20_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB20_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw and ptr %a, i8 %b acquire ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_and_i16_acquire(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_and_i16_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB21_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB21_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw and ptr %a, i16 %b acquire ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_and_i32_acquire(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_and_i32_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amand_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw and ptr %a, i32 %b acquire ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_and_i64_acquire(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_and_i64_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amand_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw and ptr %a, i64 %b acquire ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_or_i8_acquire(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_or_i8_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB24_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: or $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB24_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw or ptr %a, i8 %b acquire ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_or_i16_acquire(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_or_i16_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB25_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: or $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB25_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw or ptr %a, i16 %b acquire ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_or_i32_acquire(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_or_i32_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amor_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw or ptr %a, i32 %b acquire ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_or_i64_acquire(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_or_i64_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amor_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw or ptr %a, i64 %b acquire ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_xor_i8_acquire(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xor_i8_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB28_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: xor $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB28_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xor ptr %a, i8 %b acquire ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_xor_i16_acquire(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xor_i16_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB29_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: xor $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB29_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xor ptr %a, i16 %b acquire ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_xor_i32_acquire(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xor_i32_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amxor_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xor ptr %a, i32 %b acquire ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_xor_i64_acquire(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xor_i64_acquire: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amxor_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xor ptr %a, i64 %b acquire ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_xchg_i8_release(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_i8_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB32_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB32_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i8 %b release ++ ret i8 %1 ++} ++ ++define i8 @atomicrmw_xchg_0_i8_release(ptr %a) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_0_i8_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB33_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB33_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i8 0 release ++ ret i8 %1 ++} ++ ++define i8 @atomicrmw_xchg_minus_1_i8_release(ptr %a) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_minus_1_i8_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r5, $zero, -1 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB34_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB34_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i8 -1 release ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_xchg_i16_release(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_i16_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB35_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB35_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i16 %b release ++ ret i16 %1 ++} ++ ++define i16 @atomicrmw_xchg_0_i16_release(ptr %a) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_0_i16_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB36_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB36_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i16 0 release ++ ret i16 %1 ++} ++ ++define i16 @atomicrmw_xchg_minus_1_i16_release(ptr %a) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_minus_1_i16_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r5, $zero, -1 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB37_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB37_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i16 -1 release ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_xchg_i32_release(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_i32_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amswap_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i32 %b release ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_xchg_i64_release(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_i64_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amswap_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i64 %b release ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_add_i8_release(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_add_i8_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB40_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: add.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB40_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw add ptr %a, i8 %b release ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_add_i16_release(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_add_i16_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB41_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: add.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB41_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw add ptr %a, i16 %b release ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_add_i32_release(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_add_i32_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amadd_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw add ptr %a, i32 %b release ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_add_i64_release(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_add_i64_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amadd_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw add ptr %a, i64 %b release ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_sub_i8_release(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_sub_i8_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB44_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: sub.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB44_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw sub ptr %a, i8 %b release ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_sub_i16_release(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_sub_i16_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB45_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: sub.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB45_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw sub ptr %a, i16 %b release ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_sub_i32_release(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_sub_i32_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: sub.w $r7, $zero, $r6 ++; CHECK-NEXT: amadd_db.w $r5, $r7, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw sub ptr %a, i32 %b release ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_sub_i64_release(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_sub_i64_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: sub.d $r7, $zero, $r5 ++; CHECK-NEXT: amadd_db.d $r6, $r7, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw sub ptr %a, i64 %b release ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_nand_i8_release(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_nand_i8_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB48_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: nor $r11, $zero, $r11 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB48_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw nand ptr %a, i8 %b release ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_nand_i16_release(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_nand_i16_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB49_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: nor $r11, $zero, $r11 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB49_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw nand ptr %a, i16 %b release ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_nand_i32_release(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_nand_i32_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: .LBB50_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r5, $r4, 0 ++; CHECK-NEXT: and $r7, $r5, $r6 ++; CHECK-NEXT: nor $r7, $zero, $r7 ++; CHECK-NEXT: sc.w $r7, $r4, 0 ++; CHECK-NEXT: beq $r7, $zero, .LBB50_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw nand ptr %a, i32 %b release ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_nand_i64_release(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_nand_i64_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: .LBB51_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.d $r6, $r4, 0 ++; CHECK-NEXT: and $r7, $r6, $r5 ++; CHECK-NEXT: nor $r7, $zero, $r7 ++; CHECK-NEXT: sc.d $r7, $r4, 0 ++; CHECK-NEXT: beq $r7, $zero, .LBB51_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw nand ptr %a, i64 %b release ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_and_i8_release(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_and_i8_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB52_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB52_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw and ptr %a, i8 %b release ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_and_i16_release(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_and_i16_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB53_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB53_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw and ptr %a, i16 %b release ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_and_i32_release(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_and_i32_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amand_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw and ptr %a, i32 %b release ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_and_i64_release(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_and_i64_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amand_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw and ptr %a, i64 %b release ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_or_i8_release(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_or_i8_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB56_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: or $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB56_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw or ptr %a, i8 %b release ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_or_i16_release(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_or_i16_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB57_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: or $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB57_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw or ptr %a, i16 %b release ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_or_i32_release(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_or_i32_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amor_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw or ptr %a, i32 %b release ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_or_i64_release(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_or_i64_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amor_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw or ptr %a, i64 %b release ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_xor_i8_release(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xor_i8_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB60_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: xor $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB60_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xor ptr %a, i8 %b release ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_xor_i16_release(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xor_i16_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB61_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: xor $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB61_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xor ptr %a, i16 %b release ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_xor_i32_release(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xor_i32_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amxor_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xor ptr %a, i32 %b release ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_xor_i64_release(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xor_i64_release: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amxor_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xor ptr %a, i64 %b release ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_xchg_i8_acq_rel(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_i8_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB64_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB64_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i8 %b acq_rel ++ ret i8 %1 ++} ++ ++define i8 @atomicrmw_xchg_0_i8_acq_rel(ptr %a) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_0_i8_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB65_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB65_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i8 0 acq_rel ++ ret i8 %1 ++} ++ ++define i8 @atomicrmw_xchg_minus_1_i8_acq_rel(ptr %a) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_minus_1_i8_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r5, $zero, -1 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB66_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB66_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i8 -1 acq_rel ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_xchg_i16_acq_rel(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_i16_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB67_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB67_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i16 %b acq_rel ++ ret i16 %1 ++} ++ ++define i16 @atomicrmw_xchg_0_i16_acq_rel(ptr %a) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_0_i16_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB68_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB68_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i16 0 acq_rel ++ ret i16 %1 ++} ++ ++define i16 @atomicrmw_xchg_minus_1_i16_acq_rel(ptr %a) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_minus_1_i16_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r5, $zero, -1 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB69_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB69_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i16 -1 acq_rel ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_xchg_i32_acq_rel(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_i32_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amswap_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i32 %b acq_rel ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_xchg_i64_acq_rel(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_i64_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amswap_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i64 %b acq_rel ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_add_i8_acq_rel(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_add_i8_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB72_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: add.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB72_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw add ptr %a, i8 %b acq_rel ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_add_i16_acq_rel(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_add_i16_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB73_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: add.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB73_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw add ptr %a, i16 %b acq_rel ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_add_i32_acq_rel(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_add_i32_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amadd_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw add ptr %a, i32 %b acq_rel ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_add_i64_acq_rel(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_add_i64_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amadd_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw add ptr %a, i64 %b acq_rel ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_sub_i8_acq_rel(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_sub_i8_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB76_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: sub.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB76_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw sub ptr %a, i8 %b acq_rel ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_sub_i16_acq_rel(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_sub_i16_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB77_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: sub.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB77_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw sub ptr %a, i16 %b acq_rel ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_sub_i32_acq_rel(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_sub_i32_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: sub.w $r7, $zero, $r6 ++; CHECK-NEXT: amadd_db.w $r5, $r7, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw sub ptr %a, i32 %b acq_rel ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_sub_i64_acq_rel(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_sub_i64_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: sub.d $r7, $zero, $r5 ++; CHECK-NEXT: amadd_db.d $r6, $r7, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw sub ptr %a, i64 %b acq_rel ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_nand_i8_acq_rel(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_nand_i8_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB80_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: nor $r11, $zero, $r11 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB80_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw nand ptr %a, i8 %b acq_rel ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_nand_i16_acq_rel(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_nand_i16_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB81_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: nor $r11, $zero, $r11 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB81_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw nand ptr %a, i16 %b acq_rel ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_nand_i32_acq_rel(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_nand_i32_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: .LBB82_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r5, $r4, 0 ++; CHECK-NEXT: and $r7, $r5, $r6 ++; CHECK-NEXT: nor $r7, $zero, $r7 ++; CHECK-NEXT: sc.w $r7, $r4, 0 ++; CHECK-NEXT: beq $r7, $zero, .LBB82_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw nand ptr %a, i32 %b acq_rel ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_nand_i64_acq_rel(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_nand_i64_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: .LBB83_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.d $r6, $r4, 0 ++; CHECK-NEXT: and $r7, $r6, $r5 ++; CHECK-NEXT: nor $r7, $zero, $r7 ++; CHECK-NEXT: sc.d $r7, $r4, 0 ++; CHECK-NEXT: beq $r7, $zero, .LBB83_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw nand ptr %a, i64 %b acq_rel ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_and_i8_acq_rel(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_and_i8_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB84_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB84_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw and ptr %a, i8 %b acq_rel ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_and_i16_acq_rel(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_and_i16_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB85_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB85_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw and ptr %a, i16 %b acq_rel ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_and_i32_acq_rel(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_and_i32_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amand_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw and ptr %a, i32 %b acq_rel ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_and_i64_acq_rel(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_and_i64_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amand_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw and ptr %a, i64 %b acq_rel ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_or_i8_acq_rel(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_or_i8_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB88_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: or $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB88_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw or ptr %a, i8 %b acq_rel ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_or_i16_acq_rel(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_or_i16_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB89_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: or $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB89_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw or ptr %a, i16 %b acq_rel ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_or_i32_acq_rel(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_or_i32_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amor_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw or ptr %a, i32 %b acq_rel ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_or_i64_acq_rel(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_or_i64_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amor_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw or ptr %a, i64 %b acq_rel ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_xor_i8_acq_rel(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xor_i8_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB92_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: xor $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB92_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xor ptr %a, i8 %b acq_rel ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_xor_i16_acq_rel(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xor_i16_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB93_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: xor $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB93_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xor ptr %a, i16 %b acq_rel ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_xor_i32_acq_rel(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xor_i32_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amxor_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xor ptr %a, i32 %b acq_rel ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_xor_i64_acq_rel(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xor_i64_acq_rel: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amxor_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xor ptr %a, i64 %b acq_rel ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_xchg_i8_seq_cst(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_i8_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB96_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB96_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i8 %b seq_cst ++ ret i8 %1 ++} ++ ++define i8 @atomicrmw_xchg_0_i8_seq_cst(ptr %a) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_0_i8_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB97_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB97_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i8 0 seq_cst ++ ret i8 %1 ++} ++ ++define i8 @atomicrmw_xchg_minus_1_i8_seq_cst(ptr %a) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_minus_1_i8_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r5, $zero, -1 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB98_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB98_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i8 -1 seq_cst ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_xchg_i16_seq_cst(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_i16_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB99_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB99_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i16 %b seq_cst ++ ret i16 %1 ++} ++ ++define i16 @atomicrmw_xchg_0_i16_seq_cst(ptr %a) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_0_i16_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB100_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB100_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i16 0 seq_cst ++ ret i16 %1 ++} ++ ++define i16 @atomicrmw_xchg_minus_1_i16_seq_cst(ptr %a) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_minus_1_i16_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r5, $zero, -1 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB101_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB101_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i16 -1 seq_cst ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_xchg_i32_seq_cst(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_i32_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amswap_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i32 %b seq_cst ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_xchg_i64_seq_cst(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_i64_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amswap_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i64 %b seq_cst ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_add_i8_seq_cst(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_add_i8_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB104_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: add.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB104_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw add ptr %a, i8 %b seq_cst ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_add_i16_seq_cst(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_add_i16_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB105_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: add.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB105_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw add ptr %a, i16 %b seq_cst ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_add_i32_seq_cst(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_add_i32_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amadd_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw add ptr %a, i32 %b seq_cst ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_add_i64_seq_cst(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_add_i64_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amadd_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw add ptr %a, i64 %b seq_cst ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_sub_i8_seq_cst(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_sub_i8_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB108_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: sub.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB108_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw sub ptr %a, i8 %b seq_cst ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_sub_i16_seq_cst(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_sub_i16_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB109_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: sub.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB109_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw sub ptr %a, i16 %b seq_cst ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_sub_i32_seq_cst(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_sub_i32_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: sub.w $r7, $zero, $r6 ++; CHECK-NEXT: amadd_db.w $r5, $r7, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw sub ptr %a, i32 %b seq_cst ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_sub_i64_seq_cst(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_sub_i64_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: sub.d $r7, $zero, $r5 ++; CHECK-NEXT: amadd_db.d $r6, $r7, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw sub ptr %a, i64 %b seq_cst ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_nand_i8_seq_cst(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_nand_i8_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB112_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: nor $r11, $zero, $r11 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB112_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw nand ptr %a, i8 %b seq_cst ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_nand_i16_seq_cst(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_nand_i16_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB113_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: nor $r11, $zero, $r11 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB113_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw nand ptr %a, i16 %b seq_cst ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_nand_i32_seq_cst(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_nand_i32_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: .LBB114_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r5, $r4, 0 ++; CHECK-NEXT: and $r7, $r5, $r6 ++; CHECK-NEXT: nor $r7, $zero, $r7 ++; CHECK-NEXT: sc.w $r7, $r4, 0 ++; CHECK-NEXT: beq $r7, $zero, .LBB114_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw nand ptr %a, i32 %b seq_cst ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_nand_i64_seq_cst(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_nand_i64_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: .LBB115_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.d $r6, $r4, 0 ++; CHECK-NEXT: and $r7, $r6, $r5 ++; CHECK-NEXT: nor $r7, $zero, $r7 ++; CHECK-NEXT: sc.d $r7, $r4, 0 ++; CHECK-NEXT: beq $r7, $zero, .LBB115_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw nand ptr %a, i64 %b seq_cst ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_and_i8_seq_cst(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_and_i8_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB116_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB116_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw and ptr %a, i8 %b seq_cst ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_and_i16_seq_cst(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_and_i16_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB117_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB117_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw and ptr %a, i16 %b seq_cst ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_and_i32_seq_cst(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_and_i32_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amand_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw and ptr %a, i32 %b seq_cst ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_and_i64_seq_cst(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_and_i64_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amand_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw and ptr %a, i64 %b seq_cst ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_or_i8_seq_cst(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_or_i8_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB120_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: or $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB120_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw or ptr %a, i8 %b seq_cst ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_or_i16_seq_cst(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_or_i16_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB121_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: or $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB121_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw or ptr %a, i16 %b seq_cst ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_or_i32_seq_cst(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_or_i32_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amor_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw or ptr %a, i32 %b seq_cst ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_or_i64_seq_cst(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_or_i64_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amor_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw or ptr %a, i64 %b seq_cst ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_xor_i8_seq_cst(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xor_i8_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB124_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: xor $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB124_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xor ptr %a, i8 %b seq_cst ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_xor_i16_seq_cst(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xor_i16_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB125_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: xor $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB125_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xor ptr %a, i16 %b seq_cst ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_xor_i32_seq_cst(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xor_i32_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amxor_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xor ptr %a, i32 %b seq_cst ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_xor_i64_seq_cst(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xor_i64_seq_cst: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amxor_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xor ptr %a, i64 %b seq_cst ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_xchg_i8_monotonic(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_i8_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB128_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB128_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i8 %b monotonic ++ ret i8 %1 ++} ++ ++define i8 @atomicrmw_xchg_0_i8_monotonic(ptr %a) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_0_i8_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB129_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB129_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i8 0 monotonic ++ ret i8 %1 ++} ++ ++define i8 @atomicrmw_xchg_minus_1_i8_monotonic(ptr %a) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_minus_1_i8_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r5, $zero, -1 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB130_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB130_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i8 -1 monotonic ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_xchg_i16_monotonic(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_i16_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB131_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB131_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i16 %b monotonic ++ ret i16 %1 ++} ++ ++define i16 @atomicrmw_xchg_0_i16_monotonic(ptr %a) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_0_i16_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r5, $zero, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB132_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB132_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i16 0 monotonic ++ ret i16 %1 ++} ++ ++define i16 @atomicrmw_xchg_minus_1_i16_monotonic(ptr %a) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_minus_1_i16_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r5, $zero, -1 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB133_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r5, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB133_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i16 -1 monotonic ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_xchg_i32_monotonic(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_i32_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amswap_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i32 %b monotonic ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_xchg_i64_monotonic(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xchg_i64_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amswap_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xchg ptr %a, i64 %b monotonic ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_add_i8_monotonic(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_add_i8_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB136_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: add.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB136_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw add ptr %a, i8 %b monotonic ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_add_i16_monotonic(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_add_i16_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB137_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: add.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB137_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw add ptr %a, i16 %b monotonic ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_add_i32_monotonic(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_add_i32_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amadd_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw add ptr %a, i32 %b monotonic ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_add_i64_monotonic(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_add_i64_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amadd_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw add ptr %a, i64 %b monotonic ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_sub_i8_monotonic(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_sub_i8_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB140_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: sub.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB140_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw sub ptr %a, i8 %b monotonic ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_sub_i16_monotonic(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_sub_i16_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB141_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: sub.w $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB141_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw sub ptr %a, i16 %b monotonic ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_sub_i32_monotonic(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_sub_i32_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: sub.w $r7, $zero, $r6 ++; CHECK-NEXT: amadd_db.w $r5, $r7, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw sub ptr %a, i32 %b monotonic ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_sub_i64_monotonic(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_sub_i64_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: sub.d $r7, $zero, $r5 ++; CHECK-NEXT: amadd_db.d $r6, $r7, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw sub ptr %a, i64 %b monotonic ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_nand_i8_monotonic(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_nand_i8_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB144_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: nor $r11, $zero, $r11 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB144_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw nand ptr %a, i8 %b monotonic ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_nand_i16_monotonic(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_nand_i16_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB145_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: nor $r11, $zero, $r11 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB145_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw nand ptr %a, i16 %b monotonic ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_nand_i32_monotonic(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_nand_i32_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: .LBB146_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r5, $r4, 0 ++; CHECK-NEXT: and $r7, $r5, $r6 ++; CHECK-NEXT: nor $r7, $zero, $r7 ++; CHECK-NEXT: sc.w $r7, $r4, 0 ++; CHECK-NEXT: beq $r7, $zero, .LBB146_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw nand ptr %a, i32 %b monotonic ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_nand_i64_monotonic(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_nand_i64_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: .LBB147_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.d $r6, $r4, 0 ++; CHECK-NEXT: and $r7, $r6, $r5 ++; CHECK-NEXT: nor $r7, $zero, $r7 ++; CHECK-NEXT: sc.d $r7, $r4, 0 ++; CHECK-NEXT: beq $r7, $zero, .LBB147_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw nand ptr %a, i64 %b monotonic ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_and_i8_monotonic(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_and_i8_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB148_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB148_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw and ptr %a, i8 %b monotonic ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_and_i16_monotonic(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_and_i16_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB149_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: and $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB149_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw and ptr %a, i16 %b monotonic ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_and_i32_monotonic(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_and_i32_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amand_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw and ptr %a, i32 %b monotonic ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_and_i64_monotonic(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_and_i64_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amand_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw and ptr %a, i64 %b monotonic ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_or_i8_monotonic(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_or_i8_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB152_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: or $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB152_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw or ptr %a, i8 %b monotonic ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_or_i16_monotonic(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_or_i16_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB153_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: or $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB153_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw or ptr %a, i16 %b monotonic ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_or_i32_monotonic(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_or_i32_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amor_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw or ptr %a, i32 %b monotonic ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_or_i64_monotonic(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_or_i64_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amor_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw or ptr %a, i64 %b monotonic ++ ret i64 %1 ++} ++ ++define i8 @atomicrmw_xor_i8_monotonic(ptr %a, i8 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xor_i8_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: ori $r4, $zero, 255 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB156_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: xor $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB156_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xor ptr %a, i8 %b monotonic ++ ret i8 %1 ++} ++ ++define i16 @atomicrmw_xor_i16_monotonic(ptr %a, i16 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xor_i16_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: addi.d $r6, $zero, -4 ++; CHECK-NEXT: and $r6, $r4, $r6 ++; CHECK-NEXT: andi $r4, $r4, 3 ++; CHECK-NEXT: slli.w $r7, $r4, 3 ++; CHECK-NEXT: lu12i.w $r4, 15 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: sll.w $r8, $r4, $r7 ++; CHECK-NEXT: nor $r9, $zero, $r8 ++; CHECK-NEXT: sll.w $r5, $r5, $r7 ++; CHECK-NEXT: .LBB157_1: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: ll.w $r10, $r6, 0 ++; CHECK-NEXT: xor $r11, $r10, $r5 ++; CHECK-NEXT: and $r11, $r11, $r8 ++; CHECK-NEXT: and $r12, $r10, $r9 ++; CHECK-NEXT: or $r12, $r12, $r11 ++; CHECK-NEXT: sc.w $r12, $r6, 0 ++; CHECK-NEXT: beq $r12, $zero, .LBB157_1 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: and $r4, $r10, $r8 ++; CHECK-NEXT: srl.w $r4, $r4, $r7 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: # %bb.3: ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xor ptr %a, i16 %b monotonic ++ ret i16 %1 ++} ++ ++define i32 @atomicrmw_xor_i32_monotonic(ptr %a, i32 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xor_i32_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r6, $r5, 0 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amxor_db.w $r5, $r6, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xor ptr %a, i32 %b monotonic ++ ret i32 %1 ++} ++ ++define i64 @atomicrmw_xor_i64_monotonic(ptr %a, i64 %b) nounwind { ++; CHECK-LABEL: atomicrmw_xor_i64_monotonic: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: amxor_db.d $r6, $r5, $r4, 0 ++; CHECK-NEXT: # %bb.2: ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++ %1 = atomicrmw xor ptr %a, i64 %b monotonic ++ ret i64 %1 ++} +diff --git a/llvm/test/CodeGen/LoongArch/bitreverse.ll b/llvm/test/CodeGen/LoongArch/bitreverse.ll +deleted file mode 100644 +index 259d8565c..000000000 +--- a/llvm/test/CodeGen/LoongArch/bitreverse.ll ++++ /dev/null +@@ -1,188 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --verify-machineinstrs < %s \ +-; RUN: | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s \ +-; RUN: | FileCheck %s --check-prefix=LA64 +- +-declare i7 @llvm.bitreverse.i7(i7) +-declare i8 @llvm.bitreverse.i8(i8) +-declare i16 @llvm.bitreverse.i16(i16) +-declare i24 @llvm.bitreverse.i24(i24) +-declare i32 @llvm.bitreverse.i32(i32) +-declare i48 @llvm.bitreverse.i48(i48) +-declare i64 @llvm.bitreverse.i64(i64) +-declare i77 @llvm.bitreverse.i77(i77) +-declare i128 @llvm.bitreverse.i128(i128) +- +-define i8 @test_bitreverse_i8(i8 %a) nounwind { +-; LA32-LABEL: test_bitreverse_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: bitrev.4b $a0, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_bitreverse_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: bitrev.4b $a0, $a0 +-; LA64-NEXT: ret +- %tmp = call i8 @llvm.bitreverse.i8(i8 %a) +- ret i8 %tmp +-} +- +-define i16 @test_bitreverse_i16(i16 %a) nounwind { +-; LA32-LABEL: test_bitreverse_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: bitrev.w $a0, $a0 +-; LA32-NEXT: srli.w $a0, $a0, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_bitreverse_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: bitrev.d $a0, $a0 +-; LA64-NEXT: srli.d $a0, $a0, 48 +-; LA64-NEXT: ret +- %tmp = call i16 @llvm.bitreverse.i16(i16 %a) +- ret i16 %tmp +-} +- +-define i32 @test_bitreverse_i32(i32 %a) nounwind { +-; LA32-LABEL: test_bitreverse_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: bitrev.w $a0, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_bitreverse_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: bitrev.w $a0, $a0 +-; LA64-NEXT: ret +- %tmp = call i32 @llvm.bitreverse.i32(i32 %a) +- ret i32 %tmp +-} +- +-define i64 @test_bitreverse_i64(i64 %a) nounwind { +-; LA32-LABEL: test_bitreverse_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: bitrev.w $a2, $a1 +-; LA32-NEXT: bitrev.w $a1, $a0 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_bitreverse_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: bitrev.d $a0, $a0 +-; LA64-NEXT: ret +- %tmp = call i64 @llvm.bitreverse.i64(i64 %a) +- ret i64 %tmp +-} +- +-;; Bitreverse on non-native integer widths. +- +-define i7 @test_bitreverse_i7(i7 %a) nounwind { +-; LA32-LABEL: test_bitreverse_i7: +-; LA32: # %bb.0: +-; LA32-NEXT: bitrev.w $a0, $a0 +-; LA32-NEXT: srli.w $a0, $a0, 25 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_bitreverse_i7: +-; LA64: # %bb.0: +-; LA64-NEXT: bitrev.d $a0, $a0 +-; LA64-NEXT: srli.d $a0, $a0, 57 +-; LA64-NEXT: ret +- %tmp = call i7 @llvm.bitreverse.i7(i7 %a) +- ret i7 %tmp +-} +- +-define i24 @test_bitreverse_i24(i24 %a) nounwind { +-; LA32-LABEL: test_bitreverse_i24: +-; LA32: # %bb.0: +-; LA32-NEXT: bitrev.w $a0, $a0 +-; LA32-NEXT: srli.w $a0, $a0, 8 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_bitreverse_i24: +-; LA64: # %bb.0: +-; LA64-NEXT: bitrev.d $a0, $a0 +-; LA64-NEXT: srli.d $a0, $a0, 40 +-; LA64-NEXT: ret +- %tmp = call i24 @llvm.bitreverse.i24(i24 %a) +- ret i24 %tmp +-} +- +-define i48 @test_bitreverse_i48(i48 %a) nounwind { +-; LA32-LABEL: test_bitreverse_i48: +-; LA32: # %bb.0: +-; LA32-NEXT: bitrev.w $a2, $a0 +-; LA32-NEXT: bitrev.w $a0, $a1 +-; LA32-NEXT: bytepick.w $a0, $a0, $a2, 2 +-; LA32-NEXT: srli.w $a1, $a2, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_bitreverse_i48: +-; LA64: # %bb.0: +-; LA64-NEXT: bitrev.d $a0, $a0 +-; LA64-NEXT: srli.d $a0, $a0, 16 +-; LA64-NEXT: ret +- %tmp = call i48 @llvm.bitreverse.i48(i48 %a) +- ret i48 %tmp +-} +- +-define i77 @test_bitreverse_i77(i77 %a) nounwind { +-; LA32-LABEL: test_bitreverse_i77: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a2, $a1, 0 +-; LA32-NEXT: bitrev.w $a2, $a2 +-; LA32-NEXT: ld.w $a3, $a1, 4 +-; LA32-NEXT: bitrev.w $a3, $a3 +-; LA32-NEXT: srli.w $a4, $a3, 19 +-; LA32-NEXT: slli.w $a5, $a2, 13 +-; LA32-NEXT: or $a4, $a5, $a4 +-; LA32-NEXT: srli.w $a2, $a2, 19 +-; LA32-NEXT: st.h $a2, $a0, 8 +-; LA32-NEXT: st.w $a4, $a0, 4 +-; LA32-NEXT: slli.w $a2, $a3, 13 +-; LA32-NEXT: ld.w $a1, $a1, 8 +-; LA32-NEXT: bitrev.w $a1, $a1 +-; LA32-NEXT: srli.w $a1, $a1, 19 +-; LA32-NEXT: or $a1, $a1, $a2 +-; LA32-NEXT: st.w $a1, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_bitreverse_i77: +-; LA64: # %bb.0: +-; LA64-NEXT: bitrev.d $a1, $a1 +-; LA64-NEXT: srli.d $a1, $a1, 51 +-; LA64-NEXT: bitrev.d $a2, $a0 +-; LA64-NEXT: slli.d $a0, $a2, 13 +-; LA64-NEXT: or $a0, $a1, $a0 +-; LA64-NEXT: srli.d $a1, $a2, 51 +-; LA64-NEXT: ret +- %tmp = call i77 @llvm.bitreverse.i77(i77 %a) +- ret i77 %tmp +-} +- +-define i128 @test_bitreverse_i128(i128 %a) nounwind { +-; LA32-LABEL: test_bitreverse_i128: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a2, $a1, 0 +-; LA32-NEXT: bitrev.w $a2, $a2 +-; LA32-NEXT: st.w $a2, $a0, 12 +-; LA32-NEXT: ld.w $a2, $a1, 4 +-; LA32-NEXT: bitrev.w $a2, $a2 +-; LA32-NEXT: st.w $a2, $a0, 8 +-; LA32-NEXT: ld.w $a2, $a1, 8 +-; LA32-NEXT: bitrev.w $a2, $a2 +-; LA32-NEXT: st.w $a2, $a0, 4 +-; LA32-NEXT: ld.w $a1, $a1, 12 +-; LA32-NEXT: bitrev.w $a1, $a1 +-; LA32-NEXT: st.w $a1, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_bitreverse_i128: +-; LA64: # %bb.0: +-; LA64-NEXT: bitrev.d $a2, $a1 +-; LA64-NEXT: bitrev.d $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %tmp = call i128 @llvm.bitreverse.i128(i128 %a) +- ret i128 %tmp +-} +diff --git a/llvm/test/CodeGen/LoongArch/block-address.ll b/llvm/test/CodeGen/LoongArch/block-address.ll +deleted file mode 100644 +index 63d310dd9..000000000 +--- a/llvm/test/CodeGen/LoongArch/block-address.ll ++++ /dev/null +@@ -1,39 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-@addr = dso_local global ptr null +- +-define void @test_blockaddress() nounwind { +-; LA32-LABEL: test_blockaddress: +-; LA32: # %bb.0: +-; LA32-NEXT: pcalau12i $a0, %pc_hi20(addr) +-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(addr) +-; LA32-NEXT: pcalau12i $a1, %pc_hi20(.Ltmp0) +-; LA32-NEXT: addi.w $a1, $a1, %pc_lo12(.Ltmp0) +-; LA32-NEXT: st.w $a1, $a0, 0 +-; LA32-NEXT: ld.w $a0, $a0, 0 +-; LA32-NEXT: jr $a0 +-; LA32-NEXT: .Ltmp0: # Block address taken +-; LA32-NEXT: .LBB0_1: # %block +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_blockaddress: +-; LA64: # %bb.0: +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(addr) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(addr) +-; LA64-NEXT: pcalau12i $a1, %pc_hi20(.Ltmp0) +-; LA64-NEXT: addi.d $a1, $a1, %pc_lo12(.Ltmp0) +-; LA64-NEXT: st.d $a1, $a0, 0 +-; LA64-NEXT: ld.d $a0, $a0, 0 +-; LA64-NEXT: jr $a0 +-; LA64-NEXT: .Ltmp0: # Block address taken +-; LA64-NEXT: .LBB0_1: # %block +-; LA64-NEXT: ret +- store volatile ptr blockaddress(@test_blockaddress, %block), ptr @addr +- %val = load volatile ptr, ptr @addr +- indirectbr ptr %val, [label %block] +- +-block: +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/blockaddress-symbol.ll b/llvm/test/CodeGen/LoongArch/blockaddress-symbol.ll +deleted file mode 100644 +index d07092230..000000000 +--- a/llvm/test/CodeGen/LoongArch/blockaddress-symbol.ll ++++ /dev/null +@@ -1,25 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s +-; RUN: llc --mtriple=loongarch32 --no-integrated-as < %s | FileCheck %s +-; RUN: llc --mtriple=loongarch64 --no-integrated-as < %s | FileCheck %s +- +-;; This regression test is for ensuring the AsmParser does not use the +-;; getOrCreateSymbol interface to create blockaddress symbols. +-;; Otherwise incorrect symbols will be created: +-;; `.Ltmp0` -> `.Ltmp00`. +- +-define void @operand_block_address() nounwind { +-; CHECK-LABEL: operand_block_address: +-; CHECK: # %bb.0: +-; CHECK-NEXT: #APP +-; CHECK-NEXT: b .Ltmp0 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: .Ltmp0: # Block address taken +-; CHECK-NEXT: # %bb.1: # %bb +-; CHECK-NEXT: ret +- call void asm sideeffect "b $0", "i"(ptr blockaddress(@operand_block_address, %bb)) +- br label %bb +-bb: +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/bnez-beqz.ll b/llvm/test/CodeGen/LoongArch/bnez-beqz.ll +deleted file mode 100644 +index d1652c73c..000000000 +--- a/llvm/test/CodeGen/LoongArch/bnez-beqz.ll ++++ /dev/null +@@ -1,119 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-declare void @bar() +- +-define void @bnez_i32(i32 signext %0) nounwind { +-; LA32-LABEL: bnez_i32: +-; LA32: # %bb.0: # %start +-; LA32-NEXT: beqz $a0, .LBB0_2 +-; LA32-NEXT: # %bb.1: # %f +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB0_2: # %t +-; LA32-NEXT: b %plt(bar) +-; +-; LA64-LABEL: bnez_i32: +-; LA64: # %bb.0: # %start +-; LA64-NEXT: beqz $a0, .LBB0_2 +-; LA64-NEXT: # %bb.1: # %f +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB0_2: # %t +-; LA64-NEXT: b %plt(bar) +-start: +- %1 = icmp eq i32 %0, 0 +- br i1 %1, label %t, label %f +- +-t: +- tail call void @bar() +- br label %f +- +-f: +- ret void +-} +- +-define void @beqz_i32(i32 signext %0) nounwind { +-; LA32-LABEL: beqz_i32: +-; LA32: # %bb.0: # %start +-; LA32-NEXT: beqz $a0, .LBB1_2 +-; LA32-NEXT: # %bb.1: # %t +-; LA32-NEXT: b %plt(bar) +-; LA32-NEXT: .LBB1_2: # %f +-; LA32-NEXT: ret +-; +-; LA64-LABEL: beqz_i32: +-; LA64: # %bb.0: # %start +-; LA64-NEXT: beqz $a0, .LBB1_2 +-; LA64-NEXT: # %bb.1: # %t +-; LA64-NEXT: b %plt(bar) +-; LA64-NEXT: .LBB1_2: # %f +-; LA64-NEXT: ret +-start: +- %1 = icmp ne i32 %0, 0 +- br i1 %1, label %t, label %f +- +-t: +- tail call void @bar() +- br label %f +- +-f: +- ret void +-} +- +-define void @bnez_i64(i64 %0) nounwind { +-; LA32-LABEL: bnez_i64: +-; LA32: # %bb.0: # %start +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: beqz $a0, .LBB2_2 +-; LA32-NEXT: # %bb.1: # %f +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB2_2: # %t +-; LA32-NEXT: b %plt(bar) +-; +-; LA64-LABEL: bnez_i64: +-; LA64: # %bb.0: # %start +-; LA64-NEXT: beqz $a0, .LBB2_2 +-; LA64-NEXT: # %bb.1: # %f +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB2_2: # %t +-; LA64-NEXT: b %plt(bar) +-start: +- %1 = icmp eq i64 %0, 0 +- br i1 %1, label %t, label %f +- +-t: +- tail call void @bar() +- br label %f +- +-f: +- ret void +-} +- +-define void @beqz_i64(i64 %0) nounwind { +-; LA32-LABEL: beqz_i64: +-; LA32: # %bb.0: # %start +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: beqz $a0, .LBB3_2 +-; LA32-NEXT: # %bb.1: # %t +-; LA32-NEXT: b %plt(bar) +-; LA32-NEXT: .LBB3_2: # %f +-; LA32-NEXT: ret +-; +-; LA64-LABEL: beqz_i64: +-; LA64: # %bb.0: # %start +-; LA64-NEXT: beqz $a0, .LBB3_2 +-; LA64-NEXT: # %bb.1: # %t +-; LA64-NEXT: b %plt(bar) +-; LA64-NEXT: .LBB3_2: # %f +-; LA64-NEXT: ret +-start: +- %1 = icmp ne i64 %0, 0 +- br i1 %1, label %t, label %f +- +-t: +- tail call void @bar() +- br label %f +- +-f: +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/branch-relaxation-spill-32.ll b/llvm/test/CodeGen/LoongArch/branch-relaxation-spill-32.ll +deleted file mode 100644 +index 1ed938631..000000000 +--- a/llvm/test/CodeGen/LoongArch/branch-relaxation-spill-32.ll ++++ /dev/null +@@ -1,313 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --filetype=obj --verify-machineinstrs < %s \ +-; RUN: -o /dev/null 2>&1 +-; RUN: llc --mtriple=loongarch32 --verify-machineinstrs < %s | FileCheck %s +- +-define void @relax_b28_spill() { +-; CHECK-LABEL: relax_b28_spill: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.w $sp, $sp, -48 +-; CHECK-NEXT: .cfi_def_cfa_offset 48 +-; CHECK-NEXT: st.w $ra, $sp, 44 # 4-byte Folded Spill +-; CHECK-NEXT: st.w $fp, $sp, 40 # 4-byte Folded Spill +-; CHECK-NEXT: st.w $s0, $sp, 36 # 4-byte Folded Spill +-; CHECK-NEXT: st.w $s1, $sp, 32 # 4-byte Folded Spill +-; CHECK-NEXT: st.w $s2, $sp, 28 # 4-byte Folded Spill +-; CHECK-NEXT: st.w $s3, $sp, 24 # 4-byte Folded Spill +-; CHECK-NEXT: st.w $s4, $sp, 20 # 4-byte Folded Spill +-; CHECK-NEXT: st.w $s5, $sp, 16 # 4-byte Folded Spill +-; CHECK-NEXT: st.w $s6, $sp, 12 # 4-byte Folded Spill +-; CHECK-NEXT: st.w $s7, $sp, 8 # 4-byte Folded Spill +-; CHECK-NEXT: st.w $s8, $sp, 4 # 4-byte Folded Spill +-; CHECK-NEXT: .cfi_offset 1, -4 +-; CHECK-NEXT: .cfi_offset 22, -8 +-; CHECK-NEXT: .cfi_offset 23, -12 +-; CHECK-NEXT: .cfi_offset 24, -16 +-; CHECK-NEXT: .cfi_offset 25, -20 +-; CHECK-NEXT: .cfi_offset 26, -24 +-; CHECK-NEXT: .cfi_offset 27, -28 +-; CHECK-NEXT: .cfi_offset 28, -32 +-; CHECK-NEXT: .cfi_offset 29, -36 +-; CHECK-NEXT: .cfi_offset 30, -40 +-; CHECK-NEXT: .cfi_offset 31, -44 +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $zero, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $ra, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $tp, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $a0, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $a1, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $a2, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $a3, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $a4, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $a5, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $a6, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $a7, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $t0, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $t1, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $t2, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $t3, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $t4, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $t5, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $t6, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $t7, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $t8, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $fp, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $s0, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $s1, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $s2, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $s3, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $s4, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $s5, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $s6, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $s7, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $s8, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: beq $s7, $s8, .LBB0_1 +-; CHECK-NEXT: # %bb.4: +-; CHECK-NEXT: st.w $t8, $sp, 0 +-; CHECK-NEXT: pcalau12i $t8, %pc_hi20(.LBB0_5) +-; CHECK-NEXT: addi.w $t8, $t8, %pc_lo12(.LBB0_5) +-; CHECK-NEXT: jr $t8 +-; CHECK-NEXT: .LBB0_1: # %iftrue +-; CHECK-NEXT: #APP +-; CHECK-NEXT: .space 536870912 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: b .LBB0_3 +-; CHECK-NEXT: .LBB0_5: # %iffalse +-; CHECK-NEXT: ld.w $t8, $sp, 0 +-; CHECK-NEXT: # %bb.2: # %iffalse +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $zero +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $ra +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $tp +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $a0 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $a1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $a2 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $a3 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $a4 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $a5 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $a6 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $a7 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $t0 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $t1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $t2 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $t3 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $t4 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $t5 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $t6 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $t7 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $t8 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $fp +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $s0 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $s1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $s2 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $s3 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $s4 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $s5 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $s6 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $s7 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $s8 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: .LBB0_3: # %iftrue +-; CHECK-NEXT: ld.w $s8, $sp, 4 # 4-byte Folded Reload +-; CHECK-NEXT: ld.w $s7, $sp, 8 # 4-byte Folded Reload +-; CHECK-NEXT: ld.w $s6, $sp, 12 # 4-byte Folded Reload +-; CHECK-NEXT: ld.w $s5, $sp, 16 # 4-byte Folded Reload +-; CHECK-NEXT: ld.w $s4, $sp, 20 # 4-byte Folded Reload +-; CHECK-NEXT: ld.w $s3, $sp, 24 # 4-byte Folded Reload +-; CHECK-NEXT: ld.w $s2, $sp, 28 # 4-byte Folded Reload +-; CHECK-NEXT: ld.w $s1, $sp, 32 # 4-byte Folded Reload +-; CHECK-NEXT: ld.w $s0, $sp, 36 # 4-byte Folded Reload +-; CHECK-NEXT: ld.w $fp, $sp, 40 # 4-byte Folded Reload +-; CHECK-NEXT: ld.w $ra, $sp, 44 # 4-byte Folded Reload +-; CHECK-NEXT: addi.w $sp, $sp, 48 +-; CHECK-NEXT: ret +- %zero = call i32 asm sideeffect "addi.w $$zero, $$zero, 1", "={r0}"() +- %ra = call i32 asm sideeffect "addi.w $$ra, $$zero, 1", "={r1}"() +- %tp = call i32 asm sideeffect "addi.w $$tp, $$zero, 1", "={r2}"() +- %a0 = call i32 asm sideeffect "addi.w $$a0, $$zero, 1", "={r4}"() +- %a1 = call i32 asm sideeffect "addi.w $$a1, $$zero, 1", "={r5}"() +- %a2 = call i32 asm sideeffect "addi.w $$a2, $$zero, 1", "={r6}"() +- %a3 = call i32 asm sideeffect "addi.w $$a3, $$zero, 1", "={r7}"() +- %a4 = call i32 asm sideeffect "addi.w $$a4, $$zero, 1", "={r8}"() +- %a5 = call i32 asm sideeffect "addi.w $$a5, $$zero, 1", "={r9}"() +- %a6 = call i32 asm sideeffect "addi.w $$a6, $$zero, 1", "={r10}"() +- %a7 = call i32 asm sideeffect "addi.w $$a7, $$zero, 1", "={r11}"() +- %t0 = call i32 asm sideeffect "addi.w $$t0, $$zero, 1", "={r12}"() +- %t1 = call i32 asm sideeffect "addi.w $$t1, $$zero, 1", "={r13}"() +- %t2 = call i32 asm sideeffect "addi.w $$t2, $$zero, 1", "={r14}"() +- %t3 = call i32 asm sideeffect "addi.w $$t3, $$zero, 1", "={r15}"() +- %t4 = call i32 asm sideeffect "addi.w $$t4, $$zero, 1", "={r16}"() +- %t5 = call i32 asm sideeffect "addi.w $$t5, $$zero, 1", "={r17}"() +- %t6 = call i32 asm sideeffect "addi.w $$t6, $$zero, 1", "={r18}"() +- %t7 = call i32 asm sideeffect "addi.w $$t7, $$zero, 1", "={r19}"() +- %t8 = call i32 asm sideeffect "addi.w $$t8, $$zero, 1", "={r20}"() +- ;; r21 Reserved (Non-allocatable) +- %s9 = call i32 asm sideeffect "addi.w $$s9, $$zero, 1", "={r22}"() +- %s0 = call i32 asm sideeffect "addi.w $$s0, $$zero, 1", "={r23}"() +- %s1 = call i32 asm sideeffect "addi.w $$s1, $$zero, 1", "={r24}"() +- %s2 = call i32 asm sideeffect "addi.w $$s2, $$zero, 1", "={r25}"() +- %s3 = call i32 asm sideeffect "addi.w $$s3, $$zero, 1", "={r26}"() +- %s4 = call i32 asm sideeffect "addi.w $$s4, $$zero, 1", "={r27}"() +- %s5 = call i32 asm sideeffect "addi.w $$s5, $$zero, 1", "={r28}"() +- %s6 = call i32 asm sideeffect "addi.w $$s6, $$zero, 1", "={r29}"() +- %s7 = call i32 asm sideeffect "addi.w $$s7, $$zero, 1", "={r30}"() +- %s8 = call i32 asm sideeffect "addi.w $$s8, $$zero, 1", "={r31}"() +- +- %cmp = icmp eq i32 %s7, %s8 +- br i1 %cmp, label %iftrue, label %iffalse +- +-iftrue: +- call void asm sideeffect ".space 536870912", ""() +- ret void +- +-iffalse: +- call void asm sideeffect "# reg use $0", "{r0}"(i32 %zero) +- call void asm sideeffect "# reg use $0", "{r1}"(i32 %ra) +- call void asm sideeffect "# reg use $0", "{r2}"(i32 %tp) +- call void asm sideeffect "# reg use $0", "{r4}"(i32 %a0) +- call void asm sideeffect "# reg use $0", "{r5}"(i32 %a1) +- call void asm sideeffect "# reg use $0", "{r6}"(i32 %a2) +- call void asm sideeffect "# reg use $0", "{r7}"(i32 %a3) +- call void asm sideeffect "# reg use $0", "{r8}"(i32 %a4) +- call void asm sideeffect "# reg use $0", "{r9}"(i32 %a5) +- call void asm sideeffect "# reg use $0", "{r10}"(i32 %a6) +- call void asm sideeffect "# reg use $0", "{r11}"(i32 %a7) +- call void asm sideeffect "# reg use $0", "{r12}"(i32 %t0) +- call void asm sideeffect "# reg use $0", "{r13}"(i32 %t1) +- call void asm sideeffect "# reg use $0", "{r14}"(i32 %t2) +- call void asm sideeffect "# reg use $0", "{r15}"(i32 %t3) +- call void asm sideeffect "# reg use $0", "{r16}"(i32 %t4) +- call void asm sideeffect "# reg use $0", "{r17}"(i32 %t5) +- call void asm sideeffect "# reg use $0", "{r18}"(i32 %t6) +- call void asm sideeffect "# reg use $0", "{r19}"(i32 %t7) +- call void asm sideeffect "# reg use $0", "{r20}"(i32 %t8) +- ;; r21 Reserved (Non-allocatable) +- call void asm sideeffect "# reg use $0", "{r22}"(i32 %s9) +- call void asm sideeffect "# reg use $0", "{r23}"(i32 %s0) +- call void asm sideeffect "# reg use $0", "{r24}"(i32 %s1) +- call void asm sideeffect "# reg use $0", "{r25}"(i32 %s2) +- call void asm sideeffect "# reg use $0", "{r26}"(i32 %s3) +- call void asm sideeffect "# reg use $0", "{r27}"(i32 %s4) +- call void asm sideeffect "# reg use $0", "{r28}"(i32 %s5) +- call void asm sideeffect "# reg use $0", "{r29}"(i32 %s6) +- call void asm sideeffect "# reg use $0", "{r30}"(i32 %s7) +- call void asm sideeffect "# reg use $0", "{r31}"(i32 %s8) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/branch-relaxation-spill-64.ll b/llvm/test/CodeGen/LoongArch/branch-relaxation-spill-64.ll +deleted file mode 100644 +index 1c4ef48a9..000000000 +--- a/llvm/test/CodeGen/LoongArch/branch-relaxation-spill-64.ll ++++ /dev/null +@@ -1,313 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --filetype=obj --verify-machineinstrs < %s \ +-; RUN: -o /dev/null 2>&1 +-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s | FileCheck %s +- +-define void @relax_b28_spill() { +-; CHECK-LABEL: relax_b28_spill: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -96 +-; CHECK-NEXT: .cfi_def_cfa_offset 96 +-; CHECK-NEXT: st.d $ra, $sp, 88 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $fp, $sp, 80 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $s0, $sp, 72 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $s1, $sp, 64 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $s2, $sp, 56 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $s3, $sp, 48 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $s4, $sp, 40 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $s5, $sp, 32 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $s6, $sp, 24 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $s7, $sp, 16 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $s8, $sp, 8 # 8-byte Folded Spill +-; CHECK-NEXT: .cfi_offset 1, -8 +-; CHECK-NEXT: .cfi_offset 22, -16 +-; CHECK-NEXT: .cfi_offset 23, -24 +-; CHECK-NEXT: .cfi_offset 24, -32 +-; CHECK-NEXT: .cfi_offset 25, -40 +-; CHECK-NEXT: .cfi_offset 26, -48 +-; CHECK-NEXT: .cfi_offset 27, -56 +-; CHECK-NEXT: .cfi_offset 28, -64 +-; CHECK-NEXT: .cfi_offset 29, -72 +-; CHECK-NEXT: .cfi_offset 30, -80 +-; CHECK-NEXT: .cfi_offset 31, -88 +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $zero, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $ra, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $tp, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $a0, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $a1, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $a2, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $a3, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $a4, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $a5, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $a6, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $a7, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $t0, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $t1, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $t2, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $t3, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $t4, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $t5, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $t6, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $t7, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $t8, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $fp, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $s0, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $s1, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $s2, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $s3, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $s4, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $s5, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $s6, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $s7, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.d $s8, $zero, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: beq $s7, $s8, .LBB0_1 +-; CHECK-NEXT: # %bb.4: +-; CHECK-NEXT: st.d $t8, $sp, 0 +-; CHECK-NEXT: pcalau12i $t8, %pc_hi20(.LBB0_5) +-; CHECK-NEXT: addi.d $t8, $t8, %pc_lo12(.LBB0_5) +-; CHECK-NEXT: jr $t8 +-; CHECK-NEXT: .LBB0_1: # %iftrue +-; CHECK-NEXT: #APP +-; CHECK-NEXT: .space 536870912 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: b .LBB0_3 +-; CHECK-NEXT: .LBB0_5: # %iffalse +-; CHECK-NEXT: ld.d $t8, $sp, 0 +-; CHECK-NEXT: # %bb.2: # %iffalse +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $zero +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $ra +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $tp +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $a0 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $a1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $a2 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $a3 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $a4 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $a5 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $a6 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $a7 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $t0 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $t1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $t2 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $t3 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $t4 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $t5 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $t6 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $t7 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $t8 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $fp +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $s0 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $s1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $s2 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $s3 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $s4 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $s5 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $s6 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $s7 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: # reg use $s8 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: .LBB0_3: # %iftrue +-; CHECK-NEXT: ld.d $s8, $sp, 8 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $s7, $sp, 16 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $s6, $sp, 24 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $s5, $sp, 32 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $s4, $sp, 40 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $s3, $sp, 48 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $s2, $sp, 56 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $s1, $sp, 64 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $s0, $sp, 72 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $fp, $sp, 80 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $ra, $sp, 88 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 96 +-; CHECK-NEXT: ret +- %zero = call i64 asm sideeffect "addi.d $$zero, $$zero, 1", "={r0}"() +- %ra = call i64 asm sideeffect "addi.d $$ra, $$zero, 1", "={r1}"() +- %tp = call i64 asm sideeffect "addi.d $$tp, $$zero, 1", "={r2}"() +- %a0 = call i64 asm sideeffect "addi.d $$a0, $$zero, 1", "={r4}"() +- %a1 = call i64 asm sideeffect "addi.d $$a1, $$zero, 1", "={r5}"() +- %a2 = call i64 asm sideeffect "addi.d $$a2, $$zero, 1", "={r6}"() +- %a3 = call i64 asm sideeffect "addi.d $$a3, $$zero, 1", "={r7}"() +- %a4 = call i64 asm sideeffect "addi.d $$a4, $$zero, 1", "={r8}"() +- %a5 = call i64 asm sideeffect "addi.d $$a5, $$zero, 1", "={r9}"() +- %a6 = call i64 asm sideeffect "addi.d $$a6, $$zero, 1", "={r10}"() +- %a7 = call i64 asm sideeffect "addi.d $$a7, $$zero, 1", "={r11}"() +- %t0 = call i64 asm sideeffect "addi.d $$t0, $$zero, 1", "={r12}"() +- %t1 = call i64 asm sideeffect "addi.d $$t1, $$zero, 1", "={r13}"() +- %t2 = call i64 asm sideeffect "addi.d $$t2, $$zero, 1", "={r14}"() +- %t3 = call i64 asm sideeffect "addi.d $$t3, $$zero, 1", "={r15}"() +- %t4 = call i64 asm sideeffect "addi.d $$t4, $$zero, 1", "={r16}"() +- %t5 = call i64 asm sideeffect "addi.d $$t5, $$zero, 1", "={r17}"() +- %t6 = call i64 asm sideeffect "addi.d $$t6, $$zero, 1", "={r18}"() +- %t7 = call i64 asm sideeffect "addi.d $$t7, $$zero, 1", "={r19}"() +- %t8 = call i64 asm sideeffect "addi.d $$t8, $$zero, 1", "={r20}"() +- ;; r21 Reserved (Non-allocatable) +- %s9 = call i64 asm sideeffect "addi.d $$s9, $$zero, 1", "={r22}"() +- %s0 = call i64 asm sideeffect "addi.d $$s0, $$zero, 1", "={r23}"() +- %s1 = call i64 asm sideeffect "addi.d $$s1, $$zero, 1", "={r24}"() +- %s2 = call i64 asm sideeffect "addi.d $$s2, $$zero, 1", "={r25}"() +- %s3 = call i64 asm sideeffect "addi.d $$s3, $$zero, 1", "={r26}"() +- %s4 = call i64 asm sideeffect "addi.d $$s4, $$zero, 1", "={r27}"() +- %s5 = call i64 asm sideeffect "addi.d $$s5, $$zero, 1", "={r28}"() +- %s6 = call i64 asm sideeffect "addi.d $$s6, $$zero, 1", "={r29}"() +- %s7 = call i64 asm sideeffect "addi.d $$s7, $$zero, 1", "={r30}"() +- %s8 = call i64 asm sideeffect "addi.d $$s8, $$zero, 1", "={r31}"() +- +- %cmp = icmp eq i64 %s7, %s8 +- br i1 %cmp, label %iftrue, label %iffalse +- +-iftrue: +- call void asm sideeffect ".space 536870912", ""() +- ret void +- +-iffalse: +- call void asm sideeffect "# reg use $0", "{r0}"(i64 %zero) +- call void asm sideeffect "# reg use $0", "{r1}"(i64 %ra) +- call void asm sideeffect "# reg use $0", "{r2}"(i64 %tp) +- call void asm sideeffect "# reg use $0", "{r4}"(i64 %a0) +- call void asm sideeffect "# reg use $0", "{r5}"(i64 %a1) +- call void asm sideeffect "# reg use $0", "{r6}"(i64 %a2) +- call void asm sideeffect "# reg use $0", "{r7}"(i64 %a3) +- call void asm sideeffect "# reg use $0", "{r8}"(i64 %a4) +- call void asm sideeffect "# reg use $0", "{r9}"(i64 %a5) +- call void asm sideeffect "# reg use $0", "{r10}"(i64 %a6) +- call void asm sideeffect "# reg use $0", "{r11}"(i64 %a7) +- call void asm sideeffect "# reg use $0", "{r12}"(i64 %t0) +- call void asm sideeffect "# reg use $0", "{r13}"(i64 %t1) +- call void asm sideeffect "# reg use $0", "{r14}"(i64 %t2) +- call void asm sideeffect "# reg use $0", "{r15}"(i64 %t3) +- call void asm sideeffect "# reg use $0", "{r16}"(i64 %t4) +- call void asm sideeffect "# reg use $0", "{r17}"(i64 %t5) +- call void asm sideeffect "# reg use $0", "{r18}"(i64 %t6) +- call void asm sideeffect "# reg use $0", "{r19}"(i64 %t7) +- call void asm sideeffect "# reg use $0", "{r20}"(i64 %t8) +- ;; r21 Reserved (Non-allocatable) +- call void asm sideeffect "# reg use $0", "{r22}"(i64 %s9) +- call void asm sideeffect "# reg use $0", "{r23}"(i64 %s0) +- call void asm sideeffect "# reg use $0", "{r24}"(i64 %s1) +- call void asm sideeffect "# reg use $0", "{r25}"(i64 %s2) +- call void asm sideeffect "# reg use $0", "{r26}"(i64 %s3) +- call void asm sideeffect "# reg use $0", "{r27}"(i64 %s4) +- call void asm sideeffect "# reg use $0", "{r28}"(i64 %s5) +- call void asm sideeffect "# reg use $0", "{r29}"(i64 %s6) +- call void asm sideeffect "# reg use $0", "{r30}"(i64 %s7) +- call void asm sideeffect "# reg use $0", "{r31}"(i64 %s8) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/branch-relaxation.ll b/llvm/test/CodeGen/LoongArch/branch-relaxation.ll +deleted file mode 100644 +index 7d064ddcf..000000000 +--- a/llvm/test/CodeGen/LoongArch/branch-relaxation.ll ++++ /dev/null +@@ -1,140 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --filetype=obj --verify-machineinstrs < %s \ +-; RUN: -o /dev/null 2>&1 +-; RUN: llc --mtriple=loongarch64 --filetype=obj --verify-machineinstrs < %s \ +-; RUN: -o /dev/null 2>&1 +-; RUN: llc --mtriple=loongarch32 --verify-machineinstrs < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s | FileCheck %s --check-prefix=LA64 +- +-define i32 @relax_b18(i32 signext %a, i32 signext %b) { +-; LA32-LABEL: relax_b18: +-; LA32: # %bb.0: +-; LA32-NEXT: beq $a0, $a1, .LBB0_1 +-; LA32-NEXT: b .LBB0_2 +-; LA32-NEXT: .LBB0_1: # %iftrue +-; LA32-NEXT: #APP +-; LA32-NEXT: .space 1048576 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ori $a0, $zero, 1 +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB0_2: # %iffalse +-; LA32-NEXT: move $a0, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: relax_b18: +-; LA64: # %bb.0: +-; LA64-NEXT: beq $a0, $a1, .LBB0_1 +-; LA64-NEXT: b .LBB0_2 +-; LA64-NEXT: .LBB0_1: # %iftrue +-; LA64-NEXT: #APP +-; LA64-NEXT: .space 1048576 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ori $a0, $zero, 1 +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB0_2: # %iffalse +-; LA64-NEXT: move $a0, $zero +-; LA64-NEXT: ret +- %cond = icmp eq i32 %a, %b +- br i1 %cond, label %iftrue, label %iffalse +- +-iftrue: +- call void asm sideeffect ".space 1048576", ""() +- ret i32 1 +- +-iffalse: +- ret i32 0 +-} +- +-define i32 @relax_b23(i1 %a) { +-; LA32-LABEL: relax_b23: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a0, $a0, 1 +-; LA32-NEXT: bnez $a0, .LBB1_1 +-; LA32-NEXT: b .LBB1_2 +-; LA32-NEXT: .LBB1_1: # %iftrue +-; LA32-NEXT: #APP +-; LA32-NEXT: .space 16777216 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ori $a0, $zero, 1 +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB1_2: # %iffalse +-; LA32-NEXT: move $a0, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: relax_b23: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 1 +-; LA64-NEXT: bnez $a0, .LBB1_1 +-; LA64-NEXT: b .LBB1_2 +-; LA64-NEXT: .LBB1_1: # %iftrue +-; LA64-NEXT: #APP +-; LA64-NEXT: .space 16777216 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ori $a0, $zero, 1 +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB1_2: # %iffalse +-; LA64-NEXT: move $a0, $zero +-; LA64-NEXT: ret +- br i1 %a, label %iftrue, label %iffalse +- +-iftrue: +- call void asm sideeffect ".space 16777216", ""() +- ret i32 1 +- +-iffalse: +- ret i32 0 +-} +- +-define i32 @relax_b28(i1 %a) { +-; LA32-LABEL: relax_b28: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: andi $a0, $a0, 1 +-; LA32-NEXT: bnez $a0, .LBB2_1 +-; LA32-NEXT: # %bb.3: +-; LA32-NEXT: pcalau12i $a0, %pc_hi20(.LBB2_2) +-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(.LBB2_2) +-; LA32-NEXT: jr $a0 +-; LA32-NEXT: .LBB2_1: # %iftrue +-; LA32-NEXT: #APP +-; LA32-NEXT: .space 536870912 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ori $a0, $zero, 1 +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB2_2: # %iffalse +-; LA32-NEXT: move $a0, $zero +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: relax_b28: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: .cfi_def_cfa_offset 16 +-; LA64-NEXT: andi $a0, $a0, 1 +-; LA64-NEXT: bnez $a0, .LBB2_1 +-; LA64-NEXT: # %bb.3: +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(.LBB2_2) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(.LBB2_2) +-; LA64-NEXT: jr $a0 +-; LA64-NEXT: .LBB2_1: # %iftrue +-; LA64-NEXT: #APP +-; LA64-NEXT: .space 536870912 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ori $a0, $zero, 1 +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB2_2: # %iffalse +-; LA64-NEXT: move $a0, $zero +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- br i1 %a, label %iftrue, label %iffalse +- +-iftrue: +- call void asm sideeffect ".space 536870912", ""() +- ret i32 1 +- +-iffalse: +- ret i32 0 +-} +diff --git a/llvm/test/CodeGen/LoongArch/bss.ll b/llvm/test/CodeGen/LoongArch/bss.ll +new file mode 100644 +index 000000000..cfc30b3a7 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/bss.ll +@@ -0,0 +1,5 @@ ++; RUN: llc -march=loongarch64 -o - %s | FileCheck %s ++ ++; CHECK: .section .bss,"aw",@nobits ++; CHECK: .globl a ++@a = global i32 0, align 4 +diff --git a/llvm/test/CodeGen/LoongArch/bstrins_d.ll b/llvm/test/CodeGen/LoongArch/bstrins_d.ll +index fe1f6270f..819bfdbb3 100644 +--- a/llvm/test/CodeGen/LoongArch/bstrins_d.ll ++++ b/llvm/test/CodeGen/LoongArch/bstrins_d.ll +@@ -1,207 +1,53 @@ + ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s +- +-;; Test generation of the bstrins.d instruction. +-;; There are 8 patterns that can be matched to bstrins.d. See performORCombine +-;; for details. +- +-;; Pattern 1 +-;; R = or (and X, mask0), (and (shl Y, lsb), mask1) +-;; => +-;; R = BSTRINS X, Y, msb, lsb +-define i64 @pat1(i64 %a, i64 %b) nounwind { +-; CHECK-LABEL: pat1: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrins.d $a0, $a1, 39, 16 +-; CHECK-NEXT: ret +- %and1 = and i64 %a, -1099511562241 ; 0xffffff000000ffff +- %shl = shl i64 %b, 16 +- %and2 = and i64 %shl, 1099511562240 ; 0x000000ffffff0000 +- %or = or i64 %and1, %and2 +- ret i64 %or +-} +- +-define i64 @pat1_swap(i64 %a, i64 %b) nounwind { +-; CHECK-LABEL: pat1_swap: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrins.d $a0, $a1, 39, 16 +-; CHECK-NEXT: ret +- %and1 = and i64 %a, -1099511562241 ; 0xffffff000000ffff +- %shl = shl i64 %b, 16 +- %and2 = and i64 %shl, 1099511562240 ; 0x000000ffffff0000 +- %or = or i64 %and2, %and1 +- ret i64 %or +-} +- +-;; Pattern 2 +-;; R = or (and X, mask0), (shl (and Y, mask1), lsb) +-;; => +-;; R = BSTRINS X, Y, msb, lsb +-define i64 @pat2(i64 %a, i64 %b) nounwind { +-; CHECK-LABEL: pat2: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrins.d $a0, $a1, 39, 16 +-; CHECK-NEXT: ret +- %and1 = and i64 %a, -1099511562241 ; 0xffffff000000ffff +- %and2 = and i64 %b, 16777215 ; 0x0000000000ffffff +- %shl = shl i64 %and2, 16 +- %or = or i64 %and1, %shl +- ret i64 %or +-} +- +-define i64 @pat2_swap(i64 %a, i64 %b) nounwind { +-; CHECK-LABEL: pat2_swap: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrins.d $a0, $a1, 39, 16 +-; CHECK-NEXT: ret +- %and1 = and i64 %a, -1099511562241 ; 0xffffff000000ffff +- %and2 = and i64 %b, 16777215 ; 0x0000000000ffffff +- %shl = shl i64 %and2, 16 +- %or = or i64 %shl, %and1 +- ret i64 %or +-} +- +-;; Pattern 3 +-;; R = or (and X, mask0), (and Y, mask1) +-;; => +-;; R = BSTRINS X, (srl (and Y, mask1), lsb), msb, lsb +-define i64 @pat3(i64 %a, i64 %b) nounwind { +-; CHECK-LABEL: pat3: +-; CHECK: # %bb.0: +-; CHECK-NEXT: andi $a1, $a1, 288 +-; CHECK-NEXT: srli.d $a1, $a1, 4 +-; CHECK-NEXT: bstrins.d $a0, $a1, 11, 4 +-; CHECK-NEXT: ret +- %and1 = and i64 %a, -4081 ; 0xfffffffffffff00f +- %and2 = and i64 %b, 288 ; 0x0000000000000120 +- %or = or i64 %and1, %and2 +- ret i64 %or +-} +- +-define i64 @pat3_swap(i64 %a, i64 %b) nounwind { +-; CHECK-LABEL: pat3_swap: +-; CHECK: # %bb.0: +-; CHECK-NEXT: andi $a1, $a1, 288 +-; CHECK-NEXT: srli.d $a1, $a1, 4 +-; CHECK-NEXT: bstrins.d $a0, $a1, 11, 4 +-; CHECK-NEXT: ret +- %and1 = and i64 %a, -4081 ; 0xfffffffffffff00f +- %and2 = and i64 %b, 288 ; 0x0000000000000120 +- %or = or i64 %and2, %and1 +- ret i64 %or +-} +- +-;; Pattern 4 +-;; R = or (and X, mask), (shl Y, shamt) +-;; => +-;; R = BSTRINS X, Y, 63, shamt +-define i64 @pat4(i64 %a, i64 %b) nounwind { +-; CHECK-LABEL: pat4: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrins.d $a0, $a1, 63, 8 +-; CHECK-NEXT: ret +- %and = and i64 %a, 255 +- %shl = shl i64 %b, 8 ++; RUN: llc -mtriple=loongarch64 -o - %s | FileCheck %s ++ ++define void @bstrinsd_63_27(i64* nocapture %d) nounwind { ++; CHECK-LABEL: bstrinsd_63_27: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: ld.d $r5, $r4, 0 ++; CHECK-NEXT: addi.d $r6, $zero, 123 ++; CHECK-NEXT: bstrins.d $r5, $r6, 63, 27 ++; CHECK-NEXT: st.d $r5, $r4, 0 ++; CHECK-NEXT: jr $ra ++entry: ++ %tmp = load i64, i64* %d, align 8 ++ %and5 = and i64 %tmp, 134217727 ++ %or = or i64 %and5, 16508780544 ++ store i64 %or, i64* %d, align 8 ++ ret void ++} ++ ++define void @bstrinsd_33_28(i64* nocapture %d) nounwind { ++; CHECK-LABEL: bstrinsd_33_28: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: ld.d $r5, $r4, 0 ++; CHECK-NEXT: addi.d $r6, $zero, 4 ++; CHECK-NEXT: bstrins.d $r5, $r6, 33, 28 ++; CHECK-NEXT: st.d $r5, $r4, 0 ++; CHECK-NEXT: jr $ra ++entry: ++ %tmp = load i64, i64* %d, align 8 ++ %and5 = and i64 %tmp, -16911433729 ++ %or = or i64 %and5, 1073741824 ++ store i64 %or, i64* %d, align 8 ++ ret void ++} ++ ++define void @bstrinsd_49_34(i64* nocapture %d) nounwind { ++; CHECK-LABEL: bstrinsd_49_34: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: ld.d $r5, $r4, 0 ++; CHECK-NEXT: srli.d $r6, $r5, 50 ++; CHECK-NEXT: bstrins.d $r5, $r6, 49, 34 ++; CHECK-NEXT: st.d $r5, $r4, 0 ++; CHECK-NEXT: jr $ra ++entry: ++ %tmp0 = load i64, i64* %d, align 8 ++ %lshr = lshr i64 %tmp0, 50 ++ %tmp1 = load i64, i64* %d, align 8 ++ %shl = shl nuw nsw i64 %lshr, 34 ++ %and = and i64 %tmp1, -1125882726973441 + %or = or i64 %and, %shl +- ret i64 %or +-} +- +-define i64 @pat4_swap(i64 %a, i64 %b) nounwind { +-; CHECK-LABEL: pat4_swap: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrins.d $a0, $a1, 63, 8 +-; CHECK-NEXT: ret +- %and = and i64 %a, 255 +- %shl = shl i64 %b, 8 +- %or = or i64 %shl, %and +- ret i64 %or +-} +- +-;; Pattern 5 +-;; R = or (and X, mask0), const +-;; => +-;; R = BSTRINS X, (const >> lsb), msb, lsb +-define i64 @pat5(i64 %a) nounwind { +-; CHECK-LABEL: pat5: +-; CHECK: # %bb.0: +-; CHECK-NEXT: lu12i.w $a1, 74565 +-; CHECK-NEXT: ori $a1, $a1, 1656 +-; CHECK-NEXT: bstrins.d $a0, $a1, 47, 16 +-; CHECK-NEXT: ret +- %and = and i64 %a, 18446462598732906495 ; 0xffff00000000ffff +- %or = or i64 %and, 20015998304256 ; 0x0000123456780000 +- ret i64 %or +-} +- +-;; Pattern 6: a = b | ((c & mask) << shamt) +-;; In this testcase b is 0x123456000000789a, but in fact we do not require b +-;; being a constant. As long as all positions in b to be overwritten by the +-;; incoming bits are known to be zero, the pattern could be matched. +-define i64 @pat6(i64 %c) nounwind { +-; CHECK-LABEL: pat6: +-; CHECK: # %bb.0: +-; CHECK-NEXT: lu12i.w $a1, 7 +-; CHECK-NEXT: ori $a1, $a1, 2202 +-; CHECK-NEXT: lu32i.d $a1, 284160 +-; CHECK-NEXT: lu52i.d $a1, $a1, 291 +-; CHECK-NEXT: bstrins.d $a1, $a0, 39, 16 +-; CHECK-NEXT: move $a0, $a1 +-; CHECK-NEXT: ret +- %and = and i64 %c, 16777215 ; 0x0000000000ffffff +- %shl = shl i64 %and, 16 +- %or = or i64 %shl, 1311767949471676570 ; 0x123456000000789a +- ret i64 %or +-} +- +-;; Pattern 7: a = b | ((c << shamt) & shifted_mask) +-;; Similar to pattern 6. +-define i64 @pat7(i64 %c) nounwind { +-; CHECK-LABEL: pat7: +-; CHECK: # %bb.0: +-; CHECK-NEXT: lu12i.w $a1, 7 +-; CHECK-NEXT: ori $a1, $a1, 2202 +-; CHECK-NEXT: lu32i.d $a1, 284160 +-; CHECK-NEXT: lu52i.d $a1, $a1, 291 +-; CHECK-NEXT: bstrins.d $a1, $a0, 39, 16 +-; CHECK-NEXT: move $a0, $a1 +-; CHECK-NEXT: ret +- %shl = shl i64 %c, 16 +- %and = and i64 %shl, 1099511562240 ; 0x000000ffffff0000 +- %or = or i64 %and, 1311767949471676570 ; 0x123456000000789a +- ret i64 %or +-} +- +-;; Pattern 8: a = b | (c & shifted_mask) +-;; Similar to pattern 7 but without shift to c. +-define i64 @pat8(i64 %c) nounwind { +-; CHECK-LABEL: pat8: +-; CHECK: # %bb.0: +-; CHECK-NEXT: srli.d $a1, $a0, 16 +-; CHECK-NEXT: lu12i.w $a0, 7 +-; CHECK-NEXT: ori $a0, $a0, 2202 +-; CHECK-NEXT: lu32i.d $a0, 284160 +-; CHECK-NEXT: lu52i.d $a0, $a0, 291 +-; CHECK-NEXT: bstrins.d $a0, $a1, 39, 16 +-; CHECK-NEXT: ret +- %and = and i64 %c, 1099511562240 ; 0x000000ffffff0000 +- %or = or i64 %and, 1311767949471676570 ; 0x123456000000789a +- ret i64 %or +-} +- +-;; Test that bstrins.d is not generated because constant OR operand +-;; doesn't fit into bits cleared by constant AND operand. +-define i64 @no_bstrins_d(i64 %a) nounwind { +-; CHECK-LABEL: no_bstrins_d: +-; CHECK: # %bb.0: +-; CHECK-NEXT: lu12i.w $a1, 354185 +-; CHECK-NEXT: lu32i.d $a1, 4660 +-; CHECK-NEXT: or $a0, $a0, $a1 +-; CHECK-NEXT: lu12i.w $a1, 354191 +-; CHECK-NEXT: ori $a1, $a1, 4095 +-; CHECK-NEXT: lu32i.d $a1, -60876 +-; CHECK-NEXT: and $a0, $a0, $a1 +-; CHECK-NEXT: ret +- %and = and i64 %a, 18446462598732906495 ; 0xffff00000000ffff +- %or = or i64 %and, 20015998341120 ; 0x0000123456789000 +- ret i64 %or ++ store i64 %or, i64* %d, align 8 ++ ret void + } +diff --git a/llvm/test/CodeGen/LoongArch/bstrins_w.ll b/llvm/test/CodeGen/LoongArch/bstrins_w.ll +index e008caaca..3b62a760e 100644 +--- a/llvm/test/CodeGen/LoongArch/bstrins_w.ll ++++ b/llvm/test/CodeGen/LoongArch/bstrins_w.ll +@@ -1,225 +1,28 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s +- +-;; Test generation of the bstrins.w instruction. +-;; There are 8 patterns that can be matched to bstrins.w. See performORCombine +-;; for details. +- +-;; Pattern 1 +-;; R = or (and X, mask0), (and (shl Y, lsb), mask1) +-;; => +-;; R = BSTRINS X, Y, msb, lsb +-define i32 @pat1(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: pat1: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrins.w $a0, $a1, 19, 8 +-; CHECK-NEXT: ret +- %and1 = and i32 %a, -1048321 ; 0xfff000ff +- %shl = shl i32 %b, 8 +- %and2 = and i32 %shl, 1048320 ; 0x000fff00 +- %or = or i32 %and1, %and2 +- ret i32 %or +-} +- +-define i32 @pat1_swap(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: pat1_swap: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrins.w $a0, $a1, 19, 8 +-; CHECK-NEXT: ret +- %and1 = and i32 %a, -1048321 ; 0xfff000ff +- %shl = shl i32 %b, 8 +- %and2 = and i32 %shl, 1048320 ; 0x000fff00 +- %or = or i32 %and2, %and1 +- ret i32 %or +-} +- +-;; Pattern 2 +-;; R = or (and X, mask0), (shl (and Y, mask1), lsb) +-;; => +-;; R = BSTRINS X, Y, msb, lsb +-define i32 @pat2(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: pat2: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrins.w $a0, $a1, 19, 8 +-; CHECK-NEXT: ret +- %and1 = and i32 %a, -1048321 ; 0xfff000ff +- %and2 = and i32 %b, 4095 ; 0x00000fff +- %shl = shl i32 %and2, 8 +- %or = or i32 %and1, %shl +- ret i32 %or +-} +- +-define i32 @pat2_swap(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: pat2_swap: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrins.w $a0, $a1, 19, 8 +-; CHECK-NEXT: ret +- %and1 = and i32 %a, -1048321 ; 0xfff000ff +- %and2 = and i32 %b, 4095 ; 0x00000fff +- %shl = shl i32 %and2, 8 +- %or = or i32 %shl, %and1 +- ret i32 %or +-} +- +-;; Pattern 3 +-;; R = or (and X, mask0), (and Y, mask1) +-;; => +-;; R = BSTRINS X, (srl (and Y, mask1), lsb), msb, lsb +-define i32 @pat3(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: pat3: +-; CHECK: # %bb.0: +-; CHECK-NEXT: andi $a1, $a1, 288 +-; CHECK-NEXT: srli.w $a1, $a1, 4 +-; CHECK-NEXT: bstrins.w $a0, $a1, 11, 4 +-; CHECK-NEXT: ret +- %and1 = and i32 %a, -4081 ; 0xfffff00f +- %and2 = and i32 %b, 288 ; 0x00000120 +- %or = or i32 %and1, %and2 +- ret i32 %or +-} +- +-define i32 @pat3_swap(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: pat3_swap: +-; CHECK: # %bb.0: +-; CHECK-NEXT: andi $a1, $a1, 288 +-; CHECK-NEXT: srli.w $a1, $a1, 4 +-; CHECK-NEXT: bstrins.w $a0, $a1, 11, 4 +-; CHECK-NEXT: ret +- %and1 = and i32 %a, -4081 ; 0xfffff00f +- %and2 = and i32 %b, 288 ; 0x00000120 +- %or = or i32 %and2, %and1 +- ret i32 %or +-} +- +-define i32 @pat3_positive_mask0(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: pat3_positive_mask0: +-; CHECK: # %bb.0: +-; CHECK-NEXT: srli.w $a1, $a1, 28 +-; CHECK-NEXT: bstrins.w $a0, $a1, 31, 28 +-; CHECK-NEXT: ret +- %and1 = and i32 %a, 268435455 ; 0x0fffffff +- %and2 = and i32 %b, 4026531840 ; 0xf0000000 +- %or = or i32 %and1, %and2 +- ret i32 %or +-} +- +-;; Pattern 4 +-;; R = or (and X, mask), (shl Y, shamt) +-;; => +-;; R = BSTRINS X, Y, 31, shamt +-define i32 @pat4(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: pat4: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrins.w $a0, $a1, 31, 28 +-; CHECK-NEXT: ret +- %and = and i32 %a, 268435455 ; 0x0fffffff +- %shl = shl i32 %b, 28 +- %or = or i32 %and, %shl +- ret i32 %or +-} +- +-define i32 @pat4_swap(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: pat4_swap: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrins.w $a0, $a1, 31, 28 +-; CHECK-NEXT: ret +- %and = and i32 %a, 268435455 ; 0x0fffffff +- %shl = shl i32 %b, 28 +- %or = or i32 %shl, %and +- ret i32 %or +-} +- +-;; Pattern 5 +-;; R = or (and X, mask), const +-;; => +-;; R = BSTRINS X, (const >> lsb), msb, lsb +-define i32 @pat5(i32 %a) nounwind { +-; CHECK-LABEL: pat5: +-; CHECK: # %bb.0: +-; CHECK-NEXT: lu12i.w $a1, 1 +-; CHECK-NEXT: ori $a1, $a1, 564 +-; CHECK-NEXT: bstrins.w $a0, $a1, 23, 8 +-; CHECK-NEXT: ret +- %and = and i32 %a, 4278190335 ; 0xff0000ff +- %or = or i32 %and, 1192960 ; 0x00123400 +- ret i32 %or +-} +- +-;; The high bits of `const` are zero. +-define i32 @pat5_high_zeros(i32 %a) nounwind { +-; CHECK-LABEL: pat5_high_zeros: +-; CHECK: # %bb.0: +-; CHECK-NEXT: lu12i.w $a1, 1 +-; CHECK-NEXT: ori $a1, $a1, 564 +-; CHECK-NEXT: bstrins.w $a0, $a1, 31, 16 +-; CHECK-NEXT: ret +- %and = and i32 %a, 65535 ; 0x0000ffff +- %or = or i32 %and, 305397760 ; 0x12340000 +- ret i32 %or +-} +- +-;; Pattern 6: a = b | ((c & mask) << shamt) +-;; In this testcase b is 0x10000002, but in fact we do not require b being a +-;; constant. As long as all positions in b to be overwritten by the incoming +-;; bits are known to be zero, the pattern could be matched. +-define i32 @pat6(i32 %c) nounwind { +-; CHECK-LABEL: pat6: +-; CHECK: # %bb.0: +-; CHECK-NEXT: lu12i.w $a1, 65536 +-; CHECK-NEXT: ori $a1, $a1, 2 +-; CHECK-NEXT: bstrins.w $a1, $a0, 27, 4 +-; CHECK-NEXT: move $a0, $a1 +-; CHECK-NEXT: ret +- %and = and i32 %c, 16777215 ; 0x00ffffff +- %shl = shl i32 %and, 4 +- %or = or i32 %shl, 268435458 ; 0x10000002 +- ret i32 %or +-} +- +-;; Pattern 7: a = b | ((c << shamt) & shifted_mask) +-;; Similar to pattern 6. +-define i32 @pat7(i32 %c) nounwind { +-; CHECK-LABEL: pat7: +-; CHECK: # %bb.0: +-; CHECK-NEXT: lu12i.w $a1, 65536 +-; CHECK-NEXT: ori $a1, $a1, 2 +-; CHECK-NEXT: bstrins.w $a1, $a0, 27, 4 +-; CHECK-NEXT: move $a0, $a1 +-; CHECK-NEXT: ret +- %shl = shl i32 %c, 4 +- %and = and i32 %shl, 268435440 ; 0x0ffffff0 +- %or = or i32 %and, 268435458 ; 0x10000002 +- ret i32 %or +-} +- +-;; Pattern 8: a = b | (c & shifted_mask) +-;; Similar to pattern 7 but without shift to c. +-define i32 @pat8(i32 %c) nounwind { +-; CHECK-LABEL: pat8: +-; CHECK: # %bb.0: +-; CHECK-NEXT: srli.w $a1, $a0, 4 +-; CHECK-NEXT: lu12i.w $a0, 65536 +-; CHECK-NEXT: ori $a0, $a0, 2 +-; CHECK-NEXT: bstrins.w $a0, $a1, 27, 4 +-; CHECK-NEXT: ret +- %and = and i32 %c, 268435440 ; 0x0ffffff0 +- %or = or i32 %and, 268435458 ; 0x10000002 +- ret i32 %or +-} +- +-;; Test that bstrins.w is not generated because constant OR operand +-;; doesn't fit into bits cleared by constant AND operand. +-define i32 @no_bstrins_w(i32 %a) nounwind { +-; CHECK-LABEL: no_bstrins_w: +-; CHECK: # %bb.0: +-; CHECK-NEXT: lu12i.w $a1, 291 +-; CHECK-NEXT: ori $a1, $a1, 1104 +-; CHECK-NEXT: or $a0, $a0, $a1 +-; CHECK-NEXT: lu12i.w $a1, -3805 +-; CHECK-NEXT: ori $a1, $a1, 1279 +-; CHECK-NEXT: and $a0, $a0, $a1 +-; CHECK-NEXT: ret +- %and = and i32 %a, 4278190335 ; 0xff0000ff +- %or = or i32 %and, 1193040 ; 0x00123450 +- ret i32 %or ++; RUN: llc -march=loongarch64 -o - %s | FileCheck %s ++ ++define void @bstrins_w(i32 %s, i32* nocapture %d) nounwind { ++; CHECK-LABEL: bstrins_w: ++; CHECK: bstrins.w $r[[REG2:[0-9]+]], $r[[REG1:[0-9]+]], 13, 5 ++entry: ++ %and = shl i32 %s, 5 ++ %shl = and i32 %and, 16352 ++ %tmp3 = load i32, i32* %d, align 4 ++ %and5 = and i32 %tmp3, -16353 ++ %or = or i32 %and5, %shl ++ store i32 %or, i32* %d, align 4 ++ ret void ++} ++ ++define i32 @no_bstrinsw(i32* nocapture %d) { ++; CHECK-LABEL: no_bstrinsw: ++; CHECK: addi.w $r[[REG2:[0-9]+]], $zero, -4 ++; CHECK: and $r[[REG1:[0-9]+]], $r[[REG1:[0-9]+]], $r[[REG2:[0-9]+]] ++; CHECK: ori $r[[REG2:[0-9]+]], $r[[REG1:[0-9]+]], 8 ++; CHECK-NOT: bstrins.w {{[[:space:]].*}} ++entry: ++ %tmp = load volatile i32, i32* %d, align 4 ++ %and = and i32 %tmp, -4 ++ %or = or i32 %and, 8 ++ store volatile i32 %or, i32* %d, align 4 ++ ret i32 %and + } +diff --git a/llvm/test/CodeGen/LoongArch/bstrpick_d.ll b/llvm/test/CodeGen/LoongArch/bstrpick_d.ll +index e93c1391d..e1169cb21 100644 +--- a/llvm/test/CodeGen/LoongArch/bstrpick_d.ll ++++ b/llvm/test/CodeGen/LoongArch/bstrpick_d.ll +@@ -1,98 +1,64 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s +- +-define i64 @lshr40_and255(i64 %a) { +-; CHECK-LABEL: lshr40_and255: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrpick.d $a0, $a0, 47, 40 +-; CHECK-NEXT: ret +- %shr = lshr i64 %a, 40 +- %and = and i64 %shr, 255 +- ret i64 %and ++; RUN: llc -march=loongarch64 -o - %s | FileCheck %s ++ ++define i64 @bstrpickd_add_zext(i32 signext %n) { ++entry: ++ %add = add i32 %n, 1 ++ %res = zext i32 %add to i64 ++ ret i64 %res ++ ++; CHECK-LABEL: bstrpickd_add_zext: ++; CHECK: bstrpick.d $r[[REG:[0-9]+]], $r[[REG:[0-9]+]], 31, 0 ++ + } + +-define i64 @ashr50_and511(i64 %a) { +-; CHECK-LABEL: ashr50_and511: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrpick.d $a0, $a0, 58, 50 +-; CHECK-NEXT: ret +- %shr = ashr i64 %a, 50 +- %and = and i64 %shr, 511 ++define i64 @bstrpickd_and12(i64 zeroext %a) { ++entry: ++ %and = and i64 %a, 4095 + ret i64 %and +-} + +-define i64 @zext_i32_to_i64(i32 %a) { +-; CHECK-LABEL: zext_i32_to_i64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrpick.d $a0, $a0, 31, 0 +-; CHECK-NEXT: ret +- %res = zext i32 %a to i64 +- ret i64 %res ++; CHECK-LABEL: bstrpickd_and12: ++; CHECK: andi $r[[REG:[0-9]+]], $r[[REG:[0-9]+]], 4095 ++ + } + +-define i64 @and8191(i64 %a) { +-; CHECK-LABEL: and8191: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrpick.d $a0, $a0, 12, 0 +-; CHECK-NEXT: ret ++define i64 @bstrpickd_and13(i64 zeroext %a) { ++entry: + %and = and i64 %a, 8191 + ret i64 %and ++ ++; CHECK-LABEL: bstrpickd_and13: ++; CHECK: bstrpick.d $r[[REG:[0-9]+]], $r[[REG:[0-9]+]], 12, 0 ++ + } + +-;; Check that andi but not bstrpick.d is generated. +-define i64 @and4095(i64 %a) { +-; CHECK-LABEL: and4095: +-; CHECK: # %bb.0: +-; CHECK-NEXT: andi $a0, $a0, 4095 +-; CHECK-NEXT: ret +- %and = and i64 %a, 4095 ++define i64 @bstrpickd_lsr_and8(i64 zeroext %a) { ++entry: ++ %shr = lshr i64 %a, 40 ++ %and = and i64 %shr, 255 + ret i64 %and +-} + +-;; (srl (and a, 0xff0), 4) => (BSTRPICK a, 11, 4) +-define i64 @and0xff0_lshr4(i64 %a) { +-; CHECK-LABEL: and0xff0_lshr4: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrpick.d $a0, $a0, 11, 4 +-; CHECK-NEXT: ret +- %and = and i64 %a, 4080 +- %shr = lshr i64 %and, 4 +- ret i64 %shr +-} ++; CHECK-LABEL: bstrpickd_lsr_and8: ++; CHECK: bstrpick.d $r[[REG:[0-9]+]], $r[[REG:[0-9]+]], 47, 40 + +-;; (sra (and a, 0xff0), 5) can also be combined to (BSTRPICK a, 11, 5). +-;; This is because (sra (and a, 0xff0)) would be combined to (srl (and a, 0xff0), 5) +-;; firstly by DAGCombiner::SimplifyDemandedBits. +-define i64 @and4080_ashr5(i64 %a) { +-; CHECK-LABEL: and4080_ashr5: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrpick.d $a0, $a0, 11, 5 +-; CHECK-NEXT: ret +- %and = and i64 %a, 4080 +- %shr = ashr i64 %and, 5 +- ret i64 %shr + } + +-;; Negative test: the second operand of AND is not a shifted mask +-define i64 @and0xf30_lshr4(i64 %a) { +-; CHECK-LABEL: and0xf30_lshr4: +-; CHECK: # %bb.0: +-; CHECK-NEXT: andi $a0, $a0, 3888 +-; CHECK-NEXT: srli.d $a0, $a0, 4 +-; CHECK-NEXT: ret +- %and = and i64 %a, 3888 +- %shr = lshr i64 %and, 4 +- ret i64 %shr ++define i64 @bstrpickd_zext(i32 signext %a) { ++entry: ++ %conv = zext i32 %a to i64 ++ ret i64 %conv ++ ++; CHECK-LABEL: bstrpickd_zext: ++; CHECK: bstrpick.d $r[[REG:[0-9]+]], $r[[REG:[0-9]+]], 31, 0 ++ + } + +-;; Negative test: Shamt < MaskIdx +-define i64 @and0xff0_lshr3(i64 %a) { +-; CHECK-LABEL: and0xff0_lshr3: +-; CHECK: # %bb.0: +-; CHECK-NEXT: andi $a0, $a0, 4080 +-; CHECK-NEXT: srli.d $a0, $a0, 3 +-; CHECK-NEXT: ret +- %and = and i64 %a, 4080 +- %shr = lshr i64 %and, 3 ++define i64 @bstrpickd_and_lsr(i64 zeroext %n) { ++entry: ++ %and = lshr i64 %n, 8 ++ %shr = and i64 %and, 4095 + ret i64 %shr ++ ++; CHECK-LABEL: bstrpickd_and_lsr: ++; CHECK: bstrpick.d $r[[REG:[0-9]+]], $r[[REG:[0-9]+]], 19, 8 ++ + } +diff --git a/llvm/test/CodeGen/LoongArch/bstrpick_w.ll b/llvm/test/CodeGen/LoongArch/bstrpick_w.ll +index f9027e1fb..e60de4737 100644 +--- a/llvm/test/CodeGen/LoongArch/bstrpick_w.ll ++++ b/llvm/test/CodeGen/LoongArch/bstrpick_w.ll +@@ -1,98 +1,18 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s ++; RUN: llc -march=loongarch64 -o - %s | FileCheck %s + +-define i32 @lshr10_and255(i32 %a) { +-; CHECK-LABEL: lshr10_and255: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrpick.w $a0, $a0, 17, 10 +-; CHECK-NEXT: ret +- %shr = lshr i32 %a, 10 +- %and = and i32 %shr, 255 ++define i32 @bstrpickw_and24(i32 signext %a) { ++; CHECK-LABEL: bstrpickw_and24: ++; CHECK: bstrpick.w $r[[REG:[0-9]+]], $r[[REG:[0-9]+]], 23, 0 ++entry: ++ %and = and i32 %a, 16777215 + ret i32 %and + } + +-define i32 @ashr20_and511(i32 %a) { +-; CHECK-LABEL: ashr20_and511: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrpick.w $a0, $a0, 28, 20 +-; CHECK-NEXT: ret +- %shr = ashr i32 %a, 20 ++define i32 @bstrpickw_lshr_and(i32 %s, i32 %pos, i32 %sz) nounwind readnone { ++; CHECK-LABEL: bstrpickw_lshr_and: ++; CHECK: bstrpick.w $r[[REG:[0-9]+]], $r[[REG:[0-9]+]], 13, 5 ++entry: ++ %shr = lshr i32 %s, 5 + %and = and i32 %shr, 511 + ret i32 %and + } +- +-define i32 @zext_i16_to_i32(i16 %a) { +-; CHECK-LABEL: zext_i16_to_i32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrpick.w $a0, $a0, 15, 0 +-; CHECK-NEXT: ret +- %res = zext i16 %a to i32 +- ret i32 %res +-} +- +-define i32 @and8191(i32 %a) { +-; CHECK-LABEL: and8191: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrpick.w $a0, $a0, 12, 0 +-; CHECK-NEXT: ret +- %and = and i32 %a, 8191 +- ret i32 %and +-} +- +-;; Check that andi but not bstrpick.d is generated. +-define i32 @and4095(i32 %a) { +-; CHECK-LABEL: and4095: +-; CHECK: # %bb.0: +-; CHECK-NEXT: andi $a0, $a0, 4095 +-; CHECK-NEXT: ret +- %and = and i32 %a, 4095 +- ret i32 %and +-} +- +-;; (srl (and a, 0xff0), 4) => (BSTRPICK a, 11, 4) +-define i32 @and0xff0_lshr4(i32 %a) { +-; CHECK-LABEL: and0xff0_lshr4: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrpick.w $a0, $a0, 11, 4 +-; CHECK-NEXT: ret +- %and = and i32 %a, 4080 +- %shr = lshr i32 %and, 4 +- ret i32 %shr +-} +- +-;; (sra (and a, 0xff0), 5) can also be combined to (BSTRPICK a, 11, 5). +-;; This is because (sra (and a, 0xff0)) would be combined to (srl (and a, 0xff0), 5) +-;; firstly by DAGCombiner::SimplifyDemandedBits. +-define i32 @and4080_ashr5(i32 %a) { +-; CHECK-LABEL: and4080_ashr5: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrpick.w $a0, $a0, 11, 5 +-; CHECK-NEXT: ret +- %and = and i32 %a, 4080 +- %shr = ashr i32 %and, 5 +- ret i32 %shr +-} +- +-;; Negative test: the second operand of AND is not a shifted mask +-define i32 @and0xf30_lshr4(i32 %a) { +-; CHECK-LABEL: and0xf30_lshr4: +-; CHECK: # %bb.0: +-; CHECK-NEXT: andi $a0, $a0, 3888 +-; CHECK-NEXT: srli.w $a0, $a0, 4 +-; CHECK-NEXT: ret +- %and = and i32 %a, 3888 +- %shr = lshr i32 %and, 4 +- ret i32 %shr +-} +- +-;; Negative test: Shamt < MaskIdx +-define i32 @and0xff0_lshr3(i32 %a) { +-; CHECK-LABEL: and0xff0_lshr3: +-; CHECK: # %bb.0: +-; CHECK-NEXT: andi $a0, $a0, 4080 +-; CHECK-NEXT: srli.w $a0, $a0, 3 +-; CHECK-NEXT: ret +- %and = and i32 %a, 4080 +- %shr = lshr i32 %and, 3 +- ret i32 %shr +-} +diff --git a/llvm/test/CodeGen/LoongArch/bswap-bitreverse.ll b/llvm/test/CodeGen/LoongArch/bswap-bitreverse.ll +deleted file mode 100644 +index c99adfbb0..000000000 +--- a/llvm/test/CodeGen/LoongArch/bswap-bitreverse.ll ++++ /dev/null +@@ -1,136 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --verify-machineinstrs < %s \ +-; RUN: | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s \ +-; RUN: | FileCheck %s --check-prefix=LA64 +- +-declare i16 @llvm.bitreverse.i16(i16) +-declare i32 @llvm.bitreverse.i32(i32) +-declare i64 @llvm.bitreverse.i64(i64) +-declare i16 @llvm.bswap.i16(i16) +-declare i32 @llvm.bswap.i32(i32) +-declare i64 @llvm.bswap.i64(i64) +- +-define i16 @test_bswap_bitreverse_i16(i16 %a) nounwind { +-; LA32-LABEL: test_bswap_bitreverse_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: revb.2h $a0, $a0 +-; LA32-NEXT: bitrev.w $a0, $a0 +-; LA32-NEXT: srli.w $a0, $a0, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_bswap_bitreverse_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: revb.2h $a0, $a0 +-; LA64-NEXT: bitrev.d $a0, $a0 +-; LA64-NEXT: srli.d $a0, $a0, 48 +-; LA64-NEXT: ret +- %tmp = call i16 @llvm.bswap.i16(i16 %a) +- %tmp2 = call i16 @llvm.bitreverse.i16(i16 %tmp) +- ret i16 %tmp2 +-} +- +-define i32 @test_bswap_bitreverse_i32(i32 %a) nounwind { +-; LA32-LABEL: test_bswap_bitreverse_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: bitrev.4b $a0, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_bswap_bitreverse_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: bitrev.4b $a0, $a0 +-; LA64-NEXT: ret +- %tmp = call i32 @llvm.bswap.i32(i32 %a) +- %tmp2 = call i32 @llvm.bitreverse.i32(i32 %tmp) +- ret i32 %tmp2 +-} +- +-define i64 @test_bswap_bitreverse_i64(i64 %a) nounwind { +-; LA32-LABEL: test_bswap_bitreverse_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: bitrev.4b $a0, $a0 +-; LA32-NEXT: bitrev.4b $a1, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_bswap_bitreverse_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: bitrev.8b $a0, $a0 +-; LA64-NEXT: ret +- %tmp = call i64 @llvm.bswap.i64(i64 %a) +- %tmp2 = call i64 @llvm.bitreverse.i64(i64 %tmp) +- ret i64 %tmp2 +-} +- +-define i16 @test_bitreverse_bswap_i16(i16 %a) nounwind { +-; LA32-LABEL: test_bitreverse_bswap_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: revb.2h $a0, $a0 +-; LA32-NEXT: bitrev.w $a0, $a0 +-; LA32-NEXT: srli.w $a0, $a0, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_bitreverse_bswap_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: revb.2h $a0, $a0 +-; LA64-NEXT: bitrev.d $a0, $a0 +-; LA64-NEXT: srli.d $a0, $a0, 48 +-; LA64-NEXT: ret +- %tmp = call i16 @llvm.bitreverse.i16(i16 %a) +- %tmp2 = call i16 @llvm.bswap.i16(i16 %tmp) +- ret i16 %tmp2 +-} +- +-define i32 @test_bitreverse_bswap_i32(i32 %a) nounwind { +-; LA32-LABEL: test_bitreverse_bswap_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: bitrev.4b $a0, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_bitreverse_bswap_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: bitrev.4b $a0, $a0 +-; LA64-NEXT: ret +- %tmp = call i32 @llvm.bitreverse.i32(i32 %a) +- %tmp2 = call i32 @llvm.bswap.i32(i32 %tmp) +- ret i32 %tmp2 +-} +- +-define i64 @test_bitreverse_bswap_i64(i64 %a) nounwind { +-; LA32-LABEL: test_bitreverse_bswap_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: bitrev.4b $a0, $a0 +-; LA32-NEXT: bitrev.4b $a1, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_bitreverse_bswap_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: bitrev.8b $a0, $a0 +-; LA64-NEXT: ret +- %tmp = call i64 @llvm.bitreverse.i64(i64 %a) +- %tmp2 = call i64 @llvm.bswap.i64(i64 %tmp) +- ret i64 %tmp2 +-} +- +-define i32 @pr55484(i32 %0) { +-; LA32-LABEL: pr55484: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a0, 8 +-; LA32-NEXT: srli.w $a0, $a0, 8 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ext.w.h $a0, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: pr55484: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 8 +-; LA64-NEXT: srli.d $a0, $a0, 8 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ext.w.h $a0, $a0 +-; LA64-NEXT: ret +- %2 = lshr i32 %0, 8 +- %3 = shl i32 %0, 8 +- %4 = or i32 %2, %3 +- %5 = trunc i32 %4 to i16 +- %6 = sext i16 %5 to i32 +- ret i32 %6 +-} +diff --git a/llvm/test/CodeGen/LoongArch/bswap.ll b/llvm/test/CodeGen/LoongArch/bswap.ll +deleted file mode 100644 +index eb9107302..000000000 +--- a/llvm/test/CodeGen/LoongArch/bswap.ll ++++ /dev/null +@@ -1,143 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --verify-machineinstrs < %s \ +-; RUN: | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s \ +-; RUN: | FileCheck %s --check-prefix=LA64 +- +-declare i16 @llvm.bswap.i16(i16) +-declare i32 @llvm.bswap.i32(i32) +-declare i48 @llvm.bswap.i48(i48) +-declare i64 @llvm.bswap.i64(i64) +-declare i80 @llvm.bswap.i80(i80) +-declare i128 @llvm.bswap.i128(i128) +- +-define i16 @test_bswap_i16(i16 %a) nounwind { +-; LA32-LABEL: test_bswap_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: revb.2h $a0, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_bswap_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: revb.2h $a0, $a0 +-; LA64-NEXT: ret +- %tmp = call i16 @llvm.bswap.i16(i16 %a) +- ret i16 %tmp +-} +- +-define i32 @test_bswap_i32(i32 %a) nounwind { +-; LA32-LABEL: test_bswap_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: revb.2h $a0, $a0 +-; LA32-NEXT: rotri.w $a0, $a0, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_bswap_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: revb.2w $a0, $a0 +-; LA64-NEXT: ret +- %tmp = call i32 @llvm.bswap.i32(i32 %a) +- ret i32 %tmp +-} +- +-define i64 @test_bswap_i64(i64 %a) nounwind { +-; LA32-LABEL: test_bswap_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: revb.2h $a1, $a1 +-; LA32-NEXT: rotri.w $a2, $a1, 16 +-; LA32-NEXT: revb.2h $a0, $a0 +-; LA32-NEXT: rotri.w $a1, $a0, 16 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_bswap_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: revb.d $a0, $a0 +-; LA64-NEXT: ret +- %tmp = call i64 @llvm.bswap.i64(i64 %a) +- ret i64 %tmp +-} +- +-;; Bswap on non-native integer widths. +- +-define i48 @test_bswap_i48(i48 %a) nounwind { +-; LA32-LABEL: test_bswap_i48: +-; LA32: # %bb.0: +-; LA32-NEXT: revb.2h $a0, $a0 +-; LA32-NEXT: rotri.w $a2, $a0, 16 +-; LA32-NEXT: revb.2h $a0, $a1 +-; LA32-NEXT: rotri.w $a0, $a0, 16 +-; LA32-NEXT: bytepick.w $a0, $a0, $a2, 2 +-; LA32-NEXT: srli.w $a1, $a2, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_bswap_i48: +-; LA64: # %bb.0: +-; LA64-NEXT: revb.d $a0, $a0 +-; LA64-NEXT: srli.d $a0, $a0, 16 +-; LA64-NEXT: ret +- %tmp = call i48 @llvm.bswap.i48(i48 %a) +- ret i48 %tmp +-} +- +-define i80 @test_bswap_i80(i80 %a) nounwind { +-; LA32-LABEL: test_bswap_i80: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a2, $a1, 0 +-; LA32-NEXT: revb.2h $a2, $a2 +-; LA32-NEXT: rotri.w $a2, $a2, 16 +-; LA32-NEXT: ld.w $a3, $a1, 4 +-; LA32-NEXT: revb.2h $a3, $a3 +-; LA32-NEXT: rotri.w $a3, $a3, 16 +-; LA32-NEXT: bytepick.w $a4, $a3, $a2, 2 +-; LA32-NEXT: st.w $a4, $a0, 4 +-; LA32-NEXT: ld.w $a1, $a1, 8 +-; LA32-NEXT: revb.2h $a1, $a1 +-; LA32-NEXT: rotri.w $a1, $a1, 16 +-; LA32-NEXT: bytepick.w $a1, $a1, $a3, 2 +-; LA32-NEXT: st.w $a1, $a0, 0 +-; LA32-NEXT: srli.w $a1, $a2, 16 +-; LA32-NEXT: st.h $a1, $a0, 8 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_bswap_i80: +-; LA64: # %bb.0: +-; LA64-NEXT: revb.d $a2, $a0 +-; LA64-NEXT: revb.d $a0, $a1 +-; LA64-NEXT: bytepick.d $a0, $a0, $a2, 2 +-; LA64-NEXT: srli.d $a1, $a2, 48 +-; LA64-NEXT: ret +- %tmp = call i80 @llvm.bswap.i80(i80 %a) +- ret i80 %tmp +-} +- +-define i128 @test_bswap_i128(i128 %a) nounwind { +-; LA32-LABEL: test_bswap_i128: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a2, $a1, 0 +-; LA32-NEXT: revb.2h $a2, $a2 +-; LA32-NEXT: rotri.w $a2, $a2, 16 +-; LA32-NEXT: st.w $a2, $a0, 12 +-; LA32-NEXT: ld.w $a2, $a1, 4 +-; LA32-NEXT: revb.2h $a2, $a2 +-; LA32-NEXT: rotri.w $a2, $a2, 16 +-; LA32-NEXT: st.w $a2, $a0, 8 +-; LA32-NEXT: ld.w $a2, $a1, 8 +-; LA32-NEXT: revb.2h $a2, $a2 +-; LA32-NEXT: rotri.w $a2, $a2, 16 +-; LA32-NEXT: st.w $a2, $a0, 4 +-; LA32-NEXT: ld.w $a1, $a1, 12 +-; LA32-NEXT: revb.2h $a1, $a1 +-; LA32-NEXT: rotri.w $a1, $a1, 16 +-; LA32-NEXT: st.w $a1, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_bswap_i128: +-; LA64: # %bb.0: +-; LA64-NEXT: revb.d $a2, $a1 +-; LA64-NEXT: revb.d $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %tmp = call i128 @llvm.bswap.i128(i128 %a) +- ret i128 %tmp +-} +diff --git a/llvm/test/CodeGen/LoongArch/builtins-loongarch-base.ll b/llvm/test/CodeGen/LoongArch/builtins-loongarch-base.ll +new file mode 100644 +index 000000000..ee3760afb +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/builtins-loongarch-base.ll +@@ -0,0 +1,752 @@ ++; Test the base intrinsics. ++; RUN: llc -march=loongarch64 -o - %s | FileCheck %s ++ ++define void @cpucfg() { ++entry: ++ %u32_r = alloca i32, align 4 ++ %u32_a = alloca i32, align 4 ++ %0 = load i32, i32* %u32_a, align 4 ++ %1 = call i32 @llvm.loongarch.cpucfg(i32 %0) ++ store i32 %1, i32* %u32_r, align 4 ++ ret void ++} ++ ++declare i32 @llvm.loongarch.cpucfg(i32) ++ ++; CHECK-LABEL: cpucfg: ++; CHECK: ld.w $r[[REG:[0-9]+]], $sp, 8 ++; CHECK: cpucfg $r[[REG:[0-9]+]], $r[[REG:[0-9]+]] ++; CHECK: st.w $r[[REG:[0-9]+]], $sp, 12 ++; CHECK: jr $ra ++; ++ ++define void @csrrd_w() { ++entry: ++ %u32_r = alloca i32, align 4 ++ %0 = call i32 @llvm.loongarch.csrrd.w(i32 1) ++ store i32 %0, i32* %u32_r, align 4 ++ ret void ++} ++ ++declare i32 @llvm.loongarch.csrrd.w(i32) ++ ++; CHECK-LABEL: csrrd_w: ++; CHECK: csrrd $r[[REG:[0-9]+]], 1 ++; CHECK: st.w $r[[REG:[0-9]+]], $sp, 12 ++; CHECK: jr $ra ++; ++ ++define void @csrrd_d() { ++entry: ++ %u64_r = alloca i64, align 8 ++ %0 = call i64 @llvm.loongarch.csrrd.d(i64 1) ++ store i64 %0, i64* %u64_r, align 8 ++ ret void ++} ++ ++declare i64 @llvm.loongarch.csrrd.d(i64) ++ ++; CHECK-LABEL: csrrd_d: ++; CHECK: csrrd $r[[REG:[0-9]+]], 1 ++; CHECK: st.d $r[[REG:[0-9]+]], $sp, 8 ++; CHECK: jr $ra ++; ++ ++define void @csrwr_w() { ++entry: ++ %u32_r = alloca i32, align 4 ++ %u32_a = alloca i32, align 4 ++ %0 = load i32, i32* %u32_a, align 4 ++ %1 = call i32 @llvm.loongarch.csrwr.w(i32 %0, i32 1) ++ store i32 %1, i32* %u32_r, align 4 ++ ret void ++} ++ ++declare i32 @llvm.loongarch.csrwr.w(i32, i32) ++ ++; CHECK-LABEL: csrwr_w: ++; CHECK: ld.w $r[[REG:[0-9]+]], $sp, 8 ++; CHECK: csrwr $r[[REG:[0-9]+]], 1 ++; CHECK: st.w $r[[REG:[0-9]+]], $sp, 12 ++; CHECK: jr $ra ++; ++ ++define void @csrwr_d() { ++entry: ++ %u64_r = alloca i64, align 8 ++ %u64_a = alloca i64, align 8 ++ %0 = load i64, i64* %u64_a, align 8 ++ %1 = call i64 @llvm.loongarch.csrwr.d(i64 %0, i64 1) ++ store i64 %1, i64* %u64_r, align 8 ++ ret void ++} ++ ++declare i64 @llvm.loongarch.csrwr.d(i64, i64) ++ ++; CHECK-LABEL: csrwr_d: ++; CHECK: ld.d $r[[REG:[0-9]+]], $sp, 0 ++; CHECK: csrwr $r[[REG:[0-9]+]], 1 ++; CHECK: st.d $r[[REG:[0-9]+]], $sp, 8 ++; CHECK: jr $ra ++; ++ ++define void @csrxchg_w() { ++entry: ++ %u32_r = alloca i32, align 4 ++ %u32_a = alloca i32, align 4 ++ %u32_b = alloca i32, align 4 ++ %0 = load i32, i32* %u32_a, align 4 ++ %1 = load i32, i32* %u32_b, align 4 ++ %2 = call i32 @llvm.loongarch.csrxchg.w(i32 %0, i32 %1, i32 1) ++ store i32 %2, i32* %u32_r, align 4 ++ ret void ++} ++ ++declare i32 @llvm.loongarch.csrxchg.w(i32, i32, i32) ++ ++; CHECK-LABEL: csrxchg_w: ++; CHECK: ld.w $r[[REG1:[0-9]+]], $sp, 4 ++; CHECK: ld.w $r[[REG2:[0-9]+]], $sp, 8 ++; CHECK: csrxchg $r[[REG1:[0-9]+]], $r[[REG2:[0-9]+]], 1 ++; CHECK: st.w $r[[REG1:[0-9]+]], $sp, 12 ++; CHECK: jr $ra ++; ++ ++define void @csrxchg_d() { ++entry: ++ %u64_r = alloca i64, align 8 ++ %u64_a = alloca i64, align 8 ++ %u64_b = alloca i64, align 8 ++ %0 = load i64, i64* %u64_a, align 8 ++ %1 = load i64, i64* %u64_b, align 8 ++ %2 = call i64 @llvm.loongarch.csrxchg.d(i64 %0, i64 %1, i64 1) ++ store i64 %2, i64* %u64_r, align 8 ++ ret void ++} ++ ++declare i64 @llvm.loongarch.csrxchg.d(i64, i64, i64) ++ ++; CHECK-LABEL: csrxchg_d: ++; CHECK: ld.d $r[[REG1:[0-9]+]], $sp, 8 ++; CHECK: ld.d $r[[REG2:[0-9]+]], $sp, 16 ++; CHECK: csrxchg $r[[REG1:[0-9]+]], $r[[REG2:[0-9]+]], 1 ++; CHECK: st.d $r[[REG1:[0-9]+]], $sp, 24 ++; CHECK: jr $ra ++; ++ ++define void @iocsrrd_b() { ++entry: ++ %u32_a = alloca i32, align 4 ++ %u8_r = alloca i8, align 1 ++ %0 = load i32, i32* %u32_a, align 4 ++ %1 = call i32 @llvm.loongarch.iocsrrd.b(i32 %0) ++ %conv = trunc i32 %1 to i8 ++ store i8 %conv, i8* %u8_r, align 1 ++ ret void ++} ++ ++declare i32 @llvm.loongarch.iocsrrd.b(i32) ++ ++; CHECK-LABEL: iocsrrd_b: ++; CHECK: ld.w $r[[REG:[0-9]+]], $sp, 12 ++; CHECK: iocsrrd.b $r[[REG:[0-9]+]], $r[[REG:[0-9]+]] ++; CHECK: st.b $r[[REG:[0-9]+]], $sp, 11 ++; CHECK: jr $ra ++; ++ ++define void @iocsrrd_h() { ++entry: ++ %u32_a = alloca i32, align 4 ++ %u16_r = alloca i16, align 2 ++ %0 = load i32, i32* %u32_a, align 4 ++ %1 = call i32 @llvm.loongarch.iocsrrd.h(i32 %0) ++ %conv = trunc i32 %1 to i16 ++ store i16 %conv, i16* %u16_r, align 2 ++ ret void ++} ++ ++declare i32 @llvm.loongarch.iocsrrd.h(i32) ++ ++; CHECK-LABEL: iocsrrd_h: ++; CHECK: ld.w $r[[REG:[0-9]+]], $sp, 12 ++; CHECK: iocsrrd.h $r[[REG:[0-9]+]], $r[[REG:[0-9]+]] ++; CHECK: st.h $r[[REG:[0-9]+]], $sp, 10 ++; CHECK: jr $ra ++; ++ ++define void @iocsrrd_w() { ++entry: ++ %u32_r = alloca i32, align 4 ++ %u32_a = alloca i32, align 4 ++ %0 = load i32, i32* %u32_a, align 4 ++ %1 = call i32 @llvm.loongarch.iocsrrd.w(i32 %0) ++ store i32 %1, i32* %u32_r, align 4 ++ ret void ++} ++ ++declare i32 @llvm.loongarch.iocsrrd.w(i32) ++ ++; CHECK-LABEL: iocsrrd_w: ++; CHECK: ld.w $r[[REG:[0-9]+]], $sp, 8 ++; CHECK: iocsrrd.w $r[[REG:[0-9]+]], $r[[REG:[0-9]+]] ++; CHECK: st.w $r[[REG:[0-9]+]], $sp, 12 ++; CHECK: jr $ra ++; ++ ++define void @iocsrrd_d() { ++entry: ++ %u32_a = alloca i32, align 4 ++ %u64_r = alloca i64, align 8 ++ %0 = load i32, i32* %u32_a, align 4 ++ %1 = call i64 @llvm.loongarch.iocsrrd.d(i32 %0) ++ store i64 %1, i64* %u64_r, align 8 ++ ret void ++} ++ ++declare i64 @llvm.loongarch.iocsrrd.d(i32) ++ ++; CHECK-LABEL: iocsrrd_d: ++; CHECK: ld.w $r[[REG:[0-9]+]], $sp, 12 ++; CHECK: iocsrrd.d $r[[REG:[0-9]+]], $r[[REG:[0-9]+]] ++; CHECK: st.d $r[[REG:[0-9]+]], $sp, 0 ++; CHECK: jr $ra ++; ++ ++define void @iocsrwr_b() { ++entry: ++ %u32_a = alloca i32, align 4 ++ %u8_a = alloca i8, align 1 ++ %0 = load i8, i8* %u8_a, align 1 ++ %conv = zext i8 %0 to i32 ++ %1 = load i32, i32* %u32_a, align 4 ++ call void @llvm.loongarch.iocsrwr.b(i32 %conv, i32 %1) ++ ret void ++} ++ ++declare void @llvm.loongarch.iocsrwr.b(i32, i32) ++ ++; CHECK-LABEL: iocsrwr_b: ++; CHECK: ld.w $r[[REG1:[0-9]+]], $sp, 12 ++; CHECK: ld.bu $r[[REG2:[0-9]+]], $sp, 11 ++; CHECK: iocsrwr.b $r[[REG2:[0-9]+]], $r[[REG1:[0-9]+]] ++; CHECK: jr $ra ++; ++ ++define void @iocsrwr_h() { ++entry: ++ %u32_a = alloca i32, align 4 ++ %u16_a = alloca i16, align 2 ++ %0 = load i16, i16* %u16_a, align 2 ++ %conv = zext i16 %0 to i32 ++ %1 = load i32, i32* %u32_a, align 4 ++ call void @llvm.loongarch.iocsrwr.h(i32 %conv, i32 %1) ++ ret void ++} ++ ++declare void @llvm.loongarch.iocsrwr.h(i32, i32) ++ ++; CHECK-LABEL: iocsrwr_h: ++; CHECK: ld.w $r[[REG1:[0-9]+]], $sp, 12 ++; CHECK: ld.hu $r[[REG2:[0-9]+]], $sp, 10 ++; CHECK: iocsrwr.h $r[[REG2:[0-9]+]], $r[[REG1:[0-9]+]] ++; CHECK: jr $ra ++; ++ ++define void @iocsrwr_w() { ++entry: ++ %u32_a = alloca i32, align 4 ++ %u32_b = alloca i32, align 4 ++ %0 = load i32, i32* %u32_a, align 4 ++ %1 = load i32, i32* %u32_b, align 4 ++ call void @llvm.loongarch.iocsrwr.w(i32 %0, i32 %1) ++ ret void ++} ++ ++declare void @llvm.loongarch.iocsrwr.w(i32, i32) ++ ++; CHECK-LABEL: iocsrwr_w: ++; CHECK: ld.w $r[[REG1:[0-9]+]], $sp, 8 ++; CHECK: ld.w $r[[REG2:[0-9]+]], $sp, 12 ++; CHECK: iocsrwr.w $r[[REG2:[0-9]+]], $r[[REG1:[0-9]+]] ++; CHECK: jr $ra ++; ++ ++define void @iocsrwr_d() { ++entry: ++ %u32_a = alloca i32, align 4 ++ %u64_a = alloca i64, align 8 ++ %0 = load i64, i64* %u64_a, align 8 ++ %1 = load i32, i32* %u32_a, align 4 ++ call void @llvm.loongarch.iocsrwr.d(i64 %0, i32 %1) ++ ret void ++} ++ ++declare void @llvm.loongarch.iocsrwr.d(i64, i32) ++ ++; CHECK-LABEL: iocsrwr_d: ++; CHECK: ld.w $r[[REG1:[0-9]+]], $sp, 12 ++; CHECK: ld.d $r[[REG2:[0-9]+]], $sp, 0 ++; CHECK: iocsrwr.d $r[[REG2:[0-9]+]], $r[[REG1:[0-9]+]] ++; CHECK: jr $ra ++; ++ ++define void @cacop_w() { ++entry: ++ %i32_a = alloca i32, align 4 ++ %0 = load i32, i32* %i32_a, align 4 ++ call void @llvm.loongarch.cacop.w(i32 1, i32 %0, i32 2) ++ ret void ++} ++ ++declare void @llvm.loongarch.cacop.w(i32, i32, i32) ++ ++; CHECK-LABEL: cacop_w: ++; CHECK: ld.w $r[[REG:[0-9]+]], $sp, 12 ++; CHECK: cacop 1, $r[[REG:[0-9]+]], 2 ++; CHECK: jr $ra ++; ++ ++define void @cacop_d() { ++entry: ++ %i64_a = alloca i64, align 8 ++ %0 = load i64, i64* %i64_a, align 8 ++ call void @llvm.loongarch.cacop.d(i32 1, i64 %0, i64 2) ++ ret void ++} ++ ++declare void @llvm.loongarch.cacop.d(i32, i64, i64) ++ ++; CHECK-LABEL: cacop_d: ++; CHECK: ld.d $r[[REG:[0-9]+]], $sp, 8 ++; CHECK: cacop 1, $r[[REG:[0-9]+]], 2 ++; CHECK: jr $ra ++; ++ ++define void @rdtime_d() { ++entry: ++ %value = alloca i64, align 8 ++ %timeid = alloca i64, align 8 ++ %0 = call { i64, i64 } asm sideeffect "rdtime.d\09$0,$1\0A\09", "=&r,=&r"() nounwind ++ %asmresult0 = extractvalue { i64, i64 } %0, 0 ++ %asmresult1 = extractvalue { i64, i64 } %0, 1 ++ store i64 %asmresult0, i64* %value, align 8 ++ store i64 %asmresult1, i64* %timeid, align 8 ++ ret void ++} ++ ++; CHECK-LABEL: rdtime_d: ++; CHECK: rdtime.d $r[[REG1:[0-9]+]], $r[[REG2:[0-9]+]] ++; CHECK: st.d $r[[REG2:[0-9]+]], $sp, 8 ++; CHECK: st.d $r[[REG1:[0-9]+]], $sp, 0 ++; CHECK: jr $ra ++; ++ ++define void @rdtimeh_w() { ++entry: ++ %value = alloca i32, align 4 ++ %timeid = alloca i32, align 4 ++ %0 = call { i32, i32 } asm sideeffect "rdtimeh.w\09$0,$1\0A\09", "=&r,=&r"() nounwind ++ %asmresult0 = extractvalue { i32, i32 } %0, 0 ++ %asmresult1 = extractvalue { i32, i32 } %0, 1 ++ store i32 %asmresult0, i32* %value, align 4 ++ store i32 %asmresult1, i32* %timeid, align 4 ++ ret void ++} ++ ++; CHECK-LABEL: rdtimeh_w: ++; CHECK: rdtimeh.w $r[[REG1:[0-9]+]], $r[[REG2:[0-9]+]] ++; CHECK: st.w $r[[REG2:[0-9]+]], $sp, 12 ++; CHECK: st.w $r[[REG1:[0-9]+]], $sp, 8 ++; CHECK: jr $ra ++; ++ ++define void @rdtimel_w() { ++entry: ++ %value = alloca i32, align 4 ++ %timeid = alloca i32, align 4 ++ %0 = call { i32, i32 } asm sideeffect "rdtimel.w\09$0,$1\0A\09", "=&r,=&r"() nounwind ++ %asmresult0 = extractvalue { i32, i32 } %0, 0 ++ %asmresult1 = extractvalue { i32, i32 } %0, 1 ++ store i32 %asmresult0, i32* %value, align 4 ++ store i32 %asmresult1, i32* %timeid, align 4 ++ ret void ++} ++ ++; CHECK-LABEL: rdtimel_w: ++; CHECK: rdtimel.w $r[[REG1:[0-9]+]], $r[[REG2:[0-9]+]] ++; CHECK: st.w $r[[REG2:[0-9]+]], $sp, 12 ++; CHECK: st.w $r[[REG1:[0-9]+]], $sp, 8 ++; CHECK: jr $ra ++; ++ ++define void @crc_w_b_w() { ++entry: ++ %i32_r = alloca i32, align 4 ++ %i32_a = alloca i32, align 4 ++ %i8_a = alloca i8, align 1 ++ %0 = load i8, i8* %i8_a, align 1 ++ %conv = sext i8 %0 to i32 ++ %1 = load i32, i32* %i32_a, align 4 ++ %2 = call i32 @llvm.loongarch.crc.w.b.w(i32 %conv, i32 %1) ++ store i32 %2, i32* %i32_r, align 4 ++ ret void ++} ++ ++declare i32 @llvm.loongarch.crc.w.b.w(i32, i32) ++ ++; CHECK-LABEL: crc_w_b_w: ++; CHECK: ld.w $r[[REG1:[0-9]+]], $sp, 8 ++; CHECK: ld.b $r[[REG2:[0-9]+]], $sp, 7 ++; CHECK: crc.w.b.w $r[[REG1:[0-9]+]], $r[[REG2:[0-9]+]], $r[[REG1:[0-9]+]] ++; CHECK: jr $ra ++; ++ ++define void @crc_w_h_w() { ++entry: ++ %i32_r = alloca i32, align 4 ++ %i32_a = alloca i32, align 4 ++ %i16_a = alloca i16, align 2 ++ %0 = load i16, i16* %i16_a, align 2 ++ %conv = sext i16 %0 to i32 ++ %1 = load i32, i32* %i32_a, align 4 ++ %2 = call i32 @llvm.loongarch.crc.w.h.w(i32 %conv, i32 %1) ++ store i32 %2, i32* %i32_r, align 4 ++ ret void ++} ++ ++declare i32 @llvm.loongarch.crc.w.h.w(i32, i32) ++ ++; CHECK-LABEL: crc_w_h_w: ++; CHECK: ld.w $r[[REG1:[0-9]+]], $sp, 8 ++; CHECK: ld.h $r[[REG2:[0-9]+]], $sp, 6 ++; CHECK: crc.w.h.w $r[[REG1:[0-9]+]], $r[[REG2:[0-9]+]], $r[[REG1:[0-9]+]] ++; CHECK: jr $ra ++; ++ ++define void @crc_w_w_w() { ++entry: ++ %i32_r = alloca i32, align 4 ++ %i32_a = alloca i32, align 4 ++ %i32_b = alloca i32, align 4 ++ %0 = load i32, i32* %i32_a, align 4 ++ %1 = load i32, i32* %i32_b, align 4 ++ %2 = call i32 @llvm.loongarch.crc.w.w.w(i32 %0, i32 %1) ++ store i32 %2, i32* %i32_r, align 4 ++ ret void ++} ++ ++declare i32 @llvm.loongarch.crc.w.w.w(i32, i32) ++ ++; CHECK-LABEL: crc_w_w_w: ++; CHECK: ld.w $r[[REG1:[0-9]+]], $sp, 4 ++; CHECK: ld.w $r[[REG2:[0-9]+]], $sp, 8 ++; CHECK: crc.w.w.w $r[[REG1:[0-9]+]], $r[[REG2:[0-9]+]], $r[[REG1:[0-9]+]] ++; CHECK: jr $ra ++; ++ ++define void @crc_w_d_w() { ++entry: ++ %i32_r = alloca i32, align 4 ++ %i32_a = alloca i32, align 4 ++ %i64_a = alloca i64, align 8 ++ %0 = load i64, i64* %i64_a, align 8 ++ %1 = load i32, i32* %i32_a, align 4 ++ %2 = call i32 @llvm.loongarch.crc.w.d.w(i64 %0, i32 %1) ++ store i32 %2, i32* %i32_r, align 4 ++ ret void ++} ++ ++declare i32 @llvm.loongarch.crc.w.d.w(i64, i32) ++ ++; CHECK-LABEL: crc_w_d_w: ++; CHECK: ld.w $r[[REG1:[0-9]+]], $sp, 8 ++; CHECK: ld.d $r[[REG2:[0-9]+]], $sp, 0 ++; CHECK: crc.w.d.w $r[[REG1:[0-9]+]], $r[[REG2:[0-9]+]], $r[[REG1:[0-9]+]] ++; CHECK: jr $ra ++; ++ ++define void @crcc_w_b_w() { ++entry: ++ %i32_r = alloca i32, align 4 ++ %i32_a = alloca i32, align 4 ++ %i8_a = alloca i8, align 1 ++ %0 = load i8, i8* %i8_a, align 1 ++ %conv = sext i8 %0 to i32 ++ %1 = load i32, i32* %i32_a, align 4 ++ %2 = call i32 @llvm.loongarch.crcc.w.b.w(i32 %conv, i32 %1) ++ store i32 %2, i32* %i32_r, align 4 ++ ret void ++} ++ ++declare i32 @llvm.loongarch.crcc.w.b.w(i32, i32) ++ ++; CHECK-LABEL: crcc_w_b_w: ++; CHECK: ld.w $r[[REG1:[0-9]+]], $sp, 8 ++; CHECK: ld.b $r[[REG2:[0-9]+]], $sp, 7 ++; CHECK: crcc.w.b.w $r[[REG1:[0-9]+]], $r[[REG2:[0-9]+]], $r[[REG1:[0-9]+]] ++; CHECK: jr $ra ++; ++ ++define void @crcc_w_h_w() { ++entry: ++ %i32_r = alloca i32, align 4 ++ %i32_a = alloca i32, align 4 ++ %i16_a = alloca i16, align 2 ++ %0 = load i16, i16* %i16_a, align 2 ++ %conv = sext i16 %0 to i32 ++ %1 = load i32, i32* %i32_a, align 4 ++ %2 = call i32 @llvm.loongarch.crcc.w.h.w(i32 %conv, i32 %1) ++ store i32 %2, i32* %i32_r, align 4 ++ ret void ++} ++ ++declare i32 @llvm.loongarch.crcc.w.h.w(i32, i32) ++ ++; CHECK-LABEL: crcc_w_h_w: ++; CHECK: ld.w $r[[REG1:[0-9]+]], $sp, 8 ++; CHECK: ld.h $r[[REG2:[0-9]+]], $sp, 6 ++; CHECK: crcc.w.h.w $r[[REG1:[0-9]+]], $r[[REG2:[0-9]+]], $r[[REG1:[0-9]+]] ++; CHECK: jr $ra ++; ++ ++define void @crcc_w_w_w() { ++entry: ++ %i32_r = alloca i32, align 4 ++ %i32_a = alloca i32, align 4 ++ %i32_b = alloca i32, align 4 ++ %0 = load i32, i32* %i32_a, align 4 ++ %1 = load i32, i32* %i32_b, align 4 ++ %2 = call i32 @llvm.loongarch.crcc.w.w.w(i32 %0, i32 %1) ++ store i32 %2, i32* %i32_r, align 4 ++ ret void ++} ++ ++declare i32 @llvm.loongarch.crcc.w.w.w(i32, i32) ++ ++; CHECK-LABEL: crcc_w_w_w: ++; CHECK: ld.w $r[[REG1:[0-9]+]], $sp, 4 ++; CHECK: ld.w $r[[REG2:[0-9]+]], $sp, 8 ++; CHECK: crcc.w.w.w $r[[REG1:[0-9]+]], $r[[REG2:[0-9]+]], $r[[REG1:[0-9]+]] ++; CHECK: jr $ra ++; ++ ++define void @crcc_w_d_w() { ++entry: ++ %i32_r = alloca i32, align 4 ++ %i32_a = alloca i32, align 4 ++ %i64_a = alloca i64, align 8 ++ %0 = load i64, i64* %i64_a, align 8 ++ %1 = load i32, i32* %i32_a, align 4 ++ %2 = call i32 @llvm.loongarch.crcc.w.d.w(i64 %0, i32 %1) ++ store i32 %2, i32* %i32_r, align 4 ++ ret void ++} ++ ++declare i32 @llvm.loongarch.crcc.w.d.w(i64, i32) ++ ++; CHECK-LABEL: crcc_w_d_w: ++; CHECK: ld.w $r[[REG1:[0-9]+]], $sp, 8 ++; CHECK: ld.d $r[[REG2:[0-9]+]], $sp, 0 ++; CHECK: crcc.w.d.w $r[[REG1:[0-9]+]], $r[[REG2:[0-9]+]], $r[[REG1:[0-9]+]] ++; CHECK: jr $ra ++; ++ ++define void @tlbclr() { ++entry: ++ call void @llvm.loongarch.tlbclr() ++ ret void ++} ++ ++declare void @llvm.loongarch.tlbclr() ++ ++; CHECK-LABEL: tlbclr: ++; CHECK: tlbclr ++; CHECK: jr $ra ++; ++ ++define void @tlbflush() { ++entry: ++ call void @llvm.loongarch.tlbflush() ++ ret void ++} ++ ++declare void @llvm.loongarch.tlbflush() ++ ++; CHECK-LABEL: tlbflush: ++; CHECK: tlbflush ++; CHECK: jr $ra ++; ++ ++define void @tlbfill() { ++entry: ++ call void @llvm.loongarch.tlbfill() ++ ret void ++} ++ ++declare void @llvm.loongarch.tlbfill() ++ ++; CHECK-LABEL: tlbfill: ++; CHECK: tlbfill ++; CHECK: jr $ra ++; ++ ++define void @tlbrd() { ++entry: ++ call void @llvm.loongarch.tlbrd() ++ ret void ++} ++ ++declare void @llvm.loongarch.tlbrd() ++ ++; CHECK-LABEL: tlbrd: ++; CHECK: tlbrd ++; CHECK: jr $ra ++; ++ ++define void @tlbwr() { ++entry: ++ call void @llvm.loongarch.tlbwr() ++ ret void ++} ++ ++declare void @llvm.loongarch.tlbwr() ++ ++; CHECK-LABEL: tlbwr: ++; CHECK: tlbwr ++; CHECK: jr $ra ++; ++ ++define void @tlbsrch() { ++entry: ++ call void @llvm.loongarch.tlbsrch() ++ ret void ++} ++ ++declare void @llvm.loongarch.tlbsrch() ++ ++; CHECK-LABEL: tlbsrch: ++; CHECK: tlbsrch ++; CHECK: jr $ra ++; ++ ++define void @syscall() { ++entry: ++ call void @llvm.loongarch.syscall(i64 1) ++ ret void ++} ++ ++declare void @llvm.loongarch.syscall(i64) ++ ++; CHECK-LABEL: syscall: ++; CHECK: syscall 1 ++; CHECK: jr $ra ++; ++ ++define void @break_builtin() { ++entry: ++ call void @llvm.loongarch.break(i64 1) ++ ret void ++} ++ ++declare void @llvm.loongarch.break(i64) ++ ++; CHECK-LABEL: break_builtin: ++; CHECK: break 1 ++; CHECK: jr $ra ++; ++ ++define void @asrtle_d() { ++entry: ++ %i64_a = alloca i64, align 8 ++ %i64_b = alloca i64, align 8 ++ %0 = load i64, i64* %i64_a, align 8 ++ %1 = load i64, i64* %i64_b, align 8 ++ call void @llvm.loongarch.asrtle.d(i64 %0, i64 %1) ++ ret void ++} ++ ++declare void @llvm.loongarch.asrtle.d(i64, i64) ++ ++; CHECK-LABEL: asrtle_d: ++; CHECK: ld.d $r[[REG1:[0-9]+]], $sp, 0 ++; CHECK: ld.d $r[[REG2:[0-9]+]], $sp, 8 ++; CHECK: asrtle.d $r[[REG2:[0-9]+]], $r[[REG1:[0-9]+]] ++; CHECK: jr $ra ++; ++ ++define void @asrtgt_d() { ++entry: ++ %i64_a = alloca i64, align 8 ++ %i64_b = alloca i64, align 8 ++ %0 = load i64, i64* %i64_a, align 8 ++ %1 = load i64, i64* %i64_b, align 8 ++ call void @llvm.loongarch.asrtgt.d(i64 %0, i64 %1) ++ ret void ++} ++ ++declare void @llvm.loongarch.asrtgt.d(i64, i64) ++ ++; CHECK-LABEL: asrtgt_d: ++; CHECK: ld.d $r[[REG1:[0-9]+]], $sp, 0 ++; CHECK: ld.d $r[[REG2:[0-9]+]], $sp, 8 ++; CHECK: asrtgt.d $r[[REG2:[0-9]+]], $r[[REG1:[0-9]+]] ++; CHECK: jr $ra ++; ++ ++define void @dbar() { ++entry: ++ call void @llvm.loongarch.dbar(i64 0) ++ ret void ++} ++ ++declare void @llvm.loongarch.dbar(i64) ++ ++; CHECK-LABEL: dbar: ++; CHECK: dbar 0 ++; CHECK: jr $ra ++; ++ ++define void @ibar() { ++entry: ++ call void @llvm.loongarch.ibar(i64 0) ++ ret void ++} ++ ++declare void @llvm.loongarch.ibar(i64) ++ ++; CHECK-LABEL: ibar: ++; CHECK: ibar 0 ++; CHECK: jr $ra ++; ++ ++define void @movfcsr2gr() { ++entry: ++ %u32_r = alloca i32, align 4 ++ %rd = alloca i32, align 4 ++ %0 = call i32 asm sideeffect "movfcsr2gr $0, $$fcsr0", "=&r"() ++ store i32 %0, i32* %rd, align 4 ++ %1 = load i32, i32* %rd, align 4 ++ store i32 %1, i32* %u32_r, align 4 ++ ret void ++} ++ ++; CHECK-LABEL: movfcsr2gr: ++; CHECK: movfcsr2gr $r[[REG:[0-9]+]], $fcsr[[REG:[0-9]+]] ++; CHECK: st.w $r[[REG:[0-9]+]], $sp, 8 ++; CHECK: st.w $r[[REG:[0-9]+]], $sp, 12 ++; CHECK: jr $ra ++; ++ ++define void @movgr2fcsr() { ++entry: ++ %u32_a = alloca i32, align 4 ++ %0 = load i32, i32* %u32_a, align 4 ++ call void asm sideeffect "movgr2fcsr $$fcsr0, $0", "r"(i32 %0) ++ ret void ++} ++ ++; CHECK-LABEL: movgr2fcsr: ++; CHECK: ld.w $r[[REG:[0-9]+]], $sp, 12 ++; CHECK: movgr2fcsr $fcsr[[REG:[0-9]+]], $r[[REG:[0-9]+]] ++; CHECK: jr $ra ++; +diff --git a/llvm/test/CodeGen/LoongArch/bytepick.ll b/llvm/test/CodeGen/LoongArch/bytepick.ll +deleted file mode 100644 +index 86148b374..000000000 +--- a/llvm/test/CodeGen/LoongArch/bytepick.ll ++++ /dev/null +@@ -1,258 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --verify-machineinstrs < %s \ +-; RUN: | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s \ +-; RUN: | FileCheck %s --check-prefix=LA64 +- +-;; a=00112233 b=44556677 +-;; expected 11223344 +-define i32 @pick_i32_1(i32 %a, i32 %b) { +-; LA32-LABEL: pick_i32_1: +-; LA32: # %bb.0: +-; LA32-NEXT: bytepick.w $a0, $a1, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: pick_i32_1: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a0, $a0, 8 +-; LA64-NEXT: bstrpick.d $a1, $a1, 31, 24 +-; LA64-NEXT: or $a0, $a1, $a0 +-; LA64-NEXT: ret +- %1 = lshr i32 %b, 24 +- %2 = shl i32 %a, 8 +- %3 = or i32 %1, %2 +- ret i32 %3 +-} +- +-;; a=00112233 b=44556677 +-;; expected 11223344 +-define signext i32 @pick_i32_1_sext(i32 %a, i32 %b) { +-; LA32-LABEL: pick_i32_1_sext: +-; LA32: # %bb.0: +-; LA32-NEXT: bytepick.w $a0, $a1, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: pick_i32_1_sext: +-; LA64: # %bb.0: +-; LA64-NEXT: bytepick.w $a0, $a1, $a0, 1 +-; LA64-NEXT: ret +- %1 = lshr i32 %b, 24 +- %2 = shl i32 %a, 8 +- %3 = or i32 %1, %2 +- ret i32 %3 +-} +- +-;; a=00112233 b=44556677 +-;; expected 22334455 +-define i32 @pick_i32_2(i32 %a, i32 %b) { +-; LA32-LABEL: pick_i32_2: +-; LA32: # %bb.0: +-; LA32-NEXT: bytepick.w $a0, $a1, $a0, 2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: pick_i32_2: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a0, $a0, 16 +-; LA64-NEXT: bstrpick.d $a1, $a1, 31, 16 +-; LA64-NEXT: or $a0, $a1, $a0 +-; LA64-NEXT: ret +- %1 = lshr i32 %b, 16 +- %2 = shl i32 %a, 16 +- %3 = or i32 %1, %2 +- ret i32 %3 +-} +- +-;; a=00112233 b=44556677 +-;; expected 22334455 +-define signext i32 @pick_i32_2_sext(i32 %a, i32 %b) { +-; LA32-LABEL: pick_i32_2_sext: +-; LA32: # %bb.0: +-; LA32-NEXT: bytepick.w $a0, $a1, $a0, 2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: pick_i32_2_sext: +-; LA64: # %bb.0: +-; LA64-NEXT: bytepick.w $a0, $a1, $a0, 2 +-; LA64-NEXT: ret +- %1 = lshr i32 %b, 16 +- %2 = shl i32 %a, 16 +- %3 = or i32 %1, %2 +- ret i32 %3 +-} +- +-;; a=00112233 b=44556677 +-;; expected 33445566 +-define i32 @pick_i32_3(i32 %a, i32 %b) { +-; LA32-LABEL: pick_i32_3: +-; LA32: # %bb.0: +-; LA32-NEXT: bytepick.w $a0, $a1, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: pick_i32_3: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a0, $a0, 24 +-; LA64-NEXT: bstrpick.d $a1, $a1, 31, 8 +-; LA64-NEXT: or $a0, $a1, $a0 +-; LA64-NEXT: ret +- %1 = lshr i32 %b, 8 +- %2 = shl i32 %a, 24 +- %3 = or i32 %1, %2 +- ret i32 %3 +-} +- +-;; a=00112233 b=44556677 +-;; expected 33445566 +-define signext i32 @pick_i32_3_sext(i32 %a, i32 %b) { +-; LA32-LABEL: pick_i32_3_sext: +-; LA32: # %bb.0: +-; LA32-NEXT: bytepick.w $a0, $a1, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: pick_i32_3_sext: +-; LA64: # %bb.0: +-; LA64-NEXT: bytepick.w $a0, $a1, $a0, 3 +-; LA64-NEXT: ret +- %1 = lshr i32 %b, 8 +- %2 = shl i32 %a, 24 +- %3 = or i32 %1, %2 +- ret i32 %3 +-} +- +-;; a=0011223344556677 b=8899aabbccddeeff +-;; expected 1122334455667788 +-define i64 @pick_i64_1(i64 %a, i64 %b) { +-; LA32-LABEL: pick_i64_1: +-; LA32: # %bb.0: +-; LA32-NEXT: bytepick.w $a2, $a3, $a0, 1 +-; LA32-NEXT: bytepick.w $a1, $a0, $a1, 1 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: pick_i64_1: +-; LA64: # %bb.0: +-; LA64-NEXT: bytepick.d $a0, $a1, $a0, 1 +-; LA64-NEXT: ret +- %1 = lshr i64 %b, 56 +- %2 = shl i64 %a, 8 +- %3 = or i64 %1, %2 +- ret i64 %3 +-} +- +-;; a=0011223344556677 b=8899aabbccddeeff +-;; expected 2233445566778899 +-define i64 @pick_i64_2(i64 %a, i64 %b) { +-; LA32-LABEL: pick_i64_2: +-; LA32: # %bb.0: +-; LA32-NEXT: bytepick.w $a2, $a3, $a0, 2 +-; LA32-NEXT: bytepick.w $a1, $a0, $a1, 2 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: pick_i64_2: +-; LA64: # %bb.0: +-; LA64-NEXT: bytepick.d $a0, $a1, $a0, 2 +-; LA64-NEXT: ret +- %1 = lshr i64 %b, 48 +- %2 = shl i64 %a, 16 +- %3 = or i64 %1, %2 +- ret i64 %3 +-} +- +-;; a=0011223344556677 b=8899aabbccddeeff +-;; expected 33445566778899aa +-define i64 @pick_i64_3(i64 %a, i64 %b) { +-; LA32-LABEL: pick_i64_3: +-; LA32: # %bb.0: +-; LA32-NEXT: bytepick.w $a2, $a3, $a0, 3 +-; LA32-NEXT: bytepick.w $a1, $a0, $a1, 3 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: pick_i64_3: +-; LA64: # %bb.0: +-; LA64-NEXT: bytepick.d $a0, $a1, $a0, 3 +-; LA64-NEXT: ret +- %1 = lshr i64 %b, 40 +- %2 = shl i64 %a, 24 +- %3 = or i64 %1, %2 +- ret i64 %3 +-} +- +-;; a=0011223344556677 b=8899aabbccddeeff +-;; expected 445566778899aabb +-define i64 @pick_i64_4(i64 %a, i64 %b) { +-; LA32-LABEL: pick_i64_4: +-; LA32: # %bb.0: +-; LA32-NEXT: move $a1, $a0 +-; LA32-NEXT: move $a0, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: pick_i64_4: +-; LA64: # %bb.0: +-; LA64-NEXT: bytepick.d $a0, $a1, $a0, 4 +-; LA64-NEXT: ret +- %1 = lshr i64 %b, 32 +- %2 = shl i64 %a, 32 +- %3 = or i64 %1, %2 +- ret i64 %3 +-} +- +-;; a=0011223344556677 b=8899aabbccddeeff +-;; expected 5566778899aabbcc +-define i64 @pick_i64_5(i64 %a, i64 %b) { +-; LA32-LABEL: pick_i64_5: +-; LA32: # %bb.0: +-; LA32-NEXT: bytepick.w $a2, $a2, $a3, 1 +-; LA32-NEXT: bytepick.w $a1, $a3, $a0, 1 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: pick_i64_5: +-; LA64: # %bb.0: +-; LA64-NEXT: bytepick.d $a0, $a1, $a0, 5 +-; LA64-NEXT: ret +- %1 = lshr i64 %b, 24 +- %2 = shl i64 %a,40 +- %3 = or i64 %1, %2 +- ret i64 %3 +-} +- +-;; a=0011223344556677 b=8899aabbccddeeff +-;; expected 66778899aabbccdd +-define i64 @pick_i64_6(i64 %a, i64 %b) { +-; LA32-LABEL: pick_i64_6: +-; LA32: # %bb.0: +-; LA32-NEXT: bytepick.w $a2, $a2, $a3, 2 +-; LA32-NEXT: bytepick.w $a1, $a3, $a0, 2 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: pick_i64_6: +-; LA64: # %bb.0: +-; LA64-NEXT: bytepick.d $a0, $a1, $a0, 6 +-; LA64-NEXT: ret +- %1 = lshr i64 %b, 16 +- %2 = shl i64 %a, 48 +- %3 = or i64 %1, %2 +- ret i64 %3 +-} +- +-;; a=0011223344556677 b=8899aabbccddeeff +-;; expected 778899aabbccddee +-define i64 @pick_i64_7(i64 %a, i64 %b) { +-; LA32-LABEL: pick_i64_7: +-; LA32: # %bb.0: +-; LA32-NEXT: bytepick.w $a2, $a2, $a3, 3 +-; LA32-NEXT: bytepick.w $a1, $a3, $a0, 3 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: pick_i64_7: +-; LA64: # %bb.0: +-; LA64-NEXT: bytepick.d $a0, $a1, $a0, 7 +-; LA64-NEXT: ret +- %1 = lshr i64 %b, 8 +- %2 = shl i64 %a, 56 +- %3 = or i64 %1, %2 +- ret i64 %3 +-} +diff --git a/llvm/test/CodeGen/LoongArch/calling-conv-common.ll b/llvm/test/CodeGen/LoongArch/calling-conv-common.ll +deleted file mode 100644 +index 08fff9f8c..000000000 +--- a/llvm/test/CodeGen/LoongArch/calling-conv-common.ll ++++ /dev/null +@@ -1,403 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --target-abi=lp64s < %s | FileCheck %s +-; RUN: llc --mtriple=loongarch64 --mattr=+d --target-abi=lp64d < %s | FileCheck %s +- +-;; This file contains tests that should have identical output for all ABIs, i.e. +-;; where no arguments are passed via floating point registers. +- +-;; Check that on LA64, i128 is passed in a pair of GPRs. +-define i64 @callee_i128_in_regs(i64 %a, i128 %b) nounwind { +-; CHECK-LABEL: callee_i128_in_regs: +-; CHECK: # %bb.0: +-; CHECK-NEXT: add.d $a0, $a0, $a1 +-; CHECK-NEXT: ret +- %b_trunc = trunc i128 %b to i64 +- %1 = add i64 %a, %b_trunc +- ret i64 %1 +-} +- +-define i64 @caller_i128_in_regs() nounwind { +-; CHECK-LABEL: caller_i128_in_regs: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: ori $a1, $zero, 2 +-; CHECK-NEXT: move $a2, $zero +-; CHECK-NEXT: bl %plt(callee_i128_in_regs) +-; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +- %1 = call i64 @callee_i128_in_regs(i64 1, i128 2) +- ret i64 %1 +-} +- +-;; Check that the stack is used once the GPRs are exhausted. +-define i64 @callee_many_scalars(i8 %a, i16 %b, i32 %c, i64 %d, i128 %e, i64 %f, i128 %g, i64 %h) nounwind { +-; CHECK-LABEL: callee_many_scalars: +-; CHECK: # %bb.0: +-; CHECK-NEXT: ld.d $t0, $sp, 0 +-; CHECK-NEXT: xor $a5, $a5, $t0 +-; CHECK-NEXT: xor $a4, $a4, $a7 +-; CHECK-NEXT: or $a4, $a4, $a5 +-; CHECK-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; CHECK-NEXT: andi $a0, $a0, 255 +-; CHECK-NEXT: add.d $a0, $a0, $a1 +-; CHECK-NEXT: bstrpick.d $a1, $a2, 31, 0 +-; CHECK-NEXT: add.d $a0, $a0, $a1 +-; CHECK-NEXT: add.d $a0, $a0, $a3 +-; CHECK-NEXT: sltui $a1, $a4, 1 +-; CHECK-NEXT: add.d $a0, $a1, $a0 +-; CHECK-NEXT: add.d $a0, $a0, $a6 +-; CHECK-NEXT: ld.d $a1, $sp, 8 +-; CHECK-NEXT: add.d $a0, $a0, $a1 +-; CHECK-NEXT: ret +- %a_ext = zext i8 %a to i64 +- %b_ext = zext i16 %b to i64 +- %c_ext = zext i32 %c to i64 +- %1 = add i64 %a_ext, %b_ext +- %2 = add i64 %1, %c_ext +- %3 = add i64 %2, %d +- %4 = icmp eq i128 %e, %g +- %5 = zext i1 %4 to i64 +- %6 = add i64 %5, %3 +- %7 = add i64 %6, %f +- %8 = add i64 %7, %h +- ret i64 %8 +-} +- +-define i64 @caller_many_scalars() nounwind { +-; CHECK-LABEL: caller_many_scalars: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -32 +-; CHECK-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill +-; CHECK-NEXT: ori $a0, $zero, 8 +-; CHECK-NEXT: st.d $a0, $sp, 8 +-; CHECK-NEXT: st.d $zero, $sp, 0 +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: ori $a1, $zero, 2 +-; CHECK-NEXT: ori $a2, $zero, 3 +-; CHECK-NEXT: ori $a3, $zero, 4 +-; CHECK-NEXT: ori $a4, $zero, 5 +-; CHECK-NEXT: ori $a6, $zero, 6 +-; CHECK-NEXT: ori $a7, $zero, 7 +-; CHECK-NEXT: move $a5, $zero +-; CHECK-NEXT: bl %plt(callee_many_scalars) +-; CHECK-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 32 +-; CHECK-NEXT: ret +- %1 = call i64 @callee_many_scalars(i8 1, i16 2, i32 3, i64 4, i128 5, i64 6, i128 7, i64 8) +- ret i64 %1 +-} +- +-;; Check that i256 is passed indirectly. +- +-define i64 @callee_large_scalars(i256 %a, i256 %b) nounwind { +-; CHECK-LABEL: callee_large_scalars: +-; CHECK: # %bb.0: +-; CHECK-NEXT: ld.d $a2, $a1, 24 +-; CHECK-NEXT: ld.d $a3, $a0, 24 +-; CHECK-NEXT: xor $a2, $a3, $a2 +-; CHECK-NEXT: ld.d $a3, $a1, 8 +-; CHECK-NEXT: ld.d $a4, $a0, 8 +-; CHECK-NEXT: xor $a3, $a4, $a3 +-; CHECK-NEXT: or $a2, $a3, $a2 +-; CHECK-NEXT: ld.d $a3, $a1, 16 +-; CHECK-NEXT: ld.d $a4, $a0, 16 +-; CHECK-NEXT: xor $a3, $a4, $a3 +-; CHECK-NEXT: ld.d $a1, $a1, 0 +-; CHECK-NEXT: ld.d $a0, $a0, 0 +-; CHECK-NEXT: xor $a0, $a0, $a1 +-; CHECK-NEXT: or $a0, $a0, $a3 +-; CHECK-NEXT: or $a0, $a0, $a2 +-; CHECK-NEXT: sltui $a0, $a0, 1 +-; CHECK-NEXT: ret +- %1 = icmp eq i256 %a, %b +- %2 = zext i1 %1 to i64 +- ret i64 %2 +-} +- +-define i64 @caller_large_scalars() nounwind { +-; CHECK-LABEL: caller_large_scalars: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -80 +-; CHECK-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; CHECK-NEXT: ori $a0, $zero, 2 +-; CHECK-NEXT: st.d $a0, $sp, 0 +-; CHECK-NEXT: st.d $zero, $sp, 24 +-; CHECK-NEXT: st.d $zero, $sp, 16 +-; CHECK-NEXT: st.d $zero, $sp, 8 +-; CHECK-NEXT: st.d $zero, $sp, 56 +-; CHECK-NEXT: st.d $zero, $sp, 48 +-; CHECK-NEXT: st.d $zero, $sp, 40 +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: st.d $a0, $sp, 32 +-; CHECK-NEXT: addi.d $a0, $sp, 32 +-; CHECK-NEXT: addi.d $a1, $sp, 0 +-; CHECK-NEXT: bl %plt(callee_large_scalars) +-; CHECK-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 80 +-; CHECK-NEXT: ret +- %1 = call i64 @callee_large_scalars(i256 1, i256 2) +- ret i64 %1 +-} +- +-;; Check that arguments larger than 2*GRLen are handled correctly when their +-;; address is passed on the stack rather than in memory. +- +-;; Must keep define on a single line due to an update_llc_test_checks.py limitation +-define i64 @callee_large_scalars_exhausted_regs(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e, i64 %f, i64 %g, i256 %h, i64 %i, i256 %j) nounwind { +-; CHECK-LABEL: callee_large_scalars_exhausted_regs: +-; CHECK: # %bb.0: +-; CHECK-NEXT: ld.d $a0, $sp, 8 +-; CHECK-NEXT: ld.d $a1, $a0, 24 +-; CHECK-NEXT: ld.d $a2, $a7, 24 +-; CHECK-NEXT: xor $a1, $a2, $a1 +-; CHECK-NEXT: ld.d $a2, $a0, 8 +-; CHECK-NEXT: ld.d $a3, $a7, 8 +-; CHECK-NEXT: xor $a2, $a3, $a2 +-; CHECK-NEXT: or $a1, $a2, $a1 +-; CHECK-NEXT: ld.d $a2, $a0, 16 +-; CHECK-NEXT: ld.d $a3, $a7, 16 +-; CHECK-NEXT: xor $a2, $a3, $a2 +-; CHECK-NEXT: ld.d $a0, $a0, 0 +-; CHECK-NEXT: ld.d $a3, $a7, 0 +-; CHECK-NEXT: xor $a0, $a3, $a0 +-; CHECK-NEXT: or $a0, $a0, $a2 +-; CHECK-NEXT: or $a0, $a0, $a1 +-; CHECK-NEXT: sltui $a0, $a0, 1 +-; CHECK-NEXT: ret +- %1 = icmp eq i256 %h, %j +- %2 = zext i1 %1 to i64 +- ret i64 %2 +-} +- +-define i64 @caller_large_scalars_exhausted_regs() nounwind { +-; CHECK-LABEL: caller_large_scalars_exhausted_regs: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -96 +-; CHECK-NEXT: st.d $ra, $sp, 88 # 8-byte Folded Spill +-; CHECK-NEXT: addi.d $a0, $sp, 16 +-; CHECK-NEXT: st.d $a0, $sp, 8 +-; CHECK-NEXT: ori $a0, $zero, 9 +-; CHECK-NEXT: st.d $a0, $sp, 0 +-; CHECK-NEXT: ori $a0, $zero, 10 +-; CHECK-NEXT: st.d $a0, $sp, 16 +-; CHECK-NEXT: st.d $zero, $sp, 40 +-; CHECK-NEXT: st.d $zero, $sp, 32 +-; CHECK-NEXT: st.d $zero, $sp, 24 +-; CHECK-NEXT: st.d $zero, $sp, 72 +-; CHECK-NEXT: st.d $zero, $sp, 64 +-; CHECK-NEXT: st.d $zero, $sp, 56 +-; CHECK-NEXT: ori $a0, $zero, 8 +-; CHECK-NEXT: st.d $a0, $sp, 48 +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: ori $a1, $zero, 2 +-; CHECK-NEXT: ori $a2, $zero, 3 +-; CHECK-NEXT: ori $a3, $zero, 4 +-; CHECK-NEXT: ori $a4, $zero, 5 +-; CHECK-NEXT: ori $a5, $zero, 6 +-; CHECK-NEXT: ori $a6, $zero, 7 +-; CHECK-NEXT: addi.d $a7, $sp, 48 +-; CHECK-NEXT: bl %plt(callee_large_scalars_exhausted_regs) +-; CHECK-NEXT: ld.d $ra, $sp, 88 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 96 +-; CHECK-NEXT: ret +- %1 = call i64 @callee_large_scalars_exhausted_regs( +- i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i256 8, i64 9, +- i256 10) +- ret i64 %1 +-} +- +-;; Check large struct arguments, which are passed byval +- +-%struct.large = type { i64, i64, i64, i64 } +- +-define i64 @callee_large_struct(ptr byval(%struct.large) align 8 %a) nounwind { +-; CHECK-LABEL: callee_large_struct: +-; CHECK: # %bb.0: +-; CHECK-NEXT: ld.d $a1, $a0, 24 +-; CHECK-NEXT: ld.d $a0, $a0, 0 +-; CHECK-NEXT: add.d $a0, $a0, $a1 +-; CHECK-NEXT: ret +- %1 = getelementptr inbounds %struct.large, ptr %a, i64 0, i32 0 +- %2 = getelementptr inbounds %struct.large, ptr %a, i64 0, i32 3 +- %3 = load i64, ptr %1 +- %4 = load i64, ptr %2 +- %5 = add i64 %3, %4 +- ret i64 %5 +-} +- +-define i64 @caller_large_struct() nounwind { +-; CHECK-LABEL: caller_large_struct: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -80 +-; CHECK-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: st.d $a0, $sp, 40 +-; CHECK-NEXT: st.d $a0, $sp, 8 +-; CHECK-NEXT: ori $a0, $zero, 2 +-; CHECK-NEXT: st.d $a0, $sp, 48 +-; CHECK-NEXT: st.d $a0, $sp, 16 +-; CHECK-NEXT: ori $a0, $zero, 3 +-; CHECK-NEXT: st.d $a0, $sp, 56 +-; CHECK-NEXT: st.d $a0, $sp, 24 +-; CHECK-NEXT: ori $a0, $zero, 4 +-; CHECK-NEXT: st.d $a0, $sp, 64 +-; CHECK-NEXT: st.d $a0, $sp, 32 +-; CHECK-NEXT: addi.d $a0, $sp, 8 +-; CHECK-NEXT: bl %plt(callee_large_struct) +-; CHECK-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 80 +-; CHECK-NEXT: ret +- %ls = alloca %struct.large, align 8 +- %a = getelementptr inbounds %struct.large, ptr %ls, i64 0, i32 0 +- store i64 1, ptr %a +- %b = getelementptr inbounds %struct.large, ptr %ls, i64 0, i32 1 +- store i64 2, ptr %b +- %c = getelementptr inbounds %struct.large, ptr %ls, i64 0, i32 2 +- store i64 3, ptr %c +- %d = getelementptr inbounds %struct.large, ptr %ls, i64 0, i32 3 +- store i64 4, ptr %d +- %1 = call i64 @callee_large_struct(ptr byval(%struct.large) align 8 %ls) +- ret i64 %1 +-} +- +-;; Check return scalar which size is 2*GRLen. +- +-define i128 @callee_small_scalar_ret() nounwind { +-; CHECK-LABEL: callee_small_scalar_ret: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.w $a0, $zero, -1 +-; CHECK-NEXT: move $a1, $a0 +-; CHECK-NEXT: ret +- ret i128 -1 +-} +- +-define i64 @caller_small_scalar_ret() nounwind { +-; CHECK-LABEL: caller_small_scalar_ret: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; CHECK-NEXT: bl %plt(callee_small_scalar_ret) +-; CHECK-NEXT: addi.w $a2, $zero, -2 +-; CHECK-NEXT: xor $a0, $a0, $a2 +-; CHECK-NEXT: orn $a0, $a0, $a1 +-; CHECK-NEXT: sltui $a0, $a0, 1 +-; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +- %1 = call i128 @callee_small_scalar_ret() +- %2 = icmp eq i128 -2, %1 +- %3 = zext i1 %2 to i64 +- ret i64 %3 +-} +- +-;; Check return struct which size is 2*GRLen. +- +-%struct.small = type { i64, ptr } +- +-define %struct.small @callee_small_struct_ret() nounwind { +-; CHECK-LABEL: callee_small_struct_ret: +-; CHECK: # %bb.0: +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: move $a1, $zero +-; CHECK-NEXT: ret +- ret %struct.small { i64 1, ptr null } +-} +- +-define i64 @caller_small_struct_ret() nounwind { +-; CHECK-LABEL: caller_small_struct_ret: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; CHECK-NEXT: bl %plt(callee_small_struct_ret) +-; CHECK-NEXT: add.d $a0, $a0, $a1 +-; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +- %1 = call %struct.small @callee_small_struct_ret() +- %2 = extractvalue %struct.small %1, 0 +- %3 = extractvalue %struct.small %1, 1 +- %4 = ptrtoint ptr %3 to i64 +- %5 = add i64 %2, %4 +- ret i64 %5 +-} +- +-;; Check return scalar which size is more than 2*GRLen. +- +-define i256 @callee_large_scalar_ret() nounwind { +-; CHECK-LABEL: callee_large_scalar_ret: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.w $a1, $zero, -1 +-; CHECK-NEXT: st.d $a1, $a0, 24 +-; CHECK-NEXT: st.d $a1, $a0, 16 +-; CHECK-NEXT: st.d $a1, $a0, 8 +-; CHECK-NEXT: lu12i.w $a1, -30141 +-; CHECK-NEXT: ori $a1, $a1, 747 +-; CHECK-NEXT: st.d $a1, $a0, 0 +-; CHECK-NEXT: ret +- ret i256 -123456789 +-} +- +-define void @caller_large_scalar_ret() nounwind { +-; CHECK-LABEL: caller_large_scalar_ret: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -48 +-; CHECK-NEXT: st.d $ra, $sp, 40 # 8-byte Folded Spill +-; CHECK-NEXT: addi.d $a0, $sp, 0 +-; CHECK-NEXT: bl %plt(callee_large_scalar_ret) +-; CHECK-NEXT: ld.d $ra, $sp, 40 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 48 +-; CHECK-NEXT: ret +- %1 = call i256 @callee_large_scalar_ret() +- ret void +-} +- +-;; Check return struct which size is more than 2*GRLen. +- +-define void @callee_large_struct_ret(ptr noalias sret(%struct.large) %agg.result) nounwind { +-; CHECK-LABEL: callee_large_struct_ret: +-; CHECK: # %bb.0: +-; CHECK-NEXT: ori $a1, $zero, 4 +-; CHECK-NEXT: st.d $a1, $a0, 24 +-; CHECK-NEXT: ori $a1, $zero, 3 +-; CHECK-NEXT: st.d $a1, $a0, 16 +-; CHECK-NEXT: ori $a1, $zero, 2 +-; CHECK-NEXT: st.d $a1, $a0, 8 +-; CHECK-NEXT: ori $a1, $zero, 1 +-; CHECK-NEXT: st.d $a1, $a0, 0 +-; CHECK-NEXT: ret +- %a = getelementptr inbounds %struct.large, ptr %agg.result, i64 0, i32 0 +- store i64 1, ptr %a, align 4 +- %b = getelementptr inbounds %struct.large, ptr %agg.result, i64 0, i32 1 +- store i64 2, ptr %b, align 4 +- %c = getelementptr inbounds %struct.large, ptr %agg.result, i64 0, i32 2 +- store i64 3, ptr %c, align 4 +- %d = getelementptr inbounds %struct.large, ptr %agg.result, i64 0, i32 3 +- store i64 4, ptr %d, align 4 +- ret void +-} +- +-define i64 @caller_large_struct_ret() nounwind { +-; CHECK-LABEL: caller_large_struct_ret: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -48 +-; CHECK-NEXT: st.d $ra, $sp, 40 # 8-byte Folded Spill +-; CHECK-NEXT: addi.d $a0, $sp, 8 +-; CHECK-NEXT: bl %plt(callee_large_struct_ret) +-; CHECK-NEXT: ld.d $a0, $sp, 32 +-; CHECK-NEXT: ld.d $a1, $sp, 8 +-; CHECK-NEXT: add.d $a0, $a1, $a0 +-; CHECK-NEXT: ld.d $ra, $sp, 40 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 48 +-; CHECK-NEXT: ret +- %1 = alloca %struct.large +- call void @callee_large_struct_ret(ptr sret(%struct.large) %1) +- %2 = getelementptr inbounds %struct.large, ptr %1, i64 0, i32 0 +- %3 = load i64, ptr %2 +- %4 = getelementptr inbounds %struct.large, ptr %1, i64 0, i32 3 +- %5 = load i64, ptr %4 +- %6 = add i64 %3, %5 +- ret i64 %6 +-} +diff --git a/llvm/test/CodeGen/LoongArch/calling-conv-lp64d.ll b/llvm/test/CodeGen/LoongArch/calling-conv-lp64d.ll +deleted file mode 100644 +index ceb38876c..000000000 +--- a/llvm/test/CodeGen/LoongArch/calling-conv-lp64d.ll ++++ /dev/null +@@ -1,128 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+d --target-abi=lp64d < %s \ +-; RUN: | FileCheck %s +- +-;; This file contains specific tests for the lp64d ABI. +- +-;; Check pass floating-point arguments whith FPRs. +- +-define i64 @callee_float_in_fpr(i64 %a, float %b, double %c) nounwind { +-; CHECK-LABEL: callee_float_in_fpr: +-; CHECK: # %bb.0: +-; CHECK-NEXT: ftintrz.l.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.d $a1, $fa0 +-; CHECK-NEXT: add.d $a0, $a0, $a1 +-; CHECK-NEXT: ftintrz.l.d $fa0, $fa1 +-; CHECK-NEXT: movfr2gr.d $a1, $fa0 +-; CHECK-NEXT: add.d $a0, $a0, $a1 +-; CHECK-NEXT: ret +- %b_fptosi = fptosi float %b to i64 +- %c_fptosi = fptosi double %c to i64 +- %1 = add i64 %a, %b_fptosi +- %2 = add i64 %1, %c_fptosi +- ret i64 %2 +-} +- +-define i64 @caller_float_in_fpr() nounwind { +-; CHECK-LABEL: caller_float_in_fpr: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: movgr2fr.w $fa0, $zero +-; CHECK-NEXT: movgr2fr.d $fa1, $zero +-; CHECK-NEXT: bl %plt(callee_float_in_fpr) +-; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +- %1 = call i64 @callee_float_in_fpr(i64 1, float 0.0, double 0.0) +- ret i64 %1 +-} +- +-;; Check that the GPR is used once the FPRs are exhausted. +- +-;; Must keep define on a single line due to an update_llc_test_checks.py limitation. +-define i64 @callee_double_in_gpr_exhausted_fprs(double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i) nounwind { +-; CHECK-LABEL: callee_double_in_gpr_exhausted_fprs: +-; CHECK: # %bb.0: +-; CHECK-NEXT: ftintrz.l.d $fa0, $fa7 +-; CHECK-NEXT: movfr2gr.d $a1, $fa0 +-; CHECK-NEXT: movgr2fr.d $fa0, $a0 +-; CHECK-NEXT: ftintrz.l.d $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK-NEXT: add.d $a0, $a1, $a0 +-; CHECK-NEXT: ret +- %h_fptosi = fptosi double %h to i64 +- %i_fptosi = fptosi double %i to i64 +- %1 = add i64 %h_fptosi, %i_fptosi +- ret i64 %1 +-} +- +-define i64 @caller_double_in_gpr_exhausted_fprs() nounwind { +-; CHECK-LABEL: caller_double_in_gpr_exhausted_fprs: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI3_0) +-; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI3_0) +-; CHECK-NEXT: fld.d $fa1, $a0, 0 +-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI3_1) +-; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI3_1) +-; CHECK-NEXT: fld.d $fa2, $a0, 0 +-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI3_2) +-; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI3_2) +-; CHECK-NEXT: fld.d $fa3, $a0, 0 +-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI3_3) +-; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI3_3) +-; CHECK-NEXT: fld.d $fa4, $a0, 0 +-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI3_4) +-; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI3_4) +-; CHECK-NEXT: fld.d $fa5, $a0, 0 +-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI3_5) +-; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI3_5) +-; CHECK-NEXT: fld.d $fa6, $a0, 0 +-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI3_6) +-; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI3_6) +-; CHECK-NEXT: fld.d $fa7, $a0, 0 +-; CHECK-NEXT: addi.d $a0, $zero, 1 +-; CHECK-NEXT: movgr2fr.d $fa0, $a0 +-; CHECK-NEXT: ffint.d.l $fa0, $fa0 +-; CHECK-NEXT: ori $a0, $zero, 0 +-; CHECK-NEXT: lu32i.d $a0, 131072 +-; CHECK-NEXT: lu52i.d $a0, $a0, 1026 +-; CHECK-NEXT: bl %plt(callee_double_in_gpr_exhausted_fprs) +-; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +- %1 = call i64 @callee_double_in_gpr_exhausted_fprs( +- double 1.0, double 2.0, double 3.0, double 4.0, double 5.0, double 6.0, +- double 7.0, double 8.0, double 9.0) +- ret i64 %1 +-} +- +-;; Check returning doubles. +- +-define double @callee_double_ret() nounwind { +-; CHECK-LABEL: callee_double_ret: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $a0, $zero, 1 +-; CHECK-NEXT: movgr2fr.d $fa0, $a0 +-; CHECK-NEXT: ffint.d.l $fa0, $fa0 +-; CHECK-NEXT: ret +- ret double 1.0 +-} +- +-define i64 @caller_double_ret() nounwind { +-; CHECK-LABEL: caller_double_ret: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; CHECK-NEXT: bl %plt(callee_double_ret) +-; CHECK-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +- %1 = call double @callee_double_ret() +- %2 = bitcast double %1 to i64 +- ret i64 %2 +-} +diff --git a/llvm/test/CodeGen/LoongArch/calling-conv-lp64s.ll b/llvm/test/CodeGen/LoongArch/calling-conv-lp64s.ll +deleted file mode 100644 +index d738c066e..000000000 +--- a/llvm/test/CodeGen/LoongArch/calling-conv-lp64s.ll ++++ /dev/null +@@ -1,97 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 +-; RUN: llc --mtriple=loongarch64 --target-abi=lp64s < %s | FileCheck %s +- +-;; This file contains specific tests for the lp64s ABI. +- +-define i64 @callee_float_in_regs(i64 %a, float %b) nounwind { +-; CHECK-LABEL: callee_float_in_regs: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $fp, $sp, 0 # 8-byte Folded Spill +-; CHECK-NEXT: move $fp, $a0 +-; CHECK-NEXT: bstrpick.d $a0, $a1, 31, 0 +-; CHECK-NEXT: bl %plt(__fixsfdi) +-; CHECK-NEXT: add.d $a0, $fp, $a0 +-; CHECK-NEXT: ld.d $fp, $sp, 0 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +- %b_fptosi = fptosi float %b to i64 +- %1 = add i64 %a, %b_fptosi +- ret i64 %1 +-} +- +-define i64 @caller_float_in_regs() nounwind { +-; CHECK-LABEL: caller_float_in_regs: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: lu12i.w $a1, 262144 +-; CHECK-NEXT: bl %plt(callee_float_in_regs) +-; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +- %1 = call i64 @callee_float_in_regs(i64 1, float 2.0) +- ret i64 %1 +-} +- +-define i64 @callee_float_on_stack(i128 %a, i128 %b, i128 %c, i128 %d, float %e) nounwind { +-; CHECK-LABEL: callee_float_on_stack: +-; CHECK: # %bb.0: +-; CHECK-NEXT: ld.w $a0, $sp, 0 +-; CHECK-NEXT: ret +- %1 = trunc i128 %d to i64 +- %2 = bitcast float %e to i32 +- %3 = sext i32 %2 to i64 +- %4 = add i64 %1, %3 +- ret i64 %3 +-} +- +-define i64 @caller_float_on_stack() nounwind { +-; CHECK-LABEL: caller_float_on_stack: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; CHECK-NEXT: lu12i.w $a0, 264704 +-; CHECK-NEXT: st.d $a0, $sp, 0 +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: ori $a2, $zero, 2 +-; CHECK-NEXT: ori $a4, $zero, 3 +-; CHECK-NEXT: ori $a6, $zero, 4 +-; CHECK-NEXT: move $a1, $zero +-; CHECK-NEXT: move $a3, $zero +-; CHECK-NEXT: move $a5, $zero +-; CHECK-NEXT: move $a7, $zero +-; CHECK-NEXT: bl %plt(callee_float_on_stack) +-; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +- %1 = call i64 @callee_float_on_stack(i128 1, i128 2, i128 3, i128 4, float 5.0) +- ret i64 %1 +-} +- +-define float @callee_tiny_scalar_ret() nounwind { +-; CHECK-LABEL: callee_tiny_scalar_ret: +-; CHECK: # %bb.0: +-; CHECK-NEXT: lu12i.w $a0, 260096 +-; CHECK-NEXT: ret +- ret float 1.0 +-} +- +-define i64 @caller_tiny_scalar_ret() nounwind { +-; CHECK-LABEL: caller_tiny_scalar_ret: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; CHECK-NEXT: bl %plt(callee_tiny_scalar_ret) +-; CHECK-NEXT: addi.w $a0, $a0, 0 +-; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +- %1 = call float @callee_tiny_scalar_ret() +- %2 = bitcast float %1 to i32 +- %3 = sext i32 %2 to i64 +- ret i64 %3 +-} +diff --git a/llvm/test/CodeGen/LoongArch/can-not-realign-stack.ll b/llvm/test/CodeGen/LoongArch/can-not-realign-stack.ll +deleted file mode 100644 +index af24ae64b..000000000 +--- a/llvm/test/CodeGen/LoongArch/can-not-realign-stack.ll ++++ /dev/null +@@ -1,85 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --frame-pointer=none --mattr=+lasx < %s | FileCheck %s +- +-;; This test is checking that when a function allows stack realignment and +-;; realignment needs were not detected before register allocation (at this +-;; point, fp is not preserved), but realignment is required during register +-;; allocation, the stack should not undergo realignment. +- +-;; Ensure that the `bstrins.d $sp, $zero, n, 0` instruction is not generated. +-;; n = log2(realign_size) - 1 +- +-%struct.S = type { [64 x i16] } +- +-define dso_local noundef signext i32 @main() nounwind { +-; CHECK-LABEL: main: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: addi.d $sp, $sp, -272 +-; CHECK-NEXT: st.d $ra, $sp, 264 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $fp, $sp, 256 # 8-byte Folded Spill +-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI0_0) +-; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI0_0) +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvst $xr0, $sp, 96 # 32-byte Folded Spill +-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI0_1) +-; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI0_1) +-; CHECK-NEXT: xvld $xr1, $a0, 0 +-; CHECK-NEXT: xvst $xr1, $sp, 64 # 32-byte Folded Spill +-; CHECK-NEXT: xvst $xr1, $sp, 224 +-; CHECK-NEXT: xvst $xr0, $sp, 192 +-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI0_2) +-; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI0_2) +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvst $xr0, $sp, 32 # 32-byte Folded Spill +-; CHECK-NEXT: xvst $xr0, $sp, 160 +-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI0_3) +-; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI0_3) +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvst $xr0, $sp, 0 # 32-byte Folded Spill +-; CHECK-NEXT: xvst $xr0, $sp, 128 +-; CHECK-NEXT: addi.d $fp, $sp, 128 +-; CHECK-NEXT: move $a0, $fp +-; CHECK-NEXT: bl %plt(foo) +-; CHECK-NEXT: xvld $xr0, $sp, 64 # 32-byte Folded Reload +-; CHECK-NEXT: xvst $xr0, $sp, 224 +-; CHECK-NEXT: xvld $xr0, $sp, 96 # 32-byte Folded Reload +-; CHECK-NEXT: xvst $xr0, $sp, 192 +-; CHECK-NEXT: xvld $xr0, $sp, 32 # 32-byte Folded Reload +-; CHECK-NEXT: xvst $xr0, $sp, 160 +-; CHECK-NEXT: xvld $xr0, $sp, 0 # 32-byte Folded Reload +-; CHECK-NEXT: xvst $xr0, $sp, 128 +-; CHECK-NEXT: move $a0, $fp +-; CHECK-NEXT: bl %plt(bar) +-; CHECK-NEXT: move $a0, $zero +-; CHECK-NEXT: ld.d $fp, $sp, 256 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $ra, $sp, 264 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 272 +-; CHECK-NEXT: ret +-entry: +- %s = alloca %struct.S, align 2 +- call void @llvm.lifetime.start.p0(i64 128, ptr nonnull %s) +- store <16 x i16> , ptr %s, align 2 +- %0 = getelementptr inbounds [64 x i16], ptr %s, i64 0, i64 16 +- store <16 x i16> , ptr %0, align 2 +- %1 = getelementptr inbounds [64 x i16], ptr %s, i64 0, i64 32 +- store <16 x i16> , ptr %1, align 2 +- %2 = getelementptr inbounds [64 x i16], ptr %s, i64 0, i64 48 +- store <16 x i16> , ptr %2, align 2 +- call void @foo(ptr noundef nonnull %s) +- store <16 x i16> , ptr %s, align 2 +- %3 = getelementptr inbounds [64 x i16], ptr %s, i64 0, i64 16 +- store <16 x i16> , ptr %3, align 2 +- %4 = getelementptr inbounds [64 x i16], ptr %s, i64 0, i64 32 +- store <16 x i16> , ptr %4, align 2 +- %5 = getelementptr inbounds [64 x i16], ptr %s, i64 0, i64 48 +- store <16 x i16> , ptr %5, align 2 +- call void @bar(ptr noundef nonnull %s) +- call void @llvm.lifetime.end.p0(i64 128, ptr nonnull %s) +- ret i32 0 +-} +- +-declare void @foo(ptr nocapture noundef) +-declare void @bar(ptr nocapture noundef) +- +-declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) +-declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) +diff --git a/llvm/test/CodeGen/LoongArch/cfr-copy.mir b/llvm/test/CodeGen/LoongArch/cfr-copy.mir +deleted file mode 100644 +index 4224c9908..000000000 +--- a/llvm/test/CodeGen/LoongArch/cfr-copy.mir ++++ /dev/null +@@ -1,34 +0,0 @@ +-# NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-# RUN: llc --mtriple=loongarch64 --mattr=+d %s -o - | FileCheck %s +- +-## Check the PseudoCopyCFR instruction expand. +- +---- | +- target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128" +- target triple = "loongarch64" +- +- define void @test() { +- ; CHECK-LABEL: test: +- ; CHECK: # %bb.0: +- ; CHECK-NEXT: fcmp.caf.s $fcc1, $fa0, $fa0 +- ; CHECK-NEXT: bceqz $fcc0, .LBB0_2 +- ; CHECK-NEXT: # %bb.1: +- ; CHECK-NEXT: fcmp.cueq.s $fcc1, $fa0, $fa0 +- ; CHECK-NEXT: .LBB0_2: +- ; CHECK-NEXT: movcf2gr $a0, $fcc1 +- ; CHECK-NEXT: ret +- ret void +- } +-... +---- +-name: test +-tracksRegLiveness: true +-body: | +- bb.0: +- liveins: $fcc0 +- +- $fcc1 = COPY $fcc0 +- $r4 = COPY $fcc1 +- PseudoRET implicit killed $r4 +- +-... +diff --git a/llvm/test/CodeGen/LoongArch/cfr-pseudo-copy.mir b/llvm/test/CodeGen/LoongArch/cfr-pseudo-copy.mir +deleted file mode 100644 +index c5a6da723..000000000 +--- a/llvm/test/CodeGen/LoongArch/cfr-pseudo-copy.mir ++++ /dev/null +@@ -1,26 +0,0 @@ +-# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +-# RUN: llc --mtriple=loongarch64 --mattr=+d --stop-after=postrapseudos %s \ +-# RUN: -o - | FileCheck %s +- +-## Check the COPY instruction between CFRs. +-## A pseudo (PseudoCopyCFR) is generated after postrapseudos pass. +- +-... +---- +-name: test +-tracksRegLiveness: true +-body: | +- bb.0.entry: +- liveins: $fcc0 +- +- ; CHECK-LABEL: name: test +- ; CHECK: liveins: $fcc0 +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: $fcc1 = PseudoCopyCFR $fcc0 +- ; CHECK-NEXT: $r4 = MOVCF2GR killed $fcc1 +- ; CHECK-NEXT: PseudoRET implicit killed $r4 +- $fcc1 = COPY $fcc0 +- $r4 = COPY $fcc1 +- PseudoRET implicit killed $r4 +- +-... +diff --git a/llvm/test/CodeGen/LoongArch/code-models.ll b/llvm/test/CodeGen/LoongArch/code-models.ll +deleted file mode 100644 +index f93c31670..000000000 +--- a/llvm/test/CodeGen/LoongArch/code-models.ll ++++ /dev/null +@@ -1,122 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --code-model=small < %s | \ +-; RUN: FileCheck --check-prefix=SMALL %s +-; RUN: llc --mtriple=loongarch64 --code-model=medium < %s | \ +-; RUN: FileCheck --check-prefix=MEDIUM %s +-; RUN: llc --mtriple=loongarch64 --code-model=large < %s | \ +-; RUN: FileCheck --check-prefix=LARGE %s +- +-declare void @llvm.memset.p0.i64(ptr, i8, i64, i1) +-declare i32 @callee(i32) +- +-define i32 @call_globaladdress(i32 %a) nounwind { +-; SMALL-LABEL: call_globaladdress: +-; SMALL: # %bb.0: +-; SMALL-NEXT: addi.d $sp, $sp, -16 +-; SMALL-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; SMALL-NEXT: bl %plt(callee) +-; SMALL-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; SMALL-NEXT: addi.d $sp, $sp, 16 +-; SMALL-NEXT: ret +-; +-; MEDIUM-LABEL: call_globaladdress: +-; MEDIUM: # %bb.0: +-; MEDIUM-NEXT: addi.d $sp, $sp, -16 +-; MEDIUM-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; MEDIUM-NEXT: pcaddu18i $ra, %call36(callee) +-; MEDIUM-NEXT: jirl $ra, $ra, 0 +-; MEDIUM-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; MEDIUM-NEXT: addi.d $sp, $sp, 16 +-; MEDIUM-NEXT: ret +-; +-; LARGE-LABEL: call_globaladdress: +-; LARGE: # %bb.0: +-; LARGE-NEXT: addi.d $sp, $sp, -16 +-; LARGE-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LARGE-NEXT: pcalau12i $ra, %got_pc_hi20(callee) +-; LARGE-NEXT: addi.d $t8, $zero, %got_pc_lo12(callee) +-; LARGE-NEXT: lu32i.d $t8, %got64_pc_lo20(callee) +-; LARGE-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(callee) +-; LARGE-NEXT: ldx.d $ra, $t8, $ra +-; LARGE-NEXT: jirl $ra, $ra, 0 +-; LARGE-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LARGE-NEXT: addi.d $sp, $sp, 16 +-; LARGE-NEXT: ret +- %1 = call i32 @callee(i32 %a) +- ret i32 %1 +-} +- +-define void @call_external_sym(ptr %dst) { +-; SMALL-LABEL: call_external_sym: +-; SMALL: # %bb.0: # %entry +-; SMALL-NEXT: addi.d $sp, $sp, -16 +-; SMALL-NEXT: .cfi_def_cfa_offset 16 +-; SMALL-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; SMALL-NEXT: .cfi_offset 1, -8 +-; SMALL-NEXT: ori $a2, $zero, 1000 +-; SMALL-NEXT: move $a1, $zero +-; SMALL-NEXT: bl %plt(memset) +-; SMALL-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; SMALL-NEXT: addi.d $sp, $sp, 16 +-; SMALL-NEXT: ret +-; +-; MEDIUM-LABEL: call_external_sym: +-; MEDIUM: # %bb.0: # %entry +-; MEDIUM-NEXT: addi.d $sp, $sp, -16 +-; MEDIUM-NEXT: .cfi_def_cfa_offset 16 +-; MEDIUM-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; MEDIUM-NEXT: .cfi_offset 1, -8 +-; MEDIUM-NEXT: ori $a2, $zero, 1000 +-; MEDIUM-NEXT: move $a1, $zero +-; MEDIUM-NEXT: pcaddu18i $ra, %call36(memset) +-; MEDIUM-NEXT: jirl $ra, $ra, 0 +-; MEDIUM-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; MEDIUM-NEXT: addi.d $sp, $sp, 16 +-; MEDIUM-NEXT: ret +-; +-; LARGE-LABEL: call_external_sym: +-; LARGE: # %bb.0: # %entry +-; LARGE-NEXT: addi.d $sp, $sp, -16 +-; LARGE-NEXT: .cfi_def_cfa_offset 16 +-; LARGE-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LARGE-NEXT: .cfi_offset 1, -8 +-; LARGE-NEXT: ori $a2, $zero, 1000 +-; LARGE-NEXT: move $a1, $zero +-; LARGE-NEXT: pcalau12i $ra, %pc_hi20(memset) +-; LARGE-NEXT: addi.d $t8, $zero, %pc_lo12(memset) +-; LARGE-NEXT: lu32i.d $t8, %pc64_lo20(memset) +-; LARGE-NEXT: lu52i.d $t8, $t8, %pc64_hi12(memset) +-; LARGE-NEXT: add.d $ra, $t8, $ra +-; LARGE-NEXT: jirl $ra, $ra, 0 +-; LARGE-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LARGE-NEXT: addi.d $sp, $sp, 16 +-; LARGE-NEXT: ret +-entry: +- call void @llvm.memset.p0.i64(ptr %dst, i8 0, i64 1000, i1 false) +- ret void +-} +- +-;; Tail call with different codemodel. +-declare i32 @callee_tail(i32 %i) +-define i32 @caller_tail(i32 %i) nounwind { +-; SMALL-LABEL: caller_tail: +-; SMALL: # %bb.0: # %entry +-; SMALL-NEXT: b %plt(callee_tail) +-; +-; MEDIUM-LABEL: caller_tail: +-; MEDIUM: # %bb.0: # %entry +-; MEDIUM-NEXT: pcaddu18i $t8, %call36(callee_tail) +-; MEDIUM-NEXT: jr $t8 +-; +-; LARGE-LABEL: caller_tail: +-; LARGE: # %bb.0: # %entry +-; LARGE-NEXT: pcalau12i $t7, %got_pc_hi20(callee_tail) +-; LARGE-NEXT: addi.d $t8, $zero, %got_pc_lo12(callee_tail) +-; LARGE-NEXT: lu32i.d $t8, %got64_pc_lo20(callee_tail) +-; LARGE-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(callee_tail) +-; LARGE-NEXT: ldx.d $t7, $t8, $t7 +-; LARGE-NEXT: jr $t7 +-entry: +- %r = tail call i32 @callee_tail(i32 %i) +- ret i32 %r +-} +diff --git a/llvm/test/CodeGen/LoongArch/const-mult.ll b/llvm/test/CodeGen/LoongArch/const-mult.ll +new file mode 100644 +index 000000000..955e16268 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/const-mult.ll +@@ -0,0 +1,245 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -mtriple=loongarch64-linux-gnu < %s | FileCheck %s ++ ++ ++; This test is copied from Mips except the mul2730_32 and mul2730_64 ++ ++define i32 @mul5_32(i32 signext %a) { ++; CHECK-LABEL: mul5_32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: alsl.w $r4, $r4, $r4, 2 ++; CHECK-NEXT: jr $ra ++entry: ++ %mul = mul nsw i32 %a, 5 ++ ret i32 %mul ++} ++ ++define i32 @mul27_32(i32 signext %a) { ++; CHECK-LABEL: mul27_32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: alsl.w $r5, $r4, $r4, 2 ++; CHECK-NEXT: slli.w $r4, $r4, 5 ++; CHECK-NEXT: sub.w $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %mul = mul nsw i32 %a, 27 ++ ret i32 %mul ++} ++ ++define i32 @muln2147483643_32(i32 signext %a) { ++; CHECK-LABEL: muln2147483643_32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: alsl.w $r5, $r4, $r4, 2 ++; CHECK-NEXT: slli.w $r4, $r4, 31 ++; CHECK-NEXT: add.w $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %mul = mul nsw i32 %a, -2147483643 ++ ret i32 %mul ++} ++ ++define i64 @muln9223372036854775805_64(i64 signext %a) { ++; CHECK-LABEL: muln9223372036854775805_64: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: alsl.d $r5, $r4, $r4, 1 ++; CHECK-NEXT: slli.d $r4, $r4, 63 ++; CHECK-NEXT: add.d $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %mul = mul nsw i64 %a, -9223372036854775805 ++ ret i64 %mul ++} ++ ++define i128 @muln170141183460469231731687303715884105725_128(i128 signext %a) { ++; CHECK-LABEL: muln170141183460469231731687303715884105725_128: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: srli.d $r6, $r4, 63 ++; CHECK-NEXT: slli.d $r7, $r5, 1 ++; CHECK-NEXT: or $r6, $r7, $r6 ++; CHECK-NEXT: add.d $r5, $r6, $r5 ++; CHECK-NEXT: slli.d $r7, $r4, 1 ++; CHECK-NEXT: alsl.d $r6, $r4, $r4, 1 ++; CHECK-NEXT: sltu $r7, $r6, $r7 ++; CHECK-NEXT: bstrpick.d $r7, $r7, 31, 0 ++; CHECK-NEXT: add.d $r5, $r5, $r7 ++; CHECK-NEXT: slli.d $r4, $r4, 63 ++; CHECK-NEXT: add.d $r5, $r4, $r5 ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++entry: ++ %mul = mul nsw i128 %a, -170141183460469231731687303715884105725 ++ ret i128 %mul ++} ++ ++define i128 @mul170141183460469231731687303715884105723_128(i128 signext %a) { ++; CHECK-LABEL: mul170141183460469231731687303715884105723_128: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: srli.d $r6, $r4, 62 ++; CHECK-NEXT: slli.d $r7, $r5, 2 ++; CHECK-NEXT: or $r6, $r7, $r6 ++; CHECK-NEXT: add.d $r5, $r6, $r5 ++; CHECK-NEXT: slli.d $r6, $r4, 2 ++; CHECK-NEXT: alsl.d $r7, $r4, $r4, 2 ++; CHECK-NEXT: sltu $r6, $r7, $r6 ++; CHECK-NEXT: bstrpick.d $r6, $r6, 31, 0 ++; CHECK-NEXT: add.d $r5, $r5, $r6 ++; CHECK-NEXT: slli.d $r4, $r4, 63 ++; CHECK-NEXT: sub.d $r4, $r4, $r5 ++; CHECK-NEXT: sltu $r5, $zero, $r7 ++; CHECK-NEXT: bstrpick.d $r5, $r5, 31, 0 ++; CHECK-NEXT: sub.d $r5, $r4, $r5 ++; CHECK-NEXT: addi.d $r4, $zero, 0 ++; CHECK-NEXT: sub.d $r4, $r4, $r7 ++; CHECK-NEXT: jr $ra ++entry: ++ %mul = mul nsw i128 %a, 170141183460469231731687303715884105723 ++ ret i128 %mul ++} ++ ++define i32 @mul42949673_32(i32 %a) { ++; CHECK-LABEL: mul42949673_32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r5, 10485 ++; CHECK-NEXT: ori $r5, $r5, 3113 ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: mul.w $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %b = mul i32 %a, 42949673 ++ ret i32 %b ++} ++ ++define i64 @mul42949673_64(i64 %a) { ++; CHECK-LABEL: mul42949673_64: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: lu12i.w $r5, 10485 ++; CHECK-NEXT: ori $r5, $r5, 3113 ++; CHECK-NEXT: mul.d $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %b = mul i64 %a, 42949673 ++ ret i64 %b ++} ++ ++define i32 @mul22224078_32(i32 %a) { ++; CHECK-LABEL: mul22224078_32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: lu12i.w $r5, 5425 ++; CHECK-NEXT: ori $r5, $r5, 3278 ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: mul.w $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %b = mul i32 %a, 22224078 ++ ret i32 %b ++} ++ ++define i64 @mul22224078_64(i64 %a) { ++; CHECK-LABEL: mul22224078_64: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: lu12i.w $r5, 5425 ++; CHECK-NEXT: ori $r5, $r5, 3278 ++; CHECK-NEXT: mul.d $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %b = mul i64 %a, 22224078 ++ ret i64 %b ++} ++ ++define i32 @mul22245375_32(i32 %a) { ++; CHECK-LABEL: mul22245375_32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: lu12i.w $r5, 5430 ++; CHECK-NEXT: ori $r5, $r5, 4095 ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: mul.w $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %b = mul i32 %a, 22245375 ++ ret i32 %b ++} ++ ++define i64 @mul22245375_64(i64 %a) { ++; CHECK-LABEL: mul22245375_64: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: lu12i.w $r5, 5430 ++; CHECK-NEXT: ori $r5, $r5, 4095 ++; CHECK-NEXT: mul.d $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %b = mul i64 %a, 22245375 ++ ret i64 %b ++} ++ ++define i32 @mul25165824_32(i32 %a) { ++; CHECK-LABEL: mul25165824_32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: lu12i.w $r5, 5430 ++; CHECK-NEXT: ori $r5, $r5, 4095 ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: mul.w $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %b = mul i32 %a, 22245375 ++ ret i32 %b ++} ++ ++define i64 @mul25165824_64(i64 %a) { ++; CHECK-LABEL: mul25165824_64: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: slli.d $r5, $r4, 23 ++; CHECK-NEXT: slli.d $r4, $r4, 24 ++; CHECK-NEXT: add.d $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %b = mul i64 %a, 25165824 ++ ret i64 %b ++} ++ ++define i32 @mul33554432_32(i32 %a) { ++; CHECK-LABEL: mul33554432_32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: lu12i.w $r5, 5430 ++; CHECK-NEXT: ori $r5, $r5, 4095 ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: mul.w $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %b = mul i32 %a, 22245375 ++ ret i32 %b ++} ++ ++define i64 @mul33554432_64(i64 %a) { ++; CHECK-LABEL: mul33554432_64: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: slli.d $r4, $r4, 25 ++; CHECK-NEXT: jr $ra ++entry: ++ %b = mul i64 %a, 33554432 ++ ret i64 %b ++} ++ ++define i32 @mul2730_32(i32 %a) { ++; CHECK-LABEL: mul2730_32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: ori $r5, $zero, 2730 ++; CHECK-NEXT: mul.w $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %b = mul i32 %a, 2730 ++ ret i32 %b ++} ++ ++define i64 @mul2730_64(i64 %a) { ++; CHECK-LABEL: mul2730_64: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: ori $r5, $zero, 2730 ++; CHECK-NEXT: mul.d $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %b = mul i64 %a, 2730 ++ ret i64 %b ++} +diff --git a/llvm/test/CodeGen/LoongArch/cpu-name-generic.ll b/llvm/test/CodeGen/LoongArch/cpu-name-generic.ll +deleted file mode 100644 +index 1129d9fcb..000000000 +--- a/llvm/test/CodeGen/LoongArch/cpu-name-generic.ll ++++ /dev/null +@@ -1,29 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mcpu=generic < %s \ +-; RUN: | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch32 --mcpu=generic-la32 < %s \ +-; RUN: | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mcpu=generic < %s \ +-; RUN: | FileCheck %s --check-prefix=LA64 +-; RUN: llc --mtriple=loongarch64 --mcpu=generic-la64 < %s \ +-; RUN: | FileCheck %s --check-prefix=LA64 +- +-;; The CPU name "generic" should map to the corresponding concrete names +-;; according to the target triple's bitness. +-define i64 @f(i64 signext %a, i64 signext %b) { +-; LA32-LABEL: f: +-; LA32: # %bb.0: +-; LA32-NEXT: add.w $a1, $a1, $a3 +-; LA32-NEXT: add.w $a2, $a0, $a2 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: add.w $a1, $a1, $a0 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f: +-; LA64: # %bb.0: +-; LA64-NEXT: add.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = add nsw i64 %a, %b +- ret i64 %1 +-} +diff --git a/llvm/test/CodeGen/LoongArch/cpus-invalid.ll b/llvm/test/CodeGen/LoongArch/cpus-invalid.ll +deleted file mode 100644 +index b5435fb90..000000000 +--- a/llvm/test/CodeGen/LoongArch/cpus-invalid.ll ++++ /dev/null +@@ -1,7 +0,0 @@ +-; RUN: llc < %s --mtriple=loongarch64 --mattr=+64bit --mcpu=invalidcpu 2>&1 | FileCheck %s +- +-; CHECK: {{.*}} is not a recognized processor for this target +- +-define void @f() { +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/cpus.ll b/llvm/test/CodeGen/LoongArch/cpus.ll +deleted file mode 100644 +index 35945ae4d..000000000 +--- a/llvm/test/CodeGen/LoongArch/cpus.ll ++++ /dev/null +@@ -1,20 +0,0 @@ +-;; This tests that llc accepts all valid LoongArch CPUs. +-;; Note the 'generic' names have been tested in cpu-name-generic.ll. +- +-; RUN: llc < %s --mtriple=loongarch64 --mcpu=loongarch64 2>&1 | FileCheck %s +-; RUN: llc < %s --mtriple=loongarch64 --mcpu=la464 2>&1 | FileCheck %s +-; RUN: llc < %s --mtriple=loongarch64 2>&1 | FileCheck %s +- +-; CHECK-NOT: {{.*}} is not a recognized processor for this target +- +-define void @f() { +- ret void +-} +- +-define void @tune_cpu_loongarch64() "tune-cpu"="loongarch64" { +- ret void +-} +- +-define void @tune_cpu_la464() "tune-cpu"="la464" { +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/ctlz-cttz-ctpop.ll b/llvm/test/CodeGen/LoongArch/ctlz-cttz-ctpop.ll +deleted file mode 100644 +index fa4fda9b8..000000000 +--- a/llvm/test/CodeGen/LoongArch/ctlz-cttz-ctpop.ll ++++ /dev/null +@@ -1,514 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-declare i8 @llvm.ctlz.i8(i8, i1) +-declare i16 @llvm.ctlz.i16(i16, i1) +-declare i32 @llvm.ctlz.i32(i32, i1) +-declare i64 @llvm.ctlz.i64(i64, i1) +-declare i8 @llvm.ctpop.i8(i8) +-declare i16 @llvm.ctpop.i16(i16) +-declare i32 @llvm.ctpop.i32(i32) +-declare i64 @llvm.ctpop.i64(i64) +-declare i8 @llvm.cttz.i8(i8, i1) +-declare i16 @llvm.cttz.i16(i16, i1) +-declare i32 @llvm.cttz.i32(i32, i1) +-declare i64 @llvm.cttz.i64(i64, i1) +- +-define i8 @test_ctlz_i8(i8 %a) nounwind { +-; LA32-LABEL: test_ctlz_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a0, $a0, 255 +-; LA32-NEXT: clz.w $a0, $a0 +-; LA32-NEXT: addi.w $a0, $a0, -24 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_ctlz_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 255 +-; LA64-NEXT: clz.d $a0, $a0 +-; LA64-NEXT: addi.d $a0, $a0, -56 +-; LA64-NEXT: ret +- %tmp = call i8 @llvm.ctlz.i8(i8 %a, i1 false) +- ret i8 %tmp +-} +- +-define i16 @test_ctlz_i16(i16 %a) nounwind { +-; LA32-LABEL: test_ctlz_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: bstrpick.w $a0, $a0, 15, 0 +-; LA32-NEXT: clz.w $a0, $a0 +-; LA32-NEXT: addi.w $a0, $a0, -16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_ctlz_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a0, $a0, 15, 0 +-; LA64-NEXT: clz.d $a0, $a0 +-; LA64-NEXT: addi.d $a0, $a0, -48 +-; LA64-NEXT: ret +- %tmp = call i16 @llvm.ctlz.i16(i16 %a, i1 false) +- ret i16 %tmp +-} +- +-define i32 @test_ctlz_i32(i32 %a) nounwind { +-; LA32-LABEL: test_ctlz_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: clz.w $a0, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_ctlz_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: clz.w $a0, $a0 +-; LA64-NEXT: ret +- %tmp = call i32 @llvm.ctlz.i32(i32 %a, i1 false) +- ret i32 %tmp +-} +- +-define i64 @test_ctlz_i64(i64 %a) nounwind { +-; LA32-LABEL: test_ctlz_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a2, $zero, $a1 +-; LA32-NEXT: clz.w $a1, $a1 +-; LA32-NEXT: maskeqz $a1, $a1, $a2 +-; LA32-NEXT: clz.w $a0, $a0 +-; LA32-NEXT: addi.w $a0, $a0, 32 +-; LA32-NEXT: masknez $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a1, $a0 +-; LA32-NEXT: move $a1, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_ctlz_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: clz.d $a0, $a0 +-; LA64-NEXT: ret +- %tmp = call i64 @llvm.ctlz.i64(i64 %a, i1 false) +- ret i64 %tmp +-} +- +-define i8 @test_not_ctlz_i8(i8 %a) nounwind { +-; LA32-LABEL: test_not_ctlz_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a1, $zero, 255 +-; LA32-NEXT: andn $a0, $a1, $a0 +-; LA32-NEXT: clz.w $a0, $a0 +-; LA32-NEXT: addi.w $a0, $a0, -24 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_not_ctlz_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: ori $a1, $zero, 255 +-; LA64-NEXT: andn $a0, $a1, $a0 +-; LA64-NEXT: clz.d $a0, $a0 +-; LA64-NEXT: addi.d $a0, $a0, -56 +-; LA64-NEXT: ret +- %neg = xor i8 %a, -1 +- %tmp = call i8 @llvm.ctlz.i8(i8 %neg, i1 false) +- ret i8 %tmp +-} +- +-define i16 @test_not_ctlz_i16(i16 %a) nounwind { +-; LA32-LABEL: test_not_ctlz_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: nor $a0, $a0, $zero +-; LA32-NEXT: bstrpick.w $a0, $a0, 15, 0 +-; LA32-NEXT: clz.w $a0, $a0 +-; LA32-NEXT: addi.w $a0, $a0, -16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_not_ctlz_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: nor $a0, $a0, $zero +-; LA64-NEXT: bstrpick.d $a0, $a0, 15, 0 +-; LA64-NEXT: clz.d $a0, $a0 +-; LA64-NEXT: addi.d $a0, $a0, -48 +-; LA64-NEXT: ret +- %neg = xor i16 %a, -1 +- %tmp = call i16 @llvm.ctlz.i16(i16 %neg, i1 false) +- ret i16 %tmp +-} +- +-define i32 @test_not_ctlz_i32(i32 %a) nounwind { +-; LA32-LABEL: test_not_ctlz_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: clo.w $a0, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_not_ctlz_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: clo.w $a0, $a0 +-; LA64-NEXT: ret +- %neg = xor i32 %a, -1 +- %tmp = call i32 @llvm.ctlz.i32(i32 %neg, i1 false) +- ret i32 %tmp +-} +- +-define i64 @test_not_ctlz_i64(i64 %a) nounwind { +-; LA32-LABEL: test_not_ctlz_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: nor $a2, $a1, $zero +-; LA32-NEXT: sltu $a2, $zero, $a2 +-; LA32-NEXT: clo.w $a0, $a0 +-; LA32-NEXT: addi.w $a0, $a0, 32 +-; LA32-NEXT: masknez $a0, $a0, $a2 +-; LA32-NEXT: clo.w $a1, $a1 +-; LA32-NEXT: maskeqz $a1, $a1, $a2 +-; LA32-NEXT: or $a0, $a1, $a0 +-; LA32-NEXT: move $a1, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_not_ctlz_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: clo.d $a0, $a0 +-; LA64-NEXT: ret +- %neg = xor i64 %a, -1 +- %tmp = call i64 @llvm.ctlz.i64(i64 %neg, i1 false) +- ret i64 %tmp +-} +- +-define i8 @test_ctpop_i8(i8 %a) nounwind { +-; LA32-LABEL: test_ctpop_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: srli.w $a1, $a0, 1 +-; LA32-NEXT: andi $a1, $a1, 85 +-; LA32-NEXT: sub.w $a0, $a0, $a1 +-; LA32-NEXT: andi $a1, $a0, 51 +-; LA32-NEXT: srli.w $a0, $a0, 2 +-; LA32-NEXT: andi $a0, $a0, 51 +-; LA32-NEXT: add.w $a0, $a1, $a0 +-; LA32-NEXT: srli.w $a1, $a0, 4 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: andi $a0, $a0, 15 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_ctpop_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: srli.d $a1, $a0, 1 +-; LA64-NEXT: andi $a1, $a1, 85 +-; LA64-NEXT: sub.d $a0, $a0, $a1 +-; LA64-NEXT: andi $a1, $a0, 51 +-; LA64-NEXT: srli.d $a0, $a0, 2 +-; LA64-NEXT: andi $a0, $a0, 51 +-; LA64-NEXT: add.d $a0, $a1, $a0 +-; LA64-NEXT: srli.d $a1, $a0, 4 +-; LA64-NEXT: add.d $a0, $a0, $a1 +-; LA64-NEXT: andi $a0, $a0, 15 +-; LA64-NEXT: ret +- %1 = call i8 @llvm.ctpop.i8(i8 %a) +- ret i8 %1 +-} +- +-define i16 @test_ctpop_i16(i16 %a) nounwind { +-; LA32-LABEL: test_ctpop_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 5 +-; LA32-NEXT: ori $a1, $a1, 1365 +-; LA32-NEXT: srli.w $a2, $a0, 1 +-; LA32-NEXT: and $a1, $a2, $a1 +-; LA32-NEXT: sub.w $a0, $a0, $a1 +-; LA32-NEXT: lu12i.w $a1, 3 +-; LA32-NEXT: ori $a1, $a1, 819 +-; LA32-NEXT: and $a2, $a0, $a1 +-; LA32-NEXT: srli.w $a0, $a0, 2 +-; LA32-NEXT: and $a0, $a0, $a1 +-; LA32-NEXT: add.w $a0, $a2, $a0 +-; LA32-NEXT: srli.w $a1, $a0, 4 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: bstrpick.w $a1, $a0, 11, 8 +-; LA32-NEXT: andi $a0, $a0, 15 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_ctpop_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, 5 +-; LA64-NEXT: ori $a1, $a1, 1365 +-; LA64-NEXT: srli.d $a2, $a0, 1 +-; LA64-NEXT: and $a1, $a2, $a1 +-; LA64-NEXT: sub.d $a0, $a0, $a1 +-; LA64-NEXT: lu12i.w $a1, 3 +-; LA64-NEXT: ori $a1, $a1, 819 +-; LA64-NEXT: and $a2, $a0, $a1 +-; LA64-NEXT: srli.d $a0, $a0, 2 +-; LA64-NEXT: and $a0, $a0, $a1 +-; LA64-NEXT: add.d $a0, $a2, $a0 +-; LA64-NEXT: srli.d $a1, $a0, 4 +-; LA64-NEXT: add.d $a0, $a0, $a1 +-; LA64-NEXT: bstrpick.d $a1, $a0, 11, 8 +-; LA64-NEXT: andi $a0, $a0, 15 +-; LA64-NEXT: add.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = call i16 @llvm.ctpop.i16(i16 %a) +- ret i16 %1 +-} +- +-define i32 @test_ctpop_i32(i32 %a) nounwind { +-; LA32-LABEL: test_ctpop_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 349525 +-; LA32-NEXT: ori $a1, $a1, 1365 +-; LA32-NEXT: srli.w $a2, $a0, 1 +-; LA32-NEXT: and $a1, $a2, $a1 +-; LA32-NEXT: sub.w $a0, $a0, $a1 +-; LA32-NEXT: lu12i.w $a1, 209715 +-; LA32-NEXT: ori $a1, $a1, 819 +-; LA32-NEXT: and $a2, $a0, $a1 +-; LA32-NEXT: srli.w $a0, $a0, 2 +-; LA32-NEXT: and $a0, $a0, $a1 +-; LA32-NEXT: add.w $a0, $a2, $a0 +-; LA32-NEXT: srli.w $a1, $a0, 4 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: lu12i.w $a1, 61680 +-; LA32-NEXT: ori $a1, $a1, 3855 +-; LA32-NEXT: and $a0, $a0, $a1 +-; LA32-NEXT: lu12i.w $a1, 4112 +-; LA32-NEXT: ori $a1, $a1, 257 +-; LA32-NEXT: mul.w $a0, $a0, $a1 +-; LA32-NEXT: srli.w $a0, $a0, 24 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_ctpop_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, 349525 +-; LA64-NEXT: ori $a1, $a1, 1365 +-; LA64-NEXT: srli.d $a2, $a0, 1 +-; LA64-NEXT: and $a1, $a2, $a1 +-; LA64-NEXT: sub.d $a0, $a0, $a1 +-; LA64-NEXT: lu12i.w $a1, 209715 +-; LA64-NEXT: ori $a1, $a1, 819 +-; LA64-NEXT: and $a2, $a0, $a1 +-; LA64-NEXT: srli.d $a0, $a0, 2 +-; LA64-NEXT: and $a0, $a0, $a1 +-; LA64-NEXT: add.d $a0, $a2, $a0 +-; LA64-NEXT: srli.d $a1, $a0, 4 +-; LA64-NEXT: add.d $a0, $a0, $a1 +-; LA64-NEXT: lu12i.w $a1, 61680 +-; LA64-NEXT: ori $a1, $a1, 3855 +-; LA64-NEXT: and $a0, $a0, $a1 +-; LA64-NEXT: lu12i.w $a1, 4112 +-; LA64-NEXT: ori $a1, $a1, 257 +-; LA64-NEXT: mul.d $a0, $a0, $a1 +-; LA64-NEXT: bstrpick.d $a0, $a0, 31, 24 +-; LA64-NEXT: ret +- %1 = call i32 @llvm.ctpop.i32(i32 %a) +- ret i32 %1 +-} +- +-define i64 @test_ctpop_i64(i64 %a) nounwind { +-; LA32-LABEL: test_ctpop_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 349525 +-; LA32-NEXT: ori $a2, $a2, 1365 +-; LA32-NEXT: srli.w $a3, $a0, 1 +-; LA32-NEXT: and $a3, $a3, $a2 +-; LA32-NEXT: sub.w $a0, $a0, $a3 +-; LA32-NEXT: lu12i.w $a3, 209715 +-; LA32-NEXT: ori $a3, $a3, 819 +-; LA32-NEXT: and $a4, $a0, $a3 +-; LA32-NEXT: srli.w $a0, $a0, 2 +-; LA32-NEXT: and $a0, $a0, $a3 +-; LA32-NEXT: add.w $a0, $a4, $a0 +-; LA32-NEXT: srli.w $a4, $a1, 1 +-; LA32-NEXT: and $a2, $a4, $a2 +-; LA32-NEXT: sub.w $a1, $a1, $a2 +-; LA32-NEXT: srli.w $a2, $a0, 4 +-; LA32-NEXT: add.w $a0, $a0, $a2 +-; LA32-NEXT: and $a2, $a1, $a3 +-; LA32-NEXT: srli.w $a1, $a1, 2 +-; LA32-NEXT: and $a1, $a1, $a3 +-; LA32-NEXT: add.w $a1, $a2, $a1 +-; LA32-NEXT: srli.w $a2, $a1, 4 +-; LA32-NEXT: add.w $a1, $a1, $a2 +-; LA32-NEXT: lu12i.w $a2, 61680 +-; LA32-NEXT: ori $a2, $a2, 3855 +-; LA32-NEXT: and $a1, $a1, $a2 +-; LA32-NEXT: and $a0, $a0, $a2 +-; LA32-NEXT: lu12i.w $a2, 4112 +-; LA32-NEXT: ori $a2, $a2, 257 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: srli.w $a1, $a1, 24 +-; LA32-NEXT: srli.w $a0, $a0, 24 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: move $a1, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_ctpop_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, 349525 +-; LA64-NEXT: ori $a1, $a1, 1365 +-; LA64-NEXT: lu32i.d $a1, 349525 +-; LA64-NEXT: lu52i.d $a1, $a1, 1365 +-; LA64-NEXT: srli.d $a2, $a0, 1 +-; LA64-NEXT: and $a1, $a2, $a1 +-; LA64-NEXT: sub.d $a0, $a0, $a1 +-; LA64-NEXT: lu12i.w $a1, 209715 +-; LA64-NEXT: ori $a1, $a1, 819 +-; LA64-NEXT: lu32i.d $a1, 209715 +-; LA64-NEXT: lu52i.d $a1, $a1, 819 +-; LA64-NEXT: and $a2, $a0, $a1 +-; LA64-NEXT: srli.d $a0, $a0, 2 +-; LA64-NEXT: and $a0, $a0, $a1 +-; LA64-NEXT: add.d $a0, $a2, $a0 +-; LA64-NEXT: srli.d $a1, $a0, 4 +-; LA64-NEXT: add.d $a0, $a0, $a1 +-; LA64-NEXT: lu12i.w $a1, 61680 +-; LA64-NEXT: ori $a1, $a1, 3855 +-; LA64-NEXT: lu32i.d $a1, -61681 +-; LA64-NEXT: lu52i.d $a1, $a1, 240 +-; LA64-NEXT: and $a0, $a0, $a1 +-; LA64-NEXT: lu12i.w $a1, 4112 +-; LA64-NEXT: ori $a1, $a1, 257 +-; LA64-NEXT: lu32i.d $a1, 65793 +-; LA64-NEXT: lu52i.d $a1, $a1, 16 +-; LA64-NEXT: mul.d $a0, $a0, $a1 +-; LA64-NEXT: srli.d $a0, $a0, 56 +-; LA64-NEXT: ret +- %1 = call i64 @llvm.ctpop.i64(i64 %a) +- ret i64 %1 +-} +- +-define i8 @test_cttz_i8(i8 %a) nounwind { +-; LA32-LABEL: test_cttz_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a0, $a0, 256 +-; LA32-NEXT: ctz.w $a0, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_cttz_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: ori $a0, $a0, 256 +-; LA64-NEXT: ctz.d $a0, $a0 +-; LA64-NEXT: ret +- %tmp = call i8 @llvm.cttz.i8(i8 %a, i1 false) +- ret i8 %tmp +-} +- +-define i16 @test_cttz_i16(i16 %a) nounwind { +-; LA32-LABEL: test_cttz_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 16 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ctz.w $a0, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_cttz_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, 16 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ctz.d $a0, $a0 +-; LA64-NEXT: ret +- %tmp = call i16 @llvm.cttz.i16(i16 %a, i1 false) +- ret i16 %tmp +-} +- +-define i32 @test_cttz_i32(i32 %a) nounwind { +-; LA32-LABEL: test_cttz_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: ctz.w $a0, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_cttz_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: ctz.w $a0, $a0 +-; LA64-NEXT: ret +- %tmp = call i32 @llvm.cttz.i32(i32 %a, i1 false) +- ret i32 %tmp +-} +- +-define i64 @test_cttz_i64(i64 %a) nounwind { +-; LA32-LABEL: test_cttz_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a2, $zero, $a0 +-; LA32-NEXT: ctz.w $a0, $a0 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: ctz.w $a1, $a1 +-; LA32-NEXT: addi.w $a1, $a1, 32 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: move $a1, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_cttz_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: ctz.d $a0, $a0 +-; LA64-NEXT: ret +- %tmp = call i64 @llvm.cttz.i64(i64 %a, i1 false) +- ret i64 %tmp +-} +- +-define i8 @test_not_cttz_i8(i8 %a) nounwind { +-; LA32-LABEL: test_not_cttz_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a1, $zero, 256 +-; LA32-NEXT: orn $a0, $a1, $a0 +-; LA32-NEXT: ctz.w $a0, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_not_cttz_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: ori $a1, $zero, 256 +-; LA64-NEXT: orn $a0, $a1, $a0 +-; LA64-NEXT: ctz.d $a0, $a0 +-; LA64-NEXT: ret +- %neg = xor i8 %a, -1 +- %tmp = call i8 @llvm.cttz.i8(i8 %neg, i1 false) +- ret i8 %tmp +-} +- +-define i16 @test_not_cttz_i16(i16 %a) nounwind { +-; LA32-LABEL: test_not_cttz_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 16 +-; LA32-NEXT: orn $a0, $a1, $a0 +-; LA32-NEXT: ctz.w $a0, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_not_cttz_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, 16 +-; LA64-NEXT: orn $a0, $a1, $a0 +-; LA64-NEXT: ctz.d $a0, $a0 +-; LA64-NEXT: ret +- %neg = xor i16 %a, -1 +- %tmp = call i16 @llvm.cttz.i16(i16 %neg, i1 false) +- ret i16 %tmp +-} +- +-define i32 @test_not_cttz_i32(i32 %a) nounwind { +-; LA32-LABEL: test_not_cttz_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: cto.w $a0, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_not_cttz_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: cto.w $a0, $a0 +-; LA64-NEXT: ret +- %neg = xor i32 %a, -1 +- %tmp = call i32 @llvm.cttz.i32(i32 %neg, i1 false) +- ret i32 %tmp +-} +- +-define i64 @test_not_cttz_i64(i64 %a) nounwind { +-; LA32-LABEL: test_not_cttz_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: nor $a2, $a0, $zero +-; LA32-NEXT: sltu $a2, $zero, $a2 +-; LA32-NEXT: cto.w $a1, $a1 +-; LA32-NEXT: addi.w $a1, $a1, 32 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: cto.w $a0, $a0 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: move $a1, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_not_cttz_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: cto.d $a0, $a0 +-; LA64-NEXT: ret +- %neg = xor i64 %a, -1 +- %tmp = call i64 @llvm.cttz.i64(i64 %neg, i1 false) +- ret i64 %tmp +-} +diff --git a/llvm/test/CodeGen/LoongArch/disable-tail-calls.ll b/llvm/test/CodeGen/LoongArch/disable-tail-calls.ll +new file mode 100644 +index 000000000..586daca23 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/disable-tail-calls.ll +@@ -0,0 +1,94 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -relocation-model=pic < %s \ ++; RUN: | FileCheck %s --check-prefixes=CHECK1 ++; RUN: llc -march=loongarch64 -relocation-model=pic -disable-tail-calls < %s \ ++; RUN: | FileCheck %s --check-prefixes=CHECK2 ++; RUN: llc -march=loongarch64 -relocation-model=pic -disable-tail-calls=false < %s \ ++; RUN: | FileCheck %s --check-prefixes=CHECK3 ++ ++; Function with attribute #0 = { "disable-tail-calls"="true" } ++define i32 @caller1(i32 %a) #0 { ++; CHECK1-LABEL: caller1: ++; CHECK1: # %bb.0: # %entry ++; CHECK1-NEXT: addi.d $sp, $sp, -16 ++; CHECK1-NEXT: .cfi_def_cfa_offset 16 ++; CHECK1-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill ++; CHECK1-NEXT: .cfi_offset 1, -8 ++; CHECK1-NEXT: bl callee ++; CHECK1-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ++; CHECK1-NEXT: addi.d $sp, $sp, 16 ++; CHECK1-NEXT: jr $ra ++; ++; CHECK2-LABEL: caller1: ++; CHECK2: # %bb.0: # %entry ++; CHECK2-NEXT: addi.d $sp, $sp, -16 ++; CHECK2-NEXT: .cfi_def_cfa_offset 16 ++; CHECK2-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill ++; CHECK2-NEXT: .cfi_offset 1, -8 ++; CHECK2-NEXT: bl callee ++; CHECK2-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ++; CHECK2-NEXT: addi.d $sp, $sp, 16 ++; CHECK2-NEXT: jr $ra ++; ++; CHECK3-LABEL: caller1: ++; CHECK3: # %bb.0: # %entry ++; CHECK3-NEXT: b callee ++entry: ++ %call = tail call i32 @callee(i32 %a) ++ ret i32 %call ++} ++ ++ ++; Function with attribute #1 = { "disable-tail-calls"="false" } ++define i32 @caller2(i32 %a) #1 { ++; CHECK1-LABEL: caller2: ++; CHECK1: # %bb.0: # %entry ++; CHECK1-NEXT: b callee ++; ++; CHECK2-LABEL: caller2: ++; CHECK2: # %bb.0: # %entry ++; CHECK2-NEXT: addi.d $sp, $sp, -16 ++; CHECK2-NEXT: .cfi_def_cfa_offset 16 ++; CHECK2-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill ++; CHECK2-NEXT: .cfi_offset 1, -8 ++; CHECK2-NEXT: bl callee ++; CHECK2-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ++; CHECK2-NEXT: addi.d $sp, $sp, 16 ++; CHECK2-NEXT: jr $ra ++; ++; CHECK3-LABEL: caller2: ++; CHECK3: # %bb.0: # %entry ++; CHECK3-NEXT: b callee ++entry: ++ %call = tail call i32 @callee(i32 %a) ++ ret i32 %call ++} ++ ++define i32 @caller3(i32 %a) { ++; CHECK1-LABEL: caller3: ++; CHECK1: # %bb.0: # %entry ++; CHECK1-NEXT: b callee ++; ++; CHECK2-LABEL: caller3: ++; CHECK2: # %bb.0: # %entry ++; CHECK2-NEXT: addi.d $sp, $sp, -16 ++; CHECK2-NEXT: .cfi_def_cfa_offset 16 ++; CHECK2-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill ++; CHECK2-NEXT: .cfi_offset 1, -8 ++; CHECK2-NEXT: bl callee ++; CHECK2-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ++; CHECK2-NEXT: addi.d $sp, $sp, 16 ++; CHECK2-NEXT: jr $ra ++; ++; CHECK3-LABEL: caller3: ++; CHECK3: # %bb.0: # %entry ++; CHECK3-NEXT: b callee ++entry: ++ %call = tail call i32 @callee(i32 %a) ++ ret i32 %call ++} ++ ++declare i32 @callee(i32) ++ ++attributes #0 = { "disable-tail-calls"="true" } ++attributes #1 = { "disable-tail-calls"="false" } +diff --git a/llvm/test/CodeGen/LoongArch/divrem.ll b/llvm/test/CodeGen/LoongArch/divrem.ll +new file mode 100644 +index 000000000..34293a83c +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/divrem.ll +@@ -0,0 +1,68 @@ ++; RUN: llc -march=loongarch64 -relocation-model=pic < %s | FileCheck %s -check-prefixes=CHECK,CHECK-TRAP ++ ++; RUN: llc -march=loongarch64 -mnocheck-zero-division -relocation-model=pic < %s | FileCheck %s -check-prefixes=CHECK,NOCHECK ++ ++; FileCheck Prefixes: ++; CHECK-TRAP - trap ++; NOCHECK - Division by zero will not be detected ++ ++define i32 @sdiv1(i32 signext %a0, i32 signext %a1) nounwind readnone { ++entry: ++; CHECK-LABEL: sdiv1: ++ ++; CHECK: div.w $r4, $r4, $r5 ++; CHECK-TRAP: bne $r5, $zero, 8 ++; CHECK-TRAP: break 7 ++ ++; NOCHECK-NOT: bne ++; NOCHECK-NOT: break ++ ++ %div = sdiv i32 %a0, %a1 ++ ret i32 %div ++} ++ ++define i32 @srem1(i32 signext %a0, i32 signext %a1) nounwind readnone { ++entry: ++; CHECK-LABEL: srem1: ++ ++; CHECK: mod.w $r4, $r4, $r5 ++; CHECK-TRAP: bne $r5, $zero, 8 ++; CHECK-TRAP: break 7 ++ ++; NOCHECK-NOT: bne ++; NOCHECK-NOT: break ++ ++ %rem = srem i32 %a0, %a1 ++ ret i32 %rem ++} ++ ++define i32 @udiv1(i32 signext %a0, i32 signext %a1) nounwind readnone { ++entry: ++; CHECK-LABEL: udiv1: ++ ++; CHECK: div.wu $r4, $r4, $r5 ++; CHECK-TRAP: bne $r5, $zero, 8 ++; CHECK-TRAP: break 7 ++ ++; NOCHECK-NOT: bne ++; NOCHECK-NOT: break ++ ++ %div = udiv i32 %a0, %a1 ++ ret i32 %div ++} ++ ++define i32 @urem1(i32 signext %a0, i32 signext %a1) nounwind readnone { ++entry: ++; CHECK-LABEL: urem1: ++ ++ ++; CHECK: mod.wu $r4, $r4, $r5 ++; CHECK-TRAP: bne $r5, $zero, 8 ++; CHECK-TRAP: break 7 ++ ++; NOCHECK-NOT: bne ++; NOCHECK-NOT: break ++ ++ %rem = urem i32 %a0, %a1 ++ ret i32 %rem ++} +diff --git a/llvm/test/CodeGen/LoongArch/double-br-fcmp.ll b/llvm/test/CodeGen/LoongArch/double-br-fcmp.ll +deleted file mode 100644 +index 50cbb11be..000000000 +--- a/llvm/test/CodeGen/LoongArch/double-br-fcmp.ll ++++ /dev/null +@@ -1,873 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64 +- +-declare void @abort() +- +-define void @br_fcmp_oeq_bcnez(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_oeq_bcnez: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.ceq.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: bcnez $fcc0, .LBB0_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB0_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_oeq_bcnez: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.ceq.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: bcnez $fcc0, .LBB0_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB0_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp oeq double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_oeq_bceqz(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_oeq_bceqz: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cune.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: bceqz $fcc0, .LBB1_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB1_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_oeq_bceqz: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cune.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: bceqz $fcc0, .LBB1_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB1_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp oeq double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_ogt_bcnez(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_ogt_bcnez: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: bcnez $fcc0, .LBB2_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB2_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ogt_bcnez: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: bcnez $fcc0, .LBB2_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB2_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ogt double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_ogt_bceqz(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_ogt_bceqz: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: bceqz $fcc0, .LBB3_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB3_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ogt_bceqz: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: bceqz $fcc0, .LBB3_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB3_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ogt double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_oge_bcnez(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_oge_bcnez: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: bcnez $fcc0, .LBB4_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB4_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_oge_bcnez: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: bcnez $fcc0, .LBB4_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB4_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp oge double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_oge_bceqz(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_oge_bceqz: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: bceqz $fcc0, .LBB5_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB5_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_oge_bceqz: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: bceqz $fcc0, .LBB5_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB5_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp oge double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_olt_bcnez(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_olt_bcnez: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: bcnez $fcc0, .LBB6_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB6_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_olt_bcnez: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: bcnez $fcc0, .LBB6_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB6_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp olt double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_olt_bceqz(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_olt_bceqz: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: bceqz $fcc0, .LBB7_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB7_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_olt_bceqz: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: bceqz $fcc0, .LBB7_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB7_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp olt double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_ole_bcnez(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_ole_bcnez: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: bcnez $fcc0, .LBB8_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB8_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ole_bcnez: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: bcnez $fcc0, .LBB8_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB8_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ole double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_ole_bceqz(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_ole_bceqz: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: bceqz $fcc0, .LBB9_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB9_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ole_bceqz: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: bceqz $fcc0, .LBB9_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB9_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ole double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_one_bcnez(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_one_bcnez: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cne.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: bcnez $fcc0, .LBB10_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB10_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_one_bcnez: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cne.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: bcnez $fcc0, .LBB10_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB10_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp one double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_one_bceqz(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_one_bceqz: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cueq.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: bceqz $fcc0, .LBB11_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB11_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_one_bceqz: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cueq.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: bceqz $fcc0, .LBB11_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB11_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp one double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_ord_bcnez(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_ord_bcnez: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cor.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: bcnez $fcc0, .LBB12_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB12_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ord_bcnez: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cor.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: bcnez $fcc0, .LBB12_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB12_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ord double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_ord_bceqz(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_ord_bceqz: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cun.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: bceqz $fcc0, .LBB13_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB13_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ord_bceqz: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cun.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: bceqz $fcc0, .LBB13_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB13_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ord double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_ueq_bcnez(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_ueq_bcnez: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cueq.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: bcnez $fcc0, .LBB14_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB14_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ueq_bcnez: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cueq.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: bcnez $fcc0, .LBB14_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB14_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ueq double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_ueq_bceqz(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_ueq_bceqz: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cne.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: bceqz $fcc0, .LBB15_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB15_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ueq_bceqz: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cne.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: bceqz $fcc0, .LBB15_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB15_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ueq double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_ugt_bcnez(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_ugt_bcnez: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: bcnez $fcc0, .LBB16_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB16_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ugt_bcnez: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: bcnez $fcc0, .LBB16_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB16_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ugt double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_ugt_bceqz(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_ugt_bceqz: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: bceqz $fcc0, .LBB17_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB17_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ugt_bceqz: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: bceqz $fcc0, .LBB17_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB17_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ugt double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_uge_bcnez(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_uge_bcnez: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: bcnez $fcc0, .LBB18_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB18_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_uge_bcnez: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: bcnez $fcc0, .LBB18_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB18_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp uge double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_uge_bceqz(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_uge_bceqz: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: bceqz $fcc0, .LBB19_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB19_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_uge_bceqz: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: bceqz $fcc0, .LBB19_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB19_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp uge double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_ult_bcnez(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_ult_bcnez: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: bcnez $fcc0, .LBB20_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB20_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ult_bcnez: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: bcnez $fcc0, .LBB20_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB20_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ult double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_ult_bceqz(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_ult_bceqz: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: bceqz $fcc0, .LBB21_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB21_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ult_bceqz: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: bceqz $fcc0, .LBB21_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB21_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ult double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_ule_bcnez(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_ule_bcnez: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: bcnez $fcc0, .LBB22_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB22_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ule_bcnez: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: bcnez $fcc0, .LBB22_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB22_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ule double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_ule_bceqz(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_ule_bceqz: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: bceqz $fcc0, .LBB23_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB23_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ule_bceqz: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: bceqz $fcc0, .LBB23_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB23_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ule double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_une_bcnez(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_une_bcnez: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cune.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: bcnez $fcc0, .LBB24_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB24_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_une_bcnez: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cune.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: bcnez $fcc0, .LBB24_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB24_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp une double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_une_bceqz(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_une_bceqz: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.ceq.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: bceqz $fcc0, .LBB25_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB25_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_une_bceqz: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.ceq.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: bceqz $fcc0, .LBB25_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB25_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp une double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_uno_bcnez(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_uno_bcnez: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cun.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: bcnez $fcc0, .LBB26_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB26_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_uno_bcnez: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cun.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: bcnez $fcc0, .LBB26_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB26_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp uno double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_uno_bceqz(double %a, double %b) nounwind { +-; LA32-LABEL: br_fcmp_uno_bceqz: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cor.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: bceqz $fcc0, .LBB27_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB27_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_uno_bceqz: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cor.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: bceqz $fcc0, .LBB27_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB27_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp uno double %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/double-fcmp-strict.ll b/llvm/test/CodeGen/LoongArch/double-fcmp-strict.ll +deleted file mode 100644 +index 066f60752..000000000 +--- a/llvm/test/CodeGen/LoongArch/double-fcmp-strict.ll ++++ /dev/null +@@ -1,243 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64 +- +-declare i1 @llvm.experimental.constrained.fcmp.f64(double, double, metadata, metadata) +- +-define i32 @fcmp_oeq(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_oeq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.ceq.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_oeq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.ceq.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"oeq", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ogt(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ogt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ogt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"ogt", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_oge(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_oge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_oge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"oge", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_olt(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_olt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_olt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"olt", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ole(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ole: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ole: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"ole", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_one(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_one: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cne.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_one: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cne.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"one", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ord(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ord: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cor.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ord: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cor.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"ord", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ueq(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ueq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cueq.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ueq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cueq.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"ueq", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ugt(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ugt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ugt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"ugt", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_uge(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_uge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_uge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"uge", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ult(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ult: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ult: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"ult", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ule(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ule: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ule: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"ule", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_une(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_une: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cune.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_une: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cune.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"une", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_uno(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_uno: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cun.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_uno: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cun.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"uno", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +diff --git a/llvm/test/CodeGen/LoongArch/double-fcmps-strict.ll b/llvm/test/CodeGen/LoongArch/double-fcmps-strict.ll +deleted file mode 100644 +index c8974fb94..000000000 +--- a/llvm/test/CodeGen/LoongArch/double-fcmps-strict.ll ++++ /dev/null +@@ -1,482 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64 +- +-declare i1 @llvm.experimental.constrained.fcmps.f64(double, double, metadata, metadata) +-declare i1 @llvm.experimental.constrained.fcmp.f64(double, double, metadata, metadata) +- +-define i32 @fcmps_oeq(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmps_oeq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.seq.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_oeq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.seq.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"oeq", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_ogt(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmps_ogt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.slt.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_ogt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.slt.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"ogt", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_oge(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmps_oge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.sle.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_oge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.sle.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"oge", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_olt(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmps_olt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.slt.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_olt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.slt.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"olt", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_ole(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmps_ole: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.sle.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_ole: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.sle.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"ole", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_one(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmps_one: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.sne.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_one: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.sne.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"one", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_ord(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmps_ord: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.sor.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_ord: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.sor.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"ord", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_ueq(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmps_ueq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.sueq.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_ueq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.sueq.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"ueq", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_ugt(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmps_ugt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.sult.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_ugt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.sult.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"ugt", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_uge(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmps_uge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.sule.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_uge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.sule.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"uge", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_ult(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmps_ult: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.sult.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_ult: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.sult.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"ult", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_ule(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmps_ule: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.sule.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_ule: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.sule.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"ule", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_une(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmps_une: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.sune.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_une: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.sune.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"une", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_uno(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmps_uno: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.sun.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_uno: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.sun.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"uno", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_oeq(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_oeq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.ceq.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_oeq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.ceq.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"oeq", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ogt(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ogt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ogt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"ogt", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_oge(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_oge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_oge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"oge", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_olt(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_olt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_olt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"olt", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ole(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ole: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ole: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"ole", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_one(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_one: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cne.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_one: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cne.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"one", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ord(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ord: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cor.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ord: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cor.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"ord", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ueq(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ueq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cueq.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ueq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cueq.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"ueq", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ugt(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ugt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ugt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"ugt", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_uge(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_uge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_uge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"uge", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ult(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ult: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ult: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"ult", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ule(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ule: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ule: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"ule", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_une(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_une: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cune.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_une: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cune.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"une", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_uno(double %a, double %b) nounwind strictfp { +-; LA32-LABEL: fcmp_uno: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cun.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_uno: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cun.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"uno", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +diff --git a/llvm/test/CodeGen/LoongArch/double-fma.ll b/llvm/test/CodeGen/LoongArch/double-fma.ll +deleted file mode 100644 +index 58d20c62a..000000000 +--- a/llvm/test/CodeGen/LoongArch/double-fma.ll ++++ /dev/null +@@ -1,1100 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+d --fp-contract=fast < %s \ +-; RUN: | FileCheck %s --check-prefix=LA32-CONTRACT-FAST +-; RUN: llc --mtriple=loongarch32 --mattr=+d --fp-contract=on < %s \ +-; RUN: | FileCheck %s --check-prefix=LA32-CONTRACT-ON +-; RUN: llc --mtriple=loongarch32 --mattr=+d --fp-contract=off < %s \ +-; RUN: | FileCheck %s --check-prefix=LA32-CONTRACT-OFF +-; RUN: llc --mtriple=loongarch64 --mattr=+d --fp-contract=fast < %s \ +-; RUN: | FileCheck %s --check-prefix=LA64-CONTRACT-FAST +-; RUN: llc --mtriple=loongarch64 --mattr=+d --fp-contract=on < %s \ +-; RUN: | FileCheck %s --check-prefix=LA64-CONTRACT-ON +-; RUN: llc --mtriple=loongarch64 --mattr=+d --fp-contract=off < %s \ +-; RUN: | FileCheck %s --check-prefix=LA64-CONTRACT-OFF +- +-define double @fmadd_d(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fmadd_d: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fmadd_d: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA32-CONTRACT-ON-NEXT: fadd.d $fa0, $fa0, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fmadd_d: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA32-CONTRACT-OFF-NEXT: fadd.d $fa0, $fa0, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fmadd_d: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fmadd_d: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA64-CONTRACT-ON-NEXT: fadd.d $fa0, $fa0, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fmadd_d: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA64-CONTRACT-OFF-NEXT: fadd.d $fa0, $fa0, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %mul = fmul double %a, %b +- %add = fadd double %mul, %c +- ret double %add +-} +- +-define double @fmsub_d(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fmsub_d: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fmsub_d: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA32-CONTRACT-ON-NEXT: fsub.d $fa0, $fa0, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fmsub_d: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA32-CONTRACT-OFF-NEXT: fsub.d $fa0, $fa0, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fmsub_d: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fmsub_d: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA64-CONTRACT-ON-NEXT: fsub.d $fa0, $fa0, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fmsub_d: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA64-CONTRACT-OFF-NEXT: fsub.d $fa0, $fa0, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %mul = fmul double %a, %b +- %sub = fsub double %mul, %c +- ret double %sub +-} +- +-define double @fnmadd_d(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fnmadd_d: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fnmadd_d: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA32-CONTRACT-ON-NEXT: fadd.d $fa0, $fa0, $fa2 +-; LA32-CONTRACT-ON-NEXT: fneg.d $fa0, $fa0 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fnmadd_d: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA32-CONTRACT-OFF-NEXT: fadd.d $fa0, $fa0, $fa2 +-; LA32-CONTRACT-OFF-NEXT: fneg.d $fa0, $fa0 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fnmadd_d: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fnmadd_d: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA64-CONTRACT-ON-NEXT: fadd.d $fa0, $fa0, $fa2 +-; LA64-CONTRACT-ON-NEXT: fneg.d $fa0, $fa0 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fnmadd_d: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA64-CONTRACT-OFF-NEXT: fadd.d $fa0, $fa0, $fa2 +-; LA64-CONTRACT-OFF-NEXT: fneg.d $fa0, $fa0 +-; LA64-CONTRACT-OFF-NEXT: ret +- %mul = fmul double %a, %b +- %add = fadd double %mul, %c +- %negadd = fneg double %add +- ret double %negadd +-} +- +-define double @fnmadd_d_nsz(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fnmadd_d_nsz: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fnmadd_d_nsz: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fneg.d $fa0, $fa0 +-; LA32-CONTRACT-ON-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA32-CONTRACT-ON-NEXT: fsub.d $fa0, $fa0, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fnmadd_d_nsz: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fneg.d $fa0, $fa0 +-; LA32-CONTRACT-OFF-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA32-CONTRACT-OFF-NEXT: fsub.d $fa0, $fa0, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fnmadd_d_nsz: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fnmadd_d_nsz: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fneg.d $fa0, $fa0 +-; LA64-CONTRACT-ON-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA64-CONTRACT-ON-NEXT: fsub.d $fa0, $fa0, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fnmadd_d_nsz: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fneg.d $fa0, $fa0 +-; LA64-CONTRACT-OFF-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA64-CONTRACT-OFF-NEXT: fsub.d $fa0, $fa0, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg nsz double %a +- %negc = fneg nsz double %c +- %mul = fmul nsz double %nega, %b +- %add = fadd nsz double %mul, %negc +- ret double %add +-} +- +-;; Check that fnmadd.d is not emitted. +-define double @not_fnmadd_d(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: not_fnmadd_d: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fneg.d $fa0, $fa0 +-; LA32-CONTRACT-FAST-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: not_fnmadd_d: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fneg.d $fa0, $fa0 +-; LA32-CONTRACT-ON-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA32-CONTRACT-ON-NEXT: fsub.d $fa0, $fa0, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: not_fnmadd_d: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fneg.d $fa0, $fa0 +-; LA32-CONTRACT-OFF-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA32-CONTRACT-OFF-NEXT: fsub.d $fa0, $fa0, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: not_fnmadd_d: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fneg.d $fa0, $fa0 +-; LA64-CONTRACT-FAST-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: not_fnmadd_d: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fneg.d $fa0, $fa0 +-; LA64-CONTRACT-ON-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA64-CONTRACT-ON-NEXT: fsub.d $fa0, $fa0, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: not_fnmadd_d: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fneg.d $fa0, $fa0 +-; LA64-CONTRACT-OFF-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA64-CONTRACT-OFF-NEXT: fsub.d $fa0, $fa0, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg double %a +- %negc = fneg double %c +- %mul = fmul double %nega, %b +- %add = fadd double %mul, %negc +- ret double %add +-} +- +-define double @fnmsub_d(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fnmsub_d: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fnmsub_d: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA32-CONTRACT-ON-NEXT: fsub.d $fa0, $fa0, $fa2 +-; LA32-CONTRACT-ON-NEXT: fneg.d $fa0, $fa0 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fnmsub_d: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA32-CONTRACT-OFF-NEXT: fsub.d $fa0, $fa0, $fa2 +-; LA32-CONTRACT-OFF-NEXT: fneg.d $fa0, $fa0 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fnmsub_d: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fnmsub_d: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA64-CONTRACT-ON-NEXT: fsub.d $fa0, $fa0, $fa2 +-; LA64-CONTRACT-ON-NEXT: fneg.d $fa0, $fa0 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fnmsub_d: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA64-CONTRACT-OFF-NEXT: fsub.d $fa0, $fa0, $fa2 +-; LA64-CONTRACT-OFF-NEXT: fneg.d $fa0, $fa0 +-; LA64-CONTRACT-OFF-NEXT: ret +- %negc = fneg double %c +- %mul = fmul double %a, %b +- %add = fadd double %mul, %negc +- %neg = fneg double %add +- ret double %neg +-} +- +-define double @fnmsub_d_nsz(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fnmsub_d_nsz: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fnmsub_d_nsz: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA32-CONTRACT-ON-NEXT: fsub.d $fa0, $fa2, $fa0 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fnmsub_d_nsz: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA32-CONTRACT-OFF-NEXT: fsub.d $fa0, $fa2, $fa0 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fnmsub_d_nsz: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fnmsub_d_nsz: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA64-CONTRACT-ON-NEXT: fsub.d $fa0, $fa2, $fa0 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fnmsub_d_nsz: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA64-CONTRACT-OFF-NEXT: fsub.d $fa0, $fa2, $fa0 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg nsz double %a +- %mul = fmul nsz double %nega, %b +- %add = fadd nsz double %mul, %c +- ret double %add +-} +- +-;; Check that fnmsub.d is not emitted. +-define double @not_fnmsub_d(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: not_fnmsub_d: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fneg.d $fa0, $fa0 +-; LA32-CONTRACT-FAST-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: not_fnmsub_d: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA32-CONTRACT-ON-NEXT: fsub.d $fa0, $fa2, $fa0 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: not_fnmsub_d: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA32-CONTRACT-OFF-NEXT: fsub.d $fa0, $fa2, $fa0 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: not_fnmsub_d: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fneg.d $fa0, $fa0 +-; LA64-CONTRACT-FAST-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: not_fnmsub_d: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA64-CONTRACT-ON-NEXT: fsub.d $fa0, $fa2, $fa0 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: not_fnmsub_d: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA64-CONTRACT-OFF-NEXT: fsub.d $fa0, $fa2, $fa0 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg double %a +- %mul = fmul double %nega, %b +- %add = fadd double %mul, %c +- ret double %add +-} +- +-define double @contract_fmadd_d(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: contract_fmadd_d: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: contract_fmadd_d: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: contract_fmadd_d: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: contract_fmadd_d: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: contract_fmadd_d: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: contract_fmadd_d: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %mul = fmul contract double %a, %b +- %add = fadd contract double %mul, %c +- ret double %add +-} +- +-define double @contract_fmsub_d(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: contract_fmsub_d: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: contract_fmsub_d: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: contract_fmsub_d: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: contract_fmsub_d: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: contract_fmsub_d: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: contract_fmsub_d: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %mul = fmul contract double %a, %b +- %sub = fsub contract double %mul, %c +- ret double %sub +-} +- +-define double @contract_fnmadd_d(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: contract_fnmadd_d: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: contract_fnmadd_d: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: contract_fnmadd_d: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: contract_fnmadd_d: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: contract_fnmadd_d: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: contract_fnmadd_d: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %mul = fmul contract double %a, %b +- %add = fadd contract double %mul, %c +- %negadd = fneg contract double %add +- ret double %negadd +-} +- +-define double @contract_fnmadd_d_nsz(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: contract_fnmadd_d_nsz: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: contract_fnmadd_d_nsz: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: contract_fnmadd_d_nsz: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: contract_fnmadd_d_nsz: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: contract_fnmadd_d_nsz: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: contract_fnmadd_d_nsz: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg contract nsz double %a +- %negc = fneg contract nsz double %c +- %mul = fmul contract nsz double %nega, %b +- %add = fadd contract nsz double %mul, %negc +- ret double %add +-} +- +-;; Check that fnmadd.d is not emitted. +-define double @not_contract_fnmadd_d(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: not_contract_fnmadd_d: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fneg.d $fa0, $fa0 +-; LA32-CONTRACT-FAST-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: not_contract_fnmadd_d: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fneg.d $fa0, $fa0 +-; LA32-CONTRACT-ON-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: not_contract_fnmadd_d: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fneg.d $fa0, $fa0 +-; LA32-CONTRACT-OFF-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: not_contract_fnmadd_d: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fneg.d $fa0, $fa0 +-; LA64-CONTRACT-FAST-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: not_contract_fnmadd_d: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fneg.d $fa0, $fa0 +-; LA64-CONTRACT-ON-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: not_contract_fnmadd_d: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fneg.d $fa0, $fa0 +-; LA64-CONTRACT-OFF-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg contract double %a +- %negc = fneg contract double %c +- %mul = fmul contract double %nega, %b +- %add = fadd contract double %mul, %negc +- ret double %add +-} +- +-define double @contract_fnmsub_d(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: contract_fnmsub_d: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: contract_fnmsub_d: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: contract_fnmsub_d: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: contract_fnmsub_d: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: contract_fnmsub_d: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: contract_fnmsub_d: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %negc = fneg contract double %c +- %mul = fmul contract double %a, %b +- %add = fadd contract double %mul, %negc +- %neg = fneg contract double %add +- ret double %neg +-} +- +-define double @contract_fnmsub_d_nsz(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: contract_fnmsub_d_nsz: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: contract_fnmsub_d_nsz: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: contract_fnmsub_d_nsz: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: contract_fnmsub_d_nsz: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: contract_fnmsub_d_nsz: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: contract_fnmsub_d_nsz: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg contract nsz double %a +- %mul = fmul contract nsz double %nega, %b +- %add = fadd contract nsz double %mul, %c +- ret double %add +-} +- +-;; Check that fnmsub.d is not emitted. +-define double @not_contract_fnmsub_d(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: not_contract_fnmsub_d: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fneg.d $fa0, $fa0 +-; LA32-CONTRACT-FAST-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: not_contract_fnmsub_d: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fneg.d $fa0, $fa0 +-; LA32-CONTRACT-ON-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: not_contract_fnmsub_d: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fneg.d $fa0, $fa0 +-; LA32-CONTRACT-OFF-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: not_contract_fnmsub_d: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fneg.d $fa0, $fa0 +-; LA64-CONTRACT-FAST-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: not_contract_fnmsub_d: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fneg.d $fa0, $fa0 +-; LA64-CONTRACT-ON-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: not_contract_fnmsub_d: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fneg.d $fa0, $fa0 +-; LA64-CONTRACT-OFF-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg contract double %a +- %mul = fmul contract double %nega, %b +- %add = fadd contract double %mul, %c +- ret double %add +-} +- +-declare double @llvm.fma.f64(double, double, double) +- +-define double @fmadd_d_intrinsics(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fmadd_d_intrinsics: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fmadd_d_intrinsics: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fmadd_d_intrinsics: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fmadd_d_intrinsics: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fmadd_d_intrinsics: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fmadd_d_intrinsics: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %fma = call double @llvm.fma.f64(double %a, double %b, double %c) +- ret double %fma +-} +- +-define double @fmsub_d_intrinsics(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fmsub_d_intrinsics: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fmsub_d_intrinsics: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fmsub_d_intrinsics: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fmsub_d_intrinsics: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fmsub_d_intrinsics: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fmsub_d_intrinsics: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %negc = fneg double %c +- %fma = call double @llvm.fma.f64(double %a, double %b, double %negc) +- ret double %fma +-} +- +-define double @fnmadd_d_intrinsics(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fnmadd_d_intrinsics: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fnmadd_d_intrinsics: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fnmadd_d_intrinsics: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fnmadd_d_intrinsics: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fnmadd_d_intrinsics: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fnmadd_d_intrinsics: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %fma = call double @llvm.fma.f64(double %a, double %b, double %c) +- %negfma = fneg double %fma +- ret double %negfma +-} +- +-define double @fnmadd_d_nsz_intrinsics(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fnmadd_d_nsz_intrinsics: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fnmadd_d_nsz_intrinsics: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fnmadd_d_nsz_intrinsics: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fnmadd_d_nsz_intrinsics: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fnmadd_d_nsz_intrinsics: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fnmadd_d_nsz_intrinsics: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg double %a +- %negc = fneg double %c +- %fma = call nsz double @llvm.fma.f64(double %nega, double %b, double %negc) +- ret double %fma +-} +- +-;; Check that fnmadd.d is not emitted. +-define double @not_fnmadd_d_intrinsics(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: not_fnmadd_d_intrinsics: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fneg.d $fa0, $fa0 +-; LA32-CONTRACT-FAST-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: not_fnmadd_d_intrinsics: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fneg.d $fa0, $fa0 +-; LA32-CONTRACT-ON-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: not_fnmadd_d_intrinsics: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fneg.d $fa0, $fa0 +-; LA32-CONTRACT-OFF-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: not_fnmadd_d_intrinsics: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fneg.d $fa0, $fa0 +-; LA64-CONTRACT-FAST-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: not_fnmadd_d_intrinsics: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fneg.d $fa0, $fa0 +-; LA64-CONTRACT-ON-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: not_fnmadd_d_intrinsics: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fneg.d $fa0, $fa0 +-; LA64-CONTRACT-OFF-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg double %a +- %negc = fneg double %c +- %fma = call double @llvm.fma.f64(double %nega, double %b, double %negc) +- ret double %fma +-} +- +-define double @fnmsub_d_intrinsics(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fnmsub_d_intrinsics: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fnmsub_d_intrinsics: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fnmsub_d_intrinsics: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fnmsub_d_intrinsics: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fnmsub_d_intrinsics: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fnmsub_d_intrinsics: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %negc = fneg double %c +- %fma = call double @llvm.fma.f64(double %a, double %b, double %negc) +- %negfma = fneg double %fma +- ret double %negfma +-} +- +-define double @fnmsub_d_nsz_intrinsics(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fnmsub_d_nsz_intrinsics: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fnmsub_d_nsz_intrinsics: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fnmsub_d_nsz_intrinsics: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fnmsub_d_nsz_intrinsics: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fnmsub_d_nsz_intrinsics: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fnmsub_d_nsz_intrinsics: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg double %a +- %fma = call nsz double @llvm.fma.f64(double %nega, double %b, double %c) +- ret double %fma +-} +- +-;; Check that fnmsub.d is not emitted. +-define double @not_fnmsub_d_intrinsics(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: not_fnmsub_d_intrinsics: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fneg.d $fa0, $fa0 +-; LA32-CONTRACT-FAST-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: not_fnmsub_d_intrinsics: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fneg.d $fa0, $fa0 +-; LA32-CONTRACT-ON-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: not_fnmsub_d_intrinsics: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fneg.d $fa0, $fa0 +-; LA32-CONTRACT-OFF-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: not_fnmsub_d_intrinsics: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fneg.d $fa0, $fa0 +-; LA64-CONTRACT-FAST-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: not_fnmsub_d_intrinsics: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fneg.d $fa0, $fa0 +-; LA64-CONTRACT-ON-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: not_fnmsub_d_intrinsics: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fneg.d $fa0, $fa0 +-; LA64-CONTRACT-OFF-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg double %a +- %fma = call double @llvm.fma.f64(double %nega, double %b, double %c) +- ret double %fma +-} +- +-define double @fmadd_d_contract(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fmadd_d_contract: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fmadd_d_contract: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fmadd_d_contract: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fmadd_d_contract: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fmadd_d_contract: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fmadd_d_contract: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %mul = fmul contract double %a, %b +- %add = fadd contract double %mul, %c +- ret double %add +-} +- +-define double @fmsub_d_contract(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fmsub_d_contract: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fmsub_d_contract: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fmsub_d_contract: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fmsub_d_contract: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fmsub_d_contract: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fmsub_d_contract: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %mul = fmul contract double %a, %b +- %sub = fsub contract double %mul, %c +- ret double %sub +-} +- +-define double @fnmadd_d_contract(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fnmadd_d_contract: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fnmadd_d_contract: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fnmadd_d_contract: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fnmadd_d_contract: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fnmadd_d_contract: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fnmadd_d_contract: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %mul = fmul contract double %a, %b +- %add = fadd contract double %mul, %c +- %negadd = fneg contract double %add +- ret double %negadd +-} +- +-define double @fnmsub_d_contract(double %a, double %b, double %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fnmsub_d_contract: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fnmsub_d_contract: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fnmsub_d_contract: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fnmsub_d_contract: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fnmsub_d_contract: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fnmsub_d_contract: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %mul = fmul contract double %a, %b +- %negc = fneg contract double %c +- %add = fadd contract double %negc, %mul +- %negadd = fneg contract double %add +- ret double %negadd +-} +diff --git a/llvm/test/CodeGen/LoongArch/double-imm.ll b/llvm/test/CodeGen/LoongArch/double-imm.ll +deleted file mode 100644 +index 3e89db3ec..000000000 +--- a/llvm/test/CodeGen/LoongArch/double-imm.ll ++++ /dev/null +@@ -1,89 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64 +- +-define double @f64_positive_zero() nounwind { +-; LA32-LABEL: f64_positive_zero: +-; LA32: # %bb.0: +-; LA32-NEXT: movgr2fr.w $fa0, $zero +-; LA32-NEXT: movgr2frh.w $fa0, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f64_positive_zero: +-; LA64: # %bb.0: +-; LA64-NEXT: movgr2fr.d $fa0, $zero +-; LA64-NEXT: ret +- ret double 0.0 +-} +- +-define double @f64_negative_zero() nounwind { +-; LA32-LABEL: f64_negative_zero: +-; LA32: # %bb.0: +-; LA32-NEXT: movgr2fr.w $fa0, $zero +-; LA32-NEXT: movgr2frh.w $fa0, $zero +-; LA32-NEXT: fneg.d $fa0, $fa0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f64_negative_zero: +-; LA64: # %bb.0: +-; LA64-NEXT: movgr2fr.d $fa0, $zero +-; LA64-NEXT: fneg.d $fa0, $fa0 +-; LA64-NEXT: ret +- ret double -0.0 +-} +- +-define double @f64_constant_pi() nounwind { +-; LA32-LABEL: f64_constant_pi: +-; LA32: # %bb.0: +-; LA32-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_0) +-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI2_0) +-; LA32-NEXT: fld.d $fa0, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f64_constant_pi: +-; LA64: # %bb.0: +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_0) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI2_0) +-; LA64-NEXT: fld.d $fa0, $a0, 0 +-; LA64-NEXT: ret +- ret double 3.1415926535897931159979634685441851615905761718750 +-} +- +-define double @f64_add_fimm1(double %a) nounwind { +-; LA32-LABEL: f64_add_fimm1: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $zero, 1 +-; LA32-NEXT: movgr2fr.w $fa1, $a0 +-; LA32-NEXT: ffint.s.w $fa1, $fa1 +-; LA32-NEXT: fcvt.d.s $fa1, $fa1 +-; LA32-NEXT: fadd.d $fa0, $fa0, $fa1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f64_add_fimm1: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $a0, $zero, 1 +-; LA64-NEXT: movgr2fr.d $fa1, $a0 +-; LA64-NEXT: ffint.d.l $fa1, $fa1 +-; LA64-NEXT: fadd.d $fa0, $fa0, $fa1 +-; LA64-NEXT: ret +- %1 = fadd double %a, 1.0 +- ret double %1 +-} +- +-define double @f64_positive_fimm1() nounwind { +-; LA32-LABEL: f64_positive_fimm1: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $zero, 1 +-; LA32-NEXT: movgr2fr.w $fa0, $a0 +-; LA32-NEXT: ffint.s.w $fa0, $fa0 +-; LA32-NEXT: fcvt.d.s $fa0, $fa0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f64_positive_fimm1: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $a0, $zero, 1 +-; LA64-NEXT: movgr2fr.d $fa0, $a0 +-; LA64-NEXT: ffint.d.l $fa0, $fa0 +-; LA64-NEXT: ret +- ret double 1.0 +-} +diff --git a/llvm/test/CodeGen/LoongArch/dup-tail.ll b/llvm/test/CodeGen/LoongArch/dup-tail.ll +new file mode 100644 +index 000000000..cad67e98c +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/dup-tail.ll +@@ -0,0 +1,45 @@ ++; RUN: llc --mtriple=loongarch64 --relocation-model=pic -o - %s | FileCheck %s ++ ++;; Duplicate returns to enable tail call optimizations. ++declare i32 @test() ++declare i32 @test1() ++declare i32 @test2() ++declare i32 @test3() ++define i32 @duplicate_returns(i32 %a, i32 %b) nounwind { ++; CHECK-LABEL: duplicate_returns: ++; CHECK: b test2 ++; CHECK: b test ++; CHECK: b test1 ++; CHECK: b test3 ++entry: ++ %cmp = icmp eq i32 %a, 0 ++ br i1 %cmp, label %if.then, label %if.else ++ ++if.then: ; preds = %entry ++ %call = tail call i32 @test() ++ br label %return ++ ++if.else: ; preds = %entry ++ %cmp1 = icmp eq i32 %b, 0 ++ br i1 %cmp1, label %if.then2, label %if.else4 ++ ++if.then2: ; preds = %if.else ++ %call3 = tail call i32 @test1() ++ br label %return ++ ++if.else4: ; preds = %if.else ++ %cmp5 = icmp sgt i32 %a, %b ++ br i1 %cmp5, label %if.then6, label %if.else8 ++ ++if.then6: ; preds = %if.else4 ++ %call7 = tail call i32 @test2() ++ br label %return ++ ++if.else8: ; preds = %if.else4 ++ %call9 = tail call i32 @test3() ++ br label %return ++ ++return: ; preds = %if.else8, %if.then6, %if.then2, %if.then ++ %retval = phi i32 [ %call, %if.then ], [ %call3, %if.then2 ], [ %call7, %if.then6 ], [ %call9, %if.else8 ] ++ ret i32 %retval ++} +diff --git a/llvm/test/CodeGen/LoongArch/duplicate-returns-for-tailcall.ll b/llvm/test/CodeGen/LoongArch/duplicate-returns-for-tailcall.ll +deleted file mode 100644 +index 80e55ef9e..000000000 +--- a/llvm/test/CodeGen/LoongArch/duplicate-returns-for-tailcall.ll ++++ /dev/null +@@ -1,58 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s +- +-;; Perform tail call optimization for duplicate returns. +-declare i32 @test() +-declare i32 @test1() +-declare i32 @test2() +-declare i32 @test3() +-define i32 @duplicate_returns(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: duplicate_returns: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: addi.w $a0, $a0, 0 +-; CHECK-NEXT: beqz $a0, .LBB0_4 +-; CHECK-NEXT: # %bb.1: # %if.else +-; CHECK-NEXT: addi.w $a1, $a1, 0 +-; CHECK-NEXT: beqz $a1, .LBB0_5 +-; CHECK-NEXT: # %bb.2: # %if.else2 +-; CHECK-NEXT: bge $a1, $a0, .LBB0_6 +-; CHECK-NEXT: # %bb.3: # %if.then3 +-; CHECK-NEXT: b %plt(test2) +-; CHECK-NEXT: .LBB0_4: # %if.then +-; CHECK-NEXT: b %plt(test) +-; CHECK-NEXT: .LBB0_5: # %if.then2 +-; CHECK-NEXT: b %plt(test1) +-; CHECK-NEXT: .LBB0_6: # %if.else3 +-; CHECK-NEXT: b %plt(test3) +-entry: +- %cmp = icmp eq i32 %a, 0 +- br i1 %cmp, label %if.then, label %if.else +- +-if.then: +- %call = tail call i32 @test() +- br label %return +- +-if.else: +- %cmp1 = icmp eq i32 %b, 0 +- br i1 %cmp1, label %if.then2, label %if.else2 +- +-if.then2: +- %call1 = tail call i32 @test1() +- br label %return +- +-if.else2: +- %cmp5 = icmp sgt i32 %a, %b +- br i1 %cmp5, label %if.then3, label %if.else3 +- +-if.then3: +- %call2 = tail call i32 @test2() +- br label %return +- +-if.else3: +- %call3 = tail call i32 @test3() +- br label %return +- +-return: +- %retval = phi i32 [ %call, %if.then ], [ %call1, %if.then2 ], [ %call2, %if.then3 ], [ %call3, %if.else3 ] +- ret i32 %retval +-} +diff --git a/llvm/test/CodeGen/LoongArch/dwarf-eh.ll b/llvm/test/CodeGen/LoongArch/dwarf-eh.ll +deleted file mode 100644 +index f4e347e07..000000000 +--- a/llvm/test/CodeGen/LoongArch/dwarf-eh.ll ++++ /dev/null +@@ -1,54 +0,0 @@ +-; RUN: llc --mtriple=loongarch32 --relocation-model=static < %s | FileCheck %s +-; RUN: llc --mtriple=loongarch32 --relocation-model=pic < %s | FileCheck %s +-; RUN: llc --mtriple=loongarch64 --relocation-model=static < %s | FileCheck %s +-; RUN: llc --mtriple=loongarch64 --relocation-model=pic < %s | FileCheck %s +- +-declare void @throw_exception() +- +-declare i32 @__gxx_personality_v0(...) +- +-declare ptr @__cxa_begin_catch(ptr) +- +-declare void @__cxa_end_catch() +- +-; CHECK-LABEL: test1: +-; CHECK: .cfi_startproc +-;; PersonalityEncoding = DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4 +-; CHECK-NEXT: .cfi_personality 155, DW.ref.__gxx_personality_v0 +-;; LSDAEncoding = DW_EH_PE_pcrel | DW_EH_PE_sdata4 +-; CHECK-NEXT: .cfi_lsda 27, .Lexception0 +- +-define void @test1() personality ptr @__gxx_personality_v0 { +-entry: +- invoke void @throw_exception() to label %try.cont unwind label %lpad +- +-lpad: +- %0 = landingpad { ptr, i32 } +- catch ptr null +- %1 = extractvalue { ptr, i32 } %0, 0 +- %2 = tail call ptr @__cxa_begin_catch(ptr %1) +- tail call void @__cxa_end_catch() +- br label %try.cont +- +-try.cont: +- ret void +-} +- +-; CHECK-LABEL: GCC_except_table0: +-; CHECK-NEXT: .Lexception0: +-; CHECK-NEXT: .byte 255 # @LPStart Encoding = omit +-;; TTypeEncoding = DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4 +-; CHECK-NEXT: .byte 155 # @TType Encoding = indirect pcrel sdata4 +-; CHECK: .Lttbaseref0: +-;; CallSiteEncoding = dwarf::DW_EH_PE_uleb128 +-; CHECK-NEXT: .byte 1 # Call site Encoding = uleb128 +-; CHECK-NEXT: .uleb128 .Lcst_end0-.Lcst_begin0 +-; CHECK-NEXT: .Lcst_begin0: +-; CHECK-NEXT: .uleb128 .Ltmp0-.Lfunc_begin0 # >> Call Site 1 << +-; CHECK-NEXT: .uleb128 .Ltmp1-.Ltmp0 # Call between .Ltmp0 and .Ltmp1 +-; CHECK-NEXT: .uleb128 .Ltmp2-.Lfunc_begin0 # jumps to .Ltmp2 +-; CHECK-NEXT: .byte 1 # On action: 1 +-; CHECK-NEXT: .uleb128 .Ltmp1-.Lfunc_begin0 # >> Call Site 2 << +-; CHECK-NEXT: .uleb128 .Lfunc_end0-.Ltmp1 # Call between .Ltmp1 and .Lfunc_end0 +-; CHECK-NEXT: .byte 0 # has no landing pad +-; CHECK-NEXT: .byte 0 # On action: cleanup +diff --git a/llvm/test/CodeGen/LoongArch/e_flags.ll b/llvm/test/CodeGen/LoongArch/e_flags.ll +deleted file mode 100644 +index c004d1f9c..000000000 +--- a/llvm/test/CodeGen/LoongArch/e_flags.ll ++++ /dev/null +@@ -1,34 +0,0 @@ +-; RUN: llc --mtriple=loongarch32 --filetype=obj %s -o %t-la32 +-; RUN: llvm-readelf -h %t-la32 | FileCheck %s --check-prefixes=ILP32,ABI-D --match-full-lines +- +-; RUN: llc --mtriple=loongarch32 --filetype=obj %s --target-abi=ilp32s -o %t-ilp32s +-; RUN: llvm-readelf -h %t-ilp32s | FileCheck %s --check-prefixes=ILP32,ABI-S --match-full-lines +- +-; RUN: llc --mtriple=loongarch32 --filetype=obj %s --target-abi=ilp32f -o %t-ilp32f +-; RUN: llvm-readelf -h %t-ilp32f | FileCheck %s --check-prefixes=ILP32,ABI-F --match-full-lines +- +-; RUN: llc --mtriple=loongarch32 --filetype=obj %s --target-abi=ilp32d -o %t-ilp32d +-; RUN: llvm-readelf -h %t-ilp32d | FileCheck %s --check-prefixes=ILP32,ABI-D --match-full-lines +- +-; RUN: llc --mtriple=loongarch64 --filetype=obj %s -o %t-la64 +-; RUN: llvm-readelf -h %t-la64 | FileCheck %s --check-prefixes=LP64,ABI-D --match-full-lines +- +-; RUN: llc --mtriple=loongarch64 --filetype=obj %s --target-abi=lp64s -o %t-lp64s +-; RUN: llvm-readelf -h %t-lp64s | FileCheck %s --check-prefixes=LP64,ABI-S --match-full-lines +- +-; RUN: llc --mtriple=loongarch64 --filetype=obj %s --target-abi=lp64f -o %t-lp64f +-; RUN: llvm-readelf -h %t-lp64f | FileCheck %s --check-prefixes=LP64,ABI-F --match-full-lines +- +-; RUN: llc --mtriple=loongarch64 --filetype=obj %s --mattr=+d --target-abi=lp64d -o %t-lp64d +-; RUN: llvm-readelf -h %t-lp64d | FileCheck %s --check-prefixes=LP64,ABI-D --match-full-lines +- +-; LP64: Class: ELF64 +-; ILP32: Class: ELF32 +- +-; ABI-S: Flags: 0x41, SOFT-FLOAT, OBJ-v1 +-; ABI-F: Flags: 0x42, SINGLE-FLOAT, OBJ-v1 +-; ABI-D: Flags: 0x43, DOUBLE-FLOAT, OBJ-v1 +- +-define void @foo() { +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/eh-dwarf-cfa.ll b/llvm/test/CodeGen/LoongArch/eh-dwarf-cfa.ll +deleted file mode 100644 +index 796ada3a1..000000000 +--- a/llvm/test/CodeGen/LoongArch/eh-dwarf-cfa.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck --check-prefix=LA32 %s +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck --check-prefix=LA64 %s +- +-define void @dwarf() { +-; LA32-LABEL: dwarf: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: addi.w $a0, $sp, 16 +-; LA32-NEXT: bl %plt(foo) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: dwarf: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: .cfi_def_cfa_offset 16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: addi.d $a0, $sp, 16 +-; LA64-NEXT: bl %plt(foo) +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +-entry: +- %0 = call ptr @llvm.eh.dwarf.cfa(i32 0) +- call void @foo(ptr %0) +- ret void +-} +- +-declare void @foo(ptr) +- +-declare ptr @llvm.eh.dwarf.cfa(i32) nounwind +diff --git a/llvm/test/CodeGen/LoongArch/eliminateFI.ll b/llvm/test/CodeGen/LoongArch/eliminateFI.ll +new file mode 100644 +index 000000000..0272c95bd +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/eliminateFI.ll +@@ -0,0 +1,106 @@ ++; Check whether LoongArchSERegisterInfo::eliminateFI works well ++; RUN: llc -march=loongarch64 -o - %s | FileCheck %s ++ ++define signext i32 @ldptr_w_unaligned() { ++; CHECK-LABEL: ldptr_w_unaligned: ++; CHECK: # %bb.0: # %entry ++entry: ++ %array = alloca [6000 x i8], align 1 ++ %arrayidx = getelementptr inbounds [6000 x i8], [6000 x i8]* %array, i64 0, i64 5001 ++ %0 = bitcast i8* %arrayidx to i32* ++; the offset MUST be 0 ++; CHECK: ldptr.w $r{{[0-9]+}}, $r{{[0-9]+}}, 0 ++ %1 = load i32, i32* %0, align 1 ++ ret i32 %1 ++} ++ ++define signext i32 @ldptr_w_aligned() { ++; CHECK-LABEL: ldptr_w_aligned: ++; CHECK: # %bb.0: # %entry ++entry: ++ %array = alloca [6000 x i8], align 1 ++ %arrayidx = getelementptr inbounds [6000 x i8], [6000 x i8]* %array, i64 0, i64 5000 ++ %0 = bitcast i8* %arrayidx to i32* ++; the offset may not be 0, but MUST be 4-bytes aligned ++; CHECK: ldptr.w $r{{[0-9]+}}, $r{{[0-9]+}}, {{[0-9]+}} ++ %1 = load i32, i32* %0, align 1 ++ ret i32 %1 ++} ++ ++define signext i64 @ldptr_d_unaligned() { ++; CHECK-LABEL: ldptr_d_unaligned: ++; CHECK: # %bb.0: # %entry ++entry: ++ %array = alloca [6000 x i8], align 1 ++ %arrayidx = getelementptr inbounds [6000 x i8], [6000 x i8]* %array, i64 0, i64 5001 ++ %0 = bitcast i8* %arrayidx to i64* ++; the offset MUST be 0 ++; CHECK: ldptr.d $r{{[0-9]+}}, $r{{[0-9]+}}, 0 ++ %1 = load i64, i64* %0, align 1 ++ ret i64 %1 ++} ++ ++define signext i64 @ldptr_d_aligned() { ++; CHECK-LABEL: ldptr_d_aligned: ++; CHECK: # %bb.0: # %entry ++entry: ++ %array = alloca [6000 x i8], align 1 ++ %arrayidx = getelementptr inbounds [6000 x i8], [6000 x i8]* %array, i64 0, i64 5000 ++ %0 = bitcast i8* %arrayidx to i64* ++; the offset may not be 0, but MUST be 4-bytes aligned ++; CHECK: ldptr.d $r{{[0-9]+}}, $r{{[0-9]+}}, {{[0-9]+}} ++ %1 = load i64, i64* %0, align 1 ++ ret i64 %1 ++} ++ ++define void @stptr_w_unaligned(i32 signext %val) { ++; CHECK-LABEL: stptr_w_unaligned: ++; CHECK: # %bb.0: # %entry ++entry: ++ %array = alloca [6000 x i8], align 1 ++ %arrayidx = getelementptr inbounds [6000 x i8], [6000 x i8]* %array, i64 0, i64 5001 ++ %0 = bitcast i8* %arrayidx to i32* ++; the offset MUST be 0 ++; CHECK: stptr.w $r{{[0-9]+}}, $r{{[0-9]+}}, 0 ++ store i32 %val, i32* %0, align 1 ++ ret void ++} ++ ++define void @stptr_w_aligned(i32 signext %val) { ++; CHECK-LABEL: stptr_w_aligned: ++; CHECK: # %bb.0: # %entry ++entry: ++ %array = alloca [6000 x i8], align 1 ++ %arrayidx = getelementptr inbounds [6000 x i8], [6000 x i8]* %array, i64 0, i64 5000 ++ %0 = bitcast i8* %arrayidx to i32* ++; the offset may not be 0, but MUST be 4-bytes aligned ++; CHECK: stptr.w $r{{[0-9]+}}, $r{{[0-9]+}}, {{[0-9]+}} ++ store i32 %val, i32* %0, align 1 ++ ret void ++} ++ ++define void @stptr_d_unaligned(i64 %val) { ++; CHECK-LABEL: stptr_d_unaligned: ++; CHECK: # %bb.0: # %entry ++entry: ++ %array = alloca [6000 x i8], align 1 ++ %arrayidx = getelementptr inbounds [6000 x i8], [6000 x i8]* %array, i64 0, i64 5001 ++ %0 = bitcast i8* %arrayidx to i64* ++; the offset MUST be 0 ++; CHECK: stptr.d $r{{[0-9]+}}, $r{{[0-9]+}}, 0 ++ store i64 %val, i64* %0, align 1 ++ ret void ++} ++ ++define void @stptr_d_aligned(i64 %val) { ++; CHECK-LABEL: stptr_d_aligned: ++; CHECK: # %bb.0: # %entry ++entry: ++ %array = alloca [6000 x i8], align 1 ++ %arrayidx = getelementptr inbounds [6000 x i8], [6000 x i8]* %array, i64 0, i64 5000 ++ %0 = bitcast i8* %arrayidx to i64* ++; the offset may not be 0, but MUST be 4-bytes aligned ++; CHECK: stptr.d $r{{[0-9]+}}, $r{{[0-9]+}}, {{[0-9]+}} ++ store i64 %val, i64* %0, align 1 ++ ret void ++} +diff --git a/llvm/test/CodeGen/LoongArch/emergency-spill-slot.ll b/llvm/test/CodeGen/LoongArch/emergency-spill-slot.ll +index 08426b07b..80fa7a855 100644 +--- a/llvm/test/CodeGen/LoongArch/emergency-spill-slot.ll ++++ b/llvm/test/CodeGen/LoongArch/emergency-spill-slot.ll +@@ -10,92 +10,94 @@ define void @func() { + ; CHECK-NEXT: addi.d $sp, $sp, -2048 + ; CHECK-NEXT: addi.d $sp, $sp, -16 + ; CHECK-NEXT: .cfi_def_cfa_offset 4112 +-; CHECK-NEXT: pcalau12i $a0, %got_pc_hi20(var) +-; CHECK-NEXT: ld.d $a1, $a0, %got_pc_lo12(var) +-; CHECK-NEXT: ld.w $t8, $a1, 0 +-; CHECK-NEXT: ld.w $t7, $a1, 0 +-; CHECK-NEXT: ld.w $t6, $a1, 0 +-; CHECK-NEXT: ld.w $t5, $a1, 0 +-; CHECK-NEXT: ld.w $t4, $a1, 0 +-; CHECK-NEXT: ld.w $t3, $a1, 0 +-; CHECK-NEXT: ld.w $t2, $a1, 0 +-; CHECK-NEXT: ld.w $t1, $a1, 0 +-; CHECK-NEXT: ld.w $t0, $a1, 0 +-; CHECK-NEXT: ld.w $a7, $a1, 0 +-; CHECK-NEXT: ld.w $a6, $a1, 0 +-; CHECK-NEXT: ld.w $a5, $a1, 0 +-; CHECK-NEXT: ld.w $a4, $a1, 0 +-; CHECK-NEXT: ld.w $a3, $a1, 0 +-; CHECK-NEXT: ld.w $a2, $a1, 0 +-; CHECK-NEXT: ld.w $a0, $a1, 0 +-; CHECK-NEXT: st.d $fp, $sp, 0 +-; CHECK-NEXT: lu12i.w $fp, 1 +-; CHECK-NEXT: ori $fp, $fp, 12 +-; CHECK-NEXT: add.d $fp, $sp, $fp +-; CHECK-NEXT: st.w $t8, $fp, 0 +-; CHECK-NEXT: ld.d $fp, $sp, 0 +-; CHECK-NEXT: st.w $t8, $a1, 0 +-; CHECK-NEXT: st.w $t7, $a1, 0 +-; CHECK-NEXT: st.w $t6, $a1, 0 +-; CHECK-NEXT: st.w $t5, $a1, 0 +-; CHECK-NEXT: st.w $t4, $a1, 0 +-; CHECK-NEXT: st.w $t3, $a1, 0 +-; CHECK-NEXT: st.w $t2, $a1, 0 +-; CHECK-NEXT: st.w $t1, $a1, 0 +-; CHECK-NEXT: st.w $t0, $a1, 0 +-; CHECK-NEXT: st.w $a7, $a1, 0 +-; CHECK-NEXT: st.w $a6, $a1, 0 +-; CHECK-NEXT: st.w $a5, $a1, 0 +-; CHECK-NEXT: st.w $a4, $a1, 0 +-; CHECK-NEXT: st.w $a3, $a1, 0 +-; CHECK-NEXT: st.w $a2, $a1, 0 +-; CHECK-NEXT: st.w $a0, $a1, 0 +-; CHECK-NEXT: lu12i.w $a0, 1 +-; CHECK-NEXT: ori $a0, $a0, 16 +-; CHECK-NEXT: add.d $sp, $sp, $a0 +-; CHECK-NEXT: ret ++; CHECK-NEXT: lu12i.w $r5, var ++; CHECK-NEXT: ori $r5, $r5, var ++; CHECK-NEXT: lu32i.d $r5, var ++; CHECK-NEXT: lu52i.d $r5, $r5, var ++; CHECK-NEXT: ld.w $r20, $r5, 0 ++; CHECK-NEXT: ld.w $r19, $r5, 0 ++; CHECK-NEXT: ld.w $r18, $r5, 0 ++; CHECK-NEXT: ld.w $r17, $r5, 0 ++; CHECK-NEXT: ld.w $r16, $r5, 0 ++; CHECK-NEXT: ld.w $r15, $r5, 0 ++; CHECK-NEXT: ld.w $r14, $r5, 0 ++; CHECK-NEXT: ld.w $r13, $r5, 0 ++; CHECK-NEXT: ld.w $r12, $r5, 0 ++; CHECK-NEXT: ld.w $r11, $r5, 0 ++; CHECK-NEXT: ld.w $r10, $r5, 0 ++; CHECK-NEXT: ld.w $r9, $r5, 0 ++; CHECK-NEXT: ld.w $r8, $r5, 0 ++; CHECK-NEXT: ld.w $r7, $r5, 0 ++; CHECK-NEXT: ld.w $r6, $r5, 0 ++; CHECK-NEXT: ld.w $r4, $r5, 0 ++; CHECK-NEXT: st.d $r23, $sp, 0 ++; CHECK-NEXT: lu12i.w $r23, 1 ++; CHECK-NEXT: ori $r23, $r23, 12 ++; CHECK-NEXT: add.d $r23, $sp, $r23 ++; CHECK-NEXT: st.w $r20, $r23, 0 ++; CHECK-NEXT: ld.d $r23, $sp, 0 ++; CHECK-NEXT: st.w $r20, $r5, 0 ++; CHECK-NEXT: st.w $r19, $r5, 0 ++; CHECK-NEXT: st.w $r18, $r5, 0 ++; CHECK-NEXT: st.w $r17, $r5, 0 ++; CHECK-NEXT: st.w $r16, $r5, 0 ++; CHECK-NEXT: st.w $r15, $r5, 0 ++; CHECK-NEXT: st.w $r14, $r5, 0 ++; CHECK-NEXT: st.w $r13, $r5, 0 ++; CHECK-NEXT: st.w $r12, $r5, 0 ++; CHECK-NEXT: st.w $r11, $r5, 0 ++; CHECK-NEXT: st.w $r10, $r5, 0 ++; CHECK-NEXT: st.w $r9, $r5, 0 ++; CHECK-NEXT: st.w $r8, $r5, 0 ++; CHECK-NEXT: st.w $r7, $r5, 0 ++; CHECK-NEXT: st.w $r6, $r5, 0 ++; CHECK-NEXT: st.w $r4, $r5, 0 ++; CHECK-NEXT: lu12i.w $r4, 1 ++; CHECK-NEXT: ori $r4, $r4, 16 ++; CHECK-NEXT: add.d $sp, $sp, $r4 ++; CHECK-NEXT: jr $ra + %space = alloca i32, align 4 + %stackspace = alloca[1024 x i32], align 4 + + ;; Load values to increase register pressure. +- %v0 = load volatile i32, ptr @var +- %v1 = load volatile i32, ptr @var +- %v2 = load volatile i32, ptr @var +- %v3 = load volatile i32, ptr @var +- %v4 = load volatile i32, ptr @var +- %v5 = load volatile i32, ptr @var +- %v6 = load volatile i32, ptr @var +- %v7 = load volatile i32, ptr @var +- %v8 = load volatile i32, ptr @var +- %v9 = load volatile i32, ptr @var +- %v10 = load volatile i32, ptr @var +- %v11 = load volatile i32, ptr @var +- %v12 = load volatile i32, ptr @var +- %v13 = load volatile i32, ptr @var +- %v14 = load volatile i32, ptr @var +- %v15 = load volatile i32, ptr @var ++ %v0 = load volatile i32, i32* @var ++ %v1 = load volatile i32, i32* @var ++ %v2 = load volatile i32, i32* @var ++ %v3 = load volatile i32, i32* @var ++ %v4 = load volatile i32, i32* @var ++ %v5 = load volatile i32, i32* @var ++ %v6 = load volatile i32, i32* @var ++ %v7 = load volatile i32, i32* @var ++ %v8 = load volatile i32, i32* @var ++ %v9 = load volatile i32, i32* @var ++ %v10 = load volatile i32, i32* @var ++ %v11 = load volatile i32, i32* @var ++ %v12 = load volatile i32, i32* @var ++ %v13 = load volatile i32, i32* @var ++ %v14 = load volatile i32, i32* @var ++ %v15 = load volatile i32, i32* @var + + ;; Computing a stack-relative values needs an additional register. + ;; We should get an emergency spill/reload for this. +- store volatile i32 %v0, ptr %space ++ store volatile i32 %v0, i32* %space + + ;; store values so they are used. +- store volatile i32 %v0, ptr @var +- store volatile i32 %v1, ptr @var +- store volatile i32 %v2, ptr @var +- store volatile i32 %v3, ptr @var +- store volatile i32 %v4, ptr @var +- store volatile i32 %v5, ptr @var +- store volatile i32 %v6, ptr @var +- store volatile i32 %v7, ptr @var +- store volatile i32 %v8, ptr @var +- store volatile i32 %v9, ptr @var +- store volatile i32 %v10, ptr @var +- store volatile i32 %v11, ptr @var +- store volatile i32 %v12, ptr @var +- store volatile i32 %v13, ptr @var +- store volatile i32 %v14, ptr @var +- store volatile i32 %v15, ptr @var ++ store volatile i32 %v0, i32* @var ++ store volatile i32 %v1, i32* @var ++ store volatile i32 %v2, i32* @var ++ store volatile i32 %v3, i32* @var ++ store volatile i32 %v4, i32* @var ++ store volatile i32 %v5, i32* @var ++ store volatile i32 %v6, i32* @var ++ store volatile i32 %v7, i32* @var ++ store volatile i32 %v8, i32* @var ++ store volatile i32 %v9, i32* @var ++ store volatile i32 %v10, i32* @var ++ store volatile i32 %v11, i32* @var ++ store volatile i32 %v12, i32* @var ++ store volatile i32 %v13, i32* @var ++ store volatile i32 %v14, i32* @var ++ store volatile i32 %v15, i32* @var + + ret void + } +diff --git a/llvm/test/CodeGen/LoongArch/exception-pointer-register.ll b/llvm/test/CodeGen/LoongArch/exception-pointer-register.ll +deleted file mode 100644 +index 797c7e520..000000000 +--- a/llvm/test/CodeGen/LoongArch/exception-pointer-register.ll ++++ /dev/null +@@ -1,120 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --verify-machineinstrs < %s \ +-; RUN: | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s \ +-; RUN: | FileCheck %s --check-prefix=LA64 +- +-declare void @foo(ptr %p); +-declare void @bar(ptr %p); +-declare dso_local i32 @__gxx_personality_v0(...) +- +-;; Before getExceptionPointerRegister() and getExceptionSelectorRegister() +-;; lowering hooks were defined this would trigger an assertion during live +-;; variable analysis. +- +-define void @caller(ptr %p) personality ptr @__gxx_personality_v0 { +-; LA32-LABEL: caller: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: st.w $fp, $sp, 8 # 4-byte Folded Spill +-; LA32-NEXT: st.w $s0, $sp, 4 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: .cfi_offset 22, -8 +-; LA32-NEXT: .cfi_offset 23, -12 +-; LA32-NEXT: move $fp, $a0 +-; LA32-NEXT: beqz $a0, .LBB0_2 +-; LA32-NEXT: # %bb.1: # %bb2 +-; LA32-NEXT: .Ltmp0: +-; LA32-NEXT: move $a0, $fp +-; LA32-NEXT: bl %plt(bar) +-; LA32-NEXT: .Ltmp1: +-; LA32-NEXT: b .LBB0_3 +-; LA32-NEXT: .LBB0_2: # %bb1 +-; LA32-NEXT: .Ltmp2: +-; LA32-NEXT: move $a0, $fp +-; LA32-NEXT: bl %plt(foo) +-; LA32-NEXT: .Ltmp3: +-; LA32-NEXT: .LBB0_3: # %end2 +-; LA32-NEXT: ld.w $s0, $sp, 4 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $fp, $sp, 8 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB0_4: # %lpad +-; LA32-NEXT: .Ltmp4: +-; LA32-NEXT: move $s0, $a0 +-; LA32-NEXT: move $a0, $fp +-; LA32-NEXT: bl callee +-; LA32-NEXT: move $a0, $s0 +-; LA32-NEXT: bl %plt(_Unwind_Resume) +-; +-; LA64-LABEL: caller: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: addi.d $sp, $sp, -32 +-; LA64-NEXT: .cfi_def_cfa_offset 32 +-; LA64-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill +-; LA64-NEXT: st.d $fp, $sp, 16 # 8-byte Folded Spill +-; LA64-NEXT: st.d $s0, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: .cfi_offset 22, -16 +-; LA64-NEXT: .cfi_offset 23, -24 +-; LA64-NEXT: move $fp, $a0 +-; LA64-NEXT: beqz $a0, .LBB0_2 +-; LA64-NEXT: # %bb.1: # %bb2 +-; LA64-NEXT: .Ltmp0: +-; LA64-NEXT: move $a0, $fp +-; LA64-NEXT: bl %plt(bar) +-; LA64-NEXT: .Ltmp1: +-; LA64-NEXT: b .LBB0_3 +-; LA64-NEXT: .LBB0_2: # %bb1 +-; LA64-NEXT: .Ltmp2: +-; LA64-NEXT: move $a0, $fp +-; LA64-NEXT: bl %plt(foo) +-; LA64-NEXT: .Ltmp3: +-; LA64-NEXT: .LBB0_3: # %end2 +-; LA64-NEXT: ld.d $s0, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $fp, $sp, 16 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 32 +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB0_4: # %lpad +-; LA64-NEXT: .Ltmp4: +-; LA64-NEXT: move $s0, $a0 +-; LA64-NEXT: move $a0, $fp +-; LA64-NEXT: bl callee +-; LA64-NEXT: move $a0, $s0 +-; LA64-NEXT: bl %plt(_Unwind_Resume) +-entry: +- %0 = icmp eq ptr %p, null +- br i1 %0, label %bb1, label %bb2 +- +-bb1: +- invoke void @foo(ptr %p) to label %end1 unwind label %lpad +- +-bb2: +- invoke void @bar(ptr %p) to label %end2 unwind label %lpad +- +-lpad: +- %1 = landingpad { ptr, i32 } cleanup +- call void @callee(ptr %p) +- resume { ptr, i32 } %1 +- +-end1: +- ret void +- +-end2: +- ret void +-} +- +-define internal void @callee(ptr %p) { +-; LA32-LABEL: callee: +-; LA32: # %bb.0: +-; LA32-NEXT: ret +-; +-; LA64-LABEL: callee: +-; LA64: # %bb.0: +-; LA64-NEXT: ret +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/expand-call.ll b/llvm/test/CodeGen/LoongArch/expand-call.ll +deleted file mode 100644 +index e0d179f92..000000000 +--- a/llvm/test/CodeGen/LoongArch/expand-call.ll ++++ /dev/null +@@ -1,16 +0,0 @@ +-; RUN: llc --mtriple=loongarch64 --stop-before loongarch-prera-expand-pseudo \ +-; RUN: --verify-machineinstrs < %s | FileCheck %s --check-prefix=NOEXPAND +-; RUN: llc --mtriple=loongarch64 --stop-before machine-opt-remark-emitter \ +-; RUN: --verify-machineinstrs < %s | FileCheck %s --check-prefix=EXPAND +- +-declare void @callee() +- +-define void @caller() nounwind { +-; NOEXPAND-LABEL: name: caller +-; NOEXPAND: PseudoCALL target-flags{{.*}}callee +-; +-; EXPAND-LABEL: name: caller +-; EXPAND: BL target-flags{{.*}}callee +- call void @callee() +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/fabs.ll b/llvm/test/CodeGen/LoongArch/fabs.ll +deleted file mode 100644 +index 3f3dacd9b..000000000 +--- a/llvm/test/CodeGen/LoongArch/fabs.ll ++++ /dev/null +@@ -1,56 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA32F +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32D +-; RUN: llc --mtriple=loongarch64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA64F +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64D +- +-declare float @llvm.fabs.f32(float) +-declare double @llvm.fabs.f64(double) +- +-define float @fabs_f32(float %a) nounwind { +-; LA32F-LABEL: fabs_f32: +-; LA32F: # %bb.0: +-; LA32F-NEXT: fabs.s $fa0, $fa0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: fabs_f32: +-; LA32D: # %bb.0: +-; LA32D-NEXT: fabs.s $fa0, $fa0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: fabs_f32: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fabs.s $fa0, $fa0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: fabs_f32: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fabs.s $fa0, $fa0 +-; LA64D-NEXT: ret +- %1 = call float @llvm.fabs.f32(float %a) +- ret float %1 +-} +- +-define double @fabs_f64(double %a) nounwind { +-; LA32F-LABEL: fabs_f64: +-; LA32F: # %bb.0: +-; LA32F-NEXT: bstrpick.w $a1, $a1, 30, 0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: fabs_f64: +-; LA32D: # %bb.0: +-; LA32D-NEXT: fabs.d $fa0, $fa0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: fabs_f64: +-; LA64F: # %bb.0: +-; LA64F-NEXT: bstrpick.d $a0, $a0, 62, 0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: fabs_f64: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fabs.d $fa0, $fa0 +-; LA64D-NEXT: ret +- %1 = call double @llvm.fabs.f64(double %a) +- ret double %1 +-} +diff --git a/llvm/test/CodeGen/LoongArch/fcopysign.ll b/llvm/test/CodeGen/LoongArch/fcopysign.ll +index 181130d2c..c16413715 100644 +--- a/llvm/test/CodeGen/LoongArch/fcopysign.ll ++++ b/llvm/test/CodeGen/LoongArch/fcopysign.ll +@@ -1,123 +1,17 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA32F +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32D +-; RUN: llc --mtriple=loongarch64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA64F +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64D ++; RUN: llc -march=loongarch64 -o - %s | FileCheck %s + +-declare float @llvm.copysign.f32(float, float) +-declare double @llvm.copysign.f64(double, double) +- +-define float @fcopysign_s(float %a, float %b) nounwind { +-; LA32F-LABEL: fcopysign_s: +-; LA32F: # %bb.0: +-; LA32F-NEXT: fcopysign.s $fa0, $fa0, $fa1 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: fcopysign_s: +-; LA32D: # %bb.0: +-; LA32D-NEXT: fcopysign.s $fa0, $fa0, $fa1 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: fcopysign_s: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fcopysign.s $fa0, $fa0, $fa1 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: fcopysign_s: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fcopysign.s $fa0, $fa0, $fa1 +-; LA64D-NEXT: ret +- %1 = call float @llvm.copysign.f32(float %a, float %b) +- ret float %1 +-} +- +-define double @fcopysign_d(double %a, double %b) nounwind { +-; LA32F-LABEL: fcopysign_d: +-; LA32F: # %bb.0: +-; LA32F-NEXT: srli.w $a2, $a3, 31 +-; LA32F-NEXT: bstrins.w $a1, $a2, 31, 31 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: fcopysign_d: +-; LA32D: # %bb.0: +-; LA32D-NEXT: fcopysign.d $fa0, $fa0, $fa1 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: fcopysign_d: +-; LA64F: # %bb.0: +-; LA64F-NEXT: srli.d $a1, $a1, 63 +-; LA64F-NEXT: bstrins.d $a0, $a1, 63, 63 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: fcopysign_d: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fcopysign.d $fa0, $fa0, $fa1 +-; LA64D-NEXT: ret +- %1 = call double @llvm.copysign.f64(double %a, double %b) +- ret double %1 +-} +- +-define double @fold_promote_d_s(double %a, float %b) nounwind { +-; LA32F-LABEL: fold_promote_d_s: +-; LA32F: # %bb.0: +-; LA32F-NEXT: movfr2gr.s $a2, $fa0 +-; LA32F-NEXT: srli.w $a2, $a2, 31 +-; LA32F-NEXT: bstrins.w $a1, $a2, 31, 31 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: fold_promote_d_s: +-; LA32D: # %bb.0: +-; LA32D-NEXT: fcvt.d.s $fa1, $fa1 +-; LA32D-NEXT: fcopysign.d $fa0, $fa0, $fa1 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: fold_promote_d_s: +-; LA64F: # %bb.0: +-; LA64F-NEXT: lu12i.w $a1, -524288 +-; LA64F-NEXT: lu32i.d $a1, 0 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: and $a1, $a2, $a1 +-; LA64F-NEXT: slli.d $a1, $a1, 32 +-; LA64F-NEXT: bstrins.d $a1, $a0, 62, 0 +-; LA64F-NEXT: move $a0, $a1 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: fold_promote_d_s: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fcvt.d.s $fa1, $fa1 +-; LA64D-NEXT: fcopysign.d $fa0, $fa0, $fa1 +-; LA64D-NEXT: ret +- %c = fpext float %b to double +- %t = call double @llvm.copysign.f64(double %a, double %c) +- ret double %t ++define float @fcopysign_s(float %a, float %b) { ++; CHECK-LABEL: fcopysign_s: ++; CHECK: fcopysign.s $f0, $f0, $f1 ++ %ret = call float @llvm.copysign.f32(float %a, float %b) ++ ret float %ret + } ++declare float @llvm.copysign.f32(float %a, float %b) + +-define float @fold_demote_s_d(float %a, double %b) nounwind { +-; LA32F-LABEL: fold_demote_s_d: +-; LA32F: # %bb.0: +-; LA32F-NEXT: movgr2fr.w $fa1, $a1 +-; LA32F-NEXT: fcopysign.s $fa0, $fa0, $fa1 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: fold_demote_s_d: +-; LA32D: # %bb.0: +-; LA32D-NEXT: fcvt.s.d $fa1, $fa1 +-; LA32D-NEXT: fcopysign.s $fa0, $fa0, $fa1 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: fold_demote_s_d: +-; LA64F: # %bb.0: +-; LA64F-NEXT: srli.d $a0, $a0, 32 +-; LA64F-NEXT: movgr2fr.w $fa1, $a0 +-; LA64F-NEXT: fcopysign.s $fa0, $fa0, $fa1 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: fold_demote_s_d: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fcvt.s.d $fa1, $fa1 +-; LA64D-NEXT: fcopysign.s $fa0, $fa0, $fa1 +-; LA64D-NEXT: ret +- %c = fptrunc double %b to float +- %t = call float @llvm.copysign.f32(float %a, float %c) +- ret float %t ++define double @fcopysign_d(double %a, double %b) { ++; CHECK-LABEL: fcopysign_d: ++; CHECK: fcopysign.d $f0, $f0, $f1 ++ %ret = call double @llvm.copysign.f64(double %a, double %b) ++ ret double %ret + } ++declare double @llvm.copysign.f64(double %a, double %b) +diff --git a/llvm/test/CodeGen/LoongArch/feature-32bit.ll b/llvm/test/CodeGen/LoongArch/feature-32bit.ll +deleted file mode 100644 +index ef3cbd989..000000000 +--- a/llvm/test/CodeGen/LoongArch/feature-32bit.ll ++++ /dev/null +@@ -1,5 +0,0 @@ +-; RUN: llc --mtriple=loongarch64 --mattr=help 2>&1 | FileCheck %s +-; RUN: llc --mtriple=loongarch32 --mattr=help 2>&1 | FileCheck %s +- +-; CHECK: Available features for this target: +-; CHECK: 32bit - LA32 Basic Integer and Privilege Instruction Set. +diff --git a/llvm/test/CodeGen/LoongArch/fence-singlethread.ll b/llvm/test/CodeGen/LoongArch/fence-singlethread.ll +new file mode 100644 +index 000000000..f4d1a3965 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/fence-singlethread.ll +@@ -0,0 +1,11 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s ++ ++define void @fence_singlethread() { ++; CHECK-LABEL: fence_singlethread: ++; CHECK: # %bb.0: ++; CHECK-NEXT: dbar 16 ++; CHECK-NEXT: jr $ra ++ fence syncscope("singlethread") seq_cst ++ ret void ++} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/fence.ll b/llvm/test/CodeGen/LoongArch/fence.ll +similarity index 57% +rename from llvm/test/CodeGen/LoongArch/ir-instruction/fence.ll +rename to llvm/test/CodeGen/LoongArch/fence.ll +index c5b2232f9..05e2639ca 100644 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/fence.ll ++++ b/llvm/test/CodeGen/LoongArch/fence.ll +@@ -1,59 +1,38 @@ + ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 + ; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 + + define void @fence_acquire() nounwind { +-; LA32-LABEL: fence_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: dbar 20 +-; LA32-NEXT: ret +-; + ; LA64-LABEL: fence_acquire: + ; LA64: # %bb.0: + ; LA64-NEXT: dbar 20 +-; LA64-NEXT: ret ++; LA64-NEXT: jr $ra + fence acquire + ret void + } + + define void @fence_release() nounwind { +-; LA32-LABEL: fence_release: +-; LA32: # %bb.0: +-; LA32-NEXT: dbar 18 +-; LA32-NEXT: ret +-; + ; LA64-LABEL: fence_release: + ; LA64: # %bb.0: + ; LA64-NEXT: dbar 18 +-; LA64-NEXT: ret ++; LA64-NEXT: jr $ra + fence release + ret void + } + + define void @fence_acq_rel() nounwind { +-; LA32-LABEL: fence_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: dbar 16 +-; LA32-NEXT: ret +-; + ; LA64-LABEL: fence_acq_rel: + ; LA64: # %bb.0: + ; LA64-NEXT: dbar 16 +-; LA64-NEXT: ret ++; LA64-NEXT: jr $ra + fence acq_rel + ret void + } + + define void @fence_seq_cst() nounwind { +-; LA32-LABEL: fence_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: dbar 16 +-; LA32-NEXT: ret +-; + ; LA64-LABEL: fence_seq_cst: + ; LA64: # %bb.0: + ; LA64-NEXT: dbar 16 +-; LA64-NEXT: ret ++; LA64-NEXT: jr $ra + fence seq_cst + ret void + } +diff --git a/llvm/test/CodeGen/LoongArch/float-br-fcmp.ll b/llvm/test/CodeGen/LoongArch/float-br-fcmp.ll +deleted file mode 100644 +index a5edc9aa2..000000000 +--- a/llvm/test/CodeGen/LoongArch/float-br-fcmp.ll ++++ /dev/null +@@ -1,873 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA64 +- +-declare void @abort() +- +-define void @br_fcmp_oeq_bcnez_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_oeq_bcnez_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.ceq.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: bcnez $fcc0, .LBB0_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB0_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_oeq_bcnez_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.ceq.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: bcnez $fcc0, .LBB0_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB0_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp oeq float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_oeq_bceqz_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_oeq_bceqz_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cune.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: bceqz $fcc0, .LBB1_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB1_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_oeq_bceqz_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cune.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: bceqz $fcc0, .LBB1_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB1_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp oeq float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_ogt_bcnez_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_ogt_bcnez_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: bcnez $fcc0, .LBB2_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB2_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ogt_bcnez_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: bcnez $fcc0, .LBB2_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB2_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ogt float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_ogt_bceqz_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_ogt_bceqz_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: bceqz $fcc0, .LBB3_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB3_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ogt_bceqz_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: bceqz $fcc0, .LBB3_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB3_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ogt float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_oge_bcnez_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_oge_bcnez_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: bcnez $fcc0, .LBB4_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB4_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_oge_bcnez_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: bcnez $fcc0, .LBB4_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB4_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp oge float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_oge_bceqz_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_oge_bceqz_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: bceqz $fcc0, .LBB5_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB5_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_oge_bceqz_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: bceqz $fcc0, .LBB5_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB5_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp oge float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_olt_bcnez_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_olt_bcnez_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: bcnez $fcc0, .LBB6_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB6_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_olt_bcnez_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: bcnez $fcc0, .LBB6_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB6_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp olt float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_olt_bceqz_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_olt_bceqz_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: bceqz $fcc0, .LBB7_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB7_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_olt_bceqz_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: bceqz $fcc0, .LBB7_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB7_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp olt float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_ole_bcnez_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_ole_bcnez_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: bcnez $fcc0, .LBB8_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB8_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ole_bcnez_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: bcnez $fcc0, .LBB8_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB8_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ole float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_ole_bceqz_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_ole_bceqz_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: bceqz $fcc0, .LBB9_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB9_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ole_bceqz_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: bceqz $fcc0, .LBB9_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB9_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ole float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_one_bcnez_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_one_bcnez_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cne.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: bcnez $fcc0, .LBB10_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB10_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_one_bcnez_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cne.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: bcnez $fcc0, .LBB10_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB10_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp one float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_one_bceqz_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_one_bceqz_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cueq.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: bceqz $fcc0, .LBB11_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB11_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_one_bceqz_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cueq.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: bceqz $fcc0, .LBB11_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB11_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp one float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_ord_bcnez_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_ord_bcnez_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cor.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: bcnez $fcc0, .LBB12_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB12_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ord_bcnez_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cor.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: bcnez $fcc0, .LBB12_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB12_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ord float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_ord_bceqz_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_ord_bceqz_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cun.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: bceqz $fcc0, .LBB13_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB13_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ord_bceqz_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cun.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: bceqz $fcc0, .LBB13_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB13_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ord float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_ueq_bcnez_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_ueq_bcnez_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cueq.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: bcnez $fcc0, .LBB14_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB14_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ueq_bcnez_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cueq.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: bcnez $fcc0, .LBB14_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB14_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ueq float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_ueq_bceqz_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_ueq_bceqz_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cne.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: bceqz $fcc0, .LBB15_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB15_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ueq_bceqz_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cne.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: bceqz $fcc0, .LBB15_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB15_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ueq float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_ugt_bcnez_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_ugt_bcnez_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: bcnez $fcc0, .LBB16_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB16_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ugt_bcnez_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: bcnez $fcc0, .LBB16_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB16_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ugt float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_ugt_bceqz_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_ugt_bceqz_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: bceqz $fcc0, .LBB17_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB17_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ugt_bceqz_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: bceqz $fcc0, .LBB17_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB17_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ugt float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_uge_bcnez_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_uge_bcnez_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: bcnez $fcc0, .LBB18_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB18_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_uge_bcnez_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: bcnez $fcc0, .LBB18_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB18_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp uge float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_uge_bceqz_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_uge_bceqz_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: bceqz $fcc0, .LBB19_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB19_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_uge_bceqz_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: bceqz $fcc0, .LBB19_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB19_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp uge float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_ult_bcnez_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_ult_bcnez_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: bcnez $fcc0, .LBB20_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB20_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ult_bcnez_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: bcnez $fcc0, .LBB20_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB20_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ult float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_ult_bceqz_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_ult_bceqz_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: bceqz $fcc0, .LBB21_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB21_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ult_bceqz_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: bceqz $fcc0, .LBB21_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB21_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ult float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_ule_bcnez_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_ule_bcnez_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: bcnez $fcc0, .LBB22_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB22_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ule_bcnez_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: bcnez $fcc0, .LBB22_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB22_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ule float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_ule_bceqz_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_ule_bceqz_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: bceqz $fcc0, .LBB23_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB23_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_ule_bceqz_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: bceqz $fcc0, .LBB23_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB23_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp ule float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_une_bcnez_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_une_bcnez_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cune.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: bcnez $fcc0, .LBB24_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB24_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_une_bcnez_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cune.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: bcnez $fcc0, .LBB24_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB24_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp une float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_une_bceqz_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_une_bceqz_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.ceq.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: bceqz $fcc0, .LBB25_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB25_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_une_bceqz_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.ceq.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: bceqz $fcc0, .LBB25_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB25_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp une float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +- +-define void @br_fcmp_uno_bcnez_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_uno_bcnez_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cun.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: bcnez $fcc0, .LBB26_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB26_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_uno_bcnez_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cun.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: bcnez $fcc0, .LBB26_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB26_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp uno float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.else: +- ret void +-if.then: +- tail call void @abort() +- unreachable +-} +- +-define void @br_fcmp_uno_bceqz_float(float %a, float %b) nounwind { +-; LA32-LABEL: br_fcmp_uno_bceqz_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cor.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: bceqz $fcc0, .LBB27_2 +-; LA32-NEXT: # %bb.1: # %if.else +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB27_2: # %if.then +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(abort) +-; +-; LA64-LABEL: br_fcmp_uno_bceqz_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cor.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: bceqz $fcc0, .LBB27_2 +-; LA64-NEXT: # %bb.1: # %if.else +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB27_2: # %if.then +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(abort) +- %1 = fcmp uno float %a, %b +- br i1 %1, label %if.then, label %if.else +-if.then: +- tail call void @abort() +- unreachable +-if.else: +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/float-fcmp-strict.ll b/llvm/test/CodeGen/LoongArch/float-fcmp-strict.ll +deleted file mode 100644 +index 0459d5019..000000000 +--- a/llvm/test/CodeGen/LoongArch/float-fcmp-strict.ll ++++ /dev/null +@@ -1,243 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA64 +- +-declare i1 @llvm.experimental.constrained.fcmp.f32(float, float, metadata, metadata) +- +-define i32 @fcmp_oeq(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_oeq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.ceq.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_oeq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.ceq.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"oeq", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ogt(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ogt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ogt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"ogt", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_oge(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_oge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_oge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"oge", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_olt(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_olt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_olt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"olt", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ole(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ole: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ole: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"ole", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_one(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_one: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cne.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_one: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cne.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"one", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ord(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ord: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cor.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ord: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cor.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"ord", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ueq(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ueq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cueq.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ueq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cueq.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"ueq", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ugt(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ugt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ugt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"ugt", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_uge(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_uge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_uge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"uge", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ult(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ult: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ult: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"ult", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ule(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ule: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ule: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"ule", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_une(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_une: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cune.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_une: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cune.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"une", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_uno(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_uno: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cun.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_uno: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cun.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"uno", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +diff --git a/llvm/test/CodeGen/LoongArch/float-fcmps-strict.ll b/llvm/test/CodeGen/LoongArch/float-fcmps-strict.ll +deleted file mode 100644 +index cad4d45c1..000000000 +--- a/llvm/test/CodeGen/LoongArch/float-fcmps-strict.ll ++++ /dev/null +@@ -1,482 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA64 +- +-declare i1 @llvm.experimental.constrained.fcmps.f32(float, float, metadata, metadata) +-declare i1 @llvm.experimental.constrained.fcmp.f32(float, float, metadata, metadata) +- +-define i32 @fcmps_oeq(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmps_oeq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.seq.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_oeq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.seq.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"oeq", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_ogt(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmps_ogt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.slt.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_ogt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.slt.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"ogt", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_oge(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmps_oge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.sle.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_oge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.sle.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"oge", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_olt(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmps_olt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.slt.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_olt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.slt.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"olt", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_ole(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmps_ole: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.sle.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_ole: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.sle.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"ole", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_one(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmps_one: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.sne.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_one: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.sne.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"one", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_ord(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmps_ord: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.sor.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_ord: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.sor.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"ord", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_ueq(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmps_ueq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.sueq.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_ueq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.sueq.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"ueq", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_ugt(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmps_ugt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.sult.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_ugt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.sult.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"ugt", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_uge(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmps_uge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.sule.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_uge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.sule.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"uge", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_ult(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmps_ult: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.sult.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_ult: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.sult.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"ult", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_ule(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmps_ule: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.sule.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_ule: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.sule.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"ule", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_une(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmps_une: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.sune.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_une: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.sune.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"une", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmps_uno(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmps_uno: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.sun.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmps_uno: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.sun.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"uno", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_oeq(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_oeq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.ceq.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_oeq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.ceq.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"oeq", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ogt(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ogt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ogt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"ogt", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_oge(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_oge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_oge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"oge", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_olt(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_olt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_olt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"olt", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ole(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ole: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ole: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"ole", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_one(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_one: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cne.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_one: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cne.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"one", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ord(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ord: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cor.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ord: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cor.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"ord", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ueq(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ueq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cueq.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ueq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cueq.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"ueq", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ugt(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ugt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ugt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"ugt", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_uge(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_uge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_uge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"uge", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ult(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ult: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ult: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"ult", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_ule(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_ule: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ule: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"ule", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_une(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_une: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cune.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_une: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cune.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"une", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +- +-define i32 @fcmp_uno(float %a, float %b) nounwind strictfp { +-; LA32-LABEL: fcmp_uno: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cun.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_uno: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cun.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %1 = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"uno", metadata !"fpexcept.strict") strictfp +- %2 = zext i1 %1 to i32 +- ret i32 %2 +-} +diff --git a/llvm/test/CodeGen/LoongArch/float-fma.ll b/llvm/test/CodeGen/LoongArch/float-fma.ll +deleted file mode 100644 +index c236255d9..000000000 +--- a/llvm/test/CodeGen/LoongArch/float-fma.ll ++++ /dev/null +@@ -1,1100 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+f,-d --fp-contract=fast < %s \ +-; RUN: | FileCheck %s --check-prefix=LA32-CONTRACT-FAST +-; RUN: llc --mtriple=loongarch32 --mattr=+f,-d --fp-contract=on < %s \ +-; RUN: | FileCheck %s --check-prefix=LA32-CONTRACT-ON +-; RUN: llc --mtriple=loongarch32 --mattr=+f,-d --fp-contract=off < %s \ +-; RUN: | FileCheck %s --check-prefix=LA32-CONTRACT-OFF +-; RUN: llc --mtriple=loongarch64 --mattr=+f,-d --fp-contract=fast < %s \ +-; RUN: | FileCheck %s --check-prefix=LA64-CONTRACT-FAST +-; RUN: llc --mtriple=loongarch64 --mattr=+f,-d --fp-contract=on < %s \ +-; RUN: | FileCheck %s --check-prefix=LA64-CONTRACT-ON +-; RUN: llc --mtriple=loongarch64 --mattr=+f,-d --fp-contract=off < %s \ +-; RUN: | FileCheck %s --check-prefix=LA64-CONTRACT-OFF +- +-define float @fmadd_s(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fmadd_s: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fmadd_s: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA32-CONTRACT-ON-NEXT: fadd.s $fa0, $fa0, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fmadd_s: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA32-CONTRACT-OFF-NEXT: fadd.s $fa0, $fa0, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fmadd_s: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fmadd_s: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA64-CONTRACT-ON-NEXT: fadd.s $fa0, $fa0, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fmadd_s: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA64-CONTRACT-OFF-NEXT: fadd.s $fa0, $fa0, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %mul = fmul float %a, %b +- %add = fadd float %mul, %c +- ret float %add +-} +- +-define float @fmsub_s(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fmsub_s: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fmsub_s: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA32-CONTRACT-ON-NEXT: fsub.s $fa0, $fa0, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fmsub_s: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA32-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa0, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fmsub_s: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fmsub_s: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA64-CONTRACT-ON-NEXT: fsub.s $fa0, $fa0, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fmsub_s: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA64-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa0, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %mul = fmul float %a, %b +- %sub = fsub float %mul, %c +- ret float %sub +-} +- +-define float @fnmadd_s(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fnmadd_s: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fnmadd_s: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA32-CONTRACT-ON-NEXT: fadd.s $fa0, $fa0, $fa2 +-; LA32-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fnmadd_s: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA32-CONTRACT-OFF-NEXT: fadd.s $fa0, $fa0, $fa2 +-; LA32-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fnmadd_s: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fnmadd_s: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA64-CONTRACT-ON-NEXT: fadd.s $fa0, $fa0, $fa2 +-; LA64-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fnmadd_s: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA64-CONTRACT-OFF-NEXT: fadd.s $fa0, $fa0, $fa2 +-; LA64-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0 +-; LA64-CONTRACT-OFF-NEXT: ret +- %mul = fmul float %a, %b +- %add = fadd float %mul, %c +- %negadd = fneg float %add +- ret float %negadd +-} +- +-define float @fnmadd_s_nsz(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fnmadd_s_nsz: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fnmadd_s_nsz: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0 +-; LA32-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA32-CONTRACT-ON-NEXT: fsub.s $fa0, $fa0, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fnmadd_s_nsz: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0 +-; LA32-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA32-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa0, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fnmadd_s_nsz: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fnmadd_s_nsz: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0 +-; LA64-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA64-CONTRACT-ON-NEXT: fsub.s $fa0, $fa0, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fnmadd_s_nsz: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0 +-; LA64-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA64-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa0, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg nsz float %a +- %negc = fneg nsz float %c +- %mul = fmul nsz float %nega, %b +- %add = fadd nsz float %mul, %negc +- ret float %add +-} +- +-;; Check that fnmadd.s is not emitted. +-define float @not_fnmadd_s(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: not_fnmadd_s: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0 +-; LA32-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: not_fnmadd_s: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0 +-; LA32-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA32-CONTRACT-ON-NEXT: fsub.s $fa0, $fa0, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: not_fnmadd_s: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0 +-; LA32-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA32-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa0, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: not_fnmadd_s: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0 +-; LA64-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: not_fnmadd_s: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0 +-; LA64-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA64-CONTRACT-ON-NEXT: fsub.s $fa0, $fa0, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: not_fnmadd_s: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0 +-; LA64-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA64-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa0, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg float %a +- %negc = fneg float %c +- %mul = fmul float %nega, %b +- %add = fadd float %mul, %negc +- ret float %add +-} +- +-define float @fnmsub_s(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fnmsub_s: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fnmsub_s: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA32-CONTRACT-ON-NEXT: fsub.s $fa0, $fa0, $fa2 +-; LA32-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fnmsub_s: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA32-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa0, $fa2 +-; LA32-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fnmsub_s: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fnmsub_s: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA64-CONTRACT-ON-NEXT: fsub.s $fa0, $fa0, $fa2 +-; LA64-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fnmsub_s: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA64-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa0, $fa2 +-; LA64-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0 +-; LA64-CONTRACT-OFF-NEXT: ret +- %negc = fneg float %c +- %mul = fmul float %a, %b +- %add = fadd float %mul, %negc +- %neg = fneg float %add +- ret float %neg +-} +- +-define float @fnmsub_s_nsz(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fnmsub_s_nsz: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fnmsub_s_nsz: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA32-CONTRACT-ON-NEXT: fsub.s $fa0, $fa2, $fa0 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fnmsub_s_nsz: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA32-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa2, $fa0 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fnmsub_s_nsz: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fnmsub_s_nsz: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA64-CONTRACT-ON-NEXT: fsub.s $fa0, $fa2, $fa0 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fnmsub_s_nsz: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA64-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa2, $fa0 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg nsz float %a +- %mul = fmul nsz float %nega, %b +- %add = fadd nsz float %mul, %c +- ret float %add +-} +- +-;; Check that fnmsub.s is not emitted. +-define float @not_fnmsub_s(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: not_fnmsub_s: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0 +-; LA32-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: not_fnmsub_s: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA32-CONTRACT-ON-NEXT: fsub.s $fa0, $fa2, $fa0 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: not_fnmsub_s: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA32-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa2, $fa0 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: not_fnmsub_s: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0 +-; LA64-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: not_fnmsub_s: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA64-CONTRACT-ON-NEXT: fsub.s $fa0, $fa2, $fa0 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: not_fnmsub_s: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA64-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa2, $fa0 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg float %a +- %mul = fmul float %nega, %b +- %add = fadd float %mul, %c +- ret float %add +-} +- +-define float @contract_fmadd_s(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: contract_fmadd_s: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: contract_fmadd_s: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: contract_fmadd_s: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: contract_fmadd_s: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: contract_fmadd_s: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: contract_fmadd_s: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %mul = fmul contract float %a, %b +- %add = fadd contract float %mul, %c +- ret float %add +-} +- +-define float @contract_fmsub_s(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: contract_fmsub_s: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: contract_fmsub_s: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: contract_fmsub_s: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: contract_fmsub_s: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: contract_fmsub_s: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: contract_fmsub_s: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %mul = fmul contract float %a, %b +- %sub = fsub contract float %mul, %c +- ret float %sub +-} +- +-define float @contract_fnmadd_s(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: contract_fnmadd_s: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: contract_fnmadd_s: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: contract_fnmadd_s: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: contract_fnmadd_s: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: contract_fnmadd_s: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: contract_fnmadd_s: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %mul = fmul contract float %a, %b +- %add = fadd contract float %mul, %c +- %negadd = fneg contract float %add +- ret float %negadd +-} +- +-define float @contract_fnmadd_s_nsz(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: contract_fnmadd_s_nsz: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: contract_fnmadd_s_nsz: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: contract_fnmadd_s_nsz: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: contract_fnmadd_s_nsz: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: contract_fnmadd_s_nsz: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: contract_fnmadd_s_nsz: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg contract nsz float %a +- %negc = fneg contract nsz float %c +- %mul = fmul contract nsz float %nega, %b +- %add = fadd contract nsz float %mul, %negc +- ret float %add +-} +- +-;; Check that fnmadd.s is not emitted. +-define float @not_contract_fnmadd_s(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: not_contract_fnmadd_s: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0 +-; LA32-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: not_contract_fnmadd_s: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0 +-; LA32-CONTRACT-ON-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: not_contract_fnmadd_s: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0 +-; LA32-CONTRACT-OFF-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: not_contract_fnmadd_s: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0 +-; LA64-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: not_contract_fnmadd_s: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0 +-; LA64-CONTRACT-ON-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: not_contract_fnmadd_s: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0 +-; LA64-CONTRACT-OFF-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg contract float %a +- %negc = fneg contract float %c +- %mul = fmul contract float %nega, %b +- %add = fadd contract float %mul, %negc +- ret float %add +-} +- +-define float @contract_fnmsub_s(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: contract_fnmsub_s: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: contract_fnmsub_s: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: contract_fnmsub_s: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: contract_fnmsub_s: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: contract_fnmsub_s: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: contract_fnmsub_s: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %negc = fneg contract float %c +- %mul = fmul contract float %a, %b +- %add = fadd contract float %mul, %negc +- %neg = fneg contract float %add +- ret float %neg +-} +- +-define float @contract_fnmsub_s_nsz(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: contract_fnmsub_s_nsz: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: contract_fnmsub_s_nsz: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: contract_fnmsub_s_nsz: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: contract_fnmsub_s_nsz: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: contract_fnmsub_s_nsz: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: contract_fnmsub_s_nsz: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg contract nsz float %a +- %mul = fmul contract nsz float %nega, %b +- %add = fadd contract nsz float %mul, %c +- ret float %add +-} +- +-;; Check that fnmsub.s is not emitted. +-define float @not_contract_fnmsub_s(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: not_contract_fnmsub_s: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0 +-; LA32-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: not_contract_fnmsub_s: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0 +-; LA32-CONTRACT-ON-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: not_contract_fnmsub_s: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0 +-; LA32-CONTRACT-OFF-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: not_contract_fnmsub_s: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0 +-; LA64-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: not_contract_fnmsub_s: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0 +-; LA64-CONTRACT-ON-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: not_contract_fnmsub_s: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0 +-; LA64-CONTRACT-OFF-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg contract float %a +- %mul = fmul contract float %nega, %b +- %add = fadd contract float %mul, %c +- ret float %add +-} +- +-declare float @llvm.fma.f64(float, float, float) +- +-define float @fmadd_s_intrinsics(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fmadd_s_intrinsics: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fmadd_s_intrinsics: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fmadd_s_intrinsics: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fmadd_s_intrinsics: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fmadd_s_intrinsics: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fmadd_s_intrinsics: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %fma = call float @llvm.fma.f64(float %a, float %b, float %c) +- ret float %fma +-} +- +-define float @fmsub_s_intrinsics(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fmsub_s_intrinsics: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fmsub_s_intrinsics: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fmsub_s_intrinsics: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fmsub_s_intrinsics: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fmsub_s_intrinsics: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fmsub_s_intrinsics: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %negc = fneg float %c +- %fma = call float @llvm.fma.f64(float %a, float %b, float %negc) +- ret float %fma +-} +- +-define float @fnmadd_s_intrinsics(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fnmadd_s_intrinsics: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fnmadd_s_intrinsics: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fnmadd_s_intrinsics: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fnmadd_s_intrinsics: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fnmadd_s_intrinsics: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fnmadd_s_intrinsics: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %fma = call float @llvm.fma.f64(float %a, float %b, float %c) +- %negfma = fneg float %fma +- ret float %negfma +-} +- +-define float @fnmadd_s_nsz_intrinsics(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fnmadd_s_nsz_intrinsics: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fnmadd_s_nsz_intrinsics: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fnmadd_s_nsz_intrinsics: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fnmadd_s_nsz_intrinsics: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fnmadd_s_nsz_intrinsics: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fnmadd_s_nsz_intrinsics: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg float %a +- %negc = fneg float %c +- %fma = call nsz float @llvm.fma.f64(float %nega, float %b, float %negc) +- ret float %fma +-} +- +-;; Check that fnmadd.s is not emitted. +-define float @not_fnmadd_s_intrinsics(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: not_fnmadd_s_intrinsics: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0 +-; LA32-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: not_fnmadd_s_intrinsics: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0 +-; LA32-CONTRACT-ON-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: not_fnmadd_s_intrinsics: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0 +-; LA32-CONTRACT-OFF-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: not_fnmadd_s_intrinsics: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0 +-; LA64-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: not_fnmadd_s_intrinsics: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0 +-; LA64-CONTRACT-ON-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: not_fnmadd_s_intrinsics: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0 +-; LA64-CONTRACT-OFF-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg float %a +- %negc = fneg float %c +- %fma = call float @llvm.fma.f64(float %nega, float %b, float %negc) +- ret float %fma +-} +- +-define float @fnmsub_s_intrinsics(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fnmsub_s_intrinsics: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fnmsub_s_intrinsics: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fnmsub_s_intrinsics: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fnmsub_s_intrinsics: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fnmsub_s_intrinsics: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fnmsub_s_intrinsics: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %negc = fneg float %c +- %fma = call float @llvm.fma.f64(float %a, float %b, float %negc) +- %negfma = fneg float %fma +- ret float %negfma +-} +- +-define float @fnmsub_s_nsz_intrinsics(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fnmsub_s_nsz_intrinsics: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fnmsub_s_nsz_intrinsics: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fnmsub_s_nsz_intrinsics: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fnmsub_s_nsz_intrinsics: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fnmsub_s_nsz_intrinsics: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fnmsub_s_nsz_intrinsics: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg float %a +- %fma = call nsz float @llvm.fma.f64(float %nega, float %b, float %c) +- ret float %fma +-} +- +-;; Check that fnmsub.s is not emitted. +-define float @not_fnmsub_s_intrinsics(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: not_fnmsub_s_intrinsics: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0 +-; LA32-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: not_fnmsub_s_intrinsics: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0 +-; LA32-CONTRACT-ON-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: not_fnmsub_s_intrinsics: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0 +-; LA32-CONTRACT-OFF-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: not_fnmsub_s_intrinsics: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0 +-; LA64-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: not_fnmsub_s_intrinsics: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0 +-; LA64-CONTRACT-ON-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: not_fnmsub_s_intrinsics: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0 +-; LA64-CONTRACT-OFF-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %nega = fneg float %a +- %fma = call float @llvm.fma.f64(float %nega, float %b, float %c) +- ret float %fma +-} +- +-define float @fmadd_s_contract(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fmadd_s_contract: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fmadd_s_contract: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fmadd_s_contract: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fmadd_s_contract: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fmadd_s_contract: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fmadd_s_contract: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %mul = fmul contract float %a, %b +- %add = fadd contract float %mul, %c +- ret float %add +-} +- +-define float @fmsub_s_contract(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fmsub_s_contract: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fmsub_s_contract: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fmsub_s_contract: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fmsub_s_contract: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fmsub_s_contract: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fmsub_s_contract: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %mul = fmul contract float %a, %b +- %sub = fsub contract float %mul, %c +- ret float %sub +-} +- +-define float @fnmadd_s_contract(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fnmadd_s_contract: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fnmadd_s_contract: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fnmadd_s_contract: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fnmadd_s_contract: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fnmadd_s_contract: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fnmadd_s_contract: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %mul = fmul contract float %a, %b +- %add = fadd contract float %mul, %c +- %negadd = fneg contract float %add +- ret float %negadd +-} +- +-define float @fnmsub_s_contract(float %a, float %b, float %c) nounwind { +-; LA32-CONTRACT-FAST-LABEL: fnmsub_s_contract: +-; LA32-CONTRACT-FAST: # %bb.0: +-; LA32-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-FAST-NEXT: ret +-; +-; LA32-CONTRACT-ON-LABEL: fnmsub_s_contract: +-; LA32-CONTRACT-ON: # %bb.0: +-; LA32-CONTRACT-ON-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-ON-NEXT: ret +-; +-; LA32-CONTRACT-OFF-LABEL: fnmsub_s_contract: +-; LA32-CONTRACT-OFF: # %bb.0: +-; LA32-CONTRACT-OFF-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA32-CONTRACT-OFF-NEXT: ret +-; +-; LA64-CONTRACT-FAST-LABEL: fnmsub_s_contract: +-; LA64-CONTRACT-FAST: # %bb.0: +-; LA64-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-FAST-NEXT: ret +-; +-; LA64-CONTRACT-ON-LABEL: fnmsub_s_contract: +-; LA64-CONTRACT-ON: # %bb.0: +-; LA64-CONTRACT-ON-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-ON-NEXT: ret +-; +-; LA64-CONTRACT-OFF-LABEL: fnmsub_s_contract: +-; LA64-CONTRACT-OFF: # %bb.0: +-; LA64-CONTRACT-OFF-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2 +-; LA64-CONTRACT-OFF-NEXT: ret +- %mul = fmul contract float %a, %b +- %negc = fneg contract float %c +- %add = fadd contract float %negc, %mul +- %negadd = fneg contract float %add +- ret float %negadd +-} +diff --git a/llvm/test/CodeGen/LoongArch/float-imm.ll b/llvm/test/CodeGen/LoongArch/float-imm.ll +deleted file mode 100644 +index e2cbf4bf9..000000000 +--- a/llvm/test/CodeGen/LoongArch/float-imm.ll ++++ /dev/null +@@ -1,85 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA64 +- +-define float @f32_positive_zero() nounwind { +-; LA32-LABEL: f32_positive_zero: +-; LA32: # %bb.0: +-; LA32-NEXT: movgr2fr.w $fa0, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f32_positive_zero: +-; LA64: # %bb.0: +-; LA64-NEXT: movgr2fr.w $fa0, $zero +-; LA64-NEXT: ret +- ret float 0.0 +-} +- +-define float @f32_negative_zero() nounwind { +-; LA32-LABEL: f32_negative_zero: +-; LA32: # %bb.0: +-; LA32-NEXT: movgr2fr.w $fa0, $zero +-; LA32-NEXT: fneg.s $fa0, $fa0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f32_negative_zero: +-; LA64: # %bb.0: +-; LA64-NEXT: movgr2fr.w $fa0, $zero +-; LA64-NEXT: fneg.s $fa0, $fa0 +-; LA64-NEXT: ret +- ret float -0.0 +-} +- +-define float @f32_constant_pi() nounwind { +-; LA32-LABEL: f32_constant_pi: +-; LA32: # %bb.0: +-; LA32-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_0) +-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI2_0) +-; LA32-NEXT: fld.s $fa0, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f32_constant_pi: +-; LA64: # %bb.0: +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_0) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI2_0) +-; LA64-NEXT: fld.s $fa0, $a0, 0 +-; LA64-NEXT: ret +- ret float 3.14159274101257324218750 +-} +- +-define float @f32_add_fimm1(float %a) nounwind { +-; LA32-LABEL: f32_add_fimm1: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $zero, 1 +-; LA32-NEXT: movgr2fr.w $fa1, $a0 +-; LA32-NEXT: ffint.s.w $fa1, $fa1 +-; LA32-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f32_add_fimm1: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.w $a0, $zero, 1 +-; LA64-NEXT: movgr2fr.w $fa1, $a0 +-; LA64-NEXT: ffint.s.w $fa1, $fa1 +-; LA64-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA64-NEXT: ret +- %1 = fadd float %a, 1.0 +- ret float %1 +-} +- +-define float @f32_positive_fimm1() nounwind { +-; LA32-LABEL: f32_positive_fimm1: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $zero, 1 +-; LA32-NEXT: movgr2fr.w $fa0, $a0 +-; LA32-NEXT: ffint.s.w $fa0, $fa0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f32_positive_fimm1: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.w $a0, $zero, 1 +-; LA64-NEXT: movgr2fr.w $fa0, $a0 +-; LA64-NEXT: ffint.s.w $fa0, $fa0 +-; LA64-NEXT: ret +- ret float 1.0 +-} +diff --git a/llvm/test/CodeGen/LoongArch/fp-expand.ll b/llvm/test/CodeGen/LoongArch/fp-expand.ll +deleted file mode 100644 +index 7b5be82ef..000000000 +--- a/llvm/test/CodeGen/LoongArch/fp-expand.ll ++++ /dev/null +@@ -1,192 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64 +- +-;; TODO: Add more test cases after ABI implementation for ilp32f and lp64f. +- +-declare float @llvm.sin.f32(float) +-declare float @llvm.cos.f32(float) +-declare float @llvm.pow.f32(float, float) +-declare double @llvm.sin.f64(double) +-declare double @llvm.cos.f64(double) +-declare double @llvm.pow.f64(double, double) +- +-define float @sin_f32(float %a) nounwind { +-; LA32-LABEL: sin_f32: +-; LA32: # %bb.0: +-; LA32-NEXT: b %plt(sinf) +-; +-; LA64-LABEL: sin_f32: +-; LA64: # %bb.0: +-; LA64-NEXT: b %plt(sinf) +- %1 = call float @llvm.sin.f32(float %a) +- ret float %1 +-} +- +-define float @cos_f32(float %a) nounwind { +-; LA32-LABEL: cos_f32: +-; LA32: # %bb.0: +-; LA32-NEXT: b %plt(cosf) +-; +-; LA64-LABEL: cos_f32: +-; LA64: # %bb.0: +-; LA64-NEXT: b %plt(cosf) +- %1 = call float @llvm.cos.f32(float %a) +- ret float %1 +-} +- +-define float @sincos_f32(float %a) nounwind { +-; LA32-LABEL: sincos_f32: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -32 +-; LA32-NEXT: st.w $ra, $sp, 28 # 4-byte Folded Spill +-; LA32-NEXT: fst.d $fs0, $sp, 16 # 8-byte Folded Spill +-; LA32-NEXT: fst.d $fs1, $sp, 8 # 8-byte Folded Spill +-; LA32-NEXT: fmov.s $fs0, $fa0 +-; LA32-NEXT: bl %plt(sinf) +-; LA32-NEXT: fmov.s $fs1, $fa0 +-; LA32-NEXT: fmov.s $fa0, $fs0 +-; LA32-NEXT: bl %plt(cosf) +-; LA32-NEXT: fadd.s $fa0, $fs1, $fa0 +-; LA32-NEXT: fld.d $fs1, $sp, 8 # 8-byte Folded Reload +-; LA32-NEXT: fld.d $fs0, $sp, 16 # 8-byte Folded Reload +-; LA32-NEXT: ld.w $ra, $sp, 28 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 32 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sincos_f32: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -32 +-; LA64-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill +-; LA64-NEXT: fst.d $fs0, $sp, 16 # 8-byte Folded Spill +-; LA64-NEXT: fst.d $fs1, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: fmov.s $fs0, $fa0 +-; LA64-NEXT: bl %plt(sinf) +-; LA64-NEXT: fmov.s $fs1, $fa0 +-; LA64-NEXT: fmov.s $fa0, $fs0 +-; LA64-NEXT: bl %plt(cosf) +-; LA64-NEXT: fadd.s $fa0, $fs1, $fa0 +-; LA64-NEXT: fld.d $fs1, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: fld.d $fs0, $sp, 16 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 32 +-; LA64-NEXT: ret +- %1 = call float @llvm.sin.f32(float %a) +- %2 = call float @llvm.cos.f32(float %a) +- %3 = fadd float %1, %2 +- ret float %3 +-} +- +-define float @pow_f32(float %a, float %b) nounwind { +-; LA32-LABEL: pow_f32: +-; LA32: # %bb.0: +-; LA32-NEXT: b %plt(powf) +-; +-; LA64-LABEL: pow_f32: +-; LA64: # %bb.0: +-; LA64-NEXT: b %plt(powf) +- %1 = call float @llvm.pow.f32(float %a, float %b) +- ret float %1 +-} +- +-define float @frem_f32(float %a, float %b) nounwind { +-; LA32-LABEL: frem_f32: +-; LA32: # %bb.0: +-; LA32-NEXT: b %plt(fmodf) +-; +-; LA64-LABEL: frem_f32: +-; LA64: # %bb.0: +-; LA64-NEXT: b %plt(fmodf) +- %1 = frem float %a, %b +- ret float %1 +-} +- +-define double @sin_f64(double %a) nounwind { +-; LA32-LABEL: sin_f64: +-; LA32: # %bb.0: +-; LA32-NEXT: b %plt(sin) +-; +-; LA64-LABEL: sin_f64: +-; LA64: # %bb.0: +-; LA64-NEXT: b %plt(sin) +- %1 = call double @llvm.sin.f64(double %a) +- ret double %1 +-} +- +-define double @cos_f64(double %a) nounwind { +-; LA32-LABEL: cos_f64: +-; LA32: # %bb.0: +-; LA32-NEXT: b %plt(cos) +-; +-; LA64-LABEL: cos_f64: +-; LA64: # %bb.0: +-; LA64-NEXT: b %plt(cos) +- %1 = call double @llvm.cos.f64(double %a) +- ret double %1 +-} +- +-define double @sincos_f64(double %a) nounwind { +-; LA32-LABEL: sincos_f64: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -32 +-; LA32-NEXT: st.w $ra, $sp, 28 # 4-byte Folded Spill +-; LA32-NEXT: fst.d $fs0, $sp, 16 # 8-byte Folded Spill +-; LA32-NEXT: fst.d $fs1, $sp, 8 # 8-byte Folded Spill +-; LA32-NEXT: fmov.d $fs0, $fa0 +-; LA32-NEXT: bl %plt(sin) +-; LA32-NEXT: fmov.d $fs1, $fa0 +-; LA32-NEXT: fmov.d $fa0, $fs0 +-; LA32-NEXT: bl %plt(cos) +-; LA32-NEXT: fadd.d $fa0, $fs1, $fa0 +-; LA32-NEXT: fld.d $fs1, $sp, 8 # 8-byte Folded Reload +-; LA32-NEXT: fld.d $fs0, $sp, 16 # 8-byte Folded Reload +-; LA32-NEXT: ld.w $ra, $sp, 28 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 32 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sincos_f64: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -32 +-; LA64-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill +-; LA64-NEXT: fst.d $fs0, $sp, 16 # 8-byte Folded Spill +-; LA64-NEXT: fst.d $fs1, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: fmov.d $fs0, $fa0 +-; LA64-NEXT: bl %plt(sin) +-; LA64-NEXT: fmov.d $fs1, $fa0 +-; LA64-NEXT: fmov.d $fa0, $fs0 +-; LA64-NEXT: bl %plt(cos) +-; LA64-NEXT: fadd.d $fa0, $fs1, $fa0 +-; LA64-NEXT: fld.d $fs1, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: fld.d $fs0, $sp, 16 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 32 +-; LA64-NEXT: ret +- %1 = call double @llvm.sin.f64(double %a) +- %2 = call double @llvm.cos.f64(double %a) +- %3 = fadd double %1, %2 +- ret double %3 +-} +- +-define double @pow_f64(double %a, double %b) nounwind { +-; LA32-LABEL: pow_f64: +-; LA32: # %bb.0: +-; LA32-NEXT: b %plt(pow) +-; +-; LA64-LABEL: pow_f64: +-; LA64: # %bb.0: +-; LA64-NEXT: b %plt(pow) +- %1 = call double @llvm.pow.f64(double %a, double %b) +- ret double %1 +-} +- +-define double @frem_f64(double %a, double %b) nounwind { +-; LA32-LABEL: frem_f64: +-; LA32: # %bb.0: +-; LA32-NEXT: b %plt(fmod) +-; +-; LA64-LABEL: frem_f64: +-; LA64: # %bb.0: +-; LA64-NEXT: b %plt(fmod) +- %1 = frem double %a, %b +- ret double %1 +-} +diff --git a/llvm/test/CodeGen/LoongArch/fp-max-min.ll b/llvm/test/CodeGen/LoongArch/fp-max-min.ll +deleted file mode 100644 +index b2ca475b1..000000000 +--- a/llvm/test/CodeGen/LoongArch/fp-max-min.ll ++++ /dev/null +@@ -1,154 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA32F +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32D +-; RUN: llc --mtriple=loongarch64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA64F +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64D +- +-declare float @llvm.maxnum.f32(float, float) +-declare double @llvm.maxnum.f64(double, double) +-declare float @llvm.minnum.f32(float, float) +-declare double @llvm.minnum.f64(double, double) +- +-define float @maxnum_float(float %x, float %y) { +-; LA32F-LABEL: maxnum_float: +-; LA32F: # %bb.0: +-; LA32F-NEXT: fmax.s $fa1, $fa1, $fa1 +-; LA32F-NEXT: fmax.s $fa0, $fa0, $fa0 +-; LA32F-NEXT: fmax.s $fa0, $fa0, $fa1 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: maxnum_float: +-; LA32D: # %bb.0: +-; LA32D-NEXT: fmax.s $fa1, $fa1, $fa1 +-; LA32D-NEXT: fmax.s $fa0, $fa0, $fa0 +-; LA32D-NEXT: fmax.s $fa0, $fa0, $fa1 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: maxnum_float: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fmax.s $fa1, $fa1, $fa1 +-; LA64F-NEXT: fmax.s $fa0, $fa0, $fa0 +-; LA64F-NEXT: fmax.s $fa0, $fa0, $fa1 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: maxnum_float: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fmax.s $fa1, $fa1, $fa1 +-; LA64D-NEXT: fmax.s $fa0, $fa0, $fa0 +-; LA64D-NEXT: fmax.s $fa0, $fa0, $fa1 +-; LA64D-NEXT: ret +- %z = call float @llvm.maxnum.f32(float %x, float %y) +- ret float %z +-} +- +-define double @maxnum_double(double %x, double %y) { +-; LA32F-LABEL: maxnum_double: +-; LA32F: # %bb.0: +-; LA32F-NEXT: addi.w $sp, $sp, -16 +-; LA32F-NEXT: .cfi_def_cfa_offset 16 +-; LA32F-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32F-NEXT: .cfi_offset 1, -4 +-; LA32F-NEXT: bl %plt(fmax) +-; LA32F-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32F-NEXT: addi.w $sp, $sp, 16 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: maxnum_double: +-; LA32D: # %bb.0: +-; LA32D-NEXT: fmax.d $fa1, $fa1, $fa1 +-; LA32D-NEXT: fmax.d $fa0, $fa0, $fa0 +-; LA32D-NEXT: fmax.d $fa0, $fa0, $fa1 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: maxnum_double: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -16 +-; LA64F-NEXT: .cfi_def_cfa_offset 16 +-; LA64F-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64F-NEXT: .cfi_offset 1, -8 +-; LA64F-NEXT: bl %plt(fmax) +-; LA64F-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 16 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: maxnum_double: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fmax.d $fa1, $fa1, $fa1 +-; LA64D-NEXT: fmax.d $fa0, $fa0, $fa0 +-; LA64D-NEXT: fmax.d $fa0, $fa0, $fa1 +-; LA64D-NEXT: ret +- %z = call double @llvm.maxnum.f64(double %x, double %y) +- ret double %z +-} +- +-define float @minnum_float(float %x, float %y) { +-; LA32F-LABEL: minnum_float: +-; LA32F: # %bb.0: +-; LA32F-NEXT: fmax.s $fa1, $fa1, $fa1 +-; LA32F-NEXT: fmax.s $fa0, $fa0, $fa0 +-; LA32F-NEXT: fmin.s $fa0, $fa0, $fa1 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: minnum_float: +-; LA32D: # %bb.0: +-; LA32D-NEXT: fmax.s $fa1, $fa1, $fa1 +-; LA32D-NEXT: fmax.s $fa0, $fa0, $fa0 +-; LA32D-NEXT: fmin.s $fa0, $fa0, $fa1 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: minnum_float: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fmax.s $fa1, $fa1, $fa1 +-; LA64F-NEXT: fmax.s $fa0, $fa0, $fa0 +-; LA64F-NEXT: fmin.s $fa0, $fa0, $fa1 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: minnum_float: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fmax.s $fa1, $fa1, $fa1 +-; LA64D-NEXT: fmax.s $fa0, $fa0, $fa0 +-; LA64D-NEXT: fmin.s $fa0, $fa0, $fa1 +-; LA64D-NEXT: ret +- %z = call float @llvm.minnum.f32(float %x, float %y) +- ret float %z +-} +- +-define double @minnum_double(double %x, double %y) { +-; LA32F-LABEL: minnum_double: +-; LA32F: # %bb.0: +-; LA32F-NEXT: addi.w $sp, $sp, -16 +-; LA32F-NEXT: .cfi_def_cfa_offset 16 +-; LA32F-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32F-NEXT: .cfi_offset 1, -4 +-; LA32F-NEXT: bl %plt(fmin) +-; LA32F-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32F-NEXT: addi.w $sp, $sp, 16 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: minnum_double: +-; LA32D: # %bb.0: +-; LA32D-NEXT: fmax.d $fa1, $fa1, $fa1 +-; LA32D-NEXT: fmax.d $fa0, $fa0, $fa0 +-; LA32D-NEXT: fmin.d $fa0, $fa0, $fa1 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: minnum_double: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -16 +-; LA64F-NEXT: .cfi_def_cfa_offset 16 +-; LA64F-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64F-NEXT: .cfi_offset 1, -8 +-; LA64F-NEXT: bl %plt(fmin) +-; LA64F-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 16 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: minnum_double: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fmax.d $fa1, $fa1, $fa1 +-; LA64D-NEXT: fmax.d $fa0, $fa0, $fa0 +-; LA64D-NEXT: fmin.d $fa0, $fa0, $fa1 +-; LA64D-NEXT: ret +- %z = call double @llvm.minnum.f64(double %x, double %y) +- ret double %z +-} +diff --git a/llvm/test/CodeGen/LoongArch/fp-reciprocal.ll b/llvm/test/CodeGen/LoongArch/fp-reciprocal.ll +deleted file mode 100644 +index b85809983..000000000 +--- a/llvm/test/CodeGen/LoongArch/fp-reciprocal.ll ++++ /dev/null +@@ -1,68 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA32F +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32D +-; RUN: llc --mtriple=loongarch64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA64F +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64D +- +- +-define float @f32_reciprocal(float %a) nounwind { +-; LA32F-LABEL: f32_reciprocal: +-; LA32F: # %bb.0: +-; LA32F-NEXT: frecip.s $fa0, $fa0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: f32_reciprocal: +-; LA32D: # %bb.0: +-; LA32D-NEXT: frecip.s $fa0, $fa0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: f32_reciprocal: +-; LA64F: # %bb.0: +-; LA64F-NEXT: frecip.s $fa0, $fa0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: f32_reciprocal: +-; LA64D: # %bb.0: +-; LA64D-NEXT: frecip.s $fa0, $fa0 +-; LA64D-NEXT: ret +- %1 = fdiv float 1.0, %a +- ret float %1 +-} +- +-define double @f64_reciprocal(double %a) nounwind { +-; LA32F-LABEL: f64_reciprocal: +-; LA32F: # %bb.0: +-; LA32F-NEXT: addi.w $sp, $sp, -16 +-; LA32F-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32F-NEXT: move $a3, $a1 +-; LA32F-NEXT: move $a2, $a0 +-; LA32F-NEXT: lu12i.w $a1, 261888 +-; LA32F-NEXT: move $a0, $zero +-; LA32F-NEXT: bl %plt(__divdf3) +-; LA32F-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32F-NEXT: addi.w $sp, $sp, 16 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: f64_reciprocal: +-; LA32D: # %bb.0: +-; LA32D-NEXT: frecip.d $fa0, $fa0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: f64_reciprocal: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -16 +-; LA64F-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64F-NEXT: move $a1, $a0 +-; LA64F-NEXT: lu52i.d $a0, $zero, 1023 +-; LA64F-NEXT: bl %plt(__divdf3) +-; LA64F-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 16 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: f64_reciprocal: +-; LA64D: # %bb.0: +-; LA64D-NEXT: frecip.d $fa0, $fa0 +-; LA64D-NEXT: ret +- %1 = fdiv double 1.0, %a +- ret double %1 +-} +diff --git a/llvm/test/CodeGen/LoongArch/fp-trunc-store.ll b/llvm/test/CodeGen/LoongArch/fp-trunc-store.ll +deleted file mode 100644 +index 84e52d9d1..000000000 +--- a/llvm/test/CodeGen/LoongArch/fp-trunc-store.ll ++++ /dev/null +@@ -1,51 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA32F +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32D +-; RUN: llc --mtriple=loongarch64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA64F +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64D +- +-define void @fp_trunc(ptr %a, double %b) nounwind { +-; LA32F-LABEL: fp_trunc: +-; LA32F: # %bb.0: +-; LA32F-NEXT: addi.w $sp, $sp, -16 +-; LA32F-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32F-NEXT: st.w $fp, $sp, 8 # 4-byte Folded Spill +-; LA32F-NEXT: move $fp, $a0 +-; LA32F-NEXT: move $a0, $a1 +-; LA32F-NEXT: move $a1, $a2 +-; LA32F-NEXT: bl %plt(__truncdfsf2) +-; LA32F-NEXT: fst.s $fa0, $fp, 0 +-; LA32F-NEXT: ld.w $fp, $sp, 8 # 4-byte Folded Reload +-; LA32F-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32F-NEXT: addi.w $sp, $sp, 16 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: fp_trunc: +-; LA32D: # %bb.0: +-; LA32D-NEXT: fcvt.s.d $fa0, $fa0 +-; LA32D-NEXT: fst.s $fa0, $a0, 0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: fp_trunc: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -16 +-; LA64F-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 0 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a0 +-; LA64F-NEXT: move $a0, $a1 +-; LA64F-NEXT: bl %plt(__truncdfsf2) +-; LA64F-NEXT: fst.s $fa0, $fp, 0 +-; LA64F-NEXT: ld.d $fp, $sp, 0 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 16 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: fp_trunc: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fcvt.s.d $fa0, $fa0 +-; LA64D-NEXT: fst.s $fa0, $a0, 0 +-; LA64D-NEXT: ret +- %1 = fptrunc double %b to float +- store float %1, ptr %a, align 4 +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/frame-info.ll b/llvm/test/CodeGen/LoongArch/frame-info.ll +new file mode 100644 +index 000000000..eb4fc69fa +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/frame-info.ll +@@ -0,0 +1,132 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -relocation-model=pic -mtriple=loongarch64 -frame-pointer=all < %s | FileCheck %s ++ ++define void @trivial() { ++; CHECK-LABEL: trivial: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -16 ++; CHECK-NEXT: .cfi_def_cfa_offset 16 ++; CHECK-NEXT: st.d $r22, $sp, 8 # 8-byte Folded Spill ++; CHECK-NEXT: .cfi_offset 22, -8 ++; CHECK-NEXT: addi.d $r22, $sp, 16 ++; CHECK-NEXT: .cfi_def_cfa 22, 0 ++; CHECK-NEXT: ld.d $r22, $sp, 8 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 16 ++; CHECK-NEXT: jr $ra ++ ret void ++} ++ ++define void @stack_alloc(i32 signext %size) { ++; CHECK-LABEL: stack_alloc: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: addi.d $sp, $sp, -32 ++; CHECK-NEXT: .cfi_def_cfa_offset 32 ++; CHECK-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r22, $sp, 16 # 8-byte Folded Spill ++; CHECK-NEXT: .cfi_offset 1, -8 ++; CHECK-NEXT: .cfi_offset 22, -16 ++; CHECK-NEXT: addi.d $r22, $sp, 32 ++; CHECK-NEXT: .cfi_def_cfa 22, 0 ++; CHECK-NEXT: addi.w $r5, $zero, -16 ++; CHECK-NEXT: lu32i.d $r5, 1 ++; CHECK-NEXT: bstrpick.d $r4, $r4, 31, 0 ++; CHECK-NEXT: addi.d $r4, $r4, 15 ++; CHECK-NEXT: and $r4, $r4, $r5 ++; CHECK-NEXT: sub.d $r4, $sp, $r4 ++; CHECK-NEXT: move $sp, $r4 ++; CHECK-NEXT: bl callee_with_args ++; CHECK-NEXT: addi.d $sp, $r22, -32 ++; CHECK-NEXT: ld.d $r22, $sp, 16 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 32 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = alloca i8, i32 %size, align 16 ++ call void @callee_with_args(i8* nonnull %0) ++ ret void ++} ++ ++define void @branch_and_tail_call(i1 %a) { ++; CHECK-LABEL: branch_and_tail_call: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: andi $r4, $r4, 1 ++; CHECK-NEXT: beqz $r4, .LBB2_2 ++; CHECK-NEXT: # %bb.1: # %blue_pill ++; CHECK-NEXT: b callee1 ++; CHECK-NEXT: .LBB2_2: # %red_pill ++; CHECK-NEXT: addi.d $sp, $sp, -16 ++; CHECK-NEXT: .cfi_def_cfa_offset 16 ++; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r22, $sp, 0 # 8-byte Folded Spill ++; CHECK-NEXT: .cfi_offset 1, -8 ++; CHECK-NEXT: .cfi_offset 22, -16 ++; CHECK-NEXT: addi.d $r22, $sp, 16 ++; CHECK-NEXT: .cfi_def_cfa 22, 0 ++; CHECK-NEXT: bl callee2 ++; CHECK-NEXT: ld.d $r22, $sp, 0 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 16 ++; CHECK-NEXT: jr $ra ++ br i1 %a, label %blue_pill, label %red_pill ++blue_pill: ++ tail call void @callee1() ++ ret void ++red_pill: ++ call void @callee2() ++ ret void ++} ++ ++define void @big_frame() { ++; CHECK-LABEL: big_frame: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: addi.d $sp, $sp, -2032 ++; CHECK-NEXT: .cfi_def_cfa_offset 2032 ++; CHECK-NEXT: st.d $ra, $sp, 2024 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r22, $sp, 2016 # 8-byte Folded Spill ++; CHECK-NEXT: .cfi_offset 1, -8 ++; CHECK-NEXT: .cfi_offset 22, -16 ++; CHECK-NEXT: addi.d $r22, $sp, 2032 ++; CHECK-NEXT: .cfi_def_cfa 22, 0 ++; CHECK-NEXT: addi.d $sp, $sp, -48 ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: ori $r4, $r4, 2016 ++; CHECK-NEXT: add.d $r4, $r22, $r4 ++; CHECK-NEXT: addi.d $r4, $r4, 0 ++; CHECK-NEXT: bl callee_with_args ++; CHECK-NEXT: addi.d $sp, $sp, 48 ++; CHECK-NEXT: ld.d $r22, $sp, 2016 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 2024 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 2032 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = alloca i8, i32 2048, align 16 ++ call void @callee_with_args(i8* nonnull %0) ++ ret void ++} ++ ++define void @varargs_frame(i32 %i, ...) { ++; CHECK-LABEL: varargs_frame: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -80 ++; CHECK-NEXT: .cfi_def_cfa_offset 80 ++; CHECK-NEXT: st.d $r22, $sp, 8 # 8-byte Folded Spill ++; CHECK-NEXT: .cfi_offset 22, -72 ++; CHECK-NEXT: addi.d $r22, $sp, 16 ++; CHECK-NEXT: .cfi_def_cfa 22, 64 ++; CHECK-NEXT: st.d $r11, $r22, 56 ++; CHECK-NEXT: st.d $r10, $r22, 48 ++; CHECK-NEXT: st.d $r9, $r22, 40 ++; CHECK-NEXT: st.d $r8, $r22, 32 ++; CHECK-NEXT: st.d $r7, $r22, 24 ++; CHECK-NEXT: st.d $r6, $r22, 16 ++; CHECK-NEXT: st.d $r5, $r22, 8 ++; CHECK-NEXT: ld.d $r22, $sp, 8 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 80 ++; CHECK-NEXT: jr $ra ++ ret void ++} ++ ++declare void @callee1() ++declare void @callee2() ++declare void @callee_with_args(i8*) +diff --git a/llvm/test/CodeGen/LoongArch/frame.ll b/llvm/test/CodeGen/LoongArch/frame.ll +deleted file mode 100644 +index 2a9700522..000000000 +--- a/llvm/test/CodeGen/LoongArch/frame.ll ++++ /dev/null +@@ -1,99 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s +- +-%struct.key_t = type { i32, [16 x i8] } +- +-declare void @llvm.memset.p0i8.i64(ptr, i8, i64, i1) +-declare void @test1(ptr) +- +-define i32 @test() nounwind { +-; CHECK-LABEL: test: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -32 +-; CHECK-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill +-; CHECK-NEXT: st.w $zero, $sp, 16 +-; CHECK-NEXT: st.d $zero, $sp, 8 +-; CHECK-NEXT: st.d $zero, $sp, 0 +-; CHECK-NEXT: addi.d $a0, $sp, 4 +-; CHECK-NEXT: bl %plt(test1) +-; CHECK-NEXT: move $a0, $zero +-; CHECK-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 32 +-; CHECK-NEXT: ret +- %key = alloca %struct.key_t, align 4 +- call void @llvm.memset.p0i8.i64(ptr %key, i8 0, i64 20, i1 false) +- %1 = getelementptr inbounds %struct.key_t, ptr %key, i64 0, i32 1, i64 0 +- call void @test1(ptr %1) +- ret i32 0 +-} +- +-;; Note: will create an emergency spill slot, if (!isInt<11>(StackSize)). +-;; Should involve only one SP-adjusting addi per adjustment. +-define void @test_large_frame_size_2032() { +-; CHECK-LABEL: test_large_frame_size_2032: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -2032 +-; CHECK-NEXT: .cfi_def_cfa_offset 2032 +-; CHECK-NEXT: addi.d $sp, $sp, 2032 +-; CHECK-NEXT: ret +- %1 = alloca i8, i32 2016 ; + 16(emergency slot) = 2032 +- ret void +-} +- +-;; Should involve two SP-adjusting addi's when adjusting SP up, but only one +-;; when adjusting down. +-define void @test_large_frame_size_2048() { +-; CHECK-LABEL: test_large_frame_size_2048: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -2048 +-; CHECK-NEXT: .cfi_def_cfa_offset 2048 +-; CHECK-NEXT: addi.d $sp, $sp, 2032 +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +- %1 = alloca i8, i32 2032 ; + 16(emergency slot) = 2048 +- ret void +-} +- +-;; Should involve two SP-adjusting addi's per adjustment. +-define void @test_large_frame_size_2064() { +-; CHECK-LABEL: test_large_frame_size_2064: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -2048 +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: .cfi_def_cfa_offset 2064 +-; CHECK-NEXT: addi.d $sp, $sp, 2032 +-; CHECK-NEXT: addi.d $sp, $sp, 32 +-; CHECK-NEXT: ret +- %1 = alloca i8, i32 2048 ; + 16(emergency slot) = 2064 +- ret void +-} +- +-;; NOTE: Due to the problem with the emegency spill slot, the scratch register +-;; will not be used when the fp is eliminated. To make this test valid, add the +-;; attribute "frame-pointer=all". +- +-;; SP should be adjusted with help of a scratch register. +-define void @test_large_frame_size_1234576() "frame-pointer"="all" { +-; CHECK-LABEL: test_large_frame_size_1234576: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -2032 +-; CHECK-NEXT: .cfi_def_cfa_offset 2032 +-; CHECK-NEXT: st.d $ra, $sp, 2024 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $fp, $sp, 2016 # 8-byte Folded Spill +-; CHECK-NEXT: .cfi_offset 1, -8 +-; CHECK-NEXT: .cfi_offset 22, -16 +-; CHECK-NEXT: addi.d $fp, $sp, 2032 +-; CHECK-NEXT: .cfi_def_cfa 22, 0 +-; CHECK-NEXT: lu12i.w $a0, 300 +-; CHECK-NEXT: ori $a0, $a0, 3760 +-; CHECK-NEXT: sub.d $sp, $sp, $a0 +-; CHECK-NEXT: lu12i.w $a0, 300 +-; CHECK-NEXT: ori $a0, $a0, 3760 +-; CHECK-NEXT: add.d $sp, $sp, $a0 +-; CHECK-NEXT: ld.d $fp, $sp, 2016 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $ra, $sp, 2024 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 2032 +-; CHECK-NEXT: ret +- %1 = alloca i8, i32 1234567 +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/frameaddr-returnaddr.ll b/llvm/test/CodeGen/LoongArch/frameaddr-returnaddr.ll +deleted file mode 100644 +index 01c9173c2..000000000 +--- a/llvm/test/CodeGen/LoongArch/frameaddr-returnaddr.ll ++++ /dev/null +@@ -1,78 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-declare ptr @llvm.frameaddress(i32) +-declare ptr @llvm.returnaddress(i32) +- +-define ptr @test_frameaddress_0() nounwind { +-; LA32-LABEL: test_frameaddress_0: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: st.w $fp, $sp, 8 # 4-byte Folded Spill +-; LA32-NEXT: addi.w $fp, $sp, 16 +-; LA32-NEXT: move $a0, $fp +-; LA32-NEXT: ld.w $fp, $sp, 8 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_frameaddress_0: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: st.d $fp, $sp, 0 # 8-byte Folded Spill +-; LA64-NEXT: addi.d $fp, $sp, 16 +-; LA64-NEXT: move $a0, $fp +-; LA64-NEXT: ld.d $fp, $sp, 0 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %1 = call ptr @llvm.frameaddress(i32 0) +- ret ptr %1 +-} +- +-define ptr @test_frameaddress_2() nounwind { +-; LA32-LABEL: test_frameaddress_2: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: st.w $fp, $sp, 8 # 4-byte Folded Spill +-; LA32-NEXT: addi.w $fp, $sp, 16 +-; LA32-NEXT: ld.w $a0, $fp, -8 +-; LA32-NEXT: ld.w $a0, $a0, -8 +-; LA32-NEXT: ld.w $fp, $sp, 8 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_frameaddress_2: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: st.d $fp, $sp, 0 # 8-byte Folded Spill +-; LA64-NEXT: addi.d $fp, $sp, 16 +-; LA64-NEXT: ld.d $a0, $fp, -16 +-; LA64-NEXT: ld.d $a0, $a0, -16 +-; LA64-NEXT: ld.d $fp, $sp, 0 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %1 = call ptr @llvm.frameaddress(i32 2) +- ret ptr %1 +-} +- +-define ptr @test_returnaddress_0() nounwind { +-; LA32-LABEL: test_returnaddress_0: +-; LA32: # %bb.0: +-; LA32-NEXT: move $a0, $ra +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_returnaddress_0: +-; LA64: # %bb.0: +-; LA64-NEXT: move $a0, $ra +-; LA64-NEXT: ret +- %1 = call ptr @llvm.returnaddress(i32 0) +- ret ptr %1 +-} +diff --git a/llvm/test/CodeGen/LoongArch/frint.ll b/llvm/test/CodeGen/LoongArch/frint.ll +deleted file mode 100644 +index 30718f7c7..000000000 +--- a/llvm/test/CodeGen/LoongArch/frint.ll ++++ /dev/null +@@ -1,64 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA32F +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32D +-; RUN: llc --mtriple=loongarch64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA64F +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64D +- +-define float @rint_f32(float %f) nounwind { +-; LA32F-LABEL: rint_f32: +-; LA32F: # %bb.0: # %entry +-; LA32F-NEXT: b %plt(rintf) +-; +-; LA32D-LABEL: rint_f32: +-; LA32D: # %bb.0: # %entry +-; LA32D-NEXT: b %plt(rintf) +-; +-; LA64F-LABEL: rint_f32: +-; LA64F: # %bb.0: # %entry +-; LA64F-NEXT: frint.s $fa0, $fa0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: rint_f32: +-; LA64D: # %bb.0: # %entry +-; LA64D-NEXT: frint.s $fa0, $fa0 +-; LA64D-NEXT: ret +-entry: +- %0 = tail call float @llvm.rint.f32(float %f) +- ret float %0 +-} +- +-declare float @llvm.rint.f32(float) +- +-define double @rint_f64(double %d) nounwind { +-; LA32F-LABEL: rint_f64: +-; LA32F: # %bb.0: # %entry +-; LA32F-NEXT: addi.w $sp, $sp, -16 +-; LA32F-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32F-NEXT: bl %plt(rint) +-; LA32F-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32F-NEXT: addi.w $sp, $sp, 16 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: rint_f64: +-; LA32D: # %bb.0: # %entry +-; LA32D-NEXT: b %plt(rint) +-; +-; LA64F-LABEL: rint_f64: +-; LA64F: # %bb.0: # %entry +-; LA64F-NEXT: addi.d $sp, $sp, -16 +-; LA64F-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64F-NEXT: bl %plt(rint) +-; LA64F-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 16 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: rint_f64: +-; LA64D: # %bb.0: # %entry +-; LA64D-NEXT: frint.d $fa0, $fa0 +-; LA64D-NEXT: ret +-entry: +- %0 = tail call double @llvm.rint.f64(double %d) +- ret double %0 +-} +- +-declare double @llvm.rint.f64(double) +diff --git a/llvm/test/CodeGen/LoongArch/fsel.ll b/llvm/test/CodeGen/LoongArch/fsel.ll +new file mode 100644 +index 000000000..f41ee08c0 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/fsel.ll +@@ -0,0 +1,47 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -o - %s | FileCheck %s ++ ++ ++define double @olt_f64(double %a, double %b) { ++; CHECK-LABEL: olt_f64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fcmp.clt.d $fcc0, $f0, $f1 ++; CHECK-NEXT: fsel $f0, $f1, $f0, $fcc0 ++; CHECK-NEXT: jr $ra ++ %cond = fcmp olt double %a, %b ++ %ret = select i1 %cond, double %a, double %b ++ ret double %ret ++} ++ ++define double @ogt_f64(double %a, double %b) { ++; CHECK-LABEL: ogt_f64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fcmp.cule.d $fcc0, $f0, $f1 ++; CHECK-NEXT: fsel $f0, $f0, $f1, $fcc0 ++; CHECK-NEXT: jr $ra ++ %cond = fcmp ogt double %a, %b ++ %ret = select i1 %cond, double %a, double %b ++ ret double %ret ++} ++ ++define float @olt_f32(float %a, float %b) { ++; CHECK-LABEL: olt_f32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fcmp.clt.s $fcc0, $f0, $f1 ++; CHECK-NEXT: fsel $f0, $f1, $f0, $fcc0 ++; CHECK-NEXT: jr $ra ++ %cond = fcmp olt float %a, %b ++ %ret = select i1 %cond, float %a, float %b ++ ret float %ret ++} ++ ++define float @ogt_f32(float %a, float %b) { ++; CHECK-LABEL: ogt_f32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: fcmp.cule.s $fcc0, $f0, $f1 ++; CHECK-NEXT: fsel $f0, $f0, $f1, $fcc0 ++; CHECK-NEXT: jr $ra ++ %cond = fcmp ogt float %a, %b ++ %ret = select i1 %cond, float %a, float %b ++ ret float %ret ++} +diff --git a/llvm/test/CodeGen/LoongArch/fsqrt.ll b/llvm/test/CodeGen/LoongArch/fsqrt.ll +deleted file mode 100644 +index 776de7f72..000000000 +--- a/llvm/test/CodeGen/LoongArch/fsqrt.ll ++++ /dev/null +@@ -1,130 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA32F +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32D +-; RUN: llc --mtriple=loongarch64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA64F +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64D +- +-declare float @llvm.sqrt.f32(float) +-declare double @llvm.sqrt.f64(double) +- +-define float @fsqrt_f32(float %a) nounwind { +-; LA32F-LABEL: fsqrt_f32: +-; LA32F: # %bb.0: +-; LA32F-NEXT: fsqrt.s $fa0, $fa0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: fsqrt_f32: +-; LA32D: # %bb.0: +-; LA32D-NEXT: fsqrt.s $fa0, $fa0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: fsqrt_f32: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fsqrt.s $fa0, $fa0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: fsqrt_f32: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fsqrt.s $fa0, $fa0 +-; LA64D-NEXT: ret +- %1 = call float @llvm.sqrt.f32(float %a) +- ret float %1 +-} +- +-define double @fsqrt_f64(double %a) nounwind { +-; LA32F-LABEL: fsqrt_f64: +-; LA32F: # %bb.0: +-; LA32F-NEXT: addi.w $sp, $sp, -16 +-; LA32F-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32F-NEXT: bl %plt(sqrt) +-; LA32F-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32F-NEXT: addi.w $sp, $sp, 16 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: fsqrt_f64: +-; LA32D: # %bb.0: +-; LA32D-NEXT: fsqrt.d $fa0, $fa0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: fsqrt_f64: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -16 +-; LA64F-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64F-NEXT: bl %plt(sqrt) +-; LA64F-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 16 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: fsqrt_f64: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fsqrt.d $fa0, $fa0 +-; LA64D-NEXT: ret +- %1 = call double @llvm.sqrt.f64(double %a) +- ret double %1 +-} +- +-define float @frsqrt_f32(float %a) nounwind { +-; LA32F-LABEL: frsqrt_f32: +-; LA32F: # %bb.0: +-; LA32F-NEXT: frsqrt.s $fa0, $fa0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: frsqrt_f32: +-; LA32D: # %bb.0: +-; LA32D-NEXT: frsqrt.s $fa0, $fa0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: frsqrt_f32: +-; LA64F: # %bb.0: +-; LA64F-NEXT: frsqrt.s $fa0, $fa0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: frsqrt_f32: +-; LA64D: # %bb.0: +-; LA64D-NEXT: frsqrt.s $fa0, $fa0 +-; LA64D-NEXT: ret +- %1 = call float @llvm.sqrt.f32(float %a) +- %2 = fdiv float 1.0, %1 +- ret float %2 +-} +- +-define double @frsqrt_f64(double %a) nounwind { +-; LA32F-LABEL: frsqrt_f64: +-; LA32F: # %bb.0: +-; LA32F-NEXT: addi.w $sp, $sp, -16 +-; LA32F-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32F-NEXT: bl %plt(sqrt) +-; LA32F-NEXT: move $a2, $a0 +-; LA32F-NEXT: move $a3, $a1 +-; LA32F-NEXT: lu12i.w $a1, 261888 +-; LA32F-NEXT: move $a0, $zero +-; LA32F-NEXT: bl %plt(__divdf3) +-; LA32F-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32F-NEXT: addi.w $sp, $sp, 16 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: frsqrt_f64: +-; LA32D: # %bb.0: +-; LA32D-NEXT: frsqrt.d $fa0, $fa0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: frsqrt_f64: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -16 +-; LA64F-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64F-NEXT: bl %plt(sqrt) +-; LA64F-NEXT: move $a1, $a0 +-; LA64F-NEXT: lu52i.d $a0, $zero, 1023 +-; LA64F-NEXT: bl %plt(__divdf3) +-; LA64F-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 16 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: frsqrt_f64: +-; LA64D: # %bb.0: +-; LA64D-NEXT: frsqrt.d $fa0, $fa0 +-; LA64D-NEXT: ret +- %1 = call double @llvm.sqrt.f64(double %a) +- %2 = fdiv double 1.0, %1 +- ret double %2 +-} +diff --git a/llvm/test/CodeGen/LoongArch/get-reg-error-la32.ll b/llvm/test/CodeGen/LoongArch/get-reg-error-la32.ll +deleted file mode 100644 +index 7440bfe5c..000000000 +--- a/llvm/test/CodeGen/LoongArch/get-reg-error-la32.ll ++++ /dev/null +@@ -1,21 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: not llc < %s --mtriple=loongarch32 2>&1 | FileCheck %s +- +-define i64 @read_sp() nounwind { +-entry: +-; CHECK: On LA32, only 32-bit registers can be read. +- %a1 = call i64 @llvm.read_register.i64(metadata !0) +- ret i64 %a1 +-} +- +-define void @write_sp(i64 %val) nounwind { +-entry: +-; CHECK: On LA32, only 32-bit registers can be written. +- call void @llvm.write_register.i64(metadata !0, i64 %val) +- ret void +-} +- +-declare i64 @llvm.read_register.i64(metadata) nounwind +-declare void @llvm.write_register.i64(metadata, i64) nounwind +- +-!0 = !{!"$sp\00"} +diff --git a/llvm/test/CodeGen/LoongArch/get-reg-error-la64.ll b/llvm/test/CodeGen/LoongArch/get-reg-error-la64.ll +deleted file mode 100644 +index 9312aa902..000000000 +--- a/llvm/test/CodeGen/LoongArch/get-reg-error-la64.ll ++++ /dev/null +@@ -1,21 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: not llc < %s --mtriple=loongarch64 2>&1 | FileCheck %s +- +-define i32 @read_sp() nounwind { +-entry: +-; CHECK: On LA64, only 64-bit registers can be read. +- %a1 = call i32 @llvm.read_register.i32(metadata !0) +- ret i32 %a1 +-} +- +-define void @write_sp(i32 %val) nounwind { +-entry: +-; CHECK: On LA64, only 64-bit registers can be written. +- call void @llvm.write_register.i32(metadata !0, i32 %val) +- ret void +-} +- +-declare i32 @llvm.read_register.i32(metadata) nounwind +-declare void @llvm.write_register.i32(metadata, i32) nounwind +- +-!0 = !{!"$sp\00"} +diff --git a/llvm/test/CodeGen/LoongArch/get-reg.ll b/llvm/test/CodeGen/LoongArch/get-reg.ll +deleted file mode 100644 +index 323030da9..000000000 +--- a/llvm/test/CodeGen/LoongArch/get-reg.ll ++++ /dev/null +@@ -1,27 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc < %s --mtriple=loongarch64 | FileCheck %s +- +-define i64 @get_stack() nounwind { +-; CHECK-LABEL: get_stack: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: move $a0, $sp +-; CHECK-NEXT: ret +-entry: +- %sp = call i64 @llvm.read_register.i64(metadata !0) +- ret i64 %sp +-} +- +-define void @set_stack(i64 %val) nounwind { +-; CHECK-LABEL: set_stack: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: move $sp, $a0 +-; CHECK-NEXT: ret +-entry: +- call void @llvm.write_register.i64(metadata !0, i64 %val) +- ret void +-} +- +-declare i64 @llvm.read_register.i64(metadata) nounwind +-declare void @llvm.write_register.i64(metadata, i64) nounwind +- +-!0 = !{!"$sp\00"} +diff --git a/llvm/test/CodeGen/LoongArch/get-setcc-result-type.ll b/llvm/test/CodeGen/LoongArch/get-setcc-result-type.ll +deleted file mode 100644 +index 432cedff6..000000000 +--- a/llvm/test/CodeGen/LoongArch/get-setcc-result-type.ll ++++ /dev/null +@@ -1,31 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s \ +-; RUN: | FileCheck %s +- +-define void @getSetCCResultType(ptr %p) { +-; CHECK-LABEL: getSetCCResultType: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: ld.w $a1, $a0, 12 +-; CHECK-NEXT: sltui $a1, $a1, 1 +-; CHECK-NEXT: sub.d $a1, $zero, $a1 +-; CHECK-NEXT: st.w $a1, $a0, 12 +-; CHECK-NEXT: ld.w $a1, $a0, 8 +-; CHECK-NEXT: sltui $a1, $a1, 1 +-; CHECK-NEXT: sub.d $a1, $zero, $a1 +-; CHECK-NEXT: st.w $a1, $a0, 8 +-; CHECK-NEXT: ld.w $a1, $a0, 4 +-; CHECK-NEXT: sltui $a1, $a1, 1 +-; CHECK-NEXT: sub.d $a1, $zero, $a1 +-; CHECK-NEXT: st.w $a1, $a0, 4 +-; CHECK-NEXT: ld.w $a1, $a0, 0 +-; CHECK-NEXT: sltui $a1, $a1, 1 +-; CHECK-NEXT: sub.d $a1, $zero, $a1 +-; CHECK-NEXT: st.w $a1, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %0 = load <4 x i32>, ptr %p, align 16 +- %cmp = icmp eq <4 x i32> %0, zeroinitializer +- %sext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %sext, ptr %p, align 16 +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/ghc-cc.ll b/llvm/test/CodeGen/LoongArch/ghc-cc.ll +deleted file mode 100644 +index 0ab125e87..000000000 +--- a/llvm/test/CodeGen/LoongArch/ghc-cc.ll ++++ /dev/null +@@ -1,107 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+f,+d < %s | FileCheck %s --check-prefix=LA64 +- +-; Check the GHC call convention works (la64) +- +-@base = external dso_local global i64 ; assigned to register: s0 +-@sp = external dso_local global i64 ; assigned to register: s1 +-@hp = external dso_local global i64 ; assigned to register: s2 +-@r1 = external dso_local global i64 ; assigned to register: s3 +-@r2 = external dso_local global i64 ; assigned to register: s4 +-@r3 = external dso_local global i64 ; assigned to register: s5 +-@r4 = external dso_local global i64 ; assigned to register: s6 +-@r5 = external dso_local global i64 ; assigned to register: s7 +-@splim = external dso_local global i64 ; assigned to register: s8 +- +-@f1 = external dso_local global float ; assigned to register: fs0 +-@f2 = external dso_local global float ; assigned to register: fs1 +-@f3 = external dso_local global float ; assigned to register: fs2 +-@f4 = external dso_local global float ; assigned to register: fs3 +- +-@d1 = external dso_local global double ; assigned to register: fs4 +-@d2 = external dso_local global double ; assigned to register: fs5 +-@d3 = external dso_local global double ; assigned to register: fs6 +-@d4 = external dso_local global double ; assigned to register: fs7 +- +-define ghccc void @foo() nounwind { +-; LA64-LABEL: foo: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(base) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(base) +-; LA64-NEXT: ld.d $s0, $a0, 0 +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(sp) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(sp) +-; LA64-NEXT: ld.d $s1, $a0, 0 +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(hp) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(hp) +-; LA64-NEXT: ld.d $s2, $a0, 0 +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(r1) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(r1) +-; LA64-NEXT: ld.d $s3, $a0, 0 +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(r2) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(r2) +-; LA64-NEXT: ld.d $s4, $a0, 0 +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(r3) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(r3) +-; LA64-NEXT: ld.d $s5, $a0, 0 +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(r4) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(r4) +-; LA64-NEXT: ld.d $s6, $a0, 0 +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(r5) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(r5) +-; LA64-NEXT: ld.d $s7, $a0, 0 +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(splim) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(splim) +-; LA64-NEXT: ld.d $s8, $a0, 0 +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(f1) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(f1) +-; LA64-NEXT: fld.s $fs0, $a0, 0 +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(f2) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(f2) +-; LA64-NEXT: fld.s $fs1, $a0, 0 +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(f3) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(f3) +-; LA64-NEXT: fld.s $fs2, $a0, 0 +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(f4) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(f4) +-; LA64-NEXT: fld.s $fs3, $a0, 0 +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(d1) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(d1) +-; LA64-NEXT: fld.d $fs4, $a0, 0 +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(d2) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(d2) +-; LA64-NEXT: fld.d $fs5, $a0, 0 +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(d3) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(d3) +-; LA64-NEXT: fld.d $fs6, $a0, 0 +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(d4) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(d4) +-; LA64-NEXT: fld.d $fs7, $a0, 0 +-; LA64-NEXT: b %plt(bar) +- +-entry: +- %0 = load double, ptr @d4 +- %1 = load double, ptr @d3 +- %2 = load double, ptr @d2 +- %3 = load double, ptr @d1 +- %4 = load float, ptr @f4 +- %5 = load float, ptr @f3 +- %6 = load float, ptr @f2 +- %7 = load float, ptr @f1 +- %8 = load i64, ptr @splim +- %9 = load i64, ptr @r5 +- %10 = load i64, ptr @r4 +- %11 = load i64, ptr @r3 +- %12 = load i64, ptr @r2 +- %13 = load i64, ptr @r1 +- %14 = load i64, ptr @hp +- %15 = load i64, ptr @sp +- %16 = load i64, ptr @base +- tail call ghccc void @bar(i64 %16, i64 %15, i64 %14, i64 %13, i64 %12, +- i64 %11, i64 %10, i64 %9, i64 %8, float %7, float %6, +- float %5, float %4, double %3, double %2, double %1, double %0) nounwind +- ret void +-} +-declare ghccc void @bar(i64, i64, i64, i64, i64, i64, i64, i64, i64, +- float, float, float, float, +- double, double, double, double) +diff --git a/llvm/test/CodeGen/LoongArch/global-address.ll b/llvm/test/CodeGen/LoongArch/global-address.ll +deleted file mode 100644 +index d32a17f48..000000000 +--- a/llvm/test/CodeGen/LoongArch/global-address.ll ++++ /dev/null +@@ -1,87 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --relocation-model=static < %s | FileCheck %s --check-prefix=LA32NOPIC +-; RUN: llc --mtriple=loongarch32 --relocation-model=pic < %s | FileCheck %s --check-prefix=LA32PIC +-; RUN: llc --mtriple=loongarch64 --relocation-model=static < %s | FileCheck %s --check-prefix=LA64NOPIC +-; RUN: llc --mtriple=loongarch64 --relocation-model=pic < %s | FileCheck %s --check-prefix=LA64PIC +-; RUN: llc --mtriple=loongarch64 --code-model=large --relocation-model=static < %s | FileCheck %s --check-prefix=LA64LARGENOPIC +-; RUN: llc --mtriple=loongarch64 --code-model=large --relocation-model=pic < %s | FileCheck %s --check-prefix=LA64LARGEPIC +- +-@g = dso_local global i32 zeroinitializer, align 4 +-@G = global i32 zeroinitializer, align 4 +- +-define void @foo() nounwind { +-; LA32NOPIC-LABEL: foo: +-; LA32NOPIC: # %bb.0: +-; LA32NOPIC-NEXT: pcalau12i $a0, %got_pc_hi20(G) +-; LA32NOPIC-NEXT: ld.w $a0, $a0, %got_pc_lo12(G) +-; LA32NOPIC-NEXT: ld.w $a0, $a0, 0 +-; LA32NOPIC-NEXT: pcalau12i $a0, %pc_hi20(g) +-; LA32NOPIC-NEXT: addi.w $a0, $a0, %pc_lo12(g) +-; LA32NOPIC-NEXT: ld.w $a0, $a0, 0 +-; LA32NOPIC-NEXT: ret +-; +-; LA32PIC-LABEL: foo: +-; LA32PIC: # %bb.0: +-; LA32PIC-NEXT: pcalau12i $a0, %got_pc_hi20(G) +-; LA32PIC-NEXT: ld.w $a0, $a0, %got_pc_lo12(G) +-; LA32PIC-NEXT: ld.w $a0, $a0, 0 +-; LA32PIC-NEXT: pcalau12i $a0, %pc_hi20(.Lg$local) +-; LA32PIC-NEXT: addi.w $a0, $a0, %pc_lo12(.Lg$local) +-; LA32PIC-NEXT: ld.w $a0, $a0, 0 +-; LA32PIC-NEXT: ret +-; +-; LA64NOPIC-LABEL: foo: +-; LA64NOPIC: # %bb.0: +-; LA64NOPIC-NEXT: pcalau12i $a0, %got_pc_hi20(G) +-; LA64NOPIC-NEXT: ld.d $a0, $a0, %got_pc_lo12(G) +-; LA64NOPIC-NEXT: ld.w $a0, $a0, 0 +-; LA64NOPIC-NEXT: pcalau12i $a0, %pc_hi20(g) +-; LA64NOPIC-NEXT: addi.d $a0, $a0, %pc_lo12(g) +-; LA64NOPIC-NEXT: ld.w $a0, $a0, 0 +-; LA64NOPIC-NEXT: ret +-; +-; LA64PIC-LABEL: foo: +-; LA64PIC: # %bb.0: +-; LA64PIC-NEXT: pcalau12i $a0, %got_pc_hi20(G) +-; LA64PIC-NEXT: ld.d $a0, $a0, %got_pc_lo12(G) +-; LA64PIC-NEXT: ld.w $a0, $a0, 0 +-; LA64PIC-NEXT: pcalau12i $a0, %pc_hi20(.Lg$local) +-; LA64PIC-NEXT: addi.d $a0, $a0, %pc_lo12(.Lg$local) +-; LA64PIC-NEXT: ld.w $a0, $a0, 0 +-; LA64PIC-NEXT: ret +-; +-; LA64LARGENOPIC-LABEL: foo: +-; LA64LARGENOPIC: # %bb.0: +-; LA64LARGENOPIC-NEXT: pcalau12i $a0, %got_pc_hi20(G) +-; LA64LARGENOPIC-NEXT: addi.d $t8, $zero, %got_pc_lo12(G) +-; LA64LARGENOPIC-NEXT: lu32i.d $t8, %got64_pc_lo20(G) +-; LA64LARGENOPIC-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(G) +-; LA64LARGENOPIC-NEXT: ldx.d $a0, $t8, $a0 +-; LA64LARGENOPIC-NEXT: ld.w $a0, $a0, 0 +-; LA64LARGENOPIC-NEXT: pcalau12i $a0, %pc_hi20(g) +-; LA64LARGENOPIC-NEXT: addi.d $t8, $zero, %pc_lo12(g) +-; LA64LARGENOPIC-NEXT: lu32i.d $t8, %pc64_lo20(g) +-; LA64LARGENOPIC-NEXT: lu52i.d $t8, $t8, %pc64_hi12(g) +-; LA64LARGENOPIC-NEXT: add.d $a0, $t8, $a0 +-; LA64LARGENOPIC-NEXT: ld.w $a0, $a0, 0 +-; LA64LARGENOPIC-NEXT: ret +-; +-; LA64LARGEPIC-LABEL: foo: +-; LA64LARGEPIC: # %bb.0: +-; LA64LARGEPIC-NEXT: pcalau12i $a0, %got_pc_hi20(G) +-; LA64LARGEPIC-NEXT: addi.d $t8, $zero, %got_pc_lo12(G) +-; LA64LARGEPIC-NEXT: lu32i.d $t8, %got64_pc_lo20(G) +-; LA64LARGEPIC-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(G) +-; LA64LARGEPIC-NEXT: ldx.d $a0, $t8, $a0 +-; LA64LARGEPIC-NEXT: ld.w $a0, $a0, 0 +-; LA64LARGEPIC-NEXT: pcalau12i $a0, %pc_hi20(.Lg$local) +-; LA64LARGEPIC-NEXT: addi.d $t8, $zero, %pc_lo12(.Lg$local) +-; LA64LARGEPIC-NEXT: lu32i.d $t8, %pc64_lo20(.Lg$local) +-; LA64LARGEPIC-NEXT: lu52i.d $t8, $t8, %pc64_hi12(.Lg$local) +-; LA64LARGEPIC-NEXT: add.d $a0, $t8, $a0 +-; LA64LARGEPIC-NEXT: ld.w $a0, $a0, 0 +-; LA64LARGEPIC-NEXT: ret +- %V = load volatile i32, ptr @G +- %v = load volatile i32, ptr @g +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/global-variable-code-model.ll b/llvm/test/CodeGen/LoongArch/global-variable-code-model.ll +deleted file mode 100644 +index aa4780834..000000000 +--- a/llvm/test/CodeGen/LoongArch/global-variable-code-model.ll ++++ /dev/null +@@ -1,44 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s +- +-@a= external dso_local global i32, code_model "small", align 4 +- +-define dso_local signext i32 @local_small() #0 { +-; CHECK-LABEL: local_small: +-; CHECK: # %bb.0: +-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(a) +-; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(a) +-; CHECK-NEXT: ld.w $a0, $a0, 0 +-; CHECK-NEXT: ret +- %1 = load i32, ptr @a, align 4 +- ret i32 %1 +-} +- +-@b= external dso_local global i32, code_model "large", align 4 +- +-define dso_local signext i32 @local_large() #0 { +-; CHECK-LABEL: local_large: +-; CHECK: # %bb.0: +-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(b) +-; CHECK-NEXT: addi.d $t8, $zero, %pc_lo12(b) +-; CHECK-NEXT: lu32i.d $t8, %pc64_lo20(b) +-; CHECK-NEXT: lu52i.d $t8, $t8, %pc64_hi12(b) +-; CHECK-NEXT: add.d $a0, $t8, $a0 +-; CHECK-NEXT: ld.w $a0, $a0, 0 +-; CHECK-NEXT: ret +- %1 = load i32, ptr @b, align 4 +- ret i32 %1 +-} +- +-@c= external global i32, code_model "large", align 4 +- +-define dso_local signext i32 @non_local_large() #0 { +-; CHECK-LABEL: non_local_large: +-; CHECK: # %bb.0: +-; CHECK-NEXT: pcalau12i $a0, %got_pc_hi20(c) +-; CHECK-NEXT: ld.d $a0, $a0, %got_pc_lo12(c) +-; CHECK-NEXT: ld.w $a0, $a0, 0 +-; CHECK-NEXT: ret +- %1 = load i32, ptr @c, align 4 +- ret i32 %1 +-} +diff --git a/llvm/test/CodeGen/LoongArch/imm.ll b/llvm/test/CodeGen/LoongArch/imm.ll +deleted file mode 100644 +index f8b7a61d6..000000000 +--- a/llvm/test/CodeGen/LoongArch/imm.ll ++++ /dev/null +@@ -1,166 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s +- +-define i64 @imm0() { +-; CHECK-LABEL: imm0: +-; CHECK: # %bb.0: +-; CHECK-NEXT: move $a0, $zero +-; CHECK-NEXT: ret +- ret i64 0 +-} +- +-define i64 @imm7ff0000000000000() { +-; CHECK-LABEL: imm7ff0000000000000: +-; CHECK: # %bb.0: +-; CHECK-NEXT: lu52i.d $a0, $zero, 2047 +-; CHECK-NEXT: ret +- ret i64 9218868437227405312 +-} +- +-define i64 @imm0000000000000fff() { +-; CHECK-LABEL: imm0000000000000fff: +-; CHECK: # %bb.0: +-; CHECK-NEXT: ori $a0, $zero, 4095 +-; CHECK-NEXT: ret +- ret i64 4095 +-} +- +-define i64 @imm0007ffff00000800() { +-; CHECK-LABEL: imm0007ffff00000800: +-; CHECK: # %bb.0: +-; CHECK-NEXT: ori $a0, $zero, 2048 +-; CHECK-NEXT: lu32i.d $a0, 524287 +-; CHECK-NEXT: ret +- ret i64 2251795518720000 +-} +- +-define i64 @immfff0000000000fff() { +-; CHECK-LABEL: immfff0000000000fff: +-; CHECK: # %bb.0: +-; CHECK-NEXT: ori $a0, $zero, 4095 +-; CHECK-NEXT: lu52i.d $a0, $a0, -1 +-; CHECK-NEXT: ret +- ret i64 -4503599627366401 +-} +- +-define i64 @imm0008000000000fff() { +-; CHECK-LABEL: imm0008000000000fff: +-; CHECK: # %bb.0: +-; CHECK-NEXT: ori $a0, $zero, 4095 +-; CHECK-NEXT: lu32i.d $a0, -524288 +-; CHECK-NEXT: lu52i.d $a0, $a0, 0 +-; CHECK-NEXT: ret +- ret i64 2251799813689343 +-} +- +-define i64 @immfffffffffffff800() { +-; CHECK-LABEL: immfffffffffffff800: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.w $a0, $zero, -2048 +-; CHECK-NEXT: ret +- ret i64 -2048 +-} +- +-define i64 @imm00000000fffff800() { +-; CHECK-LABEL: imm00000000fffff800: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.w $a0, $zero, -2048 +-; CHECK-NEXT: lu32i.d $a0, 0 +-; CHECK-NEXT: ret +- ret i64 4294965248 +-} +- +-define i64 @imm000ffffffffff800() { +-; CHECK-LABEL: imm000ffffffffff800: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.w $a0, $zero, -2048 +-; CHECK-NEXT: lu52i.d $a0, $a0, 0 +-; CHECK-NEXT: ret +- ret i64 4503599627368448 +-} +- +-define i64 @imm00080000fffff800() { +-; CHECK-LABEL: imm00080000fffff800: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.w $a0, $zero, -2048 +-; CHECK-NEXT: lu32i.d $a0, -524288 +-; CHECK-NEXT: lu52i.d $a0, $a0, 0 +-; CHECK-NEXT: ret +- ret i64 2251804108650496 +-} +- +-define i64 @imm000000007ffff000() { +-; CHECK-LABEL: imm000000007ffff000: +-; CHECK: # %bb.0: +-; CHECK-NEXT: lu12i.w $a0, 524287 +-; CHECK-NEXT: ret +- ret i64 2147479552 +-} +- +-define i64 @imm0000000080000000() { +-; CHECK-LABEL: imm0000000080000000: +-; CHECK: # %bb.0: +-; CHECK-NEXT: lu12i.w $a0, -524288 +-; CHECK-NEXT: lu32i.d $a0, 0 +-; CHECK-NEXT: ret +- ret i64 2147483648 +-} +- +-define i64 @imm000ffffffffff000() { +-; CHECK-LABEL: imm000ffffffffff000: +-; CHECK: # %bb.0: +-; CHECK-NEXT: lu12i.w $a0, -1 +-; CHECK-NEXT: lu52i.d $a0, $a0, 0 +-; CHECK-NEXT: ret +- ret i64 4503599627366400 +-} +- +-define i64 @imm7ff0000080000000() { +-; CHECK-LABEL: imm7ff0000080000000: +-; CHECK: # %bb.0: +-; CHECK-NEXT: lu12i.w $a0, -524288 +-; CHECK-NEXT: lu32i.d $a0, 0 +-; CHECK-NEXT: lu52i.d $a0, $a0, 2047 +-; CHECK-NEXT: ret +- ret i64 9218868439374888960 +-} +- +-define i64 @immffffffff80000800() { +-; CHECK-LABEL: immffffffff80000800: +-; CHECK: # %bb.0: +-; CHECK-NEXT: lu12i.w $a0, -524288 +-; CHECK-NEXT: ori $a0, $a0, 2048 +-; CHECK-NEXT: ret +- ret i64 -2147481600 +-} +- +-define i64 @immffffffff7ffff800() { +-; CHECK-LABEL: immffffffff7ffff800: +-; CHECK: # %bb.0: +-; CHECK-NEXT: lu12i.w $a0, 524287 +-; CHECK-NEXT: ori $a0, $a0, 2048 +-; CHECK-NEXT: lu32i.d $a0, -1 +-; CHECK-NEXT: ret +- ret i64 -2147485696 +-} +- +-define i64 @imm7fffffff800007ff() { +-; CHECK-LABEL: imm7fffffff800007ff: +-; CHECK: # %bb.0: +-; CHECK-NEXT: lu12i.w $a0, -524288 +-; CHECK-NEXT: ori $a0, $a0, 2047 +-; CHECK-NEXT: lu52i.d $a0, $a0, 2047 +-; CHECK-NEXT: ret +- ret i64 9223372034707294207 +-} +- +-define i64 @imm0008000080000800() { +-; CHECK-LABEL: imm0008000080000800: +-; CHECK: # %bb.0: +-; CHECK-NEXT: lu12i.w $a0, -524288 +-; CHECK-NEXT: ori $a0, $a0, 2048 +-; CHECK-NEXT: lu32i.d $a0, -524288 +-; CHECK-NEXT: lu52i.d $a0, $a0, 0 +-; CHECK-NEXT: ret +- ret i64 2251801961170944 +-} +diff --git a/llvm/test/CodeGen/LoongArch/immediate.ll b/llvm/test/CodeGen/LoongArch/immediate.ll +new file mode 100644 +index 000000000..1de3ef0fc +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/immediate.ll +@@ -0,0 +1,2542 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -mtriple=loongarch64 < %s | FileCheck %s ++define i64 @li0000000000000000() { ++; CHECK-LABEL: li0000000000000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $r4, $zero, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 0 ++} ++ ++define i64 @li00000000000007ff() { ++; CHECK-LABEL: li00000000000007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $r4, $zero, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 2047 ++} ++ ++define i64 @li0000000000000800() { ++; CHECK-LABEL: li0000000000000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2048 ++; CHECK-NEXT: jr $ra ++ ret i64 2048 ++} ++ ++define i64 @li0000000000000fff() { ++; CHECK-LABEL: li0000000000000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 4095 ++; CHECK-NEXT: jr $ra ++ ret i64 4095 ++} ++ ++define i64 @li000000007ffff000() { ++; CHECK-LABEL: li000000007ffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: jr $ra ++ ret i64 2147479552 ++} ++ ++define i64 @li000000007ffff7ff() { ++; CHECK-LABEL: li000000007ffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 2147481599 ++} ++ ++define i64 @li000000007ffff800() { ++; CHECK-LABEL: li000000007ffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: jr $ra ++ ret i64 2147481600 ++} ++ ++define i64 @li000000007fffffff() { ++; CHECK-LABEL: li000000007fffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: jr $ra ++ ret i64 2147483647 ++} ++ ++define i64 @li0000000080000000() { ++; CHECK-LABEL: li0000000080000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 2147483648 ++} ++ ++define i64 @li00000000800007ff() { ++; CHECK-LABEL: li00000000800007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 2147485695 ++} ++ ++define i64 @li0000000080000800() { ++; CHECK-LABEL: li0000000080000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 2147485696 ++} ++ ++define i64 @li0000000080000fff() { ++; CHECK-LABEL: li0000000080000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 2147487743 ++} ++ ++define i64 @li00000000fffff000() { ++; CHECK-LABEL: li00000000fffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 4294963200 ++} ++ ++define i64 @li00000000fffff7ff() { ++; CHECK-LABEL: li00000000fffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 4294965247 ++} ++ ++define i64 @li00000000fffff800() { ++; CHECK-LABEL: li00000000fffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -2048 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 4294965248 ++} ++ ++define i64 @li00000000ffffffff() { ++; CHECK-LABEL: li00000000ffffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -1 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 4294967295 ++} ++ ++define i64 @li0007ffff00000000() { ++; CHECK-LABEL: li0007ffff00000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 0 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: jr $ra ++ ret i64 2251795518717952 ++} ++ ++define i64 @li0007ffff000007ff() { ++; CHECK-LABEL: li0007ffff000007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2047 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: jr $ra ++ ret i64 2251795518719999 ++} ++ ++define i64 @li0007ffff00000800() { ++; CHECK-LABEL: li0007ffff00000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2048 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: jr $ra ++ ret i64 2251795518720000 ++} ++ ++define i64 @li0007ffff00000fff() { ++; CHECK-LABEL: li0007ffff00000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 4095 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: jr $ra ++ ret i64 2251795518722047 ++} ++ ++define i64 @li0007ffff7ffff000() { ++; CHECK-LABEL: li0007ffff7ffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: jr $ra ++ ret i64 2251797666197504 ++} ++ ++define i64 @li0007ffff7ffff7ff() { ++; CHECK-LABEL: li0007ffff7ffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: jr $ra ++ ret i64 2251797666199551 ++} ++ ++define i64 @li0007ffff7ffff800() { ++; CHECK-LABEL: li0007ffff7ffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: jr $ra ++ ret i64 2251797666199552 ++} ++ ++define i64 @li0007ffff7fffffff() { ++; CHECK-LABEL: li0007ffff7fffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: jr $ra ++ ret i64 2251797666201599 ++} ++ ++define i64 @li0007ffff80000000() { ++; CHECK-LABEL: li0007ffff80000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: jr $ra ++ ret i64 2251797666201600 ++} ++ ++define i64 @li0007ffff800007ff() { ++; CHECK-LABEL: li0007ffff800007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: jr $ra ++ ret i64 2251797666203647 ++} ++ ++define i64 @li0007ffff80000800() { ++; CHECK-LABEL: li0007ffff80000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: jr $ra ++ ret i64 2251797666203648 ++} ++ ++define i64 @li0007ffff80000fff() { ++; CHECK-LABEL: li0007ffff80000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: jr $ra ++ ret i64 2251797666205695 ++} ++ ++define i64 @li0007fffffffff000() { ++; CHECK-LABEL: li0007fffffffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: jr $ra ++ ret i64 2251799813681152 ++} ++ ++define i64 @li0007fffffffff7ff() { ++; CHECK-LABEL: li0007fffffffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: jr $ra ++ ret i64 2251799813683199 ++} ++ ++define i64 @li0007fffffffff800() { ++; CHECK-LABEL: li0007fffffffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -2048 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: jr $ra ++ ret i64 2251799813683200 ++} ++ ++define i64 @li0007ffffffffffff() { ++; CHECK-LABEL: li0007ffffffffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -1 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: jr $ra ++ ret i64 2251799813685247 ++} ++ ++define i64 @li0008000000000000() { ++; CHECK-LABEL: li0008000000000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 0 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 2251799813685248 ++} ++ ++define i64 @li00080000000007ff() { ++; CHECK-LABEL: li00080000000007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2047 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 2251799813687295 ++} ++ ++define i64 @li0008000000000800() { ++; CHECK-LABEL: li0008000000000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2048 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 2251799813687296 ++} ++ ++define i64 @li0008000000000fff() { ++; CHECK-LABEL: li0008000000000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 4095 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 2251799813689343 ++} ++ ++define i64 @li000800007ffff000() { ++; CHECK-LABEL: li000800007ffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 2251801961164800 ++} ++ ++define i64 @li000800007ffff7ff() { ++; CHECK-LABEL: li000800007ffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 2251801961166847 ++} ++ ++define i64 @li000800007ffff800() { ++; CHECK-LABEL: li000800007ffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 2251801961166848 ++} ++ ++define i64 @li000800007fffffff() { ++; CHECK-LABEL: li000800007fffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 2251801961168895 ++} ++ ++define i64 @li0008000080000000() { ++; CHECK-LABEL: li0008000080000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 2251801961168896 ++} ++ ++define i64 @li00080000800007ff() { ++; CHECK-LABEL: li00080000800007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 2251801961170943 ++} ++ ++define i64 @li0008000080000800() { ++; CHECK-LABEL: li0008000080000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 2251801961170944 ++} ++ ++define i64 @li0008000080000fff() { ++; CHECK-LABEL: li0008000080000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 2251801961172991 ++} ++ ++define i64 @li00080000fffff000() { ++; CHECK-LABEL: li00080000fffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 2251804108648448 ++} ++ ++define i64 @li00080000fffff7ff() { ++; CHECK-LABEL: li00080000fffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 2251804108650495 ++} ++ ++define i64 @li00080000fffff800() { ++; CHECK-LABEL: li00080000fffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -2048 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 2251804108650496 ++} ++ ++define i64 @li00080000ffffffff() { ++; CHECK-LABEL: li00080000ffffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -1 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 2251804108652543 ++} ++ ++define i64 @li000fffff00000000() { ++; CHECK-LABEL: li000fffff00000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 0 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 4503595332403200 ++} ++ ++define i64 @li000fffff000007ff() { ++; CHECK-LABEL: li000fffff000007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2047 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 4503595332405247 ++} ++ ++define i64 @li000fffff00000800() { ++; CHECK-LABEL: li000fffff00000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2048 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 4503595332405248 ++} ++ ++define i64 @li000fffff00000fff() { ++; CHECK-LABEL: li000fffff00000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 4095 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 4503595332407295 ++} ++ ++define i64 @li000fffff7ffff000() { ++; CHECK-LABEL: li000fffff7ffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 4503597479882752 ++} ++ ++define i64 @li000fffff7ffff7ff() { ++; CHECK-LABEL: li000fffff7ffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 4503597479884799 ++} ++ ++define i64 @li000fffff7ffff800() { ++; CHECK-LABEL: li000fffff7ffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 4503597479884800 ++} ++ ++define i64 @li000fffff7fffffff() { ++; CHECK-LABEL: li000fffff7fffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 4503597479886847 ++} ++ ++define i64 @li000fffff80000000() { ++; CHECK-LABEL: li000fffff80000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 4503597479886848 ++} ++ ++define i64 @li000fffff800007ff() { ++; CHECK-LABEL: li000fffff800007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 4503597479888895 ++} ++ ++define i64 @li000fffff80000800() { ++; CHECK-LABEL: li000fffff80000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 4503597479888896 ++} ++ ++define i64 @li000fffff80000fff() { ++; CHECK-LABEL: li000fffff80000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 4503597479890943 ++} ++ ++define i64 @li000ffffffffff000() { ++; CHECK-LABEL: li000ffffffffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 4503599627366400 ++} ++ ++define i64 @li000ffffffffff7ff() { ++; CHECK-LABEL: li000ffffffffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 4503599627368447 ++} ++ ++define i64 @li000ffffffffff800() { ++; CHECK-LABEL: li000ffffffffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -2048 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 4503599627368448 ++} ++ ++define i64 @li000fffffffffffff() { ++; CHECK-LABEL: li000fffffffffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i64 4503599627370495 ++} ++ ++define i64 @li7ff0000000000000() { ++; CHECK-LABEL: li7ff0000000000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu52i.d $r4, $zero, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9218868437227405312 ++} ++ ++define i64 @li7ff00000000007ff() { ++; CHECK-LABEL: li7ff00000000007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2047 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9218868437227407359 ++} ++ ++define i64 @li7ff0000000000800() { ++; CHECK-LABEL: li7ff0000000000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2048 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9218868437227407360 ++} ++ ++define i64 @li7ff0000000000fff() { ++; CHECK-LABEL: li7ff0000000000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 4095 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9218868437227409407 ++} ++ ++define i64 @li7ff000007ffff000() { ++; CHECK-LABEL: li7ff000007ffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9218868439374884864 ++} ++ ++define i64 @li7ff000007ffff7ff() { ++; CHECK-LABEL: li7ff000007ffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9218868439374886911 ++} ++ ++define i64 @li7ff000007ffff800() { ++; CHECK-LABEL: li7ff000007ffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9218868439374886912 ++} ++ ++define i64 @li7ff000007fffffff() { ++; CHECK-LABEL: li7ff000007fffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9218868439374888959 ++} ++ ++define i64 @li7ff0000080000000() { ++; CHECK-LABEL: li7ff0000080000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9218868439374888960 ++} ++ ++define i64 @li7ff00000800007ff() { ++; CHECK-LABEL: li7ff00000800007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9218868439374891007 ++} ++ ++define i64 @li7ff0000080000800() { ++; CHECK-LABEL: li7ff0000080000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9218868439374891008 ++} ++ ++define i64 @li7ff0000080000fff() { ++; CHECK-LABEL: li7ff0000080000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9218868439374893055 ++} ++ ++define i64 @li7ff00000fffff000() { ++; CHECK-LABEL: li7ff00000fffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9218868441522368512 ++} ++ ++define i64 @li7ff00000fffff7ff() { ++; CHECK-LABEL: li7ff00000fffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9218868441522370559 ++} ++ ++define i64 @li7ff00000fffff800() { ++; CHECK-LABEL: li7ff00000fffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -2048 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9218868441522370560 ++} ++ ++define i64 @li7ff00000ffffffff() { ++; CHECK-LABEL: li7ff00000ffffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -1 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9218868441522372607 ++} ++ ++define i64 @li7ff7ffff00000000() { ++; CHECK-LABEL: li7ff7ffff00000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 0 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120232746123264 ++} ++ ++define i64 @li7ff7ffff000007ff() { ++; CHECK-LABEL: li7ff7ffff000007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2047 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120232746125311 ++} ++ ++define i64 @li7ff7ffff00000800() { ++; CHECK-LABEL: li7ff7ffff00000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2048 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120232746125312 ++} ++ ++define i64 @li7ff7ffff00000fff() { ++; CHECK-LABEL: li7ff7ffff00000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 4095 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120232746127359 ++} ++ ++define i64 @li7ff7ffff7ffff000() { ++; CHECK-LABEL: li7ff7ffff7ffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120234893602816 ++} ++ ++define i64 @li7ff7ffff7ffff7ff() { ++; CHECK-LABEL: li7ff7ffff7ffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120234893604863 ++} ++ ++define i64 @li7ff7ffff7ffff800() { ++; CHECK-LABEL: li7ff7ffff7ffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120234893604864 ++} ++ ++define i64 @li7ff7ffff7fffffff() { ++; CHECK-LABEL: li7ff7ffff7fffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120234893606911 ++} ++ ++define i64 @li7ff7ffff80000000() { ++; CHECK-LABEL: li7ff7ffff80000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120234893606912 ++} ++ ++define i64 @li7ff7ffff800007ff() { ++; CHECK-LABEL: li7ff7ffff800007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120234893608959 ++} ++ ++define i64 @li7ff7ffff80000800() { ++; CHECK-LABEL: li7ff7ffff80000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120234893608960 ++} ++ ++define i64 @li7ff7ffff80000fff() { ++; CHECK-LABEL: li7ff7ffff80000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120234893611007 ++} ++ ++define i64 @li7ff7fffffffff000() { ++; CHECK-LABEL: li7ff7fffffffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120237041086464 ++} ++ ++define i64 @li7ff7fffffffff7ff() { ++; CHECK-LABEL: li7ff7fffffffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120237041088511 ++} ++ ++define i64 @li7ff7fffffffff800() { ++; CHECK-LABEL: li7ff7fffffffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -2048 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120237041088512 ++} ++ ++define i64 @li7ff7ffffffffffff() { ++; CHECK-LABEL: li7ff7ffffffffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -1 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120237041090559 ++} ++ ++define i64 @li7ff8000000000000() { ++; CHECK-LABEL: li7ff8000000000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 0 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120237041090560 ++} ++ ++define i64 @li7ff80000000007ff() { ++; CHECK-LABEL: li7ff80000000007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2047 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120237041092607 ++} ++ ++define i64 @li7ff8000000000800() { ++; CHECK-LABEL: li7ff8000000000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2048 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120237041092608 ++} ++ ++define i64 @li7ff8000000000fff() { ++; CHECK-LABEL: li7ff8000000000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 4095 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120237041094655 ++} ++ ++define i64 @li7ff800007ffff000() { ++; CHECK-LABEL: li7ff800007ffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120239188570112 ++} ++ ++define i64 @li7ff800007ffff7ff() { ++; CHECK-LABEL: li7ff800007ffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120239188572159 ++} ++ ++define i64 @li7ff800007ffff800() { ++; CHECK-LABEL: li7ff800007ffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120239188572160 ++} ++ ++define i64 @li7ff800007fffffff() { ++; CHECK-LABEL: li7ff800007fffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120239188574207 ++} ++ ++define i64 @li7ff8000080000000() { ++; CHECK-LABEL: li7ff8000080000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120239188574208 ++} ++ ++define i64 @li7ff80000800007ff() { ++; CHECK-LABEL: li7ff80000800007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120239188576255 ++} ++ ++define i64 @li7ff8000080000800() { ++; CHECK-LABEL: li7ff8000080000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120239188576256 ++} ++ ++define i64 @li7ff8000080000fff() { ++; CHECK-LABEL: li7ff8000080000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120239188578303 ++} ++ ++define i64 @li7ff80000fffff000() { ++; CHECK-LABEL: li7ff80000fffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120241336053760 ++} ++ ++define i64 @li7ff80000fffff7ff() { ++; CHECK-LABEL: li7ff80000fffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120241336055807 ++} ++ ++define i64 @li7ff80000fffff800() { ++; CHECK-LABEL: li7ff80000fffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -2048 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120241336055808 ++} ++ ++define i64 @li7ff80000ffffffff() { ++; CHECK-LABEL: li7ff80000ffffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -1 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9221120241336057855 ++} ++ ++define i64 @li7fffffff00000000() { ++; CHECK-LABEL: li7fffffff00000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 0 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9223372032559808512 ++} ++ ++define i64 @li7fffffff000007ff() { ++; CHECK-LABEL: li7fffffff000007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2047 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9223372032559810559 ++} ++ ++define i64 @li7fffffff00000800() { ++; CHECK-LABEL: li7fffffff00000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2048 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9223372032559810560 ++} ++ ++define i64 @li7fffffff00000fff() { ++; CHECK-LABEL: li7fffffff00000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 4095 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9223372032559812607 ++} ++ ++define i64 @li7fffffff7ffff000() { ++; CHECK-LABEL: li7fffffff7ffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9223372034707288064 ++} ++ ++define i64 @li7fffffff7ffff7ff() { ++; CHECK-LABEL: li7fffffff7ffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9223372034707290111 ++} ++ ++define i64 @li7fffffff7ffff800() { ++; CHECK-LABEL: li7fffffff7ffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9223372034707290112 ++} ++ ++define i64 @li7fffffff7fffffff() { ++; CHECK-LABEL: li7fffffff7fffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9223372034707292159 ++} ++ ++define i64 @li7fffffff80000000() { ++; CHECK-LABEL: li7fffffff80000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9223372034707292160 ++} ++ ++define i64 @li7fffffff800007ff() { ++; CHECK-LABEL: li7fffffff800007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9223372034707294207 ++} ++ ++define i64 @li7fffffff80000800() { ++; CHECK-LABEL: li7fffffff80000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9223372034707294208 ++} ++ ++define i64 @li7fffffff80000fff() { ++; CHECK-LABEL: li7fffffff80000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9223372034707296255 ++} ++ ++define i64 @li7ffffffffffff000() { ++; CHECK-LABEL: li7ffffffffffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9223372036854771712 ++} ++ ++define i64 @li7ffffffffffff7ff() { ++; CHECK-LABEL: li7ffffffffffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9223372036854773759 ++} ++ ++define i64 @li7ffffffffffff800() { ++; CHECK-LABEL: li7ffffffffffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -2048 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9223372036854773760 ++} ++ ++define i64 @li7fffffffffffffff() { ++; CHECK-LABEL: li7fffffffffffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 9223372036854775807 ++} ++ ++define i64 @li8000000000000000() { ++; CHECK-LABEL: li8000000000000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu52i.d $r4, $zero, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9223372036854775808 ++} ++ ++define i64 @li80000000000007ff() { ++; CHECK-LABEL: li80000000000007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2047 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9223372036854773761 ++} ++ ++define i64 @li8000000000000800() { ++; CHECK-LABEL: li8000000000000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2048 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9223372036854773760 ++} ++ ++define i64 @li8000000000000fff() { ++; CHECK-LABEL: li8000000000000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 4095 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9223372036854771713 ++} ++ ++define i64 @li800000007ffff000() { ++; CHECK-LABEL: li800000007ffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9223372034707296256 ++} ++ ++define i64 @li800000007ffff7ff() { ++; CHECK-LABEL: li800000007ffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9223372034707294209 ++} ++ ++define i64 @li800000007ffff800() { ++; CHECK-LABEL: li800000007ffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9223372034707294208 ++} ++ ++define i64 @li800000007fffffff() { ++; CHECK-LABEL: li800000007fffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9223372034707292161 ++} ++ ++define i64 @li8000000080000000() { ++; CHECK-LABEL: li8000000080000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9223372034707292160 ++} ++ ++define i64 @li80000000800007ff() { ++; CHECK-LABEL: li80000000800007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9223372034707290113 ++} ++ ++define i64 @li8000000080000800() { ++; CHECK-LABEL: li8000000080000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9223372034707290112 ++} ++ ++define i64 @li8000000080000fff() { ++; CHECK-LABEL: li8000000080000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9223372034707288065 ++} ++ ++define i64 @li80000000fffff000() { ++; CHECK-LABEL: li80000000fffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9223372032559812608 ++} ++ ++define i64 @li80000000fffff7ff() { ++; CHECK-LABEL: li80000000fffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9223372032559810561 ++} ++ ++define i64 @li80000000fffff800() { ++; CHECK-LABEL: li80000000fffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -2048 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9223372032559810560 ++} ++ ++define i64 @li80000000ffffffff() { ++; CHECK-LABEL: li80000000ffffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -1 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9223372032559808513 ++} ++ ++define i64 @li8007ffff00000000() { ++; CHECK-LABEL: li8007ffff00000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 0 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120241336057856 ++} ++ ++define i64 @li8007ffff000007ff() { ++; CHECK-LABEL: li8007ffff000007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2047 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120241336055809 ++} ++ ++define i64 @li8007ffff00000800() { ++; CHECK-LABEL: li8007ffff00000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2048 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120241336055808 ++} ++ ++define i64 @li8007ffff00000fff() { ++; CHECK-LABEL: li8007ffff00000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 4095 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120241336053761 ++} ++ ++define i64 @li8007ffff7ffff000() { ++; CHECK-LABEL: li8007ffff7ffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120239188578304 ++} ++ ++define i64 @li8007ffff7ffff7ff() { ++; CHECK-LABEL: li8007ffff7ffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120239188576257 ++} ++ ++define i64 @li8007ffff7ffff800() { ++; CHECK-LABEL: li8007ffff7ffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120239188576256 ++} ++ ++define i64 @li8007ffff7fffffff() { ++; CHECK-LABEL: li8007ffff7fffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120239188574209 ++} ++ ++define i64 @li8007ffff80000000() { ++; CHECK-LABEL: li8007ffff80000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120239188574208 ++} ++ ++define i64 @li8007ffff800007ff() { ++; CHECK-LABEL: li8007ffff800007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120239188572161 ++} ++ ++define i64 @li8007ffff80000800() { ++; CHECK-LABEL: li8007ffff80000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120239188572160 ++} ++ ++define i64 @li8007ffff80000fff() { ++; CHECK-LABEL: li8007ffff80000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120239188570113 ++} ++ ++define i64 @li8007fffffffff000() { ++; CHECK-LABEL: li8007fffffffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120237041094656 ++} ++ ++define i64 @li8007fffffffff7ff() { ++; CHECK-LABEL: li8007fffffffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120237041092609 ++} ++ ++define i64 @li8007fffffffff800() { ++; CHECK-LABEL: li8007fffffffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -2048 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120237041092608 ++} ++ ++define i64 @li8007ffffffffffff() { ++; CHECK-LABEL: li8007ffffffffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -1 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120237041090561 ++} ++ ++define i64 @li8008000000000000() { ++; CHECK-LABEL: li8008000000000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 0 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120237041090560 ++} ++ ++define i64 @li80080000000007ff() { ++; CHECK-LABEL: li80080000000007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2047 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120237041088513 ++} ++ ++define i64 @li8008000000000800() { ++; CHECK-LABEL: li8008000000000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2048 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120237041088512 ++} ++ ++define i64 @li8008000000000fff() { ++; CHECK-LABEL: li8008000000000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 4095 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120237041086465 ++} ++ ++define i64 @li800800007ffff000() { ++; CHECK-LABEL: li800800007ffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120234893611008 ++} ++ ++define i64 @li800800007ffff7ff() { ++; CHECK-LABEL: li800800007ffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120234893608961 ++} ++ ++define i64 @li800800007ffff800() { ++; CHECK-LABEL: li800800007ffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120234893608960 ++} ++ ++define i64 @li800800007fffffff() { ++; CHECK-LABEL: li800800007fffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120234893606913 ++} ++ ++define i64 @li8008000080000000() { ++; CHECK-LABEL: li8008000080000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120234893606912 ++} ++ ++define i64 @li80080000800007ff() { ++; CHECK-LABEL: li80080000800007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120234893604865 ++} ++ ++define i64 @li8008000080000800() { ++; CHECK-LABEL: li8008000080000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120234893604864 ++} ++ ++define i64 @li8008000080000fff() { ++; CHECK-LABEL: li8008000080000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120234893602817 ++} ++ ++define i64 @li80080000fffff000() { ++; CHECK-LABEL: li80080000fffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120232746127360 ++} ++ ++define i64 @li80080000fffff7ff() { ++; CHECK-LABEL: li80080000fffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120232746125313 ++} ++ ++define i64 @li80080000fffff800() { ++; CHECK-LABEL: li80080000fffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -2048 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120232746125312 ++} ++ ++define i64 @li80080000ffffffff() { ++; CHECK-LABEL: li80080000ffffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -1 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9221120232746123265 ++} ++ ++define i64 @li800fffff00000000() { ++; CHECK-LABEL: li800fffff00000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 0 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9218868441522372608 ++} ++ ++define i64 @li800fffff000007ff() { ++; CHECK-LABEL: li800fffff000007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2047 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9218868441522370561 ++} ++ ++define i64 @li800fffff00000800() { ++; CHECK-LABEL: li800fffff00000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2048 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9218868441522370560 ++} ++ ++define i64 @li800fffff00000fff() { ++; CHECK-LABEL: li800fffff00000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 4095 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9218868441522368513 ++} ++ ++define i64 @li800fffff7ffff000() { ++; CHECK-LABEL: li800fffff7ffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9218868439374893056 ++} ++ ++define i64 @li800fffff7ffff7ff() { ++; CHECK-LABEL: li800fffff7ffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9218868439374891009 ++} ++ ++define i64 @li800fffff7ffff800() { ++; CHECK-LABEL: li800fffff7ffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9218868439374891008 ++} ++ ++define i64 @li800fffff7fffffff() { ++; CHECK-LABEL: li800fffff7fffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9218868439374888961 ++} ++ ++define i64 @li800fffff80000000() { ++; CHECK-LABEL: li800fffff80000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9218868439374888960 ++} ++ ++define i64 @li800fffff800007ff() { ++; CHECK-LABEL: li800fffff800007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9218868439374886913 ++} ++ ++define i64 @li800fffff80000800() { ++; CHECK-LABEL: li800fffff80000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9218868439374886912 ++} ++ ++define i64 @li800fffff80000fff() { ++; CHECK-LABEL: li800fffff80000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9218868439374884865 ++} ++ ++define i64 @li800ffffffffff000() { ++; CHECK-LABEL: li800ffffffffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9218868437227409408 ++} ++ ++define i64 @li800ffffffffff7ff() { ++; CHECK-LABEL: li800ffffffffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9218868437227407361 ++} ++ ++define i64 @li800ffffffffff800() { ++; CHECK-LABEL: li800ffffffffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -2048 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9218868437227407360 ++} ++ ++define i64 @li800fffffffffffff() { ++; CHECK-LABEL: li800fffffffffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -9218868437227405313 ++} ++ ++define i64 @lifff0000000000000() { ++; CHECK-LABEL: lifff0000000000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu52i.d $r4, $zero, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -4503599627370496 ++} ++ ++define i64 @lifff00000000007ff() { ++; CHECK-LABEL: lifff00000000007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2047 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -4503599627368449 ++} ++ ++define i64 @lifff0000000000800() { ++; CHECK-LABEL: lifff0000000000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2048 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -4503599627368448 ++} ++ ++define i64 @lifff0000000000fff() { ++; CHECK-LABEL: lifff0000000000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 4095 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -4503599627366401 ++} ++ ++define i64 @lifff000007ffff000() { ++; CHECK-LABEL: lifff000007ffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -4503597479890944 ++} ++ ++define i64 @lifff000007ffff7ff() { ++; CHECK-LABEL: lifff000007ffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -4503597479888897 ++} ++ ++define i64 @lifff000007ffff800() { ++; CHECK-LABEL: lifff000007ffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -4503597479888896 ++} ++ ++define i64 @lifff000007fffffff() { ++; CHECK-LABEL: lifff000007fffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -4503597479886849 ++} ++ ++define i64 @lifff0000080000000() { ++; CHECK-LABEL: lifff0000080000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -4503597479886848 ++} ++ ++define i64 @lifff00000800007ff() { ++; CHECK-LABEL: lifff00000800007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -4503597479884801 ++} ++ ++define i64 @lifff0000080000800() { ++; CHECK-LABEL: lifff0000080000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -4503597479884800 ++} ++ ++define i64 @lifff0000080000fff() { ++; CHECK-LABEL: lifff0000080000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -4503597479882753 ++} ++ ++define i64 @lifff00000fffff000() { ++; CHECK-LABEL: lifff00000fffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -4503595332407296 ++} ++ ++define i64 @lifff00000fffff7ff() { ++; CHECK-LABEL: lifff00000fffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -4503595332405249 ++} ++ ++define i64 @lifff00000fffff800() { ++; CHECK-LABEL: lifff00000fffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -2048 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -4503595332405248 ++} ++ ++define i64 @lifff00000ffffffff() { ++; CHECK-LABEL: lifff00000ffffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -1 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -4503595332403201 ++} ++ ++define i64 @lifff7ffff00000000() { ++; CHECK-LABEL: lifff7ffff00000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 0 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251804108652544 ++} ++ ++define i64 @lifff7ffff000007ff() { ++; CHECK-LABEL: lifff7ffff000007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2047 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251804108650497 ++} ++ ++define i64 @lifff7ffff00000800() { ++; CHECK-LABEL: lifff7ffff00000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2048 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251804108650496 ++} ++ ++define i64 @lifff7ffff00000fff() { ++; CHECK-LABEL: lifff7ffff00000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 4095 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251804108648449 ++} ++ ++define i64 @lifff7ffff7ffff000() { ++; CHECK-LABEL: lifff7ffff7ffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251801961172992 ++} ++ ++define i64 @lifff7ffff7ffff7ff() { ++; CHECK-LABEL: lifff7ffff7ffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251801961170945 ++} ++ ++define i64 @lifff7ffff7ffff800() { ++; CHECK-LABEL: lifff7ffff7ffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251801961170944 ++} ++ ++define i64 @lifff7ffff7fffffff() { ++; CHECK-LABEL: lifff7ffff7fffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251801961168897 ++} ++ ++define i64 @lifff7ffff80000000() { ++; CHECK-LABEL: lifff7ffff80000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251801961168896 ++} ++ ++define i64 @lifff7ffff800007ff() { ++; CHECK-LABEL: lifff7ffff800007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251801961166849 ++} ++ ++define i64 @lifff7ffff80000800() { ++; CHECK-LABEL: lifff7ffff80000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251801961166848 ++} ++ ++define i64 @lifff7ffff80000fff() { ++; CHECK-LABEL: lifff7ffff80000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251801961164801 ++} ++ ++define i64 @lifff7fffffffff000() { ++; CHECK-LABEL: lifff7fffffffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251799813689344 ++} ++ ++define i64 @lifff7fffffffff7ff() { ++; CHECK-LABEL: lifff7fffffffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251799813687297 ++} ++ ++define i64 @lifff7fffffffff800() { ++; CHECK-LABEL: lifff7fffffffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -2048 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251799813687296 ++} ++ ++define i64 @lifff7ffffffffffff() { ++; CHECK-LABEL: lifff7ffffffffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -1 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251799813685249 ++} ++ ++define i64 @lifff8000000000000() { ++; CHECK-LABEL: lifff8000000000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 0 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251799813685248 ++} ++ ++define i64 @lifff80000000007ff() { ++; CHECK-LABEL: lifff80000000007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2047 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251799813683201 ++} ++ ++define i64 @lifff8000000000800() { ++; CHECK-LABEL: lifff8000000000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2048 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251799813683200 ++} ++ ++define i64 @lifff8000000000fff() { ++; CHECK-LABEL: lifff8000000000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 4095 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251799813681153 ++} ++ ++define i64 @lifff800007ffff000() { ++; CHECK-LABEL: lifff800007ffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251797666205696 ++} ++ ++define i64 @lifff800007ffff7ff() { ++; CHECK-LABEL: lifff800007ffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251797666203649 ++} ++ ++define i64 @lifff800007ffff800() { ++; CHECK-LABEL: lifff800007ffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251797666203648 ++} ++ ++define i64 @lifff800007fffffff() { ++; CHECK-LABEL: lifff800007fffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251797666201601 ++} ++ ++define i64 @lifff8000080000000() { ++; CHECK-LABEL: lifff8000080000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251797666201600 ++} ++ ++define i64 @lifff80000800007ff() { ++; CHECK-LABEL: lifff80000800007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251797666199553 ++} ++ ++define i64 @lifff8000080000800() { ++; CHECK-LABEL: lifff8000080000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251797666199552 ++} ++ ++define i64 @lifff8000080000fff() { ++; CHECK-LABEL: lifff8000080000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251797666197505 ++} ++ ++define i64 @lifff80000fffff000() { ++; CHECK-LABEL: lifff80000fffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251795518722048 ++} ++ ++define i64 @lifff80000fffff7ff() { ++; CHECK-LABEL: lifff80000fffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251795518720001 ++} ++ ++define i64 @lifff80000fffff800() { ++; CHECK-LABEL: lifff80000fffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -2048 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251795518720000 ++} ++ ++define i64 @lifff80000ffffffff() { ++; CHECK-LABEL: lifff80000ffffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -1 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: jr $ra ++ ret i64 -2251795518717953 ++} ++ ++define i64 @liffffffff00000000() { ++; CHECK-LABEL: liffffffff00000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 0 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -4294967296 ++} ++ ++define i64 @liffffffff000007ff() { ++; CHECK-LABEL: liffffffff000007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2047 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -4294965249 ++} ++ ++define i64 @liffffffff00000800() { ++; CHECK-LABEL: liffffffff00000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2048 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -4294965248 ++} ++ ++define i64 @liffffffff00000fff() { ++; CHECK-LABEL: liffffffff00000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 4095 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -4294963201 ++} ++ ++define i64 @liffffffff7ffff000() { ++; CHECK-LABEL: liffffffff7ffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -2147487744 ++} ++ ++define i64 @liffffffff7ffff7ff() { ++; CHECK-LABEL: liffffffff7ffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -2147485697 ++} ++ ++define i64 @liffffffff7ffff800() { ++; CHECK-LABEL: liffffffff7ffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -2147485696 ++} ++ ++define i64 @liffffffff7fffffff() { ++; CHECK-LABEL: liffffffff7fffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -2147483649 ++} ++ ++define i64 @liffffffff80000000() { ++; CHECK-LABEL: liffffffff80000000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: jr $ra ++ ret i64 -2147483648 ++} ++ ++define i64 @liffffffff800007ff() { ++; CHECK-LABEL: liffffffff800007ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 -2147481601 ++} ++ ++define i64 @liffffffff80000800() { ++; CHECK-LABEL: liffffffff80000800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -2147481600 ++} ++ ++define i64 @liffffffff80000fff() { ++; CHECK-LABEL: liffffffff80000fff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 4095 ++; CHECK-NEXT: jr $ra ++ ret i64 -2147479553 ++} ++ ++define i64 @lifffffffffffff000() { ++; CHECK-LABEL: lifffffffffffff000: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -4096 ++} ++ ++define i64 @lifffffffffffff7ff() { ++; CHECK-LABEL: lifffffffffffff7ff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: jr $ra ++ ret i64 -2049 ++} ++ ++define i64 @lifffffffffffff800() { ++; CHECK-LABEL: lifffffffffffff800: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $r4, $zero, -2048 ++; CHECK-NEXT: jr $ra ++ ret i64 -2048 ++} ++ ++define i64 @liffffffffffffffff() { ++; CHECK-LABEL: liffffffffffffffff: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $r4, $zero, -1 ++; CHECK-NEXT: jr $ra ++ ret i64 -1 ++} +diff --git a/llvm/test/CodeGen/LoongArch/inline-asm-clobbers-fcc.mir b/llvm/test/CodeGen/LoongArch/inline-asm-clobbers-fcc.mir +deleted file mode 100644 +index 18dbc5ca2..000000000 +--- a/llvm/test/CodeGen/LoongArch/inline-asm-clobbers-fcc.mir ++++ /dev/null +@@ -1,32 +0,0 @@ +-# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +-# RUN: llc --mtriple=loongarch64 --mattr=+d --regalloc=fast \ +-# RUN: --stop-before=postra-machine-sink %s -o - | FileCheck %s +- +-## Check that fcc register clobbered by inlineasm is correctly saved by examing +-## a pair of pseudos (PseudoST_CFR and PseudoLD_CFR) are generated before and +-## after the INLINEASM. +-... +---- +-name: test +-tracksRegLiveness: true +-body: | +- bb.0.entry: +- liveins: $f0_64, $f1_64 +- +- ; CHECK-LABEL: name: test +- ; CHECK: liveins: $f0_64, $f1_64 +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: renamable $fcc0 = FCMP_CLT_D renamable $f1_64, renamable $f0_64 +- ; CHECK-NEXT: PseudoST_CFR $fcc0, %stack.0, 0 :: (store (s64) into %stack.0) +- ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead early-clobber $fcc0 +- ; CHECK-NEXT: $fcc0 = PseudoLD_CFR %stack.0, 0 :: (load (s64) from %stack.0) +- ; CHECK-NEXT: $r4 = COPY killed renamable $fcc0 +- ; CHECK-NEXT: PseudoRET implicit killed $r4 +- %1:fpr64 = COPY $f1_64 +- %0:fpr64 = COPY $f0_64 +- %2:cfr = FCMP_CLT_D %1, %0 +- INLINEASM &"nop", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead early-clobber $fcc0 +- $r4 = COPY %2 +- PseudoRET implicit killed $r4 +- +-... +diff --git a/llvm/test/CodeGen/LoongArch/inline-asm-clobbers.ll b/llvm/test/CodeGen/LoongArch/inline-asm-clobbers.ll +deleted file mode 100644 +index f7e460e47..000000000 +--- a/llvm/test/CodeGen/LoongArch/inline-asm-clobbers.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+d --target-abi=ilp32d --verify-machineinstrs < %s \ +-; RUN: | FileCheck --check-prefix=LA32 %s +-; RUN: llc --mtriple=loongarch64 --mattr=+d --target-abi=lp64d --verify-machineinstrs < %s \ +-; RUN: | FileCheck --check-prefix=LA64 %s +- +-;; Check that callee-saved registers clobbered by inlineasm are correctly saved. +-;; +-;; $r23: $s0 (callee-saved register under all ABIs) +-;; $r24: $s1 (callee-saved register under all ABIs) +-;; $f24: $fs0 (callee-saved register under *d/*f ABIs) +-;; $f25: $fs1 (callee-saved register under *d/*f ABIs) +- +-;; TODO: test other ABIs. +- +-define void @test() nounwind { +-; LA32-LABEL: test: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -32 +-; LA32-NEXT: st.w $s0, $sp, 28 # 4-byte Folded Spill +-; LA32-NEXT: st.w $s1, $sp, 24 # 4-byte Folded Spill +-; LA32-NEXT: fst.d $fs0, $sp, 16 # 8-byte Folded Spill +-; LA32-NEXT: fst.d $fs1, $sp, 8 # 8-byte Folded Spill +-; LA32-NEXT: #APP +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: fld.d $fs1, $sp, 8 # 8-byte Folded Reload +-; LA32-NEXT: fld.d $fs0, $sp, 16 # 8-byte Folded Reload +-; LA32-NEXT: ld.w $s1, $sp, 24 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $s0, $sp, 28 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 32 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -32 +-; LA64-NEXT: st.d $s0, $sp, 24 # 8-byte Folded Spill +-; LA64-NEXT: st.d $s1, $sp, 16 # 8-byte Folded Spill +-; LA64-NEXT: fst.d $fs0, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: fst.d $fs1, $sp, 0 # 8-byte Folded Spill +-; LA64-NEXT: #APP +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: fld.d $fs1, $sp, 0 # 8-byte Folded Reload +-; LA64-NEXT: fld.d $fs0, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $s1, $sp, 16 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $s0, $sp, 24 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 32 +-; LA64-NEXT: ret +- tail call void asm sideeffect "", "~{$f24},~{$f25},~{$r23},~{$r24}"() +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/inline-asm-constraint-ZB.ll b/llvm/test/CodeGen/LoongArch/inline-asm-constraint-ZB.ll +deleted file mode 100644 +index 1a8f50abb..000000000 +--- a/llvm/test/CodeGen/LoongArch/inline-asm-constraint-ZB.ll ++++ /dev/null +@@ -1,62 +0,0 @@ +-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s \ +-; RUN: | FileCheck %s --check-prefix=ASM +-; RUN: llc --mtriple=loongarch64 --print-after-isel -o /dev/null 2>&1 < %s \ +-; RUN: | FileCheck %s --check-prefix=MACHINE-INSTR +- +-;; Note amswap.w is not available on loongarch32. +- +-define void @ZB(ptr %p) nounwind { +-; ASM-LABEL: ZB: +-; ASM: # %bb.0: +-; ASM-NEXT: #APP +-; ASM-NEXT: amswap.w $t0, $t1, $a0 +-; ASM-NEXT: #NO_APP +-; ASM-NEXT: ret +-;; Make sure machine instr with this "ZB" constraint is printed correctly. +-; MACHINE-INSTR: INLINEASM{{.*}}[mem:ZB] +- call void asm "amswap.w $$r12, $$r13, $0", "*^ZB"(ptr elementtype(i32) %p) +- ret void +-} +- +-define void @ZB_constant_offset(ptr %p) nounwind { +-; ASM-LABEL: ZB_constant_offset: +-; ASM: # %bb.0: +-; ASM-NEXT: addi.d $a0, $a0, 1 +-; ASM-NEXT: #APP +-; ASM-NEXT: amswap.w $t0, $t1, $a0 +-; ASM-NEXT: #NO_APP +-; ASM-NEXT: ret +- %1 = getelementptr inbounds i8, ptr %p, i32 1 +-;; Make sure machine instr with this "ZB" constraint is printed correctly. +-; MACHINE-INSTR: INLINEASM{{.*}}[mem:ZB] +- call void asm "amswap.w $$r12, $$r13, $0", "*^ZB"(ptr elementtype(i32) %1) +- ret void +-} +- +-define void @ZB_variable_offset(ptr %p, i32 signext %idx) nounwind { +-; ASM-LABEL: ZB_variable_offset: +-; ASM: # %bb.0: +-; ASM-NEXT: add.d $a0, $a0, $a1 +-; ASM-NEXT: #APP +-; ASM-NEXT: amswap.w $t0, $t1, $a0 +-; ASM-NEXT: #NO_APP +-; ASM-NEXT: ret +- %1 = getelementptr inbounds i8, ptr %p, i32 %idx +-;; Make sure machine instr with this "ZB" constraint is printed correctly. +-; MACHINE-INSTR: INLINEASM{{.*}}[mem:ZB] +- call void asm "amswap.w $$r12, $$r13, $0", "*^ZB"(ptr elementtype(i32) %1) +- ret void +-} +- +-define void @ZB_Input_Output(ptr %p) nounwind { +-; ASM-LABEL: ZB_Input_Output: +-; ASM: # %bb.0: +-; ASM-NEXT: #APP +-; ASM-NEXT: amadd_db.d $zero, $t1, $a0 +-; ASM-NEXT: #NO_APP +-; ASM-NEXT: ret +-;; Make sure machine instr with this "ZB" constraint is printed correctly. +-; MACHINE-INSTR: INLINEASM{{.*}}[mem:ZB], %0:gpr, 0 +- call void asm "amadd_db.d $$zero, $$r13, $0", "=*^ZB,*^ZB,~{memory}"(ptr elementtype(i64) %p, ptr elementtype(i64) %p) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/inline-asm-constraint-ZC.ll b/llvm/test/CodeGen/LoongArch/inline-asm-constraint-ZC.ll +deleted file mode 100644 +index 9c053c4d2..000000000 +--- a/llvm/test/CodeGen/LoongArch/inline-asm-constraint-ZC.ll ++++ /dev/null +@@ -1,170 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --verify-machineinstrs < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s | FileCheck %s --check-prefix=LA64 +- +-define i32 @ZC_offset_neg_32769(ptr %p) nounwind { +-; LA32-LABEL: ZC_offset_neg_32769: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, -9 +-; LA32-NEXT: ori $a1, $a1, 4095 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: #APP +-; LA32-NEXT: ll.w $a0, $a0, 0 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ZC_offset_neg_32769: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, -9 +-; LA64-NEXT: ori $a1, $a1, 4095 +-; LA64-NEXT: add.d $a0, $a0, $a1 +-; LA64-NEXT: #APP +-; LA64-NEXT: ll.w $a0, $a0, 0 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ret +- %1 = getelementptr inbounds i8, ptr %p, i32 -32769 +- %2 = call i32 asm "ll.w $0, $1", "=r,*^ZC"(ptr elementtype(i32) %1) +- ret i32 %2 +-} +- +-define i32 @ZC_offset_neg_32768(ptr %p) nounwind { +-; LA32-LABEL: ZC_offset_neg_32768: +-; LA32: # %bb.0: +-; LA32-NEXT: #APP +-; LA32-NEXT: ll.w $a0, $a0, -32768 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ZC_offset_neg_32768: +-; LA64: # %bb.0: +-; LA64-NEXT: #APP +-; LA64-NEXT: ll.w $a0, $a0, -32768 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ret +- %1 = getelementptr inbounds i8, ptr %p, i32 -32768 +- %2 = call i32 asm "ll.w $0, $1", "=r,*^ZC"(ptr elementtype(i32) %1) +- ret i32 %2 +-} +- +-define i32 @ZC_offset_neg_4(ptr %p) nounwind { +-; LA32-LABEL: ZC_offset_neg_4: +-; LA32: # %bb.0: +-; LA32-NEXT: #APP +-; LA32-NEXT: ll.w $a0, $a0, -4 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ZC_offset_neg_4: +-; LA64: # %bb.0: +-; LA64-NEXT: #APP +-; LA64-NEXT: ll.w $a0, $a0, -4 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ret +- %1 = getelementptr inbounds i8, ptr %p, i32 -4 +- %2 = call i32 asm "ll.w $0, $1", "=r,*^ZC"(ptr elementtype(i32) %1) +- ret i32 %2 +-} +- +-define i32 @ZC_offset_neg_1(ptr %p) nounwind { +-; LA32-LABEL: ZC_offset_neg_1: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $a0, -1 +-; LA32-NEXT: #APP +-; LA32-NEXT: ll.w $a0, $a0, 0 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ZC_offset_neg_1: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $a0, $a0, -1 +-; LA64-NEXT: #APP +-; LA64-NEXT: ll.w $a0, $a0, 0 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ret +- %1 = getelementptr inbounds i8, ptr %p, i32 -1 +- %2 = call i32 asm "ll.w $0, $1", "=r,*^ZC"(ptr elementtype(i32) %1) +- ret i32 %2 +-} +- +-define i32 @ZC_offset_0(ptr %p) nounwind { +-; LA32-LABEL: ZC_offset_0: +-; LA32: # %bb.0: +-; LA32-NEXT: #APP +-; LA32-NEXT: ll.w $a0, $a0, 0 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ZC_offset_0: +-; LA64: # %bb.0: +-; LA64-NEXT: #APP +-; LA64-NEXT: ll.w $a0, $a0, 0 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ret +- %1 = call i32 asm "ll.w $0, $1", "=r,*^ZC"(ptr elementtype(i32) %p) +- ret i32 %1 +-} +- +-define i32 @ZC_offset_1(ptr %p) nounwind { +-; LA32-LABEL: ZC_offset_1: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $a0, 1 +-; LA32-NEXT: #APP +-; LA32-NEXT: ll.w $a0, $a0, 0 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ZC_offset_1: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $a0, $a0, 1 +-; LA64-NEXT: #APP +-; LA64-NEXT: ll.w $a0, $a0, 0 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ret +- %1 = getelementptr inbounds i8, ptr %p, i32 1 +- %2 = call i32 asm "ll.w $0, $1", "=r,*^ZC"(ptr elementtype(i32) %1) +- ret i32 %2 +-} +- +-define i32 @ZC_offset_32764(ptr %p) nounwind { +-; LA32-LABEL: ZC_offset_32764: +-; LA32: # %bb.0: +-; LA32-NEXT: #APP +-; LA32-NEXT: ll.w $a0, $a0, 32764 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ZC_offset_32764: +-; LA64: # %bb.0: +-; LA64-NEXT: #APP +-; LA64-NEXT: ll.w $a0, $a0, 32764 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ret +- %1 = getelementptr inbounds i8, ptr %p, i32 32764 +- %2 = call i32 asm "ll.w $0, $1", "=r,*^ZC"(ptr elementtype(i32) %1) +- ret i32 %2 +-} +- +-define i32 @ZC_offset_32767(ptr %p) nounwind { +-; LA32-LABEL: ZC_offset_32767: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 7 +-; LA32-NEXT: ori $a1, $a1, 4095 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: #APP +-; LA32-NEXT: ll.w $a0, $a0, 0 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ZC_offset_32767: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, 7 +-; LA64-NEXT: ori $a1, $a1, 4095 +-; LA64-NEXT: add.d $a0, $a0, $a1 +-; LA64-NEXT: #APP +-; LA64-NEXT: ll.w $a0, $a0, 0 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ret +- %1 = getelementptr inbounds i8, ptr %p, i32 32767 +- %2 = call i32 asm "ll.w $0, $1", "=r,*^ZC"(ptr elementtype(i32) %1) +- ret i32 %2 +-} +diff --git a/llvm/test/CodeGen/LoongArch/inline-asm-constraint-error.ll b/llvm/test/CodeGen/LoongArch/inline-asm-constraint-error.ll +deleted file mode 100644 +index 570fd438b..000000000 +--- a/llvm/test/CodeGen/LoongArch/inline-asm-constraint-error.ll ++++ /dev/null +@@ -1,46 +0,0 @@ +-; RUN: not llc --mtriple=loongarch32 < %s 2>&1 | FileCheck %s +-; RUN: not llc --mtriple=loongarch64 < %s 2>&1 | FileCheck %s +- +-define void @constraint_l() { +-; CHECK: error: value out of range for constraint 'l' +- tail call void asm sideeffect "lu12i.w $$a0, $0", "l"(i32 32768) +-; CHECK: error: value out of range for constraint 'l' +- tail call void asm sideeffect "lu12i.w $$a0, $0", "l"(i32 -32769) +- ret void +-} +- +-define void @constraint_I() { +-; CHECK: error: value out of range for constraint 'I' +- tail call void asm sideeffect "addi.w $$a0, $$a0, $0", "I"(i32 2048) +-; CHECK: error: value out of range for constraint 'I' +- tail call void asm sideeffect "addi.w $$a0, $$a0, $0", "I"(i32 -2049) +- ret void +-} +- +-define void @constraint_J() { +-; CHECK: error: value out of range for constraint 'J' +- tail call void asm sideeffect "addi.w $$a0, $$a0, $$0", "J"(i32 1) +- ret void +-} +- +-define void @constraint_K() { +-; CHECK: error: value out of range for constraint 'K' +- tail call void asm sideeffect "andi.w $$a0, $$a0, $0", "K"(i32 4096) +-; CHECK: error: value out of range for constraint 'K' +- tail call void asm sideeffect "andi.w $$a0, $$a0, $0", "K"(i32 -1) +- ret void +-} +- +-define void @constraint_f() nounwind { +-; CHECK: error: couldn't allocate input reg for constraint 'f' +- tail call void asm "fadd.s $$fa0, $$fa0, $0", "f"(float 0.0) +-; CHECK: error: couldn't allocate input reg for constraint 'f' +- tail call void asm "fadd.s $$fa0, $$fa0, $0", "f"(double 0.0) +- ret void +-} +- +-define void @constraint_r_vec() nounwind { +-; CHECK: error: couldn't allocate input reg for constraint 'r' +- tail call void asm "add.w $$a0, $$a0, $0", "r"(<4 x i32> zeroinitializer) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/inline-asm-constraint-f.ll b/llvm/test/CodeGen/LoongArch/inline-asm-constraint-f.ll +deleted file mode 100644 +index fa675e4bb..000000000 +--- a/llvm/test/CodeGen/LoongArch/inline-asm-constraint-f.ll ++++ /dev/null +@@ -1,62 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+d --target-abi=ilp32d --verify-machineinstrs < %s \ +-; RUN: | FileCheck --check-prefix=LA32 %s +-; RUN: llc --mtriple=loongarch64 --mattr=+d --target-abi=lp64d --verify-machineinstrs < %s \ +-; RUN: | FileCheck --check-prefix=LA64 %s +- +-@gd = external dso_local global double +- +-define double @constraint_f_double(double %a) nounwind { +-; LA32-LABEL: constraint_f_double: +-; LA32: # %bb.0: +-; LA32-NEXT: pcalau12i $a0, %pc_hi20(gd) +-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(gd) +-; LA32-NEXT: fld.d $fa1, $a0, 0 +-; LA32-NEXT: #APP +-; LA32-NEXT: fadd.d $fa0, $fa0, $fa1 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ret +-; +-; LA64-LABEL: constraint_f_double: +-; LA64: # %bb.0: +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(gd) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(gd) +-; LA64-NEXT: fld.d $fa1, $a0, 0 +-; LA64-NEXT: #APP +-; LA64-NEXT: fadd.d $fa0, $fa0, $fa1 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ret +- %1 = load double, ptr @gd +- %2 = tail call double asm "fadd.d $0, $1, $2", "=f,f,f"(double %a, double %1) +- ret double %2 +-} +- +-define double @constraint_gpr(double %a) { +-; LA32-LABEL: constraint_gpr: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: fst.d $fa0, $sp, 8 +-; LA32-NEXT: ld.w $a7, $sp, 8 +-; LA32-NEXT: ld.w $t0, $sp, 12 +-; LA32-NEXT: #APP +-; LA32-NEXT: move $a6, $a7 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: st.w $a7, $sp, 4 +-; LA32-NEXT: st.w $a6, $sp, 0 +-; LA32-NEXT: fld.d $fa0, $sp, 0 +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: constraint_gpr: +-; LA64: # %bb.0: +-; LA64-NEXT: .cfi_def_cfa_offset 0 +-; LA64-NEXT: movfr2gr.d $a7, $fa0 +-; LA64-NEXT: #APP +-; LA64-NEXT: move $a6, $a7 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: movgr2fr.d $fa0, $a6 +-; LA64-NEXT: ret +- %1 = tail call double asm sideeffect alignstack "move $0, $1", "={$r10},{$r11}"(double %a) +- ret double %1 +-} +diff --git a/llvm/test/CodeGen/LoongArch/inline-asm-constraint-k.ll b/llvm/test/CodeGen/LoongArch/inline-asm-constraint-k.ll +deleted file mode 100644 +index 5ffe4b48c..000000000 +--- a/llvm/test/CodeGen/LoongArch/inline-asm-constraint-k.ll ++++ /dev/null +@@ -1,33 +0,0 @@ +-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s \ +-; RUN: | FileCheck %s --check-prefix=ASM +-; RUN: llc --mtriple=loongarch64 --print-after-isel -o /dev/null 2>&1 < %s \ +-; RUN: | FileCheck %s --check-prefix=MACHINE-INSTR +- +-define i64 @k_variable_offset(ptr %p, i64 %idx) nounwind { +-; ASM-LABEL: k_variable_offset: +-; ASM: # %bb.0: +-; ASM-NEXT: #APP +-; ASM-NEXT: ldx.d $a0, $a0, $a1 +-; ASM-NEXT: #NO_APP +-; ASM-NEXT: ret +- %1 = getelementptr inbounds i8, ptr %p, i64 %idx +-;; Make sure machine instr with this 'k' constraint is printed correctly. +-; MACHINE-INSTR: INLINEASM{{.*}}[mem:k] +- %2 = call i64 asm "ldx.d $0, $1", "=r,*k"(ptr elementtype(i64) %1) +- ret i64 %2 +-} +- +-define i64 @k_constant_offset(ptr %p) nounwind { +-; ASM-LABEL: k_constant_offset: +-; ASM: # %bb.0: +-; ASM-NEXT: ori $a1, $zero, 5 +-; ASM-NEXT: #APP +-; ASM-NEXT: ldx.d $a0, $a0, $a1 +-; ASM-NEXT: #NO_APP +-; ASM-NEXT: ret +- %1 = getelementptr inbounds i8, ptr %p, i64 5 +-;; Make sure machine instr with this 'k' constraint is printed correctly. +-; MACHINE-INSTR: INLINEASM{{.*}}[mem:k] +- %2 = call i64 asm "ldx.d $0, $1", "=r,*k"(ptr elementtype(i64) %1) +- ret i64 %2 +-} +diff --git a/llvm/test/CodeGen/LoongArch/inline-asm-constraint-m.ll b/llvm/test/CodeGen/LoongArch/inline-asm-constraint-m.ll +deleted file mode 100644 +index b6d8893d8..000000000 +--- a/llvm/test/CodeGen/LoongArch/inline-asm-constraint-m.ll ++++ /dev/null +@@ -1,143 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --verify-machineinstrs < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s | FileCheck %s --check-prefix=LA64 +- +-define i32 @m_offset_neg_2049(ptr %p) nounwind { +-; LA32-LABEL: m_offset_neg_2049: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $a0, -2048 +-; LA32-NEXT: addi.w $a0, $a0, -1 +-; LA32-NEXT: #APP +-; LA32-NEXT: ld.w $a0, $a0, 0 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ret +-; +-; LA64-LABEL: m_offset_neg_2049: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $a0, $a0, -2048 +-; LA64-NEXT: addi.d $a0, $a0, -1 +-; LA64-NEXT: #APP +-; LA64-NEXT: ld.w $a0, $a0, 0 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ret +- %1 = getelementptr inbounds i8, ptr %p, i32 -2049 +- %2 = call i32 asm "ld.w $0, $1", "=r,*m"(ptr elementtype(i32) %1) +- ret i32 %2 +-} +- +-define i32 @m_offset_neg_2048(ptr %p) nounwind { +-; LA32-LABEL: m_offset_neg_2048: +-; LA32: # %bb.0: +-; LA32-NEXT: #APP +-; LA32-NEXT: ld.w $a0, $a0, -2048 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ret +-; +-; LA64-LABEL: m_offset_neg_2048: +-; LA64: # %bb.0: +-; LA64-NEXT: #APP +-; LA64-NEXT: ld.w $a0, $a0, -2048 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ret +- %1 = getelementptr inbounds i8, ptr %p, i32 -2048 +- %2 = call i32 asm "ld.w $0, $1", "=r,*m"(ptr elementtype(i32) %1) +- ret i32 %2 +-} +- +-define i32 @m_offset_neg_1(ptr %p) nounwind { +-; LA32-LABEL: m_offset_neg_1: +-; LA32: # %bb.0: +-; LA32-NEXT: #APP +-; LA32-NEXT: ld.w $a0, $a0, -1 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ret +-; +-; LA64-LABEL: m_offset_neg_1: +-; LA64: # %bb.0: +-; LA64-NEXT: #APP +-; LA64-NEXT: ld.w $a0, $a0, -1 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ret +- %1 = getelementptr inbounds i8, ptr %p, i32 -1 +- %2 = call i32 asm "ld.w $0, $1", "=r,*m"(ptr elementtype(i32) %1) +- ret i32 %2 +-} +- +-define i32 @m_offset_0(ptr %p) nounwind { +-; LA32-LABEL: m_offset_0: +-; LA32: # %bb.0: +-; LA32-NEXT: #APP +-; LA32-NEXT: ld.w $a0, $a0, 0 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ret +-; +-; LA64-LABEL: m_offset_0: +-; LA64: # %bb.0: +-; LA64-NEXT: #APP +-; LA64-NEXT: ld.w $a0, $a0, 0 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ret +- %1 = call i32 asm "ld.w $0, $1", "=r,*m"(ptr elementtype(i32) %p) +- ret i32 %1 +-} +- +-define i32 @m_offset_1(ptr %p) nounwind { +-; LA32-LABEL: m_offset_1: +-; LA32: # %bb.0: +-; LA32-NEXT: #APP +-; LA32-NEXT: ld.w $a0, $a0, 1 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ret +-; +-; LA64-LABEL: m_offset_1: +-; LA64: # %bb.0: +-; LA64-NEXT: #APP +-; LA64-NEXT: ld.w $a0, $a0, 1 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ret +- %1 = getelementptr inbounds i8, ptr %p, i32 1 +- %2 = call i32 asm "ld.w $0, $1", "=r,*m"(ptr elementtype(i32) %1) +- ret i32 %2 +-} +- +-define i32 @m_offset_2047(ptr %p) nounwind { +-; LA32-LABEL: m_offset_2047: +-; LA32: # %bb.0: +-; LA32-NEXT: #APP +-; LA32-NEXT: ld.w $a0, $a0, 2047 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ret +-; +-; LA64-LABEL: m_offset_2047: +-; LA64: # %bb.0: +-; LA64-NEXT: #APP +-; LA64-NEXT: ld.w $a0, $a0, 2047 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ret +- %1 = getelementptr inbounds i8, ptr %p, i32 2047 +- %2 = call i32 asm "ld.w $0, $1", "=r,*m"(ptr elementtype(i32) %1) +- ret i32 %2 +-} +- +-define i32 @m_offset_2048(ptr %p) nounwind { +-; LA32-LABEL: m_offset_2048: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $a0, 2047 +-; LA32-NEXT: addi.w $a0, $a0, 1 +-; LA32-NEXT: #APP +-; LA32-NEXT: ld.w $a0, $a0, 0 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ret +-; +-; LA64-LABEL: m_offset_2048: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $a0, $a0, 2047 +-; LA64-NEXT: addi.d $a0, $a0, 1 +-; LA64-NEXT: #APP +-; LA64-NEXT: ld.w $a0, $a0, 0 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ret +- %1 = getelementptr inbounds i8, ptr %p, i32 2048 +- %2 = call i32 asm "ld.w $0, $1", "=r,*m"(ptr elementtype(i32) %1) +- ret i32 %2 +-} +diff --git a/llvm/test/CodeGen/LoongArch/inline-asm-constraint.ll b/llvm/test/CodeGen/LoongArch/inline-asm-constraint.ll +deleted file mode 100644 +index 6ad52756b..000000000 +--- a/llvm/test/CodeGen/LoongArch/inline-asm-constraint.ll ++++ /dev/null +@@ -1,111 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --verify-machineinstrs --no-integrated-as < %s \ +-; RUN: | FileCheck %s +-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs --no-integrated-as < %s \ +-; RUN: | FileCheck %s +- +-@gi = external dso_local global i32, align 4 +- +-define i32 @constraint_r(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: constraint_r: +-; CHECK: # %bb.0: +-; CHECK-NEXT: #APP +-; CHECK-NEXT: add.w $a0, $a0, $a1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: ret +- %1 = tail call i32 asm "add.w $0, $1, $2", "=r,r,r"(i32 %a, i32 %b) +- ret i32 %1 +-} +- +-define i32 @constraint_i(i32 %a) nounwind { +-; CHECK-LABEL: constraint_i: +-; CHECK: # %bb.0: +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $a0, $a0, 113 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: ret +- %1 = tail call i32 asm "addi.w $0, $1, $2", "=r,r,i"(i32 %a, i32 113) +- ret i32 %1 +-} +- +-define void @constraint_l() nounwind { +-; CHECK-LABEL: constraint_l: +-; CHECK: # %bb.0: +-; CHECK-NEXT: #APP +-; CHECK-NEXT: lu12i.w $a0, 32767 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: lu12i.w $a0, -32768 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: ret +- tail call void asm sideeffect "lu12i.w $$a0, $0", "l"(i32 32767) +- tail call void asm sideeffect "lu12i.w $$a0, $0", "l"(i32 -32768) +- ret void +-} +- +-define void @constraint_I() nounwind { +-; CHECK-LABEL: constraint_I: +-; CHECK: # %bb.0: +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $a0, $a0, 2047 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $a0, $a0, -2048 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: ret +- tail call void asm sideeffect "addi.w $$a0, $$a0, $0", "I"(i32 2047) +- tail call void asm sideeffect "addi.w $$a0, $$a0, $0", "I"(i32 -2048) +- ret void +-} +- +-define void @constraint_J() nounwind { +-; CHECK-LABEL: constraint_J: +-; CHECK: # %bb.0: +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $a0, $a0, 0 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: ret +- tail call void asm sideeffect "addi.w $$a0, $$a0, $0", "J"(i32 0) +- ret void +-} +- +-define void @constraint_K() nounwind { +-; CHECK-LABEL: constraint_K: +-; CHECK: # %bb.0: +-; CHECK-NEXT: #APP +-; CHECK-NEXT: andi $a0, $a0, 4095 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: #APP +-; CHECK-NEXT: andi $a0, $a0, 0 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: ret +- tail call void asm sideeffect "andi $$a0, $$a0, $0", "K"(i32 4095) +- tail call void asm sideeffect "andi $$a0, $$a0, $0", "K"(i32 0) +- ret void +-} +- +-define void @operand_global() nounwind { +-; CHECK-LABEL: operand_global: +-; CHECK: # %bb.0: +-; CHECK-NEXT: #APP +-; CHECK-NEXT: .8byte gi +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: ret +- tail call void asm sideeffect ".8byte $0", "i"(ptr @gi) +- ret void +-} +- +-define void @operand_block_address() nounwind { +-; CHECK-LABEL: operand_block_address: +-; CHECK: # %bb.0: +-; CHECK-NEXT: #APP +-; CHECK-NEXT: b .Ltmp0 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: .Ltmp0: # Block address taken +-; CHECK-NEXT: # %bb.1: # %bb +-; CHECK-NEXT: ret +- call void asm sideeffect "b $0", "i"(ptr blockaddress(@operand_block_address, %bb)) +- br label %bb +-bb: +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/inline-asm-operand-modifiers.ll b/llvm/test/CodeGen/LoongArch/inline-asm-operand-modifiers.ll +deleted file mode 100644 +index d3cf288bf..000000000 +--- a/llvm/test/CodeGen/LoongArch/inline-asm-operand-modifiers.ll ++++ /dev/null +@@ -1,25 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --verify-machineinstrs < %s | FileCheck %s +-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s | FileCheck %s +- +-define i32 @modifier_z_zero(i32 %a) nounwind { +-; CHECK-LABEL: modifier_z_zero: +-; CHECK: # %bb.0: +-; CHECK-NEXT: #APP +-; CHECK-NEXT: add.w $a0, $a0, $zero +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: ret +- %1 = tail call i32 asm "add.w $0, $1, ${2:z}", "=r,r,ri"(i32 %a, i32 0) +- ret i32 %1 +-} +- +-define i32 @modifier_z_nonzero(i32 %a) nounwind { +-; CHECK-LABEL: modifier_z_nonzero: +-; CHECK: # %bb.0: +-; CHECK-NEXT: #APP +-; CHECK-NEXT: addi.w $a0, $a0, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: ret +- %1 = tail call i32 asm "addi.w $0, $1, ${2:z}", "=r,r,ri"(i32 %a, i32 1) +- ret i32 %1 +-} +diff --git a/llvm/test/CodeGen/LoongArch/inline-asm-reg-names-error.ll b/llvm/test/CodeGen/LoongArch/inline-asm-reg-names-error.ll +deleted file mode 100644 +index 56c335ffb..000000000 +--- a/llvm/test/CodeGen/LoongArch/inline-asm-reg-names-error.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; RUN: not llc --mtriple=loongarch32 2>&1 < %s | FileCheck %s +-; RUN: not llc --mtriple=loongarch64 2>&1 < %s | FileCheck %s +- +-define i32 @non_exit_r32(i32 %a) nounwind { +-; CHECK: error: couldn't allocate input reg for constraint '{$r32}' +- %1 = tail call i32 asm "addi.w $0, $1, 1", "=r,{$r32}"(i32 %a) +- ret i32 %1 +-} +- +-define i32 @non_exit_foo(i32 %a) nounwind { +-; CHECK: error: couldn't allocate input reg for constraint '{$foo}' +- %1 = tail call i32 asm "addi.w $0, $1, 1", "=r,{$foo}"(i32 %a) +- ret i32 %1 +-} +diff --git a/llvm/test/CodeGen/LoongArch/inline-asm-reg-names-f-error.ll b/llvm/test/CodeGen/LoongArch/inline-asm-reg-names-f-error.ll +deleted file mode 100644 +index 82d0d21e1..000000000 +--- a/llvm/test/CodeGen/LoongArch/inline-asm-reg-names-f-error.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; RUN: not llc --mtriple=loongarch32 --mattr=+f,+d 2>&1 < %s | FileCheck %s +-; RUN: not llc --mtriple=loongarch64 --mattr=+f,+d 2>&1 < %s | FileCheck %s +- +-define double @non_exit_f32(double %a) nounwind { +-; CHECK: error: couldn't allocate input reg for constraint '{$f32}' +- %1 = tail call double asm "fabs.d $0, $1", "=f,{$f32}"(double %a) +- ret double %1 +-} +- +-define double @non_exit_foo(double %a) nounwind { +-; CHECK: error: couldn't allocate input reg for constraint '{$foo}' +- %1 = tail call double asm "fabs.d $0, $1", "=f,{$foo}"(double %a) +- ret double %1 +-} +diff --git a/llvm/test/CodeGen/LoongArch/inline-asm-reg-names-f.ll b/llvm/test/CodeGen/LoongArch/inline-asm-reg-names-f.ll +deleted file mode 100644 +index 8cf112223..000000000 +--- a/llvm/test/CodeGen/LoongArch/inline-asm-reg-names-f.ll ++++ /dev/null +@@ -1,89 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+f,+d --target-abi=ilp32d --verify-machineinstrs < %s \ +-; RUN: | FileCheck --check-prefix=LA32 %s +-; RUN: llc --mtriple=loongarch64 --mattr=+f,+d --target-abi=lp64d --verify-machineinstrs < %s \ +-; RUN: | FileCheck --check-prefix=LA64 %s +- +-;; These test that we can use architectural names ($f[0-9]*) refer to registers in +-;; inline asm constraint lists. In each case, the named register should be used +-;; for the source register of the `fabs.d`. It is very likely that `$fa0` will +-;; be chosen as the designation register, but this is left to the compiler to +-;; choose. +-;; +-;; Parenthesised registers in comments are the other aliases for this register. +- +-define double @register_f0(double %a) nounwind { +-; LA32-LABEL: register_f0: +-; LA32: # %bb.0: +-; LA32-NEXT: #APP +-; LA32-NEXT: fabs.d $fa0, $fa0 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ret +-; +-; LA64-LABEL: register_f0: +-; LA64: # %bb.0: +-; LA64-NEXT: #APP +-; LA64-NEXT: fabs.d $fa0, $fa0 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ret +- %1 = tail call double asm "fabs.d $0, $1", "=f,{$f0}"(double %a) +- ret double %1 +-} +- +-;; NOTE: This test uses `$f24` (`$fs0`) as an input, so it should be saved. +-define double @register_f24(double %a) nounwind { +-; LA32-LABEL: register_f24: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: fst.d $fs0, $sp, 8 # 8-byte Folded Spill +-; LA32-NEXT: fmov.d $fs0, $fa0 +-; LA32-NEXT: #APP +-; LA32-NEXT: fabs.d $fa0, $fs0 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: fld.d $fs0, $sp, 8 # 8-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: register_f24: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: fst.d $fs0, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: fmov.d $fs0, $fa0 +-; LA64-NEXT: #APP +-; LA64-NEXT: fabs.d $fa0, $fs0 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: fld.d $fs0, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %1 = tail call double asm "fabs.d $0, $1", "=f,{$f24}"(double %a) +- ret double %1 +-} +- +-;; NOTE: This test uses `$f31` (`$fs7`) as an input, so it should be saved. +-define double @register_f31(double %a) nounwind { +-; LA32-LABEL: register_f31: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: fst.d $fs7, $sp, 8 # 8-byte Folded Spill +-; LA32-NEXT: fmov.d $fs7, $fa0 +-; LA32-NEXT: #APP +-; LA32-NEXT: fabs.d $fa0, $fs7 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: fld.d $fs7, $sp, 8 # 8-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: register_f31: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: fst.d $fs7, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: fmov.d $fs7, $fa0 +-; LA64-NEXT: #APP +-; LA64-NEXT: fabs.d $fa0, $fs7 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: fld.d $fs7, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %1 = tail call double asm "fabs.d $0, $1", "=f,{$f31}"(double %a) +- ret double %1 +-} +diff --git a/llvm/test/CodeGen/LoongArch/inline-asm-reg-names.ll b/llvm/test/CodeGen/LoongArch/inline-asm-reg-names.ll +deleted file mode 100644 +index 4bc16e6cc..000000000 +--- a/llvm/test/CodeGen/LoongArch/inline-asm-reg-names.ll ++++ /dev/null +@@ -1,109 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --verify-machineinstrs < %s \ +-; RUN: | FileCheck --check-prefix=LA32 %s +-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s \ +-; RUN: | FileCheck --check-prefix=LA64 %s +- +-;; These test that we can use architectural names ($r*) refer to registers in +-;; inline asm constraint lists. In each case, the named register should be used +-;; for the source register of the `addi.w`. It is very likely that `$a0` will +-;; be chosen as the designation register, but this is left to the compiler to +-;; choose. +-;; +-;; Parenthesised registers in comments are the other aliases for this register. +- +-;; NOTE: This test has to pass in 0 to the inline asm, because that's the only +-;; value `$r0` (`$zero`) can take. +-define i32 @register_r0() nounwind { +-; LA32-LABEL: register_r0: +-; LA32: # %bb.0: +-; LA32-NEXT: #APP +-; LA32-NEXT: addi.w $a0, $zero, 0 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ret +-; +-; LA64-LABEL: register_r0: +-; LA64: # %bb.0: +-; LA64-NEXT: #APP +-; LA64-NEXT: addi.w $a0, $zero, 0 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ret +- %1 = tail call i32 asm "addi.w $0, $1, 0", "=r,{$r0}"(i32 0) +- ret i32 %1 +-} +- +-define i32 @register_r4(i32 %a) nounwind { +-; LA32-LABEL: register_r4: +-; LA32: # %bb.0: +-; LA32-NEXT: #APP +-; LA32-NEXT: addi.w $a0, $a0, 1 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ret +-; +-; LA64-LABEL: register_r4: +-; LA64: # %bb.0: +-; LA64-NEXT: #APP +-; LA64-NEXT: addi.w $a0, $a0, 1 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ret +- %1 = tail call i32 asm "addi.w $0, $1, 1", "=r,{$r4}"(i32 %a) +- ret i32 %1 +-} +- +-;; NOTE: This test uses `$r22` (`$s9`, `$fp`) as an input, so it should be saved. +-define i32 @register_r22(i32 %a) nounwind { +-; LA32-LABEL: register_r22: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $fp, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: move $fp, $a0 +-; LA32-NEXT: #APP +-; LA32-NEXT: addi.w $a0, $fp, 1 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ld.w $fp, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: register_r22: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $fp, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: move $fp, $a0 +-; LA64-NEXT: #APP +-; LA64-NEXT: addi.w $a0, $fp, 1 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ld.d $fp, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %1 = tail call i32 asm "addi.w $0, $1, 1", "=r,{$r22}"(i32 %a) +- ret i32 %1 +-} +- +-;; NOTE: This test uses `$r31` (`$s8`) as an input, so it should be saved. +-define i32 @register_r31(i32 %a) nounwind { +-; LA32-LABEL: register_r31: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $s8, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: move $s8, $a0 +-; LA32-NEXT: #APP +-; LA32-NEXT: addi.w $a0, $s8, 1 +-; LA32-NEXT: #NO_APP +-; LA32-NEXT: ld.w $s8, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: register_r31: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $s8, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: move $s8, $a0 +-; LA64-NEXT: #APP +-; LA64-NEXT: addi.w $a0, $s8, 1 +-; LA64-NEXT: #NO_APP +-; LA64-NEXT: ld.d $s8, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %1 = tail call i32 asm "addi.w $0, $1, 1", "=r,{$r31}"(i32 %a) +- ret i32 %1 +-} +diff --git a/llvm/test/CodeGen/LoongArch/inlineasm/extra-code.ll b/llvm/test/CodeGen/LoongArch/inlineasm/extra-code.ll +new file mode 100644 +index 000000000..986e27e2a +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/inlineasm/extra-code.ll +@@ -0,0 +1,8 @@ ++; RUN: llc -march=loongarch64 -no-integrated-as -o - %s | FileCheck %s ++ ++define i64 @test(i64 %a) { ++; CHECK: add.d $r4, $r4, $r0 ++entry: ++ %0 = tail call i64 asm sideeffect "add.d $0, $1, ${2:z} \0A", "=r,r,Jr"(i64 %a, i64 0) ++ ret i64 %0 ++} +diff --git a/llvm/test/CodeGen/LoongArch/inlineasm/floating-point-in-gpr.ll b/llvm/test/CodeGen/LoongArch/inlineasm/floating-point-in-gpr.ll +new file mode 100644 +index 000000000..94e330673 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/inlineasm/floating-point-in-gpr.ll +@@ -0,0 +1,31 @@ ++; RUN: llc -march=loongarch64 -target-abi=lp64 -o - %s 2>&1 | FileCheck %s ++ ++;; Test that floating-point bits can be stored in GPR. ++ ++define void @reg_float(float %x) { ++; CHECK-LABEL: reg_float: ++; CHECK: movfr2gr.s $r{{[0-9]+}}, $f0 ++ call void asm "", "r"(float %x) ++ ret void ++} ++ ++define void @r10_float(float %x) { ++; CHECK-LABEL: r10_float: ++; CHECK: movfr2gr.s $r10, $f0 ++ call void asm "", "{$r10}"(float %x) ++ ret void ++} ++ ++define void @reg_double(double %x) { ++; CHECK-LABEL: reg_double: ++; CHECK: movfr2gr.d $r{{[0-9]+}}, $f0 ++ call void asm "", "r"(double %x) ++ ret void ++} ++ ++define void @r10_double(double %x) { ++; CHECK-LABEL: r10_double: ++; CHECK: movfr2gr.d $r10, $f0 ++ call void asm "", "{$r10}"(double %x) ++ ret void ++} +diff --git a/llvm/test/CodeGen/LoongArch/inlineasm/non-native-value-type-registers-error.ll b/llvm/test/CodeGen/LoongArch/inlineasm/non-native-value-type-registers-error.ll +new file mode 100644 +index 000000000..7f58ea2ee +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/inlineasm/non-native-value-type-registers-error.ll +@@ -0,0 +1,8 @@ ++; RUN: not llc -march=loongarch64 %s 2>&1 | FileCheck %s ++ ++define void @test_i128() { ++; CHECK: error: couldn't allocate input reg for constraint '{$r20}' ++start: ++ call void asm "", "{$r20}"(i128 5) ++ ret void ++} +diff --git a/llvm/test/CodeGen/LoongArch/inlineasm/non-native-value-type-registers.ll b/llvm/test/CodeGen/LoongArch/inlineasm/non-native-value-type-registers.ll +new file mode 100644 +index 000000000..d18a184ab +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/inlineasm/non-native-value-type-registers.ll +@@ -0,0 +1,42 @@ ++; RUN: llc -march=loongarch64 -o - %s 2>&1 | FileCheck %s ++ ++;; Test that non native value types can be parsed. ++ ++define void @test_i1() { ++; CHECK-LABEL: test_i1: ++; CHECK: ori $r6, $zero, 0 ++; CHECK: jr $ra ++start: ++ call void asm "", "{$r6}"(i1 0) ++ ret void ++} ++ ++;; Note: non-simple values like `i3` are only allowed in newer llvm versions (>= 12). ++;; In older llvm versions (<= 11), SelectionDAGBuilder::visitInlineAsm asserts simple ++;; values must be used. For details, please see https://reviews.llvm.org/D91710. ++define void @test_i3() { ++; CHECK-LABEL: test_i3: ++; CHECK: ori $r7, $zero, 0 ++; CHECK: jr $ra ++start: ++ call void asm "", "{$r7}"(i3 0) ++ ret void ++} ++ ++define void @test_i8() { ++; CHECK-LABEL: test_i8: ++; CHECK: ori $r5, $zero, 0 ++; CHECK: jr $ra ++start: ++ call void asm "", "{$r5}"(i8 0) ++ ret void ++} ++ ++define void @test_i16() { ++; CHECK-LABEL: test_i16: ++; CHECK: ori $r20, $zero, 5 ++; CHECK: jr $ra ++start: ++ call void asm "", "{$r20}"(i16 5) ++ ret void ++} +diff --git a/llvm/test/CodeGen/LoongArch/inlineasm/preld.ll b/llvm/test/CodeGen/LoongArch/inlineasm/preld.ll +new file mode 100644 +index 000000000..8dbbed99f +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/inlineasm/preld.ll +@@ -0,0 +1,8 @@ ++; RUN: llc -march=loongarch64 -o - %s | FileCheck %s ++ ++define void @preld(i32* %p) { ++entry: ++ ; CHECK: preld 10, $r4, 23 ++ tail call void asm sideeffect "preld 10, $0, 23 \0A\09", "r"(i32* %p) ++ ret void ++} +diff --git a/llvm/test/CodeGen/LoongArch/intrinsic-csr-side-effects.ll b/llvm/test/CodeGen/LoongArch/intrinsic-csr-side-effects.ll +deleted file mode 100644 +index e3e23e46b..000000000 +--- a/llvm/test/CodeGen/LoongArch/intrinsic-csr-side-effects.ll ++++ /dev/null +@@ -1,47 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s +- +-declare i32 @llvm.loongarch.csrrd.w(i32 immarg) nounwind +-declare i32 @llvm.loongarch.csrwr.w(i32, i32 immarg) nounwind +-declare void @bug() +- +-define dso_local void @foo(i32 noundef signext %flag) nounwind { +-; CHECK-LABEL: foo: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: beqz $a0, .LBB0_2 +-; CHECK-NEXT: # %bb.1: # %if.then +-; CHECK-NEXT: csrrd $a0, 2 +-; CHECK-NEXT: ori $a0, $a0, 1 +-; CHECK-NEXT: csrwr $a0, 2 +-; CHECK-NEXT: .LBB0_2: # %if.end +-; CHECK-NEXT: csrrd $a0, 2 +-; CHECK-NEXT: andi $a0, $a0, 1 +-; CHECK-NEXT: bnez $a0, .LBB0_4 +-; CHECK-NEXT: # %bb.3: # %if.then2 +-; CHECK-NEXT: b %plt(bug) +-; CHECK-NEXT: .LBB0_4: # %if.end3 +-; CHECK-NEXT: ret +-entry: +- %tobool.not = icmp eq i32 %flag, 0 +- br i1 %tobool.not, label %if.end, label %if.then +- +-if.then: ; preds = %entry +- %0 = tail call i32 @llvm.loongarch.csrrd.w(i32 2) +- %or = or i32 %0, 1 +- %1 = tail call i32 @llvm.loongarch.csrwr.w(i32 %or, i32 2) +- br label %if.end +- +-if.end: ; preds = %if.then, %entry +- %2 = tail call i32 @llvm.loongarch.csrrd.w(i32 2) +- %and = and i32 %2, 1 +- %tobool1.not = icmp eq i32 %and, 0 +- br i1 %tobool1.not, label %if.then2, label %if.end3 +- +-if.then2: ; preds = %if.end +- tail call void @bug() +- br label %if.end3 +- +-if.end3: ; preds = %if.then2, %if.end +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/intrinsic-error.ll b/llvm/test/CodeGen/LoongArch/intrinsic-error.ll +deleted file mode 100644 +index a839ab149..000000000 +--- a/llvm/test/CodeGen/LoongArch/intrinsic-error.ll ++++ /dev/null +@@ -1,154 +0,0 @@ +-; RUN: not llc --mtriple=loongarch32 < %s 2>&1 | FileCheck %s +-; RUN: not llc --mtriple=loongarch64 < %s 2>&1 | FileCheck %s +- +-declare void @llvm.loongarch.dbar(i32) +-declare void @llvm.loongarch.ibar(i32) +-declare void @llvm.loongarch.break(i32) +-declare void @llvm.loongarch.movgr2fcsr(i32, i32) +-declare i32 @llvm.loongarch.movfcsr2gr(i32) +-declare void @llvm.loongarch.syscall(i32) +-declare i32 @llvm.loongarch.csrrd.w(i32 immarg) +-declare i32 @llvm.loongarch.csrwr.w(i32, i32 immarg) +-declare i32 @llvm.loongarch.csrxchg.w(i32, i32, i32 immarg) +- +-define void @dbar_imm_out_of_hi_range() #0 { +-; CHECK: llvm.loongarch.dbar: argument out of range. +-entry: +- call void @llvm.loongarch.dbar(i32 32769) +- ret void +-} +- +-define void @dbar_imm_out_of_lo_range() #0 { +-; CHECK: llvm.loongarch.dbar: argument out of range. +-entry: +- call void @llvm.loongarch.dbar(i32 -1) +- ret void +-} +- +-define void @ibar_imm_out_of_hi_range() #0 { +-; CHECK: llvm.loongarch.ibar: argument out of range. +-entry: +- call void @llvm.loongarch.ibar(i32 32769) +- ret void +-} +- +-define void @ibar_imm_out_of_lo_range() #0 { +-; CHECK: llvm.loongarch.ibar: argument out of range. +-entry: +- call void @llvm.loongarch.ibar(i32 -1) +- ret void +-} +- +-define void @break_imm_out_of_hi_range() #0 { +-; CHECK: llvm.loongarch.break: argument out of range. +-entry: +- call void @llvm.loongarch.break(i32 32769) +- ret void +-} +- +-define void @break_imm_out_of_lo_range() #0 { +-; CHECK: llvm.loongarch.break: argument out of range. +-entry: +- call void @llvm.loongarch.break(i32 -1) +- ret void +-} +- +-define void @movgr2fcsr(i32 %a) nounwind { +-; CHECK: llvm.loongarch.movgr2fcsr: requires basic 'f' target feature. +-entry: +- call void @llvm.loongarch.movgr2fcsr(i32 1, i32 %a) +- ret void +-} +- +-define void @movgr2fcsr_imm_out_of_hi_range(i32 %a) #0 { +-; CHECK: llvm.loongarch.movgr2fcsr: argument out of range. +-entry: +- call void @llvm.loongarch.movgr2fcsr(i32 32, i32 %a) +- ret void +-} +- +-define void @movgr2fcsr_imm_out_of_lo_range(i32 %a) #0 { +-; CHECK: llvm.loongarch.movgr2fcsr: argument out of range. +-entry: +- call void @llvm.loongarch.movgr2fcsr(i32 -1, i32 %a) +- ret void +-} +- +-define i32 @movfcsr2gr() nounwind { +-; CHECK: llvm.loongarch.movfcsr2gr: requires basic 'f' target feature. +-entry: +- %res = call i32 @llvm.loongarch.movfcsr2gr(i32 1) +- ret i32 %res +-} +- +-define i32 @movfcsr2gr_imm_out_of_hi_range() #0 { +-; CHECK: llvm.loongarch.movfcsr2gr: argument out of range. +-entry: +- %res = call i32 @llvm.loongarch.movfcsr2gr(i32 32) +- ret i32 %res +-} +- +-define i32 @movfcsr2gr_imm_out_of_lo_range() #0 { +-; CHECK: llvm.loongarch.movfcsr2gr: argument out of range. +-entry: +- %res = call i32 @llvm.loongarch.movfcsr2gr(i32 -1) +- ret i32 %res +-} +- +-define void @syscall_imm_out_of_hi_range() #0 { +-; CHECK: llvm.loongarch.syscall: argument out of range. +-entry: +- call void @llvm.loongarch.syscall(i32 32769) +- ret void +-} +- +-define void @syscall_imm_out_of_lo_range() #0 { +-; CHECK: llvm.loongarch.syscall: argument out of range. +-entry: +- call void @llvm.loongarch.syscall(i32 -1) +- ret void +-} +- +-define i32 @csrrd_w_imm_out_of_hi_range() #0 { +-; CHECK: llvm.loongarch.csrrd.w: argument out of range. +-entry: +- %0 = call i32 @llvm.loongarch.csrrd.w(i32 16384) +- ret i32 %0 +-} +- +-define i32 @csrrd_w_imm_out_of_lo_range() #0 { +-; CHECK: llvm.loongarch.csrrd.w: argument out of range. +-entry: +- %0 = call i32 @llvm.loongarch.csrrd.w(i32 -1) +- ret i32 %0 +-} +- +-define i32 @csrwr_w_imm_out_of_hi_range(i32 %a) #0 { +-; CHECK: llvm.loongarch.csrwr.w: argument out of range. +-entry: +- %0 = call i32 @llvm.loongarch.csrwr.w(i32 %a, i32 16384) +- ret i32 %0 +-} +- +-define i32 @csrwr_w_imm_out_of_lo_range(i32 %a) #0 { +-; CHECK: llvm.loongarch.csrwr.w: argument out of range. +-entry: +- %0 = call i32 @llvm.loongarch.csrwr.w(i32 %a, i32 -1) +- ret i32 %0 +-} +- +-define i32 @csrxchg_w_imm_out_of_hi_range(i32 %a, i32 %b) #0 { +-; CHECK: llvm.loongarch.csrxchg.w: argument out of range. +-entry: +- %0 = call i32 @llvm.loongarch.csrxchg.w(i32 %a, i32 %b, i32 16384) +- ret i32 %0 +-} +- +-define i32 @csrxchg_w_imm_out_of_lo_range(i32 %a, i32 %b) #0 { +-; CHECK: llvm.loongarch.csrxchg.w: argument out of range. +-entry: +- %0 = call i32 @llvm.loongarch.csrxchg.w(i32 %a, i32 %b, i32 -1) +- ret i32 %0 +-} +- +-attributes #0 = { nounwind "target-features"="+f" } +diff --git a/llvm/test/CodeGen/LoongArch/intrinsic-frecipe-dbl.ll b/llvm/test/CodeGen/LoongArch/intrinsic-frecipe-dbl.ll +index 9f572500c..37e8b7223 100644 +--- a/llvm/test/CodeGen/LoongArch/intrinsic-frecipe-dbl.ll ++++ b/llvm/test/CodeGen/LoongArch/intrinsic-frecipe-dbl.ll +@@ -1,13 +1,13 @@ +-; RUN: llc --mtriple=loongarch32 --mattr=+d,+frecipe < %s | FileCheck %s +-; RUN: llc --mtriple=loongarch64 --mattr=+d,+frecipe < %s | FileCheck %s ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc --mtriple=loongarch64 --mattr=+frecipe < %s | FileCheck %s + + declare double @llvm.loongarch.frecipe.d(double) + + define double @frecipe_d(double %a) { + ; CHECK-LABEL: frecipe_d: + ; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: frecipe.d $fa0, $fa0 +-; CHECK-NEXT: ret ++; CHECK-NEXT: frecipe.d $f0, $f0 ++; CHECK-NEXT: jr $ra + entry: + %res = call double @llvm.loongarch.frecipe.d(double %a) + ret double %res +@@ -18,8 +18,8 @@ declare double @llvm.loongarch.frsqrte.d(double) + define double @frsqrte_d(double %a) { + ; CHECK-LABEL: frsqrte_d: + ; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: frsqrte.d $fa0, $fa0 +-; CHECK-NEXT: ret ++; CHECK-NEXT: frsqrte.d $f0, $f0 ++; CHECK-NEXT: jr $ra + entry: + %res = call double @llvm.loongarch.frsqrte.d(double %a) + ret double %res +diff --git a/llvm/test/CodeGen/LoongArch/intrinsic-frecipe-flt.ll b/llvm/test/CodeGen/LoongArch/intrinsic-frecipe-flt.ll +index 0b2029f2e..d54473980 100644 +--- a/llvm/test/CodeGen/LoongArch/intrinsic-frecipe-flt.ll ++++ b/llvm/test/CodeGen/LoongArch/intrinsic-frecipe-flt.ll +@@ -1,13 +1,13 @@ +-; RUN: llc --mtriple=loongarch32 --mattr=+f,+frecipe < %s | FileCheck %s +-; RUN: llc --mtriple=loongarch64 --mattr=+f,+frecipe < %s | FileCheck %s ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc --mtriple=loongarch64 --mattr=+frecipe < %s | FileCheck %s + + declare float @llvm.loongarch.frecipe.s(float) + + define float @frecipe_s(float %a) { + ; CHECK-LABEL: frecipe_s: + ; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: frecipe.s $fa0, $fa0 +-; CHECK-NEXT: ret ++; CHECK-NEXT: frecipe.s $f0, $f0 ++; CHECK-NEXT: jr $ra + entry: + %res = call float @llvm.loongarch.frecipe.s(float %a) + ret float %res +@@ -18,8 +18,8 @@ declare float @llvm.loongarch.frsqrte.s(float) + define float @frsqrte_s(float %a) { + ; CHECK-LABEL: frsqrte_s: + ; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: frsqrte.s $fa0, $fa0 +-; CHECK-NEXT: ret ++; CHECK-NEXT: frsqrte.s $f0, $f0 ++; CHECK-NEXT: jr $ra + entry: + %res = call float @llvm.loongarch.frsqrte.s(float %a) + ret float %res +diff --git a/llvm/test/CodeGen/LoongArch/intrinsic-iocsr-side-effects.ll b/llvm/test/CodeGen/LoongArch/intrinsic-iocsr-side-effects.ll +deleted file mode 100644 +index ad78f7f53..000000000 +--- a/llvm/test/CodeGen/LoongArch/intrinsic-iocsr-side-effects.ll ++++ /dev/null +@@ -1,180 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s +- +-declare i32 @llvm.loongarch.iocsrrd.b(i32) nounwind +-declare void @llvm.loongarch.iocsrwr.b(i32, i32) nounwind +-declare i32 @llvm.loongarch.iocsrrd.h(i32) nounwind +-declare void @llvm.loongarch.iocsrwr.h(i32, i32) nounwind +-declare i32 @llvm.loongarch.iocsrrd.w(i32) nounwind +-declare void @llvm.loongarch.iocsrwr.w(i32, i32) nounwind +-declare i64 @llvm.loongarch.iocsrrd.d(i32) nounwind +-declare void @llvm.loongarch.iocsrwr.d(i64, i32) nounwind +-declare void @bug() +- +-define dso_local void @test_b(i32 noundef signext %flag) nounwind { +-; CHECK-LABEL: test_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: beqz $a0, .LBB0_2 +-; CHECK-NEXT: # %bb.1: # %if.then +-; CHECK-NEXT: ori $a0, $zero, 2 +-; CHECK-NEXT: iocsrrd.b $a1, $a0 +-; CHECK-NEXT: ori $a1, $a1, 1 +-; CHECK-NEXT: iocsrwr.b $a1, $a0 +-; CHECK-NEXT: .LBB0_2: # %if.end +-; CHECK-NEXT: ori $a0, $zero, 2 +-; CHECK-NEXT: iocsrrd.b $a0, $a0 +-; CHECK-NEXT: andi $a0, $a0, 1 +-; CHECK-NEXT: bnez $a0, .LBB0_4 +-; CHECK-NEXT: # %bb.3: # %if.then2 +-; CHECK-NEXT: b %plt(bug) +-; CHECK-NEXT: .LBB0_4: # %if.end3 +-; CHECK-NEXT: ret +-entry: +- %tobool.not = icmp eq i32 %flag, 0 +- br i1 %tobool.not, label %if.end, label %if.then +- +-if.then: ; preds = %entry +- %0 = tail call i32 @llvm.loongarch.iocsrrd.b(i32 2) +- %or = or i32 %0, 1 +- tail call void @llvm.loongarch.iocsrwr.b(i32 %or, i32 2) +- br label %if.end +- +-if.end: ; preds = %if.then, %entry +- %1 = tail call i32 @llvm.loongarch.iocsrrd.b(i32 2) +- %and = and i32 %1, 1 +- %tobool1.not = icmp eq i32 %and, 0 +- br i1 %tobool1.not, label %if.then2, label %if.end3 +- +-if.then2: ; preds = %if.end +- tail call void @bug() +- br label %if.end3 +- +-if.end3: ; preds = %if.then2, %if.end +- ret void +-} +- +-define dso_local void @test_h(i32 noundef signext %flag) nounwind { +-; CHECK-LABEL: test_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: beqz $a0, .LBB1_2 +-; CHECK-NEXT: # %bb.1: # %if.then +-; CHECK-NEXT: ori $a0, $zero, 2 +-; CHECK-NEXT: iocsrrd.h $a1, $a0 +-; CHECK-NEXT: ori $a1, $a1, 1 +-; CHECK-NEXT: iocsrwr.h $a1, $a0 +-; CHECK-NEXT: .LBB1_2: # %if.end +-; CHECK-NEXT: ori $a0, $zero, 2 +-; CHECK-NEXT: iocsrrd.h $a0, $a0 +-; CHECK-NEXT: andi $a0, $a0, 1 +-; CHECK-NEXT: bnez $a0, .LBB1_4 +-; CHECK-NEXT: # %bb.3: # %if.then2 +-; CHECK-NEXT: b %plt(bug) +-; CHECK-NEXT: .LBB1_4: # %if.end3 +-; CHECK-NEXT: ret +-entry: +- %tobool.not = icmp eq i32 %flag, 0 +- br i1 %tobool.not, label %if.end, label %if.then +- +-if.then: ; preds = %entry +- %0 = tail call i32 @llvm.loongarch.iocsrrd.h(i32 2) +- %or = or i32 %0, 1 +- tail call void @llvm.loongarch.iocsrwr.h(i32 %or, i32 2) +- br label %if.end +- +-if.end: ; preds = %if.then, %entry +- %1 = tail call i32 @llvm.loongarch.iocsrrd.h(i32 2) +- %and = and i32 %1, 1 +- %tobool1.not = icmp eq i32 %and, 0 +- br i1 %tobool1.not, label %if.then2, label %if.end3 +- +-if.then2: ; preds = %if.end +- tail call void @bug() +- br label %if.end3 +- +-if.end3: ; preds = %if.then2, %if.end +- ret void +-} +- +-define dso_local void @test_w(i32 noundef signext %flag) nounwind { +-; CHECK-LABEL: test_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: beqz $a0, .LBB2_2 +-; CHECK-NEXT: # %bb.1: # %if.then +-; CHECK-NEXT: ori $a0, $zero, 2 +-; CHECK-NEXT: iocsrrd.w $a1, $a0 +-; CHECK-NEXT: ori $a1, $a1, 1 +-; CHECK-NEXT: iocsrwr.w $a1, $a0 +-; CHECK-NEXT: .LBB2_2: # %if.end +-; CHECK-NEXT: ori $a0, $zero, 2 +-; CHECK-NEXT: iocsrrd.w $a0, $a0 +-; CHECK-NEXT: andi $a0, $a0, 1 +-; CHECK-NEXT: bnez $a0, .LBB2_4 +-; CHECK-NEXT: # %bb.3: # %if.then2 +-; CHECK-NEXT: b %plt(bug) +-; CHECK-NEXT: .LBB2_4: # %if.end3 +-; CHECK-NEXT: ret +-entry: +- %tobool.not = icmp eq i32 %flag, 0 +- br i1 %tobool.not, label %if.end, label %if.then +- +-if.then: ; preds = %entry +- %0 = tail call i32 @llvm.loongarch.iocsrrd.w(i32 2) +- %or = or i32 %0, 1 +- tail call void @llvm.loongarch.iocsrwr.w(i32 %or, i32 2) +- br label %if.end +- +-if.end: ; preds = %if.then, %entry +- %1 = tail call i32 @llvm.loongarch.iocsrrd.w(i32 2) +- %and = and i32 %1, 1 +- %tobool1.not = icmp eq i32 %and, 0 +- br i1 %tobool1.not, label %if.then2, label %if.end3 +- +-if.then2: ; preds = %if.end +- tail call void @bug() +- br label %if.end3 +- +-if.end3: ; preds = %if.then2, %if.end +- ret void +-} +- +-define dso_local void @test_d(i32 noundef signext %flag) nounwind { +-; CHECK-LABEL: test_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: beqz $a0, .LBB3_2 +-; CHECK-NEXT: # %bb.1: # %if.then +-; CHECK-NEXT: ori $a0, $zero, 2 +-; CHECK-NEXT: iocsrrd.d $a1, $a0 +-; CHECK-NEXT: ori $a1, $a1, 1 +-; CHECK-NEXT: iocsrwr.d $a1, $a0 +-; CHECK-NEXT: .LBB3_2: # %if.end +-; CHECK-NEXT: ori $a0, $zero, 2 +-; CHECK-NEXT: iocsrrd.d $a0, $a0 +-; CHECK-NEXT: andi $a0, $a0, 1 +-; CHECK-NEXT: bnez $a0, .LBB3_4 +-; CHECK-NEXT: # %bb.3: # %if.then2 +-; CHECK-NEXT: b %plt(bug) +-; CHECK-NEXT: .LBB3_4: # %if.end3 +-; CHECK-NEXT: ret +-entry: +- %tobool.not = icmp eq i32 %flag, 0 +- br i1 %tobool.not, label %if.end, label %if.then +- +-if.then: ; preds = %entry +- %0 = tail call i64 @llvm.loongarch.iocsrrd.d(i32 2) +- %or = or i64 %0, 1 +- tail call void @llvm.loongarch.iocsrwr.d(i64 %or, i32 2) +- br label %if.end +- +-if.end: ; preds = %if.then, %entry +- %1 = tail call i64 @llvm.loongarch.iocsrrd.d(i32 2) +- %and = and i64 %1, 1 +- %tobool1.not = icmp eq i64 %and, 0 +- br i1 %tobool1.not, label %if.then2, label %if.end3 +- +-if.then2: ; preds = %if.end +- tail call void @bug() +- br label %if.end3 +- +-if.end3: ; preds = %if.then2, %if.end +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/intrinsic-la32-error.ll b/llvm/test/CodeGen/LoongArch/intrinsic-la32-error.ll +deleted file mode 100644 +index 5302ba558..000000000 +--- a/llvm/test/CodeGen/LoongArch/intrinsic-la32-error.ll ++++ /dev/null +@@ -1,167 +0,0 @@ +-; RUN: not llc --mtriple=loongarch32 < %s 2>&1 | FileCheck %s +- +-declare void @llvm.loongarch.cacop.w(i32, i32, i32) +-declare i32 @llvm.loongarch.crc.w.b.w(i32, i32) +-declare i32 @llvm.loongarch.crc.w.h.w(i32, i32) +-declare i32 @llvm.loongarch.crc.w.w.w(i32, i32) +-declare i32 @llvm.loongarch.crc.w.d.w(i64, i32) +-declare i32 @llvm.loongarch.crcc.w.b.w(i32, i32) +-declare i32 @llvm.loongarch.crcc.w.h.w(i32, i32) +-declare i32 @llvm.loongarch.crcc.w.w.w(i32, i32) +-declare i32 @llvm.loongarch.crcc.w.d.w(i64, i32) +-declare i64 @llvm.loongarch.csrrd.d(i32 immarg) +-declare i64 @llvm.loongarch.csrwr.d(i64, i32 immarg) +-declare i64 @llvm.loongarch.csrxchg.d(i64, i64, i32 immarg) +-declare i64 @llvm.loongarch.iocsrrd.d(i32) +-declare void @llvm.loongarch.iocsrwr.d(i64, i32) +-declare void @llvm.loongarch.asrtle.d(i64, i64) +-declare void @llvm.loongarch.asrtgt.d(i64, i64) +-declare i64 @llvm.loongarch.lddir.d(i64, i64 immarg) +-declare void @llvm.loongarch.ldpte.d(i64, i64 immarg) +- +-define void @cacop_arg0_out_of_hi_range(i32 %a) nounwind { +-; CHECK: llvm.loongarch.cacop.w: argument out of range +-entry: +- call void @llvm.loongarch.cacop.w(i32 32, i32 %a, i32 1024) +- ret void +-} +- +-define void @cacop_arg0_out_of_lo_range(i32 %a) nounwind { +-; CHECK: llvm.loongarch.cacop.w: argument out of range +-entry: +- call void @llvm.loongarch.cacop.w(i32 -1, i32 %a, i32 1024) +- ret void +-} +- +-define void @cacop_arg2_out_of_hi_range(i32 %a) nounwind { +-; CHECK: llvm.loongarch.cacop.w: argument out of range +-entry: +- call void @llvm.loongarch.cacop.w(i32 1, i32 %a, i32 4096) +- ret void +-} +- +-define void @cacop_arg2_out_of_lo_range(i32 %a) nounwind { +-; CHECK: llvm.loongarch.cacop.w: argument out of range +-entry: +- call void @llvm.loongarch.cacop.w(i32 1, i32 %a, i32 -4096) +- ret void +-} +- +-define i32 @crc_w_b_w(i32 %a, i32 %b) nounwind { +-; CHECK: llvm.loongarch.crc.w.b.w: requires loongarch64 +-entry: +- %res = call i32 @llvm.loongarch.crc.w.b.w(i32 %a, i32 %b) +- ret i32 %res +-} +- +-define i32 @crc_w_h_w(i32 %a, i32 %b) nounwind { +-; CHECK: llvm.loongarch.crc.w.h.w: requires loongarch64 +-entry: +- %res = call i32 @llvm.loongarch.crc.w.h.w(i32 %a, i32 %b) +- ret i32 %res +-} +- +-define i32 @crc_w_w_w(i32 %a, i32 %b) nounwind { +-; CHECK: llvm.loongarch.crc.w.w.w: requires loongarch64 +-entry: +- %res = call i32 @llvm.loongarch.crc.w.w.w(i32 %a, i32 %b) +- ret i32 %res +-} +- +-define i32 @crc_w_d_w(i64 %a, i32 %b) nounwind { +-; CHECK: llvm.loongarch.crc.w.d.w: requires loongarch64 +-entry: +- %res = call i32 @llvm.loongarch.crc.w.d.w(i64 %a, i32 %b) +- ret i32 %res +-} +- +-define i32 @crcc_w_b_w(i32 %a, i32 %b) nounwind { +-; CHECK: llvm.loongarch.crcc.w.b.w: requires loongarch64 +-entry: +- %res = call i32 @llvm.loongarch.crcc.w.b.w(i32 %a, i32 %b) +- ret i32 %res +-} +- +-define i32 @crcc_w_h_w(i32 %a, i32 %b) nounwind { +-; CHECK: llvm.loongarch.crcc.w.h.w: requires loongarch64 +-entry: +- %res = call i32 @llvm.loongarch.crcc.w.h.w(i32 %a, i32 %b) +- ret i32 %res +-} +- +-define i32 @crcc_w_w_w(i32 %a, i32 %b) nounwind { +-; CHECK: llvm.loongarch.crcc.w.w.w: requires loongarch64 +-entry: +- %res = call i32 @llvm.loongarch.crcc.w.w.w(i32 %a, i32 %b) +- ret i32 %res +-} +- +-define i32 @crcc_w_d_w(i64 %a, i32 %b) nounwind { +-; CHECK: llvm.loongarch.crcc.w.d.w: requires loongarch64 +-entry: +- %res = call i32 @llvm.loongarch.crcc.w.d.w(i64 %a, i32 %b) +- ret i32 %res +-} +- +-define i64 @csrrd_d() { +-; CHECK: llvm.loongarch.csrrd.d: requires loongarch64 +-entry: +- %0 = tail call i64 @llvm.loongarch.csrrd.d(i32 1) +- ret i64 %0 +-} +- +-define i64 @csrwr_d(i64 %a) { +-; CHECK: llvm.loongarch.csrwr.d: requires loongarch64 +-entry: +- %0 = tail call i64 @llvm.loongarch.csrwr.d(i64 %a, i32 1) +- ret i64 %0 +-} +- +-define i64 @csrxchg_d(i64 %a, i64 %b) { +-; CHECK: llvm.loongarch.csrxchg.d: requires loongarch64 +-entry: +- %0 = tail call i64 @llvm.loongarch.csrxchg.d(i64 %a, i64 %b, i32 1) +- ret i64 %0 +-} +- +-define i64 @iocsrrd_d(i32 %a) { +-; CHECK: llvm.loongarch.iocsrrd.d: requires loongarch64 +-entry: +- %0 = tail call i64 @llvm.loongarch.iocsrrd.d(i32 %a) +- ret i64 %0 +-} +- +-define void @iocsrwr_d(i64 %a, i32 signext %b) { +-; CHECK: llvm.loongarch.iocsrwr.d: requires loongarch64 +-entry: +- tail call void @llvm.loongarch.iocsrwr.d(i64 %a, i32 %b) +- ret void +-} +- +-define void @asrtle_d(i64 %a, i64 %b) { +-; CHECK: llvm.loongarch.asrtle.d: requires loongarch64 +-entry: +- tail call void @llvm.loongarch.asrtle.d(i64 %a, i64 %b) +- ret void +-} +- +-define void @asrtgt_d(i64 %a, i64 %b) { +-; CHECK: llvm.loongarch.asrtgt.d: requires loongarch64 +-entry: +- tail call void @llvm.loongarch.asrtgt.d(i64 %a, i64 %b) +- ret void +-} +- +-define i64 @lddir_d(i64 %a) { +-; CHECK: llvm.loongarch.lddir.d: requires loongarch64 +-entry: +- %0 = tail call i64 @llvm.loongarch.lddir.d(i64 %a, i64 1) +- ret i64 %0 +-} +- +-define void @ldpte_d(i64 %a) { +-; CHECK: llvm.loongarch.ldpte.d: requires loongarch64 +-entry: +- tail call void @llvm.loongarch.ldpte.d(i64 %a, i64 1) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/intrinsic-la32.ll b/llvm/test/CodeGen/LoongArch/intrinsic-la32.ll +deleted file mode 100644 +index 37e090262..000000000 +--- a/llvm/test/CodeGen/LoongArch/intrinsic-la32.ll ++++ /dev/null +@@ -1,13 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s +- +-declare void @llvm.loongarch.cacop.w(i32, i32, i32) +- +-define void @cacop_w(i32 %a) nounwind { +-; CHECK-LABEL: cacop_w: +-; CHECK: # %bb.0: +-; CHECK-NEXT: cacop 1, $a0, 4 +-; CHECK-NEXT: ret +- call void @llvm.loongarch.cacop.w(i32 1, i32 %a, i32 4) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/intrinsic-la64-error.ll b/llvm/test/CodeGen/LoongArch/intrinsic-la64-error.ll +deleted file mode 100644 +index 4716d401d..000000000 +--- a/llvm/test/CodeGen/LoongArch/intrinsic-la64-error.ll ++++ /dev/null +@@ -1,84 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: not llc --mtriple=loongarch64 < %s 2>&1 | FileCheck %s +- +-declare void @llvm.loongarch.cacop.w(i32, i32, i32) +-declare void @llvm.loongarch.cacop.d(i64, i64, i64) +-declare i64 @llvm.loongarch.csrrd.d(i32 immarg) +-declare i64 @llvm.loongarch.csrwr.d(i64, i32 immarg) +-declare i64 @llvm.loongarch.csrxchg.d(i64, i64, i32 immarg) +- +-define i64 @csrrd_d_imm_out_of_hi_range() nounwind { +-; CHECK: llvm.loongarch.csrrd.d: argument out of range +-entry: +- %0 = call i64 @llvm.loongarch.csrrd.d(i32 16384) +- ret i64 %0 +-} +- +-define i64 @csrrd_d_imm_out_of_lo_range() nounwind { +-; CHECK: llvm.loongarch.csrrd.d: argument out of range +-entry: +- %0 = call i64 @llvm.loongarch.csrrd.d(i32 -1) +- ret i64 %0 +-} +- +-define i64 @csrwr_d_imm_out_of_hi_range(i64 %a) nounwind { +-; CHECK: llvm.loongarch.csrwr.d: argument out of range +-entry: +- %0 = call i64 @llvm.loongarch.csrwr.d(i64 %a, i32 16384) +- ret i64 %0 +-} +- +-define i64 @csrwr_d_imm_out_of_lo_range(i64 %a) nounwind { +-; CHECK: llvm.loongarch.csrwr.d: argument out of range +-entry: +- %0 = call i64 @llvm.loongarch.csrwr.d(i64 %a, i32 -1) +- ret i64 %0 +-} +- +-define i64 @csrxchg_d_imm_out_of_hi_range(i64 %a, i64 %b) nounwind { +-; CHECK: llvm.loongarch.csrxchg.d: argument out of range +-entry: +- %0 = call i64 @llvm.loongarch.csrxchg.d(i64 %a, i64 %b, i32 16384) +- ret i64 %0 +-} +- +-define i64 @csrxchg_d_imm_out_of_lo_range(i64 %a, i64 %b) nounwind { +-; CHECK: llvm.loongarch.csrxchg.d: argument out of range +-entry: +- %0 = call i64 @llvm.loongarch.csrxchg.d(i64 %a, i64 %b, i32 -1) +- ret i64 %0 +-} +- +-define void @cacop_w(i32 %a) nounwind { +-; CHECK: llvm.loongarch.cacop.w: requires loongarch32 +- call void @llvm.loongarch.cacop.w(i32 1, i32 %a, i32 4) +- ret void +-} +- +-define void @cacop_arg0_out_of_hi_range(i64 %a) nounwind { +-; CHECK: llvm.loongarch.cacop.d: argument out of range +-entry: +- call void @llvm.loongarch.cacop.d(i64 32, i64 %a, i64 1024) +- ret void +-} +- +-define void @cacop_arg0_out_of_lo_range(i64 %a) nounwind { +-; CHECK: llvm.loongarch.cacop.d: argument out of range +-entry: +- call void @llvm.loongarch.cacop.d(i64 -1, i64 %a, i64 1024) +- ret void +-} +- +-define void @cacop_arg2_out_of_hi_range(i64 %a) nounwind { +-; CHECK: llvm.loongarch.cacop.d: argument out of range +-entry: +- call void @llvm.loongarch.cacop.d(i64 1, i64 %a, i64 4096) +- ret void +-} +- +-define void @cacop_arg2_out_of_lo_range(i64 %a) nounwind { +-; CHECK: llvm.loongarch.cacop.d: argument out of range +-entry: +- call void @llvm.loongarch.cacop.d(i64 1, i64 %a, i64 -4096) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/intrinsic-la64.ll b/llvm/test/CodeGen/LoongArch/intrinsic-la64.ll +deleted file mode 100644 +index f0ebd8508..000000000 +--- a/llvm/test/CodeGen/LoongArch/intrinsic-la64.ll ++++ /dev/null +@@ -1,308 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s +- +-declare void @llvm.loongarch.cacop.d(i64, i64, i64) +-declare i32 @llvm.loongarch.crc.w.b.w(i32, i32) +-declare i32 @llvm.loongarch.crc.w.h.w(i32, i32) +-declare i32 @llvm.loongarch.crc.w.w.w(i32, i32) +-declare i32 @llvm.loongarch.crc.w.d.w(i64, i32) +-declare i32 @llvm.loongarch.crcc.w.b.w(i32, i32) +-declare i32 @llvm.loongarch.crcc.w.h.w(i32, i32) +-declare i32 @llvm.loongarch.crcc.w.w.w(i32, i32) +-declare i32 @llvm.loongarch.crcc.w.d.w(i64, i32) +-declare i64 @llvm.loongarch.csrrd.d(i32 immarg) +-declare i64 @llvm.loongarch.csrwr.d(i64, i32 immarg) +-declare i64 @llvm.loongarch.csrxchg.d(i64, i64, i32 immarg) +-declare i64 @llvm.loongarch.iocsrrd.d(i32) +-declare void @llvm.loongarch.iocsrwr.d(i64, i32) +-declare void @llvm.loongarch.asrtle.d(i64, i64) +-declare void @llvm.loongarch.asrtgt.d(i64, i64) +-declare i64 @llvm.loongarch.lddir.d(i64, i64) +-declare void @llvm.loongarch.ldpte.d(i64, i64) +- +-define i32 @crc_w_b_w(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: crc_w_b_w: +-; CHECK: # %bb.0: +-; CHECK-NEXT: crc.w.b.w $a0, $a0, $a1 +-; CHECK-NEXT: ret +- %res = call i32 @llvm.loongarch.crc.w.b.w(i32 %a, i32 %b) +- ret i32 %res +-} +- +-define void @crc_w_b_w_noret(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: crc_w_b_w_noret: +-; CHECK: # %bb.0: +-; CHECK-NEXT: ret +- %res = call i32 @llvm.loongarch.crc.w.b.w(i32 %a, i32 %b) +- ret void +-} +- +-define i32 @crc_w_h_w(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: crc_w_h_w: +-; CHECK: # %bb.0: +-; CHECK-NEXT: crc.w.h.w $a0, $a0, $a1 +-; CHECK-NEXT: ret +- %res = call i32 @llvm.loongarch.crc.w.h.w(i32 %a, i32 %b) +- ret i32 %res +-} +- +-define void @crc_w_h_w_noret(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: crc_w_h_w_noret: +-; CHECK: # %bb.0: +-; CHECK-NEXT: ret +- %res = call i32 @llvm.loongarch.crc.w.h.w(i32 %a, i32 %b) +- ret void +-} +- +-define i32 @crc_w_w_w(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: crc_w_w_w: +-; CHECK: # %bb.0: +-; CHECK-NEXT: crc.w.w.w $a0, $a0, $a1 +-; CHECK-NEXT: ret +- %res = call i32 @llvm.loongarch.crc.w.w.w(i32 %a, i32 %b) +- ret i32 %res +-} +- +-define void @crc_w_w_w_noret(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: crc_w_w_w_noret: +-; CHECK: # %bb.0: +-; CHECK-NEXT: ret +- %res = call i32 @llvm.loongarch.crc.w.w.w(i32 %a, i32 %b) +- ret void +-} +- +-define void @cacop_d(i64 %a) nounwind { +-; CHECK-LABEL: cacop_d: +-; CHECK: # %bb.0: +-; CHECK-NEXT: cacop 1, $a0, 4 +-; CHECK-NEXT: ret +- call void @llvm.loongarch.cacop.d(i64 1, i64 %a, i64 4) +- ret void +-} +- +-define i32 @crc_w_d_w(i64 %a, i32 %b) nounwind { +-; CHECK-LABEL: crc_w_d_w: +-; CHECK: # %bb.0: +-; CHECK-NEXT: crc.w.d.w $a0, $a0, $a1 +-; CHECK-NEXT: ret +- %res = call i32 @llvm.loongarch.crc.w.d.w(i64 %a, i32 %b) +- ret i32 %res +-} +- +-define void @crc_w_d_w_noret(i64 %a, i32 %b) nounwind { +-; CHECK-LABEL: crc_w_d_w_noret: +-; CHECK: # %bb.0: +-; CHECK-NEXT: ret +- %res = call i32 @llvm.loongarch.crc.w.d.w(i64 %a, i32 %b) +- ret void +-} +- +-define i32 @crcc_w_b_w(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: crcc_w_b_w: +-; CHECK: # %bb.0: +-; CHECK-NEXT: crcc.w.b.w $a0, $a0, $a1 +-; CHECK-NEXT: ret +- %res = call i32 @llvm.loongarch.crcc.w.b.w(i32 %a, i32 %b) +- ret i32 %res +-} +- +-define void @crcc_w_b_w_noret(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: crcc_w_b_w_noret: +-; CHECK: # %bb.0: +-; CHECK-NEXT: ret +- %res = call i32 @llvm.loongarch.crcc.w.b.w(i32 %a, i32 %b) +- ret void +-} +- +-define i32 @crcc_w_h_w(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: crcc_w_h_w: +-; CHECK: # %bb.0: +-; CHECK-NEXT: crcc.w.h.w $a0, $a0, $a1 +-; CHECK-NEXT: ret +- %res = call i32 @llvm.loongarch.crcc.w.h.w(i32 %a, i32 %b) +- ret i32 %res +-} +- +-define void @crcc_w_h_w_noret(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: crcc_w_h_w_noret: +-; CHECK: # %bb.0: +-; CHECK-NEXT: ret +- %res = call i32 @llvm.loongarch.crcc.w.h.w(i32 %a, i32 %b) +- ret void +-} +- +-define i32 @crcc_w_w_w(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: crcc_w_w_w: +-; CHECK: # %bb.0: +-; CHECK-NEXT: crcc.w.w.w $a0, $a0, $a1 +-; CHECK-NEXT: ret +- %res = call i32 @llvm.loongarch.crcc.w.w.w(i32 %a, i32 %b) +- ret i32 %res +-} +- +-define void @crcc_w_w_w_noret(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: crcc_w_w_w_noret: +-; CHECK: # %bb.0: +-; CHECK-NEXT: ret +- %res = call i32 @llvm.loongarch.crcc.w.w.w(i32 %a, i32 %b) +- ret void +-} +- +-define i32 @crcc_w_d_w(i64 %a, i32 %b) nounwind { +-; CHECK-LABEL: crcc_w_d_w: +-; CHECK: # %bb.0: +-; CHECK-NEXT: crcc.w.d.w $a0, $a0, $a1 +-; CHECK-NEXT: ret +- %res = call i32 @llvm.loongarch.crcc.w.d.w(i64 %a, i32 %b) +- ret i32 %res +-} +- +-define void @crcc_w_d_w_noret(i64 %a, i32 %b) nounwind { +-; CHECK-LABEL: crcc_w_d_w_noret: +-; CHECK: # %bb.0: +-; CHECK-NEXT: ret +- %res = call i32 @llvm.loongarch.crcc.w.d.w(i64 %a, i32 %b) +- ret void +-} +- +-define i64 @csrrd_d() { +-; CHECK-LABEL: csrrd_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: csrrd $a0, 1 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i64 @llvm.loongarch.csrrd.d(i32 1) +- ret i64 %0 +-} +- +-define void @csrrd_d_noret() { +-; CHECK-LABEL: csrrd_d_noret: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: csrrd $a0, 1 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i64 @llvm.loongarch.csrrd.d(i32 1) +- ret void +-} +- +-define i64 @csrwr_d(i64 %a) { +-; CHECK-LABEL: csrwr_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: csrwr $a0, 1 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i64 @llvm.loongarch.csrwr.d(i64 %a, i32 1) +- ret i64 %0 +-} +- +-;; Check that csrwr is emitted even if the return value of the intrinsic is not used. +-define void @csrwr_d_noret(i64 %a) { +-; CHECK-LABEL: csrwr_d_noret: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: csrwr $a0, 1 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i64 @llvm.loongarch.csrwr.d(i64 %a, i32 1) +- ret void +-} +- +-define i64 @csrxchg_d(i64 %a, i64 %b) { +-; CHECK-LABEL: csrxchg_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: csrxchg $a0, $a1, 1 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i64 @llvm.loongarch.csrxchg.d(i64 %a, i64 %b, i32 1) +- ret i64 %0 +-} +- +-;; Check that csrxchg is emitted even if the return value of the intrinsic is not used. +-define void @csrxchg_d_noret(i64 %a, i64 %b) { +-; CHECK-LABEL: csrxchg_d_noret: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: csrxchg $a0, $a1, 1 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i64 @llvm.loongarch.csrxchg.d(i64 %a, i64 %b, i32 1) +- ret void +-} +- +-define i64 @iocsrrd_d(i32 %a) { +-; CHECK-LABEL: iocsrrd_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: iocsrrd.d $a0, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i64 @llvm.loongarch.iocsrrd.d(i32 %a) +- ret i64 %0 +-} +- +-define void @iocsrrd_d_noret(i32 %a) { +-; CHECK-LABEL: iocsrrd_d_noret: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: iocsrrd.d $a0, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i64 @llvm.loongarch.iocsrrd.d(i32 %a) +- ret void +-} +- +-define void @iocsrwr_d(i64 %a, i32 signext %b) { +-; CHECK-LABEL: iocsrwr_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: iocsrwr.d $a0, $a1 +-; CHECK-NEXT: ret +-entry: +- tail call void @llvm.loongarch.iocsrwr.d(i64 %a, i32 %b) +- ret void +-} +- +-define void @asrtle_d(i64 %a, i64 %b) { +-; CHECK-LABEL: asrtle_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: asrtle.d $a0, $a1 +-; CHECK-NEXT: ret +-entry: +- tail call void @llvm.loongarch.asrtle.d(i64 %a, i64 %b) +- ret void +-} +- +-define void @asrtgt_d(i64 %a, i64 %b) { +-; CHECK-LABEL: asrtgt_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: asrtgt.d $a0, $a1 +-; CHECK-NEXT: ret +-entry: +- tail call void @llvm.loongarch.asrtgt.d(i64 %a, i64 %b) +- ret void +-} +- +-define i64 @lddir_d(i64 %a) { +-; CHECK-LABEL: lddir_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: lddir $a0, $a0, 1 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i64 @llvm.loongarch.lddir.d(i64 %a, i64 1) +- ret i64 %0 +-} +- +-define void @lddir_d_noret(i64 %a) { +-; CHECK-LABEL: lddir_d_noret: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: lddir $a0, $a0, 1 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i64 @llvm.loongarch.lddir.d(i64 %a, i64 1) +- ret void +-} +- +-define void @ldpte_d(i64 %a) { +-; CHECK-LABEL: ldpte_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: ldpte $a0, 1 +-; CHECK-NEXT: ret +-entry: +- tail call void @llvm.loongarch.ldpte.d(i64 %a, i64 1) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/intrinsic-not-constant-error.ll b/llvm/test/CodeGen/LoongArch/intrinsic-not-constant-error.ll +deleted file mode 100644 +index 9cb89670c..000000000 +--- a/llvm/test/CodeGen/LoongArch/intrinsic-not-constant-error.ll ++++ /dev/null +@@ -1,51 +0,0 @@ +-; RUN: not llc --mtriple=loongarch32 < %s 2>&1 | FileCheck %s +-; RUN: not llc --mtriple=loongarch64 < %s 2>&1 | FileCheck %s +- +-declare void @llvm.loongarch.dbar(i32) +-declare void @llvm.loongarch.ibar(i32) +-declare void @llvm.loongarch.break(i32) +-declare void @llvm.loongarch.movgr2fcsr(i32, i32) +-declare i32 @llvm.loongarch.movfcsr2gr(i32) +-declare void @llvm.loongarch.syscall(i32) +- +-define void @dbar_not_constant(i32 %x) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.dbar(i32 %x) +- ret void +-} +- +-define void @ibar(i32 %x) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.ibar(i32 %x) +- ret void +-} +- +-define void @break(i32 %x) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.break(i32 %x) +- ret void +-} +- +-define void @movgr2fcsr(i32 %a) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.movgr2fcsr(i32 %a, i32 %a) +- ret void +-} +- +-define i32 @movfcsr2gr(i32 %a) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call i32 @llvm.loongarch.movfcsr2gr(i32 %a) +- ret i32 %res +-} +- +-define void @syscall(i32 %x) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.syscall(i32 %x) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/intrinsic.ll b/llvm/test/CodeGen/LoongArch/intrinsic.ll +deleted file mode 100644 +index f49a2500a..000000000 +--- a/llvm/test/CodeGen/LoongArch/intrinsic.ll ++++ /dev/null +@@ -1,262 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+f --verify-machineinstrs < %s | FileCheck %s +-; RUN: llc --mtriple=loongarch64 --mattr=+f --verify-machineinstrs < %s | FileCheck %s +- +-declare void @llvm.loongarch.dbar(i32) +-declare void @llvm.loongarch.ibar(i32) +-declare void @llvm.loongarch.break(i32) +-declare void @llvm.loongarch.movgr2fcsr(i32, i32) +-declare i32 @llvm.loongarch.movfcsr2gr(i32) +-declare void @llvm.loongarch.syscall(i32) +-declare i32 @llvm.loongarch.csrrd.w(i32 immarg) +-declare i32 @llvm.loongarch.csrwr.w(i32, i32 immarg) +-declare i32 @llvm.loongarch.csrxchg.w(i32, i32, i32 immarg) +-declare i32 @llvm.loongarch.iocsrrd.b(i32) +-declare i32 @llvm.loongarch.iocsrrd.h(i32) +-declare i32 @llvm.loongarch.iocsrrd.w(i32) +-declare void @llvm.loongarch.iocsrwr.b(i32, i32) +-declare void @llvm.loongarch.iocsrwr.h(i32, i32) +-declare void @llvm.loongarch.iocsrwr.w(i32, i32) +-declare i32 @llvm.loongarch.cpucfg(i32) +- +-define void @foo() nounwind { +-; CHECK-LABEL: foo: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: dbar 0 +-; CHECK-NEXT: ret +-entry: +- call void @llvm.loongarch.dbar(i32 0) +- ret void +-} +- +-define void @ibar() nounwind { +-; CHECK-LABEL: ibar: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: ibar 0 +-; CHECK-NEXT: ret +-entry: +- call void @llvm.loongarch.ibar(i32 0) +- ret void +-} +- +-define void @break() nounwind { +-; CHECK-LABEL: break: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: break 1 +-; CHECK-NEXT: ret +-entry: +- call void @llvm.loongarch.break(i32 1) +- ret void +-} +- +-define void @movgr2fcsr(i32 %a) nounwind { +-; CHECK-LABEL: movgr2fcsr: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: movgr2fcsr $fcsr1, $a0 +-; CHECK-NEXT: ret +-entry: +- call void @llvm.loongarch.movgr2fcsr(i32 1, i32 %a) +- ret void +-} +- +-define i32 @movfcsr2gr() nounwind { +-; CHECK-LABEL: movfcsr2gr: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: movfcsr2gr $a0, $fcsr1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.movfcsr2gr(i32 1) +- ret i32 %res +-} +- +-;; TODO: Optimize out `movfcsr2gr` without data-dependency. +-define void @movfcsr2gr_noret() nounwind { +-; CHECK-LABEL: movfcsr2gr_noret: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: movfcsr2gr $a0, $fcsr1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.movfcsr2gr(i32 1) +- ret void +-} +- +-define void @syscall() nounwind { +-; CHECK-LABEL: syscall: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: syscall 1 +-; CHECK-NEXT: ret +-entry: +- call void @llvm.loongarch.syscall(i32 1) +- ret void +-} +- +-define i32 @csrrd_w() { +-; CHECK-LABEL: csrrd_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: csrrd $a0, 1 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i32 @llvm.loongarch.csrrd.w(i32 1) +- ret i32 %0 +-} +- +-define void @csrrd_w_noret() { +-; CHECK-LABEL: csrrd_w_noret: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: csrrd $a0, 1 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i32 @llvm.loongarch.csrrd.w(i32 1) +- ret void +-} +- +-define i32 @csrwr_w(i32 signext %a) { +-; CHECK-LABEL: csrwr_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: csrwr $a0, 1 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i32 @llvm.loongarch.csrwr.w(i32 %a, i32 1) +- ret i32 %0 +-} +- +-;; Check that csrwr is emitted even if the return value of the intrinsic is not used. +-define void @csrwr_w_noret(i32 signext %a) { +-; CHECK-LABEL: csrwr_w_noret: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: csrwr $a0, 1 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i32 @llvm.loongarch.csrwr.w(i32 %a, i32 1) +- ret void +-} +- +-define i32 @csrxchg_w(i32 signext %a, i32 signext %b) { +-; CHECK-LABEL: csrxchg_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: csrxchg $a0, $a1, 1 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i32 @llvm.loongarch.csrxchg.w(i32 %a, i32 %b, i32 1) +- ret i32 %0 +-} +- +-;; Check that csrxchg is emitted even if the return value of the intrinsic is not used. +-define void @csrxchg_w_noret(i32 signext %a, i32 signext %b) { +-; CHECK-LABEL: csrxchg_w_noret: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: csrxchg $a0, $a1, 1 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i32 @llvm.loongarch.csrxchg.w(i32 %a, i32 %b, i32 1) +- ret void +-} +- +-define i32 @iocsrrd_b(i32 %a) { +-; CHECK-LABEL: iocsrrd_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: iocsrrd.b $a0, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i32 @llvm.loongarch.iocsrrd.b(i32 %a) +- ret i32 %0 +-} +- +-define i32 @iocsrrd_h(i32 %a) { +-; CHECK-LABEL: iocsrrd_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: iocsrrd.h $a0, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i32 @llvm.loongarch.iocsrrd.h(i32 %a) +- ret i32 %0 +-} +- +-define i32 @iocsrrd_w(i32 %a) { +-; CHECK-LABEL: iocsrrd_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: iocsrrd.w $a0, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i32 @llvm.loongarch.iocsrrd.w(i32 %a) +- ret i32 %0 +-} +- +-define void @iocsrrd_b_noret(i32 %a) { +-; CHECK-LABEL: iocsrrd_b_noret: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: iocsrrd.b $a0, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i32 @llvm.loongarch.iocsrrd.b(i32 %a) +- ret void +-} +- +-define void @iocsrrd_h_noret(i32 %a) { +-; CHECK-LABEL: iocsrrd_h_noret: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: iocsrrd.h $a0, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i32 @llvm.loongarch.iocsrrd.h(i32 %a) +- ret void +-} +- +-define void @iocsrrd_w_noret(i32 %a) { +-; CHECK-LABEL: iocsrrd_w_noret: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: iocsrrd.w $a0, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i32 @llvm.loongarch.iocsrrd.w(i32 %a) +- ret void +-} +- +-define void @iocsrwr_b(i32 %a, i32 %b) { +-; CHECK-LABEL: iocsrwr_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: iocsrwr.b $a0, $a1 +-; CHECK-NEXT: ret +-entry: +- tail call void @llvm.loongarch.iocsrwr.b(i32 %a, i32 %b) +- ret void +-} +- +-define void @iocsrwr_h(i32 %a, i32 %b) { +-; CHECK-LABEL: iocsrwr_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: iocsrwr.h $a0, $a1 +-; CHECK-NEXT: ret +-entry: +- tail call void @llvm.loongarch.iocsrwr.h(i32 %a, i32 %b) +- ret void +-} +- +-define void @iocsrwr_w(i32 %a, i32 %b) { +-; CHECK-LABEL: iocsrwr_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: iocsrwr.w $a0, $a1 +-; CHECK-NEXT: ret +-entry: +- tail call void @llvm.loongarch.iocsrwr.w(i32 %a, i32 %b) +- ret void +-} +- +-define i32 @cpucfg(i32 %a) { +-; CHECK-LABEL: cpucfg: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: cpucfg $a0, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i32 @llvm.loongarch.cpucfg(i32 %a) +- ret i32 %0 +-} +- +-define void @cpucfg_noret(i32 %a) { +-; CHECK-LABEL: cpucfg_noret: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i32 @llvm.loongarch.cpucfg(i32 %a) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/add.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/add.ll +deleted file mode 100644 +index 2c504efca..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/add.ll ++++ /dev/null +@@ -1,918 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-;; Exercise the 'add' LLVM IR: https://llvm.org/docs/LangRef.html#add-instruction +- +-define i1 @add_i1(i1 %x, i1 %y) { +-; LA32-LABEL: add_i1: +-; LA32: # %bb.0: +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i1: +-; LA64: # %bb.0: +-; LA64-NEXT: add.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %add = add i1 %x, %y +- ret i1 %add +-} +- +-define i8 @add_i8(i8 %x, i8 %y) { +-; LA32-LABEL: add_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: add.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %add = add i8 %x, %y +- ret i8 %add +-} +- +-define i16 @add_i16(i16 %x, i16 %y) { +-; LA32-LABEL: add_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: add.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %add = add i16 %x, %y +- ret i16 %add +-} +- +-define i32 @add_i32(i32 %x, i32 %y) { +-; LA32-LABEL: add_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: add.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %add = add i32 %x, %y +- ret i32 %add +-} +- +-;; Match the pattern: +-;; def : PatGprGpr_32; +-define signext i32 @add_i32_sext(i32 %x, i32 %y) { +-; LA32-LABEL: add_i32_sext: +-; LA32: # %bb.0: +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_sext: +-; LA64: # %bb.0: +-; LA64-NEXT: add.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %add = add i32 %x, %y +- ret i32 %add +-} +- +-define i64 @add_i64(i64 %x, i64 %y) { +-; LA32-LABEL: add_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: add.w $a1, $a1, $a3 +-; LA32-NEXT: add.w $a2, $a0, $a2 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: add.w $a1, $a1, $a0 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: add.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %add = add i64 %x, %y +- ret i64 %add +-} +- +-define i1 @add_i1_3(i1 %x) { +-; LA32-LABEL: add_i1_3: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i1_3: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $a0, $a0, 1 +-; LA64-NEXT: ret +- %add = add i1 %x, 3 +- ret i1 %add +-} +- +-define i8 @add_i8_3(i8 %x) { +-; LA32-LABEL: add_i8_3: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i8_3: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $a0, $a0, 3 +-; LA64-NEXT: ret +- %add = add i8 %x, 3 +- ret i8 %add +-} +- +-define i16 @add_i16_3(i16 %x) { +-; LA32-LABEL: add_i16_3: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i16_3: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $a0, $a0, 3 +-; LA64-NEXT: ret +- %add = add i16 %x, 3 +- ret i16 %add +-} +- +-define i32 @add_i32_3(i32 %x) { +-; LA32-LABEL: add_i32_3: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_3: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $a0, $a0, 3 +-; LA64-NEXT: ret +- %add = add i32 %x, 3 +- ret i32 %add +-} +- +-;; Match the pattern: +-;; def : PatGprImm_32; +-define signext i32 @add_i32_3_sext(i32 %x) { +-; LA32-LABEL: add_i32_3_sext: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_3_sext: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.w $a0, $a0, 3 +-; LA64-NEXT: ret +- %add = add i32 %x, 3 +- ret i32 %add +-} +- +-define i64 @add_i64_3(i64 %x) { +-; LA32-LABEL: add_i64_3: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a2, $a0, 3 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: add.w $a1, $a1, $a0 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i64_3: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $a0, $a0, 3 +-; LA64-NEXT: ret +- %add = add i64 %x, 3 +- ret i64 %add +-} +- +-;; Check that `addu16i.d` is emitted for these cases. +- +-define i32 @add_i32_0x12340000(i32 %x) { +-; LA32-LABEL: add_i32_0x12340000: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 74560 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_0x12340000: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, 4660 +-; LA64-NEXT: ret +- %add = add i32 %x, 305397760 +- ret i32 %add +-} +- +-define signext i32 @add_i32_0x12340000_sext(i32 %x) { +-; LA32-LABEL: add_i32_0x12340000_sext: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 74560 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_0x12340000_sext: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, 4660 +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: ret +- %add = add i32 %x, 305397760 +- ret i32 %add +-} +- +-define i64 @add_i64_0x12340000(i64 %x) { +-; LA32-LABEL: add_i64_0x12340000: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 74560 +-; LA32-NEXT: add.w $a2, $a0, $a2 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: add.w $a1, $a1, $a0 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i64_0x12340000: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, 4660 +-; LA64-NEXT: ret +- %add = add i64 %x, 305397760 +- ret i64 %add +-} +- +-define i32 @add_i32_0x7fff0000(i32 %x) { +-; LA32-LABEL: add_i32_0x7fff0000: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 524272 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_0x7fff0000: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, 32767 +-; LA64-NEXT: ret +- %add = add i32 %x, 2147418112 +- ret i32 %add +-} +- +-define signext i32 @add_i32_0x7fff0000_sext(i32 %x) { +-; LA32-LABEL: add_i32_0x7fff0000_sext: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 524272 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_0x7fff0000_sext: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, 32767 +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: ret +- %add = add i32 %x, 2147418112 +- ret i32 %add +-} +- +-define i64 @add_i64_0x7fff0000(i64 %x) { +-; LA32-LABEL: add_i64_0x7fff0000: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 524272 +-; LA32-NEXT: add.w $a2, $a0, $a2 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: add.w $a1, $a1, $a0 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i64_0x7fff0000: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, 32767 +-; LA64-NEXT: ret +- %add = add i64 %x, 2147418112 +- ret i64 %add +-} +- +-define i32 @add_i32_minus_0x80000000(i32 %x) { +-; LA32-LABEL: add_i32_minus_0x80000000: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, -524288 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_minus_0x80000000: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, -32768 +-; LA64-NEXT: ret +- %add = add i32 %x, -2147483648 +- ret i32 %add +-} +- +-define signext i32 @add_i32_minus_0x80000000_sext(i32 %x) { +-; LA32-LABEL: add_i32_minus_0x80000000_sext: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, -524288 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_minus_0x80000000_sext: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, -32768 +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: ret +- %add = add i32 %x, -2147483648 +- ret i32 %add +-} +- +-define i64 @add_i64_minus_0x80000000(i64 %x) { +-; LA32-LABEL: add_i64_minus_0x80000000: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, -524288 +-; LA32-NEXT: add.w $a2, $a0, $a2 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: add.w $a0, $a1, $a0 +-; LA32-NEXT: addi.w $a1, $a0, -1 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i64_minus_0x80000000: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, -32768 +-; LA64-NEXT: ret +- %add = add i64 %x, -2147483648 +- ret i64 %add +-} +- +-define i32 @add_i32_minus_0x10000(i32 %x) { +-; LA32-LABEL: add_i32_minus_0x10000: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, -16 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_minus_0x10000: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, -1 +-; LA64-NEXT: ret +- %add = add i32 %x, -65536 +- ret i32 %add +-} +- +-define signext i32 @add_i32_minus_0x10000_sext(i32 %x) { +-; LA32-LABEL: add_i32_minus_0x10000_sext: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, -16 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_minus_0x10000_sext: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, -1 +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: ret +- %add = add i32 %x, -65536 +- ret i32 %add +-} +- +-define i64 @add_i64_minus_0x10000(i64 %x) { +-; LA32-LABEL: add_i64_minus_0x10000: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, -16 +-; LA32-NEXT: add.w $a2, $a0, $a2 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: add.w $a0, $a1, $a0 +-; LA32-NEXT: addi.w $a1, $a0, -1 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i64_minus_0x10000: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, -1 +-; LA64-NEXT: ret +- %add = add i64 %x, -65536 +- ret i64 %add +-} +- +-;; Check that `addu16i.d + addi` is emitted for these cases. +- +-define i32 @add_i32_0x7fff07ff(i32 %x) { +-; LA32-LABEL: add_i32_0x7fff07ff: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 524272 +-; LA32-NEXT: ori $a1, $a1, 2047 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_0x7fff07ff: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, 32767 +-; LA64-NEXT: addi.d $a0, $a0, 2047 +-; LA64-NEXT: ret +- %add = add i32 %x, 2147420159 +- ret i32 %add +-} +- +-define signext i32 @add_i32_0x7fff07ff_sext(i32 %x) { +-; LA32-LABEL: add_i32_0x7fff07ff_sext: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 524272 +-; LA32-NEXT: ori $a1, $a1, 2047 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_0x7fff07ff_sext: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, 32767 +-; LA64-NEXT: addi.w $a0, $a0, 2047 +-; LA64-NEXT: ret +- %add = add i32 %x, 2147420159 +- ret i32 %add +-} +- +-define i64 @add_i64_0x7fff07ff(i64 %x) { +-; LA32-LABEL: add_i64_0x7fff07ff: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 524272 +-; LA32-NEXT: ori $a2, $a2, 2047 +-; LA32-NEXT: add.w $a2, $a0, $a2 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: add.w $a1, $a1, $a0 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i64_0x7fff07ff: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, 32767 +-; LA64-NEXT: addi.d $a0, $a0, 2047 +-; LA64-NEXT: ret +- %add = add i64 %x, 2147420159 +- ret i64 %add +-} +- +-define i32 @add_i32_0x7ffef800(i32 %x) { +-; LA32-LABEL: add_i32_0x7ffef800: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 524271 +-; LA32-NEXT: ori $a1, $a1, 2048 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_0x7ffef800: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, 32767 +-; LA64-NEXT: addi.d $a0, $a0, -2048 +-; LA64-NEXT: ret +- %add = add i32 %x, 2147416064 +- ret i32 %add +-} +- +-define signext i32 @add_i32_0x7ffef800_sext(i32 %x) { +-; LA32-LABEL: add_i32_0x7ffef800_sext: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 524271 +-; LA32-NEXT: ori $a1, $a1, 2048 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_0x7ffef800_sext: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, 32767 +-; LA64-NEXT: addi.w $a0, $a0, -2048 +-; LA64-NEXT: ret +- %add = add i32 %x, 2147416064 +- ret i32 %add +-} +- +-define i64 @add_i64_0x7ffef800(i64 %x) { +-; LA32-LABEL: add_i64_0x7ffef800: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 524271 +-; LA32-NEXT: ori $a2, $a2, 2048 +-; LA32-NEXT: add.w $a2, $a0, $a2 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: add.w $a1, $a1, $a0 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i64_0x7ffef800: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, 32767 +-; LA64-NEXT: addi.d $a0, $a0, -2048 +-; LA64-NEXT: ret +- %add = add i64 %x, 2147416064 +- ret i64 %add +-} +- +-define i64 @add_i64_minus_0x80000800(i64 %x) { +-; LA32-LABEL: add_i64_minus_0x80000800: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 524287 +-; LA32-NEXT: ori $a2, $a2, 2048 +-; LA32-NEXT: add.w $a2, $a0, $a2 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: add.w $a0, $a1, $a0 +-; LA32-NEXT: addi.w $a1, $a0, -1 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i64_minus_0x80000800: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, -32768 +-; LA64-NEXT: addi.d $a0, $a0, -2048 +-; LA64-NEXT: ret +- %add = add i64 %x, -2147485696 +- ret i64 %add +-} +- +-define i32 @add_i32_minus_0x23450679(i32 %x) { +-; LA32-LABEL: add_i32_minus_0x23450679: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, -144465 +-; LA32-NEXT: ori $a1, $a1, 2439 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_minus_0x23450679: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, -9029 +-; LA64-NEXT: addi.d $a0, $a0, -1657 +-; LA64-NEXT: ret +- %add = add i32 %x, -591726201 +- ret i32 %add +-} +- +-define signext i32 @add_i32_minus_0x23450679_sext(i32 %x) { +-; LA32-LABEL: add_i32_minus_0x23450679_sext: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, -144465 +-; LA32-NEXT: ori $a1, $a1, 2439 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_minus_0x23450679_sext: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, -9029 +-; LA64-NEXT: addi.w $a0, $a0, -1657 +-; LA64-NEXT: ret +- %add = add i32 %x, -591726201 +- ret i32 %add +-} +- +-define i64 @add_i64_minus_0x23450679(i64 %x) { +-; LA32-LABEL: add_i64_minus_0x23450679: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, -144465 +-; LA32-NEXT: ori $a2, $a2, 2439 +-; LA32-NEXT: add.w $a2, $a0, $a2 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: add.w $a0, $a1, $a0 +-; LA32-NEXT: addi.w $a1, $a0, -1 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i64_minus_0x23450679: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, -9029 +-; LA64-NEXT: addi.d $a0, $a0, -1657 +-; LA64-NEXT: ret +- %add = add i64 %x, -591726201 +- ret i64 %add +-} +- +-define i32 @add_i32_minus_0x2345fedd(i32 %x) { +-; LA32-LABEL: add_i32_minus_0x2345fedd: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, -144480 +-; LA32-NEXT: ori $a1, $a1, 291 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_minus_0x2345fedd: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, -9030 +-; LA64-NEXT: addi.d $a0, $a0, 291 +-; LA64-NEXT: ret +- %add = add i32 %x, -591789789 +- ret i32 %add +-} +- +-define signext i32 @add_i32_minus_0x2345fedd_sext(i32 %x) { +-; LA32-LABEL: add_i32_minus_0x2345fedd_sext: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, -144480 +-; LA32-NEXT: ori $a1, $a1, 291 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_minus_0x2345fedd_sext: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, -9030 +-; LA64-NEXT: addi.w $a0, $a0, 291 +-; LA64-NEXT: ret +- %add = add i32 %x, -591789789 +- ret i32 %add +-} +- +-define i64 @add_i64_minus_0x2345fedd(i64 %x) { +-; LA32-LABEL: add_i64_minus_0x2345fedd: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, -144480 +-; LA32-NEXT: ori $a2, $a2, 291 +-; LA32-NEXT: add.w $a2, $a0, $a2 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: add.w $a0, $a1, $a0 +-; LA32-NEXT: addi.w $a1, $a0, -1 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i64_minus_0x2345fedd: +-; LA64: # %bb.0: +-; LA64-NEXT: addu16i.d $a0, $a0, -9030 +-; LA64-NEXT: addi.d $a0, $a0, 291 +-; LA64-NEXT: ret +- %add = add i64 %x, -591789789 +- ret i64 %add +-} +- +-;; Check that `addu16i.d` isn't used for the following cases. +- +-define i64 @add_i64_0x80000000(i64 %x) { +-; LA32-LABEL: add_i64_0x80000000: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, -524288 +-; LA32-NEXT: add.w $a2, $a0, $a2 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: add.w $a1, $a1, $a0 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i64_0x80000000: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, -524288 +-; LA64-NEXT: lu32i.d $a1, 0 +-; LA64-NEXT: add.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %add = add i64 %x, 2147483648 +- ret i64 %add +-} +- +-define i64 @add_i64_0xffff0000(i64 %x) { +-; LA32-LABEL: add_i64_0xffff0000: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, -16 +-; LA32-NEXT: add.w $a2, $a0, $a2 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: add.w $a1, $a1, $a0 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i64_0xffff0000: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, -16 +-; LA64-NEXT: lu32i.d $a1, 0 +-; LA64-NEXT: add.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %add = add i64 %x, 4294901760 +- ret i64 %add +-} +- +-;; -0x80000800 is equivalent to +0x7ffff800 in i32, so addu16i.d isn't matched +-;; in this case. +-define i32 @add_i32_minus_0x80000800(i32 %x) { +-; LA32-LABEL: add_i32_minus_0x80000800: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 524287 +-; LA32-NEXT: ori $a1, $a1, 2048 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_minus_0x80000800: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, 524287 +-; LA64-NEXT: ori $a1, $a1, 2048 +-; LA64-NEXT: add.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %add = add i32 %x, -2147485696 +- ret i32 %add +-} +- +-define signext i32 @add_i32_minus_0x80000800_sext(i32 %x) { +-; LA32-LABEL: add_i32_minus_0x80000800_sext: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 524287 +-; LA32-NEXT: ori $a1, $a1, 2048 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_minus_0x80000800_sext: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, 524287 +-; LA64-NEXT: ori $a1, $a1, 2048 +-; LA64-NEXT: add.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %add = add i32 %x, -2147485696 +- ret i32 %add +-} +- +-define signext i32 @add_i32_4080(i32 %x) { +-; LA32-LABEL: add_i32_4080: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $a0, 2047 +-; LA32-NEXT: addi.w $a0, $a0, 2033 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_4080: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.w $a0, $a0, 2047 +-; LA64-NEXT: addi.w $a0, $a0, 2033 +-; LA64-NEXT: ret +- %add = add i32 %x, 4080 +- ret i32 %add +-} +- +-define signext i32 @add_i32_minus_4080(i32 %x) { +-; LA32-LABEL: add_i32_minus_4080: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $a0, -2048 +-; LA32-NEXT: addi.w $a0, $a0, -2032 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_minus_4080: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.w $a0, $a0, -2048 +-; LA64-NEXT: addi.w $a0, $a0, -2032 +-; LA64-NEXT: ret +- %add = add i32 %x, -4080 +- ret i32 %add +-} +- +-define signext i32 @add_i32_2048(i32 %x) { +-; LA32-LABEL: add_i32_2048: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $a0, 2047 +-; LA32-NEXT: addi.w $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_2048: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.w $a0, $a0, 2047 +-; LA64-NEXT: addi.w $a0, $a0, 1 +-; LA64-NEXT: ret +- %add = add i32 %x, 2048 +- ret i32 %add +-} +- +-define signext i32 @add_i32_4094(i32 %x) { +-; LA32-LABEL: add_i32_4094: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $a0, 2047 +-; LA32-NEXT: addi.w $a0, $a0, 2047 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_4094: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.w $a0, $a0, 2047 +-; LA64-NEXT: addi.w $a0, $a0, 2047 +-; LA64-NEXT: ret +- %add = add i32 %x, 4094 +- ret i32 %add +-} +- +-define signext i32 @add_i32_minus_2049(i32 %x) { +-; LA32-LABEL: add_i32_minus_2049: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $a0, -2048 +-; LA32-NEXT: addi.w $a0, $a0, -1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_minus_2049: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.w $a0, $a0, -2048 +-; LA64-NEXT: addi.w $a0, $a0, -1 +-; LA64-NEXT: ret +- %add = add i32 %x, -2049 +- ret i32 %add +-} +- +-define signext i32 @add_i32_minus_4096(i32 %x) { +-; LA32-LABEL: add_i32_minus_4096: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $a0, -2048 +-; LA32-NEXT: addi.w $a0, $a0, -2048 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i32_minus_4096: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.w $a0, $a0, -2048 +-; LA64-NEXT: addi.w $a0, $a0, -2048 +-; LA64-NEXT: ret +- %add = add i32 %x, -4096 +- ret i32 %add +-} +- +-define i64 @add_i64_4080(i64 %x) { +-; LA32-LABEL: add_i64_4080: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a2, $a0, 2047 +-; LA32-NEXT: addi.w $a2, $a2, 2033 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: add.w $a1, $a1, $a0 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i64_4080: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $a0, $a0, 2047 +-; LA64-NEXT: addi.d $a0, $a0, 2033 +-; LA64-NEXT: ret +- %add = add i64 %x, 4080 +- ret i64 %add +-} +- +-define i64 @add_i64_minus_4080(i64 %x) { +-; LA32-LABEL: add_i64_minus_4080: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a2, $a0, -2048 +-; LA32-NEXT: addi.w $a2, $a2, -2032 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: add.w $a0, $a1, $a0 +-; LA32-NEXT: addi.w $a1, $a0, -1 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i64_minus_4080: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $a0, $a0, -2048 +-; LA64-NEXT: addi.d $a0, $a0, -2032 +-; LA64-NEXT: ret +- %add = add i64 %x, -4080 +- ret i64 %add +-} +- +-define i64 @add_i64_2048(i64 %x) { +-; LA32-LABEL: add_i64_2048: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a2, $a0, 2047 +-; LA32-NEXT: addi.w $a2, $a2, 1 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: add.w $a1, $a1, $a0 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i64_2048: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $a0, $a0, 2047 +-; LA64-NEXT: addi.d $a0, $a0, 1 +-; LA64-NEXT: ret +- %add = add i64 %x, 2048 +- ret i64 %add +-} +- +-define i64 @add_i64_4094(i64 %x) { +-; LA32-LABEL: add_i64_4094: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a2, $a0, 2047 +-; LA32-NEXT: addi.w $a2, $a2, 2047 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: add.w $a1, $a1, $a0 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i64_4094: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $a0, $a0, 2047 +-; LA64-NEXT: addi.d $a0, $a0, 2047 +-; LA64-NEXT: ret +- %add = add i64 %x, 4094 +- ret i64 %add +-} +- +-define i64 @add_i64_minus_2049(i64 %x) { +-; LA32-LABEL: add_i64_minus_2049: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a2, $a0, -2048 +-; LA32-NEXT: addi.w $a2, $a2, -1 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: add.w $a0, $a1, $a0 +-; LA32-NEXT: addi.w $a1, $a0, -1 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i64_minus_2049: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $a0, $a0, -2048 +-; LA64-NEXT: addi.d $a0, $a0, -1 +-; LA64-NEXT: ret +- %add = add i64 %x, -2049 +- ret i64 %add +-} +- +-define i64 @add_i64_minus_4096(i64 %x) { +-; LA32-LABEL: add_i64_minus_4096: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a2, $a0, -2048 +-; LA32-NEXT: addi.w $a2, $a2, -2048 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: add.w $a0, $a1, $a0 +-; LA32-NEXT: addi.w $a1, $a0, -1 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: add_i64_minus_4096: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $a0, $a0, -2048 +-; LA64-NEXT: addi.d $a0, $a0, -2048 +-; LA64-NEXT: ret +- %add = add i64 %x, -4096 +- ret i64 %add +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/and.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/and.ll +deleted file mode 100644 +index b43ed7859..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/and.ll ++++ /dev/null +@@ -1,455 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-;; Exercise the 'and' LLVM IR: https://llvm.org/docs/LangRef.html#and-instruction +- +-define i1 @and_i1(i1 %a, i1 %b) { +-; LA32-LABEL: and_i1: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: and $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i1: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: and $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = and i1 %a, %b +- ret i1 %r +-} +- +-define i8 @and_i8(i8 %a, i8 %b) { +-; LA32-LABEL: and_i8: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: and $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i8: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: and $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = and i8 %a, %b +- ret i8 %r +-} +- +-define i16 @and_i16(i16 %a, i16 %b) { +-; LA32-LABEL: and_i16: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: and $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i16: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: and $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = and i16 %a, %b +- ret i16 %r +-} +- +-define i32 @and_i32(i32 %a, i32 %b) { +-; LA32-LABEL: and_i32: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: and $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i32: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: and $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = and i32 %a, %b +- ret i32 %r +-} +- +-define i64 @and_i64(i64 %a, i64 %b) { +-; LA32-LABEL: and_i64: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: and $a0, $a0, $a2 +-; LA32-NEXT: and $a1, $a1, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i64: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: and $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = and i64 %a, %b +- ret i64 %r +-} +- +-define i1 @and_i1_0(i1 %b) { +-; LA32-LABEL: and_i1_0: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: move $a0, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i1_0: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: move $a0, $zero +-; LA64-NEXT: ret +-entry: +- %r = and i1 4, %b +- ret i1 %r +-} +- +-define i1 @and_i1_5(i1 %b) { +-; LA32-LABEL: and_i1_5: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i1_5: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ret +-entry: +- %r = and i1 5, %b +- ret i1 %r +-} +- +-define i8 @and_i8_5(i8 %b) { +-; LA32-LABEL: and_i8_5: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: andi $a0, $a0, 5 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i8_5: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: andi $a0, $a0, 5 +-; LA64-NEXT: ret +-entry: +- %r = and i8 5, %b +- ret i8 %r +-} +- +-define i8 @and_i8_257(i8 %b) { +-; LA32-LABEL: and_i8_257: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: andi $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i8_257: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: andi $a0, $a0, 1 +-; LA64-NEXT: ret +-entry: +- %r = and i8 257, %b +- ret i8 %r +-} +- +-define i16 @and_i16_5(i16 %b) { +-; LA32-LABEL: and_i16_5: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: andi $a0, $a0, 5 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i16_5: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: andi $a0, $a0, 5 +-; LA64-NEXT: ret +-entry: +- %r = and i16 5, %b +- ret i16 %r +-} +- +-define i16 @and_i16_0x1000(i16 %b) { +-; LA32-LABEL: and_i16_0x1000: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: lu12i.w $a1, 1 +-; LA32-NEXT: and $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i16_0x1000: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: lu12i.w $a1, 1 +-; LA64-NEXT: and $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = and i16 4096, %b +- ret i16 %r +-} +- +-define i16 @and_i16_0x10001(i16 %b) { +-; LA32-LABEL: and_i16_0x10001: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: andi $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i16_0x10001: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: andi $a0, $a0, 1 +-; LA64-NEXT: ret +-entry: +- %r = and i16 65537, %b +- ret i16 %r +-} +- +-define i32 @and_i32_5(i32 %b) { +-; LA32-LABEL: and_i32_5: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: andi $a0, $a0, 5 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i32_5: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: andi $a0, $a0, 5 +-; LA64-NEXT: ret +-entry: +- %r = and i32 5, %b +- ret i32 %r +-} +- +-define i32 @and_i32_0x1000(i32 %b) { +-; LA32-LABEL: and_i32_0x1000: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: lu12i.w $a1, 1 +-; LA32-NEXT: and $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i32_0x1000: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: lu12i.w $a1, 1 +-; LA64-NEXT: and $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = and i32 4096, %b +- ret i32 %r +-} +- +-define i32 @and_i32_0x100000001(i32 %b) { +-; LA32-LABEL: and_i32_0x100000001: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: andi $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i32_0x100000001: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: andi $a0, $a0, 1 +-; LA64-NEXT: ret +-entry: +- %r = and i32 4294967297, %b +- ret i32 %r +-} +- +-define i64 @and_i64_5(i64 %b) { +-; LA32-LABEL: and_i64_5: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: andi $a0, $a0, 5 +-; LA32-NEXT: move $a1, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i64_5: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: andi $a0, $a0, 5 +-; LA64-NEXT: ret +-entry: +- %r = and i64 5, %b +- ret i64 %r +-} +- +-define i64 @and_i64_0x1000(i64 %b) { +-; LA32-LABEL: and_i64_0x1000: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: lu12i.w $a1, 1 +-; LA32-NEXT: and $a0, $a0, $a1 +-; LA32-NEXT: move $a1, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i64_0x1000: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: lu12i.w $a1, 1 +-; LA64-NEXT: and $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = and i64 4096, %b +- ret i64 %r +-} +- +-define signext i32 @and_i32_0xfff0(i32 %a) { +-; LA32-LABEL: and_i32_0xfff0: +-; LA32: # %bb.0: +-; LA32-NEXT: bstrpick.w $a0, $a0, 15, 4 +-; LA32-NEXT: slli.w $a0, $a0, 4 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i32_0xfff0: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a0, $a0, 15, 4 +-; LA64-NEXT: slli.d $a0, $a0, 4 +-; LA64-NEXT: ret +- %b = and i32 %a, 65520 +- ret i32 %b +-} +- +-define signext i32 @and_i32_0xfff0_twice(i32 %a, i32 %b) { +-; LA32-LABEL: and_i32_0xfff0_twice: +-; LA32: # %bb.0: +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 4 +-; LA32-NEXT: slli.w $a1, $a1, 4 +-; LA32-NEXT: bstrpick.w $a0, $a0, 15, 4 +-; LA32-NEXT: slli.w $a0, $a0, 4 +-; LA32-NEXT: sub.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i32_0xfff0_twice: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 4 +-; LA64-NEXT: slli.d $a1, $a1, 4 +-; LA64-NEXT: bstrpick.d $a0, $a0, 15, 4 +-; LA64-NEXT: slli.d $a0, $a0, 4 +-; LA64-NEXT: sub.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %c = and i32 %a, 65520 +- %d = and i32 %b, 65520 +- %e = sub i32 %c, %d +- ret i32 %e +-} +- +-define i64 @and_i64_0xfff0(i64 %a) { +-; LA32-LABEL: and_i64_0xfff0: +-; LA32: # %bb.0: +-; LA32-NEXT: bstrpick.w $a0, $a0, 15, 4 +-; LA32-NEXT: slli.w $a0, $a0, 4 +-; LA32-NEXT: move $a1, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i64_0xfff0: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a0, $a0, 15, 4 +-; LA64-NEXT: slli.d $a0, $a0, 4 +-; LA64-NEXT: ret +- %b = and i64 %a, 65520 +- ret i64 %b +-} +- +-define i64 @and_i64_0xfff0_twice(i64 %a, i64 %b) { +-; LA32-LABEL: and_i64_0xfff0_twice: +-; LA32: # %bb.0: +-; LA32-NEXT: bstrpick.w $a1, $a2, 15, 4 +-; LA32-NEXT: slli.w $a1, $a1, 4 +-; LA32-NEXT: bstrpick.w $a0, $a0, 15, 4 +-; LA32-NEXT: slli.w $a2, $a0, 4 +-; LA32-NEXT: sub.w $a0, $a2, $a1 +-; LA32-NEXT: sltu $a1, $a2, $a1 +-; LA32-NEXT: sub.w $a1, $zero, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i64_0xfff0_twice: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 4 +-; LA64-NEXT: slli.d $a1, $a1, 4 +-; LA64-NEXT: bstrpick.d $a0, $a0, 15, 4 +-; LA64-NEXT: slli.d $a0, $a0, 4 +-; LA64-NEXT: sub.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %c = and i64 %a, 65520 +- %d = and i64 %b, 65520 +- %e = sub i64 %c, %d +- ret i64 %e +-} +- +-;; This case is not optimized to `bstrpick + slli`, +-;; since the immediate 1044480 can be composed via +-;; a single `lu12i.w $rx, 255`. +-define i64 @and_i64_0xff000(i64 %a) { +-; LA32-LABEL: and_i64_0xff000: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 255 +-; LA32-NEXT: and $a0, $a0, $a1 +-; LA32-NEXT: move $a1, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i64_0xff000: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, 255 +-; LA64-NEXT: and $a0, $a0, $a1 +-; LA64-NEXT: ret +- %b = and i64 %a, 1044480 +- ret i64 %b +-} +- +-define i64 @and_i64_minus_2048(i64 %a) { +-; LA32-LABEL: and_i64_minus_2048: +-; LA32: # %bb.0: +-; LA32-NEXT: bstrins.w $a0, $zero, 10, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i64_minus_2048: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrins.d $a0, $zero, 10, 0 +-; LA64-NEXT: ret +- %b = and i64 %a, -2048 +- ret i64 %b +-} +- +-;; This case is not optimized to `bstrpick + slli`, +-;; since the immediate 0xfff0 has more than 2 uses. +-define i64 @and_i64_0xfff0_multiple_times(i64 %a, i64 %b, i64 %c) { +-; LA32-LABEL: and_i64_0xfff0_multiple_times: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 15 +-; LA32-NEXT: ori $a1, $a1, 4080 +-; LA32-NEXT: and $a3, $a0, $a1 +-; LA32-NEXT: and $a0, $a4, $a1 +-; LA32-NEXT: and $a1, $a2, $a1 +-; LA32-NEXT: mul.w $a0, $a1, $a0 +-; LA32-NEXT: sub.w $a2, $a3, $a1 +-; LA32-NEXT: xor $a0, $a2, $a0 +-; LA32-NEXT: sltu $a1, $a3, $a1 +-; LA32-NEXT: sub.w $a1, $zero, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i64_0xfff0_multiple_times: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a3, 15 +-; LA64-NEXT: ori $a3, $a3, 4080 +-; LA64-NEXT: and $a0, $a0, $a3 +-; LA64-NEXT: and $a2, $a2, $a3 +-; LA64-NEXT: and $a1, $a1, $a3 +-; LA64-NEXT: mul.d $a2, $a1, $a2 +-; LA64-NEXT: sub.d $a0, $a0, $a1 +-; LA64-NEXT: xor $a0, $a0, $a2 +-; LA64-NEXT: ret +- %d = and i64 %a, 65520 +- %e = and i64 %b, 65520 +- %f = and i64 %c, 65520 +- %g = sub i64 %d, %e +- %h = mul i64 %e, %f +- %i = xor i64 %g, %h +- ret i64 %i +-} +- +-define i64 @and_i64_0xffffffffff00ffff(i64 %a) { +-; LA32-LABEL: and_i64_0xffffffffff00ffff: +-; LA32: # %bb.0: +-; LA32-NEXT: bstrins.w $a0, $zero, 23, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_i64_0xffffffffff00ffff: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrins.d $a0, $zero, 23, 16 +-; LA64-NEXT: ret +- %b = and i64 %a, 18446744073692839935 +- ret i64 %b +-} +- +-define i32 @and_add_lsr(i32 %x, i32 %y) { +-; LA32-LABEL: and_add_lsr: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $a0, -1 +-; LA32-NEXT: srli.w $a1, $a1, 20 +-; LA32-NEXT: and $a0, $a1, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: and_add_lsr: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $a0, $a0, -1 +-; LA64-NEXT: bstrpick.d $a1, $a1, 31, 20 +-; LA64-NEXT: and $a0, $a1, $a0 +-; LA64-NEXT: ret +- %1 = add i32 %x, 4095 +- %2 = lshr i32 %y, 20 +- %r = and i32 %2, %1 +- ret i32 %r +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/ashr.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/ashr.ll +deleted file mode 100644 +index 0d8e7127d..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/ashr.ll ++++ /dev/null +@@ -1,169 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-;; Exercise the 'ashr' LLVM IR: https://llvm.org/docs/LangRef.html#ashr-instruction +- +-define i1 @ashr_i1(i1 %x, i1 %y) { +-; LA32-LABEL: ashr_i1: +-; LA32: # %bb.0: +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ashr_i1: +-; LA64: # %bb.0: +-; LA64-NEXT: ret +- %ashr = ashr i1 %x, %y +- ret i1 %ashr +-} +- +-define i8 @ashr_i8(i8 %x, i8 %y) { +-; LA32-LABEL: ashr_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: ext.w.b $a0, $a0 +-; LA32-NEXT: sra.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ashr_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: ext.w.b $a0, $a0 +-; LA64-NEXT: sra.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %ashr = ashr i8 %x, %y +- ret i8 %ashr +-} +- +-define i16 @ashr_i16(i16 %x, i16 %y) { +-; LA32-LABEL: ashr_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: ext.w.h $a0, $a0 +-; LA32-NEXT: sra.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ashr_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: ext.w.h $a0, $a0 +-; LA64-NEXT: sra.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %ashr = ashr i16 %x, %y +- ret i16 %ashr +-} +- +-define i32 @ashr_i32(i32 %x, i32 %y) { +-; LA32-LABEL: ashr_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: sra.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ashr_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: sra.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %ashr = ashr i32 %x, %y +- ret i32 %ashr +-} +- +-define i64 @ashr_i64(i64 %x, i64 %y) { +-; LA32-LABEL: ashr_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: srai.w $a3, $a1, 31 +-; LA32-NEXT: addi.w $a4, $a2, -32 +-; LA32-NEXT: slti $a5, $a4, 0 +-; LA32-NEXT: masknez $a3, $a3, $a5 +-; LA32-NEXT: sra.w $a6, $a1, $a2 +-; LA32-NEXT: maskeqz $a6, $a6, $a5 +-; LA32-NEXT: or $a3, $a6, $a3 +-; LA32-NEXT: srl.w $a0, $a0, $a2 +-; LA32-NEXT: xori $a2, $a2, 31 +-; LA32-NEXT: slli.w $a6, $a1, 1 +-; LA32-NEXT: sll.w $a2, $a6, $a2 +-; LA32-NEXT: or $a0, $a0, $a2 +-; LA32-NEXT: sra.w $a1, $a1, $a4 +-; LA32-NEXT: maskeqz $a0, $a0, $a5 +-; LA32-NEXT: masknez $a1, $a1, $a5 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: move $a1, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ashr_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: sra.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %ashr = ashr i64 %x, %y +- ret i64 %ashr +-} +- +-define i1 @ashr_i1_3(i1 %x) { +-; LA32-LABEL: ashr_i1_3: +-; LA32: # %bb.0: +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ashr_i1_3: +-; LA64: # %bb.0: +-; LA64-NEXT: ret +- %ashr = ashr i1 %x, 3 +- ret i1 %ashr +-} +- +-define i8 @ashr_i8_3(i8 %x) { +-; LA32-LABEL: ashr_i8_3: +-; LA32: # %bb.0: +-; LA32-NEXT: ext.w.b $a0, $a0 +-; LA32-NEXT: srai.w $a0, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ashr_i8_3: +-; LA64: # %bb.0: +-; LA64-NEXT: ext.w.b $a0, $a0 +-; LA64-NEXT: srai.d $a0, $a0, 3 +-; LA64-NEXT: ret +- %ashr = ashr i8 %x, 3 +- ret i8 %ashr +-} +- +-define i16 @ashr_i16_3(i16 %x) { +-; LA32-LABEL: ashr_i16_3: +-; LA32: # %bb.0: +-; LA32-NEXT: ext.w.h $a0, $a0 +-; LA32-NEXT: srai.w $a0, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ashr_i16_3: +-; LA64: # %bb.0: +-; LA64-NEXT: ext.w.h $a0, $a0 +-; LA64-NEXT: srai.d $a0, $a0, 3 +-; LA64-NEXT: ret +- %ashr = ashr i16 %x, 3 +- ret i16 %ashr +-} +- +-define i32 @ashr_i32_3(i32 %x) { +-; LA32-LABEL: ashr_i32_3: +-; LA32: # %bb.0: +-; LA32-NEXT: srai.w $a0, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ashr_i32_3: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: srai.d $a0, $a0, 3 +-; LA64-NEXT: ret +- %ashr = ashr i32 %x, 3 +- ret i32 %ashr +-} +- +-define i64 @ashr_i64_3(i64 %x) { +-; LA32-LABEL: ashr_i64_3: +-; LA32: # %bb.0: +-; LA32-NEXT: srli.w $a0, $a0, 3 +-; LA32-NEXT: slli.w $a2, $a1, 29 +-; LA32-NEXT: or $a0, $a0, $a2 +-; LA32-NEXT: srai.w $a1, $a1, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ashr_i64_3: +-; LA64: # %bb.0: +-; LA64-NEXT: srai.d $a0, $a0, 3 +-; LA64-NEXT: ret +- %ashr = ashr i64 %x, 3 +- ret i64 %ashr +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/atomic-cmpxchg.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/atomic-cmpxchg.ll +deleted file mode 100644 +index 31ecec6ea..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/atomic-cmpxchg.ll ++++ /dev/null +@@ -1,778 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-define void @cmpxchg_i8_acquire_acquire(ptr %ptr, i8 %cmp, i8 %val) nounwind { +-; LA64-LABEL: cmpxchg_i8_acquire_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: andi $a2, $a2, 255 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: ori $a4, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a4, $a3 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB0_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a5, $a4, $a3 +-; LA64-NEXT: bne $a5, $a1, .LBB0_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB0_1 Depth=1 +-; LA64-NEXT: andn $a5, $a4, $a3 +-; LA64-NEXT: or $a5, $a5, $a2 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB0_1 +-; LA64-NEXT: b .LBB0_4 +-; LA64-NEXT: .LBB0_3: +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: .LBB0_4: +-; LA64-NEXT: ret +- %res = cmpxchg ptr %ptr, i8 %cmp, i8 %val acquire acquire +- ret void +-} +- +-define void @cmpxchg_i16_acquire_acquire(ptr %ptr, i16 %cmp, i16 %val) nounwind { +-; LA64-LABEL: cmpxchg_i16_acquire_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: bstrpick.d $a2, $a2, 15, 0 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: lu12i.w $a4, 15 +-; LA64-NEXT: ori $a4, $a4, 4095 +-; LA64-NEXT: sll.w $a3, $a4, $a3 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB1_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a5, $a4, $a3 +-; LA64-NEXT: bne $a5, $a1, .LBB1_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB1_1 Depth=1 +-; LA64-NEXT: andn $a5, $a4, $a3 +-; LA64-NEXT: or $a5, $a5, $a2 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB1_1 +-; LA64-NEXT: b .LBB1_4 +-; LA64-NEXT: .LBB1_3: +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: .LBB1_4: +-; LA64-NEXT: ret +- %res = cmpxchg ptr %ptr, i16 %cmp, i16 %val acquire acquire +- ret void +-} +- +-define void @cmpxchg_i32_acquire_acquire(ptr %ptr, i32 %cmp, i32 %val) nounwind { +-; LA64-LABEL: cmpxchg_i32_acquire_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: .LBB2_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a3, $a0, 0 +-; LA64-NEXT: bne $a3, $a1, .LBB2_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB2_1 Depth=1 +-; LA64-NEXT: move $a4, $a2 +-; LA64-NEXT: sc.w $a4, $a0, 0 +-; LA64-NEXT: beqz $a4, .LBB2_1 +-; LA64-NEXT: b .LBB2_4 +-; LA64-NEXT: .LBB2_3: +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: .LBB2_4: +-; LA64-NEXT: ret +- %res = cmpxchg ptr %ptr, i32 %cmp, i32 %val acquire acquire +- ret void +-} +- +-define void @cmpxchg_i64_acquire_acquire(ptr %ptr, i64 %cmp, i64 %val) nounwind { +-; LA64-LABEL: cmpxchg_i64_acquire_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: .LBB3_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.d $a3, $a0, 0 +-; LA64-NEXT: bne $a3, $a1, .LBB3_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB3_1 Depth=1 +-; LA64-NEXT: move $a4, $a2 +-; LA64-NEXT: sc.d $a4, $a0, 0 +-; LA64-NEXT: beqz $a4, .LBB3_1 +-; LA64-NEXT: b .LBB3_4 +-; LA64-NEXT: .LBB3_3: +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: .LBB3_4: +-; LA64-NEXT: ret +- %res = cmpxchg ptr %ptr, i64 %cmp, i64 %val acquire acquire +- ret void +-} +- +-define void @cmpxchg_i8_acquire_monotonic(ptr %ptr, i8 %cmp, i8 %val) nounwind { +-; LA64-LABEL: cmpxchg_i8_acquire_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: andi $a2, $a2, 255 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: ori $a4, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a4, $a3 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB4_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a5, $a4, $a3 +-; LA64-NEXT: bne $a5, $a1, .LBB4_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB4_1 Depth=1 +-; LA64-NEXT: andn $a5, $a4, $a3 +-; LA64-NEXT: or $a5, $a5, $a2 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB4_1 +-; LA64-NEXT: b .LBB4_4 +-; LA64-NEXT: .LBB4_3: +-; LA64-NEXT: dbar 1792 +-; LA64-NEXT: .LBB4_4: +-; LA64-NEXT: ret +- %res = cmpxchg ptr %ptr, i8 %cmp, i8 %val acquire monotonic +- ret void +-} +- +-define void @cmpxchg_i16_acquire_monotonic(ptr %ptr, i16 %cmp, i16 %val) nounwind { +-; LA64-LABEL: cmpxchg_i16_acquire_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: bstrpick.d $a2, $a2, 15, 0 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: lu12i.w $a4, 15 +-; LA64-NEXT: ori $a4, $a4, 4095 +-; LA64-NEXT: sll.w $a3, $a4, $a3 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB5_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a5, $a4, $a3 +-; LA64-NEXT: bne $a5, $a1, .LBB5_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB5_1 Depth=1 +-; LA64-NEXT: andn $a5, $a4, $a3 +-; LA64-NEXT: or $a5, $a5, $a2 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB5_1 +-; LA64-NEXT: b .LBB5_4 +-; LA64-NEXT: .LBB5_3: +-; LA64-NEXT: dbar 1792 +-; LA64-NEXT: .LBB5_4: +-; LA64-NEXT: ret +- %res = cmpxchg ptr %ptr, i16 %cmp, i16 %val acquire monotonic +- ret void +-} +- +-define void @cmpxchg_i32_acquire_monotonic(ptr %ptr, i32 %cmp, i32 %val) nounwind { +-; LA64-LABEL: cmpxchg_i32_acquire_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: .LBB6_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a3, $a0, 0 +-; LA64-NEXT: bne $a3, $a1, .LBB6_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB6_1 Depth=1 +-; LA64-NEXT: move $a4, $a2 +-; LA64-NEXT: sc.w $a4, $a0, 0 +-; LA64-NEXT: beqz $a4, .LBB6_1 +-; LA64-NEXT: b .LBB6_4 +-; LA64-NEXT: .LBB6_3: +-; LA64-NEXT: dbar 1792 +-; LA64-NEXT: .LBB6_4: +-; LA64-NEXT: ret +- %res = cmpxchg ptr %ptr, i32 %cmp, i32 %val acquire monotonic +- ret void +-} +- +-define void @cmpxchg_i64_acquire_monotonic(ptr %ptr, i64 %cmp, i64 %val) nounwind { +-; LA64-LABEL: cmpxchg_i64_acquire_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: .LBB7_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.d $a3, $a0, 0 +-; LA64-NEXT: bne $a3, $a1, .LBB7_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB7_1 Depth=1 +-; LA64-NEXT: move $a4, $a2 +-; LA64-NEXT: sc.d $a4, $a0, 0 +-; LA64-NEXT: beqz $a4, .LBB7_1 +-; LA64-NEXT: b .LBB7_4 +-; LA64-NEXT: .LBB7_3: +-; LA64-NEXT: dbar 1792 +-; LA64-NEXT: .LBB7_4: +-; LA64-NEXT: ret +- %res = cmpxchg ptr %ptr, i64 %cmp, i64 %val acquire monotonic +- ret void +-} +- +-define i8 @cmpxchg_i8_acquire_acquire_reti8(ptr %ptr, i8 %cmp, i8 %val) nounwind { +-; LA64-LABEL: cmpxchg_i8_acquire_acquire_reti8: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: ori $a4, $zero, 255 +-; LA64-NEXT: sll.w $a4, $a4, $a3 +-; LA64-NEXT: andi $a2, $a2, 255 +-; LA64-NEXT: addi.w $a4, $a4, 0 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB8_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a6, $a5, $a4 +-; LA64-NEXT: bne $a6, $a1, .LBB8_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB8_1 Depth=1 +-; LA64-NEXT: andn $a6, $a5, $a4 +-; LA64-NEXT: or $a6, $a6, $a2 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB8_1 +-; LA64-NEXT: b .LBB8_4 +-; LA64-NEXT: .LBB8_3: +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: .LBB8_4: +-; LA64-NEXT: srl.w $a0, $a5, $a3 +-; LA64-NEXT: ret +- %tmp = cmpxchg ptr %ptr, i8 %cmp, i8 %val acquire acquire +- %res = extractvalue { i8, i1 } %tmp, 0 +- ret i8 %res +-} +- +-define i16 @cmpxchg_i16_acquire_acquire_reti16(ptr %ptr, i16 %cmp, i16 %val) nounwind { +-; LA64-LABEL: cmpxchg_i16_acquire_acquire_reti16: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a3, 15 +-; LA64-NEXT: ori $a3, $a3, 4095 +-; LA64-NEXT: slli.d $a4, $a0, 3 +-; LA64-NEXT: sll.w $a3, $a3, $a4 +-; LA64-NEXT: bstrpick.d $a2, $a2, 15, 0 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: sll.w $a2, $a2, $a4 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a4 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB9_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a6, $a5, $a3 +-; LA64-NEXT: bne $a6, $a1, .LBB9_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB9_1 Depth=1 +-; LA64-NEXT: andn $a6, $a5, $a3 +-; LA64-NEXT: or $a6, $a6, $a2 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB9_1 +-; LA64-NEXT: b .LBB9_4 +-; LA64-NEXT: .LBB9_3: +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: .LBB9_4: +-; LA64-NEXT: srl.w $a0, $a5, $a4 +-; LA64-NEXT: ret +- %tmp = cmpxchg ptr %ptr, i16 %cmp, i16 %val acquire acquire +- %res = extractvalue { i16, i1 } %tmp, 0 +- ret i16 %res +-} +- +-define i32 @cmpxchg_i32_acquire_acquire_reti32(ptr %ptr, i32 %cmp, i32 %val) nounwind { +-; LA64-LABEL: cmpxchg_i32_acquire_acquire_reti32: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.w $a3, $a1, 0 +-; LA64-NEXT: .LBB10_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a1, $a0, 0 +-; LA64-NEXT: bne $a1, $a3, .LBB10_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB10_1 Depth=1 +-; LA64-NEXT: move $a4, $a2 +-; LA64-NEXT: sc.w $a4, $a0, 0 +-; LA64-NEXT: beqz $a4, .LBB10_1 +-; LA64-NEXT: b .LBB10_4 +-; LA64-NEXT: .LBB10_3: +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: .LBB10_4: +-; LA64-NEXT: move $a0, $a1 +-; LA64-NEXT: ret +- %tmp = cmpxchg ptr %ptr, i32 %cmp, i32 %val acquire acquire +- %res = extractvalue { i32, i1 } %tmp, 0 +- ret i32 %res +-} +- +-define i64 @cmpxchg_i64_acquire_acquire_reti64(ptr %ptr, i64 %cmp, i64 %val) nounwind { +-; LA64-LABEL: cmpxchg_i64_acquire_acquire_reti64: +-; LA64: # %bb.0: +-; LA64-NEXT: .LBB11_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.d $a3, $a0, 0 +-; LA64-NEXT: bne $a3, $a1, .LBB11_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB11_1 Depth=1 +-; LA64-NEXT: move $a4, $a2 +-; LA64-NEXT: sc.d $a4, $a0, 0 +-; LA64-NEXT: beqz $a4, .LBB11_1 +-; LA64-NEXT: b .LBB11_4 +-; LA64-NEXT: .LBB11_3: +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: .LBB11_4: +-; LA64-NEXT: move $a0, $a3 +-; LA64-NEXT: ret +- %tmp = cmpxchg ptr %ptr, i64 %cmp, i64 %val acquire acquire +- %res = extractvalue { i64, i1 } %tmp, 0 +- ret i64 %res +-} +- +-define i1 @cmpxchg_i8_acquire_acquire_reti1(ptr %ptr, i8 %cmp, i8 %val) nounwind { +-; LA64-LABEL: cmpxchg_i8_acquire_acquire_reti1: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: ori $a4, $zero, 255 +-; LA64-NEXT: sll.w $a4, $a4, $a3 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: andi $a2, $a2, 255 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: addi.w $a3, $a4, 0 +-; LA64-NEXT: .LBB12_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a6, $a5, $a3 +-; LA64-NEXT: bne $a6, $a1, .LBB12_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB12_1 Depth=1 +-; LA64-NEXT: andn $a6, $a5, $a3 +-; LA64-NEXT: or $a6, $a6, $a2 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB12_1 +-; LA64-NEXT: b .LBB12_4 +-; LA64-NEXT: .LBB12_3: +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: .LBB12_4: +-; LA64-NEXT: and $a0, $a5, $a4 +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: xor $a0, $a1, $a0 +-; LA64-NEXT: sltui $a0, $a0, 1 +-; LA64-NEXT: ret +- %tmp = cmpxchg ptr %ptr, i8 %cmp, i8 %val acquire acquire +- %res = extractvalue { i8, i1 } %tmp, 1 +- ret i1 %res +-} +- +-define i1 @cmpxchg_i16_acquire_acquire_reti1(ptr %ptr, i16 %cmp, i16 %val) nounwind { +-; LA64-LABEL: cmpxchg_i16_acquire_acquire_reti1: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: lu12i.w $a3, 15 +-; LA64-NEXT: ori $a3, $a3, 4095 +-; LA64-NEXT: slli.d $a4, $a0, 3 +-; LA64-NEXT: sll.w $a3, $a3, $a4 +-; LA64-NEXT: sll.w $a1, $a1, $a4 +-; LA64-NEXT: bstrpick.d $a2, $a2, 15, 0 +-; LA64-NEXT: sll.w $a2, $a2, $a4 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: addi.w $a4, $a3, 0 +-; LA64-NEXT: .LBB13_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a6, $a5, $a4 +-; LA64-NEXT: bne $a6, $a1, .LBB13_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB13_1 Depth=1 +-; LA64-NEXT: andn $a6, $a5, $a4 +-; LA64-NEXT: or $a6, $a6, $a2 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB13_1 +-; LA64-NEXT: b .LBB13_4 +-; LA64-NEXT: .LBB13_3: +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: .LBB13_4: +-; LA64-NEXT: and $a0, $a5, $a3 +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: xor $a0, $a1, $a0 +-; LA64-NEXT: sltui $a0, $a0, 1 +-; LA64-NEXT: ret +- %tmp = cmpxchg ptr %ptr, i16 %cmp, i16 %val acquire acquire +- %res = extractvalue { i16, i1 } %tmp, 1 +- ret i1 %res +-} +- +-define i1 @cmpxchg_i32_acquire_acquire_reti1(ptr %ptr, i32 %cmp, i32 %val) nounwind { +-; LA64-LABEL: cmpxchg_i32_acquire_acquire_reti1: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: .LBB14_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a3, $a0, 0 +-; LA64-NEXT: bne $a3, $a1, .LBB14_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB14_1 Depth=1 +-; LA64-NEXT: move $a4, $a2 +-; LA64-NEXT: sc.w $a4, $a0, 0 +-; LA64-NEXT: beqz $a4, .LBB14_1 +-; LA64-NEXT: b .LBB14_4 +-; LA64-NEXT: .LBB14_3: +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: .LBB14_4: +-; LA64-NEXT: xor $a0, $a3, $a1 +-; LA64-NEXT: sltui $a0, $a0, 1 +-; LA64-NEXT: ret +- %tmp = cmpxchg ptr %ptr, i32 %cmp, i32 %val acquire acquire +- %res = extractvalue { i32, i1 } %tmp, 1 +- ret i1 %res +-} +- +-define i1 @cmpxchg_i64_acquire_acquire_reti1(ptr %ptr, i64 %cmp, i64 %val) nounwind { +-; LA64-LABEL: cmpxchg_i64_acquire_acquire_reti1: +-; LA64: # %bb.0: +-; LA64-NEXT: .LBB15_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.d $a3, $a0, 0 +-; LA64-NEXT: bne $a3, $a1, .LBB15_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1 +-; LA64-NEXT: move $a4, $a2 +-; LA64-NEXT: sc.d $a4, $a0, 0 +-; LA64-NEXT: beqz $a4, .LBB15_1 +-; LA64-NEXT: b .LBB15_4 +-; LA64-NEXT: .LBB15_3: +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: .LBB15_4: +-; LA64-NEXT: xor $a0, $a3, $a1 +-; LA64-NEXT: sltui $a0, $a0, 1 +-; LA64-NEXT: ret +- %tmp = cmpxchg ptr %ptr, i64 %cmp, i64 %val acquire acquire +- %res = extractvalue { i64, i1 } %tmp, 1 +- ret i1 %res +-} +- +-define void @cmpxchg_i8_monotonic_monotonic(ptr %ptr, i8 %cmp, i8 %val) nounwind { +-; LA64-LABEL: cmpxchg_i8_monotonic_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: andi $a2, $a2, 255 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: ori $a4, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a4, $a3 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB16_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a5, $a4, $a3 +-; LA64-NEXT: bne $a5, $a1, .LBB16_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB16_1 Depth=1 +-; LA64-NEXT: andn $a5, $a4, $a3 +-; LA64-NEXT: or $a5, $a5, $a2 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB16_1 +-; LA64-NEXT: b .LBB16_4 +-; LA64-NEXT: .LBB16_3: +-; LA64-NEXT: dbar 1792 +-; LA64-NEXT: .LBB16_4: +-; LA64-NEXT: ret +- %res = cmpxchg ptr %ptr, i8 %cmp, i8 %val monotonic monotonic +- ret void +-} +- +-define void @cmpxchg_i16_monotonic_monotonic(ptr %ptr, i16 %cmp, i16 %val) nounwind { +-; LA64-LABEL: cmpxchg_i16_monotonic_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: bstrpick.d $a2, $a2, 15, 0 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: lu12i.w $a4, 15 +-; LA64-NEXT: ori $a4, $a4, 4095 +-; LA64-NEXT: sll.w $a3, $a4, $a3 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB17_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a5, $a4, $a3 +-; LA64-NEXT: bne $a5, $a1, .LBB17_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB17_1 Depth=1 +-; LA64-NEXT: andn $a5, $a4, $a3 +-; LA64-NEXT: or $a5, $a5, $a2 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB17_1 +-; LA64-NEXT: b .LBB17_4 +-; LA64-NEXT: .LBB17_3: +-; LA64-NEXT: dbar 1792 +-; LA64-NEXT: .LBB17_4: +-; LA64-NEXT: ret +- %res = cmpxchg ptr %ptr, i16 %cmp, i16 %val monotonic monotonic +- ret void +-} +- +-define void @cmpxchg_i32_monotonic_monotonic(ptr %ptr, i32 %cmp, i32 %val) nounwind { +-; LA64-LABEL: cmpxchg_i32_monotonic_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: .LBB18_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a3, $a0, 0 +-; LA64-NEXT: bne $a3, $a1, .LBB18_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB18_1 Depth=1 +-; LA64-NEXT: move $a4, $a2 +-; LA64-NEXT: sc.w $a4, $a0, 0 +-; LA64-NEXT: beqz $a4, .LBB18_1 +-; LA64-NEXT: b .LBB18_4 +-; LA64-NEXT: .LBB18_3: +-; LA64-NEXT: dbar 1792 +-; LA64-NEXT: .LBB18_4: +-; LA64-NEXT: ret +- %res = cmpxchg ptr %ptr, i32 %cmp, i32 %val monotonic monotonic +- ret void +-} +- +-define void @cmpxchg_i64_monotonic_monotonic(ptr %ptr, i64 %cmp, i64 %val) nounwind { +-; LA64-LABEL: cmpxchg_i64_monotonic_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: .LBB19_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.d $a3, $a0, 0 +-; LA64-NEXT: bne $a3, $a1, .LBB19_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB19_1 Depth=1 +-; LA64-NEXT: move $a4, $a2 +-; LA64-NEXT: sc.d $a4, $a0, 0 +-; LA64-NEXT: beqz $a4, .LBB19_1 +-; LA64-NEXT: b .LBB19_4 +-; LA64-NEXT: .LBB19_3: +-; LA64-NEXT: dbar 1792 +-; LA64-NEXT: .LBB19_4: +-; LA64-NEXT: ret +- %res = cmpxchg ptr %ptr, i64 %cmp, i64 %val monotonic monotonic +- ret void +-} +- +-define i8 @cmpxchg_i8_monotonic_monotonic_reti8(ptr %ptr, i8 %cmp, i8 %val) nounwind { +-; LA64-LABEL: cmpxchg_i8_monotonic_monotonic_reti8: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: ori $a4, $zero, 255 +-; LA64-NEXT: sll.w $a4, $a4, $a3 +-; LA64-NEXT: andi $a2, $a2, 255 +-; LA64-NEXT: addi.w $a4, $a4, 0 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB20_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a6, $a5, $a4 +-; LA64-NEXT: bne $a6, $a1, .LBB20_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB20_1 Depth=1 +-; LA64-NEXT: andn $a6, $a5, $a4 +-; LA64-NEXT: or $a6, $a6, $a2 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB20_1 +-; LA64-NEXT: b .LBB20_4 +-; LA64-NEXT: .LBB20_3: +-; LA64-NEXT: dbar 1792 +-; LA64-NEXT: .LBB20_4: +-; LA64-NEXT: srl.w $a0, $a5, $a3 +-; LA64-NEXT: ret +- %tmp = cmpxchg ptr %ptr, i8 %cmp, i8 %val monotonic monotonic +- %res = extractvalue { i8, i1 } %tmp, 0 +- ret i8 %res +-} +- +-define i16 @cmpxchg_i16_monotonic_monotonic_reti16(ptr %ptr, i16 %cmp, i16 %val) nounwind { +-; LA64-LABEL: cmpxchg_i16_monotonic_monotonic_reti16: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a3, 15 +-; LA64-NEXT: ori $a3, $a3, 4095 +-; LA64-NEXT: slli.d $a4, $a0, 3 +-; LA64-NEXT: sll.w $a3, $a3, $a4 +-; LA64-NEXT: bstrpick.d $a2, $a2, 15, 0 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: sll.w $a2, $a2, $a4 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a4 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB21_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a6, $a5, $a3 +-; LA64-NEXT: bne $a6, $a1, .LBB21_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB21_1 Depth=1 +-; LA64-NEXT: andn $a6, $a5, $a3 +-; LA64-NEXT: or $a6, $a6, $a2 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB21_1 +-; LA64-NEXT: b .LBB21_4 +-; LA64-NEXT: .LBB21_3: +-; LA64-NEXT: dbar 1792 +-; LA64-NEXT: .LBB21_4: +-; LA64-NEXT: srl.w $a0, $a5, $a4 +-; LA64-NEXT: ret +- %tmp = cmpxchg ptr %ptr, i16 %cmp, i16 %val monotonic monotonic +- %res = extractvalue { i16, i1 } %tmp, 0 +- ret i16 %res +-} +- +-define i32 @cmpxchg_i32_monotonic_monotonic_reti32(ptr %ptr, i32 %cmp, i32 %val) nounwind { +-; LA64-LABEL: cmpxchg_i32_monotonic_monotonic_reti32: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.w $a3, $a1, 0 +-; LA64-NEXT: .LBB22_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a1, $a0, 0 +-; LA64-NEXT: bne $a1, $a3, .LBB22_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB22_1 Depth=1 +-; LA64-NEXT: move $a4, $a2 +-; LA64-NEXT: sc.w $a4, $a0, 0 +-; LA64-NEXT: beqz $a4, .LBB22_1 +-; LA64-NEXT: b .LBB22_4 +-; LA64-NEXT: .LBB22_3: +-; LA64-NEXT: dbar 1792 +-; LA64-NEXT: .LBB22_4: +-; LA64-NEXT: move $a0, $a1 +-; LA64-NEXT: ret +- %tmp = cmpxchg ptr %ptr, i32 %cmp, i32 %val monotonic monotonic +- %res = extractvalue { i32, i1 } %tmp, 0 +- ret i32 %res +-} +- +-define i64 @cmpxchg_i64_monotonic_monotonic_reti64(ptr %ptr, i64 %cmp, i64 %val) nounwind { +-; LA64-LABEL: cmpxchg_i64_monotonic_monotonic_reti64: +-; LA64: # %bb.0: +-; LA64-NEXT: .LBB23_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.d $a3, $a0, 0 +-; LA64-NEXT: bne $a3, $a1, .LBB23_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB23_1 Depth=1 +-; LA64-NEXT: move $a4, $a2 +-; LA64-NEXT: sc.d $a4, $a0, 0 +-; LA64-NEXT: beqz $a4, .LBB23_1 +-; LA64-NEXT: b .LBB23_4 +-; LA64-NEXT: .LBB23_3: +-; LA64-NEXT: dbar 1792 +-; LA64-NEXT: .LBB23_4: +-; LA64-NEXT: move $a0, $a3 +-; LA64-NEXT: ret +- %tmp = cmpxchg ptr %ptr, i64 %cmp, i64 %val monotonic monotonic +- %res = extractvalue { i64, i1 } %tmp, 0 +- ret i64 %res +-} +- +-define i1 @cmpxchg_i8_monotonic_monotonic_reti1(ptr %ptr, i8 %cmp, i8 %val) nounwind { +-; LA64-LABEL: cmpxchg_i8_monotonic_monotonic_reti1: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: ori $a4, $zero, 255 +-; LA64-NEXT: sll.w $a4, $a4, $a3 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: andi $a2, $a2, 255 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: addi.w $a3, $a4, 0 +-; LA64-NEXT: .LBB24_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a6, $a5, $a3 +-; LA64-NEXT: bne $a6, $a1, .LBB24_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB24_1 Depth=1 +-; LA64-NEXT: andn $a6, $a5, $a3 +-; LA64-NEXT: or $a6, $a6, $a2 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB24_1 +-; LA64-NEXT: b .LBB24_4 +-; LA64-NEXT: .LBB24_3: +-; LA64-NEXT: dbar 1792 +-; LA64-NEXT: .LBB24_4: +-; LA64-NEXT: and $a0, $a5, $a4 +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: xor $a0, $a1, $a0 +-; LA64-NEXT: sltui $a0, $a0, 1 +-; LA64-NEXT: ret +- %tmp = cmpxchg ptr %ptr, i8 %cmp, i8 %val monotonic monotonic +- %res = extractvalue { i8, i1 } %tmp, 1 +- ret i1 %res +-} +- +-define i1 @cmpxchg_i16_monotonic_monotonic_reti1(ptr %ptr, i16 %cmp, i16 %val) nounwind { +-; LA64-LABEL: cmpxchg_i16_monotonic_monotonic_reti1: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: lu12i.w $a3, 15 +-; LA64-NEXT: ori $a3, $a3, 4095 +-; LA64-NEXT: slli.d $a4, $a0, 3 +-; LA64-NEXT: sll.w $a3, $a3, $a4 +-; LA64-NEXT: sll.w $a1, $a1, $a4 +-; LA64-NEXT: bstrpick.d $a2, $a2, 15, 0 +-; LA64-NEXT: sll.w $a2, $a2, $a4 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: addi.w $a4, $a3, 0 +-; LA64-NEXT: .LBB25_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a6, $a5, $a4 +-; LA64-NEXT: bne $a6, $a1, .LBB25_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB25_1 Depth=1 +-; LA64-NEXT: andn $a6, $a5, $a4 +-; LA64-NEXT: or $a6, $a6, $a2 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB25_1 +-; LA64-NEXT: b .LBB25_4 +-; LA64-NEXT: .LBB25_3: +-; LA64-NEXT: dbar 1792 +-; LA64-NEXT: .LBB25_4: +-; LA64-NEXT: and $a0, $a5, $a3 +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: xor $a0, $a1, $a0 +-; LA64-NEXT: sltui $a0, $a0, 1 +-; LA64-NEXT: ret +- %tmp = cmpxchg ptr %ptr, i16 %cmp, i16 %val monotonic monotonic +- %res = extractvalue { i16, i1 } %tmp, 1 +- ret i1 %res +-} +- +-define i1 @cmpxchg_i32_monotonic_monotonic_reti1(ptr %ptr, i32 %cmp, i32 %val) nounwind { +-; LA64-LABEL: cmpxchg_i32_monotonic_monotonic_reti1: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: .LBB26_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a3, $a0, 0 +-; LA64-NEXT: bne $a3, $a1, .LBB26_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB26_1 Depth=1 +-; LA64-NEXT: move $a4, $a2 +-; LA64-NEXT: sc.w $a4, $a0, 0 +-; LA64-NEXT: beqz $a4, .LBB26_1 +-; LA64-NEXT: b .LBB26_4 +-; LA64-NEXT: .LBB26_3: +-; LA64-NEXT: dbar 1792 +-; LA64-NEXT: .LBB26_4: +-; LA64-NEXT: xor $a0, $a3, $a1 +-; LA64-NEXT: sltui $a0, $a0, 1 +-; LA64-NEXT: ret +- %tmp = cmpxchg ptr %ptr, i32 %cmp, i32 %val monotonic monotonic +- %res = extractvalue { i32, i1 } %tmp, 1 +- ret i1 %res +-} +- +-define i1 @cmpxchg_i64_monotonic_monotonic_reti1(ptr %ptr, i64 %cmp, i64 %val) nounwind { +-; LA64-LABEL: cmpxchg_i64_monotonic_monotonic_reti1: +-; LA64: # %bb.0: +-; LA64-NEXT: .LBB27_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.d $a3, $a0, 0 +-; LA64-NEXT: bne $a3, $a1, .LBB27_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB27_1 Depth=1 +-; LA64-NEXT: move $a4, $a2 +-; LA64-NEXT: sc.d $a4, $a0, 0 +-; LA64-NEXT: beqz $a4, .LBB27_1 +-; LA64-NEXT: b .LBB27_4 +-; LA64-NEXT: .LBB27_3: +-; LA64-NEXT: dbar 1792 +-; LA64-NEXT: .LBB27_4: +-; LA64-NEXT: xor $a0, $a3, $a1 +-; LA64-NEXT: sltui $a0, $a0, 1 +-; LA64-NEXT: ret +- %tmp = cmpxchg ptr %ptr, i64 %cmp, i64 %val monotonic monotonic +- %res = extractvalue { i64, i1 } %tmp, 1 +- ret i1 %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw-fp.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw-fp.ll +deleted file mode 100644 +index 4d8160d70..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw-fp.ll ++++ /dev/null +@@ -1,3393 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA64F +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64D +- +-define float @float_fadd_acquire(ptr %p) nounwind { +-; LA64F-LABEL: float_fadd_acquire: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: addi.w $a1, $zero, 1 +-; LA64F-NEXT: movgr2fr.w $fa1, $a1 +-; LA64F-NEXT: ffint.s.w $fa1, $fa1 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB0_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Loop Header: Depth=1 +-; LA64F-NEXT: # Child Loop BB0_3 Depth 2 +-; LA64F-NEXT: fadd.s $fa2, $fa0, $fa1 +-; LA64F-NEXT: movfr2gr.s $a1, $fa2 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: addi.w $a2, $a2, 0 +-; LA64F-NEXT: .LBB0_3: # %atomicrmw.start +-; LA64F-NEXT: # Parent Loop BB0_1 Depth=1 +-; LA64F-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64F-NEXT: ll.w $a3, $a0, 0 +-; LA64F-NEXT: bne $a3, $a2, .LBB0_5 +-; LA64F-NEXT: # %bb.4: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB0_3 Depth=2 +-; LA64F-NEXT: move $a4, $a1 +-; LA64F-NEXT: sc.w $a4, $a0, 0 +-; LA64F-NEXT: beqz $a4, .LBB0_3 +-; LA64F-NEXT: b .LBB0_6 +-; LA64F-NEXT: .LBB0_5: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB0_1 Depth=1 +-; LA64F-NEXT: dbar 20 +-; LA64F-NEXT: .LBB0_6: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB0_1 Depth=1 +-; LA64F-NEXT: movgr2fr.w $fa0, $a3 +-; LA64F-NEXT: bne $a3, $a2, .LBB0_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: float_fadd_acquire: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: addi.w $a1, $zero, 1 +-; LA64D-NEXT: movgr2fr.w $fa1, $a1 +-; LA64D-NEXT: ffint.s.w $fa1, $fa1 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB0_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Loop Header: Depth=1 +-; LA64D-NEXT: # Child Loop BB0_3 Depth 2 +-; LA64D-NEXT: fadd.s $fa2, $fa0, $fa1 +-; LA64D-NEXT: movfr2gr.s $a1, $fa2 +-; LA64D-NEXT: movfr2gr.s $a2, $fa0 +-; LA64D-NEXT: addi.w $a2, $a2, 0 +-; LA64D-NEXT: .LBB0_3: # %atomicrmw.start +-; LA64D-NEXT: # Parent Loop BB0_1 Depth=1 +-; LA64D-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64D-NEXT: ll.w $a3, $a0, 0 +-; LA64D-NEXT: bne $a3, $a2, .LBB0_5 +-; LA64D-NEXT: # %bb.4: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB0_3 Depth=2 +-; LA64D-NEXT: move $a4, $a1 +-; LA64D-NEXT: sc.w $a4, $a0, 0 +-; LA64D-NEXT: beqz $a4, .LBB0_3 +-; LA64D-NEXT: b .LBB0_6 +-; LA64D-NEXT: .LBB0_5: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB0_1 Depth=1 +-; LA64D-NEXT: dbar 20 +-; LA64D-NEXT: .LBB0_6: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB0_1 Depth=1 +-; LA64D-NEXT: movgr2fr.w $fa0, $a3 +-; LA64D-NEXT: bne $a3, $a2, .LBB0_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: ret +- %v = atomicrmw fadd ptr %p, float 1.0 acquire, align 4 +- ret float %v +-} +- +-define float @float_fsub_acquire(ptr %p) nounwind { +-; LA64F-LABEL: float_fsub_acquire: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: pcalau12i $a1, %pc_hi20(.LCPI1_0) +-; LA64F-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI1_0) +-; LA64F-NEXT: fld.s $fa1, $a1, 0 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB1_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Loop Header: Depth=1 +-; LA64F-NEXT: # Child Loop BB1_3 Depth 2 +-; LA64F-NEXT: fadd.s $fa2, $fa0, $fa1 +-; LA64F-NEXT: movfr2gr.s $a1, $fa2 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: addi.w $a2, $a2, 0 +-; LA64F-NEXT: .LBB1_3: # %atomicrmw.start +-; LA64F-NEXT: # Parent Loop BB1_1 Depth=1 +-; LA64F-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64F-NEXT: ll.w $a3, $a0, 0 +-; LA64F-NEXT: bne $a3, $a2, .LBB1_5 +-; LA64F-NEXT: # %bb.4: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB1_3 Depth=2 +-; LA64F-NEXT: move $a4, $a1 +-; LA64F-NEXT: sc.w $a4, $a0, 0 +-; LA64F-NEXT: beqz $a4, .LBB1_3 +-; LA64F-NEXT: b .LBB1_6 +-; LA64F-NEXT: .LBB1_5: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB1_1 Depth=1 +-; LA64F-NEXT: dbar 20 +-; LA64F-NEXT: .LBB1_6: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB1_1 Depth=1 +-; LA64F-NEXT: movgr2fr.w $fa0, $a3 +-; LA64F-NEXT: bne $a3, $a2, .LBB1_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: float_fsub_acquire: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: pcalau12i $a1, %pc_hi20(.LCPI1_0) +-; LA64D-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI1_0) +-; LA64D-NEXT: fld.s $fa1, $a1, 0 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB1_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Loop Header: Depth=1 +-; LA64D-NEXT: # Child Loop BB1_3 Depth 2 +-; LA64D-NEXT: fadd.s $fa2, $fa0, $fa1 +-; LA64D-NEXT: movfr2gr.s $a1, $fa2 +-; LA64D-NEXT: movfr2gr.s $a2, $fa0 +-; LA64D-NEXT: addi.w $a2, $a2, 0 +-; LA64D-NEXT: .LBB1_3: # %atomicrmw.start +-; LA64D-NEXT: # Parent Loop BB1_1 Depth=1 +-; LA64D-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64D-NEXT: ll.w $a3, $a0, 0 +-; LA64D-NEXT: bne $a3, $a2, .LBB1_5 +-; LA64D-NEXT: # %bb.4: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB1_3 Depth=2 +-; LA64D-NEXT: move $a4, $a1 +-; LA64D-NEXT: sc.w $a4, $a0, 0 +-; LA64D-NEXT: beqz $a4, .LBB1_3 +-; LA64D-NEXT: b .LBB1_6 +-; LA64D-NEXT: .LBB1_5: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB1_1 Depth=1 +-; LA64D-NEXT: dbar 20 +-; LA64D-NEXT: .LBB1_6: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB1_1 Depth=1 +-; LA64D-NEXT: movgr2fr.w $fa0, $a3 +-; LA64D-NEXT: bne $a3, $a2, .LBB1_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: ret +- %v = atomicrmw fsub ptr %p, float 1.0 acquire, align 4 +- ret float %v +-} +- +-define float @float_fmin_acquire(ptr %p) nounwind { +-; LA64F-LABEL: float_fmin_acquire: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: addi.w $a1, $zero, 1 +-; LA64F-NEXT: movgr2fr.w $fa1, $a1 +-; LA64F-NEXT: ffint.s.w $fa1, $fa1 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB2_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Loop Header: Depth=1 +-; LA64F-NEXT: # Child Loop BB2_3 Depth 2 +-; LA64F-NEXT: fmax.s $fa2, $fa0, $fa0 +-; LA64F-NEXT: fmin.s $fa2, $fa2, $fa1 +-; LA64F-NEXT: movfr2gr.s $a1, $fa2 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: addi.w $a2, $a2, 0 +-; LA64F-NEXT: .LBB2_3: # %atomicrmw.start +-; LA64F-NEXT: # Parent Loop BB2_1 Depth=1 +-; LA64F-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64F-NEXT: ll.w $a3, $a0, 0 +-; LA64F-NEXT: bne $a3, $a2, .LBB2_5 +-; LA64F-NEXT: # %bb.4: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB2_3 Depth=2 +-; LA64F-NEXT: move $a4, $a1 +-; LA64F-NEXT: sc.w $a4, $a0, 0 +-; LA64F-NEXT: beqz $a4, .LBB2_3 +-; LA64F-NEXT: b .LBB2_6 +-; LA64F-NEXT: .LBB2_5: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB2_1 Depth=1 +-; LA64F-NEXT: dbar 20 +-; LA64F-NEXT: .LBB2_6: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB2_1 Depth=1 +-; LA64F-NEXT: movgr2fr.w $fa0, $a3 +-; LA64F-NEXT: bne $a3, $a2, .LBB2_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: float_fmin_acquire: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: addi.w $a1, $zero, 1 +-; LA64D-NEXT: movgr2fr.w $fa1, $a1 +-; LA64D-NEXT: ffint.s.w $fa1, $fa1 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB2_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Loop Header: Depth=1 +-; LA64D-NEXT: # Child Loop BB2_3 Depth 2 +-; LA64D-NEXT: fmax.s $fa2, $fa0, $fa0 +-; LA64D-NEXT: fmin.s $fa2, $fa2, $fa1 +-; LA64D-NEXT: movfr2gr.s $a1, $fa2 +-; LA64D-NEXT: movfr2gr.s $a2, $fa0 +-; LA64D-NEXT: addi.w $a2, $a2, 0 +-; LA64D-NEXT: .LBB2_3: # %atomicrmw.start +-; LA64D-NEXT: # Parent Loop BB2_1 Depth=1 +-; LA64D-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64D-NEXT: ll.w $a3, $a0, 0 +-; LA64D-NEXT: bne $a3, $a2, .LBB2_5 +-; LA64D-NEXT: # %bb.4: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB2_3 Depth=2 +-; LA64D-NEXT: move $a4, $a1 +-; LA64D-NEXT: sc.w $a4, $a0, 0 +-; LA64D-NEXT: beqz $a4, .LBB2_3 +-; LA64D-NEXT: b .LBB2_6 +-; LA64D-NEXT: .LBB2_5: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB2_1 Depth=1 +-; LA64D-NEXT: dbar 20 +-; LA64D-NEXT: .LBB2_6: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB2_1 Depth=1 +-; LA64D-NEXT: movgr2fr.w $fa0, $a3 +-; LA64D-NEXT: bne $a3, $a2, .LBB2_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: ret +- %v = atomicrmw fmin ptr %p, float 1.0 acquire, align 4 +- ret float %v +-} +- +-define float @float_fmax_acquire(ptr %p) nounwind { +-; LA64F-LABEL: float_fmax_acquire: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: addi.w $a1, $zero, 1 +-; LA64F-NEXT: movgr2fr.w $fa1, $a1 +-; LA64F-NEXT: ffint.s.w $fa1, $fa1 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB3_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Loop Header: Depth=1 +-; LA64F-NEXT: # Child Loop BB3_3 Depth 2 +-; LA64F-NEXT: fmax.s $fa2, $fa0, $fa0 +-; LA64F-NEXT: fmax.s $fa2, $fa2, $fa1 +-; LA64F-NEXT: movfr2gr.s $a1, $fa2 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: addi.w $a2, $a2, 0 +-; LA64F-NEXT: .LBB3_3: # %atomicrmw.start +-; LA64F-NEXT: # Parent Loop BB3_1 Depth=1 +-; LA64F-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64F-NEXT: ll.w $a3, $a0, 0 +-; LA64F-NEXT: bne $a3, $a2, .LBB3_5 +-; LA64F-NEXT: # %bb.4: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB3_3 Depth=2 +-; LA64F-NEXT: move $a4, $a1 +-; LA64F-NEXT: sc.w $a4, $a0, 0 +-; LA64F-NEXT: beqz $a4, .LBB3_3 +-; LA64F-NEXT: b .LBB3_6 +-; LA64F-NEXT: .LBB3_5: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB3_1 Depth=1 +-; LA64F-NEXT: dbar 20 +-; LA64F-NEXT: .LBB3_6: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB3_1 Depth=1 +-; LA64F-NEXT: movgr2fr.w $fa0, $a3 +-; LA64F-NEXT: bne $a3, $a2, .LBB3_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: float_fmax_acquire: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: addi.w $a1, $zero, 1 +-; LA64D-NEXT: movgr2fr.w $fa1, $a1 +-; LA64D-NEXT: ffint.s.w $fa1, $fa1 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB3_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Loop Header: Depth=1 +-; LA64D-NEXT: # Child Loop BB3_3 Depth 2 +-; LA64D-NEXT: fmax.s $fa2, $fa0, $fa0 +-; LA64D-NEXT: fmax.s $fa2, $fa2, $fa1 +-; LA64D-NEXT: movfr2gr.s $a1, $fa2 +-; LA64D-NEXT: movfr2gr.s $a2, $fa0 +-; LA64D-NEXT: addi.w $a2, $a2, 0 +-; LA64D-NEXT: .LBB3_3: # %atomicrmw.start +-; LA64D-NEXT: # Parent Loop BB3_1 Depth=1 +-; LA64D-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64D-NEXT: ll.w $a3, $a0, 0 +-; LA64D-NEXT: bne $a3, $a2, .LBB3_5 +-; LA64D-NEXT: # %bb.4: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB3_3 Depth=2 +-; LA64D-NEXT: move $a4, $a1 +-; LA64D-NEXT: sc.w $a4, $a0, 0 +-; LA64D-NEXT: beqz $a4, .LBB3_3 +-; LA64D-NEXT: b .LBB3_6 +-; LA64D-NEXT: .LBB3_5: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB3_1 Depth=1 +-; LA64D-NEXT: dbar 20 +-; LA64D-NEXT: .LBB3_6: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB3_1 Depth=1 +-; LA64D-NEXT: movgr2fr.w $fa0, $a3 +-; LA64D-NEXT: bne $a3, $a2, .LBB3_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: ret +- %v = atomicrmw fmax ptr %p, float 1.0 acquire, align 4 +- ret float %v +-} +- +-define double @double_fadd_acquire(ptr %p) nounwind { +-; LA64F-LABEL: double_fadd_acquire: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -80 +-; LA64F-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s4, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 0 +-; LA64F-NEXT: lu52i.d $s0, $zero, 1023 +-; LA64F-NEXT: ori $s1, $zero, 8 +-; LA64F-NEXT: addi.d $s2, $sp, 16 +-; LA64F-NEXT: addi.d $s3, $sp, 8 +-; LA64F-NEXT: ori $s4, $zero, 2 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB4_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64F-NEXT: st.d $a0, $sp, 16 +-; LA64F-NEXT: move $a1, $s0 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $sp, 8 +-; LA64F-NEXT: move $a0, $s1 +-; LA64F-NEXT: move $a1, $fp +-; LA64F-NEXT: move $a2, $s2 +-; LA64F-NEXT: move $a3, $s3 +-; LA64F-NEXT: move $a4, $s4 +-; LA64F-NEXT: move $a5, $s4 +-; LA64F-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64F-NEXT: move $a1, $a0 +-; LA64F-NEXT: ld.d $a0, $sp, 16 +-; LA64F-NEXT: beqz $a1, .LBB4_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ld.d $s4, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 80 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: double_fadd_acquire: +-; LA64D: # %bb.0: +-; LA64D-NEXT: addi.d $sp, $sp, -80 +-; LA64D-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64D-NEXT: fst.d $fs0, $sp, 24 # 8-byte Folded Spill +-; LA64D-NEXT: move $fp, $a0 +-; LA64D-NEXT: fld.d $fa0, $a0, 0 +-; LA64D-NEXT: addi.d $a0, $zero, 1 +-; LA64D-NEXT: movgr2fr.d $fa1, $a0 +-; LA64D-NEXT: ffint.d.l $fs0, $fa1 +-; LA64D-NEXT: ori $s0, $zero, 8 +-; LA64D-NEXT: addi.d $s1, $sp, 16 +-; LA64D-NEXT: addi.d $s2, $sp, 8 +-; LA64D-NEXT: ori $s3, $zero, 2 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB4_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64D-NEXT: fst.d $fa0, $sp, 16 +-; LA64D-NEXT: fadd.d $fa0, $fa0, $fs0 +-; LA64D-NEXT: fst.d $fa0, $sp, 8 +-; LA64D-NEXT: move $a0, $s0 +-; LA64D-NEXT: move $a1, $fp +-; LA64D-NEXT: move $a2, $s1 +-; LA64D-NEXT: move $a3, $s2 +-; LA64D-NEXT: move $a4, $s3 +-; LA64D-NEXT: move $a5, $s3 +-; LA64D-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64D-NEXT: fld.d $fa0, $sp, 16 +-; LA64D-NEXT: beqz $a0, .LBB4_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: fld.d $fs0, $sp, 24 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64D-NEXT: addi.d $sp, $sp, 80 +-; LA64D-NEXT: ret +- %v = atomicrmw fadd ptr %p, double 1.0 acquire, align 4 +- ret double %v +-} +- +-define double @double_fsub_acquire(ptr %p) nounwind { +-; LA64F-LABEL: double_fsub_acquire: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -80 +-; LA64F-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s4, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 0 +-; LA64F-NEXT: lu52i.d $s0, $zero, -1025 +-; LA64F-NEXT: ori $s1, $zero, 8 +-; LA64F-NEXT: addi.d $s2, $sp, 16 +-; LA64F-NEXT: addi.d $s3, $sp, 8 +-; LA64F-NEXT: ori $s4, $zero, 2 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB5_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64F-NEXT: st.d $a0, $sp, 16 +-; LA64F-NEXT: move $a1, $s0 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $sp, 8 +-; LA64F-NEXT: move $a0, $s1 +-; LA64F-NEXT: move $a1, $fp +-; LA64F-NEXT: move $a2, $s2 +-; LA64F-NEXT: move $a3, $s3 +-; LA64F-NEXT: move $a4, $s4 +-; LA64F-NEXT: move $a5, $s4 +-; LA64F-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64F-NEXT: move $a1, $a0 +-; LA64F-NEXT: ld.d $a0, $sp, 16 +-; LA64F-NEXT: beqz $a1, .LBB5_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ld.d $s4, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 80 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: double_fsub_acquire: +-; LA64D: # %bb.0: +-; LA64D-NEXT: addi.d $sp, $sp, -80 +-; LA64D-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64D-NEXT: fst.d $fs0, $sp, 24 # 8-byte Folded Spill +-; LA64D-NEXT: move $fp, $a0 +-; LA64D-NEXT: fld.d $fa0, $a0, 0 +-; LA64D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI5_0) +-; LA64D-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI5_0) +-; LA64D-NEXT: fld.d $fs0, $a0, 0 +-; LA64D-NEXT: ori $s0, $zero, 8 +-; LA64D-NEXT: addi.d $s1, $sp, 16 +-; LA64D-NEXT: addi.d $s2, $sp, 8 +-; LA64D-NEXT: ori $s3, $zero, 2 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB5_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64D-NEXT: fst.d $fa0, $sp, 16 +-; LA64D-NEXT: fadd.d $fa0, $fa0, $fs0 +-; LA64D-NEXT: fst.d $fa0, $sp, 8 +-; LA64D-NEXT: move $a0, $s0 +-; LA64D-NEXT: move $a1, $fp +-; LA64D-NEXT: move $a2, $s1 +-; LA64D-NEXT: move $a3, $s2 +-; LA64D-NEXT: move $a4, $s3 +-; LA64D-NEXT: move $a5, $s3 +-; LA64D-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64D-NEXT: fld.d $fa0, $sp, 16 +-; LA64D-NEXT: beqz $a0, .LBB5_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: fld.d $fs0, $sp, 24 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64D-NEXT: addi.d $sp, $sp, 80 +-; LA64D-NEXT: ret +- %v = atomicrmw fsub ptr %p, double 1.0 acquire, align 4 +- ret double %v +-} +- +-define double @double_fmin_acquire(ptr %p) nounwind { +-; LA64F-LABEL: double_fmin_acquire: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -80 +-; LA64F-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s4, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 0 +-; LA64F-NEXT: lu52i.d $s0, $zero, 1023 +-; LA64F-NEXT: ori $s1, $zero, 8 +-; LA64F-NEXT: addi.d $s2, $sp, 16 +-; LA64F-NEXT: addi.d $s3, $sp, 8 +-; LA64F-NEXT: ori $s4, $zero, 2 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB6_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64F-NEXT: st.d $a0, $sp, 16 +-; LA64F-NEXT: move $a1, $s0 +-; LA64F-NEXT: bl %plt(fmin) +-; LA64F-NEXT: st.d $a0, $sp, 8 +-; LA64F-NEXT: move $a0, $s1 +-; LA64F-NEXT: move $a1, $fp +-; LA64F-NEXT: move $a2, $s2 +-; LA64F-NEXT: move $a3, $s3 +-; LA64F-NEXT: move $a4, $s4 +-; LA64F-NEXT: move $a5, $s4 +-; LA64F-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64F-NEXT: move $a1, $a0 +-; LA64F-NEXT: ld.d $a0, $sp, 16 +-; LA64F-NEXT: beqz $a1, .LBB6_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ld.d $s4, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 80 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: double_fmin_acquire: +-; LA64D: # %bb.0: +-; LA64D-NEXT: addi.d $sp, $sp, -80 +-; LA64D-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64D-NEXT: fst.d $fs0, $sp, 24 # 8-byte Folded Spill +-; LA64D-NEXT: move $fp, $a0 +-; LA64D-NEXT: fld.d $fa0, $a0, 0 +-; LA64D-NEXT: addi.d $a0, $zero, 1 +-; LA64D-NEXT: movgr2fr.d $fa1, $a0 +-; LA64D-NEXT: ffint.d.l $fs0, $fa1 +-; LA64D-NEXT: ori $s0, $zero, 8 +-; LA64D-NEXT: addi.d $s1, $sp, 16 +-; LA64D-NEXT: addi.d $s2, $sp, 8 +-; LA64D-NEXT: ori $s3, $zero, 2 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB6_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64D-NEXT: fst.d $fa0, $sp, 16 +-; LA64D-NEXT: fmax.d $fa0, $fa0, $fa0 +-; LA64D-NEXT: fmin.d $fa0, $fa0, $fs0 +-; LA64D-NEXT: fst.d $fa0, $sp, 8 +-; LA64D-NEXT: move $a0, $s0 +-; LA64D-NEXT: move $a1, $fp +-; LA64D-NEXT: move $a2, $s1 +-; LA64D-NEXT: move $a3, $s2 +-; LA64D-NEXT: move $a4, $s3 +-; LA64D-NEXT: move $a5, $s3 +-; LA64D-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64D-NEXT: fld.d $fa0, $sp, 16 +-; LA64D-NEXT: beqz $a0, .LBB6_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: fld.d $fs0, $sp, 24 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64D-NEXT: addi.d $sp, $sp, 80 +-; LA64D-NEXT: ret +- %v = atomicrmw fmin ptr %p, double 1.0 acquire, align 4 +- ret double %v +-} +- +-define double @double_fmax_acquire(ptr %p) nounwind { +-; LA64F-LABEL: double_fmax_acquire: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -80 +-; LA64F-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s4, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 0 +-; LA64F-NEXT: lu52i.d $s0, $zero, 1023 +-; LA64F-NEXT: ori $s1, $zero, 8 +-; LA64F-NEXT: addi.d $s2, $sp, 16 +-; LA64F-NEXT: addi.d $s3, $sp, 8 +-; LA64F-NEXT: ori $s4, $zero, 2 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB7_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64F-NEXT: st.d $a0, $sp, 16 +-; LA64F-NEXT: move $a1, $s0 +-; LA64F-NEXT: bl %plt(fmax) +-; LA64F-NEXT: st.d $a0, $sp, 8 +-; LA64F-NEXT: move $a0, $s1 +-; LA64F-NEXT: move $a1, $fp +-; LA64F-NEXT: move $a2, $s2 +-; LA64F-NEXT: move $a3, $s3 +-; LA64F-NEXT: move $a4, $s4 +-; LA64F-NEXT: move $a5, $s4 +-; LA64F-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64F-NEXT: move $a1, $a0 +-; LA64F-NEXT: ld.d $a0, $sp, 16 +-; LA64F-NEXT: beqz $a1, .LBB7_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ld.d $s4, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 80 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: double_fmax_acquire: +-; LA64D: # %bb.0: +-; LA64D-NEXT: addi.d $sp, $sp, -80 +-; LA64D-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64D-NEXT: fst.d $fs0, $sp, 24 # 8-byte Folded Spill +-; LA64D-NEXT: move $fp, $a0 +-; LA64D-NEXT: fld.d $fa0, $a0, 0 +-; LA64D-NEXT: addi.d $a0, $zero, 1 +-; LA64D-NEXT: movgr2fr.d $fa1, $a0 +-; LA64D-NEXT: ffint.d.l $fs0, $fa1 +-; LA64D-NEXT: ori $s0, $zero, 8 +-; LA64D-NEXT: addi.d $s1, $sp, 16 +-; LA64D-NEXT: addi.d $s2, $sp, 8 +-; LA64D-NEXT: ori $s3, $zero, 2 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB7_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64D-NEXT: fst.d $fa0, $sp, 16 +-; LA64D-NEXT: fmax.d $fa0, $fa0, $fa0 +-; LA64D-NEXT: fmax.d $fa0, $fa0, $fs0 +-; LA64D-NEXT: fst.d $fa0, $sp, 8 +-; LA64D-NEXT: move $a0, $s0 +-; LA64D-NEXT: move $a1, $fp +-; LA64D-NEXT: move $a2, $s1 +-; LA64D-NEXT: move $a3, $s2 +-; LA64D-NEXT: move $a4, $s3 +-; LA64D-NEXT: move $a5, $s3 +-; LA64D-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64D-NEXT: fld.d $fa0, $sp, 16 +-; LA64D-NEXT: beqz $a0, .LBB7_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: fld.d $fs0, $sp, 24 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64D-NEXT: addi.d $sp, $sp, 80 +-; LA64D-NEXT: ret +- %v = atomicrmw fmax ptr %p, double 1.0 acquire, align 4 +- ret double %v +-} +- +-define float @float_fadd_release(ptr %p) nounwind { +-; LA64F-LABEL: float_fadd_release: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: addi.w $a1, $zero, 1 +-; LA64F-NEXT: movgr2fr.w $fa1, $a1 +-; LA64F-NEXT: ffint.s.w $fa1, $fa1 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB8_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Loop Header: Depth=1 +-; LA64F-NEXT: # Child Loop BB8_3 Depth 2 +-; LA64F-NEXT: fadd.s $fa2, $fa0, $fa1 +-; LA64F-NEXT: movfr2gr.s $a1, $fa2 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: addi.w $a2, $a2, 0 +-; LA64F-NEXT: .LBB8_3: # %atomicrmw.start +-; LA64F-NEXT: # Parent Loop BB8_1 Depth=1 +-; LA64F-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64F-NEXT: ll.w $a3, $a0, 0 +-; LA64F-NEXT: bne $a3, $a2, .LBB8_5 +-; LA64F-NEXT: # %bb.4: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB8_3 Depth=2 +-; LA64F-NEXT: move $a4, $a1 +-; LA64F-NEXT: sc.w $a4, $a0, 0 +-; LA64F-NEXT: beqz $a4, .LBB8_3 +-; LA64F-NEXT: b .LBB8_6 +-; LA64F-NEXT: .LBB8_5: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB8_1 Depth=1 +-; LA64F-NEXT: dbar 1792 +-; LA64F-NEXT: .LBB8_6: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB8_1 Depth=1 +-; LA64F-NEXT: movgr2fr.w $fa0, $a3 +-; LA64F-NEXT: bne $a3, $a2, .LBB8_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: float_fadd_release: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: addi.w $a1, $zero, 1 +-; LA64D-NEXT: movgr2fr.w $fa1, $a1 +-; LA64D-NEXT: ffint.s.w $fa1, $fa1 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB8_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Loop Header: Depth=1 +-; LA64D-NEXT: # Child Loop BB8_3 Depth 2 +-; LA64D-NEXT: fadd.s $fa2, $fa0, $fa1 +-; LA64D-NEXT: movfr2gr.s $a1, $fa2 +-; LA64D-NEXT: movfr2gr.s $a2, $fa0 +-; LA64D-NEXT: addi.w $a2, $a2, 0 +-; LA64D-NEXT: .LBB8_3: # %atomicrmw.start +-; LA64D-NEXT: # Parent Loop BB8_1 Depth=1 +-; LA64D-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64D-NEXT: ll.w $a3, $a0, 0 +-; LA64D-NEXT: bne $a3, $a2, .LBB8_5 +-; LA64D-NEXT: # %bb.4: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB8_3 Depth=2 +-; LA64D-NEXT: move $a4, $a1 +-; LA64D-NEXT: sc.w $a4, $a0, 0 +-; LA64D-NEXT: beqz $a4, .LBB8_3 +-; LA64D-NEXT: b .LBB8_6 +-; LA64D-NEXT: .LBB8_5: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB8_1 Depth=1 +-; LA64D-NEXT: dbar 1792 +-; LA64D-NEXT: .LBB8_6: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB8_1 Depth=1 +-; LA64D-NEXT: movgr2fr.w $fa0, $a3 +-; LA64D-NEXT: bne $a3, $a2, .LBB8_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: ret +- %v = atomicrmw fadd ptr %p, float 1.0 release, align 4 +- ret float %v +-} +- +-define float @float_fsub_release(ptr %p) nounwind { +-; LA64F-LABEL: float_fsub_release: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: pcalau12i $a1, %pc_hi20(.LCPI9_0) +-; LA64F-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI9_0) +-; LA64F-NEXT: fld.s $fa1, $a1, 0 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB9_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Loop Header: Depth=1 +-; LA64F-NEXT: # Child Loop BB9_3 Depth 2 +-; LA64F-NEXT: fadd.s $fa2, $fa0, $fa1 +-; LA64F-NEXT: movfr2gr.s $a1, $fa2 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: addi.w $a2, $a2, 0 +-; LA64F-NEXT: .LBB9_3: # %atomicrmw.start +-; LA64F-NEXT: # Parent Loop BB9_1 Depth=1 +-; LA64F-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64F-NEXT: ll.w $a3, $a0, 0 +-; LA64F-NEXT: bne $a3, $a2, .LBB9_5 +-; LA64F-NEXT: # %bb.4: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB9_3 Depth=2 +-; LA64F-NEXT: move $a4, $a1 +-; LA64F-NEXT: sc.w $a4, $a0, 0 +-; LA64F-NEXT: beqz $a4, .LBB9_3 +-; LA64F-NEXT: b .LBB9_6 +-; LA64F-NEXT: .LBB9_5: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB9_1 Depth=1 +-; LA64F-NEXT: dbar 1792 +-; LA64F-NEXT: .LBB9_6: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB9_1 Depth=1 +-; LA64F-NEXT: movgr2fr.w $fa0, $a3 +-; LA64F-NEXT: bne $a3, $a2, .LBB9_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: float_fsub_release: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: pcalau12i $a1, %pc_hi20(.LCPI9_0) +-; LA64D-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI9_0) +-; LA64D-NEXT: fld.s $fa1, $a1, 0 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB9_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Loop Header: Depth=1 +-; LA64D-NEXT: # Child Loop BB9_3 Depth 2 +-; LA64D-NEXT: fadd.s $fa2, $fa0, $fa1 +-; LA64D-NEXT: movfr2gr.s $a1, $fa2 +-; LA64D-NEXT: movfr2gr.s $a2, $fa0 +-; LA64D-NEXT: addi.w $a2, $a2, 0 +-; LA64D-NEXT: .LBB9_3: # %atomicrmw.start +-; LA64D-NEXT: # Parent Loop BB9_1 Depth=1 +-; LA64D-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64D-NEXT: ll.w $a3, $a0, 0 +-; LA64D-NEXT: bne $a3, $a2, .LBB9_5 +-; LA64D-NEXT: # %bb.4: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB9_3 Depth=2 +-; LA64D-NEXT: move $a4, $a1 +-; LA64D-NEXT: sc.w $a4, $a0, 0 +-; LA64D-NEXT: beqz $a4, .LBB9_3 +-; LA64D-NEXT: b .LBB9_6 +-; LA64D-NEXT: .LBB9_5: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB9_1 Depth=1 +-; LA64D-NEXT: dbar 1792 +-; LA64D-NEXT: .LBB9_6: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB9_1 Depth=1 +-; LA64D-NEXT: movgr2fr.w $fa0, $a3 +-; LA64D-NEXT: bne $a3, $a2, .LBB9_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: ret +- %v = atomicrmw fsub ptr %p, float 1.0 release, align 4 +- ret float %v +-} +- +-define float @float_fmin_release(ptr %p) nounwind { +-; LA64F-LABEL: float_fmin_release: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: addi.w $a1, $zero, 1 +-; LA64F-NEXT: movgr2fr.w $fa1, $a1 +-; LA64F-NEXT: ffint.s.w $fa1, $fa1 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB10_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Loop Header: Depth=1 +-; LA64F-NEXT: # Child Loop BB10_3 Depth 2 +-; LA64F-NEXT: fmax.s $fa2, $fa0, $fa0 +-; LA64F-NEXT: fmin.s $fa2, $fa2, $fa1 +-; LA64F-NEXT: movfr2gr.s $a1, $fa2 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: addi.w $a2, $a2, 0 +-; LA64F-NEXT: .LBB10_3: # %atomicrmw.start +-; LA64F-NEXT: # Parent Loop BB10_1 Depth=1 +-; LA64F-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64F-NEXT: ll.w $a3, $a0, 0 +-; LA64F-NEXT: bne $a3, $a2, .LBB10_5 +-; LA64F-NEXT: # %bb.4: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB10_3 Depth=2 +-; LA64F-NEXT: move $a4, $a1 +-; LA64F-NEXT: sc.w $a4, $a0, 0 +-; LA64F-NEXT: beqz $a4, .LBB10_3 +-; LA64F-NEXT: b .LBB10_6 +-; LA64F-NEXT: .LBB10_5: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB10_1 Depth=1 +-; LA64F-NEXT: dbar 1792 +-; LA64F-NEXT: .LBB10_6: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB10_1 Depth=1 +-; LA64F-NEXT: movgr2fr.w $fa0, $a3 +-; LA64F-NEXT: bne $a3, $a2, .LBB10_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: float_fmin_release: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: addi.w $a1, $zero, 1 +-; LA64D-NEXT: movgr2fr.w $fa1, $a1 +-; LA64D-NEXT: ffint.s.w $fa1, $fa1 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB10_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Loop Header: Depth=1 +-; LA64D-NEXT: # Child Loop BB10_3 Depth 2 +-; LA64D-NEXT: fmax.s $fa2, $fa0, $fa0 +-; LA64D-NEXT: fmin.s $fa2, $fa2, $fa1 +-; LA64D-NEXT: movfr2gr.s $a1, $fa2 +-; LA64D-NEXT: movfr2gr.s $a2, $fa0 +-; LA64D-NEXT: addi.w $a2, $a2, 0 +-; LA64D-NEXT: .LBB10_3: # %atomicrmw.start +-; LA64D-NEXT: # Parent Loop BB10_1 Depth=1 +-; LA64D-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64D-NEXT: ll.w $a3, $a0, 0 +-; LA64D-NEXT: bne $a3, $a2, .LBB10_5 +-; LA64D-NEXT: # %bb.4: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB10_3 Depth=2 +-; LA64D-NEXT: move $a4, $a1 +-; LA64D-NEXT: sc.w $a4, $a0, 0 +-; LA64D-NEXT: beqz $a4, .LBB10_3 +-; LA64D-NEXT: b .LBB10_6 +-; LA64D-NEXT: .LBB10_5: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB10_1 Depth=1 +-; LA64D-NEXT: dbar 1792 +-; LA64D-NEXT: .LBB10_6: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB10_1 Depth=1 +-; LA64D-NEXT: movgr2fr.w $fa0, $a3 +-; LA64D-NEXT: bne $a3, $a2, .LBB10_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: ret +- %v = atomicrmw fmin ptr %p, float 1.0 release, align 4 +- ret float %v +-} +- +-define float @float_fmax_release(ptr %p) nounwind { +-; LA64F-LABEL: float_fmax_release: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: addi.w $a1, $zero, 1 +-; LA64F-NEXT: movgr2fr.w $fa1, $a1 +-; LA64F-NEXT: ffint.s.w $fa1, $fa1 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB11_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Loop Header: Depth=1 +-; LA64F-NEXT: # Child Loop BB11_3 Depth 2 +-; LA64F-NEXT: fmax.s $fa2, $fa0, $fa0 +-; LA64F-NEXT: fmax.s $fa2, $fa2, $fa1 +-; LA64F-NEXT: movfr2gr.s $a1, $fa2 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: addi.w $a2, $a2, 0 +-; LA64F-NEXT: .LBB11_3: # %atomicrmw.start +-; LA64F-NEXT: # Parent Loop BB11_1 Depth=1 +-; LA64F-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64F-NEXT: ll.w $a3, $a0, 0 +-; LA64F-NEXT: bne $a3, $a2, .LBB11_5 +-; LA64F-NEXT: # %bb.4: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB11_3 Depth=2 +-; LA64F-NEXT: move $a4, $a1 +-; LA64F-NEXT: sc.w $a4, $a0, 0 +-; LA64F-NEXT: beqz $a4, .LBB11_3 +-; LA64F-NEXT: b .LBB11_6 +-; LA64F-NEXT: .LBB11_5: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB11_1 Depth=1 +-; LA64F-NEXT: dbar 1792 +-; LA64F-NEXT: .LBB11_6: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB11_1 Depth=1 +-; LA64F-NEXT: movgr2fr.w $fa0, $a3 +-; LA64F-NEXT: bne $a3, $a2, .LBB11_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: float_fmax_release: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: addi.w $a1, $zero, 1 +-; LA64D-NEXT: movgr2fr.w $fa1, $a1 +-; LA64D-NEXT: ffint.s.w $fa1, $fa1 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB11_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Loop Header: Depth=1 +-; LA64D-NEXT: # Child Loop BB11_3 Depth 2 +-; LA64D-NEXT: fmax.s $fa2, $fa0, $fa0 +-; LA64D-NEXT: fmax.s $fa2, $fa2, $fa1 +-; LA64D-NEXT: movfr2gr.s $a1, $fa2 +-; LA64D-NEXT: movfr2gr.s $a2, $fa0 +-; LA64D-NEXT: addi.w $a2, $a2, 0 +-; LA64D-NEXT: .LBB11_3: # %atomicrmw.start +-; LA64D-NEXT: # Parent Loop BB11_1 Depth=1 +-; LA64D-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64D-NEXT: ll.w $a3, $a0, 0 +-; LA64D-NEXT: bne $a3, $a2, .LBB11_5 +-; LA64D-NEXT: # %bb.4: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB11_3 Depth=2 +-; LA64D-NEXT: move $a4, $a1 +-; LA64D-NEXT: sc.w $a4, $a0, 0 +-; LA64D-NEXT: beqz $a4, .LBB11_3 +-; LA64D-NEXT: b .LBB11_6 +-; LA64D-NEXT: .LBB11_5: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB11_1 Depth=1 +-; LA64D-NEXT: dbar 1792 +-; LA64D-NEXT: .LBB11_6: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB11_1 Depth=1 +-; LA64D-NEXT: movgr2fr.w $fa0, $a3 +-; LA64D-NEXT: bne $a3, $a2, .LBB11_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: ret +- %v = atomicrmw fmax ptr %p, float 1.0 release, align 4 +- ret float %v +-} +- +-define double @double_fadd_release(ptr %p) nounwind { +-; LA64F-LABEL: double_fadd_release: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -80 +-; LA64F-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s4, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 0 +-; LA64F-NEXT: lu52i.d $s0, $zero, 1023 +-; LA64F-NEXT: ori $s1, $zero, 8 +-; LA64F-NEXT: addi.d $s2, $sp, 16 +-; LA64F-NEXT: addi.d $s3, $sp, 8 +-; LA64F-NEXT: ori $s4, $zero, 3 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB12_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64F-NEXT: st.d $a0, $sp, 16 +-; LA64F-NEXT: move $a1, $s0 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $sp, 8 +-; LA64F-NEXT: move $a0, $s1 +-; LA64F-NEXT: move $a1, $fp +-; LA64F-NEXT: move $a2, $s2 +-; LA64F-NEXT: move $a3, $s3 +-; LA64F-NEXT: move $a4, $s4 +-; LA64F-NEXT: move $a5, $zero +-; LA64F-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64F-NEXT: move $a1, $a0 +-; LA64F-NEXT: ld.d $a0, $sp, 16 +-; LA64F-NEXT: beqz $a1, .LBB12_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ld.d $s4, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 80 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: double_fadd_release: +-; LA64D: # %bb.0: +-; LA64D-NEXT: addi.d $sp, $sp, -80 +-; LA64D-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64D-NEXT: fst.d $fs0, $sp, 24 # 8-byte Folded Spill +-; LA64D-NEXT: move $fp, $a0 +-; LA64D-NEXT: fld.d $fa0, $a0, 0 +-; LA64D-NEXT: addi.d $a0, $zero, 1 +-; LA64D-NEXT: movgr2fr.d $fa1, $a0 +-; LA64D-NEXT: ffint.d.l $fs0, $fa1 +-; LA64D-NEXT: ori $s0, $zero, 8 +-; LA64D-NEXT: addi.d $s1, $sp, 16 +-; LA64D-NEXT: addi.d $s2, $sp, 8 +-; LA64D-NEXT: ori $s3, $zero, 3 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB12_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64D-NEXT: fst.d $fa0, $sp, 16 +-; LA64D-NEXT: fadd.d $fa0, $fa0, $fs0 +-; LA64D-NEXT: fst.d $fa0, $sp, 8 +-; LA64D-NEXT: move $a0, $s0 +-; LA64D-NEXT: move $a1, $fp +-; LA64D-NEXT: move $a2, $s1 +-; LA64D-NEXT: move $a3, $s2 +-; LA64D-NEXT: move $a4, $s3 +-; LA64D-NEXT: move $a5, $zero +-; LA64D-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64D-NEXT: fld.d $fa0, $sp, 16 +-; LA64D-NEXT: beqz $a0, .LBB12_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: fld.d $fs0, $sp, 24 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64D-NEXT: addi.d $sp, $sp, 80 +-; LA64D-NEXT: ret +- %v = atomicrmw fadd ptr %p, double 1.0 release, align 4 +- ret double %v +-} +- +-define double @double_fsub_release(ptr %p) nounwind { +-; LA64F-LABEL: double_fsub_release: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -80 +-; LA64F-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s4, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 0 +-; LA64F-NEXT: lu52i.d $s0, $zero, -1025 +-; LA64F-NEXT: ori $s1, $zero, 8 +-; LA64F-NEXT: addi.d $s2, $sp, 16 +-; LA64F-NEXT: addi.d $s3, $sp, 8 +-; LA64F-NEXT: ori $s4, $zero, 3 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB13_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64F-NEXT: st.d $a0, $sp, 16 +-; LA64F-NEXT: move $a1, $s0 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $sp, 8 +-; LA64F-NEXT: move $a0, $s1 +-; LA64F-NEXT: move $a1, $fp +-; LA64F-NEXT: move $a2, $s2 +-; LA64F-NEXT: move $a3, $s3 +-; LA64F-NEXT: move $a4, $s4 +-; LA64F-NEXT: move $a5, $zero +-; LA64F-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64F-NEXT: move $a1, $a0 +-; LA64F-NEXT: ld.d $a0, $sp, 16 +-; LA64F-NEXT: beqz $a1, .LBB13_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ld.d $s4, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 80 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: double_fsub_release: +-; LA64D: # %bb.0: +-; LA64D-NEXT: addi.d $sp, $sp, -80 +-; LA64D-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64D-NEXT: fst.d $fs0, $sp, 24 # 8-byte Folded Spill +-; LA64D-NEXT: move $fp, $a0 +-; LA64D-NEXT: fld.d $fa0, $a0, 0 +-; LA64D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI13_0) +-; LA64D-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI13_0) +-; LA64D-NEXT: fld.d $fs0, $a0, 0 +-; LA64D-NEXT: ori $s0, $zero, 8 +-; LA64D-NEXT: addi.d $s1, $sp, 16 +-; LA64D-NEXT: addi.d $s2, $sp, 8 +-; LA64D-NEXT: ori $s3, $zero, 3 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB13_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64D-NEXT: fst.d $fa0, $sp, 16 +-; LA64D-NEXT: fadd.d $fa0, $fa0, $fs0 +-; LA64D-NEXT: fst.d $fa0, $sp, 8 +-; LA64D-NEXT: move $a0, $s0 +-; LA64D-NEXT: move $a1, $fp +-; LA64D-NEXT: move $a2, $s1 +-; LA64D-NEXT: move $a3, $s2 +-; LA64D-NEXT: move $a4, $s3 +-; LA64D-NEXT: move $a5, $zero +-; LA64D-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64D-NEXT: fld.d $fa0, $sp, 16 +-; LA64D-NEXT: beqz $a0, .LBB13_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: fld.d $fs0, $sp, 24 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64D-NEXT: addi.d $sp, $sp, 80 +-; LA64D-NEXT: ret +- %v = atomicrmw fsub ptr %p, double 1.0 release, align 4 +- ret double %v +-} +- +-define double @double_fmin_release(ptr %p) nounwind { +-; LA64F-LABEL: double_fmin_release: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -80 +-; LA64F-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s4, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 0 +-; LA64F-NEXT: lu52i.d $s0, $zero, 1023 +-; LA64F-NEXT: ori $s1, $zero, 8 +-; LA64F-NEXT: addi.d $s2, $sp, 16 +-; LA64F-NEXT: addi.d $s3, $sp, 8 +-; LA64F-NEXT: ori $s4, $zero, 3 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB14_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64F-NEXT: st.d $a0, $sp, 16 +-; LA64F-NEXT: move $a1, $s0 +-; LA64F-NEXT: bl %plt(fmin) +-; LA64F-NEXT: st.d $a0, $sp, 8 +-; LA64F-NEXT: move $a0, $s1 +-; LA64F-NEXT: move $a1, $fp +-; LA64F-NEXT: move $a2, $s2 +-; LA64F-NEXT: move $a3, $s3 +-; LA64F-NEXT: move $a4, $s4 +-; LA64F-NEXT: move $a5, $zero +-; LA64F-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64F-NEXT: move $a1, $a0 +-; LA64F-NEXT: ld.d $a0, $sp, 16 +-; LA64F-NEXT: beqz $a1, .LBB14_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ld.d $s4, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 80 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: double_fmin_release: +-; LA64D: # %bb.0: +-; LA64D-NEXT: addi.d $sp, $sp, -80 +-; LA64D-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64D-NEXT: fst.d $fs0, $sp, 24 # 8-byte Folded Spill +-; LA64D-NEXT: move $fp, $a0 +-; LA64D-NEXT: fld.d $fa0, $a0, 0 +-; LA64D-NEXT: addi.d $a0, $zero, 1 +-; LA64D-NEXT: movgr2fr.d $fa1, $a0 +-; LA64D-NEXT: ffint.d.l $fs0, $fa1 +-; LA64D-NEXT: ori $s0, $zero, 8 +-; LA64D-NEXT: addi.d $s1, $sp, 16 +-; LA64D-NEXT: addi.d $s2, $sp, 8 +-; LA64D-NEXT: ori $s3, $zero, 3 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB14_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64D-NEXT: fst.d $fa0, $sp, 16 +-; LA64D-NEXT: fmax.d $fa0, $fa0, $fa0 +-; LA64D-NEXT: fmin.d $fa0, $fa0, $fs0 +-; LA64D-NEXT: fst.d $fa0, $sp, 8 +-; LA64D-NEXT: move $a0, $s0 +-; LA64D-NEXT: move $a1, $fp +-; LA64D-NEXT: move $a2, $s1 +-; LA64D-NEXT: move $a3, $s2 +-; LA64D-NEXT: move $a4, $s3 +-; LA64D-NEXT: move $a5, $zero +-; LA64D-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64D-NEXT: fld.d $fa0, $sp, 16 +-; LA64D-NEXT: beqz $a0, .LBB14_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: fld.d $fs0, $sp, 24 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64D-NEXT: addi.d $sp, $sp, 80 +-; LA64D-NEXT: ret +- %v = atomicrmw fmin ptr %p, double 1.0 release, align 4 +- ret double %v +-} +- +-define double @double_fmax_release(ptr %p) nounwind { +-; LA64F-LABEL: double_fmax_release: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -80 +-; LA64F-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s4, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 0 +-; LA64F-NEXT: lu52i.d $s0, $zero, 1023 +-; LA64F-NEXT: ori $s1, $zero, 8 +-; LA64F-NEXT: addi.d $s2, $sp, 16 +-; LA64F-NEXT: addi.d $s3, $sp, 8 +-; LA64F-NEXT: ori $s4, $zero, 3 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB15_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64F-NEXT: st.d $a0, $sp, 16 +-; LA64F-NEXT: move $a1, $s0 +-; LA64F-NEXT: bl %plt(fmax) +-; LA64F-NEXT: st.d $a0, $sp, 8 +-; LA64F-NEXT: move $a0, $s1 +-; LA64F-NEXT: move $a1, $fp +-; LA64F-NEXT: move $a2, $s2 +-; LA64F-NEXT: move $a3, $s3 +-; LA64F-NEXT: move $a4, $s4 +-; LA64F-NEXT: move $a5, $zero +-; LA64F-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64F-NEXT: move $a1, $a0 +-; LA64F-NEXT: ld.d $a0, $sp, 16 +-; LA64F-NEXT: beqz $a1, .LBB15_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ld.d $s4, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 80 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: double_fmax_release: +-; LA64D: # %bb.0: +-; LA64D-NEXT: addi.d $sp, $sp, -80 +-; LA64D-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64D-NEXT: fst.d $fs0, $sp, 24 # 8-byte Folded Spill +-; LA64D-NEXT: move $fp, $a0 +-; LA64D-NEXT: fld.d $fa0, $a0, 0 +-; LA64D-NEXT: addi.d $a0, $zero, 1 +-; LA64D-NEXT: movgr2fr.d $fa1, $a0 +-; LA64D-NEXT: ffint.d.l $fs0, $fa1 +-; LA64D-NEXT: ori $s0, $zero, 8 +-; LA64D-NEXT: addi.d $s1, $sp, 16 +-; LA64D-NEXT: addi.d $s2, $sp, 8 +-; LA64D-NEXT: ori $s3, $zero, 3 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB15_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64D-NEXT: fst.d $fa0, $sp, 16 +-; LA64D-NEXT: fmax.d $fa0, $fa0, $fa0 +-; LA64D-NEXT: fmax.d $fa0, $fa0, $fs0 +-; LA64D-NEXT: fst.d $fa0, $sp, 8 +-; LA64D-NEXT: move $a0, $s0 +-; LA64D-NEXT: move $a1, $fp +-; LA64D-NEXT: move $a2, $s1 +-; LA64D-NEXT: move $a3, $s2 +-; LA64D-NEXT: move $a4, $s3 +-; LA64D-NEXT: move $a5, $zero +-; LA64D-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64D-NEXT: fld.d $fa0, $sp, 16 +-; LA64D-NEXT: beqz $a0, .LBB15_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: fld.d $fs0, $sp, 24 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64D-NEXT: addi.d $sp, $sp, 80 +-; LA64D-NEXT: ret +- %v = atomicrmw fmax ptr %p, double 1.0 release, align 4 +- ret double %v +-} +- +-define float @float_fadd_acq_rel(ptr %p) nounwind { +-; LA64F-LABEL: float_fadd_acq_rel: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: addi.w $a1, $zero, 1 +-; LA64F-NEXT: movgr2fr.w $fa1, $a1 +-; LA64F-NEXT: ffint.s.w $fa1, $fa1 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB16_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Loop Header: Depth=1 +-; LA64F-NEXT: # Child Loop BB16_3 Depth 2 +-; LA64F-NEXT: fadd.s $fa2, $fa0, $fa1 +-; LA64F-NEXT: movfr2gr.s $a1, $fa2 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: addi.w $a2, $a2, 0 +-; LA64F-NEXT: .LBB16_3: # %atomicrmw.start +-; LA64F-NEXT: # Parent Loop BB16_1 Depth=1 +-; LA64F-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64F-NEXT: ll.w $a3, $a0, 0 +-; LA64F-NEXT: bne $a3, $a2, .LBB16_5 +-; LA64F-NEXT: # %bb.4: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB16_3 Depth=2 +-; LA64F-NEXT: move $a4, $a1 +-; LA64F-NEXT: sc.w $a4, $a0, 0 +-; LA64F-NEXT: beqz $a4, .LBB16_3 +-; LA64F-NEXT: b .LBB16_6 +-; LA64F-NEXT: .LBB16_5: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB16_1 Depth=1 +-; LA64F-NEXT: dbar 20 +-; LA64F-NEXT: .LBB16_6: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB16_1 Depth=1 +-; LA64F-NEXT: movgr2fr.w $fa0, $a3 +-; LA64F-NEXT: bne $a3, $a2, .LBB16_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: float_fadd_acq_rel: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: addi.w $a1, $zero, 1 +-; LA64D-NEXT: movgr2fr.w $fa1, $a1 +-; LA64D-NEXT: ffint.s.w $fa1, $fa1 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB16_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Loop Header: Depth=1 +-; LA64D-NEXT: # Child Loop BB16_3 Depth 2 +-; LA64D-NEXT: fadd.s $fa2, $fa0, $fa1 +-; LA64D-NEXT: movfr2gr.s $a1, $fa2 +-; LA64D-NEXT: movfr2gr.s $a2, $fa0 +-; LA64D-NEXT: addi.w $a2, $a2, 0 +-; LA64D-NEXT: .LBB16_3: # %atomicrmw.start +-; LA64D-NEXT: # Parent Loop BB16_1 Depth=1 +-; LA64D-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64D-NEXT: ll.w $a3, $a0, 0 +-; LA64D-NEXT: bne $a3, $a2, .LBB16_5 +-; LA64D-NEXT: # %bb.4: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB16_3 Depth=2 +-; LA64D-NEXT: move $a4, $a1 +-; LA64D-NEXT: sc.w $a4, $a0, 0 +-; LA64D-NEXT: beqz $a4, .LBB16_3 +-; LA64D-NEXT: b .LBB16_6 +-; LA64D-NEXT: .LBB16_5: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB16_1 Depth=1 +-; LA64D-NEXT: dbar 20 +-; LA64D-NEXT: .LBB16_6: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB16_1 Depth=1 +-; LA64D-NEXT: movgr2fr.w $fa0, $a3 +-; LA64D-NEXT: bne $a3, $a2, .LBB16_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: ret +- %v = atomicrmw fadd ptr %p, float 1.0 acq_rel, align 4 +- ret float %v +-} +- +-define float @float_fsub_acq_rel(ptr %p) nounwind { +-; LA64F-LABEL: float_fsub_acq_rel: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: pcalau12i $a1, %pc_hi20(.LCPI17_0) +-; LA64F-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI17_0) +-; LA64F-NEXT: fld.s $fa1, $a1, 0 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB17_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Loop Header: Depth=1 +-; LA64F-NEXT: # Child Loop BB17_3 Depth 2 +-; LA64F-NEXT: fadd.s $fa2, $fa0, $fa1 +-; LA64F-NEXT: movfr2gr.s $a1, $fa2 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: addi.w $a2, $a2, 0 +-; LA64F-NEXT: .LBB17_3: # %atomicrmw.start +-; LA64F-NEXT: # Parent Loop BB17_1 Depth=1 +-; LA64F-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64F-NEXT: ll.w $a3, $a0, 0 +-; LA64F-NEXT: bne $a3, $a2, .LBB17_5 +-; LA64F-NEXT: # %bb.4: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB17_3 Depth=2 +-; LA64F-NEXT: move $a4, $a1 +-; LA64F-NEXT: sc.w $a4, $a0, 0 +-; LA64F-NEXT: beqz $a4, .LBB17_3 +-; LA64F-NEXT: b .LBB17_6 +-; LA64F-NEXT: .LBB17_5: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB17_1 Depth=1 +-; LA64F-NEXT: dbar 20 +-; LA64F-NEXT: .LBB17_6: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB17_1 Depth=1 +-; LA64F-NEXT: movgr2fr.w $fa0, $a3 +-; LA64F-NEXT: bne $a3, $a2, .LBB17_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: float_fsub_acq_rel: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: pcalau12i $a1, %pc_hi20(.LCPI17_0) +-; LA64D-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI17_0) +-; LA64D-NEXT: fld.s $fa1, $a1, 0 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB17_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Loop Header: Depth=1 +-; LA64D-NEXT: # Child Loop BB17_3 Depth 2 +-; LA64D-NEXT: fadd.s $fa2, $fa0, $fa1 +-; LA64D-NEXT: movfr2gr.s $a1, $fa2 +-; LA64D-NEXT: movfr2gr.s $a2, $fa0 +-; LA64D-NEXT: addi.w $a2, $a2, 0 +-; LA64D-NEXT: .LBB17_3: # %atomicrmw.start +-; LA64D-NEXT: # Parent Loop BB17_1 Depth=1 +-; LA64D-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64D-NEXT: ll.w $a3, $a0, 0 +-; LA64D-NEXT: bne $a3, $a2, .LBB17_5 +-; LA64D-NEXT: # %bb.4: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB17_3 Depth=2 +-; LA64D-NEXT: move $a4, $a1 +-; LA64D-NEXT: sc.w $a4, $a0, 0 +-; LA64D-NEXT: beqz $a4, .LBB17_3 +-; LA64D-NEXT: b .LBB17_6 +-; LA64D-NEXT: .LBB17_5: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB17_1 Depth=1 +-; LA64D-NEXT: dbar 20 +-; LA64D-NEXT: .LBB17_6: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB17_1 Depth=1 +-; LA64D-NEXT: movgr2fr.w $fa0, $a3 +-; LA64D-NEXT: bne $a3, $a2, .LBB17_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: ret +- %v = atomicrmw fsub ptr %p, float 1.0 acq_rel, align 4 +- ret float %v +-} +- +-define float @float_fmin_acq_rel(ptr %p) nounwind { +-; LA64F-LABEL: float_fmin_acq_rel: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: addi.w $a1, $zero, 1 +-; LA64F-NEXT: movgr2fr.w $fa1, $a1 +-; LA64F-NEXT: ffint.s.w $fa1, $fa1 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB18_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Loop Header: Depth=1 +-; LA64F-NEXT: # Child Loop BB18_3 Depth 2 +-; LA64F-NEXT: fmax.s $fa2, $fa0, $fa0 +-; LA64F-NEXT: fmin.s $fa2, $fa2, $fa1 +-; LA64F-NEXT: movfr2gr.s $a1, $fa2 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: addi.w $a2, $a2, 0 +-; LA64F-NEXT: .LBB18_3: # %atomicrmw.start +-; LA64F-NEXT: # Parent Loop BB18_1 Depth=1 +-; LA64F-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64F-NEXT: ll.w $a3, $a0, 0 +-; LA64F-NEXT: bne $a3, $a2, .LBB18_5 +-; LA64F-NEXT: # %bb.4: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB18_3 Depth=2 +-; LA64F-NEXT: move $a4, $a1 +-; LA64F-NEXT: sc.w $a4, $a0, 0 +-; LA64F-NEXT: beqz $a4, .LBB18_3 +-; LA64F-NEXT: b .LBB18_6 +-; LA64F-NEXT: .LBB18_5: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB18_1 Depth=1 +-; LA64F-NEXT: dbar 20 +-; LA64F-NEXT: .LBB18_6: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB18_1 Depth=1 +-; LA64F-NEXT: movgr2fr.w $fa0, $a3 +-; LA64F-NEXT: bne $a3, $a2, .LBB18_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: float_fmin_acq_rel: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: addi.w $a1, $zero, 1 +-; LA64D-NEXT: movgr2fr.w $fa1, $a1 +-; LA64D-NEXT: ffint.s.w $fa1, $fa1 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB18_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Loop Header: Depth=1 +-; LA64D-NEXT: # Child Loop BB18_3 Depth 2 +-; LA64D-NEXT: fmax.s $fa2, $fa0, $fa0 +-; LA64D-NEXT: fmin.s $fa2, $fa2, $fa1 +-; LA64D-NEXT: movfr2gr.s $a1, $fa2 +-; LA64D-NEXT: movfr2gr.s $a2, $fa0 +-; LA64D-NEXT: addi.w $a2, $a2, 0 +-; LA64D-NEXT: .LBB18_3: # %atomicrmw.start +-; LA64D-NEXT: # Parent Loop BB18_1 Depth=1 +-; LA64D-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64D-NEXT: ll.w $a3, $a0, 0 +-; LA64D-NEXT: bne $a3, $a2, .LBB18_5 +-; LA64D-NEXT: # %bb.4: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB18_3 Depth=2 +-; LA64D-NEXT: move $a4, $a1 +-; LA64D-NEXT: sc.w $a4, $a0, 0 +-; LA64D-NEXT: beqz $a4, .LBB18_3 +-; LA64D-NEXT: b .LBB18_6 +-; LA64D-NEXT: .LBB18_5: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB18_1 Depth=1 +-; LA64D-NEXT: dbar 20 +-; LA64D-NEXT: .LBB18_6: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB18_1 Depth=1 +-; LA64D-NEXT: movgr2fr.w $fa0, $a3 +-; LA64D-NEXT: bne $a3, $a2, .LBB18_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: ret +- %v = atomicrmw fmin ptr %p, float 1.0 acq_rel, align 4 +- ret float %v +-} +- +-define float @float_fmax_acq_rel(ptr %p) nounwind { +-; LA64F-LABEL: float_fmax_acq_rel: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: addi.w $a1, $zero, 1 +-; LA64F-NEXT: movgr2fr.w $fa1, $a1 +-; LA64F-NEXT: ffint.s.w $fa1, $fa1 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB19_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Loop Header: Depth=1 +-; LA64F-NEXT: # Child Loop BB19_3 Depth 2 +-; LA64F-NEXT: fmax.s $fa2, $fa0, $fa0 +-; LA64F-NEXT: fmax.s $fa2, $fa2, $fa1 +-; LA64F-NEXT: movfr2gr.s $a1, $fa2 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: addi.w $a2, $a2, 0 +-; LA64F-NEXT: .LBB19_3: # %atomicrmw.start +-; LA64F-NEXT: # Parent Loop BB19_1 Depth=1 +-; LA64F-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64F-NEXT: ll.w $a3, $a0, 0 +-; LA64F-NEXT: bne $a3, $a2, .LBB19_5 +-; LA64F-NEXT: # %bb.4: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB19_3 Depth=2 +-; LA64F-NEXT: move $a4, $a1 +-; LA64F-NEXT: sc.w $a4, $a0, 0 +-; LA64F-NEXT: beqz $a4, .LBB19_3 +-; LA64F-NEXT: b .LBB19_6 +-; LA64F-NEXT: .LBB19_5: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB19_1 Depth=1 +-; LA64F-NEXT: dbar 20 +-; LA64F-NEXT: .LBB19_6: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB19_1 Depth=1 +-; LA64F-NEXT: movgr2fr.w $fa0, $a3 +-; LA64F-NEXT: bne $a3, $a2, .LBB19_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: float_fmax_acq_rel: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: addi.w $a1, $zero, 1 +-; LA64D-NEXT: movgr2fr.w $fa1, $a1 +-; LA64D-NEXT: ffint.s.w $fa1, $fa1 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB19_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Loop Header: Depth=1 +-; LA64D-NEXT: # Child Loop BB19_3 Depth 2 +-; LA64D-NEXT: fmax.s $fa2, $fa0, $fa0 +-; LA64D-NEXT: fmax.s $fa2, $fa2, $fa1 +-; LA64D-NEXT: movfr2gr.s $a1, $fa2 +-; LA64D-NEXT: movfr2gr.s $a2, $fa0 +-; LA64D-NEXT: addi.w $a2, $a2, 0 +-; LA64D-NEXT: .LBB19_3: # %atomicrmw.start +-; LA64D-NEXT: # Parent Loop BB19_1 Depth=1 +-; LA64D-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64D-NEXT: ll.w $a3, $a0, 0 +-; LA64D-NEXT: bne $a3, $a2, .LBB19_5 +-; LA64D-NEXT: # %bb.4: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB19_3 Depth=2 +-; LA64D-NEXT: move $a4, $a1 +-; LA64D-NEXT: sc.w $a4, $a0, 0 +-; LA64D-NEXT: beqz $a4, .LBB19_3 +-; LA64D-NEXT: b .LBB19_6 +-; LA64D-NEXT: .LBB19_5: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB19_1 Depth=1 +-; LA64D-NEXT: dbar 20 +-; LA64D-NEXT: .LBB19_6: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB19_1 Depth=1 +-; LA64D-NEXT: movgr2fr.w $fa0, $a3 +-; LA64D-NEXT: bne $a3, $a2, .LBB19_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: ret +- %v = atomicrmw fmax ptr %p, float 1.0 acq_rel, align 4 +- ret float %v +-} +- +-define double @double_fadd_acq_rel(ptr %p) nounwind { +-; LA64F-LABEL: double_fadd_acq_rel: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -80 +-; LA64F-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s4, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s5, $sp, 16 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 0 +-; LA64F-NEXT: lu52i.d $s0, $zero, 1023 +-; LA64F-NEXT: ori $s1, $zero, 8 +-; LA64F-NEXT: addi.d $s2, $sp, 8 +-; LA64F-NEXT: addi.d $s3, $sp, 0 +-; LA64F-NEXT: ori $s4, $zero, 4 +-; LA64F-NEXT: ori $s5, $zero, 2 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB20_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64F-NEXT: st.d $a0, $sp, 8 +-; LA64F-NEXT: move $a1, $s0 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $sp, 0 +-; LA64F-NEXT: move $a0, $s1 +-; LA64F-NEXT: move $a1, $fp +-; LA64F-NEXT: move $a2, $s2 +-; LA64F-NEXT: move $a3, $s3 +-; LA64F-NEXT: move $a4, $s4 +-; LA64F-NEXT: move $a5, $s5 +-; LA64F-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64F-NEXT: move $a1, $a0 +-; LA64F-NEXT: ld.d $a0, $sp, 8 +-; LA64F-NEXT: beqz $a1, .LBB20_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ld.d $s5, $sp, 16 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s4, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 80 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: double_fadd_acq_rel: +-; LA64D: # %bb.0: +-; LA64D-NEXT: addi.d $sp, $sp, -80 +-; LA64D-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s4, $sp, 24 # 8-byte Folded Spill +-; LA64D-NEXT: fst.d $fs0, $sp, 16 # 8-byte Folded Spill +-; LA64D-NEXT: move $fp, $a0 +-; LA64D-NEXT: fld.d $fa0, $a0, 0 +-; LA64D-NEXT: addi.d $a0, $zero, 1 +-; LA64D-NEXT: movgr2fr.d $fa1, $a0 +-; LA64D-NEXT: ffint.d.l $fs0, $fa1 +-; LA64D-NEXT: ori $s0, $zero, 8 +-; LA64D-NEXT: addi.d $s1, $sp, 8 +-; LA64D-NEXT: addi.d $s2, $sp, 0 +-; LA64D-NEXT: ori $s3, $zero, 4 +-; LA64D-NEXT: ori $s4, $zero, 2 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB20_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64D-NEXT: fst.d $fa0, $sp, 8 +-; LA64D-NEXT: fadd.d $fa0, $fa0, $fs0 +-; LA64D-NEXT: fst.d $fa0, $sp, 0 +-; LA64D-NEXT: move $a0, $s0 +-; LA64D-NEXT: move $a1, $fp +-; LA64D-NEXT: move $a2, $s1 +-; LA64D-NEXT: move $a3, $s2 +-; LA64D-NEXT: move $a4, $s3 +-; LA64D-NEXT: move $a5, $s4 +-; LA64D-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64D-NEXT: fld.d $fa0, $sp, 8 +-; LA64D-NEXT: beqz $a0, .LBB20_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: fld.d $fs0, $sp, 16 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s4, $sp, 24 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64D-NEXT: addi.d $sp, $sp, 80 +-; LA64D-NEXT: ret +- %v = atomicrmw fadd ptr %p, double 1.0 acq_rel, align 4 +- ret double %v +-} +- +-define double @double_fsub_acq_rel(ptr %p) nounwind { +-; LA64F-LABEL: double_fsub_acq_rel: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -80 +-; LA64F-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s4, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s5, $sp, 16 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 0 +-; LA64F-NEXT: lu52i.d $s0, $zero, -1025 +-; LA64F-NEXT: ori $s1, $zero, 8 +-; LA64F-NEXT: addi.d $s2, $sp, 8 +-; LA64F-NEXT: addi.d $s3, $sp, 0 +-; LA64F-NEXT: ori $s4, $zero, 4 +-; LA64F-NEXT: ori $s5, $zero, 2 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB21_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64F-NEXT: st.d $a0, $sp, 8 +-; LA64F-NEXT: move $a1, $s0 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $sp, 0 +-; LA64F-NEXT: move $a0, $s1 +-; LA64F-NEXT: move $a1, $fp +-; LA64F-NEXT: move $a2, $s2 +-; LA64F-NEXT: move $a3, $s3 +-; LA64F-NEXT: move $a4, $s4 +-; LA64F-NEXT: move $a5, $s5 +-; LA64F-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64F-NEXT: move $a1, $a0 +-; LA64F-NEXT: ld.d $a0, $sp, 8 +-; LA64F-NEXT: beqz $a1, .LBB21_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ld.d $s5, $sp, 16 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s4, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 80 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: double_fsub_acq_rel: +-; LA64D: # %bb.0: +-; LA64D-NEXT: addi.d $sp, $sp, -80 +-; LA64D-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s4, $sp, 24 # 8-byte Folded Spill +-; LA64D-NEXT: fst.d $fs0, $sp, 16 # 8-byte Folded Spill +-; LA64D-NEXT: move $fp, $a0 +-; LA64D-NEXT: fld.d $fa0, $a0, 0 +-; LA64D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI21_0) +-; LA64D-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI21_0) +-; LA64D-NEXT: fld.d $fs0, $a0, 0 +-; LA64D-NEXT: ori $s0, $zero, 8 +-; LA64D-NEXT: addi.d $s1, $sp, 8 +-; LA64D-NEXT: addi.d $s2, $sp, 0 +-; LA64D-NEXT: ori $s3, $zero, 4 +-; LA64D-NEXT: ori $s4, $zero, 2 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB21_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64D-NEXT: fst.d $fa0, $sp, 8 +-; LA64D-NEXT: fadd.d $fa0, $fa0, $fs0 +-; LA64D-NEXT: fst.d $fa0, $sp, 0 +-; LA64D-NEXT: move $a0, $s0 +-; LA64D-NEXT: move $a1, $fp +-; LA64D-NEXT: move $a2, $s1 +-; LA64D-NEXT: move $a3, $s2 +-; LA64D-NEXT: move $a4, $s3 +-; LA64D-NEXT: move $a5, $s4 +-; LA64D-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64D-NEXT: fld.d $fa0, $sp, 8 +-; LA64D-NEXT: beqz $a0, .LBB21_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: fld.d $fs0, $sp, 16 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s4, $sp, 24 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64D-NEXT: addi.d $sp, $sp, 80 +-; LA64D-NEXT: ret +- %v = atomicrmw fsub ptr %p, double 1.0 acq_rel, align 4 +- ret double %v +-} +- +-define double @double_fmin_acq_rel(ptr %p) nounwind { +-; LA64F-LABEL: double_fmin_acq_rel: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -80 +-; LA64F-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s4, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s5, $sp, 16 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 0 +-; LA64F-NEXT: lu52i.d $s0, $zero, 1023 +-; LA64F-NEXT: ori $s1, $zero, 8 +-; LA64F-NEXT: addi.d $s2, $sp, 8 +-; LA64F-NEXT: addi.d $s3, $sp, 0 +-; LA64F-NEXT: ori $s4, $zero, 4 +-; LA64F-NEXT: ori $s5, $zero, 2 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB22_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64F-NEXT: st.d $a0, $sp, 8 +-; LA64F-NEXT: move $a1, $s0 +-; LA64F-NEXT: bl %plt(fmin) +-; LA64F-NEXT: st.d $a0, $sp, 0 +-; LA64F-NEXT: move $a0, $s1 +-; LA64F-NEXT: move $a1, $fp +-; LA64F-NEXT: move $a2, $s2 +-; LA64F-NEXT: move $a3, $s3 +-; LA64F-NEXT: move $a4, $s4 +-; LA64F-NEXT: move $a5, $s5 +-; LA64F-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64F-NEXT: move $a1, $a0 +-; LA64F-NEXT: ld.d $a0, $sp, 8 +-; LA64F-NEXT: beqz $a1, .LBB22_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ld.d $s5, $sp, 16 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s4, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 80 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: double_fmin_acq_rel: +-; LA64D: # %bb.0: +-; LA64D-NEXT: addi.d $sp, $sp, -80 +-; LA64D-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s4, $sp, 24 # 8-byte Folded Spill +-; LA64D-NEXT: fst.d $fs0, $sp, 16 # 8-byte Folded Spill +-; LA64D-NEXT: move $fp, $a0 +-; LA64D-NEXT: fld.d $fa0, $a0, 0 +-; LA64D-NEXT: addi.d $a0, $zero, 1 +-; LA64D-NEXT: movgr2fr.d $fa1, $a0 +-; LA64D-NEXT: ffint.d.l $fs0, $fa1 +-; LA64D-NEXT: ori $s0, $zero, 8 +-; LA64D-NEXT: addi.d $s1, $sp, 8 +-; LA64D-NEXT: addi.d $s2, $sp, 0 +-; LA64D-NEXT: ori $s3, $zero, 4 +-; LA64D-NEXT: ori $s4, $zero, 2 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB22_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64D-NEXT: fst.d $fa0, $sp, 8 +-; LA64D-NEXT: fmax.d $fa0, $fa0, $fa0 +-; LA64D-NEXT: fmin.d $fa0, $fa0, $fs0 +-; LA64D-NEXT: fst.d $fa0, $sp, 0 +-; LA64D-NEXT: move $a0, $s0 +-; LA64D-NEXT: move $a1, $fp +-; LA64D-NEXT: move $a2, $s1 +-; LA64D-NEXT: move $a3, $s2 +-; LA64D-NEXT: move $a4, $s3 +-; LA64D-NEXT: move $a5, $s4 +-; LA64D-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64D-NEXT: fld.d $fa0, $sp, 8 +-; LA64D-NEXT: beqz $a0, .LBB22_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: fld.d $fs0, $sp, 16 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s4, $sp, 24 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64D-NEXT: addi.d $sp, $sp, 80 +-; LA64D-NEXT: ret +- %v = atomicrmw fmin ptr %p, double 1.0 acq_rel, align 4 +- ret double %v +-} +- +-define double @double_fmax_acq_rel(ptr %p) nounwind { +-; LA64F-LABEL: double_fmax_acq_rel: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -80 +-; LA64F-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s4, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s5, $sp, 16 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 0 +-; LA64F-NEXT: lu52i.d $s0, $zero, 1023 +-; LA64F-NEXT: ori $s1, $zero, 8 +-; LA64F-NEXT: addi.d $s2, $sp, 8 +-; LA64F-NEXT: addi.d $s3, $sp, 0 +-; LA64F-NEXT: ori $s4, $zero, 4 +-; LA64F-NEXT: ori $s5, $zero, 2 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB23_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64F-NEXT: st.d $a0, $sp, 8 +-; LA64F-NEXT: move $a1, $s0 +-; LA64F-NEXT: bl %plt(fmax) +-; LA64F-NEXT: st.d $a0, $sp, 0 +-; LA64F-NEXT: move $a0, $s1 +-; LA64F-NEXT: move $a1, $fp +-; LA64F-NEXT: move $a2, $s2 +-; LA64F-NEXT: move $a3, $s3 +-; LA64F-NEXT: move $a4, $s4 +-; LA64F-NEXT: move $a5, $s5 +-; LA64F-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64F-NEXT: move $a1, $a0 +-; LA64F-NEXT: ld.d $a0, $sp, 8 +-; LA64F-NEXT: beqz $a1, .LBB23_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ld.d $s5, $sp, 16 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s4, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 80 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: double_fmax_acq_rel: +-; LA64D: # %bb.0: +-; LA64D-NEXT: addi.d $sp, $sp, -80 +-; LA64D-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s4, $sp, 24 # 8-byte Folded Spill +-; LA64D-NEXT: fst.d $fs0, $sp, 16 # 8-byte Folded Spill +-; LA64D-NEXT: move $fp, $a0 +-; LA64D-NEXT: fld.d $fa0, $a0, 0 +-; LA64D-NEXT: addi.d $a0, $zero, 1 +-; LA64D-NEXT: movgr2fr.d $fa1, $a0 +-; LA64D-NEXT: ffint.d.l $fs0, $fa1 +-; LA64D-NEXT: ori $s0, $zero, 8 +-; LA64D-NEXT: addi.d $s1, $sp, 8 +-; LA64D-NEXT: addi.d $s2, $sp, 0 +-; LA64D-NEXT: ori $s3, $zero, 4 +-; LA64D-NEXT: ori $s4, $zero, 2 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB23_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64D-NEXT: fst.d $fa0, $sp, 8 +-; LA64D-NEXT: fmax.d $fa0, $fa0, $fa0 +-; LA64D-NEXT: fmax.d $fa0, $fa0, $fs0 +-; LA64D-NEXT: fst.d $fa0, $sp, 0 +-; LA64D-NEXT: move $a0, $s0 +-; LA64D-NEXT: move $a1, $fp +-; LA64D-NEXT: move $a2, $s1 +-; LA64D-NEXT: move $a3, $s2 +-; LA64D-NEXT: move $a4, $s3 +-; LA64D-NEXT: move $a5, $s4 +-; LA64D-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64D-NEXT: fld.d $fa0, $sp, 8 +-; LA64D-NEXT: beqz $a0, .LBB23_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: fld.d $fs0, $sp, 16 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s4, $sp, 24 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64D-NEXT: addi.d $sp, $sp, 80 +-; LA64D-NEXT: ret +- %v = atomicrmw fmax ptr %p, double 1.0 acq_rel, align 4 +- ret double %v +-} +- +-define float @float_fadd_seq_cst(ptr %p) nounwind { +-; LA64F-LABEL: float_fadd_seq_cst: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: addi.w $a1, $zero, 1 +-; LA64F-NEXT: movgr2fr.w $fa1, $a1 +-; LA64F-NEXT: ffint.s.w $fa1, $fa1 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB24_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Loop Header: Depth=1 +-; LA64F-NEXT: # Child Loop BB24_3 Depth 2 +-; LA64F-NEXT: fadd.s $fa2, $fa0, $fa1 +-; LA64F-NEXT: movfr2gr.s $a1, $fa2 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: addi.w $a2, $a2, 0 +-; LA64F-NEXT: .LBB24_3: # %atomicrmw.start +-; LA64F-NEXT: # Parent Loop BB24_1 Depth=1 +-; LA64F-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64F-NEXT: ll.w $a3, $a0, 0 +-; LA64F-NEXT: bne $a3, $a2, .LBB24_5 +-; LA64F-NEXT: # %bb.4: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB24_3 Depth=2 +-; LA64F-NEXT: move $a4, $a1 +-; LA64F-NEXT: sc.w $a4, $a0, 0 +-; LA64F-NEXT: beqz $a4, .LBB24_3 +-; LA64F-NEXT: b .LBB24_6 +-; LA64F-NEXT: .LBB24_5: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB24_1 Depth=1 +-; LA64F-NEXT: dbar 20 +-; LA64F-NEXT: .LBB24_6: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB24_1 Depth=1 +-; LA64F-NEXT: movgr2fr.w $fa0, $a3 +-; LA64F-NEXT: bne $a3, $a2, .LBB24_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: float_fadd_seq_cst: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: addi.w $a1, $zero, 1 +-; LA64D-NEXT: movgr2fr.w $fa1, $a1 +-; LA64D-NEXT: ffint.s.w $fa1, $fa1 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB24_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Loop Header: Depth=1 +-; LA64D-NEXT: # Child Loop BB24_3 Depth 2 +-; LA64D-NEXT: fadd.s $fa2, $fa0, $fa1 +-; LA64D-NEXT: movfr2gr.s $a1, $fa2 +-; LA64D-NEXT: movfr2gr.s $a2, $fa0 +-; LA64D-NEXT: addi.w $a2, $a2, 0 +-; LA64D-NEXT: .LBB24_3: # %atomicrmw.start +-; LA64D-NEXT: # Parent Loop BB24_1 Depth=1 +-; LA64D-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64D-NEXT: ll.w $a3, $a0, 0 +-; LA64D-NEXT: bne $a3, $a2, .LBB24_5 +-; LA64D-NEXT: # %bb.4: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB24_3 Depth=2 +-; LA64D-NEXT: move $a4, $a1 +-; LA64D-NEXT: sc.w $a4, $a0, 0 +-; LA64D-NEXT: beqz $a4, .LBB24_3 +-; LA64D-NEXT: b .LBB24_6 +-; LA64D-NEXT: .LBB24_5: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB24_1 Depth=1 +-; LA64D-NEXT: dbar 20 +-; LA64D-NEXT: .LBB24_6: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB24_1 Depth=1 +-; LA64D-NEXT: movgr2fr.w $fa0, $a3 +-; LA64D-NEXT: bne $a3, $a2, .LBB24_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: ret +- %v = atomicrmw fadd ptr %p, float 1.0 seq_cst, align 4 +- ret float %v +-} +- +-define float @float_fsub_seq_cst(ptr %p) nounwind { +-; LA64F-LABEL: float_fsub_seq_cst: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: pcalau12i $a1, %pc_hi20(.LCPI25_0) +-; LA64F-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI25_0) +-; LA64F-NEXT: fld.s $fa1, $a1, 0 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB25_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Loop Header: Depth=1 +-; LA64F-NEXT: # Child Loop BB25_3 Depth 2 +-; LA64F-NEXT: fadd.s $fa2, $fa0, $fa1 +-; LA64F-NEXT: movfr2gr.s $a1, $fa2 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: addi.w $a2, $a2, 0 +-; LA64F-NEXT: .LBB25_3: # %atomicrmw.start +-; LA64F-NEXT: # Parent Loop BB25_1 Depth=1 +-; LA64F-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64F-NEXT: ll.w $a3, $a0, 0 +-; LA64F-NEXT: bne $a3, $a2, .LBB25_5 +-; LA64F-NEXT: # %bb.4: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB25_3 Depth=2 +-; LA64F-NEXT: move $a4, $a1 +-; LA64F-NEXT: sc.w $a4, $a0, 0 +-; LA64F-NEXT: beqz $a4, .LBB25_3 +-; LA64F-NEXT: b .LBB25_6 +-; LA64F-NEXT: .LBB25_5: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB25_1 Depth=1 +-; LA64F-NEXT: dbar 20 +-; LA64F-NEXT: .LBB25_6: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB25_1 Depth=1 +-; LA64F-NEXT: movgr2fr.w $fa0, $a3 +-; LA64F-NEXT: bne $a3, $a2, .LBB25_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: float_fsub_seq_cst: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: pcalau12i $a1, %pc_hi20(.LCPI25_0) +-; LA64D-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI25_0) +-; LA64D-NEXT: fld.s $fa1, $a1, 0 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB25_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Loop Header: Depth=1 +-; LA64D-NEXT: # Child Loop BB25_3 Depth 2 +-; LA64D-NEXT: fadd.s $fa2, $fa0, $fa1 +-; LA64D-NEXT: movfr2gr.s $a1, $fa2 +-; LA64D-NEXT: movfr2gr.s $a2, $fa0 +-; LA64D-NEXT: addi.w $a2, $a2, 0 +-; LA64D-NEXT: .LBB25_3: # %atomicrmw.start +-; LA64D-NEXT: # Parent Loop BB25_1 Depth=1 +-; LA64D-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64D-NEXT: ll.w $a3, $a0, 0 +-; LA64D-NEXT: bne $a3, $a2, .LBB25_5 +-; LA64D-NEXT: # %bb.4: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB25_3 Depth=2 +-; LA64D-NEXT: move $a4, $a1 +-; LA64D-NEXT: sc.w $a4, $a0, 0 +-; LA64D-NEXT: beqz $a4, .LBB25_3 +-; LA64D-NEXT: b .LBB25_6 +-; LA64D-NEXT: .LBB25_5: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB25_1 Depth=1 +-; LA64D-NEXT: dbar 20 +-; LA64D-NEXT: .LBB25_6: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB25_1 Depth=1 +-; LA64D-NEXT: movgr2fr.w $fa0, $a3 +-; LA64D-NEXT: bne $a3, $a2, .LBB25_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: ret +- %v = atomicrmw fsub ptr %p, float 1.0 seq_cst, align 4 +- ret float %v +-} +- +-define float @float_fmin_seq_cst(ptr %p) nounwind { +-; LA64F-LABEL: float_fmin_seq_cst: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: addi.w $a1, $zero, 1 +-; LA64F-NEXT: movgr2fr.w $fa1, $a1 +-; LA64F-NEXT: ffint.s.w $fa1, $fa1 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB26_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Loop Header: Depth=1 +-; LA64F-NEXT: # Child Loop BB26_3 Depth 2 +-; LA64F-NEXT: fmax.s $fa2, $fa0, $fa0 +-; LA64F-NEXT: fmin.s $fa2, $fa2, $fa1 +-; LA64F-NEXT: movfr2gr.s $a1, $fa2 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: addi.w $a2, $a2, 0 +-; LA64F-NEXT: .LBB26_3: # %atomicrmw.start +-; LA64F-NEXT: # Parent Loop BB26_1 Depth=1 +-; LA64F-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64F-NEXT: ll.w $a3, $a0, 0 +-; LA64F-NEXT: bne $a3, $a2, .LBB26_5 +-; LA64F-NEXT: # %bb.4: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB26_3 Depth=2 +-; LA64F-NEXT: move $a4, $a1 +-; LA64F-NEXT: sc.w $a4, $a0, 0 +-; LA64F-NEXT: beqz $a4, .LBB26_3 +-; LA64F-NEXT: b .LBB26_6 +-; LA64F-NEXT: .LBB26_5: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB26_1 Depth=1 +-; LA64F-NEXT: dbar 20 +-; LA64F-NEXT: .LBB26_6: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB26_1 Depth=1 +-; LA64F-NEXT: movgr2fr.w $fa0, $a3 +-; LA64F-NEXT: bne $a3, $a2, .LBB26_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: float_fmin_seq_cst: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: addi.w $a1, $zero, 1 +-; LA64D-NEXT: movgr2fr.w $fa1, $a1 +-; LA64D-NEXT: ffint.s.w $fa1, $fa1 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB26_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Loop Header: Depth=1 +-; LA64D-NEXT: # Child Loop BB26_3 Depth 2 +-; LA64D-NEXT: fmax.s $fa2, $fa0, $fa0 +-; LA64D-NEXT: fmin.s $fa2, $fa2, $fa1 +-; LA64D-NEXT: movfr2gr.s $a1, $fa2 +-; LA64D-NEXT: movfr2gr.s $a2, $fa0 +-; LA64D-NEXT: addi.w $a2, $a2, 0 +-; LA64D-NEXT: .LBB26_3: # %atomicrmw.start +-; LA64D-NEXT: # Parent Loop BB26_1 Depth=1 +-; LA64D-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64D-NEXT: ll.w $a3, $a0, 0 +-; LA64D-NEXT: bne $a3, $a2, .LBB26_5 +-; LA64D-NEXT: # %bb.4: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB26_3 Depth=2 +-; LA64D-NEXT: move $a4, $a1 +-; LA64D-NEXT: sc.w $a4, $a0, 0 +-; LA64D-NEXT: beqz $a4, .LBB26_3 +-; LA64D-NEXT: b .LBB26_6 +-; LA64D-NEXT: .LBB26_5: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB26_1 Depth=1 +-; LA64D-NEXT: dbar 20 +-; LA64D-NEXT: .LBB26_6: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB26_1 Depth=1 +-; LA64D-NEXT: movgr2fr.w $fa0, $a3 +-; LA64D-NEXT: bne $a3, $a2, .LBB26_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: ret +- %v = atomicrmw fmin ptr %p, float 1.0 seq_cst, align 4 +- ret float %v +-} +- +-define float @float_fmax_seq_cst(ptr %p) nounwind { +-; LA64F-LABEL: float_fmax_seq_cst: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: addi.w $a1, $zero, 1 +-; LA64F-NEXT: movgr2fr.w $fa1, $a1 +-; LA64F-NEXT: ffint.s.w $fa1, $fa1 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB27_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Loop Header: Depth=1 +-; LA64F-NEXT: # Child Loop BB27_3 Depth 2 +-; LA64F-NEXT: fmax.s $fa2, $fa0, $fa0 +-; LA64F-NEXT: fmax.s $fa2, $fa2, $fa1 +-; LA64F-NEXT: movfr2gr.s $a1, $fa2 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: addi.w $a2, $a2, 0 +-; LA64F-NEXT: .LBB27_3: # %atomicrmw.start +-; LA64F-NEXT: # Parent Loop BB27_1 Depth=1 +-; LA64F-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64F-NEXT: ll.w $a3, $a0, 0 +-; LA64F-NEXT: bne $a3, $a2, .LBB27_5 +-; LA64F-NEXT: # %bb.4: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB27_3 Depth=2 +-; LA64F-NEXT: move $a4, $a1 +-; LA64F-NEXT: sc.w $a4, $a0, 0 +-; LA64F-NEXT: beqz $a4, .LBB27_3 +-; LA64F-NEXT: b .LBB27_6 +-; LA64F-NEXT: .LBB27_5: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB27_1 Depth=1 +-; LA64F-NEXT: dbar 20 +-; LA64F-NEXT: .LBB27_6: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB27_1 Depth=1 +-; LA64F-NEXT: movgr2fr.w $fa0, $a3 +-; LA64F-NEXT: bne $a3, $a2, .LBB27_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: float_fmax_seq_cst: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: addi.w $a1, $zero, 1 +-; LA64D-NEXT: movgr2fr.w $fa1, $a1 +-; LA64D-NEXT: ffint.s.w $fa1, $fa1 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB27_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Loop Header: Depth=1 +-; LA64D-NEXT: # Child Loop BB27_3 Depth 2 +-; LA64D-NEXT: fmax.s $fa2, $fa0, $fa0 +-; LA64D-NEXT: fmax.s $fa2, $fa2, $fa1 +-; LA64D-NEXT: movfr2gr.s $a1, $fa2 +-; LA64D-NEXT: movfr2gr.s $a2, $fa0 +-; LA64D-NEXT: addi.w $a2, $a2, 0 +-; LA64D-NEXT: .LBB27_3: # %atomicrmw.start +-; LA64D-NEXT: # Parent Loop BB27_1 Depth=1 +-; LA64D-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64D-NEXT: ll.w $a3, $a0, 0 +-; LA64D-NEXT: bne $a3, $a2, .LBB27_5 +-; LA64D-NEXT: # %bb.4: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB27_3 Depth=2 +-; LA64D-NEXT: move $a4, $a1 +-; LA64D-NEXT: sc.w $a4, $a0, 0 +-; LA64D-NEXT: beqz $a4, .LBB27_3 +-; LA64D-NEXT: b .LBB27_6 +-; LA64D-NEXT: .LBB27_5: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB27_1 Depth=1 +-; LA64D-NEXT: dbar 20 +-; LA64D-NEXT: .LBB27_6: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB27_1 Depth=1 +-; LA64D-NEXT: movgr2fr.w $fa0, $a3 +-; LA64D-NEXT: bne $a3, $a2, .LBB27_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: ret +- %v = atomicrmw fmax ptr %p, float 1.0 seq_cst, align 4 +- ret float %v +-} +- +-define double @double_fadd_seq_cst(ptr %p) nounwind { +-; LA64F-LABEL: double_fadd_seq_cst: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -80 +-; LA64F-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s4, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 0 +-; LA64F-NEXT: lu52i.d $s0, $zero, 1023 +-; LA64F-NEXT: ori $s1, $zero, 8 +-; LA64F-NEXT: addi.d $s2, $sp, 16 +-; LA64F-NEXT: addi.d $s3, $sp, 8 +-; LA64F-NEXT: ori $s4, $zero, 5 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB28_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64F-NEXT: st.d $a0, $sp, 16 +-; LA64F-NEXT: move $a1, $s0 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $sp, 8 +-; LA64F-NEXT: move $a0, $s1 +-; LA64F-NEXT: move $a1, $fp +-; LA64F-NEXT: move $a2, $s2 +-; LA64F-NEXT: move $a3, $s3 +-; LA64F-NEXT: move $a4, $s4 +-; LA64F-NEXT: move $a5, $s4 +-; LA64F-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64F-NEXT: move $a1, $a0 +-; LA64F-NEXT: ld.d $a0, $sp, 16 +-; LA64F-NEXT: beqz $a1, .LBB28_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ld.d $s4, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 80 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: double_fadd_seq_cst: +-; LA64D: # %bb.0: +-; LA64D-NEXT: addi.d $sp, $sp, -80 +-; LA64D-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64D-NEXT: fst.d $fs0, $sp, 24 # 8-byte Folded Spill +-; LA64D-NEXT: move $fp, $a0 +-; LA64D-NEXT: fld.d $fa0, $a0, 0 +-; LA64D-NEXT: addi.d $a0, $zero, 1 +-; LA64D-NEXT: movgr2fr.d $fa1, $a0 +-; LA64D-NEXT: ffint.d.l $fs0, $fa1 +-; LA64D-NEXT: ori $s0, $zero, 8 +-; LA64D-NEXT: addi.d $s1, $sp, 16 +-; LA64D-NEXT: addi.d $s2, $sp, 8 +-; LA64D-NEXT: ori $s3, $zero, 5 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB28_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64D-NEXT: fst.d $fa0, $sp, 16 +-; LA64D-NEXT: fadd.d $fa0, $fa0, $fs0 +-; LA64D-NEXT: fst.d $fa0, $sp, 8 +-; LA64D-NEXT: move $a0, $s0 +-; LA64D-NEXT: move $a1, $fp +-; LA64D-NEXT: move $a2, $s1 +-; LA64D-NEXT: move $a3, $s2 +-; LA64D-NEXT: move $a4, $s3 +-; LA64D-NEXT: move $a5, $s3 +-; LA64D-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64D-NEXT: fld.d $fa0, $sp, 16 +-; LA64D-NEXT: beqz $a0, .LBB28_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: fld.d $fs0, $sp, 24 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64D-NEXT: addi.d $sp, $sp, 80 +-; LA64D-NEXT: ret +- %v = atomicrmw fadd ptr %p, double 1.0 seq_cst, align 4 +- ret double %v +-} +- +-define double @double_fsub_seq_cst(ptr %p) nounwind { +-; LA64F-LABEL: double_fsub_seq_cst: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -80 +-; LA64F-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s4, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 0 +-; LA64F-NEXT: lu52i.d $s0, $zero, -1025 +-; LA64F-NEXT: ori $s1, $zero, 8 +-; LA64F-NEXT: addi.d $s2, $sp, 16 +-; LA64F-NEXT: addi.d $s3, $sp, 8 +-; LA64F-NEXT: ori $s4, $zero, 5 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB29_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64F-NEXT: st.d $a0, $sp, 16 +-; LA64F-NEXT: move $a1, $s0 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $sp, 8 +-; LA64F-NEXT: move $a0, $s1 +-; LA64F-NEXT: move $a1, $fp +-; LA64F-NEXT: move $a2, $s2 +-; LA64F-NEXT: move $a3, $s3 +-; LA64F-NEXT: move $a4, $s4 +-; LA64F-NEXT: move $a5, $s4 +-; LA64F-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64F-NEXT: move $a1, $a0 +-; LA64F-NEXT: ld.d $a0, $sp, 16 +-; LA64F-NEXT: beqz $a1, .LBB29_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ld.d $s4, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 80 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: double_fsub_seq_cst: +-; LA64D: # %bb.0: +-; LA64D-NEXT: addi.d $sp, $sp, -80 +-; LA64D-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64D-NEXT: fst.d $fs0, $sp, 24 # 8-byte Folded Spill +-; LA64D-NEXT: move $fp, $a0 +-; LA64D-NEXT: fld.d $fa0, $a0, 0 +-; LA64D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI29_0) +-; LA64D-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI29_0) +-; LA64D-NEXT: fld.d $fs0, $a0, 0 +-; LA64D-NEXT: ori $s0, $zero, 8 +-; LA64D-NEXT: addi.d $s1, $sp, 16 +-; LA64D-NEXT: addi.d $s2, $sp, 8 +-; LA64D-NEXT: ori $s3, $zero, 5 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB29_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64D-NEXT: fst.d $fa0, $sp, 16 +-; LA64D-NEXT: fadd.d $fa0, $fa0, $fs0 +-; LA64D-NEXT: fst.d $fa0, $sp, 8 +-; LA64D-NEXT: move $a0, $s0 +-; LA64D-NEXT: move $a1, $fp +-; LA64D-NEXT: move $a2, $s1 +-; LA64D-NEXT: move $a3, $s2 +-; LA64D-NEXT: move $a4, $s3 +-; LA64D-NEXT: move $a5, $s3 +-; LA64D-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64D-NEXT: fld.d $fa0, $sp, 16 +-; LA64D-NEXT: beqz $a0, .LBB29_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: fld.d $fs0, $sp, 24 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64D-NEXT: addi.d $sp, $sp, 80 +-; LA64D-NEXT: ret +- %v = atomicrmw fsub ptr %p, double 1.0 seq_cst, align 4 +- ret double %v +-} +- +-define double @double_fmin_seq_cst(ptr %p) nounwind { +-; LA64F-LABEL: double_fmin_seq_cst: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -80 +-; LA64F-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s4, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 0 +-; LA64F-NEXT: lu52i.d $s0, $zero, 1023 +-; LA64F-NEXT: ori $s1, $zero, 8 +-; LA64F-NEXT: addi.d $s2, $sp, 16 +-; LA64F-NEXT: addi.d $s3, $sp, 8 +-; LA64F-NEXT: ori $s4, $zero, 5 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB30_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64F-NEXT: st.d $a0, $sp, 16 +-; LA64F-NEXT: move $a1, $s0 +-; LA64F-NEXT: bl %plt(fmin) +-; LA64F-NEXT: st.d $a0, $sp, 8 +-; LA64F-NEXT: move $a0, $s1 +-; LA64F-NEXT: move $a1, $fp +-; LA64F-NEXT: move $a2, $s2 +-; LA64F-NEXT: move $a3, $s3 +-; LA64F-NEXT: move $a4, $s4 +-; LA64F-NEXT: move $a5, $s4 +-; LA64F-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64F-NEXT: move $a1, $a0 +-; LA64F-NEXT: ld.d $a0, $sp, 16 +-; LA64F-NEXT: beqz $a1, .LBB30_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ld.d $s4, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 80 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: double_fmin_seq_cst: +-; LA64D: # %bb.0: +-; LA64D-NEXT: addi.d $sp, $sp, -80 +-; LA64D-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64D-NEXT: fst.d $fs0, $sp, 24 # 8-byte Folded Spill +-; LA64D-NEXT: move $fp, $a0 +-; LA64D-NEXT: fld.d $fa0, $a0, 0 +-; LA64D-NEXT: addi.d $a0, $zero, 1 +-; LA64D-NEXT: movgr2fr.d $fa1, $a0 +-; LA64D-NEXT: ffint.d.l $fs0, $fa1 +-; LA64D-NEXT: ori $s0, $zero, 8 +-; LA64D-NEXT: addi.d $s1, $sp, 16 +-; LA64D-NEXT: addi.d $s2, $sp, 8 +-; LA64D-NEXT: ori $s3, $zero, 5 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB30_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64D-NEXT: fst.d $fa0, $sp, 16 +-; LA64D-NEXT: fmax.d $fa0, $fa0, $fa0 +-; LA64D-NEXT: fmin.d $fa0, $fa0, $fs0 +-; LA64D-NEXT: fst.d $fa0, $sp, 8 +-; LA64D-NEXT: move $a0, $s0 +-; LA64D-NEXT: move $a1, $fp +-; LA64D-NEXT: move $a2, $s1 +-; LA64D-NEXT: move $a3, $s2 +-; LA64D-NEXT: move $a4, $s3 +-; LA64D-NEXT: move $a5, $s3 +-; LA64D-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64D-NEXT: fld.d $fa0, $sp, 16 +-; LA64D-NEXT: beqz $a0, .LBB30_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: fld.d $fs0, $sp, 24 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64D-NEXT: addi.d $sp, $sp, 80 +-; LA64D-NEXT: ret +- %v = atomicrmw fmin ptr %p, double 1.0 seq_cst, align 4 +- ret double %v +-} +- +-define double @double_fmax_seq_cst(ptr %p) nounwind { +-; LA64F-LABEL: double_fmax_seq_cst: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -80 +-; LA64F-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s4, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 0 +-; LA64F-NEXT: lu52i.d $s0, $zero, 1023 +-; LA64F-NEXT: ori $s1, $zero, 8 +-; LA64F-NEXT: addi.d $s2, $sp, 16 +-; LA64F-NEXT: addi.d $s3, $sp, 8 +-; LA64F-NEXT: ori $s4, $zero, 5 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB31_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64F-NEXT: st.d $a0, $sp, 16 +-; LA64F-NEXT: move $a1, $s0 +-; LA64F-NEXT: bl %plt(fmax) +-; LA64F-NEXT: st.d $a0, $sp, 8 +-; LA64F-NEXT: move $a0, $s1 +-; LA64F-NEXT: move $a1, $fp +-; LA64F-NEXT: move $a2, $s2 +-; LA64F-NEXT: move $a3, $s3 +-; LA64F-NEXT: move $a4, $s4 +-; LA64F-NEXT: move $a5, $s4 +-; LA64F-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64F-NEXT: move $a1, $a0 +-; LA64F-NEXT: ld.d $a0, $sp, 16 +-; LA64F-NEXT: beqz $a1, .LBB31_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ld.d $s4, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 80 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: double_fmax_seq_cst: +-; LA64D: # %bb.0: +-; LA64D-NEXT: addi.d $sp, $sp, -80 +-; LA64D-NEXT: st.d $ra, $sp, 72 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $fp, $sp, 64 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s0, $sp, 56 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s1, $sp, 48 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s2, $sp, 40 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s3, $sp, 32 # 8-byte Folded Spill +-; LA64D-NEXT: fst.d $fs0, $sp, 24 # 8-byte Folded Spill +-; LA64D-NEXT: move $fp, $a0 +-; LA64D-NEXT: fld.d $fa0, $a0, 0 +-; LA64D-NEXT: addi.d $a0, $zero, 1 +-; LA64D-NEXT: movgr2fr.d $fa1, $a0 +-; LA64D-NEXT: ffint.d.l $fs0, $fa1 +-; LA64D-NEXT: ori $s0, $zero, 8 +-; LA64D-NEXT: addi.d $s1, $sp, 16 +-; LA64D-NEXT: addi.d $s2, $sp, 8 +-; LA64D-NEXT: ori $s3, $zero, 5 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB31_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64D-NEXT: fst.d $fa0, $sp, 16 +-; LA64D-NEXT: fmax.d $fa0, $fa0, $fa0 +-; LA64D-NEXT: fmax.d $fa0, $fa0, $fs0 +-; LA64D-NEXT: fst.d $fa0, $sp, 8 +-; LA64D-NEXT: move $a0, $s0 +-; LA64D-NEXT: move $a1, $fp +-; LA64D-NEXT: move $a2, $s1 +-; LA64D-NEXT: move $a3, $s2 +-; LA64D-NEXT: move $a4, $s3 +-; LA64D-NEXT: move $a5, $s3 +-; LA64D-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64D-NEXT: fld.d $fa0, $sp, 16 +-; LA64D-NEXT: beqz $a0, .LBB31_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: fld.d $fs0, $sp, 24 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s3, $sp, 32 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s2, $sp, 40 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s1, $sp, 48 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s0, $sp, 56 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $fp, $sp, 64 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload +-; LA64D-NEXT: addi.d $sp, $sp, 80 +-; LA64D-NEXT: ret +- %v = atomicrmw fmax ptr %p, double 1.0 seq_cst, align 4 +- ret double %v +-} +- +-define float @float_fadd_monotonic(ptr %p) nounwind { +-; LA64F-LABEL: float_fadd_monotonic: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: addi.w $a1, $zero, 1 +-; LA64F-NEXT: movgr2fr.w $fa1, $a1 +-; LA64F-NEXT: ffint.s.w $fa1, $fa1 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB32_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Loop Header: Depth=1 +-; LA64F-NEXT: # Child Loop BB32_3 Depth 2 +-; LA64F-NEXT: fadd.s $fa2, $fa0, $fa1 +-; LA64F-NEXT: movfr2gr.s $a1, $fa2 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: addi.w $a2, $a2, 0 +-; LA64F-NEXT: .LBB32_3: # %atomicrmw.start +-; LA64F-NEXT: # Parent Loop BB32_1 Depth=1 +-; LA64F-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64F-NEXT: ll.w $a3, $a0, 0 +-; LA64F-NEXT: bne $a3, $a2, .LBB32_5 +-; LA64F-NEXT: # %bb.4: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB32_3 Depth=2 +-; LA64F-NEXT: move $a4, $a1 +-; LA64F-NEXT: sc.w $a4, $a0, 0 +-; LA64F-NEXT: beqz $a4, .LBB32_3 +-; LA64F-NEXT: b .LBB32_6 +-; LA64F-NEXT: .LBB32_5: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB32_1 Depth=1 +-; LA64F-NEXT: dbar 1792 +-; LA64F-NEXT: .LBB32_6: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB32_1 Depth=1 +-; LA64F-NEXT: movgr2fr.w $fa0, $a3 +-; LA64F-NEXT: bne $a3, $a2, .LBB32_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: float_fadd_monotonic: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: addi.w $a1, $zero, 1 +-; LA64D-NEXT: movgr2fr.w $fa1, $a1 +-; LA64D-NEXT: ffint.s.w $fa1, $fa1 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB32_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Loop Header: Depth=1 +-; LA64D-NEXT: # Child Loop BB32_3 Depth 2 +-; LA64D-NEXT: fadd.s $fa2, $fa0, $fa1 +-; LA64D-NEXT: movfr2gr.s $a1, $fa2 +-; LA64D-NEXT: movfr2gr.s $a2, $fa0 +-; LA64D-NEXT: addi.w $a2, $a2, 0 +-; LA64D-NEXT: .LBB32_3: # %atomicrmw.start +-; LA64D-NEXT: # Parent Loop BB32_1 Depth=1 +-; LA64D-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64D-NEXT: ll.w $a3, $a0, 0 +-; LA64D-NEXT: bne $a3, $a2, .LBB32_5 +-; LA64D-NEXT: # %bb.4: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB32_3 Depth=2 +-; LA64D-NEXT: move $a4, $a1 +-; LA64D-NEXT: sc.w $a4, $a0, 0 +-; LA64D-NEXT: beqz $a4, .LBB32_3 +-; LA64D-NEXT: b .LBB32_6 +-; LA64D-NEXT: .LBB32_5: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB32_1 Depth=1 +-; LA64D-NEXT: dbar 1792 +-; LA64D-NEXT: .LBB32_6: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB32_1 Depth=1 +-; LA64D-NEXT: movgr2fr.w $fa0, $a3 +-; LA64D-NEXT: bne $a3, $a2, .LBB32_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: ret +- %v = atomicrmw fadd ptr %p, float 1.0 monotonic, align 4 +- ret float %v +-} +- +-define float @float_fsub_monotonic(ptr %p) nounwind { +-; LA64F-LABEL: float_fsub_monotonic: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: pcalau12i $a1, %pc_hi20(.LCPI33_0) +-; LA64F-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI33_0) +-; LA64F-NEXT: fld.s $fa1, $a1, 0 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB33_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Loop Header: Depth=1 +-; LA64F-NEXT: # Child Loop BB33_3 Depth 2 +-; LA64F-NEXT: fadd.s $fa2, $fa0, $fa1 +-; LA64F-NEXT: movfr2gr.s $a1, $fa2 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: addi.w $a2, $a2, 0 +-; LA64F-NEXT: .LBB33_3: # %atomicrmw.start +-; LA64F-NEXT: # Parent Loop BB33_1 Depth=1 +-; LA64F-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64F-NEXT: ll.w $a3, $a0, 0 +-; LA64F-NEXT: bne $a3, $a2, .LBB33_5 +-; LA64F-NEXT: # %bb.4: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB33_3 Depth=2 +-; LA64F-NEXT: move $a4, $a1 +-; LA64F-NEXT: sc.w $a4, $a0, 0 +-; LA64F-NEXT: beqz $a4, .LBB33_3 +-; LA64F-NEXT: b .LBB33_6 +-; LA64F-NEXT: .LBB33_5: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB33_1 Depth=1 +-; LA64F-NEXT: dbar 1792 +-; LA64F-NEXT: .LBB33_6: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB33_1 Depth=1 +-; LA64F-NEXT: movgr2fr.w $fa0, $a3 +-; LA64F-NEXT: bne $a3, $a2, .LBB33_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: float_fsub_monotonic: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: pcalau12i $a1, %pc_hi20(.LCPI33_0) +-; LA64D-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI33_0) +-; LA64D-NEXT: fld.s $fa1, $a1, 0 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB33_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Loop Header: Depth=1 +-; LA64D-NEXT: # Child Loop BB33_3 Depth 2 +-; LA64D-NEXT: fadd.s $fa2, $fa0, $fa1 +-; LA64D-NEXT: movfr2gr.s $a1, $fa2 +-; LA64D-NEXT: movfr2gr.s $a2, $fa0 +-; LA64D-NEXT: addi.w $a2, $a2, 0 +-; LA64D-NEXT: .LBB33_3: # %atomicrmw.start +-; LA64D-NEXT: # Parent Loop BB33_1 Depth=1 +-; LA64D-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64D-NEXT: ll.w $a3, $a0, 0 +-; LA64D-NEXT: bne $a3, $a2, .LBB33_5 +-; LA64D-NEXT: # %bb.4: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB33_3 Depth=2 +-; LA64D-NEXT: move $a4, $a1 +-; LA64D-NEXT: sc.w $a4, $a0, 0 +-; LA64D-NEXT: beqz $a4, .LBB33_3 +-; LA64D-NEXT: b .LBB33_6 +-; LA64D-NEXT: .LBB33_5: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB33_1 Depth=1 +-; LA64D-NEXT: dbar 1792 +-; LA64D-NEXT: .LBB33_6: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB33_1 Depth=1 +-; LA64D-NEXT: movgr2fr.w $fa0, $a3 +-; LA64D-NEXT: bne $a3, $a2, .LBB33_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: ret +- %v = atomicrmw fsub ptr %p, float 1.0 monotonic, align 4 +- ret float %v +-} +- +-define float @float_fmin_monotonic(ptr %p) nounwind { +-; LA64F-LABEL: float_fmin_monotonic: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: addi.w $a1, $zero, 1 +-; LA64F-NEXT: movgr2fr.w $fa1, $a1 +-; LA64F-NEXT: ffint.s.w $fa1, $fa1 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB34_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Loop Header: Depth=1 +-; LA64F-NEXT: # Child Loop BB34_3 Depth 2 +-; LA64F-NEXT: fmax.s $fa2, $fa0, $fa0 +-; LA64F-NEXT: fmin.s $fa2, $fa2, $fa1 +-; LA64F-NEXT: movfr2gr.s $a1, $fa2 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: addi.w $a2, $a2, 0 +-; LA64F-NEXT: .LBB34_3: # %atomicrmw.start +-; LA64F-NEXT: # Parent Loop BB34_1 Depth=1 +-; LA64F-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64F-NEXT: ll.w $a3, $a0, 0 +-; LA64F-NEXT: bne $a3, $a2, .LBB34_5 +-; LA64F-NEXT: # %bb.4: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB34_3 Depth=2 +-; LA64F-NEXT: move $a4, $a1 +-; LA64F-NEXT: sc.w $a4, $a0, 0 +-; LA64F-NEXT: beqz $a4, .LBB34_3 +-; LA64F-NEXT: b .LBB34_6 +-; LA64F-NEXT: .LBB34_5: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB34_1 Depth=1 +-; LA64F-NEXT: dbar 1792 +-; LA64F-NEXT: .LBB34_6: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB34_1 Depth=1 +-; LA64F-NEXT: movgr2fr.w $fa0, $a3 +-; LA64F-NEXT: bne $a3, $a2, .LBB34_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: float_fmin_monotonic: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: addi.w $a1, $zero, 1 +-; LA64D-NEXT: movgr2fr.w $fa1, $a1 +-; LA64D-NEXT: ffint.s.w $fa1, $fa1 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB34_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Loop Header: Depth=1 +-; LA64D-NEXT: # Child Loop BB34_3 Depth 2 +-; LA64D-NEXT: fmax.s $fa2, $fa0, $fa0 +-; LA64D-NEXT: fmin.s $fa2, $fa2, $fa1 +-; LA64D-NEXT: movfr2gr.s $a1, $fa2 +-; LA64D-NEXT: movfr2gr.s $a2, $fa0 +-; LA64D-NEXT: addi.w $a2, $a2, 0 +-; LA64D-NEXT: .LBB34_3: # %atomicrmw.start +-; LA64D-NEXT: # Parent Loop BB34_1 Depth=1 +-; LA64D-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64D-NEXT: ll.w $a3, $a0, 0 +-; LA64D-NEXT: bne $a3, $a2, .LBB34_5 +-; LA64D-NEXT: # %bb.4: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB34_3 Depth=2 +-; LA64D-NEXT: move $a4, $a1 +-; LA64D-NEXT: sc.w $a4, $a0, 0 +-; LA64D-NEXT: beqz $a4, .LBB34_3 +-; LA64D-NEXT: b .LBB34_6 +-; LA64D-NEXT: .LBB34_5: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB34_1 Depth=1 +-; LA64D-NEXT: dbar 1792 +-; LA64D-NEXT: .LBB34_6: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB34_1 Depth=1 +-; LA64D-NEXT: movgr2fr.w $fa0, $a3 +-; LA64D-NEXT: bne $a3, $a2, .LBB34_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: ret +- %v = atomicrmw fmin ptr %p, float 1.0 monotonic, align 4 +- ret float %v +-} +- +-define float @float_fmax_monotonic(ptr %p) nounwind { +-; LA64F-LABEL: float_fmax_monotonic: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: addi.w $a1, $zero, 1 +-; LA64F-NEXT: movgr2fr.w $fa1, $a1 +-; LA64F-NEXT: ffint.s.w $fa1, $fa1 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB35_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Loop Header: Depth=1 +-; LA64F-NEXT: # Child Loop BB35_3 Depth 2 +-; LA64F-NEXT: fmax.s $fa2, $fa0, $fa0 +-; LA64F-NEXT: fmax.s $fa2, $fa2, $fa1 +-; LA64F-NEXT: movfr2gr.s $a1, $fa2 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: addi.w $a2, $a2, 0 +-; LA64F-NEXT: .LBB35_3: # %atomicrmw.start +-; LA64F-NEXT: # Parent Loop BB35_1 Depth=1 +-; LA64F-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64F-NEXT: ll.w $a3, $a0, 0 +-; LA64F-NEXT: bne $a3, $a2, .LBB35_5 +-; LA64F-NEXT: # %bb.4: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB35_3 Depth=2 +-; LA64F-NEXT: move $a4, $a1 +-; LA64F-NEXT: sc.w $a4, $a0, 0 +-; LA64F-NEXT: beqz $a4, .LBB35_3 +-; LA64F-NEXT: b .LBB35_6 +-; LA64F-NEXT: .LBB35_5: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB35_1 Depth=1 +-; LA64F-NEXT: dbar 1792 +-; LA64F-NEXT: .LBB35_6: # %atomicrmw.start +-; LA64F-NEXT: # in Loop: Header=BB35_1 Depth=1 +-; LA64F-NEXT: movgr2fr.w $fa0, $a3 +-; LA64F-NEXT: bne $a3, $a2, .LBB35_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: float_fmax_monotonic: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: addi.w $a1, $zero, 1 +-; LA64D-NEXT: movgr2fr.w $fa1, $a1 +-; LA64D-NEXT: ffint.s.w $fa1, $fa1 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB35_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Loop Header: Depth=1 +-; LA64D-NEXT: # Child Loop BB35_3 Depth 2 +-; LA64D-NEXT: fmax.s $fa2, $fa0, $fa0 +-; LA64D-NEXT: fmax.s $fa2, $fa2, $fa1 +-; LA64D-NEXT: movfr2gr.s $a1, $fa2 +-; LA64D-NEXT: movfr2gr.s $a2, $fa0 +-; LA64D-NEXT: addi.w $a2, $a2, 0 +-; LA64D-NEXT: .LBB35_3: # %atomicrmw.start +-; LA64D-NEXT: # Parent Loop BB35_1 Depth=1 +-; LA64D-NEXT: # => This Inner Loop Header: Depth=2 +-; LA64D-NEXT: ll.w $a3, $a0, 0 +-; LA64D-NEXT: bne $a3, $a2, .LBB35_5 +-; LA64D-NEXT: # %bb.4: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB35_3 Depth=2 +-; LA64D-NEXT: move $a4, $a1 +-; LA64D-NEXT: sc.w $a4, $a0, 0 +-; LA64D-NEXT: beqz $a4, .LBB35_3 +-; LA64D-NEXT: b .LBB35_6 +-; LA64D-NEXT: .LBB35_5: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB35_1 Depth=1 +-; LA64D-NEXT: dbar 1792 +-; LA64D-NEXT: .LBB35_6: # %atomicrmw.start +-; LA64D-NEXT: # in Loop: Header=BB35_1 Depth=1 +-; LA64D-NEXT: movgr2fr.w $fa0, $a3 +-; LA64D-NEXT: bne $a3, $a2, .LBB35_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: ret +- %v = atomicrmw fmax ptr %p, float 1.0 monotonic, align 4 +- ret float %v +-} +- +-define double @double_fadd_monotonic(ptr %p) nounwind { +-; LA64F-LABEL: double_fadd_monotonic: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -64 +-; LA64F-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 48 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 40 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s1, $sp, 32 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s2, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s3, $sp, 16 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 0 +-; LA64F-NEXT: lu52i.d $s0, $zero, 1023 +-; LA64F-NEXT: ori $s1, $zero, 8 +-; LA64F-NEXT: addi.d $s2, $sp, 8 +-; LA64F-NEXT: addi.d $s3, $sp, 0 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB36_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64F-NEXT: st.d $a0, $sp, 8 +-; LA64F-NEXT: move $a1, $s0 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $sp, 0 +-; LA64F-NEXT: move $a0, $s1 +-; LA64F-NEXT: move $a1, $fp +-; LA64F-NEXT: move $a2, $s2 +-; LA64F-NEXT: move $a3, $s3 +-; LA64F-NEXT: move $a4, $zero +-; LA64F-NEXT: move $a5, $zero +-; LA64F-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64F-NEXT: move $a1, $a0 +-; LA64F-NEXT: ld.d $a0, $sp, 8 +-; LA64F-NEXT: beqz $a1, .LBB36_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ld.d $s3, $sp, 16 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s2, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s1, $sp, 32 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s0, $sp, 40 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 48 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 64 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: double_fadd_monotonic: +-; LA64D: # %bb.0: +-; LA64D-NEXT: addi.d $sp, $sp, -64 +-; LA64D-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $fp, $sp, 48 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s0, $sp, 40 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s1, $sp, 32 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s2, $sp, 24 # 8-byte Folded Spill +-; LA64D-NEXT: fst.d $fs0, $sp, 16 # 8-byte Folded Spill +-; LA64D-NEXT: move $fp, $a0 +-; LA64D-NEXT: fld.d $fa0, $a0, 0 +-; LA64D-NEXT: addi.d $a0, $zero, 1 +-; LA64D-NEXT: movgr2fr.d $fa1, $a0 +-; LA64D-NEXT: ffint.d.l $fs0, $fa1 +-; LA64D-NEXT: ori $s0, $zero, 8 +-; LA64D-NEXT: addi.d $s1, $sp, 8 +-; LA64D-NEXT: addi.d $s2, $sp, 0 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB36_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64D-NEXT: fst.d $fa0, $sp, 8 +-; LA64D-NEXT: fadd.d $fa0, $fa0, $fs0 +-; LA64D-NEXT: fst.d $fa0, $sp, 0 +-; LA64D-NEXT: move $a0, $s0 +-; LA64D-NEXT: move $a1, $fp +-; LA64D-NEXT: move $a2, $s1 +-; LA64D-NEXT: move $a3, $s2 +-; LA64D-NEXT: move $a4, $zero +-; LA64D-NEXT: move $a5, $zero +-; LA64D-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64D-NEXT: fld.d $fa0, $sp, 8 +-; LA64D-NEXT: beqz $a0, .LBB36_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: fld.d $fs0, $sp, 16 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s2, $sp, 24 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s1, $sp, 32 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s0, $sp, 40 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $fp, $sp, 48 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload +-; LA64D-NEXT: addi.d $sp, $sp, 64 +-; LA64D-NEXT: ret +- %v = atomicrmw fadd ptr %p, double 1.0 monotonic, align 4 +- ret double %v +-} +- +-define double @double_fsub_monotonic(ptr %p) nounwind { +-; LA64F-LABEL: double_fsub_monotonic: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -64 +-; LA64F-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 48 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 40 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s1, $sp, 32 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s2, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s3, $sp, 16 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 0 +-; LA64F-NEXT: lu52i.d $s0, $zero, -1025 +-; LA64F-NEXT: ori $s1, $zero, 8 +-; LA64F-NEXT: addi.d $s2, $sp, 8 +-; LA64F-NEXT: addi.d $s3, $sp, 0 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB37_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64F-NEXT: st.d $a0, $sp, 8 +-; LA64F-NEXT: move $a1, $s0 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $sp, 0 +-; LA64F-NEXT: move $a0, $s1 +-; LA64F-NEXT: move $a1, $fp +-; LA64F-NEXT: move $a2, $s2 +-; LA64F-NEXT: move $a3, $s3 +-; LA64F-NEXT: move $a4, $zero +-; LA64F-NEXT: move $a5, $zero +-; LA64F-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64F-NEXT: move $a1, $a0 +-; LA64F-NEXT: ld.d $a0, $sp, 8 +-; LA64F-NEXT: beqz $a1, .LBB37_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ld.d $s3, $sp, 16 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s2, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s1, $sp, 32 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s0, $sp, 40 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 48 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 64 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: double_fsub_monotonic: +-; LA64D: # %bb.0: +-; LA64D-NEXT: addi.d $sp, $sp, -64 +-; LA64D-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $fp, $sp, 48 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s0, $sp, 40 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s1, $sp, 32 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s2, $sp, 24 # 8-byte Folded Spill +-; LA64D-NEXT: fst.d $fs0, $sp, 16 # 8-byte Folded Spill +-; LA64D-NEXT: move $fp, $a0 +-; LA64D-NEXT: fld.d $fa0, $a0, 0 +-; LA64D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI37_0) +-; LA64D-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI37_0) +-; LA64D-NEXT: fld.d $fs0, $a0, 0 +-; LA64D-NEXT: ori $s0, $zero, 8 +-; LA64D-NEXT: addi.d $s1, $sp, 8 +-; LA64D-NEXT: addi.d $s2, $sp, 0 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB37_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64D-NEXT: fst.d $fa0, $sp, 8 +-; LA64D-NEXT: fadd.d $fa0, $fa0, $fs0 +-; LA64D-NEXT: fst.d $fa0, $sp, 0 +-; LA64D-NEXT: move $a0, $s0 +-; LA64D-NEXT: move $a1, $fp +-; LA64D-NEXT: move $a2, $s1 +-; LA64D-NEXT: move $a3, $s2 +-; LA64D-NEXT: move $a4, $zero +-; LA64D-NEXT: move $a5, $zero +-; LA64D-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64D-NEXT: fld.d $fa0, $sp, 8 +-; LA64D-NEXT: beqz $a0, .LBB37_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: fld.d $fs0, $sp, 16 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s2, $sp, 24 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s1, $sp, 32 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s0, $sp, 40 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $fp, $sp, 48 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload +-; LA64D-NEXT: addi.d $sp, $sp, 64 +-; LA64D-NEXT: ret +- %v = atomicrmw fsub ptr %p, double 1.0 monotonic, align 4 +- ret double %v +-} +- +-define double @double_fmin_monotonic(ptr %p) nounwind { +-; LA64F-LABEL: double_fmin_monotonic: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -64 +-; LA64F-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 48 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 40 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s1, $sp, 32 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s2, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s3, $sp, 16 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 0 +-; LA64F-NEXT: lu52i.d $s0, $zero, 1023 +-; LA64F-NEXT: ori $s1, $zero, 8 +-; LA64F-NEXT: addi.d $s2, $sp, 8 +-; LA64F-NEXT: addi.d $s3, $sp, 0 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB38_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64F-NEXT: st.d $a0, $sp, 8 +-; LA64F-NEXT: move $a1, $s0 +-; LA64F-NEXT: bl %plt(fmin) +-; LA64F-NEXT: st.d $a0, $sp, 0 +-; LA64F-NEXT: move $a0, $s1 +-; LA64F-NEXT: move $a1, $fp +-; LA64F-NEXT: move $a2, $s2 +-; LA64F-NEXT: move $a3, $s3 +-; LA64F-NEXT: move $a4, $zero +-; LA64F-NEXT: move $a5, $zero +-; LA64F-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64F-NEXT: move $a1, $a0 +-; LA64F-NEXT: ld.d $a0, $sp, 8 +-; LA64F-NEXT: beqz $a1, .LBB38_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ld.d $s3, $sp, 16 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s2, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s1, $sp, 32 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s0, $sp, 40 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 48 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 64 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: double_fmin_monotonic: +-; LA64D: # %bb.0: +-; LA64D-NEXT: addi.d $sp, $sp, -64 +-; LA64D-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $fp, $sp, 48 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s0, $sp, 40 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s1, $sp, 32 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s2, $sp, 24 # 8-byte Folded Spill +-; LA64D-NEXT: fst.d $fs0, $sp, 16 # 8-byte Folded Spill +-; LA64D-NEXT: move $fp, $a0 +-; LA64D-NEXT: fld.d $fa0, $a0, 0 +-; LA64D-NEXT: addi.d $a0, $zero, 1 +-; LA64D-NEXT: movgr2fr.d $fa1, $a0 +-; LA64D-NEXT: ffint.d.l $fs0, $fa1 +-; LA64D-NEXT: ori $s0, $zero, 8 +-; LA64D-NEXT: addi.d $s1, $sp, 8 +-; LA64D-NEXT: addi.d $s2, $sp, 0 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB38_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64D-NEXT: fst.d $fa0, $sp, 8 +-; LA64D-NEXT: fmax.d $fa0, $fa0, $fa0 +-; LA64D-NEXT: fmin.d $fa0, $fa0, $fs0 +-; LA64D-NEXT: fst.d $fa0, $sp, 0 +-; LA64D-NEXT: move $a0, $s0 +-; LA64D-NEXT: move $a1, $fp +-; LA64D-NEXT: move $a2, $s1 +-; LA64D-NEXT: move $a3, $s2 +-; LA64D-NEXT: move $a4, $zero +-; LA64D-NEXT: move $a5, $zero +-; LA64D-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64D-NEXT: fld.d $fa0, $sp, 8 +-; LA64D-NEXT: beqz $a0, .LBB38_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: fld.d $fs0, $sp, 16 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s2, $sp, 24 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s1, $sp, 32 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s0, $sp, 40 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $fp, $sp, 48 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload +-; LA64D-NEXT: addi.d $sp, $sp, 64 +-; LA64D-NEXT: ret +- %v = atomicrmw fmin ptr %p, double 1.0 monotonic, align 4 +- ret double %v +-} +- +-define double @double_fmax_monotonic(ptr %p) nounwind { +-; LA64F-LABEL: double_fmax_monotonic: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -64 +-; LA64F-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 48 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 40 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s1, $sp, 32 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s2, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s3, $sp, 16 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 0 +-; LA64F-NEXT: lu52i.d $s0, $zero, 1023 +-; LA64F-NEXT: ori $s1, $zero, 8 +-; LA64F-NEXT: addi.d $s2, $sp, 8 +-; LA64F-NEXT: addi.d $s3, $sp, 0 +-; LA64F-NEXT: .p2align 4, , 16 +-; LA64F-NEXT: .LBB39_1: # %atomicrmw.start +-; LA64F-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64F-NEXT: st.d $a0, $sp, 8 +-; LA64F-NEXT: move $a1, $s0 +-; LA64F-NEXT: bl %plt(fmax) +-; LA64F-NEXT: st.d $a0, $sp, 0 +-; LA64F-NEXT: move $a0, $s1 +-; LA64F-NEXT: move $a1, $fp +-; LA64F-NEXT: move $a2, $s2 +-; LA64F-NEXT: move $a3, $s3 +-; LA64F-NEXT: move $a4, $zero +-; LA64F-NEXT: move $a5, $zero +-; LA64F-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64F-NEXT: move $a1, $a0 +-; LA64F-NEXT: ld.d $a0, $sp, 8 +-; LA64F-NEXT: beqz $a1, .LBB39_1 +-; LA64F-NEXT: # %bb.2: # %atomicrmw.end +-; LA64F-NEXT: ld.d $s3, $sp, 16 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s2, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s1, $sp, 32 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s0, $sp, 40 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 48 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 64 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: double_fmax_monotonic: +-; LA64D: # %bb.0: +-; LA64D-NEXT: addi.d $sp, $sp, -64 +-; LA64D-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $fp, $sp, 48 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s0, $sp, 40 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s1, $sp, 32 # 8-byte Folded Spill +-; LA64D-NEXT: st.d $s2, $sp, 24 # 8-byte Folded Spill +-; LA64D-NEXT: fst.d $fs0, $sp, 16 # 8-byte Folded Spill +-; LA64D-NEXT: move $fp, $a0 +-; LA64D-NEXT: fld.d $fa0, $a0, 0 +-; LA64D-NEXT: addi.d $a0, $zero, 1 +-; LA64D-NEXT: movgr2fr.d $fa1, $a0 +-; LA64D-NEXT: ffint.d.l $fs0, $fa1 +-; LA64D-NEXT: ori $s0, $zero, 8 +-; LA64D-NEXT: addi.d $s1, $sp, 8 +-; LA64D-NEXT: addi.d $s2, $sp, 0 +-; LA64D-NEXT: .p2align 4, , 16 +-; LA64D-NEXT: .LBB39_1: # %atomicrmw.start +-; LA64D-NEXT: # =>This Inner Loop Header: Depth=1 +-; LA64D-NEXT: fst.d $fa0, $sp, 8 +-; LA64D-NEXT: fmax.d $fa0, $fa0, $fa0 +-; LA64D-NEXT: fmax.d $fa0, $fa0, $fs0 +-; LA64D-NEXT: fst.d $fa0, $sp, 0 +-; LA64D-NEXT: move $a0, $s0 +-; LA64D-NEXT: move $a1, $fp +-; LA64D-NEXT: move $a2, $s1 +-; LA64D-NEXT: move $a3, $s2 +-; LA64D-NEXT: move $a4, $zero +-; LA64D-NEXT: move $a5, $zero +-; LA64D-NEXT: bl %plt(__atomic_compare_exchange) +-; LA64D-NEXT: fld.d $fa0, $sp, 8 +-; LA64D-NEXT: beqz $a0, .LBB39_1 +-; LA64D-NEXT: # %bb.2: # %atomicrmw.end +-; LA64D-NEXT: fld.d $fs0, $sp, 16 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s2, $sp, 24 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s1, $sp, 32 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $s0, $sp, 40 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $fp, $sp, 48 # 8-byte Folded Reload +-; LA64D-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload +-; LA64D-NEXT: addi.d $sp, $sp, 64 +-; LA64D-NEXT: ret +- %v = atomicrmw fmax ptr %p, double 1.0 monotonic, align 4 +- ret double %v +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw-minmax.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw-minmax.ll +deleted file mode 100644 +index 464c9ce97..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw-minmax.ll ++++ /dev/null +@@ -1,1715 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s | \ +-; RUN: FileCheck %s --check-prefix=LA64 +- +-;; TODO: Testing for LA32 architecture will be added later +- +-define i8 @atomicrmw_umax_i8_acquire(ptr %a, i8 %b) nounwind { +-; LA64-LABEL: atomicrmw_umax_i8_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB0_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a6, $a4, $a3 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: bgeu $a6, $a1, .LBB0_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB0_1 Depth=1 +-; LA64-NEXT: xor $a5, $a4, $a1 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: .LBB0_3: # in Loop: Header=BB0_1 Depth=1 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB0_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umax ptr %a, i8 %b acquire +- ret i8 %1 +-} +- +-define i16 @atomicrmw_umax_i16_acquire(ptr %a, i16 %b) nounwind { +-; LA64-LABEL: atomicrmw_umax_i16_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB1_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a6, $a4, $a2 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: bgeu $a6, $a1, .LBB1_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB1_1 Depth=1 +-; LA64-NEXT: xor $a5, $a4, $a1 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: .LBB1_3: # in Loop: Header=BB1_1 Depth=1 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB1_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw umax ptr %a, i16 %b acquire +- ret i16 %1 +-} +- +-define i32 @atomicrmw_umax_i32_acquire(ptr %a, i32 %b) nounwind { +-; LA64-LABEL: atomicrmw_umax_i32_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: ammax_db.wu $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umax ptr %a, i32 %b acquire +- ret i32 %1 +-} +- +-define i64 @atomicrmw_umax_i64_acquire(ptr %a, i64 %b) nounwind { +-; LA64-LABEL: atomicrmw_umax_i64_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: ammax_db.du $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umax ptr %a, i64 %b acquire +- ret i64 %1 +-} +- +-define i8 @atomicrmw_umin_i8_acquire(ptr %a, i8 %b) nounwind { +-; LA64-LABEL: atomicrmw_umin_i8_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB4_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a6, $a4, $a3 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: bgeu $a1, $a6, .LBB4_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB4_1 Depth=1 +-; LA64-NEXT: xor $a5, $a4, $a1 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: .LBB4_3: # in Loop: Header=BB4_1 Depth=1 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB4_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umin ptr %a, i8 %b acquire +- ret i8 %1 +-} +- +-define i16 @atomicrmw_umin_i16_acquire(ptr %a, i16 %b) nounwind { +-; LA64-LABEL: atomicrmw_umin_i16_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB5_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a6, $a4, $a2 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: bgeu $a1, $a6, .LBB5_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB5_1 Depth=1 +-; LA64-NEXT: xor $a5, $a4, $a1 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: .LBB5_3: # in Loop: Header=BB5_1 Depth=1 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB5_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw umin ptr %a, i16 %b acquire +- ret i16 %1 +-} +- +-define i32 @atomicrmw_umin_i32_acquire(ptr %a, i32 %b) nounwind { +-; LA64-LABEL: atomicrmw_umin_i32_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: ammin_db.wu $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umin ptr %a, i32 %b acquire +- ret i32 %1 +-} +- +-define i64 @atomicrmw_umin_i64_acquire(ptr %a, i64 %b) nounwind { +-; LA64-LABEL: atomicrmw_umin_i64_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: ammin_db.du $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umin ptr %a, i64 %b acquire +- ret i64 %1 +-} +- +-define i8 @atomicrmw_max_i8_acquire(ptr %a, i8 %b) nounwind { +-; LA64-LABEL: atomicrmw_max_i8_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: ext.w.b $a1, $a1 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: andi $a4, $a2, 24 +-; LA64-NEXT: xori $a4, $a4, 56 +-; LA64-NEXT: .LBB8_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a7, $a5, $a3 +-; LA64-NEXT: move $a6, $a5 +-; LA64-NEXT: sll.w $a7, $a7, $a4 +-; LA64-NEXT: sra.w $a7, $a7, $a4 +-; LA64-NEXT: bge $a7, $a1, .LBB8_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB8_1 Depth=1 +-; LA64-NEXT: xor $a6, $a5, $a1 +-; LA64-NEXT: and $a6, $a6, $a3 +-; LA64-NEXT: xor $a6, $a5, $a6 +-; LA64-NEXT: .LBB8_3: # in Loop: Header=BB8_1 Depth=1 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB8_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a5, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw max ptr %a, i8 %b acquire +- ret i8 %1 +-} +- +-define i16 @atomicrmw_max_i16_acquire(ptr %a, i16 %b) nounwind { +-; LA64-LABEL: atomicrmw_max_i16_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: andi $a3, $a2, 24 +-; LA64-NEXT: ori $a4, $zero, 48 +-; LA64-NEXT: sub.d $a3, $a4, $a3 +-; LA64-NEXT: lu12i.w $a4, 15 +-; LA64-NEXT: ori $a4, $a4, 4095 +-; LA64-NEXT: sll.w $a4, $a4, $a2 +-; LA64-NEXT: addi.w $a4, $a4, 0 +-; LA64-NEXT: ext.w.h $a1, $a1 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB9_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a7, $a5, $a4 +-; LA64-NEXT: move $a6, $a5 +-; LA64-NEXT: sll.w $a7, $a7, $a3 +-; LA64-NEXT: sra.w $a7, $a7, $a3 +-; LA64-NEXT: bge $a7, $a1, .LBB9_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB9_1 Depth=1 +-; LA64-NEXT: xor $a6, $a5, $a1 +-; LA64-NEXT: and $a6, $a6, $a4 +-; LA64-NEXT: xor $a6, $a5, $a6 +-; LA64-NEXT: .LBB9_3: # in Loop: Header=BB9_1 Depth=1 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB9_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a5, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw max ptr %a, i16 %b acquire +- ret i16 %1 +-} +- +-define i32 @atomicrmw_max_i32_acquire(ptr %a, i32 %b) nounwind { +-; LA64-LABEL: atomicrmw_max_i32_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: ammax_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw max ptr %a, i32 %b acquire +- ret i32 %1 +-} +- +-define i64 @atomicrmw_max_i64_acquire(ptr %a, i64 %b) nounwind { +-; LA64-LABEL: atomicrmw_max_i64_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: ammax_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw max ptr %a, i64 %b acquire +- ret i64 %1 +-} +- +-define i8 @atomicrmw_min_i8_acquire(ptr %a, i8 %b) nounwind { +-; LA64-LABEL: atomicrmw_min_i8_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: ext.w.b $a1, $a1 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: andi $a4, $a2, 24 +-; LA64-NEXT: xori $a4, $a4, 56 +-; LA64-NEXT: .LBB12_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a7, $a5, $a3 +-; LA64-NEXT: move $a6, $a5 +-; LA64-NEXT: sll.w $a7, $a7, $a4 +-; LA64-NEXT: sra.w $a7, $a7, $a4 +-; LA64-NEXT: bge $a1, $a7, .LBB12_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB12_1 Depth=1 +-; LA64-NEXT: xor $a6, $a5, $a1 +-; LA64-NEXT: and $a6, $a6, $a3 +-; LA64-NEXT: xor $a6, $a5, $a6 +-; LA64-NEXT: .LBB12_3: # in Loop: Header=BB12_1 Depth=1 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB12_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a5, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw min ptr %a, i8 %b acquire +- ret i8 %1 +-} +- +-define i16 @atomicrmw_min_i16_acquire(ptr %a, i16 %b) nounwind { +-; LA64-LABEL: atomicrmw_min_i16_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: andi $a3, $a2, 24 +-; LA64-NEXT: ori $a4, $zero, 48 +-; LA64-NEXT: sub.d $a3, $a4, $a3 +-; LA64-NEXT: lu12i.w $a4, 15 +-; LA64-NEXT: ori $a4, $a4, 4095 +-; LA64-NEXT: sll.w $a4, $a4, $a2 +-; LA64-NEXT: addi.w $a4, $a4, 0 +-; LA64-NEXT: ext.w.h $a1, $a1 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB13_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a7, $a5, $a4 +-; LA64-NEXT: move $a6, $a5 +-; LA64-NEXT: sll.w $a7, $a7, $a3 +-; LA64-NEXT: sra.w $a7, $a7, $a3 +-; LA64-NEXT: bge $a1, $a7, .LBB13_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB13_1 Depth=1 +-; LA64-NEXT: xor $a6, $a5, $a1 +-; LA64-NEXT: and $a6, $a6, $a4 +-; LA64-NEXT: xor $a6, $a5, $a6 +-; LA64-NEXT: .LBB13_3: # in Loop: Header=BB13_1 Depth=1 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB13_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a5, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw min ptr %a, i16 %b acquire +- ret i16 %1 +-} +- +-define i32 @atomicrmw_min_i32_acquire(ptr %a, i32 %b) nounwind { +-; LA64-LABEL: atomicrmw_min_i32_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: ammin_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw min ptr %a, i32 %b acquire +- ret i32 %1 +-} +- +-define i64 @atomicrmw_min_i64_acquire(ptr %a, i64 %b) nounwind { +-; LA64-LABEL: atomicrmw_min_i64_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: ammin_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw min ptr %a, i64 %b acquire +- ret i64 %1 +-} +- +-define i8 @atomicrmw_umax_i8_release(ptr %a, i8 %b) nounwind { +-; LA64-LABEL: atomicrmw_umax_i8_release: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB16_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a6, $a4, $a3 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: bgeu $a6, $a1, .LBB16_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB16_1 Depth=1 +-; LA64-NEXT: xor $a5, $a4, $a1 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: .LBB16_3: # in Loop: Header=BB16_1 Depth=1 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB16_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umax ptr %a, i8 %b release +- ret i8 %1 +-} +- +-define i16 @atomicrmw_umax_i16_release(ptr %a, i16 %b) nounwind { +-; LA64-LABEL: atomicrmw_umax_i16_release: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB17_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a6, $a4, $a2 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: bgeu $a6, $a1, .LBB17_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB17_1 Depth=1 +-; LA64-NEXT: xor $a5, $a4, $a1 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: .LBB17_3: # in Loop: Header=BB17_1 Depth=1 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB17_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw umax ptr %a, i16 %b release +- ret i16 %1 +-} +- +-define i32 @atomicrmw_umax_i32_release(ptr %a, i32 %b) nounwind { +-; LA64-LABEL: atomicrmw_umax_i32_release: +-; LA64: # %bb.0: +-; LA64-NEXT: ammax_db.wu $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umax ptr %a, i32 %b release +- ret i32 %1 +-} +- +-define i64 @atomicrmw_umax_i64_release(ptr %a, i64 %b) nounwind { +-; LA64-LABEL: atomicrmw_umax_i64_release: +-; LA64: # %bb.0: +-; LA64-NEXT: ammax_db.du $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umax ptr %a, i64 %b release +- ret i64 %1 +-} +- +-define i8 @atomicrmw_umin_i8_release(ptr %a, i8 %b) nounwind { +-; LA64-LABEL: atomicrmw_umin_i8_release: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB20_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a6, $a4, $a3 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: bgeu $a1, $a6, .LBB20_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB20_1 Depth=1 +-; LA64-NEXT: xor $a5, $a4, $a1 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: .LBB20_3: # in Loop: Header=BB20_1 Depth=1 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB20_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umin ptr %a, i8 %b release +- ret i8 %1 +-} +- +-define i16 @atomicrmw_umin_i16_release(ptr %a, i16 %b) nounwind { +-; LA64-LABEL: atomicrmw_umin_i16_release: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB21_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a6, $a4, $a2 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: bgeu $a1, $a6, .LBB21_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB21_1 Depth=1 +-; LA64-NEXT: xor $a5, $a4, $a1 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: .LBB21_3: # in Loop: Header=BB21_1 Depth=1 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB21_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw umin ptr %a, i16 %b release +- ret i16 %1 +-} +- +-define i32 @atomicrmw_umin_i32_release(ptr %a, i32 %b) nounwind { +-; LA64-LABEL: atomicrmw_umin_i32_release: +-; LA64: # %bb.0: +-; LA64-NEXT: ammin_db.wu $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umin ptr %a, i32 %b release +- ret i32 %1 +-} +- +-define i64 @atomicrmw_umin_i64_release(ptr %a, i64 %b) nounwind { +-; LA64-LABEL: atomicrmw_umin_i64_release: +-; LA64: # %bb.0: +-; LA64-NEXT: ammin_db.du $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umin ptr %a, i64 %b release +- ret i64 %1 +-} +- +-define i8 @atomicrmw_max_i8_release(ptr %a, i8 %b) nounwind { +-; LA64-LABEL: atomicrmw_max_i8_release: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: ext.w.b $a1, $a1 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: andi $a4, $a2, 24 +-; LA64-NEXT: xori $a4, $a4, 56 +-; LA64-NEXT: .LBB24_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a7, $a5, $a3 +-; LA64-NEXT: move $a6, $a5 +-; LA64-NEXT: sll.w $a7, $a7, $a4 +-; LA64-NEXT: sra.w $a7, $a7, $a4 +-; LA64-NEXT: bge $a7, $a1, .LBB24_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB24_1 Depth=1 +-; LA64-NEXT: xor $a6, $a5, $a1 +-; LA64-NEXT: and $a6, $a6, $a3 +-; LA64-NEXT: xor $a6, $a5, $a6 +-; LA64-NEXT: .LBB24_3: # in Loop: Header=BB24_1 Depth=1 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB24_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a5, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw max ptr %a, i8 %b release +- ret i8 %1 +-} +- +-define i16 @atomicrmw_max_i16_release(ptr %a, i16 %b) nounwind { +-; LA64-LABEL: atomicrmw_max_i16_release: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: andi $a3, $a2, 24 +-; LA64-NEXT: ori $a4, $zero, 48 +-; LA64-NEXT: sub.d $a3, $a4, $a3 +-; LA64-NEXT: lu12i.w $a4, 15 +-; LA64-NEXT: ori $a4, $a4, 4095 +-; LA64-NEXT: sll.w $a4, $a4, $a2 +-; LA64-NEXT: addi.w $a4, $a4, 0 +-; LA64-NEXT: ext.w.h $a1, $a1 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB25_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a7, $a5, $a4 +-; LA64-NEXT: move $a6, $a5 +-; LA64-NEXT: sll.w $a7, $a7, $a3 +-; LA64-NEXT: sra.w $a7, $a7, $a3 +-; LA64-NEXT: bge $a7, $a1, .LBB25_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB25_1 Depth=1 +-; LA64-NEXT: xor $a6, $a5, $a1 +-; LA64-NEXT: and $a6, $a6, $a4 +-; LA64-NEXT: xor $a6, $a5, $a6 +-; LA64-NEXT: .LBB25_3: # in Loop: Header=BB25_1 Depth=1 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB25_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a5, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw max ptr %a, i16 %b release +- ret i16 %1 +-} +- +-define i32 @atomicrmw_max_i32_release(ptr %a, i32 %b) nounwind { +-; LA64-LABEL: atomicrmw_max_i32_release: +-; LA64: # %bb.0: +-; LA64-NEXT: ammax_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw max ptr %a, i32 %b release +- ret i32 %1 +-} +- +-define i64 @atomicrmw_max_i64_release(ptr %a, i64 %b) nounwind { +-; LA64-LABEL: atomicrmw_max_i64_release: +-; LA64: # %bb.0: +-; LA64-NEXT: ammax_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw max ptr %a, i64 %b release +- ret i64 %1 +-} +- +-define i8 @atomicrmw_min_i8_release(ptr %a, i8 %b) nounwind { +-; LA64-LABEL: atomicrmw_min_i8_release: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: ext.w.b $a1, $a1 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: andi $a4, $a2, 24 +-; LA64-NEXT: xori $a4, $a4, 56 +-; LA64-NEXT: .LBB28_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a7, $a5, $a3 +-; LA64-NEXT: move $a6, $a5 +-; LA64-NEXT: sll.w $a7, $a7, $a4 +-; LA64-NEXT: sra.w $a7, $a7, $a4 +-; LA64-NEXT: bge $a1, $a7, .LBB28_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB28_1 Depth=1 +-; LA64-NEXT: xor $a6, $a5, $a1 +-; LA64-NEXT: and $a6, $a6, $a3 +-; LA64-NEXT: xor $a6, $a5, $a6 +-; LA64-NEXT: .LBB28_3: # in Loop: Header=BB28_1 Depth=1 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB28_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a5, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw min ptr %a, i8 %b release +- ret i8 %1 +-} +- +-define i16 @atomicrmw_min_i16_release(ptr %a, i16 %b) nounwind { +-; LA64-LABEL: atomicrmw_min_i16_release: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: andi $a3, $a2, 24 +-; LA64-NEXT: ori $a4, $zero, 48 +-; LA64-NEXT: sub.d $a3, $a4, $a3 +-; LA64-NEXT: lu12i.w $a4, 15 +-; LA64-NEXT: ori $a4, $a4, 4095 +-; LA64-NEXT: sll.w $a4, $a4, $a2 +-; LA64-NEXT: addi.w $a4, $a4, 0 +-; LA64-NEXT: ext.w.h $a1, $a1 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB29_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a7, $a5, $a4 +-; LA64-NEXT: move $a6, $a5 +-; LA64-NEXT: sll.w $a7, $a7, $a3 +-; LA64-NEXT: sra.w $a7, $a7, $a3 +-; LA64-NEXT: bge $a1, $a7, .LBB29_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB29_1 Depth=1 +-; LA64-NEXT: xor $a6, $a5, $a1 +-; LA64-NEXT: and $a6, $a6, $a4 +-; LA64-NEXT: xor $a6, $a5, $a6 +-; LA64-NEXT: .LBB29_3: # in Loop: Header=BB29_1 Depth=1 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB29_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a5, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw min ptr %a, i16 %b release +- ret i16 %1 +-} +- +-define i32 @atomicrmw_min_i32_release(ptr %a, i32 %b) nounwind { +-; LA64-LABEL: atomicrmw_min_i32_release: +-; LA64: # %bb.0: +-; LA64-NEXT: ammin_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw min ptr %a, i32 %b release +- ret i32 %1 +-} +- +-define i64 @atomicrmw_min_i64_release(ptr %a, i64 %b) nounwind { +-; LA64-LABEL: atomicrmw_min_i64_release: +-; LA64: # %bb.0: +-; LA64-NEXT: ammin_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw min ptr %a, i64 %b release +- ret i64 %1 +-} +- +-define i8 @atomicrmw_umax_i8_acq_rel(ptr %a, i8 %b) nounwind { +-; LA64-LABEL: atomicrmw_umax_i8_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB32_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a6, $a4, $a3 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: bgeu $a6, $a1, .LBB32_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB32_1 Depth=1 +-; LA64-NEXT: xor $a5, $a4, $a1 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: .LBB32_3: # in Loop: Header=BB32_1 Depth=1 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB32_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umax ptr %a, i8 %b acq_rel +- ret i8 %1 +-} +- +-define i16 @atomicrmw_umax_i16_acq_rel(ptr %a, i16 %b) nounwind { +-; LA64-LABEL: atomicrmw_umax_i16_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB33_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a6, $a4, $a2 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: bgeu $a6, $a1, .LBB33_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB33_1 Depth=1 +-; LA64-NEXT: xor $a5, $a4, $a1 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: .LBB33_3: # in Loop: Header=BB33_1 Depth=1 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB33_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw umax ptr %a, i16 %b acq_rel +- ret i16 %1 +-} +- +-define i32 @atomicrmw_umax_i32_acq_rel(ptr %a, i32 %b) nounwind { +-; LA64-LABEL: atomicrmw_umax_i32_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: ammax_db.wu $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umax ptr %a, i32 %b acq_rel +- ret i32 %1 +-} +- +-define i64 @atomicrmw_umax_i64_acq_rel(ptr %a, i64 %b) nounwind { +-; LA64-LABEL: atomicrmw_umax_i64_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: ammax_db.du $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umax ptr %a, i64 %b acq_rel +- ret i64 %1 +-} +- +-define i8 @atomicrmw_umin_i8_acq_rel(ptr %a, i8 %b) nounwind { +-; LA64-LABEL: atomicrmw_umin_i8_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB36_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a6, $a4, $a3 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: bgeu $a1, $a6, .LBB36_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB36_1 Depth=1 +-; LA64-NEXT: xor $a5, $a4, $a1 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: .LBB36_3: # in Loop: Header=BB36_1 Depth=1 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB36_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umin ptr %a, i8 %b acq_rel +- ret i8 %1 +-} +- +-define i16 @atomicrmw_umin_i16_acq_rel(ptr %a, i16 %b) nounwind { +-; LA64-LABEL: atomicrmw_umin_i16_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB37_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a6, $a4, $a2 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: bgeu $a1, $a6, .LBB37_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB37_1 Depth=1 +-; LA64-NEXT: xor $a5, $a4, $a1 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: .LBB37_3: # in Loop: Header=BB37_1 Depth=1 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB37_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw umin ptr %a, i16 %b acq_rel +- ret i16 %1 +-} +- +-define i32 @atomicrmw_umin_i32_acq_rel(ptr %a, i32 %b) nounwind { +-; LA64-LABEL: atomicrmw_umin_i32_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: ammin_db.wu $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umin ptr %a, i32 %b acq_rel +- ret i32 %1 +-} +- +-define i64 @atomicrmw_umin_i64_acq_rel(ptr %a, i64 %b) nounwind { +-; LA64-LABEL: atomicrmw_umin_i64_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: ammin_db.du $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umin ptr %a, i64 %b acq_rel +- ret i64 %1 +-} +- +-define i8 @atomicrmw_max_i8_acq_rel(ptr %a, i8 %b) nounwind { +-; LA64-LABEL: atomicrmw_max_i8_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: ext.w.b $a1, $a1 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: andi $a4, $a2, 24 +-; LA64-NEXT: xori $a4, $a4, 56 +-; LA64-NEXT: .LBB40_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a7, $a5, $a3 +-; LA64-NEXT: move $a6, $a5 +-; LA64-NEXT: sll.w $a7, $a7, $a4 +-; LA64-NEXT: sra.w $a7, $a7, $a4 +-; LA64-NEXT: bge $a7, $a1, .LBB40_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB40_1 Depth=1 +-; LA64-NEXT: xor $a6, $a5, $a1 +-; LA64-NEXT: and $a6, $a6, $a3 +-; LA64-NEXT: xor $a6, $a5, $a6 +-; LA64-NEXT: .LBB40_3: # in Loop: Header=BB40_1 Depth=1 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB40_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a5, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw max ptr %a, i8 %b acq_rel +- ret i8 %1 +-} +- +-define i16 @atomicrmw_max_i16_acq_rel(ptr %a, i16 %b) nounwind { +-; LA64-LABEL: atomicrmw_max_i16_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: andi $a3, $a2, 24 +-; LA64-NEXT: ori $a4, $zero, 48 +-; LA64-NEXT: sub.d $a3, $a4, $a3 +-; LA64-NEXT: lu12i.w $a4, 15 +-; LA64-NEXT: ori $a4, $a4, 4095 +-; LA64-NEXT: sll.w $a4, $a4, $a2 +-; LA64-NEXT: addi.w $a4, $a4, 0 +-; LA64-NEXT: ext.w.h $a1, $a1 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB41_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a7, $a5, $a4 +-; LA64-NEXT: move $a6, $a5 +-; LA64-NEXT: sll.w $a7, $a7, $a3 +-; LA64-NEXT: sra.w $a7, $a7, $a3 +-; LA64-NEXT: bge $a7, $a1, .LBB41_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB41_1 Depth=1 +-; LA64-NEXT: xor $a6, $a5, $a1 +-; LA64-NEXT: and $a6, $a6, $a4 +-; LA64-NEXT: xor $a6, $a5, $a6 +-; LA64-NEXT: .LBB41_3: # in Loop: Header=BB41_1 Depth=1 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB41_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a5, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw max ptr %a, i16 %b acq_rel +- ret i16 %1 +-} +- +-define i32 @atomicrmw_max_i32_acq_rel(ptr %a, i32 %b) nounwind { +-; LA64-LABEL: atomicrmw_max_i32_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: ammax_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw max ptr %a, i32 %b acq_rel +- ret i32 %1 +-} +- +-define i64 @atomicrmw_max_i64_acq_rel(ptr %a, i64 %b) nounwind { +-; LA64-LABEL: atomicrmw_max_i64_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: ammax_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw max ptr %a, i64 %b acq_rel +- ret i64 %1 +-} +- +-define i8 @atomicrmw_min_i8_acq_rel(ptr %a, i8 %b) nounwind { +-; LA64-LABEL: atomicrmw_min_i8_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: ext.w.b $a1, $a1 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: andi $a4, $a2, 24 +-; LA64-NEXT: xori $a4, $a4, 56 +-; LA64-NEXT: .LBB44_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a7, $a5, $a3 +-; LA64-NEXT: move $a6, $a5 +-; LA64-NEXT: sll.w $a7, $a7, $a4 +-; LA64-NEXT: sra.w $a7, $a7, $a4 +-; LA64-NEXT: bge $a1, $a7, .LBB44_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB44_1 Depth=1 +-; LA64-NEXT: xor $a6, $a5, $a1 +-; LA64-NEXT: and $a6, $a6, $a3 +-; LA64-NEXT: xor $a6, $a5, $a6 +-; LA64-NEXT: .LBB44_3: # in Loop: Header=BB44_1 Depth=1 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB44_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a5, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw min ptr %a, i8 %b acq_rel +- ret i8 %1 +-} +- +-define i16 @atomicrmw_min_i16_acq_rel(ptr %a, i16 %b) nounwind { +-; LA64-LABEL: atomicrmw_min_i16_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: andi $a3, $a2, 24 +-; LA64-NEXT: ori $a4, $zero, 48 +-; LA64-NEXT: sub.d $a3, $a4, $a3 +-; LA64-NEXT: lu12i.w $a4, 15 +-; LA64-NEXT: ori $a4, $a4, 4095 +-; LA64-NEXT: sll.w $a4, $a4, $a2 +-; LA64-NEXT: addi.w $a4, $a4, 0 +-; LA64-NEXT: ext.w.h $a1, $a1 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB45_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a7, $a5, $a4 +-; LA64-NEXT: move $a6, $a5 +-; LA64-NEXT: sll.w $a7, $a7, $a3 +-; LA64-NEXT: sra.w $a7, $a7, $a3 +-; LA64-NEXT: bge $a1, $a7, .LBB45_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB45_1 Depth=1 +-; LA64-NEXT: xor $a6, $a5, $a1 +-; LA64-NEXT: and $a6, $a6, $a4 +-; LA64-NEXT: xor $a6, $a5, $a6 +-; LA64-NEXT: .LBB45_3: # in Loop: Header=BB45_1 Depth=1 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB45_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a5, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw min ptr %a, i16 %b acq_rel +- ret i16 %1 +-} +- +-define i32 @atomicrmw_min_i32_acq_rel(ptr %a, i32 %b) nounwind { +-; LA64-LABEL: atomicrmw_min_i32_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: ammin_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw min ptr %a, i32 %b acq_rel +- ret i32 %1 +-} +- +-define i64 @atomicrmw_min_i64_acq_rel(ptr %a, i64 %b) nounwind { +-; LA64-LABEL: atomicrmw_min_i64_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: ammin_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw min ptr %a, i64 %b acq_rel +- ret i64 %1 +-} +- +-define i8 @atomicrmw_umax_i8_seq_cst(ptr %a, i8 %b) nounwind { +-; LA64-LABEL: atomicrmw_umax_i8_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB48_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a6, $a4, $a3 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: bgeu $a6, $a1, .LBB48_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB48_1 Depth=1 +-; LA64-NEXT: xor $a5, $a4, $a1 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: .LBB48_3: # in Loop: Header=BB48_1 Depth=1 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB48_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umax ptr %a, i8 %b seq_cst +- ret i8 %1 +-} +- +-define i16 @atomicrmw_umax_i16_seq_cst(ptr %a, i16 %b) nounwind { +-; LA64-LABEL: atomicrmw_umax_i16_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB49_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a6, $a4, $a2 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: bgeu $a6, $a1, .LBB49_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB49_1 Depth=1 +-; LA64-NEXT: xor $a5, $a4, $a1 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: .LBB49_3: # in Loop: Header=BB49_1 Depth=1 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB49_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw umax ptr %a, i16 %b seq_cst +- ret i16 %1 +-} +- +-define i32 @atomicrmw_umax_i32_seq_cst(ptr %a, i32 %b) nounwind { +-; LA64-LABEL: atomicrmw_umax_i32_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: ammax_db.wu $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umax ptr %a, i32 %b seq_cst +- ret i32 %1 +-} +- +-define i64 @atomicrmw_umax_i64_seq_cst(ptr %a, i64 %b) nounwind { +-; LA64-LABEL: atomicrmw_umax_i64_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: ammax_db.du $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umax ptr %a, i64 %b seq_cst +- ret i64 %1 +-} +- +-define i8 @atomicrmw_umin_i8_seq_cst(ptr %a, i8 %b) nounwind { +-; LA64-LABEL: atomicrmw_umin_i8_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB52_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a6, $a4, $a3 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: bgeu $a1, $a6, .LBB52_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB52_1 Depth=1 +-; LA64-NEXT: xor $a5, $a4, $a1 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: .LBB52_3: # in Loop: Header=BB52_1 Depth=1 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB52_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umin ptr %a, i8 %b seq_cst +- ret i8 %1 +-} +- +-define i16 @atomicrmw_umin_i16_seq_cst(ptr %a, i16 %b) nounwind { +-; LA64-LABEL: atomicrmw_umin_i16_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB53_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a6, $a4, $a2 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: bgeu $a1, $a6, .LBB53_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB53_1 Depth=1 +-; LA64-NEXT: xor $a5, $a4, $a1 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: .LBB53_3: # in Loop: Header=BB53_1 Depth=1 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB53_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw umin ptr %a, i16 %b seq_cst +- ret i16 %1 +-} +- +-define i32 @atomicrmw_umin_i32_seq_cst(ptr %a, i32 %b) nounwind { +-; LA64-LABEL: atomicrmw_umin_i32_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: ammin_db.wu $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umin ptr %a, i32 %b seq_cst +- ret i32 %1 +-} +- +-define i64 @atomicrmw_umin_i64_seq_cst(ptr %a, i64 %b) nounwind { +-; LA64-LABEL: atomicrmw_umin_i64_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: ammin_db.du $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umin ptr %a, i64 %b seq_cst +- ret i64 %1 +-} +- +-define i8 @atomicrmw_max_i8_seq_cst(ptr %a, i8 %b) nounwind { +-; LA64-LABEL: atomicrmw_max_i8_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: ext.w.b $a1, $a1 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: andi $a4, $a2, 24 +-; LA64-NEXT: xori $a4, $a4, 56 +-; LA64-NEXT: .LBB56_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a7, $a5, $a3 +-; LA64-NEXT: move $a6, $a5 +-; LA64-NEXT: sll.w $a7, $a7, $a4 +-; LA64-NEXT: sra.w $a7, $a7, $a4 +-; LA64-NEXT: bge $a7, $a1, .LBB56_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB56_1 Depth=1 +-; LA64-NEXT: xor $a6, $a5, $a1 +-; LA64-NEXT: and $a6, $a6, $a3 +-; LA64-NEXT: xor $a6, $a5, $a6 +-; LA64-NEXT: .LBB56_3: # in Loop: Header=BB56_1 Depth=1 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB56_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a5, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw max ptr %a, i8 %b seq_cst +- ret i8 %1 +-} +- +-define i16 @atomicrmw_max_i16_seq_cst(ptr %a, i16 %b) nounwind { +-; LA64-LABEL: atomicrmw_max_i16_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: andi $a3, $a2, 24 +-; LA64-NEXT: ori $a4, $zero, 48 +-; LA64-NEXT: sub.d $a3, $a4, $a3 +-; LA64-NEXT: lu12i.w $a4, 15 +-; LA64-NEXT: ori $a4, $a4, 4095 +-; LA64-NEXT: sll.w $a4, $a4, $a2 +-; LA64-NEXT: addi.w $a4, $a4, 0 +-; LA64-NEXT: ext.w.h $a1, $a1 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB57_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a7, $a5, $a4 +-; LA64-NEXT: move $a6, $a5 +-; LA64-NEXT: sll.w $a7, $a7, $a3 +-; LA64-NEXT: sra.w $a7, $a7, $a3 +-; LA64-NEXT: bge $a7, $a1, .LBB57_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB57_1 Depth=1 +-; LA64-NEXT: xor $a6, $a5, $a1 +-; LA64-NEXT: and $a6, $a6, $a4 +-; LA64-NEXT: xor $a6, $a5, $a6 +-; LA64-NEXT: .LBB57_3: # in Loop: Header=BB57_1 Depth=1 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB57_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a5, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw max ptr %a, i16 %b seq_cst +- ret i16 %1 +-} +- +-define i32 @atomicrmw_max_i32_seq_cst(ptr %a, i32 %b) nounwind { +-; LA64-LABEL: atomicrmw_max_i32_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: ammax_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw max ptr %a, i32 %b seq_cst +- ret i32 %1 +-} +- +-define i64 @atomicrmw_max_i64_seq_cst(ptr %a, i64 %b) nounwind { +-; LA64-LABEL: atomicrmw_max_i64_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: ammax_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw max ptr %a, i64 %b seq_cst +- ret i64 %1 +-} +- +-define i8 @atomicrmw_min_i8_seq_cst(ptr %a, i8 %b) nounwind { +-; LA64-LABEL: atomicrmw_min_i8_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: ext.w.b $a1, $a1 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: andi $a4, $a2, 24 +-; LA64-NEXT: xori $a4, $a4, 56 +-; LA64-NEXT: .LBB60_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a7, $a5, $a3 +-; LA64-NEXT: move $a6, $a5 +-; LA64-NEXT: sll.w $a7, $a7, $a4 +-; LA64-NEXT: sra.w $a7, $a7, $a4 +-; LA64-NEXT: bge $a1, $a7, .LBB60_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB60_1 Depth=1 +-; LA64-NEXT: xor $a6, $a5, $a1 +-; LA64-NEXT: and $a6, $a6, $a3 +-; LA64-NEXT: xor $a6, $a5, $a6 +-; LA64-NEXT: .LBB60_3: # in Loop: Header=BB60_1 Depth=1 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB60_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a5, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw min ptr %a, i8 %b seq_cst +- ret i8 %1 +-} +- +-define i16 @atomicrmw_min_i16_seq_cst(ptr %a, i16 %b) nounwind { +-; LA64-LABEL: atomicrmw_min_i16_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: andi $a3, $a2, 24 +-; LA64-NEXT: ori $a4, $zero, 48 +-; LA64-NEXT: sub.d $a3, $a4, $a3 +-; LA64-NEXT: lu12i.w $a4, 15 +-; LA64-NEXT: ori $a4, $a4, 4095 +-; LA64-NEXT: sll.w $a4, $a4, $a2 +-; LA64-NEXT: addi.w $a4, $a4, 0 +-; LA64-NEXT: ext.w.h $a1, $a1 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB61_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a7, $a5, $a4 +-; LA64-NEXT: move $a6, $a5 +-; LA64-NEXT: sll.w $a7, $a7, $a3 +-; LA64-NEXT: sra.w $a7, $a7, $a3 +-; LA64-NEXT: bge $a1, $a7, .LBB61_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB61_1 Depth=1 +-; LA64-NEXT: xor $a6, $a5, $a1 +-; LA64-NEXT: and $a6, $a6, $a4 +-; LA64-NEXT: xor $a6, $a5, $a6 +-; LA64-NEXT: .LBB61_3: # in Loop: Header=BB61_1 Depth=1 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB61_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a5, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw min ptr %a, i16 %b seq_cst +- ret i16 %1 +-} +- +-define i32 @atomicrmw_min_i32_seq_cst(ptr %a, i32 %b) nounwind { +-; LA64-LABEL: atomicrmw_min_i32_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: ammin_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw min ptr %a, i32 %b seq_cst +- ret i32 %1 +-} +- +-define i64 @atomicrmw_min_i64_seq_cst(ptr %a, i64 %b) nounwind { +-; LA64-LABEL: atomicrmw_min_i64_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: ammin_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw min ptr %a, i64 %b seq_cst +- ret i64 %1 +-} +- +-define i8 @atomicrmw_umax_i8_monotonic(ptr %a, i8 %b) nounwind { +-; LA64-LABEL: atomicrmw_umax_i8_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB64_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a6, $a4, $a3 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: bgeu $a6, $a1, .LBB64_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB64_1 Depth=1 +-; LA64-NEXT: xor $a5, $a4, $a1 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: .LBB64_3: # in Loop: Header=BB64_1 Depth=1 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB64_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umax ptr %a, i8 %b monotonic +- ret i8 %1 +-} +- +-define i16 @atomicrmw_umax_i16_monotonic(ptr %a, i16 %b) nounwind { +-; LA64-LABEL: atomicrmw_umax_i16_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB65_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a6, $a4, $a2 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: bgeu $a6, $a1, .LBB65_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB65_1 Depth=1 +-; LA64-NEXT: xor $a5, $a4, $a1 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: .LBB65_3: # in Loop: Header=BB65_1 Depth=1 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB65_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw umax ptr %a, i16 %b monotonic +- ret i16 %1 +-} +- +-define i32 @atomicrmw_umax_i32_monotonic(ptr %a, i32 %b) nounwind { +-; LA64-LABEL: atomicrmw_umax_i32_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: ammax_db.wu $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umax ptr %a, i32 %b monotonic +- ret i32 %1 +-} +- +-define i64 @atomicrmw_umax_i64_monotonic(ptr %a, i64 %b) nounwind { +-; LA64-LABEL: atomicrmw_umax_i64_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: ammax_db.du $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umax ptr %a, i64 %b monotonic +- ret i64 %1 +-} +- +-define i8 @atomicrmw_umin_i8_monotonic(ptr %a, i8 %b) nounwind { +-; LA64-LABEL: atomicrmw_umin_i8_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB68_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a6, $a4, $a3 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: bgeu $a1, $a6, .LBB68_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB68_1 Depth=1 +-; LA64-NEXT: xor $a5, $a4, $a1 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: .LBB68_3: # in Loop: Header=BB68_1 Depth=1 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB68_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umin ptr %a, i8 %b monotonic +- ret i8 %1 +-} +- +-define i16 @atomicrmw_umin_i16_monotonic(ptr %a, i16 %b) nounwind { +-; LA64-LABEL: atomicrmw_umin_i16_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB69_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a6, $a4, $a2 +-; LA64-NEXT: move $a5, $a4 +-; LA64-NEXT: bgeu $a1, $a6, .LBB69_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB69_1 Depth=1 +-; LA64-NEXT: xor $a5, $a4, $a1 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: .LBB69_3: # in Loop: Header=BB69_1 Depth=1 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB69_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw umin ptr %a, i16 %b monotonic +- ret i16 %1 +-} +- +-define i32 @atomicrmw_umin_i32_monotonic(ptr %a, i32 %b) nounwind { +-; LA64-LABEL: atomicrmw_umin_i32_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: ammin_db.wu $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umin ptr %a, i32 %b monotonic +- ret i32 %1 +-} +- +-define i64 @atomicrmw_umin_i64_monotonic(ptr %a, i64 %b) nounwind { +-; LA64-LABEL: atomicrmw_umin_i64_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: ammin_db.du $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw umin ptr %a, i64 %b monotonic +- ret i64 %1 +-} +- +-define i8 @atomicrmw_max_i8_monotonic(ptr %a, i8 %b) nounwind { +-; LA64-LABEL: atomicrmw_max_i8_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: ext.w.b $a1, $a1 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: andi $a4, $a2, 24 +-; LA64-NEXT: xori $a4, $a4, 56 +-; LA64-NEXT: .LBB72_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a7, $a5, $a3 +-; LA64-NEXT: move $a6, $a5 +-; LA64-NEXT: sll.w $a7, $a7, $a4 +-; LA64-NEXT: sra.w $a7, $a7, $a4 +-; LA64-NEXT: bge $a7, $a1, .LBB72_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB72_1 Depth=1 +-; LA64-NEXT: xor $a6, $a5, $a1 +-; LA64-NEXT: and $a6, $a6, $a3 +-; LA64-NEXT: xor $a6, $a5, $a6 +-; LA64-NEXT: .LBB72_3: # in Loop: Header=BB72_1 Depth=1 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB72_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a5, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw max ptr %a, i8 %b monotonic +- ret i8 %1 +-} +- +-define i16 @atomicrmw_max_i16_monotonic(ptr %a, i16 %b) nounwind { +-; LA64-LABEL: atomicrmw_max_i16_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: andi $a3, $a2, 24 +-; LA64-NEXT: ori $a4, $zero, 48 +-; LA64-NEXT: sub.d $a3, $a4, $a3 +-; LA64-NEXT: lu12i.w $a4, 15 +-; LA64-NEXT: ori $a4, $a4, 4095 +-; LA64-NEXT: sll.w $a4, $a4, $a2 +-; LA64-NEXT: addi.w $a4, $a4, 0 +-; LA64-NEXT: ext.w.h $a1, $a1 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB73_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a7, $a5, $a4 +-; LA64-NEXT: move $a6, $a5 +-; LA64-NEXT: sll.w $a7, $a7, $a3 +-; LA64-NEXT: sra.w $a7, $a7, $a3 +-; LA64-NEXT: bge $a7, $a1, .LBB73_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB73_1 Depth=1 +-; LA64-NEXT: xor $a6, $a5, $a1 +-; LA64-NEXT: and $a6, $a6, $a4 +-; LA64-NEXT: xor $a6, $a5, $a6 +-; LA64-NEXT: .LBB73_3: # in Loop: Header=BB73_1 Depth=1 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB73_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a5, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw max ptr %a, i16 %b monotonic +- ret i16 %1 +-} +- +-define i32 @atomicrmw_max_i32_monotonic(ptr %a, i32 %b) nounwind { +-; LA64-LABEL: atomicrmw_max_i32_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: ammax_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw max ptr %a, i32 %b monotonic +- ret i32 %1 +-} +- +-define i64 @atomicrmw_max_i64_monotonic(ptr %a, i64 %b) nounwind { +-; LA64-LABEL: atomicrmw_max_i64_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: ammax_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw max ptr %a, i64 %b monotonic +- ret i64 %1 +-} +- +-define i8 @atomicrmw_min_i8_monotonic(ptr %a, i8 %b) nounwind { +-; LA64-LABEL: atomicrmw_min_i8_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: ext.w.b $a1, $a1 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: andi $a4, $a2, 24 +-; LA64-NEXT: xori $a4, $a4, 56 +-; LA64-NEXT: .LBB76_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a7, $a5, $a3 +-; LA64-NEXT: move $a6, $a5 +-; LA64-NEXT: sll.w $a7, $a7, $a4 +-; LA64-NEXT: sra.w $a7, $a7, $a4 +-; LA64-NEXT: bge $a1, $a7, .LBB76_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB76_1 Depth=1 +-; LA64-NEXT: xor $a6, $a5, $a1 +-; LA64-NEXT: and $a6, $a6, $a3 +-; LA64-NEXT: xor $a6, $a5, $a6 +-; LA64-NEXT: .LBB76_3: # in Loop: Header=BB76_1 Depth=1 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB76_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a5, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw min ptr %a, i8 %b monotonic +- ret i8 %1 +-} +- +-define i16 @atomicrmw_min_i16_monotonic(ptr %a, i16 %b) nounwind { +-; LA64-LABEL: atomicrmw_min_i16_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: andi $a3, $a2, 24 +-; LA64-NEXT: ori $a4, $zero, 48 +-; LA64-NEXT: sub.d $a3, $a4, $a3 +-; LA64-NEXT: lu12i.w $a4, 15 +-; LA64-NEXT: ori $a4, $a4, 4095 +-; LA64-NEXT: sll.w $a4, $a4, $a2 +-; LA64-NEXT: addi.w $a4, $a4, 0 +-; LA64-NEXT: ext.w.h $a1, $a1 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB77_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a5, $a0, 0 +-; LA64-NEXT: and $a7, $a5, $a4 +-; LA64-NEXT: move $a6, $a5 +-; LA64-NEXT: sll.w $a7, $a7, $a3 +-; LA64-NEXT: sra.w $a7, $a7, $a3 +-; LA64-NEXT: bge $a1, $a7, .LBB77_3 +-; LA64-NEXT: # %bb.2: # in Loop: Header=BB77_1 Depth=1 +-; LA64-NEXT: xor $a6, $a5, $a1 +-; LA64-NEXT: and $a6, $a6, $a4 +-; LA64-NEXT: xor $a6, $a5, $a6 +-; LA64-NEXT: .LBB77_3: # in Loop: Header=BB77_1 Depth=1 +-; LA64-NEXT: sc.w $a6, $a0, 0 +-; LA64-NEXT: beqz $a6, .LBB77_1 +-; LA64-NEXT: # %bb.4: +-; LA64-NEXT: srl.w $a0, $a5, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw min ptr %a, i16 %b monotonic +- ret i16 %1 +-} +- +-define i32 @atomicrmw_min_i32_monotonic(ptr %a, i32 %b) nounwind { +-; LA64-LABEL: atomicrmw_min_i32_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: ammin_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw min ptr %a, i32 %b monotonic +- ret i32 %1 +-} +- +-define i64 @atomicrmw_min_i64_monotonic(ptr %a, i64 %b) nounwind { +-; LA64-LABEL: atomicrmw_min_i64_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: ammin_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw min ptr %a, i64 %b monotonic +- ret i64 %1 +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw.ll +deleted file mode 100644 +index d4f7ed017..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw.ll ++++ /dev/null +@@ -1,4973 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-define i8 @atomicrmw_xchg_i8_acquire(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_xchg_i8_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB0_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: addi.w $a5, $a1, 0 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a3 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB0_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_i8_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB0_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: addi.w $a5, $a1, 0 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB0_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i8 %b acquire +- ret i8 %1 +-} +- +-define i8 @atomicrmw_xchg_0_i8_acquire(ptr %a) nounwind { +-; LA32-LABEL: atomicrmw_xchg_0_i8_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a0, 3 +-; LA32-NEXT: ori $a2, $zero, 255 +-; LA32-NEXT: sll.w $a2, $a2, $a1 +-; LA32-NEXT: nor $a2, $a2, $zero +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB1_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: and $a4, $a3, $a2 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB1_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_0_i8_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 3 +-; LA64-NEXT: ori $a2, $zero, 255 +-; LA64-NEXT: sll.w $a2, $a2, $a1 +-; LA64-NEXT: nor $a2, $a2, $zero +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amand_db.w $a3, $a2, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a1 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i8 0 acquire +- ret i8 %1 +-} +- +-define i8 @atomicrmw_xchg_minus_1_i8_acquire(ptr %a) nounwind { +-; LA32-LABEL: atomicrmw_xchg_minus_1_i8_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a0, 3 +-; LA32-NEXT: ori $a2, $zero, 255 +-; LA32-NEXT: sll.w $a2, $a2, $a1 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB2_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: or $a4, $a3, $a2 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB2_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_minus_1_i8_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 3 +-; LA64-NEXT: ori $a2, $zero, 255 +-; LA64-NEXT: sll.w $a2, $a2, $a1 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amor_db.w $a3, $a2, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a1 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i8 -1 acquire +- ret i8 %1 +-} +- +-define i16 @atomicrmw_xchg_i16_acquire(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_xchg_i16_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB3_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: addi.w $a5, $a1, 0 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a2 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB3_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_i16_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB3_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: addi.w $a5, $a1, 0 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB3_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i16 %b acquire +- ret i16 %1 +-} +- +-define i16 @atomicrmw_xchg_0_i16_acquire(ptr %a) nounwind { +-; LA32-LABEL: atomicrmw_xchg_0_i16_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 15 +-; LA32-NEXT: ori $a1, $a1, 4095 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: nor $a1, $a1, $zero +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB4_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: and $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB4_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_0_i16_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, 15 +-; LA64-NEXT: ori $a1, $a1, 4095 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: nor $a1, $a1, $zero +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amand_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i16 0 acquire +- ret i16 %1 +-} +- +-define i16 @atomicrmw_xchg_minus_1_i16_acquire(ptr %a) nounwind { +-; LA32-LABEL: atomicrmw_xchg_minus_1_i16_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 15 +-; LA32-NEXT: ori $a1, $a1, 4095 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB5_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: or $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB5_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_minus_1_i16_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, 15 +-; LA64-NEXT: ori $a1, $a1, 4095 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i16 -1 acquire +- ret i16 %1 +-} +- +-define i32 @atomicrmw_xchg_i32_acquire(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_xchg_i32_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB6_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: move $a3, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB6_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_i32_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: amswap_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i32 %b acquire +- ret i32 %1 +-} +- +-define i64 @atomicrmw_xchg_i64_acquire(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_xchg_i64_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 2 +-; LA32-NEXT: bl %plt(__atomic_exchange_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_i64_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: amswap_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i64 %b acquire +- ret i64 %1 +-} +- +-define i8 @atomicrmw_add_i8_acquire(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_add_i8_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB8_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: add.w $a5, $a4, $a1 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a3 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB8_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_add_i8_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB8_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: add.w $a5, $a4, $a1 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB8_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw add ptr %a, i8 %b acquire +- ret i8 %1 +-} +- +-define i16 @atomicrmw_add_i16_acquire(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_add_i16_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB9_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: add.w $a5, $a4, $a1 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a2 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB9_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_add_i16_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB9_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: add.w $a5, $a4, $a1 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB9_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw add ptr %a, i16 %b acquire +- ret i16 %1 +-} +- +-define i32 @atomicrmw_add_i32_acquire(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_add_i32_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB10_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: add.w $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB10_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_add_i32_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: amadd_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw add ptr %a, i32 %b acquire +- ret i32 %1 +-} +- +-define i64 @atomicrmw_add_i64_acquire(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_add_i64_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 2 +-; LA32-NEXT: bl %plt(__atomic_fetch_add_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_add_i64_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: amadd_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw add ptr %a, i64 %b acquire +- ret i64 %1 +-} +- +-define i8 @atomicrmw_sub_i8_acquire(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_sub_i8_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB12_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: sub.w $a5, $a4, $a1 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a3 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB12_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_sub_i8_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB12_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: sub.w $a5, $a4, $a1 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB12_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw sub ptr %a, i8 %b acquire +- ret i8 %1 +-} +- +-define i16 @atomicrmw_sub_i16_acquire(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_sub_i16_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB13_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: sub.w $a5, $a4, $a1 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a2 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB13_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_sub_i16_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB13_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: sub.w $a5, $a4, $a1 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB13_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw sub ptr %a, i16 %b acquire +- ret i16 %1 +-} +- +-define i32 @atomicrmw_sub_i32_acquire(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_sub_i32_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB14_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: sub.w $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB14_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_sub_i32_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.w $a2, $zero, $a1 +-; LA64-NEXT: amadd_db.w $a1, $a2, $a0 +-; LA64-NEXT: move $a0, $a1 +-; LA64-NEXT: ret +- %1 = atomicrmw sub ptr %a, i32 %b acquire +- ret i32 %1 +-} +- +-define i64 @atomicrmw_sub_i64_acquire(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_sub_i64_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 2 +-; LA32-NEXT: bl %plt(__atomic_fetch_sub_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_sub_i64_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.d $a2, $zero, $a1 +-; LA64-NEXT: amadd_db.d $a1, $a2, $a0 +-; LA64-NEXT: move $a0, $a1 +-; LA64-NEXT: ret +- %1 = atomicrmw sub ptr %a, i64 %b acquire +- ret i64 %1 +-} +- +-define i8 @atomicrmw_nand_i8_acquire(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_nand_i8_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB16_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: and $a5, $a4, $a1 +-; LA32-NEXT: nor $a5, $a5, $zero +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a3 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB16_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_nand_i8_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB16_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a5, $a4, $a1 +-; LA64-NEXT: nor $a5, $a5, $zero +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB16_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw nand ptr %a, i8 %b acquire +- ret i8 %1 +-} +- +-define i16 @atomicrmw_nand_i16_acquire(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_nand_i16_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB17_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: and $a5, $a4, $a1 +-; LA32-NEXT: nor $a5, $a5, $zero +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a2 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB17_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_nand_i16_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB17_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a5, $a4, $a1 +-; LA64-NEXT: nor $a5, $a5, $zero +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB17_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw nand ptr %a, i16 %b acquire +- ret i16 %1 +-} +- +-define i32 @atomicrmw_nand_i32_acquire(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_nand_i32_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB18_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: and $a3, $a2, $a1 +-; LA32-NEXT: nor $a3, $a3, $zero +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB18_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_nand_i32_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: .LBB18_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a2, $a0, 0 +-; LA64-NEXT: and $a3, $a2, $a1 +-; LA64-NEXT: nor $a3, $a3, $zero +-; LA64-NEXT: sc.w $a3, $a0, 0 +-; LA64-NEXT: beqz $a3, .LBB18_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw nand ptr %a, i32 %b acquire +- ret i32 %1 +-} +- +-define i64 @atomicrmw_nand_i64_acquire(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_nand_i64_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 2 +-; LA32-NEXT: bl %plt(__atomic_fetch_nand_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_nand_i64_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: .LBB19_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.d $a2, $a0, 0 +-; LA64-NEXT: and $a3, $a2, $a1 +-; LA64-NEXT: nor $a3, $a3, $zero +-; LA64-NEXT: sc.d $a3, $a0, 0 +-; LA64-NEXT: beqz $a3, .LBB19_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw nand ptr %a, i64 %b acquire +- ret i64 %1 +-} +- +-define i8 @atomicrmw_and_i8_acquire(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_and_i8_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: orn $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB20_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: and $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB20_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_and_i8_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: orn $a1, $a1, $a3 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amand_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw and ptr %a, i8 %b acquire +- ret i8 %1 +-} +- +-define i16 @atomicrmw_and_i16_acquire(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_and_i16_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: orn $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB21_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: and $a4, $a2, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB21_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a2, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_and_i16_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: orn $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amand_db.w $a2, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a2, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw and ptr %a, i16 %b acquire +- ret i16 %1 +-} +- +-define i32 @atomicrmw_and_i32_acquire(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_and_i32_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB22_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: and $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB22_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_and_i32_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: amand_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw and ptr %a, i32 %b acquire +- ret i32 %1 +-} +- +-define i64 @atomicrmw_and_i64_acquire(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_and_i64_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 2 +-; LA32-NEXT: bl %plt(__atomic_fetch_and_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_and_i64_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: amand_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw and ptr %a, i64 %b acquire +- ret i64 %1 +-} +- +-define i8 @atomicrmw_or_i8_acquire(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_or_i8_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB24_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: or $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB24_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_or_i8_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw or ptr %a, i8 %b acquire +- ret i8 %1 +-} +- +-define i16 @atomicrmw_or_i16_acquire(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_or_i16_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB25_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: or $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB25_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_or_i16_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw or ptr %a, i16 %b acquire +- ret i16 %1 +-} +- +-define i32 @atomicrmw_or_i32_acquire(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_or_i32_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB26_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: or $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB26_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_or_i32_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: amor_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw or ptr %a, i32 %b acquire +- ret i32 %1 +-} +- +-define i64 @atomicrmw_or_i64_acquire(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_or_i64_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 2 +-; LA32-NEXT: bl %plt(__atomic_fetch_or_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_or_i64_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: amor_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw or ptr %a, i64 %b acquire +- ret i64 %1 +-} +- +-define i8 @atomicrmw_xor_i8_acquire(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_xor_i8_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB28_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: xor $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB28_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xor_i8_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amxor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xor ptr %a, i8 %b acquire +- ret i8 %1 +-} +- +-define i16 @atomicrmw_xor_i16_acquire(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_xor_i16_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB29_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: xor $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB29_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xor_i16_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amxor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xor ptr %a, i16 %b acquire +- ret i16 %1 +-} +- +-define i32 @atomicrmw_xor_i32_acquire(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_xor_i32_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB30_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: xor $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB30_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xor_i32_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: amxor_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xor ptr %a, i32 %b acquire +- ret i32 %1 +-} +- +-define i64 @atomicrmw_xor_i64_acquire(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_xor_i64_acquire: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 2 +-; LA32-NEXT: bl %plt(__atomic_fetch_xor_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xor_i64_acquire: +-; LA64: # %bb.0: +-; LA64-NEXT: amxor_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xor ptr %a, i64 %b acquire +- ret i64 %1 +-} +- +-define i8 @atomicrmw_xchg_i8_release(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_xchg_i8_release: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB32_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: addi.w $a5, $a1, 0 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a3 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB32_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_i8_release: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB32_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: addi.w $a5, $a1, 0 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB32_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i8 %b release +- ret i8 %1 +-} +- +-define i8 @atomicrmw_xchg_0_i8_release(ptr %a) nounwind { +-; LA32-LABEL: atomicrmw_xchg_0_i8_release: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a0, 3 +-; LA32-NEXT: ori $a2, $zero, 255 +-; LA32-NEXT: sll.w $a2, $a2, $a1 +-; LA32-NEXT: nor $a2, $a2, $zero +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB33_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: and $a4, $a3, $a2 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB33_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_0_i8_release: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 3 +-; LA64-NEXT: ori $a2, $zero, 255 +-; LA64-NEXT: sll.w $a2, $a2, $a1 +-; LA64-NEXT: nor $a2, $a2, $zero +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amand_db.w $a3, $a2, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a1 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i8 0 release +- ret i8 %1 +-} +- +-define i8 @atomicrmw_xchg_minus_1_i8_release(ptr %a) nounwind { +-; LA32-LABEL: atomicrmw_xchg_minus_1_i8_release: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a0, 3 +-; LA32-NEXT: ori $a2, $zero, 255 +-; LA32-NEXT: sll.w $a2, $a2, $a1 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB34_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: or $a4, $a3, $a2 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB34_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_minus_1_i8_release: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 3 +-; LA64-NEXT: ori $a2, $zero, 255 +-; LA64-NEXT: sll.w $a2, $a2, $a1 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amor_db.w $a3, $a2, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a1 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i8 -1 release +- ret i8 %1 +-} +- +-define i16 @atomicrmw_xchg_i16_release(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_xchg_i16_release: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB35_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: addi.w $a5, $a1, 0 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a2 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB35_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_i16_release: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB35_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: addi.w $a5, $a1, 0 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB35_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i16 %b release +- ret i16 %1 +-} +- +-define i16 @atomicrmw_xchg_0_i16_release(ptr %a) nounwind { +-; LA32-LABEL: atomicrmw_xchg_0_i16_release: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 15 +-; LA32-NEXT: ori $a1, $a1, 4095 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: nor $a1, $a1, $zero +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB36_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: and $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB36_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_0_i16_release: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, 15 +-; LA64-NEXT: ori $a1, $a1, 4095 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: nor $a1, $a1, $zero +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amand_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i16 0 release +- ret i16 %1 +-} +- +-define i16 @atomicrmw_xchg_minus_1_i16_release(ptr %a) nounwind { +-; LA32-LABEL: atomicrmw_xchg_minus_1_i16_release: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 15 +-; LA32-NEXT: ori $a1, $a1, 4095 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB37_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: or $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB37_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_minus_1_i16_release: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, 15 +-; LA64-NEXT: ori $a1, $a1, 4095 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i16 -1 release +- ret i16 %1 +-} +- +-define i32 @atomicrmw_xchg_i32_release(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_xchg_i32_release: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB38_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: move $a3, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB38_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_i32_release: +-; LA64: # %bb.0: +-; LA64-NEXT: amswap_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i32 %b release +- ret i32 %1 +-} +- +-define i64 @atomicrmw_xchg_i64_release(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_xchg_i64_release: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 3 +-; LA32-NEXT: bl %plt(__atomic_exchange_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_i64_release: +-; LA64: # %bb.0: +-; LA64-NEXT: amswap_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i64 %b release +- ret i64 %1 +-} +- +-define i8 @atomicrmw_add_i8_release(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_add_i8_release: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB40_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: add.w $a5, $a4, $a1 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a3 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB40_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_add_i8_release: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB40_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: add.w $a5, $a4, $a1 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB40_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw add ptr %a, i8 %b release +- ret i8 %1 +-} +- +-define i16 @atomicrmw_add_i16_release(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_add_i16_release: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB41_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: add.w $a5, $a4, $a1 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a2 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB41_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_add_i16_release: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB41_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: add.w $a5, $a4, $a1 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB41_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw add ptr %a, i16 %b release +- ret i16 %1 +-} +- +-define i32 @atomicrmw_add_i32_release(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_add_i32_release: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB42_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: add.w $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB42_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_add_i32_release: +-; LA64: # %bb.0: +-; LA64-NEXT: amadd_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw add ptr %a, i32 %b release +- ret i32 %1 +-} +- +-define i64 @atomicrmw_add_i64_release(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_add_i64_release: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 3 +-; LA32-NEXT: bl %plt(__atomic_fetch_add_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_add_i64_release: +-; LA64: # %bb.0: +-; LA64-NEXT: amadd_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw add ptr %a, i64 %b release +- ret i64 %1 +-} +- +-define i8 @atomicrmw_sub_i8_release(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_sub_i8_release: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB44_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: sub.w $a5, $a4, $a1 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a3 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB44_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_sub_i8_release: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB44_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: sub.w $a5, $a4, $a1 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB44_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw sub ptr %a, i8 %b release +- ret i8 %1 +-} +- +-define i16 @atomicrmw_sub_i16_release(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_sub_i16_release: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB45_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: sub.w $a5, $a4, $a1 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a2 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB45_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_sub_i16_release: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB45_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: sub.w $a5, $a4, $a1 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB45_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw sub ptr %a, i16 %b release +- ret i16 %1 +-} +- +-define i32 @atomicrmw_sub_i32_release(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_sub_i32_release: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB46_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: sub.w $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB46_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_sub_i32_release: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.w $a2, $zero, $a1 +-; LA64-NEXT: amadd_db.w $a1, $a2, $a0 +-; LA64-NEXT: move $a0, $a1 +-; LA64-NEXT: ret +- %1 = atomicrmw sub ptr %a, i32 %b release +- ret i32 %1 +-} +- +-define i64 @atomicrmw_sub_i64_release(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_sub_i64_release: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 3 +-; LA32-NEXT: bl %plt(__atomic_fetch_sub_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_sub_i64_release: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.d $a2, $zero, $a1 +-; LA64-NEXT: amadd_db.d $a1, $a2, $a0 +-; LA64-NEXT: move $a0, $a1 +-; LA64-NEXT: ret +- %1 = atomicrmw sub ptr %a, i64 %b release +- ret i64 %1 +-} +- +-define i8 @atomicrmw_nand_i8_release(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_nand_i8_release: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB48_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: and $a5, $a4, $a1 +-; LA32-NEXT: nor $a5, $a5, $zero +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a3 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB48_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_nand_i8_release: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB48_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a5, $a4, $a1 +-; LA64-NEXT: nor $a5, $a5, $zero +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB48_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw nand ptr %a, i8 %b release +- ret i8 %1 +-} +- +-define i16 @atomicrmw_nand_i16_release(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_nand_i16_release: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB49_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: and $a5, $a4, $a1 +-; LA32-NEXT: nor $a5, $a5, $zero +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a2 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB49_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_nand_i16_release: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB49_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a5, $a4, $a1 +-; LA64-NEXT: nor $a5, $a5, $zero +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB49_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw nand ptr %a, i16 %b release +- ret i16 %1 +-} +- +-define i32 @atomicrmw_nand_i32_release(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_nand_i32_release: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB50_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: and $a3, $a2, $a1 +-; LA32-NEXT: nor $a3, $a3, $zero +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB50_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_nand_i32_release: +-; LA64: # %bb.0: +-; LA64-NEXT: .LBB50_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a2, $a0, 0 +-; LA64-NEXT: and $a3, $a2, $a1 +-; LA64-NEXT: nor $a3, $a3, $zero +-; LA64-NEXT: sc.w $a3, $a0, 0 +-; LA64-NEXT: beqz $a3, .LBB50_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw nand ptr %a, i32 %b release +- ret i32 %1 +-} +- +-define i64 @atomicrmw_nand_i64_release(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_nand_i64_release: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 3 +-; LA32-NEXT: bl %plt(__atomic_fetch_nand_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_nand_i64_release: +-; LA64: # %bb.0: +-; LA64-NEXT: .LBB51_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.d $a2, $a0, 0 +-; LA64-NEXT: and $a3, $a2, $a1 +-; LA64-NEXT: nor $a3, $a3, $zero +-; LA64-NEXT: sc.d $a3, $a0, 0 +-; LA64-NEXT: beqz $a3, .LBB51_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw nand ptr %a, i64 %b release +- ret i64 %1 +-} +- +-define i8 @atomicrmw_and_i8_release(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_and_i8_release: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: orn $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB52_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: and $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB52_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_and_i8_release: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: orn $a1, $a1, $a3 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amand_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw and ptr %a, i8 %b release +- ret i8 %1 +-} +- +-define i16 @atomicrmw_and_i16_release(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_and_i16_release: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: orn $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB53_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: and $a4, $a2, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB53_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a2, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_and_i16_release: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: orn $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amand_db.w $a2, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a2, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw and ptr %a, i16 %b release +- ret i16 %1 +-} +- +-define i32 @atomicrmw_and_i32_release(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_and_i32_release: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB54_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: and $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB54_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_and_i32_release: +-; LA64: # %bb.0: +-; LA64-NEXT: amand_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw and ptr %a, i32 %b release +- ret i32 %1 +-} +- +-define i64 @atomicrmw_and_i64_release(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_and_i64_release: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 3 +-; LA32-NEXT: bl %plt(__atomic_fetch_and_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_and_i64_release: +-; LA64: # %bb.0: +-; LA64-NEXT: amand_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw and ptr %a, i64 %b release +- ret i64 %1 +-} +- +-define i8 @atomicrmw_or_i8_release(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_or_i8_release: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB56_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: or $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB56_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_or_i8_release: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw or ptr %a, i8 %b release +- ret i8 %1 +-} +- +-define i16 @atomicrmw_or_i16_release(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_or_i16_release: +-; LA32: # %bb.0: +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB57_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: or $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB57_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_or_i16_release: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw or ptr %a, i16 %b release +- ret i16 %1 +-} +- +-define i32 @atomicrmw_or_i32_release(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_or_i32_release: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB58_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: or $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB58_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_or_i32_release: +-; LA64: # %bb.0: +-; LA64-NEXT: amor_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw or ptr %a, i32 %b release +- ret i32 %1 +-} +- +-define i64 @atomicrmw_or_i64_release(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_or_i64_release: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 3 +-; LA32-NEXT: bl %plt(__atomic_fetch_or_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_or_i64_release: +-; LA64: # %bb.0: +-; LA64-NEXT: amor_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw or ptr %a, i64 %b release +- ret i64 %1 +-} +- +-define i8 @atomicrmw_xor_i8_release(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_xor_i8_release: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB60_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: xor $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB60_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xor_i8_release: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amxor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xor ptr %a, i8 %b release +- ret i8 %1 +-} +- +-define i16 @atomicrmw_xor_i16_release(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_xor_i16_release: +-; LA32: # %bb.0: +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB61_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: xor $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB61_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xor_i16_release: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amxor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xor ptr %a, i16 %b release +- ret i16 %1 +-} +- +-define i32 @atomicrmw_xor_i32_release(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_xor_i32_release: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB62_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: xor $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB62_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xor_i32_release: +-; LA64: # %bb.0: +-; LA64-NEXT: amxor_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xor ptr %a, i32 %b release +- ret i32 %1 +-} +- +-define i64 @atomicrmw_xor_i64_release(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_xor_i64_release: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 3 +-; LA32-NEXT: bl %plt(__atomic_fetch_xor_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xor_i64_release: +-; LA64: # %bb.0: +-; LA64-NEXT: amxor_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xor ptr %a, i64 %b release +- ret i64 %1 +-} +- +-define i8 @atomicrmw_xchg_i8_acq_rel(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_xchg_i8_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB64_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: addi.w $a5, $a1, 0 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a3 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB64_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_i8_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB64_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: addi.w $a5, $a1, 0 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB64_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i8 %b acq_rel +- ret i8 %1 +-} +- +-define i8 @atomicrmw_xchg_0_i8_acq_rel(ptr %a) nounwind { +-; LA32-LABEL: atomicrmw_xchg_0_i8_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a0, 3 +-; LA32-NEXT: ori $a2, $zero, 255 +-; LA32-NEXT: sll.w $a2, $a2, $a1 +-; LA32-NEXT: nor $a2, $a2, $zero +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB65_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: and $a4, $a3, $a2 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB65_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_0_i8_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 3 +-; LA64-NEXT: ori $a2, $zero, 255 +-; LA64-NEXT: sll.w $a2, $a2, $a1 +-; LA64-NEXT: nor $a2, $a2, $zero +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amand_db.w $a3, $a2, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a1 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i8 0 acq_rel +- ret i8 %1 +-} +- +-define i8 @atomicrmw_xchg_minus_1_i8_acq_rel(ptr %a) nounwind { +-; LA32-LABEL: atomicrmw_xchg_minus_1_i8_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a0, 3 +-; LA32-NEXT: ori $a2, $zero, 255 +-; LA32-NEXT: sll.w $a2, $a2, $a1 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB66_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: or $a4, $a3, $a2 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB66_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_minus_1_i8_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 3 +-; LA64-NEXT: ori $a2, $zero, 255 +-; LA64-NEXT: sll.w $a2, $a2, $a1 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amor_db.w $a3, $a2, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a1 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i8 -1 acq_rel +- ret i8 %1 +-} +- +-define i16 @atomicrmw_xchg_i16_acq_rel(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_xchg_i16_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB67_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: addi.w $a5, $a1, 0 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a2 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB67_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_i16_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB67_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: addi.w $a5, $a1, 0 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB67_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i16 %b acq_rel +- ret i16 %1 +-} +- +-define i16 @atomicrmw_xchg_0_i16_acq_rel(ptr %a) nounwind { +-; LA32-LABEL: atomicrmw_xchg_0_i16_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 15 +-; LA32-NEXT: ori $a1, $a1, 4095 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: nor $a1, $a1, $zero +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB68_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: and $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB68_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_0_i16_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, 15 +-; LA64-NEXT: ori $a1, $a1, 4095 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: nor $a1, $a1, $zero +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amand_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i16 0 acq_rel +- ret i16 %1 +-} +- +-define i16 @atomicrmw_xchg_minus_1_i16_acq_rel(ptr %a) nounwind { +-; LA32-LABEL: atomicrmw_xchg_minus_1_i16_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 15 +-; LA32-NEXT: ori $a1, $a1, 4095 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB69_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: or $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB69_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_minus_1_i16_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, 15 +-; LA64-NEXT: ori $a1, $a1, 4095 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i16 -1 acq_rel +- ret i16 %1 +-} +- +-define i32 @atomicrmw_xchg_i32_acq_rel(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_xchg_i32_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB70_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: move $a3, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB70_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_i32_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: amswap_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i32 %b acq_rel +- ret i32 %1 +-} +- +-define i64 @atomicrmw_xchg_i64_acq_rel(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_xchg_i64_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 4 +-; LA32-NEXT: bl %plt(__atomic_exchange_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_i64_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: amswap_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i64 %b acq_rel +- ret i64 %1 +-} +- +-define i8 @atomicrmw_add_i8_acq_rel(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_add_i8_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB72_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: add.w $a5, $a4, $a1 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a3 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB72_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_add_i8_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB72_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: add.w $a5, $a4, $a1 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB72_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw add ptr %a, i8 %b acq_rel +- ret i8 %1 +-} +- +-define i16 @atomicrmw_add_i16_acq_rel(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_add_i16_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB73_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: add.w $a5, $a4, $a1 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a2 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB73_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_add_i16_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB73_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: add.w $a5, $a4, $a1 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB73_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw add ptr %a, i16 %b acq_rel +- ret i16 %1 +-} +- +-define i32 @atomicrmw_add_i32_acq_rel(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_add_i32_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB74_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: add.w $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB74_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_add_i32_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: amadd_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw add ptr %a, i32 %b acq_rel +- ret i32 %1 +-} +- +-define i64 @atomicrmw_add_i64_acq_rel(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_add_i64_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 4 +-; LA32-NEXT: bl %plt(__atomic_fetch_add_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_add_i64_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: amadd_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw add ptr %a, i64 %b acq_rel +- ret i64 %1 +-} +- +-define i8 @atomicrmw_sub_i8_acq_rel(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_sub_i8_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB76_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: sub.w $a5, $a4, $a1 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a3 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB76_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_sub_i8_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB76_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: sub.w $a5, $a4, $a1 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB76_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw sub ptr %a, i8 %b acq_rel +- ret i8 %1 +-} +- +-define i16 @atomicrmw_sub_i16_acq_rel(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_sub_i16_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB77_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: sub.w $a5, $a4, $a1 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a2 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB77_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_sub_i16_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB77_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: sub.w $a5, $a4, $a1 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB77_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw sub ptr %a, i16 %b acq_rel +- ret i16 %1 +-} +- +-define i32 @atomicrmw_sub_i32_acq_rel(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_sub_i32_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB78_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: sub.w $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB78_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_sub_i32_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.w $a2, $zero, $a1 +-; LA64-NEXT: amadd_db.w $a1, $a2, $a0 +-; LA64-NEXT: move $a0, $a1 +-; LA64-NEXT: ret +- %1 = atomicrmw sub ptr %a, i32 %b acq_rel +- ret i32 %1 +-} +- +-define i64 @atomicrmw_sub_i64_acq_rel(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_sub_i64_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 4 +-; LA32-NEXT: bl %plt(__atomic_fetch_sub_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_sub_i64_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.d $a2, $zero, $a1 +-; LA64-NEXT: amadd_db.d $a1, $a2, $a0 +-; LA64-NEXT: move $a0, $a1 +-; LA64-NEXT: ret +- %1 = atomicrmw sub ptr %a, i64 %b acq_rel +- ret i64 %1 +-} +- +-define i8 @atomicrmw_nand_i8_acq_rel(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_nand_i8_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB80_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: and $a5, $a4, $a1 +-; LA32-NEXT: nor $a5, $a5, $zero +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a3 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB80_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_nand_i8_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB80_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a5, $a4, $a1 +-; LA64-NEXT: nor $a5, $a5, $zero +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB80_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw nand ptr %a, i8 %b acq_rel +- ret i8 %1 +-} +- +-define i16 @atomicrmw_nand_i16_acq_rel(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_nand_i16_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB81_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: and $a5, $a4, $a1 +-; LA32-NEXT: nor $a5, $a5, $zero +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a2 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB81_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_nand_i16_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB81_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a5, $a4, $a1 +-; LA64-NEXT: nor $a5, $a5, $zero +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB81_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw nand ptr %a, i16 %b acq_rel +- ret i16 %1 +-} +- +-define i32 @atomicrmw_nand_i32_acq_rel(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_nand_i32_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB82_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: and $a3, $a2, $a1 +-; LA32-NEXT: nor $a3, $a3, $zero +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB82_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_nand_i32_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: .LBB82_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a2, $a0, 0 +-; LA64-NEXT: and $a3, $a2, $a1 +-; LA64-NEXT: nor $a3, $a3, $zero +-; LA64-NEXT: sc.w $a3, $a0, 0 +-; LA64-NEXT: beqz $a3, .LBB82_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw nand ptr %a, i32 %b acq_rel +- ret i32 %1 +-} +- +-define i64 @atomicrmw_nand_i64_acq_rel(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_nand_i64_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 4 +-; LA32-NEXT: bl %plt(__atomic_fetch_nand_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_nand_i64_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: .LBB83_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.d $a2, $a0, 0 +-; LA64-NEXT: and $a3, $a2, $a1 +-; LA64-NEXT: nor $a3, $a3, $zero +-; LA64-NEXT: sc.d $a3, $a0, 0 +-; LA64-NEXT: beqz $a3, .LBB83_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw nand ptr %a, i64 %b acq_rel +- ret i64 %1 +-} +- +-define i8 @atomicrmw_and_i8_acq_rel(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_and_i8_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: orn $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB84_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: and $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB84_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_and_i8_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: orn $a1, $a1, $a3 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amand_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw and ptr %a, i8 %b acq_rel +- ret i8 %1 +-} +- +-define i16 @atomicrmw_and_i16_acq_rel(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_and_i16_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: orn $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB85_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: and $a4, $a2, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB85_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a2, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_and_i16_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: orn $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amand_db.w $a2, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a2, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw and ptr %a, i16 %b acq_rel +- ret i16 %1 +-} +- +-define i32 @atomicrmw_and_i32_acq_rel(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_and_i32_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB86_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: and $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB86_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_and_i32_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: amand_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw and ptr %a, i32 %b acq_rel +- ret i32 %1 +-} +- +-define i64 @atomicrmw_and_i64_acq_rel(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_and_i64_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 4 +-; LA32-NEXT: bl %plt(__atomic_fetch_and_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_and_i64_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: amand_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw and ptr %a, i64 %b acq_rel +- ret i64 %1 +-} +- +-define i8 @atomicrmw_or_i8_acq_rel(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_or_i8_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB88_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: or $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB88_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_or_i8_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw or ptr %a, i8 %b acq_rel +- ret i8 %1 +-} +- +-define i16 @atomicrmw_or_i16_acq_rel(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_or_i16_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB89_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: or $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB89_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_or_i16_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw or ptr %a, i16 %b acq_rel +- ret i16 %1 +-} +- +-define i32 @atomicrmw_or_i32_acq_rel(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_or_i32_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB90_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: or $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB90_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_or_i32_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: amor_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw or ptr %a, i32 %b acq_rel +- ret i32 %1 +-} +- +-define i64 @atomicrmw_or_i64_acq_rel(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_or_i64_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 4 +-; LA32-NEXT: bl %plt(__atomic_fetch_or_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_or_i64_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: amor_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw or ptr %a, i64 %b acq_rel +- ret i64 %1 +-} +- +-define i8 @atomicrmw_xor_i8_acq_rel(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_xor_i8_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB92_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: xor $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB92_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xor_i8_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amxor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xor ptr %a, i8 %b acq_rel +- ret i8 %1 +-} +- +-define i16 @atomicrmw_xor_i16_acq_rel(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_xor_i16_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB93_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: xor $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB93_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xor_i16_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amxor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xor ptr %a, i16 %b acq_rel +- ret i16 %1 +-} +- +-define i32 @atomicrmw_xor_i32_acq_rel(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_xor_i32_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB94_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: xor $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB94_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xor_i32_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: amxor_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xor ptr %a, i32 %b acq_rel +- ret i32 %1 +-} +- +-define i64 @atomicrmw_xor_i64_acq_rel(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_xor_i64_acq_rel: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 4 +-; LA32-NEXT: bl %plt(__atomic_fetch_xor_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xor_i64_acq_rel: +-; LA64: # %bb.0: +-; LA64-NEXT: amxor_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xor ptr %a, i64 %b acq_rel +- ret i64 %1 +-} +- +-define i8 @atomicrmw_xchg_i8_seq_cst(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_xchg_i8_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB96_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: addi.w $a5, $a1, 0 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a3 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB96_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_i8_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB96_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: addi.w $a5, $a1, 0 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB96_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i8 %b seq_cst +- ret i8 %1 +-} +- +-define i8 @atomicrmw_xchg_0_i8_seq_cst(ptr %a) nounwind { +-; LA32-LABEL: atomicrmw_xchg_0_i8_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a0, 3 +-; LA32-NEXT: ori $a2, $zero, 255 +-; LA32-NEXT: sll.w $a2, $a2, $a1 +-; LA32-NEXT: nor $a2, $a2, $zero +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB97_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: and $a4, $a3, $a2 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB97_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_0_i8_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 3 +-; LA64-NEXT: ori $a2, $zero, 255 +-; LA64-NEXT: sll.w $a2, $a2, $a1 +-; LA64-NEXT: nor $a2, $a2, $zero +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amand_db.w $a3, $a2, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a1 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i8 0 seq_cst +- ret i8 %1 +-} +- +-define i8 @atomicrmw_xchg_minus_1_i8_seq_cst(ptr %a) nounwind { +-; LA32-LABEL: atomicrmw_xchg_minus_1_i8_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a0, 3 +-; LA32-NEXT: ori $a2, $zero, 255 +-; LA32-NEXT: sll.w $a2, $a2, $a1 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB98_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: or $a4, $a3, $a2 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB98_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_minus_1_i8_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 3 +-; LA64-NEXT: ori $a2, $zero, 255 +-; LA64-NEXT: sll.w $a2, $a2, $a1 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amor_db.w $a3, $a2, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a1 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i8 -1 seq_cst +- ret i8 %1 +-} +- +-define i16 @atomicrmw_xchg_i16_seq_cst(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_xchg_i16_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB99_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: addi.w $a5, $a1, 0 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a2 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB99_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_i16_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB99_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: addi.w $a5, $a1, 0 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB99_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i16 %b seq_cst +- ret i16 %1 +-} +- +-define i16 @atomicrmw_xchg_0_i16_seq_cst(ptr %a) nounwind { +-; LA32-LABEL: atomicrmw_xchg_0_i16_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 15 +-; LA32-NEXT: ori $a1, $a1, 4095 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: nor $a1, $a1, $zero +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB100_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: and $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB100_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_0_i16_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, 15 +-; LA64-NEXT: ori $a1, $a1, 4095 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: nor $a1, $a1, $zero +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amand_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i16 0 seq_cst +- ret i16 %1 +-} +- +-define i16 @atomicrmw_xchg_minus_1_i16_seq_cst(ptr %a) nounwind { +-; LA32-LABEL: atomicrmw_xchg_minus_1_i16_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 15 +-; LA32-NEXT: ori $a1, $a1, 4095 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB101_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: or $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB101_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_minus_1_i16_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, 15 +-; LA64-NEXT: ori $a1, $a1, 4095 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i16 -1 seq_cst +- ret i16 %1 +-} +- +-define i32 @atomicrmw_xchg_i32_seq_cst(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_xchg_i32_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB102_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: move $a3, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB102_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_i32_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: amswap_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i32 %b seq_cst +- ret i32 %1 +-} +- +-define i64 @atomicrmw_xchg_i64_seq_cst(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_xchg_i64_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 5 +-; LA32-NEXT: bl %plt(__atomic_exchange_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_i64_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: amswap_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i64 %b seq_cst +- ret i64 %1 +-} +- +-define i8 @atomicrmw_add_i8_seq_cst(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_add_i8_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB104_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: add.w $a5, $a4, $a1 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a3 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB104_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_add_i8_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB104_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: add.w $a5, $a4, $a1 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB104_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw add ptr %a, i8 %b seq_cst +- ret i8 %1 +-} +- +-define i16 @atomicrmw_add_i16_seq_cst(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_add_i16_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB105_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: add.w $a5, $a4, $a1 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a2 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB105_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_add_i16_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB105_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: add.w $a5, $a4, $a1 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB105_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw add ptr %a, i16 %b seq_cst +- ret i16 %1 +-} +- +-define i32 @atomicrmw_add_i32_seq_cst(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_add_i32_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB106_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: add.w $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB106_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_add_i32_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: amadd_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw add ptr %a, i32 %b seq_cst +- ret i32 %1 +-} +- +-define i64 @atomicrmw_add_i64_seq_cst(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_add_i64_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 5 +-; LA32-NEXT: bl %plt(__atomic_fetch_add_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_add_i64_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: amadd_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw add ptr %a, i64 %b seq_cst +- ret i64 %1 +-} +- +-define i8 @atomicrmw_sub_i8_seq_cst(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_sub_i8_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB108_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: sub.w $a5, $a4, $a1 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a3 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB108_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_sub_i8_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB108_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: sub.w $a5, $a4, $a1 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB108_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw sub ptr %a, i8 %b seq_cst +- ret i8 %1 +-} +- +-define i16 @atomicrmw_sub_i16_seq_cst(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_sub_i16_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB109_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: sub.w $a5, $a4, $a1 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a2 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB109_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_sub_i16_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB109_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: sub.w $a5, $a4, $a1 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB109_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw sub ptr %a, i16 %b seq_cst +- ret i16 %1 +-} +- +-define i32 @atomicrmw_sub_i32_seq_cst(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_sub_i32_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB110_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: sub.w $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB110_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_sub_i32_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.w $a2, $zero, $a1 +-; LA64-NEXT: amadd_db.w $a1, $a2, $a0 +-; LA64-NEXT: move $a0, $a1 +-; LA64-NEXT: ret +- %1 = atomicrmw sub ptr %a, i32 %b seq_cst +- ret i32 %1 +-} +- +-define i64 @atomicrmw_sub_i64_seq_cst(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_sub_i64_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 5 +-; LA32-NEXT: bl %plt(__atomic_fetch_sub_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_sub_i64_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.d $a2, $zero, $a1 +-; LA64-NEXT: amadd_db.d $a1, $a2, $a0 +-; LA64-NEXT: move $a0, $a1 +-; LA64-NEXT: ret +- %1 = atomicrmw sub ptr %a, i64 %b seq_cst +- ret i64 %1 +-} +- +-define i8 @atomicrmw_nand_i8_seq_cst(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_nand_i8_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB112_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: and $a5, $a4, $a1 +-; LA32-NEXT: nor $a5, $a5, $zero +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a3 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB112_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_nand_i8_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB112_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a5, $a4, $a1 +-; LA64-NEXT: nor $a5, $a5, $zero +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB112_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw nand ptr %a, i8 %b seq_cst +- ret i8 %1 +-} +- +-define i16 @atomicrmw_nand_i16_seq_cst(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_nand_i16_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB113_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: and $a5, $a4, $a1 +-; LA32-NEXT: nor $a5, $a5, $zero +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a2 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB113_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_nand_i16_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB113_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a5, $a4, $a1 +-; LA64-NEXT: nor $a5, $a5, $zero +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB113_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw nand ptr %a, i16 %b seq_cst +- ret i16 %1 +-} +- +-define i32 @atomicrmw_nand_i32_seq_cst(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_nand_i32_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB114_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: and $a3, $a2, $a1 +-; LA32-NEXT: nor $a3, $a3, $zero +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB114_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_nand_i32_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: .LBB114_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a2, $a0, 0 +-; LA64-NEXT: and $a3, $a2, $a1 +-; LA64-NEXT: nor $a3, $a3, $zero +-; LA64-NEXT: sc.w $a3, $a0, 0 +-; LA64-NEXT: beqz $a3, .LBB114_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw nand ptr %a, i32 %b seq_cst +- ret i32 %1 +-} +- +-define i64 @atomicrmw_nand_i64_seq_cst(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_nand_i64_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 5 +-; LA32-NEXT: bl %plt(__atomic_fetch_nand_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_nand_i64_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: .LBB115_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.d $a2, $a0, 0 +-; LA64-NEXT: and $a3, $a2, $a1 +-; LA64-NEXT: nor $a3, $a3, $zero +-; LA64-NEXT: sc.d $a3, $a0, 0 +-; LA64-NEXT: beqz $a3, .LBB115_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw nand ptr %a, i64 %b seq_cst +- ret i64 %1 +-} +- +-define i8 @atomicrmw_and_i8_seq_cst(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_and_i8_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: orn $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB116_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: and $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB116_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_and_i8_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: orn $a1, $a1, $a3 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amand_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw and ptr %a, i8 %b seq_cst +- ret i8 %1 +-} +- +-define i16 @atomicrmw_and_i16_seq_cst(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_and_i16_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: orn $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB117_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: and $a4, $a2, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB117_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a2, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_and_i16_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: orn $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amand_db.w $a2, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a2, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw and ptr %a, i16 %b seq_cst +- ret i16 %1 +-} +- +-define i32 @atomicrmw_and_i32_seq_cst(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_and_i32_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB118_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: and $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB118_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_and_i32_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: amand_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw and ptr %a, i32 %b seq_cst +- ret i32 %1 +-} +- +-define i64 @atomicrmw_and_i64_seq_cst(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_and_i64_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 5 +-; LA32-NEXT: bl %plt(__atomic_fetch_and_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_and_i64_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: amand_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw and ptr %a, i64 %b seq_cst +- ret i64 %1 +-} +- +-define i8 @atomicrmw_or_i8_seq_cst(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_or_i8_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB120_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: or $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB120_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_or_i8_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw or ptr %a, i8 %b seq_cst +- ret i8 %1 +-} +- +-define i16 @atomicrmw_or_i16_seq_cst(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_or_i16_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB121_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: or $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB121_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_or_i16_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw or ptr %a, i16 %b seq_cst +- ret i16 %1 +-} +- +-define i32 @atomicrmw_or_i32_seq_cst(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_or_i32_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB122_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: or $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB122_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_or_i32_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: amor_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw or ptr %a, i32 %b seq_cst +- ret i32 %1 +-} +- +-define i64 @atomicrmw_or_i64_seq_cst(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_or_i64_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 5 +-; LA32-NEXT: bl %plt(__atomic_fetch_or_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_or_i64_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: amor_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw or ptr %a, i64 %b seq_cst +- ret i64 %1 +-} +- +-define i8 @atomicrmw_xor_i8_seq_cst(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_xor_i8_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB124_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: xor $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB124_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xor_i8_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amxor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xor ptr %a, i8 %b seq_cst +- ret i8 %1 +-} +- +-define i16 @atomicrmw_xor_i16_seq_cst(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_xor_i16_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB125_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: xor $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB125_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xor_i16_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amxor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xor ptr %a, i16 %b seq_cst +- ret i16 %1 +-} +- +-define i32 @atomicrmw_xor_i32_seq_cst(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_xor_i32_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB126_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: xor $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB126_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xor_i32_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: amxor_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xor ptr %a, i32 %b seq_cst +- ret i32 %1 +-} +- +-define i64 @atomicrmw_xor_i64_seq_cst(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_xor_i64_seq_cst: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ori $a3, $zero, 5 +-; LA32-NEXT: bl %plt(__atomic_fetch_xor_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xor_i64_seq_cst: +-; LA64: # %bb.0: +-; LA64-NEXT: amxor_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xor ptr %a, i64 %b seq_cst +- ret i64 %1 +-} +- +-define i8 @atomicrmw_xchg_i8_monotonic(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_xchg_i8_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB128_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: addi.w $a5, $a1, 0 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a3 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB128_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_i8_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB128_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: addi.w $a5, $a1, 0 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB128_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i8 %b monotonic +- ret i8 %1 +-} +- +-define i8 @atomicrmw_xchg_0_i8_monotonic(ptr %a) nounwind { +-; LA32-LABEL: atomicrmw_xchg_0_i8_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a0, 3 +-; LA32-NEXT: ori $a2, $zero, 255 +-; LA32-NEXT: sll.w $a2, $a2, $a1 +-; LA32-NEXT: nor $a2, $a2, $zero +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB129_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: and $a4, $a3, $a2 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB129_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_0_i8_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 3 +-; LA64-NEXT: ori $a2, $zero, 255 +-; LA64-NEXT: sll.w $a2, $a2, $a1 +-; LA64-NEXT: nor $a2, $a2, $zero +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amand_db.w $a3, $a2, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a1 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i8 0 monotonic +- ret i8 %1 +-} +- +-define i8 @atomicrmw_xchg_minus_1_i8_monotonic(ptr %a) nounwind { +-; LA32-LABEL: atomicrmw_xchg_minus_1_i8_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a0, 3 +-; LA32-NEXT: ori $a2, $zero, 255 +-; LA32-NEXT: sll.w $a2, $a2, $a1 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB130_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: or $a4, $a3, $a2 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB130_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_minus_1_i8_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 3 +-; LA64-NEXT: ori $a2, $zero, 255 +-; LA64-NEXT: sll.w $a2, $a2, $a1 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amor_db.w $a3, $a2, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a1 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i8 -1 monotonic +- ret i8 %1 +-} +- +-define i16 @atomicrmw_xchg_i16_monotonic(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_xchg_i16_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB131_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: addi.w $a5, $a1, 0 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a2 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB131_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_i16_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB131_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: addi.w $a5, $a1, 0 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB131_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i16 %b monotonic +- ret i16 %1 +-} +- +-define i16 @atomicrmw_xchg_0_i16_monotonic(ptr %a) nounwind { +-; LA32-LABEL: atomicrmw_xchg_0_i16_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 15 +-; LA32-NEXT: ori $a1, $a1, 4095 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: nor $a1, $a1, $zero +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB132_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: and $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB132_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_0_i16_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, 15 +-; LA64-NEXT: ori $a1, $a1, 4095 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: nor $a1, $a1, $zero +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amand_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i16 0 monotonic +- ret i16 %1 +-} +- +-define i16 @atomicrmw_xchg_minus_1_i16_monotonic(ptr %a) nounwind { +-; LA32-LABEL: atomicrmw_xchg_minus_1_i16_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a1, 15 +-; LA32-NEXT: ori $a1, $a1, 4095 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB133_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: or $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB133_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_minus_1_i16_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, 15 +-; LA64-NEXT: ori $a1, $a1, 4095 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i16 -1 monotonic +- ret i16 %1 +-} +- +-define i32 @atomicrmw_xchg_i32_monotonic(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_xchg_i32_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB134_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: move $a3, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB134_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_i32_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: amswap_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i32 %b monotonic +- ret i32 %1 +-} +- +-define i64 @atomicrmw_xchg_i64_monotonic(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_xchg_i64_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: move $a3, $zero +-; LA32-NEXT: bl %plt(__atomic_exchange_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xchg_i64_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: amswap_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xchg ptr %a, i64 %b monotonic +- ret i64 %1 +-} +- +-define i8 @atomicrmw_add_i8_monotonic(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_add_i8_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB136_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: add.w $a5, $a4, $a1 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a3 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB136_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_add_i8_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB136_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: add.w $a5, $a4, $a1 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB136_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw add ptr %a, i8 %b monotonic +- ret i8 %1 +-} +- +-define i16 @atomicrmw_add_i16_monotonic(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_add_i16_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB137_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: add.w $a5, $a4, $a1 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a2 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB137_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_add_i16_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB137_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: add.w $a5, $a4, $a1 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB137_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw add ptr %a, i16 %b monotonic +- ret i16 %1 +-} +- +-define i32 @atomicrmw_add_i32_monotonic(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_add_i32_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB138_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: add.w $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB138_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_add_i32_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: amadd_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw add ptr %a, i32 %b monotonic +- ret i32 %1 +-} +- +-define i64 @atomicrmw_add_i64_monotonic(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_add_i64_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: move $a3, $zero +-; LA32-NEXT: bl %plt(__atomic_fetch_add_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_add_i64_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: amadd_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw add ptr %a, i64 %b monotonic +- ret i64 %1 +-} +- +-define i8 @atomicrmw_sub_i8_monotonic(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_sub_i8_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB140_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: sub.w $a5, $a4, $a1 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a3 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB140_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_sub_i8_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB140_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: sub.w $a5, $a4, $a1 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB140_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw sub ptr %a, i8 %b monotonic +- ret i8 %1 +-} +- +-define i16 @atomicrmw_sub_i16_monotonic(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_sub_i16_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB141_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: sub.w $a5, $a4, $a1 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a2 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB141_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_sub_i16_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB141_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: sub.w $a5, $a4, $a1 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB141_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw sub ptr %a, i16 %b monotonic +- ret i16 %1 +-} +- +-define i32 @atomicrmw_sub_i32_monotonic(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_sub_i32_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB142_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: sub.w $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB142_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_sub_i32_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.w $a2, $zero, $a1 +-; LA64-NEXT: amadd_db.w $a1, $a2, $a0 +-; LA64-NEXT: move $a0, $a1 +-; LA64-NEXT: ret +- %1 = atomicrmw sub ptr %a, i32 %b monotonic +- ret i32 %1 +-} +- +-define i64 @atomicrmw_sub_i64_monotonic(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_sub_i64_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: move $a3, $zero +-; LA32-NEXT: bl %plt(__atomic_fetch_sub_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_sub_i64_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.d $a2, $zero, $a1 +-; LA64-NEXT: amadd_db.d $a1, $a2, $a0 +-; LA64-NEXT: move $a0, $a1 +-; LA64-NEXT: ret +- %1 = atomicrmw sub ptr %a, i64 %b monotonic +- ret i64 %1 +-} +- +-define i8 @atomicrmw_nand_i8_monotonic(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_nand_i8_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB144_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: and $a5, $a4, $a1 +-; LA32-NEXT: nor $a5, $a5, $zero +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a3 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB144_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_nand_i8_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: addi.w $a3, $a3, 0 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB144_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a5, $a4, $a1 +-; LA64-NEXT: nor $a5, $a5, $zero +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a3 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB144_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw nand ptr %a, i8 %b monotonic +- ret i8 %1 +-} +- +-define i16 @atomicrmw_nand_i16_monotonic(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_nand_i16_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB145_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a4, $a0, 0 +-; LA32-NEXT: and $a5, $a4, $a1 +-; LA32-NEXT: nor $a5, $a5, $zero +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: and $a5, $a5, $a2 +-; LA32-NEXT: xor $a5, $a4, $a5 +-; LA32-NEXT: sc.w $a5, $a0, 0 +-; LA32-NEXT: beqz $a5, .LBB145_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a4, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_nand_i16_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: addi.w $a2, $a2, 0 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: .LBB145_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a4, $a0, 0 +-; LA64-NEXT: and $a5, $a4, $a1 +-; LA64-NEXT: nor $a5, $a5, $zero +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: and $a5, $a5, $a2 +-; LA64-NEXT: xor $a5, $a4, $a5 +-; LA64-NEXT: sc.w $a5, $a0, 0 +-; LA64-NEXT: beqz $a5, .LBB145_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: srl.w $a0, $a4, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw nand ptr %a, i16 %b monotonic +- ret i16 %1 +-} +- +-define i32 @atomicrmw_nand_i32_monotonic(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_nand_i32_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB146_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: and $a3, $a2, $a1 +-; LA32-NEXT: nor $a3, $a3, $zero +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB146_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_nand_i32_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: .LBB146_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.w $a2, $a0, 0 +-; LA64-NEXT: and $a3, $a2, $a1 +-; LA64-NEXT: nor $a3, $a3, $zero +-; LA64-NEXT: sc.w $a3, $a0, 0 +-; LA64-NEXT: beqz $a3, .LBB146_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw nand ptr %a, i32 %b monotonic +- ret i32 %1 +-} +- +-define i64 @atomicrmw_nand_i64_monotonic(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_nand_i64_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: move $a3, $zero +-; LA32-NEXT: bl %plt(__atomic_fetch_nand_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_nand_i64_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: .LBB147_1: # =>This Inner Loop Header: Depth=1 +-; LA64-NEXT: ll.d $a2, $a0, 0 +-; LA64-NEXT: and $a3, $a2, $a1 +-; LA64-NEXT: nor $a3, $a3, $zero +-; LA64-NEXT: sc.d $a3, $a0, 0 +-; LA64-NEXT: beqz $a3, .LBB147_1 +-; LA64-NEXT: # %bb.2: +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw nand ptr %a, i64 %b monotonic +- ret i64 %1 +-} +- +-define i8 @atomicrmw_and_i8_monotonic(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_and_i8_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: ori $a3, $zero, 255 +-; LA32-NEXT: sll.w $a3, $a3, $a2 +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: orn $a1, $a1, $a3 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB148_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: and $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB148_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_and_i8_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: ori $a3, $zero, 255 +-; LA64-NEXT: sll.w $a3, $a3, $a2 +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: orn $a1, $a1, $a3 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amand_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw and ptr %a, i8 %b monotonic +- ret i8 %1 +-} +- +-define i16 @atomicrmw_and_i16_monotonic(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_and_i16_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 4095 +-; LA32-NEXT: slli.w $a3, $a0, 3 +-; LA32-NEXT: sll.w $a2, $a2, $a3 +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: sll.w $a1, $a1, $a3 +-; LA32-NEXT: orn $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB149_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: and $a4, $a2, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB149_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a2, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_and_i16_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 4095 +-; LA64-NEXT: slli.d $a3, $a0, 3 +-; LA64-NEXT: sll.w $a2, $a2, $a3 +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: sll.w $a1, $a1, $a3 +-; LA64-NEXT: orn $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amand_db.w $a2, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a2, $a3 +-; LA64-NEXT: ret +- %1 = atomicrmw and ptr %a, i16 %b monotonic +- ret i16 %1 +-} +- +-define i32 @atomicrmw_and_i32_monotonic(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_and_i32_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB150_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: and $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB150_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_and_i32_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: amand_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw and ptr %a, i32 %b monotonic +- ret i32 %1 +-} +- +-define i64 @atomicrmw_and_i64_monotonic(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_and_i64_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: move $a3, $zero +-; LA32-NEXT: bl %plt(__atomic_fetch_and_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_and_i64_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: amand_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw and ptr %a, i64 %b monotonic +- ret i64 %1 +-} +- +-define i8 @atomicrmw_or_i8_monotonic(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_or_i8_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB152_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: or $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB152_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_or_i8_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw or ptr %a, i8 %b monotonic +- ret i8 %1 +-} +- +-define i16 @atomicrmw_or_i16_monotonic(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_or_i16_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB153_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: or $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB153_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_or_i16_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw or ptr %a, i16 %b monotonic +- ret i16 %1 +-} +- +-define i32 @atomicrmw_or_i32_monotonic(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_or_i32_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB154_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: or $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB154_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_or_i32_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: amor_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw or ptr %a, i32 %b monotonic +- ret i32 %1 +-} +- +-define i64 @atomicrmw_or_i64_monotonic(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_or_i64_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: move $a3, $zero +-; LA32-NEXT: bl %plt(__atomic_fetch_or_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_or_i64_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: amor_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw or ptr %a, i64 %b monotonic +- ret i64 %1 +-} +- +-define i8 @atomicrmw_xor_i8_monotonic(ptr %a, i8 %b) nounwind { +-; LA32-LABEL: atomicrmw_xor_i8_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB156_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: xor $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB156_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xor_i8_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amxor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xor ptr %a, i8 %b monotonic +- ret i8 %1 +-} +- +-define i16 @atomicrmw_xor_i16_monotonic(ptr %a, i16 %b) nounwind { +-; LA32-LABEL: atomicrmw_xor_i16_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: slli.w $a2, $a0, 3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: bstrins.w $a0, $zero, 1, 0 +-; LA32-NEXT: .LBB157_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a3, $a0, 0 +-; LA32-NEXT: xor $a4, $a3, $a1 +-; LA32-NEXT: sc.w $a4, $a0, 0 +-; LA32-NEXT: beqz $a4, .LBB157_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: srl.w $a0, $a3, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xor_i16_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: slli.d $a2, $a0, 3 +-; LA64-NEXT: sll.w $a1, $a1, $a2 +-; LA64-NEXT: bstrins.d $a0, $zero, 1, 0 +-; LA64-NEXT: amxor_db.w $a3, $a1, $a0 +-; LA64-NEXT: srl.w $a0, $a3, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xor ptr %a, i16 %b monotonic +- ret i16 %1 +-} +- +-define i32 @atomicrmw_xor_i32_monotonic(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: atomicrmw_xor_i32_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: .LBB158_1: # =>This Inner Loop Header: Depth=1 +-; LA32-NEXT: ll.w $a2, $a0, 0 +-; LA32-NEXT: xor $a3, $a2, $a1 +-; LA32-NEXT: sc.w $a3, $a0, 0 +-; LA32-NEXT: beqz $a3, .LBB158_1 +-; LA32-NEXT: # %bb.2: +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xor_i32_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: amxor_db.w $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xor ptr %a, i32 %b monotonic +- ret i32 %1 +-} +- +-define i64 @atomicrmw_xor_i64_monotonic(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: atomicrmw_xor_i64_monotonic: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: move $a3, $zero +-; LA32-NEXT: bl %plt(__atomic_fetch_xor_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: atomicrmw_xor_i64_monotonic: +-; LA64: # %bb.0: +-; LA64-NEXT: amxor_db.d $a2, $a1, $a0 +-; LA64-NEXT: move $a0, $a2 +-; LA64-NEXT: ret +- %1 = atomicrmw xor ptr %a, i64 %b monotonic +- ret i64 %1 +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/br.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/br.ll +deleted file mode 100644 +index 36e39cc6d..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/br.ll ++++ /dev/null +@@ -1,339 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefixes=ALL,LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefixes=ALL,LA64 +- +-define void @foo() noreturn nounwind { +-; ALL-LABEL: foo: +-; ALL: # %bb.0: # %entry +-; ALL-NEXT: .p2align 4, , 16 +-; ALL-NEXT: .LBB0_1: # %loop +-; ALL-NEXT: # =>This Inner Loop Header: Depth=1 +-; ALL-NEXT: b .LBB0_1 +-entry: +- br label %loop +-loop: +- br label %loop +-} +- +-define void @foo_br_eq(i32 %a, ptr %b) nounwind { +-; LA32-LABEL: foo_br_eq: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a2, $a1, 0 +-; LA32-NEXT: beq $a2, $a0, .LBB1_2 +-; LA32-NEXT: # %bb.1: # %test +-; LA32-NEXT: ld.w $a0, $a1, 0 +-; LA32-NEXT: .LBB1_2: # %end +-; LA32-NEXT: ret +-; +-; LA64-LABEL: foo_br_eq: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.w $a2, $a1, 0 +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: beq $a2, $a0, .LBB1_2 +-; LA64-NEXT: # %bb.1: # %test +-; LA64-NEXT: ld.w $a0, $a1, 0 +-; LA64-NEXT: .LBB1_2: # %end +-; LA64-NEXT: ret +- %val = load volatile i32, ptr %b +- %cc = icmp eq i32 %val, %a +- br i1 %cc, label %end, label %test +-test: +- %tmp = load volatile i32, ptr %b +- br label %end +- +-end: +- ret void +-} +- +-define void @foo_br_ne(i32 %a, ptr %b) nounwind { +-; LA32-LABEL: foo_br_ne: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a2, $a1, 0 +-; LA32-NEXT: bne $a2, $a0, .LBB2_2 +-; LA32-NEXT: # %bb.1: # %test +-; LA32-NEXT: ld.w $a0, $a1, 0 +-; LA32-NEXT: .LBB2_2: # %end +-; LA32-NEXT: ret +-; +-; LA64-LABEL: foo_br_ne: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.w $a2, $a1, 0 +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: bne $a2, $a0, .LBB2_2 +-; LA64-NEXT: # %bb.1: # %test +-; LA64-NEXT: ld.w $a0, $a1, 0 +-; LA64-NEXT: .LBB2_2: # %end +-; LA64-NEXT: ret +- %val = load volatile i32, ptr %b +- %cc = icmp ne i32 %val, %a +- br i1 %cc, label %end, label %test +-test: +- %tmp = load volatile i32, ptr %b +- br label %end +- +-end: +- ret void +-} +- +-define void @foo_br_slt(i32 %a, ptr %b) nounwind { +-; LA32-LABEL: foo_br_slt: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a2, $a1, 0 +-; LA32-NEXT: blt $a2, $a0, .LBB3_2 +-; LA32-NEXT: # %bb.1: # %test +-; LA32-NEXT: ld.w $a0, $a1, 0 +-; LA32-NEXT: .LBB3_2: # %end +-; LA32-NEXT: ret +-; +-; LA64-LABEL: foo_br_slt: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.w $a2, $a1, 0 +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: blt $a2, $a0, .LBB3_2 +-; LA64-NEXT: # %bb.1: # %test +-; LA64-NEXT: ld.w $a0, $a1, 0 +-; LA64-NEXT: .LBB3_2: # %end +-; LA64-NEXT: ret +- %val = load volatile i32, ptr %b +- %cc = icmp slt i32 %val, %a +- br i1 %cc, label %end, label %test +-test: +- %tmp = load volatile i32, ptr %b +- br label %end +- +-end: +- ret void +-} +- +-define void @foo_br_sge(i32 %a, ptr %b) nounwind { +-; LA32-LABEL: foo_br_sge: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a2, $a1, 0 +-; LA32-NEXT: bge $a2, $a0, .LBB4_2 +-; LA32-NEXT: # %bb.1: # %test +-; LA32-NEXT: ld.w $a0, $a1, 0 +-; LA32-NEXT: .LBB4_2: # %end +-; LA32-NEXT: ret +-; +-; LA64-LABEL: foo_br_sge: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.w $a2, $a1, 0 +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: bge $a2, $a0, .LBB4_2 +-; LA64-NEXT: # %bb.1: # %test +-; LA64-NEXT: ld.w $a0, $a1, 0 +-; LA64-NEXT: .LBB4_2: # %end +-; LA64-NEXT: ret +- %val = load volatile i32, ptr %b +- %cc = icmp sge i32 %val, %a +- br i1 %cc, label %end, label %test +-test: +- %tmp = load volatile i32, ptr %b +- br label %end +- +-end: +- ret void +-} +- +-define void @foo_br_ult(i32 %a, ptr %b) nounwind { +-; LA32-LABEL: foo_br_ult: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a2, $a1, 0 +-; LA32-NEXT: bltu $a2, $a0, .LBB5_2 +-; LA32-NEXT: # %bb.1: # %test +-; LA32-NEXT: ld.w $a0, $a1, 0 +-; LA32-NEXT: .LBB5_2: # %end +-; LA32-NEXT: ret +-; +-; LA64-LABEL: foo_br_ult: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.w $a2, $a1, 0 +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: bltu $a2, $a0, .LBB5_2 +-; LA64-NEXT: # %bb.1: # %test +-; LA64-NEXT: ld.w $a0, $a1, 0 +-; LA64-NEXT: .LBB5_2: # %end +-; LA64-NEXT: ret +- %val = load volatile i32, ptr %b +- %cc = icmp ult i32 %val, %a +- br i1 %cc, label %end, label %test +-test: +- %tmp = load volatile i32, ptr %b +- br label %end +- +-end: +- ret void +-} +- +-define void @foo_br_uge(i32 %a, ptr %b) nounwind { +-; LA32-LABEL: foo_br_uge: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a2, $a1, 0 +-; LA32-NEXT: bgeu $a2, $a0, .LBB6_2 +-; LA32-NEXT: # %bb.1: # %test +-; LA32-NEXT: ld.w $a0, $a1, 0 +-; LA32-NEXT: .LBB6_2: # %end +-; LA32-NEXT: ret +-; +-; LA64-LABEL: foo_br_uge: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.w $a2, $a1, 0 +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: bgeu $a2, $a0, .LBB6_2 +-; LA64-NEXT: # %bb.1: # %test +-; LA64-NEXT: ld.w $a0, $a1, 0 +-; LA64-NEXT: .LBB6_2: # %end +-; LA64-NEXT: ret +- %val = load volatile i32, ptr %b +- %cc = icmp uge i32 %val, %a +- br i1 %cc, label %end, label %test +-test: +- %tmp = load volatile i32, ptr %b +- br label %end +- +-end: +- ret void +-} +- +-;; Check for condition codes that don't have a matching instruction. +-define void @foo_br_sgt(i32 %a, ptr %b) nounwind { +-; LA32-LABEL: foo_br_sgt: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a2, $a1, 0 +-; LA32-NEXT: blt $a0, $a2, .LBB7_2 +-; LA32-NEXT: # %bb.1: # %test +-; LA32-NEXT: ld.w $a0, $a1, 0 +-; LA32-NEXT: .LBB7_2: # %end +-; LA32-NEXT: ret +-; +-; LA64-LABEL: foo_br_sgt: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.w $a2, $a1, 0 +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: blt $a0, $a2, .LBB7_2 +-; LA64-NEXT: # %bb.1: # %test +-; LA64-NEXT: ld.w $a0, $a1, 0 +-; LA64-NEXT: .LBB7_2: # %end +-; LA64-NEXT: ret +- %val = load volatile i32, ptr %b +- %cc = icmp sgt i32 %val, %a +- br i1 %cc, label %end, label %test +-test: +- %tmp = load volatile i32, ptr %b +- br label %end +- +-end: +- ret void +-} +- +-define void @foo_br_sle(i32 %a, ptr %b) nounwind { +-; LA32-LABEL: foo_br_sle: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a2, $a1, 0 +-; LA32-NEXT: bge $a0, $a2, .LBB8_2 +-; LA32-NEXT: # %bb.1: # %test +-; LA32-NEXT: ld.w $a0, $a1, 0 +-; LA32-NEXT: .LBB8_2: # %end +-; LA32-NEXT: ret +-; +-; LA64-LABEL: foo_br_sle: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.w $a2, $a1, 0 +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: bge $a0, $a2, .LBB8_2 +-; LA64-NEXT: # %bb.1: # %test +-; LA64-NEXT: ld.w $a0, $a1, 0 +-; LA64-NEXT: .LBB8_2: # %end +-; LA64-NEXT: ret +- %val = load volatile i32, ptr %b +- %cc = icmp sle i32 %val, %a +- br i1 %cc, label %end, label %test +-test: +- %tmp = load volatile i32, ptr %b +- br label %end +- +-end: +- ret void +-} +- +-define void @foo_br_ugt(i32 %a, ptr %b) nounwind { +-; LA32-LABEL: foo_br_ugt: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a2, $a1, 0 +-; LA32-NEXT: bltu $a0, $a2, .LBB9_2 +-; LA32-NEXT: # %bb.1: # %test +-; LA32-NEXT: ld.w $a0, $a1, 0 +-; LA32-NEXT: .LBB9_2: # %end +-; LA32-NEXT: ret +-; +-; LA64-LABEL: foo_br_ugt: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.w $a2, $a1, 0 +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: bltu $a0, $a2, .LBB9_2 +-; LA64-NEXT: # %bb.1: # %test +-; LA64-NEXT: ld.w $a0, $a1, 0 +-; LA64-NEXT: .LBB9_2: # %end +-; LA64-NEXT: ret +- %val = load volatile i32, ptr %b +- %cc = icmp ugt i32 %val, %a +- br i1 %cc, label %end, label %test +-test: +- %tmp = load volatile i32, ptr %b +- br label %end +- +-end: +- ret void +-} +- +-define void @foo_br_ule(i32 %a, ptr %b) nounwind { +-; LA32-LABEL: foo_br_ule: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a2, $a1, 0 +-; LA32-NEXT: bgeu $a0, $a2, .LBB10_2 +-; LA32-NEXT: # %bb.1: # %test +-; LA32-NEXT: ld.w $a0, $a1, 0 +-; LA32-NEXT: .LBB10_2: # %end +-; LA32-NEXT: ret +-; +-; LA64-LABEL: foo_br_ule: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.w $a2, $a1, 0 +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: bgeu $a0, $a2, .LBB10_2 +-; LA64-NEXT: # %bb.1: # %test +-; LA64-NEXT: ld.w $a0, $a1, 0 +-; LA64-NEXT: .LBB10_2: # %end +-; LA64-NEXT: ret +- %val = load volatile i32, ptr %b +- %cc = icmp ule i32 %val, %a +- br i1 %cc, label %end, label %test +-test: +- %tmp = load volatile i32, ptr %b +- br label %end +- +-end: +- ret void +-} +- +-;; Check the case of a branch where the condition was generated in another +-;; function. +-define void @foo_br_cc(ptr %a, i1 %cc) nounwind { +-; ALL-LABEL: foo_br_cc: +-; ALL: # %bb.0: +-; ALL-NEXT: ld.w $a2, $a0, 0 +-; ALL-NEXT: andi $a1, $a1, 1 +-; ALL-NEXT: bnez $a1, .LBB11_2 +-; ALL-NEXT: # %bb.1: # %test +-; ALL-NEXT: ld.w $a0, $a0, 0 +-; ALL-NEXT: .LBB11_2: # %end +-; ALL-NEXT: ret +- %val = load volatile i32, ptr %a +- br i1 %cc, label %end, label %test +-test: +- %tmp = load volatile i32, ptr %a +- br label %end +- +-end: +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/call.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/call.ll +deleted file mode 100644 +index 90ee9490d..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/call.ll ++++ /dev/null +@@ -1,89 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck --check-prefix=LA32 %s +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck --check-prefix=LA64 %s +- +-declare i32 @external_function(i32) +- +-define i32 @test_call_external(i32 %a) nounwind { +-; LA32-LABEL: test_call_external: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(external_function) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_call_external: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(external_function) +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %1 = call i32 @external_function(i32 %a) +- ret i32 %1 +-} +- +-define i32 @defined_function(i32 %a) nounwind { +-; LA32-LABEL: defined_function: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: defined_function: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $a0, $a0, 1 +-; LA64-NEXT: ret +- %1 = add i32 %a, 1 +- ret i32 %1 +-} +- +-define i32 @test_call_defined(i32 %a) nounwind { +-; LA32-LABEL: test_call_defined: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(defined_function) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_call_defined: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(defined_function) +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %1 = call i32 @defined_function(i32 %a) nounwind +- ret i32 %1 +-} +- +-define i32 @test_call_indirect(ptr %a, i32 %b) nounwind { +-; LA32-LABEL: test_call_indirect: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: move $a2, $a0 +-; LA32-NEXT: move $a0, $a1 +-; LA32-NEXT: jirl $ra, $a2, 0 +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_call_indirect: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: move $a2, $a0 +-; LA64-NEXT: move $a0, $a1 +-; LA64-NEXT: jirl $ra, $a2, 0 +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %1 = call i32 %a(i32 %b) +- ret i32 %1 +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/double-convert.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/double-convert.ll +deleted file mode 100644 +index 03a126a73..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/double-convert.ll ++++ /dev/null +@@ -1,316 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64 +- +-define float @convert_double_to_float(double %a) nounwind { +-; LA32-LABEL: convert_double_to_float: +-; LA32: # %bb.0: +-; LA32-NEXT: fcvt.s.d $fa0, $fa0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: convert_double_to_float: +-; LA64: # %bb.0: +-; LA64-NEXT: fcvt.s.d $fa0, $fa0 +-; LA64-NEXT: ret +- %1 = fptrunc double %a to float +- ret float %1 +-} +- +-define double @convert_float_to_double(float %a) nounwind { +-; LA32-LABEL: convert_float_to_double: +-; LA32: # %bb.0: +-; LA32-NEXT: fcvt.d.s $fa0, $fa0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: convert_float_to_double: +-; LA64: # %bb.0: +-; LA64-NEXT: fcvt.d.s $fa0, $fa0 +-; LA64-NEXT: ret +- %1 = fpext float %a to double +- ret double %1 +-} +- +-define double @convert_i8_to_double(i8 signext %a) nounwind { +-; LA32-LABEL: convert_i8_to_double: +-; LA32: # %bb.0: +-; LA32-NEXT: movgr2fr.w $fa0, $a0 +-; LA32-NEXT: ffint.d.w $fa0, $fa0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: convert_i8_to_double: +-; LA64: # %bb.0: +-; LA64-NEXT: movgr2fr.w $fa0, $a0 +-; LA64-NEXT: ffint.d.w $fa0, $fa0 +-; LA64-NEXT: ret +- %1 = sitofp i8 %a to double +- ret double %1 +-} +- +-define double @convert_i16_to_double(i16 signext %a) nounwind { +-; LA32-LABEL: convert_i16_to_double: +-; LA32: # %bb.0: +-; LA32-NEXT: movgr2fr.w $fa0, $a0 +-; LA32-NEXT: ffint.d.w $fa0, $fa0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: convert_i16_to_double: +-; LA64: # %bb.0: +-; LA64-NEXT: movgr2fr.w $fa0, $a0 +-; LA64-NEXT: ffint.d.w $fa0, $fa0 +-; LA64-NEXT: ret +- %1 = sitofp i16 %a to double +- ret double %1 +-} +- +-define double @convert_i32_to_double(i32 %a) nounwind { +-; LA32-LABEL: convert_i32_to_double: +-; LA32: # %bb.0: +-; LA32-NEXT: movgr2fr.w $fa0, $a0 +-; LA32-NEXT: ffint.d.w $fa0, $fa0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: convert_i32_to_double: +-; LA64: # %bb.0: +-; LA64-NEXT: movgr2fr.w $fa0, $a0 +-; LA64-NEXT: ffint.d.w $fa0, $fa0 +-; LA64-NEXT: ret +- %1 = sitofp i32 %a to double +- ret double %1 +-} +- +-define double @convert_i64_to_double(i64 %a) nounwind { +-; LA32-LABEL: convert_i64_to_double: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(__floatdidf) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: convert_i64_to_double: +-; LA64: # %bb.0: +-; LA64-NEXT: movgr2fr.d $fa0, $a0 +-; LA64-NEXT: ffint.d.l $fa0, $fa0 +-; LA64-NEXT: ret +- %1 = sitofp i64 %a to double +- ret double %1 +-} +- +-define i32 @convert_double_to_i32(double %a) nounwind { +-; LA32-LABEL: convert_double_to_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: ftintrz.w.d $fa0, $fa0 +-; LA32-NEXT: movfr2gr.s $a0, $fa0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: convert_double_to_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: ftintrz.w.d $fa0, $fa0 +-; LA64-NEXT: movfr2gr.s $a0, $fa0 +-; LA64-NEXT: ret +- %1 = fptosi double %a to i32 +- ret i32 %1 +-} +- +-define i32 @convert_double_to_u32(double %a) nounwind { +-; LA32-LABEL: convert_double_to_u32: +-; LA32: # %bb.0: +-; LA32-NEXT: pcalau12i $a0, %pc_hi20(.LCPI7_0) +-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI7_0) +-; LA32-NEXT: fld.d $fa1, $a0, 0 +-; LA32-NEXT: fsub.d $fa2, $fa0, $fa1 +-; LA32-NEXT: ftintrz.w.d $fa2, $fa2 +-; LA32-NEXT: movfr2gr.s $a0, $fa2 +-; LA32-NEXT: lu12i.w $a1, -524288 +-; LA32-NEXT: xor $a0, $a0, $a1 +-; LA32-NEXT: fcmp.clt.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a1, $fcc0 +-; LA32-NEXT: masknez $a0, $a0, $a1 +-; LA32-NEXT: ftintrz.w.d $fa0, $fa0 +-; LA32-NEXT: movfr2gr.s $a2, $fa0 +-; LA32-NEXT: maskeqz $a1, $a2, $a1 +-; LA32-NEXT: or $a0, $a1, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: convert_double_to_u32: +-; LA64: # %bb.0: +-; LA64-NEXT: ftintrz.l.d $fa0, $fa0 +-; LA64-NEXT: movfr2gr.d $a0, $fa0 +-; LA64-NEXT: ret +- %1 = fptoui double %a to i32 +- ret i32 %1 +-} +- +-define i64 @convert_double_to_i64(double %a) nounwind { +-; LA32-LABEL: convert_double_to_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(__fixdfdi) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: convert_double_to_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: ftintrz.l.d $fa0, $fa0 +-; LA64-NEXT: movfr2gr.d $a0, $fa0 +-; LA64-NEXT: ret +- %1 = fptosi double %a to i64 +- ret i64 %1 +-} +- +-define i64 @convert_double_to_u64(double %a) nounwind { +-; LA32-LABEL: convert_double_to_u64: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(__fixunsdfdi) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: convert_double_to_u64: +-; LA64: # %bb.0: +-; LA64-NEXT: pcalau12i $a0, %pc_hi20(.LCPI9_0) +-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI9_0) +-; LA64-NEXT: fld.d $fa1, $a0, 0 +-; LA64-NEXT: fsub.d $fa2, $fa0, $fa1 +-; LA64-NEXT: ftintrz.l.d $fa2, $fa2 +-; LA64-NEXT: movfr2gr.d $a0, $fa2 +-; LA64-NEXT: lu52i.d $a1, $zero, -2048 +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: fcmp.clt.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a1, $fcc0 +-; LA64-NEXT: masknez $a0, $a0, $a1 +-; LA64-NEXT: ftintrz.l.d $fa0, $fa0 +-; LA64-NEXT: movfr2gr.d $a2, $fa0 +-; LA64-NEXT: maskeqz $a1, $a2, $a1 +-; LA64-NEXT: or $a0, $a1, $a0 +-; LA64-NEXT: ret +- %1 = fptoui double %a to i64 +- ret i64 %1 +-} +- +-define double @convert_u8_to_double(i8 zeroext %a) nounwind { +-; LA32-LABEL: convert_u8_to_double: +-; LA32: # %bb.0: +-; LA32-NEXT: movgr2fr.w $fa0, $a0 +-; LA32-NEXT: ffint.d.w $fa0, $fa0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: convert_u8_to_double: +-; LA64: # %bb.0: +-; LA64-NEXT: movgr2fr.w $fa0, $a0 +-; LA64-NEXT: ffint.d.w $fa0, $fa0 +-; LA64-NEXT: ret +- %1 = uitofp i8 %a to double +- ret double %1 +-} +- +-define double @convert_u16_to_double(i16 zeroext %a) nounwind { +-; LA32-LABEL: convert_u16_to_double: +-; LA32: # %bb.0: +-; LA32-NEXT: movgr2fr.w $fa0, $a0 +-; LA32-NEXT: ffint.d.w $fa0, $fa0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: convert_u16_to_double: +-; LA64: # %bb.0: +-; LA64-NEXT: movgr2fr.w $fa0, $a0 +-; LA64-NEXT: ffint.d.w $fa0, $fa0 +-; LA64-NEXT: ret +- %1 = uitofp i16 %a to double +- ret double %1 +-} +- +-define double @convert_u32_to_double(i32 %a) nounwind { +-; LA32-LABEL: convert_u32_to_double: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: lu12i.w $a1, 275200 +-; LA32-NEXT: st.w $a1, $sp, 12 +-; LA32-NEXT: st.w $a0, $sp, 8 +-; LA32-NEXT: pcalau12i $a0, %pc_hi20(.LCPI12_0) +-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI12_0) +-; LA32-NEXT: fld.d $fa0, $a0, 0 +-; LA32-NEXT: fld.d $fa1, $sp, 8 +-; LA32-NEXT: fsub.d $fa0, $fa1, $fa0 +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: convert_u32_to_double: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 +-; LA64-NEXT: movgr2fr.d $fa0, $a0 +-; LA64-NEXT: ffint.d.l $fa0, $fa0 +-; LA64-NEXT: ret +- %1 = uitofp i32 %a to double +- ret double %1 +-} +- +-define double @convert_u64_to_double(i64 %a) nounwind { +-; LA32-LABEL: convert_u64_to_double: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(__floatundidf) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: convert_u64_to_double: +-; LA64: # %bb.0: +-; LA64-NEXT: srli.d $a1, $a0, 32 +-; LA64-NEXT: lu52i.d $a2, $zero, 1107 +-; LA64-NEXT: or $a1, $a1, $a2 +-; LA64-NEXT: movgr2fr.d $fa0, $a1 +-; LA64-NEXT: pcalau12i $a1, %pc_hi20(.LCPI13_0) +-; LA64-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI13_0) +-; LA64-NEXT: fld.d $fa1, $a1, 0 +-; LA64-NEXT: fsub.d $fa0, $fa0, $fa1 +-; LA64-NEXT: lu12i.w $a1, 275200 +-; LA64-NEXT: bstrins.d $a0, $a1, 63, 32 +-; LA64-NEXT: movgr2fr.d $fa1, $a0 +-; LA64-NEXT: fadd.d $fa0, $fa1, $fa0 +-; LA64-NEXT: ret +- %1 = uitofp i64 %a to double +- ret double %1 +-} +- +-define double @bitcast_i64_to_double(i64 %a, i64 %b) nounwind { +-; LA32-LABEL: bitcast_i64_to_double: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $a1, $sp, 12 +-; LA32-NEXT: st.w $a0, $sp, 8 +-; LA32-NEXT: fld.d $fa0, $sp, 8 +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: bitcast_i64_to_double: +-; LA64: # %bb.0: +-; LA64-NEXT: movgr2fr.d $fa0, $a0 +-; LA64-NEXT: ret +- %1 = bitcast i64 %a to double +- ret double %1 +-} +- +-define i64 @bitcast_double_to_i64(double %a) nounwind { +-; LA32-LABEL: bitcast_double_to_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: fst.d $fa0, $sp, 8 +-; LA32-NEXT: ld.w $a0, $sp, 8 +-; LA32-NEXT: ld.w $a1, $sp, 12 +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: bitcast_double_to_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: movfr2gr.d $a0, $fa0 +-; LA64-NEXT: ret +- %1 = bitcast double %a to i64 +- ret i64 %1 +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/fadd.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/fadd.ll +deleted file mode 100644 +index 0c509297e..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/fadd.ll ++++ /dev/null +@@ -1,33 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64 +- +-;; Exercise the 'fadd' LLVM IR: https://llvm.org/docs/LangRef.html#fadd-instruction +- +-define float @fadd_s(float %x, float %y) { +-; LA32-LABEL: fadd_s: +-; LA32: # %bb.0: +-; LA32-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fadd_s: +-; LA64: # %bb.0: +-; LA64-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA64-NEXT: ret +- %add = fadd float %x, %y +- ret float %add +-} +- +-define double @fadd_d(double %x, double %y) { +-; LA32-LABEL: fadd_d: +-; LA32: # %bb.0: +-; LA32-NEXT: fadd.d $fa0, $fa0, $fa1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fadd_d: +-; LA64: # %bb.0: +-; LA64-NEXT: fadd.d $fa0, $fa0, $fa1 +-; LA64-NEXT: ret +- %add = fadd double %x, %y +- ret double %add +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/fcmp-dbl.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/fcmp-dbl.ll +deleted file mode 100644 +index 3db98d20f..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/fcmp-dbl.ll ++++ /dev/null +@@ -1,367 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64 +- +-;; Test the 'fcmp' LLVM IR: https://llvm.org/docs/LangRef.html#fcmp-instruction +-;; over double values. +- +-define i1 @fcmp_false(double %a, double %b) { +-; LA32-LABEL: fcmp_false: +-; LA32: # %bb.0: +-; LA32-NEXT: move $a0, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_false: +-; LA64: # %bb.0: +-; LA64-NEXT: move $a0, $zero +-; LA64-NEXT: ret +- %cmp = fcmp false double %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_oeq(double %a, double %b) { +-; LA32-LABEL: fcmp_oeq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.ceq.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_oeq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.ceq.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp oeq double %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_ogt(double %a, double %b) { +-; LA32-LABEL: fcmp_ogt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ogt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ogt double %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_oge(double %a, double %b) { +-; LA32-LABEL: fcmp_oge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_oge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp oge double %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_olt(double %a, double %b) { +-; LA32-LABEL: fcmp_olt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_olt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp olt double %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_ole(double %a, double %b) { +-; LA32-LABEL: fcmp_ole: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ole: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ole double %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_one(double %a, double %b) { +-; LA32-LABEL: fcmp_one: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cne.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_one: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cne.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp one double %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_ord(double %a, double %b) { +-; LA32-LABEL: fcmp_ord: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cor.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ord: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cor.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ord double %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_ueq(double %a, double %b) { +-; LA32-LABEL: fcmp_ueq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cueq.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ueq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cueq.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ueq double %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_ugt(double %a, double %b) { +-; LA32-LABEL: fcmp_ugt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ugt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ugt double %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_uge(double %a, double %b) { +-; LA32-LABEL: fcmp_uge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_uge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp uge double %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_ult(double %a, double %b) { +-; LA32-LABEL: fcmp_ult: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ult: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ult double %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_ule(double %a, double %b) { +-; LA32-LABEL: fcmp_ule: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ule: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ule double %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_une(double %a, double %b) { +-; LA32-LABEL: fcmp_une: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cune.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_une: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cune.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp une double %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_uno(double %a, double %b) { +-; LA32-LABEL: fcmp_uno: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cun.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_uno: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cun.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp uno double %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_true(double %a, double %b) { +-; LA32-LABEL: fcmp_true: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a0, $zero, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_true: +-; LA64: # %bb.0: +-; LA64-NEXT: ori $a0, $zero, 1 +-; LA64-NEXT: ret +- %cmp = fcmp true double %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_fast_olt(double %a, double %b, i1 %c) nounwind { +-; LA32-LABEL: fcmp_fast_olt: +-; LA32: # %bb.0: +-; LA32-NEXT: movgr2fr.w $fa1, $zero +-; LA32-NEXT: movgr2frh.w $fa1, $zero +-; LA32-NEXT: fcmp.cle.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a1, $fcc0 +-; LA32-NEXT: bnez $a1, .LBB16_2 +-; LA32-NEXT: # %bb.1: # %if.then +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB16_2: # %if.else +-; LA32-NEXT: fcmp.clt.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_fast_olt: +-; LA64: # %bb.0: +-; LA64-NEXT: movgr2fr.d $fa1, $zero +-; LA64-NEXT: fcmp.cle.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a1, $fcc0 +-; LA64-NEXT: bnez $a1, .LBB16_2 +-; LA64-NEXT: # %bb.1: # %if.then +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB16_2: # %if.else +-; LA64-NEXT: fcmp.clt.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp fast olt double %a, 0.000000e+00 +- br i1 %cmp, label %if.then, label %if.else +- +-if.then: +- ret i1 %c +- +-if.else: +- ret i1 %cmp +-} +- +-define i1 @fcmp_fast_oeq(double %a, double %b, i1 %c) nounwind { +-; LA32-LABEL: fcmp_fast_oeq: +-; LA32: # %bb.0: +-; LA32-NEXT: movgr2fr.w $fa1, $zero +-; LA32-NEXT: movgr2frh.w $fa1, $zero +-; LA32-NEXT: fcmp.ceq.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a1, $fcc0 +-; LA32-NEXT: xori $a1, $a1, 1 +-; LA32-NEXT: bnez $a1, .LBB17_2 +-; LA32-NEXT: # %bb.1: # %if.then +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB17_2: # %if.else +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_fast_oeq: +-; LA64: # %bb.0: +-; LA64-NEXT: movgr2fr.d $fa1, $zero +-; LA64-NEXT: fcmp.ceq.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a1, $fcc0 +-; LA64-NEXT: xori $a1, $a1, 1 +-; LA64-NEXT: bnez $a1, .LBB17_2 +-; LA64-NEXT: # %bb.1: # %if.then +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB17_2: # %if.else +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp fast oeq double %a, 0.000000e+00 +- br i1 %cmp, label %if.then, label %if.else +- +-if.then: +- ret i1 %c +- +-if.else: +- ret i1 %cmp +-} +- +-define i1 @fcmp_fast_ole(double %a, double %b, i1 %c) nounwind { +-; LA32-LABEL: fcmp_fast_ole: +-; LA32: # %bb.0: +-; LA32-NEXT: movgr2fr.w $fa1, $zero +-; LA32-NEXT: movgr2frh.w $fa1, $zero +-; LA32-NEXT: fcmp.clt.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: bcnez $fcc0, .LBB18_2 +-; LA32-NEXT: # %bb.1: # %if.then +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB18_2: # %if.else +-; LA32-NEXT: fcmp.cle.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_fast_ole: +-; LA64: # %bb.0: +-; LA64-NEXT: movgr2fr.d $fa1, $zero +-; LA64-NEXT: fcmp.clt.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: bcnez $fcc0, .LBB18_2 +-; LA64-NEXT: # %bb.1: # %if.then +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB18_2: # %if.else +-; LA64-NEXT: fcmp.cle.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp fast ole double %a, 0.000000e+00 +- br i1 %cmp, label %if.then, label %if.else +- +-if.then: +- ret i1 %c +- +-if.else: +- ret i1 %cmp +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/fcmp-flt.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/fcmp-flt.ll +deleted file mode 100644 +index d0f8d5342..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/fcmp-flt.ll ++++ /dev/null +@@ -1,364 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA64 +- +-;; Test the 'fcmp' LLVM IR: https://llvm.org/docs/LangRef.html#fcmp-instruction +-;; over float values. +- +-define i1 @fcmp_false(float %a, float %b) { +-; LA32-LABEL: fcmp_false: +-; LA32: # %bb.0: +-; LA32-NEXT: move $a0, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_false: +-; LA64: # %bb.0: +-; LA64-NEXT: move $a0, $zero +-; LA64-NEXT: ret +- %cmp = fcmp false float %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_oeq(float %a, float %b) { +-; LA32-LABEL: fcmp_oeq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.ceq.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_oeq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.ceq.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp oeq float %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_ogt(float %a, float %b) { +-; LA32-LABEL: fcmp_ogt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ogt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ogt float %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_oge(float %a, float %b) { +-; LA32-LABEL: fcmp_oge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_oge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp oge float %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_olt(float %a, float %b) { +-; LA32-LABEL: fcmp_olt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_olt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp olt float %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_ole(float %a, float %b) { +-; LA32-LABEL: fcmp_ole: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ole: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ole float %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_one(float %a, float %b) { +-; LA32-LABEL: fcmp_one: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cne.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_one: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cne.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp one float %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_ord(float %a, float %b) { +-; LA32-LABEL: fcmp_ord: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cor.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ord: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cor.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ord float %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_ueq(float %a, float %b) { +-; LA32-LABEL: fcmp_ueq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cueq.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ueq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cueq.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ueq float %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_ugt(float %a, float %b) { +-; LA32-LABEL: fcmp_ugt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ugt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ugt float %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_uge(float %a, float %b) { +-; LA32-LABEL: fcmp_uge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_uge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp uge float %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_ult(float %a, float %b) { +-; LA32-LABEL: fcmp_ult: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ult: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ult float %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_ule(float %a, float %b) { +-; LA32-LABEL: fcmp_ule: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ule: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ule float %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_une(float %a, float %b) { +-; LA32-LABEL: fcmp_une: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cune.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_une: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cune.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp une float %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_uno(float %a, float %b) { +-; LA32-LABEL: fcmp_uno: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cun.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_uno: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cun.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp uno float %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_true(float %a, float %b) { +-; LA32-LABEL: fcmp_true: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a0, $zero, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_true: +-; LA64: # %bb.0: +-; LA64-NEXT: ori $a0, $zero, 1 +-; LA64-NEXT: ret +- %cmp = fcmp true float %a, %b +- ret i1 %cmp +-} +- +-define i1 @fcmp_fast_olt(float %a, float %b, i1 %c) nounwind { +-; LA32-LABEL: fcmp_fast_olt: +-; LA32: # %bb.0: +-; LA32-NEXT: movgr2fr.w $fa1, $zero +-; LA32-NEXT: fcmp.cle.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a1, $fcc0 +-; LA32-NEXT: bnez $a1, .LBB16_2 +-; LA32-NEXT: # %bb.1: # %if.then +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB16_2: # %if.else +-; LA32-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_fast_olt: +-; LA64: # %bb.0: +-; LA64-NEXT: movgr2fr.w $fa1, $zero +-; LA64-NEXT: fcmp.cle.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a1, $fcc0 +-; LA64-NEXT: bnez $a1, .LBB16_2 +-; LA64-NEXT: # %bb.1: # %if.then +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB16_2: # %if.else +-; LA64-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp fast olt float %a, 0.000000e+00 +- br i1 %cmp, label %if.then, label %if.else +- +-if.then: +- ret i1 %c +- +-if.else: +- ret i1 %cmp +-} +- +-define i1 @fcmp_fast_oeq(float %a, float %b, i1 %c) nounwind { +-; LA32-LABEL: fcmp_fast_oeq: +-; LA32: # %bb.0: +-; LA32-NEXT: movgr2fr.w $fa1, $zero +-; LA32-NEXT: fcmp.ceq.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a1, $fcc0 +-; LA32-NEXT: xori $a1, $a1, 1 +-; LA32-NEXT: bnez $a1, .LBB17_2 +-; LA32-NEXT: # %bb.1: # %if.then +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB17_2: # %if.else +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_fast_oeq: +-; LA64: # %bb.0: +-; LA64-NEXT: movgr2fr.w $fa1, $zero +-; LA64-NEXT: fcmp.ceq.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a1, $fcc0 +-; LA64-NEXT: xori $a1, $a1, 1 +-; LA64-NEXT: bnez $a1, .LBB17_2 +-; LA64-NEXT: # %bb.1: # %if.then +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB17_2: # %if.else +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp fast oeq float %a, 0.000000e+00 +- br i1 %cmp, label %if.then, label %if.else +- +-if.then: +- ret i1 %c +- +-if.else: +- ret i1 %cmp +-} +- +-define i1 @fcmp_fast_ole(float %a, float %b, i1 %c) nounwind { +-; LA32-LABEL: fcmp_fast_ole: +-; LA32: # %bb.0: +-; LA32-NEXT: movgr2fr.w $fa1, $zero +-; LA32-NEXT: fcmp.clt.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: bcnez $fcc0, .LBB18_2 +-; LA32-NEXT: # %bb.1: # %if.then +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB18_2: # %if.else +-; LA32-NEXT: fcmp.cle.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_fast_ole: +-; LA64: # %bb.0: +-; LA64-NEXT: movgr2fr.w $fa1, $zero +-; LA64-NEXT: fcmp.clt.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: bcnez $fcc0, .LBB18_2 +-; LA64-NEXT: # %bb.1: # %if.then +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB18_2: # %if.else +-; LA64-NEXT: fcmp.cle.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp fast ole float %a, 0.000000e+00 +- br i1 %cmp, label %if.then, label %if.else +- +-if.then: +- ret i1 %c +- +-if.else: +- ret i1 %cmp +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/fdiv.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/fdiv.ll +deleted file mode 100644 +index e3154122c..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/fdiv.ll ++++ /dev/null +@@ -1,33 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64 +- +-;; Exercise the 'fdiv' LLVM IR: https://llvm.org/docs/LangRef.html#fdiv-instruction +- +-define float @fdiv_s(float %x, float %y) { +-; LA32-LABEL: fdiv_s: +-; LA32: # %bb.0: +-; LA32-NEXT: fdiv.s $fa0, $fa0, $fa1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fdiv_s: +-; LA64: # %bb.0: +-; LA64-NEXT: fdiv.s $fa0, $fa0, $fa1 +-; LA64-NEXT: ret +- %div = fdiv float %x, %y +- ret float %div +-} +- +-define double @fdiv_d(double %x, double %y) { +-; LA32-LABEL: fdiv_d: +-; LA32: # %bb.0: +-; LA32-NEXT: fdiv.d $fa0, $fa0, $fa1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fdiv_d: +-; LA64: # %bb.0: +-; LA64-NEXT: fdiv.d $fa0, $fa0, $fa1 +-; LA64-NEXT: ret +- %div = fdiv double %x, %y +- ret double %div +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/fence-singlethread.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/fence-singlethread.ll +deleted file mode 100644 +index a8b164a4c..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/fence-singlethread.ll ++++ /dev/null +@@ -1,17 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-define void @fence_singlethread() { +-; LA32-LABEL: fence_singlethread: +-; LA32: # %bb.0: +-; LA32-NEXT: #MEMBARRIER +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fence_singlethread: +-; LA64: # %bb.0: +-; LA64-NEXT: #MEMBARRIER +-; LA64-NEXT: ret +- fence syncscope("singlethread") seq_cst +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/float-convert.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/float-convert.ll +deleted file mode 100644 +index b57d96aee..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/float-convert.ll ++++ /dev/null +@@ -1,628 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA32F +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32D +-; RUN: llc --mtriple=loongarch64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA64F +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64D +- +-define signext i8 @convert_float_to_i8(float %a) nounwind { +-; LA32F-LABEL: convert_float_to_i8: +-; LA32F: # %bb.0: +-; LA32F-NEXT: ftintrz.w.s $fa0, $fa0 +-; LA32F-NEXT: movfr2gr.s $a0, $fa0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: convert_float_to_i8: +-; LA32D: # %bb.0: +-; LA32D-NEXT: ftintrz.w.s $fa0, $fa0 +-; LA32D-NEXT: movfr2gr.s $a0, $fa0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: convert_float_to_i8: +-; LA64F: # %bb.0: +-; LA64F-NEXT: ftintrz.w.s $fa0, $fa0 +-; LA64F-NEXT: movfr2gr.s $a0, $fa0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: convert_float_to_i8: +-; LA64D: # %bb.0: +-; LA64D-NEXT: ftintrz.l.s $fa0, $fa0 +-; LA64D-NEXT: movfr2gr.d $a0, $fa0 +-; LA64D-NEXT: ret +- %1 = fptosi float %a to i8 +- ret i8 %1 +-} +- +-define signext i16 @convert_float_to_i16(float %a) nounwind { +-; LA32F-LABEL: convert_float_to_i16: +-; LA32F: # %bb.0: +-; LA32F-NEXT: ftintrz.w.s $fa0, $fa0 +-; LA32F-NEXT: movfr2gr.s $a0, $fa0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: convert_float_to_i16: +-; LA32D: # %bb.0: +-; LA32D-NEXT: ftintrz.w.s $fa0, $fa0 +-; LA32D-NEXT: movfr2gr.s $a0, $fa0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: convert_float_to_i16: +-; LA64F: # %bb.0: +-; LA64F-NEXT: ftintrz.w.s $fa0, $fa0 +-; LA64F-NEXT: movfr2gr.s $a0, $fa0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: convert_float_to_i16: +-; LA64D: # %bb.0: +-; LA64D-NEXT: ftintrz.l.s $fa0, $fa0 +-; LA64D-NEXT: movfr2gr.d $a0, $fa0 +-; LA64D-NEXT: ret +- %1 = fptosi float %a to i16 +- ret i16 %1 +-} +- +-define i32 @convert_float_to_i32(float %a) nounwind { +-; LA32F-LABEL: convert_float_to_i32: +-; LA32F: # %bb.0: +-; LA32F-NEXT: ftintrz.w.s $fa0, $fa0 +-; LA32F-NEXT: movfr2gr.s $a0, $fa0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: convert_float_to_i32: +-; LA32D: # %bb.0: +-; LA32D-NEXT: ftintrz.w.s $fa0, $fa0 +-; LA32D-NEXT: movfr2gr.s $a0, $fa0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: convert_float_to_i32: +-; LA64F: # %bb.0: +-; LA64F-NEXT: ftintrz.w.s $fa0, $fa0 +-; LA64F-NEXT: movfr2gr.s $a0, $fa0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: convert_float_to_i32: +-; LA64D: # %bb.0: +-; LA64D-NEXT: ftintrz.w.s $fa0, $fa0 +-; LA64D-NEXT: movfr2gr.s $a0, $fa0 +-; LA64D-NEXT: ret +- %1 = fptosi float %a to i32 +- ret i32 %1 +-} +- +-define i64 @convert_float_to_i64(float %a) nounwind { +-; LA32F-LABEL: convert_float_to_i64: +-; LA32F: # %bb.0: +-; LA32F-NEXT: addi.w $sp, $sp, -16 +-; LA32F-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32F-NEXT: bl %plt(__fixsfdi) +-; LA32F-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32F-NEXT: addi.w $sp, $sp, 16 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: convert_float_to_i64: +-; LA32D: # %bb.0: +-; LA32D-NEXT: addi.w $sp, $sp, -16 +-; LA32D-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32D-NEXT: bl %plt(__fixsfdi) +-; LA32D-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32D-NEXT: addi.w $sp, $sp, 16 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: convert_float_to_i64: +-; LA64F: # %bb.0: +-; LA64F-NEXT: ftintrz.w.s $fa0, $fa0 +-; LA64F-NEXT: movfr2gr.s $a0, $fa0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: convert_float_to_i64: +-; LA64D: # %bb.0: +-; LA64D-NEXT: ftintrz.l.s $fa0, $fa0 +-; LA64D-NEXT: movfr2gr.d $a0, $fa0 +-; LA64D-NEXT: ret +- %1 = fptosi float %a to i64 +- ret i64 %1 +-} +- +-define zeroext i8 @convert_float_to_u8(float %a) nounwind { +-; LA32F-LABEL: convert_float_to_u8: +-; LA32F: # %bb.0: +-; LA32F-NEXT: ftintrz.w.s $fa0, $fa0 +-; LA32F-NEXT: movfr2gr.s $a0, $fa0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: convert_float_to_u8: +-; LA32D: # %bb.0: +-; LA32D-NEXT: ftintrz.w.s $fa0, $fa0 +-; LA32D-NEXT: movfr2gr.s $a0, $fa0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: convert_float_to_u8: +-; LA64F: # %bb.0: +-; LA64F-NEXT: ftintrz.w.s $fa0, $fa0 +-; LA64F-NEXT: movfr2gr.s $a0, $fa0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: convert_float_to_u8: +-; LA64D: # %bb.0: +-; LA64D-NEXT: ftintrz.l.s $fa0, $fa0 +-; LA64D-NEXT: movfr2gr.d $a0, $fa0 +-; LA64D-NEXT: ret +- %1 = fptoui float %a to i8 +- ret i8 %1 +-} +- +-define zeroext i16 @convert_float_to_u16(float %a) nounwind { +-; LA32F-LABEL: convert_float_to_u16: +-; LA32F: # %bb.0: +-; LA32F-NEXT: ftintrz.w.s $fa0, $fa0 +-; LA32F-NEXT: movfr2gr.s $a0, $fa0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: convert_float_to_u16: +-; LA32D: # %bb.0: +-; LA32D-NEXT: ftintrz.w.s $fa0, $fa0 +-; LA32D-NEXT: movfr2gr.s $a0, $fa0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: convert_float_to_u16: +-; LA64F: # %bb.0: +-; LA64F-NEXT: ftintrz.w.s $fa0, $fa0 +-; LA64F-NEXT: movfr2gr.s $a0, $fa0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: convert_float_to_u16: +-; LA64D: # %bb.0: +-; LA64D-NEXT: ftintrz.l.s $fa0, $fa0 +-; LA64D-NEXT: movfr2gr.d $a0, $fa0 +-; LA64D-NEXT: ret +- %1 = fptoui float %a to i16 +- ret i16 %1 +-} +- +-define i32 @convert_float_to_u32(float %a) nounwind { +-; LA32F-LABEL: convert_float_to_u32: +-; LA32F: # %bb.0: +-; LA32F-NEXT: pcalau12i $a0, %pc_hi20(.LCPI6_0) +-; LA32F-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI6_0) +-; LA32F-NEXT: fld.s $fa1, $a0, 0 +-; LA32F-NEXT: fsub.s $fa2, $fa0, $fa1 +-; LA32F-NEXT: ftintrz.w.s $fa2, $fa2 +-; LA32F-NEXT: movfr2gr.s $a0, $fa2 +-; LA32F-NEXT: lu12i.w $a1, -524288 +-; LA32F-NEXT: xor $a0, $a0, $a1 +-; LA32F-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1 +-; LA32F-NEXT: movcf2gr $a1, $fcc0 +-; LA32F-NEXT: masknez $a0, $a0, $a1 +-; LA32F-NEXT: ftintrz.w.s $fa0, $fa0 +-; LA32F-NEXT: movfr2gr.s $a2, $fa0 +-; LA32F-NEXT: maskeqz $a1, $a2, $a1 +-; LA32F-NEXT: or $a0, $a1, $a0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: convert_float_to_u32: +-; LA32D: # %bb.0: +-; LA32D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI6_0) +-; LA32D-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI6_0) +-; LA32D-NEXT: fld.s $fa1, $a0, 0 +-; LA32D-NEXT: fsub.s $fa2, $fa0, $fa1 +-; LA32D-NEXT: ftintrz.w.s $fa2, $fa2 +-; LA32D-NEXT: movfr2gr.s $a0, $fa2 +-; LA32D-NEXT: lu12i.w $a1, -524288 +-; LA32D-NEXT: xor $a0, $a0, $a1 +-; LA32D-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1 +-; LA32D-NEXT: movcf2gr $a1, $fcc0 +-; LA32D-NEXT: masknez $a0, $a0, $a1 +-; LA32D-NEXT: ftintrz.w.s $fa0, $fa0 +-; LA32D-NEXT: movfr2gr.s $a2, $fa0 +-; LA32D-NEXT: maskeqz $a1, $a2, $a1 +-; LA32D-NEXT: or $a0, $a1, $a0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: convert_float_to_u32: +-; LA64F: # %bb.0: +-; LA64F-NEXT: pcalau12i $a0, %pc_hi20(.LCPI6_0) +-; LA64F-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI6_0) +-; LA64F-NEXT: fld.s $fa1, $a0, 0 +-; LA64F-NEXT: fsub.s $fa2, $fa0, $fa1 +-; LA64F-NEXT: ftintrz.w.s $fa2, $fa2 +-; LA64F-NEXT: movfr2gr.s $a0, $fa2 +-; LA64F-NEXT: lu12i.w $a1, -524288 +-; LA64F-NEXT: xor $a0, $a0, $a1 +-; LA64F-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1 +-; LA64F-NEXT: movcf2gr $a1, $fcc0 +-; LA64F-NEXT: masknez $a0, $a0, $a1 +-; LA64F-NEXT: ftintrz.w.s $fa0, $fa0 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: maskeqz $a1, $a2, $a1 +-; LA64F-NEXT: or $a0, $a1, $a0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: convert_float_to_u32: +-; LA64D: # %bb.0: +-; LA64D-NEXT: ftintrz.l.s $fa0, $fa0 +-; LA64D-NEXT: movfr2gr.d $a0, $fa0 +-; LA64D-NEXT: ret +- %1 = fptoui float %a to i32 +- ret i32 %1 +-} +- +-define i64 @convert_float_to_u64(float %a) nounwind { +-; LA32F-LABEL: convert_float_to_u64: +-; LA32F: # %bb.0: +-; LA32F-NEXT: addi.w $sp, $sp, -16 +-; LA32F-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32F-NEXT: bl %plt(__fixunssfdi) +-; LA32F-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32F-NEXT: addi.w $sp, $sp, 16 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: convert_float_to_u64: +-; LA32D: # %bb.0: +-; LA32D-NEXT: addi.w $sp, $sp, -16 +-; LA32D-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32D-NEXT: bl %plt(__fixunssfdi) +-; LA32D-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32D-NEXT: addi.w $sp, $sp, 16 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: convert_float_to_u64: +-; LA64F: # %bb.0: +-; LA64F-NEXT: pcalau12i $a0, %pc_hi20(.LCPI7_0) +-; LA64F-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI7_0) +-; LA64F-NEXT: fld.s $fa1, $a0, 0 +-; LA64F-NEXT: fsub.s $fa2, $fa0, $fa1 +-; LA64F-NEXT: ftintrz.w.s $fa2, $fa2 +-; LA64F-NEXT: movfr2gr.s $a0, $fa2 +-; LA64F-NEXT: lu52i.d $a1, $zero, -2048 +-; LA64F-NEXT: xor $a0, $a0, $a1 +-; LA64F-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1 +-; LA64F-NEXT: movcf2gr $a1, $fcc0 +-; LA64F-NEXT: masknez $a0, $a0, $a1 +-; LA64F-NEXT: ftintrz.w.s $fa0, $fa0 +-; LA64F-NEXT: movfr2gr.s $a2, $fa0 +-; LA64F-NEXT: maskeqz $a1, $a2, $a1 +-; LA64F-NEXT: or $a0, $a1, $a0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: convert_float_to_u64: +-; LA64D: # %bb.0: +-; LA64D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI7_0) +-; LA64D-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI7_0) +-; LA64D-NEXT: fld.s $fa1, $a0, 0 +-; LA64D-NEXT: fsub.s $fa2, $fa0, $fa1 +-; LA64D-NEXT: ftintrz.l.s $fa2, $fa2 +-; LA64D-NEXT: movfr2gr.d $a0, $fa2 +-; LA64D-NEXT: lu52i.d $a1, $zero, -2048 +-; LA64D-NEXT: xor $a0, $a0, $a1 +-; LA64D-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1 +-; LA64D-NEXT: movcf2gr $a1, $fcc0 +-; LA64D-NEXT: masknez $a0, $a0, $a1 +-; LA64D-NEXT: ftintrz.l.s $fa0, $fa0 +-; LA64D-NEXT: movfr2gr.d $a2, $fa0 +-; LA64D-NEXT: maskeqz $a1, $a2, $a1 +-; LA64D-NEXT: or $a0, $a1, $a0 +-; LA64D-NEXT: ret +- %1 = fptoui float %a to i64 +- ret i64 %1 +-} +- +-define float @convert_i8_to_float(i8 signext %a) nounwind { +-; LA32F-LABEL: convert_i8_to_float: +-; LA32F: # %bb.0: +-; LA32F-NEXT: movgr2fr.w $fa0, $a0 +-; LA32F-NEXT: ffint.s.w $fa0, $fa0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: convert_i8_to_float: +-; LA32D: # %bb.0: +-; LA32D-NEXT: movgr2fr.w $fa0, $a0 +-; LA32D-NEXT: ffint.s.w $fa0, $fa0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: convert_i8_to_float: +-; LA64F: # %bb.0: +-; LA64F-NEXT: movgr2fr.w $fa0, $a0 +-; LA64F-NEXT: ffint.s.w $fa0, $fa0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: convert_i8_to_float: +-; LA64D: # %bb.0: +-; LA64D-NEXT: movgr2fr.w $fa0, $a0 +-; LA64D-NEXT: ffint.s.w $fa0, $fa0 +-; LA64D-NEXT: ret +- %1 = sitofp i8 %a to float +- ret float %1 +-} +- +-define float @convert_i16_to_float(i16 signext %a) nounwind { +-; LA32F-LABEL: convert_i16_to_float: +-; LA32F: # %bb.0: +-; LA32F-NEXT: movgr2fr.w $fa0, $a0 +-; LA32F-NEXT: ffint.s.w $fa0, $fa0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: convert_i16_to_float: +-; LA32D: # %bb.0: +-; LA32D-NEXT: movgr2fr.w $fa0, $a0 +-; LA32D-NEXT: ffint.s.w $fa0, $fa0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: convert_i16_to_float: +-; LA64F: # %bb.0: +-; LA64F-NEXT: movgr2fr.w $fa0, $a0 +-; LA64F-NEXT: ffint.s.w $fa0, $fa0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: convert_i16_to_float: +-; LA64D: # %bb.0: +-; LA64D-NEXT: movgr2fr.w $fa0, $a0 +-; LA64D-NEXT: ffint.s.w $fa0, $fa0 +-; LA64D-NEXT: ret +- %1 = sitofp i16 %a to float +- ret float %1 +-} +- +-define float @convert_i32_to_float(i32 %a) nounwind { +-; LA32F-LABEL: convert_i32_to_float: +-; LA32F: # %bb.0: +-; LA32F-NEXT: movgr2fr.w $fa0, $a0 +-; LA32F-NEXT: ffint.s.w $fa0, $fa0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: convert_i32_to_float: +-; LA32D: # %bb.0: +-; LA32D-NEXT: movgr2fr.w $fa0, $a0 +-; LA32D-NEXT: ffint.s.w $fa0, $fa0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: convert_i32_to_float: +-; LA64F: # %bb.0: +-; LA64F-NEXT: movgr2fr.w $fa0, $a0 +-; LA64F-NEXT: ffint.s.w $fa0, $fa0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: convert_i32_to_float: +-; LA64D: # %bb.0: +-; LA64D-NEXT: movgr2fr.w $fa0, $a0 +-; LA64D-NEXT: ffint.s.w $fa0, $fa0 +-; LA64D-NEXT: ret +- %1 = sitofp i32 %a to float +- ret float %1 +-} +- +-define float @convert_i64_to_float(i64 %a) nounwind { +-; LA32F-LABEL: convert_i64_to_float: +-; LA32F: # %bb.0: +-; LA32F-NEXT: addi.w $sp, $sp, -16 +-; LA32F-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32F-NEXT: bl %plt(__floatdisf) +-; LA32F-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32F-NEXT: addi.w $sp, $sp, 16 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: convert_i64_to_float: +-; LA32D: # %bb.0: +-; LA32D-NEXT: addi.w $sp, $sp, -16 +-; LA32D-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32D-NEXT: bl %plt(__floatdisf) +-; LA32D-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32D-NEXT: addi.w $sp, $sp, 16 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: convert_i64_to_float: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -16 +-; LA64F-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64F-NEXT: bl %plt(__floatdisf) +-; LA64F-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 16 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: convert_i64_to_float: +-; LA64D: # %bb.0: +-; LA64D-NEXT: movgr2fr.d $fa0, $a0 +-; LA64D-NEXT: ffint.s.l $fa0, $fa0 +-; LA64D-NEXT: ret +- %1 = sitofp i64 %a to float +- ret float %1 +-} +- +-define float @convert_u8_to_float(i8 zeroext %a) nounwind { +-; LA32F-LABEL: convert_u8_to_float: +-; LA32F: # %bb.0: +-; LA32F-NEXT: movgr2fr.w $fa0, $a0 +-; LA32F-NEXT: ffint.s.w $fa0, $fa0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: convert_u8_to_float: +-; LA32D: # %bb.0: +-; LA32D-NEXT: movgr2fr.w $fa0, $a0 +-; LA32D-NEXT: ffint.s.w $fa0, $fa0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: convert_u8_to_float: +-; LA64F: # %bb.0: +-; LA64F-NEXT: movgr2fr.w $fa0, $a0 +-; LA64F-NEXT: ffint.s.w $fa0, $fa0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: convert_u8_to_float: +-; LA64D: # %bb.0: +-; LA64D-NEXT: movgr2fr.w $fa0, $a0 +-; LA64D-NEXT: ffint.s.w $fa0, $fa0 +-; LA64D-NEXT: ret +- %1 = uitofp i8 %a to float +- ret float %1 +-} +- +-define float @convert_u16_to_float(i16 zeroext %a) nounwind { +-; LA32F-LABEL: convert_u16_to_float: +-; LA32F: # %bb.0: +-; LA32F-NEXT: movgr2fr.w $fa0, $a0 +-; LA32F-NEXT: ffint.s.w $fa0, $fa0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: convert_u16_to_float: +-; LA32D: # %bb.0: +-; LA32D-NEXT: movgr2fr.w $fa0, $a0 +-; LA32D-NEXT: ffint.s.w $fa0, $fa0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: convert_u16_to_float: +-; LA64F: # %bb.0: +-; LA64F-NEXT: movgr2fr.w $fa0, $a0 +-; LA64F-NEXT: ffint.s.w $fa0, $fa0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: convert_u16_to_float: +-; LA64D: # %bb.0: +-; LA64D-NEXT: movgr2fr.w $fa0, $a0 +-; LA64D-NEXT: ffint.s.w $fa0, $fa0 +-; LA64D-NEXT: ret +- %1 = uitofp i16 %a to float +- ret float %1 +-} +- +-define float @convert_u32_to_float(i32 %a) nounwind { +-; LA32F-LABEL: convert_u32_to_float: +-; LA32F: # %bb.0: +-; LA32F-NEXT: srli.w $a1, $a0, 1 +-; LA32F-NEXT: andi $a2, $a0, 1 +-; LA32F-NEXT: or $a1, $a2, $a1 +-; LA32F-NEXT: movgr2fr.w $fa0, $a1 +-; LA32F-NEXT: ffint.s.w $fa0, $fa0 +-; LA32F-NEXT: fadd.s $fa0, $fa0, $fa0 +-; LA32F-NEXT: slti $a1, $a0, 0 +-; LA32F-NEXT: movgr2fr.w $fa1, $a0 +-; LA32F-NEXT: ffint.s.w $fa1, $fa1 +-; LA32F-NEXT: movgr2cf $fcc0, $a1 +-; LA32F-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: convert_u32_to_float: +-; LA32D: # %bb.0: +-; LA32D-NEXT: addi.w $sp, $sp, -16 +-; LA32D-NEXT: lu12i.w $a1, 275200 +-; LA32D-NEXT: st.w $a1, $sp, 12 +-; LA32D-NEXT: st.w $a0, $sp, 8 +-; LA32D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI14_0) +-; LA32D-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI14_0) +-; LA32D-NEXT: fld.d $fa0, $a0, 0 +-; LA32D-NEXT: fld.d $fa1, $sp, 8 +-; LA32D-NEXT: fsub.d $fa0, $fa1, $fa0 +-; LA32D-NEXT: fcvt.s.d $fa0, $fa0 +-; LA32D-NEXT: addi.w $sp, $sp, 16 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: convert_u32_to_float: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -16 +-; LA64F-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64F-NEXT: bstrpick.d $a0, $a0, 31, 0 +-; LA64F-NEXT: bl %plt(__floatundisf) +-; LA64F-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 16 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: convert_u32_to_float: +-; LA64D: # %bb.0: +-; LA64D-NEXT: bstrpick.d $a0, $a0, 31, 0 +-; LA64D-NEXT: movgr2fr.d $fa0, $a0 +-; LA64D-NEXT: ffint.s.l $fa0, $fa0 +-; LA64D-NEXT: ret +- %1 = uitofp i32 %a to float +- ret float %1 +-} +- +-define float @convert_u64_to_float(i64 %a) nounwind { +-; LA32F-LABEL: convert_u64_to_float: +-; LA32F: # %bb.0: +-; LA32F-NEXT: addi.w $sp, $sp, -16 +-; LA32F-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32F-NEXT: bl %plt(__floatundisf) +-; LA32F-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32F-NEXT: addi.w $sp, $sp, 16 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: convert_u64_to_float: +-; LA32D: # %bb.0: +-; LA32D-NEXT: addi.w $sp, $sp, -16 +-; LA32D-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32D-NEXT: bl %plt(__floatundisf) +-; LA32D-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32D-NEXT: addi.w $sp, $sp, 16 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: convert_u64_to_float: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -16 +-; LA64F-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64F-NEXT: bl %plt(__floatundisf) +-; LA64F-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 16 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: convert_u64_to_float: +-; LA64D: # %bb.0: +-; LA64D-NEXT: srli.d $a1, $a0, 1 +-; LA64D-NEXT: andi $a2, $a0, 1 +-; LA64D-NEXT: or $a1, $a2, $a1 +-; LA64D-NEXT: movgr2fr.d $fa0, $a1 +-; LA64D-NEXT: ffint.s.l $fa0, $fa0 +-; LA64D-NEXT: fadd.s $fa0, $fa0, $fa0 +-; LA64D-NEXT: slti $a1, $a0, 0 +-; LA64D-NEXT: movgr2fr.d $fa1, $a0 +-; LA64D-NEXT: ffint.s.l $fa1, $fa1 +-; LA64D-NEXT: movgr2cf $fcc0, $a1 +-; LA64D-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64D-NEXT: ret +- %1 = uitofp i64 %a to float +- ret float %1 +-} +- +-define i32 @bitcast_float_to_i32(float %a) nounwind { +-; LA32F-LABEL: bitcast_float_to_i32: +-; LA32F: # %bb.0: +-; LA32F-NEXT: movfr2gr.s $a0, $fa0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: bitcast_float_to_i32: +-; LA32D: # %bb.0: +-; LA32D-NEXT: movfr2gr.s $a0, $fa0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: bitcast_float_to_i32: +-; LA64F: # %bb.0: +-; LA64F-NEXT: movfr2gr.s $a0, $fa0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: bitcast_float_to_i32: +-; LA64D: # %bb.0: +-; LA64D-NEXT: movfr2gr.s $a0, $fa0 +-; LA64D-NEXT: ret +- %1 = bitcast float %a to i32 +- ret i32 %1 +-} +- +-define float @bitcast_i32_to_float(i32 %a) nounwind { +-; LA32F-LABEL: bitcast_i32_to_float: +-; LA32F: # %bb.0: +-; LA32F-NEXT: movgr2fr.w $fa0, $a0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: bitcast_i32_to_float: +-; LA32D: # %bb.0: +-; LA32D-NEXT: movgr2fr.w $fa0, $a0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: bitcast_i32_to_float: +-; LA64F: # %bb.0: +-; LA64F-NEXT: movgr2fr.w $fa0, $a0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: bitcast_i32_to_float: +-; LA64D: # %bb.0: +-; LA64D-NEXT: movgr2fr.w $fa0, $a0 +-; LA64D-NEXT: ret +- %1 = bitcast i32 %a to float +- ret float %1 +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/fmul.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/fmul.ll +deleted file mode 100644 +index d3acb566c..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/fmul.ll ++++ /dev/null +@@ -1,33 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64 +- +-;; Exercise the 'fmul' LLVM IR: https://llvm.org/docs/LangRef.html#fmul-instruction +- +-define float @fmul_s(float %x, float %y) { +-; LA32-LABEL: fmul_s: +-; LA32: # %bb.0: +-; LA32-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fmul_s: +-; LA64: # %bb.0: +-; LA64-NEXT: fmul.s $fa0, $fa0, $fa1 +-; LA64-NEXT: ret +- %mul = fmul float %x, %y +- ret float %mul +-} +- +-define double @fmul_d(double %x, double %y) { +-; LA32-LABEL: fmul_d: +-; LA32: # %bb.0: +-; LA32-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fmul_d: +-; LA64: # %bb.0: +-; LA64-NEXT: fmul.d $fa0, $fa0, $fa1 +-; LA64-NEXT: ret +- %mul = fmul double %x, %y +- ret double %mul +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/fneg.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/fneg.ll +deleted file mode 100644 +index da1952654..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/fneg.ll ++++ /dev/null +@@ -1,33 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64 +- +-;; Exercise the 'fneg' LLVM IR: https://llvm.org/docs/LangRef.html#fneg-instruction +- +-define float @fneg_s(float %x) { +-; LA32-LABEL: fneg_s: +-; LA32: # %bb.0: +-; LA32-NEXT: fneg.s $fa0, $fa0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fneg_s: +-; LA64: # %bb.0: +-; LA64-NEXT: fneg.s $fa0, $fa0 +-; LA64-NEXT: ret +- %neg = fneg float %x +- ret float %neg +-} +- +-define double @fneg_d(double %x) { +-; LA32-LABEL: fneg_d: +-; LA32: # %bb.0: +-; LA32-NEXT: fneg.d $fa0, $fa0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fneg_d: +-; LA64: # %bb.0: +-; LA64-NEXT: fneg.d $fa0, $fa0 +-; LA64-NEXT: ret +- %neg = fneg double %x +- ret double %neg +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/fsub.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/fsub.ll +deleted file mode 100644 +index 0aa0d634f..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/fsub.ll ++++ /dev/null +@@ -1,61 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64 +- +-;; Exercise the 'fsub' LLVM IR: https://llvm.org/docs/LangRef.html#fsub-instruction +- +-define float @fsub_s(float %x, float %y) { +-; LA32-LABEL: fsub_s: +-; LA32: # %bb.0: +-; LA32-NEXT: fsub.s $fa0, $fa0, $fa1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fsub_s: +-; LA64: # %bb.0: +-; LA64-NEXT: fsub.s $fa0, $fa0, $fa1 +-; LA64-NEXT: ret +- %sub = fsub float %x, %y +- ret float %sub +-} +- +-define double @fsub_d(double %x, double %y) { +-; LA32-LABEL: fsub_d: +-; LA32: # %bb.0: +-; LA32-NEXT: fsub.d $fa0, $fa0, $fa1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fsub_d: +-; LA64: # %bb.0: +-; LA64-NEXT: fsub.d $fa0, $fa0, $fa1 +-; LA64-NEXT: ret +- %sub = fsub double %x, %y +- ret double %sub +-} +- +-define float @fneg_s(float %x) { +-; LA32-LABEL: fneg_s: +-; LA32: # %bb.0: +-; LA32-NEXT: fneg.s $fa0, $fa0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fneg_s: +-; LA64: # %bb.0: +-; LA64-NEXT: fneg.s $fa0, $fa0 +-; LA64-NEXT: ret +- %res = fsub float -0.0, %x +- ret float %res +-} +- +-define double @fneg_d(double %x) { +-; LA32-LABEL: fneg_d: +-; LA32: # %bb.0: +-; LA32-NEXT: fneg.d $fa0, $fa0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fneg_d: +-; LA64: # %bb.0: +-; LA64-NEXT: fneg.d $fa0, $fa0 +-; LA64-NEXT: ret +- %res = fsub double -0.0, %x +- ret double %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/icmp.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/icmp.ll +deleted file mode 100644 +index 605b3ab29..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/icmp.ll ++++ /dev/null +@@ -1,245 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-;; Exercise the 'icmp' LLVM IR: https://llvm.org/docs/LangRef.html#icmp-instruction +- +-define i1 @icmp_eq(i32 signext %a, i32 signext %b) { +-; LA32-LABEL: icmp_eq: +-; LA32: # %bb.0: +-; LA32-NEXT: xor $a0, $a0, $a1 +-; LA32-NEXT: sltui $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: icmp_eq: +-; LA64: # %bb.0: +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: sltui $a0, $a0, 1 +-; LA64-NEXT: ret +- %res = icmp eq i32 %a, %b +- ret i1 %res +-} +- +-define i1 @icmp_ne(i32 signext %a, i32 signext %b) { +-; LA32-LABEL: icmp_ne: +-; LA32: # %bb.0: +-; LA32-NEXT: xor $a0, $a0, $a1 +-; LA32-NEXT: sltu $a0, $zero, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: icmp_ne: +-; LA64: # %bb.0: +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: sltu $a0, $zero, $a0 +-; LA64-NEXT: ret +- %res = icmp ne i32 %a, %b +- ret i1 %res +-} +- +-define i1 @icmp_ugt(i32 signext %a, i32 signext %b) { +-; LA32-LABEL: icmp_ugt: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a0, $a1, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: icmp_ugt: +-; LA64: # %bb.0: +-; LA64-NEXT: sltu $a0, $a1, $a0 +-; LA64-NEXT: ret +- %res = icmp ugt i32 %a, %b +- ret i1 %res +-} +- +-define i1 @icmp_uge(i32 signext %a, i32 signext %b) { +-; LA32-LABEL: icmp_uge: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a0, $a0, $a1 +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: icmp_uge: +-; LA64: # %bb.0: +-; LA64-NEXT: sltu $a0, $a0, $a1 +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: ret +- %res = icmp uge i32 %a, %b +- ret i1 %res +-} +- +-define i1 @icmp_ult(i32 signext %a, i32 signext %b) { +-; LA32-LABEL: icmp_ult: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: icmp_ult: +-; LA64: # %bb.0: +-; LA64-NEXT: sltu $a0, $a0, $a1 +-; LA64-NEXT: ret +- %res = icmp ult i32 %a, %b +- ret i1 %res +-} +- +-define i1 @icmp_ule(i32 signext %a, i32 signext %b) { +-; LA32-LABEL: icmp_ule: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a0, $a1, $a0 +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: icmp_ule: +-; LA64: # %bb.0: +-; LA64-NEXT: sltu $a0, $a1, $a0 +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: ret +- %res = icmp ule i32 %a, %b +- ret i1 %res +-} +- +-define i1 @icmp_sgt(i32 signext %a, i32 signext %b) { +-; LA32-LABEL: icmp_sgt: +-; LA32: # %bb.0: +-; LA32-NEXT: slt $a0, $a1, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: icmp_sgt: +-; LA64: # %bb.0: +-; LA64-NEXT: slt $a0, $a1, $a0 +-; LA64-NEXT: ret +- %res = icmp sgt i32 %a, %b +- ret i1 %res +-} +- +-define i1 @icmp_sge(i32 signext %a, i32 signext %b) { +-; LA32-LABEL: icmp_sge: +-; LA32: # %bb.0: +-; LA32-NEXT: slt $a0, $a0, $a1 +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: icmp_sge: +-; LA64: # %bb.0: +-; LA64-NEXT: slt $a0, $a0, $a1 +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: ret +- %res = icmp sge i32 %a, %b +- ret i1 %res +-} +- +-define i1 @icmp_slt(i32 signext %a, i32 signext %b) { +-; LA32-LABEL: icmp_slt: +-; LA32: # %bb.0: +-; LA32-NEXT: slt $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: icmp_slt: +-; LA64: # %bb.0: +-; LA64-NEXT: slt $a0, $a0, $a1 +-; LA64-NEXT: ret +- %res = icmp slt i32 %a, %b +- ret i1 %res +-} +- +-define i1 @icmp_sle(i32 signext %a, i32 signext %b) { +-; LA32-LABEL: icmp_sle: +-; LA32: # %bb.0: +-; LA32-NEXT: slt $a0, $a1, $a0 +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: icmp_sle: +-; LA64: # %bb.0: +-; LA64-NEXT: slt $a0, $a1, $a0 +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: ret +- %res = icmp sle i32 %a, %b +- ret i1 %res +-} +- +-define i1 @icmp_slt_3(i32 signext %a) { +-; LA32-LABEL: icmp_slt_3: +-; LA32: # %bb.0: +-; LA32-NEXT: slti $a0, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: icmp_slt_3: +-; LA64: # %bb.0: +-; LA64-NEXT: slti $a0, $a0, 3 +-; LA64-NEXT: ret +- %res = icmp slt i32 %a, 3 +- ret i1 %res +-} +- +-define i1 @icmp_ult_3(i32 signext %a) { +-; LA32-LABEL: icmp_ult_3: +-; LA32: # %bb.0: +-; LA32-NEXT: sltui $a0, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: icmp_ult_3: +-; LA64: # %bb.0: +-; LA64-NEXT: sltui $a0, $a0, 3 +-; LA64-NEXT: ret +- %res = icmp ult i32 %a, 3 +- ret i1 %res +-} +- +-define i1 @icmp_eq_0(i32 signext %a) { +-; LA32-LABEL: icmp_eq_0: +-; LA32: # %bb.0: +-; LA32-NEXT: sltui $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: icmp_eq_0: +-; LA64: # %bb.0: +-; LA64-NEXT: sltui $a0, $a0, 1 +-; LA64-NEXT: ret +- %res = icmp eq i32 %a, 0 +- ret i1 %res +-} +- +-define i1 @icmp_eq_3(i32 signext %a) { +-; LA32-LABEL: icmp_eq_3: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $a0, -3 +-; LA32-NEXT: sltui $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: icmp_eq_3: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $a0, $a0, -3 +-; LA64-NEXT: sltui $a0, $a0, 1 +-; LA64-NEXT: ret +- %res = icmp eq i32 %a, 3 +- ret i1 %res +-} +- +-define i1 @icmp_ne_0(i32 signext %a) { +-; LA32-LABEL: icmp_ne_0: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a0, $zero, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: icmp_ne_0: +-; LA64: # %bb.0: +-; LA64-NEXT: sltu $a0, $zero, $a0 +-; LA64-NEXT: ret +- %res = icmp ne i32 %a, 0 +- ret i1 %res +-} +- +-define i1 @icmp_ne_3(i32 signext %a) { +-; LA32-LABEL: icmp_ne_3: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $a0, -3 +-; LA32-NEXT: sltu $a0, $zero, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: icmp_ne_3: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $a0, $a0, -3 +-; LA64-NEXT: sltu $a0, $zero, $a0 +-; LA64-NEXT: ret +- %res = icmp ne i32 %a, 3 +- ret i1 %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/indirectbr.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/indirectbr.ll +deleted file mode 100644 +index cd60183a0..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/indirectbr.ll ++++ /dev/null +@@ -1,31 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s +- +-define i32 @indirectbr(ptr %target) nounwind { +-; CHECK-LABEL: indirectbr: +-; CHECK: # %bb.0: +-; CHECK-NEXT: jr $a0 +-; CHECK-NEXT: .LBB0_1: # %test_label +-; CHECK-NEXT: move $a0, $zero +-; CHECK-NEXT: ret +- indirectbr ptr %target, [label %test_label] +-test_label: +- br label %ret +-ret: +- ret i32 0 +-} +- +-define i32 @indirectbr_with_offset(ptr %a) nounwind { +-; CHECK-LABEL: indirectbr_with_offset: +-; CHECK: # %bb.0: +-; CHECK-NEXT: jirl $zero, $a0, 1380 +-; CHECK-NEXT: .LBB1_1: # %test_label +-; CHECK-NEXT: move $a0, $zero +-; CHECK-NEXT: ret +- %target = getelementptr inbounds i8, ptr %a, i32 1380 +- indirectbr ptr %target, [label %test_label] +-test_label: +- br label %ret +-ret: +- ret i32 0 +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/load-store-atomic.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/load-store-atomic.ll +deleted file mode 100644 +index 8b170c479..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/load-store-atomic.ll ++++ /dev/null +@@ -1,536 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-define i8 @load_acquire_i8(ptr %ptr) { +-; LA32-LABEL: load_acquire_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.b $a0, $a0, 0 +-; LA32-NEXT: dbar 20 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_acquire_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.b $a0, $a0, 0 +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: ret +- %val = load atomic i8, ptr %ptr acquire, align 1 +- ret i8 %val +-} +- +-define i16 @load_acquire_i16(ptr %ptr) { +-; LA32-LABEL: load_acquire_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.h $a0, $a0, 0 +-; LA32-NEXT: dbar 20 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_acquire_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.h $a0, $a0, 0 +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: ret +- %val = load atomic i16, ptr %ptr acquire, align 2 +- ret i16 %val +-} +- +-define i32 @load_acquire_i32(ptr %ptr) { +-; LA32-LABEL: load_acquire_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a0, $a0, 0 +-; LA32-NEXT: dbar 20 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_acquire_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.w $a0, $a0, 0 +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: ret +- %val = load atomic i32, ptr %ptr acquire, align 4 +- ret i32 %val +-} +- +-define i64 @load_acquire_i64(ptr %ptr) { +-; LA32-LABEL: load_acquire_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: ori $a1, $zero, 2 +-; LA32-NEXT: bl %plt(__atomic_load_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_acquire_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.d $a0, $a0, 0 +-; LA64-NEXT: dbar 20 +-; LA64-NEXT: ret +- %val = load atomic i64, ptr %ptr acquire, align 8 +- ret i64 %val +-} +- +-define i8 @load_unordered_i8(ptr %ptr) { +-; LA32-LABEL: load_unordered_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.b $a0, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_unordered_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.b $a0, $a0, 0 +-; LA64-NEXT: ret +- %val = load atomic i8, ptr %ptr unordered, align 1 +- ret i8 %val +-} +- +-define i16 @load_unordered_i16(ptr %ptr) { +-; LA32-LABEL: load_unordered_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.h $a0, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_unordered_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.h $a0, $a0, 0 +-; LA64-NEXT: ret +- %val = load atomic i16, ptr %ptr unordered, align 2 +- ret i16 %val +-} +- +-define i32 @load_unordered_i32(ptr %ptr) { +-; LA32-LABEL: load_unordered_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a0, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_unordered_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.w $a0, $a0, 0 +-; LA64-NEXT: ret +- %val = load atomic i32, ptr %ptr unordered, align 4 +- ret i32 %val +-} +- +-define i64 @load_unordered_i64(ptr %ptr) { +-; LA32-LABEL: load_unordered_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: move $a1, $zero +-; LA32-NEXT: bl %plt(__atomic_load_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_unordered_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.d $a0, $a0, 0 +-; LA64-NEXT: ret +- %val = load atomic i64, ptr %ptr unordered, align 8 +- ret i64 %val +-} +- +-define i8 @load_monotonic_i8(ptr %ptr) { +-; LA32-LABEL: load_monotonic_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.b $a0, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_monotonic_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.b $a0, $a0, 0 +-; LA64-NEXT: ret +- %val = load atomic i8, ptr %ptr monotonic, align 1 +- ret i8 %val +-} +- +-define i16 @load_monotonic_i16(ptr %ptr) { +-; LA32-LABEL: load_monotonic_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.h $a0, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_monotonic_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.h $a0, $a0, 0 +-; LA64-NEXT: ret +- %val = load atomic i16, ptr %ptr monotonic, align 2 +- ret i16 %val +-} +- +-define i32 @load_monotonic_i32(ptr %ptr) { +-; LA32-LABEL: load_monotonic_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a0, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_monotonic_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.w $a0, $a0, 0 +-; LA64-NEXT: ret +- %val = load atomic i32, ptr %ptr monotonic, align 4 +- ret i32 %val +-} +- +-define i64 @load_monotonic_i64(ptr %ptr) { +-; LA32-LABEL: load_monotonic_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: move $a1, $zero +-; LA32-NEXT: bl %plt(__atomic_load_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_monotonic_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.d $a0, $a0, 0 +-; LA64-NEXT: ret +- %val = load atomic i64, ptr %ptr monotonic, align 8 +- ret i64 %val +-} +- +-define i8 @load_seq_cst_i8(ptr %ptr) { +-; LA32-LABEL: load_seq_cst_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.b $a0, $a0, 0 +-; LA32-NEXT: dbar 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_seq_cst_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.b $a0, $a0, 0 +-; LA64-NEXT: dbar 16 +-; LA64-NEXT: ret +- %val = load atomic i8, ptr %ptr seq_cst, align 1 +- ret i8 %val +-} +- +-define i16 @load_seq_cst_i16(ptr %ptr) { +-; LA32-LABEL: load_seq_cst_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.h $a0, $a0, 0 +-; LA32-NEXT: dbar 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_seq_cst_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.h $a0, $a0, 0 +-; LA64-NEXT: dbar 16 +-; LA64-NEXT: ret +- %val = load atomic i16, ptr %ptr seq_cst, align 2 +- ret i16 %val +-} +- +-define i32 @load_seq_cst_i32(ptr %ptr) { +-; LA32-LABEL: load_seq_cst_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a0, $a0, 0 +-; LA32-NEXT: dbar 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_seq_cst_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.w $a0, $a0, 0 +-; LA64-NEXT: dbar 16 +-; LA64-NEXT: ret +- %val = load atomic i32, ptr %ptr seq_cst, align 4 +- ret i32 %val +-} +- +-define i64 @load_seq_cst_i64(ptr %ptr) { +-; LA32-LABEL: load_seq_cst_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: ori $a1, $zero, 5 +-; LA32-NEXT: bl %plt(__atomic_load_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_seq_cst_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.d $a0, $a0, 0 +-; LA64-NEXT: dbar 16 +-; LA64-NEXT: ret +- %val = load atomic i64, ptr %ptr seq_cst, align 8 +- ret i64 %val +-} +- +-define void @store_release_i8(ptr %ptr, i8 signext %v) { +-; LA32-LABEL: store_release_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: dbar 18 +-; LA32-NEXT: st.b $a1, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: store_release_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: dbar 18 +-; LA64-NEXT: st.b $a1, $a0, 0 +-; LA64-NEXT: ret +- store atomic i8 %v, ptr %ptr release, align 1 +- ret void +-} +- +-define void @store_release_i16(ptr %ptr, i16 signext %v) { +-; LA32-LABEL: store_release_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: dbar 18 +-; LA32-NEXT: st.h $a1, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: store_release_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: dbar 18 +-; LA64-NEXT: st.h $a1, $a0, 0 +-; LA64-NEXT: ret +- store atomic i16 %v, ptr %ptr release, align 2 +- ret void +-} +- +-define void @store_release_i32(ptr %ptr, i32 signext %v) { +-; LA32-LABEL: store_release_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: dbar 18 +-; LA32-NEXT: st.w $a1, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: store_release_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: amswap_db.w $zero, $a1, $a0 +-; LA64-NEXT: ret +- store atomic i32 %v, ptr %ptr release, align 4 +- ret void +-} +- +-define void @store_release_i64(ptr %ptr, i64 %v) { +-; LA32-LABEL: store_release_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: ori $a3, $zero, 3 +-; LA32-NEXT: bl %plt(__atomic_store_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: store_release_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: amswap_db.d $zero, $a1, $a0 +-; LA64-NEXT: ret +- store atomic i64 %v, ptr %ptr release, align 8 +- ret void +-} +- +-define void @store_unordered_i8(ptr %ptr, i8 signext %v) { +-; LA32-LABEL: store_unordered_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: st.b $a1, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: store_unordered_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: st.b $a1, $a0, 0 +-; LA64-NEXT: ret +- store atomic i8 %v, ptr %ptr unordered, align 1 +- ret void +-} +- +-define void @store_unordered_i16(ptr %ptr, i16 signext %v) { +-; LA32-LABEL: store_unordered_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: st.h $a1, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: store_unordered_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: st.h $a1, $a0, 0 +-; LA64-NEXT: ret +- store atomic i16 %v, ptr %ptr unordered, align 2 +- ret void +-} +- +-define void @store_unordered_i32(ptr %ptr, i32 signext %v) { +-; LA32-LABEL: store_unordered_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: st.w $a1, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: store_unordered_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: st.w $a1, $a0, 0 +-; LA64-NEXT: ret +- store atomic i32 %v, ptr %ptr unordered, align 4 +- ret void +-} +- +-define void @store_unordered_i64(ptr %ptr, i64 %v) { +-; LA32-LABEL: store_unordered_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: move $a3, $zero +-; LA32-NEXT: bl %plt(__atomic_store_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: store_unordered_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: st.d $a1, $a0, 0 +-; LA64-NEXT: ret +- store atomic i64 %v, ptr %ptr unordered, align 8 +- ret void +-} +- +-define void @store_monotonic_i8(ptr %ptr, i8 signext %v) { +-; LA32-LABEL: store_monotonic_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: st.b $a1, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: store_monotonic_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: st.b $a1, $a0, 0 +-; LA64-NEXT: ret +- store atomic i8 %v, ptr %ptr monotonic, align 1 +- ret void +-} +- +-define void @store_monotonic_i16(ptr %ptr, i16 signext %v) { +-; LA32-LABEL: store_monotonic_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: st.h $a1, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: store_monotonic_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: st.h $a1, $a0, 0 +-; LA64-NEXT: ret +- store atomic i16 %v, ptr %ptr monotonic, align 2 +- ret void +-} +- +-define void @store_monotonic_i32(ptr %ptr, i32 signext %v) { +-; LA32-LABEL: store_monotonic_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: st.w $a1, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: store_monotonic_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: st.w $a1, $a0, 0 +-; LA64-NEXT: ret +- store atomic i32 %v, ptr %ptr monotonic, align 4 +- ret void +-} +- +-define void @store_monotonic_i64(ptr %ptr, i64 %v) { +-; LA32-LABEL: store_monotonic_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: move $a3, $zero +-; LA32-NEXT: bl %plt(__atomic_store_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: store_monotonic_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: st.d $a1, $a0, 0 +-; LA64-NEXT: ret +- store atomic i64 %v, ptr %ptr monotonic, align 8 +- ret void +-} +- +-define void @store_seq_cst_i8(ptr %ptr, i8 signext %v) { +-; LA32-LABEL: store_seq_cst_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: dbar 16 +-; LA32-NEXT: st.b $a1, $a0, 0 +-; LA32-NEXT: dbar 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: store_seq_cst_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: dbar 16 +-; LA64-NEXT: st.b $a1, $a0, 0 +-; LA64-NEXT: dbar 16 +-; LA64-NEXT: ret +- store atomic i8 %v, ptr %ptr seq_cst, align 1 +- ret void +-} +- +-define void @store_seq_cst_i16(ptr %ptr, i16 signext %v) { +-; LA32-LABEL: store_seq_cst_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: dbar 16 +-; LA32-NEXT: st.h $a1, $a0, 0 +-; LA32-NEXT: dbar 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: store_seq_cst_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: dbar 16 +-; LA64-NEXT: st.h $a1, $a0, 0 +-; LA64-NEXT: dbar 16 +-; LA64-NEXT: ret +- store atomic i16 %v, ptr %ptr seq_cst, align 2 +- ret void +-} +- +-define void @store_seq_cst_i32(ptr %ptr, i32 signext %v) { +-; LA32-LABEL: store_seq_cst_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: dbar 16 +-; LA32-NEXT: st.w $a1, $a0, 0 +-; LA32-NEXT: dbar 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: store_seq_cst_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: amswap_db.w $zero, $a1, $a0 +-; LA64-NEXT: ret +- store atomic i32 %v, ptr %ptr seq_cst, align 4 +- ret void +-} +- +-define void @store_seq_cst_i64(ptr %ptr, i64 %v) { +-; LA32-LABEL: store_seq_cst_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: ori $a3, $zero, 5 +-; LA32-NEXT: bl %plt(__atomic_store_8) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: store_seq_cst_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: amswap_db.d $zero, $a1, $a0 +-; LA64-NEXT: ret +- store atomic i64 %v, ptr %ptr seq_cst, align 8 +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/load-store-fp.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/load-store-fp.ll +deleted file mode 100644 +index 3f392c5e3..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/load-store-fp.ll ++++ /dev/null +@@ -1,123 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA32F +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32D +-; RUN: llc --mtriple=loongarch64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA64F +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64D +- +-define float @fldx_s(ptr %a, i64 %idx) nounwind { +-; LA32F-LABEL: fldx_s: +-; LA32F: # %bb.0: +-; LA32F-NEXT: slli.w $a1, $a1, 2 +-; LA32F-NEXT: fldx.s $fa0, $a0, $a1 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: fldx_s: +-; LA32D: # %bb.0: +-; LA32D-NEXT: slli.w $a1, $a1, 2 +-; LA32D-NEXT: fldx.s $fa0, $a0, $a1 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: fldx_s: +-; LA64F: # %bb.0: +-; LA64F-NEXT: slli.d $a1, $a1, 2 +-; LA64F-NEXT: fldx.s $fa0, $a0, $a1 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: fldx_s: +-; LA64D: # %bb.0: +-; LA64D-NEXT: slli.d $a1, $a1, 2 +-; LA64D-NEXT: fldx.s $fa0, $a0, $a1 +-; LA64D-NEXT: ret +- %1 = getelementptr float, ptr %a, i64 %idx +- %2 = load float, ptr %1 +- ret float %2 +-} +- +-define double @fldx_d(ptr %a, i64 %idx) nounwind { +-; LA32F-LABEL: fldx_d: +-; LA32F: # %bb.0: +-; LA32F-NEXT: alsl.w $a1, $a1, $a0, 3 +-; LA32F-NEXT: ld.w $a0, $a1, 0 +-; LA32F-NEXT: ld.w $a1, $a1, 4 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: fldx_d: +-; LA32D: # %bb.0: +-; LA32D-NEXT: slli.w $a1, $a1, 3 +-; LA32D-NEXT: fldx.d $fa0, $a0, $a1 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: fldx_d: +-; LA64F: # %bb.0: +-; LA64F-NEXT: slli.d $a1, $a1, 3 +-; LA64F-NEXT: ldx.d $a0, $a0, $a1 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: fldx_d: +-; LA64D: # %bb.0: +-; LA64D-NEXT: slli.d $a1, $a1, 3 +-; LA64D-NEXT: fldx.d $fa0, $a0, $a1 +-; LA64D-NEXT: ret +- %1 = getelementptr double, ptr %a, i64 %idx +- %2 = load double, ptr %1 +- ret double %2 +-} +- +-define void @fstx_s(ptr %dst, i64 %idx, float %val) nounwind { +-; LA32F-LABEL: fstx_s: +-; LA32F: # %bb.0: +-; LA32F-NEXT: slli.w $a1, $a1, 2 +-; LA32F-NEXT: fstx.s $fa0, $a0, $a1 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: fstx_s: +-; LA32D: # %bb.0: +-; LA32D-NEXT: slli.w $a1, $a1, 2 +-; LA32D-NEXT: fstx.s $fa0, $a0, $a1 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: fstx_s: +-; LA64F: # %bb.0: +-; LA64F-NEXT: slli.d $a1, $a1, 2 +-; LA64F-NEXT: fstx.s $fa0, $a0, $a1 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: fstx_s: +-; LA64D: # %bb.0: +-; LA64D-NEXT: slli.d $a1, $a1, 2 +-; LA64D-NEXT: fstx.s $fa0, $a0, $a1 +-; LA64D-NEXT: ret +- %1 = getelementptr float, ptr %dst, i64 %idx +- store float %val, ptr %1 +- ret void +-} +- +-define void @fstx_d(ptr %dst, i64 %idx, double %val) nounwind { +-; LA32F-LABEL: fstx_d: +-; LA32F: # %bb.0: +-; LA32F-NEXT: alsl.w $a0, $a1, $a0, 3 +-; LA32F-NEXT: st.w $a4, $a0, 4 +-; LA32F-NEXT: st.w $a3, $a0, 0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: fstx_d: +-; LA32D: # %bb.0: +-; LA32D-NEXT: slli.w $a1, $a1, 3 +-; LA32D-NEXT: fstx.d $fa0, $a0, $a1 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: fstx_d: +-; LA64F: # %bb.0: +-; LA64F-NEXT: slli.d $a1, $a1, 3 +-; LA64F-NEXT: stx.d $a2, $a0, $a1 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: fstx_d: +-; LA64D: # %bb.0: +-; LA64D-NEXT: slli.d $a1, $a1, 3 +-; LA64D-NEXT: fstx.d $fa0, $a0, $a1 +-; LA64D-NEXT: ret +- %1 = getelementptr double, ptr %dst, i64 %idx +- store double %val, ptr %1 +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll +deleted file mode 100644 +index 387a62bd6..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll ++++ /dev/null +@@ -1,646 +0,0 @@ +-; RUN: llc --mtriple=loongarch32 --mattr=+d --relocation-model=static < %s | FileCheck %s --check-prefixes=ALL,LA32NOPIC,LA32 +-; RUN: llc --mtriple=loongarch32 --mattr=+d --relocation-model=pic < %s | FileCheck %s --check-prefixes=ALL,LA32PIC,LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+d --relocation-model=static < %s | FileCheck %s --check-prefixes=ALL,LA64NOPIC,LA64 +-; RUN: llc --mtriple=loongarch64 --mattr=+d --relocation-model=pic < %s | FileCheck %s --check-prefixes=ALL,LA64PIC,LA64 +- +-;; Check load from and store to global variables. +-@G = dso_local global i32 zeroinitializer, align 4 +-@arr = dso_local global [10 x i32] zeroinitializer, align 4 +- +-define i32 @load_store_global() nounwind { +-; ALL-LABEL: load_store_global: +-; ALL: # %bb.0: +- +-; LA32NOPIC-NEXT: pcalau12i $a0, %pc_hi20(G) +-; LA32NOPIC-NEXT: addi.w $a1, $a0, %pc_lo12(G) +-; LA32PIC-NEXT: pcalau12i $a0, %pc_hi20(.LG$local) +-; LA32PIC-NEXT: addi.w $a1, $a0, %pc_lo12(.LG$local) +-; LA32-NEXT: ld.w $a0, $a1, 0 +-; LA32-NEXT: addi.w $a0, $a0, 1 +-; LA32-NEXT: st.w $a0, $a1, 0 +- +-; LA64NOPIC-NEXT: pcalau12i $a0, %pc_hi20(G) +-; LA64NOPIC-NEXT: addi.d $a1, $a0, %pc_lo12(G) +-; LA64PIC-NEXT: pcalau12i $a0, %pc_hi20(.LG$local) +-; LA64PIC-NEXT: addi.d $a1, $a0, %pc_lo12(.LG$local) +-; LA64-NEXT: ld.w $a0, $a1, 0 +-; LA64-NEXT: addi.d $a0, $a0, 1 +-; LA64-NEXT: st.w $a0, $a1, 0 +- +-; ALL-NEXT: ret +- +- %v = load i32, ptr @G +- %sum = add i32 %v, 1 +- store i32 %sum, ptr @G +- ret i32 %sum +-} +- +-define i32 @load_store_global_array(i32 %a) nounwind { +-; ALL-LABEL: load_store_global_array: +-; ALL: # %bb.0: +- +-; LA32NOPIC-NEXT: pcalau12i $a1, %pc_hi20(arr) +-; LA32NOPIC-NEXT: addi.w $a2, $a1, %pc_lo12(arr) +-; LA32PIC-NEXT: pcalau12i $a1, %pc_hi20(.Larr$local) +-; LA32PIC-NEXT: addi.w $a2, $a1, %pc_lo12(.Larr$local) +-; LA32-NEXT: ld.w $a1, $a2, 0 +-; LA32-NEXT: st.w $a0, $a2, 0 +-; LA32NOPIC-NEXT: ld.w $a3, $a2, 36 +-; LA32NOPIC-NEXT: st.w $a0, $a2, 36 +-; LA32PIC-NEXT: ld.w $a3, $a2, 36 +-; LA32PIC-NEXT: st.w $a0, $a2, 36 +- +-; LA64NOPIC-NEXT: pcalau12i $a1, %pc_hi20(arr) +-; LA64NOPIC-NEXT: addi.d $a2, $a1, %pc_lo12(arr) +-; LA64PIC-NEXT: pcalau12i $a1, %pc_hi20(.Larr$local) +-; LA64PIC-NEXT: addi.d $a2, $a1, %pc_lo12(.Larr$local) +-; LA64-NEXT: ld.w $a1, $a2, 0 +-; LA64-NEXT: st.w $a0, $a2, 0 +-; LA64NOPIC-NEXT: ld.w $a3, $a2, 36 +-; LA64NOPIC-NEXT: st.w $a0, $a2, 36 +-; LA64PIC-NEXT: ld.w $a3, $a2, 36 +-; LA64PIC-NEXT: st.w $a0, $a2, 36 +- +-; ALL-NEXT: move $a0, $a1 +-; ALL-NEXT: ret +- +- %1 = load volatile i32, ptr @arr, align 4 +- store i32 %a, ptr @arr, align 4 +- %2 = getelementptr [10 x i32], ptr @arr, i32 0, i32 9 +- %3 = load volatile i32, ptr %2, align 4 +- store i32 %a, ptr %2, align 4 +- ret i32 %1 +-} +- +-;; Check indexed and unindexed, sext, zext and anyext loads. +- +-define i64 @ld_b(ptr %a) nounwind { +-; LA32-LABEL: ld_b: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.b $a1, $a0, 0 +-; LA32-NEXT: ld.b $a0, $a0, 1 +-; LA32-NEXT: srai.w $a1, $a0, 31 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ld_b: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.b $a1, $a0, 0 +-; LA64-NEXT: ld.b $a0, $a0, 1 +-; LA64-NEXT: ret +- %1 = getelementptr i8, ptr %a, i64 1 +- %2 = load i8, ptr %1 +- %3 = sext i8 %2 to i64 +- %4 = load volatile i8, ptr %a +- ret i64 %3 +-} +- +-define i64 @ld_h(ptr %a) nounwind { +-; LA32-LABEL: ld_h: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.h $a1, $a0, 0 +-; LA32-NEXT: ld.h $a0, $a0, 4 +-; LA32-NEXT: srai.w $a1, $a0, 31 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ld_h: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.h $a1, $a0, 0 +-; LA64-NEXT: ld.h $a0, $a0, 4 +-; LA64-NEXT: ret +- %1 = getelementptr i16, ptr %a, i64 2 +- %2 = load i16, ptr %1 +- %3 = sext i16 %2 to i64 +- %4 = load volatile i16, ptr %a +- ret i64 %3 +-} +- +-define i64 @ld_w(ptr %a) nounwind { +-; LA32-LABEL: ld_w: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a1, $a0, 0 +-; LA32-NEXT: ld.w $a0, $a0, 12 +-; LA32-NEXT: srai.w $a1, $a0, 31 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ld_w: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.w $a1, $a0, 0 +-; LA64-NEXT: ld.w $a0, $a0, 12 +-; LA64-NEXT: ret +- %1 = getelementptr i32, ptr %a, i64 3 +- %2 = load i32, ptr %1 +- %3 = sext i32 %2 to i64 +- %4 = load volatile i32, ptr %a +- ret i64 %3 +-} +- +-define i64 @ld_d(ptr %a) nounwind { +-; LA32-LABEL: ld_d: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a1, $a0, 4 +-; LA32-NEXT: ld.w $a1, $a0, 0 +-; LA32-NEXT: ld.w $a1, $a0, 28 +-; LA32-NEXT: ld.w $a0, $a0, 24 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ld_d: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.d $a1, $a0, 0 +-; LA64-NEXT: ld.d $a0, $a0, 24 +-; LA64-NEXT: ret +- %1 = getelementptr i64, ptr %a, i64 3 +- %2 = load i64, ptr %1 +- %3 = load volatile i64, ptr %a +- ret i64 %2 +-} +- +-define i64 @ld_bu(ptr %a) nounwind { +-; LA32-LABEL: ld_bu: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.bu $a1, $a0, 0 +-; LA32-NEXT: ld.bu $a2, $a0, 4 +-; LA32-NEXT: add.w $a0, $a2, $a1 +-; LA32-NEXT: sltu $a1, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ld_bu: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.bu $a1, $a0, 0 +-; LA64-NEXT: ld.bu $a0, $a0, 4 +-; LA64-NEXT: add.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = getelementptr i8, ptr %a, i64 4 +- %2 = load i8, ptr %1 +- %3 = zext i8 %2 to i64 +- %4 = load volatile i8, ptr %a +- %5 = zext i8 %4 to i64 +- %6 = add i64 %3, %5 +- ret i64 %6 +-} +- +-define i64 @ld_hu(ptr %a) nounwind { +-; LA32-LABEL: ld_hu: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.hu $a1, $a0, 0 +-; LA32-NEXT: ld.hu $a2, $a0, 10 +-; LA32-NEXT: add.w $a0, $a2, $a1 +-; LA32-NEXT: sltu $a1, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ld_hu: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.hu $a1, $a0, 0 +-; LA64-NEXT: ld.hu $a0, $a0, 10 +-; LA64-NEXT: add.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = getelementptr i16, ptr %a, i64 5 +- %2 = load i16, ptr %1 +- %3 = zext i16 %2 to i64 +- %4 = load volatile i16, ptr %a +- %5 = zext i16 %4 to i64 +- %6 = add i64 %3, %5 +- ret i64 %6 +-} +- +-define i64 @ld_wu(ptr %a) nounwind { +-; LA32-LABEL: ld_wu: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a1, $a0, 0 +-; LA32-NEXT: ld.w $a2, $a0, 20 +-; LA32-NEXT: add.w $a0, $a2, $a1 +-; LA32-NEXT: sltu $a1, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ld_wu: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.wu $a1, $a0, 0 +-; LA64-NEXT: ld.wu $a0, $a0, 20 +-; LA64-NEXT: add.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = getelementptr i32, ptr %a, i64 5 +- %2 = load i32, ptr %1 +- %3 = zext i32 %2 to i64 +- %4 = load volatile i32, ptr %a +- %5 = zext i32 %4 to i64 +- %6 = add i64 %3, %5 +- ret i64 %6 +-} +- +-define i64 @ldx_b(ptr %a, i64 %idx) nounwind { +-; LA32-LABEL: ldx_b: +-; LA32: # %bb.0: +-; LA32-NEXT: add.w $a1, $a0, $a1 +-; LA32-NEXT: ld.b $a2, $a1, 0 +-; LA32-NEXT: ld.b $a0, $a0, 0 +-; LA32-NEXT: srai.w $a1, $a2, 31 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ldx_b: +-; LA64: # %bb.0: +-; LA64-NEXT: ldx.b $a1, $a0, $a1 +-; LA64-NEXT: ld.b $a0, $a0, 0 +-; LA64-NEXT: move $a0, $a1 +-; LA64-NEXT: ret +- %1 = getelementptr i8, ptr %a, i64 %idx +- %2 = load i8, ptr %1 +- %3 = sext i8 %2 to i64 +- %4 = load volatile i8, ptr %a +- ret i64 %3 +-} +- +-define i64 @ldx_h(ptr %a, i64 %idx) nounwind { +-; LA32-LABEL: ldx_h: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a1, $a1, $a0, 1 +-; LA32-NEXT: ld.h $a2, $a1, 0 +-; LA32-NEXT: ld.h $a0, $a0, 0 +-; LA32-NEXT: srai.w $a1, $a2, 31 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ldx_h: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a1, 1 +-; LA64-NEXT: ldx.h $a1, $a0, $a1 +-; LA64-NEXT: ld.h $a0, $a0, 0 +-; LA64-NEXT: move $a0, $a1 +-; LA64-NEXT: ret +- %1 = getelementptr i16, ptr %a, i64 %idx +- %2 = load i16, ptr %1 +- %3 = sext i16 %2 to i64 +- %4 = load volatile i16, ptr %a +- ret i64 %3 +-} +- +-define i64 @ldx_w(ptr %a, i64 %idx) nounwind { +-; LA32-LABEL: ldx_w: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a1, $a1, $a0, 2 +-; LA32-NEXT: ld.w $a2, $a1, 0 +-; LA32-NEXT: ld.w $a0, $a0, 0 +-; LA32-NEXT: srai.w $a1, $a2, 31 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ldx_w: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a1, 2 +-; LA64-NEXT: ldx.w $a1, $a0, $a1 +-; LA64-NEXT: ld.w $a0, $a0, 0 +-; LA64-NEXT: move $a0, $a1 +-; LA64-NEXT: ret +- %1 = getelementptr i32, ptr %a, i64 %idx +- %2 = load i32, ptr %1 +- %3 = sext i32 %2 to i64 +- %4 = load volatile i32, ptr %a +- ret i64 %3 +-} +- +-define i64 @ldx_d(ptr %a, i64 %idx) nounwind { +-; LA32-LABEL: ldx_d: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a1, $a1, $a0, 3 +-; LA32-NEXT: ld.w $a2, $a1, 0 +-; LA32-NEXT: ld.w $a3, $a0, 0 +-; LA32-NEXT: ld.w $a1, $a1, 4 +-; LA32-NEXT: ld.w $a0, $a0, 4 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ldx_d: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a1, 3 +-; LA64-NEXT: ldx.d $a1, $a0, $a1 +-; LA64-NEXT: ld.d $a0, $a0, 0 +-; LA64-NEXT: move $a0, $a1 +-; LA64-NEXT: ret +- %1 = getelementptr i64, ptr %a, i64 %idx +- %2 = load i64, ptr %1 +- %3 = load volatile i64, ptr %a +- ret i64 %2 +-} +- +-define i64 @ldx_bu(ptr %a, i64 %idx) nounwind { +-; LA32-LABEL: ldx_bu: +-; LA32: # %bb.0: +-; LA32-NEXT: add.w $a1, $a0, $a1 +-; LA32-NEXT: ld.bu $a1, $a1, 0 +-; LA32-NEXT: ld.bu $a0, $a0, 0 +-; LA32-NEXT: add.w $a0, $a1, $a0 +-; LA32-NEXT: sltu $a1, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ldx_bu: +-; LA64: # %bb.0: +-; LA64-NEXT: ldx.bu $a1, $a0, $a1 +-; LA64-NEXT: ld.bu $a0, $a0, 0 +-; LA64-NEXT: add.d $a0, $a1, $a0 +-; LA64-NEXT: ret +- %1 = getelementptr i8, ptr %a, i64 %idx +- %2 = load i8, ptr %1 +- %3 = zext i8 %2 to i64 +- %4 = load volatile i8, ptr %a +- %5 = zext i8 %4 to i64 +- %6 = add i64 %3, %5 +- ret i64 %6 +-} +- +-define i64 @ldx_hu(ptr %a, i64 %idx) nounwind { +-; LA32-LABEL: ldx_hu: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a1, $a1, $a0, 1 +-; LA32-NEXT: ld.hu $a1, $a1, 0 +-; LA32-NEXT: ld.hu $a0, $a0, 0 +-; LA32-NEXT: add.w $a0, $a1, $a0 +-; LA32-NEXT: sltu $a1, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ldx_hu: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a1, 1 +-; LA64-NEXT: ldx.hu $a1, $a0, $a1 +-; LA64-NEXT: ld.hu $a0, $a0, 0 +-; LA64-NEXT: add.d $a0, $a1, $a0 +-; LA64-NEXT: ret +- %1 = getelementptr i16, ptr %a, i64 %idx +- %2 = load i16, ptr %1 +- %3 = zext i16 %2 to i64 +- %4 = load volatile i16, ptr %a +- %5 = zext i16 %4 to i64 +- %6 = add i64 %3, %5 +- ret i64 %6 +-} +- +-define i64 @ldx_wu(ptr %a, i64 %idx) nounwind { +-; LA32-LABEL: ldx_wu: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a1, $a1, $a0, 2 +-; LA32-NEXT: ld.w $a1, $a1, 0 +-; LA32-NEXT: ld.w $a0, $a0, 0 +-; LA32-NEXT: add.w $a0, $a1, $a0 +-; LA32-NEXT: sltu $a1, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ldx_wu: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a1, 2 +-; LA64-NEXT: ldx.wu $a1, $a0, $a1 +-; LA64-NEXT: ld.wu $a0, $a0, 0 +-; LA64-NEXT: add.d $a0, $a1, $a0 +-; LA64-NEXT: ret +- %1 = getelementptr i32, ptr %a, i64 %idx +- %2 = load i32, ptr %1 +- %3 = zext i32 %2 to i64 +- %4 = load volatile i32, ptr %a +- %5 = zext i32 %4 to i64 +- %6 = add i64 %3, %5 +- ret i64 %6 +-} +- +-;; Check indexed and unindexed stores. +- +-define void @st_b(ptr %a, i8 %b) nounwind { +-; ALL-LABEL: st_b: +-; ALL: # %bb.0: +-; ALL-NEXT: st.b $a1, $a0, 6 +-; ALL-NEXT: st.b $a1, $a0, 0 +-; ALL-NEXT: ret +- store i8 %b, ptr %a +- %1 = getelementptr i8, ptr %a, i64 6 +- store i8 %b, ptr %1 +- ret void +-} +- +-define void @st_h(ptr %a, i16 %b) nounwind { +-; ALL-LABEL: st_h: +-; ALL: # %bb.0: +-; ALL-NEXT: st.h $a1, $a0, 14 +-; ALL-NEXT: st.h $a1, $a0, 0 +-; ALL-NEXT: ret +- store i16 %b, ptr %a +- %1 = getelementptr i16, ptr %a, i64 7 +- store i16 %b, ptr %1 +- ret void +-} +- +-define void @st_w(ptr %a, i32 %b) nounwind { +-; ALL-LABEL: st_w: +-; ALL: # %bb.0: +-; ALL-NEXT: st.w $a1, $a0, 28 +-; ALL-NEXT: st.w $a1, $a0, 0 +-; ALL-NEXT: ret +- store i32 %b, ptr %a +- %1 = getelementptr i32, ptr %a, i64 7 +- store i32 %b, ptr %1 +- ret void +-} +- +-define void @st_d(ptr %a, i64 %b) nounwind { +-; LA32-LABEL: st_d: +-; LA32: # %bb.0: +-; LA32-NEXT: st.w $a2, $a0, 68 +-; LA32-NEXT: st.w $a2, $a0, 4 +-; LA32-NEXT: st.w $a1, $a0, 64 +-; LA32-NEXT: st.w $a1, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: st_d: +-; LA64: # %bb.0: +-; LA64-NEXT: st.d $a1, $a0, 64 +-; LA64-NEXT: st.d $a1, $a0, 0 +-; LA64-NEXT: ret +- store i64 %b, ptr %a +- %1 = getelementptr i64, ptr %a, i64 8 +- store i64 %b, ptr %1 +- ret void +-} +- +-define void @stx_b(ptr %dst, i64 %idx, i8 %val) nounwind { +-; LA32-LABEL: stx_b: +-; LA32: # %bb.0: +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: st.b $a3, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: stx_b: +-; LA64: # %bb.0: +-; LA64-NEXT: stx.b $a2, $a0, $a1 +-; LA64-NEXT: ret +- %1 = getelementptr i8, ptr %dst, i64 %idx +- store i8 %val, ptr %1 +- ret void +-} +- +-define void @stx_h(ptr %dst, i64 %idx, i16 %val) nounwind { +-; LA32-LABEL: stx_h: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a0, $a1, $a0, 1 +-; LA32-NEXT: st.h $a3, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: stx_h: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a1, 1 +-; LA64-NEXT: stx.h $a2, $a0, $a1 +-; LA64-NEXT: ret +- %1 = getelementptr i16, ptr %dst, i64 %idx +- store i16 %val, ptr %1 +- ret void +-} +- +-define void @stx_w(ptr %dst, i64 %idx, i32 %val) nounwind { +-; LA32-LABEL: stx_w: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a0, $a1, $a0, 2 +-; LA32-NEXT: st.w $a3, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: stx_w: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a1, 2 +-; LA64-NEXT: stx.w $a2, $a0, $a1 +-; LA64-NEXT: ret +- %1 = getelementptr i32, ptr %dst, i64 %idx +- store i32 %val, ptr %1 +- ret void +-} +- +-define void @stx_d(ptr %dst, i64 %idx, i64 %val) nounwind { +-; LA32-LABEL: stx_d: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a0, $a1, $a0, 3 +-; LA32-NEXT: st.w $a4, $a0, 4 +-; LA32-NEXT: st.w $a3, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: stx_d: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a1, 3 +-; LA64-NEXT: stx.d $a2, $a0, $a1 +-; LA64-NEXT: ret +- %1 = getelementptr i64, ptr %dst, i64 %idx +- store i64 %val, ptr %1 +- ret void +-} +- +-;; Check load from and store to an i1 location. +-define i64 @load_sext_zext_anyext_i1(ptr %a) nounwind { +- ;; sextload i1 +-; LA32-LABEL: load_sext_zext_anyext_i1: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.b $a1, $a0, 0 +-; LA32-NEXT: ld.bu $a1, $a0, 1 +-; LA32-NEXT: ld.bu $a2, $a0, 2 +-; LA32-NEXT: sub.w $a0, $a2, $a1 +-; LA32-NEXT: sltu $a1, $a2, $a1 +-; LA32-NEXT: sub.w $a1, $zero, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_sext_zext_anyext_i1: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.b $a1, $a0, 0 +-; LA64-NEXT: ld.bu $a1, $a0, 1 +-; LA64-NEXT: ld.bu $a0, $a0, 2 +-; LA64-NEXT: sub.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = getelementptr i1, ptr %a, i64 1 +- %2 = load i1, ptr %1 +- %3 = sext i1 %2 to i64 +- ;; zextload i1 +- %4 = getelementptr i1, ptr %a, i64 2 +- %5 = load i1, ptr %4 +- %6 = zext i1 %5 to i64 +- %7 = add i64 %3, %6 +- ;; extload i1 (anyext). Produced as the load is unused. +- %8 = load volatile i1, ptr %a +- ret i64 %7 +-} +- +-define i16 @load_sext_zext_anyext_i1_i16(ptr %a) nounwind { +- ;; sextload i1 +-; LA32-LABEL: load_sext_zext_anyext_i1_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.b $a1, $a0, 0 +-; LA32-NEXT: ld.bu $a1, $a0, 1 +-; LA32-NEXT: ld.bu $a0, $a0, 2 +-; LA32-NEXT: sub.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_sext_zext_anyext_i1_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.b $a1, $a0, 0 +-; LA64-NEXT: ld.bu $a1, $a0, 1 +-; LA64-NEXT: ld.bu $a0, $a0, 2 +-; LA64-NEXT: sub.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = getelementptr i1, ptr %a, i64 1 +- %2 = load i1, ptr %1 +- %3 = sext i1 %2 to i16 +- ;; zextload i1 +- %4 = getelementptr i1, ptr %a, i64 2 +- %5 = load i1, ptr %4 +- %6 = zext i1 %5 to i16 +- %7 = add i16 %3, %6 +- ;; extload i1 (anyext). Produced as the load is unused. +- %8 = load volatile i1, ptr %a +- ret i16 %7 +-} +- +-define i64 @ld_sd_constant(i64 %a) nounwind { +-; LA32-LABEL: ld_sd_constant: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a3, -136485 +-; LA32-NEXT: ori $a4, $a3, 3823 +-; LA32-NEXT: ld.w $a2, $a4, 0 +-; LA32-NEXT: st.w $a0, $a4, 0 +-; LA32-NEXT: ori $a0, $a3, 3827 +-; LA32-NEXT: ld.w $a3, $a0, 0 +-; LA32-NEXT: st.w $a1, $a0, 0 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: move $a1, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ld_sd_constant: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a1, -136485 +-; LA64-NEXT: ori $a1, $a1, 3823 +-; LA64-NEXT: lu32i.d $a1, -147729 +-; LA64-NEXT: lu52i.d $a2, $a1, -534 +-; LA64-NEXT: ld.d $a1, $a2, 0 +-; LA64-NEXT: st.d $a0, $a2, 0 +-; LA64-NEXT: move $a0, $a1 +-; LA64-NEXT: ret +- %1 = inttoptr i64 16045690984833335023 to ptr +- %2 = load volatile i64, ptr %1 +- store i64 %a, ptr %1 +- ret i64 %2 +-} +- +-;; Check load from and store to a float location. +-define float @load_store_float(ptr %a, float %b) nounwind { +-; ALL-LABEL: load_store_float: +-; ALL: # %bb.0: +-; ALL-NEXT: fld.s $fa1, $a0, 4 +-; ALL-NEXT: fst.s $fa0, $a0, 4 +-; ALL-NEXT: fmov.s $fa0, $fa1 +-; ALL-NEXT: ret +- %1 = getelementptr float, ptr %a, i64 1 +- %2 = load float, ptr %1 +- store float %b, ptr %1 +- ret float %2 +-} +- +-;; Check load from and store to a double location. +-define double @load_store_double(ptr %a, double %b) nounwind { +-; ALL-LABEL: load_store_double: +-; ALL: # %bb.0: +-; ALL-NEXT: fld.d $fa1, $a0, 8 +-; ALL-NEXT: fst.d $fa0, $a0, 8 +-; ALL-NEXT: fmov.d $fa0, $fa1 +-; ALL-NEXT: ret +- %1 = getelementptr double, ptr %a, i64 1 +- %2 = load double, ptr %1 +- store double %b, ptr %1 +- ret double %2 +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/lshr.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/lshr.ll +deleted file mode 100644 +index 3916298e2..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/lshr.ll ++++ /dev/null +@@ -1,161 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-;; Exercise the 'lshr' LLVM IR: https://llvm.org/docs/LangRef.html#lshr-instruction +- +-define i1 @lshr_i1(i1 %x, i1 %y) { +-; LA32-LABEL: lshr_i1: +-; LA32: # %bb.0: +-; LA32-NEXT: ret +-; +-; LA64-LABEL: lshr_i1: +-; LA64: # %bb.0: +-; LA64-NEXT: ret +- %lshr = lshr i1 %x, %y +- ret i1 %lshr +-} +- +-define i8 @lshr_i8(i8 %x, i8 %y) { +-; LA32-LABEL: lshr_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a0, $a0, 255 +-; LA32-NEXT: srl.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: lshr_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 255 +-; LA64-NEXT: srl.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %lshr = lshr i8 %x, %y +- ret i8 %lshr +-} +- +-define i16 @lshr_i16(i16 %x, i16 %y) { +-; LA32-LABEL: lshr_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: bstrpick.w $a0, $a0, 15, 0 +-; LA32-NEXT: srl.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: lshr_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a0, $a0, 15, 0 +-; LA64-NEXT: srl.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %lshr = lshr i16 %x, %y +- ret i16 %lshr +-} +- +-define i32 @lshr_i32(i32 %x, i32 %y) { +-; LA32-LABEL: lshr_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: srl.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: lshr_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: srl.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %lshr = lshr i32 %x, %y +- ret i32 %lshr +-} +- +-define i64 @lshr_i64(i64 %x, i64 %y) { +-; LA32-LABEL: lshr_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: xori $a3, $a2, 31 +-; LA32-NEXT: slli.w $a4, $a1, 1 +-; LA32-NEXT: sll.w $a3, $a4, $a3 +-; LA32-NEXT: srl.w $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a3 +-; LA32-NEXT: addi.w $a3, $a2, -32 +-; LA32-NEXT: slti $a4, $a3, 0 +-; LA32-NEXT: maskeqz $a0, $a0, $a4 +-; LA32-NEXT: srl.w $a5, $a1, $a3 +-; LA32-NEXT: masknez $a4, $a5, $a4 +-; LA32-NEXT: or $a0, $a0, $a4 +-; LA32-NEXT: srl.w $a1, $a1, $a2 +-; LA32-NEXT: srai.w $a2, $a3, 31 +-; LA32-NEXT: and $a1, $a2, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: lshr_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: srl.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %lshr = lshr i64 %x, %y +- ret i64 %lshr +-} +- +-define i1 @lshr_i1_3(i1 %x) { +-; LA32-LABEL: lshr_i1_3: +-; LA32: # %bb.0: +-; LA32-NEXT: ret +-; +-; LA64-LABEL: lshr_i1_3: +-; LA64: # %bb.0: +-; LA64-NEXT: ret +- %lshr = lshr i1 %x, 3 +- ret i1 %lshr +-} +- +-define i8 @lshr_i8_3(i8 %x) { +-; LA32-LABEL: lshr_i8_3: +-; LA32: # %bb.0: +-; LA32-NEXT: bstrpick.w $a0, $a0, 7, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: lshr_i8_3: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a0, $a0, 7, 3 +-; LA64-NEXT: ret +- %lshr = lshr i8 %x, 3 +- ret i8 %lshr +-} +- +-define i16 @lshr_i16_3(i16 %x) { +-; LA32-LABEL: lshr_i16_3: +-; LA32: # %bb.0: +-; LA32-NEXT: bstrpick.w $a0, $a0, 15, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: lshr_i16_3: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a0, $a0, 15, 3 +-; LA64-NEXT: ret +- %lshr = lshr i16 %x, 3 +- ret i16 %lshr +-} +- +-define i32 @lshr_i32_3(i32 %x) { +-; LA32-LABEL: lshr_i32_3: +-; LA32: # %bb.0: +-; LA32-NEXT: srli.w $a0, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: lshr_i32_3: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a0, $a0, 31, 3 +-; LA64-NEXT: ret +- %lshr = lshr i32 %x, 3 +- ret i32 %lshr +-} +- +-define i64 @lshr_i64_3(i64 %x) { +-; LA32-LABEL: lshr_i64_3: +-; LA32: # %bb.0: +-; LA32-NEXT: srli.w $a0, $a0, 3 +-; LA32-NEXT: slli.w $a2, $a1, 29 +-; LA32-NEXT: or $a0, $a0, $a2 +-; LA32-NEXT: srli.w $a1, $a1, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: lshr_i64_3: +-; LA64: # %bb.0: +-; LA64-NEXT: srli.d $a0, $a0, 3 +-; LA64-NEXT: ret +- %lshr = lshr i64 %x, 3 +- ret i64 %lshr +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/mul.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/mul.ll +deleted file mode 100644 +index 53a352921..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/mul.ll ++++ /dev/null +@@ -1,1521 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-;; Exercise the 'mul' LLVM IR: https://llvm.org/docs/LangRef.html#mul-instruction +- +-define i1 @mul_i1(i1 %a, i1 %b) { +-; LA32-LABEL: mul_i1: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: mul.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i1: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: mul.d $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = mul i1 %a, %b +- ret i1 %r +-} +- +-define i8 @mul_i8(i8 %a, i8 %b) { +-; LA32-LABEL: mul_i8: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: mul.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i8: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: mul.d $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = mul i8 %a, %b +- ret i8 %r +-} +- +-define i16 @mul_i16(i16 %a, i16 %b) { +-; LA32-LABEL: mul_i16: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: mul.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i16: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: mul.d $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = mul i16 %a, %b +- ret i16 %r +-} +- +-define i32 @mul_i32(i32 %a, i32 %b) { +-; LA32-LABEL: mul_i32: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: mul.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: mul.d $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = mul i32 %a, %b +- ret i32 %r +-} +- +-define i64 @mul_i64(i64 %a, i64 %b) { +-; LA32-LABEL: mul_i64: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: mul.w $a3, $a0, $a3 +-; LA32-NEXT: mulh.wu $a4, $a0, $a2 +-; LA32-NEXT: add.w $a3, $a4, $a3 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: mul.d $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = mul i64 %a, %b +- ret i64 %r +-} +- +-define i64 @mul_pow2(i64 %a) { +-; LA32-LABEL: mul_pow2: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a1, 3 +-; LA32-NEXT: srli.w $a2, $a0, 29 +-; LA32-NEXT: or $a1, $a1, $a2 +-; LA32-NEXT: slli.w $a0, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_pow2: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a0, $a0, 3 +-; LA64-NEXT: ret +- %1 = mul i64 %a, 8 +- ret i64 %1 +-} +- +-define i64 @mul_p5(i64 %a) { +-; LA32-LABEL: mul_p5: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 5 +-; LA32-NEXT: mulh.wu $a2, $a0, $a2 +-; LA32-NEXT: alsl.w $a1, $a1, $a1, 2 +-; LA32-NEXT: add.w $a1, $a2, $a1 +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_p5: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 2 +-; LA64-NEXT: ret +- %1 = mul i64 %a, 5 +- ret i64 %1 +-} +- +-define i32 @mulh_w(i32 %a, i32 %b) { +-; LA32-LABEL: mulh_w: +-; LA32: # %bb.0: +-; LA32-NEXT: mulh.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mulh_w: +-; LA64: # %bb.0: +-; LA64-NEXT: mulw.d.w $a0, $a0, $a1 +-; LA64-NEXT: srli.d $a0, $a0, 32 +-; LA64-NEXT: ret +- %1 = sext i32 %a to i64 +- %2 = sext i32 %b to i64 +- %3 = mul i64 %1, %2 +- %4 = lshr i64 %3, 32 +- %5 = trunc i64 %4 to i32 +- ret i32 %5 +-} +- +-define i32 @mulh_wu(i32 %a, i32 %b) { +-; LA32-LABEL: mulh_wu: +-; LA32: # %bb.0: +-; LA32-NEXT: mulh.wu $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mulh_wu: +-; LA64: # %bb.0: +-; LA64-NEXT: mulw.d.wu $a0, $a0, $a1 +-; LA64-NEXT: srli.d $a0, $a0, 32 +-; LA64-NEXT: ret +- %1 = zext i32 %a to i64 +- %2 = zext i32 %b to i64 +- %3 = mul i64 %1, %2 +- %4 = lshr i64 %3, 32 +- %5 = trunc i64 %4 to i32 +- ret i32 %5 +-} +- +-define i64 @mulh_d(i64 %a, i64 %b) { +-; LA32-LABEL: mulh_d: +-; LA32: # %bb.0: +-; LA32-NEXT: mulh.wu $a4, $a0, $a2 +-; LA32-NEXT: mul.w $a5, $a1, $a2 +-; LA32-NEXT: add.w $a4, $a5, $a4 +-; LA32-NEXT: sltu $a5, $a4, $a5 +-; LA32-NEXT: mulh.wu $a6, $a1, $a2 +-; LA32-NEXT: add.w $a5, $a6, $a5 +-; LA32-NEXT: mul.w $a6, $a0, $a3 +-; LA32-NEXT: add.w $a4, $a6, $a4 +-; LA32-NEXT: sltu $a4, $a4, $a6 +-; LA32-NEXT: mulh.wu $a6, $a0, $a3 +-; LA32-NEXT: add.w $a4, $a6, $a4 +-; LA32-NEXT: add.w $a4, $a5, $a4 +-; LA32-NEXT: sltu $a5, $a4, $a5 +-; LA32-NEXT: mulh.wu $a6, $a1, $a3 +-; LA32-NEXT: add.w $a5, $a6, $a5 +-; LA32-NEXT: mul.w $a6, $a1, $a3 +-; LA32-NEXT: add.w $a4, $a6, $a4 +-; LA32-NEXT: sltu $a6, $a4, $a6 +-; LA32-NEXT: add.w $a5, $a5, $a6 +-; LA32-NEXT: srai.w $a6, $a1, 31 +-; LA32-NEXT: mul.w $a7, $a2, $a6 +-; LA32-NEXT: mulh.wu $a2, $a2, $a6 +-; LA32-NEXT: add.w $a2, $a2, $a7 +-; LA32-NEXT: mul.w $a6, $a3, $a6 +-; LA32-NEXT: add.w $a2, $a2, $a6 +-; LA32-NEXT: srai.w $a3, $a3, 31 +-; LA32-NEXT: mul.w $a1, $a3, $a1 +-; LA32-NEXT: mulh.wu $a6, $a3, $a0 +-; LA32-NEXT: add.w $a1, $a6, $a1 +-; LA32-NEXT: mul.w $a0, $a3, $a0 +-; LA32-NEXT: add.w $a1, $a1, $a0 +-; LA32-NEXT: add.w $a1, $a1, $a2 +-; LA32-NEXT: add.w $a2, $a0, $a7 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: add.w $a0, $a1, $a0 +-; LA32-NEXT: add.w $a1, $a5, $a0 +-; LA32-NEXT: add.w $a0, $a4, $a2 +-; LA32-NEXT: sltu $a2, $a0, $a4 +-; LA32-NEXT: add.w $a1, $a1, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mulh_d: +-; LA64: # %bb.0: +-; LA64-NEXT: mulh.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = sext i64 %a to i128 +- %2 = sext i64 %b to i128 +- %3 = mul i128 %1, %2 +- %4 = lshr i128 %3, 64 +- %5 = trunc i128 %4 to i64 +- ret i64 %5 +-} +- +-define i64 @mulh_du(i64 %a, i64 %b) { +-; LA32-LABEL: mulh_du: +-; LA32: # %bb.0: +-; LA32-NEXT: mulh.wu $a4, $a0, $a2 +-; LA32-NEXT: mul.w $a5, $a1, $a2 +-; LA32-NEXT: add.w $a4, $a5, $a4 +-; LA32-NEXT: sltu $a5, $a4, $a5 +-; LA32-NEXT: mulh.wu $a2, $a1, $a2 +-; LA32-NEXT: add.w $a2, $a2, $a5 +-; LA32-NEXT: mul.w $a5, $a0, $a3 +-; LA32-NEXT: add.w $a4, $a5, $a4 +-; LA32-NEXT: sltu $a4, $a4, $a5 +-; LA32-NEXT: mulh.wu $a0, $a0, $a3 +-; LA32-NEXT: add.w $a0, $a0, $a4 +-; LA32-NEXT: mul.w $a4, $a1, $a3 +-; LA32-NEXT: mulh.wu $a1, $a1, $a3 +-; LA32-NEXT: add.w $a0, $a2, $a0 +-; LA32-NEXT: sltu $a2, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a1, $a2 +-; LA32-NEXT: add.w $a0, $a4, $a0 +-; LA32-NEXT: sltu $a2, $a0, $a4 +-; LA32-NEXT: add.w $a1, $a1, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mulh_du: +-; LA64: # %bb.0: +-; LA64-NEXT: mulh.du $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = zext i64 %a to i128 +- %2 = zext i64 %b to i128 +- %3 = mul i128 %1, %2 +- %4 = lshr i128 %3, 64 +- %5 = trunc i128 %4 to i64 +- ret i64 %5 +-} +- +-define i64 @mulw_d_w(i32 %a, i32 %b) { +-; LA32-LABEL: mulw_d_w: +-; LA32: # %bb.0: +-; LA32-NEXT: mul.w $a2, $a0, $a1 +-; LA32-NEXT: mulh.w $a1, $a0, $a1 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mulw_d_w: +-; LA64: # %bb.0: +-; LA64-NEXT: mulw.d.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = sext i32 %a to i64 +- %2 = sext i32 %b to i64 +- %3 = mul i64 %1, %2 +- ret i64 %3 +-} +- +-define i64 @mulw_d_wu(i32 %a, i32 %b) { +-; LA32-LABEL: mulw_d_wu: +-; LA32: # %bb.0: +-; LA32-NEXT: mul.w $a2, $a0, $a1 +-; LA32-NEXT: mulh.wu $a1, $a0, $a1 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mulw_d_wu: +-; LA64: # %bb.0: +-; LA64-NEXT: mulw.d.wu $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = zext i32 %a to i64 +- %2 = zext i32 %b to i64 +- %3 = mul i64 %1, %2 +- ret i64 %3 +-} +- +-define signext i32 @mul_i32_11(i32 %a) { +-; LA32-LABEL: mul_i32_11: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a1, $a0, $a0, 2 +-; LA32-NEXT: alsl.w $a0, $a1, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_11: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a1, $a0, $a0, 2 +-; LA64-NEXT: alsl.w $a0, $a1, $a0, 1 +-; LA64-NEXT: ret +- %b = mul i32 %a, 11 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_13(i32 %a) { +-; LA32-LABEL: mul_i32_13: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a1, $a0, $a0, 1 +-; LA32-NEXT: alsl.w $a0, $a1, $a0, 2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_13: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a1, $a0, $a0, 1 +-; LA64-NEXT: alsl.w $a0, $a1, $a0, 2 +-; LA64-NEXT: ret +- %b = mul i32 %a, 13 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_19(i32 %a) { +-; LA32-LABEL: mul_i32_19: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a1, $a0, $a0, 3 +-; LA32-NEXT: alsl.w $a0, $a1, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_19: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a1, $a0, $a0, 3 +-; LA64-NEXT: alsl.w $a0, $a1, $a0, 1 +-; LA64-NEXT: ret +- %b = mul i32 %a, 19 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_21(i32 %a) { +-; LA32-LABEL: mul_i32_21: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a1, $a0, $a0, 2 +-; LA32-NEXT: alsl.w $a0, $a1, $a0, 2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_21: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a1, $a0, $a0, 2 +-; LA64-NEXT: alsl.w $a0, $a1, $a0, 2 +-; LA64-NEXT: ret +- %b = mul i32 %a, 21 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_25(i32 %a) { +-; LA32-LABEL: mul_i32_25: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a1, $a0, $a0, 1 +-; LA32-NEXT: alsl.w $a0, $a1, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_25: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a1, $a0, $a0, 1 +-; LA64-NEXT: alsl.w $a0, $a1, $a0, 3 +-; LA64-NEXT: ret +- %b = mul i32 %a, 25 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_27(i32 %a) { +-; LA32-LABEL: mul_i32_27: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 1 +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_27: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a0, $a0, $a0, 1 +-; LA64-NEXT: alsl.w $a0, $a0, $a0, 3 +-; LA64-NEXT: ret +- %b = mul i32 %a, 27 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_35(i32 %a) { +-; LA32-LABEL: mul_i32_35: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a1, $a0, $a0, 4 +-; LA32-NEXT: alsl.w $a0, $a1, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_35: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a1, $a0, $a0, 4 +-; LA64-NEXT: alsl.w $a0, $a1, $a0, 1 +-; LA64-NEXT: ret +- %b = mul i32 %a, 35 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_37(i32 %a) { +-; LA32-LABEL: mul_i32_37: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a1, $a0, $a0, 3 +-; LA32-NEXT: alsl.w $a0, $a1, $a0, 2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_37: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a1, $a0, $a0, 3 +-; LA64-NEXT: alsl.w $a0, $a1, $a0, 2 +-; LA64-NEXT: ret +- %b = mul i32 %a, 37 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_41(i32 %a) { +-; LA32-LABEL: mul_i32_41: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a1, $a0, $a0, 2 +-; LA32-NEXT: alsl.w $a0, $a1, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_41: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a1, $a0, $a0, 2 +-; LA64-NEXT: alsl.w $a0, $a1, $a0, 3 +-; LA64-NEXT: ret +- %b = mul i32 %a, 41 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_45(i32 %a) { +-; LA32-LABEL: mul_i32_45: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 2 +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_45: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a0, $a0, $a0, 2 +-; LA64-NEXT: alsl.w $a0, $a0, $a0, 3 +-; LA64-NEXT: ret +- %b = mul i32 %a, 45 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_49(i32 %a) { +-; LA32-LABEL: mul_i32_49: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a1, $a0, $a0, 1 +-; LA32-NEXT: alsl.w $a0, $a1, $a0, 4 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_49: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a1, $a0, $a0, 1 +-; LA64-NEXT: alsl.w $a0, $a1, $a0, 4 +-; LA64-NEXT: ret +- %b = mul i32 %a, 49 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_51(i32 %a) { +-; LA32-LABEL: mul_i32_51: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 1 +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 4 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_51: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a0, $a0, $a0, 1 +-; LA64-NEXT: alsl.w $a0, $a0, $a0, 4 +-; LA64-NEXT: ret +- %b = mul i32 %a, 51 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_69(i32 %a) { +-; LA32-LABEL: mul_i32_69: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a1, $a0, $a0, 4 +-; LA32-NEXT: alsl.w $a0, $a1, $a0, 2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_69: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a1, $a0, $a0, 4 +-; LA64-NEXT: alsl.w $a0, $a1, $a0, 2 +-; LA64-NEXT: ret +- %b = mul i32 %a, 69 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_73(i32 %a) { +-; LA32-LABEL: mul_i32_73: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a1, $a0, $a0, 3 +-; LA32-NEXT: alsl.w $a0, $a1, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_73: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a1, $a0, $a0, 3 +-; LA64-NEXT: alsl.w $a0, $a1, $a0, 3 +-; LA64-NEXT: ret +- %b = mul i32 %a, 73 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_81(i32 %a) { +-; LA32-LABEL: mul_i32_81: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a1, $a0, $a0, 2 +-; LA32-NEXT: alsl.w $a0, $a1, $a0, 4 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_81: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a1, $a0, $a0, 2 +-; LA64-NEXT: alsl.w $a0, $a1, $a0, 4 +-; LA64-NEXT: ret +- %b = mul i32 %a, 81 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_85(i32 %a) { +-; LA32-LABEL: mul_i32_85: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 2 +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 4 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_85: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a0, $a0, $a0, 2 +-; LA64-NEXT: alsl.w $a0, $a0, $a0, 4 +-; LA64-NEXT: ret +- %b = mul i32 %a, 85 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_137(i32 %a) { +-; LA32-LABEL: mul_i32_137: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a1, $a0, $a0, 4 +-; LA32-NEXT: alsl.w $a0, $a1, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_137: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a1, $a0, $a0, 4 +-; LA64-NEXT: alsl.w $a0, $a1, $a0, 3 +-; LA64-NEXT: ret +- %b = mul i32 %a, 137 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_145(i32 %a) { +-; LA32-LABEL: mul_i32_145: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a1, $a0, $a0, 3 +-; LA32-NEXT: alsl.w $a0, $a1, $a0, 4 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_145: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a1, $a0, $a0, 3 +-; LA64-NEXT: alsl.w $a0, $a1, $a0, 4 +-; LA64-NEXT: ret +- %b = mul i32 %a, 145 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_153(i32 %a) { +-; LA32-LABEL: mul_i32_153: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 3 +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 4 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_153: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a0, $a0, $a0, 3 +-; LA64-NEXT: alsl.w $a0, $a0, $a0, 4 +-; LA64-NEXT: ret +- %b = mul i32 %a, 153 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_273(i32 %a) { +-; LA32-LABEL: mul_i32_273: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a1, $a0, $a0, 4 +-; LA32-NEXT: alsl.w $a0, $a1, $a0, 4 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_273: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a1, $a0, $a0, 4 +-; LA64-NEXT: alsl.w $a0, $a1, $a0, 4 +-; LA64-NEXT: ret +- %b = mul i32 %a, 273 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_289(i32 %a) { +-; LA32-LABEL: mul_i32_289: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 4 +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 4 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_289: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a0, $a0, $a0, 4 +-; LA64-NEXT: alsl.w $a0, $a0, $a0, 4 +-; LA64-NEXT: ret +- %b = mul i32 %a, 289 +- ret i32 %b +-} +- +-define i64 @mul_i64_11(i64 %a) { +-; LA32-LABEL: mul_i64_11: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 11 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_11: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a1, $a0, $a0, 2 +-; LA64-NEXT: alsl.d $a0, $a1, $a0, 1 +-; LA64-NEXT: ret +- %b = mul i64 %a, 11 +- ret i64 %b +-} +- +-define i64 @mul_i64_13(i64 %a) { +-; LA32-LABEL: mul_i64_13: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 13 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_13: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a1, $a0, $a0, 1 +-; LA64-NEXT: alsl.d $a0, $a1, $a0, 2 +-; LA64-NEXT: ret +- %b = mul i64 %a, 13 +- ret i64 %b +-} +- +-define i64 @mul_i64_19(i64 %a) { +-; LA32-LABEL: mul_i64_19: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 19 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_19: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a1, $a0, $a0, 3 +-; LA64-NEXT: alsl.d $a0, $a1, $a0, 1 +-; LA64-NEXT: ret +- %b = mul i64 %a, 19 +- ret i64 %b +-} +- +-define i64 @mul_i64_21(i64 %a) { +-; LA32-LABEL: mul_i64_21: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 21 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_21: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a1, $a0, $a0, 2 +-; LA64-NEXT: alsl.d $a0, $a1, $a0, 2 +-; LA64-NEXT: ret +- %b = mul i64 %a, 21 +- ret i64 %b +-} +- +-define i64 @mul_i64_25(i64 %a) { +-; LA32-LABEL: mul_i64_25: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 25 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_25: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a1, $a0, $a0, 1 +-; LA64-NEXT: alsl.d $a0, $a1, $a0, 3 +-; LA64-NEXT: ret +- %b = mul i64 %a, 25 +- ret i64 %b +-} +- +-define i64 @mul_i64_27(i64 %a) { +-; LA32-LABEL: mul_i64_27: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 27 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_27: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 1 +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 3 +-; LA64-NEXT: ret +- %b = mul i64 %a, 27 +- ret i64 %b +-} +- +-define i64 @mul_i64_35(i64 %a) { +-; LA32-LABEL: mul_i64_35: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 35 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_35: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a1, $a0, $a0, 4 +-; LA64-NEXT: alsl.d $a0, $a1, $a0, 1 +-; LA64-NEXT: ret +- %b = mul i64 %a, 35 +- ret i64 %b +-} +- +-define i64 @mul_i64_37(i64 %a) { +-; LA32-LABEL: mul_i64_37: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 37 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_37: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a1, $a0, $a0, 3 +-; LA64-NEXT: alsl.d $a0, $a1, $a0, 2 +-; LA64-NEXT: ret +- %b = mul i64 %a, 37 +- ret i64 %b +-} +- +-define i64 @mul_i64_41(i64 %a) { +-; LA32-LABEL: mul_i64_41: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 41 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_41: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a1, $a0, $a0, 2 +-; LA64-NEXT: alsl.d $a0, $a1, $a0, 3 +-; LA64-NEXT: ret +- %b = mul i64 %a, 41 +- ret i64 %b +-} +- +-define i64 @mul_i64_45(i64 %a) { +-; LA32-LABEL: mul_i64_45: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 45 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_45: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 2 +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 3 +-; LA64-NEXT: ret +- %b = mul i64 %a, 45 +- ret i64 %b +-} +- +-define i64 @mul_i64_49(i64 %a) { +-; LA32-LABEL: mul_i64_49: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 49 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_49: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a1, $a0, $a0, 1 +-; LA64-NEXT: alsl.d $a0, $a1, $a0, 4 +-; LA64-NEXT: ret +- %b = mul i64 %a, 49 +- ret i64 %b +-} +- +-define i64 @mul_i64_51(i64 %a) { +-; LA32-LABEL: mul_i64_51: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 51 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_51: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 1 +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 4 +-; LA64-NEXT: ret +- %b = mul i64 %a, 51 +- ret i64 %b +-} +- +-define i64 @mul_i64_69(i64 %a) { +-; LA32-LABEL: mul_i64_69: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 69 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_69: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a1, $a0, $a0, 4 +-; LA64-NEXT: alsl.d $a0, $a1, $a0, 2 +-; LA64-NEXT: ret +- %b = mul i64 %a, 69 +- ret i64 %b +-} +- +-define i64 @mul_i64_73(i64 %a) { +-; LA32-LABEL: mul_i64_73: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 73 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_73: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a1, $a0, $a0, 3 +-; LA64-NEXT: alsl.d $a0, $a1, $a0, 3 +-; LA64-NEXT: ret +- %b = mul i64 %a, 73 +- ret i64 %b +-} +- +-define i64 @mul_i64_81(i64 %a) { +-; LA32-LABEL: mul_i64_81: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 81 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_81: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a1, $a0, $a0, 2 +-; LA64-NEXT: alsl.d $a0, $a1, $a0, 4 +-; LA64-NEXT: ret +- %b = mul i64 %a, 81 +- ret i64 %b +-} +- +-define i64 @mul_i64_85(i64 %a) { +-; LA32-LABEL: mul_i64_85: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 85 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_85: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 2 +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 4 +-; LA64-NEXT: ret +- %b = mul i64 %a, 85 +- ret i64 %b +-} +- +-define i64 @mul_i64_137(i64 %a) { +-; LA32-LABEL: mul_i64_137: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 137 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_137: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a1, $a0, $a0, 4 +-; LA64-NEXT: alsl.d $a0, $a1, $a0, 3 +-; LA64-NEXT: ret +- %b = mul i64 %a, 137 +- ret i64 %b +-} +- +-define i64 @mul_i64_145(i64 %a) { +-; LA32-LABEL: mul_i64_145: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 145 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_145: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a1, $a0, $a0, 3 +-; LA64-NEXT: alsl.d $a0, $a1, $a0, 4 +-; LA64-NEXT: ret +- %b = mul i64 %a, 145 +- ret i64 %b +-} +- +-define i64 @mul_i64_153(i64 %a) { +-; LA32-LABEL: mul_i64_153: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 153 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_153: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 3 +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 4 +-; LA64-NEXT: ret +- %b = mul i64 %a, 153 +- ret i64 %b +-} +- +-define i64 @mul_i64_273(i64 %a) { +-; LA32-LABEL: mul_i64_273: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 273 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_273: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a1, $a0, $a0, 4 +-; LA64-NEXT: alsl.d $a0, $a1, $a0, 4 +-; LA64-NEXT: ret +- %b = mul i64 %a, 273 +- ret i64 %b +-} +- +-define i64 @mul_i64_289(i64 %a) { +-; LA32-LABEL: mul_i64_289: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 289 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_289: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 4 +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 4 +-; LA64-NEXT: ret +- %b = mul i64 %a, 289 +- ret i64 %b +-} +- +-define signext i32 @mul_i32_4098(i32 %a) { +-; LA32-LABEL: mul_i32_4098: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a0, 12 +-; LA32-NEXT: alsl.w $a0, $a0, $a1, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_4098: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 12 +-; LA64-NEXT: alsl.w $a0, $a0, $a1, 1 +-; LA64-NEXT: ret +- %b = mul i32 %a, 4098 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_4100(i32 %a) { +-; LA32-LABEL: mul_i32_4100: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a0, 12 +-; LA32-NEXT: alsl.w $a0, $a0, $a1, 2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_4100: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 12 +-; LA64-NEXT: alsl.w $a0, $a0, $a1, 2 +-; LA64-NEXT: ret +- %b = mul i32 %a, 4100 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_4104(i32 %a) { +-; LA32-LABEL: mul_i32_4104: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a0, 12 +-; LA32-NEXT: alsl.w $a0, $a0, $a1, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_4104: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 12 +-; LA64-NEXT: alsl.w $a0, $a0, $a1, 3 +-; LA64-NEXT: ret +- %b = mul i32 %a, 4104 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_4112(i32 %a) { +-; LA32-LABEL: mul_i32_4112: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a0, 12 +-; LA32-NEXT: alsl.w $a0, $a0, $a1, 4 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_4112: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 12 +-; LA64-NEXT: alsl.w $a0, $a0, $a1, 4 +-; LA64-NEXT: ret +- %b = mul i32 %a, 4112 +- ret i32 %b +-} +- +-define i64 @mul_i64_4098(i64 %a) { +-; LA32-LABEL: mul_i64_4098: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 1 +-; LA32-NEXT: ori $a2, $a2, 2 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_4098: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 12 +-; LA64-NEXT: alsl.d $a0, $a0, $a1, 1 +-; LA64-NEXT: ret +- %b = mul i64 %a, 4098 +- ret i64 %b +-} +- +-define i64 @mul_i64_4100(i64 %a) { +-; LA32-LABEL: mul_i64_4100: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 1 +-; LA32-NEXT: ori $a2, $a2, 4 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_4100: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 12 +-; LA64-NEXT: alsl.d $a0, $a0, $a1, 2 +-; LA64-NEXT: ret +- %b = mul i64 %a, 4100 +- ret i64 %b +-} +- +-define i64 @mul_i64_4104(i64 %a) { +-; LA32-LABEL: mul_i64_4104: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 1 +-; LA32-NEXT: ori $a2, $a2, 8 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_4104: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 12 +-; LA64-NEXT: alsl.d $a0, $a0, $a1, 3 +-; LA64-NEXT: ret +- %b = mul i64 %a, 4104 +- ret i64 %b +-} +- +-define i64 @mul_i64_4112(i64 %a) { +-; LA32-LABEL: mul_i64_4112: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 1 +-; LA32-NEXT: ori $a2, $a2, 16 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_4112: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 12 +-; LA64-NEXT: alsl.d $a0, $a0, $a1, 4 +-; LA64-NEXT: ret +- %b = mul i64 %a, 4112 +- ret i64 %b +-} +- +-define signext i32 @mul_i32_768(i32 %a) { +-; LA32-LABEL: mul_i32_768: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 1 +-; LA32-NEXT: slli.w $a0, $a0, 8 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_768: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a0, $a0, $a0, 1 +-; LA64-NEXT: slli.w $a0, $a0, 8 +-; LA64-NEXT: ret +- %b = mul i32 %a, 768 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_1280(i32 %a) { +-; LA32-LABEL: mul_i32_1280: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 2 +-; LA32-NEXT: slli.w $a0, $a0, 8 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_1280: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a0, $a0, $a0, 2 +-; LA64-NEXT: slli.w $a0, $a0, 8 +-; LA64-NEXT: ret +- %b = mul i32 %a, 1280 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_2304(i32 %a) { +-; LA32-LABEL: mul_i32_2304: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 3 +-; LA32-NEXT: slli.w $a0, $a0, 8 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_2304: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a0, $a0, $a0, 3 +-; LA64-NEXT: slli.w $a0, $a0, 8 +-; LA64-NEXT: ret +- %b = mul i32 %a, 2304 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_4352(i32 %a) { +-; LA32-LABEL: mul_i32_4352: +-; LA32: # %bb.0: +-; LA32-NEXT: alsl.w $a0, $a0, $a0, 4 +-; LA32-NEXT: slli.w $a0, $a0, 8 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_4352: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.w $a0, $a0, $a0, 4 +-; LA64-NEXT: slli.w $a0, $a0, 8 +-; LA64-NEXT: ret +- %b = mul i32 %a, 4352 +- ret i32 %b +-} +- +-define i64 @mul_i64_768(i64 %a) { +-; LA32-LABEL: mul_i64_768: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 768 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_768: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 1 +-; LA64-NEXT: slli.d $a0, $a0, 8 +-; LA64-NEXT: ret +- %b = mul i64 %a, 768 +- ret i64 %b +-} +- +-define i64 @mul_i64_1280(i64 %a) { +-; LA32-LABEL: mul_i64_1280: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 1280 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_1280: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 2 +-; LA64-NEXT: slli.d $a0, $a0, 8 +-; LA64-NEXT: ret +- %b = mul i64 %a, 1280 +- ret i64 %b +-} +- +-define i64 @mul_i64_2304(i64 %a) { +-; LA32-LABEL: mul_i64_2304: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 2304 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_2304: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 3 +-; LA64-NEXT: slli.d $a0, $a0, 8 +-; LA64-NEXT: ret +- %b = mul i64 %a, 2304 +- ret i64 %b +-} +- +-define i64 @mul_i64_4352(i64 %a) { +-; LA32-LABEL: mul_i64_4352: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 1 +-; LA32-NEXT: ori $a2, $a2, 256 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_4352: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 4 +-; LA64-NEXT: slli.d $a0, $a0, 8 +-; LA64-NEXT: ret +- %b = mul i64 %a, 4352 +- ret i64 %b +-} +- +-define signext i32 @mul_i32_65792(i32 %a) { +-; LA32-LABEL: mul_i32_65792: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a0, 8 +-; LA32-NEXT: slli.w $a0, $a0, 16 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_65792: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 8 +-; LA64-NEXT: slli.d $a0, $a0, 16 +-; LA64-NEXT: add.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %b = mul i32 %a, 65792 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_65280(i32 %a) { +-; LA32-LABEL: mul_i32_65280: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a0, 8 +-; LA32-NEXT: slli.w $a0, $a0, 16 +-; LA32-NEXT: sub.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_65280: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 8 +-; LA64-NEXT: slli.d $a0, $a0, 16 +-; LA64-NEXT: sub.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %b = mul i32 %a, 65280 +- ret i32 %b +-} +- +-define signext i32 @mul_i32_minus_65280(i32 %a) { +-; LA32-LABEL: mul_i32_minus_65280: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a0, 16 +-; LA32-NEXT: slli.w $a0, $a0, 8 +-; LA32-NEXT: sub.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i32_minus_65280: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 16 +-; LA64-NEXT: slli.d $a0, $a0, 8 +-; LA64-NEXT: sub.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %b = mul i32 %a, -65280 +- ret i32 %b +-} +- +-define i64 @mul_i64_65792(i64 %a) { +-; LA32-LABEL: mul_i64_65792: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 16 +-; LA32-NEXT: ori $a2, $a2, 256 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_65792: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 8 +-; LA64-NEXT: slli.d $a0, $a0, 16 +-; LA64-NEXT: add.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %b = mul i64 %a, 65792 +- ret i64 %b +-} +- +-define i64 @mul_i64_65280(i64 %a) { +-; LA32-LABEL: mul_i64_65280: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 15 +-; LA32-NEXT: ori $a2, $a2, 3840 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_65280: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 8 +-; LA64-NEXT: slli.d $a0, $a0, 16 +-; LA64-NEXT: sub.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %b = mul i64 %a, 65280 +- ret i64 %b +-} +- +-define i64 @mul_i64_minus_65280(i64 %a) { +-; LA32-LABEL: mul_i64_minus_65280: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, -16 +-; LA32-NEXT: ori $a2, $a2, 256 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: sub.w $a3, $a3, $a0 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_minus_65280: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 16 +-; LA64-NEXT: slli.d $a0, $a0, 8 +-; LA64-NEXT: sub.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %b = mul i64 %a, -65280 +- ret i64 %b +-} +- +-;; This multiplication is not transformed, due to +-;; 1088 can be composed via a single ORI. +-define i64 @mul_i64_1088(i64 %a) { +-; LA32-LABEL: mul_i64_1088: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 1088 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_1088: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 4 +-; LA64-NEXT: slli.d $a0, $a0, 6 +-; LA64-NEXT: ret +- %b = mul i64 %a, 1088 +- ret i64 %b +-} +- +-;; This multiplication is not transformed, due to +-;; -992 can be composed via a single ADDI. +-define i64 @mul_i64_minus_992(i64 %a) { +-; LA32-LABEL: mul_i64_minus_992: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a2, $zero, -992 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: sub.w $a3, $a3, $a0 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_minus_992: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.w $a1, $zero, -992 +-; LA64-NEXT: mul.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %b = mul i64 %a, -992 +- ret i64 %b +-} +- +-;; This multiplication is not transformed, due to +-;; 4456448 can be composed via a single LUI. +-define i64 @mul_i64_4456448(i64 %a) { +-; LA32-LABEL: mul_i64_4456448: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 1088 +-; LA32-NEXT: mul.w $a1, $a1, $a2 +-; LA32-NEXT: mulh.wu $a3, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a3, $a1 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_4456448: +-; LA64: # %bb.0: +-; LA64-NEXT: alsl.d $a0, $a0, $a0, 4 +-; LA64-NEXT: slli.d $a0, $a0, 18 +-; LA64-NEXT: ret +- %b = mul i64 %a, 4456448 +- ret i64 %b +-} +- +-;; This multiplication is not transformed, due to +-;; 65280 is used multiple times. +-define i64 @mul_i64_65280_twice(i64 %a, i64 %b) { +-; LA32-LABEL: mul_i64_65280_twice: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a4, 15 +-; LA32-NEXT: ori $a4, $a4, 3840 +-; LA32-NEXT: mul.w $a3, $a3, $a4 +-; LA32-NEXT: mulh.wu $a5, $a2, $a4 +-; LA32-NEXT: add.w $a3, $a5, $a3 +-; LA32-NEXT: mul.w $a1, $a1, $a4 +-; LA32-NEXT: mulh.wu $a5, $a0, $a4 +-; LA32-NEXT: add.w $a1, $a5, $a1 +-; LA32-NEXT: xor $a1, $a1, $a3 +-; LA32-NEXT: mul.w $a2, $a2, $a4 +-; LA32-NEXT: mul.w $a0, $a0, $a4 +-; LA32-NEXT: xor $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: mul_i64_65280_twice: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 15 +-; LA64-NEXT: ori $a2, $a2, 3840 +-; LA64-NEXT: mul.d $a1, $a1, $a2 +-; LA64-NEXT: mul.d $a0, $a0, $a2 +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: ret +- %c = mul i64 %a, 65280 +- %d = mul i64 %b, 65280 +- %e = xor i64 %c, %d +- ret i64 %e +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/or.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/or.ll +deleted file mode 100644 +index ead72507d..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/or.ll ++++ /dev/null +@@ -1,265 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-;; Exercise the 'or' LLVM IR: https://llvm.org/docs/LangRef.html#or-instruction +- +-define i1 @or_i1(i1 %a, i1 %b) { +-; LA32-LABEL: or_i1: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: or_i1: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = or i1 %a, %b +- ret i1 %r +-} +- +-define i8 @or_i8(i8 %a, i8 %b) { +-; LA32-LABEL: or_i8: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: or_i8: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = or i8 %a, %b +- ret i8 %r +-} +- +-define i16 @or_i16(i16 %a, i16 %b) { +-; LA32-LABEL: or_i16: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: or_i16: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = or i16 %a, %b +- ret i16 %r +-} +- +-define i32 @or_i32(i32 %a, i32 %b) { +-; LA32-LABEL: or_i32: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: or_i32: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = or i32 %a, %b +- ret i32 %r +-} +- +-define i64 @or_i64(i64 %a, i64 %b) { +-; LA32-LABEL: or_i64: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: or $a0, $a0, $a2 +-; LA32-NEXT: or $a1, $a1, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: or_i64: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = or i64 %a, %b +- ret i64 %r +-} +- +-define i1 @or_i1_0(i1 %b) { +-; LA32-LABEL: or_i1_0: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: ret +-; +-; LA64-LABEL: or_i1_0: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ret +-entry: +- %r = or i1 4, %b +- ret i1 %r +-} +- +-define i1 @or_i1_5(i1 %b) { +-; LA32-LABEL: or_i1_5: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: ori $a0, $zero, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: or_i1_5: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ori $a0, $zero, 1 +-; LA64-NEXT: ret +-entry: +- %r = or i1 5, %b +- ret i1 %r +-} +- +-define i8 @or_i8_5(i8 %b) { +-; LA32-LABEL: or_i8_5: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: ori $a0, $a0, 5 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: or_i8_5: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ori $a0, $a0, 5 +-; LA64-NEXT: ret +-entry: +- %r = or i8 5, %b +- ret i8 %r +-} +- +-define i8 @or_i8_257(i8 %b) { +-; LA32-LABEL: or_i8_257: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: ori $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: or_i8_257: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ori $a0, $a0, 1 +-; LA64-NEXT: ret +-entry: +- %r = or i8 257, %b +- ret i8 %r +-} +- +-define i16 @or_i16_5(i16 %b) { +-; LA32-LABEL: or_i16_5: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: ori $a0, $a0, 5 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: or_i16_5: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ori $a0, $a0, 5 +-; LA64-NEXT: ret +-entry: +- %r = or i16 5, %b +- ret i16 %r +-} +- +-define i16 @or_i16_0x1000(i16 %b) { +-; LA32-LABEL: or_i16_0x1000: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: lu12i.w $a1, 1 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: or_i16_0x1000: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: lu12i.w $a1, 1 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = or i16 4096, %b +- ret i16 %r +-} +- +-define i16 @or_i16_0x10001(i16 %b) { +-; LA32-LABEL: or_i16_0x10001: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: ori $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: or_i16_0x10001: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ori $a0, $a0, 1 +-; LA64-NEXT: ret +-entry: +- %r = or i16 65537, %b +- ret i16 %r +-} +- +-define i32 @or_i32_5(i32 %b) { +-; LA32-LABEL: or_i32_5: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: ori $a0, $a0, 5 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: or_i32_5: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ori $a0, $a0, 5 +-; LA64-NEXT: ret +-entry: +- %r = or i32 5, %b +- ret i32 %r +-} +- +-define i32 @or_i32_0x1000(i32 %b) { +-; LA32-LABEL: or_i32_0x1000: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: lu12i.w $a1, 1 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: or_i32_0x1000: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: lu12i.w $a1, 1 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = or i32 4096, %b +- ret i32 %r +-} +- +-define i32 @or_i32_0x100000001(i32 %b) { +-; LA32-LABEL: or_i32_0x100000001: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: ori $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: or_i32_0x100000001: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ori $a0, $a0, 1 +-; LA64-NEXT: ret +-entry: +- %r = or i32 4294967297, %b +- ret i32 %r +-} +- +-define i64 @or_i64_5(i64 %b) { +-; LA32-LABEL: or_i64_5: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: ori $a0, $a0, 5 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: or_i64_5: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ori $a0, $a0, 5 +-; LA64-NEXT: ret +-entry: +- %r = or i64 5, %b +- ret i64 %r +-} +- +-define i64 @or_i64_0x1000(i64 %b) { +-; LA32-LABEL: or_i64_0x1000: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: lu12i.w $a2, 1 +-; LA32-NEXT: or $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: or_i64_0x1000: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: lu12i.w $a1, 1 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = or i64 4096, %b +- ret i64 %r +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/sdiv-udiv-srem-urem.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/sdiv-udiv-srem-urem.ll +deleted file mode 100644 +index 9c94bfeea..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/sdiv-udiv-srem-urem.ll ++++ /dev/null +@@ -1,741 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +-; RUN: llc --mtriple=loongarch32 -loongarch-check-zero-division < %s \ +-; RUN: | FileCheck %s --check-prefix=LA32-TRAP +-; RUN: llc --mtriple=loongarch64 -loongarch-check-zero-division < %s \ +-; RUN: | FileCheck %s --check-prefix=LA64-TRAP +- +-;; Test the sdiv/udiv/srem/urem LLVM IR. +- +-define i1 @sdiv_i1(i1 %a, i1 %b) { +-; LA32-LABEL: sdiv_i1: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sdiv_i1: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ret +-; +-; LA32-TRAP-LABEL: sdiv_i1: +-; LA32-TRAP: # %bb.0: # %entry +-; LA32-TRAP-NEXT: ret +-; +-; LA64-TRAP-LABEL: sdiv_i1: +-; LA64-TRAP: # %bb.0: # %entry +-; LA64-TRAP-NEXT: ret +-entry: +- %r = sdiv i1 %a, %b +- ret i1 %r +-} +- +-define i8 @sdiv_i8(i8 %a, i8 %b) { +-; LA32-LABEL: sdiv_i8: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: ext.w.b $a1, $a1 +-; LA32-NEXT: ext.w.b $a0, $a0 +-; LA32-NEXT: div.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sdiv_i8: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ext.w.b $a1, $a1 +-; LA64-NEXT: ext.w.b $a0, $a0 +-; LA64-NEXT: div.d $a0, $a0, $a1 +-; LA64-NEXT: ret +-; +-; LA32-TRAP-LABEL: sdiv_i8: +-; LA32-TRAP: # %bb.0: # %entry +-; LA32-TRAP-NEXT: ext.w.b $a1, $a1 +-; LA32-TRAP-NEXT: ext.w.b $a0, $a0 +-; LA32-TRAP-NEXT: div.w $a0, $a0, $a1 +-; LA32-TRAP-NEXT: bnez $a1, .LBB1_2 +-; LA32-TRAP-NEXT: # %bb.1: # %entry +-; LA32-TRAP-NEXT: break 7 +-; LA32-TRAP-NEXT: .LBB1_2: # %entry +-; LA32-TRAP-NEXT: ret +-; +-; LA64-TRAP-LABEL: sdiv_i8: +-; LA64-TRAP: # %bb.0: # %entry +-; LA64-TRAP-NEXT: ext.w.b $a1, $a1 +-; LA64-TRAP-NEXT: ext.w.b $a0, $a0 +-; LA64-TRAP-NEXT: div.d $a0, $a0, $a1 +-; LA64-TRAP-NEXT: bnez $a1, .LBB1_2 +-; LA64-TRAP-NEXT: # %bb.1: # %entry +-; LA64-TRAP-NEXT: break 7 +-; LA64-TRAP-NEXT: .LBB1_2: # %entry +-; LA64-TRAP-NEXT: ret +-entry: +- %r = sdiv i8 %a, %b +- ret i8 %r +-} +- +-define i16 @sdiv_i16(i16 %a, i16 %b) { +-; LA32-LABEL: sdiv_i16: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: ext.w.h $a1, $a1 +-; LA32-NEXT: ext.w.h $a0, $a0 +-; LA32-NEXT: div.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sdiv_i16: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ext.w.h $a1, $a1 +-; LA64-NEXT: ext.w.h $a0, $a0 +-; LA64-NEXT: div.d $a0, $a0, $a1 +-; LA64-NEXT: ret +-; +-; LA32-TRAP-LABEL: sdiv_i16: +-; LA32-TRAP: # %bb.0: # %entry +-; LA32-TRAP-NEXT: ext.w.h $a1, $a1 +-; LA32-TRAP-NEXT: ext.w.h $a0, $a0 +-; LA32-TRAP-NEXT: div.w $a0, $a0, $a1 +-; LA32-TRAP-NEXT: bnez $a1, .LBB2_2 +-; LA32-TRAP-NEXT: # %bb.1: # %entry +-; LA32-TRAP-NEXT: break 7 +-; LA32-TRAP-NEXT: .LBB2_2: # %entry +-; LA32-TRAP-NEXT: ret +-; +-; LA64-TRAP-LABEL: sdiv_i16: +-; LA64-TRAP: # %bb.0: # %entry +-; LA64-TRAP-NEXT: ext.w.h $a1, $a1 +-; LA64-TRAP-NEXT: ext.w.h $a0, $a0 +-; LA64-TRAP-NEXT: div.d $a0, $a0, $a1 +-; LA64-TRAP-NEXT: bnez $a1, .LBB2_2 +-; LA64-TRAP-NEXT: # %bb.1: # %entry +-; LA64-TRAP-NEXT: break 7 +-; LA64-TRAP-NEXT: .LBB2_2: # %entry +-; LA64-TRAP-NEXT: ret +-entry: +- %r = sdiv i16 %a, %b +- ret i16 %r +-} +- +-define i32 @sdiv_i32(i32 %a, i32 %b) { +-; LA32-LABEL: sdiv_i32: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: div.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sdiv_i32: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: div.d $a0, $a0, $a1 +-; LA64-NEXT: ret +-; +-; LA32-TRAP-LABEL: sdiv_i32: +-; LA32-TRAP: # %bb.0: # %entry +-; LA32-TRAP-NEXT: div.w $a0, $a0, $a1 +-; LA32-TRAP-NEXT: bnez $a1, .LBB3_2 +-; LA32-TRAP-NEXT: # %bb.1: # %entry +-; LA32-TRAP-NEXT: break 7 +-; LA32-TRAP-NEXT: .LBB3_2: # %entry +-; LA32-TRAP-NEXT: ret +-; +-; LA64-TRAP-LABEL: sdiv_i32: +-; LA64-TRAP: # %bb.0: # %entry +-; LA64-TRAP-NEXT: addi.w $a1, $a1, 0 +-; LA64-TRAP-NEXT: addi.w $a0, $a0, 0 +-; LA64-TRAP-NEXT: div.d $a0, $a0, $a1 +-; LA64-TRAP-NEXT: bnez $a1, .LBB3_2 +-; LA64-TRAP-NEXT: # %bb.1: # %entry +-; LA64-TRAP-NEXT: break 7 +-; LA64-TRAP-NEXT: .LBB3_2: # %entry +-; LA64-TRAP-NEXT: ret +-entry: +- %r = sdiv i32 %a, %b +- ret i32 %r +-} +- +-define i64 @sdiv_i64(i64 %a, i64 %b) { +-; LA32-LABEL: sdiv_i64: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: bl %plt(__divdi3) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sdiv_i64: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: div.d $a0, $a0, $a1 +-; LA64-NEXT: ret +-; +-; LA32-TRAP-LABEL: sdiv_i64: +-; LA32-TRAP: # %bb.0: # %entry +-; LA32-TRAP-NEXT: addi.w $sp, $sp, -16 +-; LA32-TRAP-NEXT: .cfi_def_cfa_offset 16 +-; LA32-TRAP-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-TRAP-NEXT: .cfi_offset 1, -4 +-; LA32-TRAP-NEXT: bl %plt(__divdi3) +-; LA32-TRAP-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-TRAP-NEXT: addi.w $sp, $sp, 16 +-; LA32-TRAP-NEXT: ret +-; +-; LA64-TRAP-LABEL: sdiv_i64: +-; LA64-TRAP: # %bb.0: # %entry +-; LA64-TRAP-NEXT: div.d $a0, $a0, $a1 +-; LA64-TRAP-NEXT: bnez $a1, .LBB4_2 +-; LA64-TRAP-NEXT: # %bb.1: # %entry +-; LA64-TRAP-NEXT: break 7 +-; LA64-TRAP-NEXT: .LBB4_2: # %entry +-; LA64-TRAP-NEXT: ret +-entry: +- %r = sdiv i64 %a, %b +- ret i64 %r +-} +- +-define i1 @udiv_i1(i1 %a, i1 %b) { +-; LA32-LABEL: udiv_i1: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: ret +-; +-; LA64-LABEL: udiv_i1: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ret +-; +-; LA32-TRAP-LABEL: udiv_i1: +-; LA32-TRAP: # %bb.0: # %entry +-; LA32-TRAP-NEXT: ret +-; +-; LA64-TRAP-LABEL: udiv_i1: +-; LA64-TRAP: # %bb.0: # %entry +-; LA64-TRAP-NEXT: ret +-entry: +- %r = udiv i1 %a, %b +- ret i1 %r +-} +- +-define i8 @udiv_i8(i8 %a, i8 %b) { +-; LA32-LABEL: udiv_i8: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: andi $a0, $a0, 255 +-; LA32-NEXT: div.wu $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: udiv_i8: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: andi $a0, $a0, 255 +-; LA64-NEXT: div.du $a0, $a0, $a1 +-; LA64-NEXT: ret +-; +-; LA32-TRAP-LABEL: udiv_i8: +-; LA32-TRAP: # %bb.0: # %entry +-; LA32-TRAP-NEXT: andi $a1, $a1, 255 +-; LA32-TRAP-NEXT: andi $a0, $a0, 255 +-; LA32-TRAP-NEXT: div.wu $a0, $a0, $a1 +-; LA32-TRAP-NEXT: bnez $a1, .LBB6_2 +-; LA32-TRAP-NEXT: # %bb.1: # %entry +-; LA32-TRAP-NEXT: break 7 +-; LA32-TRAP-NEXT: .LBB6_2: # %entry +-; LA32-TRAP-NEXT: ret +-; +-; LA64-TRAP-LABEL: udiv_i8: +-; LA64-TRAP: # %bb.0: # %entry +-; LA64-TRAP-NEXT: andi $a1, $a1, 255 +-; LA64-TRAP-NEXT: andi $a0, $a0, 255 +-; LA64-TRAP-NEXT: div.du $a0, $a0, $a1 +-; LA64-TRAP-NEXT: bnez $a1, .LBB6_2 +-; LA64-TRAP-NEXT: # %bb.1: # %entry +-; LA64-TRAP-NEXT: break 7 +-; LA64-TRAP-NEXT: .LBB6_2: # %entry +-; LA64-TRAP-NEXT: ret +-entry: +- %r = udiv i8 %a, %b +- ret i8 %r +-} +- +-define i16 @udiv_i16(i16 %a, i16 %b) { +-; LA32-LABEL: udiv_i16: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: bstrpick.w $a0, $a0, 15, 0 +-; LA32-NEXT: div.wu $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: udiv_i16: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: bstrpick.d $a0, $a0, 15, 0 +-; LA64-NEXT: div.du $a0, $a0, $a1 +-; LA64-NEXT: ret +-; +-; LA32-TRAP-LABEL: udiv_i16: +-; LA32-TRAP: # %bb.0: # %entry +-; LA32-TRAP-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-TRAP-NEXT: bstrpick.w $a0, $a0, 15, 0 +-; LA32-TRAP-NEXT: div.wu $a0, $a0, $a1 +-; LA32-TRAP-NEXT: bnez $a1, .LBB7_2 +-; LA32-TRAP-NEXT: # %bb.1: # %entry +-; LA32-TRAP-NEXT: break 7 +-; LA32-TRAP-NEXT: .LBB7_2: # %entry +-; LA32-TRAP-NEXT: ret +-; +-; LA64-TRAP-LABEL: udiv_i16: +-; LA64-TRAP: # %bb.0: # %entry +-; LA64-TRAP-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-TRAP-NEXT: bstrpick.d $a0, $a0, 15, 0 +-; LA64-TRAP-NEXT: div.du $a0, $a0, $a1 +-; LA64-TRAP-NEXT: bnez $a1, .LBB7_2 +-; LA64-TRAP-NEXT: # %bb.1: # %entry +-; LA64-TRAP-NEXT: break 7 +-; LA64-TRAP-NEXT: .LBB7_2: # %entry +-; LA64-TRAP-NEXT: ret +-entry: +- %r = udiv i16 %a, %b +- ret i16 %r +-} +- +-define i32 @udiv_i32(i32 %a, i32 %b) { +-; LA32-LABEL: udiv_i32: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: div.wu $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: udiv_i32: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: bstrpick.d $a1, $a1, 31, 0 +-; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 +-; LA64-NEXT: div.du $a0, $a0, $a1 +-; LA64-NEXT: ret +-; +-; LA32-TRAP-LABEL: udiv_i32: +-; LA32-TRAP: # %bb.0: # %entry +-; LA32-TRAP-NEXT: div.wu $a0, $a0, $a1 +-; LA32-TRAP-NEXT: bnez $a1, .LBB8_2 +-; LA32-TRAP-NEXT: # %bb.1: # %entry +-; LA32-TRAP-NEXT: break 7 +-; LA32-TRAP-NEXT: .LBB8_2: # %entry +-; LA32-TRAP-NEXT: ret +-; +-; LA64-TRAP-LABEL: udiv_i32: +-; LA64-TRAP: # %bb.0: # %entry +-; LA64-TRAP-NEXT: bstrpick.d $a1, $a1, 31, 0 +-; LA64-TRAP-NEXT: bstrpick.d $a0, $a0, 31, 0 +-; LA64-TRAP-NEXT: div.du $a0, $a0, $a1 +-; LA64-TRAP-NEXT: bnez $a1, .LBB8_2 +-; LA64-TRAP-NEXT: # %bb.1: # %entry +-; LA64-TRAP-NEXT: break 7 +-; LA64-TRAP-NEXT: .LBB8_2: # %entry +-; LA64-TRAP-NEXT: ret +-entry: +- %r = udiv i32 %a, %b +- ret i32 %r +-} +- +-define i64 @udiv_i64(i64 %a, i64 %b) { +-; LA32-LABEL: udiv_i64: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: bl %plt(__udivdi3) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: udiv_i64: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: div.du $a0, $a0, $a1 +-; LA64-NEXT: ret +-; +-; LA32-TRAP-LABEL: udiv_i64: +-; LA32-TRAP: # %bb.0: # %entry +-; LA32-TRAP-NEXT: addi.w $sp, $sp, -16 +-; LA32-TRAP-NEXT: .cfi_def_cfa_offset 16 +-; LA32-TRAP-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-TRAP-NEXT: .cfi_offset 1, -4 +-; LA32-TRAP-NEXT: bl %plt(__udivdi3) +-; LA32-TRAP-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-TRAP-NEXT: addi.w $sp, $sp, 16 +-; LA32-TRAP-NEXT: ret +-; +-; LA64-TRAP-LABEL: udiv_i64: +-; LA64-TRAP: # %bb.0: # %entry +-; LA64-TRAP-NEXT: div.du $a0, $a0, $a1 +-; LA64-TRAP-NEXT: bnez $a1, .LBB9_2 +-; LA64-TRAP-NEXT: # %bb.1: # %entry +-; LA64-TRAP-NEXT: break 7 +-; LA64-TRAP-NEXT: .LBB9_2: # %entry +-; LA64-TRAP-NEXT: ret +-entry: +- %r = udiv i64 %a, %b +- ret i64 %r +-} +- +-define i1 @srem_i1(i1 %a, i1 %b) { +-; LA32-LABEL: srem_i1: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: move $a0, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: srem_i1: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: move $a0, $zero +-; LA64-NEXT: ret +-; +-; LA32-TRAP-LABEL: srem_i1: +-; LA32-TRAP: # %bb.0: # %entry +-; LA32-TRAP-NEXT: move $a0, $zero +-; LA32-TRAP-NEXT: ret +-; +-; LA64-TRAP-LABEL: srem_i1: +-; LA64-TRAP: # %bb.0: # %entry +-; LA64-TRAP-NEXT: move $a0, $zero +-; LA64-TRAP-NEXT: ret +-entry: +- %r = srem i1 %a, %b +- ret i1 %r +-} +- +-define i8 @srem_i8(i8 %a, i8 %b) { +-; LA32-LABEL: srem_i8: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: ext.w.b $a1, $a1 +-; LA32-NEXT: ext.w.b $a0, $a0 +-; LA32-NEXT: mod.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: srem_i8: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ext.w.b $a1, $a1 +-; LA64-NEXT: ext.w.b $a0, $a0 +-; LA64-NEXT: mod.d $a0, $a0, $a1 +-; LA64-NEXT: ret +-; +-; LA32-TRAP-LABEL: srem_i8: +-; LA32-TRAP: # %bb.0: # %entry +-; LA32-TRAP-NEXT: ext.w.b $a1, $a1 +-; LA32-TRAP-NEXT: ext.w.b $a0, $a0 +-; LA32-TRAP-NEXT: mod.w $a0, $a0, $a1 +-; LA32-TRAP-NEXT: bnez $a1, .LBB11_2 +-; LA32-TRAP-NEXT: # %bb.1: # %entry +-; LA32-TRAP-NEXT: break 7 +-; LA32-TRAP-NEXT: .LBB11_2: # %entry +-; LA32-TRAP-NEXT: ret +-; +-; LA64-TRAP-LABEL: srem_i8: +-; LA64-TRAP: # %bb.0: # %entry +-; LA64-TRAP-NEXT: ext.w.b $a1, $a1 +-; LA64-TRAP-NEXT: ext.w.b $a0, $a0 +-; LA64-TRAP-NEXT: mod.d $a0, $a0, $a1 +-; LA64-TRAP-NEXT: bnez $a1, .LBB11_2 +-; LA64-TRAP-NEXT: # %bb.1: # %entry +-; LA64-TRAP-NEXT: break 7 +-; LA64-TRAP-NEXT: .LBB11_2: # %entry +-; LA64-TRAP-NEXT: ret +-entry: +- %r = srem i8 %a, %b +- ret i8 %r +-} +- +-define i16 @srem_i16(i16 %a, i16 %b) { +-; LA32-LABEL: srem_i16: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: ext.w.h $a1, $a1 +-; LA32-NEXT: ext.w.h $a0, $a0 +-; LA32-NEXT: mod.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: srem_i16: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ext.w.h $a1, $a1 +-; LA64-NEXT: ext.w.h $a0, $a0 +-; LA64-NEXT: mod.d $a0, $a0, $a1 +-; LA64-NEXT: ret +-; +-; LA32-TRAP-LABEL: srem_i16: +-; LA32-TRAP: # %bb.0: # %entry +-; LA32-TRAP-NEXT: ext.w.h $a1, $a1 +-; LA32-TRAP-NEXT: ext.w.h $a0, $a0 +-; LA32-TRAP-NEXT: mod.w $a0, $a0, $a1 +-; LA32-TRAP-NEXT: bnez $a1, .LBB12_2 +-; LA32-TRAP-NEXT: # %bb.1: # %entry +-; LA32-TRAP-NEXT: break 7 +-; LA32-TRAP-NEXT: .LBB12_2: # %entry +-; LA32-TRAP-NEXT: ret +-; +-; LA64-TRAP-LABEL: srem_i16: +-; LA64-TRAP: # %bb.0: # %entry +-; LA64-TRAP-NEXT: ext.w.h $a1, $a1 +-; LA64-TRAP-NEXT: ext.w.h $a0, $a0 +-; LA64-TRAP-NEXT: mod.d $a0, $a0, $a1 +-; LA64-TRAP-NEXT: bnez $a1, .LBB12_2 +-; LA64-TRAP-NEXT: # %bb.1: # %entry +-; LA64-TRAP-NEXT: break 7 +-; LA64-TRAP-NEXT: .LBB12_2: # %entry +-; LA64-TRAP-NEXT: ret +-entry: +- %r = srem i16 %a, %b +- ret i16 %r +-} +- +-define i32 @srem_i32(i32 %a, i32 %b) { +-; LA32-LABEL: srem_i32: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: mod.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: srem_i32: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: addi.w $a1, $a1, 0 +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: mod.d $a0, $a0, $a1 +-; LA64-NEXT: ret +-; +-; LA32-TRAP-LABEL: srem_i32: +-; LA32-TRAP: # %bb.0: # %entry +-; LA32-TRAP-NEXT: mod.w $a0, $a0, $a1 +-; LA32-TRAP-NEXT: bnez $a1, .LBB13_2 +-; LA32-TRAP-NEXT: # %bb.1: # %entry +-; LA32-TRAP-NEXT: break 7 +-; LA32-TRAP-NEXT: .LBB13_2: # %entry +-; LA32-TRAP-NEXT: ret +-; +-; LA64-TRAP-LABEL: srem_i32: +-; LA64-TRAP: # %bb.0: # %entry +-; LA64-TRAP-NEXT: addi.w $a1, $a1, 0 +-; LA64-TRAP-NEXT: addi.w $a0, $a0, 0 +-; LA64-TRAP-NEXT: mod.d $a0, $a0, $a1 +-; LA64-TRAP-NEXT: bnez $a1, .LBB13_2 +-; LA64-TRAP-NEXT: # %bb.1: # %entry +-; LA64-TRAP-NEXT: break 7 +-; LA64-TRAP-NEXT: .LBB13_2: # %entry +-; LA64-TRAP-NEXT: ret +-entry: +- %r = srem i32 %a, %b +- ret i32 %r +-} +- +-define i64 @srem_i64(i64 %a, i64 %b) { +-; LA32-LABEL: srem_i64: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: bl %plt(__moddi3) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: srem_i64: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: mod.d $a0, $a0, $a1 +-; LA64-NEXT: ret +-; +-; LA32-TRAP-LABEL: srem_i64: +-; LA32-TRAP: # %bb.0: # %entry +-; LA32-TRAP-NEXT: addi.w $sp, $sp, -16 +-; LA32-TRAP-NEXT: .cfi_def_cfa_offset 16 +-; LA32-TRAP-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-TRAP-NEXT: .cfi_offset 1, -4 +-; LA32-TRAP-NEXT: bl %plt(__moddi3) +-; LA32-TRAP-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-TRAP-NEXT: addi.w $sp, $sp, 16 +-; LA32-TRAP-NEXT: ret +-; +-; LA64-TRAP-LABEL: srem_i64: +-; LA64-TRAP: # %bb.0: # %entry +-; LA64-TRAP-NEXT: mod.d $a0, $a0, $a1 +-; LA64-TRAP-NEXT: bnez $a1, .LBB14_2 +-; LA64-TRAP-NEXT: # %bb.1: # %entry +-; LA64-TRAP-NEXT: break 7 +-; LA64-TRAP-NEXT: .LBB14_2: # %entry +-; LA64-TRAP-NEXT: ret +-entry: +- %r = srem i64 %a, %b +- ret i64 %r +-} +- +-define i1 @urem_i1(i1 %a, i1 %b) { +-; LA32-LABEL: urem_i1: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: move $a0, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: urem_i1: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: move $a0, $zero +-; LA64-NEXT: ret +-; +-; LA32-TRAP-LABEL: urem_i1: +-; LA32-TRAP: # %bb.0: # %entry +-; LA32-TRAP-NEXT: move $a0, $zero +-; LA32-TRAP-NEXT: ret +-; +-; LA64-TRAP-LABEL: urem_i1: +-; LA64-TRAP: # %bb.0: # %entry +-; LA64-TRAP-NEXT: move $a0, $zero +-; LA64-TRAP-NEXT: ret +-entry: +- %r = urem i1 %a, %b +- ret i1 %r +-} +- +-define i8 @urem_i8(i8 %a, i8 %b) { +-; LA32-LABEL: urem_i8: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: andi $a1, $a1, 255 +-; LA32-NEXT: andi $a0, $a0, 255 +-; LA32-NEXT: mod.wu $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: urem_i8: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: andi $a1, $a1, 255 +-; LA64-NEXT: andi $a0, $a0, 255 +-; LA64-NEXT: mod.du $a0, $a0, $a1 +-; LA64-NEXT: ret +-; +-; LA32-TRAP-LABEL: urem_i8: +-; LA32-TRAP: # %bb.0: # %entry +-; LA32-TRAP-NEXT: andi $a1, $a1, 255 +-; LA32-TRAP-NEXT: andi $a0, $a0, 255 +-; LA32-TRAP-NEXT: mod.wu $a0, $a0, $a1 +-; LA32-TRAP-NEXT: bnez $a1, .LBB16_2 +-; LA32-TRAP-NEXT: # %bb.1: # %entry +-; LA32-TRAP-NEXT: break 7 +-; LA32-TRAP-NEXT: .LBB16_2: # %entry +-; LA32-TRAP-NEXT: ret +-; +-; LA64-TRAP-LABEL: urem_i8: +-; LA64-TRAP: # %bb.0: # %entry +-; LA64-TRAP-NEXT: andi $a1, $a1, 255 +-; LA64-TRAP-NEXT: andi $a0, $a0, 255 +-; LA64-TRAP-NEXT: mod.du $a0, $a0, $a1 +-; LA64-TRAP-NEXT: bnez $a1, .LBB16_2 +-; LA64-TRAP-NEXT: # %bb.1: # %entry +-; LA64-TRAP-NEXT: break 7 +-; LA64-TRAP-NEXT: .LBB16_2: # %entry +-; LA64-TRAP-NEXT: ret +-entry: +- %r = urem i8 %a, %b +- ret i8 %r +-} +- +-define i16 @urem_i16(i16 %a, i16 %b) { +-; LA32-LABEL: urem_i16: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-NEXT: bstrpick.w $a0, $a0, 15, 0 +-; LA32-NEXT: mod.wu $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: urem_i16: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-NEXT: bstrpick.d $a0, $a0, 15, 0 +-; LA64-NEXT: mod.du $a0, $a0, $a1 +-; LA64-NEXT: ret +-; +-; LA32-TRAP-LABEL: urem_i16: +-; LA32-TRAP: # %bb.0: # %entry +-; LA32-TRAP-NEXT: bstrpick.w $a1, $a1, 15, 0 +-; LA32-TRAP-NEXT: bstrpick.w $a0, $a0, 15, 0 +-; LA32-TRAP-NEXT: mod.wu $a0, $a0, $a1 +-; LA32-TRAP-NEXT: bnez $a1, .LBB17_2 +-; LA32-TRAP-NEXT: # %bb.1: # %entry +-; LA32-TRAP-NEXT: break 7 +-; LA32-TRAP-NEXT: .LBB17_2: # %entry +-; LA32-TRAP-NEXT: ret +-; +-; LA64-TRAP-LABEL: urem_i16: +-; LA64-TRAP: # %bb.0: # %entry +-; LA64-TRAP-NEXT: bstrpick.d $a1, $a1, 15, 0 +-; LA64-TRAP-NEXT: bstrpick.d $a0, $a0, 15, 0 +-; LA64-TRAP-NEXT: mod.du $a0, $a0, $a1 +-; LA64-TRAP-NEXT: bnez $a1, .LBB17_2 +-; LA64-TRAP-NEXT: # %bb.1: # %entry +-; LA64-TRAP-NEXT: break 7 +-; LA64-TRAP-NEXT: .LBB17_2: # %entry +-; LA64-TRAP-NEXT: ret +-entry: +- %r = urem i16 %a, %b +- ret i16 %r +-} +- +-define i32 @urem_i32(i32 %a, i32 %b) { +-; LA32-LABEL: urem_i32: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: mod.wu $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: urem_i32: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: bstrpick.d $a1, $a1, 31, 0 +-; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 +-; LA64-NEXT: mod.du $a0, $a0, $a1 +-; LA64-NEXT: ret +-; +-; LA32-TRAP-LABEL: urem_i32: +-; LA32-TRAP: # %bb.0: # %entry +-; LA32-TRAP-NEXT: mod.wu $a0, $a0, $a1 +-; LA32-TRAP-NEXT: bnez $a1, .LBB18_2 +-; LA32-TRAP-NEXT: # %bb.1: # %entry +-; LA32-TRAP-NEXT: break 7 +-; LA32-TRAP-NEXT: .LBB18_2: # %entry +-; LA32-TRAP-NEXT: ret +-; +-; LA64-TRAP-LABEL: urem_i32: +-; LA64-TRAP: # %bb.0: # %entry +-; LA64-TRAP-NEXT: bstrpick.d $a1, $a1, 31, 0 +-; LA64-TRAP-NEXT: bstrpick.d $a0, $a0, 31, 0 +-; LA64-TRAP-NEXT: mod.du $a0, $a0, $a1 +-; LA64-TRAP-NEXT: bnez $a1, .LBB18_2 +-; LA64-TRAP-NEXT: # %bb.1: # %entry +-; LA64-TRAP-NEXT: break 7 +-; LA64-TRAP-NEXT: .LBB18_2: # %entry +-; LA64-TRAP-NEXT: ret +-entry: +- %r = urem i32 %a, %b +- ret i32 %r +-} +- +-define i64 @urem_i64(i64 %a, i64 %b) { +-; LA32-LABEL: urem_i64: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: bl %plt(__umoddi3) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: urem_i64: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: mod.du $a0, $a0, $a1 +-; LA64-NEXT: ret +-; +-; LA32-TRAP-LABEL: urem_i64: +-; LA32-TRAP: # %bb.0: # %entry +-; LA32-TRAP-NEXT: addi.w $sp, $sp, -16 +-; LA32-TRAP-NEXT: .cfi_def_cfa_offset 16 +-; LA32-TRAP-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-TRAP-NEXT: .cfi_offset 1, -4 +-; LA32-TRAP-NEXT: bl %plt(__umoddi3) +-; LA32-TRAP-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-TRAP-NEXT: addi.w $sp, $sp, 16 +-; LA32-TRAP-NEXT: ret +-; +-; LA64-TRAP-LABEL: urem_i64: +-; LA64-TRAP: # %bb.0: # %entry +-; LA64-TRAP-NEXT: mod.du $a0, $a0, $a1 +-; LA64-TRAP-NEXT: bnez $a1, .LBB19_2 +-; LA64-TRAP-NEXT: # %bb.1: # %entry +-; LA64-TRAP-NEXT: break 7 +-; LA64-TRAP-NEXT: .LBB19_2: # %entry +-; LA64-TRAP-NEXT: ret +-entry: +- %r = urem i64 %a, %b +- ret i64 %r +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/select-bare-dbl.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/select-bare-dbl.ll +deleted file mode 100644 +index c26519de3..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/select-bare-dbl.ll ++++ /dev/null +@@ -1,24 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64 +- +-;; Test the bare double-precision floating-point values selection: +-;; https://llvm.org/docs/LangRef.html#select-instruction +- +-define double @test(i1 %a, double %b, double %c) { +-; LA32-LABEL: test: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a0, $a0, 1 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 1 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64-NEXT: ret +- %res = select i1 %a, double %b, double %c +- ret double %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/select-bare-flt.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/select-bare-flt.ll +deleted file mode 100644 +index a625fd478..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/select-bare-flt.ll ++++ /dev/null +@@ -1,24 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA64 +- +-;; Test the bare single-precision floating-point values selection: +-;; https://llvm.org/docs/LangRef.html#select-instruction +- +-define float @test(i1 %a, float %b, float %c) { +-; LA32-LABEL: test: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a0, $a0, 1 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 1 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64-NEXT: ret +- %res = select i1 %a, float %b, float %c +- ret float %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/select-bare-int.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/select-bare-int.ll +deleted file mode 100644 +index ad0a241f5..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/select-bare-int.ll ++++ /dev/null +@@ -1,140 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-;; Exercise the bare integers 'select' LLVM IR: https://llvm.org/docs/LangRef.html#select-instruction +- +-define i1 @bare_select_i1(i1 %a, i1 %b, i1 %c) { +-; LA32-LABEL: bare_select_i1: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a0, $a0, 1 +-; LA32-NEXT: masknez $a2, $a2, $a0 +-; LA32-NEXT: maskeqz $a0, $a1, $a0 +-; LA32-NEXT: or $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: bare_select_i1: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 1 +-; LA64-NEXT: masknez $a2, $a2, $a0 +-; LA64-NEXT: maskeqz $a0, $a1, $a0 +-; LA64-NEXT: or $a0, $a0, $a2 +-; LA64-NEXT: ret +- %res = select i1 %a, i1 %b, i1 %c +- ret i1 %res +-} +- +-define i8 @bare_select_i8(i1 %a, i8 %b, i8 %c) { +-; LA32-LABEL: bare_select_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a0, $a0, 1 +-; LA32-NEXT: masknez $a2, $a2, $a0 +-; LA32-NEXT: maskeqz $a0, $a1, $a0 +-; LA32-NEXT: or $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: bare_select_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 1 +-; LA64-NEXT: masknez $a2, $a2, $a0 +-; LA64-NEXT: maskeqz $a0, $a1, $a0 +-; LA64-NEXT: or $a0, $a0, $a2 +-; LA64-NEXT: ret +- %res = select i1 %a, i8 %b, i8 %c +- ret i8 %res +-} +- +-define i16 @bare_select_i16(i1 %a, i16 %b, i16 %c) { +-; LA32-LABEL: bare_select_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a0, $a0, 1 +-; LA32-NEXT: masknez $a2, $a2, $a0 +-; LA32-NEXT: maskeqz $a0, $a1, $a0 +-; LA32-NEXT: or $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: bare_select_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 1 +-; LA64-NEXT: masknez $a2, $a2, $a0 +-; LA64-NEXT: maskeqz $a0, $a1, $a0 +-; LA64-NEXT: or $a0, $a0, $a2 +-; LA64-NEXT: ret +- %res = select i1 %a, i16 %b, i16 %c +- ret i16 %res +-} +- +-define i32 @bare_select_i32(i1 %a, i32 %b, i32 %c) { +-; LA32-LABEL: bare_select_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a0, $a0, 1 +-; LA32-NEXT: masknez $a2, $a2, $a0 +-; LA32-NEXT: maskeqz $a0, $a1, $a0 +-; LA32-NEXT: or $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: bare_select_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 1 +-; LA64-NEXT: masknez $a2, $a2, $a0 +-; LA64-NEXT: maskeqz $a0, $a1, $a0 +-; LA64-NEXT: or $a0, $a0, $a2 +-; LA64-NEXT: ret +- %res = select i1 %a, i32 %b, i32 %c +- ret i32 %res +-} +- +-define i64 @bare_select_i64(i1 %a, i64 %b, i64 %c) { +-; LA32-LABEL: bare_select_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a5, $a0, 1 +-; LA32-NEXT: masknez $a0, $a3, $a5 +-; LA32-NEXT: maskeqz $a1, $a1, $a5 +-; LA32-NEXT: or $a0, $a1, $a0 +-; LA32-NEXT: masknez $a1, $a4, $a5 +-; LA32-NEXT: maskeqz $a2, $a2, $a5 +-; LA32-NEXT: or $a1, $a2, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: bare_select_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 1 +-; LA64-NEXT: masknez $a2, $a2, $a0 +-; LA64-NEXT: maskeqz $a0, $a1, $a0 +-; LA64-NEXT: or $a0, $a0, $a2 +-; LA64-NEXT: ret +- %res = select i1 %a, i64 %b, i64 %c +- ret i64 %res +-} +- +-define i16 @bare_select_zero_i16(i1 %a, i16 %b) { +-; LA32-LABEL: bare_select_zero_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a0, $a0, 1 +-; LA32-NEXT: masknez $a0, $a1, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: bare_select_zero_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 1 +-; LA64-NEXT: masknez $a0, $a1, $a0 +-; LA64-NEXT: ret +- %res = select i1 %a, i16 0, i16 %b +- ret i16 %res +-} +- +-define i32 @bare_select_zero_i32(i1 %a, i32 %b) { +-; LA32-LABEL: bare_select_zero_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a0, $a0, 1 +-; LA32-NEXT: maskeqz $a0, $a1, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: bare_select_zero_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 1 +-; LA64-NEXT: maskeqz $a0, $a1, $a0 +-; LA64-NEXT: ret +- %res = select i1 %a, i32 %b, i32 0 +- ret i32 %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/select-fpcc-dbl.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/select-fpcc-dbl.ll +deleted file mode 100644 +index 8d26996b8..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/select-fpcc-dbl.ll ++++ /dev/null +@@ -1,273 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64 +- +-;; Test double-precision floating-point values selection after comparison +- +-define double @fcmp_false(double %a, double %b, double %x, double %y) { +-; LA32-LABEL: fcmp_false: +-; LA32: # %bb.0: +-; LA32-NEXT: fmov.d $fa0, $fa3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_false: +-; LA64: # %bb.0: +-; LA64-NEXT: fmov.d $fa0, $fa3 +-; LA64-NEXT: ret +- %cmp = fcmp false double %a, %b +- %res = select i1 %cmp, double %x, double %y +- ret double %res +-} +- +-define double @fcmp_oeq(double %a, double %b, double %x, double %y) { +-; LA32-LABEL: fcmp_oeq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.ceq.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_oeq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.ceq.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp oeq double %a, %b +- %res = select i1 %cmp, double %x, double %y +- ret double %res +-} +- +-define double @fcmp_ogt(double %a, double %b, double %x, double %y) { +-; LA32-LABEL: fcmp_ogt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ogt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ogt double %a, %b +- %res = select i1 %cmp, double %x, double %y +- ret double %res +-} +- +-define double @fcmp_oge(double %a, double %b, double %x, double %y) { +-; LA32-LABEL: fcmp_oge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_oge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp oge double %a, %b +- %res = select i1 %cmp, double %x, double %y +- ret double %res +-} +- +-define double @fcmp_olt(double %a, double %b, double %x, double %y) { +-; LA32-LABEL: fcmp_olt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_olt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp olt double %a, %b +- %res = select i1 %cmp, double %x, double %y +- ret double %res +-} +- +-define double @fcmp_ole(double %a, double %b, double %x, double %y) { +-; LA32-LABEL: fcmp_ole: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ole: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ole double %a, %b +- %res = select i1 %cmp, double %x, double %y +- ret double %res +-} +- +-define double @fcmp_one(double %a, double %b, double %x, double %y) { +-; LA32-LABEL: fcmp_one: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cne.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_one: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cne.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp one double %a, %b +- %res = select i1 %cmp, double %x, double %y +- ret double %res +-} +- +-define double @fcmp_ord(double %a, double %b, double %x, double %y) { +-; LA32-LABEL: fcmp_ord: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cor.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ord: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cor.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ord double %a, %b +- %res = select i1 %cmp, double %x, double %y +- ret double %res +-} +- +-define double @fcmp_ueq(double %a, double %b, double %x, double %y) { +-; LA32-LABEL: fcmp_ueq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cueq.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ueq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cueq.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ueq double %a, %b +- %res = select i1 %cmp, double %x, double %y +- ret double %res +-} +- +-define double @fcmp_ugt(double %a, double %b, double %x, double %y) { +-; LA32-LABEL: fcmp_ugt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ugt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ugt double %a, %b +- %res = select i1 %cmp, double %x, double %y +- ret double %res +-} +- +-define double @fcmp_uge(double %a, double %b, double %x, double %y) { +-; LA32-LABEL: fcmp_uge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_uge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp uge double %a, %b +- %res = select i1 %cmp, double %x, double %y +- ret double %res +-} +- +-define double @fcmp_ult(double %a, double %b, double %x, double %y) { +-; LA32-LABEL: fcmp_ult: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ult: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ult double %a, %b +- %res = select i1 %cmp, double %x, double %y +- ret double %res +-} +- +-define double @fcmp_ule(double %a, double %b, double %x, double %y) { +-; LA32-LABEL: fcmp_ule: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ule: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ule double %a, %b +- %res = select i1 %cmp, double %x, double %y +- ret double %res +-} +- +-define double @fcmp_une(double %a, double %b, double %x, double %y) { +-; LA32-LABEL: fcmp_une: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cune.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_une: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cune.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp une double %a, %b +- %res = select i1 %cmp, double %x, double %y +- ret double %res +-} +- +-define double @fcmp_uno(double %a, double %b, double %x, double %y) { +-; LA32-LABEL: fcmp_uno: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cun.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_uno: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cun.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp uno double %a, %b +- %res = select i1 %cmp, double %x, double %y +- ret double %res +-} +- +-define double @fcmp_true(double %a, double %b, double %x, double %y) { +-; LA32-LABEL: fcmp_true: +-; LA32: # %bb.0: +-; LA32-NEXT: fmov.d $fa0, $fa2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_true: +-; LA64: # %bb.0: +-; LA64-NEXT: fmov.d $fa0, $fa2 +-; LA64-NEXT: ret +- %cmp = fcmp true double %a, %b +- %res = select i1 %cmp, double %x, double %y +- ret double %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/select-fpcc-flt.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/select-fpcc-flt.ll +deleted file mode 100644 +index 1f6d2313a..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/select-fpcc-flt.ll ++++ /dev/null +@@ -1,273 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA64 +- +-;; Test single-precision floating-point values selection after comparison +- +-define float @fcmp_false(float %a, float %b, float %x, float %y) { +-; LA32-LABEL: fcmp_false: +-; LA32: # %bb.0: +-; LA32-NEXT: fmov.s $fa0, $fa3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_false: +-; LA64: # %bb.0: +-; LA64-NEXT: fmov.s $fa0, $fa3 +-; LA64-NEXT: ret +- %cmp = fcmp false float %a, %b +- %res = select i1 %cmp, float %x, float %y +- ret float %res +-} +- +-define float @fcmp_oeq(float %a, float %b, float %x, float %y) { +-; LA32-LABEL: fcmp_oeq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.ceq.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_oeq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.ceq.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp oeq float %a, %b +- %res = select i1 %cmp, float %x, float %y +- ret float %res +-} +- +-define float @fcmp_ogt(float %a, float %b, float %x, float %y) { +-; LA32-LABEL: fcmp_ogt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ogt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ogt float %a, %b +- %res = select i1 %cmp, float %x, float %y +- ret float %res +-} +- +-define float @fcmp_oge(float %a, float %b, float %x, float %y) { +-; LA32-LABEL: fcmp_oge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_oge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp oge float %a, %b +- %res = select i1 %cmp, float %x, float %y +- ret float %res +-} +- +-define float @fcmp_olt(float %a, float %b, float %x, float %y) { +-; LA32-LABEL: fcmp_olt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_olt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp olt float %a, %b +- %res = select i1 %cmp, float %x, float %y +- ret float %res +-} +- +-define float @fcmp_ole(float %a, float %b, float %x, float %y) { +-; LA32-LABEL: fcmp_ole: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ole: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ole float %a, %b +- %res = select i1 %cmp, float %x, float %y +- ret float %res +-} +- +-define float @fcmp_one(float %a, float %b, float %x, float %y) { +-; LA32-LABEL: fcmp_one: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cne.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_one: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cne.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp one float %a, %b +- %res = select i1 %cmp, float %x, float %y +- ret float %res +-} +- +-define float @fcmp_ord(float %a, float %b, float %x, float %y) { +-; LA32-LABEL: fcmp_ord: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cor.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ord: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cor.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ord float %a, %b +- %res = select i1 %cmp, float %x, float %y +- ret float %res +-} +- +-define float @fcmp_ueq(float %a, float %b, float %x, float %y) { +-; LA32-LABEL: fcmp_ueq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cueq.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ueq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cueq.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ueq float %a, %b +- %res = select i1 %cmp, float %x, float %y +- ret float %res +-} +- +-define float @fcmp_ugt(float %a, float %b, float %x, float %y) { +-; LA32-LABEL: fcmp_ugt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ugt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ugt float %a, %b +- %res = select i1 %cmp, float %x, float %y +- ret float %res +-} +- +-define float @fcmp_uge(float %a, float %b, float %x, float %y) { +-; LA32-LABEL: fcmp_uge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_uge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp uge float %a, %b +- %res = select i1 %cmp, float %x, float %y +- ret float %res +-} +- +-define float @fcmp_ult(float %a, float %b, float %x, float %y) { +-; LA32-LABEL: fcmp_ult: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ult: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ult float %a, %b +- %res = select i1 %cmp, float %x, float %y +- ret float %res +-} +- +-define float @fcmp_ule(float %a, float %b, float %x, float %y) { +-; LA32-LABEL: fcmp_ule: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_ule: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp ule float %a, %b +- %res = select i1 %cmp, float %x, float %y +- ret float %res +-} +- +-define float @fcmp_une(float %a, float %b, float %x, float %y) { +-; LA32-LABEL: fcmp_une: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cune.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_une: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cune.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp une float %a, %b +- %res = select i1 %cmp, float %x, float %y +- ret float %res +-} +- +-define float @fcmp_uno(float %a, float %b, float %x, float %y) { +-; LA32-LABEL: fcmp_uno: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cun.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_uno: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cun.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: fsel $fa0, $fa3, $fa2, $fcc0 +-; LA64-NEXT: ret +- %cmp = fcmp uno float %a, %b +- %res = select i1 %cmp, float %x, float %y +- ret float %res +-} +- +-define float @fcmp_true(float %a, float %b, float %x, float %y) { +-; LA32-LABEL: fcmp_true: +-; LA32: # %bb.0: +-; LA32-NEXT: fmov.s $fa0, $fa2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fcmp_true: +-; LA64: # %bb.0: +-; LA64-NEXT: fmov.s $fa0, $fa2 +-; LA64-NEXT: ret +- %cmp = fcmp true float %a, %b +- %res = select i1 %cmp, float %x, float %y +- ret float %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/select-fpcc-int.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/select-fpcc-int.ll +deleted file mode 100644 +index 3e88181a1..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/select-fpcc-int.ll ++++ /dev/null +@@ -1,705 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64 +- +-;; Test integers selection after `fcmp` +- +-define i32 @f32_fcmp_false(float %a, float %b, i32 %x, i32 %y) { +-; LA32-LABEL: f32_fcmp_false: +-; LA32: # %bb.0: +-; LA32-NEXT: move $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f32_fcmp_false: +-; LA64: # %bb.0: +-; LA64-NEXT: move $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp false float %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f32_fcmp_oeq(float %a, float %b, i32 %x, i32 %y) { +-; LA32-LABEL: f32_fcmp_oeq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.ceq.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f32_fcmp_oeq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.ceq.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp oeq float %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f32_fcmp_ogt(float %a, float %b, i32 %x, i32 %y) { +-; LA32-LABEL: f32_fcmp_ogt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f32_fcmp_ogt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp ogt float %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f32_fcmp_oge(float %a, float %b, i32 %x, i32 %y) { +-; LA32-LABEL: f32_fcmp_oge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f32_fcmp_oge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp oge float %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f32_fcmp_olt(float %a, float %b, i32 %x, i32 %y) { +-; LA32-LABEL: f32_fcmp_olt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f32_fcmp_olt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp olt float %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f32_fcmp_ole(float %a, float %b, i32 %x, i32 %y) { +-; LA32-LABEL: f32_fcmp_ole: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f32_fcmp_ole: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp ole float %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f32_fcmp_one(float %a, float %b, i32 %x, i32 %y) { +-; LA32-LABEL: f32_fcmp_one: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cne.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f32_fcmp_one: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cne.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp one float %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f32_fcmp_ord(float %a, float %b, i32 %x, i32 %y) { +-; LA32-LABEL: f32_fcmp_ord: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cor.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f32_fcmp_ord: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cor.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp ord float %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f32_fcmp_ueq(float %a, float %b, i32 %x, i32 %y) { +-; LA32-LABEL: f32_fcmp_ueq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cueq.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f32_fcmp_ueq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cueq.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp ueq float %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f32_fcmp_ugt(float %a, float %b, i32 %x, i32 %y) { +-; LA32-LABEL: f32_fcmp_ugt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f32_fcmp_ugt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp ugt float %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f32_fcmp_uge(float %a, float %b, i32 %x, i32 %y) { +-; LA32-LABEL: f32_fcmp_uge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.s $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f32_fcmp_uge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.s $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp uge float %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f32_fcmp_ult(float %a, float %b, i32 %x, i32 %y) { +-; LA32-LABEL: f32_fcmp_ult: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f32_fcmp_ult: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp ult float %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f32_fcmp_ule(float %a, float %b, i32 %x, i32 %y) { +-; LA32-LABEL: f32_fcmp_ule: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f32_fcmp_ule: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp ule float %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f32_fcmp_une(float %a, float %b, i32 %x, i32 %y) { +-; LA32-LABEL: f32_fcmp_une: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cune.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f32_fcmp_une: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cune.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp une float %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f32_fcmp_uno(float %a, float %b, i32 %x, i32 %y) { +-; LA32-LABEL: f32_fcmp_uno: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cun.s $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f32_fcmp_uno: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cun.s $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp uno float %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f32_fcmp_true(float %a, float %b, i32 %x, i32 %y) { +-; LA32-LABEL: f32_fcmp_true: +-; LA32: # %bb.0: +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f32_fcmp_true: +-; LA64: # %bb.0: +-; LA64-NEXT: ret +- %cmp = fcmp true float %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f64_fcmp_false(double %a, double %b, i32 %x, i32 %y) { +-; LA32-LABEL: f64_fcmp_false: +-; LA32: # %bb.0: +-; LA32-NEXT: move $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f64_fcmp_false: +-; LA64: # %bb.0: +-; LA64-NEXT: move $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp false double %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f64_fcmp_oeq(double %a, double %b, i32 %x, i32 %y) { +-; LA32-LABEL: f64_fcmp_oeq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.ceq.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f64_fcmp_oeq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.ceq.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp oeq double %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f64_fcmp_ogt(double %a, double %b, i32 %x, i32 %y) { +-; LA32-LABEL: f64_fcmp_ogt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f64_fcmp_ogt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp ogt double %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f64_fcmp_oge(double %a, double %b, i32 %x, i32 %y) { +-; LA32-LABEL: f64_fcmp_oge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f64_fcmp_oge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp oge double %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f64_fcmp_olt(double %a, double %b, i32 %x, i32 %y) { +-; LA32-LABEL: f64_fcmp_olt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.clt.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f64_fcmp_olt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.clt.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp olt double %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f64_fcmp_ole(double %a, double %b, i32 %x, i32 %y) { +-; LA32-LABEL: f64_fcmp_ole: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cle.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f64_fcmp_ole: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cle.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp ole double %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f64_fcmp_one(double %a, double %b, i32 %x, i32 %y) { +-; LA32-LABEL: f64_fcmp_one: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cne.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f64_fcmp_one: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cne.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp one double %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f64_fcmp_ord(double %a, double %b, i32 %x, i32 %y) { +-; LA32-LABEL: f64_fcmp_ord: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cor.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f64_fcmp_ord: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cor.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp ord double %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f64_fcmp_ueq(double %a, double %b, i32 %x, i32 %y) { +-; LA32-LABEL: f64_fcmp_ueq: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cueq.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f64_fcmp_ueq: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cueq.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp ueq double %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f64_fcmp_ugt(double %a, double %b, i32 %x, i32 %y) { +-; LA32-LABEL: f64_fcmp_ugt: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f64_fcmp_ugt: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp ugt double %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f64_fcmp_uge(double %a, double %b, i32 %x, i32 %y) { +-; LA32-LABEL: f64_fcmp_uge: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.d $fcc0, $fa1, $fa0 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f64_fcmp_uge: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.d $fcc0, $fa1, $fa0 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp uge double %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f64_fcmp_ult(double %a, double %b, i32 %x, i32 %y) { +-; LA32-LABEL: f64_fcmp_ult: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cult.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f64_fcmp_ult: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cult.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp ult double %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f64_fcmp_ule(double %a, double %b, i32 %x, i32 %y) { +-; LA32-LABEL: f64_fcmp_ule: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cule.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f64_fcmp_ule: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cule.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp ule double %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f64_fcmp_une(double %a, double %b, i32 %x, i32 %y) { +-; LA32-LABEL: f64_fcmp_une: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cune.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f64_fcmp_une: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cune.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp une double %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f64_fcmp_uno(double %a, double %b, i32 %x, i32 %y) { +-; LA32-LABEL: f64_fcmp_uno: +-; LA32: # %bb.0: +-; LA32-NEXT: fcmp.cun.d $fcc0, $fa0, $fa1 +-; LA32-NEXT: movcf2gr $a2, $fcc0 +-; LA32-NEXT: masknez $a1, $a1, $a2 +-; LA32-NEXT: maskeqz $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f64_fcmp_uno: +-; LA64: # %bb.0: +-; LA64-NEXT: fcmp.cun.d $fcc0, $fa0, $fa1 +-; LA64-NEXT: movcf2gr $a2, $fcc0 +-; LA64-NEXT: masknez $a1, $a1, $a2 +-; LA64-NEXT: maskeqz $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = fcmp uno double %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @f64_fcmp_true(double %a, double %b, i32 %x, i32 %y) { +-; LA32-LABEL: f64_fcmp_true: +-; LA32: # %bb.0: +-; LA32-NEXT: ret +-; +-; LA64-LABEL: f64_fcmp_true: +-; LA64: # %bb.0: +-; LA64-NEXT: ret +- %cmp = fcmp true double %a, %b +- %res = select i1 %cmp, i32 %x, i32 %y +- ret i32 %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/select-icc-dbl.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/select-icc-dbl.ll +deleted file mode 100644 +index d8b0ecfd5..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/select-icc-dbl.ll ++++ /dev/null +@@ -1,207 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64 +- +-;; Test double-precision floating-point values selection after integers comparison +- +-define double @select_eq(i32 signext %a, i32 signext %b, double %x, double %y) { +-; LA32-LABEL: select_eq: +-; LA32: # %bb.0: +-; LA32-NEXT: xor $a0, $a0, $a1 +-; LA32-NEXT: sltui $a0, $a0, 1 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_eq: +-; LA64: # %bb.0: +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: sltui $a0, $a0, 1 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64-NEXT: ret +- %cond = icmp eq i32 %a, %b +- %res = select i1 %cond, double %x, double %y +- ret double %res +-} +- +-define double @select_ne(i32 signext %a, i32 signext %b, double %x, double %y) { +-; LA32-LABEL: select_ne: +-; LA32: # %bb.0: +-; LA32-NEXT: xor $a0, $a0, $a1 +-; LA32-NEXT: sltu $a0, $zero, $a0 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_ne: +-; LA64: # %bb.0: +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: sltu $a0, $zero, $a0 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64-NEXT: ret +- %cond = icmp ne i32 %a, %b +- %res = select i1 %cond, double %x, double %y +- ret double %res +-} +- +-define double @select_ugt(i32 signext %a, i32 signext %b, double %x, double %y) { +-; LA32-LABEL: select_ugt: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a0, $a1, $a0 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_ugt: +-; LA64: # %bb.0: +-; LA64-NEXT: sltu $a0, $a1, $a0 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64-NEXT: ret +- %cond = icmp ugt i32 %a, %b +- %res = select i1 %cond, double %x, double %y +- ret double %res +-} +- +-define double @select_uge(i32 signext %a, i32 signext %b, double %x, double %y) { +-; LA32-LABEL: select_uge: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a0, $a0, $a1 +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_uge: +-; LA64: # %bb.0: +-; LA64-NEXT: sltu $a0, $a0, $a1 +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64-NEXT: ret +- %cond = icmp uge i32 %a, %b +- %res = select i1 %cond, double %x, double %y +- ret double %res +-} +- +-define double @select_ult(i32 signext %a, i32 signext %b, double %x, double %y) { +-; LA32-LABEL: select_ult: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a0, $a0, $a1 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_ult: +-; LA64: # %bb.0: +-; LA64-NEXT: sltu $a0, $a0, $a1 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64-NEXT: ret +- %cond = icmp ult i32 %a, %b +- %res = select i1 %cond, double %x, double %y +- ret double %res +-} +- +-define double @select_ule(i32 signext %a, i32 signext %b, double %x, double %y) { +-; LA32-LABEL: select_ule: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a0, $a1, $a0 +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_ule: +-; LA64: # %bb.0: +-; LA64-NEXT: sltu $a0, $a1, $a0 +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64-NEXT: ret +- %cond = icmp ule i32 %a, %b +- %res = select i1 %cond, double %x, double %y +- ret double %res +-} +- +-define double @select_sgt(i32 signext %a, i32 signext %b, double %x, double %y) { +-; LA32-LABEL: select_sgt: +-; LA32: # %bb.0: +-; LA32-NEXT: slt $a0, $a1, $a0 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_sgt: +-; LA64: # %bb.0: +-; LA64-NEXT: slt $a0, $a1, $a0 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64-NEXT: ret +- %cond = icmp sgt i32 %a, %b +- %res = select i1 %cond, double %x, double %y +- ret double %res +-} +- +-define double @select_sge(i32 signext %a, i32 signext %b, double %x, double %y) { +-; LA32-LABEL: select_sge: +-; LA32: # %bb.0: +-; LA32-NEXT: slt $a0, $a0, $a1 +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_sge: +-; LA64: # %bb.0: +-; LA64-NEXT: slt $a0, $a0, $a1 +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64-NEXT: ret +- %cond = icmp sge i32 %a, %b +- %res = select i1 %cond, double %x, double %y +- ret double %res +-} +- +-define double @select_slt(i32 signext %a, i32 signext %b, double %x, double %y) { +-; LA32-LABEL: select_slt: +-; LA32: # %bb.0: +-; LA32-NEXT: slt $a0, $a0, $a1 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_slt: +-; LA64: # %bb.0: +-; LA64-NEXT: slt $a0, $a0, $a1 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64-NEXT: ret +- %cond = icmp slt i32 %a, %b +- %res = select i1 %cond, double %x, double %y +- ret double %res +-} +- +-define double @select_sle(i32 signext %a, i32 signext %b, double %x, double %y) { +-; LA32-LABEL: select_sle: +-; LA32: # %bb.0: +-; LA32-NEXT: slt $a0, $a1, $a0 +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_sle: +-; LA64: # %bb.0: +-; LA64-NEXT: slt $a0, $a1, $a0 +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64-NEXT: ret +- %cond = icmp sle i32 %a, %b +- %res = select i1 %cond, double %x, double %y +- ret double %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/select-icc-flt.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/select-icc-flt.ll +deleted file mode 100644 +index 8870e78ed..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/select-icc-flt.ll ++++ /dev/null +@@ -1,207 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA64 +- +-;; Test single-precision floating-point values selection after integers comparison +- +-define float @select_eq(i32 signext %a, i32 signext %b, float %x, float %y) { +-; LA32-LABEL: select_eq: +-; LA32: # %bb.0: +-; LA32-NEXT: xor $a0, $a0, $a1 +-; LA32-NEXT: sltui $a0, $a0, 1 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_eq: +-; LA64: # %bb.0: +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: sltui $a0, $a0, 1 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64-NEXT: ret +- %cond = icmp eq i32 %a, %b +- %res = select i1 %cond, float %x, float %y +- ret float %res +-} +- +-define float @select_ne(i32 signext %a, i32 signext %b, float %x, float %y) { +-; LA32-LABEL: select_ne: +-; LA32: # %bb.0: +-; LA32-NEXT: xor $a0, $a0, $a1 +-; LA32-NEXT: sltu $a0, $zero, $a0 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_ne: +-; LA64: # %bb.0: +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: sltu $a0, $zero, $a0 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64-NEXT: ret +- %cond = icmp ne i32 %a, %b +- %res = select i1 %cond, float %x, float %y +- ret float %res +-} +- +-define float @select_ugt(i32 signext %a, i32 signext %b, float %x, float %y) { +-; LA32-LABEL: select_ugt: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a0, $a1, $a0 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_ugt: +-; LA64: # %bb.0: +-; LA64-NEXT: sltu $a0, $a1, $a0 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64-NEXT: ret +- %cond = icmp ugt i32 %a, %b +- %res = select i1 %cond, float %x, float %y +- ret float %res +-} +- +-define float @select_uge(i32 signext %a, i32 signext %b, float %x, float %y) { +-; LA32-LABEL: select_uge: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a0, $a0, $a1 +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_uge: +-; LA64: # %bb.0: +-; LA64-NEXT: sltu $a0, $a0, $a1 +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64-NEXT: ret +- %cond = icmp uge i32 %a, %b +- %res = select i1 %cond, float %x, float %y +- ret float %res +-} +- +-define float @select_ult(i32 signext %a, i32 signext %b, float %x, float %y) { +-; LA32-LABEL: select_ult: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a0, $a0, $a1 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_ult: +-; LA64: # %bb.0: +-; LA64-NEXT: sltu $a0, $a0, $a1 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64-NEXT: ret +- %cond = icmp ult i32 %a, %b +- %res = select i1 %cond, float %x, float %y +- ret float %res +-} +- +-define float @select_ule(i32 signext %a, i32 signext %b, float %x, float %y) { +-; LA32-LABEL: select_ule: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a0, $a1, $a0 +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_ule: +-; LA64: # %bb.0: +-; LA64-NEXT: sltu $a0, $a1, $a0 +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64-NEXT: ret +- %cond = icmp ule i32 %a, %b +- %res = select i1 %cond, float %x, float %y +- ret float %res +-} +- +-define float @select_sgt(i32 signext %a, i32 signext %b, float %x, float %y) { +-; LA32-LABEL: select_sgt: +-; LA32: # %bb.0: +-; LA32-NEXT: slt $a0, $a1, $a0 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_sgt: +-; LA64: # %bb.0: +-; LA64-NEXT: slt $a0, $a1, $a0 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64-NEXT: ret +- %cond = icmp sgt i32 %a, %b +- %res = select i1 %cond, float %x, float %y +- ret float %res +-} +- +-define float @select_sge(i32 signext %a, i32 signext %b, float %x, float %y) { +-; LA32-LABEL: select_sge: +-; LA32: # %bb.0: +-; LA32-NEXT: slt $a0, $a0, $a1 +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_sge: +-; LA64: # %bb.0: +-; LA64-NEXT: slt $a0, $a0, $a1 +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64-NEXT: ret +- %cond = icmp sge i32 %a, %b +- %res = select i1 %cond, float %x, float %y +- ret float %res +-} +- +-define float @select_slt(i32 signext %a, i32 signext %b, float %x, float %y) { +-; LA32-LABEL: select_slt: +-; LA32: # %bb.0: +-; LA32-NEXT: slt $a0, $a0, $a1 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_slt: +-; LA64: # %bb.0: +-; LA64-NEXT: slt $a0, $a0, $a1 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64-NEXT: ret +- %cond = icmp slt i32 %a, %b +- %res = select i1 %cond, float %x, float %y +- ret float %res +-} +- +-define float @select_sle(i32 signext %a, i32 signext %b, float %x, float %y) { +-; LA32-LABEL: select_sle: +-; LA32: # %bb.0: +-; LA32-NEXT: slt $a0, $a1, $a0 +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_sle: +-; LA64: # %bb.0: +-; LA64-NEXT: slt $a0, $a1, $a0 +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: fsel $fa0, $fa1, $fa0, $fcc0 +-; LA64-NEXT: ret +- %cond = icmp sle i32 %a, %b +- %res = select i1 %cond, float %x, float %y +- ret float %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/select-icc-int.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/select-icc-int.ll +deleted file mode 100644 +index 0acf31f8b..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/select-icc-int.ll ++++ /dev/null +@@ -1,227 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-;; Test integers selection after integers comparison +- +-define i32 @select_eq(i32 signext %a, i32 signext %b, i32 %x, i32 %y) { +-; LA32-LABEL: select_eq: +-; LA32: # %bb.0: +-; LA32-NEXT: xor $a0, $a0, $a1 +-; LA32-NEXT: sltui $a0, $a0, 1 +-; LA32-NEXT: masknez $a1, $a3, $a0 +-; LA32-NEXT: maskeqz $a0, $a2, $a0 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_eq: +-; LA64: # %bb.0: +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: sltui $a0, $a0, 1 +-; LA64-NEXT: masknez $a1, $a3, $a0 +-; LA64-NEXT: maskeqz $a0, $a2, $a0 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cond = icmp eq i32 %a, %b +- %res = select i1 %cond, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @select_ne(i32 signext %a, i32 signext %b, i32 %x, i32 %y) { +-; LA32-LABEL: select_ne: +-; LA32: # %bb.0: +-; LA32-NEXT: xor $a0, $a0, $a1 +-; LA32-NEXT: sltu $a0, $zero, $a0 +-; LA32-NEXT: masknez $a1, $a3, $a0 +-; LA32-NEXT: maskeqz $a0, $a2, $a0 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_ne: +-; LA64: # %bb.0: +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: sltu $a0, $zero, $a0 +-; LA64-NEXT: masknez $a1, $a3, $a0 +-; LA64-NEXT: maskeqz $a0, $a2, $a0 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cond = icmp ne i32 %a, %b +- %res = select i1 %cond, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @select_ugt(i32 signext %a, i32 signext %b, i32 %x, i32 %y) { +-; LA32-LABEL: select_ugt: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a0, $a1, $a0 +-; LA32-NEXT: masknez $a1, $a3, $a0 +-; LA32-NEXT: maskeqz $a0, $a2, $a0 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_ugt: +-; LA64: # %bb.0: +-; LA64-NEXT: sltu $a0, $a1, $a0 +-; LA64-NEXT: masknez $a1, $a3, $a0 +-; LA64-NEXT: maskeqz $a0, $a2, $a0 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cond = icmp ugt i32 %a, %b +- %res = select i1 %cond, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @select_uge(i32 signext %a, i32 signext %b, i32 %x, i32 %y) { +-; LA32-LABEL: select_uge: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a0, $a0, $a1 +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: masknez $a1, $a3, $a0 +-; LA32-NEXT: maskeqz $a0, $a2, $a0 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_uge: +-; LA64: # %bb.0: +-; LA64-NEXT: sltu $a0, $a0, $a1 +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: masknez $a1, $a3, $a0 +-; LA64-NEXT: maskeqz $a0, $a2, $a0 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cond = icmp uge i32 %a, %b +- %res = select i1 %cond, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @select_ult(i32 signext %a, i32 signext %b, i32 %x, i32 %y) { +-; LA32-LABEL: select_ult: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a0, $a0, $a1 +-; LA32-NEXT: masknez $a1, $a3, $a0 +-; LA32-NEXT: maskeqz $a0, $a2, $a0 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_ult: +-; LA64: # %bb.0: +-; LA64-NEXT: sltu $a0, $a0, $a1 +-; LA64-NEXT: masknez $a1, $a3, $a0 +-; LA64-NEXT: maskeqz $a0, $a2, $a0 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cond = icmp ult i32 %a, %b +- %res = select i1 %cond, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @select_ule(i32 signext %a, i32 signext %b, i32 %x, i32 %y) { +-; LA32-LABEL: select_ule: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a0, $a1, $a0 +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: masknez $a1, $a3, $a0 +-; LA32-NEXT: maskeqz $a0, $a2, $a0 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_ule: +-; LA64: # %bb.0: +-; LA64-NEXT: sltu $a0, $a1, $a0 +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: masknez $a1, $a3, $a0 +-; LA64-NEXT: maskeqz $a0, $a2, $a0 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cond = icmp ule i32 %a, %b +- %res = select i1 %cond, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @select_sgt(i32 signext %a, i32 signext %b, i32 %x, i32 %y) { +-; LA32-LABEL: select_sgt: +-; LA32: # %bb.0: +-; LA32-NEXT: slt $a0, $a1, $a0 +-; LA32-NEXT: masknez $a1, $a3, $a0 +-; LA32-NEXT: maskeqz $a0, $a2, $a0 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_sgt: +-; LA64: # %bb.0: +-; LA64-NEXT: slt $a0, $a1, $a0 +-; LA64-NEXT: masknez $a1, $a3, $a0 +-; LA64-NEXT: maskeqz $a0, $a2, $a0 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cond = icmp sgt i32 %a, %b +- %res = select i1 %cond, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @select_sge(i32 signext %a, i32 signext %b, i32 %x, i32 %y) { +-; LA32-LABEL: select_sge: +-; LA32: # %bb.0: +-; LA32-NEXT: slt $a0, $a0, $a1 +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: masknez $a1, $a3, $a0 +-; LA32-NEXT: maskeqz $a0, $a2, $a0 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_sge: +-; LA64: # %bb.0: +-; LA64-NEXT: slt $a0, $a0, $a1 +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: masknez $a1, $a3, $a0 +-; LA64-NEXT: maskeqz $a0, $a2, $a0 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cond = icmp sge i32 %a, %b +- %res = select i1 %cond, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @select_slt(i32 signext %a, i32 signext %b, i32 %x, i32 %y) { +-; LA32-LABEL: select_slt: +-; LA32: # %bb.0: +-; LA32-NEXT: slt $a0, $a0, $a1 +-; LA32-NEXT: masknez $a1, $a3, $a0 +-; LA32-NEXT: maskeqz $a0, $a2, $a0 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_slt: +-; LA64: # %bb.0: +-; LA64-NEXT: slt $a0, $a0, $a1 +-; LA64-NEXT: masknez $a1, $a3, $a0 +-; LA64-NEXT: maskeqz $a0, $a2, $a0 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cond = icmp slt i32 %a, %b +- %res = select i1 %cond, i32 %x, i32 %y +- ret i32 %res +-} +- +-define i32 @select_sle(i32 signext %a, i32 signext %b, i32 %x, i32 %y) { +-; LA32-LABEL: select_sle: +-; LA32: # %bb.0: +-; LA32-NEXT: slt $a0, $a1, $a0 +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: masknez $a1, $a3, $a0 +-; LA32-NEXT: maskeqz $a0, $a2, $a0 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_sle: +-; LA64: # %bb.0: +-; LA64-NEXT: slt $a0, $a1, $a0 +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: masknez $a1, $a3, $a0 +-; LA64-NEXT: maskeqz $a0, $a2, $a0 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cond = icmp sle i32 %a, %b +- %res = select i1 %cond, i32 %x, i32 %y +- ret i32 %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/sext-zext-trunc.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/sext-zext-trunc.ll +deleted file mode 100644 +index 7053d5340..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/sext-zext-trunc.ll ++++ /dev/null +@@ -1,419 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-;; Test sext/zext/trunc +- +-define i8 @sext_i1_to_i8(i1 %a) { +-; LA32-LABEL: sext_i1_to_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a0, $a0, 1 +-; LA32-NEXT: sub.w $a0, $zero, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sext_i1_to_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 1 +-; LA64-NEXT: sub.d $a0, $zero, $a0 +-; LA64-NEXT: ret +- %1 = sext i1 %a to i8 +- ret i8 %1 +-} +- +-define i16 @sext_i1_to_i16(i1 %a) { +-; LA32-LABEL: sext_i1_to_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a0, $a0, 1 +-; LA32-NEXT: sub.w $a0, $zero, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sext_i1_to_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 1 +-; LA64-NEXT: sub.d $a0, $zero, $a0 +-; LA64-NEXT: ret +- %1 = sext i1 %a to i16 +- ret i16 %1 +-} +- +-define i32 @sext_i1_to_i32(i1 %a) { +-; LA32-LABEL: sext_i1_to_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a0, $a0, 1 +-; LA32-NEXT: sub.w $a0, $zero, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sext_i1_to_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 1 +-; LA64-NEXT: sub.d $a0, $zero, $a0 +-; LA64-NEXT: ret +- %1 = sext i1 %a to i32 +- ret i32 %1 +-} +- +-define i64 @sext_i1_to_i64(i1 %a) { +-; LA32-LABEL: sext_i1_to_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a0, $a0, 1 +-; LA32-NEXT: sub.w $a0, $zero, $a0 +-; LA32-NEXT: move $a1, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sext_i1_to_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 1 +-; LA64-NEXT: sub.d $a0, $zero, $a0 +-; LA64-NEXT: ret +- %1 = sext i1 %a to i64 +- ret i64 %1 +-} +- +-define i16 @sext_i8_to_i16(i8 %a) { +-; LA32-LABEL: sext_i8_to_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: ext.w.b $a0, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sext_i8_to_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: ext.w.b $a0, $a0 +-; LA64-NEXT: ret +- %1 = sext i8 %a to i16 +- ret i16 %1 +-} +- +-define i32 @sext_i8_to_i32(i8 %a) { +-; LA32-LABEL: sext_i8_to_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: ext.w.b $a0, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sext_i8_to_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: ext.w.b $a0, $a0 +-; LA64-NEXT: ret +- %1 = sext i8 %a to i32 +- ret i32 %1 +-} +- +-define i64 @sext_i8_to_i64(i8 %a) { +-; LA32-LABEL: sext_i8_to_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: ext.w.b $a0, $a0 +-; LA32-NEXT: srai.w $a1, $a0, 31 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sext_i8_to_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: ext.w.b $a0, $a0 +-; LA64-NEXT: ret +- %1 = sext i8 %a to i64 +- ret i64 %1 +-} +- +-define i32 @sext_i16_to_i32(i16 %a) { +-; LA32-LABEL: sext_i16_to_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: ext.w.h $a0, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sext_i16_to_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: ext.w.h $a0, $a0 +-; LA64-NEXT: ret +- %1 = sext i16 %a to i32 +- ret i32 %1 +-} +- +-define i64 @sext_i16_to_i64(i16 %a) { +-; LA32-LABEL: sext_i16_to_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: ext.w.h $a0, $a0 +-; LA32-NEXT: srai.w $a1, $a0, 31 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sext_i16_to_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: ext.w.h $a0, $a0 +-; LA64-NEXT: ret +- %1 = sext i16 %a to i64 +- ret i64 %1 +-} +- +-define i64 @sext_i32_to_i64(i32 %a) { +-; LA32-LABEL: sext_i32_to_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: srai.w $a1, $a0, 31 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sext_i32_to_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: ret +- %1 = sext i32 %a to i64 +- ret i64 %1 +-} +- +-define i8 @zext_i1_to_i8(i1 %a) { +-; LA32-LABEL: zext_i1_to_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: zext_i1_to_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 1 +-; LA64-NEXT: ret +- %1 = zext i1 %a to i8 +- ret i8 %1 +-} +- +-define i16 @zext_i1_to_i16(i1 %a) { +-; LA32-LABEL: zext_i1_to_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: zext_i1_to_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 1 +-; LA64-NEXT: ret +- %1 = zext i1 %a to i16 +- ret i16 %1 +-} +- +-define i32 @zext_i1_to_i32(i1 %a) { +-; LA32-LABEL: zext_i1_to_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: zext_i1_to_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 1 +-; LA64-NEXT: ret +- %1 = zext i1 %a to i32 +- ret i32 %1 +-} +- +-define i64 @zext_i1_to_i64(i1 %a) { +-; LA32-LABEL: zext_i1_to_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a0, $a0, 1 +-; LA32-NEXT: move $a1, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: zext_i1_to_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 1 +-; LA64-NEXT: ret +- %1 = zext i1 %a to i64 +- ret i64 %1 +-} +- +-define i16 @zext_i8_to_i16(i8 %a) { +-; LA32-LABEL: zext_i8_to_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a0, $a0, 255 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: zext_i8_to_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 255 +-; LA64-NEXT: ret +- %1 = zext i8 %a to i16 +- ret i16 %1 +-} +- +-define i32 @zext_i8_to_i32(i8 %a) { +-; LA32-LABEL: zext_i8_to_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a0, $a0, 255 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: zext_i8_to_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 255 +-; LA64-NEXT: ret +- %1 = zext i8 %a to i32 +- ret i32 %1 +-} +- +-define i64 @zext_i8_to_i64(i8 %a) { +-; LA32-LABEL: zext_i8_to_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a0, $a0, 255 +-; LA32-NEXT: move $a1, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: zext_i8_to_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a0, $a0, 255 +-; LA64-NEXT: ret +- %1 = zext i8 %a to i64 +- ret i64 %1 +-} +- +-define i32 @zext_i16_to_i32(i16 %a) { +-; LA32-LABEL: zext_i16_to_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: bstrpick.w $a0, $a0, 15, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: zext_i16_to_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a0, $a0, 15, 0 +-; LA64-NEXT: ret +- %1 = zext i16 %a to i32 +- ret i32 %1 +-} +- +-define i64 @zext_i16_to_i64(i16 %a) { +-; LA32-LABEL: zext_i16_to_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: bstrpick.w $a0, $a0, 15, 0 +-; LA32-NEXT: move $a1, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: zext_i16_to_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a0, $a0, 15, 0 +-; LA64-NEXT: ret +- %1 = zext i16 %a to i64 +- ret i64 %1 +-} +- +-define i64 @zext_i32_to_i64(i32 %a) { +-; LA32-LABEL: zext_i32_to_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: move $a1, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: zext_i32_to_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 +-; LA64-NEXT: ret +- %1 = zext i32 %a to i64 +- ret i64 %1 +-} +- +-define i1 @trunc_i8_to_i1(i8 %a) { +-; LA32-LABEL: trunc_i8_to_i1: +-; LA32: # %bb.0: +-; LA32-NEXT: ret +-; +-; LA64-LABEL: trunc_i8_to_i1: +-; LA64: # %bb.0: +-; LA64-NEXT: ret +- %1 = trunc i8 %a to i1 +- ret i1 %1 +-} +- +-define i1 @trunc_i16_to_i1(i16 %a) { +-; LA32-LABEL: trunc_i16_to_i1: +-; LA32: # %bb.0: +-; LA32-NEXT: ret +-; +-; LA64-LABEL: trunc_i16_to_i1: +-; LA64: # %bb.0: +-; LA64-NEXT: ret +- %1 = trunc i16 %a to i1 +- ret i1 %1 +-} +- +-define i1 @trunc_i32_to_i1(i32 %a) { +-; LA32-LABEL: trunc_i32_to_i1: +-; LA32: # %bb.0: +-; LA32-NEXT: ret +-; +-; LA64-LABEL: trunc_i32_to_i1: +-; LA64: # %bb.0: +-; LA64-NEXT: ret +- %1 = trunc i32 %a to i1 +- ret i1 %1 +-} +- +-define i1 @trunc_i64_to_i1(i64 %a) { +-; LA32-LABEL: trunc_i64_to_i1: +-; LA32: # %bb.0: +-; LA32-NEXT: ret +-; +-; LA64-LABEL: trunc_i64_to_i1: +-; LA64: # %bb.0: +-; LA64-NEXT: ret +- %1 = trunc i64 %a to i1 +- ret i1 %1 +-} +- +-define i8 @trunc_i16_to_i8(i16 %a) { +-; LA32-LABEL: trunc_i16_to_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: ret +-; +-; LA64-LABEL: trunc_i16_to_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: ret +- %1 = trunc i16 %a to i8 +- ret i8 %1 +-} +- +-define i8 @trunc_i32_to_i8(i32 %a) { +-; LA32-LABEL: trunc_i32_to_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: ret +-; +-; LA64-LABEL: trunc_i32_to_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: ret +- %1 = trunc i32 %a to i8 +- ret i8 %1 +-} +- +-define i8 @trunc_i64_to_i8(i64 %a) { +-; LA32-LABEL: trunc_i64_to_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: ret +-; +-; LA64-LABEL: trunc_i64_to_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: ret +- %1 = trunc i64 %a to i8 +- ret i8 %1 +-} +- +-define i16 @trunc_i32_to_i16(i32 %a) { +-; LA32-LABEL: trunc_i32_to_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: ret +-; +-; LA64-LABEL: trunc_i32_to_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: ret +- %1 = trunc i32 %a to i16 +- ret i16 %1 +-} +- +-define i16 @trunc_i64_to_i16(i64 %a) { +-; LA32-LABEL: trunc_i64_to_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: ret +-; +-; LA64-LABEL: trunc_i64_to_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: ret +- %1 = trunc i64 %a to i16 +- ret i16 %1 +-} +- +-define i32 @trunc_i64_to_i32(i64 %a) { +-; LA32-LABEL: trunc_i64_to_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: ret +-; +-; LA64-LABEL: trunc_i64_to_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: ret +- %1 = trunc i64 %a to i32 +- ret i32 %1 +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/shl.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/shl.ll +deleted file mode 100644 +index 4baf18931..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/shl.ll ++++ /dev/null +@@ -1,157 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-;; Exercise the 'shl' LLVM IR: https://llvm.org/docs/LangRef.html#shl-instruction +- +-define i1 @shl_i1(i1 %x, i1 %y) { +-; LA32-LABEL: shl_i1: +-; LA32: # %bb.0: +-; LA32-NEXT: ret +-; +-; LA64-LABEL: shl_i1: +-; LA64: # %bb.0: +-; LA64-NEXT: ret +- %shl = shl i1 %x, %y +- ret i1 %shl +-} +- +-define i8 @shl_i8(i8 %x, i8 %y) { +-; LA32-LABEL: shl_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: sll.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: shl_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: sll.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %shl = shl i8 %x, %y +- ret i8 %shl +-} +- +-define i16 @shl_i16(i16 %x, i16 %y) { +-; LA32-LABEL: shl_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: sll.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: shl_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: sll.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %shl = shl i16 %x, %y +- ret i16 %shl +-} +- +-define i32 @shl_i32(i32 %x, i32 %y) { +-; LA32-LABEL: shl_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: sll.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: shl_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: sll.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %shl = shl i32 %x, %y +- ret i32 %shl +-} +- +-define i64 @shl_i64(i64 %x, i64 %y) { +-; LA32-LABEL: shl_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: xori $a3, $a2, 31 +-; LA32-NEXT: srli.w $a4, $a0, 1 +-; LA32-NEXT: srl.w $a3, $a4, $a3 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: or $a1, $a1, $a3 +-; LA32-NEXT: addi.w $a3, $a2, -32 +-; LA32-NEXT: slti $a4, $a3, 0 +-; LA32-NEXT: maskeqz $a1, $a1, $a4 +-; LA32-NEXT: sll.w $a5, $a0, $a3 +-; LA32-NEXT: masknez $a4, $a5, $a4 +-; LA32-NEXT: or $a1, $a1, $a4 +-; LA32-NEXT: sll.w $a0, $a0, $a2 +-; LA32-NEXT: srai.w $a2, $a3, 31 +-; LA32-NEXT: and $a0, $a2, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: shl_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: sll.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %shl = shl i64 %x, %y +- ret i64 %shl +-} +- +-define i1 @shl_i1_3(i1 %x) { +-; LA32-LABEL: shl_i1_3: +-; LA32: # %bb.0: +-; LA32-NEXT: ret +-; +-; LA64-LABEL: shl_i1_3: +-; LA64: # %bb.0: +-; LA64-NEXT: ret +- %shl = shl i1 %x, 3 +- ret i1 %shl +-} +- +-define i8 @shl_i8_3(i8 %x) { +-; LA32-LABEL: shl_i8_3: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a0, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: shl_i8_3: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a0, $a0, 3 +-; LA64-NEXT: ret +- %shl = shl i8 %x, 3 +- ret i8 %shl +-} +- +-define i16 @shl_i16_3(i16 %x) { +-; LA32-LABEL: shl_i16_3: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a0, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: shl_i16_3: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a0, $a0, 3 +-; LA64-NEXT: ret +- %shl = shl i16 %x, 3 +- ret i16 %shl +-} +- +-define i32 @shl_i32_3(i32 %x) { +-; LA32-LABEL: shl_i32_3: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a0, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: shl_i32_3: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a0, $a0, 3 +-; LA64-NEXT: ret +- %shl = shl i32 %x, 3 +- ret i32 %shl +-} +- +-define i64 @shl_i64_3(i64 %x) { +-; LA32-LABEL: shl_i64_3: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a1, 3 +-; LA32-NEXT: srli.w $a2, $a0, 29 +-; LA32-NEXT: or $a1, $a1, $a2 +-; LA32-NEXT: slli.w $a0, $a0, 3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: shl_i64_3: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a0, $a0, 3 +-; LA64-NEXT: ret +- %shl = shl i64 %x, 3 +- ret i64 %shl +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/sub.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/sub.ll +deleted file mode 100644 +index 98357744f..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/sub.ll ++++ /dev/null +@@ -1,94 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-;; Exercise the 'sub' LLVM IR: https://llvm.org/docs/LangRef.html#sub-instruction +- +-define i1 @sub_i1(i1 %x, i1 %y) { +-; LA32-LABEL: sub_i1: +-; LA32: # %bb.0: +-; LA32-NEXT: sub.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sub_i1: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %sub = sub i1 %x, %y +- ret i1 %sub +-} +- +-define i8 @sub_i8(i8 %x, i8 %y) { +-; LA32-LABEL: sub_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: sub.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sub_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %sub = sub i8 %x, %y +- ret i8 %sub +-} +- +-define i16 @sub_i16(i16 %x, i16 %y) { +-; LA32-LABEL: sub_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: sub.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sub_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %sub = sub i16 %x, %y +- ret i16 %sub +-} +- +-define i32 @sub_i32(i32 %x, i32 %y) { +-; LA32-LABEL: sub_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: sub.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sub_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %sub = sub i32 %x, %y +- ret i32 %sub +-} +- +-;; Match the pattern: +-;; def : PatGprGpr_32; +-define signext i32 @sub_i32_sext(i32 %x, i32 %y) { +-; LA32-LABEL: sub_i32_sext: +-; LA32: # %bb.0: +-; LA32-NEXT: sub.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sub_i32_sext: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %sub = sub i32 %x, %y +- ret i32 %sub +-} +- +-define i64 @sub_i64(i64 %x, i64 %y) { +-; LA32-LABEL: sub_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: sub.w $a1, $a1, $a3 +-; LA32-NEXT: sltu $a3, $a0, $a2 +-; LA32-NEXT: sub.w $a1, $a1, $a3 +-; LA32-NEXT: sub.w $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sub_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %sub = sub i64 %x, %y +- ret i64 %sub +-} +diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/xor.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/xor.ll +deleted file mode 100644 +index 373c9cf4b..000000000 +--- a/llvm/test/CodeGen/LoongArch/ir-instruction/xor.ll ++++ /dev/null +@@ -1,265 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-;; Exercise the 'xor' LLVM IR: https://llvm.org/docs/LangRef.html#xor-instruction +- +-define i1 @xor_i1(i1 %a, i1 %b) { +-; LA32-LABEL: xor_i1: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: xor $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: xor_i1: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = xor i1 %a, %b +- ret i1 %r +-} +- +-define i8 @xor_i8(i8 %a, i8 %b) { +-; LA32-LABEL: xor_i8: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: xor $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: xor_i8: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = xor i8 %a, %b +- ret i8 %r +-} +- +-define i16 @xor_i16(i16 %a, i16 %b) { +-; LA32-LABEL: xor_i16: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: xor $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: xor_i16: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = xor i16 %a, %b +- ret i16 %r +-} +- +-define i32 @xor_i32(i32 %a, i32 %b) { +-; LA32-LABEL: xor_i32: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: xor $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: xor_i32: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = xor i32 %a, %b +- ret i32 %r +-} +- +-define i64 @xor_i64(i64 %a, i64 %b) { +-; LA32-LABEL: xor_i64: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: xor $a0, $a0, $a2 +-; LA32-NEXT: xor $a1, $a1, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: xor_i64: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = xor i64 %a, %b +- ret i64 %r +-} +- +-define i1 @xor_i1_0(i1 %b) { +-; LA32-LABEL: xor_i1_0: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: ret +-; +-; LA64-LABEL: xor_i1_0: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ret +-entry: +- %r = xor i1 4, %b +- ret i1 %r +-} +- +-define i1 @xor_i1_5(i1 %b) { +-; LA32-LABEL: xor_i1_5: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: xor_i1_5: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: ret +-entry: +- %r = xor i1 5, %b +- ret i1 %r +-} +- +-define i8 @xor_i8_5(i8 %b) { +-; LA32-LABEL: xor_i8_5: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: xori $a0, $a0, 5 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: xor_i8_5: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: xori $a0, $a0, 5 +-; LA64-NEXT: ret +-entry: +- %r = xor i8 5, %b +- ret i8 %r +-} +- +-define i8 @xor_i8_257(i8 %b) { +-; LA32-LABEL: xor_i8_257: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: xor_i8_257: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: ret +-entry: +- %r = xor i8 257, %b +- ret i8 %r +-} +- +-define i16 @xor_i16_5(i16 %b) { +-; LA32-LABEL: xor_i16_5: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: xori $a0, $a0, 5 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: xor_i16_5: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: xori $a0, $a0, 5 +-; LA64-NEXT: ret +-entry: +- %r = xor i16 5, %b +- ret i16 %r +-} +- +-define i16 @xor_i16_0x1000(i16 %b) { +-; LA32-LABEL: xor_i16_0x1000: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: lu12i.w $a1, 1 +-; LA32-NEXT: xor $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: xor_i16_0x1000: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: lu12i.w $a1, 1 +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = xor i16 4096, %b +- ret i16 %r +-} +- +-define i16 @xor_i16_0x10001(i16 %b) { +-; LA32-LABEL: xor_i16_0x10001: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: xor_i16_0x10001: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: ret +-entry: +- %r = xor i16 65537, %b +- ret i16 %r +-} +- +-define i32 @xor_i32_5(i32 %b) { +-; LA32-LABEL: xor_i32_5: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: xori $a0, $a0, 5 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: xor_i32_5: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: xori $a0, $a0, 5 +-; LA64-NEXT: ret +-entry: +- %r = xor i32 5, %b +- ret i32 %r +-} +- +-define i32 @xor_i32_0x1000(i32 %b) { +-; LA32-LABEL: xor_i32_0x1000: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: lu12i.w $a1, 1 +-; LA32-NEXT: xor $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: xor_i32_0x1000: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: lu12i.w $a1, 1 +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = xor i32 4096, %b +- ret i32 %r +-} +- +-define i32 @xor_i32_0x100000001(i32 %b) { +-; LA32-LABEL: xor_i32_0x100000001: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: xor_i32_0x100000001: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: ret +-entry: +- %r = xor i32 4294967297, %b +- ret i32 %r +-} +- +-define i64 @xor_i64_5(i64 %b) { +-; LA32-LABEL: xor_i64_5: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: xori $a0, $a0, 5 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: xor_i64_5: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: xori $a0, $a0, 5 +-; LA64-NEXT: ret +-entry: +- %r = xor i64 5, %b +- ret i64 %r +-} +- +-define i64 @xor_i64_0x1000(i64 %b) { +-; LA32-LABEL: xor_i64_0x1000: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: lu12i.w $a2, 1 +-; LA32-NEXT: xor $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: xor_i64_0x1000: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: lu12i.w $a1, 1 +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: ret +-entry: +- %r = xor i64 4096, %b +- ret i64 %r +-} +diff --git a/llvm/test/CodeGen/LoongArch/is_fpclass_f32.ll b/llvm/test/CodeGen/LoongArch/is_fpclass_f32.ll +deleted file mode 100644 +index af128fa52..000000000 +--- a/llvm/test/CodeGen/LoongArch/is_fpclass_f32.ll ++++ /dev/null +@@ -1,843 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch32 --mattr=+f --verify-machineinstrs < %s | FileCheck %s +-; RUN: llc --mtriple=loongarch64 --mattr=+f --verify-machineinstrs < %s | FileCheck %s +- +-define i1 @isnan_f(float %x) { +-; CHECK-LABEL: isnan_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 3 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 3) ; "nan" +- ret i1 %0 +-} +- +-define i1 @isnot_nan_f(float %x) { +-; CHECK-LABEL: isnot_nan_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 1020 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1020) ; 0x3fc = "zero|subnormal|normal|inf" +- ret i1 %0 +-} +- +-define i1 @issignaling_f(float %x) { +-; CHECK-LABEL: issignaling_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 1 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1) ; "snan" +- ret i1 %0 +-} +- +-define i1 @not_issignaling_f(float %x) { +-; CHECK-LABEL: not_issignaling_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 1022 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1022) ; ~"snan" +- ret i1 %0 +-} +- +-define i1 @isquiet_f(float %x) { +-; CHECK-LABEL: isquiet_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 2 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 2) ; "qnan" +- ret i1 %0 +-} +- +-define i1 @not_isquiet_f(float %x) { +-; CHECK-LABEL: not_isquiet_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 1021 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1021) ; ~"qnan" +- ret i1 %0 +-} +- +-define i1 @isinf_f(float %x) { +-; CHECK-LABEL: isinf_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 68 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 516) ; 0x204 = "inf" +- ret i1 %0 +-} +- +-define i1 @not_isinf_f(float %x) { +-; CHECK-LABEL: not_isinf_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 955 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 507) ; ~0x204 = "~inf" +- ret i1 %0 +-} +- +-define i1 @is_plus_inf_f(float %x) { +-; CHECK-LABEL: is_plus_inf_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 64 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 512) ; 0x200 = "+inf" +- ret i1 %0 +-} +- +-define i1 @is_minus_inf_f(float %x) { +-; CHECK-LABEL: is_minus_inf_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 4 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 4) ; "-inf" +- ret i1 %0 +-} +- +-define i1 @not_is_minus_inf_f(float %x) { +-; CHECK-LABEL: not_is_minus_inf_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 1019 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1019) ; ~"-inf" +- ret i1 %0 +-} +- +-define i1 @isfinite_f(float %x) { +-; CHECK-LABEL: isfinite_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 952 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 504) ; 0x1f8 = "finite" +- ret i1 %0 +-} +- +-define i1 @not_isfinite_f(float %x) { +-; CHECK-LABEL: not_isfinite_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 71 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 519) ; ~0x1f8 = "~finite" +- ret i1 %0 +-} +- +-define i1 @is_plus_finite_f(float %x) { +-; CHECK-LABEL: is_plus_finite_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 896 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 448) ; 0x1c0 = "+finite" +- ret i1 %0 +-} +- +-define i1 @not_is_plus_finite_f(float %x) { +-; CHECK-LABEL: not_is_plus_finite_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 127 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 575) ; ~0x1c0 = ~"+finite" +- ret i1 %0 +-} +- +-define i1 @is_minus_finite_f(float %x) { +-; CHECK-LABEL: is_minus_finite_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 56 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 56) ; 0x38 = "-finite" +- ret i1 %0 +-} +- +-define i1 @not_is_minus_finite_f(float %x) { +-; CHECK-LABEL: not_is_minus_finite_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 967 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 967) ; ~0x38 = ~"-finite" +- ret i1 %0 +-} +- +-define i1 @isnormal_f(float %x) { +-; CHECK-LABEL: isnormal_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 136 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 264) ; 0x108 = "normal" +- ret i1 %0 +-} +- +-define i1 @not_isnormal_f(float %x) { +-; CHECK-LABEL: not_isnormal_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 887 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 759) ; ~0x108 = "~normal" +- ret i1 %0 +-} +- +-define i1 @is_plus_normal_f(float %x) { +-; CHECK-LABEL: is_plus_normal_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 128 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 256) ; 0x100 = "+normal" +- ret i1 %0 +-} +- +-define i1 @issubnormal_f(float %x) { +-; CHECK-LABEL: issubnormal_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 272 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 144) ; 0x90 = "subnormal" +- ret i1 %0 +-} +- +-define i1 @not_issubnormal_f(float %x) { +-; CHECK-LABEL: not_issubnormal_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 751 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 879) ; ~0x90 = "~subnormal" +- ret i1 %0 +-} +- +-define i1 @is_plus_subnormal_f(float %x) { +-; CHECK-LABEL: is_plus_subnormal_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 256 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 128) ; 0x80 = "+subnormal" +- ret i1 %0 +-} +- +-define i1 @not_is_plus_subnormal_f(float %x) { +-; CHECK-LABEL: not_is_plus_subnormal_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 767 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 895) ; ~0x80 = ~"+subnormal" +- ret i1 %0 +-} +- +-define i1 @is_minus_subnormal_f(float %x) { +-; CHECK-LABEL: is_minus_subnormal_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 16 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 16) ; 0x10 = "-subnormal" +- ret i1 %0 +-} +- +-define i1 @not_is_minus_subnormal_f(float %x) { +-; CHECK-LABEL: not_is_minus_subnormal_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 1007 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1007) ; ~0x10 = ~"-subnormal" +- ret i1 %0 +-} +- +-define i1 @iszero_f(float %x) { +-; CHECK-LABEL: iszero_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 544 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 96) ; 0x60 = "zero" +- ret i1 %0 +-} +- +-define i1 @not_iszero_f(float %x) { +-; CHECK-LABEL: not_iszero_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 479 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 927) ; ~0x60 = "~zero" +- ret i1 %0 +-} +- +-define i1 @issubnormal_or_zero_f(float %x) { +-; CHECK-LABEL: issubnormal_or_zero_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 816 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 240) ; 0xf0 = "subnormal|zero" +- ret i1 %0 +-} +- +-define i1 @not_issubnormal_or_zero_f(float %x) { +-; CHECK-LABEL: not_issubnormal_or_zero_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 207 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 783) ; ~0xf0 = "~(subnormal|zero)" +- ret i1 %0 +-} +- +-define i1 @is_plus_zero_f(float %x) { +-; CHECK-LABEL: is_plus_zero_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 512 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 64) ; 0x40 = "+zero" +- ret i1 %0 +-} +- +-define i1 @not_is_plus_zero_f(float %x) { +-; CHECK-LABEL: not_is_plus_zero_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 511 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 959) ; ~0x40 = ~"+zero" +- ret i1 %0 +-} +- +-define i1 @is_minus_zero_f(float %x) { +-; CHECK-LABEL: is_minus_zero_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 32 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 32) ; 0x20 = "-zero" +- ret i1 %0 +-} +- +-define i1 @not_is_minus_zero_f(float %x) { +-; CHECK-LABEL: not_is_minus_zero_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 991 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 991) ; ~0x20 = ~"-zero" +- ret i1 %0 +-} +- +-define i1 @isnone_f(float %x) { +-; CHECK-LABEL: isnone_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 0 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 0) +- ret i1 %0 +-} +- +-define i1 @isany_f(float %x) { +-; CHECK-LABEL: isany_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 1023 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1023) +- ret i1 %0 +-} +- +-define i1 @iszero_or_nan_f(float %x) { +-; CHECK-LABEL: iszero_or_nan_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 547 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 99) ; 0x60|0x3 = "zero|nan" +- ret i1 %0 +-} +- +-define i1 @not_iszero_or_nan_f(float %x) { +-; CHECK-LABEL: not_iszero_or_nan_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 476 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 924) ; ~0x60 = "~(zero|nan)" +- ret i1 %0 +-} +- +-define i1 @iszero_or_qnan_f(float %x) { +-; CHECK-LABEL: iszero_or_qnan_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 546 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 98) ; 0x60|0x2 = "zero|qnan" +- ret i1 %0 +-} +- +-define i1 @iszero_or_snan_f(float %x) { +-; CHECK-LABEL: iszero_or_snan_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 545 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 97) ; 0x60|0x1 = "zero|snan" +- ret i1 %0 +-} +- +-define i1 @not_iszero_or_qnan_f(float %x) { +-; CHECK-LABEL: not_iszero_or_qnan_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 477 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 925) ; ~(0x60|0x2) = "~(zero|qnan)" +- ret i1 %0 +-} +- +-define i1 @not_iszero_or_snan_f(float %x) { +-; CHECK-LABEL: not_iszero_or_snan_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 478 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 926) ; ~(0x60|0x1) = "~(zero|snan)" +- ret i1 %0 +-} +- +-define i1 @isinf_or_nan_f(float %x) { +-; CHECK-LABEL: isinf_or_nan_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 71 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 519) ; 0x204|0x3 = "inf|nan" +- ret i1 %0 +-} +- +-define i1 @not_isinf_or_nan_f(float %x) { +-; CHECK-LABEL: not_isinf_or_nan_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 952 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 504) ; ~(0x204|0x3) = "~(inf|nan)" +- ret i1 %0 +-} +- +-define i1 @isfinite_or_nan_f(float %x) { +-; CHECK-LABEL: isfinite_or_nan_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 955 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 507) ; 0x1f8|0x3 = "finite|nan" +- ret i1 %0 +-} +- +-define i1 @not_isfinite_or_nan_f(float %x) { +-; CHECK-LABEL: not_isfinite_or_nan_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 68 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 516) ; ~(0x1f8|0x3) = "~(finite|nan)" +- ret i1 %0 +-} +- +-define i1 @is_plus_inf_or_nan_f(float %x) { +-; CHECK-LABEL: is_plus_inf_or_nan_f: +-; CHECK: # %bb.0: +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 67 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 515) ; 0x200|0x3 = "+inf|nan" +- ret i1 %class +-} +- +-define i1 @is_minus_inf_or_nan_f(float %x) { +-; CHECK-LABEL: is_minus_inf_or_nan_f: +-; CHECK: # %bb.0: +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 7 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 7) ; "-inf|nan" +- ret i1 %class +-} +- +-define i1 @not_is_plus_inf_or_nan_f(float %x) { +-; CHECK-LABEL: not_is_plus_inf_or_nan_f: +-; CHECK: # %bb.0: +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 956 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 508) ; ~(0x200|0x3) = "~(+inf|nan)" +- ret i1 %class +-} +- +-define i1 @not_is_minus_inf_or_nan_f(float %x) { +-; CHECK-LABEL: not_is_minus_inf_or_nan_f: +-; CHECK: # %bb.0: +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 1016 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1016) ; "~(-inf|nan)" +- ret i1 %class +-} +- +-define i1 @is_plus_inf_or_snan_f(float %x) { +-; CHECK-LABEL: is_plus_inf_or_snan_f: +-; CHECK: # %bb.0: +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 65 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 513) ; 0x200|0x1 = "+inf|snan" +- ret i1 %class +-} +- +-define i1 @is_plus_inf_or_qnan_f(float %x) { +-; CHECK-LABEL: is_plus_inf_or_qnan_f: +-; CHECK: # %bb.0: +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 66 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 514) ; 0x200|0x1 = "+inf|qnan" +- ret i1 %class +-} +- +-define i1 @not_is_plus_inf_or_snan_f(float %x) { +-; CHECK-LABEL: not_is_plus_inf_or_snan_f: +-; CHECK: # %bb.0: +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 958 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 510) ; ~(+inf|snan) +- ret i1 %class +-} +- +-define i1 @not_is_plus_inf_or_qnan_f(float %x) { +-; CHECK-LABEL: not_is_plus_inf_or_qnan_f: +-; CHECK: # %bb.0: +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 957 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 509) ; ~(+inf|qnan) +- ret i1 %class +-} +- +-define i1 @is_minus_inf_or_snan_f(float %x) { +-; CHECK-LABEL: is_minus_inf_or_snan_f: +-; CHECK: # %bb.0: +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 5 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 5) ; "-inf|snan" +- ret i1 %class +-} +- +-define i1 @is_minus_inf_or_qnan_f(float %x) { +-; CHECK-LABEL: is_minus_inf_or_qnan_f: +-; CHECK: # %bb.0: +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 6 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 6) ; "-inf|qnan" +- ret i1 %class +-} +- +-define i1 @not_is_minus_inf_or_snan_f(float %x) { +-; CHECK-LABEL: not_is_minus_inf_or_snan_f: +-; CHECK: # %bb.0: +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 1018 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1018) ; "~(-inf|snan)" +- ret i1 %class +-} +- +-define i1 @not_is_minus_inf_or_qnan_f(float %x) { +-; CHECK-LABEL: not_is_minus_inf_or_qnan_f: +-; CHECK: # %bb.0: +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 1017 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1017) ; "-inf|qnan" +- ret i1 %class +-} +- +-define i1 @issubnormal_or_nan_f(float %x) { +-; CHECK-LABEL: issubnormal_or_nan_f: +-; CHECK: # %bb.0: +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 275 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 147) ; 0x90|0x3 = "subnormal|nan" +- ret i1 %class +-} +- +-define i1 @issubnormal_or_zero_or_nan_f(float %x) { +-; CHECK-LABEL: issubnormal_or_zero_or_nan_f: +-; CHECK: # %bb.0: +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 819 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 243) ; 0xf0|0x3 = "subnormal|zero|nan" +- ret i1 %class +-} +- +-define i1 @issubnormal_or_zero_or_snan_f(float %x) { +-; CHECK-LABEL: issubnormal_or_zero_or_snan_f: +-; CHECK: # %bb.0: +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 817 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 241) ; 0x90|0x1 = "subnormal|snan" +- ret i1 %class +-} +- +-define i1 @issubnormal_or_zero_or_qnan_f(float %x) { +-; CHECK-LABEL: issubnormal_or_zero_or_qnan_f: +-; CHECK: # %bb.0: +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 818 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 242) ; 0x90|0x2 = "subnormal|qnan" +- ret i1 %class +-} +- +-define i1 @not_issubnormal_or_nan_f(float %x) { +-; CHECK-LABEL: not_issubnormal_or_nan_f: +-; CHECK: # %bb.0: +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 748 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 876) ; ~(0x90|0x3) = ~"subnormal|nan" +- ret i1 %class +-} +- +-define i1 @not_issubnormal_or_zero_or_nan_f(float %x) { +-; CHECK-LABEL: not_issubnormal_or_zero_or_nan_f: +-; CHECK: # %bb.0: +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 204 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 780) ; ~(0xf0|0x3) = ~"subnormal|zero|nan" +- ret i1 %class +-} +- +-define i1 @not_issubnormal_or_zero_or_snan_f(float %x) { +-; CHECK-LABEL: not_issubnormal_or_zero_or_snan_f: +-; CHECK: # %bb.0: +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 206 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 782) ; ~(0x90|0x1) = ~"subnormal|snan" +- ret i1 %class +-} +- +-define i1 @not_issubnormal_or_zero_or_qnan_f(float %x) { +-; CHECK-LABEL: not_issubnormal_or_zero_or_qnan_f: +-; CHECK: # %bb.0: +-; CHECK-NEXT: fclass.s $fa0, $fa0 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: andi $a0, $a0, 205 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f32(float %x, i32 781) ; ~(0x90|0x2) = ~"subnormal|qnan" +- ret i1 %class +-} +- +-declare i1 @llvm.is.fpclass.f32(float, i32) +diff --git a/llvm/test/CodeGen/LoongArch/is_fpclass_f64.ll b/llvm/test/CodeGen/LoongArch/is_fpclass_f64.ll +deleted file mode 100644 +index e58f81a08..000000000 +--- a/llvm/test/CodeGen/LoongArch/is_fpclass_f64.ll ++++ /dev/null +@@ -1,1371 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch32 --mattr=+d --verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK32 +-; RUN: llc --mtriple=loongarch64 --mattr=+d --verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK64 +- +-define i1 @isnan_d(double %x) { +-; CHECK32-LABEL: isnan_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 3 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: isnan_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 3 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 3) ; "nan" +- ret i1 %0 +-} +- +-define i1 @isnot_nan_d(double %x) { +-; CHECK32-LABEL: isnot_nan_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 1020 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: isnot_nan_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 1020 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 1020) ; 0x3fc = "zero|subnormal|normal|inf" +- ret i1 %0 +-} +- +-define i1 @issignaling_d(double %x) { +-; CHECK32-LABEL: issignaling_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 1 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: issignaling_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 1 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 1) ; "snan" +- ret i1 %0 +-} +- +-define i1 @not_issignaling_d(double %x) { +-; CHECK32-LABEL: not_issignaling_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 1022 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_issignaling_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 1022 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 1022) ; ~"snan" +- ret i1 %0 +-} +- +-define i1 @isquiet_d(double %x) { +-; CHECK32-LABEL: isquiet_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 2 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: isquiet_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 2 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 2) ; "qnan" +- ret i1 %0 +-} +- +-define i1 @not_isquiet_d(double %x) { +-; CHECK32-LABEL: not_isquiet_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 1021 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_isquiet_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 1021 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 1021) ; ~"qnan" +- ret i1 %0 +-} +- +-define i1 @isinf_d(double %x) { +-; CHECK32-LABEL: isinf_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 68 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: isinf_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 68 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 516) ; 0x204 = "inf" +- ret i1 %0 +-} +- +-define i1 @not_isinf_d(double %x) { +-; CHECK32-LABEL: not_isinf_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 955 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_isinf_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 955 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 507) ; ~0x204 = "~inf" +- ret i1 %0 +-} +- +-define i1 @is_plus_inf_d(double %x) { +-; CHECK32-LABEL: is_plus_inf_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 64 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: is_plus_inf_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 64 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 512) ; 0x200 = "+inf" +- ret i1 %0 +-} +- +-define i1 @is_minus_inf_d(double %x) { +-; CHECK32-LABEL: is_minus_inf_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 4 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: is_minus_inf_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 4 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 4) ; "-inf" +- ret i1 %0 +-} +- +-define i1 @not_is_minus_inf_d(double %x) { +-; CHECK32-LABEL: not_is_minus_inf_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 1019 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_is_minus_inf_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 1019 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 1019) ; ~"-inf" +- ret i1 %0 +-} +- +-define i1 @isfinite_d(double %x) { +-; CHECK32-LABEL: isfinite_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 952 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: isfinite_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 952 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 504) ; 0x1f8 = "finite" +- ret i1 %0 +-} +- +-define i1 @not_isfinite_d(double %x) { +-; CHECK32-LABEL: not_isfinite_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 71 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_isfinite_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 71 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 519) ; ~0x1f8 = "~finite" +- ret i1 %0 +-} +- +-define i1 @is_plus_finite_d(double %x) { +-; CHECK32-LABEL: is_plus_finite_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 896 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: is_plus_finite_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 896 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 448) ; 0x1c0 = "+finite" +- ret i1 %0 +-} +- +-define i1 @not_is_plus_finite_d(double %x) { +-; CHECK32-LABEL: not_is_plus_finite_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 127 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_is_plus_finite_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 127 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 575) ; ~0x1c0 = ~"+finite" +- ret i1 %0 +-} +- +-define i1 @is_minus_finite_d(double %x) { +-; CHECK32-LABEL: is_minus_finite_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 56 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: is_minus_finite_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 56 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 56) ; 0x38 = "-finite" +- ret i1 %0 +-} +- +-define i1 @not_is_minus_finite_d(double %x) { +-; CHECK32-LABEL: not_is_minus_finite_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 967 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_is_minus_finite_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 967 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 967) ; ~0x38 = ~"-finite" +- ret i1 %0 +-} +- +-define i1 @isnormal_d(double %x) { +-; CHECK32-LABEL: isnormal_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 136 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: isnormal_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 136 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 264) ; 0x108 = "normal" +- ret i1 %0 +-} +- +-define i1 @not_isnormal_d(double %x) { +-; CHECK32-LABEL: not_isnormal_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 887 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_isnormal_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 887 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 759) ; ~0x108 = "~normal" +- ret i1 %0 +-} +- +-define i1 @is_plus_normal_d(double %x) { +-; CHECK32-LABEL: is_plus_normal_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 128 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: is_plus_normal_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 128 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 256) ; 0x100 = "+normal" +- ret i1 %0 +-} +- +-define i1 @issubnormal_d(double %x) { +-; CHECK32-LABEL: issubnormal_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 272 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: issubnormal_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 272 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 144) ; 0x90 = "subnormal" +- ret i1 %0 +-} +- +-define i1 @not_issubnormal_d(double %x) { +-; CHECK32-LABEL: not_issubnormal_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 751 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_issubnormal_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 751 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 879) ; ~0x90 = "~subnormal" +- ret i1 %0 +-} +- +-define i1 @is_plus_subnormal_d(double %x) { +-; CHECK32-LABEL: is_plus_subnormal_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 256 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: is_plus_subnormal_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 256 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 128) ; 0x80 = "+subnormal" +- ret i1 %0 +-} +- +-define i1 @not_is_plus_subnormal_d(double %x) { +-; CHECK32-LABEL: not_is_plus_subnormal_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 767 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_is_plus_subnormal_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 767 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 895) ; ~0x80 = ~"+subnormal" +- ret i1 %0 +-} +- +-define i1 @is_minus_subnormal_d(double %x) { +-; CHECK32-LABEL: is_minus_subnormal_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 16 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: is_minus_subnormal_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 16 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 16) ; 0x10 = "-subnormal" +- ret i1 %0 +-} +- +-define i1 @not_is_minus_subnormal_d(double %x) { +-; CHECK32-LABEL: not_is_minus_subnormal_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 1007 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_is_minus_subnormal_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 1007 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 1007) ; ~0x10 = ~"-subnormal" +- ret i1 %0 +-} +- +-define i1 @iszero_d(double %x) { +-; CHECK32-LABEL: iszero_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 544 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: iszero_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 544 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 96) ; 0x60 = "zero" +- ret i1 %0 +-} +- +-define i1 @not_iszero_d(double %x) { +-; CHECK32-LABEL: not_iszero_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 479 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_iszero_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 479 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 927) ; ~0x60 = "~zero" +- ret i1 %0 +-} +- +-define i1 @issubnormal_or_zero_d(double %x) { +-; CHECK32-LABEL: issubnormal_or_zero_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 816 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: issubnormal_or_zero_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 816 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 240) ; 0xf0 = "subnormal|zero" +- ret i1 %0 +-} +- +-define i1 @not_issubnormal_or_zero_d(double %x) { +-; CHECK32-LABEL: not_issubnormal_or_zero_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 207 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_issubnormal_or_zero_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 207 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 783) ; ~0xf0 = "~(subnormal|zero)" +- ret i1 %0 +-} +- +-define i1 @is_plus_zero_d(double %x) { +-; CHECK32-LABEL: is_plus_zero_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 512 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: is_plus_zero_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 512 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 64) ; 0x40 = "+zero" +- ret i1 %0 +-} +- +-define i1 @not_is_plus_zero_d(double %x) { +-; CHECK32-LABEL: not_is_plus_zero_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 511 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_is_plus_zero_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 511 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 959) ; ~0x40 = ~"+zero" +- ret i1 %0 +-} +- +-define i1 @is_minus_zero_d(double %x) { +-; CHECK32-LABEL: is_minus_zero_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 32 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: is_minus_zero_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 32 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 32) ; 0x20 = "-zero" +- ret i1 %0 +-} +- +-define i1 @not_is_minus_zero_d(double %x) { +-; CHECK32-LABEL: not_is_minus_zero_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 991 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_is_minus_zero_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 991 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 991) ; ~0x20 = ~"-zero" +- ret i1 %0 +-} +- +-define i1 @isnone_d(double %x) { +-; CHECK32-LABEL: isnone_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 0 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: isnone_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 0 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 0) +- ret i1 %0 +-} +- +-define i1 @isany_d(double %x) { +-; CHECK32-LABEL: isany_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 1023 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: isany_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 1023 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 1023) +- ret i1 %0 +-} +- +-define i1 @iszero_or_nan_d(double %x) { +-; CHECK32-LABEL: iszero_or_nan_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 547 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: iszero_or_nan_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 547 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 99) ; 0x60|0x3 = "zero|nan" +- ret i1 %0 +-} +- +-define i1 @not_iszero_or_nan_d(double %x) { +-; CHECK32-LABEL: not_iszero_or_nan_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 476 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_iszero_or_nan_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 476 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 924) ; ~0x60 = "~(zero|nan)" +- ret i1 %0 +-} +- +-define i1 @iszero_or_qnan_d(double %x) { +-; CHECK32-LABEL: iszero_or_qnan_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 546 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: iszero_or_qnan_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 546 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 98) ; 0x60|0x2 = "zero|qnan" +- ret i1 %0 +-} +- +-define i1 @iszero_or_snan_d(double %x) { +-; CHECK32-LABEL: iszero_or_snan_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 545 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: iszero_or_snan_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 545 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 97) ; 0x60|0x1 = "zero|snan" +- ret i1 %0 +-} +- +-define i1 @not_iszero_or_qnan_d(double %x) { +-; CHECK32-LABEL: not_iszero_or_qnan_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 477 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_iszero_or_qnan_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 477 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 925) ; ~(0x60|0x2) = "~(zero|qnan)" +- ret i1 %0 +-} +- +-define i1 @not_iszero_or_snan_d(double %x) { +-; CHECK32-LABEL: not_iszero_or_snan_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 478 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_iszero_or_snan_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 478 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 926) ; ~(0x60|0x1) = "~(zero|snan)" +- ret i1 %0 +-} +- +-define i1 @isinf_or_nan_d(double %x) { +-; CHECK32-LABEL: isinf_or_nan_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 71 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: isinf_or_nan_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 71 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 519) ; 0x204|0x3 = "inf|nan" +- ret i1 %0 +-} +- +-define i1 @not_isinf_or_nan_d(double %x) { +-; CHECK32-LABEL: not_isinf_or_nan_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 952 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_isinf_or_nan_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 952 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 504) ; ~(0x204|0x3) = "~(inf|nan)" +- ret i1 %0 +-} +- +-define i1 @isfinite_or_nan_d(double %x) { +-; CHECK32-LABEL: isfinite_or_nan_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 955 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: isfinite_or_nan_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 955 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 507) ; 0x1f8|0x3 = "finite|nan" +- ret i1 %0 +-} +- +-define i1 @not_isfinite_or_nan_d(double %x) { +-; CHECK32-LABEL: not_isfinite_or_nan_d: +-; CHECK32: # %bb.0: # %entry +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 68 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_isfinite_or_nan_d: +-; CHECK64: # %bb.0: # %entry +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 68 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +-entry: +- %0 = tail call i1 @llvm.is.fpclass.f64(double %x, i32 516) ; ~(0x1f8|0x3) = "~(finite|nan)" +- ret i1 %0 +-} +- +-define i1 @is_plus_inf_or_nan_d(double %x) { +-; CHECK32-LABEL: is_plus_inf_or_nan_d: +-; CHECK32: # %bb.0: +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 67 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: is_plus_inf_or_nan_d: +-; CHECK64: # %bb.0: +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 67 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 515) ; 0x200|0x3 = "+inf|nan" +- ret i1 %class +-} +- +-define i1 @is_minus_inf_or_nan_d(double %x) { +-; CHECK32-LABEL: is_minus_inf_or_nan_d: +-; CHECK32: # %bb.0: +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 7 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: is_minus_inf_or_nan_d: +-; CHECK64: # %bb.0: +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 7 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 7) ; "-inf|nan" +- ret i1 %class +-} +- +-define i1 @not_is_plus_inf_or_nan_d(double %x) { +-; CHECK32-LABEL: not_is_plus_inf_or_nan_d: +-; CHECK32: # %bb.0: +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 956 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_is_plus_inf_or_nan_d: +-; CHECK64: # %bb.0: +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 956 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 508) ; ~(0x200|0x3) = "~(+inf|nan)" +- ret i1 %class +-} +- +-define i1 @not_is_minus_inf_or_nan_d(double %x) { +-; CHECK32-LABEL: not_is_minus_inf_or_nan_d: +-; CHECK32: # %bb.0: +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 1016 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_is_minus_inf_or_nan_d: +-; CHECK64: # %bb.0: +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 1016 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 1016) ; "~(-inf|nan)" +- ret i1 %class +-} +- +-define i1 @is_plus_inf_or_snan_d(double %x) { +-; CHECK32-LABEL: is_plus_inf_or_snan_d: +-; CHECK32: # %bb.0: +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 65 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: is_plus_inf_or_snan_d: +-; CHECK64: # %bb.0: +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 65 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 513) ; 0x200|0x1 = "+inf|snan" +- ret i1 %class +-} +- +-define i1 @is_plus_inf_or_qnan_d(double %x) { +-; CHECK32-LABEL: is_plus_inf_or_qnan_d: +-; CHECK32: # %bb.0: +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 66 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: is_plus_inf_or_qnan_d: +-; CHECK64: # %bb.0: +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 66 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 514) ; 0x200|0x1 = "+inf|qnan" +- ret i1 %class +-} +- +-define i1 @not_is_plus_inf_or_snan_d(double %x) { +-; CHECK32-LABEL: not_is_plus_inf_or_snan_d: +-; CHECK32: # %bb.0: +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 958 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_is_plus_inf_or_snan_d: +-; CHECK64: # %bb.0: +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 958 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 510) ; ~(+inf|snan) +- ret i1 %class +-} +- +-define i1 @not_is_plus_inf_or_qnan_d(double %x) { +-; CHECK32-LABEL: not_is_plus_inf_or_qnan_d: +-; CHECK32: # %bb.0: +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 957 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_is_plus_inf_or_qnan_d: +-; CHECK64: # %bb.0: +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 957 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 509) ; ~(+inf|qnan) +- ret i1 %class +-} +- +-define i1 @is_minus_inf_or_snan_d(double %x) { +-; CHECK32-LABEL: is_minus_inf_or_snan_d: +-; CHECK32: # %bb.0: +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 5 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: is_minus_inf_or_snan_d: +-; CHECK64: # %bb.0: +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 5 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 5) ; "-inf|snan" +- ret i1 %class +-} +- +-define i1 @is_minus_inf_or_qnan_d(double %x) { +-; CHECK32-LABEL: is_minus_inf_or_qnan_d: +-; CHECK32: # %bb.0: +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 6 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: is_minus_inf_or_qnan_d: +-; CHECK64: # %bb.0: +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 6 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 6) ; "-inf|qnan" +- ret i1 %class +-} +- +-define i1 @not_is_minus_inf_or_snan_d(double %x) { +-; CHECK32-LABEL: not_is_minus_inf_or_snan_d: +-; CHECK32: # %bb.0: +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 1018 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_is_minus_inf_or_snan_d: +-; CHECK64: # %bb.0: +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 1018 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 1018) ; "~(-inf|snan)" +- ret i1 %class +-} +- +-define i1 @not_is_minus_inf_or_qnan_d(double %x) { +-; CHECK32-LABEL: not_is_minus_inf_or_qnan_d: +-; CHECK32: # %bb.0: +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 1017 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_is_minus_inf_or_qnan_d: +-; CHECK64: # %bb.0: +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 1017 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 1017) ; "-inf|qnan" +- ret i1 %class +-} +- +-define i1 @issubnormal_or_nan_d(double %x) { +-; CHECK32-LABEL: issubnormal_or_nan_d: +-; CHECK32: # %bb.0: +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 275 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: issubnormal_or_nan_d: +-; CHECK64: # %bb.0: +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 275 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 147) ; 0x90|0x3 = "subnormal|nan" +- ret i1 %class +-} +- +-define i1 @issubnormal_or_zero_or_nan_d(double %x) { +-; CHECK32-LABEL: issubnormal_or_zero_or_nan_d: +-; CHECK32: # %bb.0: +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 819 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: issubnormal_or_zero_or_nan_d: +-; CHECK64: # %bb.0: +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 819 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 243) ; 0xf0|0x3 = "subnormal|zero|nan" +- ret i1 %class +-} +- +-define i1 @issubnormal_or_zero_or_snan_d(double %x) { +-; CHECK32-LABEL: issubnormal_or_zero_or_snan_d: +-; CHECK32: # %bb.0: +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 817 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: issubnormal_or_zero_or_snan_d: +-; CHECK64: # %bb.0: +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 817 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 241) ; 0x90|0x1 = "subnormal|snan" +- ret i1 %class +-} +- +-define i1 @issubnormal_or_zero_or_qnan_d(double %x) { +-; CHECK32-LABEL: issubnormal_or_zero_or_qnan_d: +-; CHECK32: # %bb.0: +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 818 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: issubnormal_or_zero_or_qnan_d: +-; CHECK64: # %bb.0: +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 818 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 242) ; 0x90|0x2 = "subnormal|qnan" +- ret i1 %class +-} +- +-define i1 @not_issubnormal_or_nan_d(double %x) { +-; CHECK32-LABEL: not_issubnormal_or_nan_d: +-; CHECK32: # %bb.0: +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 748 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_issubnormal_or_nan_d: +-; CHECK64: # %bb.0: +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 748 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 876) ; ~(0x90|0x3) = ~"subnormal|nan" +- ret i1 %class +-} +- +-define i1 @not_issubnormal_or_zero_or_nan_d(double %x) { +-; CHECK32-LABEL: not_issubnormal_or_zero_or_nan_d: +-; CHECK32: # %bb.0: +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 204 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_issubnormal_or_zero_or_nan_d: +-; CHECK64: # %bb.0: +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 204 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 780) ; ~(0xf0|0x3) = ~"subnormal|zero|nan" +- ret i1 %class +-} +- +-define i1 @not_issubnormal_or_zero_or_snan_d(double %x) { +-; CHECK32-LABEL: not_issubnormal_or_zero_or_snan_d: +-; CHECK32: # %bb.0: +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 206 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_issubnormal_or_zero_or_snan_d: +-; CHECK64: # %bb.0: +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 206 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 782) ; ~(0x90|0x1) = ~"subnormal|snan" +- ret i1 %class +-} +- +-define i1 @not_issubnormal_or_zero_or_qnan_d(double %x) { +-; CHECK32-LABEL: not_issubnormal_or_zero_or_qnan_d: +-; CHECK32: # %bb.0: +-; CHECK32-NEXT: fclass.d $fa0, $fa0 +-; CHECK32-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK32-NEXT: andi $a0, $a0, 205 +-; CHECK32-NEXT: sltu $a0, $zero, $a0 +-; CHECK32-NEXT: ret +-; +-; CHECK64-LABEL: not_issubnormal_or_zero_or_qnan_d: +-; CHECK64: # %bb.0: +-; CHECK64-NEXT: fclass.d $fa0, $fa0 +-; CHECK64-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK64-NEXT: andi $a0, $a0, 205 +-; CHECK64-NEXT: sltu $a0, $zero, $a0 +-; CHECK64-NEXT: ret +- %class = tail call i1 @llvm.is.fpclass.f64(double %x, i32 781) ; ~(0x90|0x2) = ~"subnormal|qnan" +- ret i1 %class +-} +- +-declare i1 @llvm.is.fpclass.f64(double, i32) +diff --git a/llvm/test/CodeGen/LoongArch/jirl-verify.ll b/llvm/test/CodeGen/LoongArch/jirl-verify.ll +new file mode 100644 +index 000000000..70b588bea +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/jirl-verify.ll +@@ -0,0 +1,34 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -verify-machineinstrs -o - %s \ ++; RUN: | FileCheck %s --check-prefix=STATIC ++; RUN: llc -march=loongarch64 -verify-machineinstrs -relocation-model=pic --code-model=large -o - %s \ ++; RUN: | FileCheck %s --check-prefix=LARGE ++ ++define void @test() nounwind { ++; STATIC-LABEL: test: ++; STATIC: # %bb.0: ++; STATIC-NEXT: addi.d $sp, $sp, -16 ++; STATIC-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill ++; STATIC-NEXT: lu12i.w $ra, foo ++; STATIC-NEXT: ori $ra, $ra, foo ++; STATIC-NEXT: lu32i.d $ra, foo ++; STATIC-NEXT: lu52i.d $ra, $ra, foo ++; STATIC-NEXT: jirl $ra, $ra, 0 ++; STATIC-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ++; STATIC-NEXT: addi.d $sp, $sp, 16 ++; STATIC-NEXT: jr $ra ++; ++; LARGE-LABEL: test: ++; LARGE: # %bb.0: ++; LARGE-NEXT: addi.d $sp, $sp, -16 ++; LARGE-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill ++; LARGE-NEXT: pcaddu18i $ra, foo ++; LARGE-NEXT: jirl $ra, $ra, foo ++; LARGE-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ++; LARGE-NEXT: addi.d $sp, $sp, 16 ++; LARGE-NEXT: jr $ra ++ call void @foo() nounwind ++ ret void ++} ++ ++declare void @foo() +diff --git a/llvm/test/CodeGen/LoongArch/jump-table.ll b/llvm/test/CodeGen/LoongArch/jump-table.ll +deleted file mode 100644 +index 0cd6ef02d..000000000 +--- a/llvm/test/CodeGen/LoongArch/jump-table.ll ++++ /dev/null +@@ -1,151 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --min-jump-table-entries=5 < %s \ +-; RUN: | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --min-jump-table-entries=5 < %s \ +-; RUN: | FileCheck %s --check-prefix=LA64 +-; RUN: llc --mtriple=loongarch32 --min-jump-table-entries=4 < %s \ +-; RUN: | FileCheck %s --check-prefix=LA32-JT +-; RUN: llc --mtriple=loongarch64 --min-jump-table-entries=4 < %s \ +-; RUN: | FileCheck %s --check-prefix=LA64-JT +- +-;; The default mininum number of entries to use a jump table is 4. +-;; +-;; Note: The parameter `--min-jump-table-entries` will have no effect once we +-;; have set the default value using `setMinimumJumpTableEntries`. +- +-define void @switch_4_arms(i32 %in, ptr %out) nounwind { +-; LA32-LABEL: switch_4_arms: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: ori $a2, $zero, 2 +-; LA32-NEXT: blt $a2, $a0, .LBB0_4 +-; LA32-NEXT: # %bb.1: # %entry +-; LA32-NEXT: ori $a3, $zero, 1 +-; LA32-NEXT: beq $a0, $a3, .LBB0_7 +-; LA32-NEXT: # %bb.2: # %entry +-; LA32-NEXT: bne $a0, $a2, .LBB0_9 +-; LA32-NEXT: # %bb.3: # %bb2 +-; LA32-NEXT: ori $a0, $zero, 3 +-; LA32-NEXT: st.w $a0, $a1, 0 +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB0_4: # %entry +-; LA32-NEXT: ori $a3, $zero, 3 +-; LA32-NEXT: beq $a0, $a3, .LBB0_8 +-; LA32-NEXT: # %bb.5: # %entry +-; LA32-NEXT: ori $a2, $zero, 4 +-; LA32-NEXT: bne $a0, $a2, .LBB0_9 +-; LA32-NEXT: # %bb.6: # %bb4 +-; LA32-NEXT: ori $a0, $zero, 1 +-; LA32-NEXT: st.w $a0, $a1, 0 +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB0_7: # %bb1 +-; LA32-NEXT: ori $a0, $zero, 4 +-; LA32-NEXT: st.w $a0, $a1, 0 +-; LA32-NEXT: ret +-; LA32-NEXT: .LBB0_8: # %bb3 +-; LA32-NEXT: st.w $a2, $a1, 0 +-; LA32-NEXT: .LBB0_9: # %exit +-; LA32-NEXT: ret +-; +-; LA64-LABEL: switch_4_arms: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: ori $a2, $zero, 2 +-; LA64-NEXT: blt $a2, $a0, .LBB0_4 +-; LA64-NEXT: # %bb.1: # %entry +-; LA64-NEXT: ori $a3, $zero, 1 +-; LA64-NEXT: beq $a0, $a3, .LBB0_7 +-; LA64-NEXT: # %bb.2: # %entry +-; LA64-NEXT: bne $a0, $a2, .LBB0_9 +-; LA64-NEXT: # %bb.3: # %bb2 +-; LA64-NEXT: ori $a0, $zero, 3 +-; LA64-NEXT: st.w $a0, $a1, 0 +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB0_4: # %entry +-; LA64-NEXT: ori $a3, $zero, 3 +-; LA64-NEXT: beq $a0, $a3, .LBB0_8 +-; LA64-NEXT: # %bb.5: # %entry +-; LA64-NEXT: ori $a2, $zero, 4 +-; LA64-NEXT: bne $a0, $a2, .LBB0_9 +-; LA64-NEXT: # %bb.6: # %bb4 +-; LA64-NEXT: ori $a0, $zero, 1 +-; LA64-NEXT: st.w $a0, $a1, 0 +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB0_7: # %bb1 +-; LA64-NEXT: ori $a0, $zero, 4 +-; LA64-NEXT: st.w $a0, $a1, 0 +-; LA64-NEXT: ret +-; LA64-NEXT: .LBB0_8: # %bb3 +-; LA64-NEXT: st.w $a2, $a1, 0 +-; LA64-NEXT: .LBB0_9: # %exit +-; LA64-NEXT: ret +-; +-; LA32-JT-LABEL: switch_4_arms: +-; LA32-JT: # %bb.0: # %entry +-; LA32-JT-NEXT: addi.w $a2, $a0, -1 +-; LA32-JT-NEXT: ori $a0, $zero, 3 +-; LA32-JT-NEXT: bltu $a0, $a2, .LBB0_6 +-; LA32-JT-NEXT: # %bb.1: # %entry +-; LA32-JT-NEXT: pcalau12i $a3, %pc_hi20(.LJTI0_0) +-; LA32-JT-NEXT: addi.w $a3, $a3, %pc_lo12(.LJTI0_0) +-; LA32-JT-NEXT: alsl.w $a2, $a2, $a3, 2 +-; LA32-JT-NEXT: ld.w $a2, $a2, 0 +-; LA32-JT-NEXT: jr $a2 +-; LA32-JT-NEXT: .LBB0_2: # %bb1 +-; LA32-JT-NEXT: ori $a0, $zero, 4 +-; LA32-JT-NEXT: b .LBB0_5 +-; LA32-JT-NEXT: .LBB0_3: # %bb3 +-; LA32-JT-NEXT: ori $a0, $zero, 2 +-; LA32-JT-NEXT: b .LBB0_5 +-; LA32-JT-NEXT: .LBB0_4: # %bb4 +-; LA32-JT-NEXT: ori $a0, $zero, 1 +-; LA32-JT-NEXT: .LBB0_5: # %exit +-; LA32-JT-NEXT: st.w $a0, $a1, 0 +-; LA32-JT-NEXT: .LBB0_6: # %exit +-; LA32-JT-NEXT: ret +-; +-; LA64-JT-LABEL: switch_4_arms: +-; LA64-JT: # %bb.0: # %entry +-; LA64-JT-NEXT: addi.w $a0, $a0, 0 +-; LA64-JT-NEXT: addi.d $a2, $a0, -1 +-; LA64-JT-NEXT: ori $a0, $zero, 3 +-; LA64-JT-NEXT: bltu $a0, $a2, .LBB0_6 +-; LA64-JT-NEXT: # %bb.1: # %entry +-; LA64-JT-NEXT: slli.d $a2, $a2, 3 +-; LA64-JT-NEXT: pcalau12i $a3, %pc_hi20(.LJTI0_0) +-; LA64-JT-NEXT: addi.d $a3, $a3, %pc_lo12(.LJTI0_0) +-; LA64-JT-NEXT: ldx.d $a2, $a2, $a3 +-; LA64-JT-NEXT: jr $a2 +-; LA64-JT-NEXT: .LBB0_2: # %bb1 +-; LA64-JT-NEXT: ori $a0, $zero, 4 +-; LA64-JT-NEXT: b .LBB0_5 +-; LA64-JT-NEXT: .LBB0_3: # %bb3 +-; LA64-JT-NEXT: ori $a0, $zero, 2 +-; LA64-JT-NEXT: b .LBB0_5 +-; LA64-JT-NEXT: .LBB0_4: # %bb4 +-; LA64-JT-NEXT: ori $a0, $zero, 1 +-; LA64-JT-NEXT: .LBB0_5: # %exit +-; LA64-JT-NEXT: st.w $a0, $a1, 0 +-; LA64-JT-NEXT: .LBB0_6: # %exit +-; LA64-JT-NEXT: ret +-entry: +- switch i32 %in, label %exit [ +- i32 1, label %bb1 +- i32 2, label %bb2 +- i32 3, label %bb3 +- i32 4, label %bb4 +- ] +-bb1: +- store i32 4, ptr %out +- br label %exit +-bb2: +- store i32 3, ptr %out +- br label %exit +-bb3: +- store i32 2, ptr %out +- br label %exit +-bb4: +- store i32 1, ptr %out +- br label %exit +-exit: +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/VExtend.ll b/llvm/test/CodeGen/LoongArch/lasx/VExtend.ll +new file mode 100644 +index 000000000..1b4b52c7a +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lasx/VExtend.ll +@@ -0,0 +1,54 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lasx < %s | FileCheck %s ++ ++define <4 x i64> @uvadd(<8 x i32> %b, <8 x i32> %c) { ++; CHECK-LABEL: uvadd: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvhaddw.du.wu $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = shufflevector <8 x i32> %c, <8 x i32> undef, <4 x i32> ++ %1 = shufflevector <8 x i32> %b, <8 x i32> undef, <4 x i32> ++ %2 = add <4 x i32> %0, %1 ++ %3 = zext <4 x i32> %2 to <4 x i64> ++ ret <4 x i64> %3 ++} ++ ++define <4 x i64> @svadd(<8 x i32> %b, <8 x i32> %c) { ++; CHECK-LABEL: svadd: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvhaddw.d.w $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = shufflevector <8 x i32> %c, <8 x i32> undef, <4 x i32> ++ %1 = shufflevector <8 x i32> %b, <8 x i32> undef, <4 x i32> ++ %2 = add nsw <4 x i32> %0, %1 ++ %3 = sext <4 x i32> %2 to <4 x i64> ++ ret <4 x i64> %3 ++} ++ ++define <4 x i64> @uvsub(<8 x i32> %b, <8 x i32> %c) { ++; CHECK-LABEL: uvsub: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvhsubw.du.wu $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = shufflevector <8 x i32> %b, <8 x i32> undef, <4 x i32> ++ %1 = shufflevector <8 x i32> %c, <8 x i32> undef, <4 x i32> ++ %2 = sub <4 x i32> %0, %1 ++ %3 = zext <4 x i32> %2 to <4 x i64> ++ ret <4 x i64> %3 ++} ++ ++define <4 x i64> @svsub(<8 x i32> %b, <8 x i32> %c) { ++; CHECK-LABEL: svsub: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvhsubw.d.w $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = shufflevector <8 x i32> %b, <8 x i32> undef, <4 x i32> ++ %1 = shufflevector <8 x i32> %c, <8 x i32> undef, <4 x i32> ++ %2 = sub nsw <4 x i32> %0, %1 ++ %3 = sext <4 x i32> %2 to <4 x i64> ++ ret <4 x i64> %3 ++} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/build-vector.ll b/llvm/test/CodeGen/LoongArch/lasx/build-vector.ll +deleted file mode 100644 +index ae6f31aae..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/build-vector.ll ++++ /dev/null +@@ -1,551 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @buildvector_v32i8_splat(ptr %dst, i8 %a0) nounwind { +-; CHECK-LABEL: buildvector_v32i8_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvreplgr2vr.b $xr0, $a1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %insert = insertelement <32 x i8> undef, i8 %a0, i8 0 +- %splat = shufflevector <32 x i8> %insert, <32 x i8> undef, <32 x i32> zeroinitializer +- store <32 x i8> %splat, ptr %dst +- ret void +-} +- +-define void @buildvector_v16i16_splat(ptr %dst, i16 %a0) nounwind { +-; CHECK-LABEL: buildvector_v16i16_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvreplgr2vr.h $xr0, $a1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %insert = insertelement <16 x i16> undef, i16 %a0, i8 0 +- %splat = shufflevector <16 x i16> %insert, <16 x i16> undef, <16 x i32> zeroinitializer +- store <16 x i16> %splat, ptr %dst +- ret void +-} +- +-define void @buildvector_v8i32_splat(ptr %dst, i32 %a0) nounwind { +-; CHECK-LABEL: buildvector_v8i32_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvreplgr2vr.w $xr0, $a1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %insert = insertelement <8 x i32> undef, i32 %a0, i8 0 +- %splat = shufflevector <8 x i32> %insert, <8 x i32> undef, <8 x i32> zeroinitializer +- store <8 x i32> %splat, ptr %dst +- ret void +-} +- +-define void @buildvector_v4i64_splat(ptr %dst, i64 %a0) nounwind { +-; CHECK-LABEL: buildvector_v4i64_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvreplgr2vr.d $xr0, $a1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %insert = insertelement <4 x i64> undef, i64 %a0, i8 0 +- %splat = shufflevector <4 x i64> %insert, <4 x i64> undef, <4 x i32> zeroinitializer +- store <4 x i64> %splat, ptr %dst +- ret void +-} +- +-define void @buildvector_v8f32_splat(ptr %dst, float %a0) nounwind { +-; CHECK-LABEL: buildvector_v8f32_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: # kill: def $f0 killed $f0 def $xr0 +-; CHECK-NEXT: xvreplve0.w $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %insert = insertelement <8 x float> undef, float %a0, i8 0 +- %splat = shufflevector <8 x float> %insert, <8 x float> undef, <8 x i32> zeroinitializer +- store <8 x float> %splat, ptr %dst +- ret void +-} +- +-define void @buildvector_v4f64_splat(ptr %dst, double %a0) nounwind { +-; CHECK-LABEL: buildvector_v4f64_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: # kill: def $f0_64 killed $f0_64 def $xr0 +-; CHECK-NEXT: xvreplve0.d $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %insert = insertelement <4 x double> undef, double %a0, i8 0 +- %splat = shufflevector <4 x double> %insert, <4 x double> undef, <4 x i32> zeroinitializer +- store <4 x double> %splat, ptr %dst +- ret void +-} +- +-define void @buildvector_v32i8_const_splat(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v32i8_const_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvrepli.b $xr0, 1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <32 x i8> , ptr %dst +- ret void +-} +- +-define void @buildvector_v16i16_const_splat(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v16i16_const_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvrepli.h $xr0, 1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <16 x i16> , ptr %dst +- ret void +-} +- +-define void @buildvector_v8i32_const_splat(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v8i32_const_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvrepli.w $xr0, 1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <8 x i32> , ptr %dst +- ret void +-} +- +-define void @buildvector_v4i64_const_splat(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v4i64_const_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvrepli.d $xr0, 1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <4 x i64> , ptr %dst +- ret void +-} +- +-define void @buildvector_v2f32_const_splat(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v2f32_const_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: lu12i.w $a1, 260096 +-; CHECK-NEXT: xvreplgr2vr.w $xr0, $a1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <8 x float> , ptr %dst +- ret void +-} +- +-define void @buildvector_v4f64_const_splat(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v4f64_const_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: lu52i.d $a1, $zero, 1023 +-; CHECK-NEXT: xvreplgr2vr.d $xr0, $a1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <4 x double> , ptr %dst +- ret void +-} +- +-define void @buildvector_v32i8_const(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v32i8_const: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: pcalau12i $a1, %pc_hi20(.LCPI12_0) +-; CHECK-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI12_0) +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <32 x i8> , ptr %dst +- ret void +-} +- +-define void @buildvector_v16i16_const(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v16i16_const: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: pcalau12i $a1, %pc_hi20(.LCPI13_0) +-; CHECK-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI13_0) +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <16 x i16> , ptr %dst +- ret void +-} +- +-define void @buildvector_v8i32_const(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v8i32_const: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: pcalau12i $a1, %pc_hi20(.LCPI14_0) +-; CHECK-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI14_0) +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <8 x i32> , ptr %dst +- ret void +-} +- +-define void @buildvector_v4i64_const(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v4i64_const: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: pcalau12i $a1, %pc_hi20(.LCPI15_0) +-; CHECK-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI15_0) +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <4 x i64> , ptr %dst +- ret void +-} +- +-define void @buildvector_v2f32_const(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v2f32_const: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: pcalau12i $a1, %pc_hi20(.LCPI16_0) +-; CHECK-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI16_0) +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <8 x float> , ptr %dst +- ret void +-} +- +-define void @buildvector_v4f64_const(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v4f64_const: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: pcalau12i $a1, %pc_hi20(.LCPI17_0) +-; CHECK-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI17_0) +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <4 x double> , ptr %dst +- ret void +-} +- +-define void @buildvector_v32i8(ptr %dst, i8 %a0, i8 %a1, i8 %a2, i8 %a3, i8 %a4, i8 %a5, i8 %a6, i8 %a7, i8 %a8, i8 %a9, i8 %a10, i8 %a11, i8 %a12, i8 %a13, i8 %a14, i8 %a15, i8 %a16, i8 %a17, i8 %a18, i8 %a19, i8 %a20, i8 %a21, i8 %a22, i8 %a23, i8 %a24, i8 %a25, i8 %a26, i8 %a27, i8 %a28, i8 %a29, i8 %a30, i8 %a31) nounwind { +-; CHECK-LABEL: buildvector_v32i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 0 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a2, 1 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a3, 2 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a4, 3 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a5, 4 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a6, 5 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a7, 6 +-; CHECK-NEXT: ld.b $a1, $sp, 0 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 7 +-; CHECK-NEXT: ld.b $a1, $sp, 8 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 8 +-; CHECK-NEXT: ld.b $a1, $sp, 16 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 9 +-; CHECK-NEXT: ld.b $a1, $sp, 24 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 10 +-; CHECK-NEXT: ld.b $a1, $sp, 32 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 11 +-; CHECK-NEXT: ld.b $a1, $sp, 40 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 12 +-; CHECK-NEXT: ld.b $a1, $sp, 48 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 13 +-; CHECK-NEXT: ld.b $a1, $sp, 56 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 14 +-; CHECK-NEXT: ld.b $a1, $sp, 64 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 15 +-; CHECK-NEXT: ld.b $a1, $sp, 72 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.b $vr1, $a1, 0 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: ld.b $a1, $sp, 80 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.b $vr1, $a1, 1 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: ld.b $a1, $sp, 88 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.b $vr1, $a1, 2 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: ld.b $a1, $sp, 96 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.b $vr1, $a1, 3 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: ld.b $a1, $sp, 104 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.b $vr1, $a1, 4 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: ld.b $a1, $sp, 112 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.b $vr1, $a1, 5 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: ld.b $a1, $sp, 120 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.b $vr1, $a1, 6 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: ld.b $a1, $sp, 128 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.b $vr1, $a1, 7 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: ld.b $a1, $sp, 136 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.b $vr1, $a1, 8 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: ld.b $a1, $sp, 144 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.b $vr1, $a1, 9 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: ld.b $a1, $sp, 152 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.b $vr1, $a1, 10 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: ld.b $a1, $sp, 160 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.b $vr1, $a1, 11 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: ld.b $a1, $sp, 168 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.b $vr1, $a1, 12 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: ld.b $a1, $sp, 176 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.b $vr1, $a1, 13 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: ld.b $a1, $sp, 184 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.b $vr1, $a1, 14 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: ld.b $a1, $sp, 192 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.b $vr1, $a1, 15 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %ins0 = insertelement <32 x i8> undef, i8 %a0, i32 0 +- %ins1 = insertelement <32 x i8> %ins0, i8 %a1, i32 1 +- %ins2 = insertelement <32 x i8> %ins1, i8 %a2, i32 2 +- %ins3 = insertelement <32 x i8> %ins2, i8 %a3, i32 3 +- %ins4 = insertelement <32 x i8> %ins3, i8 %a4, i32 4 +- %ins5 = insertelement <32 x i8> %ins4, i8 %a5, i32 5 +- %ins6 = insertelement <32 x i8> %ins5, i8 %a6, i32 6 +- %ins7 = insertelement <32 x i8> %ins6, i8 %a7, i32 7 +- %ins8 = insertelement <32 x i8> %ins7, i8 %a8, i32 8 +- %ins9 = insertelement <32 x i8> %ins8, i8 %a9, i32 9 +- %ins10 = insertelement <32 x i8> %ins9, i8 %a10, i32 10 +- %ins11 = insertelement <32 x i8> %ins10, i8 %a11, i32 11 +- %ins12 = insertelement <32 x i8> %ins11, i8 %a12, i32 12 +- %ins13 = insertelement <32 x i8> %ins12, i8 %a13, i32 13 +- %ins14 = insertelement <32 x i8> %ins13, i8 %a14, i32 14 +- %ins15 = insertelement <32 x i8> %ins14, i8 %a15, i32 15 +- %ins16 = insertelement <32 x i8> %ins15, i8 %a16, i32 16 +- %ins17 = insertelement <32 x i8> %ins16, i8 %a17, i32 17 +- %ins18 = insertelement <32 x i8> %ins17, i8 %a18, i32 18 +- %ins19 = insertelement <32 x i8> %ins18, i8 %a19, i32 19 +- %ins20 = insertelement <32 x i8> %ins19, i8 %a20, i32 20 +- %ins21 = insertelement <32 x i8> %ins20, i8 %a21, i32 21 +- %ins22 = insertelement <32 x i8> %ins21, i8 %a22, i32 22 +- %ins23 = insertelement <32 x i8> %ins22, i8 %a23, i32 23 +- %ins24 = insertelement <32 x i8> %ins23, i8 %a24, i32 24 +- %ins25 = insertelement <32 x i8> %ins24, i8 %a25, i32 25 +- %ins26 = insertelement <32 x i8> %ins25, i8 %a26, i32 26 +- %ins27 = insertelement <32 x i8> %ins26, i8 %a27, i32 27 +- %ins28 = insertelement <32 x i8> %ins27, i8 %a28, i32 28 +- %ins29 = insertelement <32 x i8> %ins28, i8 %a29, i32 29 +- %ins30 = insertelement <32 x i8> %ins29, i8 %a30, i32 30 +- %ins31 = insertelement <32 x i8> %ins30, i8 %a31, i32 31 +- store <32 x i8> %ins31, ptr %dst +- ret void +-} +- +-define void @buildvector_v16i16(ptr %dst, i16 %a0, i16 %a1, i16 %a2, i16 %a3, i16 %a4, i16 %a5, i16 %a6, i16 %a7, i16 %a8, i16 %a9, i16 %a10, i16 %a11, i16 %a12, i16 %a13, i16 %a14, i16 %a15) nounwind { +-; CHECK-LABEL: buildvector_v16i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vinsgr2vr.h $vr0, $a1, 0 +-; CHECK-NEXT: vinsgr2vr.h $vr0, $a2, 1 +-; CHECK-NEXT: vinsgr2vr.h $vr0, $a3, 2 +-; CHECK-NEXT: vinsgr2vr.h $vr0, $a4, 3 +-; CHECK-NEXT: vinsgr2vr.h $vr0, $a5, 4 +-; CHECK-NEXT: vinsgr2vr.h $vr0, $a6, 5 +-; CHECK-NEXT: vinsgr2vr.h $vr0, $a7, 6 +-; CHECK-NEXT: ld.h $a1, $sp, 0 +-; CHECK-NEXT: vinsgr2vr.h $vr0, $a1, 7 +-; CHECK-NEXT: ld.h $a1, $sp, 8 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.h $vr1, $a1, 0 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: ld.h $a1, $sp, 16 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.h $vr1, $a1, 1 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: ld.h $a1, $sp, 24 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.h $vr1, $a1, 2 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: ld.h $a1, $sp, 32 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.h $vr1, $a1, 3 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: ld.h $a1, $sp, 40 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.h $vr1, $a1, 4 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: ld.h $a1, $sp, 48 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.h $vr1, $a1, 5 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: ld.h $a1, $sp, 56 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.h $vr1, $a1, 6 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: ld.h $a1, $sp, 64 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.h $vr1, $a1, 7 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %ins0 = insertelement <16 x i16> undef, i16 %a0, i32 0 +- %ins1 = insertelement <16 x i16> %ins0, i16 %a1, i32 1 +- %ins2 = insertelement <16 x i16> %ins1, i16 %a2, i32 2 +- %ins3 = insertelement <16 x i16> %ins2, i16 %a3, i32 3 +- %ins4 = insertelement <16 x i16> %ins3, i16 %a4, i32 4 +- %ins5 = insertelement <16 x i16> %ins4, i16 %a5, i32 5 +- %ins6 = insertelement <16 x i16> %ins5, i16 %a6, i32 6 +- %ins7 = insertelement <16 x i16> %ins6, i16 %a7, i32 7 +- %ins8 = insertelement <16 x i16> %ins7, i16 %a8, i32 8 +- %ins9 = insertelement <16 x i16> %ins8, i16 %a9, i32 9 +- %ins10 = insertelement <16 x i16> %ins9, i16 %a10, i32 10 +- %ins11 = insertelement <16 x i16> %ins10, i16 %a11, i32 11 +- %ins12 = insertelement <16 x i16> %ins11, i16 %a12, i32 12 +- %ins13 = insertelement <16 x i16> %ins12, i16 %a13, i32 13 +- %ins14 = insertelement <16 x i16> %ins13, i16 %a14, i32 14 +- %ins15 = insertelement <16 x i16> %ins14, i16 %a15, i32 15 +- store <16 x i16> %ins15, ptr %dst +- ret void +-} +- +-define void @buildvector_v8i32(ptr %dst, i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6, i32 %a7) nounwind { +-; CHECK-LABEL: buildvector_v8i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvinsgr2vr.w $xr0, $a1, 0 +-; CHECK-NEXT: xvinsgr2vr.w $xr0, $a2, 1 +-; CHECK-NEXT: xvinsgr2vr.w $xr0, $a3, 2 +-; CHECK-NEXT: xvinsgr2vr.w $xr0, $a4, 3 +-; CHECK-NEXT: xvinsgr2vr.w $xr0, $a5, 4 +-; CHECK-NEXT: xvinsgr2vr.w $xr0, $a6, 5 +-; CHECK-NEXT: xvinsgr2vr.w $xr0, $a7, 6 +-; CHECK-NEXT: ld.w $a1, $sp, 0 +-; CHECK-NEXT: xvinsgr2vr.w $xr0, $a1, 7 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %ins0 = insertelement <8 x i32> undef, i32 %a0, i32 0 +- %ins1 = insertelement <8 x i32> %ins0, i32 %a1, i32 1 +- %ins2 = insertelement <8 x i32> %ins1, i32 %a2, i32 2 +- %ins3 = insertelement <8 x i32> %ins2, i32 %a3, i32 3 +- %ins4 = insertelement <8 x i32> %ins3, i32 %a4, i32 4 +- %ins5 = insertelement <8 x i32> %ins4, i32 %a5, i32 5 +- %ins6 = insertelement <8 x i32> %ins5, i32 %a6, i32 6 +- %ins7 = insertelement <8 x i32> %ins6, i32 %a7, i32 7 +- store <8 x i32> %ins7, ptr %dst +- ret void +-} +- +-define void @buildvector_v4i64(ptr %dst, i64 %a0, i64 %a1, i64 %a2, i64 %a3) nounwind { +-; CHECK-LABEL: buildvector_v4i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvinsgr2vr.d $xr0, $a1, 0 +-; CHECK-NEXT: xvinsgr2vr.d $xr0, $a2, 1 +-; CHECK-NEXT: xvinsgr2vr.d $xr0, $a3, 2 +-; CHECK-NEXT: xvinsgr2vr.d $xr0, $a4, 3 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %ins0 = insertelement <4 x i64> undef, i64 %a0, i32 0 +- %ins1 = insertelement <4 x i64> %ins0, i64 %a1, i32 1 +- %ins2 = insertelement <4 x i64> %ins1, i64 %a2, i32 2 +- %ins3 = insertelement <4 x i64> %ins2, i64 %a3, i32 3 +- store <4 x i64> %ins3, ptr %dst +- ret void +-} +- +-define void @buildvector_v8f32(ptr %dst, float %a0, float %a1, float %a2, float %a3, float %a4, float %a5, float %a6, float %a7) nounwind { +-; CHECK-LABEL: buildvector_v8f32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: movfr2gr.s $a1, $fa0 +-; CHECK-NEXT: xvinsgr2vr.w $xr0, $a1, 0 +-; CHECK-NEXT: movfr2gr.s $a1, $fa1 +-; CHECK-NEXT: xvinsgr2vr.w $xr0, $a1, 1 +-; CHECK-NEXT: movfr2gr.s $a1, $fa2 +-; CHECK-NEXT: xvinsgr2vr.w $xr0, $a1, 2 +-; CHECK-NEXT: movfr2gr.s $a1, $fa3 +-; CHECK-NEXT: xvinsgr2vr.w $xr0, $a1, 3 +-; CHECK-NEXT: movfr2gr.s $a1, $fa4 +-; CHECK-NEXT: xvinsgr2vr.w $xr0, $a1, 4 +-; CHECK-NEXT: movfr2gr.s $a1, $fa5 +-; CHECK-NEXT: xvinsgr2vr.w $xr0, $a1, 5 +-; CHECK-NEXT: movfr2gr.s $a1, $fa6 +-; CHECK-NEXT: xvinsgr2vr.w $xr0, $a1, 6 +-; CHECK-NEXT: movfr2gr.s $a1, $fa7 +-; CHECK-NEXT: xvinsgr2vr.w $xr0, $a1, 7 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %ins0 = insertelement <8 x float> undef, float %a0, i32 0 +- %ins1 = insertelement <8 x float> %ins0, float %a1, i32 1 +- %ins2 = insertelement <8 x float> %ins1, float %a2, i32 2 +- %ins3 = insertelement <8 x float> %ins2, float %a3, i32 3 +- %ins4 = insertelement <8 x float> %ins3, float %a4, i32 4 +- %ins5 = insertelement <8 x float> %ins4, float %a5, i32 5 +- %ins6 = insertelement <8 x float> %ins5, float %a6, i32 6 +- %ins7 = insertelement <8 x float> %ins6, float %a7, i32 7 +- store <8 x float> %ins7, ptr %dst +- ret void +-} +- +-define void @buildvector_v4f64(ptr %dst, double %a0, double %a1, double %a2, double %a3) nounwind { +-; CHECK-LABEL: buildvector_v4f64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: movfr2gr.d $a1, $fa0 +-; CHECK-NEXT: xvinsgr2vr.d $xr0, $a1, 0 +-; CHECK-NEXT: movfr2gr.d $a1, $fa1 +-; CHECK-NEXT: xvinsgr2vr.d $xr0, $a1, 1 +-; CHECK-NEXT: movfr2gr.d $a1, $fa2 +-; CHECK-NEXT: xvinsgr2vr.d $xr0, $a1, 2 +-; CHECK-NEXT: movfr2gr.d $a1, $fa3 +-; CHECK-NEXT: xvinsgr2vr.d $xr0, $a1, 3 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %ins0 = insertelement <4 x double> undef, double %a0, i32 0 +- %ins1 = insertelement <4 x double> %ins0, double %a1, i32 1 +- %ins2 = insertelement <4 x double> %ins1, double %a2, i32 2 +- %ins3 = insertelement <4 x double> %ins2, double %a3, i32 3 +- store <4 x double> %ins3, ptr %dst +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ctpop-ctlz.ll b/llvm/test/CodeGen/LoongArch/lasx/ctpop-ctlz.ll +deleted file mode 100644 +index 7786e399c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ctpop-ctlz.ll ++++ /dev/null +@@ -1,115 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @ctpop_v32i8(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: ctpop_v32i8: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvpcnt.b $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load <32 x i8>, ptr %src +- %res = call <32 x i8> @llvm.ctpop.v32i8(<32 x i8> %v) +- store <32 x i8> %res, ptr %dst +- ret void +-} +- +-define void @ctpop_v16i16(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: ctpop_v16i16: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvpcnt.h $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load <16 x i16>, ptr %src +- %res = call <16 x i16> @llvm.ctpop.v16i16(<16 x i16> %v) +- store <16 x i16> %res, ptr %dst +- ret void +-} +- +-define void @ctpop_v8i32(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: ctpop_v8i32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvpcnt.w $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load <8 x i32>, ptr %src +- %res = call <8 x i32> @llvm.ctpop.v8i32(<8 x i32> %v) +- store <8 x i32> %res, ptr %dst +- ret void +-} +- +-define void @ctpop_v4i64(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: ctpop_v4i64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvpcnt.d $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load <4 x i64>, ptr %src +- %res = call <4 x i64> @llvm.ctpop.v4i64(<4 x i64> %v) +- store <4 x i64> %res, ptr %dst +- ret void +-} +- +-define void @ctlz_v32i8(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: ctlz_v32i8: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvclz.b $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load <32 x i8>, ptr %src +- %res = call <32 x i8> @llvm.ctlz.v32i8(<32 x i8> %v, i1 false) +- store <32 x i8> %res, ptr %dst +- ret void +-} +- +-define void @ctlz_v16i16(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: ctlz_v16i16: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvclz.h $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load <16 x i16>, ptr %src +- %res = call <16 x i16> @llvm.ctlz.v16i16(<16 x i16> %v, i1 false) +- store <16 x i16> %res, ptr %dst +- ret void +-} +- +-define void @ctlz_v8i32(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: ctlz_v8i32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvclz.w $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load <8 x i32>, ptr %src +- %res = call <8 x i32> @llvm.ctlz.v8i32(<8 x i32> %v, i1 false) +- store <8 x i32> %res, ptr %dst +- ret void +-} +- +-define void @ctlz_v4i64(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: ctlz_v4i64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvclz.d $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load <4 x i64>, ptr %src +- %res = call <4 x i64> @llvm.ctlz.v4i64(<4 x i64> %v, i1 false) +- store <4 x i64> %res, ptr %dst +- ret void +-} +- +-declare <32 x i8> @llvm.ctpop.v32i8(<32 x i8>) +-declare <16 x i16> @llvm.ctpop.v16i16(<16 x i16>) +-declare <8 x i32> @llvm.ctpop.v8i32(<8 x i32>) +-declare <4 x i64> @llvm.ctpop.v4i64(<4 x i64>) +-declare <32 x i8> @llvm.ctlz.v32i8(<32 x i8>, i1) +-declare <16 x i16> @llvm.ctlz.v16i16(<16 x i16>, i1) +-declare <8 x i32> @llvm.ctlz.v8i32(<8 x i32>, i1) +-declare <4 x i64> @llvm.ctlz.v4i64(<4 x i64>, i1) +diff --git a/llvm/test/CodeGen/LoongArch/lasx/extractelement.ll b/llvm/test/CodeGen/LoongArch/lasx/extractelement.ll +new file mode 100644 +index 000000000..554662813 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lasx/extractelement.ll +@@ -0,0 +1,252 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s ++ ++define void @extract_32xi8(<32 x i8>* %src, i8* %dst) nounwind { ++; CHECK-LABEL: extract_32xi8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -64 ++; CHECK-NEXT: st.d $r22, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: addi.d $r22, $sp, 64 ++; CHECK-NEXT: addi.d $r6, $zero, -32 ++; CHECK-NEXT: and $sp, $sp, $r6 ++; CHECK-NEXT: xvld $xr0, $r4, 0 ++; CHECK-NEXT: xvst $xr0, $sp, 0 ++; CHECK-NEXT: ld.bu $r4, $sp, 1 ++; CHECK-NEXT: st.b $r4, $r5, 0 ++; CHECK-NEXT: addi.d $sp, $r22, -64 ++; CHECK-NEXT: ld.d $r22, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 64 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <32 x i8>, <32 x i8>* %src ++ %e = extractelement <32 x i8> %v, i32 1 ++ store i8 %e, i8* %dst ++ ret void ++} ++ ++define void @extract_16xi16(<16 x i16>* %src, i16* %dst) nounwind { ++; CHECK-LABEL: extract_16xi16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -64 ++; CHECK-NEXT: st.d $r22, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: addi.d $r22, $sp, 64 ++; CHECK-NEXT: addi.d $r6, $zero, -32 ++; CHECK-NEXT: and $sp, $sp, $r6 ++; CHECK-NEXT: xvld $xr0, $r4, 0 ++; CHECK-NEXT: xvst $xr0, $sp, 0 ++; CHECK-NEXT: ld.hu $r4, $sp, 2 ++; CHECK-NEXT: st.h $r4, $r5, 0 ++; CHECK-NEXT: addi.d $sp, $r22, -64 ++; CHECK-NEXT: ld.d $r22, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 64 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <16 x i16>, <16 x i16>* %src ++ %e = extractelement <16 x i16> %v, i32 1 ++ store i16 %e, i16* %dst ++ ret void ++} ++ ++define void @extract_8xi32(<8 x i32>* %src, i32* %dst) nounwind { ++; CHECK-LABEL: extract_8xi32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvld $xr0, $r4, 0 ++; CHECK-NEXT: xvpickve2gr.w $r4, $xr0, 1 ++; CHECK-NEXT: st.w $r4, $r5, 0 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <8 x i32>, <8 x i32>* %src ++ %e = extractelement <8 x i32> %v, i32 1 ++ store i32 %e, i32* %dst ++ ret void ++} ++ ++define void @extract_4xi64(<4 x i64>* %src, i64* %dst) nounwind { ++; CHECK-LABEL: extract_4xi64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvld $xr0, $r4, 0 ++; CHECK-NEXT: xvpickve2gr.d $r4, $xr0, 1 ++; CHECK-NEXT: st.d $r4, $r5, 0 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <4 x i64>, <4 x i64>* %src ++ %e = extractelement <4 x i64> %v, i32 1 ++ store i64 %e, i64* %dst ++ ret void ++} ++ ++define void @extract_8xfloat(<8 x float>* %src, float* %dst) nounwind { ++; CHECK-LABEL: extract_8xfloat: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvld $xr0, $r4, 0 ++; CHECK-NEXT: xvpickve2gr.wu $r4, $xr0, 7 ++; CHECK-NEXT: movgr2fr.w $f0, $r4 ++; CHECK-NEXT: fst.s $f0, $r5, 0 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <8 x float>, <8 x float>* %src ++ %e = extractelement <8 x float> %v, i32 7 ++ store float %e, float* %dst ++ ret void ++} ++ ++define void @extract_4xdouble(<4 x double>* %src, double* %dst) nounwind { ++; CHECK-LABEL: extract_4xdouble: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvld $xr0, $r4, 0 ++; CHECK-NEXT: xvpickve2gr.du $r4, $xr0, 3 ++; CHECK-NEXT: movgr2fr.d $f0, $r4 ++; CHECK-NEXT: fst.d $f0, $r5, 0 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <4 x double>, <4 x double>* %src ++ %e = extractelement <4 x double> %v, i32 3 ++ store double %e, double* %dst ++ ret void ++} ++ ++define void @extract_32xi8_idx(<32 x i8>* %src, i8* %dst, i32 %idx) nounwind { ++; CHECK-LABEL: extract_32xi8_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -64 ++; CHECK-NEXT: st.d $r22, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: addi.d $r22, $sp, 64 ++; CHECK-NEXT: addi.d $r7, $zero, -32 ++; CHECK-NEXT: and $sp, $sp, $r7 ++; CHECK-NEXT: xvld $xr0, $r4, 0 ++; CHECK-NEXT: xvst $xr0, $sp, 0 ++; CHECK-NEXT: andi $r4, $r6, 31 ++; CHECK-NEXT: addi.d $r6, $sp, 0 ++; CHECK-NEXT: or $r4, $r6, $r4 ++; CHECK-NEXT: ld.bu $r4, $r4, 0 ++; CHECK-NEXT: st.b $r4, $r5, 0 ++; CHECK-NEXT: addi.d $sp, $r22, -64 ++; CHECK-NEXT: ld.d $r22, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 64 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <32 x i8>, <32 x i8>* %src ++ %e = extractelement <32 x i8> %v, i32 %idx ++ store i8 %e, i8* %dst ++ ret void ++} ++ ++define void @extract_16xi16_idx(<16 x i16>* %src, i16* %dst, i32 %idx) nounwind { ++; CHECK-LABEL: extract_16xi16_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -64 ++; CHECK-NEXT: st.d $r22, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: addi.d $r22, $sp, 64 ++; CHECK-NEXT: addi.d $r7, $zero, -32 ++; CHECK-NEXT: and $sp, $sp, $r7 ++; CHECK-NEXT: xvld $xr0, $r4, 0 ++; CHECK-NEXT: xvst $xr0, $sp, 0 ++; CHECK-NEXT: andi $r4, $r6, 15 ++; CHECK-NEXT: slli.d $r4, $r4, 1 ++; CHECK-NEXT: addi.d $r6, $sp, 0 ++; CHECK-NEXT: or $r4, $r6, $r4 ++; CHECK-NEXT: ld.hu $r4, $r4, 0 ++; CHECK-NEXT: st.h $r4, $r5, 0 ++; CHECK-NEXT: addi.d $sp, $r22, -64 ++; CHECK-NEXT: ld.d $r22, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 64 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <16 x i16>, <16 x i16>* %src ++ %e = extractelement <16 x i16> %v, i32 %idx ++ store i16 %e, i16* %dst ++ ret void ++} ++ ++define void @extract_8xi32_idx(<8 x i32>* %src, i32* %dst, i32 %idx) nounwind { ++; CHECK-LABEL: extract_8xi32_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -64 ++; CHECK-NEXT: st.d $r22, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: addi.d $r22, $sp, 64 ++; CHECK-NEXT: addi.d $r7, $zero, -32 ++; CHECK-NEXT: and $sp, $sp, $r7 ++; CHECK-NEXT: xvld $xr0, $r4, 0 ++; CHECK-NEXT: xvst $xr0, $sp, 0 ++; CHECK-NEXT: andi $r4, $r6, 7 ++; CHECK-NEXT: slli.d $r4, $r4, 2 ++; CHECK-NEXT: addi.d $r6, $sp, 0 ++; CHECK-NEXT: or $r4, $r6, $r4 ++; CHECK-NEXT: ld.w $r4, $r4, 0 ++; CHECK-NEXT: st.w $r4, $r5, 0 ++; CHECK-NEXT: addi.d $sp, $r22, -64 ++; CHECK-NEXT: ld.d $r22, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 64 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <8 x i32>, <8 x i32>* %src ++ %e = extractelement <8 x i32> %v, i32 %idx ++ store i32 %e, i32* %dst ++ ret void ++} ++ ++define void @extract_4xi64_idx(<4 x i64>* %src, i64* %dst, i32 %idx) nounwind { ++; CHECK-LABEL: extract_4xi64_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -64 ++; CHECK-NEXT: st.d $r22, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: addi.d $r22, $sp, 64 ++; CHECK-NEXT: addi.d $r7, $zero, -32 ++; CHECK-NEXT: and $sp, $sp, $r7 ++; CHECK-NEXT: xvld $xr0, $r4, 0 ++; CHECK-NEXT: xvst $xr0, $sp, 0 ++; CHECK-NEXT: andi $r4, $r6, 3 ++; CHECK-NEXT: slli.d $r4, $r4, 3 ++; CHECK-NEXT: addi.d $r6, $sp, 0 ++; CHECK-NEXT: or $r4, $r6, $r4 ++; CHECK-NEXT: ld.d $r4, $r4, 0 ++; CHECK-NEXT: st.d $r4, $r5, 0 ++; CHECK-NEXT: addi.d $sp, $r22, -64 ++; CHECK-NEXT: ld.d $r22, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 64 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <4 x i64>, <4 x i64>* %src ++ %e = extractelement <4 x i64> %v, i32 %idx ++ store i64 %e, i64* %dst ++ ret void ++} ++ ++define void @extract_8xfloat_idx(<8 x float>* %src, float* %dst, i32 %idx) nounwind { ++; CHECK-LABEL: extract_8xfloat_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: bstrpick.d $r6, $r6, 31, 0 ++; CHECK-NEXT: xvld $xr0, $r4, 0 ++; CHECK-NEXT: addi.d $r4, $zero, 4 ++; CHECK-NEXT: bge $r6, $r4, .LBB10_2 ++; CHECK-NEXT: # %bb.1: ++; CHECK-NEXT: xvreplve.w $xr0, $xr0, $r6 ++; CHECK-NEXT: fst.s $f0, $r5, 0 ++; CHECK-NEXT: jr $ra ++; CHECK-NEXT: .LBB10_2: ++; CHECK-NEXT: addi.d $r4, $r6, -4 ++; CHECK-NEXT: xvpermi.q $xr0, $xr0, 1 ++; CHECK-NEXT: xvreplve.w $xr0, $xr0, $r4 ++; CHECK-NEXT: fst.s $f0, $r5, 0 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <8 x float>, <8 x float>* %src ++ %e = extractelement <8 x float> %v, i32 %idx ++ store float %e, float* %dst ++ ret void ++} ++ ++define void @extract_4xdouble_idx(<4 x double>* %src, double* %dst, i32 %idx) nounwind { ++; CHECK-LABEL: extract_4xdouble_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -64 ++; CHECK-NEXT: st.d $r22, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: addi.d $r22, $sp, 64 ++; CHECK-NEXT: addi.d $r7, $zero, -32 ++; CHECK-NEXT: and $sp, $sp, $r7 ++; CHECK-NEXT: xvld $xr0, $r4, 0 ++; CHECK-NEXT: xvst $xr0, $sp, 0 ++; CHECK-NEXT: andi $r4, $r6, 3 ++; CHECK-NEXT: slli.d $r4, $r4, 3 ++; CHECK-NEXT: addi.d $r6, $sp, 0 ++; CHECK-NEXT: or $r4, $r6, $r4 ++; CHECK-NEXT: fld.d $f0, $r4, 0 ++; CHECK-NEXT: fst.d $f0, $r5, 0 ++; CHECK-NEXT: addi.d $sp, $r22, -64 ++; CHECK-NEXT: ld.d $r22, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 64 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <4 x double>, <4 x double>* %src ++ %e = extractelement <4 x double> %v, i32 %idx ++ store double %e, double* %dst ++ ret void ++} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/fma-v4f64.ll b/llvm/test/CodeGen/LoongArch/lasx/fma-v4f64.ll +deleted file mode 100644 +index af18c52b0..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/fma-v4f64.ll ++++ /dev/null +@@ -1,804 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx --fp-contract=fast < %s \ +-; RUN: | FileCheck %s --check-prefix=CONTRACT-FAST +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx --fp-contract=on < %s \ +-; RUN: | FileCheck %s --check-prefix=CONTRACT-ON +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx --fp-contract=off < %s \ +-; RUN: | FileCheck %s --check-prefix=CONTRACT-OFF +- +-define void @xvfmadd_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: xvfmadd_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfmadd.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: xvfmadd_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-ON-NEXT: xvfmul.d $xr0, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-ON-NEXT: xvfadd.d $xr0, $xr0, $xr1 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: xvfmadd_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfmul.d $xr0, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-OFF-NEXT: xvfadd.d $xr0, $xr0, $xr1 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = load <4 x double>, ptr %a2 +- %mul = fmul<4 x double> %v0, %v1 +- %add = fadd<4 x double> %mul, %v2 +- store <4 x double> %add, ptr %res +- ret void +-} +- +-define void @xvfmsub_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: xvfmsub_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfmsub.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: xvfmsub_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-ON-NEXT: xvfmul.d $xr0, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-ON-NEXT: xvfsub.d $xr0, $xr0, $xr1 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: xvfmsub_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfmul.d $xr0, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-OFF-NEXT: xvfsub.d $xr0, $xr0, $xr1 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = load <4 x double>, ptr %a2 +- %mul = fmul<4 x double> %v0, %v1 +- %sub = fsub<4 x double> %mul, %v2 +- store <4 x double> %sub, ptr %res +- ret void +-} +- +-define void @xvfnmadd_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: xvfnmadd_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfnmadd.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: xvfnmadd_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-ON-NEXT: xvfmul.d $xr0, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-ON-NEXT: xvfadd.d $xr0, $xr0, $xr1 +-; CONTRACT-ON-NEXT: xvbitrevi.d $xr0, $xr0, 63 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: xvfnmadd_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfmul.d $xr0, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-OFF-NEXT: xvfadd.d $xr0, $xr0, $xr1 +-; CONTRACT-OFF-NEXT: xvbitrevi.d $xr0, $xr0, 63 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = load <4 x double>, ptr %a2 +- %mul = fmul<4 x double> %v0, %v1 +- %add = fadd<4 x double> %mul, %v2 +- %negadd = fneg<4 x double> %add +- store <4 x double> %negadd, ptr %res +- ret void +-} +- +-define void @xvfnmadd_d_nsz(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: xvfnmadd_d_nsz: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfnmadd.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: xvfnmadd_d_nsz: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-ON-NEXT: xvbitrevi.d $xr1, $xr1, 63 +-; CONTRACT-ON-NEXT: xvfmul.d $xr0, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-ON-NEXT: xvfsub.d $xr0, $xr0, $xr1 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: xvfnmadd_d_nsz: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-OFF-NEXT: xvbitrevi.d $xr1, $xr1, 63 +-; CONTRACT-OFF-NEXT: xvfmul.d $xr0, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-OFF-NEXT: xvfsub.d $xr0, $xr0, $xr1 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = load <4 x double>, ptr %a2 +- %negv0 = fneg nsz<4 x double> %v0 +- %negv2 = fneg nsz<4 x double> %v2 +- %mul = fmul nsz<4 x double> %negv0, %v1 +- %add = fadd nsz<4 x double> %mul, %negv2 +- store <4 x double> %add, ptr %res +- ret void +-} +- +-;; Check that xvfnmadd.d is not emitted. +-define void @not_xvfnmadd_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: not_xvfnmadd_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvbitrevi.d $xr2, $xr2, 63 +-; CONTRACT-FAST-NEXT: xvfmsub.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: not_xvfnmadd_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-ON-NEXT: xvbitrevi.d $xr1, $xr1, 63 +-; CONTRACT-ON-NEXT: xvfmul.d $xr0, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-ON-NEXT: xvfsub.d $xr0, $xr0, $xr1 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: not_xvfnmadd_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-OFF-NEXT: xvbitrevi.d $xr1, $xr1, 63 +-; CONTRACT-OFF-NEXT: xvfmul.d $xr0, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-OFF-NEXT: xvfsub.d $xr0, $xr0, $xr1 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = load <4 x double>, ptr %a2 +- %negv0 = fneg<4 x double> %v0 +- %negv2 = fneg<4 x double> %v2 +- %mul = fmul<4 x double> %negv0, %v1 +- %add = fadd<4 x double> %mul, %negv2 +- store <4 x double> %add, ptr %res +- ret void +-} +- +-define void @xvfnmsub_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: xvfnmsub_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfnmsub.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: xvfnmsub_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-ON-NEXT: xvfmul.d $xr0, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-ON-NEXT: xvfsub.d $xr0, $xr0, $xr1 +-; CONTRACT-ON-NEXT: xvbitrevi.d $xr0, $xr0, 63 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: xvfnmsub_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfmul.d $xr0, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-OFF-NEXT: xvfsub.d $xr0, $xr0, $xr1 +-; CONTRACT-OFF-NEXT: xvbitrevi.d $xr0, $xr0, 63 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = load <4 x double>, ptr %a2 +- %negv2 = fneg<4 x double> %v2 +- %mul = fmul<4 x double> %v0, %v1 +- %add = fadd<4 x double> %mul, %negv2 +- %neg = fneg<4 x double> %add +- store <4 x double> %neg, ptr %res +- ret void +-} +- +-define void @xvfnmsub_d_nsz(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: xvfnmsub_d_nsz: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfnmsub.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: xvfnmsub_d_nsz: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-ON-NEXT: xvfmul.d $xr0, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-ON-NEXT: xvfsub.d $xr0, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: xvfnmsub_d_nsz: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfmul.d $xr0, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-OFF-NEXT: xvfsub.d $xr0, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = load <4 x double>, ptr %a2 +- %negv0 = fneg nsz<4 x double> %v0 +- %mul = fmul nsz<4 x double> %negv0, %v1 +- %add = fadd nsz<4 x double> %mul, %v2 +- store <4 x double> %add, ptr %res +- ret void +-} +- +-;; Check that xvfnmsub.d is not emitted. +-define void @not_xvfnmsub_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: not_xvfnmsub_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvbitrevi.d $xr2, $xr2, 63 +-; CONTRACT-FAST-NEXT: xvfmadd.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: not_xvfnmsub_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-ON-NEXT: xvfmul.d $xr0, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-ON-NEXT: xvfsub.d $xr0, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: not_xvfnmsub_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfmul.d $xr0, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-OFF-NEXT: xvfsub.d $xr0, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = load <4 x double>, ptr %a2 +- %negv0 = fneg<4 x double> %v0 +- %mul = fmul<4 x double> %negv0, %v1 +- %add = fadd<4 x double> %mul, %v2 +- store <4 x double> %add, ptr %res +- ret void +-} +- +-define void @contract_xvfmadd_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_xvfmadd_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfmadd.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_xvfmadd_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvfmadd.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_xvfmadd_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfmadd.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = load <4 x double>, ptr %a2 +- %mul = fmul contract <4 x double> %v0, %v1 +- %add = fadd contract <4 x double> %mul, %v2 +- store <4 x double> %add, ptr %res +- ret void +-} +- +-define void @contract_xvfmsub_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_xvfmsub_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfmsub.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_xvfmsub_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvfmsub.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_xvfmsub_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfmsub.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = load <4 x double>, ptr %a2 +- %mul = fmul contract <4 x double> %v0, %v1 +- %sub = fsub contract <4 x double> %mul, %v2 +- store <4 x double> %sub, ptr %res +- ret void +-} +- +-define void @contract_xvfnmadd_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_xvfnmadd_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfnmadd.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_xvfnmadd_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvfnmadd.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_xvfnmadd_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfnmadd.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = load <4 x double>, ptr %a2 +- %mul = fmul contract <4 x double> %v0, %v1 +- %add = fadd contract <4 x double> %mul, %v2 +- %negadd = fneg contract <4 x double> %add +- store <4 x double> %negadd, ptr %res +- ret void +-} +- +-define void @contract_xvfnmadd_d_nsz(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_xvfnmadd_d_nsz: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfnmadd.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_xvfnmadd_d_nsz: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvfnmadd.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_xvfnmadd_d_nsz: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfnmadd.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = load <4 x double>, ptr %a2 +- %negv0 = fneg contract nsz<4 x double> %v0 +- %negv2 = fneg contract nsz<4 x double> %v2 +- %mul = fmul contract nsz<4 x double> %negv0, %v1 +- %add = fadd contract nsz<4 x double> %mul, %negv2 +- store <4 x double> %add, ptr %res +- ret void +-} +- +-;; Check that xvfnmadd.d is not emitted. +-define void @not_contract_xvfnmadd_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: not_contract_xvfnmadd_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvbitrevi.d $xr2, $xr2, 63 +-; CONTRACT-FAST-NEXT: xvfmsub.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: not_contract_xvfnmadd_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvbitrevi.d $xr2, $xr2, 63 +-; CONTRACT-ON-NEXT: xvfmsub.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: not_contract_xvfnmadd_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvbitrevi.d $xr2, $xr2, 63 +-; CONTRACT-OFF-NEXT: xvfmsub.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = load <4 x double>, ptr %a2 +- %negv0 = fneg contract <4 x double> %v0 +- %negv2 = fneg contract <4 x double> %v2 +- %mul = fmul contract <4 x double> %negv0, %v1 +- %add = fadd contract <4 x double> %mul, %negv2 +- store <4 x double> %add, ptr %res +- ret void +-} +- +-define void @contract_xvfnmsub_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_xvfnmsub_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfnmsub.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_xvfnmsub_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvfnmsub.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_xvfnmsub_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfnmsub.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = load <4 x double>, ptr %a2 +- %negv2 = fneg contract <4 x double> %v2 +- %mul = fmul contract <4 x double> %v0, %v1 +- %add = fadd contract <4 x double> %mul, %negv2 +- %neg = fneg contract <4 x double> %add +- store <4 x double> %neg, ptr %res +- ret void +-} +- +-define void @contract_xvfnmsub_d_nsz(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_xvfnmsub_d_nsz: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfnmsub.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_xvfnmsub_d_nsz: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvfnmsub.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_xvfnmsub_d_nsz: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfnmsub.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = load <4 x double>, ptr %a2 +- %negv0 = fneg contract nsz<4 x double> %v0 +- %mul = fmul contract nsz<4 x double> %negv0, %v1 +- %add = fadd contract nsz<4 x double> %mul, %v2 +- store <4 x double> %add, ptr %res +- ret void +-} +- +-;; Check that xvfnmsub.d is not emitted. +-define void @not_contract_xvfnmsub_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: not_contract_xvfnmsub_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvbitrevi.d $xr2, $xr2, 63 +-; CONTRACT-FAST-NEXT: xvfmadd.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: not_contract_xvfnmsub_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvbitrevi.d $xr2, $xr2, 63 +-; CONTRACT-ON-NEXT: xvfmadd.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: not_contract_xvfnmsub_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvbitrevi.d $xr2, $xr2, 63 +-; CONTRACT-OFF-NEXT: xvfmadd.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = load <4 x double>, ptr %a2 +- %negv0 = fneg contract <4 x double> %v0 +- %mul = fmul contract <4 x double> %negv0, %v1 +- %add = fadd contract <4 x double> %mul, %v2 +- store <4 x double> %add, ptr %res +- ret void +-} +- +-define void @xvfmadd_d_contract(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: xvfmadd_d_contract: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfmadd.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: xvfmadd_d_contract: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvfmadd.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: xvfmadd_d_contract: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfmadd.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = load <4 x double>, ptr %a2 +- %mul = fmul contract <4 x double> %v0, %v1 +- %add = fadd contract <4 x double> %mul, %v2 +- store <4 x double> %add, ptr %res +- ret void +-} +- +-define void @xvfmsub_d_contract(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: xvfmsub_d_contract: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfmsub.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: xvfmsub_d_contract: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvfmsub.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: xvfmsub_d_contract: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfmsub.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = load <4 x double>, ptr %a2 +- %mul = fmul contract <4 x double> %v0, %v1 +- %sub = fsub contract <4 x double> %mul, %v2 +- store <4 x double> %sub, ptr %res +- ret void +-} +- +-define void @xvfnmadd_d_contract(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: xvfnmadd_d_contract: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfnmadd.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: xvfnmadd_d_contract: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvfnmadd.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: xvfnmadd_d_contract: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfnmadd.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = load <4 x double>, ptr %a2 +- %mul = fmul contract <4 x double> %v0, %v1 +- %add = fadd contract <4 x double> %mul, %v2 +- %negadd = fneg contract <4 x double> %add +- store <4 x double> %negadd, ptr %res +- ret void +-} +- +-define void @xvfnmsub_d_contract(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: xvfnmsub_d_contract: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfnmsub.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: xvfnmsub_d_contract: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvfnmsub.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: xvfnmsub_d_contract: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfnmsub.d $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = load <4 x double>, ptr %a2 +- %mul = fmul contract <4 x double> %v0, %v1 +- %negv2 = fneg contract <4 x double> %v2 +- %add = fadd contract <4 x double> %negv2, %mul +- %negadd = fneg contract <4 x double> %add +- store <4 x double> %negadd, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/fma-v8f32.ll b/llvm/test/CodeGen/LoongArch/lasx/fma-v8f32.ll +deleted file mode 100644 +index b7b3cb3a2..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/fma-v8f32.ll ++++ /dev/null +@@ -1,804 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx --fp-contract=fast < %s \ +-; RUN: | FileCheck %s --check-prefix=CONTRACT-FAST +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx --fp-contract=on < %s \ +-; RUN: | FileCheck %s --check-prefix=CONTRACT-ON +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx --fp-contract=off < %s \ +-; RUN: | FileCheck %s --check-prefix=CONTRACT-OFF +- +-define void @xvfmadd_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: xvfmadd_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfmadd.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: xvfmadd_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-ON-NEXT: xvfmul.s $xr0, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-ON-NEXT: xvfadd.s $xr0, $xr0, $xr1 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: xvfmadd_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfmul.s $xr0, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-OFF-NEXT: xvfadd.s $xr0, $xr0, $xr1 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = load <8 x float>, ptr %a2 +- %mul = fmul<8 x float> %v0, %v1 +- %add = fadd<8 x float> %mul, %v2 +- store <8 x float> %add, ptr %res +- ret void +-} +- +-define void @xvfmsub_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: xvfmsub_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfmsub.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: xvfmsub_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-ON-NEXT: xvfmul.s $xr0, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-ON-NEXT: xvfsub.s $xr0, $xr0, $xr1 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: xvfmsub_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfmul.s $xr0, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-OFF-NEXT: xvfsub.s $xr0, $xr0, $xr1 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = load <8 x float>, ptr %a2 +- %mul = fmul<8 x float> %v0, %v1 +- %sub = fsub<8 x float> %mul, %v2 +- store <8 x float> %sub, ptr %res +- ret void +-} +- +-define void @xvfnmadd_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: xvfnmadd_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfnmadd.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: xvfnmadd_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-ON-NEXT: xvfmul.s $xr0, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-ON-NEXT: xvfadd.s $xr0, $xr0, $xr1 +-; CONTRACT-ON-NEXT: xvbitrevi.w $xr0, $xr0, 31 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: xvfnmadd_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfmul.s $xr0, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-OFF-NEXT: xvfadd.s $xr0, $xr0, $xr1 +-; CONTRACT-OFF-NEXT: xvbitrevi.w $xr0, $xr0, 31 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = load <8 x float>, ptr %a2 +- %mul = fmul<8 x float> %v0, %v1 +- %add = fadd<8 x float> %mul, %v2 +- %negadd = fneg<8 x float> %add +- store <8 x float> %negadd, ptr %res +- ret void +-} +- +-define void @xvfnmadd_s_nsz(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: xvfnmadd_s_nsz: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfnmadd.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: xvfnmadd_s_nsz: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-ON-NEXT: xvbitrevi.w $xr1, $xr1, 31 +-; CONTRACT-ON-NEXT: xvfmul.s $xr0, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-ON-NEXT: xvfsub.s $xr0, $xr0, $xr1 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: xvfnmadd_s_nsz: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-OFF-NEXT: xvbitrevi.w $xr1, $xr1, 31 +-; CONTRACT-OFF-NEXT: xvfmul.s $xr0, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-OFF-NEXT: xvfsub.s $xr0, $xr0, $xr1 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = load <8 x float>, ptr %a2 +- %negv0 = fneg nsz<8 x float> %v0 +- %negv2 = fneg nsz<8 x float> %v2 +- %mul = fmul nsz<8 x float> %negv0, %v1 +- %add = fadd nsz<8 x float> %mul, %negv2 +- store <8 x float> %add, ptr %res +- ret void +-} +- +-;; Check that fnmadd.s is not emitted. +-define void @not_xvfnmadd_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: not_xvfnmadd_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvbitrevi.w $xr2, $xr2, 31 +-; CONTRACT-FAST-NEXT: xvfmsub.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: not_xvfnmadd_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-ON-NEXT: xvbitrevi.w $xr1, $xr1, 31 +-; CONTRACT-ON-NEXT: xvfmul.s $xr0, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-ON-NEXT: xvfsub.s $xr0, $xr0, $xr1 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: not_xvfnmadd_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-OFF-NEXT: xvbitrevi.w $xr1, $xr1, 31 +-; CONTRACT-OFF-NEXT: xvfmul.s $xr0, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-OFF-NEXT: xvfsub.s $xr0, $xr0, $xr1 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = load <8 x float>, ptr %a2 +- %negv0 = fneg<8 x float> %v0 +- %negv2 = fneg<8 x float> %v2 +- %mul = fmul<8 x float> %negv0, %v1 +- %add = fadd<8 x float> %mul, %negv2 +- store <8 x float> %add, ptr %res +- ret void +-} +- +-define void @xvfnmsub_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: xvfnmsub_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfnmsub.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: xvfnmsub_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-ON-NEXT: xvfmul.s $xr0, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-ON-NEXT: xvfsub.s $xr0, $xr0, $xr1 +-; CONTRACT-ON-NEXT: xvbitrevi.w $xr0, $xr0, 31 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: xvfnmsub_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfmul.s $xr0, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-OFF-NEXT: xvfsub.s $xr0, $xr0, $xr1 +-; CONTRACT-OFF-NEXT: xvbitrevi.w $xr0, $xr0, 31 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = load <8 x float>, ptr %a2 +- %negv2 = fneg<8 x float> %v2 +- %mul = fmul<8 x float> %v0, %v1 +- %add = fadd<8 x float> %mul, %negv2 +- %neg = fneg<8 x float> %add +- store <8 x float> %neg, ptr %res +- ret void +-} +- +-define void @xvfnmsub_s_nsz(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: xvfnmsub_s_nsz: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfnmsub.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: xvfnmsub_s_nsz: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-ON-NEXT: xvfmul.s $xr0, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-ON-NEXT: xvfsub.s $xr0, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: xvfnmsub_s_nsz: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfmul.s $xr0, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-OFF-NEXT: xvfsub.s $xr0, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = load <8 x float>, ptr %a2 +- %negv0 = fneg nsz<8 x float> %v0 +- %mul = fmul nsz<8 x float> %negv0, %v1 +- %add = fadd nsz<8 x float> %mul, %v2 +- store <8 x float> %add, ptr %res +- ret void +-} +- +-;; Check that fnmsub.s is not emitted. +-define void @not_xvfnmsub_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: not_xvfnmsub_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvbitrevi.w $xr2, $xr2, 31 +-; CONTRACT-FAST-NEXT: xvfmadd.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: not_xvfnmsub_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-ON-NEXT: xvfmul.s $xr0, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-ON-NEXT: xvfsub.s $xr0, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: not_xvfnmsub_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfmul.s $xr0, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0 +-; CONTRACT-OFF-NEXT: xvfsub.s $xr0, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = load <8 x float>, ptr %a2 +- %negv0 = fneg<8 x float> %v0 +- %mul = fmul<8 x float> %negv0, %v1 +- %add = fadd<8 x float> %mul, %v2 +- store <8 x float> %add, ptr %res +- ret void +-} +- +-define void @contract_xvfmadd_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_xvfmadd_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfmadd.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_xvfmadd_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvfmadd.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_xvfmadd_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfmadd.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = load <8 x float>, ptr %a2 +- %mul = fmul contract <8 x float> %v0, %v1 +- %add = fadd contract <8 x float> %mul, %v2 +- store <8 x float> %add, ptr %res +- ret void +-} +- +-define void @contract_xvfmsub_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_xvfmsub_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfmsub.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_xvfmsub_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvfmsub.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_xvfmsub_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfmsub.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = load <8 x float>, ptr %a2 +- %mul = fmul contract <8 x float> %v0, %v1 +- %sub = fsub contract <8 x float> %mul, %v2 +- store <8 x float> %sub, ptr %res +- ret void +-} +- +-define void @contract_xvfnmadd_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_xvfnmadd_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfnmadd.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_xvfnmadd_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvfnmadd.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_xvfnmadd_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfnmadd.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = load <8 x float>, ptr %a2 +- %mul = fmul contract <8 x float> %v0, %v1 +- %add = fadd contract <8 x float> %mul, %v2 +- %negadd = fneg contract <8 x float> %add +- store <8 x float> %negadd, ptr %res +- ret void +-} +- +-define void @contract_xvfnmadd_s_nsz(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_xvfnmadd_s_nsz: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfnmadd.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_xvfnmadd_s_nsz: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvfnmadd.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_xvfnmadd_s_nsz: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfnmadd.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = load <8 x float>, ptr %a2 +- %negv0 = fneg contract nsz<8 x float> %v0 +- %negv2 = fneg contract nsz<8 x float> %v2 +- %mul = fmul contract nsz<8 x float> %negv0, %v1 +- %add = fadd contract nsz<8 x float> %mul, %negv2 +- store <8 x float> %add, ptr %res +- ret void +-} +- +-;; Check that fnmadd.s is not emitted. +-define void @not_contract_xvfnmadd_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: not_contract_xvfnmadd_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvbitrevi.w $xr2, $xr2, 31 +-; CONTRACT-FAST-NEXT: xvfmsub.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: not_contract_xvfnmadd_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvbitrevi.w $xr2, $xr2, 31 +-; CONTRACT-ON-NEXT: xvfmsub.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: not_contract_xvfnmadd_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvbitrevi.w $xr2, $xr2, 31 +-; CONTRACT-OFF-NEXT: xvfmsub.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = load <8 x float>, ptr %a2 +- %negv0 = fneg contract <8 x float> %v0 +- %negv2 = fneg contract <8 x float> %v2 +- %mul = fmul contract <8 x float> %negv0, %v1 +- %add = fadd contract <8 x float> %mul, %negv2 +- store <8 x float> %add, ptr %res +- ret void +-} +- +-define void @contract_xvfnmsub_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_xvfnmsub_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfnmsub.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_xvfnmsub_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvfnmsub.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_xvfnmsub_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfnmsub.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = load <8 x float>, ptr %a2 +- %negv2 = fneg contract <8 x float> %v2 +- %mul = fmul contract <8 x float> %v0, %v1 +- %add = fadd contract <8 x float> %mul, %negv2 +- %neg = fneg contract <8 x float> %add +- store <8 x float> %neg, ptr %res +- ret void +-} +- +-define void @contract_xvfnmsub_s_nsz(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_xvfnmsub_s_nsz: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfnmsub.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_xvfnmsub_s_nsz: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvfnmsub.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_xvfnmsub_s_nsz: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfnmsub.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = load <8 x float>, ptr %a2 +- %negv0 = fneg contract nsz<8 x float> %v0 +- %mul = fmul contract nsz<8 x float> %negv0, %v1 +- %add = fadd contract nsz<8 x float> %mul, %v2 +- store <8 x float> %add, ptr %res +- ret void +-} +- +-;; Check that fnmsub.s is not emitted. +-define void @not_contract_xvfnmsub_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: not_contract_xvfnmsub_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvbitrevi.w $xr2, $xr2, 31 +-; CONTRACT-FAST-NEXT: xvfmadd.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: not_contract_xvfnmsub_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvbitrevi.w $xr2, $xr2, 31 +-; CONTRACT-ON-NEXT: xvfmadd.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: not_contract_xvfnmsub_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvbitrevi.w $xr2, $xr2, 31 +-; CONTRACT-OFF-NEXT: xvfmadd.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = load <8 x float>, ptr %a2 +- %negv0 = fneg contract <8 x float> %v0 +- %mul = fmul contract <8 x float> %negv0, %v1 +- %add = fadd contract <8 x float> %mul, %v2 +- store <8 x float> %add, ptr %res +- ret void +-} +- +-define void @xvfmadd_s_contract(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: xvfmadd_s_contract: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfmadd.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: xvfmadd_s_contract: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvfmadd.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: xvfmadd_s_contract: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfmadd.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = load <8 x float>, ptr %a2 +- %mul = fmul contract <8 x float> %v0, %v1 +- %add = fadd contract <8 x float> %mul, %v2 +- store <8 x float> %add, ptr %res +- ret void +-} +- +-define void @xvfmsub_s_contract(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: xvfmsub_s_contract: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfmsub.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: xvfmsub_s_contract: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvfmsub.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: xvfmsub_s_contract: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfmsub.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = load <8 x float>, ptr %a2 +- %mul = fmul contract <8 x float> %v0, %v1 +- %sub = fsub contract <8 x float> %mul, %v2 +- store <8 x float> %sub, ptr %res +- ret void +-} +- +-define void @xvfnmadd_s_contract(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: xvfnmadd_s_contract: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfnmadd.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: xvfnmadd_s_contract: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvfnmadd.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: xvfnmadd_s_contract: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfnmadd.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = load <8 x float>, ptr %a2 +- %mul = fmul contract <8 x float> %v0, %v1 +- %add = fadd contract <8 x float> %mul, %v2 +- %negadd = fneg contract <8 x float> %add +- store <8 x float> %negadd, ptr %res +- ret void +-} +- +-define void @xvfnmsub_s_contract(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: xvfnmsub_s_contract: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-FAST-NEXT: xvfnmsub.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: xvfnmsub_s_contract: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-ON-NEXT: xvfnmsub.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: xvfnmsub_s_contract: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0 +-; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0 +-; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0 +-; CONTRACT-OFF-NEXT: xvfnmsub.s $xr0, $xr2, $xr1, $xr0 +-; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = load <8 x float>, ptr %a2 +- %mul = fmul contract <8 x float> %v0, %v1 +- %negv2 = fneg contract <8 x float> %v2 +- %add = fadd contract <8 x float> %negv2, %mul +- %negadd = fneg contract <8 x float> %add +- store <8 x float> %negadd, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/fsqrt.ll b/llvm/test/CodeGen/LoongArch/lasx/fsqrt.ll +deleted file mode 100644 +index c4a881bde..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/fsqrt.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-;; fsqrt +-define void @sqrt_v8f32(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: sqrt_v8f32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvfsqrt.s $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0, align 16 +- %sqrt = call <8 x float> @llvm.sqrt.v8f32 (<8 x float> %v0) +- store <8 x float> %sqrt, ptr %res, align 16 +- ret void +-} +- +-define void @sqrt_v4f64(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: sqrt_v4f64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvfsqrt.d $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0, align 16 +- %sqrt = call <4 x double> @llvm.sqrt.v4f64 (<4 x double> %v0) +- store <4 x double> %sqrt, ptr %res, align 16 +- ret void +-} +- +-;; 1.0 / (fsqrt vec) +-define void @one_div_sqrt_v8f32(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: one_div_sqrt_v8f32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvfrsqrt.s $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0, align 16 +- %sqrt = call <8 x float> @llvm.sqrt.v8f32 (<8 x float> %v0) +- %div = fdiv <8 x float> , %sqrt +- store <8 x float> %div, ptr %res, align 16 +- ret void +-} +- +-define void @one_div_sqrt_v4f64(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: one_div_sqrt_v4f64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvfrsqrt.d $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0, align 16 +- %sqrt = call <4 x double> @llvm.sqrt.v4f64 (<4 x double> %v0) +- %div = fdiv <4 x double> , %sqrt +- store <4 x double> %div, ptr %res, align 16 +- ret void +-} +- +-declare <8 x float> @llvm.sqrt.v8f32(<8 x float>) +-declare <4 x double> @llvm.sqrt.v4f64(<4 x double>) +diff --git a/llvm/test/CodeGen/LoongArch/lasx/imm_vector_lasx.ll b/llvm/test/CodeGen/LoongArch/lasx/imm_vector_lasx.ll +new file mode 100644 +index 000000000..07b80895b +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lasx/imm_vector_lasx.ll +@@ -0,0 +1,176 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lasx < %s | FileCheck %s ++ ++define <4 x i64> @build_lasx0(<4 x i64> %a) { ++; CHECK-LABEL: build_lasx0: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -1 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: xvreplgr2vr.d $xr1, $r4 ++; CHECK-NEXT: xvadd.d $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %b = add <4 x i64> %a, ++ ret <4 x i64> %b ++} ++ ++define <4 x i64> @build_lasx1(<4 x i64> %a) { ++; CHECK-LABEL: build_lasx1: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu52i.d $r4, $zero, 2047 ++; CHECK-NEXT: xvreplgr2vr.d $xr1, $r4 ++; CHECK-NEXT: xvadd.d $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %b = add <4 x i64> %a, ++ ret <4 x i64> %b ++} ++ ++define <4 x i64> @build_lasx2(<4 x i64> %a) { ++; CHECK-LABEL: build_lasx2: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2048 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: xvreplgr2vr.d $xr1, $r4 ++; CHECK-NEXT: xvadd.d $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %b = add <4 x i64> %a, ++ ret <4 x i64> %b ++} ++ ++define <4 x i64> @build_lasx3(<4 x i64> %a) { ++; CHECK-LABEL: build_lasx3: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 4095 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: xvreplgr2vr.d $xr1, $r4 ++; CHECK-NEXT: xvadd.d $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %b = add <4 x i64> %a, ++ ret <4 x i64> %b ++} ++ ++define <4 x i64> @build_lasx4(<4 x i64> %a) { ++; CHECK-LABEL: build_lasx4: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 4095 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: xvreplgr2vr.d $xr1, $r4 ++; CHECK-NEXT: xvadd.d $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %b = add <4 x i64> %a, ++ ret <4 x i64> %b ++} ++ ++define <4 x i64> @build_lasx5(<4 x i64> %a) { ++; CHECK-LABEL: build_lasx5: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -2048 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: xvreplgr2vr.d $xr1, $r4 ++; CHECK-NEXT: xvadd.d $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %b = add <4 x i64> %a, ++ ret <4 x i64> %b ++} ++ ++define <4 x i64> @build_lasx6(<4 x i64> %a) { ++; CHECK-LABEL: build_lasx6: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -2048 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: xvreplgr2vr.d $xr1, $r4 ++; CHECK-NEXT: xvadd.d $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %b = add <4 x i64> %a, ++ ret <4 x i64> %b ++} ++ ++define <4 x i64> @build_lasx7(<4 x i64> %a) { ++; CHECK-LABEL: build_lasx7: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -2048 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: xvreplgr2vr.d $xr1, $r4 ++; CHECK-NEXT: xvadd.d $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %b = add <4 x i64> %a, ++ ret <4 x i64> %b ++} ++ ++define <4 x i64> @build_lasx8(<4 x i64> %a) { ++; CHECK-LABEL: build_lasx8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: xvreplgr2vr.d $xr1, $r4 ++; CHECK-NEXT: xvadd.d $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %b = add <4 x i64> %a, ++ ret <4 x i64> %b ++} ++ ++define <4 x i64> @build_lasx9(<4 x i64> %a) { ++; CHECK-LABEL: build_lasx9: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: xvreplgr2vr.d $xr1, $r4 ++; CHECK-NEXT: xvadd.d $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %b = add <4 x i64> %a, ++ ret <4 x i64> %b ++} ++ ++define <4 x i64> @build_lasx10(<4 x i64> %a) { ++; CHECK-LABEL: build_lasx10: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: xvreplgr2vr.d $xr1, $r4 ++; CHECK-NEXT: xvadd.d $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %b = add <4 x i64> %a, ++ ret <4 x i64> %b ++} ++ ++define <4 x i64> @build_lasx11(<4 x i64> %a) { ++; CHECK-LABEL: build_lasx11: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: xvreplgr2vr.d $xr1, $r4 ++; CHECK-NEXT: xvadd.d $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %b = add <4 x i64> %a, ++ ret <4 x i64> %b ++} ++ ++define <4 x i64> @build_lasx12(<4 x i64> %a) { ++; CHECK-LABEL: build_lasx12: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: xvreplgr2vr.d $xr1, $r4 ++; CHECK-NEXT: xvadd.d $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %b = add <4 x i64> %a, ++ ret <4 x i64> %b ++} ++ ++define <4 x i64> @build_lasx13(<4 x i64> %a) { ++; CHECK-LABEL: build_lasx13: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: xvreplgr2vr.d $xr1, $r4 ++; CHECK-NEXT: xvadd.d $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %b = add <4 x i64> %a, ++ ret <4 x i64> %b ++} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/inline-asm-operand-modifier.ll b/llvm/test/CodeGen/LoongArch/lasx/inline-asm-operand-modifier.ll +deleted file mode 100644 +index 201e34c8b..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/inline-asm-operand-modifier.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @test_u() nounwind { +-; CHECK-LABEL: test_u: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: #APP +-; CHECK-NEXT: xvldi $xr0, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: ret +-entry: +- %0 = tail call <4 x i64> asm sideeffect "xvldi ${0:u}, 1", "=f"() +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/inline-asm-reg-names.ll b/llvm/test/CodeGen/LoongArch/lasx/inline-asm-reg-names.ll +deleted file mode 100644 +index dd400ecfc..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/inline-asm-reg-names.ll ++++ /dev/null +@@ -1,58 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @register_xr1() nounwind { +-; CHECK-LABEL: register_xr1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: #APP +-; CHECK-NEXT: xvldi $xr1, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: ret +-entry: +- %0 = tail call <4 x i64> asm sideeffect "xvldi ${0:u}, 1", "={$xr1}"() +- ret void +-} +- +-define void @register_xr7() nounwind { +-; CHECK-LABEL: register_xr7: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: #APP +-; CHECK-NEXT: xvldi $xr7, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: ret +-entry: +- %0 = tail call <4 x i64> asm sideeffect "xvldi ${0:u}, 1", "={$xr7}"() +- ret void +-} +- +-define void @register_xr23() nounwind { +-; CHECK-LABEL: register_xr23: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: #APP +-; CHECK-NEXT: xvldi $xr23, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: ret +-entry: +- %0 = tail call <4 x i64> asm sideeffect "xvldi ${0:u}, 1", "={$xr23}"() +- ret void +-} +- +-;; The lower 64-bit of the vector register '$xr31' is overlapped with +-;; the floating-point register '$f31' ('$fs7'). And '$f31' ('$fs7') +-;; is a callee-saved register which is preserved across calls. +-;; That's why the fst.d and fld.d instructions are emitted. +-define void @register_xr31() nounwind { +-; CHECK-LABEL: register_xr31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: fst.d $fs7, $sp, 8 # 8-byte Folded Spill +-; CHECK-NEXT: #APP +-; CHECK-NEXT: xvldi $xr31, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: fld.d $fs7, $sp, 8 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call <4 x i64> asm sideeffect "xvldi ${0:u}, 1", "={$xr31}"() +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/inline-asm.ll b/llvm/test/CodeGen/LoongArch/lasx/inline-asm.ll +new file mode 100644 +index 000000000..337632491 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lasx/inline-asm.ll +@@ -0,0 +1,55 @@ ++; A basic inline assembly test ++ ++; RUN: llc -march=loongarch64 -mattr=+lasx < %s | FileCheck %s ++ ++@v4i64_r = global <4 x i64> zeroinitializer, align 32 ++@v8i32_r = global <8 x i32> zeroinitializer, align 32 ++ ++define void @test1() nounwind { ++entry: ++ ; CHECK-LABEL: test1: ++ %0 = call <4 x i64> asm "xvldi ${0:u}, 1", "=f"() ++ ; CHECK: xvldi $xr{{[1-3]?[0-9]}}, 1 ++ store <4 x i64> %0, <4 x i64>* @v4i64_r ++ ret void ++} ++ ++define void @test2() nounwind { ++entry: ++ ; CHECK-LABEL: test2: ++ %0 = load <8 x i32>, <8 x i32>* @v8i32_r ++ %1 = call <8 x i32> asm "xvaddi.wu ${0:u}, ${1:u}, 1", "=f,f"(<8 x i32> %0) ++ ; CHECK: xvaddi.wu $xr{{[1-3]?[0-9]}}, $xr{{[1-3]?[0-9]}}, 1 ++ store <8 x i32> %1, <8 x i32>* @v8i32_r ++ ret void ++} ++ ++define void @test2_d() nounwind { ++entry: ++ ; CHECK-LABEL: test2_d: ++ %0 = load < 4 x i64>, < 4 x i64>* @v4i64_r ++ %1 = call < 4 x i64> asm "xvaddi.wu ${0:u}, ${1:u}, 1", "=f,f"(< 4 x i64> %0) ++ ; CHECK: xvaddi.wu $xr{{[1-3]?[0-9]}}, $xr{{[1-3]?[0-9]}}, 1 ++ store < 4 x i64> %1, < 4 x i64>* @v4i64_r ++ ret void ++} ++ ++define void @test3() nounwind { ++entry: ++ ; CHECK-LABEL: test3: ++ %0 = load <8 x i32>, <8 x i32>* @v8i32_r ++ %1 = call <8 x i32> asm sideeffect "xvaddi.wu ${0:u}, ${1:u}, 1", "=f,f,~{$xr0}"(<8 x i32> %0) ++ ; CHECK: xvaddi.wu $xr{{([1-9]|[1-3][0-9])}}, $xr{{([1-9]|[1-3][0-9])}}, 1 ++ store <8 x i32> %1, <8 x i32>* @v8i32_r ++ ret void ++} ++ ++define void @test3_d() nounwind { ++entry: ++ ; CHECK-LABEL: test3_d: ++ %0 = load <4 x i64>, <4 x i64>* @v4i64_r ++ %1 = call <4 x i64> asm sideeffect "xvaddi.wu ${0:u}, ${1:u}, 1", "=f,f,~{$xr0}"(<4 x i64> %0) ++ ; CHECK: xvaddi.wu $xr{{([1-9]|[1-3][0-9])}}, $xr{{([1-9]|[1-3][0-9])}}, 1 ++ store <4 x i64> %1, <4 x i64>* @v4i64_r ++ ret void ++} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/insert-lasx.ll b/llvm/test/CodeGen/LoongArch/lasx/insert-lasx.ll +new file mode 100644 +index 000000000..6dbaa49b1 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lasx/insert-lasx.ll +@@ -0,0 +1,98 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lasx < %s | FileCheck %s ++ ++define <32 x i8> @lasxB(<32 x i8> %d, <16 x i8> %s1) { ++; CHECK-LABEL: lasxB: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: # kill: def $vr1 killed $vr1 def $xr1 ++; CHECK-NEXT: xvpermi.q $xr0, $xr1, 48 ++; CHECK-NEXT: jr $ra ++entry: ++ %r1 = shufflevector <16 x i8> %s1, <16 x i8> poison, <32 x i32> ++ %r2 = shufflevector <32 x i8> %r1, <32 x i8> %d, <32 x i32> ++ ret <32 x i8> %r2 ++} ++ ++define <16 x i16> @lasxH(<16 x i16> %d, <8 x i16> %s1) { ++; CHECK-LABEL: lasxH: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: # kill: def $vr1 killed $vr1 def $xr1 ++; CHECK-NEXT: xvpermi.q $xr0, $xr1, 48 ++; CHECK-NEXT: jr $ra ++entry: ++ %r1 = shufflevector <8 x i16> %s1, <8 x i16> poison, <16 x i32> ++ %r2 = shufflevector <16 x i16> %r1, <16 x i16> %d, <16 x i32> ++ ret <16 x i16> %r2 ++} ++ ++define <8 x i32> @lasxW(<8 x i32> %d, <4 x i32> %s1) { ++; CHECK-LABEL: lasxW: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: # kill: def $vr1 killed $vr1 def $xr1 ++; CHECK-NEXT: xvpermi.q $xr0, $xr1, 48 ++; CHECK-NEXT: jr $ra ++entry: ++ %r1 = shufflevector <4 x i32> %s1, <4 x i32> poison, <8 x i32> ++ %r2 = shufflevector <8 x i32> %r1, <8 x i32> %d, <8 x i32> ++ ret <8 x i32> %r2 ++} ++ ++define <4 x i64> @lasxD(<4 x i64> %d, <2 x i64> %s1) { ++; CHECK-LABEL: lasxD: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: # kill: def $vr1 killed $vr1 def $xr1 ++; CHECK-NEXT: xvpermi.q $xr0, $xr1, 48 ++; CHECK-NEXT: jr $ra ++entry: ++ %r1 = shufflevector <2 x i64> %s1, <2 x i64> poison, <4 x i32> ++ %r2 = shufflevector <4 x i64> %r1, <4 x i64> %d, <4 x i32> ++ ret <4 x i64> %r2 ++} ++ ++define <32 x i8> @lasxB_Hi(<32 x i8> %d, <16 x i8> %s1) { ++; CHECK-LABEL: lasxB_Hi: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: # kill: def $vr1 killed $vr1 def $xr1 ++; CHECK-NEXT: xvpermi.q $xr0, $xr1, 32 ++; CHECK-NEXT: jr $ra ++entry: ++ %r1 = shufflevector <16 x i8> %s1, <16 x i8> poison, <32 x i32> ++ %r2 = shufflevector <32 x i8> %r1, <32 x i8> %d, <32 x i32> ++ ret <32 x i8> %r2 ++} ++ ++define <16 x i16> @lasxH_Hi(<16 x i16> %d, <8 x i16> %s1) { ++; CHECK-LABEL: lasxH_Hi: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: # kill: def $vr1 killed $vr1 def $xr1 ++; CHECK-NEXT: xvpermi.q $xr0, $xr1, 32 ++; CHECK-NEXT: jr $ra ++entry: ++ %r1 = shufflevector <8 x i16> %s1, <8 x i16> poison, <16 x i32> ++ %r2 = shufflevector <16 x i16> %r1, <16 x i16> %d, <16 x i32> ++ ret <16 x i16> %r2 ++} ++ ++define <8 x i32> @lasxW_Hi(<8 x i32> %d, <4 x i32> %s1) { ++; CHECK-LABEL: lasxW_Hi: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: # kill: def $vr1 killed $vr1 def $xr1 ++; CHECK-NEXT: xvpermi.q $xr0, $xr1, 32 ++; CHECK-NEXT: jr $ra ++entry: ++ %r1 = shufflevector <4 x i32> %s1, <4 x i32> poison, <8 x i32> ++ %r2 = shufflevector <8 x i32> %r1, <8 x i32> %d, <8 x i32> ++ ret <8 x i32> %r2 ++} ++ ++define <4 x i64> @lasxD_Hi(<4 x i64> %d, <2 x i64> %s1) { ++; CHECK-LABEL: lasxD_Hi: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: # kill: def $vr1 killed $vr1 def $xr1 ++; CHECK-NEXT: xvpermi.q $xr0, $xr1, 32 ++; CHECK-NEXT: jr $ra ++entry: ++ %r1 = shufflevector <2 x i64> %s1, <2 x i64> poison, <4 x i32> ++ %r2 = shufflevector <4 x i64> %r1, <4 x i64> %d, <4 x i32> ++ ret <4 x i64> %r2 ++} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/insertelement.ll b/llvm/test/CodeGen/LoongArch/lasx/insertelement.ll +new file mode 100644 +index 000000000..14387bf7a +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lasx/insertelement.ll +@@ -0,0 +1,244 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s ++ ++define <32 x i8> @insert_32xi8(<32 x i8> %v, i8 %in) { ++; CHECK-LABEL: insert_32xi8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r4, $r5, 0 ++; CHECK-NEXT: vinsgr2vr.b $vr0, $r4, 1 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <32 x i8> %v, i8 %in, i32 1 ++ ret <32 x i8> %r ++} ++ ++define <32 x i8> @insert_32xi8_upper(<32 x i8> %v, i8 %in) { ++; CHECK-LABEL: insert_32xi8_upper: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r4, $r5, 0 ++; CHECK-NEXT: xvori.b $xr1, $xr0, 0 ++; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 ++; CHECK-NEXT: vinsgr2vr.b $vr1, $r4, 0 ++; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <32 x i8> %v, i8 %in, i32 16 ++ ret <32 x i8> %r ++} ++ ++define <16 x i16> @insert_16xi16(<16 x i16> %v, i16 %in) { ++; CHECK-LABEL: insert_16xi16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r4, $r5, 0 ++; CHECK-NEXT: vinsgr2vr.h $vr0, $r4, 1 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <16 x i16> %v, i16 %in, i32 1 ++ ret <16 x i16> %r ++} ++ ++define <16 x i16> @insert_16xi16_upper(<16 x i16> %v, i16 %in) { ++; CHECK-LABEL: insert_16xi16_upper: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r4, $r5, 0 ++; CHECK-NEXT: xvori.b $xr1, $xr0, 0 ++; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 ++; CHECK-NEXT: vinsgr2vr.h $vr1, $r4, 0 ++; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <16 x i16> %v, i16 %in, i32 8 ++ ret <16 x i16> %r ++} ++ ++define <8 x i32> @insert_8xi32(<8 x i32> %v, i32 %in) { ++; CHECK-LABEL: insert_8xi32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r4, $r5, 0 ++; CHECK-NEXT: xvinsgr2vr.w $xr0, $r4, 1 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <8 x i32> %v, i32 %in, i32 1 ++ ret <8 x i32> %r ++} ++ ++define <4 x i64> @insert_4xi64(<4 x i64> %v, i64 %in) { ++; CHECK-LABEL: insert_4xi64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvinsgr2vr.d $xr0, $r5, 1 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <4 x i64> %v, i64 %in, i32 1 ++ ret <4 x i64> %r ++} ++ ++define <8 x float> @insert_8xfloat(<8 x float> %v, float %in) { ++; CHECK-LABEL: insert_8xfloat: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # kill: def $f1 killed $f1 def $xr1 ++; CHECK-NEXT: xvpickve2gr.wu $r4, $xr1, 0 ++; CHECK-NEXT: xvinsgr2vr.w $xr0, $r4, 1 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <8 x float> %v, float %in, i32 1 ++ ret <8 x float> %r ++} ++ ++define <4 x double> @insert_4xdouble(<4 x double> %v, double %in) { ++; CHECK-LABEL: insert_4xdouble: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # kill: def $f1_64 killed $f1_64 def $xr1 ++; CHECK-NEXT: xvinsve0.d $xr0, $xr1, 1 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <4 x double> %v, double %in, i32 1 ++ ret <4 x double> %r ++} ++ ++define <32 x i8> @insert_32xi8_idx(<32 x i8> %v, i8 %in, i32 %idx) { ++; CHECK-LABEL: insert_32xi8_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -64 ++; CHECK-NEXT: .cfi_def_cfa_offset 64 ++; CHECK-NEXT: st.d $r22, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: .cfi_offset 22, -8 ++; CHECK-NEXT: addi.d $r22, $sp, 64 ++; CHECK-NEXT: .cfi_def_cfa 22, 0 ++; CHECK-NEXT: addi.d $r4, $zero, -32 ++; CHECK-NEXT: and $sp, $sp, $r4 ++; CHECK-NEXT: xvst $xr0, $sp, 0 ++; CHECK-NEXT: andi $r4, $r6, 31 ++; CHECK-NEXT: addi.d $r6, $sp, 0 ++; CHECK-NEXT: or $r4, $r6, $r4 ++; CHECK-NEXT: st.b $r5, $r4, 0 ++; CHECK-NEXT: xvld $xr0, $sp, 0 ++; CHECK-NEXT: addi.d $sp, $r22, -64 ++; CHECK-NEXT: ld.d $r22, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 64 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <32 x i8> %v, i8 %in, i32 %idx ++ ret <32 x i8> %r ++} ++ ++define <16 x i16> @insert_16xi16_idx(<16 x i16> %v, i16 %in, i32 %idx) { ++; CHECK-LABEL: insert_16xi16_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -64 ++; CHECK-NEXT: .cfi_def_cfa_offset 64 ++; CHECK-NEXT: st.d $r22, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: .cfi_offset 22, -8 ++; CHECK-NEXT: addi.d $r22, $sp, 64 ++; CHECK-NEXT: .cfi_def_cfa 22, 0 ++; CHECK-NEXT: addi.d $r4, $zero, -32 ++; CHECK-NEXT: and $sp, $sp, $r4 ++; CHECK-NEXT: xvst $xr0, $sp, 0 ++; CHECK-NEXT: andi $r4, $r6, 15 ++; CHECK-NEXT: slli.d $r4, $r4, 1 ++; CHECK-NEXT: addi.d $r6, $sp, 0 ++; CHECK-NEXT: or $r4, $r6, $r4 ++; CHECK-NEXT: st.h $r5, $r4, 0 ++; CHECK-NEXT: xvld $xr0, $sp, 0 ++; CHECK-NEXT: addi.d $sp, $r22, -64 ++; CHECK-NEXT: ld.d $r22, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 64 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <16 x i16> %v, i16 %in, i32 %idx ++ ret <16 x i16> %r ++} ++ ++define <8 x i32> @insert_8xi32_idx(<8 x i32> %v, i32 %in, i32 %idx) { ++; CHECK-LABEL: insert_8xi32_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -64 ++; CHECK-NEXT: .cfi_def_cfa_offset 64 ++; CHECK-NEXT: st.d $r22, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: .cfi_offset 22, -8 ++; CHECK-NEXT: addi.d $r22, $sp, 64 ++; CHECK-NEXT: .cfi_def_cfa 22, 0 ++; CHECK-NEXT: addi.d $r4, $zero, -32 ++; CHECK-NEXT: and $sp, $sp, $r4 ++; CHECK-NEXT: xvst $xr0, $sp, 0 ++; CHECK-NEXT: andi $r4, $r6, 7 ++; CHECK-NEXT: slli.d $r4, $r4, 2 ++; CHECK-NEXT: addi.d $r6, $sp, 0 ++; CHECK-NEXT: or $r4, $r6, $r4 ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: st.w $r5, $r4, 0 ++; CHECK-NEXT: xvld $xr0, $sp, 0 ++; CHECK-NEXT: addi.d $sp, $r22, -64 ++; CHECK-NEXT: ld.d $r22, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 64 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <8 x i32> %v, i32 %in, i32 %idx ++ ret <8 x i32> %r ++} ++ ++define <4 x i64> @insert_4xi64_idx(<4 x i64> %v, i64 %in, i32 %idx) { ++; CHECK-LABEL: insert_4xi64_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -64 ++; CHECK-NEXT: .cfi_def_cfa_offset 64 ++; CHECK-NEXT: st.d $r22, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: .cfi_offset 22, -8 ++; CHECK-NEXT: addi.d $r22, $sp, 64 ++; CHECK-NEXT: .cfi_def_cfa 22, 0 ++; CHECK-NEXT: addi.d $r4, $zero, -32 ++; CHECK-NEXT: and $sp, $sp, $r4 ++; CHECK-NEXT: xvst $xr0, $sp, 0 ++; CHECK-NEXT: andi $r4, $r6, 3 ++; CHECK-NEXT: slli.d $r4, $r4, 3 ++; CHECK-NEXT: addi.d $r6, $sp, 0 ++; CHECK-NEXT: or $r4, $r6, $r4 ++; CHECK-NEXT: st.d $r5, $r4, 0 ++; CHECK-NEXT: xvld $xr0, $sp, 0 ++; CHECK-NEXT: addi.d $sp, $r22, -64 ++; CHECK-NEXT: ld.d $r22, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 64 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <4 x i64> %v, i64 %in, i32 %idx ++ ret <4 x i64> %r ++} ++ ++define <8 x float> @insert_8xfloat_idx(<8 x float> %v, float %in, i32 %idx) { ++; CHECK-LABEL: insert_8xfloat_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -64 ++; CHECK-NEXT: .cfi_def_cfa_offset 64 ++; CHECK-NEXT: st.d $r22, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: .cfi_offset 22, -8 ++; CHECK-NEXT: addi.d $r22, $sp, 64 ++; CHECK-NEXT: .cfi_def_cfa 22, 0 ++; CHECK-NEXT: addi.d $r4, $zero, -32 ++; CHECK-NEXT: and $sp, $sp, $r4 ++; CHECK-NEXT: xvst $xr0, $sp, 0 ++; CHECK-NEXT: andi $r4, $r5, 7 ++; CHECK-NEXT: slli.d $r4, $r4, 2 ++; CHECK-NEXT: addi.d $r5, $sp, 0 ++; CHECK-NEXT: or $r4, $r5, $r4 ++; CHECK-NEXT: fst.s $f1, $r4, 0 ++; CHECK-NEXT: xvld $xr0, $sp, 0 ++; CHECK-NEXT: addi.d $sp, $r22, -64 ++; CHECK-NEXT: ld.d $r22, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 64 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <8 x float> %v, float %in, i32 %idx ++ ret <8 x float> %r ++} ++ ++define <4 x double> @insert_4xdouble_idx(<4 x double> %v, double %in, i32 %idx) { ++; CHECK-LABEL: insert_4xdouble_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -64 ++; CHECK-NEXT: .cfi_def_cfa_offset 64 ++; CHECK-NEXT: st.d $r22, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: .cfi_offset 22, -8 ++; CHECK-NEXT: addi.d $r22, $sp, 64 ++; CHECK-NEXT: .cfi_def_cfa 22, 0 ++; CHECK-NEXT: addi.d $r4, $zero, -32 ++; CHECK-NEXT: and $sp, $sp, $r4 ++; CHECK-NEXT: xvst $xr0, $sp, 0 ++; CHECK-NEXT: andi $r4, $r5, 3 ++; CHECK-NEXT: slli.d $r4, $r4, 3 ++; CHECK-NEXT: addi.d $r5, $sp, 0 ++; CHECK-NEXT: or $r4, $r5, $r4 ++; CHECK-NEXT: fst.d $f1, $r4, 0 ++; CHECK-NEXT: xvld $xr0, $sp, 0 ++; CHECK-NEXT: addi.d $sp, $r22, -64 ++; CHECK-NEXT: ld.d $r22, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 64 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <4 x double> %v, double %in, i32 %idx ++ ret <4 x double> %r ++} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-absd.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-absd.ll +deleted file mode 100644 +index bf54f4435..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-absd.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvabsd.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvabsd_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvabsd_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvabsd.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvabsd.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvabsd.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvabsd_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvabsd_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvabsd.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvabsd.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvabsd.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvabsd_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvabsd_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvabsd.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvabsd.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvabsd.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvabsd_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvabsd_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvabsd.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvabsd.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvabsd.bu(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvabsd_bu(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvabsd_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvabsd.bu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvabsd.bu(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvabsd.hu(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvabsd_hu(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvabsd_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvabsd.hu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvabsd.hu(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvabsd.wu(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvabsd_wu(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvabsd_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvabsd.wu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvabsd.wu(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvabsd.du(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvabsd_du(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvabsd_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvabsd.du $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvabsd.du(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-add.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-add.ll +deleted file mode 100644 +index 0c2f2ace2..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-add.ll ++++ /dev/null +@@ -1,62 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvadd.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvadd_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvadd_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvadd.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvadd.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvadd.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvadd_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvadd_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvadd.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvadd.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvadd.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvadd_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvadd_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvadd.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvadd.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvadd.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvadd_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvadd_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvadd.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvadd.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvadd.q(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvadd_q(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvadd_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvadd.q $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvadd.q(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-adda.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-adda.ll +deleted file mode 100644 +index c1258d53e..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-adda.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvadda.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvadda_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvadda_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvadda.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvadda.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvadda.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvadda_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvadda_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvadda.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvadda.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvadda.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvadda_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvadda_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvadda.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvadda.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvadda.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvadda_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvadda_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvadda.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvadda.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-addi-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-addi-invalid-imm.ll +deleted file mode 100644 +index 4998847f0..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-addi-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvaddi.bu(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvaddi_bu_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvaddi.bu: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvaddi.bu(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvaddi_bu_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvaddi.bu: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvaddi.bu(<32 x i8> %va, i32 32) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvaddi.hu(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvaddi_hu_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvaddi.hu: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvaddi.hu(<16 x i16> %va, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvaddi_hu_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvaddi.hu: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvaddi.hu(<16 x i16> %va, i32 32) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvaddi.wu(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvaddi_wu_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvaddi.wu: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvaddi.wu(<8 x i32> %va, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvaddi_wu_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvaddi.wu: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvaddi.wu(<8 x i32> %va, i32 32) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvaddi.du(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvaddi_du_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvaddi.du: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvaddi.du(<4 x i64> %va, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvaddi_du_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvaddi.du: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvaddi.du(<4 x i64> %va, i32 32) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-addi-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-addi-non-imm.ll +deleted file mode 100644 +index f25f0e61a..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-addi-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvaddi.bu(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvaddi_bu(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvaddi.bu(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvaddi.hu(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvaddi_hu(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvaddi.hu(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvaddi.wu(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvaddi_wu(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvaddi.wu(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvaddi.du(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvaddi_du(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvaddi.du(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-addi.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-addi.ll +deleted file mode 100644 +index 09b5d07a0..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-addi.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvaddi.bu(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvaddi_bu(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvaddi_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddi.bu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvaddi.bu(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvaddi.hu(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvaddi_hu(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvaddi_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddi.hu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvaddi.hu(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvaddi.wu(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvaddi_wu(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvaddi_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddi.wu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvaddi.wu(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvaddi.du(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvaddi_du(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvaddi_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddi.du $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvaddi.du(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-addw.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-addw.ll +deleted file mode 100644 +index ef7a1b5a5..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-addw.ll ++++ /dev/null +@@ -1,290 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <16 x i16> @llvm.loongarch.lasx.xvaddwev.h.b(<32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvaddwev_h_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwev_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwev.h.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvaddwev.h.b(<32 x i8> %va, <32 x i8> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvaddwev.w.h(<16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvaddwev_w_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwev_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwev.w.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvaddwev.w.h(<16 x i16> %va, <16 x i16> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvaddwev.d.w(<8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvaddwev_d_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwev_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwev.d.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvaddwev.d.w(<8 x i32> %va, <8 x i32> %vb) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvaddwev.q.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvaddwev_q_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwev_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwev.q.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvaddwev.q.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvaddwev.h.bu(<32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvaddwev_h_bu(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwev_h_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwev.h.bu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvaddwev.h.bu(<32 x i8> %va, <32 x i8> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvaddwev.w.hu(<16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvaddwev_w_hu(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwev_w_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwev.w.hu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvaddwev.w.hu(<16 x i16> %va, <16 x i16> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvaddwev.d.wu(<8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvaddwev_d_wu(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwev_d_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwev.d.wu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvaddwev.d.wu(<8 x i32> %va, <8 x i32> %vb) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvaddwev.q.du(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvaddwev_q_du(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwev_q_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwev.q.du $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvaddwev.q.du(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvaddwev.h.bu.b(<32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvaddwev_h_bu_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwev_h_bu_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwev.h.bu.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvaddwev.h.bu.b(<32 x i8> %va, <32 x i8> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvaddwev.w.hu.h(<16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvaddwev_w_hu_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwev_w_hu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwev.w.hu.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvaddwev.w.hu.h(<16 x i16> %va, <16 x i16> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvaddwev.d.wu.w(<8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvaddwev_d_wu_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwev_d_wu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwev.d.wu.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvaddwev.d.wu.w(<8 x i32> %va, <8 x i32> %vb) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvaddwev.q.du.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvaddwev_q_du_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwev_q_du_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwev.q.du.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvaddwev.q.du.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvaddwod.h.b(<32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvaddwod_h_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwod_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwod.h.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvaddwod.h.b(<32 x i8> %va, <32 x i8> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvaddwod.w.h(<16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvaddwod_w_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwod_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwod.w.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvaddwod.w.h(<16 x i16> %va, <16 x i16> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvaddwod.d.w(<8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvaddwod_d_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwod_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwod.d.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvaddwod.d.w(<8 x i32> %va, <8 x i32> %vb) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvaddwod.q.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvaddwod_q_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwod_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwod.q.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvaddwod.q.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvaddwod.h.bu(<32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvaddwod_h_bu(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwod_h_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwod.h.bu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvaddwod.h.bu(<32 x i8> %va, <32 x i8> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvaddwod.w.hu(<16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvaddwod_w_hu(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwod_w_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwod.w.hu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvaddwod.w.hu(<16 x i16> %va, <16 x i16> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvaddwod.d.wu(<8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvaddwod_d_wu(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwod_d_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwod.d.wu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvaddwod.d.wu(<8 x i32> %va, <8 x i32> %vb) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvaddwod.q.du(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvaddwod_q_du(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwod_q_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwod.q.du $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvaddwod.q.du(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvaddwod.h.bu.b(<32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvaddwod_h_bu_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwod_h_bu_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwod.h.bu.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvaddwod.h.bu.b(<32 x i8> %va, <32 x i8> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvaddwod.w.hu.h(<16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvaddwod_w_hu_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwod_w_hu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwod.w.hu.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvaddwod.w.hu.h(<16 x i16> %va, <16 x i16> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvaddwod.d.wu.w(<8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvaddwod_d_wu_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwod_d_wu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwod.d.wu.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvaddwod.d.wu.w(<8 x i32> %va, <8 x i32> %vb) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvaddwod.q.du.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvaddwod_q_du_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvaddwod_q_du_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvaddwod.q.du.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvaddwod.q.du.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-and.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-and.ll +deleted file mode 100644 +index 15f3a8094..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-and.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvand.v(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvand_v(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvand_v: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvand.v $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvand.v(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-andi-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-andi-invalid-imm.ll +deleted file mode 100644 +index 60f0b765f..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-andi-invalid-imm.ll ++++ /dev/null +@@ -1,17 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvandi.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvandi_b_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvandi.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvandi.b(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvandi_b_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvandi.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvandi.b(<32 x i8> %va, i32 256) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-andi-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-andi-non-imm.ll +deleted file mode 100644 +index 1273dc6b4..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-andi-non-imm.ll ++++ /dev/null +@@ -1,10 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvandi.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvandi_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvandi.b(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-andi.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-andi.ll +deleted file mode 100644 +index 88cf142d6..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-andi.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvandi.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvandi_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvandi_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvandi.b $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvandi.b(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-andn.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-andn.ll +deleted file mode 100644 +index f385ef366..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-andn.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvandn.v(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvandn_v(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvandn_v: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvandn.v $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvandn.v(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-avg.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-avg.ll +deleted file mode 100644 +index 488d3b96b..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-avg.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvavg.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvavg_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvavg_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvavg.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvavg.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvavg.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvavg_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvavg_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvavg.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvavg.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvavg.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvavg_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvavg_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvavg.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvavg.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvavg.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvavg_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvavg_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvavg.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvavg.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvavg.bu(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvavg_bu(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvavg_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvavg.bu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvavg.bu(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvavg.hu(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvavg_hu(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvavg_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvavg.hu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvavg.hu(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvavg.wu(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvavg_wu(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvavg_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvavg.wu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvavg.wu(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvavg.du(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvavg_du(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvavg_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvavg.du $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvavg.du(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-avgr.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-avgr.ll +deleted file mode 100644 +index b5ab5a536..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-avgr.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvavgr.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvavgr_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvavgr_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvavgr.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvavgr.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvavgr.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvavgr_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvavgr_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvavgr.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvavgr.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvavgr.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvavgr_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvavgr_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvavgr.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvavgr.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvavgr.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvavgr_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvavgr_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvavgr.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvavgr.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvavgr.bu(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvavgr_bu(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvavgr_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvavgr.bu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvavgr.bu(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvavgr.hu(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvavgr_hu(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvavgr_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvavgr.hu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvavgr.hu(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvavgr.wu(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvavgr_wu(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvavgr_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvavgr.wu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvavgr.wu(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvavgr.du(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvavgr_du(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvavgr_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvavgr.du $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvavgr.du(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitclr-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitclr-invalid-imm.ll +deleted file mode 100644 +index ecc287e89..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitclr-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvbitclri.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvbitclri_b_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitclri.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbitclri.b(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvbitclri_b_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitclri.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbitclri.b(<32 x i8> %va, i32 8) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvbitclri.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvbitclri_h_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitclri.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvbitclri.h(<16 x i16> %va, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvbitclri_h_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitclri.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvbitclri.h(<16 x i16> %va, i32 16) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvbitclri.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvbitclri_w_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitclri.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvbitclri.w(<8 x i32> %va, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvbitclri_w_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitclri.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvbitclri.w(<8 x i32> %va, i32 32) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvbitclri.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvbitclri_d_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitclri.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvbitclri.d(<4 x i64> %va, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvbitclri_d_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitclri.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvbitclri.d(<4 x i64> %va, i32 64) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitclr-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitclr-non-imm.ll +deleted file mode 100644 +index 09da85411..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitclr-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvbitclri.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvbitclri_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbitclri.b(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvbitclri.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvbitclri_h(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvbitclri.h(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvbitclri.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvbitclri_w(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvbitclri.w(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvbitclri.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvbitclri_d(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvbitclri.d(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitclr.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitclr.ll +deleted file mode 100644 +index cec71bab2..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitclr.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvbitclr.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvbitclr_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvbitclr_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitclr.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbitclr.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvbitclr.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvbitclr_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvbitclr_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitclr.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvbitclr.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvbitclr.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvbitclr_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvbitclr_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitclr.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvbitclr.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvbitclr.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvbitclr_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvbitclr_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitclr.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvbitclr.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvbitclri.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvbitclri_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvbitclri_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitclri.b $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbitclri.b(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvbitclri.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvbitclri_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvbitclri_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitclri.h $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvbitclri.h(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvbitclri.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvbitclri_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvbitclri_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitclri.w $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvbitclri.w(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvbitclri.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvbitclri_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvbitclri_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitclri.d $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvbitclri.d(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitrev-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitrev-invalid-imm.ll +deleted file mode 100644 +index dff0884fd..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitrev-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvbitrevi.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvbitrevi_b_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitrevi.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbitrevi.b(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvbitrevi_b_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitrevi.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbitrevi.b(<32 x i8> %va, i32 8) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvbitrevi.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvbitrevi_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitrevi.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvbitrevi.h(<16 x i16> %va, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvbitrevi_h_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitrevi.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvbitrevi.h(<16 x i16> %va, i32 16) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvbitrevi.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvbitrevi_w_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitrevi.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvbitrevi.w(<8 x i32> %va, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvbitrevi_w_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitrevi.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvbitrevi.w(<8 x i32> %va, i32 32) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvbitrevi.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvbitrevi_d_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitrevi.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvbitrevi.d(<4 x i64> %va, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvbitrevi_d_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitrevi.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvbitrevi.d(<4 x i64> %va, i32 64) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitrev-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitrev-non-imm.ll +deleted file mode 100644 +index e1aef1a82..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitrev-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvbitrevi.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvbitrevi_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbitrevi.b(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvbitrevi.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvbitrevi_h(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvbitrevi.h(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvbitrevi.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvbitrevi_w(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvbitrevi.w(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvbitrevi.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvbitrevi_d(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvbitrevi.d(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitrev.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitrev.ll +deleted file mode 100644 +index fb4f9fbc2..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitrev.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvbitrev.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvbitrev_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvbitrev_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitrev.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbitrev.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvbitrev.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvbitrev_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvbitrev_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitrev.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvbitrev.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvbitrev.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvbitrev_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvbitrev_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitrev.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvbitrev.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvbitrev.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvbitrev_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvbitrev_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitrev.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvbitrev.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvbitrevi.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvbitrevi_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvbitrevi_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitrevi.b $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbitrevi.b(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvbitrevi.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvbitrevi_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvbitrevi_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitrevi.h $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvbitrevi.h(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvbitrevi.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvbitrevi_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvbitrevi_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitrevi.w $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvbitrevi.w(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvbitrevi.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvbitrevi_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvbitrevi_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitrevi.d $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvbitrevi.d(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitsel.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitsel.ll +deleted file mode 100644 +index 2e9140759..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitsel.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvbitsel.v(<32 x i8>, <32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvbitsel_v(<32 x i8> %va, <32 x i8> %vb, <32 x i8> %vc) nounwind { +-; CHECK-LABEL: lasx_xvbitsel_v: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitsel.v $xr0, $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbitsel.v(<32 x i8> %va, <32 x i8> %vb, <32 x i8> %vc) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitseli-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitseli-invalid-imm.ll +deleted file mode 100644 +index 3f6fd44f8..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitseli-invalid-imm.ll ++++ /dev/null +@@ -1,17 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvbitseli.b(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvbitseli_b_lo(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitseli.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbitseli.b(<32 x i8> %va, <32 x i8> %vb, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvbitseli_b_hi(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitseli.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbitseli.b(<32 x i8> %va, <32 x i8> %vb, i32 256) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitseli-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitseli-non-imm.ll +deleted file mode 100644 +index 40533ab96..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitseli-non-imm.ll ++++ /dev/null +@@ -1,10 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvbitseli.b(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvbitseli_b(<32 x i8> %va, <32 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbitseli.b(<32 x i8> %va, <32 x i8> %vb, i32 %c) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitseli.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitseli.ll +deleted file mode 100644 +index 79dd55cbf..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitseli.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvbitseli.b(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvbitseli_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvbitseli_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitseli.b $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbitseli.b(<32 x i8> %va, <32 x i8> %vb, i32 1) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitset-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitset-invalid-imm.ll +deleted file mode 100644 +index 17a77ece7..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitset-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvbitseti.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvbitseti_b_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitseti.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbitseti.b(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvbitseti_b_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitseti.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbitseti.b(<32 x i8> %va, i32 8) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvbitseti.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvbitseti_h_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitseti.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvbitseti.h(<16 x i16> %va, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvbitseti_h_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitseti.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvbitseti.h(<16 x i16> %va, i32 16) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvbitseti.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvbitseti_w_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitseti.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvbitseti.w(<8 x i32> %va, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvbitseti_w_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitseti.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvbitseti.w(<8 x i32> %va, i32 32) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvbitseti.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvbitseti_d_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitseti.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvbitseti.d(<4 x i64> %va, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvbitseti_d_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbitseti.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvbitseti.d(<4 x i64> %va, i32 64) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitset-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitset-non-imm.ll +deleted file mode 100644 +index 613285804..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitset-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvbitseti.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvbitseti_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbitseti.b(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvbitseti.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvbitseti_h(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvbitseti.h(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvbitseti.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvbitseti_w(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvbitseti.w(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvbitseti.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvbitseti_d(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvbitseti.d(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitset.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitset.ll +deleted file mode 100644 +index 83d1f0ef6..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bitset.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvbitset.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvbitset_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvbitset_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitset.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbitset.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvbitset.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvbitset_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvbitset_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitset.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvbitset.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvbitset.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvbitset_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvbitset_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitset.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvbitset.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvbitset.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvbitset_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvbitset_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitset.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvbitset.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvbitseti.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvbitseti_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvbitseti_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitseti.b $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbitseti.b(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvbitseti.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvbitseti_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvbitseti_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitseti.h $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvbitseti.h(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvbitseti.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvbitseti_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvbitseti_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitseti.w $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvbitseti.w(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvbitseti.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvbitseti_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvbitseti_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbitseti.d $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvbitseti.d(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bsll-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bsll-invalid-imm.ll +deleted file mode 100644 +index 1da08a633..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bsll-invalid-imm.ll ++++ /dev/null +@@ -1,17 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvbsll.v(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvbsll_v_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbsll.v: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbsll.v(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvbsll_v_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbsll.v: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbsll.v(<32 x i8> %va, i32 32) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bsll-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bsll-non-imm.ll +deleted file mode 100644 +index e19a3232c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bsll-non-imm.ll ++++ /dev/null +@@ -1,10 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvbsll.v(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvbsll_v(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbsll.v(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bsll.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bsll.ll +deleted file mode 100644 +index cbb63ced5..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bsll.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvbsll.v(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvbsll_v(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvbsll_v: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbsll.v $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbsll.v(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bsrl-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bsrl-invalid-imm.ll +deleted file mode 100644 +index 5d2b63391..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bsrl-invalid-imm.ll ++++ /dev/null +@@ -1,17 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvbsrl.v(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvbsrl_v_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbsrl.v: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbsrl.v(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvbsrl_v_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvbsrl.v: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbsrl.v(<32 x i8> %va, i32 32) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bsrl-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bsrl-non-imm.ll +deleted file mode 100644 +index 8dfd0ca57..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bsrl-non-imm.ll ++++ /dev/null +@@ -1,10 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvbsrl.v(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvbsrl_v(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbsrl.v(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bsrl.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bsrl.ll +deleted file mode 100644 +index b0c26cbe3..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-bsrl.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvbsrl.v(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvbsrl_v(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvbsrl_v: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvbsrl.v $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvbsrl.v(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-clo.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-clo.ll +deleted file mode 100644 +index 29b2be03d..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-clo.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvclo.b(<32 x i8>) +- +-define <32 x i8> @lasx_xvclo_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvclo_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvclo.b $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvclo.b(<32 x i8> %va) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvclo.h(<16 x i16>) +- +-define <16 x i16> @lasx_xvclo_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvclo_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvclo.h $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvclo.h(<16 x i16> %va) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvclo.w(<8 x i32>) +- +-define <8 x i32> @lasx_xvclo_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvclo_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvclo.w $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvclo.w(<8 x i32> %va) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvclo.d(<4 x i64>) +- +-define <4 x i64> @lasx_xvclo_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvclo_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvclo.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvclo.d(<4 x i64> %va) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-clz.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-clz.ll +deleted file mode 100644 +index 5247ceedb..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-clz.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvclz.b(<32 x i8>) +- +-define <32 x i8> @lasx_xvclz_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvclz_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvclz.b $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvclz.b(<32 x i8> %va) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvclz.h(<16 x i16>) +- +-define <16 x i16> @lasx_xvclz_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvclz_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvclz.h $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvclz.h(<16 x i16> %va) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvclz.w(<8 x i32>) +- +-define <8 x i32> @lasx_xvclz_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvclz_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvclz.w $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvclz.w(<8 x i32> %va) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvclz.d(<4 x i64>) +- +-define <4 x i64> @lasx_xvclz_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvclz_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvclz.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvclz.d(<4 x i64> %va) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-div.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-div.ll +deleted file mode 100644 +index 813204092..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-div.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvdiv.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvdiv_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvdiv_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvdiv.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvdiv.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvdiv.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvdiv_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvdiv_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvdiv.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvdiv.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvdiv.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvdiv_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvdiv_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvdiv.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvdiv.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvdiv.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvdiv_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvdiv_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvdiv.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvdiv.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvdiv.bu(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvdiv_bu(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvdiv_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvdiv.bu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvdiv.bu(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvdiv.hu(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvdiv_hu(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvdiv_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvdiv.hu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvdiv.hu(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvdiv.wu(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvdiv_wu(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvdiv_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvdiv.wu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvdiv.wu(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvdiv.du(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvdiv_du(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvdiv_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvdiv.du $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvdiv.du(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ext2xv.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ext2xv.ll +deleted file mode 100644 +index 48721b52a..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ext2xv.ll ++++ /dev/null +@@ -1,146 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <16 x i16> @llvm.loongarch.lasx.vext2xv.h.b(<32 x i8>) +- +-define <16 x i16> @lasx_vext2xv_h_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_vext2xv_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vext2xv.h.b $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.vext2xv.h.b(<32 x i8> %va) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.vext2xv.w.b(<32 x i8>) +- +-define <8 x i32> @lasx_vext2xv_w_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_vext2xv_w_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vext2xv.w.b $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.vext2xv.w.b(<32 x i8> %va) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.vext2xv.d.b(<32 x i8>) +- +-define <4 x i64> @lasx_vext2xv_d_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_vext2xv_d_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vext2xv.d.b $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.vext2xv.d.b(<32 x i8> %va) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.vext2xv.w.h(<16 x i16>) +- +-define <8 x i32> @lasx_vext2xv_w_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_vext2xv_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vext2xv.w.h $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.vext2xv.w.h(<16 x i16> %va) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.vext2xv.d.h(<16 x i16>) +- +-define <4 x i64> @lasx_vext2xv_d_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_vext2xv_d_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vext2xv.d.h $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.vext2xv.d.h(<16 x i16> %va) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.vext2xv.d.w(<8 x i32>) +- +-define <4 x i64> @lasx_vext2xv_d_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_vext2xv_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vext2xv.d.w $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.vext2xv.d.w(<8 x i32> %va) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.vext2xv.hu.bu(<32 x i8>) +- +-define <16 x i16> @lasx_vext2xv_hu_bu(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_vext2xv_hu_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vext2xv.hu.bu $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.vext2xv.hu.bu(<32 x i8> %va) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.vext2xv.wu.bu(<32 x i8>) +- +-define <8 x i32> @lasx_vext2xv_wu_bu(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_vext2xv_wu_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vext2xv.wu.bu $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.vext2xv.wu.bu(<32 x i8> %va) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.vext2xv.du.bu(<32 x i8>) +- +-define <4 x i64> @lasx_vext2xv_du_bu(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_vext2xv_du_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vext2xv.du.bu $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.vext2xv.du.bu(<32 x i8> %va) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.vext2xv.wu.hu(<16 x i16>) +- +-define <8 x i32> @lasx_vext2xv_wu_hu(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_vext2xv_wu_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vext2xv.wu.hu $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.vext2xv.wu.hu(<16 x i16> %va) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.vext2xv.du.hu(<16 x i16>) +- +-define <4 x i64> @lasx_vext2xv_du_hu(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_vext2xv_du_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vext2xv.du.hu $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.vext2xv.du.hu(<16 x i16> %va) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.vext2xv.du.wu(<8 x i32>) +- +-define <4 x i64> @lasx_vext2xv_du_wu(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_vext2xv_du_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vext2xv.du.wu $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.vext2xv.du.wu(<8 x i32> %va) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-exth.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-exth.ll +deleted file mode 100644 +index 543589e61..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-exth.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <16 x i16> @llvm.loongarch.lasx.xvexth.h.b(<32 x i8>) +- +-define <16 x i16> @lasx_xvexth_h_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvexth_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvexth.h.b $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvexth.h.b(<32 x i8> %va) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvexth.w.h(<16 x i16>) +- +-define <8 x i32> @lasx_xvexth_w_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvexth_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvexth.w.h $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvexth.w.h(<16 x i16> %va) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvexth.d.w(<8 x i32>) +- +-define <4 x i64> @lasx_xvexth_d_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvexth_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvexth.d.w $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvexth.d.w(<8 x i32> %va) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvexth.q.d(<4 x i64>) +- +-define <4 x i64> @lasx_xvexth_q_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvexth_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvexth.q.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvexth.q.d(<4 x i64> %va) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvexth.hu.bu(<32 x i8>) +- +-define <16 x i16> @lasx_xvexth_hu_bu(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvexth_hu_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvexth.hu.bu $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvexth.hu.bu(<32 x i8> %va) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvexth.wu.hu(<16 x i16>) +- +-define <8 x i32> @lasx_xvexth_wu_hu(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvexth_wu_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvexth.wu.hu $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvexth.wu.hu(<16 x i16> %va) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvexth.du.wu(<8 x i32>) +- +-define <4 x i64> @lasx_xvexth_du_wu(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvexth_du_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvexth.du.wu $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvexth.du.wu(<8 x i32> %va) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvexth.qu.du(<4 x i64>) +- +-define <4 x i64> @lasx_xvexth_qu_du(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvexth_qu_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvexth.qu.du $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvexth.qu.du(<4 x i64> %va) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-extl.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-extl.ll +deleted file mode 100644 +index 7040c8c78..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-extl.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <4 x i64> @llvm.loongarch.lasx.xvextl.q.d(<4 x i64>) +- +-define <4 x i64> @lasx_xvextl_q_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvextl_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvextl.q.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvextl.q.d(<4 x i64> %va) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvextl.qu.du(<4 x i64>) +- +-define <4 x i64> @lasx_xvextl_qu_du(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvextl_qu_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvextl.qu.du $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvextl.qu.du(<4 x i64> %va) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-extrins-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-extrins-invalid-imm.ll +deleted file mode 100644 +index 1301b8a14..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-extrins-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvextrins.b(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvextrins_b_lo(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvextrins.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvextrins.b(<32 x i8> %va, <32 x i8> %vb, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvextrins_b_hi(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvextrins.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvextrins.b(<32 x i8> %va, <32 x i8> %vb, i32 256) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvextrins.h(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvextrins_h_lo(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvextrins.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvextrins.h(<16 x i16> %va, <16 x i16> %vb, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvextrins_h_hi(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvextrins.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvextrins.h(<16 x i16> %va, <16 x i16> %vb, i32 256) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvextrins.w(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvextrins_w_lo(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvextrins.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvextrins.w(<8 x i32> %va, <8 x i32> %vb, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvextrins_w_hi(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvextrins.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvextrins.w(<8 x i32> %va, <8 x i32> %vb, i32 256) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvextrins.d(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvextrins_d_lo(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvextrins.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvextrins.d(<4 x i64> %va, <4 x i64> %vb, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvextrins_d_hi(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvextrins.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvextrins.d(<4 x i64> %va, <4 x i64> %vb, i32 256) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-extrins-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-extrins-non-imm.ll +deleted file mode 100644 +index bca8f8b3c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-extrins-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvextrins.b(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvextrins_b(<32 x i8> %va, <32 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvextrins.b(<32 x i8> %va, <32 x i8> %vb, i32 %c) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvextrins.h(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvextrins_h(<16 x i16> %va, <16 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvextrins.h(<16 x i16> %va, <16 x i16> %vb, i32 %c) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvextrins.w(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvextrins_w(<8 x i32> %va, <8 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvextrins.w(<8 x i32> %va, <8 x i32> %vb, i32 %c) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvextrins.d(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvextrins_d(<4 x i64> %va, <4 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvextrins.d(<4 x i64> %va, <4 x i64> %vb, i32 %c) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-extrins.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-extrins.ll +deleted file mode 100644 +index c8774a7b2..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-extrins.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvextrins.b(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvextrins_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvextrins_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvextrins.b $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvextrins.b(<32 x i8> %va, <32 x i8> %vb, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvextrins.h(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvextrins_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvextrins_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvextrins.h $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvextrins.h(<16 x i16> %va, <16 x i16> %vb, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvextrins.w(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvextrins_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvextrins_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvextrins.w $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvextrins.w(<8 x i32> %va, <8 x i32> %vb, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvextrins.d(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvextrins_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvextrins_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvextrins.d $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvextrins.d(<4 x i64> %va, <4 x i64> %vb, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fadd.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fadd.ll +deleted file mode 100644 +index 563a0ce9e..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fadd.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x float> @llvm.loongarch.lasx.xvfadd.s(<8 x float>, <8 x float>) +- +-define <8 x float> @lasx_xvfadd_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfadd_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfadd.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvfadd.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvfadd.d(<4 x double>, <4 x double>) +- +-define <4 x double> @lasx_xvfadd_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfadd_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfadd.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvfadd.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fclass.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fclass.ll +deleted file mode 100644 +index 901ca5bb0..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fclass.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfclass.s(<8 x float>) +- +-define <8 x i32> @lasx_xvfclass_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvfclass_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfclass.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfclass.s(<8 x float> %va) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfclass.d(<4 x double>) +- +-define <4 x i64> @lasx_xvfclass_d(<4 x double> %va) nounwind { +-; CHECK-LABEL: lasx_xvfclass_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfclass.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfclass.d(<4 x double> %va) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fcmp.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fcmp.ll +deleted file mode 100644 +index b01f908e7..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fcmp.ll ++++ /dev/null +@@ -1,530 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfcmp.caf.s(<8 x float>, <8 x float>) +- +-define <8 x i32> @lasx_xvfcmp_caf_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_caf_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.caf.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfcmp.caf.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfcmp.caf.d(<4 x double>, <4 x double>) +- +-define <4 x i64> @lasx_xvfcmp_caf_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_caf_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.caf.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfcmp.caf.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfcmp.cun.s(<8 x float>, <8 x float>) +- +-define <8 x i32> @lasx_xvfcmp_cun_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_cun_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.cun.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cun.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfcmp.cun.d(<4 x double>, <4 x double>) +- +-define <4 x i64> @lasx_xvfcmp_cun_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_cun_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.cun.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cun.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfcmp.ceq.s(<8 x float>, <8 x float>) +- +-define <8 x i32> @lasx_xvfcmp_ceq_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_ceq_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.ceq.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfcmp.ceq.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfcmp.ceq.d(<4 x double>, <4 x double>) +- +-define <4 x i64> @lasx_xvfcmp_ceq_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_ceq_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.ceq.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfcmp.ceq.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfcmp.cueq.s(<8 x float>, <8 x float>) +- +-define <8 x i32> @lasx_xvfcmp_cueq_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_cueq_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.cueq.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cueq.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfcmp.cueq.d(<4 x double>, <4 x double>) +- +-define <4 x i64> @lasx_xvfcmp_cueq_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_cueq_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.cueq.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cueq.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfcmp.clt.s(<8 x float>, <8 x float>) +- +-define <8 x i32> @lasx_xvfcmp_clt_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_clt_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.clt.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfcmp.clt.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfcmp.clt.d(<4 x double>, <4 x double>) +- +-define <4 x i64> @lasx_xvfcmp_clt_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_clt_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.clt.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfcmp.clt.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfcmp.cult.s(<8 x float>, <8 x float>) +- +-define <8 x i32> @lasx_xvfcmp_cult_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_cult_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.cult.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cult.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfcmp.cult.d(<4 x double>, <4 x double>) +- +-define <4 x i64> @lasx_xvfcmp_cult_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_cult_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.cult.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cult.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfcmp.cle.s(<8 x float>, <8 x float>) +- +-define <8 x i32> @lasx_xvfcmp_cle_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_cle_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.cle.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cle.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfcmp.cle.d(<4 x double>, <4 x double>) +- +-define <4 x i64> @lasx_xvfcmp_cle_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_cle_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.cle.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cle.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfcmp.cule.s(<8 x float>, <8 x float>) +- +-define <8 x i32> @lasx_xvfcmp_cule_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_cule_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.cule.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cule.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfcmp.cule.d(<4 x double>, <4 x double>) +- +-define <4 x i64> @lasx_xvfcmp_cule_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_cule_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.cule.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cule.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfcmp.cne.s(<8 x float>, <8 x float>) +- +-define <8 x i32> @lasx_xvfcmp_cne_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_cne_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.cne.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cne.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfcmp.cne.d(<4 x double>, <4 x double>) +- +-define <4 x i64> @lasx_xvfcmp_cne_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_cne_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.cne.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cne.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfcmp.cor.s(<8 x float>, <8 x float>) +- +-define <8 x i32> @lasx_xvfcmp_cor_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_cor_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.cor.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cor.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfcmp.cor.d(<4 x double>, <4 x double>) +- +-define <4 x i64> @lasx_xvfcmp_cor_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_cor_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.cor.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cor.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfcmp.cune.s(<8 x float>, <8 x float>) +- +-define <8 x i32> @lasx_xvfcmp_cune_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_cune_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.cune.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfcmp.cune.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfcmp.cune.d(<4 x double>, <4 x double>) +- +-define <4 x i64> @lasx_xvfcmp_cune_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_cune_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.cune.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfcmp.cune.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfcmp.saf.s(<8 x float>, <8 x float>) +- +-define <8 x i32> @lasx_xvfcmp_saf_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_saf_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.saf.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfcmp.saf.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfcmp.saf.d(<4 x double>, <4 x double>) +- +-define <4 x i64> @lasx_xvfcmp_saf_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_saf_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.saf.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfcmp.saf.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfcmp.sun.s(<8 x float>, <8 x float>) +- +-define <8 x i32> @lasx_xvfcmp_sun_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_sun_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.sun.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sun.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfcmp.sun.d(<4 x double>, <4 x double>) +- +-define <4 x i64> @lasx_xvfcmp_sun_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_sun_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.sun.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sun.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfcmp.seq.s(<8 x float>, <8 x float>) +- +-define <8 x i32> @lasx_xvfcmp_seq_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_seq_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.seq.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfcmp.seq.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfcmp.seq.d(<4 x double>, <4 x double>) +- +-define <4 x i64> @lasx_xvfcmp_seq_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_seq_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.seq.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfcmp.seq.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfcmp.sueq.s(<8 x float>, <8 x float>) +- +-define <8 x i32> @lasx_xvfcmp_sueq_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_sueq_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.sueq.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sueq.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfcmp.sueq.d(<4 x double>, <4 x double>) +- +-define <4 x i64> @lasx_xvfcmp_sueq_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_sueq_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.sueq.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sueq.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfcmp.slt.s(<8 x float>, <8 x float>) +- +-define <8 x i32> @lasx_xvfcmp_slt_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_slt_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.slt.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfcmp.slt.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfcmp.slt.d(<4 x double>, <4 x double>) +- +-define <4 x i64> @lasx_xvfcmp_slt_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_slt_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.slt.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfcmp.slt.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfcmp.sult.s(<8 x float>, <8 x float>) +- +-define <8 x i32> @lasx_xvfcmp_sult_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_sult_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.sult.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sult.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfcmp.sult.d(<4 x double>, <4 x double>) +- +-define <4 x i64> @lasx_xvfcmp_sult_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_sult_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.sult.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sult.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfcmp.sle.s(<8 x float>, <8 x float>) +- +-define <8 x i32> @lasx_xvfcmp_sle_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_sle_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.sle.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sle.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfcmp.sle.d(<4 x double>, <4 x double>) +- +-define <4 x i64> @lasx_xvfcmp_sle_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_sle_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.sle.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sle.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfcmp.sule.s(<8 x float>, <8 x float>) +- +-define <8 x i32> @lasx_xvfcmp_sule_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_sule_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.sule.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sule.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfcmp.sule.d(<4 x double>, <4 x double>) +- +-define <4 x i64> @lasx_xvfcmp_sule_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_sule_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.sule.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sule.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfcmp.sne.s(<8 x float>, <8 x float>) +- +-define <8 x i32> @lasx_xvfcmp_sne_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_sne_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.sne.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sne.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfcmp.sne.d(<4 x double>, <4 x double>) +- +-define <4 x i64> @lasx_xvfcmp_sne_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_sne_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.sne.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sne.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfcmp.sor.s(<8 x float>, <8 x float>) +- +-define <8 x i32> @lasx_xvfcmp_sor_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_sor_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.sor.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sor.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfcmp.sor.d(<4 x double>, <4 x double>) +- +-define <4 x i64> @lasx_xvfcmp_sor_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_sor_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.sor.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sor.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvfcmp.sune.s(<8 x float>, <8 x float>) +- +-define <8 x i32> @lasx_xvfcmp_sune_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_sune_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.sune.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvfcmp.sune.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvfcmp.sune.d(<4 x double>, <4 x double>) +- +-define <4 x i64> @lasx_xvfcmp_sune_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcmp_sune_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcmp.sune.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvfcmp.sune.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fcvth.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fcvth.ll +deleted file mode 100644 +index e1a6a2923..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fcvth.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x float> @llvm.loongarch.lasx.xvfcvth.s.h(<16 x i16>) +- +-define <8 x float> @lasx_xvfcvth_s_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvfcvth_s_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcvth.s.h $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvfcvth.s.h(<16 x i16> %va) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvfcvth.d.s(<8 x float>) +- +-define <4 x double> @lasx_xvfcvth_d_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvfcvth_d_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcvth.d.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvfcvth.d.s(<8 x float> %va) +- ret <4 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fcvtl.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fcvtl.ll +deleted file mode 100644 +index 0b3e693c7..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fcvtl.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x float> @llvm.loongarch.lasx.xvfcvtl.s.h(<16 x i16>) +- +-define <8 x float> @lasx_xvfcvtl_s_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvfcvtl_s_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcvtl.s.h $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvfcvtl.s.h(<16 x i16> %va) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvfcvtl.d.s(<8 x float>) +- +-define <4 x double> @lasx_xvfcvtl_d_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvfcvtl_d_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcvtl.d.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvfcvtl.d.s(<8 x float> %va) +- ret <4 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fdiv.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fdiv.ll +deleted file mode 100644 +index 49923ddd4..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fdiv.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x float> @llvm.loongarch.lasx.xvfdiv.s(<8 x float>, <8 x float>) +- +-define <8 x float> @lasx_xvfdiv_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfdiv_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfdiv.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvfdiv.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvfdiv.d(<4 x double>, <4 x double>) +- +-define <4 x double> @lasx_xvfdiv_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfdiv_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfdiv.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvfdiv.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ffint.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ffint.ll +deleted file mode 100644 +index 24da0bd33..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ffint.ll ++++ /dev/null +@@ -1,86 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x float> @llvm.loongarch.lasx.xvffint.s.w(<8 x i32>) +- +-define <8 x float> @lasx_xvffint_s_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvffint_s_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvffint.s.w $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvffint.s.w(<8 x i32> %va) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvffint.d.l(<4 x i64>) +- +-define <4 x double> @lasx_xvffint_d_l(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvffint_d_l: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvffint.d.l $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvffint.d.l(<4 x i64> %va) +- ret <4 x double> %res +-} +- +-declare <8 x float> @llvm.loongarch.lasx.xvffint.s.wu(<8 x i32>) +- +-define <8 x float> @lasx_xvffint_s_wu(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvffint_s_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvffint.s.wu $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvffint.s.wu(<8 x i32> %va) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvffint.d.lu(<4 x i64>) +- +-define <4 x double> @lasx_xvffint_d_lu(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvffint_d_lu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvffint.d.lu $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvffint.d.lu(<4 x i64> %va) +- ret <4 x double> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvffintl.d.w(<8 x i32>) +- +-define <4 x double> @lasx_xvffintl_d_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvffintl_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvffintl.d.w $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvffintl.d.w(<8 x i32> %va) +- ret <4 x double> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvffinth.d.w(<8 x i32>) +- +-define <4 x double> @lasx_xvffinth_d_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvffinth_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvffinth.d.w $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvffinth.d.w(<8 x i32> %va) +- ret <4 x double> %res +-} +- +-declare <8 x float> @llvm.loongarch.lasx.xvffint.s.l(<4 x i64>, <4 x i64>) +- +-define <8 x float> @lasx_xvffint_s_l(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvffint_s_l: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvffint.s.l $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvffint.s.l(<4 x i64> %va, <4 x i64> %vb) +- ret <8 x float> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-flogb.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-flogb.ll +deleted file mode 100644 +index bccef4504..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-flogb.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x float> @llvm.loongarch.lasx.xvflogb.s(<8 x float>) +- +-define <8 x float> @lasx_xvflogb_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvflogb_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvflogb.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvflogb.s(<8 x float> %va) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvflogb.d(<4 x double>) +- +-define <4 x double> @lasx_xvflogb_d(<4 x double> %va) nounwind { +-; CHECK-LABEL: lasx_xvflogb_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvflogb.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvflogb.d(<4 x double> %va) +- ret <4 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fmadd.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fmadd.ll +deleted file mode 100644 +index 0fc06f971..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fmadd.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x float> @llvm.loongarch.lasx.xvfmadd.s(<8 x float>, <8 x float>, <8 x float>) +- +-define <8 x float> @lasx_xvfmadd_s(<8 x float> %va, <8 x float> %vb, <8 x float> %vc) nounwind { +-; CHECK-LABEL: lasx_xvfmadd_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfmadd.s $xr0, $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvfmadd.s(<8 x float> %va, <8 x float> %vb, <8 x float> %vc) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvfmadd.d(<4 x double>, <4 x double>, <4 x double>) +- +-define <4 x double> @lasx_xvfmadd_d(<4 x double> %va, <4 x double> %vb, <4 x double> %vc) nounwind { +-; CHECK-LABEL: lasx_xvfmadd_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfmadd.d $xr0, $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvfmadd.d(<4 x double> %va, <4 x double> %vb, <4 x double> %vc) +- ret <4 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fmax.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fmax.ll +deleted file mode 100644 +index 2422fa0c0..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fmax.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x float> @llvm.loongarch.lasx.xvfmax.s(<8 x float>, <8 x float>) +- +-define <8 x float> @lasx_xvfmax_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfmax_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfmax.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvfmax.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvfmax.d(<4 x double>, <4 x double>) +- +-define <4 x double> @lasx_xvfmax_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfmax_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfmax.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvfmax.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fmaxa.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fmaxa.ll +deleted file mode 100644 +index cd9ccc656..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fmaxa.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x float> @llvm.loongarch.lasx.xvfmaxa.s(<8 x float>, <8 x float>) +- +-define <8 x float> @lasx_xvfmaxa_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfmaxa_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfmaxa.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvfmaxa.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvfmaxa.d(<4 x double>, <4 x double>) +- +-define <4 x double> @lasx_xvfmaxa_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfmaxa_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfmaxa.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvfmaxa.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fmin.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fmin.ll +deleted file mode 100644 +index effb3f9e1..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fmin.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x float> @llvm.loongarch.lasx.xvfmin.s(<8 x float>, <8 x float>) +- +-define <8 x float> @lasx_xvfmin_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfmin_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfmin.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvfmin.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvfmin.d(<4 x double>, <4 x double>) +- +-define <4 x double> @lasx_xvfmin_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfmin_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfmin.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvfmin.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fmina.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fmina.ll +deleted file mode 100644 +index 753a6f31b..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fmina.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x float> @llvm.loongarch.lasx.xvfmina.s(<8 x float>, <8 x float>) +- +-define <8 x float> @lasx_xvfmina_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfmina_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfmina.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvfmina.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvfmina.d(<4 x double>, <4 x double>) +- +-define <4 x double> @lasx_xvfmina_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfmina_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfmina.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvfmina.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fmsub.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fmsub.ll +deleted file mode 100644 +index 57909d0dd..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fmsub.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x float> @llvm.loongarch.lasx.xvfmsub.s(<8 x float>, <8 x float>, <8 x float>) +- +-define <8 x float> @lasx_xvfmsub_s(<8 x float> %va, <8 x float> %vb, <8 x float> %vc) nounwind { +-; CHECK-LABEL: lasx_xvfmsub_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfmsub.s $xr0, $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvfmsub.s(<8 x float> %va, <8 x float> %vb, <8 x float> %vc) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvfmsub.d(<4 x double>, <4 x double>, <4 x double>) +- +-define <4 x double> @lasx_xvfmsub_d(<4 x double> %va, <4 x double> %vb, <4 x double> %vc) nounwind { +-; CHECK-LABEL: lasx_xvfmsub_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfmsub.d $xr0, $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvfmsub.d(<4 x double> %va, <4 x double> %vb, <4 x double> %vc) +- ret <4 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fmul.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fmul.ll +deleted file mode 100644 +index 9cad6f383..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fmul.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x float> @llvm.loongarch.lasx.xvfmul.s(<8 x float>, <8 x float>) +- +-define <8 x float> @lasx_xvfmul_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfmul_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfmul.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvfmul.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvfmul.d(<4 x double>, <4 x double>) +- +-define <4 x double> @lasx_xvfmul_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfmul_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfmul.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvfmul.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fnmadd.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fnmadd.ll +deleted file mode 100644 +index c30993590..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fnmadd.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x float> @llvm.loongarch.lasx.xvfnmadd.s(<8 x float>, <8 x float>, <8 x float>) +- +-define <8 x float> @lasx_xvfnmadd_s(<8 x float> %va, <8 x float> %vb, <8 x float> %vc) nounwind { +-; CHECK-LABEL: lasx_xvfnmadd_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfnmadd.s $xr0, $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvfnmadd.s(<8 x float> %va, <8 x float> %vb, <8 x float> %vc) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvfnmadd.d(<4 x double>, <4 x double>, <4 x double>) +- +-define <4 x double> @lasx_xvfnmadd_d(<4 x double> %va, <4 x double> %vb, <4 x double> %vc) nounwind { +-; CHECK-LABEL: lasx_xvfnmadd_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfnmadd.d $xr0, $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvfnmadd.d(<4 x double> %va, <4 x double> %vb, <4 x double> %vc) +- ret <4 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fnmsub.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fnmsub.ll +deleted file mode 100644 +index 2e7ca695b..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fnmsub.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x float> @llvm.loongarch.lasx.xvfnmsub.s(<8 x float>, <8 x float>, <8 x float>) +- +-define <8 x float> @lasx_xvfnmsub_s(<8 x float> %va, <8 x float> %vb, <8 x float> %vc) nounwind { +-; CHECK-LABEL: lasx_xvfnmsub_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfnmsub.s $xr0, $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvfnmsub.s(<8 x float> %va, <8 x float> %vb, <8 x float> %vc) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvfnmsub.d(<4 x double>, <4 x double>, <4 x double>) +- +-define <4 x double> @lasx_xvfnmsub_d(<4 x double> %va, <4 x double> %vb, <4 x double> %vc) nounwind { +-; CHECK-LABEL: lasx_xvfnmsub_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfnmsub.d $xr0, $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvfnmsub.d(<4 x double> %va, <4 x double> %vb, <4 x double> %vc) +- ret <4 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frecip.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frecip.ll +deleted file mode 100644 +index da3a26df2..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frecip.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x float> @llvm.loongarch.lasx.xvfrecip.s(<8 x float>) +- +-define <8 x float> @lasx_xvfrecip_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvfrecip_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfrecip.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvfrecip.s(<8 x float> %va) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvfrecip.d(<4 x double>) +- +-define <4 x double> @lasx_xvfrecip_d(<4 x double> %va) nounwind { +-; CHECK-LABEL: lasx_xvfrecip_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfrecip.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvfrecip.d(<4 x double> %va) +- ret <4 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frecipe.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frecipe.ll +index 215436823..9b35a6a3a 100644 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frecipe.ll ++++ b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frecipe.ll +@@ -7,7 +7,7 @@ define <8 x float> @lasx_xvfrecipe_s(<8 x float> %va) nounwind { + ; CHECK-LABEL: lasx_xvfrecipe_s: + ; CHECK: # %bb.0: # %entry + ; CHECK-NEXT: xvfrecipe.s $xr0, $xr0 +-; CHECK-NEXT: ret ++; CHECK-NEXT: jr $ra + entry: + %res = call <8 x float> @llvm.loongarch.lasx.xvfrecipe.s(<8 x float> %va) + ret <8 x float> %res +@@ -19,7 +19,7 @@ define <4 x double> @lasx_xvfrecipe_d(<4 x double> %va) nounwind { + ; CHECK-LABEL: lasx_xvfrecipe_d: + ; CHECK: # %bb.0: # %entry + ; CHECK-NEXT: xvfrecipe.d $xr0, $xr0 +-; CHECK-NEXT: ret ++; CHECK-NEXT: jr $ra + entry: + %res = call <4 x double> @llvm.loongarch.lasx.xvfrecipe.d(<4 x double> %va) + ret <4 x double> %res +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frint.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frint.ll +deleted file mode 100644 +index ddead27cd..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frint.ll ++++ /dev/null +@@ -1,122 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x float> @llvm.loongarch.lasx.xvfrintrne.s(<8 x float>) +- +-define <8 x float> @lasx_xvfrintrne_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvfrintrne_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfrintrne.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvfrintrne.s(<8 x float> %va) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvfrintrne.d(<4 x double>) +- +-define <4 x double> @lasx_xvfrintrne_d(<4 x double> %va) nounwind { +-; CHECK-LABEL: lasx_xvfrintrne_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfrintrne.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvfrintrne.d(<4 x double> %va) +- ret <4 x double> %res +-} +- +-declare <8 x float> @llvm.loongarch.lasx.xvfrintrz.s(<8 x float>) +- +-define <8 x float> @lasx_xvfrintrz_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvfrintrz_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfrintrz.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvfrintrz.s(<8 x float> %va) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvfrintrz.d(<4 x double>) +- +-define <4 x double> @lasx_xvfrintrz_d(<4 x double> %va) nounwind { +-; CHECK-LABEL: lasx_xvfrintrz_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfrintrz.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvfrintrz.d(<4 x double> %va) +- ret <4 x double> %res +-} +- +-declare <8 x float> @llvm.loongarch.lasx.xvfrintrp.s(<8 x float>) +- +-define <8 x float> @lasx_xvfrintrp_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvfrintrp_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfrintrp.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvfrintrp.s(<8 x float> %va) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvfrintrp.d(<4 x double>) +- +-define <4 x double> @lasx_xvfrintrp_d(<4 x double> %va) nounwind { +-; CHECK-LABEL: lasx_xvfrintrp_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfrintrp.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvfrintrp.d(<4 x double> %va) +- ret <4 x double> %res +-} +- +-declare <8 x float> @llvm.loongarch.lasx.xvfrintrm.s(<8 x float>) +- +-define <8 x float> @lasx_xvfrintrm_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvfrintrm_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfrintrm.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvfrintrm.s(<8 x float> %va) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvfrintrm.d(<4 x double>) +- +-define <4 x double> @lasx_xvfrintrm_d(<4 x double> %va) nounwind { +-; CHECK-LABEL: lasx_xvfrintrm_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfrintrm.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvfrintrm.d(<4 x double> %va) +- ret <4 x double> %res +-} +- +-declare <8 x float> @llvm.loongarch.lasx.xvfrint.s(<8 x float>) +- +-define <8 x float> @lasx_xvfrint_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvfrint_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfrint.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvfrint.s(<8 x float> %va) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvfrint.d(<4 x double>) +- +-define <4 x double> @lasx_xvfrint_d(<4 x double> %va) nounwind { +-; CHECK-LABEL: lasx_xvfrint_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfrint.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvfrint.d(<4 x double> %va) +- ret <4 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frsqrt.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frsqrt.ll +deleted file mode 100644 +index 6efa8122b..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frsqrt.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x float> @llvm.loongarch.lasx.xvfrsqrt.s(<8 x float>) +- +-define <8 x float> @lasx_xvfrsqrt_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvfrsqrt_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfrsqrt.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvfrsqrt.s(<8 x float> %va) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvfrsqrt.d(<4 x double>) +- +-define <4 x double> @lasx_xvfrsqrt_d(<4 x double> %va) nounwind { +-; CHECK-LABEL: lasx_xvfrsqrt_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfrsqrt.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvfrsqrt.d(<4 x double> %va) +- ret <4 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frsqrte.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frsqrte.ll +index ad36c3aa5..497cb7bb1 100644 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frsqrte.ll ++++ b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frsqrte.ll +@@ -7,7 +7,7 @@ define <8 x float> @lasx_xvfrsqrte_s(<8 x float> %va) nounwind { + ; CHECK-LABEL: lasx_xvfrsqrte_s: + ; CHECK: # %bb.0: # %entry + ; CHECK-NEXT: xvfrsqrte.s $xr0, $xr0 +-; CHECK-NEXT: ret ++; CHECK-NEXT: jr $ra + entry: + %res = call <8 x float> @llvm.loongarch.lasx.xvfrsqrte.s(<8 x float> %va) + ret <8 x float> %res +@@ -19,7 +19,7 @@ define <4 x double> @lasx_xvfrsqrte_d(<4 x double> %va) nounwind { + ; CHECK-LABEL: lasx_xvfrsqrte_d: + ; CHECK: # %bb.0: # %entry + ; CHECK-NEXT: xvfrsqrte.d $xr0, $xr0 +-; CHECK-NEXT: ret ++; CHECK-NEXT: jr $ra + entry: + %res = call <4 x double> @llvm.loongarch.lasx.xvfrsqrte.d(<4 x double> %va) + ret <4 x double> %res +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frstp-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frstp-invalid-imm.ll +deleted file mode 100644 +index 64b463266..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frstp-invalid-imm.ll ++++ /dev/null +@@ -1,33 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvfrstpi.b(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvfrstpi_b_lo(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvfrstpi.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvfrstpi.b(<32 x i8> %va, <32 x i8> %vb, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvfrstpi_b_hi(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvfrstpi.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvfrstpi.b(<32 x i8> %va, <32 x i8> %vb, i32 32) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvfrstpi.h(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvfrstpi_h_lo(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvfrstpi.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvfrstpi.h(<16 x i16> %va, <16 x i16> %vb, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvfrstpi_h_hi(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvfrstpi.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvfrstpi.h(<16 x i16> %va, <16 x i16> %vb, i32 32) +- ret <16 x i16> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frstp-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frstp-non-imm.ll +deleted file mode 100644 +index ca92cff9b..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frstp-non-imm.ll ++++ /dev/null +@@ -1,19 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvfrstpi.b(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvfrstpi_b(<32 x i8> %va, <32 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvfrstpi.b(<32 x i8> %va, <32 x i8> %vb, i32 %c) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvfrstpi.h(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvfrstpi_h(<16 x i16> %va, <16 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvfrstpi.h(<16 x i16> %va, <16 x i16> %vb, i32 %c) +- ret <16 x i16> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frstp.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frstp.ll +deleted file mode 100644 +index e83e55a52..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-frstp.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvfrstp.b(<32 x i8>, <32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvfrstp_b(<32 x i8> %va, <32 x i8> %vb, <32 x i8> %vc) nounwind { +-; CHECK-LABEL: lasx_xvfrstp_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfrstp.b $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvfrstp.b(<32 x i8> %va, <32 x i8> %vb, <32 x i8> %vc) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvfrstp.h(<16 x i16>, <16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvfrstp_h(<16 x i16> %va, <16 x i16> %vb, <16 x i16> %vc) nounwind { +-; CHECK-LABEL: lasx_xvfrstp_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfrstp.h $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvfrstp.h(<16 x i16> %va, <16 x i16> %vb, <16 x i16> %vc) +- ret <16 x i16> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvfrstpi.b(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvfrstpi_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfrstpi_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfrstpi.b $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvfrstpi.b(<32 x i8> %va, <32 x i8> %vb, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvfrstpi.h(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvfrstpi_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfrstpi_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfrstpi.h $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvfrstpi.h(<16 x i16> %va, <16 x i16> %vb, i32 1) +- ret <16 x i16> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fsqrt.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fsqrt.ll +deleted file mode 100644 +index a13333d8d..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fsqrt.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x float> @llvm.loongarch.lasx.xvfsqrt.s(<8 x float>) +- +-define <8 x float> @lasx_xvfsqrt_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvfsqrt_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfsqrt.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvfsqrt.s(<8 x float> %va) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvfsqrt.d(<4 x double>) +- +-define <4 x double> @lasx_xvfsqrt_d(<4 x double> %va) nounwind { +-; CHECK-LABEL: lasx_xvfsqrt_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfsqrt.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvfsqrt.d(<4 x double> %va) +- ret <4 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fsub.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fsub.ll +deleted file mode 100644 +index b52774a03..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fsub.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x float> @llvm.loongarch.lasx.xvfsub.s(<8 x float>, <8 x float>) +- +-define <8 x float> @lasx_xvfsub_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfsub_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfsub.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvfsub.s(<8 x float> %va, <8 x float> %vb) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvfsub.d(<4 x double>, <4 x double>) +- +-define <4 x double> @lasx_xvfsub_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfsub_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfsub.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvfsub.d(<4 x double> %va, <4 x double> %vb) +- ret <4 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ftint.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ftint.ll +deleted file mode 100644 +index 74cd507f1..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ftint.ll ++++ /dev/null +@@ -1,350 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x i32> @llvm.loongarch.lasx.xvftintrne.w.s(<8 x float>) +- +-define <8 x i32> @lasx_xvftintrne_w_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvftintrne_w_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintrne.w.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvftintrne.w.s(<8 x float> %va) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvftintrne.l.d(<4 x double>) +- +-define <4 x i64> @lasx_xvftintrne_l_d(<4 x double> %va) nounwind { +-; CHECK-LABEL: lasx_xvftintrne_l_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintrne.l.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvftintrne.l.d(<4 x double> %va) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvftintrz.w.s(<8 x float>) +- +-define <8 x i32> @lasx_xvftintrz_w_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvftintrz_w_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintrz.w.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvftintrz.w.s(<8 x float> %va) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvftintrz.l.d(<4 x double>) +- +-define <4 x i64> @lasx_xvftintrz_l_d(<4 x double> %va) nounwind { +-; CHECK-LABEL: lasx_xvftintrz_l_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintrz.l.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvftintrz.l.d(<4 x double> %va) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvftintrp.w.s(<8 x float>) +- +-define <8 x i32> @lasx_xvftintrp_w_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvftintrp_w_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintrp.w.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvftintrp.w.s(<8 x float> %va) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvftintrp.l.d(<4 x double>) +- +-define <4 x i64> @lasx_xvftintrp_l_d(<4 x double> %va) nounwind { +-; CHECK-LABEL: lasx_xvftintrp_l_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintrp.l.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvftintrp.l.d(<4 x double> %va) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvftintrm.w.s(<8 x float>) +- +-define <8 x i32> @lasx_xvftintrm_w_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvftintrm_w_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintrm.w.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvftintrm.w.s(<8 x float> %va) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvftintrm.l.d(<4 x double>) +- +-define <4 x i64> @lasx_xvftintrm_l_d(<4 x double> %va) nounwind { +-; CHECK-LABEL: lasx_xvftintrm_l_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintrm.l.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvftintrm.l.d(<4 x double> %va) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvftint.w.s(<8 x float>) +- +-define <8 x i32> @lasx_xvftint_w_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvftint_w_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftint.w.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvftint.w.s(<8 x float> %va) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvftint.l.d(<4 x double>) +- +-define <4 x i64> @lasx_xvftint_l_d(<4 x double> %va) nounwind { +-; CHECK-LABEL: lasx_xvftint_l_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftint.l.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvftint.l.d(<4 x double> %va) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvftintrz.wu.s(<8 x float>) +- +-define <8 x i32> @lasx_xvftintrz_wu_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvftintrz_wu_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintrz.wu.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvftintrz.wu.s(<8 x float> %va) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvftintrz.lu.d(<4 x double>) +- +-define <4 x i64> @lasx_xvftintrz_lu_d(<4 x double> %va) nounwind { +-; CHECK-LABEL: lasx_xvftintrz_lu_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintrz.lu.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvftintrz.lu.d(<4 x double> %va) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvftint.wu.s(<8 x float>) +- +-define <8 x i32> @lasx_xvftint_wu_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvftint_wu_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftint.wu.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvftint.wu.s(<8 x float> %va) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvftint.lu.d(<4 x double>) +- +-define <4 x i64> @lasx_xvftint_lu_d(<4 x double> %va) nounwind { +-; CHECK-LABEL: lasx_xvftint_lu_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftint.lu.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvftint.lu.d(<4 x double> %va) +- ret <4 x i64> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvftintrne.w.d(<4 x double>, <4 x double>) +- +-define <8 x i32> @lasx_xvftintrne_w_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvftintrne_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintrne.w.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvftintrne.w.d(<4 x double> %va, <4 x double> %vb) +- ret <8 x i32> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvftintrz.w.d(<4 x double>, <4 x double>) +- +-define <8 x i32> @lasx_xvftintrz_w_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvftintrz_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintrz.w.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvftintrz.w.d(<4 x double> %va, <4 x double> %vb) +- ret <8 x i32> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvftintrp.w.d(<4 x double>, <4 x double>) +- +-define <8 x i32> @lasx_xvftintrp_w_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvftintrp_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintrp.w.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvftintrp.w.d(<4 x double> %va, <4 x double> %vb) +- ret <8 x i32> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvftintrm.w.d(<4 x double>, <4 x double>) +- +-define <8 x i32> @lasx_xvftintrm_w_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvftintrm_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintrm.w.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvftintrm.w.d(<4 x double> %va, <4 x double> %vb) +- ret <8 x i32> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvftint.w.d(<4 x double>, <4 x double>) +- +-define <8 x i32> @lasx_xvftint_w_d(<4 x double> %va, <4 x double> %vb) nounwind { +-; CHECK-LABEL: lasx_xvftint_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftint.w.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvftint.w.d(<4 x double> %va, <4 x double> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvftintrnel.l.s(<8 x float>) +- +-define <4 x i64> @lasx_xvftintrnel_l_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvftintrnel_l_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintrnel.l.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvftintrnel.l.s(<8 x float> %va) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvftintrneh.l.s(<8 x float>) +- +-define <4 x i64> @lasx_xvftintrneh_l_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvftintrneh_l_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintrneh.l.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvftintrneh.l.s(<8 x float> %va) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvftintrzl.l.s(<8 x float>) +- +-define <4 x i64> @lasx_xvftintrzl_l_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvftintrzl_l_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintrzl.l.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvftintrzl.l.s(<8 x float> %va) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvftintrzh.l.s(<8 x float>) +- +-define <4 x i64> @lasx_xvftintrzh_l_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvftintrzh_l_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintrzh.l.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvftintrzh.l.s(<8 x float> %va) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvftintrpl.l.s(<8 x float>) +- +-define <4 x i64> @lasx_xvftintrpl_l_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvftintrpl_l_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintrpl.l.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvftintrpl.l.s(<8 x float> %va) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvftintrph.l.s(<8 x float>) +- +-define <4 x i64> @lasx_xvftintrph_l_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvftintrph_l_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintrph.l.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvftintrph.l.s(<8 x float> %va) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvftintrml.l.s(<8 x float>) +- +-define <4 x i64> @lasx_xvftintrml_l_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvftintrml_l_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintrml.l.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvftintrml.l.s(<8 x float> %va) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvftintrmh.l.s(<8 x float>) +- +-define <4 x i64> @lasx_xvftintrmh_l_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvftintrmh_l_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintrmh.l.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvftintrmh.l.s(<8 x float> %va) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvftintl.l.s(<8 x float>) +- +-define <4 x i64> @lasx_xvftintl_l_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvftintl_l_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftintl.l.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvftintl.l.s(<8 x float> %va) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvftinth.l.s(<8 x float>) +- +-define <4 x i64> @lasx_xvftinth_l_s(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvftinth_l_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvftinth.l.s $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvftinth.l.s(<8 x float> %va) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-haddw.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-haddw.ll +deleted file mode 100644 +index 2c64ab238..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-haddw.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <16 x i16> @llvm.loongarch.lasx.xvhaddw.h.b(<32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvhaddw_h_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvhaddw_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvhaddw.h.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvhaddw.h.b(<32 x i8> %va, <32 x i8> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvhaddw.w.h(<16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvhaddw_w_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvhaddw_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvhaddw.w.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvhaddw.w.h(<16 x i16> %va, <16 x i16> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvhaddw.d.w(<8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvhaddw_d_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvhaddw_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvhaddw.d.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvhaddw.d.w(<8 x i32> %va, <8 x i32> %vb) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvhaddw.q.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvhaddw_q_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvhaddw_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvhaddw.q.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvhaddw.q.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvhaddw.hu.bu(<32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvhaddw_hu_bu(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvhaddw_hu_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvhaddw.hu.bu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvhaddw.hu.bu(<32 x i8> %va, <32 x i8> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvhaddw.wu.hu(<16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvhaddw_wu_hu(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvhaddw_wu_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvhaddw.wu.hu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvhaddw.wu.hu(<16 x i16> %va, <16 x i16> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvhaddw.du.wu(<8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvhaddw_du_wu(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvhaddw_du_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvhaddw.du.wu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvhaddw.du.wu(<8 x i32> %va, <8 x i32> %vb) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvhaddw.qu.du(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvhaddw_qu_du(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvhaddw_qu_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvhaddw.qu.du $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvhaddw.qu.du(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-hsubw.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-hsubw.ll +deleted file mode 100644 +index a5223c1d8..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-hsubw.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <16 x i16> @llvm.loongarch.lasx.xvhsubw.h.b(<32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvhsubw_h_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvhsubw_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvhsubw.h.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvhsubw.h.b(<32 x i8> %va, <32 x i8> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvhsubw.w.h(<16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvhsubw_w_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvhsubw_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvhsubw.w.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvhsubw.w.h(<16 x i16> %va, <16 x i16> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvhsubw.d.w(<8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvhsubw_d_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvhsubw_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvhsubw.d.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvhsubw.d.w(<8 x i32> %va, <8 x i32> %vb) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvhsubw.q.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvhsubw_q_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvhsubw_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvhsubw.q.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvhsubw.q.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvhsubw.hu.bu(<32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvhsubw_hu_bu(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvhsubw_hu_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvhsubw.hu.bu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvhsubw.hu.bu(<32 x i8> %va, <32 x i8> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvhsubw.wu.hu(<16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvhsubw_wu_hu(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvhsubw_wu_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvhsubw.wu.hu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvhsubw.wu.hu(<16 x i16> %va, <16 x i16> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvhsubw.du.wu(<8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvhsubw_du_wu(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvhsubw_du_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvhsubw.du.wu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvhsubw.du.wu(<8 x i32> %va, <8 x i32> %vb) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvhsubw.qu.du(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvhsubw_qu_du(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvhsubw_qu_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvhsubw.qu.du $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvhsubw.qu.du(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ilv.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ilv.ll +deleted file mode 100644 +index c9d0ca6b0..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ilv.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvilvl.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvilvl_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvilvl_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvilvl.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvilvl.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvilvl.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvilvl_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvilvl_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvilvl.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvilvl.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvilvl.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvilvl_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvilvl_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvilvl.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvilvl.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvilvl.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvilvl_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvilvl_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvilvl.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvilvl.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvilvh.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvilvh_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvilvh_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvilvh.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvilvh.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvilvh.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvilvh_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvilvh_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvilvh.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvilvh.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvilvh.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvilvh_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvilvh_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvilvh.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvilvh.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvilvh.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvilvh_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvilvh_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvilvh.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvilvh.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-insgr2vr-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-insgr2vr-invalid-imm.ll +deleted file mode 100644 +index 4982f2c7d..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-insgr2vr-invalid-imm.ll ++++ /dev/null +@@ -1,33 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <8 x i32> @llvm.loongarch.lasx.xvinsgr2vr.w(<8 x i32>, i32, i32) +- +-define <8 x i32> @lasx_xvinsgr2vr_w_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvinsgr2vr.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvinsgr2vr.w(<8 x i32> %va, i32 1, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvinsgr2vr_w_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvinsgr2vr.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvinsgr2vr.w(<8 x i32> %va, i32 1, i32 8) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvinsgr2vr.d(<4 x i64>, i64, i32) +- +-define <4 x i64> @lasx_xvinsgr2vr_d_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvinsgr2vr.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvinsgr2vr.d(<4 x i64> %va, i64 1, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvinsgr2vr_d_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvinsgr2vr.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvinsgr2vr.d(<4 x i64> %va, i64 1, i32 4) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-insgr2vr-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-insgr2vr-non-imm.ll +deleted file mode 100644 +index 3accabf6d..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-insgr2vr-non-imm.ll ++++ /dev/null +@@ -1,19 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <8 x i32> @llvm.loongarch.lasx.xvinsgr2vr.w(<8 x i32>, i32, i32) +- +-define <8 x i32> @lasx_xvinsgr2vr_w(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvinsgr2vr.w(<8 x i32> %va, i32 1, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvinsgr2vr.d(<4 x i64>, i64, i32) +- +-define <4 x i64> @lasx_xvinsgr2vr_d(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvinsgr2vr.d(<4 x i64> %va, i64 1, i32 %b) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-insgr2vr.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-insgr2vr.ll +deleted file mode 100644 +index ea98c9646..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-insgr2vr.ll ++++ /dev/null +@@ -1,28 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x i32> @llvm.loongarch.lasx.xvinsgr2vr.w(<8 x i32>, i32, i32) +- +-define <8 x i32> @lasx_xvinsgr2vr_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvinsgr2vr_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: xvinsgr2vr.w $xr0, $a0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvinsgr2vr.w(<8 x i32> %va, i32 1, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvinsgr2vr.d(<4 x i64>, i64, i32) +- +-define <4 x i64> @lasx_xvinsgr2vr_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvinsgr2vr_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: xvinsgr2vr.d $xr0, $a0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvinsgr2vr.d(<4 x i64> %va, i64 1, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-insve0-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-insve0-invalid-imm.ll +deleted file mode 100644 +index a54fa8515..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-insve0-invalid-imm.ll ++++ /dev/null +@@ -1,33 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <8 x i32> @llvm.loongarch.lasx.xvinsve0.w(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvinsve0_w_lo(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvinsve0.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvinsve0.w(<8 x i32> %va, <8 x i32> %vb, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvinsve0_w_hi(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvinsve0.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvinsve0.w(<8 x i32> %va, <8 x i32> %vb, i32 8) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvinsve0.d(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvinsve0_d_lo(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvinsve0.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvinsve0.d(<4 x i64> %va, <4 x i64> %vb, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvinsve0_d_hi(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvinsve0.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvinsve0.d(<4 x i64> %va, <4 x i64> %vb, i32 4) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-insve0-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-insve0-non-imm.ll +deleted file mode 100644 +index 53e59db11..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-insve0-non-imm.ll ++++ /dev/null +@@ -1,19 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <8 x i32> @llvm.loongarch.lasx.xvinsve0.w(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvinsve0_w(<8 x i32> %va, <8 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvinsve0.w(<8 x i32> %va, <8 x i32> %vb, i32 %c) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvinsve0.d(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvinsve0_d(<4 x i64> %va, <4 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvinsve0.d(<4 x i64> %va, <4 x i64> %vb, i32 %c) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-insve0.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-insve0.ll +deleted file mode 100644 +index 27ae819c4..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-insve0.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x i32> @llvm.loongarch.lasx.xvinsve0.w(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvinsve0_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvinsve0_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvinsve0.w $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvinsve0.w(<8 x i32> %va, <8 x i32> %vb, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvinsve0.d(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvinsve0_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvinsve0_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvinsve0.d $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvinsve0.d(<4 x i64> %va, <4 x i64> %vb, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-lasx.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-lasx.ll +new file mode 100644 +index 000000000..05b720077 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-lasx.ll +@@ -0,0 +1,70 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lasx < %s | FileCheck %s ++ ++declare <32 x i8> @llvm.loongarch.lasx.xvrepli.b(i32) ++declare <16 x i16> @llvm.loongarch.lasx.xvrepli.h(i32) ++declare <8 x i32> @llvm.loongarch.lasx.xvrepli.w(i32) ++declare <4 x i64> @llvm.loongarch.lasx.xvrepli.d(i32) ++ ++declare <4 x double> @llvm.loongarch.lasx.xvpickve.d.f(<4 x double>, i32) ++declare <8 x float> @llvm.loongarch.lasx.xvpickve.w.f(<8 x float>, i32) ++ ++define <32 x i8> @lasx_xvrepli_b() { ++; CHECK-LABEL: lasx_xvrepli_b: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvldi $xr0, 2 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = tail call <32 x i8> @llvm.loongarch.lasx.xvrepli.b(i32 2) ++ ret <32 x i8> %0 ++} ++ ++define <16 x i16> @lasx_xvrepli_h() { ++; CHECK-LABEL: lasx_xvrepli_h: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvldi $xr0, 2 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = tail call <16 x i16> @llvm.loongarch.lasx.xvrepli.h(i32 2) ++ ret <16 x i16> %0 ++} ++ ++define <8 x i32> @lasx_xvrepli_w() { ++; CHECK-LABEL: lasx_xvrepli_w: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvldi $xr0, 2 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = tail call <8 x i32> @llvm.loongarch.lasx.xvrepli.w(i32 2) ++ ret <8 x i32> %0 ++} ++ ++define <4 x i64> @lasx_xvrepli_d() { ++; CHECK-LABEL: lasx_xvrepli_d: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvldi $xr0, 2 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = tail call <4 x i64> @llvm.loongarch.lasx.xvrepli.d(i32 2) ++ ret <4 x i64> %0 ++} ++ ++define <4 x double> @lasx_xvpickve_d_f(<4 x double> %a) { ++; CHECK-LABEL: lasx_xvpickve_d_f: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvpickve.d $xr0, $xr0, 2 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = tail call <4 x double> @llvm.loongarch.lasx.xvpickve.d.f(<4 x double> %a, i32 2) ++ ret <4 x double> %0 ++} ++ ++define <8 x float> @lasx_xvpickve_w_f(<8 x float> %a) { ++; CHECK-LABEL: lasx_xvpickve_w_f: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvpickve.w $xr0, $xr0, 2 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = tail call <8 x float> @llvm.loongarch.lasx.xvpickve.w.f(<8 x float> %a, i32 2) ++ ret <8 x float> %0 ++} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ld-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ld-invalid-imm.ll +deleted file mode 100644 +index 20dd8a45d..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ld-invalid-imm.ll ++++ /dev/null +@@ -1,17 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvld(i8*, i32) +- +-define <32 x i8> @lasx_xvld_lo(i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvld: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvld(i8* %p, i32 -2049) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvld_hi(i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvld: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvld(i8* %p, i32 2048) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ld-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ld-non-imm.ll +deleted file mode 100644 +index b23436a44..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ld-non-imm.ll ++++ /dev/null +@@ -1,10 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvld(i8*, i32) +- +-define <32 x i8> @lasx_xvld(i8* %p, i32 %a) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvld(i8* %p, i32 %a) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ld.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ld.ll +deleted file mode 100644 +index 5ffc629db..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ld.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvld(i8*, i32) +- +-define <32 x i8> @lasx_xvld(i8* %p) nounwind { +-; CHECK-LABEL: lasx_xvld: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvld(i8* %p, i32 1) +- ret <32 x i8> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvldx(i8*, i64) +- +-define <32 x i8> @lasx_xvldx(i8* %p, i64 %b) nounwind { +-; CHECK-LABEL: lasx_xvldx: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvldx $xr0, $a0, $a1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvldx(i8* %p, i64 %b) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ldi-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ldi-invalid-imm.ll +deleted file mode 100644 +index f3dd3650c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ldi-invalid-imm.ll ++++ /dev/null +@@ -1,81 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <4 x i64> @llvm.loongarch.lasx.xvldi(i32) +- +-define <4 x i64> @lasx_xvldi_lo() nounwind { +-; CHECK: llvm.loongarch.lasx.xvldi: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvldi(i32 -4097) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvldi_hi() nounwind { +-; CHECK: llvm.loongarch.lasx.xvldi: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvldi(i32 4096) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvrepli.b(i32) +- +-define <32 x i8> @lasx_xvrepli_b_lo() nounwind { +-; CHECK: llvm.loongarch.lasx.xvrepli.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvrepli.b(i32 -513) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvrepli_b_hi() nounwind { +-; CHECK: llvm.loongarch.lasx.xvrepli.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvrepli.b(i32 512) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvrepli.h(i32) +- +-define <16 x i16> @lasx_xvrepli_h_lo() nounwind { +-; CHECK: llvm.loongarch.lasx.xvrepli.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvrepli.h(i32 -513) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvrepli_h_hi() nounwind { +-; CHECK: llvm.loongarch.lasx.xvrepli.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvrepli.h(i32 512) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvrepli.w(i32) +- +-define <8 x i32> @lasx_xvrepli_w_lo() nounwind { +-; CHECK: llvm.loongarch.lasx.xvrepli.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvrepli.w(i32 -513) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvrepli_w_hi() nounwind { +-; CHECK: llvm.loongarch.lasx.xvrepli.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvrepli.w(i32 512) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvrepli.d(i32) +- +-define <4 x i64> @lasx_xvrepli_d_lo() nounwind { +-; CHECK: llvm.loongarch.lasx.xvrepli.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvrepli.d(i32 -513) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvrepli_d_hi() nounwind { +-; CHECK: llvm.loongarch.lasx.xvrepli.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvrepli.d(i32 512) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ldi-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ldi-non-imm.ll +deleted file mode 100644 +index 6466818bf..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ldi-non-imm.ll ++++ /dev/null +@@ -1,46 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <4 x i64> @llvm.loongarch.lasx.xvldi(i32) +- +-define <4 x i64> @lasx_xvldi(i32 %a) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvldi(i32 %a) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvrepli.b(i32) +- +-define <32 x i8> @lasx_xvrepli_b(i32 %a) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvrepli.b(i32 %a) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvrepli.h(i32) +- +-define <16 x i16> @lasx_xvrepli_h(i32 %a) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvrepli.h(i32 %a) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvrepli.w(i32) +- +-define <8 x i32> @lasx_xvrepli_w(i32 %a) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvrepli.w(i32 %a) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvrepli.d(i32) +- +-define <4 x i64> @lasx_xvrepli_d(i32 %a) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvrepli.d(i32 %a) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ldi.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ldi.ll +deleted file mode 100644 +index 59f79dd32..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ldi.ll ++++ /dev/null +@@ -1,62 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <4 x i64> @llvm.loongarch.lasx.xvldi(i32) +- +-define <4 x i64> @lasx_xvldi() nounwind { +-; CHECK-LABEL: lasx_xvldi: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvldi $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvldi(i32 1) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvrepli.b(i32) +- +-define <32 x i8> @lasx_xvrepli_b() nounwind { +-; CHECK-LABEL: lasx_xvrepli_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvrepli.b $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvrepli.b(i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvrepli.h(i32) +- +-define <16 x i16> @lasx_xvrepli_h() nounwind { +-; CHECK-LABEL: lasx_xvrepli_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvrepli.h $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvrepli.h(i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvrepli.w(i32) +- +-define <8 x i32> @lasx_xvrepli_w() nounwind { +-; CHECK-LABEL: lasx_xvrepli_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvrepli.w $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvrepli.w(i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvrepli.d(i32) +- +-define <4 x i64> @lasx_xvrepli_d() nounwind { +-; CHECK-LABEL: lasx_xvrepli_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvrepli.d $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvrepli.d(i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ldrepl-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ldrepl-invalid-imm.ll +deleted file mode 100644 +index cb62a8399..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ldrepl-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvldrepl.b(i8*, i32) +- +-define <32 x i8> @lasx_xvldrepl_b_lo(i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvldrepl.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvldrepl.b(i8* %p, i32 -2049) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvldrepl_b_hi(i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvldrepl.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvldrepl.b(i8* %p, i32 2048) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvldrepl.h(i8*, i32) +- +-define <16 x i16> @lasx_xvldrepl_h_lo(i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvldrepl.h: argument out of range or not a multiple of 2. +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvldrepl.h(i8* %p, i32 -2050) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvldrepl_h_hi(i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvldrepl.h: argument out of range or not a multiple of 2. +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvldrepl.h(i8* %p, i32 2048) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvldrepl.w(i8*, i32) +- +-define <8 x i32> @lasx_xvldrepl_w_lo(i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvldrepl.w: argument out of range or not a multiple of 4. +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvldrepl.w(i8* %p, i32 -2052) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvldrepl_w_hi(i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvldrepl.w: argument out of range or not a multiple of 4. +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvldrepl.w(i8* %p, i32 2048) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvldrepl.d(i8*, i32) +- +-define <4 x i64> @lasx_xvldrepl_d_lo(i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvldrepl.d: argument out of range or not a multiple of 8. +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvldrepl.d(i8* %p, i32 -2056) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvldrepl_d_hi(i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvldrepl.d: argument out of range or not a multiple of 8. +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvldrepl.d(i8* %p, i32 2048) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ldrepl-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ldrepl-non-imm.ll +deleted file mode 100644 +index 075d663b0..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ldrepl-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvldrepl.b(i8*, i32) +- +-define <32 x i8> @lasx_xvldrepl_b(i8* %p, i32 %a) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvldrepl.b(i8* %p, i32 %a) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvldrepl.h(i8*, i32) +- +-define <16 x i16> @lasx_xvldrepl_h(i8* %p, i32 %a) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvldrepl.h(i8* %p, i32 %a) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvldrepl.w(i8*, i32) +- +-define <8 x i32> @lasx_xvldrepl_w(i8* %p, i32 %a) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvldrepl.w(i8* %p, i32 %a) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvldrepl.d(i8*, i32) +- +-define <4 x i64> @lasx_xvldrepl_d(i8* %p, i32 %a) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvldrepl.d(i8* %p, i32 %a) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ldrepl-postra.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ldrepl-postra.ll +new file mode 100644 +index 000000000..db2c5a837 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ldrepl-postra.ll +@@ -0,0 +1,27 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 ++; RUN: llc --mtriple=loongarch64 --mattr=+lasx -O3 < %s | FileCheck %s ++ ++declare <8 x i32> @llvm.loongarch.lasx.xvldrepl.w(i8*, i32) ++declare <8 x i32> @llvm.loongarch.lasx.xvsub.w(<8 x i32>, <8 x i32>) ++ ++define <8 x i32> @test(<8 x i32>* %p) { ++; CHECK-LABEL: test: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: addi.d $sp, $sp, -16 ++; CHECK-NEXT: .cfi_def_cfa_offset 16 ++; CHECK-NEXT: ori $r5, $zero, 256 ++; CHECK-NEXT: st.w $r5, $sp, 12 ++; CHECK-NEXT: xvld $xr0, $r4, 0 ++; CHECK-NEXT: xvldrepl.w $xr1, $sp, 12 ++; CHECK-NEXT: xvsub.w $xr0, $xr1, $xr0 ++; CHECK-NEXT: addi.d $sp, $sp, 16 ++; CHECK-NEXT: jr $ra ++entry: ++ %tmp = alloca i32, align 4 ++ store i32 256, i32* %tmp, align 4 ++ %t = bitcast i32* %tmp to i8* ++ %0 = call <8 x i32> @llvm.loongarch.lasx.xvldrepl.w(i8* %t, i32 0) ++ %1 = load <8 x i32>, <8 x i32>* %p, align 32 ++ %2 = call <8 x i32> @llvm.loongarch.lasx.xvsub.w(<8 x i32> %0, <8 x i32> %1) ++ ret <8 x i32> %2 ++} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ldrepl.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ldrepl.ll +index ae6abdf81..d9dace690 100644 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ldrepl.ll ++++ b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ldrepl.ll +@@ -6,8 +6,8 @@ declare <32 x i8> @llvm.loongarch.lasx.xvldrepl.b(i8*, i32) + define <32 x i8> @lasx_xvldrepl_b(i8* %p) nounwind { + ; CHECK-LABEL: lasx_xvldrepl_b: + ; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvldrepl.b $xr0, $a0, 1 +-; CHECK-NEXT: ret ++; CHECK-NEXT: xvldrepl.b $xr0, $r4, 1 ++; CHECK-NEXT: jr $ra + entry: + %res = call <32 x i8> @llvm.loongarch.lasx.xvldrepl.b(i8* %p, i32 1) + ret <32 x i8> %res +@@ -18,8 +18,8 @@ declare <16 x i16> @llvm.loongarch.lasx.xvldrepl.h(i8*, i32) + define <16 x i16> @lasx_xvldrepl_h(i8* %p) nounwind { + ; CHECK-LABEL: lasx_xvldrepl_h: + ; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvldrepl.h $xr0, $a0, 2 +-; CHECK-NEXT: ret ++; CHECK-NEXT: xvldrepl.h $xr0, $r4, 2 ++; CHECK-NEXT: jr $ra + entry: + %res = call <16 x i16> @llvm.loongarch.lasx.xvldrepl.h(i8* %p, i32 2) + ret <16 x i16> %res +@@ -30,8 +30,8 @@ declare <8 x i32> @llvm.loongarch.lasx.xvldrepl.w(i8*, i32) + define <8 x i32> @lasx_xvldrepl_w(i8* %p) nounwind { + ; CHECK-LABEL: lasx_xvldrepl_w: + ; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvldrepl.w $xr0, $a0, 4 +-; CHECK-NEXT: ret ++; CHECK-NEXT: xvldrepl.w $xr0, $r4, 4 ++; CHECK-NEXT: jr $ra + entry: + %res = call <8 x i32> @llvm.loongarch.lasx.xvldrepl.w(i8* %p, i32 4) + ret <8 x i32> %res +@@ -42,8 +42,8 @@ declare <4 x i64> @llvm.loongarch.lasx.xvldrepl.d(i8*, i32) + define <4 x i64> @lasx_xvldrepl_d(i8* %p) nounwind { + ; CHECK-LABEL: lasx_xvldrepl_d: + ; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvldrepl.d $xr0, $a0, 8 +-; CHECK-NEXT: ret ++; CHECK-NEXT: xvldrepl.d $xr0, $r4, 8 ++; CHECK-NEXT: jr $ra + entry: + %res = call <4 x i64> @llvm.loongarch.lasx.xvldrepl.d(i8* %p, i32 8) + ret <4 x i64> %res +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-madd.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-madd.ll +deleted file mode 100644 +index d3b093967..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-madd.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmadd.b(<32 x i8>, <32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvmadd_b(<32 x i8> %va, <32 x i8> %vb, <32 x i8> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmadd_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmadd.b $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmadd.b(<32 x i8> %va, <32 x i8> %vb, <32 x i8> %vc) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmadd.h(<16 x i16>, <16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvmadd_h(<16 x i16> %va, <16 x i16> %vb, <16 x i16> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmadd_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmadd.h $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmadd.h(<16 x i16> %va, <16 x i16> %vb, <16 x i16> %vc) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmadd.w(<8 x i32>, <8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvmadd_w(<8 x i32> %va, <8 x i32> %vb, <8 x i32> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmadd_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmadd.w $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmadd.w(<8 x i32> %va, <8 x i32> %vb, <8 x i32> %vc) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmadd.d(<4 x i64>, <4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmadd_d(<4 x i64> %va, <4 x i64> %vb, <4 x i64> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmadd_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmadd.d $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmadd.d(<4 x i64> %va, <4 x i64> %vb, <4 x i64> %vc) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-maddw.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-maddw.ll +deleted file mode 100644 +index 146624a76..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-maddw.ll ++++ /dev/null +@@ -1,290 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmaddwev.h.b(<16 x i16>, <32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvmaddwev_h_b(<16 x i16> %va, <32 x i8> %vb, <32 x i8> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwev_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwev.h.b $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmaddwev.h.b(<16 x i16> %va, <32 x i8> %vb, <32 x i8> %vc) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmaddwev.w.h(<8 x i32>, <16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvmaddwev_w_h(<8 x i32> %va, <16 x i16> %vb, <16 x i16> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwev_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwev.w.h $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmaddwev.w.h(<8 x i32> %va, <16 x i16> %vb, <16 x i16> %vc) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmaddwev.d.w(<4 x i64>, <8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvmaddwev_d_w(<4 x i64> %va, <8 x i32> %vb, <8 x i32> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwev_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwev.d.w $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.d.w(<4 x i64> %va, <8 x i32> %vb, <8 x i32> %vc) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmaddwev.q.d(<4 x i64>, <4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmaddwev_q_d(<4 x i64> %va, <4 x i64> %vb, <4 x i64> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwev_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwev.q.d $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.q.d(<4 x i64> %va, <4 x i64> %vb, <4 x i64> %vc) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmaddwev.h.bu(<16 x i16>, <32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvmaddwev_h_bu(<16 x i16> %va, <32 x i8> %vb, <32 x i8> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwev_h_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwev.h.bu $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmaddwev.h.bu(<16 x i16> %va, <32 x i8> %vb, <32 x i8> %vc) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmaddwev.w.hu(<8 x i32>, <16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvmaddwev_w_hu(<8 x i32> %va, <16 x i16> %vb, <16 x i16> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwev_w_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwev.w.hu $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmaddwev.w.hu(<8 x i32> %va, <16 x i16> %vb, <16 x i16> %vc) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmaddwev.d.wu(<4 x i64>, <8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvmaddwev_d_wu(<4 x i64> %va, <8 x i32> %vb, <8 x i32> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwev_d_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwev.d.wu $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.d.wu(<4 x i64> %va, <8 x i32> %vb, <8 x i32> %vc) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmaddwev.q.du(<4 x i64>, <4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmaddwev_q_du(<4 x i64> %va, <4 x i64> %vb, <4 x i64> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwev_q_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwev.q.du $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.q.du(<4 x i64> %va, <4 x i64> %vb, <4 x i64> %vc) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmaddwev.h.bu.b(<16 x i16>, <32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvmaddwev_h_bu_b(<16 x i16> %va, <32 x i8> %vb, <32 x i8> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwev_h_bu_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwev.h.bu.b $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmaddwev.h.bu.b(<16 x i16> %va, <32 x i8> %vb, <32 x i8> %vc) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmaddwev.w.hu.h(<8 x i32>, <16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvmaddwev_w_hu_h(<8 x i32> %va, <16 x i16> %vb, <16 x i16> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwev_w_hu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwev.w.hu.h $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmaddwev.w.hu.h(<8 x i32> %va, <16 x i16> %vb, <16 x i16> %vc) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmaddwev.d.wu.w(<4 x i64>, <8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvmaddwev_d_wu_w(<4 x i64> %va, <8 x i32> %vb, <8 x i32> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwev_d_wu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwev.d.wu.w $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.d.wu.w(<4 x i64> %va, <8 x i32> %vb, <8 x i32> %vc) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmaddwev.q.du.d(<4 x i64>, <4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmaddwev_q_du_d(<4 x i64> %va, <4 x i64> %vb, <4 x i64> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwev_q_du_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwev.q.du.d $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmaddwev.q.du.d(<4 x i64> %va, <4 x i64> %vb, <4 x i64> %vc) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmaddwod.h.b(<16 x i16>, <32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvmaddwod_h_b(<16 x i16> %va, <32 x i8> %vb, <32 x i8> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwod_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwod.h.b $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmaddwod.h.b(<16 x i16> %va, <32 x i8> %vb, <32 x i8> %vc) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmaddwod.w.h(<8 x i32>, <16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvmaddwod_w_h(<8 x i32> %va, <16 x i16> %vb, <16 x i16> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwod_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwod.w.h $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmaddwod.w.h(<8 x i32> %va, <16 x i16> %vb, <16 x i16> %vc) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmaddwod.d.w(<4 x i64>, <8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvmaddwod_d_w(<4 x i64> %va, <8 x i32> %vb, <8 x i32> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwod_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwod.d.w $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.d.w(<4 x i64> %va, <8 x i32> %vb, <8 x i32> %vc) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmaddwod.q.d(<4 x i64>, <4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmaddwod_q_d(<4 x i64> %va, <4 x i64> %vb, <4 x i64> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwod_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwod.q.d $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.q.d(<4 x i64> %va, <4 x i64> %vb, <4 x i64> %vc) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmaddwod.h.bu(<16 x i16>, <32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvmaddwod_h_bu(<16 x i16> %va, <32 x i8> %vb, <32 x i8> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwod_h_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwod.h.bu $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmaddwod.h.bu(<16 x i16> %va, <32 x i8> %vb, <32 x i8> %vc) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmaddwod.w.hu(<8 x i32>, <16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvmaddwod_w_hu(<8 x i32> %va, <16 x i16> %vb, <16 x i16> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwod_w_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwod.w.hu $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmaddwod.w.hu(<8 x i32> %va, <16 x i16> %vb, <16 x i16> %vc) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmaddwod.d.wu(<4 x i64>, <8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvmaddwod_d_wu(<4 x i64> %va, <8 x i32> %vb, <8 x i32> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwod_d_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwod.d.wu $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.d.wu(<4 x i64> %va, <8 x i32> %vb, <8 x i32> %vc) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmaddwod.q.du(<4 x i64>, <4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmaddwod_q_du(<4 x i64> %va, <4 x i64> %vb, <4 x i64> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwod_q_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwod.q.du $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.q.du(<4 x i64> %va, <4 x i64> %vb, <4 x i64> %vc) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmaddwod.h.bu.b(<16 x i16>, <32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvmaddwod_h_bu_b(<16 x i16> %va, <32 x i8> %vb, <32 x i8> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwod_h_bu_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwod.h.bu.b $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmaddwod.h.bu.b(<16 x i16> %va, <32 x i8> %vb, <32 x i8> %vc) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmaddwod.w.hu.h(<8 x i32>, <16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvmaddwod_w_hu_h(<8 x i32> %va, <16 x i16> %vb, <16 x i16> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwod_w_hu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwod.w.hu.h $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmaddwod.w.hu.h(<8 x i32> %va, <16 x i16> %vb, <16 x i16> %vc) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmaddwod.d.wu.w(<4 x i64>, <8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvmaddwod_d_wu_w(<4 x i64> %va, <8 x i32> %vb, <8 x i32> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwod_d_wu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwod.d.wu.w $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.d.wu.w(<4 x i64> %va, <8 x i32> %vb, <8 x i32> %vc) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmaddwod.q.du.d(<4 x i64>, <4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmaddwod_q_du_d(<4 x i64> %va, <4 x i64> %vb, <4 x i64> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmaddwod_q_du_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaddwod.q.du.d $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmaddwod.q.du.d(<4 x i64> %va, <4 x i64> %vb, <4 x i64> %vc) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-max-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-max-invalid-imm.ll +deleted file mode 100644 +index a671e9979..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-max-invalid-imm.ll ++++ /dev/null +@@ -1,129 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmaxi.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvmaxi_b_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmaxi.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmaxi.b(<32 x i8> %va, i32 -17) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvmaxi_b_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmaxi.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmaxi.b(<32 x i8> %va, i32 16) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmaxi.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvmaxi_h_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmaxi.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmaxi.h(<16 x i16> %va, i32 -17) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvmaxi_h_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmaxi.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmaxi.h(<16 x i16> %va, i32 16) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmaxi.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvmaxi_w_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmaxi.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmaxi.w(<8 x i32> %va, i32 -17) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvmaxi_w_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmaxi.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmaxi.w(<8 x i32> %va, i32 16) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmaxi.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvmaxi_d_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmaxi.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmaxi.d(<4 x i64> %va, i32 -17) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvmaxi_d_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmaxi.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmaxi.d(<4 x i64> %va, i32 16) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmaxi.bu(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvmaxi_bu_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmaxi.bu: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmaxi.bu(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvmaxi_bu_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmaxi.bu: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmaxi.bu(<32 x i8> %va, i32 32) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmaxi.hu(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvmaxi_hu_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmaxi.hu: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmaxi.hu(<16 x i16> %va, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvmaxi_hu_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmaxi.hu: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmaxi.hu(<16 x i16> %va, i32 32) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmaxi.wu(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvmaxi_wu_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmaxi.wu: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmaxi.wu(<8 x i32> %va, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvmaxi_wu_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmaxi.wu: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmaxi.wu(<8 x i32> %va, i32 32) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmaxi.du(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvmaxi_du_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmaxi.du: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmaxi.du(<4 x i64> %va, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvmaxi_du_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmaxi.du: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmaxi.du(<4 x i64> %va, i32 32) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-max-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-max-non-imm.ll +deleted file mode 100644 +index b85798b53..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-max-non-imm.ll ++++ /dev/null +@@ -1,73 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmaxi.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvmaxi_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmaxi.b(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmaxi.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvmaxi_h(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmaxi.h(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmaxi.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvmaxi_w(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmaxi.w(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmaxi.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvmaxi_d(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmaxi.d(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmaxi.bu(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvmaxi_bu(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmaxi.bu(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmaxi.hu(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvmaxi_hu(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmaxi.hu(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmaxi.wu(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvmaxi_wu(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmaxi.wu(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmaxi.du(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvmaxi_du(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmaxi.du(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-max.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-max.ll +deleted file mode 100644 +index 9cf09df44..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-max.ll ++++ /dev/null +@@ -1,194 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmax.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvmax_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmax_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmax.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmax.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmax.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvmax_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmax_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmax.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmax.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmax.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvmax_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmax_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmax.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmax.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmax.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmax_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmax_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmax.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmax.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmaxi.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvmaxi_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvmaxi_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaxi.b $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmaxi.b(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmaxi.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvmaxi_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvmaxi_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaxi.h $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmaxi.h(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmaxi.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvmaxi_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvmaxi_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaxi.w $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmaxi.w(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmaxi.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvmaxi_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvmaxi_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaxi.d $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmaxi.d(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmax.bu(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_vmax_bu(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_vmax_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmax.bu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmax.bu(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmax.hu(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvmax_hu(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmax_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmax.hu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmax.hu(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmax.wu(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvmax_wu(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmax_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmax.wu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmax.wu(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmax.du(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmax_du(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmax_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmax.du $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmax.du(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmaxi.bu(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvmaxi_bu(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvmaxi_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaxi.bu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmaxi.bu(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmaxi.hu(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvmaxi_hu(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvmaxi_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaxi.hu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmaxi.hu(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmaxi.wu(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvmaxi_wu(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvmaxi_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaxi.wu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmaxi.wu(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmaxi.du(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvmaxi_du(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvmaxi_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmaxi.du $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmaxi.du(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-min-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-min-invalid-imm.ll +deleted file mode 100644 +index 5ed4104c2..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-min-invalid-imm.ll ++++ /dev/null +@@ -1,129 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmini.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvmini_b_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmini.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmini.b(<32 x i8> %va, i32 -17) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvmini_b_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmini.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmini.b(<32 x i8> %va, i32 16) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmini.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvmini_h_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmini.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmini.h(<16 x i16> %va, i32 -17) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvmini_h_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmini.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmini.h(<16 x i16> %va, i32 16) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmini.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvmini_w_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmini.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmini.w(<8 x i32> %va, i32 -17) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvmini_w_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmini.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmini.w(<8 x i32> %va, i32 16) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmini.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvmini_d_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmini.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmini.d(<4 x i64> %va, i32 -17) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvmini_d_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmini.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmini.d(<4 x i64> %va, i32 16) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmini.bu(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvmini_bu_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmini.bu: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmini.bu(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvmini_bu_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmini.bu: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmini.bu(<32 x i8> %va, i32 32) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmini.hu(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvmini_hu_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmini.hu: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmini.hu(<16 x i16> %va, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvmini_hu_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmini.hu: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmini.hu(<16 x i16> %va, i32 32) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmini.wu(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvmini_wu_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmini.wu: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmini.wu(<8 x i32> %va, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvmini_wu_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmini.wu: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmini.wu(<8 x i32> %va, i32 32) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmini.du(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvmini_du_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmini.du: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmini.du(<4 x i64> %va, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvmini_du_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvmini.du: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmini.du(<4 x i64> %va, i32 32) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-min-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-min-non-imm.ll +deleted file mode 100644 +index b81931977..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-min-non-imm.ll ++++ /dev/null +@@ -1,73 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmini.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvmini_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmini.b(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmini.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvmini_h(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmini.h(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmini.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvmini_w(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmini.w(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmini.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvmini_d(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmini.d(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmini.bu(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvmini_bu(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmini.bu(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmini.hu(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvmini_hu(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmini.hu(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmini.wu(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvmini_wu(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmini.wu(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmini.du(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvmini_du(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmini.du(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-min.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-min.ll +deleted file mode 100644 +index c94b1e4ea..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-min.ll ++++ /dev/null +@@ -1,194 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmin.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvmin_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmin_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmin.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmin.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmin.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvmin_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmin_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmin.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmin.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmin.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvmin_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmin_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmin.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmin.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmin.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmin_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmin_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmin.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmin.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmini.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvmini_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvmini_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmini.b $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmini.b(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmini.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvmini_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvmini_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmini.h $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmini.h(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmini.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvmini_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvmini_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmini.w $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmini.w(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmini.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvmini_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvmini_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmini.d $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmini.d(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmin.bu(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvmin_bu(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmin_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmin.bu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmin.bu(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmin.hu(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvmin_hu(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmin_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmin.hu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmin.hu(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmin.wu(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvmin_wu(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmin_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmin.wu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmin.wu(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmin.du(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmin_du(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmin_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmin.du $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmin.du(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmini.bu(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvmini_bu(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvmini_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmini.bu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmini.bu(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmini.hu(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvmini_hu(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvmini_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmini.hu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmini.hu(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmini.wu(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvmini_wu(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvmini_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmini.wu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmini.wu(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmini.du(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvmini_du(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvmini_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmini.du $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmini.du(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-mod.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-mod.ll +deleted file mode 100644 +index a177246bb..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-mod.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmod.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvmod_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmod_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmod.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmod.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmod.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvmod_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmod_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmod.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmod.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmod.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvmod_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmod_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmod.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmod.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmod.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmod_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmod_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmod.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmod.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmod.bu(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvmod_bu(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmod_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmod.bu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmod.bu(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmod.hu(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvmod_hu(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmod_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmod.hu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmod.hu(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmod.wu(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvmod_wu(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmod_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmod.wu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmod.wu(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmod.du(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmod_du(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmod_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmod.du $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmod.du(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-mskgez.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-mskgez.ll +deleted file mode 100644 +index da87c20ad..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-mskgez.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmskgez.b(<32 x i8>) +- +-define <32 x i8> @lasx_xvmskgez_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvmskgez_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmskgez.b $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmskgez.b(<32 x i8> %va) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-mskltz.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-mskltz.ll +deleted file mode 100644 +index b22184875..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-mskltz.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmskltz.b(<32 x i8>) +- +-define <32 x i8> @lasx_xvmskltz_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvmskltz_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmskltz.b $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmskltz.b(<32 x i8> %va) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmskltz.h(<16 x i16>) +- +-define <16 x i16> @lasx_xvmskltz_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvmskltz_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmskltz.h $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmskltz.h(<16 x i16> %va) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmskltz.w(<8 x i32>) +- +-define <8 x i32> @lasx_xvmskltz_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvmskltz_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmskltz.w $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmskltz.w(<8 x i32> %va) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmskltz.d(<4 x i64>) +- +-define <4 x i64> @lasx_xvmskltz_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvmskltz_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmskltz.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmskltz.d(<4 x i64> %va) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-msknz.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-msknz.ll +deleted file mode 100644 +index becd2c883..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-msknz.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmsknz.b(<32 x i8>) +- +-define <32 x i8> @lasx_xvmsknz_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvmsknz_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmsknz.b $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmsknz.b(<32 x i8> %va) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-msub.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-msub.ll +deleted file mode 100644 +index c89f9578b..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-msub.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmsub.b(<32 x i8>, <32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvmsub_b(<32 x i8> %va, <32 x i8> %vb, <32 x i8> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmsub_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmsub.b $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmsub.b(<32 x i8> %va, <32 x i8> %vb, <32 x i8> %vc) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmsub.h(<16 x i16>, <16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvmsub_h(<16 x i16> %va, <16 x i16> %vb, <16 x i16> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmsub_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmsub.h $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmsub.h(<16 x i16> %va, <16 x i16> %vb, <16 x i16> %vc) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmsub.w(<8 x i32>, <8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvmsub_w(<8 x i32> %va, <8 x i32> %vb, <8 x i32> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmsub_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmsub.w $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmsub.w(<8 x i32> %va, <8 x i32> %vb, <8 x i32> %vc) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmsub.d(<4 x i64>, <4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmsub_d(<4 x i64> %va, <4 x i64> %vb, <4 x i64> %vc) nounwind { +-; CHECK-LABEL: lasx_xvmsub_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmsub.d $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmsub.d(<4 x i64> %va, <4 x i64> %vb, <4 x i64> %vc) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-muh.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-muh.ll +deleted file mode 100644 +index 97461512c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-muh.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmuh.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvmuh_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmuh_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmuh.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmuh.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmuh.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvmuh_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmuh_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmuh.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmuh.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmuh.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvmuh_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmuh_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmuh.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmuh.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmuh.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmuh_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmuh_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmuh.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmuh.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmuh.bu(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvmuh_bu(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmuh_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmuh.bu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmuh.bu(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmuh.hu(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvmuh_hu(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmuh_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmuh.hu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmuh.hu(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmuh.wu(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvmuh_wu(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmuh_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmuh.wu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmuh.wu(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmuh.du(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmuh_du(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmuh_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmuh.du $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmuh.du(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-mul.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-mul.ll +deleted file mode 100644 +index d5d852e58..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-mul.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvmul.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvmul_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmul_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmul.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvmul.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmul.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvmul_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmul_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmul.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmul.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmul.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvmul_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmul_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmul.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmul.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmul.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmul_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmul_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmul.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmul.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-mulw.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-mulw.ll +deleted file mode 100644 +index f69e64aa7..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-mulw.ll ++++ /dev/null +@@ -1,290 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmulwev.h.b(<32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvmulwev_h_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwev_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwev.h.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmulwev.h.b(<32 x i8> %va, <32 x i8> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmulwev.w.h(<16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvmulwev_w_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwev_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwev.w.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmulwev.w.h(<16 x i16> %va, <16 x i16> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmulwev.d.w(<8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvmulwev_d_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwev_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwev.d.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmulwev.d.w(<8 x i32> %va, <8 x i32> %vb) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmulwev.q.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmulwev_q_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwev_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwev.q.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmulwev.q.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmulwev.h.bu(<32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvmulwev_h_bu(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwev_h_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwev.h.bu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmulwev.h.bu(<32 x i8> %va, <32 x i8> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmulwev.w.hu(<16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvmulwev_w_hu(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwev_w_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwev.w.hu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmulwev.w.hu(<16 x i16> %va, <16 x i16> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmulwev.d.wu(<8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvmulwev_d_wu(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwev_d_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwev.d.wu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmulwev.d.wu(<8 x i32> %va, <8 x i32> %vb) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmulwev.q.du(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmulwev_q_du(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwev_q_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwev.q.du $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmulwev.q.du(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmulwev.h.bu.b(<32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvmulwev_h_bu_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwev_h_bu_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwev.h.bu.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmulwev.h.bu.b(<32 x i8> %va, <32 x i8> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmulwev.w.hu.h(<16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvmulwev_w_hu_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwev_w_hu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwev.w.hu.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmulwev.w.hu.h(<16 x i16> %va, <16 x i16> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmulwev.d.wu.w(<8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvmulwev_d_wu_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwev_d_wu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwev.d.wu.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmulwev.d.wu.w(<8 x i32> %va, <8 x i32> %vb) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmulwev.q.du.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmulwev_q_du_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwev_q_du_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwev.q.du.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmulwev.q.du.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmulwod.h.b(<32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvmulwod_h_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwod_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwod.h.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmulwod.h.b(<32 x i8> %va, <32 x i8> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmulwod.w.h(<16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvmulwod_w_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwod_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwod.w.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmulwod.w.h(<16 x i16> %va, <16 x i16> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmulwod.d.w(<8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvmulwod_d_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwod_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwod.d.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmulwod.d.w(<8 x i32> %va, <8 x i32> %vb) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmulwod.q.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmulwod_q_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwod_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwod.q.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmulwod.q.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmulwod.h.bu(<32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvmulwod_h_bu(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwod_h_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwod.h.bu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmulwod.h.bu(<32 x i8> %va, <32 x i8> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmulwod.w.hu(<16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvmulwod_w_hu(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwod_w_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwod.w.hu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmulwod.w.hu(<16 x i16> %va, <16 x i16> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmulwod.d.wu(<8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvmulwod_d_wu(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwod_d_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwod.d.wu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmulwod.d.wu(<8 x i32> %va, <8 x i32> %vb) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmulwod.q.du(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmulwod_q_du(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwod_q_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwod.q.du $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmulwod.q.du(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvmulwod.h.bu.b(<32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvmulwod_h_bu_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwod_h_bu_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwod.h.bu.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvmulwod.h.bu.b(<32 x i8> %va, <32 x i8> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvmulwod.w.hu.h(<16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvmulwod_w_hu_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwod_w_hu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwod.w.hu.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvmulwod.w.hu.h(<16 x i16> %va, <16 x i16> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmulwod.d.wu.w(<8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvmulwod_d_wu_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwod_d_wu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwod.d.wu.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmulwod.d.wu.w(<8 x i32> %va, <8 x i32> %vb) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvmulwod.q.du.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvmulwod_q_du_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvmulwod_q_du_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvmulwod.q.du.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvmulwod.q.du.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-neg.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-neg.ll +deleted file mode 100644 +index ecbedf334..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-neg.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvneg.b(<32 x i8>) +- +-define <32 x i8> @lasx_xvneg_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvneg_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvneg.b $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvneg.b(<32 x i8> %va) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvneg.h(<16 x i16>) +- +-define <16 x i16> @lasx_xvneg_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvneg_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvneg.h $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvneg.h(<16 x i16> %va) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvneg.w(<8 x i32>) +- +-define <8 x i32> @lasx_xvneg_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvneg_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvneg.w $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvneg.w(<8 x i32> %va) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvneg.d(<4 x i64>) +- +-define <4 x i64> @lasx_xvneg_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvneg_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvneg.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvneg.d(<4 x i64> %va) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-nor.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-nor.ll +deleted file mode 100644 +index 674746b76..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-nor.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvnor.v(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvnor_v(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvnor_v: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvnor.v $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvnor.v(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-nori-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-nori-invalid-imm.ll +deleted file mode 100644 +index 1130e094b..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-nori-invalid-imm.ll ++++ /dev/null +@@ -1,17 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvnori.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvnori_b_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvnori.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvnori.b(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvnori_b_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvnori.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvnori.b(<32 x i8> %va, i32 256) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-nori-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-nori-non-imm.ll +deleted file mode 100644 +index 8f2333064..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-nori-non-imm.ll ++++ /dev/null +@@ -1,10 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvnori.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvnori_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvnori.b(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-nori.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-nori.ll +deleted file mode 100644 +index 55eebf87e..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-nori.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvnori.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvnori_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvnori_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvnori.b $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvnori.b(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-or.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-or.ll +deleted file mode 100644 +index 16462cfaf..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-or.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvor.v(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvor_v(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvor_v: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvor.v $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvor.v(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ori-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ori-invalid-imm.ll +deleted file mode 100644 +index 90dec8e55..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ori-invalid-imm.ll ++++ /dev/null +@@ -1,17 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvori.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvori_b_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvori.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvori.b(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvori_b_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvori.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvori.b(<32 x i8> %va, i32 256) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ori-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ori-non-imm.ll +deleted file mode 100644 +index ae6571d98..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ori-non-imm.ll ++++ /dev/null +@@ -1,10 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvori.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvori_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvori.b(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ori.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ori.ll +deleted file mode 100644 +index 8e53d88ba..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ori.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvori.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvori_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvori_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvori.b $xr0, $xr0, 3 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvori.b(<32 x i8> %va, i32 3) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-orn.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-orn.ll +deleted file mode 100644 +index 3a335cdd3..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-orn.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvorn.v(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvorn_v(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvorn_v: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvorn.v $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvorn.v(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pack.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pack.ll +deleted file mode 100644 +index 512b30234..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pack.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvpackev.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvpackev_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvpackev_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpackev.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvpackev.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvpackev.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvpackev_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvpackev_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpackev.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvpackev.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvpackev.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvpackev_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvpackev_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpackev.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvpackev.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvpackev.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvpackev_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvpackev_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpackev.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvpackev.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvpackod.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvpackod_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvpackod_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpackod.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvpackod.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvpackod.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvpackod_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvpackod_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpackod.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvpackod.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvpackod.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvpackod_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvpackod_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpackod.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvpackod.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvpackod.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvpackod_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvpackod_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpackod.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvpackod.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pcnt.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pcnt.ll +deleted file mode 100644 +index d77f1d208..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pcnt.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvpcnt.b(<32 x i8>) +- +-define <32 x i8> @lasx_xvpcnt_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvpcnt_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpcnt.b $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvpcnt.b(<32 x i8> %va) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvpcnt.h(<16 x i16>) +- +-define <16 x i16> @lasx_xvpcnt_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvpcnt_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpcnt.h $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvpcnt.h(<16 x i16> %va) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvpcnt.w(<8 x i32>) +- +-define <8 x i32> @lasx_xvpcnt_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvpcnt_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpcnt.w $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvpcnt.w(<8 x i32> %va) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvpcnt.d(<4 x i64>) +- +-define <4 x i64> @lasx_xvpcnt_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvpcnt_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpcnt.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvpcnt.d(<4 x i64> %va) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-perm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-perm.ll +deleted file mode 100644 +index 4ec434edd..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-perm.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x i32> @llvm.loongarch.lasx.xvperm.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvperm_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvperm_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvperm.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvperm.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi-invalid-imm.ll +deleted file mode 100644 +index 41f4856bd..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi-invalid-imm.ll ++++ /dev/null +@@ -1,49 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <8 x i32> @llvm.loongarch.lasx.xvpermi.w(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvpermi_w_lo(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvpermi.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvpermi.w(<8 x i32> %va, <8 x i32> %vb, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvpermi_w_hi(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvpermi.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvpermi.w(<8 x i32> %va, <8 x i32> %vb, i32 256) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvpermi.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvpermi_d_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvpermi.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvpermi.d(<4 x i64> %va, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvpermi_d_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvpermi.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvpermi.d(<4 x i64> %va, i32 256) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvpermi_q_lo(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvpermi.q: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8> %va, <32 x i8> %vb, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvpermi_q_hi(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvpermi.q: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8> %va, <32 x i8> %vb, i32 256) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi-non-imm.ll +deleted file mode 100644 +index afb335c5d..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi-non-imm.ll ++++ /dev/null +@@ -1,28 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <8 x i32> @llvm.loongarch.lasx.xvpermi.w(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvpermi_w(<8 x i32> %va, <8 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvpermi.w(<8 x i32> %va, <8 x i32> %vb, i32 %c) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvpermi.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvpermi_d(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvpermi.d(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvpermi_q(<32 x i8> %va, <32 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8> %va, <32 x i8> %vb, i32 %c) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi.ll +deleted file mode 100644 +index 0d9f9daab..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-permi.ll ++++ /dev/null +@@ -1,38 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x i32> @llvm.loongarch.lasx.xvpermi.w(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvpermi_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvpermi_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpermi.w $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvpermi.w(<8 x i32> %va, <8 x i32> %vb, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvpermi.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvpermi_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvpermi_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpermi.d $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvpermi.d(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvpermi_q(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvpermi_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvpermi.q(<32 x i8> %va, <32 x i8> %vb, i32 1) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pick.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pick.ll +deleted file mode 100644 +index bbd6d693c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pick.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvpickev.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvpickev_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvpickev_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpickev.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvpickev.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvpickev.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvpickev_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvpickev_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpickev.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvpickev.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvpickev.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvpickev_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvpickev_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpickev.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvpickev.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvpickev.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvpickev_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvpickev_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpickev.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvpickev.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvpickod.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvpickod_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvpickod_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpickod.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvpickod.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvpickod.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvpickod_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvpickod_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpickod.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvpickod.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvpickod.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvpickod_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvpickod_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpickod.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvpickod.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvpickod.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvpickod_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvpickod_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpickod.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvpickod.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pickve-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pickve-invalid-imm.ll +deleted file mode 100644 +index cfc6ec428..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pickve-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <8 x i32> @llvm.loongarch.lasx.xvpickve.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvpickve_w_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvpickve.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvpickve.w(<8 x i32> %va, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvpickve_w_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvpickve.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvpickve.w(<8 x i32> %va, i32 8) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvpickve.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvpickve_d_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvpickve.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvpickve.d(<4 x i64> %va, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvpickve_d_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvpickve.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvpickve.d(<4 x i64> %va, i32 4) +- ret <4 x i64> %res +-} +- +-declare <8 x float> @llvm.loongarch.lasx.xvpickve.w.f(<8 x float>, i32) +- +-define <8 x float> @lasx_xvpickve_w_f_lo(<8 x float> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvpickve.w.f: argument out of range +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvpickve.w.f(<8 x float> %va, i32 -1) +- ret <8 x float> %res +-} +- +-define <8 x float> @lasx_xvpickve_w_f_hi(<8 x float> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvpickve.w.f: argument out of range +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvpickve.w.f(<8 x float> %va, i32 8) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvpickve.d.f(<4 x double>, i32) +- +-define <4 x double> @lasx_xvpickve_d_f_lo(<4 x double> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvpickve.d.f: argument out of range +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvpickve.d.f(<4 x double> %va, i32 -1) +- ret <4 x double> %res +-} +- +-define <4 x double> @lasx_xvpickve_d_f_hi(<4 x double> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvpickve.d.f: argument out of range +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvpickve.d.f(<4 x double> %va, i32 4) +- ret <4 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pickve-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pickve-non-imm.ll +deleted file mode 100644 +index be1f19a89..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pickve-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <8 x i32> @llvm.loongarch.lasx.xvpickve.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvpickve_w(<8 x i32> %va, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvpickve.w(<8 x i32> %va, i32 %c) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvpickve.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvpickve_d(<4 x i64> %va, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvpickve.d(<4 x i64> %va, i32 %c) +- ret <4 x i64> %res +-} +- +-declare <8 x float> @llvm.loongarch.lasx.xvpickve.w.f(<8 x float>, i32) +- +-define <8 x float> @lasx_xvpickve_w_f(<8 x float> %va, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvpickve.w.f(<8 x float> %va, i32 %c) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvpickve.d.f(<4 x double>, i32) +- +-define <4 x double> @lasx_xvpickve_d_f(<4 x double> %va, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvpickve.d.f(<4 x double> %va, i32 %c) +- ret <4 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pickve.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pickve.ll +deleted file mode 100644 +index 546777bc7..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pickve.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <8 x i32> @llvm.loongarch.lasx.xvpickve.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvpickve_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvpickve_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpickve.w $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvpickve.w(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvpickve.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvpickve_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvpickve_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpickve.d $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvpickve.d(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +- +-declare <8 x float> @llvm.loongarch.lasx.xvpickve.w.f(<8 x float>, i32) +- +-define <8 x float> @lasx_xvpickve_w_f(<8 x float> %va) nounwind { +-; CHECK-LABEL: lasx_xvpickve_w_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpickve.w $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x float> @llvm.loongarch.lasx.xvpickve.w.f(<8 x float> %va, i32 1) +- ret <8 x float> %res +-} +- +-declare <4 x double> @llvm.loongarch.lasx.xvpickve.d.f(<4 x double>, i32) +- +-define <4 x double> @lasx_xvpickve_d_f(<4 x double> %va) nounwind { +-; CHECK-LABEL: lasx_xvpickve_d_f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpickve.d $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x double> @llvm.loongarch.lasx.xvpickve.d.f(<4 x double> %va, i32 1) +- ret <4 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pickve2gr-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pickve2gr-invalid-imm.ll +deleted file mode 100644 +index 93056b272..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pickve2gr-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare i32 @llvm.loongarch.lasx.xvpickve2gr.w(<8 x i32>, i32) +- +-define i32 @lasx_xvpickve2gr_w_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvpickve2gr.w: argument out of range +-entry: +- %res = call i32 @llvm.loongarch.lasx.xvpickve2gr.w(<8 x i32> %va, i32 -1) +- ret i32 %res +-} +- +-define i32 @lasx_xvpickve2gr_w_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvpickve2gr.w: argument out of range +-entry: +- %res = call i32 @llvm.loongarch.lasx.xvpickve2gr.w(<8 x i32> %va, i32 8) +- ret i32 %res +-} +- +-declare i64 @llvm.loongarch.lasx.xvpickve2gr.d(<4 x i64>, i32) +- +-define i64 @lasx_xvpickve2gr_d_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvpickve2gr.d: argument out of range +-entry: +- %res = call i64 @llvm.loongarch.lasx.xvpickve2gr.d(<4 x i64> %va, i32 -1) +- ret i64 %res +-} +- +-define i64 @lasx_xvpickve2gr_d_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvpickve2gr.d: argument out of range +-entry: +- %res = call i64 @llvm.loongarch.lasx.xvpickve2gr.d(<4 x i64> %va, i32 4) +- ret i64 %res +-} +- +-declare i32 @llvm.loongarch.lasx.xvpickve2gr.wu(<8 x i32>, i32) +- +-define i32 @lasx_xvpickve2gr_wu_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvpickve2gr.wu: argument out of range +-entry: +- %res = call i32 @llvm.loongarch.lasx.xvpickve2gr.wu(<8 x i32> %va, i32 -1) +- ret i32 %res +-} +- +-define i32 @lasx_xvpickve2gr_wu_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvpickve2gr.wu: argument out of range +-entry: +- %res = call i32 @llvm.loongarch.lasx.xvpickve2gr.wu(<8 x i32> %va, i32 8) +- ret i32 %res +-} +- +-declare i64 @llvm.loongarch.lasx.xvpickve2gr.du(<4 x i64>, i32) +- +-define i64 @lasx_xvpickve2gr_du_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvpickve2gr.du: argument out of range +-entry: +- %res = call i64 @llvm.loongarch.lasx.xvpickve2gr.du(<4 x i64> %va, i32 -1) +- ret i64 %res +-} +- +-define i64 @lasx_xvpickve2gr_du_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvpickve2gr.du: argument out of range +-entry: +- %res = call i64 @llvm.loongarch.lasx.xvpickve2gr.du(<4 x i64> %va, i32 4) +- ret i64 %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pickve2gr-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pickve2gr-non-imm.ll +deleted file mode 100644 +index 0fa8c94ad..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pickve2gr-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare i32 @llvm.loongarch.lasx.xvpickve2gr.w(<8 x i32>, i32) +- +-define i32 @lasx_xvpickve2gr_w(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call i32 @llvm.loongarch.lasx.xvpickve2gr.w(<8 x i32> %va, i32 %b) +- ret i32 %res +-} +- +-declare i64 @llvm.loongarch.lasx.xvpickve2gr.d(<4 x i64>, i32) +- +-define i64 @lasx_xvpickve2gr_d(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call i64 @llvm.loongarch.lasx.xvpickve2gr.d(<4 x i64> %va, i32 %b) +- ret i64 %res +-} +- +-declare i32 @llvm.loongarch.lasx.xvpickve2gr.wu(<8 x i32>, i32) +- +-define i32 @lasx_xvpickve2gr_wu(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call i32 @llvm.loongarch.lasx.xvpickve2gr.wu(<8 x i32> %va, i32 %b) +- ret i32 %res +-} +- +-declare i64 @llvm.loongarch.lasx.xvpickve2gr.du(<4 x i64>, i32) +- +-define i64 @lasx_xvpickve2gr_du(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call i64 @llvm.loongarch.lasx.xvpickve2gr.du(<4 x i64> %va, i32 %b) +- ret i64 %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pickve2gr.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pickve2gr.ll +deleted file mode 100644 +index 0617e7424..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-pickve2gr.ll ++++ /dev/null +@@ -1,53 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +- +- +- +-declare i32 @llvm.loongarch.lasx.xvpickve2gr.w(<8 x i32>, i32) +- +-define i32 @lasx_xvpickve2gr_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvpickve2gr_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpickve2gr.w $a0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lasx.xvpickve2gr.w(<8 x i32> %va, i32 1) +- ret i32 %res +-} +- +-declare i64 @llvm.loongarch.lasx.xvpickve2gr.d(<4 x i64>, i32) +- +-define i64 @lasx_xvpickve2gr_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvpickve2gr_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpickve2gr.d $a0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i64 @llvm.loongarch.lasx.xvpickve2gr.d(<4 x i64> %va, i32 1) +- ret i64 %res +-} +- +-declare i32 @llvm.loongarch.lasx.xvpickve2gr.wu(<8 x i32>, i32) +- +-define i32 @lasx_xvpickve2gr_wu(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvpickve2gr_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpickve2gr.wu $a0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lasx.xvpickve2gr.wu(<8 x i32> %va, i32 1) +- ret i32 %res +-} +- +-declare i64 @llvm.loongarch.lasx.xvpickve2gr.du(<4 x i64>, i32) +- +-define i64 @lasx_xvpickve2gr_du(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvpickve2gr_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvpickve2gr.du $a0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i64 @llvm.loongarch.lasx.xvpickve2gr.du(<4 x i64> %va, i32 1) +- ret i64 %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-repl128vei-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-repl128vei-invalid-imm.ll +deleted file mode 100644 +index a0cb309c5..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-repl128vei-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvrepl128vei.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvrepl128vei_b_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvrepl128vei.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvrepl128vei.b(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvrepl128vei_b_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvrepl128vei.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvrepl128vei.b(<32 x i8> %va, i32 16) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvrepl128vei.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvrepl128vei_h_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvrepl128vei.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvrepl128vei.h(<16 x i16> %va, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvrepl128vei_h_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvrepl128vei.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvrepl128vei.h(<16 x i16> %va, i32 8) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvrepl128vei.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvrepl128vei_w_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvrepl128vei.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvrepl128vei.w(<8 x i32> %va, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvrepl128vei_w_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvrepl128vei.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvrepl128vei.w(<8 x i32> %va, i32 4) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvrepl128vei.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvrepl128vei_d_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvrepl128vei.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvrepl128vei.d(<4 x i64> %va, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvrepl128vei_d_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvrepl128vei.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvrepl128vei.d(<4 x i64> %va, i32 2) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-repl128vei-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-repl128vei-non-imm.ll +deleted file mode 100644 +index c537ffa66..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-repl128vei-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvrepl128vei.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvrepl128vei_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvrepl128vei.b(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvrepl128vei.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvrepl128vei_h(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvrepl128vei.h(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvrepl128vei.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvrepl128vei_w(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvrepl128vei.w(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvrepl128vei.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvrepl128vei_d(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvrepl128vei.d(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-repl128vei.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-repl128vei.ll +deleted file mode 100644 +index 25fab44f4..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-repl128vei.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvrepl128vei.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvrepl128vei_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvrepl128vei_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvrepl128vei.b $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvrepl128vei.b(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvrepl128vei.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvrepl128vei_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvrepl128vei_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvrepl128vei.h $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvrepl128vei.h(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvrepl128vei.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvrepl128vei_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvrepl128vei_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvrepl128vei.w $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvrepl128vei.w(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvrepl128vei.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvrepl128vei_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvrepl128vei_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvrepl128vei.d $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvrepl128vei.d(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-replgr2vr.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-replgr2vr.ll +deleted file mode 100644 +index c71abd220..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-replgr2vr.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvreplgr2vr.b(i32) +- +-define <32 x i8> @lasx_xvreplgr2vr_b(i32 %a) nounwind { +-; CHECK-LABEL: lasx_xvreplgr2vr_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvreplgr2vr.b $xr0, $a0 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvreplgr2vr.b(i32 %a) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvreplgr2vr.h(i32) +- +-define <16 x i16> @lasx_xvreplgr2vr_h(i32 %a) nounwind { +-; CHECK-LABEL: lasx_xvreplgr2vr_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvreplgr2vr.h $xr0, $a0 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvreplgr2vr.h(i32 %a) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvreplgr2vr.w(i32) +- +-define <8 x i32> @lasx_xvreplgr2vr_w(i32 %a) nounwind { +-; CHECK-LABEL: lasx_xvreplgr2vr_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvreplgr2vr.w $xr0, $a0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvreplgr2vr.w(i32 %a) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvreplgr2vr.d(i64) +- +-define <4 x i64> @lasx_xvreplgr2vr_d(i64 %a) nounwind { +-; CHECK-LABEL: lasx_xvreplgr2vr_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvreplgr2vr.d $xr0, $a0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvreplgr2vr.d(i64 %a) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-replve.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-replve.ll +deleted file mode 100644 +index 21d36ff7b..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-replve.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvreplve.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvreplve_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK-LABEL: lasx_xvreplve_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvreplve.b $xr0, $xr0, $a0 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvreplve.b(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvreplve.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvreplve_h(<16 x i16> %va, i32 %b) nounwind { +-; CHECK-LABEL: lasx_xvreplve_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvreplve.h $xr0, $xr0, $a0 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvreplve.h(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvreplve.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvreplve_w(<8 x i32> %va, i32 %b) nounwind { +-; CHECK-LABEL: lasx_xvreplve_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvreplve.w $xr0, $xr0, $a0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvreplve.w(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvreplve.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvreplve_d(<4 x i64> %va, i32 %b) nounwind { +-; CHECK-LABEL: lasx_xvreplve_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvreplve.d $xr0, $xr0, $a0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvreplve.d(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-replve0.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-replve0.ll +deleted file mode 100644 +index 7996bb36e..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-replve0.ll ++++ /dev/null +@@ -1,62 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvreplve0.b(<32 x i8>) +- +-define <32 x i8> @lasx_xvreplve0_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvreplve0_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvreplve0.b $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvreplve0.b(<32 x i8> %va) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvreplve0.h(<16 x i16>) +- +-define <16 x i16> @lasx_xvreplve0_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvreplve0_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvreplve0.h $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvreplve0.h(<16 x i16> %va) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvreplve0.w(<8 x i32>) +- +-define <8 x i32> @lasx_xvreplve0_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvreplve0_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvreplve0.w $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvreplve0.w(<8 x i32> %va) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvreplve0.d(<4 x i64>) +- +-define <4 x i64> @lasx_xvreplve0_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvreplve0_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvreplve0.d $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvreplve0.d(<4 x i64> %va) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvreplve0.q(<32 x i8>) +- +-define <32 x i8> @lasx_xvreplve0_q(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvreplve0_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvreplve0.q $xr0, $xr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvreplve0.q(<32 x i8> %va) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-rotr-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-rotr-invalid-imm.ll +deleted file mode 100644 +index 40abdf497..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-rotr-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvrotri.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvrotri_b_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvrotri.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvrotri.b(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvrotri_b_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvrotri.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvrotri.b(<32 x i8> %va, i32 8) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvrotri.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvrotri_h_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvrotri.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvrotri.h(<16 x i16> %va, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvrotri_h_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvrotri.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvrotri.h(<16 x i16> %va, i32 16) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvrotri.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvrotri_w_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvrotri.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvrotri.w(<8 x i32> %va, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvrotri_w_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvrotri.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvrotri.w(<8 x i32> %va, i32 32) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvrotri.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvrotri_d_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvrotri.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvrotri.d(<4 x i64> %va, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvrotri_d_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvrotri.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvrotri.d(<4 x i64> %va, i32 64) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-rotr-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-rotr-non-imm.ll +deleted file mode 100644 +index dd38301d0..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-rotr-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvrotri.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvrotri_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvrotri.b(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvrotri.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvrotri_h(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvrotri.h(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvrotri.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvrotri_w(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvrotri.w(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvrotri.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvrotri_d(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvrotri.d(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-rotr.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-rotr.ll +deleted file mode 100644 +index 64d277386..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-rotr.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvrotr.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvrotr_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvrotr_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvrotr.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvrotr.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvrotr.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvrotr_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvrotr_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvrotr.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvrotr.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvrotr.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvrotr_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvrotr_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvrotr.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvrotr.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvrotr.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvrotr_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvrotr_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvrotr.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvrotr.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvrotri.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvrotri_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvrotri_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvrotri.b $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvrotri.b(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvrotri.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvrotri_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvrotri_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvrotri.h $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvrotri.h(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvrotri.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvrotri_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvrotri_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvrotri.w $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvrotri.w(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvrotri.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvrotri_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvrotri_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvrotri.d $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvrotri.d(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sadd.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sadd.ll +deleted file mode 100644 +index 54a5e2e9c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sadd.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsadd.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvsadd_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsadd_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsadd.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsadd.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsadd.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvsadd_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsadd_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsadd.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsadd.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsadd.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvsadd_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsadd_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsadd.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsadd.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsadd.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvsadd_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsadd_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsadd.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsadd.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsadd.bu(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvsadd_bu(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsadd_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsadd.bu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsadd.bu(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsadd.hu(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvsadd_hu(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsadd_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsadd.hu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsadd.hu(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsadd.wu(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvsadd_wu(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsadd_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsadd.wu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsadd.wu(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsadd.du(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvsadd_du(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsadd_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsadd.du $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsadd.du(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sat-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sat-invalid-imm.ll +deleted file mode 100644 +index 839fbc999..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sat-invalid-imm.ll ++++ /dev/null +@@ -1,129 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsat.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsat_b_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsat.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsat.b(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvsat_b_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsat.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsat.b(<32 x i8> %va, i32 8) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsat.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsat_h_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsat.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsat.h(<16 x i16> %va, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvsat_h_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsat.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsat.h(<16 x i16> %va, i32 16) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsat.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsat_w_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsat.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsat.w(<8 x i32> %va, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvsat_w_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsat.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsat.w(<8 x i32> %va, i32 32) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsat.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsat_d_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsat.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsat.d(<4 x i64> %va, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvsat_d_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsat.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsat.d(<4 x i64> %va, i32 64) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsat.bu(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsat_bu_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsat.bu: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsat.bu(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvsat_bu_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsat.bu: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsat.bu(<32 x i8> %va, i32 8) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsat.hu(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsat_hu_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsat.hu: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsat.hu(<16 x i16> %va, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvsat_hu_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsat.hu: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsat.hu(<16 x i16> %va, i32 16) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsat.wu(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsat_wu_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsat.wu: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsat.wu(<8 x i32> %va, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvsat_wu_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsat.wu: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsat.wu(<8 x i32> %va, i32 32) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsat.du(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsat_du_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsat.du: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsat.du(<4 x i64> %va, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvsat_du_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsat.du: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsat.du(<4 x i64> %va, i32 64) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sat-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sat-non-imm.ll +deleted file mode 100644 +index b73b32ebd..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sat-non-imm.ll ++++ /dev/null +@@ -1,73 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsat.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsat_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsat.b(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsat.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsat_h(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsat.h(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsat.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsat_w(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsat.w(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsat.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsat_d(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsat.d(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsat.bu(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsat_bu(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsat.bu(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsat.hu(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsat_hu(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsat.hu(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsat.wu(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsat_wu(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsat.wu(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsat.du(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsat_du(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsat.du(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sat.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sat.ll +deleted file mode 100644 +index 293b9dc9e..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sat.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsat.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsat_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvsat_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsat.b $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsat.b(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsat.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsat_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvsat_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsat.h $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsat.h(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsat.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsat_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvsat_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsat.w $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsat.w(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsat.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsat_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvsat_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsat.d $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsat.d(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsat.bu(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsat_bu(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvsat_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsat.bu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsat.bu(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsat.hu(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsat_hu(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvsat_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsat.hu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsat.hu(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsat.wu(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsat_wu(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvsat_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsat.wu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsat.wu(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsat.du(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsat_du(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvsat_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsat.du $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsat.du(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-seq-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-seq-invalid-imm.ll +deleted file mode 100644 +index bb6ef0cc6..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-seq-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvseqi.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvseqi_b_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvseqi.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvseqi.b(<32 x i8> %va, i32 -17) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvseqi_b_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvseqi.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvseqi.b(<32 x i8> %va, i32 16) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvseqi.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvseqi_h_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvseqi.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvseqi.h(<16 x i16> %va, i32 -17) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvseqi_h_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvseqi.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvseqi.h(<16 x i16> %va, i32 16) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvseqi.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvseqi_w_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvseqi.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvseqi.w(<8 x i32> %va, i32 -17) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvseqi_w_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvseqi.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvseqi.w(<8 x i32> %va, i32 16) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvseqi.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvseqi_d_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvseqi.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvseqi.d(<4 x i64> %va, i32 -17) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvseqi_d_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvseqi.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvseqi.d(<4 x i64> %va, i32 16) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-seq-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-seq-non-imm.ll +deleted file mode 100644 +index fb2c6206d..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-seq-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvseqi.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvseqi_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvseqi.b(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvseqi.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvseqi_h(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvseqi.h(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvseqi.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvseqi_w(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvseqi.w(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvseqi.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvseqi_d(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvseqi.d(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-seq.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-seq.ll +deleted file mode 100644 +index 83bc93c88..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-seq.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvseq.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvseq_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvseq_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvseq.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvseq.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvseq.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvseq_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvseq_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvseq.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvseq.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvseq.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvseq_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvseq_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvseq.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvseq.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvseq.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvseq_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvseq_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvseq.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvseq.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvseqi.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvseqi_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvseqi_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvseqi.b $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvseqi.b(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvseqi.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvseqi_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvseqi_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvseqi.h $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvseqi.h(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvseqi.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvseqi_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvseqi_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvseqi.w $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvseqi.w(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvseqi.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvseqi_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvseqi_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvseqi.d $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvseqi.d(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-set.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-set.ll +deleted file mode 100644 +index 6e3e2e033..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-set.ll ++++ /dev/null +@@ -1,38 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare i32 @llvm.loongarch.lasx.xbz.v(<32 x i8>) +- +-define i32 @lasx_xbz_v(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xbz_v: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvseteqz.v $fcc0, $xr0 +-; CHECK-NEXT: bcnez $fcc0, .LBB0_2 +-; CHECK-NEXT: # %bb.1: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 0 +-; CHECK-NEXT: ret +-; CHECK-NEXT: .LBB0_2: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lasx.xbz.v(<32 x i8> %va) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lasx.xbnz.v(<32 x i8>) +- +-define i32 @lasx_xbnz_v(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xbnz_v: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsetnez.v $fcc0, $xr0 +-; CHECK-NEXT: bcnez $fcc0, .LBB1_2 +-; CHECK-NEXT: # %bb.1: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 0 +-; CHECK-NEXT: ret +-; CHECK-NEXT: .LBB1_2: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lasx.xbnz.v(<32 x i8> %va) +- ret i32 %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-setallnez.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-setallnez.ll +deleted file mode 100644 +index a466b78bf..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-setallnez.ll ++++ /dev/null +@@ -1,74 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare i32 @llvm.loongarch.lasx.xbnz.b(<32 x i8>) +- +-define i32 @lasx_xbnz_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xbnz_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsetallnez.b $fcc0, $xr0 +-; CHECK-NEXT: bcnez $fcc0, .LBB0_2 +-; CHECK-NEXT: # %bb.1: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 0 +-; CHECK-NEXT: ret +-; CHECK-NEXT: .LBB0_2: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lasx.xbnz.b(<32 x i8> %va) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lasx.xbnz.h(<16 x i16>) +- +-define i32 @lasx_xbnz_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xbnz_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsetallnez.h $fcc0, $xr0 +-; CHECK-NEXT: bcnez $fcc0, .LBB1_2 +-; CHECK-NEXT: # %bb.1: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 0 +-; CHECK-NEXT: ret +-; CHECK-NEXT: .LBB1_2: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lasx.xbnz.h(<16 x i16> %va) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lasx.xbnz.w(<8 x i32>) +- +-define i32 @lasx_xbnz_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xbnz_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsetallnez.w $fcc0, $xr0 +-; CHECK-NEXT: bcnez $fcc0, .LBB2_2 +-; CHECK-NEXT: # %bb.1: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 0 +-; CHECK-NEXT: ret +-; CHECK-NEXT: .LBB2_2: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lasx.xbnz.w(<8 x i32> %va) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lasx.xbnz.d(<4 x i64>) +- +-define i32 @lasx_xbnz_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xbnz_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsetallnez.d $fcc0, $xr0 +-; CHECK-NEXT: bcnez $fcc0, .LBB3_2 +-; CHECK-NEXT: # %bb.1: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 0 +-; CHECK-NEXT: ret +-; CHECK-NEXT: .LBB3_2: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lasx.xbnz.d(<4 x i64> %va) +- ret i32 %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-setanyeqz.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-setanyeqz.ll +deleted file mode 100644 +index 36e65fc5b..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-setanyeqz.ll ++++ /dev/null +@@ -1,74 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare i32 @llvm.loongarch.lasx.xbz.b(<32 x i8>) +- +-define i32 @lasx_xbz_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xbz_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsetanyeqz.b $fcc0, $xr0 +-; CHECK-NEXT: bcnez $fcc0, .LBB0_2 +-; CHECK-NEXT: # %bb.1: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 0 +-; CHECK-NEXT: ret +-; CHECK-NEXT: .LBB0_2: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lasx.xbz.b(<32 x i8> %va) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lasx.xbz.h(<16 x i16>) +- +-define i32 @lasx_xbz_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xbz_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsetanyeqz.h $fcc0, $xr0 +-; CHECK-NEXT: bcnez $fcc0, .LBB1_2 +-; CHECK-NEXT: # %bb.1: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 0 +-; CHECK-NEXT: ret +-; CHECK-NEXT: .LBB1_2: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lasx.xbz.h(<16 x i16> %va) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lasx.xbz.w(<8 x i32>) +- +-define i32 @lasx_xbz_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xbz_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsetanyeqz.w $fcc0, $xr0 +-; CHECK-NEXT: bcnez $fcc0, .LBB2_2 +-; CHECK-NEXT: # %bb.1: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 0 +-; CHECK-NEXT: ret +-; CHECK-NEXT: .LBB2_2: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lasx.xbz.w(<8 x i32> %va) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lasx.xbz.d(<4 x i64>) +- +-define i32 @lasx_xbz_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xbz_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsetanyeqz.d $fcc0, $xr0 +-; CHECK-NEXT: bcnez $fcc0, .LBB3_2 +-; CHECK-NEXT: # %bb.1: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 0 +-; CHECK-NEXT: ret +-; CHECK-NEXT: .LBB3_2: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lasx.xbz.d(<4 x i64> %va) +- ret i32 %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-shuf.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-shuf.ll +deleted file mode 100644 +index 9b9140f6a..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-shuf.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvshuf.b(<32 x i8>, <32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvshuf_b(<32 x i8> %va, <32 x i8> %vb, <32 x i8> %vc) nounwind { +-; CHECK-LABEL: lasx_xvshuf_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvshuf.b $xr0, $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvshuf.b(<32 x i8> %va, <32 x i8> %vb, <32 x i8> %vc) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvshuf.h(<16 x i16>, <16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvshuf_h(<16 x i16> %va, <16 x i16> %vb, <16 x i16> %vc) nounwind { +-; CHECK-LABEL: lasx_xvshuf_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvshuf.h $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvshuf.h(<16 x i16> %va, <16 x i16> %vb, <16 x i16> %vc) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvshuf.w(<8 x i32>, <8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvshuf_w(<8 x i32> %va, <8 x i32> %vb, <8 x i32> %vc) nounwind { +-; CHECK-LABEL: lasx_xvshuf_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvshuf.w $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvshuf.w(<8 x i32> %va, <8 x i32> %vb, <8 x i32> %vc) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvshuf.d(<4 x i64>, <4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvshuf_d(<4 x i64> %va, <4 x i64> %vb, <4 x i64> %vc) nounwind { +-; CHECK-LABEL: lasx_xvshuf_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvshuf.d $xr0, $xr1, $xr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvshuf.d(<4 x i64> %va, <4 x i64> %vb, <4 x i64> %vc) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-shuf4i-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-shuf4i-invalid-imm.ll +deleted file mode 100644 +index 9217d1f6a..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-shuf4i-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvshuf4i.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvshuf4i_b_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvshuf4i.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvshuf4i.b(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvshuf4i_b_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvshuf4i.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvshuf4i.b(<32 x i8> %va, i32 256) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvshuf4i.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvshuf4i_h_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvshuf4i.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvshuf4i.h(<16 x i16> %va, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvshuf4i_h_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvshuf4i.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvshuf4i.h(<16 x i16> %va, i32 256) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvshuf4i.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvshuf4i_w_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvshuf4i.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvshuf4i.w(<8 x i32> %va, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvshuf4i_w_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvshuf4i.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvshuf4i.w(<8 x i32> %va, i32 256) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvshuf4i.d(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvshuf4i_d_lo(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvshuf4i.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvshuf4i.d(<4 x i64> %va, <4 x i64> %vb, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvshuf4i_d_hi(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvshuf4i.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvshuf4i.d(<4 x i64> %va, <4 x i64> %vb, i32 256) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-shuf4i-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-shuf4i-non-imm.ll +deleted file mode 100644 +index 8d6d1c694..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-shuf4i-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvshuf4i.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvshuf4i_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvshuf4i.b(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvshuf4i.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvshuf4i_h(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvshuf4i.h(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvshuf4i.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvshuf4i_w(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvshuf4i.w(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvshuf4i.d(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvshuf4i_d(<4 x i64> %va, <4 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvshuf4i.d(<4 x i64> %va, <4 x i64> %vb, i32 %c) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-shuf4i.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-shuf4i.ll +deleted file mode 100644 +index 312050867..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-shuf4i.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvshuf4i.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvshuf4i_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvshuf4i_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvshuf4i.b $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvshuf4i.b(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvshuf4i.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvshuf4i_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvshuf4i_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvshuf4i.h $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvshuf4i.h(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvshuf4i.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvshuf4i_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvshuf4i_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvshuf4i.w $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvshuf4i.w(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvshuf4i.d(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvshuf4i_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvshuf4i_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvshuf4i.d $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvshuf4i.d(<4 x i64> %va, <4 x i64> %vb, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-signcov.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-signcov.ll +deleted file mode 100644 +index e6c6d8ccd..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-signcov.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsigncov.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvsigncov_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsigncov_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsigncov.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsigncov.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsigncov.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvsigncov_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsigncov_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsigncov.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsigncov.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsigncov.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvsigncov_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsigncov_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsigncov.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsigncov.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsigncov.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvsigncov_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsigncov_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsigncov.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsigncov.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sle-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sle-invalid-imm.ll +deleted file mode 100644 +index 5b10aca98..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sle-invalid-imm.ll ++++ /dev/null +@@ -1,129 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvslei.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvslei_b_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslei.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvslei.b(<32 x i8> %va, i32 -17) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvslei_b_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslei.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvslei.b(<32 x i8> %va, i32 16) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvslei.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvslei_h_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslei.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvslei.h(<16 x i16> %va, i32 -17) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvslei_h_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslei.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvslei.h(<16 x i16> %va, i32 16) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvslei.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvslei_w_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslei.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvslei.w(<8 x i32> %va, i32 -17) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvslei_w_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslei.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvslei.w(<8 x i32> %va, i32 16) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvslei.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvslei_d_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslei.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvslei.d(<4 x i64> %va, i32 -17) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvslei_d_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslei.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvslei.d(<4 x i64> %va, i32 16) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvslei.bu(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvslei_bu_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslei.bu: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvslei.bu(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvslei_bu_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslei.bu: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvslei.bu(<32 x i8> %va, i32 32) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvslei.hu(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvslei_hu_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslei.hu: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvslei.hu(<16 x i16> %va, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvslei_hu_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslei.hu: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvslei.hu(<16 x i16> %va, i32 32) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvslei.wu(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvslei_wu_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslei.wu: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvslei.wu(<8 x i32> %va, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvslei_wu_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslei.wu: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvslei.wu(<8 x i32> %va, i32 32) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvslei.du(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvslei_du_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslei.du: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvslei.du(<4 x i64> %va, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvslei_du_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslei.du: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvslei.du(<4 x i64> %va, i32 32) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sle-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sle-non-imm.ll +deleted file mode 100644 +index 903bc10d8..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sle-non-imm.ll ++++ /dev/null +@@ -1,73 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvslei.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvslei_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvslei.b(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvslei.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvslei_h(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvslei.h(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvslei.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvslei_w(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvslei.w(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvslei.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvslei_d(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvslei.d(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvslei.bu(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvslei_bu(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvslei.bu(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvslei.hu(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvslei_hu(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvslei.hu(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvslei.wu(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvslei_wu(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvslei.wu(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvslei.du(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvslei_du(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvslei.du(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sle.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sle.ll +deleted file mode 100644 +index 8895efc84..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sle.ll ++++ /dev/null +@@ -1,194 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsle.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvsle_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsle_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsle.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsle.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsle.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvsle_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsle_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsle.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsle.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsle.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvsle_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsle_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsle.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsle.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsle.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvsle_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsle_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsle.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsle.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvslei.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvslei_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvslei_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslei.b $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvslei.b(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvslei.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvslei_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvslei_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslei.h $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvslei.h(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvslei.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvslei_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvslei_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslei.w $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvslei.w(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvslei.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvslei_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvslei_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslei.d $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvslei.d(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsle.bu(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvsle_bu(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsle_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsle.bu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsle.bu(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsle.hu(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvsle_hu(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsle_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsle.hu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsle.hu(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsle.wu(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvsle_wu(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsle_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsle.wu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsle.wu(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsle.du(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvsle_du(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsle_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsle.du $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsle.du(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvslei.bu(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvslei_bu(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvslei_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslei.bu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvslei.bu(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvslei.hu(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvslei_hu(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvslei_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslei.hu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvslei.hu(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvslei.wu(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvslei_wu(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvslei_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslei.wu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvslei.wu(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvslei.du(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvslei_du(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvslei_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslei.du $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvslei.du(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sll-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sll-invalid-imm.ll +deleted file mode 100644 +index bf8205376..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sll-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvslli.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvslli_b_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslli.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvslli.b(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvslli_b_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslli.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvslli.b(<32 x i8> %va, i32 8) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvslli.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvslli_h_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslli.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvslli.h(<16 x i16> %va, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvslli_h_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslli.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvslli.h(<16 x i16> %va, i32 16) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvslli.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvslli_w_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslli.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvslli.w(<8 x i32> %va, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvslli_w_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslli.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvslli.w(<8 x i32> %va, i32 32) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvslli.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvslli_d_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslli.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvslli.d(<4 x i64> %va, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvslli_d_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslli.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvslli.d(<4 x i64> %va, i32 64) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sll-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sll-non-imm.ll +deleted file mode 100644 +index b5368a86b..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sll-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvslli.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvslli_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvslli.b(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvslli.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvslli_h(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvslli.h(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvslli.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvslli_w(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvslli.w(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvslli.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvslli_d(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvslli.d(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sll.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sll.ll +deleted file mode 100644 +index 14110b613..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sll.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsll.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvsll_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsll_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsll.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsll.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsll.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvsll_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsll_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsll.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsll.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsll.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvsll_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsll_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsll.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsll.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsll.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvsll_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsll_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsll.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsll.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvslli.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvslli_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvslli_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslli.b $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvslli.b(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvslli.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvslli_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvslli_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslli.h $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvslli.h(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvslli.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvslli_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvslli_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslli.w $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvslli.w(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvslli.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvslli_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvslli_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslli.d $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvslli.d(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sllwil-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sllwil-invalid-imm.ll +deleted file mode 100644 +index 18803767d..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sllwil-invalid-imm.ll ++++ /dev/null +@@ -1,97 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsllwil.h.b(<32 x i8>, i32) +- +-define <16 x i16> @lasx_xvsllwil_h_b_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsllwil.h.b: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsllwil.h.b(<32 x i8> %va, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvsllwil_h_b_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsllwil.h.b: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsllwil.h.b(<32 x i8> %va, i32 8) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsllwil.w.h(<16 x i16>, i32) +- +-define <8 x i32> @lasx_xvsllwil_w_h_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsllwil.w.h: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsllwil.w.h(<16 x i16> %va, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvsllwil_w_h_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsllwil.w.h: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsllwil.w.h(<16 x i16> %va, i32 16) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsllwil.d.w(<8 x i32>, i32) +- +-define <4 x i64> @lasx_xvsllwil_d_w_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsllwil.d.w: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsllwil.d.w(<8 x i32> %va, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvsllwil_d_w_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsllwil.d.w: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsllwil.d.w(<8 x i32> %va, i32 32) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsllwil.hu.bu(<32 x i8>, i32) +- +-define <16 x i16> @lasx_xvsllwil_hu_bu_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsllwil.hu.bu: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsllwil.hu.bu(<32 x i8> %va, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvsllwil_hu_bu_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsllwil.hu.bu: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsllwil.hu.bu(<32 x i8> %va, i32 8) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsllwil.wu.hu(<16 x i16>, i32) +- +-define <8 x i32> @lasx_xvsllwil_wu_hu_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsllwil.wu.hu: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsllwil.wu.hu(<16 x i16> %va, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvsllwil_wu_hu_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsllwil.wu.hu: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsllwil.wu.hu(<16 x i16> %va, i32 16) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsllwil.du.wu(<8 x i32>, i32) +- +-define <4 x i64> @lasx_xvsllwil_du_wu_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsllwil.du.wu: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsllwil.du.wu(<8 x i32> %va, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvsllwil_du_wu_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsllwil.du.wu: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsllwil.du.wu(<8 x i32> %va, i32 32) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sllwil-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sllwil-non-imm.ll +deleted file mode 100644 +index 3f5d4d631..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sllwil-non-imm.ll ++++ /dev/null +@@ -1,55 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsllwil.h.b(<32 x i8>, i32) +- +-define <16 x i16> @lasx_xvsllwil_h_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsllwil.h.b(<32 x i8> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsllwil.w.h(<16 x i16>, i32) +- +-define <8 x i32> @lasx_xvsllwil_w_h(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsllwil.w.h(<16 x i16> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsllwil.d.w(<8 x i32>, i32) +- +-define <4 x i64> @lasx_xvsllwil_d_w(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsllwil.d.w(<8 x i32> %va, i32 %b) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsllwil.hu.bu(<32 x i8>, i32) +- +-define <16 x i16> @lasx_xvsllwil_hu_bu(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsllwil.hu.bu(<32 x i8> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsllwil.wu.hu(<16 x i16>, i32) +- +-define <8 x i32> @lasx_xvsllwil_wu_hu(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsllwil.wu.hu(<16 x i16> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsllwil.du.wu(<8 x i32>, i32) +- +-define <4 x i64> @lasx_xvsllwil_du_wu(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsllwil.du.wu(<8 x i32> %va, i32 %b) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sllwil.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sllwil.ll +deleted file mode 100644 +index a72b8a6cb..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sllwil.ll ++++ /dev/null +@@ -1,74 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsllwil.h.b(<32 x i8>, i32) +- +-define <16 x i16> @lasx_xvsllwil_h_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvsllwil_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsllwil.h.b $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsllwil.h.b(<32 x i8> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsllwil.w.h(<16 x i16>, i32) +- +-define <8 x i32> @lasx_xvsllwil_w_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvsllwil_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsllwil.w.h $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsllwil.w.h(<16 x i16> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsllwil.d.w(<8 x i32>, i32) +- +-define <4 x i64> @lasx_xvsllwil_d_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvsllwil_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsllwil.d.w $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsllwil.d.w(<8 x i32> %va, i32 1) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsllwil.hu.bu(<32 x i8>, i32) +- +-define <16 x i16> @lasx_xvsllwil_hu_bu(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvsllwil_hu_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsllwil.hu.bu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsllwil.hu.bu(<32 x i8> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsllwil.wu.hu(<16 x i16>, i32) +- +-define <8 x i32> @lasx_xvsllwil_wu_hu(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvsllwil_wu_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsllwil.wu.hu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsllwil.wu.hu(<16 x i16> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsllwil.du.wu(<8 x i32>, i32) +- +-define <4 x i64> @lasx_xvsllwil_du_wu(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvsllwil_du_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsllwil.du.wu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsllwil.du.wu(<8 x i32> %va, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-slt-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-slt-invalid-imm.ll +deleted file mode 100644 +index dc0567da4..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-slt-invalid-imm.ll ++++ /dev/null +@@ -1,129 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvslti.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvslti_b_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslti.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvslti.b(<32 x i8> %va, i32 -17) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvslti_b_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslti.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvslti.b(<32 x i8> %va, i32 16) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvslti.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvslti_h_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslti.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvslti.h(<16 x i16> %va, i32 -17) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvslti_h_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslti.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvslti.h(<16 x i16> %va, i32 16) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvslti.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvslti_w_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslti.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvslti.w(<8 x i32> %va, i32 -17) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvslti_w_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslti.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvslti.w(<8 x i32> %va, i32 16) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvslti.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvslti_d_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslti.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvslti.d(<4 x i64> %va, i32 -17) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvslti_d_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslti.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvslti.d(<4 x i64> %va, i32 16) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvslti.bu(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvslti_bu_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslti.bu: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvslti.bu(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvslti_bu_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslti.bu: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvslti.bu(<32 x i8> %va, i32 32) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvslti.hu(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvslti_hu_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslti.hu: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvslti.hu(<16 x i16> %va, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvslti_hu_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslti.hu: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvslti.hu(<16 x i16> %va, i32 32) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvslti.wu(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvslti_wu_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslti.wu: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvslti.wu(<8 x i32> %va, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvslti_wu_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslti.wu: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvslti.wu(<8 x i32> %va, i32 32) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvslti.du(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvslti_du_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslti.du: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvslti.du(<4 x i64> %va, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvslti_du_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvslti.du: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvslti.du(<4 x i64> %va, i32 32) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-slt-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-slt-non-imm.ll +deleted file mode 100644 +index a2cedc8d3..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-slt-non-imm.ll ++++ /dev/null +@@ -1,73 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvslti.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvslti_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvslti.b(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvslti.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvslti_h(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvslti.h(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvslti.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvslti_w(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvslti.w(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvslti.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvslti_d(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvslti.d(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvslti.bu(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvslti_bu(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvslti.bu(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvslti.hu(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvslti_hu(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvslti.hu(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvslti.wu(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvslti_wu(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvslti.wu(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvslti.du(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvslti_du(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvslti.du(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-slt.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-slt.ll +deleted file mode 100644 +index 3ea87adff..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-slt.ll ++++ /dev/null +@@ -1,194 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvslt.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvslt_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvslt_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslt.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvslt.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvslt.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvslt_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvslt_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslt.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvslt.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvslt.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvslt_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvslt_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslt.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvslt.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvslt.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvslt_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvslt_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslt.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvslt.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvslti.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvslti_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvslti_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslti.b $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvslti.b(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvslti.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvslti_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvslti_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslti.h $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvslti.h(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvslti.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvslti_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvslti_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslti.w $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvslti.w(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvslti.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvslti_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvslti_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslti.d $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvslti.d(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvslt.bu(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvslt_bu(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvslt_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslt.bu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvslt.bu(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvslt.hu(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvslt_hu(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvslt_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslt.hu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvslt.hu(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvslt.wu(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvslt_wu(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvslt_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslt.wu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvslt.wu(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvslt.du(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvslt_du(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvslt_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslt.du $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvslt.du(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvslti.bu(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvslti_bu(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvslti_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslti.bu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvslti.bu(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvslti.hu(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvslti_hu(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvslti_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslti.hu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvslti.hu(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvslti.wu(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvslti_wu(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvslti_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslti.wu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvslti.wu(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvslti.du(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvslti_du(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvslti_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvslti.du $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvslti.du(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sra-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sra-invalid-imm.ll +deleted file mode 100644 +index 15b522d5e..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sra-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrai.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrai_b_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrai.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrai.b(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvsrai_b_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrai.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrai.b(<32 x i8> %va, i32 8) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrai.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrai_h_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrai.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrai.h(<16 x i16> %va, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvsrai_h_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrai.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrai.h(<16 x i16> %va, i32 16) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrai.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrai_w_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrai.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrai.w(<8 x i32> %va, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvsrai_w_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrai.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrai.w(<8 x i32> %va, i32 32) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrai.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrai_d_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrai.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrai.d(<4 x i64> %va, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvsrai_d_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrai.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrai.d(<4 x i64> %va, i32 64) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sra-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sra-non-imm.ll +deleted file mode 100644 +index fefee7246..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sra-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrai.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrai_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrai.b(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrai.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrai_h(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrai.h(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrai.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrai_w(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrai.w(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrai.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrai_d(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrai.d(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sra.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sra.ll +deleted file mode 100644 +index a74986825..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sra.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsra.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvsra_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsra_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsra.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsra.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsra.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvsra_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsra_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsra.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsra.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsra.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvsra_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsra_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsra.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsra.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsra.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvsra_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsra_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsra.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsra.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrai.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrai_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvsrai_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrai.b $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrai.b(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrai.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrai_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvsrai_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrai.h $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrai.h(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrai.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrai_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvsrai_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrai.w $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrai.w(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrai.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrai_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvsrai_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrai.d $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrai.d(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sran.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sran.ll +deleted file mode 100644 +index f59ae4c19..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sran.ll ++++ /dev/null +@@ -1,38 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsran.b.h(<16 x i16>, <16 x i16>) +- +-define <32 x i8> @lasx_xvsran_b_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsran_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsran.b.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsran.b.h(<16 x i16> %va, <16 x i16> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsran.h.w(<8 x i32>, <8 x i32>) +- +-define <16 x i16> @lasx_xvsran_h_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsran_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsran.h.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsran.h.w(<8 x i32> %va, <8 x i32> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsran.w.d(<4 x i64>, <4 x i64>) +- +-define <8 x i32> @lasx_xvsran_w_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsran_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsran.w.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsran.w.d(<4 x i64> %va, <4 x i64> %vb) +- ret <8 x i32> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srani-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srani-invalid-imm.ll +deleted file mode 100644 +index bedbfc488..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srani-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrani.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrani_b_h_lo(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrani.b.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrani.b.h(<32 x i8> %va, <32 x i8> %vb, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvsrani_b_h_hi(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrani.b.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrani.b.h(<32 x i8> %va, <32 x i8> %vb, i32 16) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrani.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrani_h_w_lo(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrani.h.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrani.h.w(<16 x i16> %va, <16 x i16> %vb, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvsrani_h_w_hi(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrani.h.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrani.h.w(<16 x i16> %va, <16 x i16> %vb, i32 32) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrani.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrani_w_d_lo(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrani.w.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrani.w.d(<8 x i32> %va, <8 x i32> %vb, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvsrani_w_d_hi(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrani.w.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrani.w.d(<8 x i32> %va, <8 x i32> %vb, i32 64) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrani.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrani_d_q_lo(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrani.d.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrani.d.q(<4 x i64> %va, <4 x i64> %vb, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvsrani_d_q_hi(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrani.d.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrani.d.q(<4 x i64> %va, <4 x i64> %vb, i32 128) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srani-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srani-non-imm.ll +deleted file mode 100644 +index 3c17f2b60..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srani-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrani.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrani_b_h(<32 x i8> %va, <32 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrani.b.h(<32 x i8> %va, <32 x i8> %vb, i32 %c) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrani.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrani_h_w(<16 x i16> %va, <16 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrani.h.w(<16 x i16> %va, <16 x i16> %vb, i32 %c) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrani.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrani_w_d(<8 x i32> %va, <8 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrani.w.d(<8 x i32> %va, <8 x i32> %vb, i32 %c) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrani.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrani_d_q(<4 x i64> %va, <4 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrani.d.q(<4 x i64> %va, <4 x i64> %vb, i32 %c) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srani.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srani.ll +deleted file mode 100644 +index 91fb90da9..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srani.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrani.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrani_b_h(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrani_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrani.b.h $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrani.b.h(<32 x i8> %va, <32 x i8> %vb, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrani.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrani_h_w(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrani_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrani.h.w $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrani.h.w(<16 x i16> %va, <16 x i16> %vb, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrani.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrani_w_d(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrani_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrani.w.d $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrani.w.d(<8 x i32> %va, <8 x i32> %vb, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrani.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrani_d_q(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrani_d_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrani.d.q $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrani.d.q(<4 x i64> %va, <4 x i64> %vb, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srar-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srar-invalid-imm.ll +deleted file mode 100644 +index e417e3cc5..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srar-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrari.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrari_b_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrari.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrari.b(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvsrari_b_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrari.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrari.b(<32 x i8> %va, i32 8) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrari.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrari_h_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrari.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrari.h(<16 x i16> %va, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvsrari_h_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrari.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrari.h(<16 x i16> %va, i32 16) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrari.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrari_w_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrari.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrari.w(<8 x i32> %va, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvsrari_w_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrari.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrari.w(<8 x i32> %va, i32 32) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrari.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrari_d_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrari.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrari.d(<4 x i64> %va, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvsrari_d_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrari.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrari.d(<4 x i64> %va, i32 64) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srar-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srar-non-imm.ll +deleted file mode 100644 +index 15fed7966..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srar-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrari.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrari_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrari.b(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrari.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrari_h(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrari.h(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrari.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrari_w(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrari.w(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrari.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrari_d(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrari.d(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srar.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srar.ll +deleted file mode 100644 +index e2c160557..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srar.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrar.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvsrar_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrar_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrar.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrar.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrar.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvsrar_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrar_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrar.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrar.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrar.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvsrar_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrar_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrar.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrar.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrar.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvsrar_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrar_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrar.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrar.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrari.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrari_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvsrari_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrari.b $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrari.b(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrari.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrari_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvsrari_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrari.h $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrari.h(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrari.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrari_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvsrari_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrari.w $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrari.w(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrari.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrari_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvsrari_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrari.d $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrari.d(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srarn.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srarn.ll +deleted file mode 100644 +index 02dd98977..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srarn.ll ++++ /dev/null +@@ -1,38 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrarn.b.h(<16 x i16>, <16 x i16>) +- +-define <32 x i8> @lasx_xvsrarn_b_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrarn_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrarn.b.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrarn.b.h(<16 x i16> %va, <16 x i16> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrarn.h.w(<8 x i32>, <8 x i32>) +- +-define <16 x i16> @lasx_xvsrarn_h_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrarn_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrarn.h.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrarn.h.w(<8 x i32> %va, <8 x i32> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrarn.w.d(<4 x i64>, <4 x i64>) +- +-define <8 x i32> @lasx_xvsrarn_w_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrarn_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrarn.w.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrarn.w.d(<4 x i64> %va, <4 x i64> %vb) +- ret <8 x i32> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srarni-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srarni-invalid-imm.ll +deleted file mode 100644 +index 83e977827..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srarni-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrarni.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrarni_b_h_lo(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrarni.b.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrarni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvsrarni_b_h_hi(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrarni.b.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrarni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 16) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrarni.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrarni_h_w_lo(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrarni.h.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrarni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvsrarni_h_w_hi(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrarni.h.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrarni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 32) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrarni.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrarni_w_d_lo(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrarni.w.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrarni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvsrarni_w_d_hi(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrarni.w.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrarni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 64) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrarni.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrarni_d_q_lo(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrarni.d.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrarni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvsrarni_d_q_hi(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrarni.d.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrarni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 128) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srarni-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srarni-non-imm.ll +deleted file mode 100644 +index eb577a29f..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srarni-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrarni.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrarni_b_h(<32 x i8> %va, <32 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrarni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 %c) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrarni.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrarni_h_w(<16 x i16> %va, <16 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrarni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 %c) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrarni.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrarni_w_d(<8 x i32> %va, <8 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrarni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 %c) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrarni.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrarni_d_q(<4 x i64> %va, <4 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrarni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 %c) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srarni.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srarni.ll +deleted file mode 100644 +index a7d2c3739..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srarni.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrarni.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrarni_b_h(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrarni_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrarni.b.h $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrarni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrarni.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrarni_h_w(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrarni_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrarni.h.w $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrarni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrarni.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrarni_w_d(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrarni_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrarni.w.d $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrarni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrarni.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrarni_d_q(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrarni_d_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrarni.d.q $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrarni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srl-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srl-invalid-imm.ll +deleted file mode 100644 +index 3ab02dcb9..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srl-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrli.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrli_b_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrli.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrli.b(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvsrli_b_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrli.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrli.b(<32 x i8> %va, i32 8) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrli.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrli_h_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrli.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrli.h(<16 x i16> %va, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvsrli_h_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrli.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrli.h(<16 x i16> %va, i32 16) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrli.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrli_w_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrli.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrli.w(<8 x i32> %va, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvsrli_w_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrli.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrli.w(<8 x i32> %va, i32 32) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrli.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrli_d_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrli.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrli.d(<4 x i64> %va, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvsrli_d_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrli.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrli.d(<4 x i64> %va, i32 64) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srl-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srl-non-imm.ll +deleted file mode 100644 +index bc085aeaa..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srl-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrli.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrli_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrli.b(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrli.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrli_h(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrli.h(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrli.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrli_w(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrli.w(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrli.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrli_d(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrli.d(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srl.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srl.ll +deleted file mode 100644 +index 7b2992f2c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srl.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrl.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvsrl_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrl_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrl.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrl.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrl.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvsrl_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrl_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrl.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrl.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrl.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvsrl_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrl_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrl.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrl.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrl.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvsrl_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrl_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrl.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrl.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrli.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrli_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvsrli_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrli.b $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrli.b(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrli.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrli_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvsrli_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrli.h $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrli.h(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrli.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrli_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvsrli_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrli.w $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrli.w(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrli.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrli_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvsrli_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrli.d $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrli.d(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srln.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srln.ll +deleted file mode 100644 +index dc5c0e016..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srln.ll ++++ /dev/null +@@ -1,38 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrln.b.h(<16 x i16>, <16 x i16>) +- +-define <32 x i8> @lasx_xvsrln_b_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrln_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrln.b.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrln.b.h(<16 x i16> %va, <16 x i16> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrln.h.w(<8 x i32>, <8 x i32>) +- +-define <16 x i16> @lasx_xvsrln_h_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrln_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrln.h.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrln.h.w(<8 x i32> %va, <8 x i32> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrln.w.d(<4 x i64>, <4 x i64>) +- +-define <8 x i32> @lasx_xvsrln_w_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrln_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrln.w.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrln.w.d(<4 x i64> %va, <4 x i64> %vb) +- ret <8 x i32> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlni-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlni-invalid-imm.ll +deleted file mode 100644 +index 9e7c94305..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlni-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrlni.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrlni_b_h_lo(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlni.b.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrlni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvsrlni_b_h_hi(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlni.b.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrlni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 16) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrlni.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrlni_h_w_lo(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlni.h.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrlni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvsrlni_h_w_hi(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlni.h.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrlni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 32) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrlni.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrlni_w_d_lo(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlni.w.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrlni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvsrlni_w_d_hi(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlni.w.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrlni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 64) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrlni.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrlni_d_q_lo(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlni.d.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrlni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvsrlni_d_q_hi(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlni.d.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrlni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 128) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlni-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlni-non-imm.ll +deleted file mode 100644 +index 66d800470..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlni-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrlni.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrlni_b_h(<32 x i8> %va, <32 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrlni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 %c) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrlni.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrlni_h_w(<16 x i16> %va, <16 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrlni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 %c) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrlni.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrlni_w_d(<8 x i32> %va, <8 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrlni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 %c) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrlni.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrlni_d_q(<4 x i64> %va, <4 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrlni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 %c) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlni.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlni.ll +deleted file mode 100644 +index 0301ebb19..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlni.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrlni.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrlni_b_h(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrlni_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrlni.b.h $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrlni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrlni.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrlni_h_w(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrlni_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrlni.h.w $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrlni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrlni.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrlni_w_d(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrlni_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrlni.w.d $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrlni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrlni.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrlni_d_q(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrlni_d_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrlni.d.q $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrlni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlr-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlr-invalid-imm.ll +deleted file mode 100644 +index 52621ddc6..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlr-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrlri.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrlri_b_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlri.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrlri.b(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvsrlri_b_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlri.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrlri.b(<32 x i8> %va, i32 8) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrlri.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrlri_h_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlri.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrlri.h(<16 x i16> %va, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvsrlri_h_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlri.h: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrlri.h(<16 x i16> %va, i32 16) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrlri.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrlri_w_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlri.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrlri.w(<8 x i32> %va, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvsrlri_w_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlri.w: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrlri.w(<8 x i32> %va, i32 32) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrlri.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrlri_d_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlri.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrlri.d(<4 x i64> %va, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvsrlri_d_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlri.d: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrlri.d(<4 x i64> %va, i32 64) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlr-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlr-non-imm.ll +deleted file mode 100644 +index 5663e3475..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlr-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrlri.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrlri_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrlri.b(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrlri.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrlri_h(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrlri.h(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrlri.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrlri_w(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrlri.w(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrlri.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrlri_d(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrlri.d(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlr.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlr.ll +deleted file mode 100644 +index e04504158..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlr.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrlr.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvsrlr_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrlr_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrlr.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrlr.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrlr.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvsrlr_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrlr_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrlr.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrlr.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrlr.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvsrlr_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrlr_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrlr.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrlr.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrlr.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvsrlr_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrlr_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrlr.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrlr.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrlri.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrlri_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvsrlri_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrlri.b $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrlri.b(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrlri.h(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrlri_h(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvsrlri_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrlri.h $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrlri.h(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrlri.w(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrlri_w(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvsrlri_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrlri.w $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrlri.w(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrlri.d(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrlri_d(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvsrlri_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrlri.d $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrlri.d(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlrn.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlrn.ll +deleted file mode 100644 +index 1e7df379c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlrn.ll ++++ /dev/null +@@ -1,38 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrlrn.b.h(<16 x i16>, <16 x i16>) +- +-define <32 x i8> @lasx_xvsrlrn_b_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrlrn_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrlrn.b.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrlrn.b.h(<16 x i16> %va, <16 x i16> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrlrn.h.w(<8 x i32>, <8 x i32>) +- +-define <16 x i16> @lasx_xvsrlrn_h_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrlrn_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrlrn.h.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrlrn.h.w(<8 x i32> %va, <8 x i32> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrlrn.w.d(<4 x i64>, <4 x i64>) +- +-define <8 x i32> @lasx_xvsrlrn_w_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrlrn_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrlrn.w.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrlrn.w.d(<4 x i64> %va, <4 x i64> %vb) +- ret <8 x i32> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlrni-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlrni-invalid-imm.ll +deleted file mode 100644 +index 2d65a75b1..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlrni-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrlrni.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrlrni_b_h_lo(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlrni.b.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrlrni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvsrlrni_b_h_hi(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlrni.b.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrlrni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 16) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrlrni.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrlrni_h_w_lo(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlrni.h.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrlrni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvsrlrni_h_w_hi(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlrni.h.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrlrni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 32) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrlrni.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrlrni_w_d_lo(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlrni.w.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrlrni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvsrlrni_w_d_hi(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlrni.w.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrlrni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 64) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrlrni.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrlrni_d_q_lo(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlrni.d.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrlrni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvsrlrni_d_q_hi(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsrlrni.d.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrlrni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 128) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlrni-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlrni-non-imm.ll +deleted file mode 100644 +index 82da0d21d..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlrni-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrlrni.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrlrni_b_h(<32 x i8> %va, <32 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrlrni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 %c) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrlrni.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrlrni_h_w(<16 x i16> %va, <16 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrlrni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 %c) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrlrni.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrlrni_w_d(<8 x i32> %va, <8 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrlrni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 %c) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrlrni.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrlrni_d_q(<4 x i64> %va, <4 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrlrni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 %c) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlrni.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlrni.ll +deleted file mode 100644 +index 56dbafe8b..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-srlrni.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsrlrni.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsrlrni_b_h(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrlrni_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrlrni.b.h $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsrlrni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsrlrni.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsrlrni_h_w(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrlrni_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrlrni.h.w $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsrlrni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsrlrni.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsrlrni_w_d(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrlrni_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrlrni.w.d $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsrlrni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsrlrni.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsrlrni_d_q(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsrlrni_d_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsrlrni.d.q $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsrlrni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssran.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssran.ll +deleted file mode 100644 +index da1857dad..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssran.ll ++++ /dev/null +@@ -1,74 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssran.b.h(<16 x i16>, <16 x i16>) +- +-define <32 x i8> @lasx_xvssran_b_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssran_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssran.b.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssran.b.h(<16 x i16> %va, <16 x i16> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssran.h.w(<8 x i32>, <8 x i32>) +- +-define <16 x i16> @lasx_xvssran_h_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssran_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssran.h.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssran.h.w(<8 x i32> %va, <8 x i32> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssran.w.d(<4 x i64>, <4 x i64>) +- +-define <8 x i32> @lasx_xvssran_w_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssran_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssran.w.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssran.w.d(<4 x i64> %va, <4 x i64> %vb) +- ret <8 x i32> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssran.bu.h(<16 x i16>, <16 x i16>) +- +-define <32 x i8> @lasx_xvssran_bu_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssran_bu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssran.bu.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssran.bu.h(<16 x i16> %va, <16 x i16> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssran.hu.w(<8 x i32>, <8 x i32>) +- +-define <16 x i16> @lasx_xvssran_hu_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssran_hu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssran.hu.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssran.hu.w(<8 x i32> %va, <8 x i32> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssran.wu.d(<4 x i64>, <4 x i64>) +- +-define <8 x i32> @lasx_xvssran_wu_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssran_wu_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssran.wu.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssran.wu.d(<4 x i64> %va, <4 x i64> %vb) +- ret <8 x i32> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrani-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrani-invalid-imm.ll +deleted file mode 100644 +index e10d5d7bd..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrani-invalid-imm.ll ++++ /dev/null +@@ -1,129 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrani.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrani_b_h_lo(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrani.b.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrani.b.h(<32 x i8> %va, <32 x i8> %vb, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvssrani_b_h_hi(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrani.b.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrani.b.h(<32 x i8> %va, <32 x i8> %vb, i32 16) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrani.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrani_h_w_lo(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrani.h.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrani.h.w(<16 x i16> %va, <16 x i16> %vb, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvssrani_h_w_hi(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrani.h.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrani.h.w(<16 x i16> %va, <16 x i16> %vb, i32 32) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrani.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrani_w_d_lo(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrani.w.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrani.w.d(<8 x i32> %va, <8 x i32> %vb, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvssrani_w_d_hi(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrani.w.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrani.w.d(<8 x i32> %va, <8 x i32> %vb, i32 64) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrani.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrani_d_q_lo(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrani.d.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrani.d.q(<4 x i64> %va, <4 x i64> %vb, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvssrani_d_q_hi(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrani.d.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrani.d.q(<4 x i64> %va, <4 x i64> %vb, i32 128) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrani.bu.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrani_bu_h_lo(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrani.bu.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrani.bu.h(<32 x i8> %va, <32 x i8> %vb, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvssrani_bu_h_hi(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrani.bu.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrani.bu.h(<32 x i8> %va, <32 x i8> %vb, i32 16) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrani.hu.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrani_hu_w_lo(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrani.hu.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrani.hu.w(<16 x i16> %va, <16 x i16> %vb, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvssrani_hu_w_hi(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrani.hu.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrani.hu.w(<16 x i16> %va, <16 x i16> %vb, i32 32) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrani.wu.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrani_wu_d_lo(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrani.wu.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrani.wu.d(<8 x i32> %va, <8 x i32> %vb, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvssrani_wu_d_hi(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrani.wu.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrani.wu.d(<8 x i32> %va, <8 x i32> %vb, i32 64) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrani.du.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrani_du_q_lo(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrani.du.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrani.du.q(<4 x i64> %va, <4 x i64> %vb, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvssrani_du_q_hi(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrani.du.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrani.du.q(<4 x i64> %va, <4 x i64> %vb, i32 128) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrani-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrani-non-imm.ll +deleted file mode 100644 +index a928cc2de..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrani-non-imm.ll ++++ /dev/null +@@ -1,73 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrani.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrani_b_h(<32 x i8> %va, <32 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrani.b.h(<32 x i8> %va, <32 x i8> %vb, i32 %c) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrani.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrani_h_w(<16 x i16> %va, <16 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrani.h.w(<16 x i16> %va, <16 x i16> %vb, i32 %c) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrani.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrani_w_d(<8 x i32> %va, <8 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrani.w.d(<8 x i32> %va, <8 x i32> %vb, i32 %c) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrani.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrani_d_q(<4 x i64> %va, <4 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrani.d.q(<4 x i64> %va, <4 x i64> %vb, i32 %c) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrani.bu.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrani_bu_h(<32 x i8> %va, <32 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrani.bu.h(<32 x i8> %va, <32 x i8> %vb, i32 %c) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrani.hu.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrani_hu_w(<16 x i16> %va, <16 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrani.hu.w(<16 x i16> %va, <16 x i16> %vb, i32 %c) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrani.wu.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrani_wu_d(<8 x i32> %va, <8 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrani.wu.d(<8 x i32> %va, <8 x i32> %vb, i32 %c) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrani.du.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrani_du_q(<4 x i64> %va, <4 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrani.du.q(<4 x i64> %va, <4 x i64> %vb, i32 %c) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrani.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrani.ll +deleted file mode 100644 +index 9efa659b4..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrani.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrani.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrani_b_h(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrani_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrani.b.h $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrani.b.h(<32 x i8> %va, <32 x i8> %vb, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrani.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrani_h_w(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrani_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrani.h.w $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrani.h.w(<16 x i16> %va, <16 x i16> %vb, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrani.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrani_w_d(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrani_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrani.w.d $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrani.w.d(<8 x i32> %va, <8 x i32> %vb, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrani.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrani_d_q(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrani_d_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrani.d.q $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrani.d.q(<4 x i64> %va, <4 x i64> %vb, i32 1) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrani.bu.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrani_bu_h(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrani_bu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrani.bu.h $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrani.bu.h(<32 x i8> %va, <32 x i8> %vb, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrani.hu.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrani_hu_w(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrani_hu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrani.hu.w $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrani.hu.w(<16 x i16> %va, <16 x i16> %vb, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrani.wu.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrani_wu_d(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrani_wu_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrani.wu.d $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrani.wu.d(<8 x i32> %va, <8 x i32> %vb, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrani.du.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrani_du_q(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrani_du_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrani.du.q $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrani.du.q(<4 x i64> %va, <4 x i64> %vb, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrarn.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrarn.ll +deleted file mode 100644 +index b5d59ff06..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrarn.ll ++++ /dev/null +@@ -1,74 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrarn.b.h(<16 x i16>, <16 x i16>) +- +-define <32 x i8> @lasx_xvssrarn_b_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrarn_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrarn.b.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrarn.b.h(<16 x i16> %va, <16 x i16> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrarn.h.w(<8 x i32>, <8 x i32>) +- +-define <16 x i16> @lasx_xvssrarn_h_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrarn_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrarn.h.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrarn.h.w(<8 x i32> %va, <8 x i32> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrarn.w.d(<4 x i64>, <4 x i64>) +- +-define <8 x i32> @lasx_xvssrarn_w_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrarn_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrarn.w.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrarn.w.d(<4 x i64> %va, <4 x i64> %vb) +- ret <8 x i32> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrarn.bu.h(<16 x i16>, <16 x i16>) +- +-define <32 x i8> @lasx_xvssrarn_bu_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrarn_bu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrarn.bu.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrarn.bu.h(<16 x i16> %va, <16 x i16> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrarn.hu.w(<8 x i32>, <8 x i32>) +- +-define <16 x i16> @lasx_xvssrarn_hu_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrarn_hu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrarn.hu.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrarn.hu.w(<8 x i32> %va, <8 x i32> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrarn.wu.d(<4 x i64>, <4 x i64>) +- +-define <8 x i32> @lasx_xvssrarn_wu_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrarn_wu_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrarn.wu.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrarn.wu.d(<4 x i64> %va, <4 x i64> %vb) +- ret <8 x i32> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrarni-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrarni-invalid-imm.ll +deleted file mode 100644 +index 42cd6ac99..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrarni-invalid-imm.ll ++++ /dev/null +@@ -1,129 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrarni.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrarni_b_h_lo(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrarni.b.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrarni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvssrarni_b_h_hi(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrarni.b.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrarni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 16) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrarni.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrarni_h_w_lo(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrarni.h.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrarni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvssrarni_h_w_hi(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrarni.h.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrarni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 32) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrarni.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrarni_w_d_lo(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrarni.w.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrarni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvssrarni_w_d_hi(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrarni.w.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrarni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 64) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrarni.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrarni_d_q_lo(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrarni.d.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrarni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvssrarni_d_q_hi(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrarni.d.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrarni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 128) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrarni.bu.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrarni_bu_h_lo(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrarni.bu.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrarni.bu.h(<32 x i8> %va, <32 x i8> %vb, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvssrarni_bu_h_hi(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrarni.bu.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrarni.bu.h(<32 x i8> %va, <32 x i8> %vb, i32 16) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrarni.hu.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrarni_hu_w_lo(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrarni.hu.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrarni.hu.w(<16 x i16> %va, <16 x i16> %vb, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvssrarni_hu_w_hi(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrarni.hu.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrarni.hu.w(<16 x i16> %va, <16 x i16> %vb, i32 32) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrarni.wu.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrarni_wu_d_lo(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrarni.wu.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrarni.wu.d(<8 x i32> %va, <8 x i32> %vb, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvssrarni_wu_d_hi(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrarni.wu.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrarni.wu.d(<8 x i32> %va, <8 x i32> %vb, i32 64) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrarni.du.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrarni_du_q_lo(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrarni.du.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrarni.du.q(<4 x i64> %va, <4 x i64> %vb, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvssrarni_du_q_hi(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrarni.du.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrarni.du.q(<4 x i64> %va, <4 x i64> %vb, i32 128) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrarni-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrarni-non-imm.ll +deleted file mode 100644 +index f050e7d79..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrarni-non-imm.ll ++++ /dev/null +@@ -1,73 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrarni.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrarni_b_h(<32 x i8> %va, <32 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrarni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 %c) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrarni.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrarni_h_w(<16 x i16> %va, <16 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrarni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 %c) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrarni.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrarni_w_d(<8 x i32> %va, <8 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrarni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 %c) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrarni.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrarni_d_q(<4 x i64> %va, <4 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrarni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 %c) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrarni.bu.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrarni_bu_h(<32 x i8> %va, <32 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrarni.bu.h(<32 x i8> %va, <32 x i8> %vb, i32 %c) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrarni.hu.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrarni_hu_w(<16 x i16> %va, <16 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrarni.hu.w(<16 x i16> %va, <16 x i16> %vb, i32 %c) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrarni.wu.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrarni_wu_d(<8 x i32> %va, <8 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrarni.wu.d(<8 x i32> %va, <8 x i32> %vb, i32 %c) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrarni.du.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrarni_du_q(<4 x i64> %va, <4 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrarni.du.q(<4 x i64> %va, <4 x i64> %vb, i32 %c) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrarni.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrarni.ll +deleted file mode 100644 +index da411dad6..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrarni.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrarni.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrarni_b_h(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrarni_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrarni.b.h $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrarni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrarni.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrarni_h_w(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrarni_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrarni.h.w $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrarni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrarni.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrarni_w_d(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrarni_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrarni.w.d $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrarni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrarni.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrarni_d_q(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrarni_d_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrarni.d.q $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrarni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 1) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrarni.bu.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrarni_bu_h(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrarni_bu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrarni.bu.h $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrarni.bu.h(<32 x i8> %va, <32 x i8> %vb, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrarni.hu.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrarni_hu_w(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrarni_hu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrarni.hu.w $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrarni.hu.w(<16 x i16> %va, <16 x i16> %vb, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrarni.wu.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrarni_wu_d(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrarni_wu_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrarni.wu.d $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrarni.wu.d(<8 x i32> %va, <8 x i32> %vb, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrarni.du.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrarni_du_q(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrarni_du_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrarni.du.q $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrarni.du.q(<4 x i64> %va, <4 x i64> %vb, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrln.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrln.ll +deleted file mode 100644 +index c60b5bdf8..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrln.ll ++++ /dev/null +@@ -1,74 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrln.b.h(<16 x i16>, <16 x i16>) +- +-define <32 x i8> @lasx_xvssrln_b_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrln_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrln.b.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrln.b.h(<16 x i16> %va, <16 x i16> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrln.h.w(<8 x i32>, <8 x i32>) +- +-define <16 x i16> @lasx_xvssrln_h_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrln_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrln.h.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrln.h.w(<8 x i32> %va, <8 x i32> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrln.w.d(<4 x i64>, <4 x i64>) +- +-define <8 x i32> @lasx_xvssrln_w_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrln_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrln.w.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrln.w.d(<4 x i64> %va, <4 x i64> %vb) +- ret <8 x i32> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrln.bu.h(<16 x i16>, <16 x i16>) +- +-define <32 x i8> @lasx_xvssrln_bu_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrln_bu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrln.bu.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrln.bu.h(<16 x i16> %va, <16 x i16> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrln.hu.w(<8 x i32>, <8 x i32>) +- +-define <16 x i16> @lasx_xvssrln_hu_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrln_hu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrln.hu.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrln.hu.w(<8 x i32> %va, <8 x i32> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrln.wu.d(<4 x i64>, <4 x i64>) +- +-define <8 x i32> @lasx_xvssrln_wu_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrln_wu_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrln.wu.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrln.wu.d(<4 x i64> %va, <4 x i64> %vb) +- ret <8 x i32> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrlni-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrlni-invalid-imm.ll +deleted file mode 100644 +index 26be21a83..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrlni-invalid-imm.ll ++++ /dev/null +@@ -1,129 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrlni.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrlni_b_h_lo(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlni.b.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrlni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvssrlni_b_h_hi(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlni.b.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrlni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 16) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrlni.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrlni_h_w_lo(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlni.h.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrlni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvssrlni_h_w_hi(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlni.h.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrlni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 32) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrlni.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrlni_w_d_lo(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlni.w.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrlni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvssrlni_w_d_hi(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlni.w.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrlni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 64) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrlni.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrlni_d_q_lo(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlni.d.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrlni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvssrlni_d_q_hi(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlni.d.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrlni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 128) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrlni.bu.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrlni_bu_h_lo(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlni.bu.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrlni.bu.h(<32 x i8> %va, <32 x i8> %vb, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvssrlni_bu_h_hi(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlni.bu.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrlni.bu.h(<32 x i8> %va, <32 x i8> %vb, i32 16) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrlni.hu.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrlni_hu_w_lo(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlni.hu.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrlni.hu.w(<16 x i16> %va, <16 x i16> %vb, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvssrlni_hu_w_hi(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlni.hu.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrlni.hu.w(<16 x i16> %va, <16 x i16> %vb, i32 32) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrlni.wu.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrlni_wu_d_lo(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlni.wu.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrlni.wu.d(<8 x i32> %va, <8 x i32> %vb, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvssrlni_wu_d_hi(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlni.wu.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrlni.wu.d(<8 x i32> %va, <8 x i32> %vb, i32 64) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrlni.du.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrlni_du_q_lo(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlni.du.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrlni.du.q(<4 x i64> %va, <4 x i64> %vb, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvssrlni_du_q_hi(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlni.du.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrlni.du.q(<4 x i64> %va, <4 x i64> %vb, i32 128) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrlni-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrlni-non-imm.ll +deleted file mode 100644 +index 72da2a746..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrlni-non-imm.ll ++++ /dev/null +@@ -1,73 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrlni.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrlni_b_h(<32 x i8> %va, <32 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrlni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 %c) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrlni.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrlni_h_w(<16 x i16> %va, <16 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrlni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 %c) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrlni.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrlni_w_d(<8 x i32> %va, <8 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrlni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 %c) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrlni.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrlni_d_q(<4 x i64> %va, <4 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrlni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 %c) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrlni.bu.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrlni_bu_h(<32 x i8> %va, <32 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrlni.bu.h(<32 x i8> %va, <32 x i8> %vb, i32 %c) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrlni.hu.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrlni_hu_w(<16 x i16> %va, <16 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrlni.hu.w(<16 x i16> %va, <16 x i16> %vb, i32 %c) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrlni.wu.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrlni_wu_d(<8 x i32> %va, <8 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrlni.wu.d(<8 x i32> %va, <8 x i32> %vb, i32 %c) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrlni.du.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrlni_du_q(<4 x i64> %va, <4 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrlni.du.q(<4 x i64> %va, <4 x i64> %vb, i32 %c) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrlni.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrlni.ll +deleted file mode 100644 +index e57dd426b..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrlni.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrlni.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrlni_b_h(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrlni_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrlni.b.h $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrlni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrlni.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrlni_h_w(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrlni_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrlni.h.w $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrlni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrlni.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrlni_w_d(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrlni_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrlni.w.d $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrlni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrlni.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrlni_d_q(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrlni_d_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrlni.d.q $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrlni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 1) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrlni.bu.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrlni_bu_h(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrlni_bu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrlni.bu.h $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrlni.bu.h(<32 x i8> %va, <32 x i8> %vb, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrlni.hu.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrlni_hu_w(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrlni_hu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrlni.hu.w $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrlni.hu.w(<16 x i16> %va, <16 x i16> %vb, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrlni.wu.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrlni_wu_d(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrlni_wu_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrlni.wu.d $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrlni.wu.d(<8 x i32> %va, <8 x i32> %vb, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrlni.du.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrlni_du_q(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrlni_du_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrlni.du.q $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrlni.du.q(<4 x i64> %va, <4 x i64> %vb, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrlrn.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrlrn.ll +deleted file mode 100644 +index 774cf1bd5..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrlrn.ll ++++ /dev/null +@@ -1,74 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrlrn.b.h(<16 x i16>, <16 x i16>) +- +-define <32 x i8> @lasx_xvssrlrn_b_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrlrn_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrlrn.b.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrlrn.b.h(<16 x i16> %va, <16 x i16> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrlrn.h.w(<8 x i32>, <8 x i32>) +- +-define <16 x i16> @lasx_xvssrlrn_h_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrlrn_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrlrn.h.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrlrn.h.w(<8 x i32> %va, <8 x i32> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrlrn.w.d(<4 x i64>, <4 x i64>) +- +-define <8 x i32> @lasx_xvssrlrn_w_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrlrn_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrlrn.w.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrlrn.w.d(<4 x i64> %va, <4 x i64> %vb) +- ret <8 x i32> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrlrn.bu.h(<16 x i16>, <16 x i16>) +- +-define <32 x i8> @lasx_xvssrlrn_bu_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrlrn_bu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrlrn.bu.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrlrn.bu.h(<16 x i16> %va, <16 x i16> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrlrn.hu.w(<8 x i32>, <8 x i32>) +- +-define <16 x i16> @lasx_xvssrlrn_hu_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrlrn_hu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrlrn.hu.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrlrn.hu.w(<8 x i32> %va, <8 x i32> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrlrn.wu.d(<4 x i64>, <4 x i64>) +- +-define <8 x i32> @lasx_xvssrlrn_wu_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrlrn_wu_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrlrn.wu.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrlrn.wu.d(<4 x i64> %va, <4 x i64> %vb) +- ret <8 x i32> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrlrni-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrlrni-invalid-imm.ll +deleted file mode 100644 +index cd778e2c0..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrlrni-invalid-imm.ll ++++ /dev/null +@@ -1,129 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrlrni.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrlrni_b_h_lo(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlrni.b.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrlrni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvssrlrni_b_h_hi(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlrni.b.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrlrni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 16) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrlrni.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrlrni_h_w_lo(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlrni.h.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrlrni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvssrlrni_h_w_hi(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlrni.h.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrlrni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 32) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrlrni.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrlrni_w_d_lo(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlrni.w.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrlrni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvssrlrni_w_d_hi(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlrni.w.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrlrni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 64) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrlrni.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrlrni_d_q_lo(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlrni.d.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrlrni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvssrlrni_d_q_hi(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlrni.d.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrlrni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 128) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrlrni.bu.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrlrni_bu_h_lo(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlrni.bu.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrlrni.bu.h(<32 x i8> %va, <32 x i8> %vb, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvssrlrni_bu_h_hi(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlrni.bu.h: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrlrni.bu.h(<32 x i8> %va, <32 x i8> %vb, i32 16) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrlrni.hu.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrlrni_hu_w_lo(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlrni.hu.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrlrni.hu.w(<16 x i16> %va, <16 x i16> %vb, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvssrlrni_hu_w_hi(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlrni.hu.w: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrlrni.hu.w(<16 x i16> %va, <16 x i16> %vb, i32 32) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrlrni.wu.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrlrni_wu_d_lo(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlrni.wu.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrlrni.wu.d(<8 x i32> %va, <8 x i32> %vb, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvssrlrni_wu_d_hi(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlrni.wu.d: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrlrni.wu.d(<8 x i32> %va, <8 x i32> %vb, i32 64) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrlrni.du.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrlrni_du_q_lo(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlrni.du.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrlrni.du.q(<4 x i64> %va, <4 x i64> %vb, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvssrlrni_du_q_hi(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lasx.xvssrlrni.du.q: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrlrni.du.q(<4 x i64> %va, <4 x i64> %vb, i32 128) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrlrni-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrlrni-non-imm.ll +deleted file mode 100644 +index a10c54329..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrlrni-non-imm.ll ++++ /dev/null +@@ -1,73 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrlrni.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrlrni_b_h(<32 x i8> %va, <32 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrlrni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 %c) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrlrni.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrlrni_h_w(<16 x i16> %va, <16 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrlrni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 %c) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrlrni.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrlrni_w_d(<8 x i32> %va, <8 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrlrni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 %c) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrlrni.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrlrni_d_q(<4 x i64> %va, <4 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrlrni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 %c) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrlrni.bu.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrlrni_bu_h(<32 x i8> %va, <32 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrlrni.bu.h(<32 x i8> %va, <32 x i8> %vb, i32 %c) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrlrni.hu.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrlrni_hu_w(<16 x i16> %va, <16 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrlrni.hu.w(<16 x i16> %va, <16 x i16> %vb, i32 %c) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrlrni.wu.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrlrni_wu_d(<8 x i32> %va, <8 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrlrni.wu.d(<8 x i32> %va, <8 x i32> %vb, i32 %c) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrlrni.du.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrlrni_du_q(<4 x i64> %va, <4 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrlrni.du.q(<4 x i64> %va, <4 x i64> %vb, i32 %c) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrlrni.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrlrni.ll +deleted file mode 100644 +index 9a80516d8..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssrlrni.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrlrni.b.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrlrni_b_h(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrlrni_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrlrni.b.h $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrlrni.b.h(<32 x i8> %va, <32 x i8> %vb, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrlrni.h.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrlrni_h_w(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrlrni_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrlrni.h.w $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrlrni.h.w(<16 x i16> %va, <16 x i16> %vb, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrlrni.w.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrlrni_w_d(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrlrni_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrlrni.w.d $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrlrni.w.d(<8 x i32> %va, <8 x i32> %vb, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrlrni.d.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrlrni_d_q(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrlrni_d_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrlrni.d.q $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrlrni.d.q(<4 x i64> %va, <4 x i64> %vb, i32 1) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssrlrni.bu.h(<32 x i8>, <32 x i8>, i32) +- +-define <32 x i8> @lasx_xvssrlrni_bu_h(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrlrni_bu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrlrni.bu.h $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssrlrni.bu.h(<32 x i8> %va, <32 x i8> %vb, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssrlrni.hu.w(<16 x i16>, <16 x i16>, i32) +- +-define <16 x i16> @lasx_xvssrlrni_hu_w(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrlrni_hu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrlrni.hu.w $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssrlrni.hu.w(<16 x i16> %va, <16 x i16> %vb, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssrlrni.wu.d(<8 x i32>, <8 x i32>, i32) +- +-define <8 x i32> @lasx_xvssrlrni_wu_d(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrlrni_wu_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrlrni.wu.d $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssrlrni.wu.d(<8 x i32> %va, <8 x i32> %vb, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssrlrni.du.q(<4 x i64>, <4 x i64>, i32) +- +-define <4 x i64> @lasx_xvssrlrni_du_q(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssrlrni_du_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssrlrni.du.q $xr0, $xr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssrlrni.du.q(<4 x i64> %va, <4 x i64> %vb, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssub.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssub.ll +deleted file mode 100644 +index cd3ccd9f5..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-ssub.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssub.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvssub_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssub_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssub.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssub.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssub.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvssub_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssub_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssub.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssub.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssub.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvssub_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssub_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssub.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssub.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssub.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvssub_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssub_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssub.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssub.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <32 x i8> @llvm.loongarch.lasx.xvssub.bu(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvssub_bu(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssub_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssub.bu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvssub.bu(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvssub.hu(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvssub_hu(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssub_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssub.hu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvssub.hu(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvssub.wu(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvssub_wu(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssub_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssub.wu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvssub.wu(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvssub.du(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvssub_du(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvssub_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvssub.du $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvssub.du(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-st-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-st-invalid-imm.ll +deleted file mode 100644 +index 0177f2b77..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-st-invalid-imm.ll ++++ /dev/null +@@ -1,17 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare void @llvm.loongarch.lasx.xvst(<32 x i8>, i8*, i32) +- +-define void @lasx_xvst_lo(<32 x i8> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvst: argument out of range +-entry: +- call void @llvm.loongarch.lasx.xvst(<32 x i8> %va, i8* %p, i32 -2049) +- ret void +-} +- +-define void @lasx_xvst_hi(<32 x i8> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvst: argument out of range +-entry: +- call void @llvm.loongarch.lasx.xvst(<32 x i8> %va, i8* %p, i32 2048) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-st-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-st-non-imm.ll +deleted file mode 100644 +index c19207aad..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-st-non-imm.ll ++++ /dev/null +@@ -1,10 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare void @llvm.loongarch.lasx.xvst(<32 x i8>, i8*, i32) +- +-define void @lasx_xvst(<32 x i8> %va, i8* %p, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.lasx.xvst(<32 x i8> %va, i8* %p, i32 %b) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-st.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-st.ll +deleted file mode 100644 +index b69e7b813..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-st.ll ++++ /dev/null +@@ -1,27 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare void @llvm.loongarch.lasx.xvst(<32 x i8>, i8*, i32) +- +-define void @lasx_xvst(<32 x i8> %va, i8* %p) nounwind { +-; CHECK-LABEL: lasx_xvst: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvst $xr0, $a0, 1 +-; CHECK-NEXT: ret +-entry: +- call void @llvm.loongarch.lasx.xvst(<32 x i8> %va, i8* %p, i32 1) +- ret void +-} +- +-declare void @llvm.loongarch.lasx.xvstx(<32 x i8>, i8*, i64) +- +-define void @lasx_xvstx(<32 x i8> %va, i8* %p) nounwind { +-; CHECK-LABEL: lasx_xvstx: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: ori $a1, $zero, 1 +-; CHECK-NEXT: xvstx $xr0, $a0, $a1 +-; CHECK-NEXT: ret +-entry: +- call void @llvm.loongarch.lasx.xvstx(<32 x i8> %va, i8* %p, i64 1) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-stelm-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-stelm-invalid-imm.ll +deleted file mode 100644 +index 0ea2484e0..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-stelm-invalid-imm.ll ++++ /dev/null +@@ -1,121 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare void @llvm.loongarch.lasx.xvstelm.b(<32 x i8>, i8*, i32, i32) +- +-define void @lasx_xvstelm_b_lo(<32 x i8> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvstelm.b: argument out of range +-entry: +- call void @llvm.loongarch.lasx.xvstelm.b(<32 x i8> %va, i8* %p, i32 -129, i32 1) +- ret void +-} +- +-define void @lasx_xvstelm_b_hi(<32 x i8> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvstelm.b: argument out of range +-entry: +- call void @llvm.loongarch.lasx.xvstelm.b(<32 x i8> %va, i8* %p, i32 128, i32 1) +- ret void +-} +- +-define void @lasx_xvstelm_b_idx_lo(<32 x i8> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvstelm.b: argument out of range +-entry: +- call void @llvm.loongarch.lasx.xvstelm.b(<32 x i8> %va, i8* %p, i32 1, i32 -1) +- ret void +-} +- +-define void @lasx_xvstelm_b_idx_hi(<32 x i8> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvstelm.b: argument out of range +-entry: +- call void @llvm.loongarch.lasx.xvstelm.b(<32 x i8> %va, i8* %p, i32 1, i32 32) +- ret void +-} +- +-declare void @llvm.loongarch.lasx.xvstelm.h(<16 x i16>, i8*, i32, i32) +- +-define void @lasx_xvstelm_h_lo(<16 x i16> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvstelm.h: argument out of range or not a multiple of 2. +-entry: +- call void @llvm.loongarch.lasx.xvstelm.h(<16 x i16> %va, i8* %p, i32 -258, i32 1) +- ret void +-} +- +-define void @lasx_xvstelm_h_hi(<16 x i16> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvstelm.h: argument out of range or not a multiple of 2. +-entry: +- call void @llvm.loongarch.lasx.xvstelm.h(<16 x i16> %va, i8* %p, i32 256, i32 1) +- ret void +-} +- +-define void @lasx_xvstelm_h_idx_lo(<16 x i16> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvstelm.h: argument out of range or not a multiple of 2. +-entry: +- call void @llvm.loongarch.lasx.xvstelm.h(<16 x i16> %va, i8* %p, i32 2, i32 -1) +- ret void +-} +- +-define void @lasx_xvstelm_h_idx_hi(<16 x i16> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvstelm.h: argument out of range or not a multiple of 2. +-entry: +- call void @llvm.loongarch.lasx.xvstelm.h(<16 x i16> %va, i8* %p, i32 2, i32 16) +- ret void +-} +- +-declare void @llvm.loongarch.lasx.xvstelm.w(<8 x i32>, i8*, i32, i32) +- +-define void @lasx_xvstelm_w_lo(<8 x i32> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvstelm.w: argument out of range or not a multiple of 4. +-entry: +- call void @llvm.loongarch.lasx.xvstelm.w(<8 x i32> %va, i8* %p, i32 -516, i32 1) +- ret void +-} +- +-define void @lasx_xvstelm_w_hi(<8 x i32> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvstelm.w: argument out of range or not a multiple of 4. +-entry: +- call void @llvm.loongarch.lasx.xvstelm.w(<8 x i32> %va, i8* %p, i32 512, i32 1) +- ret void +-} +- +-define void @lasx_xvstelm_w_idx_lo(<8 x i32> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvstelm.w: argument out of range or not a multiple of 4. +-entry: +- call void @llvm.loongarch.lasx.xvstelm.w(<8 x i32> %va, i8* %p, i32 4, i32 -1) +- ret void +-} +- +-define void @lasx_xvstelm_w_idx_hi(<8 x i32> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvstelm.w: argument out of range or not a multiple of 4. +-entry: +- call void @llvm.loongarch.lasx.xvstelm.w(<8 x i32> %va, i8* %p, i32 4, i32 8) +- ret void +-} +- +-declare void @llvm.loongarch.lasx.xvstelm.d(<4 x i64>, i8*, i32, i32) +- +-define void @lasx_xvstelm_d_lo(<4 x i64> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvstelm.d: argument out of range or not a multiple of 8. +-entry: +- call void @llvm.loongarch.lasx.xvstelm.d(<4 x i64> %va, i8* %p, i32 -1032, i32 1) +- ret void +-} +- +-define void @lasx_xvstelm_d_hi(<4 x i64> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvstelm.d: argument out of range or not a multiple of 8. +-entry: +- call void @llvm.loongarch.lasx.xvstelm.d(<4 x i64> %va, i8* %p, i32 1024, i32 1) +- ret void +-} +- +-define void @lasx_xvstelm_d_idx_lo(<4 x i64> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvstelm.d: argument out of range or not a multiple of 8. +-entry: +- call void @llvm.loongarch.lasx.xvstelm.d(<4 x i64> %va, i8* %p, i32 8, i32 -1) +- ret void +-} +- +-define void @lasx_xvstelm_d_idx_hi(<4 x i64> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lasx.xvstelm.d: argument out of range or not a multiple of 8. +-entry: +- call void @llvm.loongarch.lasx.xvstelm.d(<4 x i64> %va, i8* %p, i32 8, i32 4) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-stelm-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-stelm-non-imm.ll +deleted file mode 100644 +index 42c7c0da1..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-stelm-non-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare void @llvm.loongarch.lasx.xvstelm.b(<32 x i8>, i8*, i32, i32) +- +-define void @lasx_xvstelm_b(<32 x i8> %va, i8* %p, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.lasx.xvstelm.b(<32 x i8> %va, i8* %p, i32 %b, i32 1) +- ret void +-} +- +-define void @lasx_xvstelm_b_idx(<32 x i8> %va, i8* %p, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.lasx.xvstelm.b(<32 x i8> %va, i8* %p, i32 1, i32 %b) +- ret void +-} +- +-declare void @llvm.loongarch.lasx.xvstelm.h(<16 x i16>, i8*, i32, i32) +- +-define void @lasx_xvstelm_h(<16 x i16> %va, i8* %p, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.lasx.xvstelm.h(<16 x i16> %va, i8* %p, i32 %b, i32 1) +- ret void +-} +- +-define void @lasx_xvstelm_h_idx(<16 x i16> %va, i8* %p, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.lasx.xvstelm.h(<16 x i16> %va, i8* %p, i32 2, i32 %b) +- ret void +-} +- +-declare void @llvm.loongarch.lasx.xvstelm.w(<8 x i32>, i8*, i32, i32) +- +-define void @lasx_xvstelm_w(<8 x i32> %va, i8* %p, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.lasx.xvstelm.w(<8 x i32> %va, i8* %p, i32 %b, i32 1) +- ret void +-} +- +-define void @lasx_xvstelm_w_idx(<8 x i32> %va, i8* %p, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.lasx.xvstelm.w(<8 x i32> %va, i8* %p, i32 4, i32 %b) +- ret void +-} +- +-declare void @llvm.loongarch.lasx.xvstelm.d(<4 x i64>, i8*, i32, i32) +- +-define void @lasx_xvstelm_d(<4 x i64> %va, i8* %p, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.lasx.xvstelm.d(<4 x i64> %va, i8* %p, i32 %b, i32 1) +- ret void +-} +- +-define void @lasx_xvstelm_d_idx(<4 x i64> %va, i8* %p, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.lasx.xvstelm.d(<4 x i64> %va, i8* %p, i32 8, i32 %b) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-stelm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-stelm.ll +deleted file mode 100644 +index 52ef3c471..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-stelm.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare void @llvm.loongarch.lasx.xvstelm.b(<32 x i8>, i8*, i32, i32) +- +-define void @lasx_xvstelm_b(<32 x i8> %va, i8* %p) nounwind { +-; CHECK-LABEL: lasx_xvstelm_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvstelm.b $xr0, $a0, 1, 1 +-; CHECK-NEXT: ret +-entry: +- call void @llvm.loongarch.lasx.xvstelm.b(<32 x i8> %va, i8* %p, i32 1, i32 1) +- ret void +-} +- +-declare void @llvm.loongarch.lasx.xvstelm.h(<16 x i16>, i8*, i32, i32) +- +-define void @lasx_xvstelm_h(<16 x i16> %va, i8* %p) nounwind { +-; CHECK-LABEL: lasx_xvstelm_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvstelm.h $xr0, $a0, 2, 1 +-; CHECK-NEXT: ret +-entry: +- call void @llvm.loongarch.lasx.xvstelm.h(<16 x i16> %va, i8* %p, i32 2, i32 1) +- ret void +-} +- +-declare void @llvm.loongarch.lasx.xvstelm.w(<8 x i32>, i8*, i32, i32) +- +-define void @lasx_xvstelm_w(<8 x i32> %va, i8* %p) nounwind { +-; CHECK-LABEL: lasx_xvstelm_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvstelm.w $xr0, $a0, 4, 1 +-; CHECK-NEXT: ret +-entry: +- call void @llvm.loongarch.lasx.xvstelm.w(<8 x i32> %va, i8* %p, i32 4, i32 1) +- ret void +-} +- +-declare void @llvm.loongarch.lasx.xvstelm.d(<4 x i64>, i8*, i32, i32) +- +-define void @lasx_xvstelm_d(<4 x i64> %va, i8* %p) nounwind { +-; CHECK-LABEL: lasx_xvstelm_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvstelm.d $xr0, $a0, 8, 1 +-; CHECK-NEXT: ret +-entry: +- call void @llvm.loongarch.lasx.xvstelm.d(<4 x i64> %va, i8* %p, i32 8, i32 1) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sub.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sub.ll +deleted file mode 100644 +index 4d69dd83d..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-sub.ll ++++ /dev/null +@@ -1,62 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsub.b(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvsub_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsub_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsub.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsub.b(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsub.h(<16 x i16>, <16 x i16>) +- +-define <16 x i16> @lasx_xvsub_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsub_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsub.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsub.h(<16 x i16> %va, <16 x i16> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsub.w(<8 x i32>, <8 x i32>) +- +-define <8 x i32> @lasx_xvsub_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsub_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsub.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsub.w(<8 x i32> %va, <8 x i32> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsub.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvsub_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsub_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsub.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsub.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsub.q(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvsub_q(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsub_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsub.q $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsub.q(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-subi-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-subi-invalid-imm.ll +deleted file mode 100644 +index 810008c17..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-subi-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsubi.bu(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsubi_bu_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsubi.bu: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsubi.bu(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvsubi_bu_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsubi.bu: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsubi.bu(<32 x i8> %va, i32 32) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsubi.hu(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsubi_hu_lo(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsubi.hu: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsubi.hu(<16 x i16> %va, i32 -1) +- ret <16 x i16> %res +-} +- +-define <16 x i16> @lasx_xvsubi_hu_hi(<16 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsubi.hu: argument out of range +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsubi.hu(<16 x i16> %va, i32 32) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsubi.wu(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsubi_wu_lo(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsubi.wu: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsubi.wu(<8 x i32> %va, i32 -1) +- ret <8 x i32> %res +-} +- +-define <8 x i32> @lasx_xvsubi_wu_hi(<8 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsubi.wu: argument out of range +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsubi.wu(<8 x i32> %va, i32 32) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsubi.du(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsubi_du_lo(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsubi.du: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsubi.du(<4 x i64> %va, i32 -1) +- ret <4 x i64> %res +-} +- +-define <4 x i64> @lasx_xvsubi_du_hi(<4 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvsubi.du: argument out of range +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsubi.du(<4 x i64> %va, i32 32) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-subi-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-subi-non-imm.ll +deleted file mode 100644 +index 924b89ce9..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-subi-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsubi.bu(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsubi_bu(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsubi.bu(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsubi.hu(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsubi_hu(<16 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsubi.hu(<16 x i16> %va, i32 %b) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsubi.wu(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsubi_wu(<8 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsubi.wu(<8 x i32> %va, i32 %b) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsubi.du(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsubi_du(<4 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsubi.du(<4 x i64> %va, i32 %b) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-subi.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-subi.ll +deleted file mode 100644 +index cc3235ff4..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-subi.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvsubi.bu(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvsubi_bu(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvsubi_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsubi.bu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvsubi.bu(<32 x i8> %va, i32 1) +- ret <32 x i8> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsubi.hu(<16 x i16>, i32) +- +-define <16 x i16> @lasx_xvsubi_hu(<16 x i16> %va) nounwind { +-; CHECK-LABEL: lasx_xvsubi_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsubi.hu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsubi.hu(<16 x i16> %va, i32 1) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsubi.wu(<8 x i32>, i32) +- +-define <8 x i32> @lasx_xvsubi_wu(<8 x i32> %va) nounwind { +-; CHECK-LABEL: lasx_xvsubi_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsubi.wu $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsubi.wu(<8 x i32> %va, i32 1) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsubi.du(<4 x i64>, i32) +- +-define <4 x i64> @lasx_xvsubi_du(<4 x i64> %va) nounwind { +-; CHECK-LABEL: lasx_xvsubi_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsubi.du $xr0, $xr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsubi.du(<4 x i64> %va, i32 1) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-subw.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-subw.ll +deleted file mode 100644 +index 6f203e894..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-subw.ll ++++ /dev/null +@@ -1,194 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsubwev.h.b(<32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvsubwev_h_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsubwev_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsubwev.h.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsubwev.h.b(<32 x i8> %va, <32 x i8> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsubwev.w.h(<16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvsubwev_w_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsubwev_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsubwev.w.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsubwev.w.h(<16 x i16> %va, <16 x i16> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsubwev.d.w(<8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvsubwev_d_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsubwev_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsubwev.d.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsubwev.d.w(<8 x i32> %va, <8 x i32> %vb) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsubwev.q.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvsubwev_q_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsubwev_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsubwev.q.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsubwev.q.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsubwev.h.bu(<32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvsubwev_h_bu(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsubwev_h_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsubwev.h.bu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsubwev.h.bu(<32 x i8> %va, <32 x i8> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsubwev.w.hu(<16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvsubwev_w_hu(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsubwev_w_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsubwev.w.hu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsubwev.w.hu(<16 x i16> %va, <16 x i16> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsubwev.d.wu(<8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvsubwev_d_wu(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsubwev_d_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsubwev.d.wu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsubwev.d.wu(<8 x i32> %va, <8 x i32> %vb) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsubwev.q.du(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvsubwev_q_du(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsubwev_q_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsubwev.q.du $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsubwev.q.du(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsubwod.h.b(<32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvsubwod_h_b(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsubwod_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsubwod.h.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsubwod.h.b(<32 x i8> %va, <32 x i8> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsubwod.w.h(<16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvsubwod_w_h(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsubwod_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsubwod.w.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsubwod.w.h(<16 x i16> %va, <16 x i16> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsubwod.d.w(<8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvsubwod_d_w(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsubwod_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsubwod.d.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsubwod.d.w(<8 x i32> %va, <8 x i32> %vb) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsubwod.q.d(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvsubwod_q_d(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsubwod_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsubwod.q.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsubwod.q.d(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +- +-declare <16 x i16> @llvm.loongarch.lasx.xvsubwod.h.bu(<32 x i8>, <32 x i8>) +- +-define <16 x i16> @lasx_xvsubwod_h_bu(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsubwod_h_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsubwod.h.bu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvsubwod.h.bu(<32 x i8> %va, <32 x i8> %vb) +- ret <16 x i16> %res +-} +- +-declare <8 x i32> @llvm.loongarch.lasx.xvsubwod.w.hu(<16 x i16>, <16 x i16>) +- +-define <8 x i32> @lasx_xvsubwod_w_hu(<16 x i16> %va, <16 x i16> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsubwod_w_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsubwod.w.hu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i32> @llvm.loongarch.lasx.xvsubwod.w.hu(<16 x i16> %va, <16 x i16> %vb) +- ret <8 x i32> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsubwod.d.wu(<8 x i32>, <8 x i32>) +- +-define <4 x i64> @lasx_xvsubwod_d_wu(<8 x i32> %va, <8 x i32> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsubwod_d_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsubwod.d.wu $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsubwod.d.wu(<8 x i32> %va, <8 x i32> %vb) +- ret <4 x i64> %res +-} +- +-declare <4 x i64> @llvm.loongarch.lasx.xvsubwod.q.du(<4 x i64>, <4 x i64>) +- +-define <4 x i64> @lasx_xvsubwod_q_du(<4 x i64> %va, <4 x i64> %vb) nounwind { +-; CHECK-LABEL: lasx_xvsubwod_q_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvsubwod.q.du $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i64> @llvm.loongarch.lasx.xvsubwod.q.du(<4 x i64> %va, <4 x i64> %vb) +- ret <4 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-xor.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-xor.ll +deleted file mode 100644 +index 6395b3d6f..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-xor.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvxor.v(<32 x i8>, <32 x i8>) +- +-define <32 x i8> @lasx_xvxor_v(<32 x i8> %va, <32 x i8> %vb) nounwind { +-; CHECK-LABEL: lasx_xvxor_v: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvxor.v $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvxor.v(<32 x i8> %va, <32 x i8> %vb) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-xori-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-xori-invalid-imm.ll +deleted file mode 100644 +index 0170d204c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-xori-invalid-imm.ll ++++ /dev/null +@@ -1,17 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvxori.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvxori_b_lo(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvxori.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvxori.b(<32 x i8> %va, i32 -1) +- ret <32 x i8> %res +-} +- +-define <32 x i8> @lasx_xvxori_b_hi(<32 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lasx.xvxori.b: argument out of range +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvxori.b(<32 x i8> %va, i32 256) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-xori-non-imm.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-xori-non-imm.ll +deleted file mode 100644 +index 1478f691a..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-xori-non-imm.ll ++++ /dev/null +@@ -1,10 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lasx < %s 2>&1 | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvxori.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvxori_b(<32 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvxori.b(<32 x i8> %va, i32 %b) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-xori.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-xori.ll +deleted file mode 100644 +index c71d7e731..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-xori.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-declare <32 x i8> @llvm.loongarch.lasx.xvxori.b(<32 x i8>, i32) +- +-define <32 x i8> @lasx_xvxori_b(<32 x i8> %va) nounwind { +-; CHECK-LABEL: lasx_xvxori_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvxori.b $xr0, $xr0, 3 +-; CHECK-NEXT: ret +-entry: +- %res = call <32 x i8> @llvm.loongarch.lasx.xvxori.b(<32 x i8> %va, i32 3) +- ret <32 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-xvldrepl.ll b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-xvldrepl.ll +new file mode 100644 +index 000000000..4b0d3be46 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lasx/intrinsic-xvldrepl.ll +@@ -0,0 +1,68 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc --mtriple=loongarch64-linux-gnu --mattr=+lasx --relocation-model=pic \ ++; RUN: < %s | FileCheck %s ++ ++@.str.5 = private unnamed_addr constant [12 x i8] c"lasx-xvld.c\00", align 1 ++ ++declare void @check_lasx_out(i8* nocapture readonly %expected, i8* nocapture readonly %got, i32 signext %len, i8* %fname, i32 signext %line) ++declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) ++declare signext i32 @memcmp(i8* nocapture, i8* nocapture, i64) ++declare signext i32 @printf(i8* nocapture readonly, ...) ++declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) ++ ++define signext i32 @main() nounwind { ++; CHECK-LABEL: main: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: addi.d $sp, $sp, -128 ++; CHECK-NEXT: st.d $ra, $sp, 120 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r22, $sp, 112 # 8-byte Folded Spill ++; CHECK-NEXT: addi.d $r22, $sp, 128 ++; CHECK-NEXT: addi.d $r4, $zero, -32 ++; CHECK-NEXT: and $sp, $sp, $r4 ++; CHECK-NEXT: la.pcrel $r4, .LCPI0_0 ++; CHECK-NEXT: # la expanded slot ++; CHECK-NEXT: xvld $xr0, $r4, 0 ++; CHECK-NEXT: xvst $xr0, $sp, 0 ++; CHECK-NEXT: lu12i.w $r4, -338129 ++; CHECK-NEXT: ori $r4, $r4, 3819 ++; CHECK-NEXT: lu32i.d $r4, 86693 ++; CHECK-NEXT: lu52i.d $r4, $r4, 173 ++; CHECK-NEXT: xvreplgr2vr.d $xr0, $r4 ++; CHECK-NEXT: xvst $xr0, $sp, 32 ++; CHECK-NEXT: xvldrepl.d $xr0, $sp, 0 ++; CHECK-NEXT: xvst $xr0, $sp, 64 ++; CHECK-NEXT: addi.d $r4, $sp, 32 ++; CHECK-NEXT: addi.d $r5, $sp, 64 ++; CHECK-NEXT: addi.d $r6, $zero, 32 ++; CHECK-NEXT: la.pcrel $r7, .L.str.5 ++; CHECK-NEXT: # la expanded slot ++; CHECK-NEXT: addi.d $r8, $zero, 59 ++; CHECK-NEXT: bl check_lasx_out ++; CHECK-NEXT: addi.d $r4, $zero, 0 ++; CHECK-NEXT: addi.d $sp, $r22, -128 ++; CHECK-NEXT: ld.d $r22, $sp, 112 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 120 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 128 ++; CHECK-NEXT: jr $ra ++entry: ++ %__m256i_out = alloca <4 x i64>, align 32 ++ %__m256i_result = alloca <4 x i64>, align 32 ++ %v4u64_op0 = alloca <4 x i64>, align 32 ++ %0 = bitcast <4 x i64>* %__m256i_out to i8* ++ call void @llvm.lifetime.start.p0i8(i64 32, i8* nonnull %0) ++ %1 = bitcast <4 x i64>* %__m256i_result to i8* ++ call void @llvm.lifetime.start.p0i8(i64 32, i8* nonnull %1) ++ %2 = bitcast <4 x i64>* %v4u64_op0 to i8* ++ call void @llvm.lifetime.start.p0i8(i64 32, i8* nonnull %2) ++ store <4 x i64> , <4 x i64>* %v4u64_op0, align 32 ++ store <4 x i64> , <4 x i64>* %__m256i_result, align 32 ++ %3 = call <4 x i64> @llvm.loongarch.lasx.xvldrepl.d(i8* nonnull %2, i32 0) ++ store <4 x i64> %3, <4 x i64>* %__m256i_out, align 32 ++ call void @check_lasx_out(i8* nonnull %1, i8* nonnull %0, i32 signext 32, i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str.5, i64 0, i64 0), i32 signext 59) ++ call void @llvm.lifetime.end.p0i8(i64 32, i8* nonnull %2) ++ call void @llvm.lifetime.end.p0i8(i64 32, i8* nonnull %1) ++ call void @llvm.lifetime.end.p0i8(i64 32, i8* nonnull %0) ++ ret i32 0 ++} ++ ++declare <4 x i64> @llvm.loongarch.lasx.xvldrepl.d(i8*, i32) +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/add.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/add.ll +deleted file mode 100644 +index 8e4d0dc6f..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/add.ll ++++ /dev/null +@@ -1,122 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @add_v32i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: add_v32i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvadd.b $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %v2 = add <32 x i8> %v0, %v1 +- store <32 x i8> %v2, ptr %res +- ret void +-} +- +-define void @add_v16i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: add_v16i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvadd.h $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %v2 = add <16 x i16> %v0, %v1 +- store <16 x i16> %v2, ptr %res +- ret void +-} +- +-define void @add_v8i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: add_v8i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvadd.w $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %v2 = add <8 x i32> %v0, %v1 +- store <8 x i32> %v2, ptr %res +- ret void +-} +- +-define void @add_v4i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: add_v4i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvadd.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %v2 = add <4 x i64> %v0, %v1 +- store <4 x i64> %v2, ptr %res +- ret void +-} +- +-define void @add_v32i8_31(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: add_v32i8_31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvaddi.bu $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = add <32 x i8> %v0, +- store <32 x i8> %v1, ptr %res +- ret void +-} +- +-define void @add_v16i16_31(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: add_v16i16_31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvaddi.hu $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = add <16 x i16> %v0, +- store <16 x i16> %v1, ptr %res +- ret void +-} +- +-define void @add_v8i32_31(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: add_v8i32_31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvaddi.wu $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = add <8 x i32> %v0, +- store <8 x i32> %v1, ptr %res +- ret void +-} +- +-define void @add_v4i64_31(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: add_v4i64_31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvaddi.du $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = add <4 x i64> %v0, +- store <4 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/and.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/and.ll +deleted file mode 100644 +index 98c87cade..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/and.ll ++++ /dev/null +@@ -1,125 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @and_v32i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: and_v32i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvand.v $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %v2 = and <32 x i8> %v0, %v1 +- store <32 x i8> %v2, ptr %res +- ret void +-} +- +-define void @and_v16i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: and_v16i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvand.v $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %v2 = and <16 x i16> %v0, %v1 +- store <16 x i16> %v2, ptr %res +- ret void +-} +- +-define void @and_v8i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: and_v8i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvand.v $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %v2 = and <8 x i32> %v0, %v1 +- store <8 x i32> %v2, ptr %res +- ret void +-} +- +-define void @and_v4i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: and_v4i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvand.v $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %v2 = and <4 x i64> %v0, %v1 +- store <4 x i64> %v2, ptr %res +- ret void +-} +- +-define void @and_u_v32i8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: and_u_v32i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvandi.b $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = and <32 x i8> %v0, +- store <32 x i8> %v1, ptr %res +- ret void +-} +- +-define void @and_u_v16i16(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: and_u_v16i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvrepli.h $xr1, 31 +-; CHECK-NEXT: xvand.v $xr0, $xr0, $xr1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = and <16 x i16> %v0, +- store <16 x i16> %v1, ptr %res +- ret void +-} +- +-define void @and_u_v8i32(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: and_u_v8i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvrepli.w $xr1, 31 +-; CHECK-NEXT: xvand.v $xr0, $xr0, $xr1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = and <8 x i32> %v0, +- store <8 x i32> %v1, ptr %res +- ret void +-} +- +-define void @and_u_v4i64(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: and_u_v4i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvrepli.d $xr1, 31 +-; CHECK-NEXT: xvand.v $xr0, $xr0, $xr1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = and <4 x i64> %v0, +- store <4 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/ashr.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/ashr.ll +deleted file mode 100644 +index fcbf0f140..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/ashr.ll ++++ /dev/null +@@ -1,178 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @ashr_v32i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: ashr_v32i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsra.b $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %v2 = ashr <32 x i8> %v0, %v1 +- store <32 x i8> %v2, ptr %res +- ret void +-} +- +-define void @ashr_v16i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: ashr_v16i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsra.h $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %v2 = ashr <16 x i16> %v0, %v1 +- store <16 x i16> %v2, ptr %res +- ret void +-} +- +-define void @ashr_v8i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: ashr_v8i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsra.w $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %v2 = ashr <8 x i32> %v0, %v1 +- store <8 x i32> %v2, ptr %res +- ret void +-} +- +-define void @ashr_v4i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: ashr_v4i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsra.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %v2 = ashr <4 x i64> %v0, %v1 +- store <4 x i64> %v2, ptr %res +- ret void +-} +- +-define void @ashr_v32i8_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: ashr_v32i8_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrai.b $xr0, $xr0, 1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = ashr <32 x i8> %v0, +- store <32 x i8> %v1, ptr %res +- ret void +-} +- +-define void @ashr_v32i8_7(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: ashr_v32i8_7: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrai.b $xr0, $xr0, 7 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = ashr <32 x i8> %v0, +- store <32 x i8> %v1, ptr %res +- ret void +-} +- +-define void @ashr_v16i16_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: ashr_v16i16_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrai.h $xr0, $xr0, 1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = ashr <16 x i16> %v0, +- store <16 x i16> %v1, ptr %res +- ret void +-} +- +-define void @ashr_v16i16_15(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: ashr_v16i16_15: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrai.h $xr0, $xr0, 15 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = ashr <16 x i16> %v0, +- store <16 x i16> %v1, ptr %res +- ret void +-} +- +-define void @ashr_v8i32_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: ashr_v8i32_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrai.w $xr0, $xr0, 1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = ashr <8 x i32> %v0, +- store <8 x i32> %v1, ptr %res +- ret void +-} +- +-define void @ashr_v8i32_31(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: ashr_v8i32_31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrai.w $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = ashr <8 x i32> %v0, +- store <8 x i32> %v1, ptr %res +- ret void +-} +- +-define void @ashr_v4i64_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: ashr_v4i64_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrai.d $xr0, $xr0, 1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = ashr <4 x i64> %v0, +- store <4 x i64> %v1, ptr %res +- ret void +-} +- +-define void @ashr_v4i64_63(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: ashr_v4i64_63: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrai.d $xr0, $xr0, 63 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = ashr <4 x i64> %v0, +- store <4 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/extractelement.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/extractelement.ll +deleted file mode 100644 +index fc2929d8e..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/extractelement.ll ++++ /dev/null +@@ -1,232 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @extract_32xi8(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: extract_32xi8: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: vpickve2gr.b $a0, $vr0, 1 +-; CHECK-NEXT: st.b $a0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <32 x i8>, ptr %src +- %e = extractelement <32 x i8> %v, i32 1 +- store i8 %e, ptr %dst +- ret void +-} +- +-define void @extract_16xi16(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: extract_16xi16: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 1 +-; CHECK-NEXT: st.h $a0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <16 x i16>, ptr %src +- %e = extractelement <16 x i16> %v, i32 1 +- store i16 %e, ptr %dst +- ret void +-} +- +-define void @extract_8xi32(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: extract_8xi32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvpickve2gr.w $a0, $xr0, 1 +-; CHECK-NEXT: st.w $a0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <8 x i32>, ptr %src +- %e = extractelement <8 x i32> %v, i32 1 +- store i32 %e, ptr %dst +- ret void +-} +- +-define void @extract_4xi64(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: extract_4xi64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvpickve2gr.d $a0, $xr0, 1 +-; CHECK-NEXT: st.d $a0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <4 x i64>, ptr %src +- %e = extractelement <4 x i64> %v, i32 1 +- store i64 %e, ptr %dst +- ret void +-} +- +-define void @extract_8xfloat(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: extract_8xfloat: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvpickve2gr.w $a0, $xr0, 7 +-; CHECK-NEXT: movgr2fr.w $fa0, $a0 +-; CHECK-NEXT: fst.s $fa0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <8 x float>, ptr %src +- %e = extractelement <8 x float> %v, i32 7 +- store float %e, ptr %dst +- ret void +-} +- +-define void @extract_4xdouble(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: extract_4xdouble: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvpickve2gr.d $a0, $xr0, 3 +-; CHECK-NEXT: movgr2fr.d $fa0, $a0 +-; CHECK-NEXT: fst.d $fa0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <4 x double>, ptr %src +- %e = extractelement <4 x double> %v, i32 3 +- store double %e, ptr %dst +- ret void +-} +- +-define void @extract_32xi8_idx(ptr %src, ptr %dst, i32 %idx) nounwind { +-; CHECK-LABEL: extract_32xi8_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -64 +-; CHECK-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $fp, $sp, 48 # 8-byte Folded Spill +-; CHECK-NEXT: addi.d $fp, $sp, 64 +-; CHECK-NEXT: bstrins.d $sp, $zero, 4, 0 +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvst $xr0, $sp, 0 +-; CHECK-NEXT: addi.d $a0, $sp, 0 +-; CHECK-NEXT: bstrins.d $a0, $a2, 4, 0 +-; CHECK-NEXT: ld.b $a0, $a0, 0 +-; CHECK-NEXT: st.b $a0, $a1, 0 +-; CHECK-NEXT: addi.d $sp, $fp, -64 +-; CHECK-NEXT: ld.d $fp, $sp, 48 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 64 +-; CHECK-NEXT: ret +- %v = load volatile <32 x i8>, ptr %src +- %e = extractelement <32 x i8> %v, i32 %idx +- store i8 %e, ptr %dst +- ret void +-} +- +-define void @extract_16xi16_idx(ptr %src, ptr %dst, i32 %idx) nounwind { +-; CHECK-LABEL: extract_16xi16_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -64 +-; CHECK-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $fp, $sp, 48 # 8-byte Folded Spill +-; CHECK-NEXT: addi.d $fp, $sp, 64 +-; CHECK-NEXT: bstrins.d $sp, $zero, 4, 0 +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvst $xr0, $sp, 0 +-; CHECK-NEXT: addi.d $a0, $sp, 0 +-; CHECK-NEXT: bstrins.d $a0, $a2, 4, 1 +-; CHECK-NEXT: ld.h $a0, $a0, 0 +-; CHECK-NEXT: st.h $a0, $a1, 0 +-; CHECK-NEXT: addi.d $sp, $fp, -64 +-; CHECK-NEXT: ld.d $fp, $sp, 48 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 64 +-; CHECK-NEXT: ret +- %v = load volatile <16 x i16>, ptr %src +- %e = extractelement <16 x i16> %v, i32 %idx +- store i16 %e, ptr %dst +- ret void +-} +- +-define void @extract_8xi32_idx(ptr %src, ptr %dst, i32 %idx) nounwind { +-; CHECK-LABEL: extract_8xi32_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -64 +-; CHECK-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $fp, $sp, 48 # 8-byte Folded Spill +-; CHECK-NEXT: addi.d $fp, $sp, 64 +-; CHECK-NEXT: bstrins.d $sp, $zero, 4, 0 +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvst $xr0, $sp, 0 +-; CHECK-NEXT: addi.d $a0, $sp, 0 +-; CHECK-NEXT: bstrins.d $a0, $a2, 4, 2 +-; CHECK-NEXT: ld.w $a0, $a0, 0 +-; CHECK-NEXT: st.w $a0, $a1, 0 +-; CHECK-NEXT: addi.d $sp, $fp, -64 +-; CHECK-NEXT: ld.d $fp, $sp, 48 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 64 +-; CHECK-NEXT: ret +- %v = load volatile <8 x i32>, ptr %src +- %e = extractelement <8 x i32> %v, i32 %idx +- store i32 %e, ptr %dst +- ret void +-} +- +-define void @extract_4xi64_idx(ptr %src, ptr %dst, i32 %idx) nounwind { +-; CHECK-LABEL: extract_4xi64_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -64 +-; CHECK-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $fp, $sp, 48 # 8-byte Folded Spill +-; CHECK-NEXT: addi.d $fp, $sp, 64 +-; CHECK-NEXT: bstrins.d $sp, $zero, 4, 0 +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvst $xr0, $sp, 0 +-; CHECK-NEXT: addi.d $a0, $sp, 0 +-; CHECK-NEXT: bstrins.d $a0, $a2, 4, 3 +-; CHECK-NEXT: ld.d $a0, $a0, 0 +-; CHECK-NEXT: st.d $a0, $a1, 0 +-; CHECK-NEXT: addi.d $sp, $fp, -64 +-; CHECK-NEXT: ld.d $fp, $sp, 48 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 64 +-; CHECK-NEXT: ret +- %v = load volatile <4 x i64>, ptr %src +- %e = extractelement <4 x i64> %v, i32 %idx +- store i64 %e, ptr %dst +- ret void +-} +- +-define void @extract_8xfloat_idx(ptr %src, ptr %dst, i32 %idx) nounwind { +-; CHECK-LABEL: extract_8xfloat_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -64 +-; CHECK-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $fp, $sp, 48 # 8-byte Folded Spill +-; CHECK-NEXT: addi.d $fp, $sp, 64 +-; CHECK-NEXT: bstrins.d $sp, $zero, 4, 0 +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvst $xr0, $sp, 0 +-; CHECK-NEXT: addi.d $a0, $sp, 0 +-; CHECK-NEXT: bstrins.d $a0, $a2, 4, 2 +-; CHECK-NEXT: fld.s $fa0, $a0, 0 +-; CHECK-NEXT: fst.s $fa0, $a1, 0 +-; CHECK-NEXT: addi.d $sp, $fp, -64 +-; CHECK-NEXT: ld.d $fp, $sp, 48 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 64 +-; CHECK-NEXT: ret +- %v = load volatile <8 x float>, ptr %src +- %e = extractelement <8 x float> %v, i32 %idx +- store float %e, ptr %dst +- ret void +-} +- +-define void @extract_4xdouble_idx(ptr %src, ptr %dst, i32 %idx) nounwind { +-; CHECK-LABEL: extract_4xdouble_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -64 +-; CHECK-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $fp, $sp, 48 # 8-byte Folded Spill +-; CHECK-NEXT: addi.d $fp, $sp, 64 +-; CHECK-NEXT: bstrins.d $sp, $zero, 4, 0 +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvst $xr0, $sp, 0 +-; CHECK-NEXT: addi.d $a0, $sp, 0 +-; CHECK-NEXT: bstrins.d $a0, $a2, 4, 3 +-; CHECK-NEXT: fld.d $fa0, $a0, 0 +-; CHECK-NEXT: fst.d $fa0, $a1, 0 +-; CHECK-NEXT: addi.d $sp, $fp, -64 +-; CHECK-NEXT: ld.d $fp, $sp, 48 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 64 +-; CHECK-NEXT: ret +- %v = load volatile <4 x double>, ptr %src +- %e = extractelement <4 x double> %v, i32 %idx +- store double %e, ptr %dst +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fadd.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fadd.ll +deleted file mode 100644 +index 365bb305f..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fadd.ll ++++ /dev/null +@@ -1,34 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @fadd_v8f32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: fadd_v8f32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfadd.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = fadd <8 x float> %v0, %v1 +- store <8 x float> %v2, ptr %res +- ret void +-} +- +-define void @fadd_v4f64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: fadd_v4f64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfadd.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = fadd <4 x double> %v0, %v1 +- store <4 x double> %v2, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fcmp.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fcmp.ll +deleted file mode 100644 +index ef67dbc10..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fcmp.ll ++++ /dev/null +@@ -1,692 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-;; TREU +-define void @v8f32_fcmp_true(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8f32_fcmp_true: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvrepli.b $xr0, -1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %cmp = fcmp true <8 x float> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-;; FALSE +-define void @v4f64_fcmp_false(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f64_fcmp_false: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvrepli.b $xr0, 0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %cmp = fcmp false <4 x double> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETOEQ +-define void @v8f32_fcmp_oeq(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8f32_fcmp_oeq: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.ceq.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %cmp = fcmp oeq <8 x float> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4f64_fcmp_oeq(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f64_fcmp_oeq: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.ceq.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %cmp = fcmp oeq <4 x double> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETUEQ +-define void @v8f32_fcmp_ueq(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8f32_fcmp_ueq: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.cueq.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %cmp = fcmp ueq <8 x float> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4f64_fcmp_ueq(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f64_fcmp_ueq: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.cueq.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %cmp = fcmp ueq <4 x double> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETEQ +-define void @v8f32_fcmp_eq(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8f32_fcmp_eq: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.ceq.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %cmp = fcmp fast oeq <8 x float> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4f64_fcmp_eq(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f64_fcmp_eq: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.ceq.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %cmp = fcmp fast ueq <4 x double> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETOLE +-define void @v8f32_fcmp_ole(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8f32_fcmp_ole: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.cle.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %cmp = fcmp ole <8 x float> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4f64_fcmp_ole(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f64_fcmp_ole: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.cle.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %cmp = fcmp ole <4 x double> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETULE +-define void @v8f32_fcmp_ule(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8f32_fcmp_ule: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.cule.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %cmp = fcmp ule <8 x float> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4f64_fcmp_ule(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f64_fcmp_ule: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.cule.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %cmp = fcmp ule <4 x double> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETLE +-define void @v8f32_fcmp_le(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8f32_fcmp_le: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.cle.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %cmp = fcmp fast ole <8 x float> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4f64_fcmp_le(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f64_fcmp_le: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.cle.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %cmp = fcmp fast ule <4 x double> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETOLT +-define void @v8f32_fcmp_olt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8f32_fcmp_olt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.clt.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %cmp = fcmp olt <8 x float> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4f64_fcmp_olt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f64_fcmp_olt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.clt.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %cmp = fcmp olt <4 x double> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETULT +-define void @v8f32_fcmp_ult(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8f32_fcmp_ult: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.cult.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %cmp = fcmp ult <8 x float> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4f64_fcmp_ult(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f64_fcmp_ult: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.cult.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %cmp = fcmp ult <4 x double> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETLT +-define void @v8f32_fcmp_lt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8f32_fcmp_lt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.clt.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %cmp = fcmp fast olt <8 x float> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4f64_fcmp_lt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f64_fcmp_lt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.clt.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %cmp = fcmp fast ult <4 x double> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETONE +-define void @v8f32_fcmp_one(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8f32_fcmp_one: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.cne.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %cmp = fcmp one <8 x float> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4f64_fcmp_one(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f64_fcmp_one: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.cne.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %cmp = fcmp one <4 x double> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETUNE +-define void @v8f32_fcmp_une(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8f32_fcmp_une: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.cune.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %cmp = fcmp une <8 x float> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4f64_fcmp_une(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f64_fcmp_une: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.cune.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %cmp = fcmp une <4 x double> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETNE +-define void @v8f32_fcmp_ne(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8f32_fcmp_ne: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.cne.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %cmp = fcmp fast one <8 x float> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4f64_fcmp_ne(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f64_fcmp_ne: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.cne.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %cmp = fcmp fast une <4 x double> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETO +-define void @v8f32_fcmp_ord(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8f32_fcmp_ord: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.cor.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %cmp = fcmp ord <8 x float> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4f64_fcmp_ord(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f64_fcmp_ord: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.cor.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %cmp = fcmp ord <4 x double> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETUO +-define void @v8f32_fcmp_uno(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8f32_fcmp_uno: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.cun.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %cmp = fcmp uno <8 x float> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4f64_fcmp_uno(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f64_fcmp_uno: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfcmp.cun.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %cmp = fcmp uno <4 x double> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; Expand SETOGT +-define void @v8f32_fcmp_ogt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8f32_fcmp_ogt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvfcmp.clt.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %cmp = fcmp ogt <8 x float> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4f64_fcmp_ogt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f64_fcmp_ogt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvfcmp.clt.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %cmp = fcmp ogt <4 x double> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; Expand SETUGT +-define void @v8f32_fcmp_ugt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8f32_fcmp_ugt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvfcmp.cult.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %cmp = fcmp ugt <8 x float> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4f64_fcmp_ugt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f64_fcmp_ugt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvfcmp.cult.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %cmp = fcmp ugt <4 x double> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; Expand SETGT +-define void @v8f32_fcmp_gt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8f32_fcmp_gt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvfcmp.clt.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %cmp = fcmp fast ogt <8 x float> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4f64_fcmp_gt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f64_fcmp_gt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvfcmp.clt.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %cmp = fcmp fast ugt <4 x double> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; Expand SETOGE +-define void @v8f32_fcmp_oge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8f32_fcmp_oge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvfcmp.cle.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %cmp = fcmp oge <8 x float> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4f64_fcmp_oge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f64_fcmp_oge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvfcmp.cle.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %cmp = fcmp oge <4 x double> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; Expand SETUGE +-define void @v8f32_fcmp_uge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8f32_fcmp_uge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvfcmp.cule.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %cmp = fcmp uge <8 x float> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4f64_fcmp_uge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f64_fcmp_uge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvfcmp.cule.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %cmp = fcmp uge <4 x double> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; Expand SETGE +-define void @v8f32_fcmp_ge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8f32_fcmp_ge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvfcmp.cle.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %cmp = fcmp fast oge <8 x float> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4f64_fcmp_ge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f64_fcmp_ge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvfcmp.cle.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %cmp = fcmp fast uge <4 x double> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fdiv.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fdiv.ll +deleted file mode 100644 +index 6004565b0..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fdiv.ll ++++ /dev/null +@@ -1,63 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @fdiv_v8f32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: fdiv_v8f32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfdiv.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = fdiv <8 x float> %v0, %v1 +- store <8 x float> %v2, ptr %res +- ret void +-} +- +-define void @fdiv_v4f64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: fdiv_v4f64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfdiv.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = fdiv <4 x double> %v0, %v1 +- store <4 x double> %v2, ptr %res +- ret void +-} +- +-;; 1.0 / vec +-define void @one_fdiv_v8f32(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: one_fdiv_v8f32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvfrecip.s $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %div = fdiv <8 x float> , %v0 +- store <8 x float> %div, ptr %res +- ret void +-} +- +-define void @one_fdiv_v4f64(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: one_fdiv_v4f64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvfrecip.d $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %div = fdiv <4 x double> , %v0 +- store <4 x double> %div, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fmul.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fmul.ll +deleted file mode 100644 +index a48dca8d2..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fmul.ll ++++ /dev/null +@@ -1,34 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @fmul_v8f32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: fmul_v8f32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfmul.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = fmul <8 x float> %v0, %v1 +- store <8 x float> %v2, ptr %res +- ret void +-} +- +-define void @fmul_v4f64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: fmul_v4f64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfmul.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = fmul <4 x double> %v0, %v1 +- store <4 x double> %v2, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fneg.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fneg.ll +deleted file mode 100644 +index 5eb468fc5..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fneg.ll ++++ /dev/null +@@ -1,29 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @fneg_v8f32(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: fneg_v8f32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvbitrevi.w $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = fneg <8 x float> %v0 +- store <8 x float> %v1, ptr %res +- ret void +-} +-define void @fneg_v4f64(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: fneg_v4f64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvbitrevi.d $xr0, $xr0, 63 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = fneg <4 x double> %v0 +- store <4 x double> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptosi.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptosi.ll +deleted file mode 100644 +index 0d9f57b57..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptosi.ll ++++ /dev/null +@@ -1,57 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @fptosi_v8f32_v8i32(ptr %res, ptr %in){ +-; CHECK-LABEL: fptosi_v8f32_v8i32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvftintrz.w.s $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %in +- %v1 = fptosi <8 x float> %v0 to <8 x i32> +- store <8 x i32> %v1, ptr %res +- ret void +-} +- +-define void @fptosi_v4f64_v4i64(ptr %res, ptr %in){ +-; CHECK-LABEL: fptosi_v4f64_v4i64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvftintrz.l.d $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %in +- %v1 = fptosi <4 x double> %v0 to <4 x i64> +- store <4 x i64> %v1, ptr %res +- ret void +-} +- +-define void @fptosi_v4f64_v4i32(ptr %res, ptr %in){ +-; CHECK-LABEL: fptosi_v4f64_v4i32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvpermi.d $xr1, $xr0, 238 +-; CHECK-NEXT: xvfcvt.s.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvftintrz.w.s $xr0, $xr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %in +- %v1 = fptosi <4 x double> %v0 to <4 x i32> +- store <4 x i32> %v1, ptr %res +- ret void +-} +- +-define void @fptosi_v4f32_v4i64(ptr %res, ptr %in){ +-; CHECK-LABEL: fptosi_v4f32_v4i64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vftintrz.w.s $vr0, $vr0 +-; CHECK-NEXT: vext2xv.d.w $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %in +- %v1 = fptosi <4 x float> %v0 to <4 x i64> +- store <4 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptoui.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptoui.ll +deleted file mode 100644 +index 27d70f33c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fptoui.ll ++++ /dev/null +@@ -1,57 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @fptoui_v8f32_v8i32(ptr %res, ptr %in){ +-; CHECK-LABEL: fptoui_v8f32_v8i32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvftintrz.wu.s $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x float>, ptr %in +- %v1 = fptoui <8 x float> %v0 to <8 x i32> +- store <8 x i32> %v1, ptr %res +- ret void +-} +- +-define void @fptoui_v4f64_v4i64(ptr %res, ptr %in){ +-; CHECK-LABEL: fptoui_v4f64_v4i64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvftintrz.lu.d $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %in +- %v1 = fptoui <4 x double> %v0 to <4 x i64> +- store <4 x i64> %v1, ptr %res +- ret void +-} +- +-define void @fptoui_v4f64_v4i32(ptr %res, ptr %in){ +-; CHECK-LABEL: fptoui_v4f64_v4i32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvpermi.d $xr1, $xr0, 238 +-; CHECK-NEXT: xvfcvt.s.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvftintrz.w.s $xr0, $xr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x double>, ptr %in +- %v1 = fptoui <4 x double> %v0 to <4 x i32> +- store <4 x i32> %v1, ptr %res +- ret void +-} +- +-define void @fptoui_v4f32_v4i64(ptr %res, ptr %in){ +-; CHECK-LABEL: fptoui_v4f32_v4i64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vftintrz.wu.s $vr0, $vr0 +-; CHECK-NEXT: vext2xv.du.wu $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %in +- %v1 = fptoui <4 x float> %v0 to <4 x i64> +- store <4 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fsub.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fsub.ll +deleted file mode 100644 +index 6164aa5a5..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/fsub.ll ++++ /dev/null +@@ -1,34 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @fsub_v8f32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: fsub_v8f32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfsub.s $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x float>, ptr %a0 +- %v1 = load <8 x float>, ptr %a1 +- %v2 = fsub <8 x float> %v0, %v1 +- store <8 x float> %v2, ptr %res +- ret void +-} +- +-define void @fsub_v4f64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: fsub_v4f64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvfsub.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x double>, ptr %a0 +- %v1 = load <4 x double>, ptr %a1 +- %v2 = fsub <4 x double> %v0, %v1 +- store <4 x double> %v2, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/icmp.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/icmp.ll +deleted file mode 100644 +index 6693fe0f6..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/icmp.ll ++++ /dev/null +@@ -1,939 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-;; SETEQ +-define void @v32i8_icmp_eq_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v32i8_icmp_eq_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvseqi.b $xr0, $xr0, 15 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <32 x i8>, ptr %a0 +- %cmp = icmp eq <32 x i8> %v0, +- %ext = sext <32 x i1> %cmp to <32 x i8> +- store <32 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v32i8_icmp_eq(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v32i8_icmp_eq: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvseq.b $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %cmp = icmp eq <32 x i8> %v0, %v1 +- %ext = sext <32 x i1> %cmp to <32 x i8> +- store <32 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v16i16_icmp_eq_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v16i16_icmp_eq_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvseqi.h $xr0, $xr0, 15 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i16>, ptr %a0 +- %cmp = icmp eq <16 x i16> %v0, +- %ext = sext <16 x i1> %cmp to <16 x i16> +- store <16 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v16i16_icmp_eq(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v16i16_icmp_eq: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvseq.h $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %cmp = icmp eq <16 x i16> %v0, %v1 +- %ext = sext <16 x i1> %cmp to <16 x i16> +- store <16 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v8i32_icmp_eq_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v8i32_icmp_eq_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvseqi.w $xr0, $xr0, 15 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i32>, ptr %a0 +- %cmp = icmp eq <8 x i32> %v0, +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v8i32_icmp_eq(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8i32_icmp_eq: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvseq.w $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %cmp = icmp eq <8 x i32> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4i64_icmp_eq_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v4i64_icmp_eq_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvseqi.d $xr0, $xr0, 15 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i64>, ptr %a0 +- %cmp = icmp eq <4 x i64> %v0, +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-define void @v4i64_icmp_eq(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4i64_icmp_eq: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvseq.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %cmp = icmp eq <4 x i64> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETLE +-define void @v32i8_icmp_sle_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v32i8_icmp_sle_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslei.b $xr0, $xr0, 15 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <32 x i8>, ptr %a0 +- %cmp = icmp sle <32 x i8> %v0, +- %ext = sext <32 x i1> %cmp to <32 x i8> +- store <32 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v32i8_icmp_sle(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v32i8_icmp_sle: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsle.b $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %cmp = icmp sle <32 x i8> %v0, %v1 +- %ext = sext <32 x i1> %cmp to <32 x i8> +- store <32 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v16i16_icmp_sle_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v16i16_icmp_sle_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslei.h $xr0, $xr0, 15 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i16>, ptr %a0 +- %cmp = icmp sle <16 x i16> %v0, +- %ext = sext <16 x i1> %cmp to <16 x i16> +- store <16 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v16i16_icmp_sle(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v16i16_icmp_sle: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsle.h $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %cmp = icmp sle <16 x i16> %v0, %v1 +- %ext = sext <16 x i1> %cmp to <16 x i16> +- store <16 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v8i32_icmp_sle_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v8i32_icmp_sle_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslei.w $xr0, $xr0, 15 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i32>, ptr %a0 +- %cmp = icmp sle <8 x i32> %v0, +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v8i32_icmp_sle(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8i32_icmp_sle: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsle.w $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %cmp = icmp sle <8 x i32> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4i64_icmp_sle_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v4i64_icmp_sle_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslei.d $xr0, $xr0, 15 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i64>, ptr %a0 +- %cmp = icmp sle <4 x i64> %v0, +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-define void @v4i64_icmp_sle(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4i64_icmp_sle: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsle.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %cmp = icmp sle <4 x i64> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETULE +-define void @v32i8_icmp_ule_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v32i8_icmp_ule_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslei.bu $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <32 x i8>, ptr %a0 +- %cmp = icmp ule <32 x i8> %v0, +- %ext = sext <32 x i1> %cmp to <32 x i8> +- store <32 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v32i8_icmp_ule(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v32i8_icmp_ule: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsle.bu $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %cmp = icmp ule <32 x i8> %v0, %v1 +- %ext = sext <32 x i1> %cmp to <32 x i8> +- store <32 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v16i16_icmp_ule_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v16i16_icmp_ule_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslei.hu $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i16>, ptr %a0 +- %cmp = icmp ule <16 x i16> %v0, +- %ext = sext <16 x i1> %cmp to <16 x i16> +- store <16 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v16i16_icmp_ule(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v16i16_icmp_ule: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsle.hu $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %cmp = icmp ule <16 x i16> %v0, %v1 +- %ext = sext <16 x i1> %cmp to <16 x i16> +- store <16 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v8i32_icmp_ule_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v8i32_icmp_ule_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslei.wu $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i32>, ptr %a0 +- %cmp = icmp ule <8 x i32> %v0, +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v8i32_icmp_ule(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8i32_icmp_ule: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsle.wu $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %cmp = icmp ule <8 x i32> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4i64_icmp_ule_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v4i64_icmp_ule_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslei.du $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i64>, ptr %a0 +- %cmp = icmp ule <4 x i64> %v0, +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-define void @v4i64_icmp_ule(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4i64_icmp_ule: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsle.du $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %cmp = icmp ule <4 x i64> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETLT +-define void @v32i8_icmp_slt_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v32i8_icmp_slt_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslti.b $xr0, $xr0, 15 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <32 x i8>, ptr %a0 +- %cmp = icmp slt <32 x i8> %v0, +- %ext = sext <32 x i1> %cmp to <32 x i8> +- store <32 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v32i8_icmp_slt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v32i8_icmp_slt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvslt.b $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %cmp = icmp slt <32 x i8> %v0, %v1 +- %ext = sext <32 x i1> %cmp to <32 x i8> +- store <32 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v16i16_icmp_slt_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v16i16_icmp_slt_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslti.h $xr0, $xr0, 15 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i16>, ptr %a0 +- %cmp = icmp slt <16 x i16> %v0, +- %ext = sext <16 x i1> %cmp to <16 x i16> +- store <16 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v16i16_icmp_slt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v16i16_icmp_slt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvslt.h $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %cmp = icmp slt <16 x i16> %v0, %v1 +- %ext = sext <16 x i1> %cmp to <16 x i16> +- store <16 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v8i32_icmp_slt_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v8i32_icmp_slt_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslti.w $xr0, $xr0, 15 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i32>, ptr %a0 +- %cmp = icmp slt <8 x i32> %v0, +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v8i32_icmp_slt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8i32_icmp_slt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvslt.w $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %cmp = icmp slt <8 x i32> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4i64_icmp_slt_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v4i64_icmp_slt_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslti.d $xr0, $xr0, 15 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i64>, ptr %a0 +- %cmp = icmp slt <4 x i64> %v0, +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-define void @v4i64_icmp_slt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4i64_icmp_slt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvslt.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %cmp = icmp slt <4 x i64> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETULT +-define void @v32i8_icmp_ult_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v32i8_icmp_ult_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslti.bu $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <32 x i8>, ptr %a0 +- %cmp = icmp ult <32 x i8> %v0, +- %ext = sext <32 x i1> %cmp to <32 x i8> +- store <32 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v32i8_icmp_ult(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v32i8_icmp_ult: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvslt.bu $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %cmp = icmp ult <32 x i8> %v0, %v1 +- %ext = sext <32 x i1> %cmp to <32 x i8> +- store <32 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v16i16_icmp_ult_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v16i16_icmp_ult_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslti.hu $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i16>, ptr %a0 +- %cmp = icmp ult <16 x i16> %v0, +- %ext = sext <16 x i1> %cmp to <16 x i16> +- store <16 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v16i16_icmp_ult(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v16i16_icmp_ult: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvslt.hu $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %cmp = icmp ult <16 x i16> %v0, %v1 +- %ext = sext <16 x i1> %cmp to <16 x i16> +- store <16 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v8i32_icmp_ult_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v8i32_icmp_ult_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslti.wu $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i32>, ptr %a0 +- %cmp = icmp ult <8 x i32> %v0, +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v8i32_icmp_ult(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8i32_icmp_ult: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvslt.wu $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %cmp = icmp ult <8 x i32> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4i64_icmp_ult_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v4i64_icmp_ult_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslti.du $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i64>, ptr %a0 +- %cmp = icmp ult <4 x i64> %v0, +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-define void @v4i64_icmp_ult(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4i64_icmp_ult: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvslt.du $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %cmp = icmp ult <4 x i64> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; Expand SETNE +-define void @v32i8_icmp_ne(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v32i8_icmp_ne: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvseq.b $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvxori.b $xr0, $xr0, 255 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %cmp = icmp ne <32 x i8> %v0, %v1 +- %ext = sext <32 x i1> %cmp to <32 x i8> +- store <32 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v16i16_icmp_ne(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v16i16_icmp_ne: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvseq.h $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvrepli.b $xr1, -1 +-; CHECK-NEXT: xvxor.v $xr0, $xr0, $xr1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %cmp = icmp ne <16 x i16> %v0, %v1 +- %ext = sext <16 x i1> %cmp to <16 x i16> +- store <16 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v8i32_icmp_ne(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8i32_icmp_ne: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvseq.w $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvrepli.b $xr1, -1 +-; CHECK-NEXT: xvxor.v $xr0, $xr0, $xr1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %cmp = icmp ne <8 x i32> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4i64_icmp_ne(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4i64_icmp_ne: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvseq.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvrepli.b $xr1, -1 +-; CHECK-NEXT: xvxor.v $xr0, $xr0, $xr1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %cmp = icmp ne <4 x i64> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; Expand SETGE +-define void @v32i8_icmp_sge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v32i8_icmp_sge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvsle.b $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %cmp = icmp sge <32 x i8> %v0, %v1 +- %ext = sext <32 x i1> %cmp to <32 x i8> +- store <32 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v16i16_icmp_sge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v16i16_icmp_sge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvsle.h $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %cmp = icmp sge <16 x i16> %v0, %v1 +- %ext = sext <16 x i1> %cmp to <16 x i16> +- store <16 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v8i32_icmp_sge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8i32_icmp_sge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvsle.w $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %cmp = icmp sge <8 x i32> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4i64_icmp_sge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4i64_icmp_sge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvsle.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %cmp = icmp sge <4 x i64> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; Expand SETUGE +-define void @v32i8_icmp_uge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v32i8_icmp_uge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvsle.bu $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %cmp = icmp uge <32 x i8> %v0, %v1 +- %ext = sext <32 x i1> %cmp to <32 x i8> +- store <32 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v16i16_icmp_uge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v16i16_icmp_uge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvsle.hu $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %cmp = icmp uge <16 x i16> %v0, %v1 +- %ext = sext <16 x i1> %cmp to <16 x i16> +- store <16 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v8i32_icmp_uge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8i32_icmp_uge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvsle.wu $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %cmp = icmp uge <8 x i32> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4i64_icmp_uge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4i64_icmp_uge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvsle.du $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %cmp = icmp uge <4 x i64> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; Expand SETGT +-define void @v32i8_icmp_sgt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v32i8_icmp_sgt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvslt.b $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %cmp = icmp sgt <32 x i8> %v0, %v1 +- %ext = sext <32 x i1> %cmp to <32 x i8> +- store <32 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v16i16_icmp_sgt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v16i16_icmp_sgt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvslt.h $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %cmp = icmp sgt <16 x i16> %v0, %v1 +- %ext = sext <16 x i1> %cmp to <16 x i16> +- store <16 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v8i32_icmp_sgt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8i32_icmp_sgt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvslt.w $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %cmp = icmp sgt <8 x i32> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4i64_icmp_sgt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4i64_icmp_sgt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvslt.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %cmp = icmp sgt <4 x i64> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +- +-;; Expand SETUGT +-define void @v32i8_icmp_ugt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v32i8_icmp_ugt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvslt.bu $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %cmp = icmp ugt <32 x i8> %v0, %v1 +- %ext = sext <32 x i1> %cmp to <32 x i8> +- store <32 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v16i16_icmp_ugt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v16i16_icmp_ugt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvslt.hu $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %cmp = icmp ugt <16 x i16> %v0, %v1 +- %ext = sext <16 x i1> %cmp to <16 x i16> +- store <16 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v8i32_icmp_ugt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8i32_icmp_ugt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvslt.wu $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %cmp = icmp ugt <8 x i32> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i32> +- store <8 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4i64_icmp_ugt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4i64_icmp_ugt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvslt.du $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %cmp = icmp ugt <4 x i64> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i64> +- store <4 x i64> %ext, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/insertelement.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/insertelement.ll +deleted file mode 100644 +index ceaf40027..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/insertelement.ll ++++ /dev/null +@@ -1,270 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @insert_32xi8(ptr %src, ptr %dst, i8 %in) nounwind { +-; CHECK-LABEL: insert_32xi8: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a2, 1 +-; CHECK-NEXT: xvst $xr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <32 x i8>, ptr %src +- %v_new = insertelement <32 x i8> %v, i8 %in, i32 1 +- store <32 x i8> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_32xi8_upper(ptr %src, ptr %dst, i8 %in) nounwind { +-; CHECK-LABEL: insert_32xi8_upper: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.b $vr1, $a2, 0 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: xvst $xr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <32 x i8>, ptr %src +- %v_new = insertelement <32 x i8> %v, i8 %in, i32 16 +- store <32 x i8> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_16xi16(ptr %src, ptr %dst, i16 %in) nounwind { +-; CHECK-LABEL: insert_16xi16: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: vinsgr2vr.h $vr0, $a2, 1 +-; CHECK-NEXT: xvst $xr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <16 x i16>, ptr %src +- %v_new = insertelement <16 x i16> %v, i16 %in, i32 1 +- store <16 x i16> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_16xi16_upper(ptr %src, ptr %dst, i16 %in) nounwind { +-; CHECK-LABEL: insert_16xi16_upper: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvori.b $xr1, $xr0, 0 +-; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1 +-; CHECK-NEXT: vinsgr2vr.h $vr1, $a2, 0 +-; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2 +-; CHECK-NEXT: xvst $xr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <16 x i16>, ptr %src +- %v_new = insertelement <16 x i16> %v, i16 %in, i32 8 +- store <16 x i16> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_8xi32(ptr %src, ptr %dst, i32 %in) nounwind { +-; CHECK-LABEL: insert_8xi32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvinsgr2vr.w $xr0, $a2, 1 +-; CHECK-NEXT: xvst $xr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <8 x i32>, ptr %src +- %v_new = insertelement <8 x i32> %v, i32 %in, i32 1 +- store <8 x i32> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_4xi64(ptr %src, ptr %dst, i64 %in) nounwind { +-; CHECK-LABEL: insert_4xi64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvinsgr2vr.d $xr0, $a2, 1 +-; CHECK-NEXT: xvst $xr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <4 x i64>, ptr %src +- %v_new = insertelement <4 x i64> %v, i64 %in, i32 1 +- store <4 x i64> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_8xfloat(ptr %src, ptr %dst, float %in) nounwind { +-; CHECK-LABEL: insert_8xfloat: +-; CHECK: # %bb.0: +-; CHECK-NEXT: movfr2gr.s $a2, $fa0 +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvinsgr2vr.w $xr0, $a2, 1 +-; CHECK-NEXT: xvst $xr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <8 x float>, ptr %src +- %v_new = insertelement <8 x float> %v, float %in, i32 1 +- store <8 x float> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_4xdouble(ptr %src, ptr %dst, double %in) nounwind { +-; CHECK-LABEL: insert_4xdouble: +-; CHECK: # %bb.0: +-; CHECK-NEXT: movfr2gr.d $a2, $fa0 +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvinsgr2vr.d $xr0, $a2, 1 +-; CHECK-NEXT: xvst $xr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <4 x double>, ptr %src +- %v_new = insertelement <4 x double> %v, double %in, i32 1 +- store <4 x double> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_32xi8_idx(ptr %src, ptr %dst, i8 %in, i32 %idx) nounwind { +-; CHECK-LABEL: insert_32xi8_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -64 +-; CHECK-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $fp, $sp, 48 # 8-byte Folded Spill +-; CHECK-NEXT: addi.d $fp, $sp, 64 +-; CHECK-NEXT: bstrins.d $sp, $zero, 4, 0 +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvst $xr0, $sp, 0 +-; CHECK-NEXT: addi.d $a0, $sp, 0 +-; CHECK-NEXT: bstrins.d $a0, $a3, 4, 0 +-; CHECK-NEXT: st.b $a2, $a0, 0 +-; CHECK-NEXT: xvld $xr0, $sp, 0 +-; CHECK-NEXT: xvst $xr0, $a1, 0 +-; CHECK-NEXT: addi.d $sp, $fp, -64 +-; CHECK-NEXT: ld.d $fp, $sp, 48 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 64 +-; CHECK-NEXT: ret +- %v = load volatile <32 x i8>, ptr %src +- %v_new = insertelement <32 x i8> %v, i8 %in, i32 %idx +- store <32 x i8> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_16xi16_idx(ptr %src, ptr %dst, i16 %in, i32 %idx) nounwind { +-; CHECK-LABEL: insert_16xi16_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -64 +-; CHECK-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $fp, $sp, 48 # 8-byte Folded Spill +-; CHECK-NEXT: addi.d $fp, $sp, 64 +-; CHECK-NEXT: bstrins.d $sp, $zero, 4, 0 +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvst $xr0, $sp, 0 +-; CHECK-NEXT: addi.d $a0, $sp, 0 +-; CHECK-NEXT: bstrins.d $a0, $a3, 4, 1 +-; CHECK-NEXT: st.h $a2, $a0, 0 +-; CHECK-NEXT: xvld $xr0, $sp, 0 +-; CHECK-NEXT: xvst $xr0, $a1, 0 +-; CHECK-NEXT: addi.d $sp, $fp, -64 +-; CHECK-NEXT: ld.d $fp, $sp, 48 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 64 +-; CHECK-NEXT: ret +- %v = load volatile <16 x i16>, ptr %src +- %v_new = insertelement <16 x i16> %v, i16 %in, i32 %idx +- store <16 x i16> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_8xi32_idx(ptr %src, ptr %dst, i32 %in, i32 %idx) nounwind { +-; CHECK-LABEL: insert_8xi32_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -64 +-; CHECK-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $fp, $sp, 48 # 8-byte Folded Spill +-; CHECK-NEXT: addi.d $fp, $sp, 64 +-; CHECK-NEXT: bstrins.d $sp, $zero, 4, 0 +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvst $xr0, $sp, 0 +-; CHECK-NEXT: addi.d $a0, $sp, 0 +-; CHECK-NEXT: bstrins.d $a0, $a3, 4, 2 +-; CHECK-NEXT: st.w $a2, $a0, 0 +-; CHECK-NEXT: xvld $xr0, $sp, 0 +-; CHECK-NEXT: xvst $xr0, $a1, 0 +-; CHECK-NEXT: addi.d $sp, $fp, -64 +-; CHECK-NEXT: ld.d $fp, $sp, 48 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 64 +-; CHECK-NEXT: ret +- %v = load volatile <8 x i32>, ptr %src +- %v_new = insertelement <8 x i32> %v, i32 %in, i32 %idx +- store <8 x i32> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_4xi64_idx(ptr %src, ptr %dst, i64 %in, i32 %idx) nounwind { +-; CHECK-LABEL: insert_4xi64_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -64 +-; CHECK-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $fp, $sp, 48 # 8-byte Folded Spill +-; CHECK-NEXT: addi.d $fp, $sp, 64 +-; CHECK-NEXT: bstrins.d $sp, $zero, 4, 0 +-; CHECK-NEXT: xvld $xr0, $a0, 0 +-; CHECK-NEXT: xvst $xr0, $sp, 0 +-; CHECK-NEXT: addi.d $a0, $sp, 0 +-; CHECK-NEXT: bstrins.d $a0, $a3, 4, 3 +-; CHECK-NEXT: st.d $a2, $a0, 0 +-; CHECK-NEXT: xvld $xr0, $sp, 0 +-; CHECK-NEXT: xvst $xr0, $a1, 0 +-; CHECK-NEXT: addi.d $sp, $fp, -64 +-; CHECK-NEXT: ld.d $fp, $sp, 48 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 64 +-; CHECK-NEXT: ret +- %v = load volatile <4 x i64>, ptr %src +- %v_new = insertelement <4 x i64> %v, i64 %in, i32 %idx +- store <4 x i64> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_8xfloat_idx(ptr %src, ptr %dst, float %in, i32 %idx) nounwind { +-; CHECK-LABEL: insert_8xfloat_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -64 +-; CHECK-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $fp, $sp, 48 # 8-byte Folded Spill +-; CHECK-NEXT: addi.d $fp, $sp, 64 +-; CHECK-NEXT: bstrins.d $sp, $zero, 4, 0 +-; CHECK-NEXT: xvld $xr1, $a0, 0 +-; CHECK-NEXT: xvst $xr1, $sp, 0 +-; CHECK-NEXT: addi.d $a0, $sp, 0 +-; CHECK-NEXT: bstrins.d $a0, $a2, 4, 2 +-; CHECK-NEXT: fst.s $fa0, $a0, 0 +-; CHECK-NEXT: xvld $xr0, $sp, 0 +-; CHECK-NEXT: xvst $xr0, $a1, 0 +-; CHECK-NEXT: addi.d $sp, $fp, -64 +-; CHECK-NEXT: ld.d $fp, $sp, 48 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 64 +-; CHECK-NEXT: ret +- %v = load volatile <8 x float>, ptr %src +- %v_new = insertelement <8 x float> %v, float %in, i32 %idx +- store <8 x float> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_4xdouble_idx(ptr %src, ptr %dst, double %in, i32 %idx) nounwind { +-; CHECK-LABEL: insert_4xdouble_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -64 +-; CHECK-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $fp, $sp, 48 # 8-byte Folded Spill +-; CHECK-NEXT: addi.d $fp, $sp, 64 +-; CHECK-NEXT: bstrins.d $sp, $zero, 4, 0 +-; CHECK-NEXT: xvld $xr1, $a0, 0 +-; CHECK-NEXT: xvst $xr1, $sp, 0 +-; CHECK-NEXT: addi.d $a0, $sp, 0 +-; CHECK-NEXT: bstrins.d $a0, $a2, 4, 3 +-; CHECK-NEXT: fst.d $fa0, $a0, 0 +-; CHECK-NEXT: xvld $xr0, $sp, 0 +-; CHECK-NEXT: xvst $xr0, $a1, 0 +-; CHECK-NEXT: addi.d $sp, $fp, -64 +-; CHECK-NEXT: ld.d $fp, $sp, 48 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 64 +-; CHECK-NEXT: ret +- %v = load volatile <4 x double>, ptr %src +- %v_new = insertelement <4 x double> %v, double %in, i32 %idx +- store <4 x double> %v_new, ptr %dst +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/lshr.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/lshr.ll +deleted file mode 100644 +index 24be69d80..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/lshr.ll ++++ /dev/null +@@ -1,178 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @lshr_v32i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: lshr_v32i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsrl.b $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %v2 = lshr <32 x i8> %v0, %v1 +- store <32 x i8> %v2, ptr %res +- ret void +-} +- +-define void @lshr_v16i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: lshr_v16i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsrl.h $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %v2 = lshr <16 x i16> %v0, %v1 +- store <16 x i16> %v2, ptr %res +- ret void +-} +- +-define void @lshr_v8i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: lshr_v8i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsrl.w $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %v2 = lshr <8 x i32> %v0, %v1 +- store <8 x i32> %v2, ptr %res +- ret void +-} +- +-define void @lshr_v4i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: lshr_v4i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsrl.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %v2 = lshr <4 x i64> %v0, %v1 +- store <4 x i64> %v2, ptr %res +- ret void +-} +- +-define void @lshr_v32i8_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: lshr_v32i8_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrli.b $xr0, $xr0, 1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = lshr <32 x i8> %v0, +- store <32 x i8> %v1, ptr %res +- ret void +-} +- +-define void @lshr_v32i8_7(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: lshr_v32i8_7: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrli.b $xr0, $xr0, 7 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = lshr <32 x i8> %v0, +- store <32 x i8> %v1, ptr %res +- ret void +-} +- +-define void @lshr_v16i16_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: lshr_v16i16_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrli.h $xr0, $xr0, 1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = lshr <16 x i16> %v0, +- store <16 x i16> %v1, ptr %res +- ret void +-} +- +-define void @lshr_v16i16_15(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: lshr_v16i16_15: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrli.h $xr0, $xr0, 15 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = lshr <16 x i16> %v0, +- store <16 x i16> %v1, ptr %res +- ret void +-} +- +-define void @lshr_v8i32_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: lshr_v8i32_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrli.w $xr0, $xr0, 1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = lshr <8 x i32> %v0, +- store <8 x i32> %v1, ptr %res +- ret void +-} +- +-define void @lshr_v8i32_31(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: lshr_v8i32_31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrli.w $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = lshr <8 x i32> %v0, +- store <8 x i32> %v1, ptr %res +- ret void +-} +- +-define void @lshr_v4i64_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: lshr_v4i64_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrli.d $xr0, $xr0, 1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = lshr <4 x i64> %v0, +- store <4 x i64> %v1, ptr %res +- ret void +-} +- +-define void @lshr_v4i64_63(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: lshr_v4i64_63: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrli.d $xr0, $xr0, 63 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = lshr <4 x i64> %v0, +- store <4 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/mul.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/mul.ll +deleted file mode 100644 +index dcb893caa..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/mul.ll ++++ /dev/null +@@ -1,238 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @mul_v32i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mul_v32i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvmul.b $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %v2 = mul <32 x i8> %v0, %v1 +- store <32 x i8> %v2, ptr %res +- ret void +-} +- +-define void @mul_v16i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mul_v16i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvmul.h $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %v2 = mul <16 x i16> %v0, %v1 +- store <16 x i16> %v2, ptr %res +- ret void +-} +- +-define void @mul_v8i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mul_v8i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvmul.w $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %v2 = mul <8 x i32> %v0, %v1 +- store <8 x i32> %v2, ptr %res +- ret void +-} +- +-define void @mul_v4i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mul_v4i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvmul.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %v2 = mul <4 x i64> %v0, %v1 +- store <4 x i64> %v2, ptr %res +- ret void +-} +- +-define void @mul_square_v32i8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_square_v32i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvmul.b $xr0, $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = mul <32 x i8> %v0, %v0 +- store <32 x i8> %v1, ptr %res +- ret void +-} +- +-define void @mul_square_v16i16(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_square_v16i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvmul.h $xr0, $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = mul <16 x i16> %v0, %v0 +- store <16 x i16> %v1, ptr %res +- ret void +-} +- +-define void @mul_square_v8i32(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_square_v8i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvmul.w $xr0, $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = mul <8 x i32> %v0, %v0 +- store <8 x i32> %v1, ptr %res +- ret void +-} +- +-define void @mul_square_v4i64(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_square_v4i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvmul.d $xr0, $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = mul <4 x i64> %v0, %v0 +- store <4 x i64> %v1, ptr %res +- ret void +-} +- +-define void @mul_v32i8_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_v32i8_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslli.b $xr0, $xr0, 3 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = mul <32 x i8> %v0, +- store <32 x i8> %v1, ptr %res +- ret void +-} +- +-define void @mul_v16i16_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_v16i16_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslli.h $xr0, $xr0, 3 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = mul <16 x i16> %v0, +- store <16 x i16> %v1, ptr %res +- ret void +-} +- +-define void @mul_v8i32_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_v8i32_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslli.w $xr0, $xr0, 3 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = mul <8 x i32> %v0, +- store <8 x i32> %v1, ptr %res +- ret void +-} +- +-define void @mul_v4i64_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_v4i64_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslli.d $xr0, $xr0, 3 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = mul <4 x i64> %v0, +- store <4 x i64> %v1, ptr %res +- ret void +-} +- +-define void @mul_v32i8_17(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_v32i8_17: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvrepli.b $xr1, 17 +-; CHECK-NEXT: xvmul.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = mul <32 x i8> %v0, +- store <32 x i8> %v1, ptr %res +- ret void +-} +- +-define void @mul_v16i16_17(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_v16i16_17: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvrepli.h $xr1, 17 +-; CHECK-NEXT: xvmul.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = mul <16 x i16> %v0, +- store <16 x i16> %v1, ptr %res +- ret void +-} +- +-define void @mul_v8i32_17(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_v8i32_17: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvrepli.w $xr1, 17 +-; CHECK-NEXT: xvmul.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = mul <8 x i32> %v0, +- store <8 x i32> %v1, ptr %res +- ret void +-} +- +-define void @mul_v4i64_17(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_v4i64_17: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvrepli.d $xr1, 17 +-; CHECK-NEXT: xvmul.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = mul <4 x i64> %v0, +- store <4 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/or.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/or.ll +deleted file mode 100644 +index f37cbf1ce..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/or.ll ++++ /dev/null +@@ -1,125 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @or_v32i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: or_v32i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvor.v $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %v2 = or <32 x i8> %v0, %v1 +- store <32 x i8> %v2, ptr %res +- ret void +-} +- +-define void @or_v16i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: or_v16i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvor.v $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %v2 = or <16 x i16> %v0, %v1 +- store <16 x i16> %v2, ptr %res +- ret void +-} +- +-define void @or_v8i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: or_v8i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvor.v $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %v2 = or <8 x i32> %v0, %v1 +- store <8 x i32> %v2, ptr %res +- ret void +-} +- +-define void @or_v4i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: or_v4i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvor.v $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %v2 = or <4 x i64> %v0, %v1 +- store <4 x i64> %v2, ptr %res +- ret void +-} +- +-define void @or_u_v32i8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: or_u_v32i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvori.b $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = or <32 x i8> %v0, +- store <32 x i8> %v1, ptr %res +- ret void +-} +- +-define void @or_u_v16i16(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: or_u_v16i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvrepli.h $xr1, 31 +-; CHECK-NEXT: xvor.v $xr0, $xr0, $xr1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = or <16 x i16> %v0, +- store <16 x i16> %v1, ptr %res +- ret void +-} +- +-define void @or_u_v8i32(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: or_u_v8i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvrepli.w $xr1, 31 +-; CHECK-NEXT: xvor.v $xr0, $xr0, $xr1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = or <8 x i32> %v0, +- store <8 x i32> %v1, ptr %res +- ret void +-} +- +-define void @or_u_v4i64(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: or_u_v4i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvrepli.d $xr1, 31 +-; CHECK-NEXT: xvor.v $xr0, $xr0, $xr1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = or <4 x i64> %v0, +- store <4 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/sdiv.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/sdiv.ll +deleted file mode 100644 +index e3635a5f1..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/sdiv.ll ++++ /dev/null +@@ -1,134 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @sdiv_v32i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: sdiv_v32i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvdiv.b $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %v2 = sdiv <32 x i8> %v0, %v1 +- store <32 x i8> %v2, ptr %res +- ret void +-} +- +-define void @sdiv_v16i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: sdiv_v16i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvdiv.h $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %v2 = sdiv <16 x i16> %v0, %v1 +- store <16 x i16> %v2, ptr %res +- ret void +-} +- +-define void @sdiv_v8i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: sdiv_v8i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvdiv.w $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %v2 = sdiv <8 x i32> %v0, %v1 +- store <8 x i32> %v2, ptr %res +- ret void +-} +- +-define void @sdiv_v4i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: sdiv_v4i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvdiv.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %v2 = sdiv <4 x i64> %v0, %v1 +- store <4 x i64> %v2, ptr %res +- ret void +-} +- +-define void @sdiv_v32i8_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: sdiv_v32i8_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrai.b $xr1, $xr0, 7 +-; CHECK-NEXT: xvsrli.b $xr1, $xr1, 5 +-; CHECK-NEXT: xvadd.b $xr0, $xr0, $xr1 +-; CHECK-NEXT: xvsrai.b $xr0, $xr0, 3 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = sdiv <32 x i8> %v0, +- store <32 x i8> %v1, ptr %res +- ret void +-} +- +-define void @sdiv_v16i16_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: sdiv_v16i16_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrai.h $xr1, $xr0, 15 +-; CHECK-NEXT: xvsrli.h $xr1, $xr1, 13 +-; CHECK-NEXT: xvadd.h $xr0, $xr0, $xr1 +-; CHECK-NEXT: xvsrai.h $xr0, $xr0, 3 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = sdiv <16 x i16> %v0, +- store <16 x i16> %v1, ptr %res +- ret void +-} +- +-define void @sdiv_v8i32_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: sdiv_v8i32_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrai.w $xr1, $xr0, 31 +-; CHECK-NEXT: xvsrli.w $xr1, $xr1, 29 +-; CHECK-NEXT: xvadd.w $xr0, $xr0, $xr1 +-; CHECK-NEXT: xvsrai.w $xr0, $xr0, 3 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = sdiv <8 x i32> %v0, +- store <8 x i32> %v1, ptr %res +- ret void +-} +- +-define void @sdiv_v4i64_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: sdiv_v4i64_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrai.d $xr1, $xr0, 63 +-; CHECK-NEXT: xvsrli.d $xr1, $xr1, 61 +-; CHECK-NEXT: xvadd.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: xvsrai.d $xr0, $xr0, 3 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = sdiv <4 x i64> %v0, +- store <4 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/shl.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/shl.ll +deleted file mode 100644 +index 8a02c7e3a..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/shl.ll ++++ /dev/null +@@ -1,178 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @shl_v32i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: shl_v32i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsll.b $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %v2 = shl <32 x i8> %v0, %v1 +- store <32 x i8> %v2, ptr %res +- ret void +-} +- +-define void @shl_v16i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: shl_v16i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsll.h $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %v2 = shl <16 x i16> %v0, %v1 +- store <16 x i16> %v2, ptr %res +- ret void +-} +- +-define void @shl_v8i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: shl_v8i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsll.w $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %v2 = shl <8 x i32> %v0, %v1 +- store <8 x i32> %v2, ptr %res +- ret void +-} +- +-define void @shl_v4i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: shl_v4i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsll.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %v2 = shl <4 x i64> %v0, %v1 +- store <4 x i64> %v2, ptr %res +- ret void +-} +- +-define void @shl_v32i8_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: shl_v32i8_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslli.b $xr0, $xr0, 1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = shl <32 x i8> %v0, +- store <32 x i8> %v1, ptr %res +- ret void +-} +- +-define void @shl_v32i8_7(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: shl_v32i8_7: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslli.b $xr0, $xr0, 7 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = shl <32 x i8> %v0, +- store <32 x i8> %v1, ptr %res +- ret void +-} +- +-define void @shl_v16i16_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: shl_v16i16_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslli.h $xr0, $xr0, 1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = shl <16 x i16> %v0, +- store <16 x i16> %v1, ptr %res +- ret void +-} +- +-define void @shl_v16i16_15(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: shl_v16i16_15: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslli.h $xr0, $xr0, 15 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = shl <16 x i16> %v0, +- store <16 x i16> %v1, ptr %res +- ret void +-} +- +-define void @shl_v8i32_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: shl_v8i32_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslli.w $xr0, $xr0, 1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = shl <8 x i32> %v0, +- store <8 x i32> %v1, ptr %res +- ret void +-} +- +-define void @shl_v8i32_31(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: shl_v8i32_31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslli.w $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = shl <8 x i32> %v0, +- store <8 x i32> %v1, ptr %res +- ret void +-} +- +-define void @shl_v4i64_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: shl_v4i64_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslli.d $xr0, $xr0, 1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = shl <4 x i64> %v0, +- store <4 x i64> %v1, ptr %res +- ret void +-} +- +-define void @shl_v4i64_63(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: shl_v4i64_63: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvslli.d $xr0, $xr0, 63 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = shl <4 x i64> %v0, +- store <4 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/sitofp.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/sitofp.ll +deleted file mode 100644 +index 208a758ea..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/sitofp.ll ++++ /dev/null +@@ -1,57 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @sitofp_v8i32_v8f32(ptr %res, ptr %in){ +-; CHECK-LABEL: sitofp_v8i32_v8f32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvffint.s.w $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i32>, ptr %in +- %v1 = sitofp <8 x i32> %v0 to <8 x float> +- store <8 x float> %v1, ptr %res +- ret void +-} +- +-define void @sitofp_v4f64_v4f64(ptr %res, ptr %in){ +-; CHECK-LABEL: sitofp_v4f64_v4f64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvffint.d.l $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i64>, ptr %in +- %v1 = sitofp <4 x i64> %v0 to <4 x double> +- store <4 x double> %v1, ptr %res +- ret void +-} +- +-define void @sitofp_v4i64_v4f32(ptr %res, ptr %in){ +-; CHECK-LABEL: sitofp_v4i64_v4f32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvffint.d.l $xr0, $xr0 +-; CHECK-NEXT: xvpermi.d $xr1, $xr0, 238 +-; CHECK-NEXT: xvfcvt.s.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i64>, ptr %in +- %v1 = sitofp <4 x i64> %v0 to <4 x float> +- store <4 x float> %v1, ptr %res +- ret void +-} +- +-define void @sitofp_v4i32_v4f64(ptr %res, ptr %in){ +-; CHECK-LABEL: sitofp_v4i32_v4f64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vext2xv.d.w $xr0, $xr0 +-; CHECK-NEXT: xvffint.d.l $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i32>, ptr %in +- %v1 = sitofp <4 x i32> %v0 to <4 x double> +- store <4 x double> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/sub.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/sub.ll +deleted file mode 100644 +index bcfff1651..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/sub.ll ++++ /dev/null +@@ -1,122 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @sub_v32i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: sub_v32i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsub.b $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %v2 = sub <32 x i8> %v0, %v1 +- store <32 x i8> %v2, ptr %res +- ret void +-} +- +-define void @sub_v16i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: sub_v16i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsub.h $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %v2 = sub <16 x i16> %v0, %v1 +- store <16 x i16> %v2, ptr %res +- ret void +-} +- +-define void @sub_v8i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: sub_v8i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsub.w $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %v2 = sub <8 x i32> %v0, %v1 +- store <8 x i32> %v2, ptr %res +- ret void +-} +- +-define void @sub_v4i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: sub_v4i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvsub.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %v2 = sub <4 x i64> %v0, %v1 +- store <4 x i64> %v2, ptr %res +- ret void +-} +- +-define void @sub_v32i8_31(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: sub_v32i8_31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsubi.bu $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = sub <32 x i8> %v0, +- store <32 x i8> %v1, ptr %res +- ret void +-} +- +-define void @sub_v16i16_31(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: sub_v16i16_31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsubi.hu $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = sub <16 x i16> %v0, +- store <16 x i16> %v1, ptr %res +- ret void +-} +- +-define void @sub_v8i32_31(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: sub_v8i32_31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsubi.wu $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = sub <8 x i32> %v0, +- store <8 x i32> %v1, ptr %res +- ret void +-} +- +-define void @sub_v4i64_31(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: sub_v4i64_31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsubi.du $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = sub <4 x i64> %v0, +- store <4 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/udiv.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/udiv.ll +deleted file mode 100644 +index e78084c71..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/udiv.ll ++++ /dev/null +@@ -1,122 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @udiv_v32i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: udiv_v32i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvdiv.bu $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %v2 = udiv <32 x i8> %v0, %v1 +- store <32 x i8> %v2, ptr %res +- ret void +-} +- +-define void @udiv_v16i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: udiv_v16i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvdiv.hu $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %v2 = udiv <16 x i16> %v0, %v1 +- store <16 x i16> %v2, ptr %res +- ret void +-} +- +-define void @udiv_v8i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: udiv_v8i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvdiv.wu $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %v2 = udiv <8 x i32> %v0, %v1 +- store <8 x i32> %v2, ptr %res +- ret void +-} +- +-define void @udiv_v4i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: udiv_v4i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvdiv.du $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %v2 = udiv <4 x i64> %v0, %v1 +- store <4 x i64> %v2, ptr %res +- ret void +-} +- +-define void @udiv_v32i8_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: udiv_v32i8_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrli.b $xr0, $xr0, 3 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = udiv <32 x i8> %v0, +- store <32 x i8> %v1, ptr %res +- ret void +-} +- +-define void @udiv_v16i16_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: udiv_v16i16_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrli.h $xr0, $xr0, 3 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = udiv <16 x i16> %v0, +- store <16 x i16> %v1, ptr %res +- ret void +-} +- +-define void @udiv_v8i32_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: udiv_v8i32_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrli.w $xr0, $xr0, 3 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = udiv <8 x i32> %v0, +- store <8 x i32> %v1, ptr %res +- ret void +-} +- +-define void @udiv_v4i64_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: udiv_v4i64_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvsrli.d $xr0, $xr0, 3 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = udiv <4 x i64> %v0, +- store <4 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/uitofp.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/uitofp.ll +deleted file mode 100644 +index 70cf71c4c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/uitofp.ll ++++ /dev/null +@@ -1,57 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @uitofp_v8i32_v8f32(ptr %res, ptr %in){ +-; CHECK-LABEL: uitofp_v8i32_v8f32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvffint.s.wu $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i32>, ptr %in +- %v1 = uitofp <8 x i32> %v0 to <8 x float> +- store <8 x float> %v1, ptr %res +- ret void +-} +- +-define void @uitofp_v4f64_v4f64(ptr %res, ptr %in){ +-; CHECK-LABEL: uitofp_v4f64_v4f64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvffint.d.lu $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i64>, ptr %in +- %v1 = uitofp <4 x i64> %v0 to <4 x double> +- store <4 x double> %v1, ptr %res +- ret void +-} +- +-define void @uitofp_v4i64_v4f32(ptr %res, ptr %in){ +-; CHECK-LABEL: uitofp_v4i64_v4f32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvffint.d.lu $xr0, $xr0 +-; CHECK-NEXT: xvpermi.d $xr1, $xr0, 238 +-; CHECK-NEXT: xvfcvt.s.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i64>, ptr %in +- %v1 = uitofp <4 x i64> %v0 to <4 x float> +- store <4 x float> %v1, ptr %res +- ret void +-} +- +-define void @uitofp_v4i32_v4f64(ptr %res, ptr %in){ +-; CHECK-LABEL: uitofp_v4i32_v4f64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vext2xv.du.wu $xr0, $xr0 +-; CHECK-NEXT: xvffint.d.lu $xr0, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i32>, ptr %in +- %v1 = uitofp <4 x i32> %v0 to <4 x double> +- store <4 x double> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/xor.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/xor.ll +deleted file mode 100644 +index c2fb1462b..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/xor.ll ++++ /dev/null +@@ -1,125 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @xor_v32i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: xor_v32i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvxor.v $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %v2 = xor <32 x i8> %v0, %v1 +- store <32 x i8> %v2, ptr %res +- ret void +-} +- +-define void @xor_v16i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: xor_v16i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvxor.v $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %v2 = xor <16 x i16> %v0, %v1 +- store <16 x i16> %v2, ptr %res +- ret void +-} +- +-define void @xor_v8i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: xor_v8i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvxor.v $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %v2 = xor <8 x i32> %v0, %v1 +- store <8 x i32> %v2, ptr %res +- ret void +-} +- +-define void @xor_v4i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: xor_v4i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvxor.v $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %v2 = xor <4 x i64> %v0, %v1 +- store <4 x i64> %v2, ptr %res +- ret void +-} +- +-define void @xor_u_v32i8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: xor_u_v32i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvxori.b $xr0, $xr0, 31 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = xor <32 x i8> %v0, +- store <32 x i8> %v1, ptr %res +- ret void +-} +- +-define void @xor_u_v16i16(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: xor_u_v16i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvrepli.h $xr1, 31 +-; CHECK-NEXT: xvxor.v $xr0, $xr0, $xr1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = xor <16 x i16> %v0, +- store <16 x i16> %v1, ptr %res +- ret void +-} +- +-define void @xor_u_v8i32(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: xor_u_v8i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvrepli.w $xr1, 31 +-; CHECK-NEXT: xvxor.v $xr0, $xr0, $xr1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = xor <8 x i32> %v0, +- store <8 x i32> %v1, ptr %res +- ret void +-} +- +-define void @xor_u_v4i64(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: xor_u_v4i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvrepli.d $xr1, 31 +-; CHECK-NEXT: xvxor.v $xr0, $xr0, $xr1 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = xor <4 x i64> %v0, +- store <4 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/lasxvavg.ll b/llvm/test/CodeGen/LoongArch/lasx/lasxvavg.ll +new file mode 100644 +index 000000000..a0f3e6ebe +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lasx/lasxvavg.ll +@@ -0,0 +1,106 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lasx < %s | FileCheck %s ++ ++define <32 x i8> @lsxavgr_v32i8(<32 x i8> noundef %0, <32 x i8> noundef %1) local_unnamed_addr #0 { ++; CHECK-LABEL: lsxavgr_v32i8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvadd.b $xr0, $xr0, $xr1 ++; CHECK-NEXT: xvldi $xr1, 1 ++; CHECK-NEXT: xvavg.b $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %3 = add <32 x i8> %0, ++ %4 = add <32 x i8> %3, %1 ++ %5 = sdiv <32 x i8> %4, ++ ret <32 x i8> %5 ++} ++ ++define <16 x i16> @lsxavgr_v16i16(<16 x i16> noundef %0, <16 x i16> noundef %1) local_unnamed_addr #0 { ++; CHECK-LABEL: lsxavgr_v16i16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvadd.h $xr0, $xr0, $xr1 ++; CHECK-NEXT: xvldi $xr1, 1 ++; CHECK-NEXT: xvavg.h $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %3 = add <16 x i16> %0, ++ %4 = add <16 x i16> %3, %1 ++ %5 = sdiv <16 x i16> %4, ++ ret <16 x i16> %5 ++} ++ ++define <8 x i32> @lsxavgr_v8i32(<8 x i32> noundef %0, <8 x i32> noundef %1) local_unnamed_addr #0 { ++; CHECK-LABEL: lsxavgr_v8i32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvadd.w $xr0, $xr0, $xr1 ++; CHECK-NEXT: xvldi $xr1, 1 ++; CHECK-NEXT: xvavg.w $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %3 = add <8 x i32> %0, ++ %4 = add <8 x i32> %3, %1 ++ %5 = sdiv <8 x i32> %4, ++ ret <8 x i32> %5 ++} ++ ++define <4 x i64> @lsxavgr_v4i64(<4 x i64> noundef %0, <4 x i64> noundef %1) local_unnamed_addr #0 { ++; CHECK-LABEL: lsxavgr_v4i64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvadd.d $xr0, $xr0, $xr1 ++; CHECK-NEXT: xvldi $xr1, 1 ++; CHECK-NEXT: xvavg.d $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %3 = add <4 x i64> %0, ++ %4 = add <4 x i64> %3, %1 ++ %5 = sdiv <4 x i64> %4, ++ ret <4 x i64> %5 ++} ++ ++define <32 x i8> @lsxavgr_v32u8(<32 x i8> noundef %0, <32 x i8> noundef %1) local_unnamed_addr #0 { ++; CHECK-LABEL: lsxavgr_v32u8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvadd.b $xr0, $xr0, $xr1 ++; CHECK-NEXT: xvldi $xr1, 1 ++; CHECK-NEXT: xvavg.bu $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %3 = add <32 x i8> %0, ++ %4 = add <32 x i8> %3, %1 ++ %5 = lshr <32 x i8> %4, ++ ret <32 x i8> %5 ++} ++ ++define <16 x i16> @lsxavgr_v16u16(<16 x i16> noundef %0, <16 x i16> noundef %1) local_unnamed_addr #0 { ++; CHECK-LABEL: lsxavgr_v16u16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvadd.h $xr0, $xr0, $xr1 ++; CHECK-NEXT: xvldi $xr1, 1 ++; CHECK-NEXT: xvavg.hu $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %3 = add <16 x i16> %0, ++ %4 = add <16 x i16> %3, %1 ++ %5 = lshr <16 x i16> %4, ++ ret <16 x i16> %5 ++} ++ ++define <8 x i32> @lsxavgr_v8u32(<8 x i32> noundef %0, <8 x i32> noundef %1) local_unnamed_addr #0 { ++; CHECK-LABEL: lsxavgr_v8u32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvadd.w $xr0, $xr0, $xr1 ++; CHECK-NEXT: xvldi $xr1, 1 ++; CHECK-NEXT: xvavg.wu $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %3 = add <8 x i32> %0, ++ %4 = add <8 x i32> %3, %1 ++ %5 = lshr <8 x i32> %4, ++ ret <8 x i32> %5 ++} ++ ++define <4 x i64> @lsxavgr_v4u64(<4 x i64> noundef %0, <4 x i64> noundef %1) local_unnamed_addr #0 { ++; CHECK-LABEL: lsxavgr_v4u64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvadd.d $xr0, $xr0, $xr1 ++; CHECK-NEXT: xvldi $xr1, 1 ++; CHECK-NEXT: xvavg.du $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %3 = add <4 x i64> %0, ++ %4 = add <4 x i64> %3, %1 ++ %5 = lshr <4 x i64> %4, ++ ret <4 x i64> %5 ++} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/lasxvclr.ll b/llvm/test/CodeGen/LoongArch/lasx/lasxvclr.ll +new file mode 100644 +index 000000000..b40698104 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lasx/lasxvclr.ll +@@ -0,0 +1,46 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lasx < %s | FileCheck %s ++ ++define <32 x i8> @clri8(<32 x i8> %0, <32 x i8> %1) { ++; CHECK-LABEL: clri8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvbitclr.b $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %3 = shl <32 x i8> , %1 ++ %4 = xor <32 x i8> %3, ++ %5 = and <32 x i8> %4, %0 ++ ret <32 x i8> %5 ++} ++ ++define <16 x i16> @clri16(<16 x i16> %0, <16 x i16> %1) { ++; CHECK-LABEL: clri16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvbitclr.h $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %3 = shl <16 x i16> , %1 ++ %4 = xor <16 x i16> %3, ++ %5 = and <16 x i16> %4, %0 ++ ret <16 x i16> %5 ++} ++ ++define <8 x i32> @clri32(<8 x i32> %0, <8 x i32> %1) { ++; CHECK-LABEL: clri32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvbitclr.w $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %3 = shl <8 x i32> , %1 ++ %4 = xor <8 x i32> %3, ++ %5 = and <8 x i32> %4, %0 ++ ret <8 x i32> %5 ++} ++ ++define <4 x i64> @clri64(<4 x i64> %0, <4 x i64> %1) { ++; CHECK-LABEL: clri64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvbitclr.d $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %3 = shl <4 x i64> , %1 ++ %4 = xor <4 x i64> %3, ++ %5 = and <4 x i64> %4, %0 ++ ret <4 x i64> %5 ++} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/logic-lasx.ll b/llvm/test/CodeGen/LoongArch/lasx/logic-lasx.ll +new file mode 100644 +index 000000000..ff28569a1 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lasx/logic-lasx.ll +@@ -0,0 +1,130 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lasx < %s | FileCheck %s ++ ++define <4 x i64> @not_v4i64(<4 x i64> %a) { ++; CHECK-LABEL: not_v4i64: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvnor.v $xr0, $xr0, $xr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <4 x i64> %a, ++ ret <4 x i64> %not ++} ++ ++define <8 x i32> @not_v8i32(<8 x i32> %a) { ++; CHECK-LABEL: not_v8i32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvnor.v $xr0, $xr0, $xr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <8 x i32> %a, ++ ret <8 x i32> %not ++} ++ ++define <16 x i16> @not_v16i16(<16 x i16> %a) { ++; CHECK-LABEL: not_v16i16: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvnor.v $xr0, $xr0, $xr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <16 x i16> %a, ++ ret <16 x i16> %not ++} ++ ++define <32 x i8> @not_v32i8(<32 x i8> %a) { ++; CHECK-LABEL: not_v32i8: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvxori.b $xr0, $xr0, 255 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <32 x i8> %a, ++ ret <32 x i8> %not ++} ++ ++define <4 x i64> @andn_v4i64(<4 x i64> %a, <4 x i64> %b) { ++; CHECK-LABEL: andn_v4i64: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvandn.v $xr0, $xr1, $xr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <4 x i64> %b, ++ %and = and <4 x i64> %not, %a ++ ret <4 x i64> %and ++} ++ ++define <8 x i32> @andn_v8i32(<8 x i32> %a, <8 x i32> %b) { ++; CHECK-LABEL: andn_v8i32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvandn.v $xr0, $xr1, $xr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <8 x i32> %b, ++ %and = and <8 x i32> %not, %a ++ ret <8 x i32> %and ++} ++ ++define <16 x i16> @andn_v16i16(<16 x i16> %a, <16 x i16> %b) { ++; CHECK-LABEL: andn_v16i16: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvandn.v $xr0, $xr1, $xr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <16 x i16> %b, ++ %and = and <16 x i16> %not, %a ++ ret <16 x i16> %and ++} ++ ++define <32 x i8> @andn_v32i8(<32 x i8> %a, <32 x i8> %b) { ++; CHECK-LABEL: andn_v32i8: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvandn.v $xr0, $xr1, $xr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <32 x i8> %b, ++ %and = and <32 x i8> %not, %a ++ ret <32 x i8> %and ++} ++ ++define <4 x i64> @orn_v4i64(<4 x i64> %a, <4 x i64> %b) { ++; CHECK-LABEL: orn_v4i64: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvorn.v $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <4 x i64> %b, ++ %or = or <4 x i64> %not, %a ++ ret <4 x i64> %or ++} ++ ++define <8 x i32> @orn_v8i32(<8 x i32> %a, <8 x i32> %b) { ++; CHECK-LABEL: orn_v8i32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvorn.v $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <8 x i32> %b, ++ %or = or <8 x i32> %not, %a ++ ret <8 x i32> %or ++} ++ ++define <16 x i16> @orn_v16i16(<16 x i16> %a, <16 x i16> %b) { ++; CHECK-LABEL: orn_v16i16: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvorn.v $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <16 x i16> %b, ++ %or = or <16 x i16> %not, %a ++ ret <16 x i16> %or ++} ++ ++define <32 x i8> @orn_v32i8(<32 x i8> %a, <32 x i8> %b) { ++; CHECK-LABEL: orn_v32i8: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvorn.v $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <32 x i8> %b, ++ %or = or <32 x i8> %not, %a ++ ret <32 x i8> %or ++} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/mulh.ll b/llvm/test/CodeGen/LoongArch/lasx/mulh.ll +deleted file mode 100644 +index aac711a4a..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/mulh.ll ++++ /dev/null +@@ -1,162 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @mulhs_v32i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mulhs_v32i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvmuh.b $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %v0s = sext <32 x i8> %v0 to <32 x i16> +- %v1s = sext <32 x i8> %v1 to <32 x i16> +- %m = mul <32 x i16> %v0s, %v1s +- %s = ashr <32 x i16> %m, +- %v2 = trunc <32 x i16> %s to <32 x i8> +- store <32 x i8> %v2, ptr %res +- ret void +-} +- +-define void @mulhu_v32i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mulhu_v32i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvmuh.bu $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %v0z = zext <32 x i8> %v0 to <32 x i16> +- %v1z = zext <32 x i8> %v1 to <32 x i16> +- %m = mul <32 x i16> %v0z, %v1z +- %s = lshr <32 x i16> %m, +- %v2 = trunc <32 x i16> %s to <32 x i8> +- store <32 x i8> %v2, ptr %res +- ret void +-} +- +-define void @mulhs_v16i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mulhs_v16i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvmuh.h $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %v0s = sext <16 x i16> %v0 to <16 x i32> +- %v1s = sext <16 x i16> %v1 to <16 x i32> +- %m = mul <16 x i32> %v0s, %v1s +- %s = ashr <16 x i32> %m, +- %v2 = trunc <16 x i32> %s to <16 x i16> +- store <16 x i16> %v2, ptr %res +- ret void +-} +- +-define void @mulhu_v16i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mulhu_v16i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvmuh.hu $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %v0z = zext <16 x i16> %v0 to <16 x i32> +- %v1z = zext <16 x i16> %v1 to <16 x i32> +- %m = mul <16 x i32> %v0z, %v1z +- %s = lshr <16 x i32> %m, +- %v2 = trunc <16 x i32> %s to <16 x i16> +- store <16 x i16> %v2, ptr %res +- ret void +-} +- +-define void @mulhs_v8i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mulhs_v8i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvmuh.w $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %v0s = sext <8 x i32> %v0 to <8 x i64> +- %v1s = sext <8 x i32> %v1 to <8 x i64> +- %m = mul <8 x i64> %v0s, %v1s +- %s = ashr <8 x i64> %m, +- %v2 = trunc <8 x i64> %s to <8 x i32> +- store <8 x i32> %v2, ptr %res +- ret void +-} +- +-define void @mulhu_v8i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mulhu_v8i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvmuh.wu $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %v0z = zext <8 x i32> %v0 to <8 x i64> +- %v1z = zext <8 x i32> %v1 to <8 x i64> +- %m = mul <8 x i64> %v0z, %v1z +- %s = lshr <8 x i64> %m, +- %v2 = trunc <8 x i64> %s to <8 x i32> +- store <8 x i32> %v2, ptr %res +- ret void +-} +- +-define void @mulhs_v4i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mulhs_v4i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvmuh.d $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %v0s = sext <4 x i64> %v0 to <4 x i128> +- %v1s = sext <4 x i64> %v1 to <4 x i128> +- %m = mul <4 x i128> %v0s, %v1s +- %s = ashr <4 x i128> %m, +- %v2 = trunc <4 x i128> %s to <4 x i64> +- store <4 x i64> %v2, ptr %res +- ret void +-} +- +-define void @mulhu_v4i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mulhu_v4i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvld $xr0, $a2, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvmuh.du $xr0, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %v0z = zext <4 x i64> %v0 to <4 x i128> +- %v1z = zext <4 x i64> %v1 to <4 x i128> +- %m = mul <4 x i128> %v0z, %v1z +- %s = lshr <4 x i128> %m, +- %v2 = trunc <4 x i128> %s to <4 x i64> +- store <4 x i64> %v2, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/set-lasx.ll b/llvm/test/CodeGen/LoongArch/lasx/set-lasx.ll +new file mode 100644 +index 000000000..443262eac +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lasx/set-lasx.ll +@@ -0,0 +1,38 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lasx < %s | FileCheck %s ++ ++define <32 x i8> @seti8(<32 x i8>) { ++; CHECK-LABEL: seti8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvbitseti.b $xr0, $xr0, 6 ++; CHECK-NEXT: jr $ra ++ %2 = or <32 x i8> %0, ++ ret <32 x i8> %2 ++} ++ ++define <16 x i16> @seti16(<16 x i16>) { ++; CHECK-LABEL: seti16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvbitseti.h $xr0, $xr0, 6 ++; CHECK-NEXT: jr $ra ++ %2 = or <16 x i16> %0, ++ ret <16 x i16> %2 ++} ++ ++define <8 x i32> @seti32(<8 x i32>) { ++; CHECK-LABEL: seti32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvbitseti.w $xr0, $xr0, 6 ++; CHECK-NEXT: jr $ra ++ %2 = or <8 x i32> %0, ++ ret <8 x i32> %2 ++} ++ ++define <4 x i64> @seti64(<4 x i64>) { ++; CHECK-LABEL: seti64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvbitseti.d $xr0, $xr0, 6 ++; CHECK-NEXT: jr $ra ++ %2 = or <4 x i64> %0, ++ ret <4 x i64> %2 ++} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/shuffle_v4i64_1032.ll b/llvm/test/CodeGen/LoongArch/lasx/shuffle_v4i64_1032.ll +new file mode 100644 +index 000000000..965cfe94c +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lasx/shuffle_v4i64_1032.ll +@@ -0,0 +1,19 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lasx < %s | FileCheck %s ++ ++define <4 x i64> @shuffle_v4i64_1032(<4 x i64> %vj, <4 x i64> %vk) { ++; CHECK-LABEL: shuffle_v4i64_1032: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvpickve2gr.d $r4, $xr0, 2 ++; CHECK-NEXT: xvpickve2gr.d $r5, $xr0, 3 ++; CHECK-NEXT: xvpickve2gr.d $r6, $xr0, 0 ++; CHECK-NEXT: xvpickve2gr.d $r7, $xr0, 1 ++; CHECK-NEXT: xvinsgr2vr.d $xr0, $r7, 0 ++; CHECK-NEXT: xvinsgr2vr.d $xr0, $r6, 1 ++; CHECK-NEXT: xvinsgr2vr.d $xr0, $r5, 2 ++; CHECK-NEXT: xvinsgr2vr.d $xr0, $r4, 3 ++; CHECK-NEXT: jr $ra ++entry: ++ %vd = shufflevector <4 x i64> %vj, <4 x i64> %vk, <4 x i32> ++ ret <4 x i64> %vd ++} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/v32i8-bswap.ll b/llvm/test/CodeGen/LoongArch/lasx/v32i8-bswap.ll +new file mode 100644 +index 000000000..1453dabaa +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lasx/v32i8-bswap.ll +@@ -0,0 +1,26 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s ++ ++define void @vshf_v32i8(ptr %res, ptr %a0) nounwind { ++; CHECK-LABEL: vshf_v32i8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvld $xr0, $r5, 0 ++; CHECK-NEXT: xvpickve2gr.d $r5, $xr0, 3 ++; CHECK-NEXT: xvpickve2gr.d $r6, $xr0, 2 ++; CHECK-NEXT: xvpickve2gr.d $r7, $xr0, 0 ++; CHECK-NEXT: xvpickve2gr.d $r8, $xr0, 1 ++; CHECK-NEXT: revb.d $r8, $r8 ++; CHECK-NEXT: revb.d $r7, $r7 ++; CHECK-NEXT: xvinsgr2vr.d $xr0, $r7, 0 ++; CHECK-NEXT: xvinsgr2vr.d $xr0, $r8, 1 ++; CHECK-NEXT: revb.d $r6, $r6 ++; CHECK-NEXT: xvinsgr2vr.d $xr0, $r6, 2 ++; CHECK-NEXT: revb.d $r5, $r5 ++; CHECK-NEXT: xvinsgr2vr.d $xr0, $r5, 3 ++; CHECK-NEXT: xvst $xr0, $r4, 0 ++; CHECK-NEXT: jr $ra ++ %v1 = load <32 x i8>, ptr %a0 ++ %v2 = shufflevector <32 x i8> %v1, <32 x i8> undef, <32 x i32> ++ store <32 x i8> %v2, ptr %res ++ ret void ++} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/vext2xv.ll b/llvm/test/CodeGen/LoongArch/lasx/vext2xv.ll +new file mode 100644 +index 000000000..7bd3dca73 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lasx/vext2xv.ll +@@ -0,0 +1,65 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lasx < %s | FileCheck %s ++ ++define <4 x i64> @s_v4i32_v4i64(<4 x i32> %a0) { ++; CHECK-LABEL: s_v4i32_v4i64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # kill: def $vr0 killed $vr0 def $xr0 ++; CHECK-NEXT: vext2xv.d.w $xr0, $xr0 ++; CHECK-NEXT: jr $ra ++ %1 = sext <4 x i32> %a0 to <4 x i64> ++ ret <4 x i64> %1 ++} ++ ++define <4 x i64> @z_v4i32_v4i64(<4 x i32> %a0) { ++; CHECK-LABEL: z_v4i32_v4i64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # kill: def $vr0 killed $vr0 def $xr0 ++; CHECK-NEXT: vext2xv.du.wu $xr0, $xr0 ++; CHECK-NEXT: jr $ra ++ %1 = zext <4 x i32> %a0 to <4 x i64> ++ ret <4 x i64> %1 ++} ++ ++define <16 x i16> @s_v16i8_v16i16(<16 x i8> %A) { ++; CHECK-LABEL: s_v16i8_v16i16: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: # kill: def $vr0 killed $vr0 def $xr0 ++; CHECK-NEXT: vext2xv.h.b $xr0, $xr0 ++; CHECK-NEXT: jr $ra ++ entry: ++ %B = sext <16 x i8> %A to <16 x i16> ++ ret <16 x i16> %B ++} ++ ++define <16 x i16> @z_v16i8_v16i16(<16 x i8> %A) { ++; CHECK-LABEL: z_v16i8_v16i16: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: # kill: def $vr0 killed $vr0 def $xr0 ++; CHECK-NEXT: vext2xv.hu.bu $xr0, $xr0 ++; CHECK-NEXT: jr $ra ++ entry: ++ %B = zext <16 x i8> %A to <16 x i16> ++ ret <16 x i16> %B ++} ++ ++define <8 x i32> @s_v8i16_v8i32(<8 x i16> %x) { ++; CHECK-LABEL: s_v8i16_v8i32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # kill: def $vr0 killed $vr0 def $xr0 ++; CHECK-NEXT: vext2xv.w.h $xr0, $xr0 ++; CHECK-NEXT: jr $ra ++ %1 = sext <8 x i16> %x to <8 x i32> ++ ret <8 x i32> %1 ++} ++ ++define <8 x i32> @z_v8i16_v8i32(<8 x i16> %x) { ++; CHECK-LABEL: z_v8i16_v8i32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # kill: def $vr0 killed $vr0 def $xr0 ++; CHECK-NEXT: vext2xv.wu.hu $xr0, $xr0 ++; CHECK-NEXT: jr $ra ++ %1 = zext <8 x i16> %x to <8 x i32> ++ ret <8 x i32> %1 ++} ++ +diff --git a/llvm/test/CodeGen/LoongArch/lasx/vselect.ll b/llvm/test/CodeGen/LoongArch/lasx/vselect.ll +deleted file mode 100644 +index a9a542579..000000000 +--- a/llvm/test/CodeGen/LoongArch/lasx/vselect.ll ++++ /dev/null +@@ -1,85 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s +- +-define void @select_v32i8_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: select_v32i8_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvrepli.h $xr1, -256 +-; CHECK-NEXT: xvbitseli.b $xr1, $xr0, 1 +-; CHECK-NEXT: xvst $xr1, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <32 x i8>, ptr %a0 +- %sel = select <32 x i1> , <32 x i8> , <32 x i8> %v0 +- store <32 x i8> %sel, ptr %res +- ret void +-} +- +-define void @select_v32i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: select_v32i8: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: xvrepli.h $xr2, -256 +-; CHECK-NEXT: xvbitsel.v $xr0, $xr1, $xr0, $xr2 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <32 x i8>, ptr %a0 +- %v1 = load <32 x i8>, ptr %a1 +- %sel = select <32 x i1> , <32 x i8> %v0, <32 x i8> %v1 +- store <32 x i8> %sel, ptr %res +- ret void +-} +- +-define void @select_v16i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: select_v16i16: +-; CHECK: # %bb.0: +-; CHECK-NEXT: lu12i.w $a3, -16 +-; CHECK-NEXT: xvreplgr2vr.w $xr0, $a3 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvld $xr2, $a2, 0 +-; CHECK-NEXT: xvbitsel.v $xr0, $xr2, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i16>, ptr %a0 +- %v1 = load <16 x i16>, ptr %a1 +- %sel = select <16 x i1> , <16 x i16> %v0, <16 x i16> %v1 +- store <16 x i16> %sel, ptr %res +- ret void +-} +- +-define void @select_v8i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: select_v8i32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: xvld $xr0, $a1, 0 +-; CHECK-NEXT: xvld $xr1, $a2, 0 +-; CHECK-NEXT: ori $a1, $zero, 0 +-; CHECK-NEXT: lu32i.d $a1, -1 +-; CHECK-NEXT: xvreplgr2vr.d $xr2, $a1 +-; CHECK-NEXT: xvbitsel.v $xr0, $xr1, $xr0, $xr2 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i32>, ptr %a0 +- %v1 = load <8 x i32>, ptr %a1 +- %sel = select <8 x i1> , <8 x i32> %v0, <8 x i32> %v1 +- store <8 x i32> %sel, ptr %res +- ret void +-} +- +-define void @select_v4i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: select_v4i64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: pcalau12i $a3, %pc_hi20(.LCPI4_0) +-; CHECK-NEXT: addi.d $a3, $a3, %pc_lo12(.LCPI4_0) +-; CHECK-NEXT: xvld $xr0, $a3, 0 +-; CHECK-NEXT: xvld $xr1, $a1, 0 +-; CHECK-NEXT: xvld $xr2, $a2, 0 +-; CHECK-NEXT: xvbitsel.v $xr0, $xr2, $xr1, $xr0 +-; CHECK-NEXT: xvst $xr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i64>, ptr %a0 +- %v1 = load <4 x i64>, ptr %a1 +- %sel = select <4 x i1> , <4 x i64> %v0, <4 x i64> %v1 +- store <4 x i64> %sel, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/xvabsd.ll b/llvm/test/CodeGen/LoongArch/lasx/xvabsd.ll +new file mode 100644 +index 000000000..4c4e31f0f +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lasx/xvabsd.ll +@@ -0,0 +1,106 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lasx < %s | FileCheck %s ++ ++define <32 x i8> @xvabsd_b(<32 x i8> %a, <32 x i8> %b) { ++; CHECK-LABEL: xvabsd_b: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvabsd.b $xr0, $xr1, $xr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp sgt <32 x i8> %b, %a ++ %subba = sub <32 x i8> %b, %a ++ %subab = sub <32 x i8> %a, %b ++ %select = select <32 x i1> %icmp, <32 x i8> %subba, <32 x i8> %subab ++ ret <32 x i8> %select ++} ++ ++define <16 x i16> @xvabsd_h(<16 x i16> %a, <16 x i16> %b) { ++; CHECK-LABEL: xvabsd_h: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvabsd.h $xr0, $xr1, $xr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp sgt <16 x i16> %b, %a ++ %subba = sub <16 x i16> %b, %a ++ %subab = sub <16 x i16> %a, %b ++ %select = select <16 x i1> %icmp, <16 x i16> %subba, <16 x i16> %subab ++ ret <16 x i16> %select ++} ++ ++define <8 x i32> @xvabsd_w(<8 x i32> %a, <8 x i32> %b) { ++; CHECK-LABEL: xvabsd_w: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvabsd.w $xr0, $xr1, $xr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp sgt <8 x i32> %b, %a ++ %subba = sub <8 x i32> %b, %a ++ %subab = sub <8 x i32> %a, %b ++ %select = select <8 x i1> %icmp, <8 x i32> %subba, <8 x i32> %subab ++ ret <8 x i32> %select ++} ++ ++define <4 x i64> @xvabsd_d(<4 x i64> %a, <4 x i64> %b) { ++; CHECK-LABEL: xvabsd_d: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvabsd.d $xr0, $xr1, $xr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp sgt <4 x i64> %b, %a ++ %subba = sub <4 x i64> %b, %a ++ %subab = sub <4 x i64> %a, %b ++ %select = select <4 x i1> %icmp, <4 x i64> %subba, <4 x i64> %subab ++ ret <4 x i64> %select ++} ++ ++define <32 x i8> @xvabsd_bu(<32 x i8> %a, <32 x i8> %b) { ++; CHECK-LABEL: xvabsd_bu: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvabsd.bu $xr0, $xr1, $xr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp ugt <32 x i8> %b, %a ++ %subba = sub <32 x i8> %b, %a ++ %subab = sub <32 x i8> %a, %b ++ %select = select <32 x i1> %icmp, <32 x i8> %subba, <32 x i8> %subab ++ ret <32 x i8> %select ++} ++ ++define <16 x i16> @xvabsd_hu(<16 x i16> %a, <16 x i16> %b) { ++; CHECK-LABEL: xvabsd_hu: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvabsd.hu $xr0, $xr1, $xr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp ugt <16 x i16> %b, %a ++ %subba = sub <16 x i16> %b, %a ++ %subab = sub <16 x i16> %a, %b ++ %select = select <16 x i1> %icmp, <16 x i16> %subba, <16 x i16> %subab ++ ret <16 x i16> %select ++} ++ ++define <8 x i32> @xvabsd_wu(<8 x i32> %a, <8 x i32> %b) { ++; CHECK-LABEL: xvabsd_wu: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvabsd.wu $xr0, $xr1, $xr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp ugt <8 x i32> %b, %a ++ %subba = sub <8 x i32> %b, %a ++ %subab = sub <8 x i32> %a, %b ++ %select = select <8 x i1> %icmp, <8 x i32> %subba, <8 x i32> %subab ++ ret <8 x i32> %select ++} ++ ++define <4 x i64> @xvabsd_du(<4 x i64> %a, <4 x i64> %b) { ++; CHECK-LABEL: xvabsd_du: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvabsd.du $xr0, $xr1, $xr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp ugt <4 x i64> %b, %a ++ %subba = sub <4 x i64> %b, %a ++ %subab = sub <4 x i64> %a, %b ++ %select = select <4 x i1> %icmp, <4 x i64> %subba, <4 x i64> %subab ++ ret <4 x i64> %select ++} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/xvadda.ll b/llvm/test/CodeGen/LoongArch/lasx/xvadda.ll +new file mode 100644 +index 000000000..a849fef3e +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lasx/xvadda.ll +@@ -0,0 +1,62 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lasx < %s | FileCheck %s ++ ++define <32 x i8> @xvaddab(<32 x i8>, <32 x i8>) { ++; CHECK-LABEL: xvaddab: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvadda.b $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %3 = icmp slt <32 x i8> %0, zeroinitializer ++ %4 = sub <32 x i8> zeroinitializer, %0 ++ %5 = select <32 x i1> %3, <32 x i8> %4, <32 x i8> %0 ++ %6 = icmp slt <32 x i8> %1, zeroinitializer ++ %7 = sub <32 x i8> zeroinitializer, %1 ++ %8 = select <32 x i1> %6, <32 x i8> %7, <32 x i8> %1 ++ %9 = add <32 x i8> %5, %8 ++ ret <32 x i8> %9 ++} ++ ++define <16 x i16> @xvaddah(<16 x i16>, <16 x i16>) { ++; CHECK-LABEL: xvaddah: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvadda.h $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %3 = icmp slt <16 x i16> %0, zeroinitializer ++ %4 = sub <16 x i16> zeroinitializer, %0 ++ %5 = select <16 x i1> %3, <16 x i16> %4, <16 x i16> %0 ++ %6 = icmp slt <16 x i16> %1, zeroinitializer ++ %7 = sub <16 x i16> zeroinitializer, %1 ++ %8 = select <16 x i1> %6, <16 x i16> %7, <16 x i16> %1 ++ %9 = add <16 x i16> %5, %8 ++ ret <16 x i16> %9 ++} ++ ++define <8 x i32> @xvaddaw(<8 x i32>, <8 x i32>) { ++; CHECK-LABEL: xvaddaw: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvadda.w $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %3 = icmp slt <8 x i32> %0, zeroinitializer ++ %4 = sub nsw <8 x i32> zeroinitializer, %0 ++ %5 = select <8 x i1> %3, <8 x i32> %4, <8 x i32> %0 ++ %6 = icmp slt <8 x i32> %1, zeroinitializer ++ %7 = sub nsw <8 x i32> zeroinitializer, %1 ++ %8 = select <8 x i1> %6, <8 x i32> %7, <8 x i32> %1 ++ %9 = add nuw nsw <8 x i32> %5, %8 ++ ret <8 x i32> %9 ++} ++ ++define <4 x i64> @xvaddad(<4 x i64>, <4 x i64>) { ++; CHECK-LABEL: xvaddad: ++; CHECK: # %bb.0: ++; CHECK-NEXT: xvadda.d $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++ %3 = icmp slt <4 x i64> %0, zeroinitializer ++ %4 = sub nsw <4 x i64> zeroinitializer, %0 ++ %5 = select <4 x i1> %3, <4 x i64> %4, <4 x i64> %0 ++ %6 = icmp slt <4 x i64> %1, zeroinitializer ++ %7 = sub nsw <4 x i64> zeroinitializer, %1 ++ %8 = select <4 x i1> %6, <4 x i64> %7, <4 x i64> %1 ++ %9 = add nuw nsw <4 x i64> %5, %8 ++ ret <4 x i64> %9 ++} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/xvaddsub.ll b/llvm/test/CodeGen/LoongArch/lasx/xvaddsub.ll +new file mode 100644 +index 000000000..eb2c493d2 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lasx/xvaddsub.ll +@@ -0,0 +1,98 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lasx < %s | FileCheck %s ++ ++define <4 x i64> @svaddev(<8 x i32> %b, <8 x i32> %c) { ++; CHECK-LABEL: svaddev: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvaddwev.d.w $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = add nsw <8 x i32> %c, %b ++ %1 = shufflevector <8 x i32> %0, <8 x i32> undef, <4 x i32> ++ %2 = sext <4 x i32> %1 to <4 x i64> ++ ret <4 x i64> %2 ++} ++ ++define <4 x i64> @uvaddev(<8 x i32> %b, <8 x i32> %c) { ++; CHECK-LABEL: uvaddev: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvaddwev.d.wu $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = add <8 x i32> %c, %b ++ %1 = shufflevector <8 x i32> %0, <8 x i32> undef, <4 x i32> ++ %2 = zext <4 x i32> %1 to <4 x i64> ++ ret <4 x i64> %2 ++} ++ ++define <4 x i64> @uvsubev(<8 x i32> %b, <8 x i32> %c) { ++; CHECK-LABEL: uvsubev: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvsubwev.d.wu $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = sub <8 x i32> %b, %c ++ %1 = shufflevector <8 x i32> %0, <8 x i32> undef, <4 x i32> ++ %2 = zext <4 x i32> %1 to <4 x i64> ++ ret <4 x i64> %2 ++} ++ ++define <4 x i64> @svsubev(<8 x i32> %b, <8 x i32> %c) { ++; CHECK-LABEL: svsubev: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvsubwev.d.w $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = sub nsw <8 x i32> %b, %c ++ %1 = shufflevector <8 x i32> %0, <8 x i32> undef, <4 x i32> ++ %2 = sext <4 x i32> %1 to <4 x i64> ++ ret <4 x i64> %2 ++} ++ ++define <4 x i64> @uvaddod(<8 x i32> %b, <8 x i32> %c) { ++; CHECK-LABEL: uvaddod: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvaddwod.d.wu $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = add <8 x i32> %c, %b ++ %1 = shufflevector <8 x i32> %0, <8 x i32> undef, <4 x i32> ++ %2 = zext <4 x i32> %1 to <4 x i64> ++ ret <4 x i64> %2 ++} ++ ++define <4 x i64> @svaddod(<8 x i32> %b, <8 x i32> %c) { ++; CHECK-LABEL: svaddod: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvaddwod.d.w $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = add nsw <8 x i32> %c, %b ++ %1 = shufflevector <8 x i32> %0, <8 x i32> undef, <4 x i32> ++ %2 = sext <4 x i32> %1 to <4 x i64> ++ ret <4 x i64> %2 ++} ++ ++define <4 x i64> @uvsubod(<8 x i32> %b, <8 x i32> %c) { ++; CHECK-LABEL: uvsubod: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvsubwod.d.wu $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = sub <8 x i32> %b, %c ++ %1 = shufflevector <8 x i32> %0, <8 x i32> undef, <4 x i32> ++ %2 = zext <4 x i32> %1 to <4 x i64> ++ ret <4 x i64> %2 ++} ++ ++define <4 x i64> @svsubod(<8 x i32> %b, <8 x i32> %c) { ++; CHECK-LABEL: svsubod: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvsubwod.d.w $xr0, $xr0, $xr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = sub nsw <8 x i32> %b, %c ++ %1 = shufflevector <8 x i32> %0, <8 x i32> undef, <4 x i32> ++ %2 = sext <4 x i32> %1 to <4 x i64> ++ ret <4 x i64> %2 ++} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fcvt.ll b/llvm/test/CodeGen/LoongArch/lasx/xvfcvt.ll +similarity index 55% +rename from llvm/test/CodeGen/LoongArch/lasx/intrinsic-fcvt.ll +rename to llvm/test/CodeGen/LoongArch/lasx/xvfcvt.ll +index 82bf1d3df..dc0be96d0 100644 +--- a/llvm/test/CodeGen/LoongArch/lasx/intrinsic-fcvt.ll ++++ b/llvm/test/CodeGen/LoongArch/lasx/xvfcvt.ll +@@ -1,25 +1,13 @@ + ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py + ; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s + +-declare <16 x i16> @llvm.loongarch.lasx.xvfcvt.h.s(<8 x float>, <8 x float>) +- +-define <16 x i16> @lasx_xvfcvt_h_s(<8 x float> %va, <8 x float> %vb) nounwind { +-; CHECK-LABEL: lasx_xvfcvt_h_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: xvfcvt.h.s $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i16> @llvm.loongarch.lasx.xvfcvt.h.s(<8 x float> %va, <8 x float> %vb) +- ret <16 x i16> %res +-} +- + declare <8 x float> @llvm.loongarch.lasx.xvfcvt.s.d(<4 x double>, <4 x double>) + + define <8 x float> @lasx_xvfcvt_s_d(<4 x double> %va, <4 x double> %vb) nounwind { + ; CHECK-LABEL: lasx_xvfcvt_s_d: + ; CHECK: # %bb.0: # %entry + ; CHECK-NEXT: xvfcvt.s.d $xr0, $xr0, $xr1 +-; CHECK-NEXT: ret ++; CHECK-NEXT: jr $ra + entry: + %res = call <8 x float> @llvm.loongarch.lasx.xvfcvt.s.d(<4 x double> %va, <4 x double> %vb) + ret <8 x float> %res +diff --git a/llvm/test/CodeGen/LoongArch/lasx/xvhadd.ll b/llvm/test/CodeGen/LoongArch/lasx/xvhadd.ll +new file mode 100644 +index 000000000..5b452c5eb +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lasx/xvhadd.ll +@@ -0,0 +1,21 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lasx < %s | FileCheck %s ++ ++define <4 x i64> @mul(<4 x i64> %a, <8 x i32> %m, <8 x i32> %n) { ++; CHECK-LABEL: mul: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvhaddw.d.w $xr0, $xr1, $xr2 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = shufflevector <8 x i32> %n, <8 x i32> undef, <2 x i32> ++ %1 = shufflevector <8 x i32> %m, <8 x i32> undef, <2 x i32> ++ %2 = add nsw <2 x i32> %0, %1 ++ %3 = sext <2 x i32> %2 to <2 x i64> ++ %4 = shufflevector <8 x i32> %n, <8 x i32> undef, <2 x i32> ++ %5 = shufflevector <8 x i32> %m, <8 x i32> undef, <2 x i32> ++ %6 = add nsw <2 x i32> %4, %5 ++ %7 = sext <2 x i32> %6 to <2 x i64> ++ %vecins16 = shufflevector <2 x i64> %3, <2 x i64> %7, <4 x i32> ++ ret <4 x i64> %vecins16 ++} ++ +diff --git a/llvm/test/CodeGen/LoongArch/lasx/xvilvh.ll b/llvm/test/CodeGen/LoongArch/lasx/xvilvh.ll +new file mode 100644 +index 000000000..11f96f435 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lasx/xvilvh.ll +@@ -0,0 +1,32 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lasx < %s | FileCheck %s ++ ++define <32 x i8> @xvilvhb(<32 x i8> %vj, <32 x i8> %vk) { ++; CHECK-LABEL: xvilvhb: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvilvh.b $xr0, $xr1, $xr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %vd = shufflevector <32 x i8> %vj, <32 x i8> %vk, <32 x i32> ++ ret <32 x i8> %vd ++} ++ ++define <16 x i16> @xvilvhh(<16 x i16> %vj, <16 x i16> %vk) { ++; CHECK-LABEL: xvilvhh: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvilvh.h $xr0, $xr1, $xr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %vd = shufflevector <16 x i16> %vj, <16 x i16> %vk, <16 x i32> ++ ret <16 x i16> %vd ++} ++ ++define <8 x i32> @xvilvhw(<8 x i32> %vj, <8 x i32> %vk) { ++; CHECK-LABEL: xvilvhw: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvilvh.w $xr0, $xr1, $xr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %vd = shufflevector <8 x i32> %vj, <8 x i32> %vk, <8 x i32> ++ ret <8 x i32> %vd ++} +diff --git a/llvm/test/CodeGen/LoongArch/lasx/xvilvl.ll b/llvm/test/CodeGen/LoongArch/lasx/xvilvl.ll +new file mode 100644 +index 000000000..7249bc76c +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lasx/xvilvl.ll +@@ -0,0 +1,32 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lasx < %s | FileCheck %s ++ ++define <32 x i8> @xvilvlb(<32 x i8> %vj, <32 x i8> %vk) { ++; CHECK-LABEL: xvilvlb: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvilvl.b $xr0, $xr1, $xr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %vd = shufflevector <32 x i8> %vj, <32 x i8> %vk, <32 x i32> ++ ret <32 x i8> %vd ++} ++ ++define <16 x i16> @xvilvlh(<16 x i16> %vj, <16 x i16> %vk) { ++; CHECK-LABEL: xvilvlh: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvilvl.h $xr0, $xr1, $xr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %vd = shufflevector <16 x i16> %vj, <16 x i16> %vk, <16 x i32> ++ ret <16 x i16> %vd ++} ++ ++define <8 x i32> @xvilvlw(<8 x i32> %vj, <8 x i32> %vk) { ++; CHECK-LABEL: xvilvlw: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xvilvl.w $xr0, $xr1, $xr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %vd = shufflevector <8 x i32> %vj, <8 x i32> %vk, <8 x i32> ++ ret <8 x i32> %vd ++} +diff --git a/llvm/test/CodeGen/LoongArch/ldptr.ll b/llvm/test/CodeGen/LoongArch/ldptr.ll +index c7c2374d5..8395b264f 100644 +--- a/llvm/test/CodeGen/LoongArch/ldptr.ll ++++ b/llvm/test/CodeGen/LoongArch/ldptr.ll +@@ -1,119 +1,70 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 ++; Check whether ld.w/ld.d/ldptr.w/ldptr.d/ldx.w/ldx.d instructions are properly generated ++; RUN: llc -march=loongarch64 -o - %s | FileCheck %s + +-;; Check that ldptr.w is not emitted for small offsets. +-define signext i32 @ldptr_w_too_small_offset(ptr %p) nounwind { +-; LA32-LABEL: ldptr_w_too_small_offset: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: ld.w $a0, $a0, 2044 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ldptr_w_too_small_offset: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ld.w $a0, $a0, 2044 +-; LA64-NEXT: ret ++define signext i32 @ld_w(i32* %p) { ++; CHECK-LABEL: ld_w: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: ld.w $r4, $r4, 2044 ++; CHECK-NEXT: jr $ra + entry: +- %addr = getelementptr inbounds i32, ptr %p, i64 511 +- %val = load i32, ptr %addr, align 4 ++ %addr = getelementptr inbounds i32, i32* %p, i64 511 ++ %val = load i32, i32* %addr, align 4 + ret i32 %val + } + +-;; Check that ldptr.w is emitted for applicable offsets. +-define signext i32 @ldptr_w(ptr %p) nounwind { +-; LA32-LABEL: ldptr_w: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: addi.w $a0, $a0, 2047 +-; LA32-NEXT: addi.w $a0, $a0, 1 +-; LA32-NEXT: ld.w $a0, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ldptr_w: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ldptr.w $a0, $a0, 2048 +-; LA64-NEXT: ret ++define signext i32 @ldptr_w(i32* %p) { ++; CHECK-LABEL: ldptr_w: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: ldptr.w $r4, $r4, 2048 ++; CHECK-NEXT: jr $ra + entry: +- %addr = getelementptr inbounds i32, ptr %p, i64 512 +- %val = load i32, ptr %addr, align 4 ++ %addr = getelementptr inbounds i32, i32* %p, i64 512 ++ %val = load i32, i32* %addr, align 4 + ret i32 %val + } + +-;; Check that ldptr.w is not emitted for out-of-range offsets. +-define signext i32 @ldptr_w_too_big_offset(ptr %p) nounwind { +-; LA32-LABEL: ldptr_w_too_big_offset: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: lu12i.w $a1, 8 +-; LA32-NEXT: add.w $a0, $a0, $a1 +-; LA32-NEXT: ld.w $a0, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ldptr_w_too_big_offset: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: lu12i.w $a1, 8 +-; LA64-NEXT: ldx.w $a0, $a0, $a1 +-; LA64-NEXT: ret ++define signext i32 @ldx_w(i32* %p) { ++; CHECK-LABEL: ldx_w: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: lu12i.w $r[[REG:[0-9]+]], 8 ++; CHECK-NEXT: ldx.w $r4, $r4, $r[[REG:[0-9]+]] ++; CHECK-NEXT: jr $ra + entry: +- %addr = getelementptr inbounds i32, ptr %p, i64 8192 +- %val = load i32, ptr %addr, align 4 ++ %addr = getelementptr inbounds i32, i32* %p, i64 8192 ++ %val = load i32, i32* %addr, align 4 + ret i32 %val + } + +-;; Check that ldptr.d is not emitted for small offsets. +-define i64 @ldptr_d_too_small_offset(ptr %p) nounwind { +-; LA32-LABEL: ldptr_d_too_small_offset: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: ld.w $a2, $a0, 2040 +-; LA32-NEXT: ld.w $a1, $a0, 2044 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ldptr_d_too_small_offset: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ld.d $a0, $a0, 2040 +-; LA64-NEXT: ret ++define i64 @ld_d(i64* %p) { ++; CHECK-LABEL: ld_d: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: ld.d $r4, $r4, 2040 ++; CHECK-NEXT: jr $ra + entry: +- %addr = getelementptr inbounds i64, ptr %p, i64 255 +- %val = load i64, ptr %addr, align 8 ++ %addr = getelementptr inbounds i64, i64* %p, i64 255 ++ %val = load i64, i64* %addr, align 8 + ret i64 %val + } + +-;; Check that ldptr.d is emitted for applicable offsets. +-define i64 @ldptr_d(ptr %p) nounwind { +-; LA32-LABEL: ldptr_d: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: addi.w $a0, $a0, 2047 +-; LA32-NEXT: addi.w $a1, $a0, 1 +-; LA32-NEXT: ld.w $a0, $a1, 0 +-; LA32-NEXT: ld.w $a1, $a1, 4 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ldptr_d: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ldptr.d $a0, $a0, 2048 +-; LA64-NEXT: ret ++define i64 @ldptr_d(i64* %p) { ++; CHECK-LABEL: ldptr_d: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: ldptr.d $r4, $r4, 2048 ++; CHECK-NEXT: jr $ra + entry: +- %addr = getelementptr inbounds i64, ptr %p, i64 256 +- %val = load i64, ptr %addr, align 8 ++ %addr = getelementptr inbounds i64, i64* %p, i64 256 ++ %val = load i64, i64* %addr, align 8 + ret i64 %val + } + +-;; Check that ldptr.d is not emitted for out-of-range offsets. +-define i64 @ldptr_d_too_big_offset(ptr %p) nounwind { +-; LA32-LABEL: ldptr_d_too_big_offset: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: lu12i.w $a1, 8 +-; LA32-NEXT: add.w $a1, $a0, $a1 +-; LA32-NEXT: ld.w $a0, $a1, 0 +-; LA32-NEXT: ld.w $a1, $a1, 4 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: ldptr_d_too_big_offset: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: lu12i.w $a1, 8 +-; LA64-NEXT: ldx.d $a0, $a0, $a1 +-; LA64-NEXT: ret ++define i64 @ldx_d(i64* %p) { ++; CHECK-LABEL: ldx_d: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: lu12i.w $r[[REG:[0-9]+]], 8 ++; CHECK-NEXT: ldx.d $r4, $r4, $r[[REG:[0-9]+]] ++; CHECK-NEXT: jr $ra + entry: +- %addr = getelementptr inbounds i64, ptr %p, i64 4096 +- %val = load i64, ptr %addr, align 8 ++ %addr = getelementptr inbounds i64, i64* %p, i64 4096 ++ %val = load i64, i64* %addr, align 8 + ret i64 %val + } +diff --git a/llvm/test/CodeGen/LoongArch/ldx-stx-sp-1.ll b/llvm/test/CodeGen/LoongArch/ldx-stx-sp-1.ll +deleted file mode 100644 +index 3b8fb592e..000000000 +--- a/llvm/test/CodeGen/LoongArch/ldx-stx-sp-1.ll ++++ /dev/null +@@ -1,68 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+f < %s | FileCheck %s +- +-;; This should not crash the code generator, but the indexed loads/stores +-;; should still be present (the important part is that [f]{ld,st}x shouldn't +-;; take an $sp argument). +- +-define i8 @test_load_i(i64 %i) { +-; CHECK-LABEL: test_load_i: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: .cfi_def_cfa_offset 16 +-; CHECK-NEXT: addi.d $a1, $sp, 8 +-; CHECK-NEXT: ldx.b $a0, $a0, $a1 +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +- %1 = alloca ptr +- %2 = getelementptr inbounds i8, ptr %1, i64 %i +- %3 = load i8, ptr %2 +- ret i8 %3 +-} +- +-define float @test_load_f(i64 %i) { +-; CHECK-LABEL: test_load_f: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: .cfi_def_cfa_offset 16 +-; CHECK-NEXT: slli.d $a0, $a0, 2 +-; CHECK-NEXT: addi.d $a1, $sp, 8 +-; CHECK-NEXT: fldx.s $fa0, $a0, $a1 +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +- %1 = alloca ptr +- %2 = getelementptr inbounds float, ptr %1, i64 %i +- %3 = load float, ptr %2 +- ret float %3 +-} +- +-define void @test_store_i(i64 %i, i8 %v) { +-; CHECK-LABEL: test_store_i: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: .cfi_def_cfa_offset 16 +-; CHECK-NEXT: addi.d $a2, $sp, 8 +-; CHECK-NEXT: stx.b $a1, $a0, $a2 +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +- %1 = alloca ptr +- %2 = getelementptr inbounds i8, ptr %1, i64 %i +- store i8 %v, ptr %2, align 1 +- ret void +-} +- +-define void @test_store_f(i64 %i, float %v) { +-; CHECK-LABEL: test_store_f: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: .cfi_def_cfa_offset 16 +-; CHECK-NEXT: slli.d $a0, $a0, 2 +-; CHECK-NEXT: addi.d $a1, $sp, 8 +-; CHECK-NEXT: fstx.s $fa0, $a0, $a1 +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +- %1 = alloca ptr +- %2 = getelementptr inbounds float, ptr %1, i64 %i +- store float %v, ptr %2, align 4 +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/ldx-stx-sp-2.ll b/llvm/test/CodeGen/LoongArch/ldx-stx-sp-2.ll +deleted file mode 100644 +index be125f25a..000000000 +--- a/llvm/test/CodeGen/LoongArch/ldx-stx-sp-2.ll ++++ /dev/null +@@ -1,20 +0,0 @@ +-; RUN: llc --mtriple=loongarch32 < %s +-; RUN: llc --mtriple=loongarch64 < %s +- +-;; This should not crash the code generator. +- +-@.str.2 = external dso_local unnamed_addr constant [69 x i8], align 1 +- +-define dso_local void @main() { +-entry: +- %n0 = alloca [2 x [3 x i32]], align 4 +- %0 = load i32, ptr poison, align 4 +- %idxprom15 = sext i32 %0 to i64 +- %arrayidx16 = getelementptr inbounds [2 x [3 x i32]], ptr %n0, i64 0, i64 %idxprom15 +- %arrayidx17 = getelementptr inbounds [3 x i32], ptr %arrayidx16, i64 0, i64 0 +- %1 = load i32, ptr %arrayidx17, align 4 +- call void (ptr, ...) @printf(ptr noundef @.str.2, i32 noundef signext %1) +- ret void +-} +- +-declare void @printf(ptr, ...) +diff --git a/llvm/test/CodeGen/LoongArch/ldx-stx-sp-3.ll b/llvm/test/CodeGen/LoongArch/ldx-stx-sp-3.ll +deleted file mode 100644 +index 45d2450bd..000000000 +--- a/llvm/test/CodeGen/LoongArch/ldx-stx-sp-3.ll ++++ /dev/null +@@ -1,23 +0,0 @@ +-; RUN: llc --mtriple=loongarch32 < %s +-; RUN: llc --mtriple=loongarch64 < %s +- +-;; This should not crash the code generator. +- +-define void @_ZN12_GLOBAL__N_111DumpVisitorclIN4llvm16itanium_demangle8FoldExprEEEvPKT_() { +-entry: +- %ref.tmp6.i.i = alloca [4 x i8], align 1 +- br label %for.cond.i.i +- +-for.cond.i.i: ; preds = %for.body.i.i, %entry +- %__begin0.0.add.i.i = add nuw nsw i64 poison, 1 +- br label %for.body.i.i +- +-for.body.i.i: ; preds = %for.cond.i.i +- %__begin0.0.ptr.i.i = getelementptr inbounds i8, ptr %ref.tmp6.i.i, i64 %__begin0.0.add.i.i +- %0 = load i8, ptr %__begin0.0.ptr.i.i, align 1 +- %tobool18.not.i.i = icmp eq i8 %0, 0 +- br i1 %tobool18.not.i.i, label %for.cond.i.i, label %exit +- +-exit: ; preds = %for.body.i.i +- unreachable +-} +diff --git a/llvm/test/CodeGen/LoongArch/legalicmpimm.ll b/llvm/test/CodeGen/LoongArch/legalicmpimm.ll +deleted file mode 100644 +index 3dc878563..000000000 +--- a/llvm/test/CodeGen/LoongArch/legalicmpimm.ll ++++ /dev/null +@@ -1,23 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-define i32 @icmpimm(i32 %x) { +-; LA32-LABEL: icmpimm: +-; LA32: # %bb.0: +-; LA32-NEXT: srli.w $a0, $a0, 12 +-; LA32-NEXT: addi.w $a0, $a0, -1 +-; LA32-NEXT: sltui $a0, $a0, 1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: icmpimm: +-; LA64: # %bb.0: +-; LA64-NEXT: bstrpick.d $a0, $a0, 31, 12 +-; LA64-NEXT: addi.d $a0, $a0, -1 +-; LA64-NEXT: sltui $a0, $a0, 1 +-; LA64-NEXT: ret +- %1 = and i32 %x, -4096 +- %2 = icmp eq i32 %1, 4096 +- %3 = zext i1 %2 to i32 +- ret i32 %3 +-} +diff --git a/llvm/test/CodeGen/LoongArch/lit.local.cfg b/llvm/test/CodeGen/LoongArch/lit.local.cfg +index bc630dbef..6223fc691 100644 +--- a/llvm/test/CodeGen/LoongArch/lit.local.cfg ++++ b/llvm/test/CodeGen/LoongArch/lit.local.cfg +@@ -1,16 +1,3 @@ +-import os +- +-config.suffixes = [".ll", ".mir", ".test", ".txt"] +- +-extract_section_path = os.path.join(config.llvm_src_root, "utils", "extract-section.py") +- +-config.substitutions.append( +- ( +- "extract-section", +- "'%s' %s %s" +- % (config.python_executable, extract_section_path, "--bits-endian little"), +- ) +-) +- +-if not "LoongArch" in config.root.targets: ++if not 'LoongArch' in config.root.targets: + config.unsupported = True ++ +diff --git a/llvm/test/CodeGen/LoongArch/llvm-ir/ashr.ll b/llvm/test/CodeGen/LoongArch/llvm-ir/ashr.ll +new file mode 100644 +index 000000000..73f792a9f +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/llvm-ir/ashr.ll +@@ -0,0 +1,81 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 ++; RUN: llc < %s --mtriple=loongarch64 | FileCheck %s ++ ++define signext i1 @ashr_i1(i1 signext %a, i1 signext %b) { ++; CHECK-LABEL: ashr_i1: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: # kill: def $a0 killed $a0 killed $a0_64 ++; CHECK-NEXT: jr $ra ++entry: ++ %r = ashr i1 %a, %b ++ ret i1 %r ++} ++ ++define signext i8 @ashr_i8(i8 signext %a, i8 signext %b) { ++; CHECK-LABEL: ashr_i8: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: andi $r5, $r5, 255 ++; CHECK-NEXT: sra.w $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %r = ashr i8 %a, %b ++ ret i8 %r ++} ++ ++define signext i16 @ashr_i16(i16 signext %a, i16 signext %b) { ++; CHECK-LABEL: ashr_i16: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: bstrpick.w $r5, $r5, 15, 0 ++; CHECK-NEXT: sra.w $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %r = ashr i16 %a, %b ++ ret i16 %r ++} ++ ++define signext i32 @ashr_i32(i32 signext %a, i32 signext %b) { ++; CHECK-LABEL: ashr_i32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: sra.w $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %r = ashr i32 %a, %b ++ ret i32 %r ++} ++ ++define signext i64 @ashr_i64(i64 signext %a, i64 signext %b) { ++; CHECK-LABEL: ashr_i64: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: sra.d $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %r = ashr i64 %a, %b ++ ret i64 %r ++} ++ ++define signext i128 @ashr_i128(i128 signext %a, i128 signext %b) { ++; CHECK-LABEL: ashr_i128: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: slli.w $r7, $r6, 0 ++; CHECK-NEXT: sra.d $r8, $r5, $r7 ++; CHECK-NEXT: andi $r6, $r7, 64 ++; CHECK-NEXT: slli.w $r9, $r6, 0 ++; CHECK-NEXT: masknez $r6, $r8, $r9 ++; CHECK-NEXT: srai.d $r10, $r5, 63 ++; CHECK-NEXT: maskeqz $r10, $r10, $r9 ++; CHECK-NEXT: or $r6, $r10, $r6 ++; CHECK-NEXT: srl.d $r4, $r4, $r7 ++; CHECK-NEXT: slli.d $r5, $r5, 1 ++; CHECK-NEXT: xori $r7, $r7, 63 ++; CHECK-NEXT: sll.d $r5, $r5, $r7 ++; CHECK-NEXT: or $r4, $r5, $r4 ++; CHECK-NEXT: masknez $r4, $r4, $r9 ++; CHECK-NEXT: maskeqz $r5, $r8, $r9 ++; CHECK-NEXT: or $r4, $r5, $r4 ++; CHECK-NEXT: move $r5, $r6 ++; CHECK-NEXT: jr $ra ++entry: ++ %r = ashr i128 %a, %b ++ ret i128 %r ++} +diff --git a/llvm/test/CodeGen/LoongArch/llvm-ir/lshr.ll b/llvm/test/CodeGen/LoongArch/llvm-ir/lshr.ll +new file mode 100644 +index 000000000..6401c6fcf +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/llvm-ir/lshr.ll +@@ -0,0 +1,79 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 ++; RUN: llc < %s --mtriple=loongarch64 | FileCheck %s ++ ++define signext i1 @lshr_i1(i1 signext %a, i1 signext %b) { ++; CHECK-LABEL: lshr_i1: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: # kill: def $a0 killed $a0 killed $a0_64 ++; CHECK-NEXT: jr $ra ++entry: ++ %r = lshr i1 %a, %b ++ ret i1 %r ++} ++ ++define zeroext i8 @lshr_i8(i8 zeroext %a, i8 zeroext %b) { ++; CHECK-LABEL: lshr_i8: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: srl.w $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %r = lshr i8 %a, %b ++ ret i8 %r ++} ++ ++define zeroext i16 @lshr_i16(i16 zeroext %a, i16 zeroext %b) { ++; CHECK-LABEL: lshr_i16: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: srl.w $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %r = lshr i16 %a, %b ++ ret i16 %r ++} ++ ++define signext i32 @lshr_i32(i32 signext %a, i32 signext %b) { ++; CHECK-LABEL: lshr_i32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: srl.w $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %r = lshr i32 %a, %b ++ ret i32 %r ++} ++ ++define signext i64 @lshr_i64(i64 signext %a, i64 signext %b) { ++; CHECK-LABEL: lshr_i64: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: srl.d $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %r = lshr i64 %a, %b ++ ret i64 %r ++} ++ ++define signext i128 @lshr_i128(i128 signext %a, i128 signext %b) { ++; CHECK-LABEL: lshr_i128: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: slli.w $r7, $r6, 0 ++; CHECK-NEXT: srl.d $r8, $r5, $r7 ++; CHECK-NEXT: andi $r6, $r7, 64 ++; CHECK-NEXT: slli.w $r9, $r6, 0 ++; CHECK-NEXT: masknez $r6, $r8, $r9 ++; CHECK-NEXT: addi.d $r10, $zero, 0 ++; CHECK-NEXT: maskeqz $r10, $r10, $r9 ++; CHECK-NEXT: or $r6, $r10, $r6 ++; CHECK-NEXT: srl.d $r4, $r4, $r7 ++; CHECK-NEXT: slli.d $r5, $r5, 1 ++; CHECK-NEXT: xori $r7, $r7, 63 ++; CHECK-NEXT: sll.d $r5, $r5, $r7 ++; CHECK-NEXT: or $r4, $r5, $r4 ++; CHECK-NEXT: masknez $r4, $r4, $r9 ++; CHECK-NEXT: maskeqz $r5, $r8, $r9 ++; CHECK-NEXT: or $r4, $r5, $r4 ++; CHECK-NEXT: move $r5, $r6 ++; CHECK-NEXT: jr $ra ++entry: ++ %r = lshr i128 %a, %b ++ ret i128 %r ++} +diff --git a/llvm/test/CodeGen/LoongArch/llvm-ir/shl.ll b/llvm/test/CodeGen/LoongArch/llvm-ir/shl.ll +new file mode 100644 +index 000000000..c06149259 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/llvm-ir/shl.ll +@@ -0,0 +1,83 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 ++; RUN: llc < %s --mtriple=loongarch64 | FileCheck %s ++ ++define signext i1 @shl_i1(i1 signext %a, i1 signext %b) { ++; CHECK-LABEL: shl_i1: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: # kill: def $a0 killed $a0 killed $a0_64 ++; CHECK-NEXT: jr $ra ++entry: ++ %r = shl i1 %a, %b ++ ret i1 %r ++} ++ ++define signext i8 @shl_i8(i8 signext %a, i8 signext %b) { ++; CHECK-LABEL: shl_i8: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: andi $r5, $r5, 255 ++; CHECK-NEXT: sll.w $r4, $r4, $r5 ++; CHECK-NEXT: ext.w.b $r4, $r4 ++; CHECK-NEXT: jr $ra ++entry: ++ %r = shl i8 %a, %b ++ ret i8 %r ++} ++ ++define signext i16 @shl_i16(i16 signext %a, i16 signext %b) { ++; CHECK-LABEL: shl_i16: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: bstrpick.w $r5, $r5, 15, 0 ++; CHECK-NEXT: sll.w $r4, $r4, $r5 ++; CHECK-NEXT: ext.w.h $r4, $r4 ++; CHECK-NEXT: jr $ra ++entry: ++ %r = shl i16 %a, %b ++ ret i16 %r ++} ++ ++define signext i32 @shl_i32(i32 signext %a, i32 signext %b) { ++; CHECK-LABEL: shl_i32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: sll.w $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %r = shl i32 %a, %b ++ ret i32 %r ++} ++ ++define signext i64 @shl_i64(i64 signext %a, i64 signext %b) { ++; CHECK-LABEL: shl_i64: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: sll.d $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %r = shl i64 %a, %b ++ ret i64 %r ++} ++ ++define signext i128 @shl_i128(i128 signext %a, i128 signext %b) { ++; CHECK-LABEL: shl_i128: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: slli.w $r7, $r6, 0 ++; CHECK-NEXT: sll.d $r8, $r4, $r7 ++; CHECK-NEXT: andi $r6, $r7, 64 ++; CHECK-NEXT: slli.w $r9, $r6, 0 ++; CHECK-NEXT: masknez $r6, $r8, $r9 ++; CHECK-NEXT: addi.d $r10, $zero, 0 ++; CHECK-NEXT: maskeqz $r10, $r10, $r9 ++; CHECK-NEXT: or $r6, $r10, $r6 ++; CHECK-NEXT: sll.d $r5, $r5, $r7 ++; CHECK-NEXT: srli.d $r4, $r4, 1 ++; CHECK-NEXT: xori $r7, $r7, 63 ++; CHECK-NEXT: srl.d $r4, $r4, $r7 ++; CHECK-NEXT: or $r4, $r5, $r4 ++; CHECK-NEXT: masknez $r4, $r4, $r9 ++; CHECK-NEXT: maskeqz $r5, $r8, $r9 ++; CHECK-NEXT: or $r5, $r5, $r4 ++; CHECK-NEXT: move $r4, $r6 ++; CHECK-NEXT: jr $ra ++entry: ++ %r = shl i128 %a, %b ++ ret i128 %r ++} +diff --git a/llvm/test/CodeGen/LoongArch/load-store-atomic.ll b/llvm/test/CodeGen/LoongArch/load-store-atomic.ll +new file mode 100644 +index 000000000..414d4078b +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/load-store-atomic.ll +@@ -0,0 +1,310 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s ++ ++define i8 @load_acquire_i8(ptr %ptr) { ++; CHECK-LABEL: load_acquire_i8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.b $r4, $r4, 0 ++; CHECK-NEXT: dbar 20 ++; CHECK-NEXT: jr $ra ++ %val = load atomic i8, ptr %ptr acquire, align 1 ++ ret i8 %val ++} ++ ++define i16 @load_acquire_i16(ptr %ptr) { ++; CHECK-LABEL: load_acquire_i16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.h $r4, $r4, 0 ++; CHECK-NEXT: dbar 20 ++; CHECK-NEXT: jr $ra ++ %val = load atomic i16, ptr %ptr acquire, align 2 ++ ret i16 %val ++} ++ ++define i32 @load_acquire_i32(ptr %ptr) { ++; CHECK-LABEL: load_acquire_i32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.w $r4, $r4, 0 ++; CHECK-NEXT: dbar 20 ++; CHECK-NEXT: jr $ra ++ %val = load atomic i32, ptr %ptr acquire, align 4 ++ ret i32 %val ++} ++ ++define i64 @load_acquire_i64(ptr %ptr) { ++; CHECK-LABEL: load_acquire_i64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.d $r4, $r4, 0 ++; CHECK-NEXT: dbar 20 ++; CHECK-NEXT: jr $ra ++ %val = load atomic i64, ptr %ptr acquire, align 8 ++ ret i64 %val ++} ++ ++define i8 @load_unordered_i8(ptr %ptr) { ++; CHECK-LABEL: load_unordered_i8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.b $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ %val = load atomic i8, ptr %ptr unordered, align 1 ++ ret i8 %val ++} ++ ++define i16 @load_unordered_i16(ptr %ptr) { ++; CHECK-LABEL: load_unordered_i16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.h $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ %val = load atomic i16, ptr %ptr unordered, align 2 ++ ret i16 %val ++} ++ ++define i32 @load_unordered_i32(ptr %ptr) { ++; CHECK-LABEL: load_unordered_i32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.w $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ %val = load atomic i32, ptr %ptr unordered, align 4 ++ ret i32 %val ++} ++ ++define i64 @load_unordered_i64(ptr %ptr) { ++; CHECK-LABEL: load_unordered_i64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ %val = load atomic i64, ptr %ptr unordered, align 8 ++ ret i64 %val ++} ++ ++define i8 @load_monotonic_i8(ptr %ptr) { ++; CHECK-LABEL: load_monotonic_i8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.b $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ %val = load atomic i8, ptr %ptr monotonic, align 1 ++ ret i8 %val ++} ++ ++define i16 @load_monotonic_i16(ptr %ptr) { ++; CHECK-LABEL: load_monotonic_i16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.h $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ %val = load atomic i16, ptr %ptr monotonic, align 2 ++ ret i16 %val ++} ++ ++define i32 @load_monotonic_i32(ptr %ptr) { ++; CHECK-LABEL: load_monotonic_i32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.w $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ %val = load atomic i32, ptr %ptr monotonic, align 4 ++ ret i32 %val ++} ++ ++define i64 @load_monotonic_i64(ptr %ptr) { ++; CHECK-LABEL: load_monotonic_i64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.d $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ %val = load atomic i64, ptr %ptr monotonic, align 8 ++ ret i64 %val ++} ++ ++define i8 @load_seq_cst_i8(ptr %ptr) { ++; CHECK-LABEL: load_seq_cst_i8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.b $r4, $r4, 0 ++; CHECK-NEXT: dbar 16 ++; CHECK-NEXT: jr $ra ++ %val = load atomic i8, ptr %ptr seq_cst, align 1 ++ ret i8 %val ++} ++ ++define i16 @load_seq_cst_i16(ptr %ptr) { ++; CHECK-LABEL: load_seq_cst_i16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.h $r4, $r4, 0 ++; CHECK-NEXT: dbar 16 ++; CHECK-NEXT: jr $ra ++ %val = load atomic i16, ptr %ptr seq_cst, align 2 ++ ret i16 %val ++} ++ ++define i32 @load_seq_cst_i32(ptr %ptr) { ++; CHECK-LABEL: load_seq_cst_i32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.w $r4, $r4, 0 ++; CHECK-NEXT: dbar 16 ++; CHECK-NEXT: jr $ra ++ %val = load atomic i32, ptr %ptr seq_cst, align 4 ++ ret i32 %val ++} ++ ++define i64 @load_seq_cst_i64(ptr %ptr) { ++; CHECK-LABEL: load_seq_cst_i64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.d $r4, $r4, 0 ++; CHECK-NEXT: dbar 16 ++; CHECK-NEXT: jr $ra ++ %val = load atomic i64, ptr %ptr seq_cst, align 8 ++ ret i64 %val ++} ++ ++define void @store_release_i8(ptr %ptr, i8 signext %v) { ++; CHECK-LABEL: store_release_i8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: dbar 18 ++; CHECK-NEXT: st.b $r5, $r4, 0 ++; CHECK-NEXT: jr $ra ++ store atomic i8 %v, ptr %ptr release, align 1 ++ ret void ++} ++ ++define void @store_release_i16(ptr %ptr, i16 signext %v) { ++; CHECK-LABEL: store_release_i16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: dbar 18 ++; CHECK-NEXT: st.h $r5, $r4, 0 ++; CHECK-NEXT: jr $ra ++ store atomic i16 %v, ptr %ptr release, align 2 ++ ret void ++} ++ ++define void @store_release_i32(ptr %ptr, i32 signext %v) { ++; CHECK-LABEL: store_release_i32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: dbar 18 ++; CHECK-NEXT: st.w $r5, $r4, 0 ++; CHECK-NEXT: jr $ra ++ store atomic i32 %v, ptr %ptr release, align 4 ++ ret void ++} ++ ++define void @store_release_i64(ptr %ptr, i64 %v) { ++; CHECK-LABEL: store_release_i64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: dbar 18 ++; CHECK-NEXT: st.d $r5, $r4, 0 ++; CHECK-NEXT: jr $ra ++ store atomic i64 %v, ptr %ptr release, align 8 ++ ret void ++} ++ ++define void @store_unordered_i8(ptr %ptr, i8 signext %v) { ++; CHECK-LABEL: store_unordered_i8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: st.b $r5, $r4, 0 ++; CHECK-NEXT: jr $ra ++ store atomic i8 %v, ptr %ptr unordered, align 1 ++ ret void ++} ++ ++define void @store_unordered_i16(ptr %ptr, i16 signext %v) { ++; CHECK-LABEL: store_unordered_i16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: st.h $r5, $r4, 0 ++; CHECK-NEXT: jr $ra ++ store atomic i16 %v, ptr %ptr unordered, align 2 ++ ret void ++} ++ ++define void @store_unordered_i32(ptr %ptr, i32 signext %v) { ++; CHECK-LABEL: store_unordered_i32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: st.w $r5, $r4, 0 ++; CHECK-NEXT: jr $ra ++ store atomic i32 %v, ptr %ptr unordered, align 4 ++ ret void ++} ++ ++define void @store_unordered_i64(ptr %ptr, i64 %v) { ++; CHECK-LABEL: store_unordered_i64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: st.d $r5, $r4, 0 ++; CHECK-NEXT: jr $ra ++ store atomic i64 %v, ptr %ptr unordered, align 8 ++ ret void ++} ++ ++define void @store_monotonic_i8(ptr %ptr, i8 signext %v) { ++; CHECK-LABEL: store_monotonic_i8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: st.b $r5, $r4, 0 ++; CHECK-NEXT: jr $ra ++ store atomic i8 %v, ptr %ptr monotonic, align 1 ++ ret void ++} ++ ++define void @store_monotonic_i16(ptr %ptr, i16 signext %v) { ++; CHECK-LABEL: store_monotonic_i16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: st.h $r5, $r4, 0 ++; CHECK-NEXT: jr $ra ++ store atomic i16 %v, ptr %ptr monotonic, align 2 ++ ret void ++} ++ ++define void @store_monotonic_i32(ptr %ptr, i32 signext %v) { ++; CHECK-LABEL: store_monotonic_i32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: st.w $r5, $r4, 0 ++; CHECK-NEXT: jr $ra ++ store atomic i32 %v, ptr %ptr monotonic, align 4 ++ ret void ++} ++ ++define void @store_monotonic_i64(ptr %ptr, i64 %v) { ++; CHECK-LABEL: store_monotonic_i64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: st.d $r5, $r4, 0 ++; CHECK-NEXT: jr $ra ++ store atomic i64 %v, ptr %ptr monotonic, align 8 ++ ret void ++} ++ ++define void @store_seq_cst_i8(ptr %ptr, i8 signext %v) { ++; CHECK-LABEL: store_seq_cst_i8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: dbar 16 ++; CHECK-NEXT: st.b $r5, $r4, 0 ++; CHECK-NEXT: dbar 16 ++; CHECK-NEXT: jr $ra ++ store atomic i8 %v, ptr %ptr seq_cst, align 1 ++ ret void ++} ++ ++define void @store_seq_cst_i16(ptr %ptr, i16 signext %v) { ++; CHECK-LABEL: store_seq_cst_i16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: dbar 16 ++; CHECK-NEXT: st.h $r5, $r4, 0 ++; CHECK-NEXT: dbar 16 ++; CHECK-NEXT: jr $ra ++ store atomic i16 %v, ptr %ptr seq_cst, align 2 ++ ret void ++} ++ ++define void @store_seq_cst_i32(ptr %ptr, i32 signext %v) { ++; CHECK-LABEL: store_seq_cst_i32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: dbar 16 ++; CHECK-NEXT: st.w $r5, $r4, 0 ++; CHECK-NEXT: dbar 16 ++; CHECK-NEXT: jr $ra ++ store atomic i32 %v, ptr %ptr seq_cst, align 4 ++ ret void ++} ++ ++define void @store_seq_cst_i64(ptr %ptr, i64 %v) { ++; CHECK-LABEL: store_seq_cst_i64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: dbar 16 ++; CHECK-NEXT: st.d $r5, $r4, 0 ++; CHECK-NEXT: dbar 16 ++; CHECK-NEXT: jr $ra ++ store atomic i64 %v, ptr %ptr seq_cst, align 8 ++ ret void ++} +diff --git a/llvm/test/CodeGen/LoongArch/load-store-offset.ll b/llvm/test/CodeGen/LoongArch/load-store-offset.ll +deleted file mode 100644 +index 68777dfe0..000000000 +--- a/llvm/test/CodeGen/LoongArch/load-store-offset.ll ++++ /dev/null +@@ -1,159 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-define i8 @load_i8() nounwind { +-; LA32-LABEL: load_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.b $a0, $zero, 40 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.b $a0, $zero, 40 +-; LA64-NEXT: ret +- %a = load i8, ptr inttoptr (i64 40 to ptr), align 8 +- ret i8 %a +-} +- +-define signext i8 @load_i8_sext() nounwind { +-; LA32-LABEL: load_i8_sext: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.b $a0, $zero, 40 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_i8_sext: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.b $a0, $zero, 40 +-; LA64-NEXT: ret +- %a = load i8, ptr inttoptr (i64 40 to ptr), align 8 +- ret i8 %a +-} +- +-define i16 @load_i16() nounwind { +-; LA32-LABEL: load_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.h $a0, $zero, 40 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.h $a0, $zero, 40 +-; LA64-NEXT: ret +- %a = load i16, ptr inttoptr (i64 40 to ptr), align 8 +- ret i16 %a +-} +- +-define signext i16 @load_i16_sext() nounwind { +-; LA32-LABEL: load_i16_sext: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.h $a0, $zero, 40 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_i16_sext: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.h $a0, $zero, 40 +-; LA64-NEXT: ret +- %a = load i16, ptr inttoptr (i64 40 to ptr), align 8 +- ret i16 %a +-} +- +-define i32 @load_i32() nounwind { +-; LA32-LABEL: load_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a0, $zero, 40 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.w $a0, $zero, 40 +-; LA64-NEXT: ret +- %a = load i32, ptr inttoptr (i64 40 to ptr), align 8 +- ret i32 %a +-} +- +-define signext i32 @load_i32_sext() nounwind { +-; LA32-LABEL: load_i32_sext: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a0, $zero, 40 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_i32_sext: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.w $a0, $zero, 40 +-; LA64-NEXT: ret +- %a = load i32, ptr inttoptr (i64 40 to ptr), align 8 +- ret i32 %a +-} +- +-define i64 @load_i64() nounwind { +-; LA32-LABEL: load_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.w $a0, $zero, 40 +-; LA32-NEXT: ld.w $a1, $zero, 44 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.d $a0, $zero, 40 +-; LA64-NEXT: ret +- %a = load i64, ptr inttoptr (i64 40 to ptr), align 8 +- ret i64 %a +-} +- +-define void @store_i8(i8 %v) nounwind { +-; LA32-LABEL: store_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: st.b $a0, $zero, 40 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: store_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: st.b $a0, $zero, 40 +-; LA64-NEXT: ret +- store i8 %v, ptr inttoptr (i64 40 to ptr), align 8 +- ret void +-} +- +-define void @store_i16(i16 %v) nounwind { +-; LA32-LABEL: store_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: st.h $a0, $zero, 40 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: store_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: st.h $a0, $zero, 40 +-; LA64-NEXT: ret +- store i16 %v, ptr inttoptr (i64 40 to ptr), align 8 +- ret void +-} +- +-define void @store_i32(i32 %v) nounwind { +-; LA32-LABEL: store_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: st.w $a0, $zero, 40 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: store_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: st.w $a0, $zero, 40 +-; LA64-NEXT: ret +- store i32 %v, ptr inttoptr (i64 40 to ptr), align 8 +- ret void +-} +- +-define void @store_i64(i64 %v) nounwind { +-; LA32-LABEL: store_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: st.w $a1, $zero, 44 +-; LA32-NEXT: st.w $a0, $zero, 40 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: store_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: st.d $a0, $zero, 40 +-; LA64-NEXT: ret +- store i64 %v, ptr inttoptr (i64 40 to ptr), align 8 +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/logic-op.ll b/llvm/test/CodeGen/LoongArch/logic-op.ll +new file mode 100644 +index 000000000..c1029c1ff +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/logic-op.ll +@@ -0,0 +1,171 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 < %s | FileCheck %s ++ ++define signext i32 @foo32(i32 signext %a) { ++; CHECK-LABEL: foo32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: sltui $r4, $r4, 1 ++; CHECK-NEXT: jr $ra ++entry: ++ %tobool = icmp eq i32 %a, 0 ++ %conv = zext i1 %tobool to i32 ++ ret i32 %conv ++} ++ ++define i64 @foo(i64 %a) { ++; CHECK-LABEL: foo: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: sltui $r4, $r4, 1 ++; CHECK-NEXT: jr $ra ++entry: ++ %tobool = icmp eq i64 %a, 0 ++ %conv = zext i1 %tobool to i64 ++ ret i64 %conv ++} ++ ++define i64 @not(i64 %a) { ++; CHECK-LABEL: not: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: nor $r4, $zero, $r4 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor i64 %a, -1 ++ ret i64 %not ++} ++ ++define i64 @and(i64 %a, i64 %b) { ++; CHECK-LABEL: and: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: and $r4, $r5, $r4 ++; CHECK-NEXT: jr $ra ++entry: ++ %and = and i64 %b, %a ++ ret i64 %and ++} ++ ++define i64 @or(i64 %a, i64 %b) { ++; CHECK-LABEL: or: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: or $r4, $r5, $r4 ++; CHECK-NEXT: jr $ra ++entry: ++ %or = or i64 %b, %a ++ ret i64 %or ++} ++ ++define i64 @xor(i64 %a, i64 %b) { ++; CHECK-LABEL: xor: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xor $r4, $r5, $r4 ++; CHECK-NEXT: jr $ra ++entry: ++ %xor = xor i64 %b, %a ++ ret i64 %xor ++} ++ ++define i64 @nor(i64 %a, i64 %b) { ++; CHECK-LABEL: nor: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: nor $r4, $r5, $r4 ++; CHECK-NEXT: jr $ra ++entry: ++ %or = or i64 %b, %a ++ %not = xor i64 %or, -1 ++ ret i64 %not ++} ++ ++define i64 @andn(i64 %a, i64 %b) { ++; CHECK-LABEL: andn: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: andn $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor i64 %b, -1 ++ %and = and i64 %not, %a ++ ret i64 %and ++} ++ ++define signext i32 @andn32(i32 signext %a, i32 signext %b) { ++; CHECK-LABEL: andn32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: andn $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor i32 %b, -1 ++ %and = and i32 %not, %a ++ ret i32 %and ++} ++ ++define i64 @orn(i64 %a, i64 %b) { ++; CHECK-LABEL: orn: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: orn $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor i64 %b, -1 ++ %or = or i64 %not, %a ++ ret i64 %or ++} ++ ++define signext i32 @orn32(i32 signext %a, i32 signext %b) { ++; CHECK-LABEL: orn32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: orn $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor i32 %b, -1 ++ %or = or i32 %not, %a ++ ret i32 %or ++} ++ ++define signext i32 @and32(i32 signext %a, i32 signext %b) { ++; CHECK-LABEL: and32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: and $r4, $r5, $r4 ++; CHECK-NEXT: jr $ra ++entry: ++ %and = and i32 %b, %a ++ ret i32 %and ++} ++ ++define signext i32 @or32(i32 signext %a, i32 signext %b) { ++; CHECK-LABEL: or32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: or $r4, $r5, $r4 ++; CHECK-NEXT: jr $ra ++entry: ++ %or = or i32 %b, %a ++ ret i32 %or ++} ++ ++define signext i32 @xor32(i32 signext %a, i32 signext %b) { ++; CHECK-LABEL: xor32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: xor $r4, $r5, $r4 ++; CHECK-NEXT: jr $ra ++entry: ++ %xor = xor i32 %b, %a ++ ret i32 %xor ++} ++ ++define signext i32 @nor32(i32 signext %a, i32 signext %b) { ++; CHECK-LABEL: nor32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: nor $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %or = or i32 %b, %a ++ %not = xor i32 %or, -1 ++ ret i32 %not ++} ++ ++define signext i32 @not32(i32 signext %a) { ++; CHECK-LABEL: not32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: nor $r4, $zero, $r4 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor i32 %a, -1 ++ ret i32 %not ++} ++ +diff --git a/llvm/test/CodeGen/LoongArch/lshr.ll b/llvm/test/CodeGen/LoongArch/lshr.ll +new file mode 100644 +index 000000000..54e4a5f2d +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lshr.ll +@@ -0,0 +1,12 @@ ++; RUN: llc -march=loongarch64 < %s | FileCheck %s ++ ++define signext i32 @foo(i32 %a) { ++; CHECK-LABEL: foo: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: bstrpick.d $r4, $r4, 31, 1 ++; CHECK-NEXT: jr $ra ++entry: ++ %b = lshr i32 %a, 1 ++ ret i32 %b ++} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/build-vector.ll b/llvm/test/CodeGen/LoongArch/lsx/build-vector.ll +deleted file mode 100644 +index ed1f610a5..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/build-vector.ll ++++ /dev/null +@@ -1,398 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @buildvector_v16i8_splat(ptr %dst, i8 %a0) nounwind { +-; CHECK-LABEL: buildvector_v16i8_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vreplgr2vr.b $vr0, $a1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %insert = insertelement <16 x i8> undef, i8 %a0, i8 0 +- %splat = shufflevector <16 x i8> %insert, <16 x i8> undef, <16 x i32> zeroinitializer +- store <16 x i8> %splat, ptr %dst +- ret void +-} +- +-define void @buildvector_v8i16_splat(ptr %dst, i16 %a0) nounwind { +-; CHECK-LABEL: buildvector_v8i16_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vreplgr2vr.h $vr0, $a1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %insert = insertelement <8 x i16> undef, i16 %a0, i8 0 +- %splat = shufflevector <8 x i16> %insert, <8 x i16> undef, <8 x i32> zeroinitializer +- store <8 x i16> %splat, ptr %dst +- ret void +-} +- +-define void @buildvector_v4i32_splat(ptr %dst, i32 %a0) nounwind { +-; CHECK-LABEL: buildvector_v4i32_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vreplgr2vr.w $vr0, $a1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %insert = insertelement <4 x i32> undef, i32 %a0, i8 0 +- %splat = shufflevector <4 x i32> %insert, <4 x i32> undef, <4 x i32> zeroinitializer +- store <4 x i32> %splat, ptr %dst +- ret void +-} +- +-define void @buildvector_v2i64_splat(ptr %dst, i64 %a0) nounwind { +-; CHECK-LABEL: buildvector_v2i64_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vreplgr2vr.d $vr0, $a1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %insert = insertelement <2 x i64> undef, i64 %a0, i8 0 +- %splat = shufflevector <2 x i64> %insert, <2 x i64> undef, <2 x i32> zeroinitializer +- store <2 x i64> %splat, ptr %dst +- ret void +-} +- +-define void @buildvector_v4f32_splat(ptr %dst, float %a0) nounwind { +-; CHECK-LABEL: buildvector_v4f32_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: # kill: def $f0 killed $f0 def $vr0 +-; CHECK-NEXT: vreplvei.w $vr0, $vr0, 0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %insert = insertelement <4 x float> undef, float %a0, i8 0 +- %splat = shufflevector <4 x float> %insert, <4 x float> undef, <4 x i32> zeroinitializer +- store <4 x float> %splat, ptr %dst +- ret void +-} +- +-define void @buildvector_v2f64_splat(ptr %dst, double %a0) nounwind { +-; CHECK-LABEL: buildvector_v2f64_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: # kill: def $f0_64 killed $f0_64 def $vr0 +-; CHECK-NEXT: vreplvei.d $vr0, $vr0, 0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %insert = insertelement <2 x double> undef, double %a0, i8 0 +- %splat = shufflevector <2 x double> %insert, <2 x double> undef, <2 x i32> zeroinitializer +- store <2 x double> %splat, ptr %dst +- ret void +-} +- +-define void @buildvector_v16i8_const_splat(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v16i8_const_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vrepli.b $vr0, 1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <16 x i8> , ptr %dst +- ret void +-} +- +-define void @buildvector_v8i16_const_splat(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v8i16_const_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vrepli.h $vr0, 1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <8 x i16> , ptr %dst +- ret void +-} +- +-define void @buildvector_v4i32_const_splat(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v4i32_const_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vrepli.w $vr0, 1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <4 x i32> , ptr %dst +- ret void +-} +- +-define void @buildvector_v2i64_const_splat(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v2i64_const_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vrepli.d $vr0, 1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <2 x i64> , ptr %dst +- ret void +-} +- +-define void @buildvector_v2f32_const_splat(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v2f32_const_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: lu12i.w $a1, 260096 +-; CHECK-NEXT: vreplgr2vr.w $vr0, $a1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <4 x float> , ptr %dst +- ret void +-} +- +-define void @buildvector_v2f64_const_splat(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v2f64_const_splat: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: lu52i.d $a1, $zero, 1023 +-; CHECK-NEXT: vreplgr2vr.d $vr0, $a1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <2 x double> , ptr %dst +- ret void +-} +- +-define void @buildvector_v16i8_const(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v16i8_const: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: pcalau12i $a1, %pc_hi20(.LCPI12_0) +-; CHECK-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI12_0) +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <16 x i8> , ptr %dst +- ret void +-} +- +-define void @buildvector_v8i16_const(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v8i16_const: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: pcalau12i $a1, %pc_hi20(.LCPI13_0) +-; CHECK-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI13_0) +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <8 x i16> , ptr %dst +- ret void +-} +- +-define void @buildvector_v4i32_const(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v4i32_const: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: pcalau12i $a1, %pc_hi20(.LCPI14_0) +-; CHECK-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI14_0) +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <4 x i32> , ptr %dst +- ret void +-} +- +-define void @buildvector_v2i64_const(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v2i64_const: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: pcalau12i $a1, %pc_hi20(.LCPI15_0) +-; CHECK-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI15_0) +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <2 x i64> , ptr %dst +- ret void +-} +- +-define void @buildvector_v2f32_const(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v2f32_const: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: pcalau12i $a1, %pc_hi20(.LCPI16_0) +-; CHECK-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI16_0) +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <4 x float> , ptr %dst +- ret void +-} +- +-define void @buildvector_v2f64_const(ptr %dst) nounwind { +-; CHECK-LABEL: buildvector_v2f64_const: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: pcalau12i $a1, %pc_hi20(.LCPI17_0) +-; CHECK-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI17_0) +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- store <2 x double> , ptr %dst +- ret void +-} +- +-define void @buildvector_v16i8(ptr %dst, i8 %a0, i8 %a1, i8 %a2, i8 %a3, i8 %a4, i8 %a5, i8 %a6, i8 %a7, i8 %a8, i8 %a9, i8 %a10, i8 %a11, i8 %a12, i8 %a13, i8 %a14, i8 %a15) nounwind { +-; CHECK-LABEL: buildvector_v16i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 0 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a2, 1 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a3, 2 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a4, 3 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a5, 4 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a6, 5 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a7, 6 +-; CHECK-NEXT: ld.b $a1, $sp, 0 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 7 +-; CHECK-NEXT: ld.b $a1, $sp, 8 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 8 +-; CHECK-NEXT: ld.b $a1, $sp, 16 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 9 +-; CHECK-NEXT: ld.b $a1, $sp, 24 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 10 +-; CHECK-NEXT: ld.b $a1, $sp, 32 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 11 +-; CHECK-NEXT: ld.b $a1, $sp, 40 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 12 +-; CHECK-NEXT: ld.b $a1, $sp, 48 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 13 +-; CHECK-NEXT: ld.b $a1, $sp, 56 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 14 +-; CHECK-NEXT: ld.b $a1, $sp, 64 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 15 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %ins0 = insertelement <16 x i8> undef, i8 %a0, i32 0 +- %ins1 = insertelement <16 x i8> %ins0, i8 %a1, i32 1 +- %ins2 = insertelement <16 x i8> %ins1, i8 %a2, i32 2 +- %ins3 = insertelement <16 x i8> %ins2, i8 %a3, i32 3 +- %ins4 = insertelement <16 x i8> %ins3, i8 %a4, i32 4 +- %ins5 = insertelement <16 x i8> %ins4, i8 %a5, i32 5 +- %ins6 = insertelement <16 x i8> %ins5, i8 %a6, i32 6 +- %ins7 = insertelement <16 x i8> %ins6, i8 %a7, i32 7 +- %ins8 = insertelement <16 x i8> %ins7, i8 %a8, i32 8 +- %ins9 = insertelement <16 x i8> %ins8, i8 %a9, i32 9 +- %ins10 = insertelement <16 x i8> %ins9, i8 %a10, i32 10 +- %ins11 = insertelement <16 x i8> %ins10, i8 %a11, i32 11 +- %ins12 = insertelement <16 x i8> %ins11, i8 %a12, i32 12 +- %ins13 = insertelement <16 x i8> %ins12, i8 %a13, i32 13 +- %ins14 = insertelement <16 x i8> %ins13, i8 %a14, i32 14 +- %ins15 = insertelement <16 x i8> %ins14, i8 %a15, i32 15 +- store <16 x i8> %ins15, ptr %dst +- ret void +-} +- +-define void @buildvector_v8i16(ptr %dst, i16 %a0, i16 %a1, i16 %a2, i16 %a3, i16 %a4, i16 %a5, i16 %a6, i16 %a7) nounwind { +-; CHECK-LABEL: buildvector_v8i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vinsgr2vr.h $vr0, $a1, 0 +-; CHECK-NEXT: vinsgr2vr.h $vr0, $a2, 1 +-; CHECK-NEXT: vinsgr2vr.h $vr0, $a3, 2 +-; CHECK-NEXT: vinsgr2vr.h $vr0, $a4, 3 +-; CHECK-NEXT: vinsgr2vr.h $vr0, $a5, 4 +-; CHECK-NEXT: vinsgr2vr.h $vr0, $a6, 5 +-; CHECK-NEXT: vinsgr2vr.h $vr0, $a7, 6 +-; CHECK-NEXT: ld.h $a1, $sp, 0 +-; CHECK-NEXT: vinsgr2vr.h $vr0, $a1, 7 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %ins0 = insertelement <8 x i16> undef, i16 %a0, i32 0 +- %ins1 = insertelement <8 x i16> %ins0, i16 %a1, i32 1 +- %ins2 = insertelement <8 x i16> %ins1, i16 %a2, i32 2 +- %ins3 = insertelement <8 x i16> %ins2, i16 %a3, i32 3 +- %ins4 = insertelement <8 x i16> %ins3, i16 %a4, i32 4 +- %ins5 = insertelement <8 x i16> %ins4, i16 %a5, i32 5 +- %ins6 = insertelement <8 x i16> %ins5, i16 %a6, i32 6 +- %ins7 = insertelement <8 x i16> %ins6, i16 %a7, i32 7 +- store <8 x i16> %ins7, ptr %dst +- ret void +-} +- +-define void @buildvector_v4i32(ptr %dst, i32 %a0, i32 %a1, i32 %a2, i32 %a3) nounwind { +-; CHECK-LABEL: buildvector_v4i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vinsgr2vr.w $vr0, $a1, 0 +-; CHECK-NEXT: vinsgr2vr.w $vr0, $a2, 1 +-; CHECK-NEXT: vinsgr2vr.w $vr0, $a3, 2 +-; CHECK-NEXT: vinsgr2vr.w $vr0, $a4, 3 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %ins0 = insertelement <4 x i32> undef, i32 %a0, i32 0 +- %ins1 = insertelement <4 x i32> %ins0, i32 %a1, i32 1 +- %ins2 = insertelement <4 x i32> %ins1, i32 %a2, i32 2 +- %ins3 = insertelement <4 x i32> %ins2, i32 %a3, i32 3 +- store <4 x i32> %ins3, ptr %dst +- ret void +-} +- +-define void @buildvector_v2i64(ptr %dst, i64 %a0, i64 %a1) nounwind { +-; CHECK-LABEL: buildvector_v2i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vinsgr2vr.d $vr0, $a1, 0 +-; CHECK-NEXT: vinsgr2vr.d $vr0, $a2, 1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %ins0 = insertelement <2 x i64> undef, i64 %a0, i32 0 +- %ins1 = insertelement <2 x i64> %ins0, i64 %a1, i32 1 +- store <2 x i64> %ins1, ptr %dst +- ret void +-} +- +-define void @buildvector_v4f32(ptr %dst, float %a0, float %a1, float %a2, float %a3) nounwind { +-; CHECK-LABEL: buildvector_v4f32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: movfr2gr.s $a1, $fa0 +-; CHECK-NEXT: vinsgr2vr.w $vr0, $a1, 0 +-; CHECK-NEXT: movfr2gr.s $a1, $fa1 +-; CHECK-NEXT: vinsgr2vr.w $vr0, $a1, 1 +-; CHECK-NEXT: movfr2gr.s $a1, $fa2 +-; CHECK-NEXT: vinsgr2vr.w $vr0, $a1, 2 +-; CHECK-NEXT: movfr2gr.s $a1, $fa3 +-; CHECK-NEXT: vinsgr2vr.w $vr0, $a1, 3 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %ins0 = insertelement <4 x float> undef, float %a0, i32 0 +- %ins1 = insertelement <4 x float> %ins0, float %a1, i32 1 +- %ins2 = insertelement <4 x float> %ins1, float %a2, i32 2 +- %ins3 = insertelement <4 x float> %ins2, float %a3, i32 3 +- store <4 x float> %ins3, ptr %dst +- ret void +-} +- +-define void @buildvector_v2f64(ptr %dst, double %a0, double %a1) nounwind { +-; CHECK-LABEL: buildvector_v2f64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: movfr2gr.d $a1, $fa0 +-; CHECK-NEXT: vinsgr2vr.d $vr0, $a1, 0 +-; CHECK-NEXT: movfr2gr.d $a1, $fa1 +-; CHECK-NEXT: vinsgr2vr.d $vr0, $a1, 1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %ins0 = insertelement <2 x double> undef, double %a0, i32 0 +- %ins1 = insertelement <2 x double> %ins0, double %a1, i32 1 +- store <2 x double> %ins1, ptr %dst +- ret void +-} +- +-;; BUILD_VECTOR through stack. +-;; If `isShuffleMaskLegal` returns true, it will lead to an infinite loop. +-define void @extract1_i32_zext_insert0_i64_undef(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: extract1_i32_zext_insert0_i64_undef: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vpickve2gr.w $a0, $vr0, 1 +-; CHECK-NEXT: bstrpick.d $a0, $a0, 31, 0 +-; CHECK-NEXT: st.d $a0, $sp, 0 +-; CHECK-NEXT: vld $vr0, $sp, 0 +-; CHECK-NEXT: vst $vr0, $a1, 0 +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +- %v = load volatile <4 x i32>, ptr %src +- %e = extractelement <4 x i32> %v, i32 1 +- %z = zext i32 %e to i64 +- %r = insertelement <2 x i64> undef, i64 %z, i32 0 +- store <2 x i64> %r, ptr %dst +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ctpop-ctlz.ll b/llvm/test/CodeGen/LoongArch/lsx/ctpop-ctlz.ll +deleted file mode 100644 +index 5df553fba..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ctpop-ctlz.ll ++++ /dev/null +@@ -1,115 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @ctpop_v16i8(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: ctpop_v16i8: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vpcnt.b $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load <16 x i8>, ptr %src +- %res = call <16 x i8> @llvm.ctpop.v16i8(<16 x i8> %v) +- store <16 x i8> %res, ptr %dst +- ret void +-} +- +-define void @ctpop_v8i16(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: ctpop_v8i16: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vpcnt.h $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load <8 x i16>, ptr %src +- %res = call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> %v) +- store <8 x i16> %res, ptr %dst +- ret void +-} +- +-define void @ctpop_v4i32(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: ctpop_v4i32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vpcnt.w $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load <4 x i32>, ptr %src +- %res = call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %v) +- store <4 x i32> %res, ptr %dst +- ret void +-} +- +-define void @ctpop_v2i64(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: ctpop_v2i64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vpcnt.d $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load <2 x i64>, ptr %src +- %res = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %v) +- store <2 x i64> %res, ptr %dst +- ret void +-} +- +-define void @ctlz_v16i8(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: ctlz_v16i8: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vclz.b $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load <16 x i8>, ptr %src +- %res = call <16 x i8> @llvm.ctlz.v16i8(<16 x i8> %v, i1 false) +- store <16 x i8> %res, ptr %dst +- ret void +-} +- +-define void @ctlz_v8i16(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: ctlz_v8i16: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vclz.h $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load <8 x i16>, ptr %src +- %res = call <8 x i16> @llvm.ctlz.v8i16(<8 x i16> %v, i1 false) +- store <8 x i16> %res, ptr %dst +- ret void +-} +- +-define void @ctlz_v4i32(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: ctlz_v4i32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vclz.w $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load <4 x i32>, ptr %src +- %res = call <4 x i32> @llvm.ctlz.v4i32(<4 x i32> %v, i1 false) +- store <4 x i32> %res, ptr %dst +- ret void +-} +- +-define void @ctlz_v2i64(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: ctlz_v2i64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vclz.d $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load <2 x i64>, ptr %src +- %res = call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> %v, i1 false) +- store <2 x i64> %res, ptr %dst +- ret void +-} +- +-declare <16 x i8> @llvm.ctpop.v16i8(<16 x i8>) +-declare <8 x i16> @llvm.ctpop.v8i16(<8 x i16>) +-declare <4 x i32> @llvm.ctpop.v4i32(<4 x i32>) +-declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64>) +-declare <16 x i8> @llvm.ctlz.v16i8(<16 x i8>, i1) +-declare <8 x i16> @llvm.ctlz.v8i16(<8 x i16>, i1) +-declare <4 x i32> @llvm.ctlz.v4i32(<4 x i32>, i1) +-declare <2 x i64> @llvm.ctlz.v2i64(<2 x i64>, i1) +diff --git a/llvm/test/CodeGen/LoongArch/lsx/extractelement.ll b/llvm/test/CodeGen/LoongArch/lsx/extractelement.ll +new file mode 100644 +index 000000000..ff6b4aac8 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lsx/extractelement.ll +@@ -0,0 +1,170 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s ++ ++define void @extract_16xi8(<16 x i8>* %src, i8* %dst) nounwind { ++; CHECK-LABEL: extract_16xi8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vld $vr0, $r4, 0 ++; CHECK-NEXT: vpickve2gr.b $r4, $vr0, 1 ++; CHECK-NEXT: st.b $r4, $r5, 0 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <16 x i8>, <16 x i8>* %src ++ %e = extractelement <16 x i8> %v, i32 1 ++ store i8 %e, i8* %dst ++ ret void ++} ++ ++define void @extract_8xi16(<8 x i16>* %src, i16* %dst) nounwind { ++; CHECK-LABEL: extract_8xi16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vld $vr0, $r4, 0 ++; CHECK-NEXT: vpickve2gr.h $r4, $vr0, 1 ++; CHECK-NEXT: st.h $r4, $r5, 0 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <8 x i16>, <8 x i16>* %src ++ %e = extractelement <8 x i16> %v, i32 1 ++ store i16 %e, i16* %dst ++ ret void ++} ++ ++define void @extract_4xi32(<4 x i32>* %src, i32* %dst) nounwind { ++; CHECK-LABEL: extract_4xi32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vld $vr0, $r4, 0 ++; CHECK-NEXT: vpickve2gr.w $r4, $vr0, 1 ++; CHECK-NEXT: st.w $r4, $r5, 0 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <4 x i32>, <4 x i32>* %src ++ %e = extractelement <4 x i32> %v, i32 1 ++ store i32 %e, i32* %dst ++ ret void ++} ++ ++define void @extract_2xi64(<2 x i64>* %src, i64* %dst) nounwind { ++; CHECK-LABEL: extract_2xi64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vld $vr0, $r4, 0 ++; CHECK-NEXT: vpickve2gr.d $r4, $vr0, 1 ++; CHECK-NEXT: st.d $r4, $r5, 0 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <2 x i64>, <2 x i64>* %src ++ %e = extractelement <2 x i64> %v, i32 1 ++ store i64 %e, i64* %dst ++ ret void ++} ++ ++define void @extract_4xfloat(<4 x float>* %src, float* %dst) nounwind { ++; CHECK-LABEL: extract_4xfloat: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vld $vr0, $r4, 0 ++; CHECK-NEXT: vreplvei.w $vr0, $vr0, 1 ++; CHECK-NEXT: fst.s $f0, $r5, 0 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <4 x float>, <4 x float>* %src ++ %e = extractelement <4 x float> %v, i32 1 ++ store float %e, float* %dst ++ ret void ++} ++ ++define void @extract_2xdouble(<2 x double>* %src, double* %dst) nounwind { ++; CHECK-LABEL: extract_2xdouble: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vld $vr0, $r4, 0 ++; CHECK-NEXT: vreplvei.d $vr0, $vr0, 1 ++; CHECK-NEXT: fst.d $f0, $r5, 0 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <2 x double>, <2 x double>* %src ++ %e = extractelement <2 x double> %v, i32 1 ++ store double %e, double* %dst ++ ret void ++} ++ ++define void @extract_16xi8_idx(<16 x i8>* %src, i8* %dst, i32 %idx) nounwind { ++; CHECK-LABEL: extract_16xi8_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: bstrpick.d $r6, $r6, 31, 0 ++; CHECK-NEXT: vld $vr0, $r4, 0 ++; CHECK-NEXT: vreplve.b $vr0, $vr0, $r6 ++; CHECK-NEXT: movfr2gr.s $r4, $f0 ++; CHECK-NEXT: srai.w $r4, $r4, 24 ++; CHECK-NEXT: st.b $r4, $r5, 0 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <16 x i8>, <16 x i8>* %src ++ %e = extractelement <16 x i8> %v, i32 %idx ++ store i8 %e, i8* %dst ++ ret void ++} ++ ++define void @extract_8xi16_idx(<8 x i16>* %src, i16* %dst, i32 %idx) nounwind { ++; CHECK-LABEL: extract_8xi16_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: bstrpick.d $r6, $r6, 31, 0 ++; CHECK-NEXT: vld $vr0, $r4, 0 ++; CHECK-NEXT: vreplve.h $vr0, $vr0, $r6 ++; CHECK-NEXT: movfr2gr.s $r4, $f0 ++; CHECK-NEXT: srai.w $r4, $r4, 16 ++; CHECK-NEXT: st.h $r4, $r5, 0 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <8 x i16>, <8 x i16>* %src ++ %e = extractelement <8 x i16> %v, i32 %idx ++ store i16 %e, i16* %dst ++ ret void ++} ++ ++define void @extract_4xi32_idx(<4 x i32>* %src, i32* %dst, i32 %idx) nounwind { ++; CHECK-LABEL: extract_4xi32_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: bstrpick.d $r6, $r6, 31, 0 ++; CHECK-NEXT: vld $vr0, $r4, 0 ++; CHECK-NEXT: vreplve.w $vr0, $vr0, $r6 ++; CHECK-NEXT: movfr2gr.s $r4, $f0 ++; CHECK-NEXT: st.w $r4, $r5, 0 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <4 x i32>, <4 x i32>* %src ++ %e = extractelement <4 x i32> %v, i32 %idx ++ store i32 %e, i32* %dst ++ ret void ++} ++ ++define void @extract_2xi64_idx(<2 x i64>* %src, i64* %dst, i32 %idx) nounwind { ++; CHECK-LABEL: extract_2xi64_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: bstrpick.d $r6, $r6, 31, 0 ++; CHECK-NEXT: vld $vr0, $r4, 0 ++; CHECK-NEXT: vreplve.d $vr0, $vr0, $r6 ++; CHECK-NEXT: movfr2gr.d $r4, $f0 ++; CHECK-NEXT: st.d $r4, $r5, 0 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <2 x i64>, <2 x i64>* %src ++ %e = extractelement <2 x i64> %v, i32 %idx ++ store i64 %e, i64* %dst ++ ret void ++} ++ ++define void @extract_4xfloat_idx(<4 x float>* %src, float* %dst, i32 %idx) nounwind { ++; CHECK-LABEL: extract_4xfloat_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: bstrpick.d $r6, $r6, 31, 0 ++; CHECK-NEXT: vld $vr0, $r4, 0 ++; CHECK-NEXT: vreplve.w $vr0, $vr0, $r6 ++; CHECK-NEXT: fst.s $f0, $r5, 0 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <4 x float>, <4 x float>* %src ++ %e = extractelement <4 x float> %v, i32 %idx ++ store float %e, float* %dst ++ ret void ++} ++ ++define void @extract_2xdouble_idx(<2 x double>* %src, double* %dst, i32 %idx) nounwind { ++; CHECK-LABEL: extract_2xdouble_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: bstrpick.d $r6, $r6, 31, 0 ++; CHECK-NEXT: vld $vr0, $r4, 0 ++; CHECK-NEXT: vreplve.d $vr0, $vr0, $r6 ++; CHECK-NEXT: fst.d $f0, $r5, 0 ++; CHECK-NEXT: jr $ra ++ %v = load volatile <2 x double>, <2 x double>* %src ++ %e = extractelement <2 x double> %v, i32 %idx ++ store double %e, double* %dst ++ ret void ++} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/fma-v2f64.ll b/llvm/test/CodeGen/LoongArch/lsx/fma-v2f64.ll +deleted file mode 100644 +index 8e0459b4a..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/fma-v2f64.ll ++++ /dev/null +@@ -1,804 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx --fp-contract=fast < %s \ +-; RUN: | FileCheck %s --check-prefix=CONTRACT-FAST +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx --fp-contract=on < %s \ +-; RUN: | FileCheck %s --check-prefix=CONTRACT-ON +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx --fp-contract=off < %s \ +-; RUN: | FileCheck %s --check-prefix=CONTRACT-OFF +- +-define void @vfmadd_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: vfmadd_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfmadd.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: vfmadd_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-ON-NEXT: vfmul.d $vr0, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-ON-NEXT: vfadd.d $vr0, $vr0, $vr1 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: vfmadd_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-OFF-NEXT: vfmul.d $vr0, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-OFF-NEXT: vfadd.d $vr0, $vr0, $vr1 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = load <2 x double>, ptr %a2 +- %mul = fmul<2 x double> %v0, %v1 +- %add = fadd<2 x double> %mul, %v2 +- store <2 x double> %add, ptr %res +- ret void +-} +- +-define void @vfmsub_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: vfmsub_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfmsub.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: vfmsub_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-ON-NEXT: vfmul.d $vr0, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-ON-NEXT: vfsub.d $vr0, $vr0, $vr1 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: vfmsub_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-OFF-NEXT: vfmul.d $vr0, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-OFF-NEXT: vfsub.d $vr0, $vr0, $vr1 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = load <2 x double>, ptr %a2 +- %mul = fmul<2 x double> %v0, %v1 +- %sub = fsub<2 x double> %mul, %v2 +- store <2 x double> %sub, ptr %res +- ret void +-} +- +-define void @vfnmadd_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: vfnmadd_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfnmadd.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: vfnmadd_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-ON-NEXT: vfmul.d $vr0, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-ON-NEXT: vfadd.d $vr0, $vr0, $vr1 +-; CONTRACT-ON-NEXT: vbitrevi.d $vr0, $vr0, 63 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: vfnmadd_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-OFF-NEXT: vfmul.d $vr0, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-OFF-NEXT: vfadd.d $vr0, $vr0, $vr1 +-; CONTRACT-OFF-NEXT: vbitrevi.d $vr0, $vr0, 63 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = load <2 x double>, ptr %a2 +- %mul = fmul<2 x double> %v0, %v1 +- %add = fadd<2 x double> %mul, %v2 +- %negadd = fneg<2 x double> %add +- store <2 x double> %negadd, ptr %res +- ret void +-} +- +-define void @vfnmadd_d_nsz(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: vfnmadd_d_nsz: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfnmadd.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: vfnmadd_d_nsz: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-ON-NEXT: vbitrevi.d $vr1, $vr1, 63 +-; CONTRACT-ON-NEXT: vfmul.d $vr0, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-ON-NEXT: vfsub.d $vr0, $vr0, $vr1 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: vfnmadd_d_nsz: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-OFF-NEXT: vbitrevi.d $vr1, $vr1, 63 +-; CONTRACT-OFF-NEXT: vfmul.d $vr0, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-OFF-NEXT: vfsub.d $vr0, $vr0, $vr1 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = load <2 x double>, ptr %a2 +- %negv0 = fneg nsz<2 x double> %v0 +- %negv2 = fneg nsz<2 x double> %v2 +- %mul = fmul nsz<2 x double> %negv0, %v1 +- %add = fadd nsz<2 x double> %mul, %negv2 +- store <2 x double> %add, ptr %res +- ret void +-} +- +-;; Check that vfnmadd.d is not emitted. +-define void @not_vfnmadd_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: not_vfnmadd_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vbitrevi.d $vr2, $vr2, 63 +-; CONTRACT-FAST-NEXT: vfmsub.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: not_vfnmadd_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-ON-NEXT: vbitrevi.d $vr1, $vr1, 63 +-; CONTRACT-ON-NEXT: vfmul.d $vr0, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-ON-NEXT: vfsub.d $vr0, $vr0, $vr1 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: not_vfnmadd_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-OFF-NEXT: vbitrevi.d $vr1, $vr1, 63 +-; CONTRACT-OFF-NEXT: vfmul.d $vr0, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-OFF-NEXT: vfsub.d $vr0, $vr0, $vr1 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = load <2 x double>, ptr %a2 +- %negv0 = fneg<2 x double> %v0 +- %negv2 = fneg<2 x double> %v2 +- %mul = fmul<2 x double> %negv0, %v1 +- %add = fadd<2 x double> %mul, %negv2 +- store <2 x double> %add, ptr %res +- ret void +-} +- +-define void @vfnmsub_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: vfnmsub_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfnmsub.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: vfnmsub_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-ON-NEXT: vfmul.d $vr0, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-ON-NEXT: vfsub.d $vr0, $vr0, $vr1 +-; CONTRACT-ON-NEXT: vbitrevi.d $vr0, $vr0, 63 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: vfnmsub_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-OFF-NEXT: vfmul.d $vr0, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-OFF-NEXT: vfsub.d $vr0, $vr0, $vr1 +-; CONTRACT-OFF-NEXT: vbitrevi.d $vr0, $vr0, 63 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = load <2 x double>, ptr %a2 +- %negv2 = fneg<2 x double> %v2 +- %mul = fmul<2 x double> %v0, %v1 +- %add = fadd<2 x double> %mul, %negv2 +- %neg = fneg<2 x double> %add +- store <2 x double> %neg, ptr %res +- ret void +-} +- +-define void @vfnmsub_d_nsz(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: vfnmsub_d_nsz: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfnmsub.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: vfnmsub_d_nsz: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-ON-NEXT: vfmul.d $vr0, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-ON-NEXT: vfsub.d $vr0, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: vfnmsub_d_nsz: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-OFF-NEXT: vfmul.d $vr0, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-OFF-NEXT: vfsub.d $vr0, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = load <2 x double>, ptr %a2 +- %negv0 = fneg nsz<2 x double> %v0 +- %mul = fmul nsz<2 x double> %negv0, %v1 +- %add = fadd nsz<2 x double> %mul, %v2 +- store <2 x double> %add, ptr %res +- ret void +-} +- +-;; Check that vfnmsub.d is not emitted. +-define void @not_vfnmsub_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: not_vfnmsub_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vbitrevi.d $vr2, $vr2, 63 +-; CONTRACT-FAST-NEXT: vfmadd.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: not_vfnmsub_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-ON-NEXT: vfmul.d $vr0, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-ON-NEXT: vfsub.d $vr0, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: not_vfnmsub_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-OFF-NEXT: vfmul.d $vr0, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-OFF-NEXT: vfsub.d $vr0, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = load <2 x double>, ptr %a2 +- %negv0 = fneg<2 x double> %v0 +- %mul = fmul<2 x double> %negv0, %v1 +- %add = fadd<2 x double> %mul, %v2 +- store <2 x double> %add, ptr %res +- ret void +-} +- +-define void @contract_vfmadd_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_vfmadd_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfmadd.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_vfmadd_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vfmadd.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_vfmadd_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vfmadd.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = load <2 x double>, ptr %a2 +- %mul = fmul contract <2 x double> %v0, %v1 +- %add = fadd contract <2 x double> %mul, %v2 +- store <2 x double> %add, ptr %res +- ret void +-} +- +-define void @contract_vfmsub_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_vfmsub_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfmsub.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_vfmsub_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vfmsub.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_vfmsub_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vfmsub.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = load <2 x double>, ptr %a2 +- %mul = fmul contract <2 x double> %v0, %v1 +- %sub = fsub contract <2 x double> %mul, %v2 +- store <2 x double> %sub, ptr %res +- ret void +-} +- +-define void @contract_vfnmadd_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_vfnmadd_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfnmadd.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_vfnmadd_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vfnmadd.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_vfnmadd_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vfnmadd.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = load <2 x double>, ptr %a2 +- %mul = fmul contract <2 x double> %v0, %v1 +- %add = fadd contract <2 x double> %mul, %v2 +- %negadd = fneg contract <2 x double> %add +- store <2 x double> %negadd, ptr %res +- ret void +-} +- +-define void @contract_vfnmadd_d_nsz(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_vfnmadd_d_nsz: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfnmadd.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_vfnmadd_d_nsz: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vfnmadd.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_vfnmadd_d_nsz: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vfnmadd.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = load <2 x double>, ptr %a2 +- %negv0 = fneg contract nsz<2 x double> %v0 +- %negv2 = fneg contract nsz<2 x double> %v2 +- %mul = fmul contract nsz<2 x double> %negv0, %v1 +- %add = fadd contract nsz<2 x double> %mul, %negv2 +- store <2 x double> %add, ptr %res +- ret void +-} +- +-;; Check that vfnmadd.d is not emitted. +-define void @not_contract_vfnmadd_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: not_contract_vfnmadd_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vbitrevi.d $vr2, $vr2, 63 +-; CONTRACT-FAST-NEXT: vfmsub.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: not_contract_vfnmadd_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vbitrevi.d $vr2, $vr2, 63 +-; CONTRACT-ON-NEXT: vfmsub.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: not_contract_vfnmadd_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vbitrevi.d $vr2, $vr2, 63 +-; CONTRACT-OFF-NEXT: vfmsub.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = load <2 x double>, ptr %a2 +- %negv0 = fneg contract <2 x double> %v0 +- %negv2 = fneg contract <2 x double> %v2 +- %mul = fmul contract <2 x double> %negv0, %v1 +- %add = fadd contract <2 x double> %mul, %negv2 +- store <2 x double> %add, ptr %res +- ret void +-} +- +-define void @contract_vfnmsub_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_vfnmsub_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfnmsub.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_vfnmsub_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vfnmsub.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_vfnmsub_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vfnmsub.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = load <2 x double>, ptr %a2 +- %negv2 = fneg contract <2 x double> %v2 +- %mul = fmul contract <2 x double> %v0, %v1 +- %add = fadd contract <2 x double> %mul, %negv2 +- %neg = fneg contract <2 x double> %add +- store <2 x double> %neg, ptr %res +- ret void +-} +- +-define void @contract_vfnmsub_d_nsz(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_vfnmsub_d_nsz: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfnmsub.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_vfnmsub_d_nsz: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vfnmsub.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_vfnmsub_d_nsz: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vfnmsub.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = load <2 x double>, ptr %a2 +- %negv0 = fneg contract nsz<2 x double> %v0 +- %mul = fmul contract nsz<2 x double> %negv0, %v1 +- %add = fadd contract nsz<2 x double> %mul, %v2 +- store <2 x double> %add, ptr %res +- ret void +-} +- +-;; Check that vfnmsub.d is not emitted. +-define void @not_contract_vfnmsub_d(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: not_contract_vfnmsub_d: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vbitrevi.d $vr2, $vr2, 63 +-; CONTRACT-FAST-NEXT: vfmadd.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: not_contract_vfnmsub_d: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vbitrevi.d $vr2, $vr2, 63 +-; CONTRACT-ON-NEXT: vfmadd.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: not_contract_vfnmsub_d: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vbitrevi.d $vr2, $vr2, 63 +-; CONTRACT-OFF-NEXT: vfmadd.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = load <2 x double>, ptr %a2 +- %negv0 = fneg contract <2 x double> %v0 +- %mul = fmul contract <2 x double> %negv0, %v1 +- %add = fadd contract <2 x double> %mul, %v2 +- store <2 x double> %add, ptr %res +- ret void +-} +- +-define void @vfmadd_d_contract(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: vfmadd_d_contract: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfmadd.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: vfmadd_d_contract: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vfmadd.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: vfmadd_d_contract: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vfmadd.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = load <2 x double>, ptr %a2 +- %mul = fmul contract <2 x double> %v0, %v1 +- %add = fadd contract <2 x double> %mul, %v2 +- store <2 x double> %add, ptr %res +- ret void +-} +- +-define void @vfmsub_d_contract(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: vfmsub_d_contract: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfmsub.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: vfmsub_d_contract: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vfmsub.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: vfmsub_d_contract: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vfmsub.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = load <2 x double>, ptr %a2 +- %mul = fmul contract <2 x double> %v0, %v1 +- %sub = fsub contract <2 x double> %mul, %v2 +- store <2 x double> %sub, ptr %res +- ret void +-} +- +-define void @vfnmadd_d_contract(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: vfnmadd_d_contract: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfnmadd.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: vfnmadd_d_contract: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vfnmadd.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: vfnmadd_d_contract: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vfnmadd.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = load <2 x double>, ptr %a2 +- %mul = fmul contract <2 x double> %v0, %v1 +- %add = fadd contract <2 x double> %mul, %v2 +- %negadd = fneg contract <2 x double> %add +- store <2 x double> %negadd, ptr %res +- ret void +-} +- +-define void @vfnmsub_d_contract(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: vfnmsub_d_contract: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfnmsub.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: vfnmsub_d_contract: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vfnmsub.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: vfnmsub_d_contract: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vfnmsub.d $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = load <2 x double>, ptr %a2 +- %mul = fmul contract <2 x double> %v0, %v1 +- %negv2 = fneg contract <2 x double> %v2 +- %add = fadd contract <2 x double> %negv2, %mul +- %negadd = fneg contract <2 x double> %add +- store <2 x double> %negadd, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/fma-v4f32.ll b/llvm/test/CodeGen/LoongArch/lsx/fma-v4f32.ll +deleted file mode 100644 +index 7efbd61c0..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/fma-v4f32.ll ++++ /dev/null +@@ -1,804 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx --fp-contract=fast < %s \ +-; RUN: | FileCheck %s --check-prefix=CONTRACT-FAST +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx --fp-contract=on < %s \ +-; RUN: | FileCheck %s --check-prefix=CONTRACT-ON +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx --fp-contract=off < %s \ +-; RUN: | FileCheck %s --check-prefix=CONTRACT-OFF +- +-define void @vfmadd_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: vfmadd_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfmadd.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: vfmadd_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-ON-NEXT: vfmul.s $vr0, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-ON-NEXT: vfadd.s $vr0, $vr0, $vr1 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: vfmadd_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-OFF-NEXT: vfmul.s $vr0, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-OFF-NEXT: vfadd.s $vr0, $vr0, $vr1 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = load <4 x float>, ptr %a2 +- %mul = fmul<4 x float> %v0, %v1 +- %add = fadd<4 x float> %mul, %v2 +- store <4 x float> %add, ptr %res +- ret void +-} +- +-define void @vfmsub_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: vfmsub_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfmsub.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: vfmsub_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-ON-NEXT: vfmul.s $vr0, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-ON-NEXT: vfsub.s $vr0, $vr0, $vr1 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: vfmsub_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-OFF-NEXT: vfmul.s $vr0, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-OFF-NEXT: vfsub.s $vr0, $vr0, $vr1 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = load <4 x float>, ptr %a2 +- %mul = fmul<4 x float> %v0, %v1 +- %sub = fsub<4 x float> %mul, %v2 +- store <4 x float> %sub, ptr %res +- ret void +-} +- +-define void @vfnmadd_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: vfnmadd_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfnmadd.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: vfnmadd_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-ON-NEXT: vfmul.s $vr0, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-ON-NEXT: vfadd.s $vr0, $vr0, $vr1 +-; CONTRACT-ON-NEXT: vbitrevi.w $vr0, $vr0, 31 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: vfnmadd_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-OFF-NEXT: vfmul.s $vr0, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-OFF-NEXT: vfadd.s $vr0, $vr0, $vr1 +-; CONTRACT-OFF-NEXT: vbitrevi.w $vr0, $vr0, 31 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = load <4 x float>, ptr %a2 +- %mul = fmul<4 x float> %v0, %v1 +- %add = fadd<4 x float> %mul, %v2 +- %negadd = fneg<4 x float> %add +- store <4 x float> %negadd, ptr %res +- ret void +-} +- +-define void @vfnmadd_s_nsz(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: vfnmadd_s_nsz: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfnmadd.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: vfnmadd_s_nsz: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-ON-NEXT: vbitrevi.w $vr1, $vr1, 31 +-; CONTRACT-ON-NEXT: vfmul.s $vr0, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-ON-NEXT: vfsub.s $vr0, $vr0, $vr1 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: vfnmadd_s_nsz: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-OFF-NEXT: vbitrevi.w $vr1, $vr1, 31 +-; CONTRACT-OFF-NEXT: vfmul.s $vr0, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-OFF-NEXT: vfsub.s $vr0, $vr0, $vr1 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = load <4 x float>, ptr %a2 +- %negv0 = fneg nsz<4 x float> %v0 +- %negv2 = fneg nsz<4 x float> %v2 +- %mul = fmul nsz<4 x float> %negv0, %v1 +- %add = fadd nsz<4 x float> %mul, %negv2 +- store <4 x float> %add, ptr %res +- ret void +-} +- +-;; Check that vfnmadd.s is not emitted. +-define void @not_vfnmadd_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: not_vfnmadd_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vbitrevi.w $vr2, $vr2, 31 +-; CONTRACT-FAST-NEXT: vfmsub.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: not_vfnmadd_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-ON-NEXT: vbitrevi.w $vr1, $vr1, 31 +-; CONTRACT-ON-NEXT: vfmul.s $vr0, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-ON-NEXT: vfsub.s $vr0, $vr0, $vr1 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: not_vfnmadd_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-OFF-NEXT: vbitrevi.w $vr1, $vr1, 31 +-; CONTRACT-OFF-NEXT: vfmul.s $vr0, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-OFF-NEXT: vfsub.s $vr0, $vr0, $vr1 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = load <4 x float>, ptr %a2 +- %negv0 = fneg<4 x float> %v0 +- %negv2 = fneg<4 x float> %v2 +- %mul = fmul<4 x float> %negv0, %v1 +- %add = fadd<4 x float> %mul, %negv2 +- store <4 x float> %add, ptr %res +- ret void +-} +- +-define void @vfnmsub_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: vfnmsub_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfnmsub.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: vfnmsub_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-ON-NEXT: vfmul.s $vr0, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-ON-NEXT: vfsub.s $vr0, $vr0, $vr1 +-; CONTRACT-ON-NEXT: vbitrevi.w $vr0, $vr0, 31 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: vfnmsub_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-OFF-NEXT: vfmul.s $vr0, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-OFF-NEXT: vfsub.s $vr0, $vr0, $vr1 +-; CONTRACT-OFF-NEXT: vbitrevi.w $vr0, $vr0, 31 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = load <4 x float>, ptr %a2 +- %negv2 = fneg<4 x float> %v2 +- %mul = fmul<4 x float> %v0, %v1 +- %add = fadd<4 x float> %mul, %negv2 +- %neg = fneg<4 x float> %add +- store <4 x float> %neg, ptr %res +- ret void +-} +- +-define void @vfnmsub_s_nsz(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: vfnmsub_s_nsz: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfnmsub.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: vfnmsub_s_nsz: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-ON-NEXT: vfmul.s $vr0, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-ON-NEXT: vfsub.s $vr0, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: vfnmsub_s_nsz: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-OFF-NEXT: vfmul.s $vr0, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-OFF-NEXT: vfsub.s $vr0, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = load <4 x float>, ptr %a2 +- %negv0 = fneg nsz<4 x float> %v0 +- %mul = fmul nsz<4 x float> %negv0, %v1 +- %add = fadd nsz<4 x float> %mul, %v2 +- store <4 x float> %add, ptr %res +- ret void +-} +- +-;; Check that vfnmsub.s is not emitted. +-define void @not_vfnmsub_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: not_vfnmsub_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vbitrevi.w $vr2, $vr2, 31 +-; CONTRACT-FAST-NEXT: vfmadd.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: not_vfnmsub_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-ON-NEXT: vfmul.s $vr0, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-ON-NEXT: vfsub.s $vr0, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: not_vfnmsub_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a1, 0 +-; CONTRACT-OFF-NEXT: vfmul.s $vr0, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a3, 0 +-; CONTRACT-OFF-NEXT: vfsub.s $vr0, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = load <4 x float>, ptr %a2 +- %negv0 = fneg<4 x float> %v0 +- %mul = fmul<4 x float> %negv0, %v1 +- %add = fadd<4 x float> %mul, %v2 +- store <4 x float> %add, ptr %res +- ret void +-} +- +-define void @contract_vfmadd_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_vfmadd_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfmadd.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_vfmadd_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vfmadd.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_vfmadd_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vfmadd.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = load <4 x float>, ptr %a2 +- %mul = fmul contract <4 x float> %v0, %v1 +- %add = fadd contract <4 x float> %mul, %v2 +- store <4 x float> %add, ptr %res +- ret void +-} +- +-define void @contract_vfmsub_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_vfmsub_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfmsub.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_vfmsub_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vfmsub.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_vfmsub_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vfmsub.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = load <4 x float>, ptr %a2 +- %mul = fmul contract <4 x float> %v0, %v1 +- %sub = fsub contract <4 x float> %mul, %v2 +- store <4 x float> %sub, ptr %res +- ret void +-} +- +-define void @contract_vfnmadd_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_vfnmadd_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfnmadd.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_vfnmadd_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vfnmadd.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_vfnmadd_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vfnmadd.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = load <4 x float>, ptr %a2 +- %mul = fmul contract <4 x float> %v0, %v1 +- %add = fadd contract <4 x float> %mul, %v2 +- %negadd = fneg contract <4 x float> %add +- store <4 x float> %negadd, ptr %res +- ret void +-} +- +-define void @contract_vfnmadd_s_nsz(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_vfnmadd_s_nsz: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfnmadd.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_vfnmadd_s_nsz: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vfnmadd.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_vfnmadd_s_nsz: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vfnmadd.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = load <4 x float>, ptr %a2 +- %negv0 = fneg contract nsz<4 x float> %v0 +- %negv2 = fneg contract nsz<4 x float> %v2 +- %mul = fmul contract nsz<4 x float> %negv0, %v1 +- %add = fadd contract nsz<4 x float> %mul, %negv2 +- store <4 x float> %add, ptr %res +- ret void +-} +- +-;; Check that vfnmadd.s is not emitted. +-define void @not_contract_vfnmadd_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: not_contract_vfnmadd_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vbitrevi.w $vr2, $vr2, 31 +-; CONTRACT-FAST-NEXT: vfmsub.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: not_contract_vfnmadd_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vbitrevi.w $vr2, $vr2, 31 +-; CONTRACT-ON-NEXT: vfmsub.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: not_contract_vfnmadd_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vbitrevi.w $vr2, $vr2, 31 +-; CONTRACT-OFF-NEXT: vfmsub.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = load <4 x float>, ptr %a2 +- %negv0 = fneg contract <4 x float> %v0 +- %negv2 = fneg contract <4 x float> %v2 +- %mul = fmul contract <4 x float> %negv0, %v1 +- %add = fadd contract <4 x float> %mul, %negv2 +- store <4 x float> %add, ptr %res +- ret void +-} +- +-define void @contract_vfnmsub_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_vfnmsub_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfnmsub.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_vfnmsub_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vfnmsub.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_vfnmsub_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vfnmsub.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = load <4 x float>, ptr %a2 +- %negv2 = fneg contract <4 x float> %v2 +- %mul = fmul contract <4 x float> %v0, %v1 +- %add = fadd contract <4 x float> %mul, %negv2 +- %neg = fneg contract <4 x float> %add +- store <4 x float> %neg, ptr %res +- ret void +-} +- +-define void @contract_vfnmsub_s_nsz(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: contract_vfnmsub_s_nsz: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfnmsub.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: contract_vfnmsub_s_nsz: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vfnmsub.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: contract_vfnmsub_s_nsz: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vfnmsub.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = load <4 x float>, ptr %a2 +- %negv0 = fneg contract nsz<4 x float> %v0 +- %mul = fmul contract nsz<4 x float> %negv0, %v1 +- %add = fadd contract nsz<4 x float> %mul, %v2 +- store <4 x float> %add, ptr %res +- ret void +-} +- +-;; Check that vfnmsub.s is not emitted. +-define void @not_contract_vfnmsub_s(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: not_contract_vfnmsub_s: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vbitrevi.w $vr2, $vr2, 31 +-; CONTRACT-FAST-NEXT: vfmadd.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: not_contract_vfnmsub_s: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vbitrevi.w $vr2, $vr2, 31 +-; CONTRACT-ON-NEXT: vfmadd.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: not_contract_vfnmsub_s: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vbitrevi.w $vr2, $vr2, 31 +-; CONTRACT-OFF-NEXT: vfmadd.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = load <4 x float>, ptr %a2 +- %negv0 = fneg contract <4 x float> %v0 +- %mul = fmul contract <4 x float> %negv0, %v1 +- %add = fadd contract <4 x float> %mul, %v2 +- store <4 x float> %add, ptr %res +- ret void +-} +- +-define void @vfmadd_s_contract(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: vfmadd_s_contract: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfmadd.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: vfmadd_s_contract: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vfmadd.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: vfmadd_s_contract: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vfmadd.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = load <4 x float>, ptr %a2 +- %mul = fmul contract <4 x float> %v0, %v1 +- %add = fadd contract <4 x float> %mul, %v2 +- store <4 x float> %add, ptr %res +- ret void +-} +- +-define void @vfmsub_s_contract(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: vfmsub_s_contract: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfmsub.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: vfmsub_s_contract: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vfmsub.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: vfmsub_s_contract: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vfmsub.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = load <4 x float>, ptr %a2 +- %mul = fmul contract <4 x float> %v0, %v1 +- %sub = fsub contract <4 x float> %mul, %v2 +- store <4 x float> %sub, ptr %res +- ret void +-} +- +-define void @vfnmadd_s_contract(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: vfnmadd_s_contract: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfnmadd.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: vfnmadd_s_contract: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vfnmadd.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: vfnmadd_s_contract: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vfnmadd.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = load <4 x float>, ptr %a2 +- %mul = fmul contract <4 x float> %v0, %v1 +- %add = fadd contract <4 x float> %mul, %v2 +- %negadd = fneg contract <4 x float> %add +- store <4 x float> %negadd, ptr %res +- ret void +-} +- +-define void @vfnmsub_s_contract(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind { +-; CONTRACT-FAST-LABEL: vfnmsub_s_contract: +-; CONTRACT-FAST: # %bb.0: # %entry +-; CONTRACT-FAST-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-FAST-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-FAST-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-FAST-NEXT: vfnmsub.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-FAST-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-FAST-NEXT: ret +-; +-; CONTRACT-ON-LABEL: vfnmsub_s_contract: +-; CONTRACT-ON: # %bb.0: # %entry +-; CONTRACT-ON-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-ON-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-ON-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-ON-NEXT: vfnmsub.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-ON-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-ON-NEXT: ret +-; +-; CONTRACT-OFF-LABEL: vfnmsub_s_contract: +-; CONTRACT-OFF: # %bb.0: # %entry +-; CONTRACT-OFF-NEXT: vld $vr0, $a3, 0 +-; CONTRACT-OFF-NEXT: vld $vr1, $a2, 0 +-; CONTRACT-OFF-NEXT: vld $vr2, $a1, 0 +-; CONTRACT-OFF-NEXT: vfnmsub.s $vr0, $vr2, $vr1, $vr0 +-; CONTRACT-OFF-NEXT: vst $vr0, $a0, 0 +-; CONTRACT-OFF-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = load <4 x float>, ptr %a2 +- %mul = fmul contract <4 x float> %v0, %v1 +- %negv2 = fneg contract <4 x float> %v2 +- %add = fadd contract <4 x float> %negv2, %mul +- %negadd = fneg contract <4 x float> %add +- store <4 x float> %negadd, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/fsqrt.ll b/llvm/test/CodeGen/LoongArch/lsx/fsqrt.ll +deleted file mode 100644 +index a57bc1ca0..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/fsqrt.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-;; fsqrt +-define void @sqrt_v4f32(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: sqrt_v4f32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vfsqrt.s $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0, align 16 +- %sqrt = call <4 x float> @llvm.sqrt.v4f32 (<4 x float> %v0) +- store <4 x float> %sqrt, ptr %res, align 16 +- ret void +-} +- +-define void @sqrt_v2f64(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: sqrt_v2f64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vfsqrt.d $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0, align 16 +- %sqrt = call <2 x double> @llvm.sqrt.v2f64 (<2 x double> %v0) +- store <2 x double> %sqrt, ptr %res, align 16 +- ret void +-} +- +-;; 1.0 / (fsqrt vec) +-define void @one_div_sqrt_v4f32(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: one_div_sqrt_v4f32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vfrsqrt.s $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0, align 16 +- %sqrt = call <4 x float> @llvm.sqrt.v4f32 (<4 x float> %v0) +- %div = fdiv <4 x float> , %sqrt +- store <4 x float> %div, ptr %res, align 16 +- ret void +-} +- +-define void @one_div_sqrt_v2f64(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: one_div_sqrt_v2f64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vfrsqrt.d $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0, align 16 +- %sqrt = call <2 x double> @llvm.sqrt.v2f64 (<2 x double> %v0) +- %div = fdiv <2 x double> , %sqrt +- store <2 x double> %div, ptr %res, align 16 +- ret void +-} +- +-declare <4 x float> @llvm.sqrt.v4f32(<4 x float>) +-declare <2 x double> @llvm.sqrt.v2f64(<2 x double>) +diff --git a/llvm/test/CodeGen/LoongArch/lsx/imm_vector_lsx.ll b/llvm/test/CodeGen/LoongArch/lsx/imm_vector_lsx.ll +new file mode 100644 +index 000000000..97b23be80 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lsx/imm_vector_lsx.ll +@@ -0,0 +1,176 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lsx < %s | FileCheck %s ++ ++define <2 x i64> @build_lsx0(<2 x i64> %a) { ++; CHECK-LABEL: build_lsx0: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -1 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: vreplgr2vr.d $vr1, $r4 ++; CHECK-NEXT: vadd.d $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %b = add <2 x i64> %a, ++ ret <2 x i64> %b ++} ++ ++define <2 x i64> @build_lsx1(<2 x i64> %a) { ++; CHECK-LABEL: build_lsx1: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu52i.d $r4, $zero, 2047 ++; CHECK-NEXT: vreplgr2vr.d $vr1, $r4 ++; CHECK-NEXT: vadd.d $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %b = add <2 x i64> %a, ++ ret <2 x i64> %b ++} ++ ++define <2 x i64> @build_lsx2(<2 x i64> %a) { ++; CHECK-LABEL: build_lsx2: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 2048 ++; CHECK-NEXT: lu32i.d $r4, 524287 ++; CHECK-NEXT: vreplgr2vr.d $vr1, $r4 ++; CHECK-NEXT: vadd.d $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %b = add <2 x i64> %a, ++ ret <2 x i64> %b ++} ++ ++define <2 x i64> @build_lsx3(<2 x i64> %a) { ++; CHECK-LABEL: build_lsx3: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 4095 ++; CHECK-NEXT: lu52i.d $r4, $r4, -1 ++; CHECK-NEXT: vreplgr2vr.d $vr1, $r4 ++; CHECK-NEXT: vadd.d $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %b = add <2 x i64> %a, ++ ret <2 x i64> %b ++} ++ ++define <2 x i64> @build_lsx4(<2 x i64> %a) { ++; CHECK-LABEL: build_lsx4: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ori $r4, $zero, 4095 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: vreplgr2vr.d $vr1, $r4 ++; CHECK-NEXT: vadd.d $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %b = add <2 x i64> %a, ++ ret <2 x i64> %b ++} ++ ++define <2 x i64> @build_lsx5(<2 x i64> %a) { ++; CHECK-LABEL: build_lsx5: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -2048 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: vreplgr2vr.d $vr1, $r4 ++; CHECK-NEXT: vadd.d $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %b = add <2 x i64> %a, ++ ret <2 x i64> %b ++} ++ ++define <2 x i64> @build_lsx6(<2 x i64> %a) { ++; CHECK-LABEL: build_lsx6: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -2048 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: vreplgr2vr.d $vr1, $r4 ++; CHECK-NEXT: vadd.d $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %b = add <2 x i64> %a, ++ ret <2 x i64> %b ++} ++ ++define <2 x i64> @build_lsx7(<2 x i64> %a) { ++; CHECK-LABEL: build_lsx7: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.w $r4, $zero, -2048 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: vreplgr2vr.d $vr1, $r4 ++; CHECK-NEXT: vadd.d $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %b = add <2 x i64> %a, ++ ret <2 x i64> %b ++} ++ ++define <2 x i64> @build_lsx8(<2 x i64> %a) { ++; CHECK-LABEL: build_lsx8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: vreplgr2vr.d $vr1, $r4 ++; CHECK-NEXT: vadd.d $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %b = add <2 x i64> %a, ++ ret <2 x i64> %b ++} ++ ++define <2 x i64> @build_lsx9(<2 x i64> %a) { ++; CHECK-LABEL: build_lsx9: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -1 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: vreplgr2vr.d $vr1, $r4 ++; CHECK-NEXT: vadd.d $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %b = add <2 x i64> %a, ++ ret <2 x i64> %b ++} ++ ++define <2 x i64> @build_lsx10(<2 x i64> %a) { ++; CHECK-LABEL: build_lsx10: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: lu32i.d $r4, 0 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: vreplgr2vr.d $vr1, $r4 ++; CHECK-NEXT: vadd.d $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %b = add <2 x i64> %a, ++ ret <2 x i64> %b ++} ++ ++define <2 x i64> @build_lsx11(<2 x i64> %a) { ++; CHECK-LABEL: build_lsx11: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, 524287 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, -1 ++; CHECK-NEXT: vreplgr2vr.d $vr1, $r4 ++; CHECK-NEXT: vadd.d $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %b = add <2 x i64> %a, ++ ret <2 x i64> %b ++} ++ ++define <2 x i64> @build_lsx12(<2 x i64> %a) { ++; CHECK-LABEL: build_lsx12: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2047 ++; CHECK-NEXT: lu52i.d $r4, $r4, 2047 ++; CHECK-NEXT: vreplgr2vr.d $vr1, $r4 ++; CHECK-NEXT: vadd.d $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %b = add <2 x i64> %a, ++ ret <2 x i64> %b ++} ++ ++define <2 x i64> @build_lsx13(<2 x i64> %a) { ++; CHECK-LABEL: build_lsx13: ++; CHECK: # %bb.0: ++; CHECK-NEXT: lu12i.w $r4, -524288 ++; CHECK-NEXT: ori $r4, $r4, 2048 ++; CHECK-NEXT: lu32i.d $r4, -524288 ++; CHECK-NEXT: lu52i.d $r4, $r4, 0 ++; CHECK-NEXT: vreplgr2vr.d $vr1, $r4 ++; CHECK-NEXT: vadd.d $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %b = add <2 x i64> %a, ++ ret <2 x i64> %b ++} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/inline-asm-operand-modifier.ll b/llvm/test/CodeGen/LoongArch/lsx/inline-asm-operand-modifier.ll +deleted file mode 100644 +index c46e624dd..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/inline-asm-operand-modifier.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @test_w() nounwind { +-; CHECK-LABEL: test_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: #APP +-; CHECK-NEXT: vldi $vr0, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: ret +-entry: +- %0 = tail call <2 x i64> asm sideeffect "vldi ${0:w}, 1", "=f"() +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/inline-asm-reg-names.ll b/llvm/test/CodeGen/LoongArch/lsx/inline-asm-reg-names.ll +deleted file mode 100644 +index ceea3621b..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/inline-asm-reg-names.ll ++++ /dev/null +@@ -1,58 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @register_vr1() nounwind { +-; CHECK-LABEL: register_vr1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: #APP +-; CHECK-NEXT: vldi $vr1, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: ret +-entry: +- %0 = tail call <2 x i64> asm sideeffect "vldi ${0:w}, 1", "={$vr1}"() +- ret void +-} +- +-define void @register_vr7() nounwind { +-; CHECK-LABEL: register_vr7: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: #APP +-; CHECK-NEXT: vldi $vr7, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: ret +-entry: +- %0 = tail call <2 x i64> asm sideeffect "vldi ${0:w}, 1", "={$vr7}"() +- ret void +-} +- +-define void @register_vr23() nounwind { +-; CHECK-LABEL: register_vr23: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: #APP +-; CHECK-NEXT: vldi $vr23, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: ret +-entry: +- %0 = tail call <2 x i64> asm sideeffect "vldi ${0:w}, 1", "={$vr23}"() +- ret void +-} +- +-;; The lower half of the vector register '$vr31' is overlapped with +-;; the floating-point register '$f31'. And '$f31' is a callee-saved +-;; register which is preserved across calls. That's why the +-;; fst.d and fld.d instructions are emitted. +-define void @register_vr31() nounwind { +-; CHECK-LABEL: register_vr31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: fst.d $fs7, $sp, 8 # 8-byte Folded Spill +-; CHECK-NEXT: #APP +-; CHECK-NEXT: vldi $vr31, 1 +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: fld.d $fs7, $sp, 8 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +-entry: +- %0 = tail call <2 x i64> asm sideeffect "vldi ${0:w}, 1", "={$vr31}"() +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/inline-asm.ll b/llvm/test/CodeGen/LoongArch/lsx/inline-asm.ll +new file mode 100644 +index 000000000..37cb6dfc9 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lsx/inline-asm.ll +@@ -0,0 +1,34 @@ ++; A basic inline assembly test ++ ++; RUN: llc -march=loongarch64 -mattr=+lsx < %s | FileCheck %s ++ ++@v2i64_r = global <2 x i64> zeroinitializer, align 16 ++ ++define void @test1() nounwind { ++entry: ++ ; CHECK-LABEL: test1: ++ %0 = call <2 x i64> asm "vldi ${0:w}, 1", "=f"() ++ ; CHECK: vldi $vr{{[1-3]?[0-9]}}, 1 ++ store <2 x i64> %0, <2 x i64>* @v2i64_r ++ ret void ++} ++ ++define void @test2() nounwind { ++entry: ++ ; CHECK-LABEL: test2: ++ %0 = load <2 x i64>, <2 x i64>* @v2i64_r ++ %1 = call <2 x i64> asm "vaddi.wu ${0:w}, ${1:w}, 1", "=f,f"(<2 x i64> %0) ++ ; CHECK: vaddi.wu $vr{{[1-3]?[0-9]}}, $vr{{[1-3]?[0-9]}}, 1 ++ store <2 x i64> %1, <2 x i64>* @v2i64_r ++ ret void ++} ++ ++define void @test3() nounwind { ++entry: ++ ; CHECK-LABEL: test3: ++ %0 = load <2 x i64>, <2 x i64>* @v2i64_r ++ %1 = call <2 x i64> asm sideeffect "vaddi.wu ${0:w}, ${1:w}, 1", "=f,f,~{$vr0}"(<2 x i64> %0) ++ ; CHECK: vaddi.wu $vr{{([1-9]|[1-3][0-9])}}, $vr{{([1-9]|[1-3][0-9])}}, 1 ++ store <2 x i64> %1, <2 x i64>* @v2i64_r ++ ret void ++} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/insertelement.ll b/llvm/test/CodeGen/LoongArch/lsx/insertelement.ll +new file mode 100644 +index 000000000..75001867a +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lsx/insertelement.ll +@@ -0,0 +1,171 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s ++ ++define <16 x i8> @insert_16xi8(<16 x i8> %v, i8 %in) { ++; CHECK-LABEL: insert_16xi8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r4, $r5, 0 ++; CHECK-NEXT: vinsgr2vr.b $vr0, $r4, 1 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <16 x i8> %v, i8 %in, i32 1 ++ ret <16 x i8> %r ++} ++ ++define <8 x i16> @insert_8xi16(<8 x i16> %v, i16 %in) { ++; CHECK-LABEL: insert_8xi16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r4, $r5, 0 ++; CHECK-NEXT: vinsgr2vr.h $vr0, $r4, 1 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <8 x i16> %v, i16 %in, i32 1 ++ ret <8 x i16> %r ++} ++ ++define <4 x i32> @insert_4xi32(<4 x i32> %v, i32 %in) { ++; CHECK-LABEL: insert_4xi32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r4, $r5, 0 ++; CHECK-NEXT: vinsgr2vr.w $vr0, $r4, 1 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <4 x i32> %v, i32 %in, i32 1 ++ ret <4 x i32> %r ++} ++ ++define <2 x i64> @insert_2xi64(<2 x i64> %v, i64 %in) { ++; CHECK-LABEL: insert_2xi64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vinsgr2vr.d $vr0, $r5, 1 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <2 x i64> %v, i64 %in, i32 1 ++ ret <2 x i64> %r ++} ++ ++define <4 x float> @insert_4xfloat(<4 x float> %v, float %in) { ++; CHECK-LABEL: insert_4xfloat: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # kill: def $f1 killed $f1 def $vr1 ++; CHECK-NEXT: vpickve2gr.w $r4, $vr1, 0 ++; CHECK-NEXT: vinsgr2vr.w $vr0, $r4, 1 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <4 x float> %v, float %in, i32 1 ++ ret <4 x float> %r ++} ++ ++define <2 x double> @insert_2xdouble(<2 x double> %v, double %in) { ++; CHECK-LABEL: insert_2xdouble: ++; CHECK: # %bb.0: ++; CHECK-NEXT: # kill: def $f1_64 killed $f1_64 def $vr1 ++; CHECK-NEXT: vpickve2gr.d $r4, $vr1, 0 ++; CHECK-NEXT: vinsgr2vr.d $vr0, $r4, 1 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <2 x double> %v, double %in, i32 1 ++ ret <2 x double> %r ++} ++ ++define <16 x i8> @insert_16xi8_idx(<16 x i8> %v, i8 %in, i32 %idx) { ++; CHECK-LABEL: insert_16xi8_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -16 ++; CHECK-NEXT: .cfi_def_cfa_offset 16 ++; CHECK-NEXT: vst $vr0, $sp, 0 ++; CHECK-NEXT: andi $r4, $r6, 15 ++; CHECK-NEXT: addi.d $r6, $sp, 0 ++; CHECK-NEXT: or $r4, $r6, $r4 ++; CHECK-NEXT: st.b $r5, $r4, 0 ++; CHECK-NEXT: vld $vr0, $sp, 0 ++; CHECK-NEXT: addi.d $sp, $sp, 16 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <16 x i8> %v, i8 %in, i32 %idx ++ ret <16 x i8> %r ++} ++ ++define <8 x i16> @insert_8xi16_idx(<8 x i16> %v, i16 %in, i32 %idx) { ++; CHECK-LABEL: insert_8xi16_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -16 ++; CHECK-NEXT: .cfi_def_cfa_offset 16 ++; CHECK-NEXT: vst $vr0, $sp, 0 ++; CHECK-NEXT: andi $r4, $r6, 7 ++; CHECK-NEXT: slli.d $r4, $r4, 1 ++; CHECK-NEXT: addi.d $r6, $sp, 0 ++; CHECK-NEXT: or $r4, $r6, $r4 ++; CHECK-NEXT: st.h $r5, $r4, 0 ++; CHECK-NEXT: vld $vr0, $sp, 0 ++; CHECK-NEXT: addi.d $sp, $sp, 16 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <8 x i16> %v, i16 %in, i32 %idx ++ ret <8 x i16> %r ++} ++ ++define <4 x i32> @insert_4xi32_idx(<4 x i32> %v, i32 %in, i32 %idx) { ++; CHECK-LABEL: insert_4xi32_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -16 ++; CHECK-NEXT: .cfi_def_cfa_offset 16 ++; CHECK-NEXT: vst $vr0, $sp, 0 ++; CHECK-NEXT: andi $r4, $r6, 3 ++; CHECK-NEXT: slli.d $r4, $r4, 2 ++; CHECK-NEXT: addi.d $r6, $sp, 0 ++; CHECK-NEXT: or $r4, $r6, $r4 ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: st.w $r5, $r4, 0 ++; CHECK-NEXT: vld $vr0, $sp, 0 ++; CHECK-NEXT: addi.d $sp, $sp, 16 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <4 x i32> %v, i32 %in, i32 %idx ++ ret <4 x i32> %r ++} ++ ++define <2 x i64> @insert_2xi64_idx(<2 x i64> %v, i64 %in, i32 %idx) { ++; CHECK-LABEL: insert_2xi64_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -16 ++; CHECK-NEXT: .cfi_def_cfa_offset 16 ++; CHECK-NEXT: vst $vr0, $sp, 0 ++; CHECK-NEXT: andi $r4, $r6, 1 ++; CHECK-NEXT: slli.d $r4, $r4, 3 ++; CHECK-NEXT: addi.d $r6, $sp, 0 ++; CHECK-NEXT: or $r4, $r6, $r4 ++; CHECK-NEXT: st.d $r5, $r4, 0 ++; CHECK-NEXT: vld $vr0, $sp, 0 ++; CHECK-NEXT: addi.d $sp, $sp, 16 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <2 x i64> %v, i64 %in, i32 %idx ++ ret <2 x i64> %r ++} ++ ++define <4 x float> @insert_4xfloat_idx(<4 x float> %v, float %in, i32 %idx) { ++; CHECK-LABEL: insert_4xfloat_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -16 ++; CHECK-NEXT: .cfi_def_cfa_offset 16 ++; CHECK-NEXT: vst $vr0, $sp, 0 ++; CHECK-NEXT: andi $r4, $r5, 3 ++; CHECK-NEXT: slli.d $r4, $r4, 2 ++; CHECK-NEXT: addi.d $r5, $sp, 0 ++; CHECK-NEXT: or $r4, $r5, $r4 ++; CHECK-NEXT: fst.s $f1, $r4, 0 ++; CHECK-NEXT: vld $vr0, $sp, 0 ++; CHECK-NEXT: addi.d $sp, $sp, 16 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <4 x float> %v, float %in, i32 %idx ++ ret <4 x float> %r ++} ++ ++define <2 x double> @insert_2xdouble_idx(<2 x double> %v, double %in, i32 %idx) { ++; CHECK-LABEL: insert_2xdouble_idx: ++; CHECK: # %bb.0: ++; CHECK-NEXT: addi.d $sp, $sp, -16 ++; CHECK-NEXT: .cfi_def_cfa_offset 16 ++; CHECK-NEXT: vst $vr0, $sp, 0 ++; CHECK-NEXT: andi $r4, $r5, 1 ++; CHECK-NEXT: slli.d $r4, $r4, 3 ++; CHECK-NEXT: addi.d $r5, $sp, 0 ++; CHECK-NEXT: or $r4, $r5, $r4 ++; CHECK-NEXT: fst.d $f1, $r4, 0 ++; CHECK-NEXT: vld $vr0, $sp, 0 ++; CHECK-NEXT: addi.d $sp, $sp, 16 ++; CHECK-NEXT: jr $ra ++ %r = insertelement <2 x double> %v, double %in, i32 %idx ++ ret <2 x double> %r ++} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-absd.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-absd.ll +deleted file mode 100644 +index 811d9d712..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-absd.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vabsd.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vabsd_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vabsd_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vabsd.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vabsd.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vabsd.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vabsd_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vabsd_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vabsd.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vabsd.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vabsd.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vabsd_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vabsd_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vabsd.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vabsd.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vabsd.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vabsd_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vabsd_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vabsd.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vabsd.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vabsd.bu(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vabsd_bu(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vabsd_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vabsd.bu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vabsd.bu(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vabsd.hu(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vabsd_hu(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vabsd_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vabsd.hu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vabsd.hu(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vabsd.wu(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vabsd_wu(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vabsd_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vabsd.wu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vabsd.wu(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vabsd.du(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vabsd_du(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vabsd_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vabsd.du $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vabsd.du(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-add.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-add.ll +deleted file mode 100644 +index fac16c830..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-add.ll ++++ /dev/null +@@ -1,62 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vadd.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vadd_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vadd_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vadd.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vadd.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vadd.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vadd_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vadd_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vadd.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vadd.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vadd.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vadd_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vadd_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vadd.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vadd.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vadd.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vadd_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vadd_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vadd.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vadd.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vadd.q(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vadd_q(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vadd_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vadd.q $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vadd.q(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-adda.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-adda.ll +deleted file mode 100644 +index 79be0a184..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-adda.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vadda.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vadda_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vadda_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vadda.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vadda.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vadda.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vadda_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vadda_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vadda.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vadda.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vadda.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vadda_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vadda_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vadda.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vadda.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vadda.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vadda_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vadda_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vadda.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vadda.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-addi-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-addi-invalid-imm.ll +deleted file mode 100644 +index 6875872b6..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-addi-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vaddi.bu(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vaddi_bu_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vaddi.bu: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vaddi.bu(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vaddi_bu_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vaddi.bu: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vaddi.bu(<16 x i8> %va, i32 32) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vaddi.hu(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vaddi_hu_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vaddi.hu: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vaddi.hu(<8 x i16> %va, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vaddi_hu_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vaddi.hu: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vaddi.hu(<8 x i16> %va, i32 32) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vaddi.wu(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vaddi_wu_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vaddi.wu: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vaddi.wu(<4 x i32> %va, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vaddi_wu_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vaddi.wu: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vaddi.wu(<4 x i32> %va, i32 32) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vaddi.du(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vaddi_du_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vaddi.du: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vaddi.du(<2 x i64> %va, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vaddi_du_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vaddi.du: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vaddi.du(<2 x i64> %va, i32 32) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-addi-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-addi-non-imm.ll +deleted file mode 100644 +index 87d32b3ce..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-addi-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vaddi.bu(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vaddi_bu(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vaddi.bu(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vaddi.hu(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vaddi_hu(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vaddi.hu(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vaddi.wu(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vaddi_wu(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vaddi.wu(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vaddi.du(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vaddi_du(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vaddi.du(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-addi.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-addi.ll +deleted file mode 100644 +index b9134e072..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-addi.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vaddi.bu(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vaddi_bu(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vaddi_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddi.bu $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vaddi.bu(<16 x i8> %va, i32 31) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vaddi.hu(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vaddi_hu(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vaddi_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddi.hu $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vaddi.hu(<8 x i16> %va, i32 31) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vaddi.wu(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vaddi_wu(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vaddi_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddi.wu $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vaddi.wu(<4 x i32> %va, i32 31) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vaddi.du(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vaddi_du(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vaddi_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddi.du $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vaddi.du(<2 x i64> %va, i32 31) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-addw.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-addw.ll +deleted file mode 100644 +index 086e3bec1..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-addw.ll ++++ /dev/null +@@ -1,290 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <8 x i16> @llvm.loongarch.lsx.vaddwev.h.b(<16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vaddwev_h_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwev_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwev.h.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vaddwev.h.b(<16 x i8> %va, <16 x i8> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vaddwev.w.h(<8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vaddwev_w_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwev_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwev.w.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vaddwev.w.h(<8 x i16> %va, <8 x i16> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vaddwev.d.w(<4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vaddwev_d_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwev_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwev.d.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vaddwev.d.w(<4 x i32> %va, <4 x i32> %vb) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vaddwev.q.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vaddwev_q_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwev_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwev.q.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vaddwev.q.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vaddwev.h.bu(<16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vaddwev_h_bu(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwev_h_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwev.h.bu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vaddwev.h.bu(<16 x i8> %va, <16 x i8> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vaddwev.w.hu(<8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vaddwev_w_hu(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwev_w_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwev.w.hu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vaddwev.w.hu(<8 x i16> %va, <8 x i16> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vaddwev.d.wu(<4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vaddwev_d_wu(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwev_d_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwev.d.wu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vaddwev.d.wu(<4 x i32> %va, <4 x i32> %vb) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vaddwev.q.du(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vaddwev_q_du(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwev_q_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwev.q.du $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vaddwev.q.du(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vaddwev.h.bu.b(<16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vaddwev_h_bu_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwev_h_bu_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwev.h.bu.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vaddwev.h.bu.b(<16 x i8> %va, <16 x i8> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vaddwev.w.hu.h(<8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vaddwev_w_hu_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwev_w_hu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwev.w.hu.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vaddwev.w.hu.h(<8 x i16> %va, <8 x i16> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vaddwev.d.wu.w(<4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vaddwev_d_wu_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwev_d_wu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwev.d.wu.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vaddwev.d.wu.w(<4 x i32> %va, <4 x i32> %vb) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vaddwev.q.du.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vaddwev_q_du_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwev_q_du_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwev.q.du.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vaddwev.q.du.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vaddwod.h.b(<16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vaddwod_h_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwod_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwod.h.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vaddwod.h.b(<16 x i8> %va, <16 x i8> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vaddwod.w.h(<8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vaddwod_w_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwod_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwod.w.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vaddwod.w.h(<8 x i16> %va, <8 x i16> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vaddwod.d.w(<4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vaddwod_d_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwod_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwod.d.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vaddwod.d.w(<4 x i32> %va, <4 x i32> %vb) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vaddwod.q.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vaddwod_q_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwod_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwod.q.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vaddwod.q.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vaddwod.h.bu(<16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vaddwod_h_bu(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwod_h_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwod.h.bu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vaddwod.h.bu(<16 x i8> %va, <16 x i8> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vaddwod.w.hu(<8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vaddwod_w_hu(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwod_w_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwod.w.hu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vaddwod.w.hu(<8 x i16> %va, <8 x i16> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vaddwod.d.wu(<4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vaddwod_d_wu(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwod_d_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwod.d.wu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vaddwod.d.wu(<4 x i32> %va, <4 x i32> %vb) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vaddwod.q.du(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vaddwod_q_du(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwod_q_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwod.q.du $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vaddwod.q.du(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vaddwod.h.bu.b(<16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vaddwod_h_bu_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwod_h_bu_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwod.h.bu.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vaddwod.h.bu.b(<16 x i8> %va, <16 x i8> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vaddwod.w.hu.h(<8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vaddwod_w_hu_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwod_w_hu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwod.w.hu.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vaddwod.w.hu.h(<8 x i16> %va, <8 x i16> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vaddwod.d.wu.w(<4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vaddwod_d_wu_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwod_d_wu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwod.d.wu.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vaddwod.d.wu.w(<4 x i32> %va, <4 x i32> %vb) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vaddwod.q.du.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vaddwod_q_du_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vaddwod_q_du_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vaddwod.q.du.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vaddwod.q.du.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-and.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-and.ll +deleted file mode 100644 +index 77496239c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-and.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vand.v(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vand_v(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vand_v: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vand.v $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vand.v(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-andi-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-andi-invalid-imm.ll +deleted file mode 100644 +index 82a117b2a..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-andi-invalid-imm.ll ++++ /dev/null +@@ -1,17 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vandi.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vandi_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vandi.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vandi.b(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vandi_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vandi.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vandi.b(<16 x i8> %va, i32 256) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-andi-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-andi-non-imm.ll +deleted file mode 100644 +index c0c35c775..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-andi-non-imm.ll ++++ /dev/null +@@ -1,10 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vandi.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vandi_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vandi.b(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-andi.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-andi.ll +deleted file mode 100644 +index 9a1c38a64..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-andi.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vandi.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vandi_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vandi_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vandi.b $vr0, $vr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vandi.b(<16 x i8> %va, i32 1) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-andn.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-andn.ll +deleted file mode 100644 +index b08c759ec..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-andn.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vandn.v(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vandn_v(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vandn_v: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vandn.v $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vandn.v(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-avg.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-avg.ll +deleted file mode 100644 +index fb0861f4c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-avg.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vavg.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vavg_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vavg_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vavg.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vavg.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vavg.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vavg_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vavg_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vavg.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vavg.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vavg.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vavg_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vavg_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vavg.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vavg.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vavg.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vavg_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vavg_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vavg.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vavg.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vavg.bu(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vavg_bu(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vavg_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vavg.bu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vavg.bu(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vavg.hu(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vavg_hu(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vavg_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vavg.hu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vavg.hu(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vavg.wu(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vavg_wu(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vavg_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vavg.wu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vavg.wu(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vavg.du(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vavg_du(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vavg_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vavg.du $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vavg.du(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-avgr.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-avgr.ll +deleted file mode 100644 +index 8bf7d0ed8..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-avgr.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vavgr.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vavgr_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vavgr_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vavgr.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vavgr.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vavgr.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vavgr_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vavgr_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vavgr.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vavgr.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vavgr.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vavgr_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vavgr_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vavgr.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vavgr.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vavgr.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vavgr_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vavgr_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vavgr.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vavgr.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vavgr.bu(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vavgr_bu(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vavgr_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vavgr.bu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vavgr.bu(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vavgr.hu(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vavgr_hu(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vavgr_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vavgr.hu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vavgr.hu(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vavgr.wu(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vavgr_wu(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vavgr_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vavgr.wu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vavgr.wu(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vavgr.du(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vavgr_du(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vavgr_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vavgr.du $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vavgr.du(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitclr-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitclr-invalid-imm.ll +deleted file mode 100644 +index b020806cd..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitclr-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vbitclri.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vbitclri_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitclri.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbitclri.b(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vbitclri_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitclri.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbitclri.b(<16 x i8> %va, i32 8) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vbitclri.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vbitclri_h_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitclri.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vbitclri.h(<8 x i16> %va, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vbitclri_h_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitclri.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vbitclri.h(<8 x i16> %va, i32 16) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vbitclri.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vbitclri_w_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitclri.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vbitclri.w(<4 x i32> %va, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vbitclri_w_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitclri.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vbitclri.w(<4 x i32> %va, i32 32) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vbitclri.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vbitclri_d_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitclri.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vbitclri.d(<2 x i64> %va, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vbitclri_d_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitclri.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vbitclri.d(<2 x i64> %va, i32 64) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitclr-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitclr-non-imm.ll +deleted file mode 100644 +index df6cdb99c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitclr-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vbitclri.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vbitclri_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbitclri.b(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vbitclri.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vbitclri_h(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vbitclri.h(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vbitclri.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vbitclri_w(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vbitclri.w(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vbitclri.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vbitclri_d(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vbitclri.d(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitclr.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitclr.ll +deleted file mode 100644 +index f5fba6dbb..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitclr.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vbitclr.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vbitclr_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vbitclr_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitclr.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbitclr.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vbitclr.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vbitclr_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vbitclr_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitclr.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vbitclr.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vbitclr.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vbitclr_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vbitclr_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitclr.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vbitclr.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vbitclr.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vbitclr_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vbitclr_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitclr.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vbitclr.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vbitclri.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vbitclri_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vbitclri_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitclri.b $vr0, $vr0, 7 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbitclri.b(<16 x i8> %va, i32 7) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vbitclri.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vbitclri_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vbitclri_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitclri.h $vr0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vbitclri.h(<8 x i16> %va, i32 15) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vbitclri.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vbitclri_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vbitclri_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitclri.w $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vbitclri.w(<4 x i32> %va, i32 31) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vbitclri.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vbitclri_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vbitclri_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitclri.d $vr0, $vr0, 63 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vbitclri.d(<2 x i64> %va, i32 63) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitrev-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitrev-invalid-imm.ll +deleted file mode 100644 +index 24b6ec328..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitrev-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vbitrevi.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vbitrevi_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitrevi.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbitrevi.b(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vbitrevi_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitrevi.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbitrevi.b(<16 x i8> %va, i32 8) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vbitrevi.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vbitrevi_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitrevi.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vbitrevi.h(<8 x i16> %va, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vbitrevi_h_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitrevi.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vbitrevi.h(<8 x i16> %va, i32 16) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vbitrevi.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vbitrevi_w_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitrevi.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vbitrevi.w(<4 x i32> %va, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vbitrevi_w_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitrevi.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vbitrevi.w(<4 x i32> %va, i32 32) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vbitrevi.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vbitrevi_d_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitrevi.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vbitrevi.d(<2 x i64> %va, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vbitrevi_d_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitrevi.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vbitrevi.d(<2 x i64> %va, i32 64) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitrev-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitrev-non-imm.ll +deleted file mode 100644 +index 3ffb494c9..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitrev-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vbitrevi.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vbitrevi_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbitrevi.b(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vbitrevi.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vbitrevi_h(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vbitrevi.h(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vbitrevi.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vbitrevi_w(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vbitrevi.w(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vbitrevi.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vbitrevi_d(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vbitrevi.d(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitrev.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitrev.ll +deleted file mode 100644 +index ad56e88fd..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitrev.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vbitrev.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vbitrev_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vbitrev_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitrev.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbitrev.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vbitrev.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vbitrev_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vbitrev_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitrev.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vbitrev.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vbitrev.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vbitrev_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vbitrev_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitrev.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vbitrev.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vbitrev.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vbitrev_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vbitrev_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitrev.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vbitrev.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vbitrevi.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vbitrevi_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vbitrevi_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitrevi.b $vr0, $vr0, 7 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbitrevi.b(<16 x i8> %va, i32 7) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vbitrevi.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vbitrevi_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vbitrevi_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitrevi.h $vr0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vbitrevi.h(<8 x i16> %va, i32 15) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vbitrevi.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vbitrevi_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vbitrevi_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitrevi.w $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vbitrevi.w(<4 x i32> %va, i32 31) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vbitrevi.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vbitrevi_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vbitrevi_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitrevi.d $vr0, $vr0, 63 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vbitrevi.d(<2 x i64> %va, i32 63) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitsel.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitsel.ll +deleted file mode 100644 +index 4b4b5ff1f..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitsel.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vbitsel.v(<16 x i8>, <16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vbitsel_v(<16 x i8> %va, <16 x i8> %vb, <16 x i8> %vc) nounwind { +-; CHECK-LABEL: lsx_vbitsel_v: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitsel.v $vr0, $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbitsel.v(<16 x i8> %va, <16 x i8> %vb, <16 x i8> %vc) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitseli-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitseli-invalid-imm.ll +deleted file mode 100644 +index bc63b40e9..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitseli-invalid-imm.ll ++++ /dev/null +@@ -1,17 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vbitseli.b(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vbitseli_b_lo(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitseli.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbitseli.b(<16 x i8> %va, <16 x i8> %vb, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vbitseli_b_hi(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitseli.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbitseli.b(<16 x i8> %va, <16 x i8> %vb, i32 256) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitseli-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitseli-non-imm.ll +deleted file mode 100644 +index 52c1eb7d2..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitseli-non-imm.ll ++++ /dev/null +@@ -1,10 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vbitseli.b(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vbitseli_b(<16 x i8> %va, <16 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbitseli.b(<16 x i8> %va, <16 x i8> %vb, i32 %c) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitseli.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitseli.ll +deleted file mode 100644 +index 28d342b5c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitseli.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vbitseli.b(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vbitseli_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vbitseli_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitseli.b $vr0, $vr1, 255 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbitseli.b(<16 x i8> %va, <16 x i8> %vb, i32 255) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitset-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitset-invalid-imm.ll +deleted file mode 100644 +index e57e14d8c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitset-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vbitseti.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vbitseti_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitseti.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbitseti.b(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vbitseti_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitseti.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbitseti.b(<16 x i8> %va, i32 8) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vbitseti.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vbitseti_h_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitseti.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vbitseti.h(<8 x i16> %va, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vbitseti_h_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitseti.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vbitseti.h(<8 x i16> %va, i32 16) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vbitseti.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vbitseti_w_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitseti.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vbitseti.w(<4 x i32> %va, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vbitseti_w_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitseti.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vbitseti.w(<4 x i32> %va, i32 32) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vbitseti.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vbitseti_d_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitseti.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vbitseti.d(<2 x i64> %va, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vbitseti_d_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbitseti.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vbitseti.d(<2 x i64> %va, i32 64) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitset-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitset-non-imm.ll +deleted file mode 100644 +index 9b2bde015..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitset-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vbitseti.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vbitseti_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbitseti.b(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vbitseti.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vbitseti_h(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vbitseti.h(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vbitseti.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vbitseti_w(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vbitseti.w(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vbitseti.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vbitseti_d(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vbitseti.d(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitset.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitset.ll +deleted file mode 100644 +index 75d98e6f8..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bitset.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vbitset.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vbitset_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vbitset_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitset.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbitset.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vbitset.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vbitset_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vbitset_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitset.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vbitset.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vbitset.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vbitset_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vbitset_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitset.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vbitset.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vbitset.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vbitset_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vbitset_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitset.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vbitset.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vbitseti.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vbitseti_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vbitseti_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitseti.b $vr0, $vr0, 7 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbitseti.b(<16 x i8> %va, i32 7) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vbitseti.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vbitseti_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vbitseti_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitseti.h $vr0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vbitseti.h(<8 x i16> %va, i32 15) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vbitseti.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vbitseti_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vbitseti_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitseti.w $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vbitseti.w(<4 x i32> %va, i32 31) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vbitseti.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vbitseti_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vbitseti_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbitseti.d $vr0, $vr0, 63 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vbitseti.d(<2 x i64> %va, i32 63) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bsll-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bsll-invalid-imm.ll +deleted file mode 100644 +index eb49af49c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bsll-invalid-imm.ll ++++ /dev/null +@@ -1,17 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vbsll.v(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vbsll_v_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbsll.v: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbsll.v(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vbsll_v_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbsll.v: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbsll.v(<16 x i8> %va, i32 32) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bsll-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bsll-non-imm.ll +deleted file mode 100644 +index 5b10c9e91..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bsll-non-imm.ll ++++ /dev/null +@@ -1,10 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vbsll.v(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vbsll_v(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbsll.v(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bsll.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bsll.ll +deleted file mode 100644 +index e7eb1cfcb..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bsll.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vbsll.v(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vbsll_v(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vbsll_v: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbsll.v $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbsll.v(<16 x i8> %va, i32 31) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bsrl-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bsrl-invalid-imm.ll +deleted file mode 100644 +index bf56822e2..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bsrl-invalid-imm.ll ++++ /dev/null +@@ -1,17 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vbsrl.v(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vbsrl_v_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbsrl.v: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbsrl.v(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vbsrl_v_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vbsrl.v: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbsrl.v(<16 x i8> %va, i32 32) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bsrl-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bsrl-non-imm.ll +deleted file mode 100644 +index 0bc038c86..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bsrl-non-imm.ll ++++ /dev/null +@@ -1,10 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vbsrl.v(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vbsrl_v(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbsrl.v(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bsrl.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bsrl.ll +deleted file mode 100644 +index fe0565297..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-bsrl.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vbsrl.v(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vbsrl_v(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vbsrl_v: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vbsrl.v $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vbsrl.v(<16 x i8> %va, i32 31) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-clo.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-clo.ll +deleted file mode 100644 +index c581109f3..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-clo.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vclo.b(<16 x i8>) +- +-define <16 x i8> @lsx_vclo_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vclo_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vclo.b $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vclo.b(<16 x i8> %va) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vclo.h(<8 x i16>) +- +-define <8 x i16> @lsx_vclo_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vclo_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vclo.h $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vclo.h(<8 x i16> %va) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vclo.w(<4 x i32>) +- +-define <4 x i32> @lsx_vclo_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vclo_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vclo.w $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vclo.w(<4 x i32> %va) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vclo.d(<2 x i64>) +- +-define <2 x i64> @lsx_vclo_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vclo_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vclo.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vclo.d(<2 x i64> %va) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-clz.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-clz.ll +deleted file mode 100644 +index 25c37b643..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-clz.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vclz.b(<16 x i8>) +- +-define <16 x i8> @lsx_vclz_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vclz_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vclz.b $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vclz.b(<16 x i8> %va) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vclz.h(<8 x i16>) +- +-define <8 x i16> @lsx_vclz_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vclz_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vclz.h $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vclz.h(<8 x i16> %va) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vclz.w(<4 x i32>) +- +-define <4 x i32> @lsx_vclz_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vclz_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vclz.w $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vclz.w(<4 x i32> %va) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vclz.d(<2 x i64>) +- +-define <2 x i64> @lsx_vclz_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vclz_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vclz.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vclz.d(<2 x i64> %va) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-div.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-div.ll +deleted file mode 100644 +index 53166e84d..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-div.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vdiv.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vdiv_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vdiv_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vdiv.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vdiv.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vdiv.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vdiv_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vdiv_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vdiv.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vdiv.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vdiv.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vdiv_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vdiv_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vdiv.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vdiv.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vdiv.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vdiv_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vdiv_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vdiv.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vdiv.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vdiv.bu(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vdiv_bu(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vdiv_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vdiv.bu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vdiv.bu(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vdiv.hu(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vdiv_hu(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vdiv_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vdiv.hu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vdiv.hu(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vdiv.wu(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vdiv_wu(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vdiv_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vdiv.wu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vdiv.wu(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vdiv.du(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vdiv_du(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vdiv_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vdiv.du $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vdiv.du(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-exth.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-exth.ll +deleted file mode 100644 +index 2f3e891a9..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-exth.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <8 x i16> @llvm.loongarch.lsx.vexth.h.b(<16 x i8>) +- +-define <8 x i16> @lsx_vexth_h_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vexth_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vexth.h.b $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vexth.h.b(<16 x i8> %va) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vexth.w.h(<8 x i16>) +- +-define <4 x i32> @lsx_vexth_w_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vexth_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vexth.w.h $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vexth.w.h(<8 x i16> %va) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vexth.d.w(<4 x i32>) +- +-define <2 x i64> @lsx_vexth_d_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vexth_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vexth.d.w $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vexth.d.w(<4 x i32> %va) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vexth.q.d(<2 x i64>) +- +-define <2 x i64> @lsx_vexth_q_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vexth_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vexth.q.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vexth.q.d(<2 x i64> %va) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vexth.hu.bu(<16 x i8>) +- +-define <8 x i16> @lsx_vexth_hu_bu(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vexth_hu_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vexth.hu.bu $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vexth.hu.bu(<16 x i8> %va) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vexth.wu.hu(<8 x i16>) +- +-define <4 x i32> @lsx_vexth_wu_hu(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vexth_wu_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vexth.wu.hu $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vexth.wu.hu(<8 x i16> %va) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vexth.du.wu(<4 x i32>) +- +-define <2 x i64> @lsx_vexth_du_wu(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vexth_du_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vexth.du.wu $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vexth.du.wu(<4 x i32> %va) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vexth.qu.du(<2 x i64>) +- +-define <2 x i64> @lsx_vexth_qu_du(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vexth_qu_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vexth.qu.du $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vexth.qu.du(<2 x i64> %va) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-extl.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-extl.ll +deleted file mode 100644 +index cbf19e2a3..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-extl.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <2 x i64> @llvm.loongarch.lsx.vextl.q.d(<2 x i64>) +- +-define <2 x i64> @lsx_vextl_q_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vextl_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vextl.q.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vextl.q.d(<2 x i64> %va) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vextl.qu.du(<2 x i64>) +- +-define <2 x i64> @lsx_vextl_qu_du(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vextl_qu_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vextl.qu.du $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vextl.qu.du(<2 x i64> %va) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-extrins-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-extrins-invalid-imm.ll +deleted file mode 100644 +index 7f94234ed..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-extrins-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vextrins.b(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vextrins_b_lo(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vextrins.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vextrins.b(<16 x i8> %va, <16 x i8> %vb, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vextrins_b_hi(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vextrins.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vextrins.b(<16 x i8> %va, <16 x i8> %vb, i32 256) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vextrins.h(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vextrins_h_lo(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vextrins.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vextrins.h(<8 x i16> %va, <8 x i16> %vb, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vextrins_h_hi(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vextrins.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vextrins.h(<8 x i16> %va, <8 x i16> %vb, i32 256) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vextrins.w(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vextrins_w_lo(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vextrins.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vextrins.w(<4 x i32> %va, <4 x i32> %vb, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vextrins_w_hi(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vextrins.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vextrins.w(<4 x i32> %va, <4 x i32> %vb, i32 256) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vextrins.d(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vextrins_d_lo(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vextrins.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vextrins.d(<2 x i64> %va, <2 x i64> %vb, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vextrins_d_hi(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vextrins.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vextrins.d(<2 x i64> %va, <2 x i64> %vb, i32 256) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-extrins-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-extrins-non-imm.ll +deleted file mode 100644 +index e834002bb..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-extrins-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vextrins.b(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vextrins_b(<16 x i8> %va, <16 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vextrins.b(<16 x i8> %va, <16 x i8> %vb, i32 %c) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vextrins.h(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vextrins_h(<8 x i16> %va, <8 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vextrins.h(<8 x i16> %va, <8 x i16> %vb, i32 %c) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vextrins.w(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vextrins_w(<4 x i32> %va, <4 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vextrins.w(<4 x i32> %va, <4 x i32> %vb, i32 %c) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vextrins.d(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vextrins_d(<2 x i64> %va, <2 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vextrins.d(<2 x i64> %va, <2 x i64> %vb, i32 %c) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-extrins.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-extrins.ll +deleted file mode 100644 +index 8f03a2b81..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-extrins.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vextrins.b(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vextrins_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vextrins_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vextrins.b $vr0, $vr1, 255 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vextrins.b(<16 x i8> %va, <16 x i8> %vb, i32 255) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vextrins.h(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vextrins_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vextrins_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vextrins.h $vr0, $vr1, 255 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vextrins.h(<8 x i16> %va, <8 x i16> %vb, i32 255) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vextrins.w(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vextrins_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vextrins_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vextrins.w $vr0, $vr1, 255 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vextrins.w(<4 x i32> %va, <4 x i32> %vb, i32 255) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vextrins.d(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vextrins_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vextrins_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vextrins.d $vr0, $vr1, 255 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vextrins.d(<2 x i64> %va, <2 x i64> %vb, i32 255) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fadd.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fadd.ll +deleted file mode 100644 +index 569002314..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fadd.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x float> @llvm.loongarch.lsx.vfadd.s(<4 x float>, <4 x float>) +- +-define <4 x float> @lsx_vfadd_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfadd_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfadd.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vfadd.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vfadd.d(<2 x double>, <2 x double>) +- +-define <2 x double> @lsx_vfadd_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfadd_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfadd.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vfadd.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fclass.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fclass.ll +deleted file mode 100644 +index 0c6682187..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fclass.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x i32> @llvm.loongarch.lsx.vfclass.s(<4 x float>) +- +-define <4 x i32> @lsx_vfclass_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vfclass_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfclass.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfclass.s(<4 x float> %va) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfclass.d(<2 x double>) +- +-define <2 x i64> @lsx_vfclass_d(<2 x double> %va) nounwind { +-; CHECK-LABEL: lsx_vfclass_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfclass.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfclass.d(<2 x double> %va) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fcmp.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fcmp.ll +deleted file mode 100644 +index 669c53b73..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fcmp.ll ++++ /dev/null +@@ -1,530 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x i32> @llvm.loongarch.lsx.vfcmp.caf.s(<4 x float>, <4 x float>) +- +-define <4 x i32> @lsx_vfcmp_caf_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_caf_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.caf.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfcmp.caf.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfcmp.caf.d(<2 x double>, <2 x double>) +- +-define <2 x i64> @lsx_vfcmp_caf_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_caf_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.caf.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfcmp.caf.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vfcmp.cun.s(<4 x float>, <4 x float>) +- +-define <4 x i32> @lsx_vfcmp_cun_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_cun_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.cun.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfcmp.cun.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfcmp.cun.d(<2 x double>, <2 x double>) +- +-define <2 x i64> @lsx_vfcmp_cun_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_cun_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.cun.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfcmp.cun.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vfcmp.ceq.s(<4 x float>, <4 x float>) +- +-define <4 x i32> @lsx_vfcmp_ceq_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_ceq_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.ceq.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfcmp.ceq.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfcmp.ceq.d(<2 x double>, <2 x double>) +- +-define <2 x i64> @lsx_vfcmp_ceq_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_ceq_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.ceq.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfcmp.ceq.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vfcmp.cueq.s(<4 x float>, <4 x float>) +- +-define <4 x i32> @lsx_vfcmp_cueq_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_cueq_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.cueq.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfcmp.cueq.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfcmp.cueq.d(<2 x double>, <2 x double>) +- +-define <2 x i64> @lsx_vfcmp_cueq_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_cueq_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.cueq.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfcmp.cueq.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vfcmp.clt.s(<4 x float>, <4 x float>) +- +-define <4 x i32> @lsx_vfcmp_clt_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_clt_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.clt.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfcmp.clt.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfcmp.clt.d(<2 x double>, <2 x double>) +- +-define <2 x i64> @lsx_vfcmp_clt_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_clt_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.clt.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfcmp.clt.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vfcmp.cult.s(<4 x float>, <4 x float>) +- +-define <4 x i32> @lsx_vfcmp_cult_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_cult_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.cult.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfcmp.cult.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfcmp.cult.d(<2 x double>, <2 x double>) +- +-define <2 x i64> @lsx_vfcmp_cult_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_cult_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.cult.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfcmp.cult.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vfcmp.cle.s(<4 x float>, <4 x float>) +- +-define <4 x i32> @lsx_vfcmp_cle_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_cle_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.cle.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfcmp.cle.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfcmp.cle.d(<2 x double>, <2 x double>) +- +-define <2 x i64> @lsx_vfcmp_cle_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_cle_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.cle.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfcmp.cle.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vfcmp.cule.s(<4 x float>, <4 x float>) +- +-define <4 x i32> @lsx_vfcmp_cule_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_cule_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.cule.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfcmp.cule.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfcmp.cule.d(<2 x double>, <2 x double>) +- +-define <2 x i64> @lsx_vfcmp_cule_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_cule_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.cule.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfcmp.cule.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vfcmp.cne.s(<4 x float>, <4 x float>) +- +-define <4 x i32> @lsx_vfcmp_cne_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_cne_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.cne.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfcmp.cne.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfcmp.cne.d(<2 x double>, <2 x double>) +- +-define <2 x i64> @lsx_vfcmp_cne_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_cne_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.cne.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfcmp.cne.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vfcmp.cor.s(<4 x float>, <4 x float>) +- +-define <4 x i32> @lsx_vfcmp_cor_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_cor_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.cor.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfcmp.cor.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfcmp.cor.d(<2 x double>, <2 x double>) +- +-define <2 x i64> @lsx_vfcmp_cor_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_cor_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.cor.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfcmp.cor.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vfcmp.cune.s(<4 x float>, <4 x float>) +- +-define <4 x i32> @lsx_vfcmp_cune_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_cune_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.cune.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfcmp.cune.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfcmp.cune.d(<2 x double>, <2 x double>) +- +-define <2 x i64> @lsx_vfcmp_cune_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_cune_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.cune.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfcmp.cune.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vfcmp.saf.s(<4 x float>, <4 x float>) +- +-define <4 x i32> @lsx_vfcmp_saf_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_saf_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.saf.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfcmp.saf.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfcmp.saf.d(<2 x double>, <2 x double>) +- +-define <2 x i64> @lsx_vfcmp_saf_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_saf_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.saf.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfcmp.saf.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vfcmp.sun.s(<4 x float>, <4 x float>) +- +-define <4 x i32> @lsx_vfcmp_sun_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_sun_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.sun.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfcmp.sun.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfcmp.sun.d(<2 x double>, <2 x double>) +- +-define <2 x i64> @lsx_vfcmp_sun_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_sun_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.sun.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfcmp.sun.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vfcmp.seq.s(<4 x float>, <4 x float>) +- +-define <4 x i32> @lsx_vfcmp_seq_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_seq_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.seq.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfcmp.seq.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfcmp.seq.d(<2 x double>, <2 x double>) +- +-define <2 x i64> @lsx_vfcmp_seq_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_seq_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.seq.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfcmp.seq.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vfcmp.sueq.s(<4 x float>, <4 x float>) +- +-define <4 x i32> @lsx_vfcmp_sueq_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_sueq_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.sueq.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfcmp.sueq.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfcmp.sueq.d(<2 x double>, <2 x double>) +- +-define <2 x i64> @lsx_vfcmp_sueq_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_sueq_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.sueq.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfcmp.sueq.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vfcmp.slt.s(<4 x float>, <4 x float>) +- +-define <4 x i32> @lsx_vfcmp_slt_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_slt_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.slt.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfcmp.slt.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfcmp.slt.d(<2 x double>, <2 x double>) +- +-define <2 x i64> @lsx_vfcmp_slt_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_slt_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.slt.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfcmp.slt.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vfcmp.sult.s(<4 x float>, <4 x float>) +- +-define <4 x i32> @lsx_vfcmp_sult_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_sult_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.sult.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfcmp.sult.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfcmp.sult.d(<2 x double>, <2 x double>) +- +-define <2 x i64> @lsx_vfcmp_sult_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_sult_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.sult.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfcmp.sult.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vfcmp.sle.s(<4 x float>, <4 x float>) +- +-define <4 x i32> @lsx_vfcmp_sle_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_sle_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.sle.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfcmp.sle.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfcmp.sle.d(<2 x double>, <2 x double>) +- +-define <2 x i64> @lsx_vfcmp_sle_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_sle_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.sle.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfcmp.sle.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vfcmp.sule.s(<4 x float>, <4 x float>) +- +-define <4 x i32> @lsx_vfcmp_sule_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_sule_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.sule.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfcmp.sule.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfcmp.sule.d(<2 x double>, <2 x double>) +- +-define <2 x i64> @lsx_vfcmp_sule_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_sule_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.sule.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfcmp.sule.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vfcmp.sne.s(<4 x float>, <4 x float>) +- +-define <4 x i32> @lsx_vfcmp_sne_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_sne_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.sne.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfcmp.sne.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfcmp.sne.d(<2 x double>, <2 x double>) +- +-define <2 x i64> @lsx_vfcmp_sne_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_sne_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.sne.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfcmp.sne.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vfcmp.sor.s(<4 x float>, <4 x float>) +- +-define <4 x i32> @lsx_vfcmp_sor_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_sor_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.sor.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfcmp.sor.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfcmp.sor.d(<2 x double>, <2 x double>) +- +-define <2 x i64> @lsx_vfcmp_sor_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_sor_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.sor.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfcmp.sor.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vfcmp.sune.s(<4 x float>, <4 x float>) +- +-define <4 x i32> @lsx_vfcmp_sune_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_sune_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.sune.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vfcmp.sune.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vfcmp.sune.d(<2 x double>, <2 x double>) +- +-define <2 x i64> @lsx_vfcmp_sune_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcmp_sune_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcmp.sune.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vfcmp.sune.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fcvth.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fcvth.ll +deleted file mode 100644 +index a9e4328bd..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fcvth.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x float> @llvm.loongarch.lsx.vfcvth.s.h(<8 x i16>) +- +-define <4 x float> @lsx_vfcvth_s_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vfcvth_s_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcvth.s.h $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vfcvth.s.h(<8 x i16> %va) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vfcvth.d.s(<4 x float>) +- +-define <2 x double> @lsx_vfcvth_d_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vfcvth_d_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcvth.d.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vfcvth.d.s(<4 x float> %va) +- ret <2 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fcvtl.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fcvtl.ll +deleted file mode 100644 +index 9a69964bb..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fcvtl.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x float> @llvm.loongarch.lsx.vfcvtl.s.h(<8 x i16>) +- +-define <4 x float> @lsx_vfcvtl_s_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vfcvtl_s_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcvtl.s.h $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vfcvtl.s.h(<8 x i16> %va) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vfcvtl.d.s(<4 x float>) +- +-define <2 x double> @lsx_vfcvtl_d_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vfcvtl_d_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcvtl.d.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vfcvtl.d.s(<4 x float> %va) +- ret <2 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fdiv.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fdiv.ll +deleted file mode 100644 +index 1ca8e5e2c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fdiv.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x float> @llvm.loongarch.lsx.vfdiv.s(<4 x float>, <4 x float>) +- +-define <4 x float> @lsx_vfdiv_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfdiv_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfdiv.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vfdiv.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vfdiv.d(<2 x double>, <2 x double>) +- +-define <2 x double> @lsx_vfdiv_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfdiv_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfdiv.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vfdiv.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ffint.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ffint.ll +deleted file mode 100644 +index 62fbcfa33..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ffint.ll ++++ /dev/null +@@ -1,86 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x float> @llvm.loongarch.lsx.vffint.s.w(<4 x i32>) +- +-define <4 x float> @lsx_vffint_s_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vffint_s_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vffint.s.w $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vffint.s.w(<4 x i32> %va) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vffint.d.l(<2 x i64>) +- +-define <2 x double> @lsx_vffint_d_l(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vffint_d_l: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vffint.d.l $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vffint.d.l(<2 x i64> %va) +- ret <2 x double> %res +-} +- +-declare <4 x float> @llvm.loongarch.lsx.vffint.s.wu(<4 x i32>) +- +-define <4 x float> @lsx_vffint_s_wu(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vffint_s_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vffint.s.wu $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vffint.s.wu(<4 x i32> %va) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vffint.d.lu(<2 x i64>) +- +-define <2 x double> @lsx_vffint_d_lu(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vffint_d_lu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vffint.d.lu $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vffint.d.lu(<2 x i64> %va) +- ret <2 x double> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vffintl.d.w(<4 x i32>) +- +-define <2 x double> @lsx_vffintl_d_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vffintl_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vffintl.d.w $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vffintl.d.w(<4 x i32> %va) +- ret <2 x double> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vffinth.d.w(<4 x i32>) +- +-define <2 x double> @lsx_vffinth_d_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vffinth_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vffinth.d.w $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vffinth.d.w(<4 x i32> %va) +- ret <2 x double> %res +-} +- +-declare <4 x float> @llvm.loongarch.lsx.vffint.s.l(<2 x i64>, <2 x i64>) +- +-define <4 x float> @lsx_vffint_s_l(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vffint_s_l: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vffint.s.l $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vffint.s.l(<2 x i64> %va, <2 x i64> %vb) +- ret <4 x float> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-flogb.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-flogb.ll +deleted file mode 100644 +index d8382acc7..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-flogb.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x float> @llvm.loongarch.lsx.vflogb.s(<4 x float>) +- +-define <4 x float> @lsx_vflogb_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vflogb_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vflogb.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vflogb.s(<4 x float> %va) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vflogb.d(<2 x double>) +- +-define <2 x double> @lsx_vflogb_d(<2 x double> %va) nounwind { +-; CHECK-LABEL: lsx_vflogb_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vflogb.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vflogb.d(<2 x double> %va) +- ret <2 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fmadd.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fmadd.ll +deleted file mode 100644 +index adbaf6c76..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fmadd.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x float> @llvm.loongarch.lsx.vfmadd.s(<4 x float>, <4 x float>, <4 x float>) +- +-define <4 x float> @lsx_vfmadd_s(<4 x float> %va, <4 x float> %vb, <4 x float> %vc) nounwind { +-; CHECK-LABEL: lsx_vfmadd_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfmadd.s $vr0, $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vfmadd.s(<4 x float> %va, <4 x float> %vb, <4 x float> %vc) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vfmadd.d(<2 x double>, <2 x double>, <2 x double>) +- +-define <2 x double> @lsx_vfmadd_d(<2 x double> %va, <2 x double> %vb, <2 x double> %vc) nounwind { +-; CHECK-LABEL: lsx_vfmadd_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfmadd.d $vr0, $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vfmadd.d(<2 x double> %va, <2 x double> %vb, <2 x double> %vc) +- ret <2 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fmax.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fmax.ll +deleted file mode 100644 +index 89f757c4e..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fmax.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x float> @llvm.loongarch.lsx.vfmax.s(<4 x float>, <4 x float>) +- +-define <4 x float> @lsx_vfmax_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfmax_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfmax.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vfmax.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vfmax.d(<2 x double>, <2 x double>) +- +-define <2 x double> @lsx_vfmax_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfmax_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfmax.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vfmax.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fmaxa.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fmaxa.ll +deleted file mode 100644 +index 5662acc0b..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fmaxa.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x float> @llvm.loongarch.lsx.vfmaxa.s(<4 x float>, <4 x float>) +- +-define <4 x float> @lsx_vfmaxa_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfmaxa_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfmaxa.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vfmaxa.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vfmaxa.d(<2 x double>, <2 x double>) +- +-define <2 x double> @lsx_vfmaxa_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfmaxa_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfmaxa.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vfmaxa.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fmin.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fmin.ll +deleted file mode 100644 +index 0f8442402..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fmin.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x float> @llvm.loongarch.lsx.vfmin.s(<4 x float>, <4 x float>) +- +-define <4 x float> @lsx_vfmin_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfmin_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfmin.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vfmin.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vfmin.d(<2 x double>, <2 x double>) +- +-define <2 x double> @lsx_vfmin_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfmin_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfmin.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vfmin.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fmina.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fmina.ll +deleted file mode 100644 +index 27f70b5fb..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fmina.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x float> @llvm.loongarch.lsx.vfmina.s(<4 x float>, <4 x float>) +- +-define <4 x float> @lsx_vfmina_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfmina_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfmina.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vfmina.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vfmina.d(<2 x double>, <2 x double>) +- +-define <2 x double> @lsx_vfmina_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfmina_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfmina.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vfmina.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fmsub.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fmsub.ll +deleted file mode 100644 +index 856ca9cad..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fmsub.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x float> @llvm.loongarch.lsx.vfmsub.s(<4 x float>, <4 x float>, <4 x float>) +- +-define <4 x float> @lsx_vfmsub_s(<4 x float> %va, <4 x float> %vb, <4 x float> %vc) nounwind { +-; CHECK-LABEL: lsx_vfmsub_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfmsub.s $vr0, $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vfmsub.s(<4 x float> %va, <4 x float> %vb, <4 x float> %vc) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vfmsub.d(<2 x double>, <2 x double>, <2 x double>) +- +-define <2 x double> @lsx_vfmsub_d(<2 x double> %va, <2 x double> %vb, <2 x double> %vc) nounwind { +-; CHECK-LABEL: lsx_vfmsub_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfmsub.d $vr0, $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vfmsub.d(<2 x double> %va, <2 x double> %vb, <2 x double> %vc) +- ret <2 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fmul.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fmul.ll +deleted file mode 100644 +index 1e6c4c77d..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fmul.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x float> @llvm.loongarch.lsx.vfmul.s(<4 x float>, <4 x float>) +- +-define <4 x float> @lsx_vfmul_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfmul_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfmul.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vfmul.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vfmul.d(<2 x double>, <2 x double>) +- +-define <2 x double> @lsx_vfmul_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfmul_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfmul.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vfmul.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fnmadd.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fnmadd.ll +deleted file mode 100644 +index e1a9ea78e..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fnmadd.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x float> @llvm.loongarch.lsx.vfnmadd.s(<4 x float>, <4 x float>, <4 x float>) +- +-define <4 x float> @lsx_vfnmadd_s(<4 x float> %va, <4 x float> %vb, <4 x float> %vc) nounwind { +-; CHECK-LABEL: lsx_vfnmadd_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfnmadd.s $vr0, $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vfnmadd.s(<4 x float> %va, <4 x float> %vb, <4 x float> %vc) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vfnmadd.d(<2 x double>, <2 x double>, <2 x double>) +- +-define <2 x double> @lsx_vfnmadd_d(<2 x double> %va, <2 x double> %vb, <2 x double> %vc) nounwind { +-; CHECK-LABEL: lsx_vfnmadd_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfnmadd.d $vr0, $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vfnmadd.d(<2 x double> %va, <2 x double> %vb, <2 x double> %vc) +- ret <2 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fnmsub.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fnmsub.ll +deleted file mode 100644 +index 46db0f4a5..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fnmsub.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x float> @llvm.loongarch.lsx.vfnmsub.s(<4 x float>, <4 x float>, <4 x float>) +- +-define <4 x float> @lsx_vfnmsub_s(<4 x float> %va, <4 x float> %vb, <4 x float> %vc) nounwind { +-; CHECK-LABEL: lsx_vfnmsub_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfnmsub.s $vr0, $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vfnmsub.s(<4 x float> %va, <4 x float> %vb, <4 x float> %vc) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vfnmsub.d(<2 x double>, <2 x double>, <2 x double>) +- +-define <2 x double> @lsx_vfnmsub_d(<2 x double> %va, <2 x double> %vb, <2 x double> %vc) nounwind { +-; CHECK-LABEL: lsx_vfnmsub_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfnmsub.d $vr0, $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vfnmsub.d(<2 x double> %va, <2 x double> %vb, <2 x double> %vc) +- ret <2 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frecip.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frecip.ll +deleted file mode 100644 +index 669fde591..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frecip.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x float> @llvm.loongarch.lsx.vfrecip.s(<4 x float>) +- +-define <4 x float> @lsx_vfrecip_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vfrecip_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfrecip.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vfrecip.s(<4 x float> %va) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vfrecip.d(<2 x double>) +- +-define <2 x double> @lsx_vfrecip_d(<2 x double> %va) nounwind { +-; CHECK-LABEL: lsx_vfrecip_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfrecip.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vfrecip.d(<2 x double> %va) +- ret <2 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frecipe.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frecipe.ll +index 1b7a97d9f..328550f60 100644 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frecipe.ll ++++ b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frecipe.ll +@@ -7,7 +7,7 @@ define <4 x float> @lsx_vfrecipe_s(<4 x float> %va) nounwind { + ; CHECK-LABEL: lsx_vfrecipe_s: + ; CHECK: # %bb.0: # %entry + ; CHECK-NEXT: vfrecipe.s $vr0, $vr0 +-; CHECK-NEXT: ret ++; CHECK-NEXT: jr $ra + entry: + %res = call <4 x float> @llvm.loongarch.lsx.vfrecipe.s(<4 x float> %va) + ret <4 x float> %res +@@ -19,7 +19,7 @@ define <2 x double> @lsx_vfrecipe_d(<2 x double> %va) nounwind { + ; CHECK-LABEL: lsx_vfrecipe_d: + ; CHECK: # %bb.0: # %entry + ; CHECK-NEXT: vfrecipe.d $vr0, $vr0 +-; CHECK-NEXT: ret ++; CHECK-NEXT: jr $ra + entry: + %res = call <2 x double> @llvm.loongarch.lsx.vfrecipe.d(<2 x double> %va) + ret <2 x double> %res +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frint.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frint.ll +deleted file mode 100644 +index 8d872fc72..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frint.ll ++++ /dev/null +@@ -1,122 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x float> @llvm.loongarch.lsx.vfrintrne.s(<4 x float>) +- +-define <4 x float> @lsx_vfrintrne_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vfrintrne_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfrintrne.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vfrintrne.s(<4 x float> %va) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vfrintrne.d(<2 x double>) +- +-define <2 x double> @lsx_vfrintrne_d(<2 x double> %va) nounwind { +-; CHECK-LABEL: lsx_vfrintrne_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfrintrne.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vfrintrne.d(<2 x double> %va) +- ret <2 x double> %res +-} +- +-declare <4 x float> @llvm.loongarch.lsx.vfrintrz.s(<4 x float>) +- +-define <4 x float> @lsx_vfrintrz_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vfrintrz_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfrintrz.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vfrintrz.s(<4 x float> %va) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vfrintrz.d(<2 x double>) +- +-define <2 x double> @lsx_vfrintrz_d(<2 x double> %va) nounwind { +-; CHECK-LABEL: lsx_vfrintrz_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfrintrz.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vfrintrz.d(<2 x double> %va) +- ret <2 x double> %res +-} +- +-declare <4 x float> @llvm.loongarch.lsx.vfrintrp.s(<4 x float>) +- +-define <4 x float> @lsx_vfrintrp_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vfrintrp_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfrintrp.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vfrintrp.s(<4 x float> %va) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vfrintrp.d(<2 x double>) +- +-define <2 x double> @lsx_vfrintrp_d(<2 x double> %va) nounwind { +-; CHECK-LABEL: lsx_vfrintrp_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfrintrp.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vfrintrp.d(<2 x double> %va) +- ret <2 x double> %res +-} +- +-declare <4 x float> @llvm.loongarch.lsx.vfrintrm.s(<4 x float>) +- +-define <4 x float> @lsx_vfrintrm_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vfrintrm_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfrintrm.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vfrintrm.s(<4 x float> %va) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vfrintrm.d(<2 x double>) +- +-define <2 x double> @lsx_vfrintrm_d(<2 x double> %va) nounwind { +-; CHECK-LABEL: lsx_vfrintrm_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfrintrm.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vfrintrm.d(<2 x double> %va) +- ret <2 x double> %res +-} +- +-declare <4 x float> @llvm.loongarch.lsx.vfrint.s(<4 x float>) +- +-define <4 x float> @lsx_vfrint_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vfrint_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfrint.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vfrint.s(<4 x float> %va) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vfrint.d(<2 x double>) +- +-define <2 x double> @lsx_vfrint_d(<2 x double> %va) nounwind { +-; CHECK-LABEL: lsx_vfrint_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfrint.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vfrint.d(<2 x double> %va) +- ret <2 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frsqrt.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frsqrt.ll +deleted file mode 100644 +index 326d87308..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frsqrt.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x float> @llvm.loongarch.lsx.vfrsqrt.s(<4 x float>) +- +-define <4 x float> @lsx_vfrsqrt_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vfrsqrt_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfrsqrt.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vfrsqrt.s(<4 x float> %va) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vfrsqrt.d(<2 x double>) +- +-define <2 x double> @lsx_vfrsqrt_d(<2 x double> %va) nounwind { +-; CHECK-LABEL: lsx_vfrsqrt_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfrsqrt.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vfrsqrt.d(<2 x double> %va) +- ret <2 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frsqrte.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frsqrte.ll +index 3cd6c78e8..73617e3e2 100644 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frsqrte.ll ++++ b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frsqrte.ll +@@ -7,7 +7,7 @@ define <4 x float> @lsx_vfrsqrte_s(<4 x float> %va) nounwind { + ; CHECK-LABEL: lsx_vfrsqrte_s: + ; CHECK: # %bb.0: # %entry + ; CHECK-NEXT: vfrsqrte.s $vr0, $vr0 +-; CHECK-NEXT: ret ++; CHECK-NEXT: jr $ra + entry: + %res = call <4 x float> @llvm.loongarch.lsx.vfrsqrte.s(<4 x float> %va) + ret <4 x float> %res +@@ -19,7 +19,7 @@ define <2 x double> @lsx_vfrsqrte_d(<2 x double> %va) nounwind { + ; CHECK-LABEL: lsx_vfrsqrte_d: + ; CHECK: # %bb.0: # %entry + ; CHECK-NEXT: vfrsqrte.d $vr0, $vr0 +-; CHECK-NEXT: ret ++; CHECK-NEXT: jr $ra + entry: + %res = call <2 x double> @llvm.loongarch.lsx.vfrsqrte.d(<2 x double> %va) + ret <2 x double> %res +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frstp-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frstp-invalid-imm.ll +deleted file mode 100644 +index 0184c855c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frstp-invalid-imm.ll ++++ /dev/null +@@ -1,33 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vfrstpi.b(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vfrstpi_b_lo(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vfrstpi.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vfrstpi.b(<16 x i8> %va, <16 x i8> %vb, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vfrstpi_b_hi(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vfrstpi.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vfrstpi.b(<16 x i8> %va, <16 x i8> %vb, i32 32) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vfrstpi.h(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vfrstpi_h_lo(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vfrstpi.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vfrstpi.h(<8 x i16> %va, <8 x i16> %vb, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vfrstpi_h_hi(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vfrstpi.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vfrstpi.h(<8 x i16> %va, <8 x i16> %vb, i32 32) +- ret <8 x i16> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frstp-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frstp-non-imm.ll +deleted file mode 100644 +index 9583f672a..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frstp-non-imm.ll ++++ /dev/null +@@ -1,19 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vfrstpi.b(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vfrstpi_b(<16 x i8> %va, <16 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vfrstpi.b(<16 x i8> %va, <16 x i8> %vb, i32 %c) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vfrstpi.h(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vfrstpi_h(<8 x i16> %va, <8 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vfrstpi.h(<8 x i16> %va, <8 x i16> %vb, i32 %c) +- ret <8 x i16> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frstp.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frstp.ll +deleted file mode 100644 +index 5c072b194..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-frstp.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vfrstp.b(<16 x i8>, <16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vfrstp_b(<16 x i8> %va, <16 x i8> %vb, <16 x i8> %vc) nounwind { +-; CHECK-LABEL: lsx_vfrstp_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfrstp.b $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vfrstp.b(<16 x i8> %va, <16 x i8> %vb, <16 x i8> %vc) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vfrstp.h(<8 x i16>, <8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vfrstp_h(<8 x i16> %va, <8 x i16> %vb, <8 x i16> %vc) nounwind { +-; CHECK-LABEL: lsx_vfrstp_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfrstp.h $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vfrstp.h(<8 x i16> %va, <8 x i16> %vb, <8 x i16> %vc) +- ret <8 x i16> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vfrstpi.b(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vfrstpi_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vfrstpi_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfrstpi.b $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vfrstpi.b(<16 x i8> %va, <16 x i8> %vb, i32 1) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vfrstpi.h(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vfrstpi_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vfrstpi_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfrstpi.h $vr0, $vr1, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vfrstpi.h(<8 x i16> %va, <8 x i16> %vb, i32 31) +- ret <8 x i16> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fsqrt.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fsqrt.ll +deleted file mode 100644 +index 55bffba9e..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fsqrt.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x float> @llvm.loongarch.lsx.vfsqrt.s(<4 x float>) +- +-define <4 x float> @lsx_vfsqrt_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vfsqrt_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfsqrt.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vfsqrt.s(<4 x float> %va) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vfsqrt.d(<2 x double>) +- +-define <2 x double> @lsx_vfsqrt_d(<2 x double> %va) nounwind { +-; CHECK-LABEL: lsx_vfsqrt_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfsqrt.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vfsqrt.d(<2 x double> %va) +- ret <2 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fsub.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fsub.ll +deleted file mode 100644 +index 2beba4a70..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fsub.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x float> @llvm.loongarch.lsx.vfsub.s(<4 x float>, <4 x float>) +- +-define <4 x float> @lsx_vfsub_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfsub_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfsub.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x float> @llvm.loongarch.lsx.vfsub.s(<4 x float> %va, <4 x float> %vb) +- ret <4 x float> %res +-} +- +-declare <2 x double> @llvm.loongarch.lsx.vfsub.d(<2 x double>, <2 x double>) +- +-define <2 x double> @lsx_vfsub_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vfsub_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfsub.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x double> @llvm.loongarch.lsx.vfsub.d(<2 x double> %va, <2 x double> %vb) +- ret <2 x double> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ftint.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ftint.ll +deleted file mode 100644 +index 2a494cd7f..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ftint.ll ++++ /dev/null +@@ -1,350 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x i32> @llvm.loongarch.lsx.vftintrne.w.s(<4 x float>) +- +-define <4 x i32> @lsx_vftintrne_w_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vftintrne_w_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintrne.w.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vftintrne.w.s(<4 x float> %va) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vftintrne.l.d(<2 x double>) +- +-define <2 x i64> @lsx_vftintrne_l_d(<2 x double> %va) nounwind { +-; CHECK-LABEL: lsx_vftintrne_l_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintrne.l.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vftintrne.l.d(<2 x double> %va) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vftintrz.w.s(<4 x float>) +- +-define <4 x i32> @lsx_vftintrz_w_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vftintrz_w_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintrz.w.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vftintrz.w.s(<4 x float> %va) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vftintrz.l.d(<2 x double>) +- +-define <2 x i64> @lsx_vftintrz_l_d(<2 x double> %va) nounwind { +-; CHECK-LABEL: lsx_vftintrz_l_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintrz.l.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vftintrz.l.d(<2 x double> %va) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vftintrp.w.s(<4 x float>) +- +-define <4 x i32> @lsx_vftintrp_w_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vftintrp_w_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintrp.w.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vftintrp.w.s(<4 x float> %va) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vftintrp.l.d(<2 x double>) +- +-define <2 x i64> @lsx_vftintrp_l_d(<2 x double> %va) nounwind { +-; CHECK-LABEL: lsx_vftintrp_l_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintrp.l.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vftintrp.l.d(<2 x double> %va) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vftintrm.w.s(<4 x float>) +- +-define <4 x i32> @lsx_vftintrm_w_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vftintrm_w_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintrm.w.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vftintrm.w.s(<4 x float> %va) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vftintrm.l.d(<2 x double>) +- +-define <2 x i64> @lsx_vftintrm_l_d(<2 x double> %va) nounwind { +-; CHECK-LABEL: lsx_vftintrm_l_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintrm.l.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vftintrm.l.d(<2 x double> %va) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vftint.w.s(<4 x float>) +- +-define <4 x i32> @lsx_vftint_w_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vftint_w_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftint.w.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vftint.w.s(<4 x float> %va) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vftint.l.d(<2 x double>) +- +-define <2 x i64> @lsx_vftint_l_d(<2 x double> %va) nounwind { +-; CHECK-LABEL: lsx_vftint_l_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftint.l.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vftint.l.d(<2 x double> %va) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vftintrz.wu.s(<4 x float>) +- +-define <4 x i32> @lsx_vftintrz_wu_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vftintrz_wu_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintrz.wu.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vftintrz.wu.s(<4 x float> %va) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vftintrz.lu.d(<2 x double>) +- +-define <2 x i64> @lsx_vftintrz_lu_d(<2 x double> %va) nounwind { +-; CHECK-LABEL: lsx_vftintrz_lu_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintrz.lu.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vftintrz.lu.d(<2 x double> %va) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vftint.wu.s(<4 x float>) +- +-define <4 x i32> @lsx_vftint_wu_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vftint_wu_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftint.wu.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vftint.wu.s(<4 x float> %va) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vftint.lu.d(<2 x double>) +- +-define <2 x i64> @lsx_vftint_lu_d(<2 x double> %va) nounwind { +-; CHECK-LABEL: lsx_vftint_lu_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftint.lu.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vftint.lu.d(<2 x double> %va) +- ret <2 x i64> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vftintrne.w.d(<2 x double>, <2 x double>) +- +-define <4 x i32> @lsx_vftintrne_w_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vftintrne_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintrne.w.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vftintrne.w.d(<2 x double> %va, <2 x double> %vb) +- ret <4 x i32> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vftintrz.w.d(<2 x double>, <2 x double>) +- +-define <4 x i32> @lsx_vftintrz_w_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vftintrz_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintrz.w.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vftintrz.w.d(<2 x double> %va, <2 x double> %vb) +- ret <4 x i32> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vftintrp.w.d(<2 x double>, <2 x double>) +- +-define <4 x i32> @lsx_vftintrp_w_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vftintrp_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintrp.w.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vftintrp.w.d(<2 x double> %va, <2 x double> %vb) +- ret <4 x i32> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vftintrm.w.d(<2 x double>, <2 x double>) +- +-define <4 x i32> @lsx_vftintrm_w_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vftintrm_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintrm.w.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vftintrm.w.d(<2 x double> %va, <2 x double> %vb) +- ret <4 x i32> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vftint.w.d(<2 x double>, <2 x double>) +- +-define <4 x i32> @lsx_vftint_w_d(<2 x double> %va, <2 x double> %vb) nounwind { +-; CHECK-LABEL: lsx_vftint_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftint.w.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vftint.w.d(<2 x double> %va, <2 x double> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vftintrnel.l.s(<4 x float>) +- +-define <2 x i64> @lsx_vftintrnel_l_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vftintrnel_l_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintrnel.l.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vftintrnel.l.s(<4 x float> %va) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vftintrneh.l.s(<4 x float>) +- +-define <2 x i64> @lsx_vftintrneh_l_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vftintrneh_l_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintrneh.l.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vftintrneh.l.s(<4 x float> %va) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vftintrzl.l.s(<4 x float>) +- +-define <2 x i64> @lsx_vftintrzl_l_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vftintrzl_l_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintrzl.l.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vftintrzl.l.s(<4 x float> %va) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vftintrzh.l.s(<4 x float>) +- +-define <2 x i64> @lsx_vftintrzh_l_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vftintrzh_l_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintrzh.l.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vftintrzh.l.s(<4 x float> %va) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vftintrpl.l.s(<4 x float>) +- +-define <2 x i64> @lsx_vftintrpl_l_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vftintrpl_l_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintrpl.l.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vftintrpl.l.s(<4 x float> %va) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vftintrph.l.s(<4 x float>) +- +-define <2 x i64> @lsx_vftintrph_l_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vftintrph_l_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintrph.l.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vftintrph.l.s(<4 x float> %va) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vftintrml.l.s(<4 x float>) +- +-define <2 x i64> @lsx_vftintrml_l_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vftintrml_l_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintrml.l.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vftintrml.l.s(<4 x float> %va) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vftintrmh.l.s(<4 x float>) +- +-define <2 x i64> @lsx_vftintrmh_l_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vftintrmh_l_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintrmh.l.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vftintrmh.l.s(<4 x float> %va) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vftintl.l.s(<4 x float>) +- +-define <2 x i64> @lsx_vftintl_l_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vftintl_l_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftintl.l.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vftintl.l.s(<4 x float> %va) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vftinth.l.s(<4 x float>) +- +-define <2 x i64> @lsx_vftinth_l_s(<4 x float> %va) nounwind { +-; CHECK-LABEL: lsx_vftinth_l_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vftinth.l.s $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vftinth.l.s(<4 x float> %va) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-haddw.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-haddw.ll +deleted file mode 100644 +index 057255823..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-haddw.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <8 x i16> @llvm.loongarch.lsx.vhaddw.h.b(<16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vhaddw_h_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vhaddw_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vhaddw.h.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vhaddw.h.b(<16 x i8> %va, <16 x i8> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vhaddw.w.h(<8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vhaddw_w_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vhaddw_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vhaddw.w.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vhaddw.w.h(<8 x i16> %va, <8 x i16> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vhaddw.d.w(<4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vhaddw_d_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vhaddw_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vhaddw.d.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vhaddw.d.w(<4 x i32> %va, <4 x i32> %vb) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vhaddw.q.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vhaddw_q_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vhaddw_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vhaddw.q.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vhaddw.q.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vhaddw.hu.bu(<16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vhaddw_hu_bu(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vhaddw_hu_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vhaddw.hu.bu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vhaddw.hu.bu(<16 x i8> %va, <16 x i8> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vhaddw.wu.hu(<8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vhaddw_wu_hu(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vhaddw_wu_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vhaddw.wu.hu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vhaddw.wu.hu(<8 x i16> %va, <8 x i16> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vhaddw.du.wu(<4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vhaddw_du_wu(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vhaddw_du_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vhaddw.du.wu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vhaddw.du.wu(<4 x i32> %va, <4 x i32> %vb) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vhaddw.qu.du(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vhaddw_qu_du(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vhaddw_qu_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vhaddw.qu.du $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vhaddw.qu.du(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-hsubw.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-hsubw.ll +deleted file mode 100644 +index dd5815b2e..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-hsubw.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <8 x i16> @llvm.loongarch.lsx.vhsubw.h.b(<16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vhsubw_h_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vhsubw_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vhsubw.h.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vhsubw.h.b(<16 x i8> %va, <16 x i8> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vhsubw.w.h(<8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vhsubw_w_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vhsubw_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vhsubw.w.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vhsubw.w.h(<8 x i16> %va, <8 x i16> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vhsubw.d.w(<4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vhsubw_d_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vhsubw_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vhsubw.d.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vhsubw.d.w(<4 x i32> %va, <4 x i32> %vb) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vhsubw.q.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vhsubw_q_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vhsubw_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vhsubw.q.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vhsubw.q.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vhsubw.hu.bu(<16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vhsubw_hu_bu(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vhsubw_hu_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vhsubw.hu.bu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vhsubw.hu.bu(<16 x i8> %va, <16 x i8> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vhsubw.wu.hu(<8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vhsubw_wu_hu(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vhsubw_wu_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vhsubw.wu.hu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vhsubw.wu.hu(<8 x i16> %va, <8 x i16> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vhsubw.du.wu(<4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vhsubw_du_wu(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vhsubw_du_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vhsubw.du.wu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vhsubw.du.wu(<4 x i32> %va, <4 x i32> %vb) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vhsubw.qu.du(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vhsubw_qu_du(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vhsubw_qu_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vhsubw.qu.du $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vhsubw.qu.du(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ilv.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ilv.ll +deleted file mode 100644 +index 77b0b3484..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ilv.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vilvl.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vilvl_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vilvl_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vilvl.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vilvl.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vilvl.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vilvl_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vilvl_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vilvl.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vilvl.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vilvl.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vilvl_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vilvl_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vilvl.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vilvl.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vilvl.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vilvl_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vilvl_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vilvl.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vilvl.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vilvh.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vilvh_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vilvh_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vilvh.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vilvh.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vilvh.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vilvh_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vilvh_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vilvh.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vilvh.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vilvh.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vilvh_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vilvh_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vilvh.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vilvh.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vilvh.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vilvh_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vilvh_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vilvh.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vilvh.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-insgr2vr-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-insgr2vr-invalid-imm.ll +deleted file mode 100644 +index 3d4f84fb6..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-insgr2vr-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vinsgr2vr.b(<16 x i8>, i32, i32) +- +-define <16 x i8> @lsx_vinsgr2vr_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vinsgr2vr.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vinsgr2vr.b(<16 x i8> %va, i32 1, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vinsgr2vr_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vinsgr2vr.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vinsgr2vr.b(<16 x i8> %va, i32 1, i32 16) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vinsgr2vr.h(<8 x i16>, i32, i32) +- +-define <8 x i16> @lsx_vinsgr2vr_h_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vinsgr2vr.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vinsgr2vr.h(<8 x i16> %va, i32 1, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vinsgr2vr_h_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vinsgr2vr.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vinsgr2vr.h(<8 x i16> %va, i32 1, i32 8) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vinsgr2vr.w(<4 x i32>, i32, i32) +- +-define <4 x i32> @lsx_vinsgr2vr_w_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vinsgr2vr.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vinsgr2vr.w(<4 x i32> %va, i32 1, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vinsgr2vr_w_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vinsgr2vr.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vinsgr2vr.w(<4 x i32> %va, i32 1, i32 4) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vinsgr2vr.d(<2 x i64>, i64, i32) +- +-define <2 x i64> @lsx_vinsgr2vr_d_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vinsgr2vr.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vinsgr2vr.d(<2 x i64> %va, i64 1, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vinsgr2vr_d_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vinsgr2vr.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vinsgr2vr.d(<2 x i64> %va, i64 1, i32 2) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-insgr2vr-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-insgr2vr-non-imm.ll +deleted file mode 100644 +index 2a4c2218d..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-insgr2vr-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vinsgr2vr.b(<16 x i8>, i32, i32) +- +-define <16 x i8> @lsx_vinsgr2vr_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vinsgr2vr.b(<16 x i8> %va, i32 1, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vinsgr2vr.h(<8 x i16>, i32, i32) +- +-define <8 x i16> @lsx_vinsgr2vr_h(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vinsgr2vr.h(<8 x i16> %va, i32 1, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vinsgr2vr.w(<4 x i32>, i32, i32) +- +-define <4 x i32> @lsx_vinsgr2vr_w(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vinsgr2vr.w(<4 x i32> %va, i32 1, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vinsgr2vr.d(<2 x i64>, i64, i32) +- +-define <2 x i64> @lsx_vinsgr2vr_d(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vinsgr2vr.d(<2 x i64> %va, i64 1, i32 %b) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-insgr2vr.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-insgr2vr.ll +deleted file mode 100644 +index 61d2cbd28..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-insgr2vr.ll ++++ /dev/null +@@ -1,54 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vinsgr2vr.b(<16 x i8>, i32, i32) +- +-define <16 x i8> @lsx_vinsgr2vr_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vinsgr2vr_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vinsgr2vr.b(<16 x i8> %va, i32 1, i32 15) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vinsgr2vr.h(<8 x i16>, i32, i32) +- +-define <8 x i16> @lsx_vinsgr2vr_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vinsgr2vr_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 7 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vinsgr2vr.h(<8 x i16> %va, i32 1, i32 7) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vinsgr2vr.w(<4 x i32>, i32, i32) +- +-define <4 x i32> @lsx_vinsgr2vr_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vinsgr2vr_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: vinsgr2vr.w $vr0, $a0, 3 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vinsgr2vr.w(<4 x i32> %va, i32 1, i32 3) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vinsgr2vr.d(<2 x i64>, i64, i32) +- +-define <2 x i64> @lsx_vinsgr2vr_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vinsgr2vr_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: vinsgr2vr.d $vr0, $a0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vinsgr2vr.d(<2 x i64> %va, i64 1, i32 1) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ld-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ld-invalid-imm.ll +deleted file mode 100644 +index 3aeb30ce6..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ld-invalid-imm.ll ++++ /dev/null +@@ -1,17 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vld(i8*, i32) +- +-define <16 x i8> @lsx_vld_lo(i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vld: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vld(i8* %p, i32 -2049) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vld_hi(i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vld: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vld(i8* %p, i32 2048) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ld-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ld-non-imm.ll +deleted file mode 100644 +index db6a0318d..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ld-non-imm.ll ++++ /dev/null +@@ -1,10 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vld(i8*, i32) +- +-define <16 x i8> @lsx_vld(i8* %p, i32 %a) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vld(i8* %p, i32 %a) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ld.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ld.ll +deleted file mode 100644 +index b9e2ff808..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ld.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vld(i8*, i32) +- +-define <16 x i8> @lsx_vld(i8* %p) nounwind { +-; CHECK-LABEL: lsx_vld: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vld(i8* %p, i32 1) +- ret <16 x i8> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vldx(i8*, i64) +- +-define <16 x i8> @lsx_vldx(i8* %p, i64 %b) nounwind { +-; CHECK-LABEL: lsx_vldx: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vldx $vr0, $a0, $a1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vldx(i8* %p, i64 %b) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ldi-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ldi-invalid-imm.ll +deleted file mode 100644 +index 57f6f8e81..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ldi-invalid-imm.ll ++++ /dev/null +@@ -1,81 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <2 x i64> @llvm.loongarch.lsx.vldi(i32) +- +-define <2 x i64> @lsx_vldi_lo() nounwind { +-; CHECK: llvm.loongarch.lsx.vldi: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vldi(i32 -4097) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vldi_hi() nounwind { +-; CHECK: llvm.loongarch.lsx.vldi: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vldi(i32 4096) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vrepli.b(i32) +- +-define <16 x i8> @lsx_vrepli_b_lo() nounwind { +-; CHECK: llvm.loongarch.lsx.vrepli.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vrepli.b(i32 -513) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vrepli_b_hi() nounwind { +-; CHECK: llvm.loongarch.lsx.vrepli.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vrepli.b(i32 512) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vrepli.h(i32) +- +-define <8 x i16> @lsx_vrepli_h_lo() nounwind { +-; CHECK: llvm.loongarch.lsx.vrepli.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vrepli.h(i32 -513) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vrepli_h_hi() nounwind { +-; CHECK: llvm.loongarch.lsx.vrepli.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vrepli.h(i32 512) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vrepli.w(i32) +- +-define <4 x i32> @lsx_vrepli_w_lo() nounwind { +-; CHECK: llvm.loongarch.lsx.vrepli.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vrepli.w(i32 -513) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vrepli_w_hi() nounwind { +-; CHECK: llvm.loongarch.lsx.vrepli.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vrepli.w(i32 512) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vrepli.d(i32) +- +-define <2 x i64> @lsx_vrepli_d_lo() nounwind { +-; CHECK: llvm.loongarch.lsx.vrepli.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vrepli.d(i32 -513) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vrepli_d_hi() nounwind { +-; CHECK: llvm.loongarch.lsx.vrepli.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vrepli.d(i32 512) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ldi-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ldi-non-imm.ll +deleted file mode 100644 +index a8f8278f8..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ldi-non-imm.ll ++++ /dev/null +@@ -1,46 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <2 x i64> @llvm.loongarch.lsx.vldi(i32) +- +-define <2 x i64> @lsx_vldi(i32 %a) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vldi(i32 %a) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vrepli.b(i32) +- +-define <16 x i8> @lsx_vrepli_b(i32 %a) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vrepli.b(i32 %a) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vrepli.h(i32) +- +-define <8 x i16> @lsx_vrepli_h(i32 %a) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vrepli.h(i32 %a) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vrepli.w(i32) +- +-define <4 x i32> @lsx_vrepli_w(i32 %a) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vrepli.w(i32 %a) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vrepli.d(i32) +- +-define <2 x i64> @lsx_vrepli_d(i32 %a) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vrepli.d(i32 %a) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ldi.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ldi.ll +deleted file mode 100644 +index ace910b54..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ldi.ll ++++ /dev/null +@@ -1,62 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <2 x i64> @llvm.loongarch.lsx.vldi(i32) +- +-define <2 x i64> @lsx_vldi() nounwind { +-; CHECK-LABEL: lsx_vldi: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vldi $vr0, 4095 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vldi(i32 4095) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vrepli.b(i32) +- +-define <16 x i8> @lsx_vrepli_b() nounwind { +-; CHECK-LABEL: lsx_vrepli_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vrepli.b $vr0, 511 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vrepli.b(i32 511) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vrepli.h(i32) +- +-define <8 x i16> @lsx_vrepli_h() nounwind { +-; CHECK-LABEL: lsx_vrepli_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vrepli.h $vr0, 511 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vrepli.h(i32 511) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vrepli.w(i32) +- +-define <4 x i32> @lsx_vrepli_w() nounwind { +-; CHECK-LABEL: lsx_vrepli_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vrepli.w $vr0, 511 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vrepli.w(i32 511) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vrepli.d(i32) +- +-define <2 x i64> @lsx_vrepli_d() nounwind { +-; CHECK-LABEL: lsx_vrepli_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vrepli.d $vr0, 511 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vrepli.d(i32 511) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ldrepl-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ldrepl-invalid-imm.ll +deleted file mode 100644 +index cb640e124..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ldrepl-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vldrepl.b(i8*, i32) +- +-define <16 x i8> @lsx_vldrepl_b_lo(i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vldrepl.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vldrepl.b(i8* %p, i32 -2049) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vldrepl_b_hi(i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vldrepl.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vldrepl.b(i8* %p, i32 2048) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vldrepl.h(i8*, i32) +- +-define <8 x i16> @lsx_vldrepl_h_lo(i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vldrepl.h: argument out of range or not a multiple of 2. +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vldrepl.h(i8* %p, i32 -2050) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vldrepl_h_hi(i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vldrepl.h: argument out of range or not a multiple of 2. +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vldrepl.h(i8* %p, i32 2048) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vldrepl.w(i8*, i32) +- +-define <4 x i32> @lsx_vldrepl_w_lo(i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vldrepl.w: argument out of range or not a multiple of 4. +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vldrepl.w(i8* %p, i32 -2052) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vldrepl_w_hi(i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vldrepl.w: argument out of range or not a multiple of 4. +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vldrepl.w(i8* %p, i32 2048) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vldrepl.d(i8*, i32) +- +-define <2 x i64> @lsx_vldrepl_d_lo(i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vldrepl.d: argument out of range or not a multiple of 8. +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vldrepl.d(i8* %p, i32 -2056) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vldrepl_d_hi(i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vldrepl.d: argument out of range or not a multiple of 8. +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vldrepl.d(i8* %p, i32 2048) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ldrepl-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ldrepl-non-imm.ll +deleted file mode 100644 +index e60b21913..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ldrepl-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vldrepl.b(i8*, i32) +- +-define <16 x i8> @lsx_vldrepl_b(i8* %p, i32 %a) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vldrepl.b(i8* %p, i32 %a) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vldrepl.h(i8*, i32) +- +-define <8 x i16> @lsx_vldrepl_h(i8* %p, i32 %a) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vldrepl.h(i8* %p, i32 %a) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vldrepl.w(i8*, i32) +- +-define <4 x i32> @lsx_vldrepl_w(i8* %p, i32 %a) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vldrepl.w(i8* %p, i32 %a) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vldrepl.d(i8*, i32) +- +-define <2 x i64> @lsx_vldrepl_d(i8* %p, i32 %a) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vldrepl.d(i8* %p, i32 %a) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ldrepl-postra.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ldrepl-postra.ll +new file mode 100644 +index 000000000..1de2c3129 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ldrepl-postra.ll +@@ -0,0 +1,27 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 ++; RUN: llc --mtriple=loongarch64 --mattr=+lsx -O3 < %s | FileCheck %s ++ ++declare <4 x i32> @llvm.loongarch.lsx.vldrepl.w(i8*, i32) ++declare <4 x i32> @llvm.loongarch.lsx.vsub.w(<4 x i32>, <4 x i32>) ++ ++define <4 x i32> @test(<4 x i32>* %p) { ++; CHECK-LABEL: test: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: addi.d $sp, $sp, -16 ++; CHECK-NEXT: .cfi_def_cfa_offset 16 ++; CHECK-NEXT: ori $r5, $zero, 256 ++; CHECK-NEXT: st.w $r5, $sp, 12 ++; CHECK-NEXT: vld $vr0, $r4, 0 ++; CHECK-NEXT: vldrepl.w $vr1, $sp, 12 ++; CHECK-NEXT: vsub.w $vr0, $vr1, $vr0 ++; CHECK-NEXT: addi.d $sp, $sp, 16 ++; CHECK-NEXT: jr $ra ++entry: ++ %tmp = alloca i32, align 4 ++ store i32 256, i32 *%tmp, align 4 ++ %t = bitcast i32* %tmp to i8* ++ %0 = call <4 x i32> @llvm.loongarch.lsx.vldrepl.w(i8* %t, i32 0) ++ %1 = load <4 x i32>, <4 x i32>* %p, align 32 ++ %2 = call <4 x i32> @llvm.loongarch.lsx.vsub.w(<4 x i32> %0, <4 x i32> %1) ++ ret <4 x i32> %2 ++} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ldrepl.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ldrepl.ll +index 1a9cf3d3a..a54a886f7 100644 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ldrepl.ll ++++ b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ldrepl.ll +@@ -6,8 +6,8 @@ declare <16 x i8> @llvm.loongarch.lsx.vldrepl.b(i8*, i32) + define <16 x i8> @lsx_vldrepl_b(i8* %p, i32 %b) nounwind { + ; CHECK-LABEL: lsx_vldrepl_b: + ; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vldrepl.b $vr0, $a0, 1 +-; CHECK-NEXT: ret ++; CHECK-NEXT: vldrepl.b $vr0, $r4, 1 ++; CHECK-NEXT: jr $ra + entry: + %res = call <16 x i8> @llvm.loongarch.lsx.vldrepl.b(i8* %p, i32 1) + ret <16 x i8> %res +@@ -18,8 +18,8 @@ declare <8 x i16> @llvm.loongarch.lsx.vldrepl.h(i8*, i32) + define <8 x i16> @lsx_vldrepl_h(i8* %p, i32 %b) nounwind { + ; CHECK-LABEL: lsx_vldrepl_h: + ; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vldrepl.h $vr0, $a0, 2 +-; CHECK-NEXT: ret ++; CHECK-NEXT: vldrepl.h $vr0, $r4, 2 ++; CHECK-NEXT: jr $ra + entry: + %res = call <8 x i16> @llvm.loongarch.lsx.vldrepl.h(i8* %p, i32 2) + ret <8 x i16> %res +@@ -30,8 +30,8 @@ declare <4 x i32> @llvm.loongarch.lsx.vldrepl.w(i8*, i32) + define <4 x i32> @lsx_vldrepl_w(i8* %p, i32 %b) nounwind { + ; CHECK-LABEL: lsx_vldrepl_w: + ; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vldrepl.w $vr0, $a0, 4 +-; CHECK-NEXT: ret ++; CHECK-NEXT: vldrepl.w $vr0, $r4, 4 ++; CHECK-NEXT: jr $ra + entry: + %res = call <4 x i32> @llvm.loongarch.lsx.vldrepl.w(i8* %p, i32 4) + ret <4 x i32> %res +@@ -42,8 +42,8 @@ declare <2 x i64> @llvm.loongarch.lsx.vldrepl.d(i8*, i32) + define <2 x i64> @lsx_vldrepl_d(i8* %p, i32 %b) nounwind { + ; CHECK-LABEL: lsx_vldrepl_d: + ; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vldrepl.d $vr0, $a0, 8 +-; CHECK-NEXT: ret ++; CHECK-NEXT: vldrepl.d $vr0, $r4, 8 ++; CHECK-NEXT: jr $ra + entry: + %res = call <2 x i64> @llvm.loongarch.lsx.vldrepl.d(i8* %p, i32 8) + ret <2 x i64> %res +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-lsx.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-lsx.ll +new file mode 100644 +index 000000000..60ff93095 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-lsx.ll +@@ -0,0 +1,92 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lsx < %s | FileCheck %s ++ ++declare <16 x i8> @llvm.loongarch.lsx.vsrlrni.b.h(<16 x i8>, <16 x i8>, i32) ++declare <8 x i16> @llvm.loongarch.lsx.vsrlrni.h.w(<8 x i16>, <8 x i16>, i32) ++declare <4 x i32> @llvm.loongarch.lsx.vsrlrni.w.d(<4 x i32>, <4 x i32>, i32) ++declare <2 x i64> @llvm.loongarch.lsx.vsrlrni.d.q(<2 x i64>, <2 x i64>, i32) ++ ++declare <16 x i8> @llvm.loongarch.lsx.vrepli.b(i32) ++declare <8 x i16> @llvm.loongarch.lsx.vrepli.h(i32) ++declare <4 x i32> @llvm.loongarch.lsx.vrepli.w(i32) ++declare <2 x i64> @llvm.loongarch.lsx.vrepli.d(i32) ++ ++define <16 x i8> @lsx_vsrlrni_b_h(<16 x i8> %a, <16 x i8> %b) { ++; CHECK-LABEL: lsx_vsrlrni_b_h: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vsrlrni.b.h $vr0, $vr1, 2 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = tail call <16 x i8> @llvm.loongarch.lsx.vsrlrni.b.h(<16 x i8> %a, <16 x i8> %b, i32 2) ++ ret <16 x i8> %0 ++} ++ ++define <8 x i16> @lsx_vsrlrni_h_w(<8 x i16> %a, <8 x i16> %b) { ++; CHECK-LABEL: lsx_vsrlrni_h_w: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vsrlrni.h.w $vr0, $vr1, 2 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = tail call <8 x i16> @llvm.loongarch.lsx.vsrlrni.h.w(<8 x i16> %a, <8 x i16> %b, i32 2) ++ ret <8 x i16> %0 ++} ++ ++define <4 x i32> @lsx_vsrlrni_w_d(<4 x i32> %a, <4 x i32> %b) { ++; CHECK-LABEL: lsx_vsrlrni_w_d: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vsrlrni.w.d $vr0, $vr1, 2 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = tail call <4 x i32> @llvm.loongarch.lsx.vsrlrni.w.d(<4 x i32> %a, <4 x i32> %b, i32 2) ++ ret <4 x i32> %0 ++} ++ ++define <2 x i64> @lsx_vsrlrni_d_q(<2 x i64> %a, <2 x i64> %b) { ++; CHECK-LABEL: lsx_vsrlrni_d_q: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vsrlrni.d.q $vr0, $vr1, 2 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = tail call <2 x i64> @llvm.loongarch.lsx.vsrlrni.d.q(<2 x i64> %a, <2 x i64> %b, i32 2) ++ ret <2 x i64> %0 ++} ++ ++define <16 x i8> @lsx_vrepli_b() { ++; CHECK-LABEL: lsx_vrepli_b: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vldi $vr0, 2 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = tail call <16 x i8> @llvm.loongarch.lsx.vrepli.b(i32 2) ++ ret <16 x i8> %0 ++} ++ ++define <8 x i16> @lsx_vrepli_h() { ++; CHECK-LABEL: lsx_vrepli_h: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vldi $vr0, 2 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = tail call <8 x i16> @llvm.loongarch.lsx.vrepli.h(i32 2) ++ ret <8 x i16> %0 ++} ++ ++define <4 x i32> @lsx_vrepli_w() { ++; CHECK-LABEL: lsx_vrepli_w: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vldi $vr0, 2 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = tail call <4 x i32> @llvm.loongarch.lsx.vrepli.w(i32 2) ++ ret <4 x i32> %0 ++} ++ ++define <2 x i64> @lsx_vrepli_d() { ++; CHECK-LABEL: lsx_vrepli_d: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vldi $vr0, 2 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = tail call <2 x i64> @llvm.loongarch.lsx.vrepli.d(i32 2) ++ ret <2 x i64> %0 ++} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-madd.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-madd.ll +deleted file mode 100644 +index 89503724f..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-madd.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vmadd.b(<16 x i8>, <16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vmadd_b(<16 x i8> %va, <16 x i8> %vb, <16 x i8> %vc) nounwind { +-; CHECK-LABEL: lsx_vmadd_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmadd.b $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmadd.b(<16 x i8> %va, <16 x i8> %vb, <16 x i8> %vc) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmadd.h(<8 x i16>, <8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vmadd_h(<8 x i16> %va, <8 x i16> %vb, <8 x i16> %vc) nounwind { +-; CHECK-LABEL: lsx_vmadd_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmadd.h $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmadd.h(<8 x i16> %va, <8 x i16> %vb, <8 x i16> %vc) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmadd.w(<4 x i32>, <4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vmadd_w(<4 x i32> %va, <4 x i32> %vb, <4 x i32> %vc) nounwind { +-; CHECK-LABEL: lsx_vmadd_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmadd.w $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmadd.w(<4 x i32> %va, <4 x i32> %vb, <4 x i32> %vc) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmadd.d(<2 x i64>, <2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmadd_d(<2 x i64> %va, <2 x i64> %vb, <2 x i64> %vc) nounwind { +-; CHECK-LABEL: lsx_vmadd_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmadd.d $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmadd.d(<2 x i64> %va, <2 x i64> %vb, <2 x i64> %vc) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-maddw.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-maddw.ll +deleted file mode 100644 +index 1e3ab25a5..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-maddw.ll ++++ /dev/null +@@ -1,290 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <8 x i16> @llvm.loongarch.lsx.vmaddwev.h.b(<8 x i16>, <16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vmaddwev_h_b(<8 x i16> %va, <16 x i8> %vb, <16 x i8> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwev_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwev.h.b $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmaddwev.h.b(<8 x i16> %va, <16 x i8> %vb, <16 x i8> %vc) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmaddwev.w.h(<4 x i32>, <8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vmaddwev_w_h(<4 x i32> %va, <8 x i16> %vb, <8 x i16> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwev_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwev.w.h $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmaddwev.w.h(<4 x i32> %va, <8 x i16> %vb, <8 x i16> %vc) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmaddwev.d.w(<2 x i64>, <4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vmaddwev_d_w(<2 x i64> %va, <4 x i32> %vb, <4 x i32> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwev_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwev.d.w $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmaddwev.d.w(<2 x i64> %va, <4 x i32> %vb, <4 x i32> %vc) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmaddwev.q.d(<2 x i64>, <2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmaddwev_q_d(<2 x i64> %va, <2 x i64> %vb, <2 x i64> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwev_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwev.q.d $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmaddwev.q.d(<2 x i64> %va, <2 x i64> %vb, <2 x i64> %vc) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmaddwev.h.bu(<8 x i16>, <16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vmaddwev_h_bu(<8 x i16> %va, <16 x i8> %vb, <16 x i8> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwev_h_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwev.h.bu $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmaddwev.h.bu(<8 x i16> %va, <16 x i8> %vb, <16 x i8> %vc) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmaddwev.w.hu(<4 x i32>, <8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vmaddwev_w_hu(<4 x i32> %va, <8 x i16> %vb, <8 x i16> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwev_w_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwev.w.hu $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmaddwev.w.hu(<4 x i32> %va, <8 x i16> %vb, <8 x i16> %vc) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmaddwev.d.wu(<2 x i64>, <4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vmaddwev_d_wu(<2 x i64> %va, <4 x i32> %vb, <4 x i32> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwev_d_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwev.d.wu $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmaddwev.d.wu(<2 x i64> %va, <4 x i32> %vb, <4 x i32> %vc) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmaddwev.q.du(<2 x i64>, <2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmaddwev_q_du(<2 x i64> %va, <2 x i64> %vb, <2 x i64> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwev_q_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwev.q.du $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmaddwev.q.du(<2 x i64> %va, <2 x i64> %vb, <2 x i64> %vc) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmaddwev.h.bu.b(<8 x i16>, <16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vmaddwev_h_bu_b(<8 x i16> %va, <16 x i8> %vb, <16 x i8> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwev_h_bu_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwev.h.bu.b $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmaddwev.h.bu.b(<8 x i16> %va, <16 x i8> %vb, <16 x i8> %vc) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmaddwev.w.hu.h(<4 x i32>, <8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vmaddwev_w_hu_h(<4 x i32> %va, <8 x i16> %vb, <8 x i16> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwev_w_hu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwev.w.hu.h $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmaddwev.w.hu.h(<4 x i32> %va, <8 x i16> %vb, <8 x i16> %vc) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmaddwev.d.wu.w(<2 x i64>, <4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vmaddwev_d_wu_w(<2 x i64> %va, <4 x i32> %vb, <4 x i32> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwev_d_wu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwev.d.wu.w $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmaddwev.d.wu.w(<2 x i64> %va, <4 x i32> %vb, <4 x i32> %vc) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmaddwev.q.du.d(<2 x i64>, <2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmaddwev_q_du_d(<2 x i64> %va, <2 x i64> %vb, <2 x i64> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwev_q_du_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwev.q.du.d $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmaddwev.q.du.d(<2 x i64> %va, <2 x i64> %vb, <2 x i64> %vc) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmaddwod.h.b(<8 x i16>, <16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vmaddwod_h_b(<8 x i16> %va, <16 x i8> %vb, <16 x i8> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwod_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwod.h.b $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmaddwod.h.b(<8 x i16> %va, <16 x i8> %vb, <16 x i8> %vc) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmaddwod.w.h(<4 x i32>, <8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vmaddwod_w_h(<4 x i32> %va, <8 x i16> %vb, <8 x i16> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwod_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwod.w.h $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmaddwod.w.h(<4 x i32> %va, <8 x i16> %vb, <8 x i16> %vc) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmaddwod.d.w(<2 x i64>, <4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vmaddwod_d_w(<2 x i64> %va, <4 x i32> %vb, <4 x i32> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwod_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwod.d.w $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmaddwod.d.w(<2 x i64> %va, <4 x i32> %vb, <4 x i32> %vc) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmaddwod.q.d(<2 x i64>, <2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmaddwod_q_d(<2 x i64> %va, <2 x i64> %vb, <2 x i64> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwod_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwod.q.d $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmaddwod.q.d(<2 x i64> %va, <2 x i64> %vb, <2 x i64> %vc) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmaddwod.h.bu(<8 x i16>, <16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vmaddwod_h_bu(<8 x i16> %va, <16 x i8> %vb, <16 x i8> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwod_h_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwod.h.bu $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmaddwod.h.bu(<8 x i16> %va, <16 x i8> %vb, <16 x i8> %vc) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmaddwod.w.hu(<4 x i32>, <8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vmaddwod_w_hu(<4 x i32> %va, <8 x i16> %vb, <8 x i16> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwod_w_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwod.w.hu $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmaddwod.w.hu(<4 x i32> %va, <8 x i16> %vb, <8 x i16> %vc) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmaddwod.d.wu(<2 x i64>, <4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vmaddwod_d_wu(<2 x i64> %va, <4 x i32> %vb, <4 x i32> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwod_d_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwod.d.wu $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmaddwod.d.wu(<2 x i64> %va, <4 x i32> %vb, <4 x i32> %vc) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmaddwod.q.du(<2 x i64>, <2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmaddwod_q_du(<2 x i64> %va, <2 x i64> %vb, <2 x i64> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwod_q_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwod.q.du $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmaddwod.q.du(<2 x i64> %va, <2 x i64> %vb, <2 x i64> %vc) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmaddwod.h.bu.b(<8 x i16>, <16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vmaddwod_h_bu_b(<8 x i16> %va, <16 x i8> %vb, <16 x i8> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwod_h_bu_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwod.h.bu.b $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmaddwod.h.bu.b(<8 x i16> %va, <16 x i8> %vb, <16 x i8> %vc) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmaddwod.w.hu.h(<4 x i32>, <8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vmaddwod_w_hu_h(<4 x i32> %va, <8 x i16> %vb, <8 x i16> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwod_w_hu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwod.w.hu.h $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmaddwod.w.hu.h(<4 x i32> %va, <8 x i16> %vb, <8 x i16> %vc) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmaddwod.d.wu.w(<2 x i64>, <4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vmaddwod_d_wu_w(<2 x i64> %va, <4 x i32> %vb, <4 x i32> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwod_d_wu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwod.d.wu.w $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmaddwod.d.wu.w(<2 x i64> %va, <4 x i32> %vb, <4 x i32> %vc) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmaddwod.q.du.d(<2 x i64>, <2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmaddwod_q_du_d(<2 x i64> %va, <2 x i64> %vb, <2 x i64> %vc) nounwind { +-; CHECK-LABEL: lsx_vmaddwod_q_du_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaddwod.q.du.d $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmaddwod.q.du.d(<2 x i64> %va, <2 x i64> %vb, <2 x i64> %vc) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-max-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-max-invalid-imm.ll +deleted file mode 100644 +index 667ba3272..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-max-invalid-imm.ll ++++ /dev/null +@@ -1,129 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vmaxi.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vmaxi_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmaxi.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmaxi.b(<16 x i8> %va, i32 -17) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vmaxi_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmaxi.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmaxi.b(<16 x i8> %va, i32 16) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmaxi.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vmaxi_h_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmaxi.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmaxi.h(<8 x i16> %va, i32 -17) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vmaxi_h_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmaxi.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmaxi.h(<8 x i16> %va, i32 16) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmaxi.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vmaxi_w_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmaxi.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmaxi.w(<4 x i32> %va, i32 -17) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vmaxi_w_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmaxi.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmaxi.w(<4 x i32> %va, i32 16) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmaxi.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vmaxi_d_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmaxi.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmaxi.d(<2 x i64> %va, i32 -17) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vmaxi_d_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmaxi.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmaxi.d(<2 x i64> %va, i32 16) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vmaxi.bu(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vmaxi_bu_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmaxi.bu: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmaxi.bu(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vmaxi_bu_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmaxi.bu: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmaxi.bu(<16 x i8> %va, i32 32) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmaxi.hu(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vmaxi_hu_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmaxi.hu: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmaxi.hu(<8 x i16> %va, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vmaxi_hu_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmaxi.hu: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmaxi.hu(<8 x i16> %va, i32 32) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmaxi.wu(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vmaxi_wu_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmaxi.wu: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmaxi.wu(<4 x i32> %va, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vmaxi_wu_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmaxi.wu: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmaxi.wu(<4 x i32> %va, i32 32) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmaxi.du(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vmaxi_du_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmaxi.du: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmaxi.du(<2 x i64> %va, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vmaxi_du_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmaxi.du: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmaxi.du(<2 x i64> %va, i32 32) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-max-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-max-non-imm.ll +deleted file mode 100644 +index 34bbe3495..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-max-non-imm.ll ++++ /dev/null +@@ -1,73 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vmaxi.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vmaxi_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmaxi.b(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmaxi.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vmaxi_h(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmaxi.h(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmaxi.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vmaxi_w(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmaxi.w(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmaxi.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vmaxi_d(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmaxi.d(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vmaxi.bu(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vmaxi_bu(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmaxi.bu(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmaxi.hu(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vmaxi_hu(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmaxi.hu(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmaxi.wu(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vmaxi_wu(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmaxi.wu(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmaxi.du(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vmaxi_du(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmaxi.du(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-max.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-max.ll +deleted file mode 100644 +index 4dd289cf6..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-max.ll ++++ /dev/null +@@ -1,194 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vmax.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vmax_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vmax_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmax.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmax.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmax.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vmax_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vmax_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmax.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmax.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmax.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vmax_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vmax_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmax.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmax.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmax.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmax_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vmax_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmax.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmax.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vmaxi.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vmaxi_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vmaxi_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaxi.b $vr0, $vr0, -16 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmaxi.b(<16 x i8> %va, i32 -16) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmaxi.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vmaxi_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vmaxi_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaxi.h $vr0, $vr0, -16 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmaxi.h(<8 x i16> %va, i32 -16) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmaxi.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vmaxi_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vmaxi_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaxi.w $vr0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmaxi.w(<4 x i32> %va, i32 15) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmaxi.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vmaxi_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vmaxi_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaxi.d $vr0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmaxi.d(<2 x i64> %va, i32 15) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vmax.bu(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vmax_bu(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vmax_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmax.bu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmax.bu(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmax.hu(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vmax_hu(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vmax_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmax.hu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmax.hu(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmax.wu(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vmax_wu(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vmax_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmax.wu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmax.wu(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmax.du(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmax_du(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vmax_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmax.du $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmax.du(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vmaxi.bu(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vmaxi_bu(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vmaxi_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaxi.bu $vr0, $vr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmaxi.bu(<16 x i8> %va, i32 1) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmaxi.hu(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vmaxi_hu(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vmaxi_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaxi.hu $vr0, $vr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmaxi.hu(<8 x i16> %va, i32 1) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmaxi.wu(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vmaxi_wu(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vmaxi_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaxi.wu $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmaxi.wu(<4 x i32> %va, i32 31) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmaxi.du(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vmaxi_du(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vmaxi_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmaxi.du $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmaxi.du(<2 x i64> %va, i32 31) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-min-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-min-invalid-imm.ll +deleted file mode 100644 +index b73bada4f..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-min-invalid-imm.ll ++++ /dev/null +@@ -1,129 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vmini.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vmini_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmini.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmini.b(<16 x i8> %va, i32 -17) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vmini_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmini.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmini.b(<16 x i8> %va, i32 16) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmini.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vmini_h_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmini.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmini.h(<8 x i16> %va, i32 -17) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vmini_h_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmini.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmini.h(<8 x i16> %va, i32 16) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmini.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vmini_w_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmini.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmini.w(<4 x i32> %va, i32 -17) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vmini_w_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmini.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmini.w(<4 x i32> %va, i32 16) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmini.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vmini_d_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmini.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmini.d(<2 x i64> %va, i32 -17) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vmini_d_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmini.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmini.d(<2 x i64> %va, i32 16) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vmini.bu(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vmini_bu_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmini.bu: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmini.bu(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vmini_bu_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmini.bu: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmini.bu(<16 x i8> %va, i32 32) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmini.hu(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vmini_hu_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmini.hu: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmini.hu(<8 x i16> %va, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vmini_hu_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmini.hu: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmini.hu(<8 x i16> %va, i32 32) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmini.wu(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vmini_wu_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmini.wu: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmini.wu(<4 x i32> %va, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vmini_wu_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmini.wu: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmini.wu(<4 x i32> %va, i32 32) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmini.du(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vmini_du_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmini.du: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmini.du(<2 x i64> %va, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vmini_du_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vmini.du: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmini.du(<2 x i64> %va, i32 32) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-min-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-min-non-imm.ll +deleted file mode 100644 +index 5d9b98cec..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-min-non-imm.ll ++++ /dev/null +@@ -1,73 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vmini.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vmini_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmini.b(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmini.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vmini_h(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmini.h(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmini.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vmini_w(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmini.w(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmini.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vmini_d(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmini.d(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vmini.bu(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vmini_bu(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmini.bu(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmini.hu(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vmini_hu(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmini.hu(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmini.wu(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vmini_wu(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmini.wu(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmini.du(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vmini_du(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmini.du(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-min.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-min.ll +deleted file mode 100644 +index aa12a5ead..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-min.ll ++++ /dev/null +@@ -1,194 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vmin.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vmin_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vmin_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmin.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmin.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmin.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vmin_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vmin_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmin.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmin.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmin.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vmin_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vmin_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmin.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmin.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmin.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmin_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vmin_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmin.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmin.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vmini.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vmini_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vmini_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmini.b $vr0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmini.b(<16 x i8> %va, i32 15) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmini.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vmini_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vmini_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmini.h $vr0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmini.h(<8 x i16> %va, i32 15) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmini.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vmini_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vmini_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmini.w $vr0, $vr0, -16 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmini.w(<4 x i32> %va, i32 -16) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmini.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vmini_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vmini_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmini.d $vr0, $vr0, -16 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmini.d(<2 x i64> %va, i32 -16) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vmin.bu(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vmin_bu(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vmin_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmin.bu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmin.bu(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmin.hu(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vmin_hu(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vmin_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmin.hu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmin.hu(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmin.wu(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vmin_wu(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vmin_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmin.wu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmin.wu(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmin.du(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmin_du(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vmin_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmin.du $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmin.du(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vmini.bu(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vmini_bu(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vmini_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmini.bu $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmini.bu(<16 x i8> %va, i32 31) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmini.hu(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vmini_hu(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vmini_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmini.hu $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmini.hu(<8 x i16> %va, i32 31) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmini.wu(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vmini_wu(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vmini_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmini.wu $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmini.wu(<4 x i32> %va, i32 31) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmini.du(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vmini_du(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vmini_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmini.du $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmini.du(<2 x i64> %va, i32 31) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-mod.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-mod.ll +deleted file mode 100644 +index 6b3dc6865..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-mod.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vmod.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vmod_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vmod_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmod.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmod.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmod.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vmod_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vmod_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmod.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmod.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmod.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vmod_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vmod_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmod.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmod.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmod.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmod_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vmod_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmod.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmod.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vmod.bu(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vmod_bu(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vmod_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmod.bu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmod.bu(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmod.hu(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vmod_hu(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vmod_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmod.hu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmod.hu(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmod.wu(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vmod_wu(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vmod_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmod.wu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmod.wu(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmod.du(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmod_du(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vmod_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmod.du $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmod.du(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-mskgez.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-mskgez.ll +deleted file mode 100644 +index 3ecd777ae..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-mskgez.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vmskgez.b(<16 x i8>) +- +-define <16 x i8> @lsx_vmskgez_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vmskgez_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmskgez.b $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmskgez.b(<16 x i8> %va) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-mskltz.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-mskltz.ll +deleted file mode 100644 +index be00c7613..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-mskltz.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vmskltz.b(<16 x i8>) +- +-define <16 x i8> @lsx_vmskltz_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vmskltz_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmskltz.b $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmskltz.b(<16 x i8> %va) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmskltz.h(<8 x i16>) +- +-define <8 x i16> @lsx_vmskltz_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vmskltz_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmskltz.h $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmskltz.h(<8 x i16> %va) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmskltz.w(<4 x i32>) +- +-define <4 x i32> @lsx_vmskltz_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vmskltz_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmskltz.w $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmskltz.w(<4 x i32> %va) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmskltz.d(<2 x i64>) +- +-define <2 x i64> @lsx_vmskltz_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vmskltz_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmskltz.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmskltz.d(<2 x i64> %va) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-msknz.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-msknz.ll +deleted file mode 100644 +index 02f1752f7..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-msknz.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vmsknz.b(<16 x i8>) +- +-define <16 x i8> @lsx_vmsknz_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vmsknz_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmsknz.b $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmsknz.b(<16 x i8> %va) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-msub.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-msub.ll +deleted file mode 100644 +index 98684e10c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-msub.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vmsub.b(<16 x i8>, <16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vmsub_b(<16 x i8> %va, <16 x i8> %vb, <16 x i8> %vc) nounwind { +-; CHECK-LABEL: lsx_vmsub_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmsub.b $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmsub.b(<16 x i8> %va, <16 x i8> %vb, <16 x i8> %vc) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmsub.h(<8 x i16>, <8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vmsub_h(<8 x i16> %va, <8 x i16> %vb, <8 x i16> %vc) nounwind { +-; CHECK-LABEL: lsx_vmsub_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmsub.h $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmsub.h(<8 x i16> %va, <8 x i16> %vb, <8 x i16> %vc) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmsub.w(<4 x i32>, <4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vmsub_w(<4 x i32> %va, <4 x i32> %vb, <4 x i32> %vc) nounwind { +-; CHECK-LABEL: lsx_vmsub_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmsub.w $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmsub.w(<4 x i32> %va, <4 x i32> %vb, <4 x i32> %vc) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmsub.d(<2 x i64>, <2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmsub_d(<2 x i64> %va, <2 x i64> %vb, <2 x i64> %vc) nounwind { +-; CHECK-LABEL: lsx_vmsub_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmsub.d $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmsub.d(<2 x i64> %va, <2 x i64> %vb, <2 x i64> %vc) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-muh.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-muh.ll +deleted file mode 100644 +index a4deb8f8f..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-muh.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vmuh.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vmuh_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vmuh_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmuh.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmuh.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmuh.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vmuh_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vmuh_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmuh.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmuh.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmuh.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vmuh_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vmuh_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmuh.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmuh.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmuh.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmuh_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vmuh_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmuh.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmuh.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vmuh.bu(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vmuh_bu(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vmuh_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmuh.bu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmuh.bu(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmuh.hu(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vmuh_hu(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vmuh_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmuh.hu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmuh.hu(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmuh.wu(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vmuh_wu(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vmuh_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmuh.wu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmuh.wu(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmuh.du(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmuh_du(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vmuh_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmuh.du $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmuh.du(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-mul.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-mul.ll +deleted file mode 100644 +index aca60d166..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-mul.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vmul.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vmul_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vmul_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmul.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vmul.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmul.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vmul_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vmul_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmul.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmul.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmul.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vmul_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vmul_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmul.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmul.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmul.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmul_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vmul_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmul.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmul.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-mulw.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-mulw.ll +deleted file mode 100644 +index eb55c1f80..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-mulw.ll ++++ /dev/null +@@ -1,290 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <8 x i16> @llvm.loongarch.lsx.vmulwev.h.b(<16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vmulwev_h_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwev_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwev.h.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmulwev.h.b(<16 x i8> %va, <16 x i8> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmulwev.w.h(<8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vmulwev_w_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwev_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwev.w.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmulwev.w.h(<8 x i16> %va, <8 x i16> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmulwev.d.w(<4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vmulwev_d_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwev_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwev.d.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmulwev.d.w(<4 x i32> %va, <4 x i32> %vb) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmulwev.q.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmulwev_q_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwev_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwev.q.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmulwev.q.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmulwev.h.bu(<16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vmulwev_h_bu(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwev_h_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwev.h.bu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmulwev.h.bu(<16 x i8> %va, <16 x i8> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmulwev.w.hu(<8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vmulwev_w_hu(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwev_w_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwev.w.hu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmulwev.w.hu(<8 x i16> %va, <8 x i16> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmulwev.d.wu(<4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vmulwev_d_wu(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwev_d_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwev.d.wu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmulwev.d.wu(<4 x i32> %va, <4 x i32> %vb) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmulwev.q.du(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmulwev_q_du(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwev_q_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwev.q.du $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmulwev.q.du(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmulwev.h.bu.b(<16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vmulwev_h_bu_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwev_h_bu_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwev.h.bu.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmulwev.h.bu.b(<16 x i8> %va, <16 x i8> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmulwev.w.hu.h(<8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vmulwev_w_hu_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwev_w_hu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwev.w.hu.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmulwev.w.hu.h(<8 x i16> %va, <8 x i16> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmulwev.d.wu.w(<4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vmulwev_d_wu_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwev_d_wu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwev.d.wu.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmulwev.d.wu.w(<4 x i32> %va, <4 x i32> %vb) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmulwev.q.du.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmulwev_q_du_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwev_q_du_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwev.q.du.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmulwev.q.du.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmulwod.h.b(<16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vmulwod_h_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwod_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwod.h.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmulwod.h.b(<16 x i8> %va, <16 x i8> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmulwod.w.h(<8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vmulwod_w_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwod_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwod.w.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmulwod.w.h(<8 x i16> %va, <8 x i16> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmulwod.d.w(<4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vmulwod_d_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwod_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwod.d.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmulwod.d.w(<4 x i32> %va, <4 x i32> %vb) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmulwod.q.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmulwod_q_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwod_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwod.q.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmulwod.q.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmulwod.h.bu(<16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vmulwod_h_bu(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwod_h_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwod.h.bu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmulwod.h.bu(<16 x i8> %va, <16 x i8> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmulwod.w.hu(<8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vmulwod_w_hu(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwod_w_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwod.w.hu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmulwod.w.hu(<8 x i16> %va, <8 x i16> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmulwod.d.wu(<4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vmulwod_d_wu(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwod_d_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwod.d.wu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmulwod.d.wu(<4 x i32> %va, <4 x i32> %vb) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmulwod.q.du(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmulwod_q_du(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwod_q_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwod.q.du $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmulwod.q.du(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vmulwod.h.bu.b(<16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vmulwod_h_bu_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwod_h_bu_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwod.h.bu.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vmulwod.h.bu.b(<16 x i8> %va, <16 x i8> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vmulwod.w.hu.h(<8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vmulwod_w_hu_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwod_w_hu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwod.w.hu.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vmulwod.w.hu.h(<8 x i16> %va, <8 x i16> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmulwod.d.wu.w(<4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vmulwod_d_wu_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwod_d_wu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwod.d.wu.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmulwod.d.wu.w(<4 x i32> %va, <4 x i32> %vb) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vmulwod.q.du.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vmulwod_q_du_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vmulwod_q_du_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vmulwod.q.du.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vmulwod.q.du.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-neg.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-neg.ll +deleted file mode 100644 +index 43c6e9757..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-neg.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vneg.b(<16 x i8>) +- +-define <16 x i8> @lsx_vneg_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vneg_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vneg.b $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vneg.b(<16 x i8> %va) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vneg.h(<8 x i16>) +- +-define <8 x i16> @lsx_vneg_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vneg_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vneg.h $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vneg.h(<8 x i16> %va) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vneg.w(<4 x i32>) +- +-define <4 x i32> @lsx_vneg_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vneg_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vneg.w $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vneg.w(<4 x i32> %va) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vneg.d(<2 x i64>) +- +-define <2 x i64> @lsx_vneg_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vneg_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vneg.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vneg.d(<2 x i64> %va) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-nor.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-nor.ll +deleted file mode 100644 +index 16619225f..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-nor.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vnor.v(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vnor_v(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vnor_v: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vnor.v $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vnor.v(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-nori-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-nori-invalid-imm.ll +deleted file mode 100644 +index 8c59d8fb9..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-nori-invalid-imm.ll ++++ /dev/null +@@ -1,17 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vnori.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vnori_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vnori.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vnori.b(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vnori_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vnori.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vnori.b(<16 x i8> %va, i32 256) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-nori-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-nori-non-imm.ll +deleted file mode 100644 +index 322a39c10..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-nori-non-imm.ll ++++ /dev/null +@@ -1,10 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vnori.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vnori_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vnori.b(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-nori.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-nori.ll +deleted file mode 100644 +index c2388a1e0..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-nori.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vnori.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vnori_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vnori_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vnori.b $vr0, $vr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vnori.b(<16 x i8> %va, i32 1) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-or.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-or.ll +deleted file mode 100644 +index ab557003d..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-or.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vor.v(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vor_v(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vor_v: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vor.v $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vor.v(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ori-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ori-invalid-imm.ll +deleted file mode 100644 +index 4a7fc7e10..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ori-invalid-imm.ll ++++ /dev/null +@@ -1,17 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vori.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vori_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vori.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vori.b(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vori_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vori.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vori.b(<16 x i8> %va, i32 256) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ori-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ori-non-imm.ll +deleted file mode 100644 +index 5644b8581..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ori-non-imm.ll ++++ /dev/null +@@ -1,10 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vori.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vori_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vori.b(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ori.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ori.ll +deleted file mode 100644 +index 85c0f432c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ori.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vori.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vori_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vori_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vori.b $vr0, $vr0, 3 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vori.b(<16 x i8> %va, i32 3) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-orn.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-orn.ll +deleted file mode 100644 +index 4528628e0..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-orn.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vorn.v(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vorn_v(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vorn_v: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vorn.v $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vorn.v(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-pack.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-pack.ll +deleted file mode 100644 +index 70a3620d1..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-pack.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vpackev.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vpackev_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vpackev_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpackev.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vpackev.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vpackev.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vpackev_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vpackev_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpackev.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vpackev.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vpackev.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vpackev_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vpackev_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpackev.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vpackev.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vpackev.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vpackev_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vpackev_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpackev.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vpackev.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vpackod.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vpackod_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vpackod_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpackod.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vpackod.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vpackod.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vpackod_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vpackod_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpackod.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vpackod.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vpackod.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vpackod_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vpackod_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpackod.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vpackod.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vpackod.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vpackod_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vpackod_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpackod.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vpackod.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-pcnt.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-pcnt.ll +deleted file mode 100644 +index 431b270ab..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-pcnt.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vpcnt.b(<16 x i8>) +- +-define <16 x i8> @lsx_vpcnt_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vpcnt_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpcnt.b $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vpcnt.b(<16 x i8> %va) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vpcnt.h(<8 x i16>) +- +-define <8 x i16> @lsx_vpcnt_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vpcnt_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpcnt.h $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vpcnt.h(<8 x i16> %va) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vpcnt.w(<4 x i32>) +- +-define <4 x i32> @lsx_vpcnt_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vpcnt_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpcnt.w $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vpcnt.w(<4 x i32> %va) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vpcnt.d(<2 x i64>) +- +-define <2 x i64> @lsx_vpcnt_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vpcnt_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpcnt.d $vr0, $vr0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vpcnt.d(<2 x i64> %va) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-permi-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-permi-invalid-imm.ll +deleted file mode 100644 +index e439bbae6..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-permi-invalid-imm.ll ++++ /dev/null +@@ -1,17 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <4 x i32> @llvm.loongarch.lsx.vpermi.w(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vpermi_w_lo(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vpermi.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vpermi.w(<4 x i32> %va, <4 x i32> %vb, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vpermi_w_hi(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vpermi.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vpermi.w(<4 x i32> %va, <4 x i32> %vb, i32 256) +- ret <4 x i32> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-permi-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-permi-non-imm.ll +deleted file mode 100644 +index bdfc08ed6..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-permi-non-imm.ll ++++ /dev/null +@@ -1,10 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <4 x i32> @llvm.loongarch.lsx.vpermi.w(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vpermi_w(<4 x i32> %va, <4 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vpermi.w(<4 x i32> %va, <4 x i32> %vb, i32 %c) +- ret <4 x i32> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-permi.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-permi.ll +deleted file mode 100644 +index b8367d98c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-permi.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <4 x i32> @llvm.loongarch.lsx.vpermi.w(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vpermi_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vpermi_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpermi.w $vr0, $vr1, 255 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vpermi.w(<4 x i32> %va, <4 x i32> %vb, i32 255) +- ret <4 x i32> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-pick.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-pick.ll +deleted file mode 100644 +index 4ebf29e14..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-pick.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vpickev.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vpickev_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vpickev_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpickev.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vpickev.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vpickev.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vpickev_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vpickev_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpickev.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vpickev.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vpickev.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vpickev_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vpickev_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpickev.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vpickev.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vpickev.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vpickev_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vpickev_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpickev.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vpickev.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vpickod.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vpickod_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vpickod_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpickod.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vpickod.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vpickod.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vpickod_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vpickod_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpickod.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vpickod.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vpickod.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vpickod_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vpickod_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpickod.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vpickod.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vpickod.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vpickod_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vpickod_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpickod.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vpickod.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-pickve2gr-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-pickve2gr-invalid-imm.ll +deleted file mode 100644 +index 3430c54d2..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-pickve2gr-invalid-imm.ll ++++ /dev/null +@@ -1,129 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare i32 @llvm.loongarch.lsx.vpickve2gr.b(<16 x i8>, i32) +- +-define i32 @lsx_vpickve2gr_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vpickve2gr.b: argument out of range +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.b(<16 x i8> %va, i32 -1) +- ret i32 %res +-} +- +-define i32 @lsx_vpickve2gr_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vpickve2gr.b: argument out of range +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.b(<16 x i8> %va, i32 16) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lsx.vpickve2gr.h(<8 x i16>, i32) +- +-define i32 @lsx_vpickve2gr_h_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vpickve2gr.h: argument out of range +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.h(<8 x i16> %va, i32 -1) +- ret i32 %res +-} +- +-define i32 @lsx_vpickve2gr_h_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vpickve2gr.h: argument out of range +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.h(<8 x i16> %va, i32 8) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lsx.vpickve2gr.w(<4 x i32>, i32) +- +-define i32 @lsx_vpickve2gr_w_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vpickve2gr.w: argument out of range +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.w(<4 x i32> %va, i32 -1) +- ret i32 %res +-} +- +-define i32 @lsx_vpickve2gr_w_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vpickve2gr.w: argument out of range +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.w(<4 x i32> %va, i32 4) +- ret i32 %res +-} +- +-declare i64 @llvm.loongarch.lsx.vpickve2gr.d(<2 x i64>, i32) +- +-define i64 @lsx_vpickve2gr_d_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vpickve2gr.d: argument out of range +-entry: +- %res = call i64 @llvm.loongarch.lsx.vpickve2gr.d(<2 x i64> %va, i32 -1) +- ret i64 %res +-} +- +-define i64 @lsx_vpickve2gr_d_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vpickve2gr.d: argument out of range +-entry: +- %res = call i64 @llvm.loongarch.lsx.vpickve2gr.d(<2 x i64> %va, i32 2) +- ret i64 %res +-} +- +-declare i32 @llvm.loongarch.lsx.vpickve2gr.bu(<16 x i8>, i32) +- +-define i32 @lsx_vpickve2gr_bu_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vpickve2gr.bu: argument out of range +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.bu(<16 x i8> %va, i32 -1) +- ret i32 %res +-} +- +-define i32 @lsx_vpickve2gr_bu_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vpickve2gr.bu: argument out of range +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.bu(<16 x i8> %va, i32 16) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lsx.vpickve2gr.hu(<8 x i16>, i32) +- +-define i32 @lsx_vpickve2gr_hu_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vpickve2gr.hu: argument out of range +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.hu(<8 x i16> %va, i32 -1) +- ret i32 %res +-} +- +-define i32 @lsx_vpickve2gr_hu_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vpickve2gr.hu: argument out of range +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.hu(<8 x i16> %va, i32 8) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lsx.vpickve2gr.wu(<4 x i32>, i32) +- +-define i32 @lsx_vpickve2gr_wu_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vpickve2gr.wu: argument out of range +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.wu(<4 x i32> %va, i32 -1) +- ret i32 %res +-} +- +-define i32 @lsx_vpickve2gr_wu_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vpickve2gr.wu: argument out of range +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.wu(<4 x i32> %va, i32 4) +- ret i32 %res +-} +- +-declare i64 @llvm.loongarch.lsx.vpickve2gr.du(<2 x i64>, i32) +- +-define i64 @lsx_vpickve2gr_du_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vpickve2gr.du: argument out of range +-entry: +- %res = call i64 @llvm.loongarch.lsx.vpickve2gr.du(<2 x i64> %va, i32 -1) +- ret i64 %res +-} +- +-define i64 @lsx_vpickve2gr_du_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vpickve2gr.du: argument out of range +-entry: +- %res = call i64 @llvm.loongarch.lsx.vpickve2gr.du(<2 x i64> %va, i32 2) +- ret i64 %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-pickve2gr-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-pickve2gr-non-imm.ll +deleted file mode 100644 +index 6dd3c1f27..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-pickve2gr-non-imm.ll ++++ /dev/null +@@ -1,73 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare i32 @llvm.loongarch.lsx.vpickve2gr.b(<16 x i8>, i32) +- +-define i32 @lsx_vpickve2gr_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.b(<16 x i8> %va, i32 %b) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lsx.vpickve2gr.h(<8 x i16>, i32) +- +-define i32 @lsx_vpickve2gr_h(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.h(<8 x i16> %va, i32 %b) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lsx.vpickve2gr.w(<4 x i32>, i32) +- +-define i32 @lsx_vpickve2gr_w(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.w(<4 x i32> %va, i32 %b) +- ret i32 %res +-} +- +-declare i64 @llvm.loongarch.lsx.vpickve2gr.d(<2 x i64>, i32) +- +-define i64 @lsx_vpickve2gr_d(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call i64 @llvm.loongarch.lsx.vpickve2gr.d(<2 x i64> %va, i32 %b) +- ret i64 %res +-} +- +-declare i32 @llvm.loongarch.lsx.vpickve2gr.bu(<16 x i8>, i32) +- +-define i32 @lsx_vpickve2gr_bu(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.bu(<16 x i8> %va, i32 %b) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lsx.vpickve2gr.hu(<8 x i16>, i32) +- +-define i32 @lsx_vpickve2gr_hu(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.hu(<8 x i16> %va, i32 %b) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lsx.vpickve2gr.wu(<4 x i32>, i32) +- +-define i32 @lsx_vpickve2gr_wu(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.wu(<4 x i32> %va, i32 %b) +- ret i32 %res +-} +- +-declare i64 @llvm.loongarch.lsx.vpickve2gr.du(<2 x i64>, i32) +- +-define i64 @lsx_vpickve2gr_du(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call i64 @llvm.loongarch.lsx.vpickve2gr.du(<2 x i64> %va, i32 %b) +- ret i64 %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-pickve2gr.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-pickve2gr.ll +deleted file mode 100644 +index ed56d30ce..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-pickve2gr.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare i32 @llvm.loongarch.lsx.vpickve2gr.b(<16 x i8>, i32) +- +-define i32 @lsx_vpickve2gr_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vpickve2gr_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpickve2gr.b $a0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.b(<16 x i8> %va, i32 15) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lsx.vpickve2gr.h(<8 x i16>, i32) +- +-define i32 @lsx_vpickve2gr_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vpickve2gr_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 7 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.h(<8 x i16> %va, i32 7) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lsx.vpickve2gr.w(<4 x i32>, i32) +- +-define i32 @lsx_vpickve2gr_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vpickve2gr_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpickve2gr.w $a0, $vr0, 3 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.w(<4 x i32> %va, i32 3) +- ret i32 %res +-} +- +-declare i64 @llvm.loongarch.lsx.vpickve2gr.d(<2 x i64>, i32) +- +-define i64 @lsx_vpickve2gr_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vpickve2gr_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpickve2gr.d $a0, $vr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i64 @llvm.loongarch.lsx.vpickve2gr.d(<2 x i64> %va, i32 1) +- ret i64 %res +-} +- +-declare i32 @llvm.loongarch.lsx.vpickve2gr.bu(<16 x i8>, i32) +- +-define i32 @lsx_vpickve2gr_bu(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vpickve2gr_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpickve2gr.bu $a0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.bu(<16 x i8> %va, i32 15) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lsx.vpickve2gr.hu(<8 x i16>, i32) +- +-define i32 @lsx_vpickve2gr_hu(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vpickve2gr_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpickve2gr.hu $a0, $vr0, 7 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.hu(<8 x i16> %va, i32 7) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lsx.vpickve2gr.wu(<4 x i32>, i32) +- +-define i32 @lsx_vpickve2gr_wu(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vpickve2gr_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpickve2gr.wu $a0, $vr0, 3 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lsx.vpickve2gr.wu(<4 x i32> %va, i32 3) +- ret i32 %res +-} +- +-declare i64 @llvm.loongarch.lsx.vpickve2gr.du(<2 x i64>, i32) +- +-define i64 @lsx_vpickve2gr_du(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vpickve2gr_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vpickve2gr.du $a0, $vr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i64 @llvm.loongarch.lsx.vpickve2gr.du(<2 x i64> %va, i32 1) +- ret i64 %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-replgr2vr.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-replgr2vr.ll +deleted file mode 100644 +index 091f1c98c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-replgr2vr.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vreplgr2vr.b(i32) +- +-define <16 x i8> @lsx_vreplgr2vr_b(i32 %a) nounwind { +-; CHECK-LABEL: lsx_vreplgr2vr_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vreplgr2vr.b $vr0, $a0 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vreplgr2vr.b(i32 %a) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vreplgr2vr.h(i32) +- +-define <8 x i16> @lsx_vreplgr2vr_h(i32 %a) nounwind { +-; CHECK-LABEL: lsx_vreplgr2vr_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vreplgr2vr.h $vr0, $a0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vreplgr2vr.h(i32 %a) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vreplgr2vr.w(i32) +- +-define <4 x i32> @lsx_vreplgr2vr_w(i32 %a) nounwind { +-; CHECK-LABEL: lsx_vreplgr2vr_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vreplgr2vr.w $vr0, $a0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vreplgr2vr.w(i32 %a) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vreplgr2vr.d(i64) +- +-define <2 x i64> @lsx_vreplgr2vr_d(i64 %a) nounwind { +-; CHECK-LABEL: lsx_vreplgr2vr_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vreplgr2vr.d $vr0, $a0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vreplgr2vr.d(i64 %a) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-replve.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-replve.ll +deleted file mode 100644 +index 3ba184dad..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-replve.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vreplve.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vreplve_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK-LABEL: lsx_vreplve_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vreplve.b $vr0, $vr0, $a0 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vreplve.b(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vreplve.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vreplve_h(<8 x i16> %va, i32 %b) nounwind { +-; CHECK-LABEL: lsx_vreplve_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vreplve.h $vr0, $vr0, $a0 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vreplve.h(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vreplve.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vreplve_w(<4 x i32> %va, i32 %b) nounwind { +-; CHECK-LABEL: lsx_vreplve_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vreplve.w $vr0, $vr0, $a0 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vreplve.w(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vreplve.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vreplve_d(<2 x i64> %va, i32 %b) nounwind { +-; CHECK-LABEL: lsx_vreplve_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vreplve.d $vr0, $vr0, $a0 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vreplve.d(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-replvei-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-replvei-invalid-imm.ll +deleted file mode 100644 +index d62544112..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-replvei-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vreplvei.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vreplvei_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vreplvei.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vreplvei.b(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vreplvei_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vreplvei.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vreplvei.b(<16 x i8> %va, i32 16) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vreplvei.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vreplvei_h_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vreplvei.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vreplvei.h(<8 x i16> %va, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vreplvei_h_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vreplvei.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vreplvei.h(<8 x i16> %va, i32 8) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vreplvei.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vreplvei_w_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vreplvei.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vreplvei.w(<4 x i32> %va, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vreplvei_w_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vreplvei.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vreplvei.w(<4 x i32> %va, i32 4) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vreplvei.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vreplvei_d_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vreplvei.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vreplvei.d(<2 x i64> %va, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vreplvei_d_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vreplvei.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vreplvei.d(<2 x i64> %va, i32 2) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-replvei-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-replvei-non-imm.ll +deleted file mode 100644 +index 3d271bb2b..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-replvei-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vreplvei.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vreplvei_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vreplvei.b(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vreplvei.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vreplvei_h(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vreplvei.h(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vreplvei.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vreplvei_w(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vreplvei.w(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vreplvei.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vreplvei_d(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vreplvei.d(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-replvei.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-replvei.ll +deleted file mode 100644 +index 9b8af1878..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-replvei.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vreplvei.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vreplvei_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vreplvei_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vreplvei.b $vr0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vreplvei.b(<16 x i8> %va, i32 15) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vreplvei.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vreplvei_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vreplvei_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vreplvei.h $vr0, $vr0, 7 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vreplvei.h(<8 x i16> %va, i32 7) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vreplvei.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vreplvei_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vreplvei_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vreplvei.w $vr0, $vr0, 3 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vreplvei.w(<4 x i32> %va, i32 3) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vreplvei.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vreplvei_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vreplvei_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vreplvei.d $vr0, $vr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vreplvei.d(<2 x i64> %va, i32 1) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-rotr-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-rotr-invalid-imm.ll +deleted file mode 100644 +index 3c53b3667..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-rotr-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vrotri.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vrotri_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vrotri.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vrotri.b(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vrotri_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vrotri.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vrotri.b(<16 x i8> %va, i32 8) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vrotri.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vrotri_h_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vrotri.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vrotri.h(<8 x i16> %va, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vrotri_h_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vrotri.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vrotri.h(<8 x i16> %va, i32 16) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vrotri.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vrotri_w_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vrotri.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vrotri.w(<4 x i32> %va, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vrotri_w_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vrotri.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vrotri.w(<4 x i32> %va, i32 32) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vrotri.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vrotri_d_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vrotri.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vrotri.d(<2 x i64> %va, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vrotri_d_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vrotri.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vrotri.d(<2 x i64> %va, i32 64) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-rotr-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-rotr-non-imm.ll +deleted file mode 100644 +index fd8ba3a1c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-rotr-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vrotri.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vrotri_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vrotri.b(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vrotri.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vrotri_h(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vrotri.h(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vrotri.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vrotri_w(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vrotri.w(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vrotri.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vrotri_d(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vrotri.d(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-rotr.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-rotr.ll +deleted file mode 100644 +index df8650677..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-rotr.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vrotr.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vrotr_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vrotr_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vrotr.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vrotr.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vrotr.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vrotr_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vrotr_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vrotr.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vrotr.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vrotr.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vrotr_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vrotr_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vrotr.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vrotr.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vrotr.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vrotr_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vrotr_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vrotr.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vrotr.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vrotri.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vrotri_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vrotri_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vrotri.b $vr0, $vr0, 7 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vrotri.b(<16 x i8> %va, i32 7) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vrotri.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vrotri_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vrotri_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vrotri.h $vr0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vrotri.h(<8 x i16> %va, i32 15) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vrotri.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vrotri_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vrotri_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vrotri.w $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vrotri.w(<4 x i32> %va, i32 31) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vrotri.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vrotri_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vrotri_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vrotri.d $vr0, $vr0, 63 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vrotri.d(<2 x i64> %va, i32 63) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sadd.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sadd.ll +deleted file mode 100644 +index a54f95576..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sadd.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsadd.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vsadd_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vsadd_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsadd.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsadd.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsadd.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vsadd_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsadd_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsadd.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsadd.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsadd.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vsadd_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsadd_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsadd.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsadd.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsadd.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vsadd_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsadd_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsadd.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsadd.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vsadd.bu(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vsadd_bu(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vsadd_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsadd.bu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsadd.bu(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsadd.hu(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vsadd_hu(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsadd_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsadd.hu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsadd.hu(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsadd.wu(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vsadd_wu(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsadd_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsadd.wu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsadd.wu(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsadd.du(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vsadd_du(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsadd_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsadd.du $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsadd.du(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sat-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sat-invalid-imm.ll +deleted file mode 100644 +index 45fa4e43b..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sat-invalid-imm.ll ++++ /dev/null +@@ -1,129 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsat.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vsat_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsat.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsat.b(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vsat_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsat.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsat.b(<16 x i8> %va, i32 8) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsat.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vsat_h_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsat.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsat.h(<8 x i16> %va, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vsat_h_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsat.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsat.h(<8 x i16> %va, i32 16) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsat.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vsat_w_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsat.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsat.w(<4 x i32> %va, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vsat_w_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsat.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsat.w(<4 x i32> %va, i32 32) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsat.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vsat_d_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsat.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsat.d(<2 x i64> %va, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vsat_d_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsat.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsat.d(<2 x i64> %va, i32 64) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vsat.bu(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vsat_bu_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsat.bu: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsat.bu(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vsat_bu_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsat.bu: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsat.bu(<16 x i8> %va, i32 8) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsat.hu(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vsat_hu_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsat.hu: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsat.hu(<8 x i16> %va, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vsat_hu_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsat.hu: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsat.hu(<8 x i16> %va, i32 16) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsat.wu(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vsat_wu_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsat.wu: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsat.wu(<4 x i32> %va, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vsat_wu_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsat.wu: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsat.wu(<4 x i32> %va, i32 32) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsat.du(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vsat_du_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsat.du: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsat.du(<2 x i64> %va, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vsat_du_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsat.du: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsat.du(<2 x i64> %va, i32 64) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sat-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sat-non-imm.ll +deleted file mode 100644 +index afdbe0c1c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sat-non-imm.ll ++++ /dev/null +@@ -1,73 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsat.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vsat_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsat.b(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsat.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vsat_h(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsat.h(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsat.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vsat_w(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsat.w(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsat.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vsat_d(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsat.d(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vsat.bu(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vsat_bu(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsat.bu(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsat.hu(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vsat_hu(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsat.hu(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsat.wu(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vsat_wu(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsat.wu(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsat.du(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vsat_du(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsat.du(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sat.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sat.ll +deleted file mode 100644 +index 4286842a6..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sat.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsat.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vsat_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vsat_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsat.b $vr0, $vr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsat.b(<16 x i8> %va, i32 1) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsat.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vsat_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vsat_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsat.h $vr0, $vr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsat.h(<8 x i16> %va, i32 1) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsat.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vsat_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vsat_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsat.w $vr0, $vr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsat.w(<4 x i32> %va, i32 1) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsat.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vsat_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vsat_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsat.d $vr0, $vr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsat.d(<2 x i64> %va, i32 1) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vsat.bu(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vsat_bu(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vsat_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsat.bu $vr0, $vr0, 7 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsat.bu(<16 x i8> %va, i32 7) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsat.hu(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vsat_hu(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vsat_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsat.hu $vr0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsat.hu(<8 x i16> %va, i32 15) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsat.wu(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vsat_wu(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vsat_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsat.wu $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsat.wu(<4 x i32> %va, i32 31) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsat.du(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vsat_du(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vsat_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsat.du $vr0, $vr0, 63 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsat.du(<2 x i64> %va, i32 63) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-seq-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-seq-invalid-imm.ll +deleted file mode 100644 +index 220398ff2..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-seq-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vseqi.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vseqi_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vseqi.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vseqi.b(<16 x i8> %va, i32 -17) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vseqi_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vseqi.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vseqi.b(<16 x i8> %va, i32 16) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vseqi.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vseqi_h_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vseqi.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vseqi.h(<8 x i16> %va, i32 -17) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vseqi_h_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vseqi.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vseqi.h(<8 x i16> %va, i32 16) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vseqi.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vseqi_w_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vseqi.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vseqi.w(<4 x i32> %va, i32 -17) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vseqi_w_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vseqi.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vseqi.w(<4 x i32> %va, i32 16) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vseqi.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vseqi_d_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vseqi.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vseqi.d(<2 x i64> %va, i32 -17) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vseqi_d_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vseqi.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vseqi.d(<2 x i64> %va, i32 16) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-seq-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-seq-non-imm.ll +deleted file mode 100644 +index 5fa1dd304..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-seq-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vseqi.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vseqi_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vseqi.b(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vseqi.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vseqi_h(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vseqi.h(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vseqi.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vseqi_w(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vseqi.w(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vseqi.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vseqi_d(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vseqi.d(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-seq.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-seq.ll +deleted file mode 100644 +index 3cb4acd82..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-seq.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vseq.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vseq_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vseq_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vseq.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vseq.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vseq.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vseq_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vseq_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vseq.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vseq.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vseq.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vseq_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vseq_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vseq.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vseq.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vseq.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vseq_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vseq_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vseq.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vseq.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vseqi.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vseqi_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vseqi_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vseqi.b $vr0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vseqi.b(<16 x i8> %va, i32 15) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vseqi.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vseqi_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vseqi_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vseqi.h $vr0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vseqi.h(<8 x i16> %va, i32 15) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vseqi.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vseqi_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vseqi_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vseqi.w $vr0, $vr0, -16 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vseqi.w(<4 x i32> %va, i32 -16) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vseqi.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vseqi_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vseqi_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vseqi.d $vr0, $vr0, -16 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vseqi.d(<2 x i64> %va, i32 -16) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-set.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-set.ll +deleted file mode 100644 +index 3188fb4e2..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-set.ll ++++ /dev/null +@@ -1,38 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare i32 @llvm.loongarch.lsx.bz.v(<16 x i8>) +- +-define i32 @lsx_bz_v(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_bz_v: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vseteqz.v $fcc0, $vr0 +-; CHECK-NEXT: bcnez $fcc0, .LBB0_2 +-; CHECK-NEXT: # %bb.1: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 0 +-; CHECK-NEXT: ret +-; CHECK-NEXT: .LBB0_2: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lsx.bz.v(<16 x i8> %va) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lsx.bnz.v(<16 x i8>) +- +-define i32 @lsx_bnz_v(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_bnz_v: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsetnez.v $fcc0, $vr0 +-; CHECK-NEXT: bcnez $fcc0, .LBB1_2 +-; CHECK-NEXT: # %bb.1: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 0 +-; CHECK-NEXT: ret +-; CHECK-NEXT: .LBB1_2: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lsx.bnz.v(<16 x i8> %va) +- ret i32 %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-setallnez.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-setallnez.ll +deleted file mode 100644 +index 22e01922e..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-setallnez.ll ++++ /dev/null +@@ -1,74 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare i32 @llvm.loongarch.lsx.bnz.b(<16 x i8>) +- +-define i32 @lsx_bnz_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_bnz_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsetallnez.b $fcc0, $vr0 +-; CHECK-NEXT: bcnez $fcc0, .LBB0_2 +-; CHECK-NEXT: # %bb.1: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 0 +-; CHECK-NEXT: ret +-; CHECK-NEXT: .LBB0_2: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lsx.bnz.b(<16 x i8> %va) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lsx.bnz.h(<8 x i16>) +- +-define i32 @lsx_bnz_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_bnz_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsetallnez.h $fcc0, $vr0 +-; CHECK-NEXT: bcnez $fcc0, .LBB1_2 +-; CHECK-NEXT: # %bb.1: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 0 +-; CHECK-NEXT: ret +-; CHECK-NEXT: .LBB1_2: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lsx.bnz.h(<8 x i16> %va) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lsx.bnz.w(<4 x i32>) +- +-define i32 @lsx_bnz_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_bnz_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsetallnez.w $fcc0, $vr0 +-; CHECK-NEXT: bcnez $fcc0, .LBB2_2 +-; CHECK-NEXT: # %bb.1: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 0 +-; CHECK-NEXT: ret +-; CHECK-NEXT: .LBB2_2: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lsx.bnz.w(<4 x i32> %va) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lsx.bnz.d(<2 x i64>) +- +-define i32 @lsx_bnz_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_bnz_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsetallnez.d $fcc0, $vr0 +-; CHECK-NEXT: bcnez $fcc0, .LBB3_2 +-; CHECK-NEXT: # %bb.1: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 0 +-; CHECK-NEXT: ret +-; CHECK-NEXT: .LBB3_2: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lsx.bnz.d(<2 x i64> %va) +- ret i32 %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-setanyeqz.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-setanyeqz.ll +deleted file mode 100644 +index 96c79c10e..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-setanyeqz.ll ++++ /dev/null +@@ -1,74 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare i32 @llvm.loongarch.lsx.bz.b(<16 x i8>) +- +-define i32 @lsx_bz_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_bz_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsetanyeqz.b $fcc0, $vr0 +-; CHECK-NEXT: bcnez $fcc0, .LBB0_2 +-; CHECK-NEXT: # %bb.1: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 0 +-; CHECK-NEXT: ret +-; CHECK-NEXT: .LBB0_2: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lsx.bz.b(<16 x i8> %va) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lsx.bz.h(<8 x i16>) +- +-define i32 @lsx_bz_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_bz_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsetanyeqz.h $fcc0, $vr0 +-; CHECK-NEXT: bcnez $fcc0, .LBB1_2 +-; CHECK-NEXT: # %bb.1: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 0 +-; CHECK-NEXT: ret +-; CHECK-NEXT: .LBB1_2: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lsx.bz.h(<8 x i16> %va) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lsx.bz.w(<4 x i32>) +- +-define i32 @lsx_bz_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_bz_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsetanyeqz.w $fcc0, $vr0 +-; CHECK-NEXT: bcnez $fcc0, .LBB2_2 +-; CHECK-NEXT: # %bb.1: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 0 +-; CHECK-NEXT: ret +-; CHECK-NEXT: .LBB2_2: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lsx.bz.w(<4 x i32> %va) +- ret i32 %res +-} +- +-declare i32 @llvm.loongarch.lsx.bz.d(<2 x i64>) +- +-define i32 @lsx_bz_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_bz_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsetanyeqz.d $fcc0, $vr0 +-; CHECK-NEXT: bcnez $fcc0, .LBB3_2 +-; CHECK-NEXT: # %bb.1: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 0 +-; CHECK-NEXT: ret +-; CHECK-NEXT: .LBB3_2: # %entry +-; CHECK-NEXT: addi.w $a0, $zero, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call i32 @llvm.loongarch.lsx.bz.d(<2 x i64> %va) +- ret i32 %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-shuf.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-shuf.ll +deleted file mode 100644 +index f5d516521..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-shuf.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vshuf.b(<16 x i8>, <16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vshuf_b(<16 x i8> %va, <16 x i8> %vb, <16 x i8> %vc) nounwind { +-; CHECK-LABEL: lsx_vshuf_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vshuf.b $vr0, $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vshuf.b(<16 x i8> %va, <16 x i8> %vb, <16 x i8> %vc) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vshuf.h(<8 x i16>, <8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vshuf_h(<8 x i16> %va, <8 x i16> %vb, <8 x i16> %vc) nounwind { +-; CHECK-LABEL: lsx_vshuf_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vshuf.h $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vshuf.h(<8 x i16> %va, <8 x i16> %vb, <8 x i16> %vc) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vshuf.w(<4 x i32>, <4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vshuf_w(<4 x i32> %va, <4 x i32> %vb, <4 x i32> %vc) nounwind { +-; CHECK-LABEL: lsx_vshuf_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vshuf.w $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vshuf.w(<4 x i32> %va, <4 x i32> %vb, <4 x i32> %vc) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vshuf.d(<2 x i64>, <2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vshuf_d(<2 x i64> %va, <2 x i64> %vb, <2 x i64> %vc) nounwind { +-; CHECK-LABEL: lsx_vshuf_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vshuf.d $vr0, $vr1, $vr2 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vshuf.d(<2 x i64> %va, <2 x i64> %vb, <2 x i64> %vc) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-shuf4i-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-shuf4i-invalid-imm.ll +deleted file mode 100644 +index 4d6fadf08..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-shuf4i-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vshuf4i.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vshuf4i_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vshuf4i.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vshuf4i.b(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vshuf4i_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vshuf4i.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vshuf4i.b(<16 x i8> %va, i32 256) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vshuf4i.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vshuf4i_h_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vshuf4i.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vshuf4i.h(<8 x i16> %va, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vshuf4i_h_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vshuf4i.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vshuf4i.h(<8 x i16> %va, i32 256) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vshuf4i.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vshuf4i_w_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vshuf4i.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vshuf4i.w(<4 x i32> %va, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vshuf4i_w_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vshuf4i.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vshuf4i.w(<4 x i32> %va, i32 256) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vshuf4i.d(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vshuf4i_d_lo(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vshuf4i.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vshuf4i.d(<2 x i64> %va, <2 x i64> %vb, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vshuf4i_d_hi(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vshuf4i.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vshuf4i.d(<2 x i64> %va, <2 x i64> %vb, i32 256) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-shuf4i-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-shuf4i-non-imm.ll +deleted file mode 100644 +index a7d138bcc..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-shuf4i-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vshuf4i.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vshuf4i_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vshuf4i.b(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vshuf4i.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vshuf4i_h(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vshuf4i.h(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vshuf4i.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vshuf4i_w(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vshuf4i.w(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vshuf4i.d(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vshuf4i_d(<2 x i64> %va, <2 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vshuf4i.d(<2 x i64> %va, <2 x i64> %vb, i32 %c) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-shuf4i.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-shuf4i.ll +deleted file mode 100644 +index 1ad5f2af5..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-shuf4i.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vshuf4i.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vshuf4i_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vshuf4i_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vshuf4i.b $vr0, $vr0, 255 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vshuf4i.b(<16 x i8> %va, i32 255) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vshuf4i.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vshuf4i_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vshuf4i_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vshuf4i.h $vr0, $vr0, 255 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vshuf4i.h(<8 x i16> %va, i32 255) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vshuf4i.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vshuf4i_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vshuf4i_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vshuf4i.w $vr0, $vr0, 255 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vshuf4i.w(<4 x i32> %va, i32 255) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vshuf4i.d(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vshuf4i_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vshuf4i_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vshuf4i.d $vr0, $vr1, 255 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vshuf4i.d(<2 x i64> %va, <2 x i64> %vb, i32 255) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-signcov.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-signcov.ll +deleted file mode 100644 +index 3997b0cc9..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-signcov.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsigncov.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vsigncov_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vsigncov_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsigncov.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsigncov.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsigncov.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vsigncov_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsigncov_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsigncov.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsigncov.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsigncov.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vsigncov_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsigncov_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsigncov.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsigncov.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsigncov.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vsigncov_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsigncov_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsigncov.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsigncov.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sle-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sle-invalid-imm.ll +deleted file mode 100644 +index 4c945e296..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sle-invalid-imm.ll ++++ /dev/null +@@ -1,129 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vslei.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vslei_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslei.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vslei.b(<16 x i8> %va, i32 -17) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vslei_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslei.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vslei.b(<16 x i8> %va, i32 16) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vslei.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vslei_h_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslei.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vslei.h(<8 x i16> %va, i32 -17) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vslei_h_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslei.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vslei.h(<8 x i16> %va, i32 16) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vslei.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vslei_w_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslei.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vslei.w(<4 x i32> %va, i32 -17) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vslei_w_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslei.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vslei.w(<4 x i32> %va, i32 16) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vslei.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vslei_d_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslei.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vslei.d(<2 x i64> %va, i32 -17) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vslei_d_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslei.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vslei.d(<2 x i64> %va, i32 16) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vslei.bu(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vslei_bu_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslei.bu: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vslei.bu(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vslei_bu_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslei.bu: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vslei.bu(<16 x i8> %va, i32 32) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vslei.hu(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vslei_hu_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslei.hu: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vslei.hu(<8 x i16> %va, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vslei_hu_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslei.hu: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vslei.hu(<8 x i16> %va, i32 32) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vslei.wu(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vslei_wu_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslei.wu: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vslei.wu(<4 x i32> %va, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vslei_wu_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslei.wu: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vslei.wu(<4 x i32> %va, i32 32) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vslei.du(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vslei_du_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslei.du: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vslei.du(<2 x i64> %va, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vslei_du_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslei.du: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vslei.du(<2 x i64> %va, i32 32) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sle-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sle-non-imm.ll +deleted file mode 100644 +index 0fc137bf0..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sle-non-imm.ll ++++ /dev/null +@@ -1,73 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vslei.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vslei_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vslei.b(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vslei.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vslei_h(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vslei.h(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vslei.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vslei_w(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vslei.w(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vslei.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vslei_d(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vslei.d(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vslei.bu(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vslei_bu(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vslei.bu(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vslei.hu(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vslei_hu(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vslei.hu(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vslei.wu(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vslei_wu(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vslei.wu(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vslei.du(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vslei_du(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vslei.du(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sle.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sle.ll +deleted file mode 100644 +index 5a9d5f06e..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sle.ll ++++ /dev/null +@@ -1,194 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsle.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vsle_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vsle_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsle.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsle.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsle.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vsle_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsle_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsle.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsle.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsle.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vsle_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsle_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsle.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsle.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsle.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vsle_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsle_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsle.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsle.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vslei.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vslei_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vslei_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslei.b $vr0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vslei.b(<16 x i8> %va, i32 15) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vslei.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vslei_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vslei_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslei.h $vr0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vslei.h(<8 x i16> %va, i32 15) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vslei.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vslei_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vslei_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslei.w $vr0, $vr0, -16 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vslei.w(<4 x i32> %va, i32 -16) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vslei.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vslei_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vslei_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslei.d $vr0, $vr0, -16 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vslei.d(<2 x i64> %va, i32 -16) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vsle.bu(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vsle_bu(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vsle_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsle.bu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsle.bu(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsle.hu(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vsle_hu(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsle_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsle.hu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsle.hu(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsle.wu(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vsle_wu(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsle_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsle.wu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsle.wu(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsle.du(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vsle_du(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsle_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsle.du $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsle.du(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vslei.bu(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vslei_bu(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vslei_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslei.bu $vr0, $vr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vslei.bu(<16 x i8> %va, i32 1) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vslei.hu(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vslei_hu(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vslei_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslei.hu $vr0, $vr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vslei.hu(<8 x i16> %va, i32 1) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vslei.wu(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vslei_wu(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vslei_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslei.wu $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vslei.wu(<4 x i32> %va, i32 31) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vslei.du(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vslei_du(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vslei_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslei.du $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vslei.du(<2 x i64> %va, i32 31) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sll-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sll-invalid-imm.ll +deleted file mode 100644 +index 75406f948..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sll-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vslli.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vslli_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslli.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vslli.b(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vslli_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslli.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vslli.b(<16 x i8> %va, i32 8) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vslli.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vslli_h_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslli.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vslli.h(<8 x i16> %va, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vslli_h_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslli.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vslli.h(<8 x i16> %va, i32 16) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vslli.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vslli_w_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslli.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vslli.w(<4 x i32> %va, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vslli_w_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslli.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vslli.w(<4 x i32> %va, i32 32) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vslli.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vslli_d_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslli.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vslli.d(<2 x i64> %va, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vslli_d_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslli.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vslli.d(<2 x i64> %va, i32 64) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sll-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sll-non-imm.ll +deleted file mode 100644 +index 7474b5e29..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sll-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vslli.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vslli_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vslli.b(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vslli.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vslli_h(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vslli.h(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vslli.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vslli_w(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vslli.w(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vslli.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vslli_d(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vslli.d(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sll.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sll.ll +deleted file mode 100644 +index 7bc20af41..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sll.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsll.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vsll_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vsll_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsll.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsll.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsll.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vsll_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsll_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsll.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsll.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsll.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vsll_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsll_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsll.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsll.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsll.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vsll_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsll_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsll.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsll.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vslli.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vslli_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vslli_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslli.b $vr0, $vr0, 7 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vslli.b(<16 x i8> %va, i32 7) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vslli.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vslli_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vslli_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslli.h $vr0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vslli.h(<8 x i16> %va, i32 15) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vslli.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vslli_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vslli_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslli.w $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vslli.w(<4 x i32> %va, i32 31) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vslli.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vslli_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vslli_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslli.d $vr0, $vr0, 63 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vslli.d(<2 x i64> %va, i32 63) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sllwil-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sllwil-invalid-imm.ll +deleted file mode 100644 +index bda3523a0..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sllwil-invalid-imm.ll ++++ /dev/null +@@ -1,97 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <8 x i16> @llvm.loongarch.lsx.vsllwil.h.b(<16 x i8>, i32) +- +-define <8 x i16> @lsx_vsllwil_h_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsllwil.h.b: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsllwil.h.b(<16 x i8> %va, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vsllwil_h_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsllwil.h.b: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsllwil.h.b(<16 x i8> %va, i32 8) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsllwil.w.h(<8 x i16>, i32) +- +-define <4 x i32> @lsx_vsllwil_w_h_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsllwil.w.h: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsllwil.w.h(<8 x i16> %va, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vsllwil_w_h_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsllwil.w.h: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsllwil.w.h(<8 x i16> %va, i32 16) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsllwil.d.w(<4 x i32>, i32) +- +-define <2 x i64> @lsx_vsllwil_d_w_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsllwil.d.w: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsllwil.d.w(<4 x i32> %va, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vsllwil_d_w_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsllwil.d.w: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsllwil.d.w(<4 x i32> %va, i32 32) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsllwil.hu.bu(<16 x i8>, i32) +- +-define <8 x i16> @lsx_vsllwil_hu_bu_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsllwil.hu.bu: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsllwil.hu.bu(<16 x i8> %va, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vsllwil_hu_bu_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsllwil.hu.bu: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsllwil.hu.bu(<16 x i8> %va, i32 8) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsllwil.wu.hu(<8 x i16>, i32) +- +-define <4 x i32> @lsx_vsllwil_wu_hu_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsllwil.wu.hu: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsllwil.wu.hu(<8 x i16> %va, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vsllwil_wu_hu_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsllwil.wu.hu: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsllwil.wu.hu(<8 x i16> %va, i32 16) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsllwil.du.wu(<4 x i32>, i32) +- +-define <2 x i64> @lsx_vsllwil_du_wu_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsllwil.du.wu: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsllwil.du.wu(<4 x i32> %va, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vsllwil_du_wu_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsllwil.du.wu: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsllwil.du.wu(<4 x i32> %va, i32 32) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sllwil-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sllwil-non-imm.ll +deleted file mode 100644 +index a03656d5c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sllwil-non-imm.ll ++++ /dev/null +@@ -1,55 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <8 x i16> @llvm.loongarch.lsx.vsllwil.h.b(<16 x i8>, i32) +- +-define <8 x i16> @lsx_vsllwil_h_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsllwil.h.b(<16 x i8> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsllwil.w.h(<8 x i16>, i32) +- +-define <4 x i32> @lsx_vsllwil_w_h(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsllwil.w.h(<8 x i16> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsllwil.d.w(<4 x i32>, i32) +- +-define <2 x i64> @lsx_vsllwil_d_w(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsllwil.d.w(<4 x i32> %va, i32 %b) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsllwil.hu.bu(<16 x i8>, i32) +- +-define <8 x i16> @lsx_vsllwil_hu_bu(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsllwil.hu.bu(<16 x i8> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsllwil.wu.hu(<8 x i16>, i32) +- +-define <4 x i32> @lsx_vsllwil_wu_hu(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsllwil.wu.hu(<8 x i16> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsllwil.du.wu(<4 x i32>, i32) +- +-define <2 x i64> @lsx_vsllwil_du_wu(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsllwil.du.wu(<4 x i32> %va, i32 %b) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sllwil.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sllwil.ll +deleted file mode 100644 +index 29ab70da1..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sllwil.ll ++++ /dev/null +@@ -1,74 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <8 x i16> @llvm.loongarch.lsx.vsllwil.h.b(<16 x i8>, i32) +- +-define <8 x i16> @lsx_vsllwil_h_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vsllwil_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsllwil.h.b $vr0, $vr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsllwil.h.b(<16 x i8> %va, i32 1) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsllwil.w.h(<8 x i16>, i32) +- +-define <4 x i32> @lsx_vsllwil_w_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vsllwil_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsllwil.w.h $vr0, $vr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsllwil.w.h(<8 x i16> %va, i32 1) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsllwil.d.w(<4 x i32>, i32) +- +-define <2 x i64> @lsx_vsllwil_d_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vsllwil_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsllwil.d.w $vr0, $vr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsllwil.d.w(<4 x i32> %va, i32 1) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsllwil.hu.bu(<16 x i8>, i32) +- +-define <8 x i16> @lsx_vsllwil_hu_bu(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vsllwil_hu_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsllwil.hu.bu $vr0, $vr0, 7 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsllwil.hu.bu(<16 x i8> %va, i32 7) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsllwil.wu.hu(<8 x i16>, i32) +- +-define <4 x i32> @lsx_vsllwil_wu_hu(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vsllwil_wu_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsllwil.wu.hu $vr0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsllwil.wu.hu(<8 x i16> %va, i32 15) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsllwil.du.wu(<4 x i32>, i32) +- +-define <2 x i64> @lsx_vsllwil_du_wu(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vsllwil_du_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsllwil.du.wu $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsllwil.du.wu(<4 x i32> %va, i32 31) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-slt-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-slt-invalid-imm.ll +deleted file mode 100644 +index f6d014b19..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-slt-invalid-imm.ll ++++ /dev/null +@@ -1,129 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vslti.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vslti_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslti.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vslti.b(<16 x i8> %va, i32 -17) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vslti_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslti.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vslti.b(<16 x i8> %va, i32 16) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vslti.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vslti_h_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslti.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vslti.h(<8 x i16> %va, i32 -17) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vslti_h_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslti.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vslti.h(<8 x i16> %va, i32 16) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vslti.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vslti_w_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslti.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vslti.w(<4 x i32> %va, i32 -17) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vslti_w_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslti.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vslti.w(<4 x i32> %va, i32 16) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vslti.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vslti_d_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslti.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vslti.d(<2 x i64> %va, i32 -17) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vslti_d_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslti.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vslti.d(<2 x i64> %va, i32 16) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vslti.bu(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vslti_bu_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslti.bu: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vslti.bu(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vslti_bu_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslti.bu: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vslti.bu(<16 x i8> %va, i32 32) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vslti.hu(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vslti_hu_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslti.hu: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vslti.hu(<8 x i16> %va, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vslti_hu_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslti.hu: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vslti.hu(<8 x i16> %va, i32 32) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vslti.wu(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vslti_wu_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslti.wu: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vslti.wu(<4 x i32> %va, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vslti_wu_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslti.wu: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vslti.wu(<4 x i32> %va, i32 32) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vslti.du(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vslti_du_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslti.du: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vslti.du(<2 x i64> %va, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vslti_du_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vslti.du: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vslti.du(<2 x i64> %va, i32 32) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-slt-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-slt-non-imm.ll +deleted file mode 100644 +index 9a8b757da..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-slt-non-imm.ll ++++ /dev/null +@@ -1,73 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vslti.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vslti_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vslti.b(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vslti.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vslti_h(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vslti.h(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vslti.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vslti_w(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vslti.w(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vslti.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vslti_d(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vslti.d(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vslti.bu(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vslti_bu(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vslti.bu(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vslti.hu(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vslti_hu(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vslti.hu(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vslti.wu(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vslti_wu(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vslti.wu(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vslti.du(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vslti_du(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vslti.du(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-slt.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-slt.ll +deleted file mode 100644 +index 18683e9dc..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-slt.ll ++++ /dev/null +@@ -1,194 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vslt.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vslt_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vslt_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslt.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vslt.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vslt.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vslt_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vslt_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslt.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vslt.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vslt.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vslt_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vslt_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslt.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vslt.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vslt.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vslt_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vslt_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslt.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vslt.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vslti.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vslti_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vslti_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslti.b $vr0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vslti.b(<16 x i8> %va, i32 15) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vslti.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vslti_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vslti_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslti.h $vr0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vslti.h(<8 x i16> %va, i32 15) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vslti.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vslti_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vslti_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslti.w $vr0, $vr0, -16 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vslti.w(<4 x i32> %va, i32 -16) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vslti.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vslti_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vslti_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslti.d $vr0, $vr0, -16 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vslti.d(<2 x i64> %va, i32 -16) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vslt.bu(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vslt_bu(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vslt_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslt.bu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vslt.bu(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vslt.hu(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vslt_hu(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vslt_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslt.hu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vslt.hu(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vslt.wu(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vslt_wu(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vslt_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslt.wu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vslt.wu(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vslt.du(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vslt_du(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vslt_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslt.du $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vslt.du(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vslti.bu(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vslti_bu(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vslti_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslti.bu $vr0, $vr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vslti.bu(<16 x i8> %va, i32 1) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vslti.hu(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vslti_hu(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vslti_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslti.hu $vr0, $vr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vslti.hu(<8 x i16> %va, i32 1) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vslti.wu(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vslti_wu(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vslti_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslti.wu $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vslti.wu(<4 x i32> %va, i32 31) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vslti.du(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vslti_du(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vslti_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vslti.du $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vslti.du(<2 x i64> %va, i32 31) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sra-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sra-invalid-imm.ll +deleted file mode 100644 +index 2a033a21b..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sra-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrai.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrai_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrai.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrai.b(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vsrai_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrai.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrai.b(<16 x i8> %va, i32 8) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrai.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrai_h_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrai.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrai.h(<8 x i16> %va, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vsrai_h_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrai.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrai.h(<8 x i16> %va, i32 16) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrai.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrai_w_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrai.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrai.w(<4 x i32> %va, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vsrai_w_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrai.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrai.w(<4 x i32> %va, i32 32) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrai.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrai_d_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrai.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrai.d(<2 x i64> %va, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vsrai_d_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrai.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrai.d(<2 x i64> %va, i32 64) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sra-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sra-non-imm.ll +deleted file mode 100644 +index c3b328145..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sra-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrai.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrai_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrai.b(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrai.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrai_h(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrai.h(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrai.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrai_w(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrai.w(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrai.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrai_d(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrai.d(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sra.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sra.ll +deleted file mode 100644 +index e85c8464c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sra.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsra.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vsra_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vsra_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsra.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsra.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsra.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vsra_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsra_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsra.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsra.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsra.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vsra_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsra_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsra.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsra.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsra.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vsra_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsra_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsra.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsra.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrai.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrai_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vsrai_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrai.b $vr0, $vr0, 7 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrai.b(<16 x i8> %va, i32 7) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrai.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrai_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vsrai_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrai.h $vr0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrai.h(<8 x i16> %va, i32 15) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrai.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrai_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vsrai_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrai.w $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrai.w(<4 x i32> %va, i32 31) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrai.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrai_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vsrai_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrai.d $vr0, $vr0, 63 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrai.d(<2 x i64> %va, i32 63) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sran.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sran.ll +deleted file mode 100644 +index 4ffe5a704..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sran.ll ++++ /dev/null +@@ -1,38 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsran.b.h(<8 x i16>, <8 x i16>) +- +-define <16 x i8> @lsx_vsran_b_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsran_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsran.b.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsran.b.h(<8 x i16> %va, <8 x i16> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsran.h.w(<4 x i32>, <4 x i32>) +- +-define <8 x i16> @lsx_vsran_h_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsran_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsran.h.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsran.h.w(<4 x i32> %va, <4 x i32> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsran.w.d(<2 x i64>, <2 x i64>) +- +-define <4 x i32> @lsx_vsran_w_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsran_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsran.w.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsran.w.d(<2 x i64> %va, <2 x i64> %vb) +- ret <4 x i32> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srani-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srani-invalid-imm.ll +deleted file mode 100644 +index d68064e9b..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srani-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrani.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrani_b_h_lo(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrani.b.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrani.b.h(<16 x i8> %va, <16 x i8> %vb, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vsrani_b_h_hi(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrani.b.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrani.b.h(<16 x i8> %va, <16 x i8> %vb, i32 16) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrani.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrani_h_w_lo(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrani.h.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrani.h.w(<8 x i16> %va, <8 x i16> %vb, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vsrani_h_w_hi(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrani.h.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrani.h.w(<8 x i16> %va, <8 x i16> %vb, i32 32) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrani.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrani_w_d_lo(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrani.w.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrani.w.d(<4 x i32> %va, <4 x i32> %vb, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vsrani_w_d_hi(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrani.w.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrani.w.d(<4 x i32> %va, <4 x i32> %vb, i32 64) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrani.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrani_d_q_lo(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrani.d.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrani.d.q(<2 x i64> %va, <2 x i64> %vb, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vsrani_d_q_hi(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrani.d.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrani.d.q(<2 x i64> %va, <2 x i64> %vb, i32 128) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srani-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srani-non-imm.ll +deleted file mode 100644 +index 38cfde214..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srani-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrani.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrani_b_h(<16 x i8> %va, <16 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrani.b.h(<16 x i8> %va, <16 x i8> %vb, i32 %c) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrani.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrani_h_w(<8 x i16> %va, <8 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrani.h.w(<8 x i16> %va, <8 x i16> %vb, i32 %c) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrani.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrani_w_d(<4 x i32> %va, <4 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrani.w.d(<4 x i32> %va, <4 x i32> %vb, i32 %c) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrani.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrani_d_q(<2 x i64> %va, <2 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrani.d.q(<2 x i64> %va, <2 x i64> %vb, i32 %c) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srani.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srani.ll +deleted file mode 100644 +index 717c64161..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srani.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrani.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrani_b_h(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrani_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrani.b.h $vr0, $vr1, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrani.b.h(<16 x i8> %va, <16 x i8> %vb, i32 15) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrani.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrani_h_w(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrani_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrani.h.w $vr0, $vr1, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrani.h.w(<8 x i16> %va, <8 x i16> %vb, i32 31) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrani.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrani_w_d(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrani_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrani.w.d $vr0, $vr1, 63 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrani.w.d(<4 x i32> %va, <4 x i32> %vb, i32 63) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrani.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrani_d_q(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrani_d_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrani.d.q $vr0, $vr1, 127 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrani.d.q(<2 x i64> %va, <2 x i64> %vb, i32 127) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srar-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srar-invalid-imm.ll +deleted file mode 100644 +index b6c2d70ce..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srar-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrari.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrari_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrari.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrari.b(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vsrari_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrari.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrari.b(<16 x i8> %va, i32 8) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrari.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrari_h_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrari.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrari.h(<8 x i16> %va, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vsrari_h_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrari.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrari.h(<8 x i16> %va, i32 16) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrari.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrari_w_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrari.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrari.w(<4 x i32> %va, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vsrari_w_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrari.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrari.w(<4 x i32> %va, i32 32) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrari.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrari_d_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrari.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrari.d(<2 x i64> %va, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vsrari_d_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrari.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrari.d(<2 x i64> %va, i32 64) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srar-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srar-non-imm.ll +deleted file mode 100644 +index 2ad8adcd8..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srar-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrari.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrari_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrari.b(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrari.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrari_h(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrari.h(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrari.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrari_w(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrari.w(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrari.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrari_d(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrari.d(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srar.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srar.ll +deleted file mode 100644 +index 8b52b7ac9..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srar.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrar.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vsrar_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrar_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrar.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrar.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrar.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vsrar_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrar_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrar.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrar.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrar.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vsrar_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrar_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrar.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrar.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrar.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vsrar_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrar_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrar.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrar.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrari.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrari_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vsrari_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrari.b $vr0, $vr0, 7 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrari.b(<16 x i8> %va, i32 7) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrari.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrari_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vsrari_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrari.h $vr0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrari.h(<8 x i16> %va, i32 15) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrari.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrari_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vsrari_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrari.w $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrari.w(<4 x i32> %va, i32 31) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrari.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrari_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vsrari_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrari.d $vr0, $vr0, 63 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrari.d(<2 x i64> %va, i32 63) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srarn.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srarn.ll +deleted file mode 100644 +index d4cdfb535..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srarn.ll ++++ /dev/null +@@ -1,38 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrarn.b.h(<8 x i16>, <8 x i16>) +- +-define <16 x i8> @lsx_vsrarn_b_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrarn_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrarn.b.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrarn.b.h(<8 x i16> %va, <8 x i16> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrarn.h.w(<4 x i32>, <4 x i32>) +- +-define <8 x i16> @lsx_vsrarn_h_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrarn_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrarn.h.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrarn.h.w(<4 x i32> %va, <4 x i32> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrarn.w.d(<2 x i64>, <2 x i64>) +- +-define <4 x i32> @lsx_vsrarn_w_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrarn_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrarn.w.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrarn.w.d(<2 x i64> %va, <2 x i64> %vb) +- ret <4 x i32> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srarni-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srarni-invalid-imm.ll +deleted file mode 100644 +index d24cf92a0..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srarni-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrarni.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrarni_b_h_lo(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrarni.b.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrarni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vsrarni_b_h_hi(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrarni.b.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrarni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 16) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrarni.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrarni_h_w_lo(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrarni.h.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrarni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vsrarni_h_w_hi(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrarni.h.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrarni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 32) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrarni.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrarni_w_d_lo(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrarni.w.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrarni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vsrarni_w_d_hi(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrarni.w.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrarni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 64) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrarni.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrarni_d_q_lo(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrarni.d.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrarni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vsrarni_d_q_hi(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrarni.d.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrarni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 128) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srarni-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srarni-non-imm.ll +deleted file mode 100644 +index 19de7445c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srarni-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrarni.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrarni_b_h(<16 x i8> %va, <16 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrarni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 %c) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrarni.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrarni_h_w(<8 x i16> %va, <8 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrarni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 %c) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrarni.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrarni_w_d(<4 x i32> %va, <4 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrarni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 %c) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrarni.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrarni_d_q(<2 x i64> %va, <2 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrarni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 %c) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srarni.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srarni.ll +deleted file mode 100644 +index 2253e8837..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srarni.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrarni.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrarni_b_h(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrarni_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrarni.b.h $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrarni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 1) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrarni.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrarni_h_w(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrarni_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrarni.h.w $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrarni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 1) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrarni.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrarni_w_d(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrarni_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrarni.w.d $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrarni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 1) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrarni.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrarni_d_q(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrarni_d_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrarni.d.q $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrarni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 1) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srl-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srl-invalid-imm.ll +deleted file mode 100644 +index 3beff790a..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srl-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrli.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrli_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrli.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrli.b(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vsrli_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrli.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrli.b(<16 x i8> %va, i32 8) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrli.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrli_h_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrli.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrli.h(<8 x i16> %va, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vsrli_h_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrli.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrli.h(<8 x i16> %va, i32 16) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrli.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrli_w_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrli.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrli.w(<4 x i32> %va, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vsrli_w_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrli.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrli.w(<4 x i32> %va, i32 32) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrli.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrli_d_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrli.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrli.d(<2 x i64> %va, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vsrli_d_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrli.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrli.d(<2 x i64> %va, i32 64) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srl-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srl-non-imm.ll +deleted file mode 100644 +index 98652aca0..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srl-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrli.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrli_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrli.b(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrli.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrli_h(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrli.h(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrli.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrli_w(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrli.w(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrli.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrli_d(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrli.d(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srl.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srl.ll +deleted file mode 100644 +index 1cddd9622..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srl.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrl.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vsrl_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrl_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrl.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrl.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrl.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vsrl_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrl_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrl.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrl.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrl.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vsrl_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrl_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrl.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrl.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrl.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vsrl_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrl_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrl.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrl.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrli.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrli_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vsrli_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrli.b $vr0, $vr0, 7 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrli.b(<16 x i8> %va, i32 7) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrli.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrli_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vsrli_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrli.h $vr0, $vr0, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrli.h(<8 x i16> %va, i32 15) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrli.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrli_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vsrli_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrli.w $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrli.w(<4 x i32> %va, i32 31) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrli.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrli_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vsrli_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrli.d $vr0, $vr0, 63 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrli.d(<2 x i64> %va, i32 63) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srln.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srln.ll +deleted file mode 100644 +index 1c9b23243..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srln.ll ++++ /dev/null +@@ -1,38 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrln.b.h(<8 x i16>, <8 x i16>) +- +-define <16 x i8> @lsx_vsrln_b_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrln_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrln.b.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrln.b.h(<8 x i16> %va, <8 x i16> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrln.h.w(<4 x i32>, <4 x i32>) +- +-define <8 x i16> @lsx_vsrln_h_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrln_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrln.h.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrln.h.w(<4 x i32> %va, <4 x i32> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrln.w.d(<2 x i64>, <2 x i64>) +- +-define <4 x i32> @lsx_vsrln_w_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrln_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrln.w.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrln.w.d(<2 x i64> %va, <2 x i64> %vb) +- ret <4 x i32> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlni-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlni-invalid-imm.ll +deleted file mode 100644 +index 054c4f393..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlni-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrlni.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrlni_b_h_lo(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlni.b.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrlni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vsrlni_b_h_hi(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlni.b.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrlni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 16) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrlni.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrlni_h_w_lo(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlni.h.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrlni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vsrlni_h_w_hi(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlni.h.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrlni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 32) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrlni.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrlni_w_d_lo(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlni.w.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrlni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vsrlni_w_d_hi(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlni.w.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrlni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 64) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrlni.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrlni_d_q_lo(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlni.d.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrlni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vsrlni_d_q_hi(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlni.d.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrlni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 128) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlni-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlni-non-imm.ll +deleted file mode 100644 +index 76341df19..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlni-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrlni.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrlni_b_h(<16 x i8> %va, <16 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrlni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 %c) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrlni.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrlni_h_w(<8 x i16> %va, <8 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrlni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 %c) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrlni.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrlni_w_d(<4 x i32> %va, <4 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrlni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 %c) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrlni.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrlni_d_q(<2 x i64> %va, <2 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrlni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 %c) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlni.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlni.ll +deleted file mode 100644 +index 6e523efa1..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlni.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrlni.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrlni_b_h(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrlni_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrlni.b.h $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrlni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 1) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrlni.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrlni_h_w(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrlni_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrlni.h.w $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrlni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 1) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrlni.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrlni_w_d(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrlni_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrlni.w.d $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrlni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 1) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrlni.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrlni_d_q(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrlni_d_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrlni.d.q $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrlni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 1) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlr-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlr-invalid-imm.ll +deleted file mode 100644 +index bcbd38e26..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlr-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrlri.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrlri_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlri.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrlri.b(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vsrlri_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlri.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrlri.b(<16 x i8> %va, i32 8) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrlri.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrlri_h_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlri.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrlri.h(<8 x i16> %va, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vsrlri_h_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlri.h: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrlri.h(<8 x i16> %va, i32 16) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrlri.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrlri_w_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlri.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrlri.w(<4 x i32> %va, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vsrlri_w_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlri.w: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrlri.w(<4 x i32> %va, i32 32) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrlri.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrlri_d_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlri.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrlri.d(<2 x i64> %va, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vsrlri_d_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlri.d: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrlri.d(<2 x i64> %va, i32 64) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlr-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlr-non-imm.ll +deleted file mode 100644 +index 4862b1546..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlr-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrlri.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrlri_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrlri.b(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrlri.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrlri_h(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrlri.h(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrlri.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrlri_w(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrlri.w(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrlri.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrlri_d(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrlri.d(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlr.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlr.ll +deleted file mode 100644 +index 51638fa1a..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlr.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrlr.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vsrlr_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrlr_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrlr.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrlr.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrlr.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vsrlr_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrlr_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrlr.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrlr.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrlr.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vsrlr_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrlr_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrlr.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrlr.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrlr.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vsrlr_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrlr_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrlr.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrlr.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrlri.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrlri_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vsrlri_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrlri.b $vr0, $vr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrlri.b(<16 x i8> %va, i32 1) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrlri.h(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrlri_h(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vsrlri_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrlri.h $vr0, $vr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrlri.h(<8 x i16> %va, i32 1) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrlri.w(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrlri_w(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vsrlri_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrlri.w $vr0, $vr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrlri.w(<4 x i32> %va, i32 1) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrlri.d(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrlri_d(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vsrlri_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrlri.d $vr0, $vr0, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrlri.d(<2 x i64> %va, i32 1) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlrn.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlrn.ll +deleted file mode 100644 +index 893e51396..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlrn.ll ++++ /dev/null +@@ -1,38 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrlrn.b.h(<8 x i16>, <8 x i16>) +- +-define <16 x i8> @lsx_vsrlrn_b_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrlrn_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrlrn.b.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrlrn.b.h(<8 x i16> %va, <8 x i16> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrlrn.h.w(<4 x i32>, <4 x i32>) +- +-define <8 x i16> @lsx_vsrlrn_h_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrlrn_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrlrn.h.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrlrn.h.w(<4 x i32> %va, <4 x i32> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrlrn.w.d(<2 x i64>, <2 x i64>) +- +-define <4 x i32> @lsx_vsrlrn_w_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrlrn_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrlrn.w.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrlrn.w.d(<2 x i64> %va, <2 x i64> %vb) +- ret <4 x i32> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlrni-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlrni-invalid-imm.ll +deleted file mode 100644 +index 8988ae88f..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlrni-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrlrni.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrlrni_b_h_lo(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlrni.b.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrlrni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vsrlrni_b_h_hi(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlrni.b.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrlrni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 16) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrlrni.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrlrni_h_w_lo(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlrni.h.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrlrni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vsrlrni_h_w_hi(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlrni.h.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrlrni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 32) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrlrni.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrlrni_w_d_lo(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlrni.w.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrlrni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vsrlrni_w_d_hi(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlrni.w.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrlrni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 64) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrlrni.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrlrni_d_q_lo(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlrni.d.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrlrni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vsrlrni_d_q_hi(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vsrlrni.d.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrlrni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 128) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlrni-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlrni-non-imm.ll +deleted file mode 100644 +index e5530db56..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlrni-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrlrni.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrlrni_b_h(<16 x i8> %va, <16 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrlrni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 %c) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrlrni.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrlrni_h_w(<8 x i16> %va, <8 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrlrni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 %c) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrlrni.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrlrni_w_d(<4 x i32> %va, <4 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrlrni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 %c) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrlrni.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrlrni_d_q(<2 x i64> %va, <2 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrlrni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 %c) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlrni.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlrni.ll +deleted file mode 100644 +index d1ea450d2..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-srlrni.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsrlrni.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vsrlrni_b_h(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrlrni_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrlrni.b.h $vr0, $vr1, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsrlrni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 15) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsrlrni.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vsrlrni_h_w(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrlrni_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrlrni.h.w $vr0, $vr1, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsrlrni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 31) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsrlrni.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vsrlrni_w_d(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrlrni_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrlrni.w.d $vr0, $vr1, 63 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsrlrni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 63) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsrlrni.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vsrlrni_d_q(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsrlrni_d_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsrlrni.d.q $vr0, $vr1, 127 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsrlrni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 127) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssran.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssran.ll +deleted file mode 100644 +index cecccbb73..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssran.ll ++++ /dev/null +@@ -1,74 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vssran.b.h(<8 x i16>, <8 x i16>) +- +-define <16 x i8> @lsx_vssran_b_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vssran_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssran.b.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssran.b.h(<8 x i16> %va, <8 x i16> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssran.h.w(<4 x i32>, <4 x i32>) +- +-define <8 x i16> @lsx_vssran_h_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vssran_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssran.h.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssran.h.w(<4 x i32> %va, <4 x i32> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssran.w.d(<2 x i64>, <2 x i64>) +- +-define <4 x i32> @lsx_vssran_w_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vssran_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssran.w.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssran.w.d(<2 x i64> %va, <2 x i64> %vb) +- ret <4 x i32> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vssran.bu.h(<8 x i16>, <8 x i16>) +- +-define <16 x i8> @lsx_vssran_bu_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vssran_bu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssran.bu.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssran.bu.h(<8 x i16> %va, <8 x i16> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssran.hu.w(<4 x i32>, <4 x i32>) +- +-define <8 x i16> @lsx_vssran_hu_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vssran_hu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssran.hu.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssran.hu.w(<4 x i32> %va, <4 x i32> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssran.wu.d(<2 x i64>, <2 x i64>) +- +-define <4 x i32> @lsx_vssran_wu_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vssran_wu_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssran.wu.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssran.wu.d(<2 x i64> %va, <2 x i64> %vb) +- ret <4 x i32> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrani-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrani-invalid-imm.ll +deleted file mode 100644 +index f7817921e..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrani-invalid-imm.ll ++++ /dev/null +@@ -1,129 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrani.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrani_b_h_lo(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrani.b.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrani.b.h(<16 x i8> %va, <16 x i8> %vb, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vssrani_b_h_hi(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrani.b.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrani.b.h(<16 x i8> %va, <16 x i8> %vb, i32 16) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrani.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrani_h_w_lo(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrani.h.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrani.h.w(<8 x i16> %va, <8 x i16> %vb, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vssrani_h_w_hi(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrani.h.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrani.h.w(<8 x i16> %va, <8 x i16> %vb, i32 32) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrani.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrani_w_d_lo(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrani.w.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrani.w.d(<4 x i32> %va, <4 x i32> %vb, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vssrani_w_d_hi(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrani.w.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrani.w.d(<4 x i32> %va, <4 x i32> %vb, i32 64) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrani.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrani_d_q_lo(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrani.d.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrani.d.q(<2 x i64> %va, <2 x i64> %vb, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vssrani_d_q_hi(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrani.d.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrani.d.q(<2 x i64> %va, <2 x i64> %vb, i32 128) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrani.bu.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrani_bu_h_lo(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrani.bu.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrani.bu.h(<16 x i8> %va, <16 x i8> %vb, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vssrani_bu_h_hi(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrani.bu.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrani.bu.h(<16 x i8> %va, <16 x i8> %vb, i32 16) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrani.hu.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrani_hu_w_lo(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrani.hu.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrani.hu.w(<8 x i16> %va, <8 x i16> %vb, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vssrani_hu_w_hi(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrani.hu.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrani.hu.w(<8 x i16> %va, <8 x i16> %vb, i32 32) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrani.wu.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrani_wu_d_lo(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrani.wu.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrani.wu.d(<4 x i32> %va, <4 x i32> %vb, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vssrani_wu_d_hi(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrani.wu.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrani.wu.d(<4 x i32> %va, <4 x i32> %vb, i32 64) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrani.du.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrani_du_q_lo(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrani.du.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrani.du.q(<2 x i64> %va, <2 x i64> %vb, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vssrani_du_q_hi(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrani.du.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrani.du.q(<2 x i64> %va, <2 x i64> %vb, i32 128) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrani-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrani-non-imm.ll +deleted file mode 100644 +index a80ede9c5..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrani-non-imm.ll ++++ /dev/null +@@ -1,73 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrani.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrani_b_h(<16 x i8> %va, <16 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrani.b.h(<16 x i8> %va, <16 x i8> %vb, i32 %c) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrani.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrani_h_w(<8 x i16> %va, <8 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrani.h.w(<8 x i16> %va, <8 x i16> %vb, i32 %c) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrani.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrani_w_d(<4 x i32> %va, <4 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrani.w.d(<4 x i32> %va, <4 x i32> %vb, i32 %c) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrani.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrani_d_q(<2 x i64> %va, <2 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrani.d.q(<2 x i64> %va, <2 x i64> %vb, i32 %c) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrani.bu.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrani_bu_h(<16 x i8> %va, <16 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrani.bu.h(<16 x i8> %va, <16 x i8> %vb, i32 %c) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrani.hu.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrani_hu_w(<8 x i16> %va, <8 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrani.hu.w(<8 x i16> %va, <8 x i16> %vb, i32 %c) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrani.wu.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrani_wu_d(<4 x i32> %va, <4 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrani.wu.d(<4 x i32> %va, <4 x i32> %vb, i32 %c) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrani.du.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrani_du_q(<2 x i64> %va, <2 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrani.du.q(<2 x i64> %va, <2 x i64> %vb, i32 %c) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrani.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrani.ll +deleted file mode 100644 +index 57b8eb169..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrani.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrani.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrani_b_h(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrani_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrani.b.h $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrani.b.h(<16 x i8> %va, <16 x i8> %vb, i32 1) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrani.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrani_h_w(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrani_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrani.h.w $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrani.h.w(<8 x i16> %va, <8 x i16> %vb, i32 1) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrani.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrani_w_d(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrani_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrani.w.d $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrani.w.d(<4 x i32> %va, <4 x i32> %vb, i32 1) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrani.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrani_d_q(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrani_d_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrani.d.q $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrani.d.q(<2 x i64> %va, <2 x i64> %vb, i32 1) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrani.bu.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrani_bu_h(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrani_bu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrani.bu.h $vr0, $vr1, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrani.bu.h(<16 x i8> %va, <16 x i8> %vb, i32 15) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrani.hu.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrani_hu_w(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrani_hu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrani.hu.w $vr0, $vr1, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrani.hu.w(<8 x i16> %va, <8 x i16> %vb, i32 31) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrani.wu.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrani_wu_d(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrani_wu_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrani.wu.d $vr0, $vr1, 63 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrani.wu.d(<4 x i32> %va, <4 x i32> %vb, i32 63) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrani.du.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrani_du_q(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrani_du_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrani.du.q $vr0, $vr1, 127 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrani.du.q(<2 x i64> %va, <2 x i64> %vb, i32 127) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrarn.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrarn.ll +deleted file mode 100644 +index c6b7d9ec8..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrarn.ll ++++ /dev/null +@@ -1,74 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrarn.b.h(<8 x i16>, <8 x i16>) +- +-define <16 x i8> @lsx_vssrarn_b_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrarn_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrarn.b.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrarn.b.h(<8 x i16> %va, <8 x i16> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrarn.h.w(<4 x i32>, <4 x i32>) +- +-define <8 x i16> @lsx_vssrarn_h_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrarn_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrarn.h.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrarn.h.w(<4 x i32> %va, <4 x i32> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrarn.w.d(<2 x i64>, <2 x i64>) +- +-define <4 x i32> @lsx_vssrarn_w_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrarn_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrarn.w.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrarn.w.d(<2 x i64> %va, <2 x i64> %vb) +- ret <4 x i32> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrarn.bu.h(<8 x i16>, <8 x i16>) +- +-define <16 x i8> @lsx_vssrarn_bu_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrarn_bu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrarn.bu.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrarn.bu.h(<8 x i16> %va, <8 x i16> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrarn.hu.w(<4 x i32>, <4 x i32>) +- +-define <8 x i16> @lsx_vssrarn_hu_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrarn_hu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrarn.hu.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrarn.hu.w(<4 x i32> %va, <4 x i32> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrarn.wu.d(<2 x i64>, <2 x i64>) +- +-define <4 x i32> @lsx_vssrarn_wu_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrarn_wu_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrarn.wu.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrarn.wu.d(<2 x i64> %va, <2 x i64> %vb) +- ret <4 x i32> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrarni-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrarni-invalid-imm.ll +deleted file mode 100644 +index 4edda8c0a..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrarni-invalid-imm.ll ++++ /dev/null +@@ -1,129 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrarni.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrarni_b_h_lo(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrarni.b.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrarni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vssrarni_b_h_hi(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrarni.b.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrarni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 16) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrarni.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrarni_h_w_lo(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrarni.h.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrarni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vssrarni_h_w_hi(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrarni.h.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrarni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 32) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrarni.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrarni_w_d_lo(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrarni.w.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrarni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vssrarni_w_d_hi(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrarni.w.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrarni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 64) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrarni.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrarni_d_q_lo(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrarni.d.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrarni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vssrarni_d_q_hi(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrarni.d.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrarni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 128) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrarni.bu.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrarni_bu_h_lo(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrarni.bu.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrarni.bu.h(<16 x i8> %va, <16 x i8> %vb, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vssrarni_bu_h_hi(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrarni.bu.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrarni.bu.h(<16 x i8> %va, <16 x i8> %vb, i32 16) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrarni.hu.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrarni_hu_w_lo(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrarni.hu.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrarni.hu.w(<8 x i16> %va, <8 x i16> %vb, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vssrarni_hu_w_hi(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrarni.hu.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrarni.hu.w(<8 x i16> %va, <8 x i16> %vb, i32 32) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrarni.wu.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrarni_wu_d_lo(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrarni.wu.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrarni.wu.d(<4 x i32> %va, <4 x i32> %vb, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vssrarni_wu_d_hi(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrarni.wu.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrarni.wu.d(<4 x i32> %va, <4 x i32> %vb, i32 64) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrarni.du.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrarni_du_q_lo(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrarni.du.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrarni.du.q(<2 x i64> %va, <2 x i64> %vb, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vssrarni_du_q_hi(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrarni.du.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrarni.du.q(<2 x i64> %va, <2 x i64> %vb, i32 128) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrarni-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrarni-non-imm.ll +deleted file mode 100644 +index a77e6e764..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrarni-non-imm.ll ++++ /dev/null +@@ -1,73 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrarni.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrarni_b_h(<16 x i8> %va, <16 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrarni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 %c) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrarni.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrarni_h_w(<8 x i16> %va, <8 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrarni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 %c) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrarni.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrarni_w_d(<4 x i32> %va, <4 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrarni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 %c) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrarni.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrarni_d_q(<2 x i64> %va, <2 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrarni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 %c) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrarni.bu.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrarni_bu_h(<16 x i8> %va, <16 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrarni.bu.h(<16 x i8> %va, <16 x i8> %vb, i32 %c) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrarni.hu.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrarni_hu_w(<8 x i16> %va, <8 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrarni.hu.w(<8 x i16> %va, <8 x i16> %vb, i32 %c) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrarni.wu.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrarni_wu_d(<4 x i32> %va, <4 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrarni.wu.d(<4 x i32> %va, <4 x i32> %vb, i32 %c) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrarni.du.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrarni_du_q(<2 x i64> %va, <2 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrarni.du.q(<2 x i64> %va, <2 x i64> %vb, i32 %c) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrarni.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrarni.ll +deleted file mode 100644 +index 1a2e91962..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrarni.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrarni.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrarni_b_h(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrarni_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrarni.b.h $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrarni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 1) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrarni.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrarni_h_w(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrarni_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrarni.h.w $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrarni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 1) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrarni.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrarni_w_d(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrarni_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrarni.w.d $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrarni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 1) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrarni.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrarni_d_q(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrarni_d_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrarni.d.q $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrarni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 1) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrarni.bu.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrarni_bu_h(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrarni_bu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrarni.bu.h $vr0, $vr1, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrarni.bu.h(<16 x i8> %va, <16 x i8> %vb, i32 15) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrarni.hu.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrarni_hu_w(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrarni_hu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrarni.hu.w $vr0, $vr1, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrarni.hu.w(<8 x i16> %va, <8 x i16> %vb, i32 31) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrarni.wu.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrarni_wu_d(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrarni_wu_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrarni.wu.d $vr0, $vr1, 63 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrarni.wu.d(<4 x i32> %va, <4 x i32> %vb, i32 63) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrarni.du.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrarni_du_q(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrarni_du_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrarni.du.q $vr0, $vr1, 127 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrarni.du.q(<2 x i64> %va, <2 x i64> %vb, i32 127) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrln.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrln.ll +deleted file mode 100644 +index 697ccc396..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrln.ll ++++ /dev/null +@@ -1,74 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrln.b.h(<8 x i16>, <8 x i16>) +- +-define <16 x i8> @lsx_vssrln_b_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrln_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrln.b.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrln.b.h(<8 x i16> %va, <8 x i16> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrln.h.w(<4 x i32>, <4 x i32>) +- +-define <8 x i16> @lsx_vssrln_h_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrln_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrln.h.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrln.h.w(<4 x i32> %va, <4 x i32> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrln.w.d(<2 x i64>, <2 x i64>) +- +-define <4 x i32> @lsx_vssrln_w_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrln_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrln.w.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrln.w.d(<2 x i64> %va, <2 x i64> %vb) +- ret <4 x i32> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrln.bu.h(<8 x i16>, <8 x i16>) +- +-define <16 x i8> @lsx_vssrln_bu_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrln_bu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrln.bu.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrln.bu.h(<8 x i16> %va, <8 x i16> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrln.hu.w(<4 x i32>, <4 x i32>) +- +-define <8 x i16> @lsx_vssrln_hu_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrln_hu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrln.hu.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrln.hu.w(<4 x i32> %va, <4 x i32> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrln.wu.d(<2 x i64>, <2 x i64>) +- +-define <4 x i32> @lsx_vssrln_wu_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrln_wu_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrln.wu.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrln.wu.d(<2 x i64> %va, <2 x i64> %vb) +- ret <4 x i32> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrlni-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrlni-invalid-imm.ll +deleted file mode 100644 +index 6218af1fa..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrlni-invalid-imm.ll ++++ /dev/null +@@ -1,129 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrlni.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrlni_b_h_lo(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlni.b.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrlni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vssrlni_b_h_hi(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlni.b.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrlni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 16) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrlni.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrlni_h_w_lo(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlni.h.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrlni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vssrlni_h_w_hi(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlni.h.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrlni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 32) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrlni.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrlni_w_d_lo(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlni.w.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrlni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vssrlni_w_d_hi(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlni.w.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrlni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 64) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrlni.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrlni_d_q_lo(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlni.d.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrlni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vssrlni_d_q_hi(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlni.d.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrlni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 128) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrlni.bu.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrlni_bu_h_lo(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlni.bu.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrlni.bu.h(<16 x i8> %va, <16 x i8> %vb, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vssrlni_bu_h_hi(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlni.bu.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrlni.bu.h(<16 x i8> %va, <16 x i8> %vb, i32 16) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrlni.hu.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrlni_hu_w_lo(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlni.hu.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrlni.hu.w(<8 x i16> %va, <8 x i16> %vb, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vssrlni_hu_w_hi(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlni.hu.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrlni.hu.w(<8 x i16> %va, <8 x i16> %vb, i32 32) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrlni.wu.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrlni_wu_d_lo(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlni.wu.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrlni.wu.d(<4 x i32> %va, <4 x i32> %vb, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vssrlni_wu_d_hi(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlni.wu.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrlni.wu.d(<4 x i32> %va, <4 x i32> %vb, i32 64) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrlni.du.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrlni_du_q_lo(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlni.du.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrlni.du.q(<2 x i64> %va, <2 x i64> %vb, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vssrlni_du_q_hi(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlni.du.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrlni.du.q(<2 x i64> %va, <2 x i64> %vb, i32 128) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrlni-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrlni-non-imm.ll +deleted file mode 100644 +index 688be826f..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrlni-non-imm.ll ++++ /dev/null +@@ -1,73 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrlni.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrlni_b_h(<16 x i8> %va, <16 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrlni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 %c) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrlni.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrlni_h_w(<8 x i16> %va, <8 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrlni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 %c) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrlni.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrlni_w_d(<4 x i32> %va, <4 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrlni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 %c) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrlni.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrlni_d_q(<2 x i64> %va, <2 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrlni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 %c) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrlni.bu.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrlni_bu_h(<16 x i8> %va, <16 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrlni.bu.h(<16 x i8> %va, <16 x i8> %vb, i32 %c) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrlni.hu.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrlni_hu_w(<8 x i16> %va, <8 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrlni.hu.w(<8 x i16> %va, <8 x i16> %vb, i32 %c) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrlni.wu.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrlni_wu_d(<4 x i32> %va, <4 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrlni.wu.d(<4 x i32> %va, <4 x i32> %vb, i32 %c) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrlni.du.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrlni_du_q(<2 x i64> %va, <2 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrlni.du.q(<2 x i64> %va, <2 x i64> %vb, i32 %c) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrlni.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrlni.ll +deleted file mode 100644 +index 8dd41e7ab..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrlni.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrlni.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrlni_b_h(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrlni_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrlni.b.h $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrlni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 1) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrlni.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrlni_h_w(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrlni_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrlni.h.w $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrlni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 1) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrlni.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrlni_w_d(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrlni_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrlni.w.d $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrlni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 1) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrlni.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrlni_d_q(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrlni_d_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrlni.d.q $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrlni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 1) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrlni.bu.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrlni_bu_h(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrlni_bu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrlni.bu.h $vr0, $vr1, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrlni.bu.h(<16 x i8> %va, <16 x i8> %vb, i32 15) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrlni.hu.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrlni_hu_w(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrlni_hu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrlni.hu.w $vr0, $vr1, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrlni.hu.w(<8 x i16> %va, <8 x i16> %vb, i32 31) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrlni.wu.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrlni_wu_d(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrlni_wu_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrlni.wu.d $vr0, $vr1, 63 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrlni.wu.d(<4 x i32> %va, <4 x i32> %vb, i32 63) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrlni.du.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrlni_du_q(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrlni_du_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrlni.du.q $vr0, $vr1, 127 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrlni.du.q(<2 x i64> %va, <2 x i64> %vb, i32 127) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrlrn.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrlrn.ll +deleted file mode 100644 +index a8e76cbaa..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrlrn.ll ++++ /dev/null +@@ -1,74 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrlrn.b.h(<8 x i16>, <8 x i16>) +- +-define <16 x i8> @lsx_vssrlrn_b_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrlrn_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrlrn.b.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrlrn.b.h(<8 x i16> %va, <8 x i16> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrlrn.h.w(<4 x i32>, <4 x i32>) +- +-define <8 x i16> @lsx_vssrlrn_h_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrlrn_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrlrn.h.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrlrn.h.w(<4 x i32> %va, <4 x i32> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrlrn.w.d(<2 x i64>, <2 x i64>) +- +-define <4 x i32> @lsx_vssrlrn_w_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrlrn_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrlrn.w.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrlrn.w.d(<2 x i64> %va, <2 x i64> %vb) +- ret <4 x i32> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrlrn.bu.h(<8 x i16>, <8 x i16>) +- +-define <16 x i8> @lsx_vssrlrn_bu_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrlrn_bu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrlrn.bu.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrlrn.bu.h(<8 x i16> %va, <8 x i16> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrlrn.hu.w(<4 x i32>, <4 x i32>) +- +-define <8 x i16> @lsx_vssrlrn_hu_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrlrn_hu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrlrn.hu.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrlrn.hu.w(<4 x i32> %va, <4 x i32> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrlrn.wu.d(<2 x i64>, <2 x i64>) +- +-define <4 x i32> @lsx_vssrlrn_wu_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrlrn_wu_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrlrn.wu.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrlrn.wu.d(<2 x i64> %va, <2 x i64> %vb) +- ret <4 x i32> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrlrni-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrlrni-invalid-imm.ll +deleted file mode 100644 +index 98a0c5b3c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrlrni-invalid-imm.ll ++++ /dev/null +@@ -1,129 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrlrni.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrlrni_b_h_lo(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlrni.b.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrlrni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vssrlrni_b_h_hi(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlrni.b.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrlrni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 16) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrlrni.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrlrni_h_w_lo(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlrni.h.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrlrni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vssrlrni_h_w_hi(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlrni.h.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrlrni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 32) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrlrni.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrlrni_w_d_lo(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlrni.w.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrlrni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vssrlrni_w_d_hi(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlrni.w.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrlrni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 64) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrlrni.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrlrni_d_q_lo(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlrni.d.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrlrni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vssrlrni_d_q_hi(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlrni.d.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrlrni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 128) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrlrni.bu.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrlrni_bu_h_lo(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlrni.bu.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrlrni.bu.h(<16 x i8> %va, <16 x i8> %vb, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vssrlrni_bu_h_hi(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlrni.bu.h: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrlrni.bu.h(<16 x i8> %va, <16 x i8> %vb, i32 16) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrlrni.hu.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrlrni_hu_w_lo(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlrni.hu.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrlrni.hu.w(<8 x i16> %va, <8 x i16> %vb, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vssrlrni_hu_w_hi(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlrni.hu.w: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrlrni.hu.w(<8 x i16> %va, <8 x i16> %vb, i32 32) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrlrni.wu.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrlrni_wu_d_lo(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlrni.wu.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrlrni.wu.d(<4 x i32> %va, <4 x i32> %vb, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vssrlrni_wu_d_hi(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlrni.wu.d: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrlrni.wu.d(<4 x i32> %va, <4 x i32> %vb, i32 64) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrlrni.du.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrlrni_du_q_lo(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlrni.du.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrlrni.du.q(<2 x i64> %va, <2 x i64> %vb, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vssrlrni_du_q_hi(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK: llvm.loongarch.lsx.vssrlrni.du.q: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrlrni.du.q(<2 x i64> %va, <2 x i64> %vb, i32 128) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrlrni-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrlrni-non-imm.ll +deleted file mode 100644 +index c389b4fd6..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrlrni-non-imm.ll ++++ /dev/null +@@ -1,73 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrlrni.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrlrni_b_h(<16 x i8> %va, <16 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrlrni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 %c) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrlrni.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrlrni_h_w(<8 x i16> %va, <8 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrlrni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 %c) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrlrni.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrlrni_w_d(<4 x i32> %va, <4 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrlrni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 %c) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrlrni.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrlrni_d_q(<2 x i64> %va, <2 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrlrni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 %c) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrlrni.bu.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrlrni_bu_h(<16 x i8> %va, <16 x i8> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrlrni.bu.h(<16 x i8> %va, <16 x i8> %vb, i32 %c) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrlrni.hu.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrlrni_hu_w(<8 x i16> %va, <8 x i16> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrlrni.hu.w(<8 x i16> %va, <8 x i16> %vb, i32 %c) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrlrni.wu.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrlrni_wu_d(<4 x i32> %va, <4 x i32> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrlrni.wu.d(<4 x i32> %va, <4 x i32> %vb, i32 %c) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrlrni.du.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrlrni_du_q(<2 x i64> %va, <2 x i64> %vb, i32 %c) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrlrni.du.q(<2 x i64> %va, <2 x i64> %vb, i32 %c) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrlrni.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrlrni.ll +deleted file mode 100644 +index 869e81b2b..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssrlrni.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrlrni.b.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrlrni_b_h(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrlrni_b_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrlrni.b.h $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrlrni.b.h(<16 x i8> %va, <16 x i8> %vb, i32 1) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrlrni.h.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrlrni_h_w(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrlrni_h_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrlrni.h.w $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrlrni.h.w(<8 x i16> %va, <8 x i16> %vb, i32 1) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrlrni.w.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrlrni_w_d(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrlrni_w_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrlrni.w.d $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrlrni.w.d(<4 x i32> %va, <4 x i32> %vb, i32 1) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrlrni.d.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrlrni_d_q(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrlrni_d_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrlrni.d.q $vr0, $vr1, 1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrlrni.d.q(<2 x i64> %va, <2 x i64> %vb, i32 1) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vssrlrni.bu.h(<16 x i8>, <16 x i8>, i32) +- +-define <16 x i8> @lsx_vssrlrni_bu_h(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrlrni_bu_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrlrni.bu.h $vr0, $vr1, 15 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssrlrni.bu.h(<16 x i8> %va, <16 x i8> %vb, i32 15) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssrlrni.hu.w(<8 x i16>, <8 x i16>, i32) +- +-define <8 x i16> @lsx_vssrlrni_hu_w(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrlrni_hu_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrlrni.hu.w $vr0, $vr1, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssrlrni.hu.w(<8 x i16> %va, <8 x i16> %vb, i32 31) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssrlrni.wu.d(<4 x i32>, <4 x i32>, i32) +- +-define <4 x i32> @lsx_vssrlrni_wu_d(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrlrni_wu_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrlrni.wu.d $vr0, $vr1, 63 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssrlrni.wu.d(<4 x i32> %va, <4 x i32> %vb, i32 63) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssrlrni.du.q(<2 x i64>, <2 x i64>, i32) +- +-define <2 x i64> @lsx_vssrlrni_du_q(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vssrlrni_du_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssrlrni.du.q $vr0, $vr1, 127 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssrlrni.du.q(<2 x i64> %va, <2 x i64> %vb, i32 127) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssub.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssub.ll +deleted file mode 100644 +index c594b426d..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-ssub.ll ++++ /dev/null +@@ -1,98 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vssub.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vssub_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vssub_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssub.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssub.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssub.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vssub_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vssub_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssub.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssub.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssub.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vssub_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vssub_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssub.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssub.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssub.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vssub_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vssub_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssub.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssub.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <16 x i8> @llvm.loongarch.lsx.vssub.bu(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vssub_bu(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vssub_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssub.bu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vssub.bu(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vssub.hu(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vssub_hu(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vssub_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssub.hu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vssub.hu(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vssub.wu(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vssub_wu(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vssub_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssub.wu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vssub.wu(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vssub.du(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vssub_du(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vssub_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vssub.du $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vssub.du(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-st-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-st-invalid-imm.ll +deleted file mode 100644 +index 645183809..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-st-invalid-imm.ll ++++ /dev/null +@@ -1,17 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare void @llvm.loongarch.lsx.vst(<16 x i8>, i8*, i32) +- +-define void @lsx_vst_lo(<16 x i8> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vst: argument out of range +-entry: +- call void @llvm.loongarch.lsx.vst(<16 x i8> %va, i8* %p, i32 -2049) +- ret void +-} +- +-define void @lsx_vst_hi(<16 x i8> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vst: argument out of range +-entry: +- call void @llvm.loongarch.lsx.vst(<16 x i8> %va, i8* %p, i32 2048) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-st-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-st-non-imm.ll +deleted file mode 100644 +index 119ed9b78..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-st-non-imm.ll ++++ /dev/null +@@ -1,10 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare void @llvm.loongarch.lsx.vst(<16 x i8>, i8*, i32) +- +-define void @lsx_vst(<16 x i8> %va, i8* %p, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.lsx.vst(<16 x i8> %va, i8* %p, i32 %b) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-st.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-st.ll +deleted file mode 100644 +index 798f509f2..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-st.ll ++++ /dev/null +@@ -1,26 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare void @llvm.loongarch.lsx.vst(<16 x i8>, i8*, i32) +- +-define void @lsx_vst(<16 x i8> %va, i8* %p) nounwind { +-; CHECK-LABEL: lsx_vst: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vst $vr0, $a0, -2048 +-; CHECK-NEXT: ret +-entry: +- call void @llvm.loongarch.lsx.vst(<16 x i8> %va, i8* %p, i32 -2048) +- ret void +-} +- +-declare void @llvm.loongarch.lsx.vstx(<16 x i8>, i8*, i64) +- +-define void @lsx_vstx(<16 x i8> %va, i8* %p, i64 %c) nounwind { +-; CHECK-LABEL: lsx_vstx: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vstx $vr0, $a0, $a1 +-; CHECK-NEXT: ret +-entry: +- call void @llvm.loongarch.lsx.vstx(<16 x i8> %va, i8* %p, i64 %c) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-stelm-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-stelm-invalid-imm.ll +deleted file mode 100644 +index 277abcbd3..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-stelm-invalid-imm.ll ++++ /dev/null +@@ -1,121 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare void @llvm.loongarch.lsx.vstelm.b(<16 x i8>, i8*, i32, i32) +- +-define void @lsx_vstelm_b_lo(<16 x i8> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vstelm.b: argument out of range +-entry: +- call void @llvm.loongarch.lsx.vstelm.b(<16 x i8> %va, i8* %p, i32 -129, i32 15) +- ret void +-} +- +-define void @lsx_vstelm_b_hi(<16 x i8> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vstelm.b: argument out of range +-entry: +- call void @llvm.loongarch.lsx.vstelm.b(<16 x i8> %va, i8* %p, i32 128, i32 15) +- ret void +-} +- +-define void @lsx_vstelm_b_idx_lo(<16 x i8> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vstelm.b: argument out of range +-entry: +- call void @llvm.loongarch.lsx.vstelm.b(<16 x i8> %va, i8* %p, i32 1, i32 -1) +- ret void +-} +- +-define void @lsx_vstelm_b_idx_hi(<16 x i8> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vstelm.b: argument out of range +-entry: +- call void @llvm.loongarch.lsx.vstelm.b(<16 x i8> %va, i8* %p, i32 1, i32 16) +- ret void +-} +- +-declare void @llvm.loongarch.lsx.vstelm.h(<8 x i16>, i8*, i32, i32) +- +-define void @lsx_vstelm_h_lo(<8 x i16> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vstelm.h: argument out of range or not a multiple of 2. +-entry: +- call void @llvm.loongarch.lsx.vstelm.h(<8 x i16> %va, i8* %p, i32 -258, i32 7) +- ret void +-} +- +-define void @lsx_vstelm_h_hi(<8 x i16> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vstelm.h: argument out of range or not a multiple of 2. +-entry: +- call void @llvm.loongarch.lsx.vstelm.h(<8 x i16> %va, i8* %p, i32 256, i32 7) +- ret void +-} +- +-define void @lsx_vstelm_h_idx_lo(<8 x i16> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vstelm.h: argument out of range or not a multiple of 2. +-entry: +- call void @llvm.loongarch.lsx.vstelm.h(<8 x i16> %va, i8* %p, i32 2, i32 -1) +- ret void +-} +- +-define void @lsx_vstelm_h_idx_hi(<8 x i16> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vstelm.h: argument out of range or not a multiple of 2. +-entry: +- call void @llvm.loongarch.lsx.vstelm.h(<8 x i16> %va, i8* %p, i32 2, i32 8) +- ret void +-} +- +-declare void @llvm.loongarch.lsx.vstelm.w(<4 x i32>, i8*, i32, i32) +- +-define void @lsx_vstelm_w_lo(<4 x i32> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vstelm.w: argument out of range or not a multiple of 4. +-entry: +- call void @llvm.loongarch.lsx.vstelm.w(<4 x i32> %va, i8* %p, i32 -516, i32 3) +- ret void +-} +- +-define void @lsx_vstelm_w_hi(<4 x i32> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vstelm.w: argument out of range or not a multiple of 4. +-entry: +- call void @llvm.loongarch.lsx.vstelm.w(<4 x i32> %va, i8* %p, i32 512, i32 3) +- ret void +-} +- +-define void @lsx_vstelm_w_idx_lo(<4 x i32> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vstelm.w: argument out of range or not a multiple of 4. +-entry: +- call void @llvm.loongarch.lsx.vstelm.w(<4 x i32> %va, i8* %p, i32 4, i32 -1) +- ret void +-} +- +-define void @lsx_vstelm_w_idx_hi(<4 x i32> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vstelm.w: argument out of range or not a multiple of 4. +-entry: +- call void @llvm.loongarch.lsx.vstelm.w(<4 x i32> %va, i8* %p, i32 4, i32 4) +- ret void +-} +- +-declare void @llvm.loongarch.lsx.vstelm.d(<2 x i64>, i8*, i32, i32) +- +-define void @lsx_vstelm_d_lo(<2 x i64> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vstelm.d: argument out of range or not a multiple of 8. +-entry: +- call void @llvm.loongarch.lsx.vstelm.d(<2 x i64> %va, i8* %p, i32 -1032, i32 1) +- ret void +-} +- +-define void @lsx_vstelm_d_hi(<2 x i64> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vstelm.d: argument out of range or not a multiple of 8. +-entry: +- call void @llvm.loongarch.lsx.vstelm.d(<2 x i64> %va, i8* %p, i32 1024, i32 1) +- ret void +-} +- +-define void @lsx_vstelm_d_idx_lo(<2 x i64> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vstelm.d: argument out of range or not a multiple of 8. +-entry: +- call void @llvm.loongarch.lsx.vstelm.d(<2 x i64> %va, i8* %p, i32 8, i32 -1) +- ret void +-} +- +-define void @lsx_vstelm_d_idx_hi(<2 x i64> %va, i8* %p) nounwind { +-; CHECK: llvm.loongarch.lsx.vstelm.d: argument out of range or not a multiple of 8. +-entry: +- call void @llvm.loongarch.lsx.vstelm.d(<2 x i64> %va, i8* %p, i32 8, i32 2) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-stelm-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-stelm-non-imm.ll +deleted file mode 100644 +index f53932f79..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-stelm-non-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare void @llvm.loongarch.lsx.vstelm.b(<16 x i8>, i8*, i32, i32) +- +-define void @lsx_vstelm_b(<16 x i8> %va, i8* %p, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.lsx.vstelm.b(<16 x i8> %va, i8* %p, i32 %b, i32 1) +- ret void +-} +- +-define void @lsx_vstelm_b_idx(<16 x i8> %va, i8* %p, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.lsx.vstelm.b(<16 x i8> %va, i8* %p, i32 1, i32 %b) +- ret void +-} +- +-declare void @llvm.loongarch.lsx.vstelm.h(<8 x i16>, i8*, i32, i32) +- +-define void @lsx_vstelm_h(<8 x i16> %va, i8* %p, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.lsx.vstelm.h(<8 x i16> %va, i8* %p, i32 %b, i32 1) +- ret void +-} +- +-define void @lsx_vstelm_h_idx(<8 x i16> %va, i8* %p, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.lsx.vstelm.h(<8 x i16> %va, i8* %p, i32 2, i32 %b) +- ret void +-} +- +-declare void @llvm.loongarch.lsx.vstelm.w(<4 x i32>, i8*, i32, i32) +- +-define void @lsx_vstelm_w(<4 x i32> %va, i8* %p, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.lsx.vstelm.w(<4 x i32> %va, i8* %p, i32 %b, i32 1) +- ret void +-} +- +-define void @lsx_vstelm_w_idx(<4 x i32> %va, i8* %p, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.lsx.vstelm.w(<4 x i32> %va, i8* %p, i32 4, i32 %b) +- ret void +-} +- +-declare void @llvm.loongarch.lsx.vstelm.d(<2 x i64>, i8*, i32, i32) +- +-define void @lsx_vstelm_d(<2 x i64> %va, i8* %p, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.lsx.vstelm.d(<2 x i64> %va, i8* %p, i32 %b, i32 1) +- ret void +-} +- +-define void @lsx_vstelm_d_idx(<2 x i64> %va, i8* %p, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- call void @llvm.loongarch.lsx.vstelm.d(<2 x i64> %va, i8* %p, i32 8, i32 %b) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-stelm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-stelm.ll +deleted file mode 100644 +index 6b9e7a9d7..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-stelm.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare void @llvm.loongarch.lsx.vstelm.b(<16 x i8>, i8*, i32, i32) +- +-define void @lsx_vstelm_b(<16 x i8> %va, i8* %p) nounwind { +-; CHECK-LABEL: lsx_vstelm_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vstelm.b $vr0, $a0, 1, 15 +-; CHECK-NEXT: ret +-entry: +- call void @llvm.loongarch.lsx.vstelm.b(<16 x i8> %va, i8* %p, i32 1, i32 15) +- ret void +-} +- +-declare void @llvm.loongarch.lsx.vstelm.h(<8 x i16>, i8*, i32, i32) +- +-define void @lsx_vstelm_h(<8 x i16> %va, i8* %p) nounwind { +-; CHECK-LABEL: lsx_vstelm_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vstelm.h $vr0, $a0, 2, 7 +-; CHECK-NEXT: ret +-entry: +- call void @llvm.loongarch.lsx.vstelm.h(<8 x i16> %va, i8* %p, i32 2, i32 7) +- ret void +-} +- +-declare void @llvm.loongarch.lsx.vstelm.w(<4 x i32>, i8*, i32, i32) +- +-define void @lsx_vstelm_w(<4 x i32> %va, i8* %p) nounwind { +-; CHECK-LABEL: lsx_vstelm_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vstelm.w $vr0, $a0, 4, 3 +-; CHECK-NEXT: ret +-entry: +- call void @llvm.loongarch.lsx.vstelm.w(<4 x i32> %va, i8* %p, i32 4, i32 3) +- ret void +-} +- +-declare void @llvm.loongarch.lsx.vstelm.d(<2 x i64>, i8*, i32, i32) +- +-define void @lsx_vstelm_d(<2 x i64> %va, i8* %p) nounwind { +-; CHECK-LABEL: lsx_vstelm_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vstelm.d $vr0, $a0, 8, 1 +-; CHECK-NEXT: ret +-entry: +- call void @llvm.loongarch.lsx.vstelm.d(<2 x i64> %va, i8* %p, i32 8, i32 1) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sub.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sub.ll +deleted file mode 100644 +index 5c04a3d8d..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-sub.ll ++++ /dev/null +@@ -1,62 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsub.b(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vsub_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vsub_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsub.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsub.b(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsub.h(<8 x i16>, <8 x i16>) +- +-define <8 x i16> @lsx_vsub_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsub_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsub.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsub.h(<8 x i16> %va, <8 x i16> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsub.w(<4 x i32>, <4 x i32>) +- +-define <4 x i32> @lsx_vsub_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsub_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsub.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsub.w(<4 x i32> %va, <4 x i32> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsub.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vsub_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsub_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsub.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsub.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsub.q(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vsub_q(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsub_q: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsub.q $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsub.q(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-subi-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-subi-invalid-imm.ll +deleted file mode 100644 +index 96cc1241f..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-subi-invalid-imm.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsubi.bu(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vsubi_bu_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsubi.bu: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsubi.bu(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vsubi_bu_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsubi.bu: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsubi.bu(<16 x i8> %va, i32 32) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsubi.hu(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vsubi_hu_lo(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsubi.hu: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsubi.hu(<8 x i16> %va, i32 -1) +- ret <8 x i16> %res +-} +- +-define <8 x i16> @lsx_vsubi_hu_hi(<8 x i16> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsubi.hu: argument out of range +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsubi.hu(<8 x i16> %va, i32 32) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsubi.wu(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vsubi_wu_lo(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsubi.wu: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsubi.wu(<4 x i32> %va, i32 -1) +- ret <4 x i32> %res +-} +- +-define <4 x i32> @lsx_vsubi_wu_hi(<4 x i32> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsubi.wu: argument out of range +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsubi.wu(<4 x i32> %va, i32 32) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsubi.du(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vsubi_du_lo(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsubi.du: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsubi.du(<2 x i64> %va, i32 -1) +- ret <2 x i64> %res +-} +- +-define <2 x i64> @lsx_vsubi_du_hi(<2 x i64> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vsubi.du: argument out of range +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsubi.du(<2 x i64> %va, i32 32) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-subi-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-subi-non-imm.ll +deleted file mode 100644 +index 162f9ad13..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-subi-non-imm.ll ++++ /dev/null +@@ -1,37 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsubi.bu(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vsubi_bu(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsubi.bu(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsubi.hu(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vsubi_hu(<8 x i16> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsubi.hu(<8 x i16> %va, i32 %b) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsubi.wu(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vsubi_wu(<4 x i32> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsubi.wu(<4 x i32> %va, i32 %b) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsubi.du(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vsubi_du(<2 x i64> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsubi.du(<2 x i64> %va, i32 %b) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-subi.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-subi.ll +deleted file mode 100644 +index 304a4e4a7..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-subi.ll ++++ /dev/null +@@ -1,50 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vsubi.bu(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vsubi_bu(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vsubi_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsubi.bu $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vsubi.bu(<16 x i8> %va, i32 31) +- ret <16 x i8> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsubi.hu(<8 x i16>, i32) +- +-define <8 x i16> @lsx_vsubi_hu(<8 x i16> %va) nounwind { +-; CHECK-LABEL: lsx_vsubi_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsubi.hu $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsubi.hu(<8 x i16> %va, i32 31) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsubi.wu(<4 x i32>, i32) +- +-define <4 x i32> @lsx_vsubi_wu(<4 x i32> %va) nounwind { +-; CHECK-LABEL: lsx_vsubi_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsubi.wu $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsubi.wu(<4 x i32> %va, i32 31) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsubi.du(<2 x i64>, i32) +- +-define <2 x i64> @lsx_vsubi_du(<2 x i64> %va) nounwind { +-; CHECK-LABEL: lsx_vsubi_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsubi.du $vr0, $vr0, 31 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsubi.du(<2 x i64> %va, i32 31) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-subw.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-subw.ll +deleted file mode 100644 +index 48100db74..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-subw.ll ++++ /dev/null +@@ -1,194 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <8 x i16> @llvm.loongarch.lsx.vsubwev.h.b(<16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vsubwev_h_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vsubwev_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsubwev.h.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsubwev.h.b(<16 x i8> %va, <16 x i8> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsubwev.w.h(<8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vsubwev_w_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsubwev_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsubwev.w.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsubwev.w.h(<8 x i16> %va, <8 x i16> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsubwev.d.w(<4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vsubwev_d_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsubwev_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsubwev.d.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsubwev.d.w(<4 x i32> %va, <4 x i32> %vb) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsubwev.q.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vsubwev_q_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsubwev_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsubwev.q.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsubwev.q.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsubwev.h.bu(<16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vsubwev_h_bu(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vsubwev_h_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsubwev.h.bu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsubwev.h.bu(<16 x i8> %va, <16 x i8> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsubwev.w.hu(<8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vsubwev_w_hu(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsubwev_w_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsubwev.w.hu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsubwev.w.hu(<8 x i16> %va, <8 x i16> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsubwev.d.wu(<4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vsubwev_d_wu(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsubwev_d_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsubwev.d.wu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsubwev.d.wu(<4 x i32> %va, <4 x i32> %vb) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsubwev.q.du(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vsubwev_q_du(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsubwev_q_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsubwev.q.du $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsubwev.q.du(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsubwod.h.b(<16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vsubwod_h_b(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vsubwod_h_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsubwod.h.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsubwod.h.b(<16 x i8> %va, <16 x i8> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsubwod.w.h(<8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vsubwod_w_h(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsubwod_w_h: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsubwod.w.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsubwod.w.h(<8 x i16> %va, <8 x i16> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsubwod.d.w(<4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vsubwod_d_w(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsubwod_d_w: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsubwod.d.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsubwod.d.w(<4 x i32> %va, <4 x i32> %vb) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsubwod.q.d(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vsubwod_q_d(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsubwod_q_d: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsubwod.q.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsubwod.q.d(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +- +-declare <8 x i16> @llvm.loongarch.lsx.vsubwod.h.bu(<16 x i8>, <16 x i8>) +- +-define <8 x i16> @lsx_vsubwod_h_bu(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vsubwod_h_bu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsubwod.h.bu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vsubwod.h.bu(<16 x i8> %va, <16 x i8> %vb) +- ret <8 x i16> %res +-} +- +-declare <4 x i32> @llvm.loongarch.lsx.vsubwod.w.hu(<8 x i16>, <8 x i16>) +- +-define <4 x i32> @lsx_vsubwod_w_hu(<8 x i16> %va, <8 x i16> %vb) nounwind { +-; CHECK-LABEL: lsx_vsubwod_w_hu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsubwod.w.hu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <4 x i32> @llvm.loongarch.lsx.vsubwod.w.hu(<8 x i16> %va, <8 x i16> %vb) +- ret <4 x i32> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsubwod.d.wu(<4 x i32>, <4 x i32>) +- +-define <2 x i64> @lsx_vsubwod_d_wu(<4 x i32> %va, <4 x i32> %vb) nounwind { +-; CHECK-LABEL: lsx_vsubwod_d_wu: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsubwod.d.wu $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsubwod.d.wu(<4 x i32> %va, <4 x i32> %vb) +- ret <2 x i64> %res +-} +- +-declare <2 x i64> @llvm.loongarch.lsx.vsubwod.q.du(<2 x i64>, <2 x i64>) +- +-define <2 x i64> @lsx_vsubwod_q_du(<2 x i64> %va, <2 x i64> %vb) nounwind { +-; CHECK-LABEL: lsx_vsubwod_q_du: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vsubwod.q.du $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <2 x i64> @llvm.loongarch.lsx.vsubwod.q.du(<2 x i64> %va, <2 x i64> %vb) +- ret <2 x i64> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-xor.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-xor.ll +deleted file mode 100644 +index 72a1fe93c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-xor.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vxor.v(<16 x i8>, <16 x i8>) +- +-define <16 x i8> @lsx_vxor_v(<16 x i8> %va, <16 x i8> %vb) nounwind { +-; CHECK-LABEL: lsx_vxor_v: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vxor.v $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vxor.v(<16 x i8> %va, <16 x i8> %vb) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-xori-invalid-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-xori-invalid-imm.ll +deleted file mode 100644 +index 5f5613189..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-xori-invalid-imm.ll ++++ /dev/null +@@ -1,17 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vxori.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vxori_b_lo(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vxori.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vxori.b(<16 x i8> %va, i32 -1) +- ret <16 x i8> %res +-} +- +-define <16 x i8> @lsx_vxori_b_hi(<16 x i8> %va) nounwind { +-; CHECK: llvm.loongarch.lsx.vxori.b: argument out of range +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vxori.b(<16 x i8> %va, i32 256) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-xori-non-imm.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-xori-non-imm.ll +deleted file mode 100644 +index 4238d8912..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-xori-non-imm.ll ++++ /dev/null +@@ -1,10 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 --mattr=+lsx < %s 2>&1 | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vxori.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vxori_b(<16 x i8> %va, i32 %b) nounwind { +-; CHECK: immarg operand has non-immediate parameter +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vxori.b(<16 x i8> %va, i32 %b) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-xori.ll b/llvm/test/CodeGen/LoongArch/lsx/intrinsic-xori.ll +deleted file mode 100644 +index 09669cd5a..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-xori.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-declare <16 x i8> @llvm.loongarch.lsx.vxori.b(<16 x i8>, i32) +- +-define <16 x i8> @lsx_vxori_b(<16 x i8> %va) nounwind { +-; CHECK-LABEL: lsx_vxori_b: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vxori.b $vr0, $vr0, 3 +-; CHECK-NEXT: ret +-entry: +- %res = call <16 x i8> @llvm.loongarch.lsx.vxori.b(<16 x i8> %va, i32 3) +- ret <16 x i8> %res +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/add.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/add.ll +deleted file mode 100644 +index 2a7c37c2a..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/add.ll ++++ /dev/null +@@ -1,122 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @add_v16i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: add_v16i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vadd.b $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %v2 = add <16 x i8> %v0, %v1 +- store <16 x i8> %v2, ptr %res +- ret void +-} +- +-define void @add_v8i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: add_v8i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vadd.h $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %v2 = add <8 x i16> %v0, %v1 +- store <8 x i16> %v2, ptr %res +- ret void +-} +- +-define void @add_v4i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: add_v4i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vadd.w $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %v2 = add <4 x i32> %v0, %v1 +- store <4 x i32> %v2, ptr %res +- ret void +-} +- +-define void @add_v2i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: add_v2i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vadd.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %v2 = add <2 x i64> %v0, %v1 +- store <2 x i64> %v2, ptr %res +- ret void +-} +- +-define void @add_v16i8_31(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: add_v16i8_31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vaddi.bu $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = add <16 x i8> %v0, +- store <16 x i8> %v1, ptr %res +- ret void +-} +- +-define void @add_v8i16_31(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: add_v8i16_31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vaddi.hu $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = add <8 x i16> %v0, +- store <8 x i16> %v1, ptr %res +- ret void +-} +- +-define void @add_v4i32_31(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: add_v4i32_31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vaddi.wu $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = add <4 x i32> %v0, +- store <4 x i32> %v1, ptr %res +- ret void +-} +- +-define void @add_v2i64_31(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: add_v2i64_31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vaddi.du $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = add <2 x i64> %v0, +- store <2 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/and.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/and.ll +deleted file mode 100644 +index 523255159..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/and.ll ++++ /dev/null +@@ -1,125 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @and_v16i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: and_v16i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vand.v $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %v2 = and <16 x i8> %v0, %v1 +- store <16 x i8> %v2, ptr %res +- ret void +-} +- +-define void @and_v8i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: and_v8i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vand.v $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %v2 = and <8 x i16> %v0, %v1 +- store <8 x i16> %v2, ptr %res +- ret void +-} +- +-define void @and_v4i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: and_v4i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vand.v $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %v2 = and <4 x i32> %v0, %v1 +- store <4 x i32> %v2, ptr %res +- ret void +-} +- +-define void @and_v2i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: and_v2i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vand.v $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %v2 = and <2 x i64> %v0, %v1 +- store <2 x i64> %v2, ptr %res +- ret void +-} +- +-define void @and_u_v16i8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: and_u_v16i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vandi.b $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = and <16 x i8> %v0, +- store <16 x i8> %v1, ptr %res +- ret void +-} +- +-define void @and_u_v8i16(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: and_u_v8i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vrepli.h $vr1, 31 +-; CHECK-NEXT: vand.v $vr0, $vr0, $vr1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = and <8 x i16> %v0, +- store <8 x i16> %v1, ptr %res +- ret void +-} +- +-define void @and_u_v4i32(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: and_u_v4i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vrepli.w $vr1, 31 +-; CHECK-NEXT: vand.v $vr0, $vr0, $vr1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = and <4 x i32> %v0, +- store <4 x i32> %v1, ptr %res +- ret void +-} +- +-define void @and_u_v2i64(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: and_u_v2i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vrepli.d $vr1, 31 +-; CHECK-NEXT: vand.v $vr0, $vr0, $vr1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = and <2 x i64> %v0, +- store <2 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/ashr.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/ashr.ll +deleted file mode 100644 +index fbc570d77..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/ashr.ll ++++ /dev/null +@@ -1,178 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @ashr_v16i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: ashr_v16i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsra.b $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %v2 = ashr <16 x i8> %v0, %v1 +- store <16 x i8> %v2, ptr %res +- ret void +-} +- +-define void @ashr_v8i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: ashr_v8i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsra.h $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %v2 = ashr <8 x i16> %v0, %v1 +- store <8 x i16> %v2, ptr %res +- ret void +-} +- +-define void @ashr_v4i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: ashr_v4i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsra.w $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %v2 = ashr <4 x i32> %v0, %v1 +- store <4 x i32> %v2, ptr %res +- ret void +-} +- +-define void @ashr_v2i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: ashr_v2i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsra.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %v2 = ashr <2 x i64> %v0, %v1 +- store <2 x i64> %v2, ptr %res +- ret void +-} +- +-define void @ashr_v16i8_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: ashr_v16i8_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrai.b $vr0, $vr0, 1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = ashr <16 x i8> %v0, +- store <16 x i8> %v1, ptr %res +- ret void +-} +- +-define void @ashr_v16i8_7(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: ashr_v16i8_7: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrai.b $vr0, $vr0, 7 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = ashr <16 x i8> %v0, +- store <16 x i8> %v1, ptr %res +- ret void +-} +- +-define void @ashr_v8i16_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: ashr_v8i16_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrai.h $vr0, $vr0, 1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = ashr <8 x i16> %v0, +- store <8 x i16> %v1, ptr %res +- ret void +-} +- +-define void @ashr_v8i16_15(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: ashr_v8i16_15: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrai.h $vr0, $vr0, 15 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = ashr <8 x i16> %v0, +- store <8 x i16> %v1, ptr %res +- ret void +-} +- +-define void @ashr_v4i32_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: ashr_v4i32_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrai.w $vr0, $vr0, 1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = ashr <4 x i32> %v0, +- store <4 x i32> %v1, ptr %res +- ret void +-} +- +-define void @ashr_v4i32_31(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: ashr_v4i32_31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrai.w $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = ashr <4 x i32> %v0, +- store <4 x i32> %v1, ptr %res +- ret void +-} +- +-define void @ashr_v2i64_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: ashr_v2i64_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrai.d $vr0, $vr0, 1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = ashr <2 x i64> %v0, +- store <2 x i64> %v1, ptr %res +- ret void +-} +- +-define void @ashr_v2i64_63(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: ashr_v2i64_63: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrai.d $vr0, $vr0, 63 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = ashr <2 x i64> %v0, +- store <2 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/extractelement.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/extractelement.ll +deleted file mode 100644 +index b8798c978..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/extractelement.ll ++++ /dev/null +@@ -1,170 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @extract_16xi8(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: extract_16xi8: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vpickve2gr.b $a0, $vr0, 1 +-; CHECK-NEXT: st.b $a0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <16 x i8>, ptr %src +- %e = extractelement <16 x i8> %v, i32 1 +- store i8 %e, ptr %dst +- ret void +-} +- +-define void @extract_8xi16(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: extract_8xi16: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 1 +-; CHECK-NEXT: st.h $a0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <8 x i16>, ptr %src +- %e = extractelement <8 x i16> %v, i32 1 +- store i16 %e, ptr %dst +- ret void +-} +- +-define void @extract_4xi32(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: extract_4xi32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vpickve2gr.w $a0, $vr0, 1 +-; CHECK-NEXT: st.w $a0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <4 x i32>, ptr %src +- %e = extractelement <4 x i32> %v, i32 1 +- store i32 %e, ptr %dst +- ret void +-} +- +-define void @extract_2xi64(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: extract_2xi64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vpickve2gr.d $a0, $vr0, 1 +-; CHECK-NEXT: st.d $a0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <2 x i64>, ptr %src +- %e = extractelement <2 x i64> %v, i32 1 +- store i64 %e, ptr %dst +- ret void +-} +- +-define void @extract_4xfloat(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: extract_4xfloat: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vreplvei.w $vr0, $vr0, 1 +-; CHECK-NEXT: fst.s $fa0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <4 x float>, ptr %src +- %e = extractelement <4 x float> %v, i32 1 +- store float %e, ptr %dst +- ret void +-} +- +-define void @extract_2xdouble(ptr %src, ptr %dst) nounwind { +-; CHECK-LABEL: extract_2xdouble: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vreplvei.d $vr0, $vr0, 1 +-; CHECK-NEXT: fst.d $fa0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <2 x double>, ptr %src +- %e = extractelement <2 x double> %v, i32 1 +- store double %e, ptr %dst +- ret void +-} +- +-define void @extract_16xi8_idx(ptr %src, ptr %dst, i32 %idx) nounwind { +-; CHECK-LABEL: extract_16xi8_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrpick.d $a2, $a2, 31, 0 +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vreplve.b $vr0, $vr0, $a2 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: srai.w $a0, $a0, 24 +-; CHECK-NEXT: st.b $a0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <16 x i8>, ptr %src +- %e = extractelement <16 x i8> %v, i32 %idx +- store i8 %e, ptr %dst +- ret void +-} +- +-define void @extract_8xi16_idx(ptr %src, ptr %dst, i32 %idx) nounwind { +-; CHECK-LABEL: extract_8xi16_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrpick.d $a2, $a2, 31, 0 +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vreplve.h $vr0, $vr0, $a2 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: srai.w $a0, $a0, 16 +-; CHECK-NEXT: st.h $a0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <8 x i16>, ptr %src +- %e = extractelement <8 x i16> %v, i32 %idx +- store i16 %e, ptr %dst +- ret void +-} +- +-define void @extract_4xi32_idx(ptr %src, ptr %dst, i32 %idx) nounwind { +-; CHECK-LABEL: extract_4xi32_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrpick.d $a2, $a2, 31, 0 +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vreplve.w $vr0, $vr0, $a2 +-; CHECK-NEXT: movfr2gr.s $a0, $fa0 +-; CHECK-NEXT: st.w $a0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <4 x i32>, ptr %src +- %e = extractelement <4 x i32> %v, i32 %idx +- store i32 %e, ptr %dst +- ret void +-} +- +-define void @extract_2xi64_idx(ptr %src, ptr %dst, i32 %idx) nounwind { +-; CHECK-LABEL: extract_2xi64_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrpick.d $a2, $a2, 31, 0 +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vreplve.d $vr0, $vr0, $a2 +-; CHECK-NEXT: movfr2gr.d $a0, $fa0 +-; CHECK-NEXT: st.d $a0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <2 x i64>, ptr %src +- %e = extractelement <2 x i64> %v, i32 %idx +- store i64 %e, ptr %dst +- ret void +-} +- +-define void @extract_4xfloat_idx(ptr %src, ptr %dst, i32 %idx) nounwind { +-; CHECK-LABEL: extract_4xfloat_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrpick.d $a2, $a2, 31, 0 +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vreplve.w $vr0, $vr0, $a2 +-; CHECK-NEXT: fst.s $fa0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <4 x float>, ptr %src +- %e = extractelement <4 x float> %v, i32 %idx +- store float %e, ptr %dst +- ret void +-} +- +-define void @extract_2xdouble_idx(ptr %src, ptr %dst, i32 %idx) nounwind { +-; CHECK-LABEL: extract_2xdouble_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: bstrpick.d $a2, $a2, 31, 0 +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vreplve.d $vr0, $vr0, $a2 +-; CHECK-NEXT: fst.d $fa0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <2 x double>, ptr %src +- %e = extractelement <2 x double> %v, i32 %idx +- store double %e, ptr %dst +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fadd.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fadd.ll +deleted file mode 100644 +index 1fa1f611c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fadd.ll ++++ /dev/null +@@ -1,34 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @fadd_v4f32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: fadd_v4f32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfadd.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = fadd <4 x float> %v0, %v1 +- store <4 x float> %v2, ptr %res +- ret void +-} +- +-define void @fadd_v2f64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: fadd_v2f64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfadd.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = fadd <2 x double> %v0, %v1 +- store <2 x double> %v2, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fcmp.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fcmp.ll +deleted file mode 100644 +index 53fbf0b2f..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fcmp.ll ++++ /dev/null +@@ -1,692 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-;; TREU +-define void @v4f32_fcmp_true(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f32_fcmp_true: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vrepli.b $vr0, -1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %cmp = fcmp true <4 x float> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-;; FALSE +-define void @v2f64_fcmp_false(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2f64_fcmp_false: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vrepli.b $vr0, 0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %cmp = fcmp false <2 x double> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETOEQ +-define void @v4f32_fcmp_oeq(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f32_fcmp_oeq: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.ceq.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %cmp = fcmp oeq <4 x float> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2f64_fcmp_oeq(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2f64_fcmp_oeq: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.ceq.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %cmp = fcmp oeq <2 x double> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETUEQ +-define void @v4f32_fcmp_ueq(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f32_fcmp_ueq: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.cueq.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %cmp = fcmp ueq <4 x float> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2f64_fcmp_ueq(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2f64_fcmp_ueq: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.cueq.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %cmp = fcmp ueq <2 x double> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETEQ +-define void @v4f32_fcmp_eq(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f32_fcmp_eq: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.ceq.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %cmp = fcmp fast oeq <4 x float> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2f64_fcmp_eq(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2f64_fcmp_eq: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.ceq.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %cmp = fcmp fast ueq <2 x double> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETOLE +-define void @v4f32_fcmp_ole(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f32_fcmp_ole: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.cle.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %cmp = fcmp ole <4 x float> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2f64_fcmp_ole(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2f64_fcmp_ole: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.cle.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %cmp = fcmp ole <2 x double> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETULE +-define void @v4f32_fcmp_ule(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f32_fcmp_ule: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.cule.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %cmp = fcmp ule <4 x float> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2f64_fcmp_ule(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2f64_fcmp_ule: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.cule.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %cmp = fcmp ule <2 x double> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETLE +-define void @v4f32_fcmp_le(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f32_fcmp_le: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.cle.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %cmp = fcmp fast ole <4 x float> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2f64_fcmp_le(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2f64_fcmp_le: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.cle.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %cmp = fcmp fast ule <2 x double> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETOLT +-define void @v4f32_fcmp_olt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f32_fcmp_olt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.clt.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %cmp = fcmp olt <4 x float> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2f64_fcmp_olt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2f64_fcmp_olt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.clt.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %cmp = fcmp olt <2 x double> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETULT +-define void @v4f32_fcmp_ult(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f32_fcmp_ult: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.cult.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %cmp = fcmp ult <4 x float> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2f64_fcmp_ult(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2f64_fcmp_ult: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.cult.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %cmp = fcmp ult <2 x double> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETLT +-define void @v4f32_fcmp_lt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f32_fcmp_lt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.clt.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %cmp = fcmp fast olt <4 x float> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2f64_fcmp_lt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2f64_fcmp_lt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.clt.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %cmp = fcmp fast ult <2 x double> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETONE +-define void @v4f32_fcmp_one(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f32_fcmp_one: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.cne.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %cmp = fcmp one <4 x float> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2f64_fcmp_one(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2f64_fcmp_one: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.cne.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %cmp = fcmp one <2 x double> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETUNE +-define void @v4f32_fcmp_une(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f32_fcmp_une: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.cune.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %cmp = fcmp une <4 x float> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2f64_fcmp_une(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2f64_fcmp_une: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.cune.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %cmp = fcmp une <2 x double> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETNE +-define void @v4f32_fcmp_ne(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f32_fcmp_ne: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.cne.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %cmp = fcmp fast one <4 x float> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2f64_fcmp_ne(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2f64_fcmp_ne: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.cne.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %cmp = fcmp fast une <2 x double> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETO +-define void @v4f32_fcmp_ord(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f32_fcmp_ord: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.cor.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %cmp = fcmp ord <4 x float> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2f64_fcmp_ord(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2f64_fcmp_ord: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.cor.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %cmp = fcmp ord <2 x double> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETUO +-define void @v4f32_fcmp_uno(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f32_fcmp_uno: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.cun.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %cmp = fcmp uno <4 x float> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2f64_fcmp_uno(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2f64_fcmp_uno: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfcmp.cun.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %cmp = fcmp uno <2 x double> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; Expand SETOGT +-define void @v4f32_fcmp_ogt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f32_fcmp_ogt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vfcmp.clt.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %cmp = fcmp ogt <4 x float> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2f64_fcmp_ogt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2f64_fcmp_ogt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vfcmp.clt.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %cmp = fcmp ogt <2 x double> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; Expand SETUGT +-define void @v4f32_fcmp_ugt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f32_fcmp_ugt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vfcmp.cult.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %cmp = fcmp ugt <4 x float> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2f64_fcmp_ugt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2f64_fcmp_ugt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vfcmp.cult.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %cmp = fcmp ugt <2 x double> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; Expand SETGT +-define void @v4f32_fcmp_gt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f32_fcmp_gt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vfcmp.clt.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %cmp = fcmp fast ogt <4 x float> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2f64_fcmp_gt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2f64_fcmp_gt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vfcmp.clt.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %cmp = fcmp fast ugt <2 x double> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; Expand SETOGE +-define void @v4f32_fcmp_oge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f32_fcmp_oge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vfcmp.cle.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %cmp = fcmp oge <4 x float> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2f64_fcmp_oge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2f64_fcmp_oge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vfcmp.cle.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %cmp = fcmp oge <2 x double> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; Expand SETUGE +-define void @v4f32_fcmp_uge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f32_fcmp_uge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vfcmp.cule.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %cmp = fcmp uge <4 x float> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2f64_fcmp_uge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2f64_fcmp_uge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vfcmp.cule.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %cmp = fcmp uge <2 x double> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; Expand SETGE +-define void @v4f32_fcmp_ge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4f32_fcmp_ge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vfcmp.cle.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %cmp = fcmp fast oge <4 x float> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2f64_fcmp_ge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2f64_fcmp_ge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vfcmp.cle.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %cmp = fcmp fast uge <2 x double> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fdiv.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fdiv.ll +deleted file mode 100644 +index 5f1ee9e4d..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fdiv.ll ++++ /dev/null +@@ -1,63 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @fdiv_v4f32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: fdiv_v4f32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfdiv.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = fdiv <4 x float> %v0, %v1 +- store <4 x float> %v2, ptr %res +- ret void +-} +- +-define void @fdiv_v2f64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: fdiv_v2f64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfdiv.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = fdiv <2 x double> %v0, %v1 +- store <2 x double> %v2, ptr %res +- ret void +-} +- +-;; 1.0 / vec +-define void @one_fdiv_v4f32(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: one_fdiv_v4f32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vfrecip.s $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %div = fdiv <4 x float> , %v0 +- store <4 x float> %div, ptr %res +- ret void +-} +- +-define void @one_fdiv_v2f64(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: one_fdiv_v2f64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vfrecip.d $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %div = fdiv <2 x double> , %v0 +- store <2 x double> %div, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fmul.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fmul.ll +deleted file mode 100644 +index e7fb527f7..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fmul.ll ++++ /dev/null +@@ -1,34 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @fmul_v4f32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: fmul_v4f32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfmul.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = fmul <4 x float> %v0, %v1 +- store <4 x float> %v2, ptr %res +- ret void +-} +- +-define void @fmul_v2f64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: fmul_v2f64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfmul.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = fmul <2 x double> %v0, %v1 +- store <2 x double> %v2, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fneg.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fneg.ll +deleted file mode 100644 +index 795c1ac8b..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fneg.ll ++++ /dev/null +@@ -1,29 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @fneg_v4f32(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: fneg_v4f32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vbitrevi.w $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = fneg <4 x float> %v0 +- store <4 x float> %v1, ptr %res +- ret void +-} +-define void @fneg_v2f64(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: fneg_v2f64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vbitrevi.d $vr0, $vr0, 63 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = fneg <2 x double> %v0 +- store <2 x double> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fptosi.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fptosi.ll +deleted file mode 100644 +index c3008fe96..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fptosi.ll ++++ /dev/null +@@ -1,28 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @fptosi_v4f32_v4i32(ptr %res, ptr %in){ +-; CHECK-LABEL: fptosi_v4f32_v4i32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vftintrz.w.s $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %in +- %v1 = fptosi <4 x float> %v0 to <4 x i32> +- store <4 x i32> %v1, ptr %res +- ret void +-} +- +-define void @fptosi_v2f64_v2i64(ptr %res, ptr %in){ +-; CHECK-LABEL: fptosi_v2f64_v2i64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vftintrz.l.d $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %in +- %v1 = fptosi <2 x double> %v0 to <2 x i64> +- store <2 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fptoui.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fptoui.ll +deleted file mode 100644 +index f0aeb0bd1..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fptoui.ll ++++ /dev/null +@@ -1,28 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @fptoui_v4f32_v4i32(ptr %res, ptr %in){ +-; CHECK-LABEL: fptoui_v4f32_v4i32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vftintrz.wu.s $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x float>, ptr %in +- %v1 = fptoui <4 x float> %v0 to <4 x i32> +- store <4 x i32> %v1, ptr %res +- ret void +-} +- +-define void @fptoui_v2f64_v2i64(ptr %res, ptr %in){ +-; CHECK-LABEL: fptoui_v2f64_v2i64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vftintrz.lu.d $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x double>, ptr %in +- %v1 = fptoui <2 x double> %v0 to <2 x i64> +- store <2 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fsub.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fsub.ll +deleted file mode 100644 +index df9818232..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/fsub.ll ++++ /dev/null +@@ -1,34 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @fsub_v4f32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: fsub_v4f32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfsub.s $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x float>, ptr %a0 +- %v1 = load <4 x float>, ptr %a1 +- %v2 = fsub <4 x float> %v0, %v1 +- store <4 x float> %v2, ptr %res +- ret void +-} +- +-define void @fsub_v2f64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: fsub_v2f64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vfsub.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x double>, ptr %a0 +- %v1 = load <2 x double>, ptr %a1 +- %v2 = fsub <2 x double> %v0, %v1 +- store <2 x double> %v2, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/icmp.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/icmp.ll +deleted file mode 100644 +index 448f3fa6c..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/icmp.ll ++++ /dev/null +@@ -1,939 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-;; SETEQ +-define void @v16i8_icmp_eq_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v16i8_icmp_eq_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vseqi.b $vr0, $vr0, 15 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i8>, ptr %a0 +- %cmp = icmp eq <16 x i8> %v0, +- %ext = sext <16 x i1> %cmp to <16 x i8> +- store <16 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v16i8_icmp_eq(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v16i8_icmp_eq: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vseq.b $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %cmp = icmp eq <16 x i8> %v0, %v1 +- %ext = sext <16 x i1> %cmp to <16 x i8> +- store <16 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v8i16_icmp_eq_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v8i16_icmp_eq_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vseqi.h $vr0, $vr0, 15 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i16>, ptr %a0 +- %cmp = icmp eq <8 x i16> %v0, +- %ext = sext <8 x i1> %cmp to <8 x i16> +- store <8 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v8i16_icmp_eq(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8i16_icmp_eq: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vseq.h $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %cmp = icmp eq <8 x i16> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i16> +- store <8 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v4i32_icmp_eq_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v4i32_icmp_eq_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vseqi.w $vr0, $vr0, 15 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i32>, ptr %a0 +- %cmp = icmp eq <4 x i32> %v0, +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4i32_icmp_eq(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4i32_icmp_eq: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vseq.w $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %cmp = icmp eq <4 x i32> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2i64_icmp_eq_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v2i64_icmp_eq_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vseqi.d $vr0, $vr0, 15 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x i64>, ptr %a0 +- %cmp = icmp eq <2 x i64> %v0, +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-define void @v2i64_icmp_eq(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2i64_icmp_eq: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vseq.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %cmp = icmp eq <2 x i64> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETLE +-define void @v16i8_icmp_sle_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v16i8_icmp_sle_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslei.b $vr0, $vr0, 15 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i8>, ptr %a0 +- %cmp = icmp sle <16 x i8> %v0, +- %ext = sext <16 x i1> %cmp to <16 x i8> +- store <16 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v16i8_icmp_sle(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v16i8_icmp_sle: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsle.b $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %cmp = icmp sle <16 x i8> %v0, %v1 +- %ext = sext <16 x i1> %cmp to <16 x i8> +- store <16 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v8i16_icmp_sle_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v8i16_icmp_sle_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslei.h $vr0, $vr0, 15 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i16>, ptr %a0 +- %cmp = icmp sle <8 x i16> %v0, +- %ext = sext <8 x i1> %cmp to <8 x i16> +- store <8 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v8i16_icmp_sle(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8i16_icmp_sle: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsle.h $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %cmp = icmp sle <8 x i16> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i16> +- store <8 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v4i32_icmp_sle_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v4i32_icmp_sle_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslei.w $vr0, $vr0, 15 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i32>, ptr %a0 +- %cmp = icmp sle <4 x i32> %v0, +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4i32_icmp_sle(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4i32_icmp_sle: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsle.w $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %cmp = icmp sle <4 x i32> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2i64_icmp_sle_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v2i64_icmp_sle_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslei.d $vr0, $vr0, 15 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x i64>, ptr %a0 +- %cmp = icmp sle <2 x i64> %v0, +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-define void @v2i64_icmp_sle(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2i64_icmp_sle: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsle.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %cmp = icmp sle <2 x i64> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETULE +-define void @v16i8_icmp_ule_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v16i8_icmp_ule_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslei.bu $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i8>, ptr %a0 +- %cmp = icmp ule <16 x i8> %v0, +- %ext = sext <16 x i1> %cmp to <16 x i8> +- store <16 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v16i8_icmp_ule(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v16i8_icmp_ule: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsle.bu $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %cmp = icmp ule <16 x i8> %v0, %v1 +- %ext = sext <16 x i1> %cmp to <16 x i8> +- store <16 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v8i16_icmp_ule_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v8i16_icmp_ule_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslei.hu $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i16>, ptr %a0 +- %cmp = icmp ule <8 x i16> %v0, +- %ext = sext <8 x i1> %cmp to <8 x i16> +- store <8 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v8i16_icmp_ule(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8i16_icmp_ule: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsle.hu $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %cmp = icmp ule <8 x i16> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i16> +- store <8 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v4i32_icmp_ule_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v4i32_icmp_ule_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslei.wu $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i32>, ptr %a0 +- %cmp = icmp ule <4 x i32> %v0, +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4i32_icmp_ule(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4i32_icmp_ule: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsle.wu $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %cmp = icmp ule <4 x i32> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2i64_icmp_ule_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v2i64_icmp_ule_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslei.du $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x i64>, ptr %a0 +- %cmp = icmp ule <2 x i64> %v0, +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-define void @v2i64_icmp_ule(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2i64_icmp_ule: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsle.du $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %cmp = icmp ule <2 x i64> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETLT +-define void @v16i8_icmp_slt_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v16i8_icmp_slt_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslti.b $vr0, $vr0, 15 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i8>, ptr %a0 +- %cmp = icmp slt <16 x i8> %v0, +- %ext = sext <16 x i1> %cmp to <16 x i8> +- store <16 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v16i8_icmp_slt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v16i8_icmp_slt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vslt.b $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %cmp = icmp slt <16 x i8> %v0, %v1 +- %ext = sext <16 x i1> %cmp to <16 x i8> +- store <16 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v8i16_icmp_slt_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v8i16_icmp_slt_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslti.h $vr0, $vr0, 15 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i16>, ptr %a0 +- %cmp = icmp slt <8 x i16> %v0, +- %ext = sext <8 x i1> %cmp to <8 x i16> +- store <8 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v8i16_icmp_slt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8i16_icmp_slt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vslt.h $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %cmp = icmp slt <8 x i16> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i16> +- store <8 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v4i32_icmp_slt_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v4i32_icmp_slt_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslti.w $vr0, $vr0, 15 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i32>, ptr %a0 +- %cmp = icmp slt <4 x i32> %v0, +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4i32_icmp_slt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4i32_icmp_slt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vslt.w $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %cmp = icmp slt <4 x i32> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2i64_icmp_slt_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v2i64_icmp_slt_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslti.d $vr0, $vr0, 15 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x i64>, ptr %a0 +- %cmp = icmp slt <2 x i64> %v0, +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-define void @v2i64_icmp_slt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2i64_icmp_slt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vslt.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %cmp = icmp slt <2 x i64> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; SETULT +-define void @v16i8_icmp_ult_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v16i8_icmp_ult_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslti.bu $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i8>, ptr %a0 +- %cmp = icmp ult <16 x i8> %v0, +- %ext = sext <16 x i1> %cmp to <16 x i8> +- store <16 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v16i8_icmp_ult(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v16i8_icmp_ult: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vslt.bu $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %cmp = icmp ult <16 x i8> %v0, %v1 +- %ext = sext <16 x i1> %cmp to <16 x i8> +- store <16 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v8i16_icmp_ult_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v8i16_icmp_ult_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslti.hu $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i16>, ptr %a0 +- %cmp = icmp ult <8 x i16> %v0, +- %ext = sext <8 x i1> %cmp to <8 x i16> +- store <8 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v8i16_icmp_ult(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8i16_icmp_ult: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vslt.hu $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %cmp = icmp ult <8 x i16> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i16> +- store <8 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v4i32_icmp_ult_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v4i32_icmp_ult_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslti.wu $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i32>, ptr %a0 +- %cmp = icmp ult <4 x i32> %v0, +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v4i32_icmp_ult(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4i32_icmp_ult: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vslt.wu $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %cmp = icmp ult <4 x i32> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2i64_icmp_ult_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: v2i64_icmp_ult_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslti.du $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x i64>, ptr %a0 +- %cmp = icmp ult <2 x i64> %v0, +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-define void @v2i64_icmp_ult(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2i64_icmp_ult: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vslt.du $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %cmp = icmp ult <2 x i64> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; Expand SETNE +-define void @v16i8_icmp_ne(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v16i8_icmp_ne: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vseq.b $vr0, $vr1, $vr0 +-; CHECK-NEXT: vxori.b $vr0, $vr0, 255 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %cmp = icmp ne <16 x i8> %v0, %v1 +- %ext = sext <16 x i1> %cmp to <16 x i8> +- store <16 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v8i16_icmp_ne(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8i16_icmp_ne: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vseq.h $vr0, $vr1, $vr0 +-; CHECK-NEXT: vrepli.b $vr1, -1 +-; CHECK-NEXT: vxor.v $vr0, $vr0, $vr1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %cmp = icmp ne <8 x i16> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i16> +- store <8 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v4i32_icmp_ne(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4i32_icmp_ne: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vseq.w $vr0, $vr1, $vr0 +-; CHECK-NEXT: vrepli.b $vr1, -1 +-; CHECK-NEXT: vxor.v $vr0, $vr0, $vr1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %cmp = icmp ne <4 x i32> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2i64_icmp_ne(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2i64_icmp_ne: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vseq.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vrepli.b $vr1, -1 +-; CHECK-NEXT: vxor.v $vr0, $vr0, $vr1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %cmp = icmp ne <2 x i64> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; Expand SETGE +-define void @v16i8_icmp_sge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v16i8_icmp_sge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vsle.b $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %cmp = icmp sge <16 x i8> %v0, %v1 +- %ext = sext <16 x i1> %cmp to <16 x i8> +- store <16 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v8i16_icmp_sge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8i16_icmp_sge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vsle.h $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %cmp = icmp sge <8 x i16> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i16> +- store <8 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v4i32_icmp_sge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4i32_icmp_sge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vsle.w $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %cmp = icmp sge <4 x i32> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2i64_icmp_sge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2i64_icmp_sge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vsle.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %cmp = icmp sge <2 x i64> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; Expand SETUGE +-define void @v16i8_icmp_uge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v16i8_icmp_uge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vsle.bu $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %cmp = icmp uge <16 x i8> %v0, %v1 +- %ext = sext <16 x i1> %cmp to <16 x i8> +- store <16 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v8i16_icmp_uge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8i16_icmp_uge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vsle.hu $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %cmp = icmp uge <8 x i16> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i16> +- store <8 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v4i32_icmp_uge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4i32_icmp_uge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vsle.wu $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %cmp = icmp uge <4 x i32> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2i64_icmp_uge(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2i64_icmp_uge: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vsle.du $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %cmp = icmp uge <2 x i64> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; Expand SETGT +-define void @v16i8_icmp_sgt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v16i8_icmp_sgt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vslt.b $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %cmp = icmp sgt <16 x i8> %v0, %v1 +- %ext = sext <16 x i1> %cmp to <16 x i8> +- store <16 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v8i16_icmp_sgt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8i16_icmp_sgt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vslt.h $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %cmp = icmp sgt <8 x i16> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i16> +- store <8 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v4i32_icmp_sgt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4i32_icmp_sgt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vslt.w $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %cmp = icmp sgt <4 x i32> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2i64_icmp_sgt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2i64_icmp_sgt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vslt.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %cmp = icmp sgt <2 x i64> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +- +-;; Expand SETUGT +-define void @v16i8_icmp_ugt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v16i8_icmp_ugt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vslt.bu $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %cmp = icmp ugt <16 x i8> %v0, %v1 +- %ext = sext <16 x i1> %cmp to <16 x i8> +- store <16 x i8> %ext, ptr %res +- ret void +-} +- +-define void @v8i16_icmp_ugt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v8i16_icmp_ugt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vslt.hu $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %cmp = icmp ugt <8 x i16> %v0, %v1 +- %ext = sext <8 x i1> %cmp to <8 x i16> +- store <8 x i16> %ext, ptr %res +- ret void +-} +- +-define void @v4i32_icmp_ugt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v4i32_icmp_ugt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vslt.wu $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %cmp = icmp ugt <4 x i32> %v0, %v1 +- %ext = sext <4 x i1> %cmp to <4 x i32> +- store <4 x i32> %ext, ptr %res +- ret void +-} +- +-define void @v2i64_icmp_ugt(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: v2i64_icmp_ugt: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vslt.du $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %cmp = icmp ugt <2 x i64> %v0, %v1 +- %ext = sext <2 x i1> %cmp to <2 x i64> +- store <2 x i64> %ext, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/insertelement.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/insertelement.ll +deleted file mode 100644 +index a9834591a..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/insertelement.ll ++++ /dev/null +@@ -1,196 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @insert_16xi8(ptr %src, ptr %dst, i8 %ins) nounwind { +-; CHECK-LABEL: insert_16xi8: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vinsgr2vr.b $vr0, $a2, 1 +-; CHECK-NEXT: vst $vr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <16 x i8>, ptr %src +- %v_new = insertelement <16 x i8> %v, i8 %ins, i32 1 +- store <16 x i8> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_8xi16(ptr %src, ptr %dst, i16 %ins) nounwind { +-; CHECK-LABEL: insert_8xi16: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vinsgr2vr.h $vr0, $a2, 1 +-; CHECK-NEXT: vst $vr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <8 x i16>, ptr %src +- %v_new = insertelement <8 x i16> %v, i16 %ins, i32 1 +- store <8 x i16> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_4xi32(ptr %src, ptr %dst, i32 %ins) nounwind { +-; CHECK-LABEL: insert_4xi32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vinsgr2vr.w $vr0, $a2, 1 +-; CHECK-NEXT: vst $vr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <4 x i32>, ptr %src +- %v_new = insertelement <4 x i32> %v, i32 %ins, i32 1 +- store <4 x i32> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_2xi64(ptr %src, ptr %dst, i64 %ins) nounwind { +-; CHECK-LABEL: insert_2xi64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vinsgr2vr.d $vr0, $a2, 1 +-; CHECK-NEXT: vst $vr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <2 x i64>, ptr %src +- %v_new = insertelement <2 x i64> %v, i64 %ins, i32 1 +- store <2 x i64> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_4xfloat(ptr %src, ptr %dst, float %ins) nounwind { +-; CHECK-LABEL: insert_4xfloat: +-; CHECK: # %bb.0: +-; CHECK-NEXT: movfr2gr.s $a2, $fa0 +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vinsgr2vr.w $vr0, $a2, 1 +-; CHECK-NEXT: vst $vr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <4 x float>, ptr %src +- %v_new = insertelement <4 x float> %v, float %ins, i32 1 +- store <4 x float> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_2xdouble(ptr %src, ptr %dst, double %ins) nounwind { +-; CHECK-LABEL: insert_2xdouble: +-; CHECK: # %bb.0: +-; CHECK-NEXT: movfr2gr.d $a2, $fa0 +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vinsgr2vr.d $vr0, $a2, 1 +-; CHECK-NEXT: vst $vr0, $a1, 0 +-; CHECK-NEXT: ret +- %v = load volatile <2 x double>, ptr %src +- %v_new = insertelement <2 x double> %v, double %ins, i32 1 +- store <2 x double> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_16xi8_idx(ptr %src, ptr %dst, i8 %ins, i32 %idx) nounwind { +-; CHECK-LABEL: insert_16xi8_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vst $vr0, $sp, 0 +-; CHECK-NEXT: addi.d $a0, $sp, 0 +-; CHECK-NEXT: bstrins.d $a0, $a3, 3, 0 +-; CHECK-NEXT: st.b $a2, $a0, 0 +-; CHECK-NEXT: vld $vr0, $sp, 0 +-; CHECK-NEXT: vst $vr0, $a1, 0 +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +- %v = load volatile <16 x i8>, ptr %src +- %v_new = insertelement <16 x i8> %v, i8 %ins, i32 %idx +- store <16 x i8> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_8xi16_idx(ptr %src, ptr %dst, i16 %ins, i32 %idx) nounwind { +-; CHECK-LABEL: insert_8xi16_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vst $vr0, $sp, 0 +-; CHECK-NEXT: addi.d $a0, $sp, 0 +-; CHECK-NEXT: bstrins.d $a0, $a3, 3, 1 +-; CHECK-NEXT: st.h $a2, $a0, 0 +-; CHECK-NEXT: vld $vr0, $sp, 0 +-; CHECK-NEXT: vst $vr0, $a1, 0 +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +- %v = load volatile <8 x i16>, ptr %src +- %v_new = insertelement <8 x i16> %v, i16 %ins, i32 %idx +- store <8 x i16> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_4xi32_idx(ptr %src, ptr %dst, i32 %ins, i32 %idx) nounwind { +-; CHECK-LABEL: insert_4xi32_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vst $vr0, $sp, 0 +-; CHECK-NEXT: addi.d $a0, $sp, 0 +-; CHECK-NEXT: bstrins.d $a0, $a3, 3, 2 +-; CHECK-NEXT: st.w $a2, $a0, 0 +-; CHECK-NEXT: vld $vr0, $sp, 0 +-; CHECK-NEXT: vst $vr0, $a1, 0 +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +- %v = load volatile <4 x i32>, ptr %src +- %v_new = insertelement <4 x i32> %v, i32 %ins, i32 %idx +- store <4 x i32> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_2xi64_idx(ptr %src, ptr %dst, i64 %ins, i32 %idx) nounwind { +-; CHECK-LABEL: insert_2xi64_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: vld $vr0, $a0, 0 +-; CHECK-NEXT: vst $vr0, $sp, 0 +-; CHECK-NEXT: addi.d $a0, $sp, 0 +-; CHECK-NEXT: bstrins.d $a0, $a3, 3, 3 +-; CHECK-NEXT: st.d $a2, $a0, 0 +-; CHECK-NEXT: vld $vr0, $sp, 0 +-; CHECK-NEXT: vst $vr0, $a1, 0 +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +- %v = load volatile <2 x i64>, ptr %src +- %v_new = insertelement <2 x i64> %v, i64 %ins, i32 %idx +- store <2 x i64> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_4xfloat_idx(ptr %src, ptr %dst, float %ins, i32 %idx) nounwind { +-; CHECK-LABEL: insert_4xfloat_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: vld $vr1, $a0, 0 +-; CHECK-NEXT: vst $vr1, $sp, 0 +-; CHECK-NEXT: addi.d $a0, $sp, 0 +-; CHECK-NEXT: bstrins.d $a0, $a2, 3, 2 +-; CHECK-NEXT: fst.s $fa0, $a0, 0 +-; CHECK-NEXT: vld $vr0, $sp, 0 +-; CHECK-NEXT: vst $vr0, $a1, 0 +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +- %v = load volatile <4 x float>, ptr %src +- %v_new = insertelement <4 x float> %v, float %ins, i32 %idx +- store <4 x float> %v_new, ptr %dst +- ret void +-} +- +-define void @insert_2xdouble_idx(ptr %src, ptr %dst, double %ins, i32 %idx) nounwind { +-; CHECK-LABEL: insert_2xdouble_idx: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: vld $vr1, $a0, 0 +-; CHECK-NEXT: vst $vr1, $sp, 0 +-; CHECK-NEXT: addi.d $a0, $sp, 0 +-; CHECK-NEXT: bstrins.d $a0, $a2, 3, 3 +-; CHECK-NEXT: fst.d $fa0, $a0, 0 +-; CHECK-NEXT: vld $vr0, $sp, 0 +-; CHECK-NEXT: vst $vr0, $a1, 0 +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +- %v = load volatile <2 x double>, ptr %src +- %v_new = insertelement <2 x double> %v, double %ins, i32 %idx +- store <2 x double> %v_new, ptr %dst +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/lshr.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/lshr.ll +deleted file mode 100644 +index dada52f93..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/lshr.ll ++++ /dev/null +@@ -1,178 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @lshr_v16i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: lshr_v16i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsrl.b $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %v2 = lshr <16 x i8> %v0, %v1 +- store <16 x i8> %v2, ptr %res +- ret void +-} +- +-define void @lshr_v8i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: lshr_v8i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsrl.h $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %v2 = lshr <8 x i16> %v0, %v1 +- store <8 x i16> %v2, ptr %res +- ret void +-} +- +-define void @lshr_v4i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: lshr_v4i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsrl.w $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %v2 = lshr <4 x i32> %v0, %v1 +- store <4 x i32> %v2, ptr %res +- ret void +-} +- +-define void @lshr_v2i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: lshr_v2i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsrl.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %v2 = lshr <2 x i64> %v0, %v1 +- store <2 x i64> %v2, ptr %res +- ret void +-} +- +-define void @lshr_v16i8_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: lshr_v16i8_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrli.b $vr0, $vr0, 1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = lshr <16 x i8> %v0, +- store <16 x i8> %v1, ptr %res +- ret void +-} +- +-define void @lshr_v16i8_7(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: lshr_v16i8_7: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrli.b $vr0, $vr0, 7 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = lshr <16 x i8> %v0, +- store <16 x i8> %v1, ptr %res +- ret void +-} +- +-define void @lshr_v8i16_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: lshr_v8i16_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrli.h $vr0, $vr0, 1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = lshr <8 x i16> %v0, +- store <8 x i16> %v1, ptr %res +- ret void +-} +- +-define void @lshr_v8i16_15(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: lshr_v8i16_15: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrli.h $vr0, $vr0, 15 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = lshr <8 x i16> %v0, +- store <8 x i16> %v1, ptr %res +- ret void +-} +- +-define void @lshr_v4i32_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: lshr_v4i32_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrli.w $vr0, $vr0, 1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = lshr <4 x i32> %v0, +- store <4 x i32> %v1, ptr %res +- ret void +-} +- +-define void @lshr_v4i32_31(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: lshr_v4i32_31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrli.w $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = lshr <4 x i32> %v0, +- store <4 x i32> %v1, ptr %res +- ret void +-} +- +-define void @lshr_v2i64_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: lshr_v2i64_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrli.d $vr0, $vr0, 1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = lshr <2 x i64> %v0, +- store <2 x i64> %v1, ptr %res +- ret void +-} +- +-define void @lshr_v2i64_63(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: lshr_v2i64_63: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrli.d $vr0, $vr0, 63 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = lshr <2 x i64> %v0, +- store <2 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/mul.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/mul.ll +deleted file mode 100644 +index d0be9cb7e..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/mul.ll ++++ /dev/null +@@ -1,238 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @mul_v16i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mul_v16i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vmul.b $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %v2 = mul <16 x i8> %v0, %v1 +- store <16 x i8> %v2, ptr %res +- ret void +-} +- +-define void @mul_v8i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mul_v8i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vmul.h $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %v2 = mul <8 x i16> %v0, %v1 +- store <8 x i16> %v2, ptr %res +- ret void +-} +- +-define void @mul_v4i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mul_v4i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vmul.w $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %v2 = mul <4 x i32> %v0, %v1 +- store <4 x i32> %v2, ptr %res +- ret void +-} +- +-define void @mul_v2i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mul_v2i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vmul.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %v2 = mul <2 x i64> %v0, %v1 +- store <2 x i64> %v2, ptr %res +- ret void +-} +- +-define void @mul_square_v16i8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_square_v16i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vmul.b $vr0, $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = mul <16 x i8> %v0, %v0 +- store <16 x i8> %v1, ptr %res +- ret void +-} +- +-define void @mul_square_v8i16(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_square_v8i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vmul.h $vr0, $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = mul <8 x i16> %v0, %v0 +- store <8 x i16> %v1, ptr %res +- ret void +-} +- +-define void @mul_square_v4i32(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_square_v4i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vmul.w $vr0, $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = mul <4 x i32> %v0, %v0 +- store <4 x i32> %v1, ptr %res +- ret void +-} +- +-define void @mul_square_v2i64(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_square_v2i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vmul.d $vr0, $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = mul <2 x i64> %v0, %v0 +- store <2 x i64> %v1, ptr %res +- ret void +-} +- +-define void @mul_v16i8_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_v16i8_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslli.b $vr0, $vr0, 3 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = mul <16 x i8> %v0, +- store <16 x i8> %v1, ptr %res +- ret void +-} +- +-define void @mul_v8i16_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_v8i16_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslli.h $vr0, $vr0, 3 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = mul <8 x i16> %v0, +- store <8 x i16> %v1, ptr %res +- ret void +-} +- +-define void @mul_v4i32_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_v4i32_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslli.w $vr0, $vr0, 3 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = mul <4 x i32> %v0, +- store <4 x i32> %v1, ptr %res +- ret void +-} +- +-define void @mul_v2i64_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_v2i64_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslli.d $vr0, $vr0, 3 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = mul <2 x i64> %v0, +- store <2 x i64> %v1, ptr %res +- ret void +-} +- +-define void @mul_v16i8_17(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_v16i8_17: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vrepli.b $vr1, 17 +-; CHECK-NEXT: vmul.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = mul <16 x i8> %v0, +- store <16 x i8> %v1, ptr %res +- ret void +-} +- +-define void @mul_v8i16_17(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_v8i16_17: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vrepli.h $vr1, 17 +-; CHECK-NEXT: vmul.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = mul <8 x i16> %v0, +- store <8 x i16> %v1, ptr %res +- ret void +-} +- +-define void @mul_v4i32_17(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_v4i32_17: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vrepli.w $vr1, 17 +-; CHECK-NEXT: vmul.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = mul <4 x i32> %v0, +- store <4 x i32> %v1, ptr %res +- ret void +-} +- +-define void @mul_v2i64_17(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: mul_v2i64_17: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vrepli.d $vr1, 17 +-; CHECK-NEXT: vmul.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = mul <2 x i64> %v0, +- store <2 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/or.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/or.ll +deleted file mode 100644 +index f124512ac..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/or.ll ++++ /dev/null +@@ -1,125 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @or_v16i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: or_v16i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vor.v $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %v2 = or <16 x i8> %v0, %v1 +- store <16 x i8> %v2, ptr %res +- ret void +-} +- +-define void @or_v8i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: or_v8i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vor.v $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %v2 = or <8 x i16> %v0, %v1 +- store <8 x i16> %v2, ptr %res +- ret void +-} +- +-define void @or_v4i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: or_v4i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vor.v $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %v2 = or <4 x i32> %v0, %v1 +- store <4 x i32> %v2, ptr %res +- ret void +-} +- +-define void @or_v2i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: or_v2i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vor.v $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %v2 = or <2 x i64> %v0, %v1 +- store <2 x i64> %v2, ptr %res +- ret void +-} +- +-define void @or_u_v16i8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: or_u_v16i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vori.b $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = or <16 x i8> %v0, +- store <16 x i8> %v1, ptr %res +- ret void +-} +- +-define void @or_u_v8i16(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: or_u_v8i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vrepli.h $vr1, 31 +-; CHECK-NEXT: vor.v $vr0, $vr0, $vr1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = or <8 x i16> %v0, +- store <8 x i16> %v1, ptr %res +- ret void +-} +- +-define void @or_u_v4i32(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: or_u_v4i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vrepli.w $vr1, 31 +-; CHECK-NEXT: vor.v $vr0, $vr0, $vr1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = or <4 x i32> %v0, +- store <4 x i32> %v1, ptr %res +- ret void +-} +- +-define void @or_u_v2i64(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: or_u_v2i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vrepli.d $vr1, 31 +-; CHECK-NEXT: vor.v $vr0, $vr0, $vr1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = or <2 x i64> %v0, +- store <2 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/sdiv.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/sdiv.ll +deleted file mode 100644 +index b68f73a74..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/sdiv.ll ++++ /dev/null +@@ -1,134 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @sdiv_v16i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: sdiv_v16i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vdiv.b $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %v2 = sdiv <16 x i8> %v0, %v1 +- store <16 x i8> %v2, ptr %res +- ret void +-} +- +-define void @sdiv_v8i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: sdiv_v8i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vdiv.h $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %v2 = sdiv <8 x i16> %v0, %v1 +- store <8 x i16> %v2, ptr %res +- ret void +-} +- +-define void @sdiv_v4i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: sdiv_v4i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vdiv.w $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %v2 = sdiv <4 x i32> %v0, %v1 +- store <4 x i32> %v2, ptr %res +- ret void +-} +- +-define void @sdiv_v2i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: sdiv_v2i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vdiv.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %v2 = sdiv <2 x i64> %v0, %v1 +- store <2 x i64> %v2, ptr %res +- ret void +-} +- +-define void @sdiv_v16i8_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: sdiv_v16i8_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrai.b $vr1, $vr0, 7 +-; CHECK-NEXT: vsrli.b $vr1, $vr1, 5 +-; CHECK-NEXT: vadd.b $vr0, $vr0, $vr1 +-; CHECK-NEXT: vsrai.b $vr0, $vr0, 3 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = sdiv <16 x i8> %v0, +- store <16 x i8> %v1, ptr %res +- ret void +-} +- +-define void @sdiv_v8i16_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: sdiv_v8i16_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrai.h $vr1, $vr0, 15 +-; CHECK-NEXT: vsrli.h $vr1, $vr1, 13 +-; CHECK-NEXT: vadd.h $vr0, $vr0, $vr1 +-; CHECK-NEXT: vsrai.h $vr0, $vr0, 3 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = sdiv <8 x i16> %v0, +- store <8 x i16> %v1, ptr %res +- ret void +-} +- +-define void @sdiv_v4i32_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: sdiv_v4i32_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrai.w $vr1, $vr0, 31 +-; CHECK-NEXT: vsrli.w $vr1, $vr1, 29 +-; CHECK-NEXT: vadd.w $vr0, $vr0, $vr1 +-; CHECK-NEXT: vsrai.w $vr0, $vr0, 3 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = sdiv <4 x i32> %v0, +- store <4 x i32> %v1, ptr %res +- ret void +-} +- +-define void @sdiv_v2i64_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: sdiv_v2i64_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrai.d $vr1, $vr0, 63 +-; CHECK-NEXT: vsrli.d $vr1, $vr1, 61 +-; CHECK-NEXT: vadd.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: vsrai.d $vr0, $vr0, 3 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = sdiv <2 x i64> %v0, +- store <2 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/shl.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/shl.ll +deleted file mode 100644 +index fa0aebaf2..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/shl.ll ++++ /dev/null +@@ -1,178 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @shl_v16i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: shl_v16i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsll.b $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %v2 = shl <16 x i8> %v0, %v1 +- store <16 x i8> %v2, ptr %res +- ret void +-} +- +-define void @shl_v8i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: shl_v8i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsll.h $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %v2 = shl <8 x i16> %v0, %v1 +- store <8 x i16> %v2, ptr %res +- ret void +-} +- +-define void @shl_v4i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: shl_v4i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsll.w $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %v2 = shl <4 x i32> %v0, %v1 +- store <4 x i32> %v2, ptr %res +- ret void +-} +- +-define void @shl_v2i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: shl_v2i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsll.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %v2 = shl <2 x i64> %v0, %v1 +- store <2 x i64> %v2, ptr %res +- ret void +-} +- +-define void @shl_v16i8_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: shl_v16i8_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslli.b $vr0, $vr0, 1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = shl <16 x i8> %v0, +- store <16 x i8> %v1, ptr %res +- ret void +-} +- +-define void @shl_v16i8_7(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: shl_v16i8_7: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslli.b $vr0, $vr0, 7 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = shl <16 x i8> %v0, +- store <16 x i8> %v1, ptr %res +- ret void +-} +- +-define void @shl_v8i16_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: shl_v8i16_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslli.h $vr0, $vr0, 1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = shl <8 x i16> %v0, +- store <8 x i16> %v1, ptr %res +- ret void +-} +- +-define void @shl_v8i16_15(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: shl_v8i16_15: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslli.h $vr0, $vr0, 15 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = shl <8 x i16> %v0, +- store <8 x i16> %v1, ptr %res +- ret void +-} +- +-define void @shl_v4i32_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: shl_v4i32_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslli.w $vr0, $vr0, 1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = shl <4 x i32> %v0, +- store <4 x i32> %v1, ptr %res +- ret void +-} +- +-define void @shl_v4i32_31(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: shl_v4i32_31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslli.w $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = shl <4 x i32> %v0, +- store <4 x i32> %v1, ptr %res +- ret void +-} +- +-define void @shl_v2i64_1(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: shl_v2i64_1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslli.d $vr0, $vr0, 1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = shl <2 x i64> %v0, +- store <2 x i64> %v1, ptr %res +- ret void +-} +- +-define void @shl_v2i64_63(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: shl_v2i64_63: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vslli.d $vr0, $vr0, 63 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = shl <2 x i64> %v0, +- store <2 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/sitofp.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/sitofp.ll +deleted file mode 100644 +index 1e820a37a..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/sitofp.ll ++++ /dev/null +@@ -1,28 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @sitofp_v4i32_v4f32(ptr %res, ptr %in){ +-; CHECK-LABEL: sitofp_v4i32_v4f32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vffint.s.w $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i32>, ptr %in +- %v1 = sitofp <4 x i32> %v0 to <4 x float> +- store <4 x float> %v1, ptr %res +- ret void +-} +- +-define void @sitofp_v2i64_v2f64(ptr %res, ptr %in){ +-; CHECK-LABEL: sitofp_v2i64_v2f64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vffint.d.l $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x i64>, ptr %in +- %v1 = sitofp <2 x i64> %v0 to <2 x double> +- store <2 x double> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/sub.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/sub.ll +deleted file mode 100644 +index 25b4623a4..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/sub.ll ++++ /dev/null +@@ -1,122 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @sub_v16i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: sub_v16i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsub.b $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %v2 = sub <16 x i8> %v0, %v1 +- store <16 x i8> %v2, ptr %res +- ret void +-} +- +-define void @sub_v8i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: sub_v8i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsub.h $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %v2 = sub <8 x i16> %v0, %v1 +- store <8 x i16> %v2, ptr %res +- ret void +-} +- +-define void @sub_v4i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: sub_v4i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsub.w $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %v2 = sub <4 x i32> %v0, %v1 +- store <4 x i32> %v2, ptr %res +- ret void +-} +- +-define void @sub_v2i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: sub_v2i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vsub.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %v2 = sub <2 x i64> %v0, %v1 +- store <2 x i64> %v2, ptr %res +- ret void +-} +- +-define void @sub_v16i8_31(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: sub_v16i8_31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsubi.bu $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = sub <16 x i8> %v0, +- store <16 x i8> %v1, ptr %res +- ret void +-} +- +-define void @sub_v8i16_31(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: sub_v8i16_31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsubi.hu $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = sub <8 x i16> %v0, +- store <8 x i16> %v1, ptr %res +- ret void +-} +- +-define void @sub_v4i32_31(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: sub_v4i32_31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsubi.wu $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = sub <4 x i32> %v0, +- store <4 x i32> %v1, ptr %res +- ret void +-} +- +-define void @sub_v2i64_31(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: sub_v2i64_31: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsubi.du $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = sub <2 x i64> %v0, +- store <2 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/udiv.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/udiv.ll +deleted file mode 100644 +index abb60b91d..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/udiv.ll ++++ /dev/null +@@ -1,122 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @udiv_v16i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: udiv_v16i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vdiv.bu $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %v2 = udiv <16 x i8> %v0, %v1 +- store <16 x i8> %v2, ptr %res +- ret void +-} +- +-define void @udiv_v8i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: udiv_v8i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vdiv.hu $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %v2 = udiv <8 x i16> %v0, %v1 +- store <8 x i16> %v2, ptr %res +- ret void +-} +- +-define void @udiv_v4i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: udiv_v4i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vdiv.wu $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %v2 = udiv <4 x i32> %v0, %v1 +- store <4 x i32> %v2, ptr %res +- ret void +-} +- +-define void @udiv_v2i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: udiv_v2i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vdiv.du $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %v2 = udiv <2 x i64> %v0, %v1 +- store <2 x i64> %v2, ptr %res +- ret void +-} +- +-define void @udiv_v16i8_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: udiv_v16i8_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrli.b $vr0, $vr0, 3 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = udiv <16 x i8> %v0, +- store <16 x i8> %v1, ptr %res +- ret void +-} +- +-define void @udiv_v8i16_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: udiv_v8i16_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrli.h $vr0, $vr0, 3 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = udiv <8 x i16> %v0, +- store <8 x i16> %v1, ptr %res +- ret void +-} +- +-define void @udiv_v4i32_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: udiv_v4i32_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrli.w $vr0, $vr0, 3 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = udiv <4 x i32> %v0, +- store <4 x i32> %v1, ptr %res +- ret void +-} +- +-define void @udiv_v2i64_8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: udiv_v2i64_8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vsrli.d $vr0, $vr0, 3 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = udiv <2 x i64> %v0, +- store <2 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/uitofp.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/uitofp.ll +deleted file mode 100644 +index 3d4913f12..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/uitofp.ll ++++ /dev/null +@@ -1,28 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @uitofp_v4i32_v4f32(ptr %res, ptr %in){ +-; CHECK-LABEL: uitofp_v4i32_v4f32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vffint.s.wu $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i32>, ptr %in +- %v1 = uitofp <4 x i32> %v0 to <4 x float> +- store <4 x float> %v1, ptr %res +- ret void +-} +- +-define void @uitofp_v2i64_v2f64(ptr %res, ptr %in){ +-; CHECK-LABEL: uitofp_v2i64_v2f64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vffint.d.lu $vr0, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x i64>, ptr %in +- %v1 = uitofp <2 x i64> %v0 to <2 x double> +- store <2 x double> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/xor.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/xor.ll +deleted file mode 100644 +index ce3e49c99..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/xor.ll ++++ /dev/null +@@ -1,125 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @xor_v16i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: xor_v16i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vxor.v $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %v2 = xor <16 x i8> %v0, %v1 +- store <16 x i8> %v2, ptr %res +- ret void +-} +- +-define void @xor_v8i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: xor_v8i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vxor.v $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %v2 = xor <8 x i16> %v0, %v1 +- store <8 x i16> %v2, ptr %res +- ret void +-} +- +-define void @xor_v4i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: xor_v4i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vxor.v $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %v2 = xor <4 x i32> %v0, %v1 +- store <4 x i32> %v2, ptr %res +- ret void +-} +- +-define void @xor_v2i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: xor_v2i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vxor.v $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %v2 = xor <2 x i64> %v0, %v1 +- store <2 x i64> %v2, ptr %res +- ret void +-} +- +-define void @xor_u_v16i8(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: xor_u_v16i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vxori.b $vr0, $vr0, 31 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = xor <16 x i8> %v0, +- store <16 x i8> %v1, ptr %res +- ret void +-} +- +-define void @xor_u_v8i16(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: xor_u_v8i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vrepli.h $vr1, 31 +-; CHECK-NEXT: vxor.v $vr0, $vr0, $vr1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = xor <8 x i16> %v0, +- store <8 x i16> %v1, ptr %res +- ret void +-} +- +-define void @xor_u_v4i32(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: xor_u_v4i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vrepli.w $vr1, 31 +-; CHECK-NEXT: vxor.v $vr0, $vr0, $vr1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = xor <4 x i32> %v0, +- store <4 x i32> %v1, ptr %res +- ret void +-} +- +-define void @xor_u_v2i64(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: xor_u_v2i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vrepli.d $vr1, 31 +-; CHECK-NEXT: vxor.v $vr0, $vr0, $vr1 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = xor <2 x i64> %v0, +- store <2 x i64> %v1, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/logic-lsx.ll b/llvm/test/CodeGen/LoongArch/lsx/logic-lsx.ll +new file mode 100644 +index 000000000..0dd29b27e +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lsx/logic-lsx.ll +@@ -0,0 +1,132 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lsx < %s | FileCheck %s ++ ++define <2 x i64> @not_v2i64(<2 x i64> %a) { ++; CHECK-LABEL: not_v2i64: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vnor.v $vr0, $vr0, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <2 x i64> %a, ++ ret <2 x i64> %not ++} ++ ++define <4 x i32> @not_v4i32(<4 x i32> %a) { ++; CHECK-LABEL: not_v4i32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vnor.v $vr0, $vr0, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <4 x i32> %a, ++ ret <4 x i32> %not ++} ++ ++define <8 x i16> @not_v8i16(<8 x i16> %a) { ++; CHECK-LABEL: not_v8i16: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vnor.v $vr0, $vr0, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <8 x i16> %a, ++ ret <8 x i16> %not ++} ++ ++define <16 x i8> @not_v16i8(<16 x i8> %a) { ++; CHECK-LABEL: not_v16i8: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vxori.b $vr0, $vr0, 255 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <16 x i8> %a, ++ ret <16 x i8> %not ++} ++ ++ ++define <2 x i64> @andn_v2i64(<2 x i64> %a, <2 x i64> %b) { ++; CHECK-LABEL: andn_v2i64: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vandn.v $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <2 x i64> %b, ++ %and = and <2 x i64> %not, %a ++ ret <2 x i64> %and ++} ++ ++define <4 x i32> @andn_v4i32(<4 x i32> %a, <4 x i32> %b) { ++; CHECK-LABEL: andn_v4i32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vandn.v $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <4 x i32> %b, ++ %and = and <4 x i32> %not, %a ++ ret <4 x i32> %and ++} ++ ++define <8 x i16> @andn_v8i16(<8 x i16> %a, <8 x i16> %b) { ++; CHECK-LABEL: andn_v8i16: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vandn.v $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <8 x i16> %b, ++ %and = and <8 x i16> %not, %a ++ ret <8 x i16> %and ++} ++ ++define <16 x i8> @andn_v16i8(<16 x i8> %a, <16 x i8> %b) { ++; CHECK-LABEL: andn_v16i8: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vandn.v $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <16 x i8> %b, ++ %and = and <16 x i8> %not, %a ++ ret <16 x i8> %and ++} ++ ++ ++define <2 x i64> @orn_v2i64(<2 x i64> %a, <2 x i64> %b) { ++; CHECK-LABEL: orn_v2i64: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vorn.v $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <2 x i64> %b, ++ %or = or <2 x i64> %not, %a ++ ret <2 x i64> %or ++} ++ ++define <4 x i32> @orn_v4i32(<4 x i32> %a, <4 x i32> %b) { ++; CHECK-LABEL: orn_v4i32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vorn.v $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <4 x i32> %b, ++ %or = or <4 x i32> %not, %a ++ ret <4 x i32> %or ++} ++ ++define <8 x i16> @orn_v8i16(<8 x i16> %a, <8 x i16> %b) { ++; CHECK-LABEL: orn_v8i16: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vorn.v $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <8 x i16> %b, ++ %or = or <8 x i16> %not, %a ++ ret <8 x i16> %or ++} ++ ++define <16 x i8> @orn_v16i8(<16 x i8> %a, <16 x i8> %b) { ++; CHECK-LABEL: orn_v16i8: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vorn.v $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %not = xor <16 x i8> %b, ++ %or = or <16 x i8> %not, %a ++ ret <16 x i8> %or ++} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/lsxvavg.ll b/llvm/test/CodeGen/LoongArch/lsx/lsxvavg.ll +new file mode 100644 +index 000000000..8441ed1b0 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lsx/lsxvavg.ll +@@ -0,0 +1,106 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lsx < %s | FileCheck %s ++ ++define <16 x i8> @lsxvavg_v16i8(<16 x i8> noundef %0, <16 x i8> noundef %1) local_unnamed_addr #0 { ++; CHECK-LABEL: lsxvavg_v16i8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vadd.b $vr0, $vr0, $vr1 ++; CHECK-NEXT: vldi $vr1, 1 ++; CHECK-NEXT: vavg.b $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %3 = add <16 x i8> %0, ++ %4 = add <16 x i8> %3, %1 ++ %5 = sdiv <16 x i8> %4, ++ ret <16 x i8> %5 ++} ++ ++define <8 x i16> @lsxvavg_v8i16(<8 x i16> noundef %0, <8 x i16> noundef %1) local_unnamed_addr #0 { ++; CHECK-LABEL: lsxvavg_v8i16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vadd.h $vr0, $vr0, $vr1 ++; CHECK-NEXT: vldi $vr1, 1 ++; CHECK-NEXT: vavg.h $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %3 = add <8 x i16> %0, ++ %4 = add <8 x i16> %3, %1 ++ %5 = sdiv <8 x i16> %4, ++ ret <8 x i16> %5 ++} ++ ++define <4 x i32> @lsxvavg_v4i32(<4 x i32> noundef %0, <4 x i32> noundef %1) local_unnamed_addr #0 { ++; CHECK-LABEL: lsxvavg_v4i32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vadd.w $vr0, $vr0, $vr1 ++; CHECK-NEXT: vldi $vr1, 1 ++; CHECK-NEXT: vavg.w $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %3 = add <4 x i32> %0, ++ %4 = add <4 x i32> %3, %1 ++ %5 = sdiv <4 x i32> %4, ++ ret <4 x i32> %5 ++} ++ ++define <2 x i64> @lsxvavg_v2i64(<2 x i64> noundef %0, <2 x i64> noundef %1) local_unnamed_addr #0 { ++; CHECK-LABEL: lsxvavg_v2i64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vadd.d $vr0, $vr0, $vr1 ++; CHECK-NEXT: vldi $vr1, 1 ++; CHECK-NEXT: vavg.d $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %3 = add <2 x i64> %0, ++ %4 = add <2 x i64> %3, %1 ++ %5 = sdiv <2 x i64> %4, ++ ret <2 x i64> %5 ++} ++ ++define <16 x i8> @lsxvavg_v16u8(<16 x i8> noundef %0, <16 x i8> noundef %1) local_unnamed_addr #0 { ++; CHECK-LABEL: lsxvavg_v16u8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vadd.b $vr0, $vr0, $vr1 ++; CHECK-NEXT: vldi $vr1, 1 ++; CHECK-NEXT: vavg.bu $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %3 = add <16 x i8> %0, ++ %4 = add <16 x i8> %3, %1 ++ %5 = lshr <16 x i8> %4, ++ ret <16 x i8> %5 ++} ++ ++define <8 x i16> @lsxvavg_v8u16(<8 x i16> noundef %0, <8 x i16> noundef %1) local_unnamed_addr #0 { ++; CHECK-LABEL: lsxvavg_v8u16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vadd.h $vr0, $vr0, $vr1 ++; CHECK-NEXT: vldi $vr1, 1 ++; CHECK-NEXT: vavg.hu $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %3 = add <8 x i16> %0, ++ %4 = add <8 x i16> %3, %1 ++ %5 = lshr <8 x i16> %4, ++ ret <8 x i16> %5 ++} ++ ++define <4 x i32> @lsxvavg_v4u32(<4 x i32> noundef %0, <4 x i32> noundef %1) local_unnamed_addr #0 { ++; CHECK-LABEL: lsxvavg_v4u32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vadd.w $vr0, $vr0, $vr1 ++; CHECK-NEXT: vldi $vr1, 1 ++; CHECK-NEXT: vavg.wu $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %3 = add <4 x i32> %0, ++ %4 = add <4 x i32> %3, %1 ++ %5 = lshr <4 x i32> %4, ++ ret <4 x i32> %5 ++} ++ ++define <2 x i64> @lsxvavg_v2u64(<2 x i64> noundef %0, <2 x i64> noundef %1) local_unnamed_addr #0 { ++; CHECK-LABEL: lsxvavg_v2u64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vadd.d $vr0, $vr0, $vr1 ++; CHECK-NEXT: vldi $vr1, 1 ++; CHECK-NEXT: vavg.du $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %3 = add <2 x i64> %0, ++ %4 = add <2 x i64> %3, %1 ++ %5 = lshr <2 x i64> %4, ++ ret <2 x i64> %5 ++} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/lsxvclr.ll b/llvm/test/CodeGen/LoongArch/lsx/lsxvclr.ll +new file mode 100644 +index 000000000..951254baa +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lsx/lsxvclr.ll +@@ -0,0 +1,50 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lsx < %s | FileCheck %s ++ ++define <16 x i8> @clri8(<16 x i8> %b, <16 x i8> %c) { ++; CHECK-LABEL: clri8: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vbitclr.b $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %shl = shl <16 x i8> , %c ++ %xor = xor <16 x i8> %shl, ++ %and = and <16 x i8> %xor, %b ++ ret <16 x i8> %and ++} ++ ++define <8 x i16> @clri16(<8 x i16> %b, <8 x i16> %c) { ++; CHECK-LABEL: clri16: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vbitclr.h $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %shl = shl <8 x i16> , %c ++ %xor = xor <8 x i16> %shl, ++ %and = and <8 x i16> %xor, %b ++ ret <8 x i16> %and ++} ++ ++define <4 x i32> @clri32(<4 x i32> %b, <4 x i32> %c) { ++; CHECK-LABEL: clri32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vbitclr.w $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %shl = shl <4 x i32> , %c ++ %xor = xor <4 x i32> %shl, ++ %and = and <4 x i32> %xor, %b ++ ret <4 x i32> %and ++} ++ ++define <2 x i64> @clri64(<2 x i64> %b, <2 x i64> %c) { ++; CHECK-LABEL: clri64: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vbitclr.d $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++entry: ++ %shl = shl <2 x i64> , %c ++ %xor = xor <2 x i64> %shl, ++ %and = and <2 x i64> %xor, %b ++ ret <2 x i64> %and ++} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/mulh.ll b/llvm/test/CodeGen/LoongArch/lsx/mulh.ll +deleted file mode 100644 +index e1388f00e..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/mulh.ll ++++ /dev/null +@@ -1,162 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @mulhs_v16i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mulhs_v16i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vmuh.b $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %v0s = sext <16 x i8> %v0 to <16 x i16> +- %v1s = sext <16 x i8> %v1 to <16 x i16> +- %m = mul <16 x i16> %v0s, %v1s +- %s = ashr <16 x i16> %m, +- %v2 = trunc <16 x i16> %s to <16 x i8> +- store <16 x i8> %v2, ptr %res +- ret void +-} +- +-define void @mulhu_v16i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mulhu_v16i8: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vmuh.bu $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %v0z = zext <16 x i8> %v0 to <16 x i16> +- %v1z = zext <16 x i8> %v1 to <16 x i16> +- %m = mul <16 x i16> %v0z, %v1z +- %s = lshr <16 x i16> %m, +- %v2 = trunc <16 x i16> %s to <16 x i8> +- store <16 x i8> %v2, ptr %res +- ret void +-} +- +-define void @mulhs_v8i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mulhs_v8i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vmuh.h $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %v0s = sext <8 x i16> %v0 to <8 x i32> +- %v1s = sext <8 x i16> %v1 to <8 x i32> +- %m = mul <8 x i32> %v0s, %v1s +- %s = ashr <8 x i32> %m, +- %v2 = trunc <8 x i32> %s to <8 x i16> +- store <8 x i16> %v2, ptr %res +- ret void +-} +- +-define void @mulhu_v8i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mulhu_v8i16: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vmuh.hu $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %v0z = zext <8 x i16> %v0 to <8 x i32> +- %v1z = zext <8 x i16> %v1 to <8 x i32> +- %m = mul <8 x i32> %v0z, %v1z +- %s = lshr <8 x i32> %m, +- %v2 = trunc <8 x i32> %s to <8 x i16> +- store <8 x i16> %v2, ptr %res +- ret void +-} +- +-define void @mulhs_v4i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mulhs_v4i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vmuh.w $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %v0s = sext <4 x i32> %v0 to <4 x i64> +- %v1s = sext <4 x i32> %v1 to <4 x i64> +- %m = mul <4 x i64> %v0s, %v1s +- %s = ashr <4 x i64> %m, +- %v2 = trunc <4 x i64> %s to <4 x i32> +- store <4 x i32> %v2, ptr %res +- ret void +-} +- +-define void @mulhu_v4i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mulhu_v4i32: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vmuh.wu $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %v0z = zext <4 x i32> %v0 to <4 x i64> +- %v1z = zext <4 x i32> %v1 to <4 x i64> +- %m = mul <4 x i64> %v0z, %v1z +- %s = lshr <4 x i64> %m, +- %v2 = trunc <4 x i64> %s to <4 x i32> +- store <4 x i32> %v2, ptr %res +- ret void +-} +- +-define void @mulhs_v2i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mulhs_v2i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vmuh.d $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %v0s = sext <2 x i64> %v0 to <2 x i128> +- %v1s = sext <2 x i64> %v1 to <2 x i128> +- %m = mul <2 x i128> %v0s, %v1s +- %s = ashr <2 x i128> %m, +- %v2 = trunc <2 x i128> %s to <2 x i64> +- store <2 x i64> %v2, ptr %res +- ret void +-} +- +-define void @mulhu_v2i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: mulhu_v2i64: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vld $vr0, $a2, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vmuh.du $vr0, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +-entry: +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %v0z = zext <2 x i64> %v0 to <2 x i128> +- %v1z = zext <2 x i64> %v1 to <2 x i128> +- %m = mul <2 x i128> %v0z, %v1z +- %s = lshr <2 x i128> %m, +- %v2 = trunc <2 x i128> %s to <2 x i64> +- store <2 x i64> %v2, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/set-lsx.ll b/llvm/test/CodeGen/LoongArch/lsx/set-lsx.ll +new file mode 100644 +index 000000000..69f19297d +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lsx/set-lsx.ll +@@ -0,0 +1,38 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lsx < %s | FileCheck %s ++ ++define <16 x i8> @seti8(<16 x i8>) { ++; CHECK-LABEL: seti8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vbitseti.b $vr0, $vr0, 6 ++; CHECK-NEXT: jr $ra ++ %2 = or <16 x i8> %0, ++ ret <16 x i8> %2 ++} ++ ++define <8 x i16> @seti16(<8 x i16>) { ++; CHECK-LABEL: seti16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vbitseti.h $vr0, $vr0, 6 ++; CHECK-NEXT: jr $ra ++ %2 = or <8 x i16> %0, ++ ret <8 x i16> %2 ++} ++ ++define <4 x i32> @seti32(<4 x i32>) { ++; CHECK-LABEL: seti32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vbitseti.w $vr0, $vr0, 6 ++; CHECK-NEXT: jr $ra ++ %2 = or <4 x i32> %0, ++ ret <4 x i32> %2 ++} ++ ++define <2 x i64> @seti64(<2 x i64>) { ++; CHECK-LABEL: seti64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vbitseti.d $vr0, $vr0, 6 ++; CHECK-NEXT: jr $ra ++ %2 = or <2 x i64> %0, ++ ret <2 x i64> %2 ++} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/v16i8-bswap.ll b/llvm/test/CodeGen/LoongArch/lsx/v16i8-bswap.ll +new file mode 100644 +index 000000000..25e4eb072 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lsx/v16i8-bswap.ll +@@ -0,0 +1,20 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s ++ ++define void @vshf_v16i8(ptr %res, ptr %a0) nounwind { ++; CHECK-LABEL: vshf_v16i8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vld $vr0, $r5, 0 ++; CHECK-NEXT: vpickve2gr.d $r5, $vr0, 0 ++; CHECK-NEXT: vpickve2gr.d $r6, $vr0, 1 ++; CHECK-NEXT: revb.d $r6, $r6 ++; CHECK-NEXT: revb.d $r5, $r5 ++; CHECK-NEXT: vinsgr2vr.d $vr0, $r5, 0 ++; CHECK-NEXT: vinsgr2vr.d $vr0, $r6, 1 ++; CHECK-NEXT: vst $vr0, $r4, 0 ++; CHECK-NEXT: jr $ra ++ %v1 = load <16 x i8>, ptr %a0 ++ %v2 = shufflevector <16 x i8> %v1, <16 x i8> undef, <16 x i32> ++ store <16 x i8> %v2, ptr %res ++ ret void ++} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/vabsd.ll b/llvm/test/CodeGen/LoongArch/lsx/vabsd.ll +new file mode 100644 +index 000000000..86201ae0f +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lsx/vabsd.ll +@@ -0,0 +1,262 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lsx < %s | FileCheck %s ++ ++define <16 x i8> @vabsd_b(<16 x i8> %a, <16 x i8> %b) { ++; CHECK-LABEL: vabsd_b: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vabsd.b $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp sgt <16 x i8> %b, %a ++ %subba = sub <16 x i8> %b, %a ++ %subab = sub <16 x i8> %a, %b ++ %select = select <16 x i1> %icmp, <16 x i8> %subba, <16 x i8> %subab ++ ret <16 x i8> %select ++} ++ ++define <8 x i16> @vabsd_h(<8 x i16> %a, <8 x i16> %b) { ++; CHECK-LABEL: vabsd_h: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vabsd.h $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp sgt <8 x i16> %b, %a ++ %subba = sub <8 x i16> %b, %a ++ %subab = sub <8 x i16> %a, %b ++ %select = select <8 x i1> %icmp, <8 x i16> %subba, <8 x i16> %subab ++ ret <8 x i16> %select ++} ++ ++define <8 x i8> @vabsd_h_v8i8(<8 x i8> %a, <8 x i8> %b) { ++; CHECK-LABEL: vabsd_h_v8i8: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vabsd.h $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp sgt <8 x i8> %b, %a ++ %subba = sub <8 x i8> %b, %a ++ %subab = sub <8 x i8> %a, %b ++ %select = select <8 x i1> %icmp, <8 x i8> %subba, <8 x i8> %subab ++ ret <8 x i8> %select ++} ++ ++define <4 x i32> @vabsd_w(<4 x i32> %a, <4 x i32> %b) { ++; CHECK-LABEL: vabsd_w: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vabsd.w $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp sgt <4 x i32> %b, %a ++ %subba = sub <4 x i32> %b, %a ++ %subab = sub <4 x i32> %a, %b ++ %select = select <4 x i1> %icmp, <4 x i32> %subba, <4 x i32> %subab ++ ret <4 x i32> %select ++} ++ ++define <4 x i16> @vabsd_w_v4i16(<4 x i16> %a, <4 x i16> %b) { ++; CHECK-LABEL: vabsd_w_v4i16: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vabsd.w $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp sgt <4 x i16> %b, %a ++ %subba = sub <4 x i16> %b, %a ++ %subab = sub <4 x i16> %a, %b ++ %select = select <4 x i1> %icmp, <4 x i16> %subba, <4 x i16> %subab ++ ret <4 x i16> %select ++} ++ ++define <4 x i8> @vabsd_w_v4i8(<4 x i8> %a, <4 x i8> %b) { ++; CHECK-LABEL: vabsd_w_v4i8: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vabsd.w $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp sgt <4 x i8> %b, %a ++ %subba = sub <4 x i8> %b, %a ++ %subab = sub <4 x i8> %a, %b ++ %select = select <4 x i1> %icmp, <4 x i8> %subba, <4 x i8> %subab ++ ret <4 x i8> %select ++} ++ ++define <2 x i64> @vabsd_d(<2 x i64> %a, <2 x i64> %b) { ++; CHECK-LABEL: vabsd_d: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vabsd.d $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp sgt <2 x i64> %b, %a ++ %subba = sub <2 x i64> %b, %a ++ %subab = sub <2 x i64> %a, %b ++ %select = select <2 x i1> %icmp, <2 x i64> %subba, <2 x i64> %subab ++ ret <2 x i64> %select ++} ++ ++define <2 x i32> @vabsd_d_v2i32(<2 x i32> %a, <2 x i32> %b) { ++; CHECK-LABEL: vabsd_d_v2i32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vabsd.d $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp sgt <2 x i32> %b, %a ++ %subba = sub <2 x i32> %b, %a ++ %subab = sub <2 x i32> %a, %b ++ %select = select <2 x i1> %icmp, <2 x i32> %subba, <2 x i32> %subab ++ ret <2 x i32> %select ++} ++ ++define <2 x i16> @vabsd_d_v2i16(<2 x i16> %a, <2 x i16> %b) { ++; CHECK-LABEL: vabsd_d_v2i16: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vabsd.d $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp sgt <2 x i16> %b, %a ++ %subba = sub <2 x i16> %b, %a ++ %subab = sub <2 x i16> %a, %b ++ %select = select <2 x i1> %icmp, <2 x i16> %subba, <2 x i16> %subab ++ ret <2 x i16> %select ++} ++ ++define <2 x i8> @vabsd_d_v2i8(<2 x i8> %a, <2 x i8> %b) { ++; CHECK-LABEL: vabsd_d_v2i8: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vabsd.d $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp sgt <2 x i8> %b, %a ++ %subba = sub <2 x i8> %b, %a ++ %subab = sub <2 x i8> %a, %b ++ %select = select <2 x i1> %icmp, <2 x i8> %subba, <2 x i8> %subab ++ ret <2 x i8> %select ++} ++ ++define <16 x i8> @vabsd_bu(<16 x i8> %a, <16 x i8> %b) { ++; CHECK-LABEL: vabsd_bu: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vabsd.bu $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp ugt <16 x i8> %b, %a ++ %subba = sub <16 x i8> %b, %a ++ %subab = sub <16 x i8> %a, %b ++ %select = select <16 x i1> %icmp, <16 x i8> %subba, <16 x i8> %subab ++ ret <16 x i8> %select ++} ++ ++define <8 x i16> @vabsd_hu(<8 x i16> %a, <8 x i16> %b) { ++; CHECK-LABEL: vabsd_hu: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vabsd.hu $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp ugt <8 x i16> %b, %a ++ %subba = sub <8 x i16> %b, %a ++ %subab = sub <8 x i16> %a, %b ++ %select = select <8 x i1> %icmp, <8 x i16> %subba, <8 x i16> %subab ++ ret <8 x i16> %select ++} ++ ++define <8 x i8> @vabsd_hu_v8i8(<8 x i8> %a, <8 x i8> %b) { ++; CHECK-LABEL: vabsd_hu_v8i8: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vabsd.hu $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp ugt <8 x i8> %b, %a ++ %subba = sub <8 x i8> %b, %a ++ %subab = sub <8 x i8> %a, %b ++ %select = select <8 x i1> %icmp, <8 x i8> %subba, <8 x i8> %subab ++ ret <8 x i8> %select ++} ++ ++define <4 x i32> @vabsd_wu(<4 x i32> %a, <4 x i32> %b) { ++; CHECK-LABEL: vabsd_wu: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vabsd.wu $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp ugt <4 x i32> %b, %a ++ %subba = sub <4 x i32> %b, %a ++ %subab = sub <4 x i32> %a, %b ++ %select = select <4 x i1> %icmp, <4 x i32> %subba, <4 x i32> %subab ++ ret <4 x i32> %select ++} ++ ++define <4 x i16> @vabsd_wu_v4i16(<4 x i16> %a, <4 x i16> %b) { ++; CHECK-LABEL: vabsd_wu_v4i16: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vabsd.wu $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp ugt <4 x i16> %b, %a ++ %subba = sub <4 x i16> %b, %a ++ %subab = sub <4 x i16> %a, %b ++ %select = select <4 x i1> %icmp, <4 x i16> %subba, <4 x i16> %subab ++ ret <4 x i16> %select ++} ++ ++define <4 x i8> @vabsd_wu_v4i8(<4 x i8> %a, <4 x i8> %b) { ++; CHECK-LABEL: vabsd_wu_v4i8: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vabsd.wu $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp ugt <4 x i8> %b, %a ++ %subba = sub <4 x i8> %b, %a ++ %subab = sub <4 x i8> %a, %b ++ %select = select <4 x i1> %icmp, <4 x i8> %subba, <4 x i8> %subab ++ ret <4 x i8> %select ++} ++ ++define <2 x i64> @vabsd_du(<2 x i64> %a, <2 x i64> %b) { ++; CHECK-LABEL: vabsd_du: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vabsd.du $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp ugt <2 x i64> %b, %a ++ %subba = sub <2 x i64> %b, %a ++ %subab = sub <2 x i64> %a, %b ++ %select = select <2 x i1> %icmp, <2 x i64> %subba, <2 x i64> %subab ++ ret <2 x i64> %select ++} ++ ++define <2 x i32> @vabsd_du_v2i32(<2 x i32> %a, <2 x i32> %b) { ++; CHECK-LABEL: vabsd_du_v2i32: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vabsd.du $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp ugt <2 x i32> %b, %a ++ %subba = sub <2 x i32> %b, %a ++ %subab = sub <2 x i32> %a, %b ++ %select = select <2 x i1> %icmp, <2 x i32> %subba, <2 x i32> %subab ++ ret <2 x i32> %select ++} ++ ++define <2 x i16> @vabsd_du_v2i16(<2 x i16> %a, <2 x i16> %b) { ++; CHECK-LABEL: vabsd_du_v2i16: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vabsd.du $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp ugt <2 x i16> %b, %a ++ %subba = sub <2 x i16> %b, %a ++ %subab = sub <2 x i16> %a, %b ++ %select = select <2 x i1> %icmp, <2 x i16> %subba, <2 x i16> %subab ++ ret <2 x i16> %select ++} ++ ++define <2 x i8> @vabsd_du_v2i8(<2 x i8> %a, <2 x i8> %b) { ++; CHECK-LABEL: vabsd_du_v2i8: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: vabsd.du $vr0, $vr1, $vr0 ++; CHECK-NEXT: jr $ra ++entry: ++ %icmp = icmp ugt <2 x i8> %b, %a ++ %subba = sub <2 x i8> %b, %a ++ %subab = sub <2 x i8> %a, %b ++ %select = select <2 x i1> %icmp, <2 x i8> %subba, <2 x i8> %subab ++ ret <2 x i8> %select ++} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/vadda.ll b/llvm/test/CodeGen/LoongArch/lsx/vadda.ll +new file mode 100644 +index 000000000..4c987fb1b +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lsx/vadda.ll +@@ -0,0 +1,62 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mattr=+lsx < %s | FileCheck %s ++ ++define <16 x i8> @vaddab(<16 x i8>, <16 x i8>) { ++; CHECK-LABEL: vaddab: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vadda.b $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %3 = icmp slt <16 x i8> %0, zeroinitializer ++ %4 = sub <16 x i8> zeroinitializer, %0 ++ %5 = select <16 x i1> %3, <16 x i8> %4, <16 x i8> %0 ++ %6 = icmp slt <16 x i8> %1, zeroinitializer ++ %7 = sub <16 x i8> zeroinitializer, %1 ++ %8 = select <16 x i1> %6, <16 x i8> %7, <16 x i8> %1 ++ %9 = add <16 x i8> %5, %8 ++ ret <16 x i8> %9 ++} ++ ++define <8 x i16> @vaddah(<8 x i16>, <8 x i16>) { ++; CHECK-LABEL: vaddah: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vadda.h $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %3 = icmp slt <8 x i16> %0, zeroinitializer ++ %4 = sub <8 x i16> zeroinitializer, %0 ++ %5 = select <8 x i1> %3, <8 x i16> %4, <8 x i16> %0 ++ %6 = icmp slt <8 x i16> %1, zeroinitializer ++ %7 = sub <8 x i16> zeroinitializer, %1 ++ %8 = select <8 x i1> %6, <8 x i16> %7, <8 x i16> %1 ++ %9 = add <8 x i16> %5, %8 ++ ret <8 x i16> %9 ++} ++ ++define <4 x i32> @vaddaw(<4 x i32>, <4 x i32>) { ++; CHECK-LABEL: vaddaw: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vadda.w $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %3 = icmp slt <4 x i32> %0, zeroinitializer ++ %4 = sub nsw <4 x i32> zeroinitializer, %0 ++ %5 = select <4 x i1> %3, <4 x i32> %4, <4 x i32> %0 ++ %6 = icmp slt <4 x i32> %1, zeroinitializer ++ %7 = sub nsw <4 x i32> zeroinitializer, %1 ++ %8 = select <4 x i1> %6, <4 x i32> %7, <4 x i32> %1 ++ %9 = add nuw nsw <4 x i32> %5, %8 ++ ret <4 x i32> %9 ++} ++ ++define <2 x i64> @vaddad(<2 x i64>, <2 x i64>) { ++; CHECK-LABEL: vaddad: ++; CHECK: # %bb.0: ++; CHECK-NEXT: vadda.d $vr0, $vr0, $vr1 ++; CHECK-NEXT: jr $ra ++ %3 = icmp slt <2 x i64> %0, zeroinitializer ++ %4 = sub nsw <2 x i64> zeroinitializer, %0 ++ %5 = select <2 x i1> %3, <2 x i64> %4, <2 x i64> %0 ++ %6 = icmp slt <2 x i64> %1, zeroinitializer ++ %7 = sub nsw <2 x i64> zeroinitializer, %1 ++ %8 = select <2 x i1> %6, <2 x i64> %7, <2 x i64> %1 ++ %9 = add nuw nsw <2 x i64> %5, %8 ++ ret <2 x i64> %9 ++} +diff --git a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fcvt.ll b/llvm/test/CodeGen/LoongArch/lsx/vfcvt.ll +similarity index 56% +rename from llvm/test/CodeGen/LoongArch/lsx/intrinsic-fcvt.ll +rename to llvm/test/CodeGen/LoongArch/lsx/vfcvt.ll +index a6a151a96..53e262ccf 100644 +--- a/llvm/test/CodeGen/LoongArch/lsx/intrinsic-fcvt.ll ++++ b/llvm/test/CodeGen/LoongArch/lsx/vfcvt.ll +@@ -1,25 +1,13 @@ + ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py + ; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s + +-declare <8 x i16> @llvm.loongarch.lsx.vfcvt.h.s(<4 x float>, <4 x float>) +- +-define <8 x i16> @lsx_vfcvt_h_s(<4 x float> %va, <4 x float> %vb) nounwind { +-; CHECK-LABEL: lsx_vfcvt_h_s: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: vfcvt.h.s $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret +-entry: +- %res = call <8 x i16> @llvm.loongarch.lsx.vfcvt.h.s(<4 x float> %va, <4 x float> %vb) +- ret <8 x i16> %res +-} +- + declare <4 x float> @llvm.loongarch.lsx.vfcvt.s.d(<2 x double>, <2 x double>) + + define <4 x float> @lsx_vfcvt_s_d(<2 x double> %va, <2 x double> %vb) nounwind { + ; CHECK-LABEL: lsx_vfcvt_s_d: + ; CHECK: # %bb.0: # %entry + ; CHECK-NEXT: vfcvt.s.d $vr0, $vr0, $vr1 +-; CHECK-NEXT: ret ++; CHECK-NEXT: jr $ra + entry: + %res = call <4 x float> @llvm.loongarch.lsx.vfcvt.s.d(<2 x double> %va, <2 x double> %vb) + ret <4 x float> %res +diff --git a/llvm/test/CodeGen/LoongArch/lsx/vselect.ll b/llvm/test/CodeGen/LoongArch/lsx/vselect.ll +deleted file mode 100644 +index 97a555329..000000000 +--- a/llvm/test/CodeGen/LoongArch/lsx/vselect.ll ++++ /dev/null +@@ -1,85 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s +- +-define void @select_v16i8_imm(ptr %res, ptr %a0) nounwind { +-; CHECK-LABEL: select_v16i8_imm: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vrepli.h $vr1, -256 +-; CHECK-NEXT: vbitseli.b $vr1, $vr0, 255 +-; CHECK-NEXT: vst $vr1, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i8>, ptr %a0 +- %sel = select <16 x i1> , <16 x i8> , <16 x i8> %v0 +- store <16 x i8> %sel, ptr %res +- ret void +-} +- +-define void @select_v16i8(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: select_v16i8: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: vrepli.h $vr2, -256 +-; CHECK-NEXT: vbitsel.v $vr0, $vr1, $vr0, $vr2 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <16 x i8>, ptr %a0 +- %v1 = load <16 x i8>, ptr %a1 +- %sel = select <16 x i1> , <16 x i8> %v0, <16 x i8> %v1 +- store <16 x i8> %sel, ptr %res +- ret void +-} +- +-define void @select_v8i16(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: select_v8i16: +-; CHECK: # %bb.0: +-; CHECK-NEXT: lu12i.w $a3, -16 +-; CHECK-NEXT: vreplgr2vr.w $vr0, $a3 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vld $vr2, $a2, 0 +-; CHECK-NEXT: vbitsel.v $vr0, $vr2, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <8 x i16>, ptr %a0 +- %v1 = load <8 x i16>, ptr %a1 +- %sel = select <8 x i1> , <8 x i16> %v0, <8 x i16> %v1 +- store <8 x i16> %sel, ptr %res +- ret void +-} +- +-define void @select_v4i32(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: select_v4i32: +-; CHECK: # %bb.0: +-; CHECK-NEXT: vld $vr0, $a1, 0 +-; CHECK-NEXT: vld $vr1, $a2, 0 +-; CHECK-NEXT: ori $a1, $zero, 0 +-; CHECK-NEXT: lu32i.d $a1, -1 +-; CHECK-NEXT: vreplgr2vr.d $vr2, $a1 +-; CHECK-NEXT: vbitsel.v $vr0, $vr1, $vr0, $vr2 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <4 x i32>, ptr %a0 +- %v1 = load <4 x i32>, ptr %a1 +- %sel = select <4 x i1> , <4 x i32> %v0, <4 x i32> %v1 +- store <4 x i32> %sel, ptr %res +- ret void +-} +- +-define void @select_v2i64(ptr %res, ptr %a0, ptr %a1) nounwind { +-; CHECK-LABEL: select_v2i64: +-; CHECK: # %bb.0: +-; CHECK-NEXT: pcalau12i $a3, %pc_hi20(.LCPI4_0) +-; CHECK-NEXT: addi.d $a3, $a3, %pc_lo12(.LCPI4_0) +-; CHECK-NEXT: vld $vr0, $a3, 0 +-; CHECK-NEXT: vld $vr1, $a1, 0 +-; CHECK-NEXT: vld $vr2, $a2, 0 +-; CHECK-NEXT: vbitsel.v $vr0, $vr2, $vr1, $vr0 +-; CHECK-NEXT: vst $vr0, $a0, 0 +-; CHECK-NEXT: ret +- %v0 = load <2 x i64>, ptr %a0 +- %v1 = load <2 x i64>, ptr %a1 +- %sel = select <2 x i1> , <2 x i64> %v0, <2 x i64> %v1 +- store <2 x i64> %sel, ptr %res +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/lu12i.ll b/llvm/test/CodeGen/LoongArch/lu12i.ll +new file mode 100644 +index 000000000..55fd40edd +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/lu12i.ll +@@ -0,0 +1,7 @@ ++; RUN: llc -march=loongarch64 -o - %s | FileCheck %s ++ ++define i32 @foo() { ++; CHECK: lu12i.w $r4, -1 ++entry: ++ ret i32 -4096 ++} +diff --git a/llvm/test/CodeGen/LoongArch/mafft-Lalignmm.ll b/llvm/test/CodeGen/LoongArch/mafft-Lalignmm.ll +deleted file mode 100644 +index 4a9189c97..000000000 +--- a/llvm/test/CodeGen/LoongArch/mafft-Lalignmm.ll ++++ /dev/null +@@ -1,127 +0,0 @@ +-; RUN: llc --mtriple=loongarch64 -mattr=+d %s -o /dev/null +- +-; ModuleID = 'bugpoint-reduced-simplifycfg.bc' +-source_filename = "test-suite-src/MultiSource/Benchmarks/mafft/Lalignmm.c" +- +-define float @Lalignmm_hmout(ptr %seq1, ptr %eff1, i32 %icyc) { +-entry: +- %call4 = tail call i64 @strlen(ptr dereferenceable(1) poison) +- %conv5 = trunc i64 %call4 to i32 +- %call7 = tail call i64 @strlen(ptr dereferenceable(1) poison) +- %call20 = tail call ptr @AllocateFloatVec(i32 signext poison) +- %call22 = tail call ptr @AllocateFloatVec(i32 signext poison) +- tail call void @st_OpeningGapCount(ptr poison, i32 signext %icyc, ptr %seq1, ptr %eff1, i32 signext %conv5) +- %sub110 = add nsw i32 %conv5, -1 +- %sub111 = add nsw i32 0, -1 +- br i1 poison, label %for.cond.preheader.i, label %if.end.i +- +-for.cond.preheader.i: ; preds = %entry +- %sext294 = shl i64 %call4, 32 +- %conv23.i = ashr exact i64 %sext294, 32 +- br label %for.body.i +- +-for.body.i: ; preds = %for.body.i, %for.cond.preheader.i +- %call.i = tail call ptr @strncpy(ptr poison, ptr poison, i64 %conv23.i) +- br label %for.body.i +- +-if.end.i: ; preds = %entry +- %call82.i = tail call ptr @AllocateFloatVec(i32 signext poison) +- %call84.i = tail call ptr @AllocateFloatVec(i32 signext poison) +- %call86.i = tail call ptr @AllocateFloatVec(i32 signext poison) +- %call88.i = tail call ptr @AllocateFloatVec(i32 signext poison) +- %call90.i = tail call ptr @AllocateFloatVec(i32 signext poison) +- %call92.i = tail call ptr @AllocateIntVec(i32 signext poison) +- %call94.i = tail call ptr @AllocateIntVec(i32 signext poison) +- %call104.i = tail call ptr @AllocateFloatVec(i32 signext poison) +- %call108.i = tail call ptr @AllocateFloatVec(i32 signext poison) +- %call110.i = tail call ptr @AllocateIntVec(i32 signext poison) +- %idxprom220.i = sext i32 %sub111 to i64 +- %mpjpt.018.i = getelementptr inbounds i32, ptr %call110.i, i64 1 +- %arrayidx329.i = getelementptr inbounds float, ptr %call108.i, i64 %idxprom220.i +- %idxprom332.i = and i64 %call7, 4294967295 +- %wide.trip.count130.i = zext i32 poison to i64 +- %0 = add nsw i64 1, -1 +- %arrayidx239.i = getelementptr inbounds float, ptr %call104.i, i64 1 +- %1 = load float, ptr %arrayidx239.i, align 4 +- store float %1, ptr %call84.i, align 4 +- %curpt.017.i = getelementptr inbounds float, ptr %call84.i, i64 1 +- %arrayidx279.i = getelementptr inbounds float, ptr %call20, i64 %0 +- %2 = load ptr, ptr poison, align 8 +- %3 = load ptr, ptr null, align 8 +- %4 = trunc i64 %0 to i32 +- br label %for.body260.us.i +- +-for.body260.us.i: ; preds = %if.end292.us.i, %if.end.i +- %indvars.iv132.i = phi i64 [ %indvars.iv.next133.i, %if.end292.us.i ], [ 1, %if.end.i ] +- %mpjpt.026.us.i = phi ptr [ poison, %if.end292.us.i ], [ %mpjpt.018.i, %if.end.i ] +- %curpt.025.us.i = phi ptr [ %curpt.0.us.i, %if.end292.us.i ], [ %curpt.017.i, %if.end.i ] +- %prept.022.us.i = phi ptr [ %incdec.ptr316.us.i, %if.end292.us.i ], [ %call82.i, %if.end.i ] +- %mi.021.us.i = phi float [ %mi.1.us.i, %if.end292.us.i ], [ poison, %if.end.i ] +- %5 = load float, ptr %prept.022.us.i, align 4 +- %6 = add nsw i64 %indvars.iv132.i, -1 +- %arrayidx263.us.i = getelementptr inbounds float, ptr %call22, i64 %6 +- %7 = load float, ptr %arrayidx263.us.i, align 4 +- %add264.us.i = fadd float %mi.021.us.i, %7 +- %cmp265.us.i = fcmp ogt float %add264.us.i, %5 +- %wm.0.us.i = select i1 %cmp265.us.i, float %add264.us.i, float %5 +- %arrayidx270.us.i = getelementptr inbounds float, ptr poison, i64 %indvars.iv132.i +- %cmp272.us.i = fcmp ult float 0.000000e+00, %mi.021.us.i +- %mi.1.us.i = select i1 %cmp272.us.i, float %mi.021.us.i, float 0.000000e+00 +- %8 = trunc i64 %6 to i32 +- %mpi.1.us.i = select i1 %cmp272.us.i, i32 0, i32 %8 +- %9 = load float, ptr %arrayidx279.i, align 4 +- %add280.us.i = fadd float 0.000000e+00, %9 +- %cmp281.us.i = fcmp ogt float %add280.us.i, %wm.0.us.i +- %wm.1.us.i = select i1 %cmp281.us.i, float %add280.us.i, float %wm.0.us.i +- %cmp288.us.i = fcmp ult float poison, 0.000000e+00 +- br i1 %cmp288.us.i, label %if.end292.us.i, label %if.then290.us.i +- +-if.then290.us.i: ; preds = %for.body260.us.i +- store i32 %4, ptr %mpjpt.026.us.i, align 4 +- br label %if.end292.us.i +- +-if.end292.us.i: ; preds = %if.then290.us.i, %for.body260.us.i +- %10 = phi i32 [ %4, %if.then290.us.i ], [ poison, %for.body260.us.i ] +- %add293.us.i = fadd float %wm.1.us.i, 0.000000e+00 +- %arrayidx297.us.i = getelementptr inbounds float, ptr %2, i64 %indvars.iv132.i +- store float %add293.us.i, ptr %arrayidx297.us.i, align 4 +- %arrayidx306.us.i = getelementptr inbounds i32, ptr %call94.i, i64 %indvars.iv132.i +- store i32 %10, ptr %arrayidx306.us.i, align 4 +- %arrayidx308.us.i = getelementptr inbounds i32, ptr %call92.i, i64 %indvars.iv132.i +- store i32 %mpi.1.us.i, ptr %arrayidx308.us.i, align 4 +- %11 = load float, ptr %curpt.025.us.i, align 4 +- %arrayidx310.us.i = getelementptr inbounds float, ptr %call86.i, i64 %indvars.iv132.i +- store float %11, ptr %arrayidx310.us.i, align 4 +- %arrayidx312.us.i = getelementptr inbounds float, ptr %call90.i, i64 %indvars.iv132.i +- store float 0.000000e+00, ptr %arrayidx312.us.i, align 4 +- %arrayidx314.us.i = getelementptr inbounds float, ptr %call88.i, i64 %indvars.iv132.i +- store float %mi.1.us.i, ptr %arrayidx314.us.i, align 4 +- %incdec.ptr316.us.i = getelementptr inbounds float, ptr %prept.022.us.i, i64 1 +- %indvars.iv.next133.i = add nuw nsw i64 %indvars.iv132.i, 1 +- %curpt.0.us.i = getelementptr inbounds float, ptr %curpt.025.us.i, i64 1 +- %exitcond137.not.i = icmp eq i64 %indvars.iv.next133.i, %wide.trip.count130.i +- br i1 %exitcond137.not.i, label %for.end321.i, label %for.body260.us.i +- +-for.end321.i: ; preds = %if.end292.us.i +- %12 = load float, ptr %arrayidx329.i, align 4 +- %arrayidx333.i = getelementptr inbounds float, ptr %3, i64 %idxprom332.i +- store float %12, ptr %arrayidx333.i, align 4 +- tail call fastcc void @match_calc(ptr %call104.i, ptr poison, ptr poison, i32 signext %sub111, i32 signext %conv5, ptr poison, ptr poison, i32 signext 1) +- br label %for.body429.i +- +-for.body429.i: ; preds = %for.body429.i, %for.end321.i +- %j.743.i = phi i32 [ %sub111, %for.end321.i ], [ %sub436.i, %for.body429.i ] +- %sub436.i = add nsw i32 %j.743.i, -1 +- %idxprom437.i = zext i32 %sub436.i to i64 +- %arrayidx438.i = getelementptr inbounds float, ptr %call108.i, i64 %idxprom437.i +- store float 0.000000e+00, ptr %arrayidx438.i, align 4 +- store i32 %sub110, ptr poison, align 4 +- br label %for.body429.i +-} +- +-declare i64 @strlen(ptr) +-declare ptr @AllocateFloatVec(i32) +-declare void @st_OpeningGapCount(ptr, i32, ptr, ptr, i32) +-declare ptr @strncpy(ptr, ptr, i64) +-declare ptr @AllocateIntVec(i32) +-declare void @match_calc(ptr, ptr, ptr, i32, i32, ptr, ptr, i32) +diff --git a/llvm/test/CodeGen/LoongArch/mcpu_load.ll b/llvm/test/CodeGen/LoongArch/mcpu_load.ll +new file mode 100644 +index 000000000..20d4d2eed +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/mcpu_load.ll +@@ -0,0 +1,73 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -mcpu=la264 -o - %s | FileCheck -check-prefix=ALIGNED %s ++; RUN: llc -march=loongarch64 -mcpu=la364 -o - %s | FileCheck -check-prefix=ALIGNED %s ++; RUN: llc -march=loongarch64 -mcpu=la464 -o - %s | FileCheck -check-prefix=UNALIGNED %s ++; RUN: llc -march=loongarch64 -mcpu=la664 -o - %s | FileCheck -check-prefix=UNALIGNED %s ++ ++define i32 @i32_load(i32* %p) { ++; ALIGNED-LABEL: i32_load: ++; ALIGNED: # %bb.0: ++; ALIGNED-NEXT: ld.hu $r5, $r4, 0 ++; ALIGNED-NEXT: ld.hu $r4, $r4, 2 ++; ALIGNED-NEXT: slli.w $r4, $r4, 16 ++; ALIGNED-NEXT: or $r4, $r4, $r5 ++; ALIGNED-NEXT: jr $ra ++; ++; UNALIGNED-LABEL: i32_load: ++; UNALIGNED: # %bb.0: ++; UNALIGNED-NEXT: ld.w $r4, $r4, 0 ++; UNALIGNED-NEXT: jr $ra ++ %tmp = load i32, i32* %p, align 2 ++ ret i32 %tmp ++} ++ ++define signext i32 @i32_sextload(i32* %p) { ++; ALIGNED-LABEL: i32_sextload: ++; ALIGNED: # %bb.0: ++; ALIGNED-NEXT: ld.hu $r5, $r4, 0 ++; ALIGNED-NEXT: ld.h $r4, $r4, 2 ++; ALIGNED-NEXT: slli.d $r4, $r4, 16 ++; ALIGNED-NEXT: or $r4, $r4, $r5 ++; ALIGNED-NEXT: jr $ra ++; ++; UNALIGNED-LABEL: i32_sextload: ++; UNALIGNED: # %bb.0: ++; UNALIGNED-NEXT: ld.w $r4, $r4, 0 ++; UNALIGNED-NEXT: jr $ra ++ %tmp = load i32, i32* %p, align 2 ++ ret i32 %tmp ++} ++ ++define zeroext i32 @i32_zextload(i32* %p) { ++; ALIGNED-LABEL: i32_zextload: ++; ALIGNED: # %bb.0: ++; ALIGNED-NEXT: ld.hu $r5, $r4, 0 ++; ALIGNED-NEXT: ld.hu $r4, $r4, 2 ++; ALIGNED-NEXT: slli.d $r4, $r4, 16 ++; ALIGNED-NEXT: or $r4, $r4, $r5 ++; ALIGNED-NEXT: jr $ra ++; ++; UNALIGNED-LABEL: i32_zextload: ++; UNALIGNED: # %bb.0: ++; UNALIGNED-NEXT: ld.wu $r4, $r4, 0 ++; UNALIGNED-NEXT: jr $ra ++ %tmp = load i32, i32* %p, align 2 ++ ret i32 %tmp ++} ++ ++define i64 @i64_load(i64* %p) { ++; ALIGNED-LABEL: i64_load: ++; ALIGNED: # %bb.0: ++; ALIGNED-NEXT: ld.wu $r5, $r4, 0 ++; ALIGNED-NEXT: ld.wu $r4, $r4, 4 ++; ALIGNED-NEXT: slli.d $r4, $r4, 32 ++; ALIGNED-NEXT: or $r4, $r4, $r5 ++; ALIGNED-NEXT: jr $ra ++; ++; UNALIGNED-LABEL: i64_load: ++; UNALIGNED: # %bb.0: ++; UNALIGNED-NEXT: ld.d $r4, $r4, 0 ++; UNALIGNED-NEXT: jr $ra ++ %tmp = load i64, i64* %p, align 4 ++ ret i64 %tmp ++} +diff --git a/llvm/test/CodeGen/LoongArch/memcmp.ll b/llvm/test/CodeGen/LoongArch/memcmp.ll +deleted file mode 100644 +index 4d4f376cd..000000000 +--- a/llvm/test/CodeGen/LoongArch/memcmp.ll ++++ /dev/null +@@ -1,24 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s +- +-;; Before getSelectionDAGInfo() interface hooks were defined DAGBuilder +-;; would crash. +- +-define signext i32 @test1(ptr %buffer1, ptr %buffer2) { +-; CHECK-LABEL: test1: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: .cfi_def_cfa_offset 16 +-; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; CHECK-NEXT: .cfi_offset 1, -8 +-; CHECK-NEXT: ori $a2, $zero, 16 +-; CHECK-NEXT: bl %plt(memcmp) +-; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +-entry: +- %call = call signext i32 @memcmp(ptr %buffer1, ptr %buffer2, i64 16) +- ret i32 %call +-} +- +-declare signext i32 @memcmp(ptr, ptr, i64) +diff --git a/llvm/test/CodeGen/LoongArch/mir-target-flags.ll b/llvm/test/CodeGen/LoongArch/mir-target-flags.ll +deleted file mode 100644 +index 9f3a061fe..000000000 +--- a/llvm/test/CodeGen/LoongArch/mir-target-flags.ll ++++ /dev/null +@@ -1,44 +0,0 @@ +-; RUN: llc --mtriple=loongarch64 --stop-after loongarch-prera-expand-pseudo \ +-; RUN: --relocation-model=pic %s -o %t.mir +-; RUN: llc --mtriple=loongarch64 --run-pass loongarch-prera-expand-pseudo \ +-; RUN: %t.mir -o - | FileCheck %s +- +-;; This tests the LoongArch-specific serialization and deserialization of +-;; `target-flags(...)` +- +-@g_e = external global i32 +-@g_i = internal global i32 0 +-@t_un = external thread_local global i32 +-@t_ld = external thread_local(localdynamic) global i32 +-@t_ie = external thread_local(initialexec) global i32 +-@t_le = external thread_local(localexec) global i32 +- +-declare void @callee1() nounwind +-declare dso_local void @callee2() nounwind +- +-define void @caller() nounwind { +-; CHECK-LABEL: name: caller +-; CHECK: target-flags(loongarch-got-pc-hi) @g_e +-; CHECK-NEXT: target-flags(loongarch-got-pc-lo) @g_e +-; CHECK: target-flags(loongarch-pcrel-hi) @g_i +-; CHECK-NEXT: target-flags(loongarch-pcrel-lo) @g_i +-; CHECK: target-flags(loongarch-gd-pc-hi) @t_un +-; CHECK-NEXT: target-flags(loongarch-got-pc-lo) @t_un +-; CHECK: target-flags(loongarch-ld-pc-hi) @t_ld +-; CHECK-NEXT: target-flags(loongarch-got-pc-lo) @t_ld +-; CHECK: target-flags(loongarch-ie-pc-hi) @t_ie +-; CHECK-NEXT: target-flags(loongarch-ie-pc-lo) @t_ie +-; CHECK: target-flags(loongarch-le-hi) @t_le +-; CHECK-NEXT: target-flags(loongarch-le-lo) @t_le +-; CHECK: target-flags(loongarch-call-plt) @callee1 +-; CHECK: target-flags(loongarch-call) @callee2 +- %a = load volatile i32, ptr @g_e +- %b = load volatile i32, ptr @g_i +- %c = load volatile i32, ptr @t_un +- %d = load volatile i32, ptr @t_ld +- %e = load volatile i32, ptr @t_ie +- %f = load volatile i32, ptr @t_le +- call i32 @callee1() +- call i32 @callee2() +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/mul-karatsuba-test.ll b/llvm/test/CodeGen/LoongArch/mul-karatsuba-test.ll +new file mode 100644 +index 000000000..9b3433df8 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/mul-karatsuba-test.ll +@@ -0,0 +1,36 @@ ++; RUN: llc --march=loongarch64 -mattr=+fp64 < %s | FileCheck %s ++ ++define void @_Z13KaratsubaMain8RWDigits6DigitsS0_S_i([2 x i64] %Z.coerce, [2 x i64] %X.coerce, [2 x i64] %Y.coerce, i32 %n, i64 %Z.coerce.fca.0.extract, i32 %shr, ptr %0, i64 %idx.ext.i, i32 %src.sroa.2.8.extract.trunc.i, ptr %1, i1 %exitcond248.not) { ++; CHECK-LABEL: _Z13KaratsubaMain8RWDigits6DigitsS0_S_i: ++; CHECK: # %bb.0: # %entry ++; CHECK: ld.d $r4, $sp, 48 ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: bstrpick.d $r9, $r27, 31, 0 ++; CHECK-NEXT: slt $r4, $r23, $r4 ++entry: ++ %shr2 = lshr i32 %n, 1 ++ %sub.i = or i32 %src.sroa.2.8.extract.trunc.i, %shr ++ %X1.sroa.4.8.insert.ext = zext i32 %sub.i to i64 ++ %add.ptr.i139 = getelementptr i64, ptr %1, i64 %idx.ext.i ++ %Y1.sroa.4.8.insert.ext = zext i32 %n to i64 ++ call void @_Z13KaratsubaMain8RWDigits6DigitsS0_S_i([2 x i64] zeroinitializer, [2 x i64] %Z.coerce, [2 x i64] %X.coerce, i32 %shr2, i64 0, i32 0, ptr null, i64 0, i32 0, ptr null, i1 false) ++ %sext = shl i64 %Z.coerce.fca.0.extract, 32 ++ %2 = ashr i64 %sext, 32 ++ br label %for.body ++for.cond.cleanup: ; preds = %_ZN8RWDigitsixEi.exit184 ++ %3 = ptrtoint ptr %add.ptr.i139 to i64 ++ %.fca.1.insert70 = insertvalue [2 x i64] %Z.coerce, i64 %X1.sroa.4.8.insert.ext, 1 ++ %.fca.0.insert67 = insertvalue [2 x i64] zeroinitializer, i64 %3, 0 ++ %.fca.1.insert68 = insertvalue [2 x i64] %.fca.0.insert67, i64 %Y1.sroa.4.8.insert.ext, 1 ++ call void @_Z13KaratsubaMain8RWDigits6DigitsS0_S_i([2 x i64] zeroinitializer, [2 x i64] %.fca.1.insert70, [2 x i64] %.fca.1.insert68, i32 0, i64 0, i32 0, ptr null, i64 0, i32 0, ptr null, i1 false) ++ %call41 = call [2 x i64] null(ptr null, i32 %n) ++ ret void ++for.body: ; preds = %_ZN8RWDigitsixEi.exit184, %entry ++ %cmp.i174 = icmp sgt i64 %2, 0 ++ br i1 %cmp.i174, label %_ZN8RWDigitsixEi.exit184, label %if.then.i175 ++if.then.i175: ; preds = %for.body ++ unreachable ++_ZN8RWDigitsixEi.exit184: ; preds = %for.body ++ store i64 0, ptr %0, align 4 ++ br i1 %exitcond248.not, label %for.cond.cleanup, label %for.body ++} +diff --git a/llvm/test/CodeGen/LoongArch/named-register.ll b/llvm/test/CodeGen/LoongArch/named-register.ll +new file mode 100644 +index 000000000..0b0660fca +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/named-register.ll +@@ -0,0 +1,29 @@ ++; RUN: llc -march=loongarch64 < %s | FileCheck %s ++ ++define i64 @get_r2() { ++; CHECK-LABEL: get_r2: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: move $r4, $tp ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = call i64 @llvm.read_register.i64(metadata !0) ++ ret i64 %0 ++} ++ ++define i64 @get_r21() { ++; CHECK-LABEL: get_r21: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: move $r4, $r21 ++; CHECK-NEXT: jr $ra ++entry: ++ %0 = call i64 @llvm.read_register.i64(metadata !1) ++ ret i64 %0 ++} ++ ++declare i64 @llvm.read_register.i64(metadata) ++ ++!llvm.named.register.$r2 = !{!0} ++!llvm.named.register.$r21 = !{!1} ++ ++!0 = !{!"$r2"} ++!1 = !{!"$r21"} +diff --git a/llvm/test/CodeGen/LoongArch/nomerge.ll b/llvm/test/CodeGen/LoongArch/nomerge.ll +index a8d5116f6..a8ce63225 100644 +--- a/llvm/test/CodeGen/LoongArch/nomerge.ll ++++ b/llvm/test/CodeGen/LoongArch/nomerge.ll +@@ -1,26 +1,6 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s ++; RUN: llc < %s -mtriple=loongarch64 -relocation-model=pic -o - | FileCheck %s + +-define void @foo(i32 %i) nounwind { +-; CHECK-LABEL: foo: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; CHECK-NEXT: addi.w $a0, $a0, 0 +-; CHECK-NEXT: ori $a1, $zero, 7 +-; CHECK-NEXT: beq $a0, $a1, .LBB0_3 +-; CHECK-NEXT: # %bb.1: # %entry +-; CHECK-NEXT: ori $a1, $zero, 5 +-; CHECK-NEXT: bne $a0, $a1, .LBB0_4 +-; CHECK-NEXT: # %bb.2: # %if.then +-; CHECK-NEXT: bl %plt(bar) +-; CHECK-NEXT: b .LBB0_4 +-; CHECK-NEXT: .LBB0_3: # %if.then2 +-; CHECK-NEXT: bl %plt(bar) +-; CHECK-NEXT: .LBB0_4: # %if.end3 +-; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: b %plt(bar) ++define void @foo(i32 %i) { + entry: + switch i32 %i, label %if.end3 [ + i32 5, label %if.then +@@ -40,30 +20,16 @@ if.end3: + ret void + } + +-define void @foo_tail(i1 %i) nounwind { +-; CHECK-LABEL: foo_tail: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: andi $a0, $a0, 1 +-; CHECK-NEXT: beqz $a0, .LBB1_2 +-; CHECK-NEXT: # %bb.1: # %if.then +-; CHECK-NEXT: b %plt(bar) +-; CHECK-NEXT: .LBB1_2: # %if.else +-; CHECK-NEXT: b %plt(bar) +-entry: +- br i1 %i, label %if.then, label %if.else +- +-if.then: +- tail call void @bar() #0 +- br label %if.end +- +-if.else: +- tail call void @bar() #0 +- br label %if.end +- +-if.end: +- ret void +-} +- + declare void @bar() + + attributes #0 = { nomerge } ++ ++; CHECK-LABEL: foo: ++; CHECK: # %bb.0: # %entry ++; CHECK: .LBB0_1: # %entry ++; CHECK: .LBB0_2: # %if.then ++; CHECK-NEXT: bl bar ++; CHECK: .LBB0_3: # %if.then2 ++; CHECK-NEXT: bl bar ++; CHECK: .LBB0_4: # %if.end3 ++; CHECK: b bar +diff --git a/llvm/test/CodeGen/LoongArch/not.ll b/llvm/test/CodeGen/LoongArch/not.ll +deleted file mode 100644 +index b9e02bdf1..000000000 +--- a/llvm/test/CodeGen/LoongArch/not.ll ++++ /dev/null +@@ -1,243 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-define i8 @nor_i8(i8 %a, i8 %b) nounwind { +-; LA32-LABEL: nor_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: nor $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: nor_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: nor $a0, $a0, $a1 +-; LA64-NEXT: ret +- %or = or i8 %a, %b +- %neg = xor i8 %or, -1 +- ret i8 %neg +-} +- +-define i16 @nor_i16(i16 %a, i16 %b) nounwind { +-; LA32-LABEL: nor_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: nor $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: nor_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: nor $a0, $a0, $a1 +-; LA64-NEXT: ret +- %or = or i16 %a, %b +- %neg = xor i16 %or, -1 +- ret i16 %neg +-} +- +-define i32 @nor_i32(i32 %a, i32 %b) nounwind { +-; LA32-LABEL: nor_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: nor $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: nor_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: nor $a0, $a0, $a1 +-; LA64-NEXT: ret +- %or = or i32 %a, %b +- %neg = xor i32 %or, -1 +- ret i32 %neg +-} +- +-define i64 @nor_i64(i64 %a, i64 %b) nounwind { +-; LA32-LABEL: nor_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: nor $a0, $a0, $a2 +-; LA32-NEXT: nor $a1, $a1, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: nor_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: nor $a0, $a0, $a1 +-; LA64-NEXT: ret +- %or = or i64 %a, %b +- %neg = xor i64 %or, -1 +- ret i64 %neg +-} +- +-define i8 @nor_zero_i8(i8 %a) nounwind { +-; LA32-LABEL: nor_zero_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: nor $a0, $a0, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: nor_zero_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: nor $a0, $a0, $zero +-; LA64-NEXT: ret +- %neg = xor i8 %a, -1 +- ret i8 %neg +-} +- +-define i16 @nor_zero_i16(i16 %a) nounwind { +-; LA32-LABEL: nor_zero_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: nor $a0, $a0, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: nor_zero_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: nor $a0, $a0, $zero +-; LA64-NEXT: ret +- %neg = xor i16 %a, -1 +- ret i16 %neg +-} +- +-define i32 @nor_zero_i32(i32 %a) nounwind { +-; LA32-LABEL: nor_zero_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: nor $a0, $a0, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: nor_zero_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: nor $a0, $a0, $zero +-; LA64-NEXT: ret +- %neg = xor i32 %a, -1 +- ret i32 %neg +-} +- +-define i64 @nor_zero_i64(i64 %a) nounwind { +-; LA32-LABEL: nor_zero_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: nor $a0, $a0, $zero +-; LA32-NEXT: nor $a1, $a1, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: nor_zero_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: nor $a0, $a0, $zero +-; LA64-NEXT: ret +- %neg = xor i64 %a, -1 +- ret i64 %neg +-} +- +-define i8 @orn_i8(i8 %a, i8 %b) nounwind { +-; LA32-LABEL: orn_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: orn $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: orn_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: orn $a0, $a0, $a1 +-; LA64-NEXT: ret +- %neg = xor i8 %b, -1 +- %or = or i8 %neg, %a +- ret i8 %or +-} +- +-define i16 @orn_i16(i16 %a, i16 %b) nounwind { +-; LA32-LABEL: orn_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: orn $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: orn_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: orn $a0, $a0, $a1 +-; LA64-NEXT: ret +- %neg = xor i16 %b, -1 +- %or = or i16 %neg, %a +- ret i16 %or +-} +- +-define i32 @orn_i32(i32 %a, i32 %b) nounwind { +-; LA32-LABEL: orn_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: orn $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: orn_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: orn $a0, $a0, $a1 +-; LA64-NEXT: ret +- %neg = xor i32 %b, -1 +- %or = or i32 %neg, %a +- ret i32 %or +-} +- +-define i64 @orn_i64(i64 %a, i64 %b) nounwind { +-; LA32-LABEL: orn_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: orn $a0, $a0, $a2 +-; LA32-NEXT: orn $a1, $a1, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: orn_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: orn $a0, $a0, $a1 +-; LA64-NEXT: ret +- %neg = xor i64 %b, -1 +- %or = or i64 %neg, %a +- ret i64 %or +-} +- +-define i8 @andn_i8(i8 %a, i8 %b) nounwind { +-; LA32-LABEL: andn_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: andn $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: andn_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: andn $a0, $a0, $a1 +-; LA64-NEXT: ret +- %neg = xor i8 %b, -1 +- %and = and i8 %neg, %a +- ret i8 %and +-} +- +-define i16 @andn_i16(i16 %a, i16 %b) nounwind { +-; LA32-LABEL: andn_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: andn $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: andn_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: andn $a0, $a0, $a1 +-; LA64-NEXT: ret +- %neg = xor i16 %b, -1 +- %and = and i16 %neg, %a +- ret i16 %and +-} +- +-define i32 @andn_i32(i32 %a, i32 %b) nounwind { +-; LA32-LABEL: andn_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: andn $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: andn_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: andn $a0, $a0, $a1 +-; LA64-NEXT: ret +- %neg = xor i32 %b, -1 +- %and = and i32 %neg, %a +- ret i32 %and +-} +- +-define i64 @andn_i64(i64 %a, i64 %b) nounwind { +-; LA32-LABEL: andn_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: andn $a0, $a0, $a2 +-; LA32-NEXT: andn $a1, $a1, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: andn_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: andn $a0, $a0, $a1 +-; LA64-NEXT: ret +- %neg = xor i64 %b, -1 +- %and = and i64 %neg, %a +- ret i64 %and +-} +diff --git a/llvm/test/CodeGen/LoongArch/noti32.ll b/llvm/test/CodeGen/LoongArch/noti32.ll +new file mode 100644 +index 000000000..9aa8c4391 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/noti32.ll +@@ -0,0 +1,143 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 < %s | FileCheck %s ++ ++define i8 @nor_i8(i8 %a, i8 %b) nounwind { ++; CHECK-LABEL: nor_i8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: or $r4, $r4, $r5 ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: nor $r4, $zero, $r4 ++; CHECK-NEXT: jr $ra ++ %or = or i8 %a, %b ++ %neg = xor i8 %or, -1 ++ ret i8 %neg ++} ++ ++define i16 @nor_i16(i16 %a, i16 %b) nounwind { ++; CHECK-LABEL: nor_i16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: or $r4, $r4, $r5 ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: nor $r4, $zero, $r4 ++; CHECK-NEXT: jr $ra ++ %or = or i16 %a, %b ++ %neg = xor i16 %or, -1 ++ ret i16 %neg ++} ++ ++define i32 @nor_i32(i32 %a, i32 %b) nounwind { ++; CHECK-LABEL: nor_i32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: or $r4, $r4, $r5 ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: nor $r4, $zero, $r4 ++; CHECK-NEXT: jr $ra ++ %or = or i32 %a, %b ++ %neg = xor i32 %or, -1 ++ ret i32 %neg ++} ++ ++define i8 @nor_zero_i8(i8 %a) nounwind { ++; CHECK-LABEL: nor_zero_i8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: nor $r4, $zero, $r4 ++; CHECK-NEXT: jr $ra ++ %neg = xor i8 %a, -1 ++ ret i8 %neg ++} ++ ++define i16 @nor_zero_i16(i16 %a) nounwind { ++; CHECK-LABEL: nor_zero_i16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: nor $r4, $zero, $r4 ++; CHECK-NEXT: jr $ra ++ %neg = xor i16 %a, -1 ++ ret i16 %neg ++} ++ ++define i32 @nor_zero_i32(i32 %a) nounwind { ++; CHECK-LABEL: nor_zero_i32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: nor $r4, $zero, $r4 ++; CHECK-NEXT: jr $ra ++ %neg = xor i32 %a, -1 ++ ret i32 %neg ++} ++ ++define i8 @orn_i8(i8 %a, i8 %b) nounwind { ++; CHECK-LABEL: orn_i8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: nor $r5, $zero, $r5 ++; CHECK-NEXT: or $r4, $r5, $r4 ++; CHECK-NEXT: jr $ra ++ %neg = xor i8 %b, -1 ++ %or = or i8 %neg, %a ++ ret i8 %or ++} ++ ++define i16 @orn_i16(i16 %a, i16 %b) nounwind { ++; CHECK-LABEL: orn_i16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: nor $r5, $zero, $r5 ++; CHECK-NEXT: or $r4, $r5, $r4 ++; CHECK-NEXT: jr $ra ++ %neg = xor i16 %b, -1 ++ %or = or i16 %neg, %a ++ ret i16 %or ++} ++ ++define i32 @orn_i32(i32 %a, i32 %b) nounwind { ++; CHECK-LABEL: orn_i32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: nor $r5, $zero, $r5 ++; CHECK-NEXT: or $r4, $r5, $r4 ++; CHECK-NEXT: jr $ra ++ %neg = xor i32 %b, -1 ++ %or = or i32 %neg, %a ++ ret i32 %or ++} ++ ++define i8 @andn_i8(i8 %a, i8 %b) nounwind { ++; CHECK-LABEL: andn_i8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: andn $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %neg = xor i8 %b, -1 ++ %and = and i8 %neg, %a ++ ret i8 %and ++} ++ ++define i16 @andn_i16(i16 %a, i16 %b) nounwind { ++; CHECK-LABEL: andn_i16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: andn $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %neg = xor i16 %b, -1 ++ %and = and i16 %neg, %a ++ ret i16 %and ++} ++ ++define i32 @andn_i32(i32 %a, i32 %b) nounwind { ++; CHECK-LABEL: andn_i32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: andn $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++ %neg = xor i32 %b, -1 ++ %and = and i32 %neg, %a ++ ret i32 %and ++} +diff --git a/llvm/test/CodeGen/LoongArch/numeric-reg-names.ll b/llvm/test/CodeGen/LoongArch/numeric-reg-names.ll +deleted file mode 100644 +index 153a697a5..000000000 +--- a/llvm/test/CodeGen/LoongArch/numeric-reg-names.ll ++++ /dev/null +@@ -1,42 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --loongarch-numeric-reg < %s \ +-; RUN: | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --loongarch-numeric-reg < %s \ +-; RUN: | FileCheck %s --check-prefix=LA64 +- +-@.str_1 = internal constant [7 x i8] c"hello\0A\00" +- +-declare i32 @printf(ptr, ...) +- +-define i32 @main() { +-; LA32-LABEL: main: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $r3, $r3, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $r1, $r3, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: pcalau12i $r4, %pc_hi20(.str_1) +-; LA32-NEXT: addi.w $r4, $r4, %pc_lo12(.str_1) +-; LA32-NEXT: bl %plt(printf) +-; LA32-NEXT: move $r4, $r0 +-; LA32-NEXT: ld.w $r1, $r3, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $r3, $r3, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: main: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $r3, $r3, -16 +-; LA64-NEXT: .cfi_def_cfa_offset 16 +-; LA64-NEXT: st.d $r1, $r3, 8 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: pcalau12i $r4, %pc_hi20(.str_1) +-; LA64-NEXT: addi.d $r4, $r4, %pc_lo12(.str_1) +-; LA64-NEXT: bl %plt(printf) +-; LA64-NEXT: move $r4, $r0 +-; LA64-NEXT: ld.d $r1, $r3, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $r3, $r3, 16 +-; LA64-NEXT: ret +- %s = getelementptr [7 x i8], ptr @.str_1, i64 0, i64 0 +- call i32 (ptr, ...) @printf(ptr %s) +- ret i32 0 +-} +diff --git a/llvm/test/CodeGen/LoongArch/opt-pipeline.ll b/llvm/test/CodeGen/LoongArch/opt-pipeline.ll +deleted file mode 100644 +index 3134d9405..000000000 +--- a/llvm/test/CodeGen/LoongArch/opt-pipeline.ll ++++ /dev/null +@@ -1,173 +0,0 @@ +-;; When EXPENSIVE_CHECKS are enabled, the machine verifier appears between each +-;; pass. Ignore it with 'grep -v'. +-; RUN: llc --mtriple=loongarch32 -O1 --debug-pass=Structure %s -o /dev/null 2>&1 | \ +-; RUN: grep -v "Verify generated machine code" | FileCheck %s +-; RUN: llc --mtriple=loongarch32 -O2 --debug-pass=Structure %s -o /dev/null 2>&1 | \ +-; RUN: grep -v "Verify generated machine code" | FileCheck %s +-; RUN: llc --mtriple=loongarch32 -O3 --debug-pass=Structure %s -o /dev/null 2>&1 | \ +-; RUN: grep -v "Verify generated machine code" | FileCheck %s +-; RUN: llc --mtriple=loongarch64 -O1 --debug-pass=Structure %s -o /dev/null 2>&1 | \ +-; RUN: grep -v "Verify generated machine code" | FileCheck %s +-; RUN: llc --mtriple=loongarch64 -O2 --debug-pass=Structure %s -o /dev/null 2>&1 | \ +-; RUN: grep -v "Verify generated machine code" | FileCheck %s +-; RUN: llc --mtriple=loongarch64 -O3 --debug-pass=Structure %s -o /dev/null 2>&1 | \ +-; RUN: grep -v "Verify generated machine code" | FileCheck %s +- +-; REQUIRES: asserts +- +-; CHECK-LABEL: Pass Arguments: +-; CHECK-NEXT: Target Library Information +-; CHECK-NEXT: Target Pass Configuration +-; CHECK-NEXT: Machine Module Information +-; CHECK-NEXT: Target Transform Information +-; CHECK-NEXT: Type-Based Alias Analysis +-; CHECK-NEXT: Scoped NoAlias Alias Analysis +-; CHECK-NEXT: Assumption Cache Tracker +-; CHECK-NEXT: Profile summary info +-; CHECK-NEXT: Create Garbage Collector Module Metadata +-; CHECK-NEXT: Machine Branch Probability Analysis +-; CHECK-NEXT: Default Regalloc Eviction Advisor +-; CHECK-NEXT: Default Regalloc Priority Advisor +-; CHECK-NEXT: ModulePass Manager +-; CHECK-NEXT: Pre-ISel Intrinsic Lowering +-; CHECK-NEXT: FunctionPass Manager +-; CHECK-NEXT: Expand large div/rem +-; CHECK-NEXT: Expand large fp convert +-; CHECK-NEXT: Expand Atomic instructions +-; CHECK-NEXT: Module Verifier +-; CHECK-NEXT: Dominator Tree Construction +-; CHECK-NEXT: Basic Alias Analysis (stateless AA impl) +-; CHECK-NEXT: Natural Loop Information +-; CHECK-NEXT: Canonicalize natural loops +-; CHECK-NEXT: Scalar Evolution Analysis +-; CHECK-NEXT: Loop Pass Manager +-; CHECK-NEXT: Canonicalize Freeze Instructions in Loops +-; CHECK-NEXT: Induction Variable Users +-; CHECK-NEXT: Loop Strength Reduction +-; CHECK-NEXT: Basic Alias Analysis (stateless AA impl) +-; CHECK-NEXT: Function Alias Analysis Results +-; CHECK-NEXT: Merge contiguous icmps into a memcmp +-; CHECK-NEXT: Natural Loop Information +-; CHECK-NEXT: Lazy Branch Probability Analysis +-; CHECK-NEXT: Lazy Block Frequency Analysis +-; CHECK-NEXT: Expand memcmp() to load/stores +-; CHECK-NEXT: Lower Garbage Collection Instructions +-; CHECK-NEXT: Shadow Stack GC Lowering +-; CHECK-NEXT: Lower constant intrinsics +-; CHECK-NEXT: Remove unreachable blocks from the CFG +-; CHECK-NEXT: Natural Loop Information +-; CHECK-NEXT: Post-Dominator Tree Construction +-; CHECK-NEXT: Branch Probability Analysis +-; CHECK-NEXT: Block Frequency Analysis +-; CHECK-NEXT: Constant Hoisting +-; CHECK-NEXT: Replace intrinsics with calls to vector library +-; CHECK-NEXT: Partially inline calls to library functions +-; CHECK-NEXT: Expand vector predication intrinsics +-; CHECK-NEXT: Scalarize Masked Memory Intrinsics +-; CHECK-NEXT: Expand reduction intrinsics +-; CHECK-NEXT: Natural Loop Information +-; CHECK-NEXT: TLS Variable Hoist +-; CHECK-NEXT: CodeGen Prepare +-; CHECK-NEXT: Dominator Tree Construction +-; CHECK-NEXT: Exception handling preparation +-; CHECK-NEXT: Prepare callbr +-; CHECK-NEXT: Safe Stack instrumentation pass +-; CHECK-NEXT: Insert stack protectors +-; CHECK-NEXT: Module Verifier +-; CHECK-NEXT: Basic Alias Analysis (stateless AA impl) +-; CHECK-NEXT: Function Alias Analysis Results +-; CHECK-NEXT: Natural Loop Information +-; CHECK-NEXT: Post-Dominator Tree Construction +-; CHECK-NEXT: Branch Probability Analysis +-; CHECK-NEXT: Assignment Tracking Analysis +-; CHECK-NEXT: Lazy Branch Probability Analysis +-; CHECK-NEXT: Lazy Block Frequency Analysis +-; CHECK-NEXT: LoongArch DAG->DAG Pattern Instruction Selection +-; CHECK-NEXT: Finalize ISel and expand pseudo-instructions +-; CHECK-NEXT: Lazy Machine Block Frequency Analysis +-; CHECK-NEXT: Early Tail Duplication +-; CHECK-NEXT: Optimize machine instruction PHIs +-; CHECK-NEXT: Slot index numbering +-; CHECK-NEXT: Merge disjoint stack slots +-; CHECK-NEXT: Local Stack Slot Allocation +-; CHECK-NEXT: Remove dead machine instructions +-; CHECK-NEXT: MachineDominator Tree Construction +-; CHECK-NEXT: Machine Natural Loop Construction +-; CHECK-NEXT: Machine Block Frequency Analysis +-; CHECK-NEXT: Early Machine Loop Invariant Code Motion +-; CHECK-NEXT: MachineDominator Tree Construction +-; CHECK-NEXT: Machine Block Frequency Analysis +-; CHECK-NEXT: Machine Common Subexpression Elimination +-; CHECK-NEXT: MachinePostDominator Tree Construction +-; CHECK-NEXT: Machine Cycle Info Analysis +-; CHECK-NEXT: Machine code sinking +-; CHECK-NEXT: Peephole Optimizations +-; CHECK-NEXT: Remove dead machine instructions +-; CHECK-NEXT: LoongArch Pre-RA pseudo instruction expansion pass +-; CHECK-NEXT: Detect Dead Lanes +-; CHECK-NEXT: Process Implicit Definitions +-; CHECK-NEXT: Remove unreachable machine basic blocks +-; CHECK-NEXT: Live Variable Analysis +-; CHECK-NEXT: Eliminate PHI nodes for register allocation +-; CHECK-NEXT: Two-Address instruction pass +-; CHECK-NEXT: MachineDominator Tree Construction +-; CHECK-NEXT: Slot index numbering +-; CHECK-NEXT: Live Interval Analysis +-; CHECK-NEXT: Register Coalescer +-; CHECK-NEXT: Rename Disconnected Subregister Components +-; CHECK-NEXT: Machine Instruction Scheduler +-; CHECK-NEXT: Machine Block Frequency Analysis +-; CHECK-NEXT: Debug Variable Analysis +-; CHECK-NEXT: Live Stack Slot Analysis +-; CHECK-NEXT: Virtual Register Map +-; CHECK-NEXT: Live Register Matrix +-; CHECK-NEXT: Bundle Machine CFG Edges +-; CHECK-NEXT: Spill Code Placement Analysis +-; CHECK-NEXT: Lazy Machine Block Frequency Analysis +-; CHECK-NEXT: Machine Optimization Remark Emitter +-; CHECK-NEXT: Greedy Register Allocator +-; CHECK-NEXT: Virtual Register Rewriter +-; CHECK-NEXT: Register Allocation Pass Scoring +-; CHECK-NEXT: Stack Slot Coloring +-; CHECK-NEXT: Machine Copy Propagation Pass +-; CHECK-NEXT: Machine Loop Invariant Code Motion +-; CHECK-NEXT: Remove Redundant DEBUG_VALUE analysis +-; CHECK-NEXT: Fixup Statepoint Caller Saved +-; CHECK-NEXT: PostRA Machine Sink +-; CHECK-NEXT: Machine Block Frequency Analysis +-; CHECK-NEXT: MachineDominator Tree Construction +-; CHECK-NEXT: MachinePostDominator Tree Construction +-; CHECK-NEXT: Lazy Machine Block Frequency Analysis +-; CHECK-NEXT: Machine Optimization Remark Emitter +-; CHECK-NEXT: Shrink Wrapping analysis +-; CHECK-NEXT: Prologue/Epilogue Insertion & Frame Finalization +-; CHECK-NEXT: Machine Late Instructions Cleanup Pass +-; CHECK-NEXT: Control Flow Optimizer +-; CHECK-NEXT: Lazy Machine Block Frequency Analysis +-; CHECK-NEXT: Tail Duplication +-; CHECK-NEXT: Machine Copy Propagation Pass +-; CHECK-NEXT: Post-RA pseudo instruction expansion pass +-; CHECK-NEXT: MachineDominator Tree Construction +-; CHECK-NEXT: Machine Natural Loop Construction +-; CHECK-NEXT: Post RA top-down list latency scheduler +-; CHECK-NEXT: Analyze Machine Code For Garbage Collection +-; CHECK-NEXT: Machine Block Frequency Analysis +-; CHECK-NEXT: MachinePostDominator Tree Construction +-; CHECK-NEXT: Branch Probability Basic Block Placement +-; CHECK-NEXT: Insert fentry calls +-; CHECK-NEXT: Insert XRay ops +-; CHECK-NEXT: Implement the 'patchable-function' attribute +-; CHECK-NEXT: Branch relaxation pass +-; CHECK-NEXT: Contiguously Lay Out Funclets +-; CHECK-NEXT: StackMap Liveness Analysis +-; CHECK-NEXT: Live DEBUG_VALUE analysis +-; CHECK-NEXT: Machine Sanitizer Binary Metadata +-; CHECK-NEXT: Lazy Machine Block Frequency Analysis +-; CHECK-NEXT: Machine Optimization Remark Emitter +-; CHECK-NEXT: Stack Frame Layout Analysis +-; CHECK-NEXT: LoongArch pseudo instruction expansion pass +-; CHECK-NEXT: LoongArch atomic pseudo instruction expansion pass +-; CHECK-NEXT: Lazy Machine Block Frequency Analysis +-; CHECK-NEXT: Machine Optimization Remark Emitter +-; CHECK-NEXT: LoongArch Assembly Printer +-; CHECK-NEXT: Free MachineFunction +diff --git a/llvm/test/CodeGen/LoongArch/patchable-function-entry.ll b/llvm/test/CodeGen/LoongArch/patchable-function-entry.ll +deleted file mode 100644 +index 2e390d1e2..000000000 +--- a/llvm/test/CodeGen/LoongArch/patchable-function-entry.ll ++++ /dev/null +@@ -1,63 +0,0 @@ +-;; Test the function attribute "patchable-function-entry". +-;; Adapted from the RISCV test case. +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefixes=CHECK,LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefixes=CHECK,LA64 +- +-define void @f0() "patchable-function-entry"="0" { +-; CHECK-LABEL: f0: +-; CHECK-NEXT: .Lfunc_begin0: +-; CHECK-NOT: nop +-; CHECK: ret +-; CHECK-NOT: .section __patchable_function_entries +- ret void +-} +- +-define void @f1() "patchable-function-entry"="1" { +-; CHECK-LABEL: f1: +-; CHECK-NEXT: .Lfunc_begin1: +-; CHECK: nop +-; CHECK-NEXT: ret +-; CHECK: .section __patchable_function_entries,"awo",@progbits,f1{{$}} +-; LA32: .p2align 2 +-; LA32-NEXT: .word .Lfunc_begin1 +-; LA64: .p2align 3 +-; LA64-NEXT: .dword .Lfunc_begin1 +- ret void +-} +- +-$f5 = comdat any +-define void @f5() "patchable-function-entry"="5" comdat { +-; CHECK-LABEL: f5: +-; CHECK-NEXT: .Lfunc_begin2: +-; CHECK-COUNT-5: nop +-; CHECK-NEXT: ret +-; CHECK: .section __patchable_function_entries,"awoG",@progbits,f5,f5,comdat{{$}} +-; LA32: .p2align 2 +-; LA32-NEXT: .word .Lfunc_begin2 +-; LA64: .p2align 3 +-; LA64-NEXT: .dword .Lfunc_begin2 +- ret void +-} +- +-;; -fpatchable-function-entry=3,2 +-;; "patchable-function-prefix" emits data before the function entry label. +-define void @f3_2() "patchable-function-entry"="1" "patchable-function-prefix"="2" { +-; CHECK-LABEL: .type f3_2,@function +-; CHECK-NEXT: .Ltmp0: +-; CHECK-COUNT-2: nop +-; CHECK-NEXT: f3_2: # @f3_2 +-; CHECK: # %bb.0: +-; CHECK-NEXT: nop +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA64-NEXT: addi.d $sp, $sp, -16 +-;; .size does not include the prefix. +-; CHECK: .Lfunc_end3: +-; CHECK-NEXT: .size f3_2, .Lfunc_end3-f3_2 +-; CHECK: .section __patchable_function_entries,"awo",@progbits,f3_2{{$}} +-; LA32: .p2align 2 +-; LA32-NEXT: .word .Ltmp0 +-; LA64: .p2align 3 +-; LA64-NEXT: .dword .Ltmp0 +- %frame = alloca i8, i32 16 +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/peephole-load-store-addi.ll b/llvm/test/CodeGen/LoongArch/peephole-load-store-addi.ll +new file mode 100644 +index 000000000..541ea4256 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/peephole-load-store-addi.ll +@@ -0,0 +1,100 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s ++ ++define i8 @load_i8() nounwind { ++; CHECK-LABEL: load_i8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.bu $r4, $zero, 40 ++; CHECK-NEXT: jr $ra ++ %a = load i8, i8* inttoptr (i64 40 to i8*), align 8 ++ ret i8 %a ++} ++define signext i8 @load_i8_sext() nounwind { ++; CHECK-LABEL: load_i8_sext: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.b $r4, $zero, 40 ++; CHECK-NEXT: jr $ra ++ %a = load i8, i8* inttoptr (i64 40 to i8*), align 8 ++ ret i8 %a ++} ++ ++define i16 @load_i16() nounwind { ++; CHECK-LABEL: load_i16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.hu $r4, $zero, 40 ++; CHECK-NEXT: jr $ra ++ %a = load i16, i16* inttoptr (i64 40 to i16*), align 8 ++ ret i16 %a ++} ++ ++define signext i16 @load_i16_sext() nounwind { ++; CHECK-LABEL: load_i16_sext: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.h $r4, $zero, 40 ++; CHECK-NEXT: jr $ra ++ %a = load i16, i16* inttoptr (i64 40 to i16*), align 8 ++ ret i16 %a ++} ++ ++define i32 @load_i32() nounwind { ++; CHECK-LABEL: load_i32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.w $r4, $zero, 40 ++; CHECK-NEXT: jr $ra ++ %a = load i32, i32* inttoptr (i64 40 to i32*), align 8 ++ ret i32 %a ++} ++ ++define signext i32 @load_i32_sext() nounwind { ++; CHECK-LABEL: load_i32_sext: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.w $r4, $zero, 40 ++; CHECK-NEXT: jr $ra ++ %a = load i32, i32* inttoptr (i64 40 to i32*), align 8 ++ ret i32 %a ++} ++ ++define i64 @load_i64() nounwind { ++; CHECK-LABEL: load_i64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: ld.d $r4, $zero, 40 ++; CHECK-NEXT: jr $ra ++ %a = load i64, i64* inttoptr (i64 40 to i64*), align 8 ++ ret i64 %a ++} ++ ++define void @store_i8(i8 %v) nounwind { ++; CHECK-LABEL: store_i8: ++; CHECK: # %bb.0: ++; CHECK-NEXT: st.b $r4, $zero, 40 ++; CHECK-NEXT: jr $ra ++ store i8 %v, i8* inttoptr (i64 40 to i8*), align 8 ++ ret void ++} ++ ++define void @store_i16(i16 %v) nounwind { ++; CHECK-LABEL: store_i16: ++; CHECK: # %bb.0: ++; CHECK-NEXT: st.h $r4, $zero, 40 ++; CHECK-NEXT: jr $ra ++ store i16 %v, i16* inttoptr (i64 40 to i16*), align 8 ++ ret void ++} ++ ++define void @store_i32(i32 %v) nounwind { ++; CHECK-LABEL: store_i32: ++; CHECK: # %bb.0: ++; CHECK-NEXT: st.w $r4, $zero, 40 ++; CHECK-NEXT: jr $ra ++ store i32 %v, i32* inttoptr (i64 40 to i32*), align 8 ++ ret void ++} ++ ++define void @store_i64(i64 %v) nounwind { ++; CHECK-LABEL: store_i64: ++; CHECK: # %bb.0: ++; CHECK-NEXT: st.d $r4, $zero, 40 ++; CHECK-NEXT: jr $ra ++ store i64 %v, i64* inttoptr (i64 40 to i64*), align 8 ++ ret void ++} +diff --git a/llvm/test/CodeGen/LoongArch/preferred-alignments.ll b/llvm/test/CodeGen/LoongArch/preferred-alignments.ll +deleted file mode 100644 +index 6dac52587..000000000 +--- a/llvm/test/CodeGen/LoongArch/preferred-alignments.ll ++++ /dev/null +@@ -1,47 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck --check-prefix=LA464 %s +-; RUN: llc --mtriple=loongarch64 --mcpu=la464 < %s | FileCheck --check-prefix=LA464 %s +- +-define signext i32 @sum(ptr noalias nocapture noundef readonly %0, i32 noundef signext %1) { +-; LA464-LABEL: sum: +-; LA464: # %bb.0: +-; LA464-NEXT: ori $a2, $zero, 1 +-; LA464-NEXT: blt $a1, $a2, .LBB0_4 +-; LA464-NEXT: # %bb.1: +-; LA464-NEXT: bstrpick.d $a2, $a1, 31, 0 +-; LA464-NEXT: move $a1, $zero +-; LA464-NEXT: .p2align 4, , 16 +-; LA464-NEXT: .LBB0_2: # =>This Inner Loop Header: Depth=1 +-; LA464-NEXT: ld.w $a3, $a0, 0 +-; LA464-NEXT: add.d $a1, $a3, $a1 +-; LA464-NEXT: addi.d $a0, $a0, 4 +-; LA464-NEXT: addi.d $a2, $a2, -1 +-; LA464-NEXT: bnez $a2, .LBB0_2 +-; LA464-NEXT: # %bb.3: +-; LA464-NEXT: addi.w $a0, $a1, 0 +-; LA464-NEXT: ret +-; LA464-NEXT: .LBB0_4: +-; LA464-NEXT: move $a1, $zero +-; LA464-NEXT: addi.w $a0, $a1, 0 +-; LA464-NEXT: ret +- %3 = icmp sgt i32 %1, 0 +- br i1 %3, label %4, label %6 +- +-4: ; preds = %2 +- %5 = zext i32 %1 to i64 +- br label %8 +- +-6: ; preds = %8, %2 +- %7 = phi i32 [ 0, %2 ], [ %13, %8 ] +- ret i32 %7 +- +-8: ; preds = %4, %8 +- %9 = phi i64 [ 0, %4 ], [ %14, %8 ] +- %10 = phi i32 [ 0, %4 ], [ %13, %8 ] +- %11 = getelementptr inbounds i32, ptr %0, i64 %9 +- %12 = load i32, ptr %11, align 4 +- %13 = add nsw i32 %12, %10 +- %14 = add nuw nsw i64 %9, 1 +- %15 = icmp eq i64 %14, %5 +- br i1 %15, label %6, label %8 +-} +diff --git a/llvm/test/CodeGen/LoongArch/psabi-restricted-scheduling.ll b/llvm/test/CodeGen/LoongArch/psabi-restricted-scheduling.ll +deleted file mode 100644 +index d6f3e3469..000000000 +--- a/llvm/test/CodeGen/LoongArch/psabi-restricted-scheduling.ll ++++ /dev/null +@@ -1,172 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +-; RUN: llc --mtriple=loongarch64 --code-model=medium --post-RA-scheduler=0 < %s \ +-; RUN: | FileCheck %s --check-prefix=MEDIUM_NO_SCH +-; RUN: llc --mtriple=loongarch64 --code-model=medium --post-RA-scheduler=1 < %s \ +-; RUN: | FileCheck %s --check-prefix=MEDIUM_SCH +-; RUN: llc --mtriple=loongarch64 --code-model=large --post-RA-scheduler=0 < %s \ +-; RUN: | FileCheck %s --check-prefix=LARGE_NO_SCH +-; RUN: llc --mtriple=loongarch64 --code-model=large --post-RA-scheduler=1 < %s \ +-; RUN: | FileCheck %s --check-prefix=LARGE_SCH +- +-;; FIXME: According to the description of the psABI v2.30, the code sequences +-;; of `PseudoLA*_LARGE` instruction and Medium code model's function call must +-;; be adjacent. +- +-@g = dso_local global i64 zeroinitializer, align 4 +-@G = global i64 zeroinitializer, align 4 +-@gd = external thread_local global i64 +-@ld = external thread_local(localdynamic) global i64 +-@ie = external thread_local(initialexec) global i64 +- +-declare ptr @bar(i64) +- +-define void @foo() nounwind { +-; MEDIUM_NO_SCH-LABEL: foo: +-; MEDIUM_NO_SCH: # %bb.0: +-; MEDIUM_NO_SCH-NEXT: addi.d $sp, $sp, -16 +-; MEDIUM_NO_SCH-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; MEDIUM_NO_SCH-NEXT: pcalau12i $a0, %got_pc_hi20(G) +-; MEDIUM_NO_SCH-NEXT: ld.d $a0, $a0, %got_pc_lo12(G) +-; MEDIUM_NO_SCH-NEXT: ld.d $a0, $a0, 0 +-; MEDIUM_NO_SCH-NEXT: pcalau12i $a0, %pc_hi20(g) +-; MEDIUM_NO_SCH-NEXT: addi.d $a0, $a0, %pc_lo12(g) +-; MEDIUM_NO_SCH-NEXT: ld.d $a0, $a0, 0 +-; MEDIUM_NO_SCH-NEXT: ori $a0, $zero, 1 +-; MEDIUM_NO_SCH-NEXT: pcaddu18i $ra, %call36(bar) +-; MEDIUM_NO_SCH-NEXT: jirl $ra, $ra, 0 +-; MEDIUM_NO_SCH-NEXT: pcalau12i $a0, %ie_pc_hi20(gd) +-; MEDIUM_NO_SCH-NEXT: ld.d $a0, $a0, %ie_pc_lo12(gd) +-; MEDIUM_NO_SCH-NEXT: ldx.d $a0, $a0, $tp +-; MEDIUM_NO_SCH-NEXT: pcalau12i $a0, %ie_pc_hi20(ld) +-; MEDIUM_NO_SCH-NEXT: ld.d $a0, $a0, %ie_pc_lo12(ld) +-; MEDIUM_NO_SCH-NEXT: ldx.d $a0, $a0, $tp +-; MEDIUM_NO_SCH-NEXT: pcalau12i $a0, %ie_pc_hi20(ie) +-; MEDIUM_NO_SCH-NEXT: ld.d $a0, $a0, %ie_pc_lo12(ie) +-; MEDIUM_NO_SCH-NEXT: ldx.d $a0, $a0, $tp +-; MEDIUM_NO_SCH-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; MEDIUM_NO_SCH-NEXT: addi.d $sp, $sp, 16 +-; MEDIUM_NO_SCH-NEXT: ret +-; +-; MEDIUM_SCH-LABEL: foo: +-; MEDIUM_SCH: # %bb.0: +-; MEDIUM_SCH-NEXT: addi.d $sp, $sp, -16 +-; MEDIUM_SCH-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; MEDIUM_SCH-NEXT: pcalau12i $a0, %got_pc_hi20(G) +-; MEDIUM_SCH-NEXT: ld.d $a0, $a0, %got_pc_lo12(G) +-; MEDIUM_SCH-NEXT: ld.d $a0, $a0, 0 +-; MEDIUM_SCH-NEXT: pcalau12i $a0, %pc_hi20(g) +-; MEDIUM_SCH-NEXT: addi.d $a0, $a0, %pc_lo12(g) +-; MEDIUM_SCH-NEXT: ld.d $a0, $a0, 0 +-; MEDIUM_SCH-NEXT: ori $a0, $zero, 1 +-; MEDIUM_SCH-NEXT: pcaddu18i $ra, %call36(bar) +-; MEDIUM_SCH-NEXT: jirl $ra, $ra, 0 +-; MEDIUM_SCH-NEXT: pcalau12i $a0, %ie_pc_hi20(gd) +-; MEDIUM_SCH-NEXT: ld.d $a0, $a0, %ie_pc_lo12(gd) +-; MEDIUM_SCH-NEXT: ldx.d $a0, $a0, $tp +-; MEDIUM_SCH-NEXT: pcalau12i $a0, %ie_pc_hi20(ld) +-; MEDIUM_SCH-NEXT: ld.d $a0, $a0, %ie_pc_lo12(ld) +-; MEDIUM_SCH-NEXT: ldx.d $a0, $a0, $tp +-; MEDIUM_SCH-NEXT: pcalau12i $a0, %ie_pc_hi20(ie) +-; MEDIUM_SCH-NEXT: ld.d $a0, $a0, %ie_pc_lo12(ie) +-; MEDIUM_SCH-NEXT: ldx.d $a0, $a0, $tp +-; MEDIUM_SCH-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; MEDIUM_SCH-NEXT: addi.d $sp, $sp, 16 +-; MEDIUM_SCH-NEXT: ret +-; +-; LARGE_NO_SCH-LABEL: foo: +-; LARGE_NO_SCH: # %bb.0: +-; LARGE_NO_SCH-NEXT: addi.d $sp, $sp, -16 +-; LARGE_NO_SCH-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LARGE_NO_SCH-NEXT: pcalau12i $a0, %got_pc_hi20(G) +-; LARGE_NO_SCH-NEXT: addi.d $t8, $zero, %got_pc_lo12(G) +-; LARGE_NO_SCH-NEXT: lu32i.d $t8, %got64_pc_lo20(G) +-; LARGE_NO_SCH-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(G) +-; LARGE_NO_SCH-NEXT: ldx.d $a0, $t8, $a0 +-; LARGE_NO_SCH-NEXT: ld.d $a0, $a0, 0 +-; LARGE_NO_SCH-NEXT: pcalau12i $a0, %pc_hi20(g) +-; LARGE_NO_SCH-NEXT: addi.d $t8, $zero, %pc_lo12(g) +-; LARGE_NO_SCH-NEXT: lu32i.d $t8, %pc64_lo20(g) +-; LARGE_NO_SCH-NEXT: lu52i.d $t8, $t8, %pc64_hi12(g) +-; LARGE_NO_SCH-NEXT: add.d $a0, $t8, $a0 +-; LARGE_NO_SCH-NEXT: ld.d $a0, $a0, 0 +-; LARGE_NO_SCH-NEXT: ori $a0, $zero, 1 +-; LARGE_NO_SCH-NEXT: pcalau12i $ra, %got_pc_hi20(bar) +-; LARGE_NO_SCH-NEXT: addi.d $t8, $zero, %got_pc_lo12(bar) +-; LARGE_NO_SCH-NEXT: lu32i.d $t8, %got64_pc_lo20(bar) +-; LARGE_NO_SCH-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(bar) +-; LARGE_NO_SCH-NEXT: ldx.d $ra, $t8, $ra +-; LARGE_NO_SCH-NEXT: jirl $ra, $ra, 0 +-; LARGE_NO_SCH-NEXT: pcalau12i $a0, %ie_pc_hi20(gd) +-; LARGE_NO_SCH-NEXT: addi.d $t8, $zero, %ie_pc_lo12(gd) +-; LARGE_NO_SCH-NEXT: lu32i.d $t8, %ie64_pc_lo20(gd) +-; LARGE_NO_SCH-NEXT: lu52i.d $t8, $t8, %ie64_pc_hi12(gd) +-; LARGE_NO_SCH-NEXT: ldx.d $a0, $t8, $a0 +-; LARGE_NO_SCH-NEXT: ldx.d $a0, $a0, $tp +-; LARGE_NO_SCH-NEXT: pcalau12i $a0, %ie_pc_hi20(ld) +-; LARGE_NO_SCH-NEXT: addi.d $t8, $zero, %ie_pc_lo12(ld) +-; LARGE_NO_SCH-NEXT: lu32i.d $t8, %ie64_pc_lo20(ld) +-; LARGE_NO_SCH-NEXT: lu52i.d $t8, $t8, %ie64_pc_hi12(ld) +-; LARGE_NO_SCH-NEXT: ldx.d $a0, $t8, $a0 +-; LARGE_NO_SCH-NEXT: ldx.d $a0, $a0, $tp +-; LARGE_NO_SCH-NEXT: pcalau12i $a0, %ie_pc_hi20(ie) +-; LARGE_NO_SCH-NEXT: addi.d $t8, $zero, %ie_pc_lo12(ie) +-; LARGE_NO_SCH-NEXT: lu32i.d $t8, %ie64_pc_lo20(ie) +-; LARGE_NO_SCH-NEXT: lu52i.d $t8, $t8, %ie64_pc_hi12(ie) +-; LARGE_NO_SCH-NEXT: ldx.d $a0, $t8, $a0 +-; LARGE_NO_SCH-NEXT: ldx.d $a0, $a0, $tp +-; LARGE_NO_SCH-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LARGE_NO_SCH-NEXT: addi.d $sp, $sp, 16 +-; LARGE_NO_SCH-NEXT: ret +-; +-; LARGE_SCH-LABEL: foo: +-; LARGE_SCH: # %bb.0: +-; LARGE_SCH-NEXT: addi.d $sp, $sp, -16 +-; LARGE_SCH-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LARGE_SCH-NEXT: pcalau12i $a0, %got_pc_hi20(G) +-; LARGE_SCH-NEXT: addi.d $t8, $zero, %got_pc_lo12(G) +-; LARGE_SCH-NEXT: lu32i.d $t8, %got64_pc_lo20(G) +-; LARGE_SCH-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(G) +-; LARGE_SCH-NEXT: ldx.d $a0, $t8, $a0 +-; LARGE_SCH-NEXT: ld.d $a0, $a0, 0 +-; LARGE_SCH-NEXT: pcalau12i $a0, %pc_hi20(g) +-; LARGE_SCH-NEXT: addi.d $t8, $zero, %pc_lo12(g) +-; LARGE_SCH-NEXT: lu32i.d $t8, %pc64_lo20(g) +-; LARGE_SCH-NEXT: lu52i.d $t8, $t8, %pc64_hi12(g) +-; LARGE_SCH-NEXT: add.d $a0, $t8, $a0 +-; LARGE_SCH-NEXT: ld.d $a0, $a0, 0 +-; LARGE_SCH-NEXT: ori $a0, $zero, 1 +-; LARGE_SCH-NEXT: pcalau12i $ra, %got_pc_hi20(bar) +-; LARGE_SCH-NEXT: addi.d $t8, $zero, %got_pc_lo12(bar) +-; LARGE_SCH-NEXT: lu32i.d $t8, %got64_pc_lo20(bar) +-; LARGE_SCH-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(bar) +-; LARGE_SCH-NEXT: ldx.d $ra, $t8, $ra +-; LARGE_SCH-NEXT: jirl $ra, $ra, 0 +-; LARGE_SCH-NEXT: pcalau12i $a0, %ie_pc_hi20(gd) +-; LARGE_SCH-NEXT: addi.d $t8, $zero, %ie_pc_lo12(gd) +-; LARGE_SCH-NEXT: lu32i.d $t8, %ie64_pc_lo20(gd) +-; LARGE_SCH-NEXT: lu52i.d $t8, $t8, %ie64_pc_hi12(gd) +-; LARGE_SCH-NEXT: ldx.d $a0, $t8, $a0 +-; LARGE_SCH-NEXT: ldx.d $a0, $a0, $tp +-; LARGE_SCH-NEXT: pcalau12i $a0, %ie_pc_hi20(ld) +-; LARGE_SCH-NEXT: addi.d $t8, $zero, %ie_pc_lo12(ld) +-; LARGE_SCH-NEXT: lu32i.d $t8, %ie64_pc_lo20(ld) +-; LARGE_SCH-NEXT: lu52i.d $t8, $t8, %ie64_pc_hi12(ld) +-; LARGE_SCH-NEXT: ldx.d $a0, $t8, $a0 +-; LARGE_SCH-NEXT: ldx.d $a0, $a0, $tp +-; LARGE_SCH-NEXT: pcalau12i $a0, %ie_pc_hi20(ie) +-; LARGE_SCH-NEXT: addi.d $t8, $zero, %ie_pc_lo12(ie) +-; LARGE_SCH-NEXT: lu32i.d $t8, %ie64_pc_lo20(ie) +-; LARGE_SCH-NEXT: lu52i.d $t8, $t8, %ie64_pc_hi12(ie) +-; LARGE_SCH-NEXT: ldx.d $a0, $t8, $a0 +-; LARGE_SCH-NEXT: ldx.d $a0, $a0, $tp +-; LARGE_SCH-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LARGE_SCH-NEXT: addi.d $sp, $sp, 16 +-; LARGE_SCH-NEXT: ret +- %V = load volatile i64, ptr @G +- %v = load volatile i64, ptr @g +- call void @bar(i64 1) +- %v_gd = load volatile i64, ptr @gd +- %v_ld = load volatile i64, ptr @ld +- %v_ie = load volatile i64, ptr @ie +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/register-coalescer-crash-pr79718.mir b/llvm/test/CodeGen/LoongArch/register-coalescer-crash-pr79718.mir +deleted file mode 100644 +index 9bbb579b7..000000000 +--- a/llvm/test/CodeGen/LoongArch/register-coalescer-crash-pr79718.mir ++++ /dev/null +@@ -1,213 +0,0 @@ +-# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4 +-# RUN: llc -o - %s -mtriple=loongarch64 \ +-# RUN: -run-pass=register-coalescer -join-liveintervals=1 -join-splitedges=0 | FileCheck %s +- +---- +-name: foo +-tracksRegLiveness: true +-body: | +- ; CHECK-LABEL: name: foo +- ; CHECK: bb.0: +- ; CHECK-NEXT: successors: %bb.1(0x80000000) +- ; CHECK-NEXT: liveins: $r4, $r5, $r6, $r7, $r8 +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $r8 +- ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $r7 +- ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $r6 +- ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $r5 +- ; CHECK-NEXT: [[COPY4:%[0-9]+]]:gpr = COPY $r4 +- ; CHECK-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY3]], 1 +- ; CHECK-NEXT: [[ORI:%[0-9]+]]:gpr = ORI $r0, 1 +- ; CHECK-NEXT: [[ANDI1:%[0-9]+]]:gpr = ANDI [[COPY2]], 1 +- ; CHECK-NEXT: [[ANDI2:%[0-9]+]]:gpr = ANDI [[COPY1]], 1 +- ; CHECK-NEXT: [[ANDI3:%[0-9]+]]:gpr = ANDI [[COPY]], 1 +- ; CHECK-NEXT: [[COPY5:%[0-9]+]]:gpr = COPY $r0 +- ; CHECK-NEXT: [[COPY6:%[0-9]+]]:gpr = COPY $r0 +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: bb.1: +- ; CHECK-NEXT: successors: %bb.2(0x80000000) +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: [[COPY7:%[0-9]+]]:gpr = COPY [[COPY5]] +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: bb.2: +- ; CHECK-NEXT: successors: %bb.3(0x40000000), %bb.4(0x40000000) +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: BEQZ [[ANDI]], %bb.4 +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: bb.3: +- ; CHECK-NEXT: successors: %bb.9(0x80000000) +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: PseudoBR %bb.9 +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: bb.4: +- ; CHECK-NEXT: successors: %bb.5(0x80000000) +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: bb.5: +- ; CHECK-NEXT: successors: %bb.7(0x7c000000), %bb.6(0x04000000) +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: dead [[LD_D:%[0-9]+]]:gpr = LD_D $r0, 8 +- ; CHECK-NEXT: dead [[LD_D1:%[0-9]+]]:gpr = LD_D $r0, 0 +- ; CHECK-NEXT: BNEZ [[ANDI1]], %bb.7 +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: bb.6: +- ; CHECK-NEXT: successors: %bb.11(0x80000000) +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: [[COPY6:%[0-9]+]]:gpr = COPY $r0 +- ; CHECK-NEXT: PseudoBR %bb.11 +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: bb.7: +- ; CHECK-NEXT: successors: %bb.8(0x7c000000), %bb.10(0x04000000) +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: BEQZ [[ANDI2]], %bb.10 +- ; CHECK-NEXT: PseudoBR %bb.8 +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: bb.8: +- ; CHECK-NEXT: successors: %bb.9(0x04000000), %bb.5(0x7c000000) +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: [[COPY6:%[0-9]+]]:gpr = ADDI_D [[COPY6]], 1 +- ; CHECK-NEXT: BEQZ [[ANDI3]], %bb.5 +- ; CHECK-NEXT: PseudoBR %bb.9 +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: bb.9: +- ; CHECK-NEXT: successors: %bb.12(0x80000000) +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: ST_B $r0, [[COPY4]], 0 +- ; CHECK-NEXT: PseudoBR %bb.12 +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: bb.10: +- ; CHECK-NEXT: successors: %bb.11(0x80000000) +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: [[COPY5:%[0-9]+]]:gpr = ADDI_D [[COPY6]], 1 +- ; CHECK-NEXT: [[COPY6:%[0-9]+]]:gpr = COPY [[ORI]] +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: bb.11: +- ; CHECK-NEXT: successors: %bb.12(0x80000000) +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: ST_D $r0, [[COPY4]], 0 +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: bb.12: +- ; CHECK-NEXT: successors: %bb.2(0x7c000000), %bb.1(0x04000000) +- ; CHECK-NEXT: {{ $}} +- ; CHECK-NEXT: BEQ [[COPY7]], [[ORI]], %bb.2 +- ; CHECK-NEXT: PseudoBR %bb.1 +- bb.0: +- liveins: $r4, $r5, $r6, $r7, $r8 +- +- %0:gpr = COPY killed $r8 +- %1:gpr = COPY killed $r7 +- %2:gpr = COPY killed $r6 +- %3:gpr = COPY killed $r5 +- %4:gpr = COPY killed $r4 +- %5:gpr = COPY $r0 +- %6:gpr = COPY killed %5 +- %7:gpr = ANDI killed %3, 1 +- %8:gpr = ORI $r0, 1 +- %9:gpr = ANDI killed %2, 1 +- %10:gpr = ANDI killed %1, 1 +- %11:gpr = ANDI killed %0, 1 +- %12:gpr = COPY %6 +- %13:gpr = COPY killed %6 +- %14:gpr = IMPLICIT_DEF +- +- bb.1: +- %15:gpr = COPY killed %14 +- %16:gpr = COPY killed %13 +- %17:gpr = COPY killed %12 +- %18:gpr = COPY %17 +- %19:gpr = COPY %16 +- %20:gpr = COPY killed %16 +- %21:gpr = COPY killed %15 +- +- bb.2: +- successors: %bb.3, %bb.4 +- +- %22:gpr = COPY killed %21 +- %23:gpr = COPY killed %20 +- %24:gpr = COPY killed %19 +- %25:gpr = COPY killed %18 +- BEQZ %7, %bb.4 +- +- bb.3: +- %26:gpr = COPY killed %24 +- %27:gpr = COPY killed %23 +- PseudoBR %bb.9 +- +- bb.4: +- %28:gpr = COPY killed %23 +- +- bb.5: +- successors: %bb.7(0x7c000000), %bb.6(0x04000000) +- +- %29:gpr = COPY killed %28 +- dead %30:gpr = LD_D $r0, 8 +- dead %31:gpr = LD_D $r0, 0 +- BNEZ %9, %bb.7 +- +- bb.6: +- %32:gpr = COPY $r0 +- %33:gpr = COPY killed %32 +- %34:gpr = COPY killed %33 +- %35:gpr = COPY killed %22 +- PseudoBR %bb.11 +- +- bb.7: +- successors: %bb.8(0x7c000000), %bb.10(0x04000000) +- +- BEQZ %10, %bb.10 +- PseudoBR %bb.8 +- +- bb.8: +- successors: %bb.9(0x04000000), %bb.5(0x7c000000) +- +- %36:gpr = ADDI_D killed %29, 1 +- %28:gpr = COPY %36 +- %26:gpr = COPY %36 +- %27:gpr = COPY killed %36 +- BEQZ %11, %bb.5 +- PseudoBR %bb.9 +- +- bb.9: +- %37:gpr = COPY killed %27 +- %38:gpr = COPY killed %26 +- %39:gpr = COPY $r0 +- ST_B killed %39, %4, 0 +- %40:gpr = COPY killed %25 +- %41:gpr = COPY killed %38 +- %42:gpr = COPY killed %37 +- %43:gpr = COPY killed %22 +- PseudoBR %bb.12 +- +- bb.10: +- %44:gpr = ADDI_D killed %29, 1 +- %34:gpr = COPY %8 +- %35:gpr = COPY killed %44 +- +- bb.11: +- %45:gpr = COPY killed %35 +- %46:gpr = COPY killed %34 +- %47:gpr = COPY $r0 +- ST_D killed %47, %4, 0 +- %40:gpr = COPY %45 +- %41:gpr = COPY %46 +- %42:gpr = COPY killed %46 +- %43:gpr = COPY killed %45 +- +- bb.12: +- successors: %bb.2(0x7c000000), %bb.1(0x04000000) +- +- %48:gpr = COPY killed %43 +- %49:gpr = COPY killed %42 +- %50:gpr = COPY killed %41 +- %51:gpr = COPY killed %40 +- %12:gpr = COPY %51 +- %13:gpr = COPY %50 +- %14:gpr = COPY %48 +- %18:gpr = COPY killed %51 +- %19:gpr = COPY killed %50 +- %20:gpr = COPY killed %49 +- %21:gpr = COPY killed %48 +- BEQ %17, %8, %bb.2 +- PseudoBR %bb.1 +- +-... +diff --git a/llvm/test/CodeGen/LoongArch/returnaddr-error.ll b/llvm/test/CodeGen/LoongArch/returnaddr-error.ll +deleted file mode 100644 +index 6ac1e0afc..000000000 +--- a/llvm/test/CodeGen/LoongArch/returnaddr-error.ll ++++ /dev/null +@@ -1,9 +0,0 @@ +-; RUN: not llc --mtriple=loongarch64 < %s 2>&1 | FileCheck %s +- +-declare ptr @llvm.returnaddress(i32 immarg) +- +-define ptr @non_zero_returnaddress() nounwind { +-; CHECK: return address can only be determined for the current frame +- %1 = call ptr @llvm.returnaddress(i32 1) +- ret ptr %1 +-} +diff --git a/llvm/test/CodeGen/LoongArch/rotl-rotr.ll b/llvm/test/CodeGen/LoongArch/rotl-rotr.ll +deleted file mode 100644 +index b9a6ebdcd..000000000 +--- a/llvm/test/CodeGen/LoongArch/rotl-rotr.ll ++++ /dev/null +@@ -1,625 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-;; TODO: Add optimization to ISD::ROTL +- +-define i32 @rotl_32(i32 %x, i32 %y) nounwind { +-; LA32-LABEL: rotl_32: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a2, $zero, 32 +-; LA32-NEXT: sub.w $a1, $a2, $a1 +-; LA32-NEXT: rotr.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: rotl_32: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.d $a2, $zero, $a1 +-; LA64-NEXT: sll.w $a1, $a0, $a1 +-; LA64-NEXT: srl.w $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a1, $a0 +-; LA64-NEXT: ret +- %z = sub i32 32, %y +- %b = shl i32 %x, %y +- %c = lshr i32 %x, %z +- %d = or i32 %b, %c +- ret i32 %d +-} +- +-define i32 @rotr_32(i32 %x, i32 %y) nounwind { +-; LA32-LABEL: rotr_32: +-; LA32: # %bb.0: +-; LA32-NEXT: rotr.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: rotr_32: +-; LA64: # %bb.0: +-; LA64-NEXT: rotr.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %z = sub i32 32, %y +- %b = lshr i32 %x, %y +- %c = shl i32 %x, %z +- %d = or i32 %b, %c +- ret i32 %d +-} +- +-define i64 @rotl_64(i64 %x, i64 %y) nounwind { +-; LA32-LABEL: rotl_64: +-; LA32: # %bb.0: +-; LA32-NEXT: xori $a3, $a2, 31 +-; LA32-NEXT: srli.w $a4, $a0, 1 +-; LA32-NEXT: srl.w $a3, $a4, $a3 +-; LA32-NEXT: sll.w $a4, $a1, $a2 +-; LA32-NEXT: or $a3, $a4, $a3 +-; LA32-NEXT: addi.w $a4, $a2, -32 +-; LA32-NEXT: slti $a5, $a4, 0 +-; LA32-NEXT: maskeqz $a3, $a3, $a5 +-; LA32-NEXT: sll.w $a6, $a0, $a4 +-; LA32-NEXT: masknez $a5, $a6, $a5 +-; LA32-NEXT: or $a3, $a3, $a5 +-; LA32-NEXT: ori $a5, $zero, 64 +-; LA32-NEXT: sub.w $a5, $a5, $a2 +-; LA32-NEXT: xori $a5, $a5, 31 +-; LA32-NEXT: slli.w $a6, $a1, 1 +-; LA32-NEXT: sll.w $a5, $a6, $a5 +-; LA32-NEXT: sub.w $a6, $zero, $a2 +-; LA32-NEXT: srl.w $a7, $a1, $a6 +-; LA32-NEXT: ori $a1, $zero, 32 +-; LA32-NEXT: sub.w $t0, $a1, $a2 +-; LA32-NEXT: srai.w $a1, $t0, 31 +-; LA32-NEXT: and $a1, $a1, $a7 +-; LA32-NEXT: or $a1, $a3, $a1 +-; LA32-NEXT: srl.w $a3, $a0, $a6 +-; LA32-NEXT: or $a3, $a3, $a5 +-; LA32-NEXT: slti $a5, $t0, 0 +-; LA32-NEXT: masknez $a6, $a7, $a5 +-; LA32-NEXT: maskeqz $a3, $a3, $a5 +-; LA32-NEXT: or $a3, $a3, $a6 +-; LA32-NEXT: sll.w $a0, $a0, $a2 +-; LA32-NEXT: srai.w $a2, $a4, 31 +-; LA32-NEXT: and $a0, $a2, $a0 +-; LA32-NEXT: or $a0, $a0, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: rotl_64: +-; LA64: # %bb.0: +-; LA64-NEXT: ori $a2, $zero, 64 +-; LA64-NEXT: sub.d $a1, $a2, $a1 +-; LA64-NEXT: rotr.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %z = sub i64 64, %y +- %b = shl i64 %x, %y +- %c = lshr i64 %x, %z +- %d = or i64 %b, %c +- ret i64 %d +-} +- +-define i64 @rotr_64(i64 %x, i64 %y) nounwind { +-; LA32-LABEL: rotr_64: +-; LA32: # %bb.0: +-; LA32-NEXT: xori $a3, $a2, 31 +-; LA32-NEXT: slli.w $a4, $a1, 1 +-; LA32-NEXT: sll.w $a3, $a4, $a3 +-; LA32-NEXT: srl.w $a4, $a0, $a2 +-; LA32-NEXT: or $a3, $a4, $a3 +-; LA32-NEXT: addi.w $a4, $a2, -32 +-; LA32-NEXT: slti $a5, $a4, 0 +-; LA32-NEXT: maskeqz $a3, $a3, $a5 +-; LA32-NEXT: srl.w $a6, $a1, $a4 +-; LA32-NEXT: masknez $a5, $a6, $a5 +-; LA32-NEXT: or $a3, $a3, $a5 +-; LA32-NEXT: ori $a5, $zero, 64 +-; LA32-NEXT: sub.w $a5, $a5, $a2 +-; LA32-NEXT: xori $a5, $a5, 31 +-; LA32-NEXT: srli.w $a6, $a0, 1 +-; LA32-NEXT: srl.w $a5, $a6, $a5 +-; LA32-NEXT: sub.w $a6, $zero, $a2 +-; LA32-NEXT: sll.w $a7, $a0, $a6 +-; LA32-NEXT: ori $a0, $zero, 32 +-; LA32-NEXT: sub.w $t0, $a0, $a2 +-; LA32-NEXT: srai.w $a0, $t0, 31 +-; LA32-NEXT: and $a0, $a0, $a7 +-; LA32-NEXT: or $a0, $a3, $a0 +-; LA32-NEXT: sll.w $a3, $a1, $a6 +-; LA32-NEXT: or $a3, $a3, $a5 +-; LA32-NEXT: slti $a5, $t0, 0 +-; LA32-NEXT: masknez $a6, $a7, $a5 +-; LA32-NEXT: maskeqz $a3, $a3, $a5 +-; LA32-NEXT: or $a3, $a3, $a6 +-; LA32-NEXT: srl.w $a1, $a1, $a2 +-; LA32-NEXT: srai.w $a2, $a4, 31 +-; LA32-NEXT: and $a1, $a2, $a1 +-; LA32-NEXT: or $a1, $a1, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: rotr_64: +-; LA64: # %bb.0: +-; LA64-NEXT: rotr.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %z = sub i64 64, %y +- %b = lshr i64 %x, %y +- %c = shl i64 %x, %z +- %d = or i64 %b, %c +- ret i64 %d +-} +- +-define i32 @rotl_32_mask(i32 %x, i32 %y) nounwind { +-; LA32-LABEL: rotl_32_mask: +-; LA32: # %bb.0: +-; LA32-NEXT: sub.w $a1, $zero, $a1 +-; LA32-NEXT: rotr.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: rotl_32_mask: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.d $a2, $zero, $a1 +-; LA64-NEXT: sll.w $a1, $a0, $a1 +-; LA64-NEXT: srl.w $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a1, $a0 +-; LA64-NEXT: ret +- %z = sub i32 0, %y +- %and = and i32 %z, 31 +- %b = shl i32 %x, %y +- %c = lshr i32 %x, %and +- %d = or i32 %b, %c +- ret i32 %d +-} +- +-define i32 @rotl_32_mask_and_63_and_31(i32 %x, i32 %y) nounwind { +-; LA32-LABEL: rotl_32_mask_and_63_and_31: +-; LA32: # %bb.0: +-; LA32-NEXT: sub.w $a1, $zero, $a1 +-; LA32-NEXT: rotr.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: rotl_32_mask_and_63_and_31: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.d $a2, $zero, $a1 +-; LA64-NEXT: sll.w $a1, $a0, $a1 +-; LA64-NEXT: srl.w $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a1, $a0 +-; LA64-NEXT: ret +- %a = and i32 %y, 63 +- %b = shl i32 %x, %a +- %c = sub i32 0, %y +- %d = and i32 %c, 31 +- %e = lshr i32 %x, %d +- %f = or i32 %b, %e +- ret i32 %f +-} +- +-define i32 @rotl_32_mask_or_64_or_32(i32 %x, i32 %y) nounwind { +-; LA32-LABEL: rotl_32_mask_or_64_or_32: +-; LA32: # %bb.0: +-; LA32-NEXT: sub.w $a1, $zero, $a1 +-; LA32-NEXT: rotr.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: rotl_32_mask_or_64_or_32: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.d $a2, $zero, $a1 +-; LA64-NEXT: sll.w $a1, $a0, $a1 +-; LA64-NEXT: srl.w $a0, $a0, $a2 +-; LA64-NEXT: or $a0, $a1, $a0 +-; LA64-NEXT: ret +- %a = or i32 %y, 64 +- %b = shl i32 %x, %a +- %c = sub i32 0, %y +- %d = or i32 %c, 32 +- %e = lshr i32 %x, %d +- %f = or i32 %b, %e +- ret i32 %f +-} +- +-define i32 @rotr_32_mask(i32 %x, i32 %y) nounwind { +-; LA32-LABEL: rotr_32_mask: +-; LA32: # %bb.0: +-; LA32-NEXT: rotr.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: rotr_32_mask: +-; LA64: # %bb.0: +-; LA64-NEXT: rotr.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %z = sub i32 0, %y +- %and = and i32 %z, 31 +- %b = lshr i32 %x, %y +- %c = shl i32 %x, %and +- %d = or i32 %b, %c +- ret i32 %d +-} +- +-define i32 @rotr_32_mask_and_63_and_31(i32 %x, i32 %y) nounwind { +-; LA32-LABEL: rotr_32_mask_and_63_and_31: +-; LA32: # %bb.0: +-; LA32-NEXT: rotr.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: rotr_32_mask_and_63_and_31: +-; LA64: # %bb.0: +-; LA64-NEXT: rotr.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %a = and i32 %y, 63 +- %b = lshr i32 %x, %a +- %c = sub i32 0, %y +- %d = and i32 %c, 31 +- %e = shl i32 %x, %d +- %f = or i32 %b, %e +- ret i32 %f +-} +- +-define i32 @rotr_32_mask_or_64_or_32(i32 %x, i32 %y) nounwind { +-; LA32-LABEL: rotr_32_mask_or_64_or_32: +-; LA32: # %bb.0: +-; LA32-NEXT: rotr.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: rotr_32_mask_or_64_or_32: +-; LA64: # %bb.0: +-; LA64-NEXT: rotr.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %a = or i32 %y, 64 +- %b = lshr i32 %x, %a +- %c = sub i32 0, %y +- %d = or i32 %c, 32 +- %e = shl i32 %x, %d +- %f = or i32 %b, %e +- ret i32 %f +-} +- +-define i64 @rotl_64_mask(i64 %x, i64 %y) nounwind { +-; LA32-LABEL: rotl_64_mask: +-; LA32: # %bb.0: +-; LA32-NEXT: xori $a3, $a2, 31 +-; LA32-NEXT: srli.w $a4, $a0, 1 +-; LA32-NEXT: srl.w $a3, $a4, $a3 +-; LA32-NEXT: sll.w $a4, $a1, $a2 +-; LA32-NEXT: or $a3, $a4, $a3 +-; LA32-NEXT: sub.w $a4, $zero, $a2 +-; LA32-NEXT: srl.w $a5, $a1, $a4 +-; LA32-NEXT: andi $a6, $a4, 63 +-; LA32-NEXT: addi.w $a7, $a6, -32 +-; LA32-NEXT: srai.w $t0, $a7, 31 +-; LA32-NEXT: and $a5, $t0, $a5 +-; LA32-NEXT: addi.w $t0, $a2, -32 +-; LA32-NEXT: slti $t1, $t0, 0 +-; LA32-NEXT: maskeqz $a3, $a3, $t1 +-; LA32-NEXT: sll.w $t2, $a0, $t0 +-; LA32-NEXT: masknez $t1, $t2, $t1 +-; LA32-NEXT: or $a3, $a3, $t1 +-; LA32-NEXT: xori $a6, $a6, 31 +-; LA32-NEXT: slli.w $t1, $a1, 1 +-; LA32-NEXT: sll.w $a6, $t1, $a6 +-; LA32-NEXT: or $a3, $a3, $a5 +-; LA32-NEXT: srl.w $a4, $a0, $a4 +-; LA32-NEXT: or $a4, $a4, $a6 +-; LA32-NEXT: srl.w $a1, $a1, $a7 +-; LA32-NEXT: slti $a5, $a7, 0 +-; LA32-NEXT: masknez $a1, $a1, $a5 +-; LA32-NEXT: maskeqz $a4, $a4, $a5 +-; LA32-NEXT: or $a1, $a4, $a1 +-; LA32-NEXT: sll.w $a0, $a0, $a2 +-; LA32-NEXT: srai.w $a2, $t0, 31 +-; LA32-NEXT: and $a0, $a2, $a0 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: move $a1, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: rotl_64_mask: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.d $a1, $zero, $a1 +-; LA64-NEXT: rotr.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %z = sub i64 0, %y +- %and = and i64 %z, 63 +- %b = shl i64 %x, %y +- %c = lshr i64 %x, %and +- %d = or i64 %b, %c +- ret i64 %d +-} +- +-define i64 @rotl_64_mask_and_127_and_63(i64 %x, i64 %y) nounwind { +-; LA32-LABEL: rotl_64_mask_and_127_and_63: +-; LA32: # %bb.0: +-; LA32-NEXT: srli.w $a3, $a0, 1 +-; LA32-NEXT: andi $a4, $a2, 127 +-; LA32-NEXT: xori $a5, $a4, 31 +-; LA32-NEXT: srl.w $a3, $a3, $a5 +-; LA32-NEXT: sll.w $a5, $a1, $a2 +-; LA32-NEXT: or $a3, $a5, $a3 +-; LA32-NEXT: sub.w $a5, $zero, $a2 +-; LA32-NEXT: srl.w $a6, $a1, $a5 +-; LA32-NEXT: andi $a7, $a5, 63 +-; LA32-NEXT: addi.w $t0, $a7, -32 +-; LA32-NEXT: srai.w $t1, $t0, 31 +-; LA32-NEXT: and $a6, $t1, $a6 +-; LA32-NEXT: addi.w $a4, $a4, -32 +-; LA32-NEXT: slti $t1, $a4, 0 +-; LA32-NEXT: maskeqz $a3, $a3, $t1 +-; LA32-NEXT: sll.w $t2, $a0, $a4 +-; LA32-NEXT: masknez $t1, $t2, $t1 +-; LA32-NEXT: or $a3, $a3, $t1 +-; LA32-NEXT: xori $a7, $a7, 31 +-; LA32-NEXT: slli.w $t1, $a1, 1 +-; LA32-NEXT: sll.w $a7, $t1, $a7 +-; LA32-NEXT: or $a3, $a3, $a6 +-; LA32-NEXT: srl.w $a5, $a0, $a5 +-; LA32-NEXT: or $a5, $a5, $a7 +-; LA32-NEXT: srl.w $a1, $a1, $t0 +-; LA32-NEXT: slti $a6, $t0, 0 +-; LA32-NEXT: masknez $a1, $a1, $a6 +-; LA32-NEXT: maskeqz $a5, $a5, $a6 +-; LA32-NEXT: or $a1, $a5, $a1 +-; LA32-NEXT: sll.w $a0, $a0, $a2 +-; LA32-NEXT: srai.w $a2, $a4, 31 +-; LA32-NEXT: and $a0, $a2, $a0 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: move $a1, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: rotl_64_mask_and_127_and_63: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.d $a1, $zero, $a1 +-; LA64-NEXT: rotr.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %a = and i64 %y, 127 +- %b = shl i64 %x, %a +- %c = sub i64 0, %y +- %d = and i64 %c, 63 +- %e = lshr i64 %x, %d +- %f = or i64 %b, %e +- ret i64 %f +-} +- +-define i64 @rotl_64_mask_or_128_or_64(i64 %x, i64 %y) nounwind { +-; LA32-LABEL: rotl_64_mask_or_128_or_64: +-; LA32: # %bb.0: +-; LA32-NEXT: move $a0, $zero +-; LA32-NEXT: move $a1, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: rotl_64_mask_or_128_or_64: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.d $a1, $zero, $a1 +-; LA64-NEXT: rotr.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %a = or i64 %y, 128 +- %b = shl i64 %x, %a +- %c = sub i64 0, %y +- %d = or i64 %c, 64 +- %e = lshr i64 %x, %d +- %f = or i64 %b, %e +- ret i64 %f +-} +- +-define i64 @rotr_64_mask(i64 %x, i64 %y) nounwind { +-; LA32-LABEL: rotr_64_mask: +-; LA32: # %bb.0: +-; LA32-NEXT: xori $a3, $a2, 31 +-; LA32-NEXT: slli.w $a4, $a1, 1 +-; LA32-NEXT: sll.w $a3, $a4, $a3 +-; LA32-NEXT: srl.w $a4, $a0, $a2 +-; LA32-NEXT: or $a3, $a4, $a3 +-; LA32-NEXT: sub.w $a4, $zero, $a2 +-; LA32-NEXT: sll.w $a5, $a0, $a4 +-; LA32-NEXT: andi $a6, $a4, 63 +-; LA32-NEXT: addi.w $a7, $a6, -32 +-; LA32-NEXT: srai.w $t0, $a7, 31 +-; LA32-NEXT: and $a5, $t0, $a5 +-; LA32-NEXT: addi.w $t0, $a2, -32 +-; LA32-NEXT: slti $t1, $t0, 0 +-; LA32-NEXT: maskeqz $a3, $a3, $t1 +-; LA32-NEXT: srl.w $t2, $a1, $t0 +-; LA32-NEXT: masknez $t1, $t2, $t1 +-; LA32-NEXT: or $a3, $a3, $t1 +-; LA32-NEXT: xori $a6, $a6, 31 +-; LA32-NEXT: srli.w $t1, $a0, 1 +-; LA32-NEXT: srl.w $a6, $t1, $a6 +-; LA32-NEXT: or $a3, $a3, $a5 +-; LA32-NEXT: sll.w $a4, $a1, $a4 +-; LA32-NEXT: or $a4, $a4, $a6 +-; LA32-NEXT: sll.w $a0, $a0, $a7 +-; LA32-NEXT: slti $a5, $a7, 0 +-; LA32-NEXT: masknez $a0, $a0, $a5 +-; LA32-NEXT: maskeqz $a4, $a4, $a5 +-; LA32-NEXT: or $a0, $a4, $a0 +-; LA32-NEXT: srl.w $a1, $a1, $a2 +-; LA32-NEXT: srai.w $a2, $t0, 31 +-; LA32-NEXT: and $a1, $a2, $a1 +-; LA32-NEXT: or $a1, $a1, $a0 +-; LA32-NEXT: move $a0, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: rotr_64_mask: +-; LA64: # %bb.0: +-; LA64-NEXT: rotr.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %z = sub i64 0, %y +- %and = and i64 %z, 63 +- %b = lshr i64 %x, %y +- %c = shl i64 %x, %and +- %d = or i64 %b, %c +- ret i64 %d +-} +- +-define i64 @rotr_64_mask_and_127_and_63(i64 %x, i64 %y) nounwind { +-; LA32-LABEL: rotr_64_mask_and_127_and_63: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a3, $a1, 1 +-; LA32-NEXT: andi $a4, $a2, 127 +-; LA32-NEXT: xori $a5, $a4, 31 +-; LA32-NEXT: sll.w $a3, $a3, $a5 +-; LA32-NEXT: srl.w $a5, $a0, $a2 +-; LA32-NEXT: or $a3, $a5, $a3 +-; LA32-NEXT: sub.w $a5, $zero, $a2 +-; LA32-NEXT: sll.w $a6, $a0, $a5 +-; LA32-NEXT: andi $a7, $a5, 63 +-; LA32-NEXT: addi.w $t0, $a7, -32 +-; LA32-NEXT: srai.w $t1, $t0, 31 +-; LA32-NEXT: and $a6, $t1, $a6 +-; LA32-NEXT: addi.w $a4, $a4, -32 +-; LA32-NEXT: slti $t1, $a4, 0 +-; LA32-NEXT: maskeqz $a3, $a3, $t1 +-; LA32-NEXT: srl.w $t2, $a1, $a4 +-; LA32-NEXT: masknez $t1, $t2, $t1 +-; LA32-NEXT: or $a3, $a3, $t1 +-; LA32-NEXT: xori $a7, $a7, 31 +-; LA32-NEXT: srli.w $t1, $a0, 1 +-; LA32-NEXT: srl.w $a7, $t1, $a7 +-; LA32-NEXT: or $a3, $a3, $a6 +-; LA32-NEXT: sll.w $a5, $a1, $a5 +-; LA32-NEXT: or $a5, $a5, $a7 +-; LA32-NEXT: sll.w $a0, $a0, $t0 +-; LA32-NEXT: slti $a6, $t0, 0 +-; LA32-NEXT: masknez $a0, $a0, $a6 +-; LA32-NEXT: maskeqz $a5, $a5, $a6 +-; LA32-NEXT: or $a0, $a5, $a0 +-; LA32-NEXT: srl.w $a1, $a1, $a2 +-; LA32-NEXT: srai.w $a2, $a4, 31 +-; LA32-NEXT: and $a1, $a2, $a1 +-; LA32-NEXT: or $a1, $a1, $a0 +-; LA32-NEXT: move $a0, $a3 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: rotr_64_mask_and_127_and_63: +-; LA64: # %bb.0: +-; LA64-NEXT: rotr.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %a = and i64 %y, 127 +- %b = lshr i64 %x, %a +- %c = sub i64 0, %y +- %d = and i64 %c, 63 +- %e = shl i64 %x, %d +- %f = or i64 %b, %e +- ret i64 %f +-} +- +-define i64 @rotr_64_mask_or_128_or_64(i64 %x, i64 %y) nounwind { +-; LA32-LABEL: rotr_64_mask_or_128_or_64: +-; LA32: # %bb.0: +-; LA32-NEXT: move $a0, $zero +-; LA32-NEXT: move $a1, $zero +-; LA32-NEXT: ret +-; +-; LA64-LABEL: rotr_64_mask_or_128_or_64: +-; LA64: # %bb.0: +-; LA64-NEXT: rotr.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %a = or i64 %y, 128 +- %b = lshr i64 %x, %a +- %c = sub i64 0, %y +- %d = or i64 %c, 64 +- %e = shl i64 %x, %d +- %f = or i64 %b, %e +- ret i64 %f +-} +- +-define i32 @rotri_i32(i32 %a) nounwind { +-; LA32-LABEL: rotri_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: rotri.w $a0, $a0, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: rotri_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: rotri.w $a0, $a0, 16 +-; LA64-NEXT: ret +- %shl = shl i32 %a, 16 +- %shr = lshr i32 %a, 16 +- %or = or i32 %shl, %shr +- ret i32 %or +-} +- +-define i64 @rotri_i64(i64 %a) nounwind { +-; LA32-LABEL: rotri_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: move $a2, $a0 +-; LA32-NEXT: move $a0, $a1 +-; LA32-NEXT: move $a1, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: rotri_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: rotri.d $a0, $a0, 32 +-; LA64-NEXT: ret +- %shl = shl i64 %a, 32 +- %shr = lshr i64 %a, 32 +- %or = or i64 %shl, %shr +- ret i64 %or +-} +- +-declare i32 @llvm.fshl.i32(i32, i32, i32) +-declare i64 @llvm.fshl.i64(i64, i64, i64) +-declare i32 @llvm.fshr.i32(i32, i32, i32) +-declare i64 @llvm.fshr.i64(i64, i64, i64) +- +-define signext i32 @rotl_i32_fshl(i32 signext %a) nounwind { +-; LA32-LABEL: rotl_i32_fshl: +-; LA32: # %bb.0: +-; LA32-NEXT: rotri.w $a0, $a0, 20 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: rotl_i32_fshl: +-; LA64: # %bb.0: +-; LA64-NEXT: rotri.w $a0, $a0, 20 +-; LA64-NEXT: ret +- %or = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 12) +- ret i32 %or +-} +- +-define i64 @rotl_i64_fshl(i64 %a) nounwind { +-; LA32-LABEL: rotl_i64_fshl: +-; LA32: # %bb.0: +-; LA32-NEXT: srli.w $a2, $a1, 20 +-; LA32-NEXT: slli.w $a3, $a0, 12 +-; LA32-NEXT: or $a2, $a3, $a2 +-; LA32-NEXT: srli.w $a0, $a0, 20 +-; LA32-NEXT: slli.w $a1, $a1, 12 +-; LA32-NEXT: or $a1, $a1, $a0 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: rotl_i64_fshl: +-; LA64: # %bb.0: +-; LA64-NEXT: rotri.d $a0, $a0, 52 +-; LA64-NEXT: ret +- %or = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 12) +- ret i64 %or +-} +- +-define signext i32 @rotr_i32_fshr(i32 signext %a) nounwind { +-; LA32-LABEL: rotr_i32_fshr: +-; LA32: # %bb.0: +-; LA32-NEXT: rotri.w $a0, $a0, 12 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: rotr_i32_fshr: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a0, 20 +-; LA64-NEXT: bstrpick.d $a0, $a0, 31, 12 +-; LA64-NEXT: or $a0, $a0, $a1 +-; LA64-NEXT: addi.w $a0, $a0, 0 +-; LA64-NEXT: ret +- %or = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 12) +- ret i32 %or +-} +- +-define i64 @rotr_i64_fshr(i64 %a) nounwind { +-; LA32-LABEL: rotr_i64_fshr: +-; LA32: # %bb.0: +-; LA32-NEXT: srli.w $a2, $a0, 12 +-; LA32-NEXT: slli.w $a3, $a1, 20 +-; LA32-NEXT: or $a2, $a3, $a2 +-; LA32-NEXT: srli.w $a1, $a1, 12 +-; LA32-NEXT: slli.w $a0, $a0, 20 +-; LA32-NEXT: or $a1, $a0, $a1 +-; LA32-NEXT: move $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: rotr_i64_fshr: +-; LA64: # %bb.0: +-; LA64-NEXT: rotri.d $a0, $a0, 12 +-; LA64-NEXT: ret +- %or = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 12) +- ret i64 %or +-} +diff --git a/llvm/test/CodeGen/LoongArch/select-const.ll b/llvm/test/CodeGen/LoongArch/select-const.ll +deleted file mode 100644 +index 6a61cb66e..000000000 +--- a/llvm/test/CodeGen/LoongArch/select-const.ll ++++ /dev/null +@@ -1,303 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-define signext i32 @select_const_int_one_away(i1 zeroext %a) nounwind { +-; LA32-LABEL: select_const_int_one_away: +-; LA32: # %bb.0: +-; LA32-NEXT: ori $a1, $zero, 4 +-; LA32-NEXT: sub.w $a0, $a1, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_const_int_one_away: +-; LA64: # %bb.0: +-; LA64-NEXT: ori $a1, $zero, 4 +-; LA64-NEXT: sub.d $a0, $a1, $a0 +-; LA64-NEXT: ret +- %1 = select i1 %a, i32 3, i32 4 +- ret i32 %1 +-} +- +-define signext i32 @select_const_int_pow2_zero(i1 zeroext %a) nounwind { +-; LA32-LABEL: select_const_int_pow2_zero: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a0, $a0, 2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_const_int_pow2_zero: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a0, $a0, 2 +-; LA64-NEXT: ret +- %1 = select i1 %a, i32 4, i32 0 +- ret i32 %1 +-} +- +-define signext i32 @select_eq_zero_negone(i32 signext %a, i32 signext %b) nounwind { +-; LA32-LABEL: select_eq_zero_negone: +-; LA32: # %bb.0: +-; LA32-NEXT: xor $a0, $a0, $a1 +-; LA32-NEXT: sltui $a0, $a0, 1 +-; LA32-NEXT: sub.w $a0, $zero, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_eq_zero_negone: +-; LA64: # %bb.0: +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: sltui $a0, $a0, 1 +-; LA64-NEXT: sub.d $a0, $zero, $a0 +-; LA64-NEXT: ret +- %1 = icmp eq i32 %a, %b +- %2 = select i1 %1, i32 -1, i32 0 +- ret i32 %2 +-} +- +-define signext i32 @select_ne_zero_negone(i32 signext %a, i32 signext %b) nounwind { +-; LA32-LABEL: select_ne_zero_negone: +-; LA32: # %bb.0: +-; LA32-NEXT: xor $a0, $a0, $a1 +-; LA32-NEXT: sltu $a0, $zero, $a0 +-; LA32-NEXT: sub.w $a0, $zero, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_ne_zero_negone: +-; LA64: # %bb.0: +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: sltu $a0, $zero, $a0 +-; LA64-NEXT: sub.d $a0, $zero, $a0 +-; LA64-NEXT: ret +- %1 = icmp ne i32 %a, %b +- %2 = select i1 %1, i32 -1, i32 0 +- ret i32 %2 +-} +- +-define signext i32 @select_sgt_zero_negone(i32 signext %a, i32 signext %b) nounwind { +-; LA32-LABEL: select_sgt_zero_negone: +-; LA32: # %bb.0: +-; LA32-NEXT: slt $a0, $a1, $a0 +-; LA32-NEXT: sub.w $a0, $zero, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_sgt_zero_negone: +-; LA64: # %bb.0: +-; LA64-NEXT: slt $a0, $a1, $a0 +-; LA64-NEXT: sub.d $a0, $zero, $a0 +-; LA64-NEXT: ret +- %1 = icmp sgt i32 %a, %b +- %2 = select i1 %1, i32 -1, i32 0 +- ret i32 %2 +-} +- +-define signext i32 @select_slt_zero_negone(i32 signext %a, i32 signext %b) nounwind { +-; LA32-LABEL: select_slt_zero_negone: +-; LA32: # %bb.0: +-; LA32-NEXT: slt $a0, $a0, $a1 +-; LA32-NEXT: sub.w $a0, $zero, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_slt_zero_negone: +-; LA64: # %bb.0: +-; LA64-NEXT: slt $a0, $a0, $a1 +-; LA64-NEXT: sub.d $a0, $zero, $a0 +-; LA64-NEXT: ret +- %1 = icmp slt i32 %a, %b +- %2 = select i1 %1, i32 -1, i32 0 +- ret i32 %2 +-} +- +-define signext i32 @select_sge_zero_negone(i32 signext %a, i32 signext %b) nounwind { +-; LA32-LABEL: select_sge_zero_negone: +-; LA32: # %bb.0: +-; LA32-NEXT: slt $a0, $a0, $a1 +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: sub.w $a0, $zero, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_sge_zero_negone: +-; LA64: # %bb.0: +-; LA64-NEXT: slt $a0, $a0, $a1 +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: sub.d $a0, $zero, $a0 +-; LA64-NEXT: ret +- %1 = icmp sge i32 %a, %b +- %2 = select i1 %1, i32 -1, i32 0 +- ret i32 %2 +-} +- +-define signext i32 @select_sle_zero_negone(i32 signext %a, i32 signext %b) nounwind { +-; LA32-LABEL: select_sle_zero_negone: +-; LA32: # %bb.0: +-; LA32-NEXT: slt $a0, $a1, $a0 +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: sub.w $a0, $zero, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_sle_zero_negone: +-; LA64: # %bb.0: +-; LA64-NEXT: slt $a0, $a1, $a0 +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: sub.d $a0, $zero, $a0 +-; LA64-NEXT: ret +- %1 = icmp sle i32 %a, %b +- %2 = select i1 %1, i32 -1, i32 0 +- ret i32 %2 +-} +- +-define signext i32 @select_ugt_zero_negone(i32 signext %a, i32 signext %b) nounwind { +-; LA32-LABEL: select_ugt_zero_negone: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a0, $a1, $a0 +-; LA32-NEXT: sub.w $a0, $zero, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_ugt_zero_negone: +-; LA64: # %bb.0: +-; LA64-NEXT: sltu $a0, $a1, $a0 +-; LA64-NEXT: sub.d $a0, $zero, $a0 +-; LA64-NEXT: ret +- %1 = icmp ugt i32 %a, %b +- %2 = select i1 %1, i32 -1, i32 0 +- ret i32 %2 +-} +- +-define signext i32 @select_ult_zero_negone(i32 signext %a, i32 signext %b) nounwind { +-; LA32-LABEL: select_ult_zero_negone: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a0, $a0, $a1 +-; LA32-NEXT: sub.w $a0, $zero, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_ult_zero_negone: +-; LA64: # %bb.0: +-; LA64-NEXT: sltu $a0, $a0, $a1 +-; LA64-NEXT: sub.d $a0, $zero, $a0 +-; LA64-NEXT: ret +- %1 = icmp ult i32 %a, %b +- %2 = select i1 %1, i32 -1, i32 0 +- ret i32 %2 +-} +- +-define signext i32 @select_uge_zero_negone(i32 signext %a, i32 signext %b) nounwind { +-; LA32-LABEL: select_uge_zero_negone: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a0, $a0, $a1 +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: sub.w $a0, $zero, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_uge_zero_negone: +-; LA64: # %bb.0: +-; LA64-NEXT: sltu $a0, $a0, $a1 +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: sub.d $a0, $zero, $a0 +-; LA64-NEXT: ret +- %1 = icmp uge i32 %a, %b +- %2 = select i1 %1, i32 -1, i32 0 +- ret i32 %2 +-} +- +-define signext i32 @select_ule_zero_negone(i32 signext %a, i32 signext %b) nounwind { +-; LA32-LABEL: select_ule_zero_negone: +-; LA32: # %bb.0: +-; LA32-NEXT: sltu $a0, $a1, $a0 +-; LA32-NEXT: xori $a0, $a0, 1 +-; LA32-NEXT: sub.w $a0, $zero, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_ule_zero_negone: +-; LA64: # %bb.0: +-; LA64-NEXT: sltu $a0, $a1, $a0 +-; LA64-NEXT: xori $a0, $a0, 1 +-; LA64-NEXT: sub.d $a0, $zero, $a0 +-; LA64-NEXT: ret +- %1 = icmp ule i32 %a, %b +- %2 = select i1 %1, i32 -1, i32 0 +- ret i32 %2 +-} +- +-define i32 @select_eq_1_2(i32 signext %a, i32 signext %b) { +-; LA32-LABEL: select_eq_1_2: +-; LA32: # %bb.0: +-; LA32-NEXT: xor $a0, $a0, $a1 +-; LA32-NEXT: sltui $a0, $a0, 1 +-; LA32-NEXT: ori $a1, $zero, 2 +-; LA32-NEXT: sub.w $a0, $a1, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_eq_1_2: +-; LA64: # %bb.0: +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: sltui $a0, $a0, 1 +-; LA64-NEXT: ori $a1, $zero, 2 +-; LA64-NEXT: sub.d $a0, $a1, $a0 +-; LA64-NEXT: ret +- %1 = icmp eq i32 %a, %b +- %2 = select i1 %1, i32 1, i32 2 +- ret i32 %2 +-} +- +-define i32 @select_ne_1_2(i32 signext %a, i32 signext %b) { +-; LA32-LABEL: select_ne_1_2: +-; LA32: # %bb.0: +-; LA32-NEXT: xor $a0, $a0, $a1 +-; LA32-NEXT: sltu $a0, $zero, $a0 +-; LA32-NEXT: ori $a1, $zero, 2 +-; LA32-NEXT: sub.w $a0, $a1, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_ne_1_2: +-; LA64: # %bb.0: +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: sltu $a0, $zero, $a0 +-; LA64-NEXT: ori $a1, $zero, 2 +-; LA64-NEXT: sub.d $a0, $a1, $a0 +-; LA64-NEXT: ret +- %1 = icmp ne i32 %a, %b +- %2 = select i1 %1, i32 1, i32 2 +- ret i32 %2 +-} +- +-define i32 @select_eq_10000_10001(i32 signext %a, i32 signext %b) { +-; LA32-LABEL: select_eq_10000_10001: +-; LA32: # %bb.0: +-; LA32-NEXT: xor $a0, $a0, $a1 +-; LA32-NEXT: sltui $a0, $a0, 1 +-; LA32-NEXT: lu12i.w $a1, 2 +-; LA32-NEXT: ori $a1, $a1, 1810 +-; LA32-NEXT: sub.w $a0, $a1, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_eq_10000_10001: +-; LA64: # %bb.0: +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: sltui $a0, $a0, 1 +-; LA64-NEXT: lu12i.w $a1, 2 +-; LA64-NEXT: ori $a1, $a1, 1810 +-; LA64-NEXT: sub.d $a0, $a1, $a0 +-; LA64-NEXT: ret +- %1 = icmp eq i32 %a, %b +- %2 = select i1 %1, i32 10001, i32 10002 +- ret i32 %2 +-} +- +-define i32 @select_ne_10001_10002(i32 signext %a, i32 signext %b) { +-; LA32-LABEL: select_ne_10001_10002: +-; LA32: # %bb.0: +-; LA32-NEXT: xor $a0, $a0, $a1 +-; LA32-NEXT: sltu $a0, $zero, $a0 +-; LA32-NEXT: lu12i.w $a1, 2 +-; LA32-NEXT: ori $a1, $a1, 1810 +-; LA32-NEXT: sub.w $a0, $a1, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: select_ne_10001_10002: +-; LA64: # %bb.0: +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: sltu $a0, $zero, $a0 +-; LA64-NEXT: lu12i.w $a1, 2 +-; LA64-NEXT: ori $a1, $a1, 1810 +-; LA64-NEXT: sub.d $a0, $a1, $a0 +-; LA64-NEXT: ret +- %1 = icmp ne i32 %a, %b +- %2 = select i1 %1, i32 10001, i32 10002 +- ret i32 %2 +-} +diff --git a/llvm/test/CodeGen/LoongArch/select-to-shiftand.ll b/llvm/test/CodeGen/LoongArch/select-to-shiftand.ll +deleted file mode 100644 +index 61fe123ee..000000000 +--- a/llvm/test/CodeGen/LoongArch/select-to-shiftand.ll ++++ /dev/null +@@ -1,234 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-;; Compare if positive and select variable or zero. +-define i8 @pos_sel_variable_and_zero_i8(i8 signext %a, i8 signext %b) { +-; LA32-LABEL: pos_sel_variable_and_zero_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: srai.w $a0, $a0, 7 +-; LA32-NEXT: andn $a0, $a1, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: pos_sel_variable_and_zero_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: srai.d $a0, $a0, 7 +-; LA64-NEXT: andn $a0, $a1, $a0 +-; LA64-NEXT: ret +- %cmp = icmp sgt i8 %a, -1 +- %sel = select i1 %cmp, i8 %b, i8 0 +- ret i8 %sel +-} +- +-define i16 @pos_sel_variable_and_zero_i16(i16 signext %a, i16 signext %b) { +-; LA32-LABEL: pos_sel_variable_and_zero_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: srai.w $a0, $a0, 15 +-; LA32-NEXT: andn $a0, $a1, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: pos_sel_variable_and_zero_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: srai.d $a0, $a0, 15 +-; LA64-NEXT: andn $a0, $a1, $a0 +-; LA64-NEXT: ret +- %cmp = icmp sgt i16 %a, -1 +- %sel = select i1 %cmp, i16 %b, i16 0 +- ret i16 %sel +-} +- +-define i32 @pos_sel_variable_and_zero_i32(i32 signext %a, i32 signext %b) { +-; LA32-LABEL: pos_sel_variable_and_zero_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: srai.w $a0, $a0, 31 +-; LA32-NEXT: andn $a0, $a1, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: pos_sel_variable_and_zero_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: srai.d $a0, $a0, 31 +-; LA64-NEXT: andn $a0, $a1, $a0 +-; LA64-NEXT: ret +- %cmp = icmp sgt i32 %a, -1 +- %sel = select i1 %cmp, i32 %b, i32 0 +- ret i32 %sel +-} +- +-define i64 @pos_sel_variable_and_zero_i64(i64 signext %a, i64 signext %b) { +-; LA32-LABEL: pos_sel_variable_and_zero_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: srai.w $a1, $a1, 31 +-; LA32-NEXT: andn $a0, $a2, $a1 +-; LA32-NEXT: andn $a1, $a3, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: pos_sel_variable_and_zero_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: srai.d $a0, $a0, 63 +-; LA64-NEXT: andn $a0, $a1, $a0 +-; LA64-NEXT: ret +- %cmp = icmp sgt i64 %a, -1 +- %sel = select i1 %cmp, i64 %b, i64 0 +- ret i64 %sel +-} +- +-;; Compare if not negative or zero and select the same variable as being +-;; compared: smax(a, 0). +-define i8 @not_neg_not_zero_sel_same_variable_i8(i8 signext %a) { +-; LA32-LABEL: not_neg_not_zero_sel_same_variable_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: srai.w $a1, $a0, 7 +-; LA32-NEXT: andn $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: not_neg_not_zero_sel_same_variable_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: srai.d $a1, $a0, 7 +-; LA64-NEXT: andn $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = icmp sgt i8 %a, 0 +- %sel = select i1 %cmp, i8 %a, i8 0 +- ret i8 %sel +-} +- +-define i16 @not_neg_not_zero_sel_same_variable_i16(i16 signext %a) { +-; LA32-LABEL: not_neg_not_zero_sel_same_variable_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: srai.w $a1, $a0, 15 +-; LA32-NEXT: andn $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: not_neg_not_zero_sel_same_variable_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: srai.d $a1, $a0, 15 +-; LA64-NEXT: andn $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = icmp sgt i16 %a, 0 +- %sel = select i1 %cmp, i16 %a, i16 0 +- ret i16 %sel +-} +- +-define i32 @not_neg_not_zero_sel_same_variable_i32(i32 signext %a) { +-; LA32-LABEL: not_neg_not_zero_sel_same_variable_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: srai.w $a1, $a0, 31 +-; LA32-NEXT: andn $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: not_neg_not_zero_sel_same_variable_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: srai.d $a1, $a0, 31 +-; LA64-NEXT: andn $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = icmp sgt i32 %a, 0 +- %sel = select i1 %cmp, i32 %a, i32 0 +- ret i32 %sel +-} +- +-define i64 @not_neg_not_zero_sel_same_variable_i64(i64 signext %a) { +-; LA32-LABEL: not_neg_not_zero_sel_same_variable_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: srai.w $a2, $a1, 31 +-; LA32-NEXT: andn $a0, $a0, $a2 +-; LA32-NEXT: andn $a1, $a1, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: not_neg_not_zero_sel_same_variable_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: srai.d $a1, $a0, 63 +-; LA64-NEXT: andn $a0, $a0, $a1 +-; LA64-NEXT: ret +- %cmp = icmp sgt i64 %a, 0 +- %sel = select i1 %cmp, i64 %a, i64 0 +- ret i64 %sel +-} +- +-;; ret = (x-y) > 0 ? x-y : 0 +-define i8 @sub_clamp_zero_i8(i8 signext %x, i8 signext %y) { +-; LA32-LABEL: sub_clamp_zero_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: sub.w $a0, $a0, $a1 +-; LA32-NEXT: ext.w.b $a1, $a0 +-; LA32-NEXT: srai.w $a1, $a1, 7 +-; LA32-NEXT: andn $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sub_clamp_zero_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.d $a0, $a0, $a1 +-; LA64-NEXT: ext.w.b $a1, $a0 +-; LA64-NEXT: srai.d $a1, $a1, 7 +-; LA64-NEXT: andn $a0, $a0, $a1 +-; LA64-NEXT: ret +- %sub = sub nsw i8 %x, %y +- %cmp = icmp sgt i8 %sub, 0 +- %sel = select i1 %cmp, i8 %sub, i8 0 +- ret i8 %sel +-} +- +-define i16 @sub_clamp_zero_i16(i16 signext %x, i16 signext %y) { +-; LA32-LABEL: sub_clamp_zero_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: sub.w $a0, $a0, $a1 +-; LA32-NEXT: ext.w.h $a1, $a0 +-; LA32-NEXT: srai.w $a1, $a1, 15 +-; LA32-NEXT: andn $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sub_clamp_zero_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.d $a0, $a0, $a1 +-; LA64-NEXT: ext.w.h $a1, $a0 +-; LA64-NEXT: srai.d $a1, $a1, 15 +-; LA64-NEXT: andn $a0, $a0, $a1 +-; LA64-NEXT: ret +- %sub = sub nsw i16 %x, %y +- %cmp = icmp sgt i16 %sub, 0 +- %sel = select i1 %cmp, i16 %sub, i16 0 +- ret i16 %sel +-} +- +-define i32 @sub_clamp_zero_i32(i32 signext %x, i32 signext %y) { +-; LA32-LABEL: sub_clamp_zero_i32: +-; LA32: # %bb.0: +-; LA32-NEXT: sub.w $a0, $a0, $a1 +-; LA32-NEXT: srai.w $a1, $a0, 31 +-; LA32-NEXT: andn $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sub_clamp_zero_i32: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.d $a2, $a0, $a1 +-; LA64-NEXT: sub.w $a0, $a0, $a1 +-; LA64-NEXT: srai.d $a0, $a0, 31 +-; LA64-NEXT: andn $a0, $a2, $a0 +-; LA64-NEXT: ret +- %sub = sub nsw i32 %x, %y +- %cmp = icmp sgt i32 %sub, 0 +- %sel = select i1 %cmp, i32 %sub, i32 0 +- ret i32 %sel +-} +- +-define i64 @sub_clamp_zero_i64(i64 signext %x, i64 signext %y) { +-; LA32-LABEL: sub_clamp_zero_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: sub.w $a1, $a1, $a3 +-; LA32-NEXT: sltu $a3, $a0, $a2 +-; LA32-NEXT: sub.w $a1, $a1, $a3 +-; LA32-NEXT: sub.w $a0, $a0, $a2 +-; LA32-NEXT: srai.w $a2, $a1, 31 +-; LA32-NEXT: andn $a1, $a1, $a2 +-; LA32-NEXT: andn $a0, $a0, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sub_clamp_zero_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: sub.d $a0, $a0, $a1 +-; LA64-NEXT: srai.d $a1, $a0, 63 +-; LA64-NEXT: andn $a0, $a0, $a1 +-; LA64-NEXT: ret +- %sub = sub nsw i64 %x, %y +- %cmp = icmp sgt i64 %sub, 0 +- %sel = select i1 %cmp, i64 %sub, i64 0 +- ret i64 %sel +-} +diff --git a/llvm/test/CodeGen/LoongArch/sext-cheaper-than-zext.ll b/llvm/test/CodeGen/LoongArch/sext-cheaper-than-zext.ll +deleted file mode 100644 +index c363948a1..000000000 +--- a/llvm/test/CodeGen/LoongArch/sext-cheaper-than-zext.ll ++++ /dev/null +@@ -1,15 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s +- +-define signext i32 @sext_icmp(i32 signext %x, i32 signext %y) { +-; CHECK-LABEL: sext_icmp: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.w $a0, $a0, 1 +-; CHECK-NEXT: xor $a0, $a0, $a1 +-; CHECK-NEXT: sltu $a0, $zero, $a0 +-; CHECK-NEXT: ret +- %1 = add nsw i32 %x, 1 +- %2 = icmp ne i32 %1, %y +- %3 = zext i1 %2 to i32 +- ret i32 %3 +-} +diff --git a/llvm/test/CodeGen/LoongArch/shift-masked-shamt.ll b/llvm/test/CodeGen/LoongArch/shift-masked-shamt.ll +deleted file mode 100644 +index e151624d9..000000000 +--- a/llvm/test/CodeGen/LoongArch/shift-masked-shamt.ll ++++ /dev/null +@@ -1,256 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-;; This test checks that unnecessary masking of shift amount operands is +-;; eliminated during instruction selection. The test needs to ensure that the +-;; masking is not removed if it may affect the shift amount. +- +-define i32 @sll_redundant_mask(i32 %a, i32 %b) { +-; LA32-LABEL: sll_redundant_mask: +-; LA32: # %bb.0: +-; LA32-NEXT: sll.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sll_redundant_mask: +-; LA64: # %bb.0: +-; LA64-NEXT: sll.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = and i32 %b, 31 +- %2 = shl i32 %a, %1 +- ret i32 %2 +-} +- +-define i32 @sll_non_redundant_mask(i32 %a, i32 %b) { +-; LA32-LABEL: sll_non_redundant_mask: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a1, $a1, 15 +-; LA32-NEXT: sll.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sll_non_redundant_mask: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a1, $a1, 15 +-; LA64-NEXT: sll.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = and i32 %b, 15 +- %2 = shl i32 %a, %1 +- ret i32 %2 +-} +- +-define i32 @srl_redundant_mask(i32 %a, i32 %b) { +-; LA32-LABEL: srl_redundant_mask: +-; LA32: # %bb.0: +-; LA32-NEXT: srl.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: srl_redundant_mask: +-; LA64: # %bb.0: +-; LA64-NEXT: srl.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = and i32 %b, 4095 +- %2 = lshr i32 %a, %1 +- ret i32 %2 +-} +- +-define i32 @srl_non_redundant_mask(i32 %a, i32 %b) { +-; LA32-LABEL: srl_non_redundant_mask: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a1, $a1, 7 +-; LA32-NEXT: srl.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: srl_non_redundant_mask: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a1, $a1, 7 +-; LA64-NEXT: srl.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = and i32 %b, 7 +- %2 = lshr i32 %a, %1 +- ret i32 %2 +-} +- +-define i32 @sra_redundant_mask(i32 %a, i32 %b) { +-; LA32-LABEL: sra_redundant_mask: +-; LA32: # %bb.0: +-; LA32-NEXT: sra.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sra_redundant_mask: +-; LA64: # %bb.0: +-; LA64-NEXT: sra.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = and i32 %b, 65535 +- %2 = ashr i32 %a, %1 +- ret i32 %2 +-} +- +-define i32 @sra_non_redundant_mask(i32 %a, i32 %b) { +-; LA32-LABEL: sra_non_redundant_mask: +-; LA32: # %bb.0: +-; LA32-NEXT: andi $a1, $a1, 32 +-; LA32-NEXT: sra.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sra_non_redundant_mask: +-; LA64: # %bb.0: +-; LA64-NEXT: andi $a1, $a1, 32 +-; LA64-NEXT: sra.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = and i32 %b, 32 +- %2 = ashr i32 %a, %1 +- ret i32 %2 +-} +- +-define i32 @sll_redundant_mask_zeros(i32 %a, i32 %b) { +-; LA32-LABEL: sll_redundant_mask_zeros: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a1, 1 +-; LA32-NEXT: sll.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sll_redundant_mask_zeros: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a1, 1 +-; LA64-NEXT: sll.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = shl i32 %b, 1 +- %2 = and i32 %1, 30 +- %3 = shl i32 %a, %2 +- ret i32 %3 +-} +- +-define i32 @srl_redundant_mask_zeros(i32 %a, i32 %b) { +-; LA32-LABEL: srl_redundant_mask_zeros: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a1, 2 +-; LA32-NEXT: srl.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: srl_redundant_mask_zeros: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a1, 2 +-; LA64-NEXT: srl.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = shl i32 %b, 2 +- %2 = and i32 %1, 28 +- %3 = lshr i32 %a, %2 +- ret i32 %3 +-} +- +-define i32 @sra_redundant_mask_zeros(i32 %a, i32 %b) { +-; LA32-LABEL: sra_redundant_mask_zeros: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a1, $a1, 3 +-; LA32-NEXT: sra.w $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sra_redundant_mask_zeros: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a1, 3 +-; LA64-NEXT: sra.w $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = shl i32 %b, 3 +- %2 = and i32 %1, 24 +- %3 = ashr i32 %a, %2 +- ret i32 %3 +-} +- +-define i64 @sll_redundant_mask_zeros_i64(i64 %a, i64 %b) { +-; LA32-LABEL: sll_redundant_mask_zeros_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a2, 2 +-; LA32-NEXT: srli.w $a3, $a0, 1 +-; LA32-NEXT: andi $a4, $a2, 60 +-; LA32-NEXT: xori $a5, $a4, 31 +-; LA32-NEXT: srl.w $a3, $a3, $a5 +-; LA32-NEXT: sll.w $a1, $a1, $a2 +-; LA32-NEXT: or $a1, $a1, $a3 +-; LA32-NEXT: addi.w $a3, $a4, -32 +-; LA32-NEXT: slti $a4, $a3, 0 +-; LA32-NEXT: maskeqz $a1, $a1, $a4 +-; LA32-NEXT: sll.w $a5, $a0, $a3 +-; LA32-NEXT: masknez $a4, $a5, $a4 +-; LA32-NEXT: or $a1, $a1, $a4 +-; LA32-NEXT: sll.w $a0, $a0, $a2 +-; LA32-NEXT: srai.w $a2, $a3, 31 +-; LA32-NEXT: and $a0, $a2, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sll_redundant_mask_zeros_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a1, 2 +-; LA64-NEXT: sll.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = shl i64 %b, 2 +- %2 = and i64 %1, 60 +- %3 = shl i64 %a, %2 +- ret i64 %3 +-} +- +-define i64 @srl_redundant_mask_zeros_i64(i64 %a, i64 %b) { +-; LA32-LABEL: srl_redundant_mask_zeros_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a2, $a2, 3 +-; LA32-NEXT: slli.w $a3, $a1, 1 +-; LA32-NEXT: andi $a4, $a2, 56 +-; LA32-NEXT: xori $a5, $a4, 31 +-; LA32-NEXT: sll.w $a3, $a3, $a5 +-; LA32-NEXT: srl.w $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a0, $a3 +-; LA32-NEXT: addi.w $a3, $a4, -32 +-; LA32-NEXT: slti $a4, $a3, 0 +-; LA32-NEXT: maskeqz $a0, $a0, $a4 +-; LA32-NEXT: srl.w $a5, $a1, $a3 +-; LA32-NEXT: masknez $a4, $a5, $a4 +-; LA32-NEXT: or $a0, $a0, $a4 +-; LA32-NEXT: srl.w $a1, $a1, $a2 +-; LA32-NEXT: srai.w $a2, $a3, 31 +-; LA32-NEXT: and $a1, $a2, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: srl_redundant_mask_zeros_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a1, 3 +-; LA64-NEXT: srl.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = shl i64 %b, 3 +- %2 = and i64 %1, 56 +- %3 = lshr i64 %a, %2 +- ret i64 %3 +-} +- +-define i64 @sra_redundant_mask_zeros_i64(i64 %a, i64 %b) { +-; LA32-LABEL: sra_redundant_mask_zeros_i64: +-; LA32: # %bb.0: +-; LA32-NEXT: slli.w $a3, $a2, 4 +-; LA32-NEXT: srai.w $a2, $a1, 31 +-; LA32-NEXT: andi $a4, $a3, 48 +-; LA32-NEXT: addi.w $a5, $a4, -32 +-; LA32-NEXT: slti $a6, $a5, 0 +-; LA32-NEXT: masknez $a2, $a2, $a6 +-; LA32-NEXT: sra.w $a7, $a1, $a3 +-; LA32-NEXT: maskeqz $a7, $a7, $a6 +-; LA32-NEXT: or $a2, $a7, $a2 +-; LA32-NEXT: srl.w $a0, $a0, $a3 +-; LA32-NEXT: xori $a3, $a4, 31 +-; LA32-NEXT: slli.w $a4, $a1, 1 +-; LA32-NEXT: sll.w $a3, $a4, $a3 +-; LA32-NEXT: or $a0, $a0, $a3 +-; LA32-NEXT: sra.w $a1, $a1, $a5 +-; LA32-NEXT: maskeqz $a0, $a0, $a6 +-; LA32-NEXT: masknez $a1, $a1, $a6 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: move $a1, $a2 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: sra_redundant_mask_zeros_i64: +-; LA64: # %bb.0: +-; LA64-NEXT: slli.d $a1, $a1, 4 +-; LA64-NEXT: sra.d $a0, $a0, $a1 +-; LA64-NEXT: ret +- %1 = shl i64 %b, 4 +- %2 = and i64 %1, 48 +- %3 = ashr i64 %a, %2 +- ret i64 %3 +-} +diff --git a/llvm/test/CodeGen/LoongArch/shrinkwrap.ll b/llvm/test/CodeGen/LoongArch/shrinkwrap.ll +deleted file mode 100644 +index 5f15dd2e7..000000000 +--- a/llvm/test/CodeGen/LoongArch/shrinkwrap.ll ++++ /dev/null +@@ -1,112 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 -O0 < %s | FileCheck %s --check-prefix=NOSHRINKW +-; RUN: llc --mtriple=loongarch64 -O2 < %s | FileCheck %s --check-prefix=SHRINKW +- +-declare void @abort() +- +-define void @eliminate_restore(i32 %n) nounwind { +-; NOSHRINKW-LABEL: eliminate_restore: +-; NOSHRINKW: # %bb.0: +-; NOSHRINKW-NEXT: addi.d $sp, $sp, -16 +-; NOSHRINKW-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; NOSHRINKW-NEXT: # kill: def $r5 killed $r4 +-; NOSHRINKW-NEXT: addi.w $a1, $a0, 0 +-; NOSHRINKW-NEXT: ori $a0, $zero, 32 +-; NOSHRINKW-NEXT: bltu $a0, $a1, .LBB0_2 +-; NOSHRINKW-NEXT: b .LBB0_1 +-; NOSHRINKW-NEXT: .LBB0_1: # %if.then +-; NOSHRINKW-NEXT: bl %plt(abort) +-; NOSHRINKW-NEXT: .LBB0_2: # %if.end +-; NOSHRINKW-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; NOSHRINKW-NEXT: addi.d $sp, $sp, 16 +-; NOSHRINKW-NEXT: ret +-; +-; SHRINKW-LABEL: eliminate_restore: +-; SHRINKW: # %bb.0: +-; SHRINKW-NEXT: addi.w $a0, $a0, 0 +-; SHRINKW-NEXT: ori $a1, $zero, 32 +-; SHRINKW-NEXT: bgeu $a1, $a0, .LBB0_2 +-; SHRINKW-NEXT: # %bb.1: # %if.end +-; SHRINKW-NEXT: ret +-; SHRINKW-NEXT: .LBB0_2: # %if.then +-; SHRINKW-NEXT: addi.d $sp, $sp, -16 +-; SHRINKW-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; SHRINKW-NEXT: bl %plt(abort) +- %cmp = icmp ule i32 %n, 32 +- br i1 %cmp, label %if.then, label %if.end +- +-if.then: +- call void @abort() +- unreachable +- +-if.end: +- ret void +-} +- +-declare void @notdead(ptr) +- +-define void @conditional_alloca(i32 %n) nounwind { +-; NOSHRINKW-LABEL: conditional_alloca: +-; NOSHRINKW: # %bb.0: +-; NOSHRINKW-NEXT: addi.d $sp, $sp, -32 +-; NOSHRINKW-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill +-; NOSHRINKW-NEXT: st.d $fp, $sp, 16 # 8-byte Folded Spill +-; NOSHRINKW-NEXT: addi.d $fp, $sp, 32 +-; NOSHRINKW-NEXT: move $a1, $a0 +-; NOSHRINKW-NEXT: st.d $a1, $fp, -24 # 8-byte Folded Spill +-; NOSHRINKW-NEXT: addi.w $a1, $a0, 0 +-; NOSHRINKW-NEXT: ori $a0, $zero, 32 +-; NOSHRINKW-NEXT: bltu $a0, $a1, .LBB1_2 +-; NOSHRINKW-NEXT: b .LBB1_1 +-; NOSHRINKW-NEXT: .LBB1_1: # %if.then +-; NOSHRINKW-NEXT: ld.d $a0, $fp, -24 # 8-byte Folded Reload +-; NOSHRINKW-NEXT: bstrpick.d $a0, $a0, 31, 0 +-; NOSHRINKW-NEXT: addi.d $a0, $a0, 15 +-; NOSHRINKW-NEXT: bstrpick.d $a0, $a0, 32, 4 +-; NOSHRINKW-NEXT: slli.d $a1, $a0, 4 +-; NOSHRINKW-NEXT: move $a0, $sp +-; NOSHRINKW-NEXT: sub.d $a0, $a0, $a1 +-; NOSHRINKW-NEXT: move $sp, $a0 +-; NOSHRINKW-NEXT: bl %plt(notdead) +-; NOSHRINKW-NEXT: b .LBB1_2 +-; NOSHRINKW-NEXT: .LBB1_2: # %if.end +-; NOSHRINKW-NEXT: addi.d $sp, $fp, -32 +-; NOSHRINKW-NEXT: ld.d $fp, $sp, 16 # 8-byte Folded Reload +-; NOSHRINKW-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload +-; NOSHRINKW-NEXT: addi.d $sp, $sp, 32 +-; NOSHRINKW-NEXT: ret +-; +-; SHRINKW-LABEL: conditional_alloca: +-; SHRINKW: # %bb.0: +-; SHRINKW-NEXT: addi.w $a1, $a0, 0 +-; SHRINKW-NEXT: ori $a2, $zero, 32 +-; SHRINKW-NEXT: bltu $a2, $a1, .LBB1_2 +-; SHRINKW-NEXT: # %bb.1: # %if.then +-; SHRINKW-NEXT: addi.d $sp, $sp, -16 +-; SHRINKW-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; SHRINKW-NEXT: st.d $fp, $sp, 0 # 8-byte Folded Spill +-; SHRINKW-NEXT: addi.d $fp, $sp, 16 +-; SHRINKW-NEXT: bstrpick.d $a0, $a0, 31, 0 +-; SHRINKW-NEXT: addi.d $a0, $a0, 15 +-; SHRINKW-NEXT: bstrpick.d $a0, $a0, 32, 4 +-; SHRINKW-NEXT: slli.d $a0, $a0, 4 +-; SHRINKW-NEXT: sub.d $a0, $sp, $a0 +-; SHRINKW-NEXT: move $sp, $a0 +-; SHRINKW-NEXT: bl %plt(notdead) +-; SHRINKW-NEXT: addi.d $sp, $fp, -16 +-; SHRINKW-NEXT: ld.d $fp, $sp, 0 # 8-byte Folded Reload +-; SHRINKW-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; SHRINKW-NEXT: addi.d $sp, $sp, 16 +-; SHRINKW-NEXT: .LBB1_2: # %if.end +-; SHRINKW-NEXT: ret +- %cmp = icmp ule i32 %n, 32 +- br i1 %cmp, label %if.then, label %if.end +- +-if.then: +- %addr = alloca i8, i32 %n +- call void @notdead(ptr %addr) +- br label %if.end +- +-if.end: +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/signext.ll b/llvm/test/CodeGen/LoongArch/signext.ll +new file mode 100644 +index 000000000..13c710d14 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/signext.ll +@@ -0,0 +1,37 @@ ++; RUN: llc -march=loongarch64 < %s | FileCheck %s ++ ++define i32 @foo(i32 signext %a) { ++; CHECK-LABEL: foo: ++; CHECK: # %bb.0: ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++ ret i32 %a ++} ++ ++define signext i32 @foo1() { ++; CHECK-LABEL: foo1: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: ori $r4, $zero, 0 ++; CHECK-NEXT: ori $r5, $zero, 896 ++; CHECK-NEXT: move $r6, $r4 ++; CHECK-NEXT: .LBB1_1: # %for.body ++; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ++; CHECK-NEXT: add.w $r4, $r4, $r6 ++; CHECK-NEXT: addi.w $r6, $r6, 1 ++; CHECK-NEXT: bne $r6, $r5, .LBB1_1 ++; CHECK-NEXT: # %bb.2: # %for.end ++; CHECK-NEXT: jr $ra ++entry: ++ br label %for.body ++ ++for.body: ++ %sum.013 = phi i32 [ 0, %entry ], [ %add, %for.body ] ++ %i.010 = phi i32 [ 0, %entry ], [ %inc, %for.body ] ++ %add = add i32 %sum.013, %i.010 ++ %inc = add nuw nsw i32 %i.010, 1 ++ %exitcond = icmp eq i32 %inc, 896 ++ br i1 %exitcond, label %for.end, label %for.body ++ ++for.end: ++ ret i32 %add ++} +diff --git a/llvm/test/CodeGen/LoongArch/smul-with-overflow.ll b/llvm/test/CodeGen/LoongArch/smul-with-overflow.ll +deleted file mode 100644 +index 6cba4108d..000000000 +--- a/llvm/test/CodeGen/LoongArch/smul-with-overflow.ll ++++ /dev/null +@@ -1,439 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-define zeroext i1 @smuloi64(i64 %v1, i64 %v2, ptr %res) { +-; LA32-LABEL: smuloi64: +-; LA32: # %bb.0: +-; LA32-NEXT: srai.w $a5, $a1, 31 +-; LA32-NEXT: mul.w $a6, $a2, $a5 +-; LA32-NEXT: mulh.wu $a7, $a2, $a5 +-; LA32-NEXT: add.w $a7, $a7, $a6 +-; LA32-NEXT: mul.w $a5, $a3, $a5 +-; LA32-NEXT: add.w $a5, $a7, $a5 +-; LA32-NEXT: srai.w $a7, $a3, 31 +-; LA32-NEXT: mul.w $t0, $a7, $a1 +-; LA32-NEXT: mulh.wu $t1, $a7, $a0 +-; LA32-NEXT: add.w $t0, $t1, $t0 +-; LA32-NEXT: mul.w $a7, $a7, $a0 +-; LA32-NEXT: add.w $t0, $t0, $a7 +-; LA32-NEXT: add.w $a5, $t0, $a5 +-; LA32-NEXT: mulh.wu $t0, $a0, $a2 +-; LA32-NEXT: mul.w $t1, $a1, $a2 +-; LA32-NEXT: add.w $t0, $t1, $t0 +-; LA32-NEXT: sltu $t1, $t0, $t1 +-; LA32-NEXT: mulh.wu $t2, $a1, $a2 +-; LA32-NEXT: add.w $t1, $t2, $t1 +-; LA32-NEXT: mul.w $t2, $a0, $a3 +-; LA32-NEXT: add.w $t0, $t2, $t0 +-; LA32-NEXT: sltu $t2, $t0, $t2 +-; LA32-NEXT: mulh.wu $t3, $a0, $a3 +-; LA32-NEXT: add.w $t2, $t3, $t2 +-; LA32-NEXT: add.w $a6, $a7, $a6 +-; LA32-NEXT: sltu $a7, $a6, $a7 +-; LA32-NEXT: add.w $a5, $a5, $a7 +-; LA32-NEXT: mul.w $a0, $a0, $a2 +-; LA32-NEXT: mul.w $a2, $a1, $a3 +-; LA32-NEXT: mulh.wu $a1, $a1, $a3 +-; LA32-NEXT: add.w $a3, $t1, $t2 +-; LA32-NEXT: sltu $a7, $a3, $t1 +-; LA32-NEXT: add.w $a1, $a1, $a7 +-; LA32-NEXT: st.w $a0, $a4, 0 +-; LA32-NEXT: add.w $a0, $a2, $a3 +-; LA32-NEXT: sltu $a2, $a0, $a2 +-; LA32-NEXT: add.w $a1, $a1, $a2 +-; LA32-NEXT: st.w $t0, $a4, 4 +-; LA32-NEXT: add.w $a1, $a1, $a5 +-; LA32-NEXT: add.w $a2, $a0, $a6 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: add.w $a0, $a1, $a0 +-; LA32-NEXT: srai.w $a1, $t0, 31 +-; LA32-NEXT: xor $a0, $a0, $a1 +-; LA32-NEXT: xor $a1, $a2, $a1 +-; LA32-NEXT: or $a0, $a1, $a0 +-; LA32-NEXT: sltu $a0, $zero, $a0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: smuloi64: +-; LA64: # %bb.0: +-; LA64-NEXT: mul.d $a3, $a0, $a1 +-; LA64-NEXT: st.d $a3, $a2, 0 +-; LA64-NEXT: mulh.d $a0, $a0, $a1 +-; LA64-NEXT: srai.d $a1, $a3, 63 +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: sltu $a0, $zero, $a0 +-; LA64-NEXT: ret +- %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) +- %val = extractvalue {i64, i1} %t, 0 +- %obit = extractvalue {i64, i1} %t, 1 +- store i64 %val, ptr %res +- ret i1 %obit +-} +- +-define zeroext i1 @smuloi128(i128 %v1, i128 %v2, ptr %res) { +-; LA32-LABEL: smuloi128: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -96 +-; LA32-NEXT: .cfi_def_cfa_offset 96 +-; LA32-NEXT: st.w $ra, $sp, 92 # 4-byte Folded Spill +-; LA32-NEXT: st.w $fp, $sp, 88 # 4-byte Folded Spill +-; LA32-NEXT: st.w $s0, $sp, 84 # 4-byte Folded Spill +-; LA32-NEXT: st.w $s1, $sp, 80 # 4-byte Folded Spill +-; LA32-NEXT: st.w $s2, $sp, 76 # 4-byte Folded Spill +-; LA32-NEXT: st.w $s3, $sp, 72 # 4-byte Folded Spill +-; LA32-NEXT: st.w $s4, $sp, 68 # 4-byte Folded Spill +-; LA32-NEXT: st.w $s5, $sp, 64 # 4-byte Folded Spill +-; LA32-NEXT: st.w $s6, $sp, 60 # 4-byte Folded Spill +-; LA32-NEXT: st.w $s7, $sp, 56 # 4-byte Folded Spill +-; LA32-NEXT: st.w $s8, $sp, 52 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: .cfi_offset 22, -8 +-; LA32-NEXT: .cfi_offset 23, -12 +-; LA32-NEXT: .cfi_offset 24, -16 +-; LA32-NEXT: .cfi_offset 25, -20 +-; LA32-NEXT: .cfi_offset 26, -24 +-; LA32-NEXT: .cfi_offset 27, -28 +-; LA32-NEXT: .cfi_offset 28, -32 +-; LA32-NEXT: .cfi_offset 29, -36 +-; LA32-NEXT: .cfi_offset 30, -40 +-; LA32-NEXT: .cfi_offset 31, -44 +-; LA32-NEXT: st.w $a2, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: ld.w $a6, $a1, 0 +-; LA32-NEXT: ld.w $a7, $a0, 0 +-; LA32-NEXT: mulh.wu $a3, $a7, $a6 +-; LA32-NEXT: ld.w $a5, $a0, 4 +-; LA32-NEXT: mul.w $a4, $a5, $a6 +-; LA32-NEXT: add.w $a3, $a4, $a3 +-; LA32-NEXT: sltu $a4, $a3, $a4 +-; LA32-NEXT: mulh.wu $t0, $a5, $a6 +-; LA32-NEXT: add.w $a4, $t0, $a4 +-; LA32-NEXT: ld.w $t0, $a1, 4 +-; LA32-NEXT: mul.w $t1, $a7, $t0 +-; LA32-NEXT: add.w $a3, $t1, $a3 +-; LA32-NEXT: st.w $a3, $sp, 44 # 4-byte Folded Spill +-; LA32-NEXT: sltu $t1, $a3, $t1 +-; LA32-NEXT: mulh.wu $t2, $a7, $t0 +-; LA32-NEXT: add.w $t1, $t2, $t1 +-; LA32-NEXT: ld.w $t4, $a0, 12 +-; LA32-NEXT: ld.w $t2, $a0, 8 +-; LA32-NEXT: ld.w $t3, $a1, 8 +-; LA32-NEXT: mulh.wu $a0, $t2, $t3 +-; LA32-NEXT: mul.w $t5, $t4, $t3 +-; LA32-NEXT: add.w $a0, $t5, $a0 +-; LA32-NEXT: sltu $t5, $a0, $t5 +-; LA32-NEXT: mulh.wu $t6, $t4, $t3 +-; LA32-NEXT: add.w $t5, $t6, $t5 +-; LA32-NEXT: ld.w $t7, $a1, 12 +-; LA32-NEXT: mul.w $a1, $t2, $t7 +-; LA32-NEXT: add.w $a0, $a1, $a0 +-; LA32-NEXT: st.w $a0, $sp, 48 # 4-byte Folded Spill +-; LA32-NEXT: sltu $a1, $a0, $a1 +-; LA32-NEXT: mulh.wu $t6, $t2, $t7 +-; LA32-NEXT: add.w $t6, $t6, $a1 +-; LA32-NEXT: srai.w $s7, $t4, 31 +-; LA32-NEXT: mul.w $a1, $s7, $t7 +-; LA32-NEXT: mulh.wu $t8, $s7, $t3 +-; LA32-NEXT: add.w $t8, $t8, $a1 +-; LA32-NEXT: mulh.wu $fp, $a6, $s7 +-; LA32-NEXT: mul.w $s6, $t0, $s7 +-; LA32-NEXT: add.w $s8, $s6, $fp +-; LA32-NEXT: mul.w $a1, $a6, $s7 +-; LA32-NEXT: add.w $ra, $a1, $s8 +-; LA32-NEXT: sltu $s0, $ra, $a1 +-; LA32-NEXT: add.w $a0, $fp, $s0 +-; LA32-NEXT: add.w $a3, $a4, $t1 +-; LA32-NEXT: st.w $a3, $sp, 20 # 4-byte Folded Spill +-; LA32-NEXT: sltu $a4, $a3, $a4 +-; LA32-NEXT: mulh.wu $t1, $a5, $t0 +-; LA32-NEXT: add.w $a3, $t1, $a4 +-; LA32-NEXT: st.w $a3, $sp, 28 # 4-byte Folded Spill +-; LA32-NEXT: srai.w $s4, $t7, 31 +-; LA32-NEXT: mul.w $fp, $a7, $s4 +-; LA32-NEXT: mulh.wu $a4, $a7, $s4 +-; LA32-NEXT: add.w $s1, $a4, $fp +-; LA32-NEXT: sltu $s0, $s1, $fp +-; LA32-NEXT: add.w $s5, $a4, $s0 +-; LA32-NEXT: mul.w $a4, $s7, $t3 +-; LA32-NEXT: add.w $t8, $t8, $a4 +-; LA32-NEXT: add.w $s0, $ra, $t8 +-; LA32-NEXT: add.w $a3, $a1, $a4 +-; LA32-NEXT: st.w $a3, $sp, 32 # 4-byte Folded Spill +-; LA32-NEXT: sltu $a4, $a3, $a1 +-; LA32-NEXT: add.w $a3, $s0, $a4 +-; LA32-NEXT: st.w $a3, $sp, 24 # 4-byte Folded Spill +-; LA32-NEXT: add.w $s3, $t5, $t6 +-; LA32-NEXT: sltu $a4, $s3, $t5 +-; LA32-NEXT: mulh.wu $t5, $t4, $t7 +-; LA32-NEXT: add.w $a3, $t5, $a4 +-; LA32-NEXT: st.w $a3, $sp, 16 # 4-byte Folded Spill +-; LA32-NEXT: mul.w $a4, $a7, $a6 +-; LA32-NEXT: st.w $a4, $a2, 0 +-; LA32-NEXT: sltu $a4, $s8, $s6 +-; LA32-NEXT: mulh.wu $t5, $t0, $s7 +-; LA32-NEXT: add.w $a4, $t5, $a4 +-; LA32-NEXT: add.w $t1, $a4, $a0 +-; LA32-NEXT: sltu $a4, $t1, $a4 +-; LA32-NEXT: add.w $s2, $t5, $a4 +-; LA32-NEXT: mulh.wu $a4, $a7, $t3 +-; LA32-NEXT: mul.w $t5, $a5, $t3 +-; LA32-NEXT: add.w $a4, $t5, $a4 +-; LA32-NEXT: sltu $t5, $a4, $t5 +-; LA32-NEXT: mulh.wu $t6, $a5, $t3 +-; LA32-NEXT: add.w $a3, $t6, $t5 +-; LA32-NEXT: mul.w $t6, $a7, $t7 +-; LA32-NEXT: add.w $t5, $t6, $a4 +-; LA32-NEXT: sltu $a4, $t5, $t6 +-; LA32-NEXT: mulh.wu $t6, $a7, $t7 +-; LA32-NEXT: add.w $a4, $t6, $a4 +-; LA32-NEXT: mulh.wu $t6, $t2, $a6 +-; LA32-NEXT: mul.w $s7, $t4, $a6 +-; LA32-NEXT: add.w $t6, $s7, $t6 +-; LA32-NEXT: sltu $s7, $t6, $s7 +-; LA32-NEXT: mulh.wu $s8, $t4, $a6 +-; LA32-NEXT: add.w $a0, $s8, $s7 +-; LA32-NEXT: mul.w $s7, $t2, $t0 +-; LA32-NEXT: add.w $t6, $s7, $t6 +-; LA32-NEXT: sltu $s7, $t6, $s7 +-; LA32-NEXT: mulh.wu $s8, $t2, $t0 +-; LA32-NEXT: add.w $a2, $s8, $s7 +-; LA32-NEXT: mul.w $s8, $a5, $s4 +-; LA32-NEXT: add.w $s7, $s1, $s8 +-; LA32-NEXT: add.w $s1, $s7, $ra +-; LA32-NEXT: add.w $a1, $fp, $a1 +-; LA32-NEXT: st.w $a1, $sp, 40 # 4-byte Folded Spill +-; LA32-NEXT: sltu $ra, $a1, $fp +-; LA32-NEXT: add.w $a1, $s1, $ra +-; LA32-NEXT: st.w $a1, $sp, 36 # 4-byte Folded Spill +-; LA32-NEXT: xor $s0, $a1, $s7 +-; LA32-NEXT: sltui $s0, $s0, 1 +-; LA32-NEXT: sltu $a1, $a1, $s7 +-; LA32-NEXT: masknez $s1, $a1, $s0 +-; LA32-NEXT: maskeqz $s0, $ra, $s0 +-; LA32-NEXT: add.w $t1, $s6, $t1 +-; LA32-NEXT: sltu $s6, $t1, $s6 +-; LA32-NEXT: add.w $s2, $s2, $s6 +-; LA32-NEXT: add.w $a2, $a0, $a2 +-; LA32-NEXT: sltu $a0, $a2, $a0 +-; LA32-NEXT: mulh.wu $s6, $t4, $t0 +-; LA32-NEXT: add.w $t8, $s6, $a0 +-; LA32-NEXT: add.w $a4, $a3, $a4 +-; LA32-NEXT: sltu $a3, $a4, $a3 +-; LA32-NEXT: mulh.wu $s6, $a5, $t7 +-; LA32-NEXT: add.w $a3, $s6, $a3 +-; LA32-NEXT: mul.w $s6, $t4, $t7 +-; LA32-NEXT: mul.w $t7, $a5, $t7 +-; LA32-NEXT: mul.w $ra, $t4, $t0 +-; LA32-NEXT: mul.w $t0, $a5, $t0 +-; LA32-NEXT: mul.w $t4, $t4, $s4 +-; LA32-NEXT: mul.w $a7, $a7, $t3 +-; LA32-NEXT: mul.w $a6, $t2, $a6 +-; LA32-NEXT: mul.w $t3, $t2, $t3 +-; LA32-NEXT: mul.w $a0, $t2, $s4 +-; LA32-NEXT: mulh.wu $t2, $t2, $s4 +-; LA32-NEXT: mulh.wu $a5, $s4, $a5 +-; LA32-NEXT: sltu $s4, $s7, $s8 +-; LA32-NEXT: add.w $s4, $a5, $s4 +-; LA32-NEXT: add.w $s4, $s5, $s4 +-; LA32-NEXT: sltu $s5, $s4, $s5 +-; LA32-NEXT: add.w $s5, $a5, $s5 +-; LA32-NEXT: ld.w $a1, $sp, 20 # 4-byte Folded Reload +-; LA32-NEXT: add.w $a1, $t0, $a1 +-; LA32-NEXT: sltu $a5, $a1, $t0 +-; LA32-NEXT: ld.w $t0, $sp, 28 # 4-byte Folded Reload +-; LA32-NEXT: add.w $t0, $t0, $a5 +-; LA32-NEXT: or $s0, $s0, $s1 +-; LA32-NEXT: add.w $a4, $t7, $a4 +-; LA32-NEXT: sltu $a5, $a4, $t7 +-; LA32-NEXT: add.w $t7, $a3, $a5 +-; LA32-NEXT: add.w $s1, $ra, $a2 +-; LA32-NEXT: sltu $a2, $s1, $ra +-; LA32-NEXT: add.w $t8, $t8, $a2 +-; LA32-NEXT: add.w $a5, $s6, $s3 +-; LA32-NEXT: sltu $a2, $a5, $s6 +-; LA32-NEXT: ld.w $a3, $sp, 16 # 4-byte Folded Reload +-; LA32-NEXT: add.w $a2, $a3, $a2 +-; LA32-NEXT: ld.w $s6, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $a3, $sp, 44 # 4-byte Folded Reload +-; LA32-NEXT: st.w $a3, $s6, 4 +-; LA32-NEXT: ld.w $a3, $sp, 24 # 4-byte Folded Reload +-; LA32-NEXT: add.w $a3, $s2, $a3 +-; LA32-NEXT: ld.w $s2, $sp, 32 # 4-byte Folded Reload +-; LA32-NEXT: add.w $s2, $t1, $s2 +-; LA32-NEXT: sltu $t1, $s2, $t1 +-; LA32-NEXT: add.w $a3, $a3, $t1 +-; LA32-NEXT: add.w $t1, $s8, $s4 +-; LA32-NEXT: sltu $s3, $t1, $s8 +-; LA32-NEXT: add.w $s3, $s5, $s3 +-; LA32-NEXT: add.w $t2, $t2, $a0 +-; LA32-NEXT: add.w $t2, $t2, $t4 +-; LA32-NEXT: add.w $t2, $t2, $s7 +-; LA32-NEXT: add.w $t4, $a0, $fp +-; LA32-NEXT: sltu $a0, $t4, $a0 +-; LA32-NEXT: add.w $a0, $t2, $a0 +-; LA32-NEXT: add.w $a0, $s3, $a0 +-; LA32-NEXT: add.w $t2, $t1, $t4 +-; LA32-NEXT: sltu $t1, $t2, $t1 +-; LA32-NEXT: add.w $a0, $a0, $t1 +-; LA32-NEXT: add.w $a0, $a0, $a3 +-; LA32-NEXT: add.w $t1, $t2, $s2 +-; LA32-NEXT: sltu $a3, $t1, $t2 +-; LA32-NEXT: add.w $a0, $a0, $a3 +-; LA32-NEXT: add.w $a3, $t6, $t0 +-; LA32-NEXT: add.w $a1, $a6, $a1 +-; LA32-NEXT: sltu $a6, $a1, $a6 +-; LA32-NEXT: add.w $t0, $a3, $a6 +-; LA32-NEXT: add.w $a1, $a7, $a1 +-; LA32-NEXT: sltu $a7, $a1, $a7 +-; LA32-NEXT: add.w $a3, $t5, $t0 +-; LA32-NEXT: add.w $a3, $a3, $a7 +-; LA32-NEXT: sltu $t2, $a3, $t5 +-; LA32-NEXT: xor $t4, $a3, $t5 +-; LA32-NEXT: sltui $t4, $t4, 1 +-; LA32-NEXT: masknez $t2, $t2, $t4 +-; LA32-NEXT: maskeqz $a7, $a7, $t4 +-; LA32-NEXT: st.w $a1, $s6, 8 +-; LA32-NEXT: or $a1, $a7, $t2 +-; LA32-NEXT: sltu $a7, $t0, $t6 +-; LA32-NEXT: xor $t0, $t0, $t6 +-; LA32-NEXT: sltui $t0, $t0, 1 +-; LA32-NEXT: masknez $a7, $a7, $t0 +-; LA32-NEXT: maskeqz $a6, $a6, $t0 +-; LA32-NEXT: or $a6, $a6, $a7 +-; LA32-NEXT: add.w $a6, $s1, $a6 +-; LA32-NEXT: sltu $a7, $a6, $s1 +-; LA32-NEXT: add.w $a7, $t8, $a7 +-; LA32-NEXT: add.w $a1, $a4, $a1 +-; LA32-NEXT: sltu $a4, $a1, $a4 +-; LA32-NEXT: add.w $a4, $t7, $a4 +-; LA32-NEXT: add.w $t0, $t1, $s0 +-; LA32-NEXT: sltu $t1, $t0, $t1 +-; LA32-NEXT: add.w $a0, $a0, $t1 +-; LA32-NEXT: st.w $a3, $s6, 12 +-; LA32-NEXT: add.w $a1, $a6, $a1 +-; LA32-NEXT: sltu $a6, $a1, $a6 +-; LA32-NEXT: add.w $a4, $a7, $a4 +-; LA32-NEXT: add.w $a4, $a4, $a6 +-; LA32-NEXT: sltu $t1, $a4, $a7 +-; LA32-NEXT: xor $a7, $a4, $a7 +-; LA32-NEXT: sltui $a7, $a7, 1 +-; LA32-NEXT: masknez $t1, $t1, $a7 +-; LA32-NEXT: maskeqz $a6, $a6, $a7 +-; LA32-NEXT: or $a6, $a6, $t1 +-; LA32-NEXT: add.w $a6, $a5, $a6 +-; LA32-NEXT: sltu $a5, $a6, $a5 +-; LA32-NEXT: add.w $a2, $a2, $a5 +-; LA32-NEXT: ld.w $t1, $sp, 48 # 4-byte Folded Reload +-; LA32-NEXT: add.w $a4, $t1, $a4 +-; LA32-NEXT: add.w $a1, $t3, $a1 +-; LA32-NEXT: sltu $a5, $a1, $t3 +-; LA32-NEXT: add.w $a4, $a4, $a5 +-; LA32-NEXT: sltu $a7, $a4, $t1 +-; LA32-NEXT: xor $t1, $a4, $t1 +-; LA32-NEXT: sltui $t1, $t1, 1 +-; LA32-NEXT: masknez $a7, $a7, $t1 +-; LA32-NEXT: maskeqz $a5, $a5, $t1 +-; LA32-NEXT: or $a5, $a5, $a7 +-; LA32-NEXT: add.w $a5, $a6, $a5 +-; LA32-NEXT: sltu $a6, $a5, $a6 +-; LA32-NEXT: add.w $a2, $a2, $a6 +-; LA32-NEXT: add.w $a0, $a2, $a0 +-; LA32-NEXT: add.w $a2, $a5, $t0 +-; LA32-NEXT: sltu $a5, $a2, $a5 +-; LA32-NEXT: add.w $a0, $a0, $a5 +-; LA32-NEXT: ld.w $a5, $sp, 40 # 4-byte Folded Reload +-; LA32-NEXT: add.w $a5, $a1, $a5 +-; LA32-NEXT: sltu $a1, $a5, $a1 +-; LA32-NEXT: ld.w $a6, $sp, 36 # 4-byte Folded Reload +-; LA32-NEXT: add.w $a6, $a4, $a6 +-; LA32-NEXT: add.w $a6, $a6, $a1 +-; LA32-NEXT: sltu $a7, $a6, $a4 +-; LA32-NEXT: xor $a4, $a6, $a4 +-; LA32-NEXT: sltui $a4, $a4, 1 +-; LA32-NEXT: masknez $a7, $a7, $a4 +-; LA32-NEXT: maskeqz $a1, $a1, $a4 +-; LA32-NEXT: or $a1, $a1, $a7 +-; LA32-NEXT: add.w $a1, $a2, $a1 +-; LA32-NEXT: sltu $a2, $a1, $a2 +-; LA32-NEXT: add.w $a0, $a0, $a2 +-; LA32-NEXT: srai.w $a2, $a3, 31 +-; LA32-NEXT: xor $a3, $a6, $a2 +-; LA32-NEXT: xor $a0, $a0, $a2 +-; LA32-NEXT: or $a0, $a3, $a0 +-; LA32-NEXT: xor $a3, $a5, $a2 +-; LA32-NEXT: xor $a1, $a1, $a2 +-; LA32-NEXT: or $a1, $a3, $a1 +-; LA32-NEXT: or $a0, $a1, $a0 +-; LA32-NEXT: sltu $a0, $zero, $a0 +-; LA32-NEXT: ld.w $s8, $sp, 52 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $s7, $sp, 56 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $s6, $sp, 60 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $s5, $sp, 64 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $s4, $sp, 68 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $s3, $sp, 72 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $s2, $sp, 76 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $s1, $sp, 80 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $s0, $sp, 84 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $fp, $sp, 88 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $ra, $sp, 92 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 96 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: smuloi128: +-; LA64: # %bb.0: +-; LA64-NEXT: srai.d $a5, $a1, 63 +-; LA64-NEXT: mul.d $a6, $a2, $a5 +-; LA64-NEXT: mulh.du $a7, $a2, $a5 +-; LA64-NEXT: add.d $a7, $a7, $a6 +-; LA64-NEXT: mul.d $a5, $a3, $a5 +-; LA64-NEXT: add.d $a5, $a7, $a5 +-; LA64-NEXT: srai.d $a7, $a3, 63 +-; LA64-NEXT: mul.d $t0, $a7, $a1 +-; LA64-NEXT: mulh.du $t1, $a7, $a0 +-; LA64-NEXT: add.d $t0, $t1, $t0 +-; LA64-NEXT: mul.d $a7, $a7, $a0 +-; LA64-NEXT: add.d $t0, $t0, $a7 +-; LA64-NEXT: add.d $a5, $t0, $a5 +-; LA64-NEXT: mulh.du $t0, $a0, $a2 +-; LA64-NEXT: mul.d $t1, $a1, $a2 +-; LA64-NEXT: add.d $t0, $t1, $t0 +-; LA64-NEXT: sltu $t1, $t0, $t1 +-; LA64-NEXT: mulh.du $t2, $a1, $a2 +-; LA64-NEXT: add.d $t1, $t2, $t1 +-; LA64-NEXT: mul.d $t2, $a0, $a3 +-; LA64-NEXT: add.d $t0, $t2, $t0 +-; LA64-NEXT: sltu $t2, $t0, $t2 +-; LA64-NEXT: mulh.du $t3, $a0, $a3 +-; LA64-NEXT: add.d $t2, $t3, $t2 +-; LA64-NEXT: add.d $a6, $a7, $a6 +-; LA64-NEXT: sltu $a7, $a6, $a7 +-; LA64-NEXT: add.d $a5, $a5, $a7 +-; LA64-NEXT: mul.d $a0, $a0, $a2 +-; LA64-NEXT: mul.d $a2, $a1, $a3 +-; LA64-NEXT: mulh.du $a1, $a1, $a3 +-; LA64-NEXT: add.d $a3, $t1, $t2 +-; LA64-NEXT: sltu $a7, $a3, $t1 +-; LA64-NEXT: add.d $a1, $a1, $a7 +-; LA64-NEXT: st.d $a0, $a4, 0 +-; LA64-NEXT: add.d $a0, $a2, $a3 +-; LA64-NEXT: sltu $a2, $a0, $a2 +-; LA64-NEXT: add.d $a1, $a1, $a2 +-; LA64-NEXT: st.d $t0, $a4, 8 +-; LA64-NEXT: add.d $a1, $a1, $a5 +-; LA64-NEXT: add.d $a2, $a0, $a6 +-; LA64-NEXT: sltu $a0, $a2, $a0 +-; LA64-NEXT: add.d $a0, $a1, $a0 +-; LA64-NEXT: srai.d $a1, $t0, 63 +-; LA64-NEXT: xor $a0, $a0, $a1 +-; LA64-NEXT: xor $a1, $a2, $a1 +-; LA64-NEXT: or $a0, $a1, $a0 +-; LA64-NEXT: sltu $a0, $zero, $a0 +-; LA64-NEXT: ret +- %t = call {i128, i1} @llvm.smul.with.overflow.i128(i128 %v1, i128 %v2) +- %val = extractvalue {i128, i1} %t, 0 +- %obit = extractvalue {i128, i1} %t, 1 +- store i128 %val, ptr %res +- ret i1 %obit +-} +- +-declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone +-declare {i128, i1} @llvm.smul.with.overflow.i128(i128, i128) nounwind readnone +diff --git a/llvm/test/CodeGen/LoongArch/soft-fp-to-int.ll b/llvm/test/CodeGen/LoongArch/soft-fp-to-int.ll +deleted file mode 100644 +index d12cbaaab..000000000 +--- a/llvm/test/CodeGen/LoongArch/soft-fp-to-int.ll ++++ /dev/null +@@ -1,155 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 +- +-define i32 @fptosi_i32_fp128(fp128 %X) nounwind { +-; LA32-LABEL: fptosi_i32_fp128: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -32 +-; LA32-NEXT: st.w $ra, $sp, 28 # 4-byte Folded Spill +-; LA32-NEXT: ld.w $a1, $a0, 12 +-; LA32-NEXT: st.w $a1, $sp, 20 +-; LA32-NEXT: ld.w $a1, $a0, 8 +-; LA32-NEXT: st.w $a1, $sp, 16 +-; LA32-NEXT: ld.w $a1, $a0, 4 +-; LA32-NEXT: st.w $a1, $sp, 12 +-; LA32-NEXT: ld.w $a0, $a0, 0 +-; LA32-NEXT: st.w $a0, $sp, 8 +-; LA32-NEXT: addi.w $a0, $sp, 8 +-; LA32-NEXT: bl %plt(__fixtfsi) +-; LA32-NEXT: ld.w $ra, $sp, 28 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 32 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fptosi_i32_fp128: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(__fixtfsi) +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %tmp = fptosi fp128 %X to i32 +- ret i32 %tmp +-} +- +-define i32 @fptosi_i32_double(double %X) nounwind { +-; LA32-LABEL: fptosi_i32_double: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(__fixdfsi) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fptosi_i32_double: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(__fixdfsi) +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %tmp = fptosi double %X to i32 +- ret i32 %tmp +-} +- +-define i32 @fptosi_i32_float(float %X) nounwind { +-; LA32-LABEL: fptosi_i32_float: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(__fixsfsi) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fptosi_i32_float: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 +-; LA64-NEXT: bl %plt(__fixsfsi) +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %tmp = fptosi float %X to i32 +- ret i32 %tmp +-} +- +-define i64 @fptosi_i64_fp128(fp128 %X) nounwind { +-; LA32-LABEL: fptosi_i64_fp128: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -32 +-; LA32-NEXT: st.w $ra, $sp, 28 # 4-byte Folded Spill +-; LA32-NEXT: ld.w $a1, $a0, 12 +-; LA32-NEXT: st.w $a1, $sp, 12 +-; LA32-NEXT: ld.w $a1, $a0, 8 +-; LA32-NEXT: st.w $a1, $sp, 8 +-; LA32-NEXT: ld.w $a1, $a0, 4 +-; LA32-NEXT: st.w $a1, $sp, 4 +-; LA32-NEXT: ld.w $a0, $a0, 0 +-; LA32-NEXT: st.w $a0, $sp, 0 +-; LA32-NEXT: addi.w $a0, $sp, 0 +-; LA32-NEXT: bl %plt(__fixtfdi) +-; LA32-NEXT: ld.w $ra, $sp, 28 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 32 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fptosi_i64_fp128: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(__fixtfdi) +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %tmp = fptosi fp128 %X to i64 +- ret i64 %tmp +-} +- +-define i64 @fptosi_i64_double(double %X) nounwind { +-; LA32-LABEL: fptosi_i64_double: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(__fixdfdi) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fptosi_i64_double: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bl %plt(__fixdfdi) +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %tmp = fptosi double %X to i64 +- ret i64 %tmp +-} +- +-define i64 @fptosi_i64_float(float %X) nounwind { +-; LA32-LABEL: fptosi_i64_float: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: bl %plt(__fixsfdi) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: fptosi_i64_float: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 +-; LA64-NEXT: bl %plt(__fixsfdi) +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %tmp = fptosi float %X to i64 +- ret i64 %tmp +-} +diff --git a/llvm/test/CodeGen/LoongArch/spill-ra-without-kill.ll b/llvm/test/CodeGen/LoongArch/spill-ra-without-kill.ll +deleted file mode 100644 +index 092da5aba..000000000 +--- a/llvm/test/CodeGen/LoongArch/spill-ra-without-kill.ll ++++ /dev/null +@@ -1,102 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc -O0 --mtriple=loongarch64 --verify-machineinstrs < %s | FileCheck %s +- +-;; This test case is reduced from pr17377.c of the GCC C Torture Suite using +-;; bugpoint. +- +-@calls = external dso_local global i32, align 4 +-declare ptr @llvm.returnaddress(i32 immarg) +- +-define dso_local ptr @f(i32 noundef signext %i) "frame-pointer"="all" { +-; CHECK-LABEL: f: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: addi.d $sp, $sp, -48 +-; CHECK-NEXT: .cfi_def_cfa_offset 48 +-; CHECK-NEXT: st.d $ra, $sp, 40 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $fp, $sp, 32 # 8-byte Folded Spill +-; CHECK-NEXT: .cfi_offset 1, -8 +-; CHECK-NEXT: .cfi_offset 22, -16 +-; CHECK-NEXT: addi.d $fp, $sp, 48 +-; CHECK-NEXT: .cfi_def_cfa 22, 0 +-; CHECK-NEXT: st.d $ra, $fp, -40 # 8-byte Folded Spill +-; CHECK-NEXT: move $a1, $a0 +-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(calls) +-; CHECK-NEXT: addi.d $a3, $a0, %pc_lo12(calls) +-; CHECK-NEXT: ld.w $a0, $a3, 0 +-; CHECK-NEXT: addi.d $a2, $a0, 1 +-; CHECK-NEXT: st.w $a2, $a3, 0 +-; CHECK-NEXT: st.w $a1, $fp, -28 +-; CHECK-NEXT: bnez $a0, .LBB0_2 +-; CHECK-NEXT: b .LBB0_1 +-; CHECK-NEXT: .LBB0_1: # %if.then +-; CHECK-NEXT: ld.d $a0, $fp, -40 # 8-byte Folded Reload +-; CHECK-NEXT: st.d $a0, $fp, -24 +-; CHECK-NEXT: b .LBB0_7 +-; CHECK-NEXT: .LBB0_2: # %if.end +-; CHECK-NEXT: ld.w $a0, $fp, -28 +-; CHECK-NEXT: st.d $a0, $fp, -48 # 8-byte Folded Spill +-; CHECK-NEXT: beqz $a0, .LBB0_5 +-; CHECK-NEXT: b .LBB0_3 +-; CHECK-NEXT: .LBB0_3: # %if.end +-; CHECK-NEXT: ld.d $a0, $fp, -48 # 8-byte Folded Reload +-; CHECK-NEXT: ori $a1, $zero, 1 +-; CHECK-NEXT: bne $a0, $a1, .LBB0_6 +-; CHECK-NEXT: b .LBB0_4 +-; CHECK-NEXT: .LBB0_4: # %sw.bb +-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(f) +-; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(f) +-; CHECK-NEXT: st.d $a0, $fp, -24 +-; CHECK-NEXT: b .LBB0_7 +-; CHECK-NEXT: .LBB0_5: # %sw.bb1 +-; CHECK-NEXT: ld.d $a0, $fp, -40 # 8-byte Folded Reload +-; CHECK-NEXT: st.d $a0, $fp, -24 +-; CHECK-NEXT: b .LBB0_7 +-; CHECK-NEXT: .LBB0_6: # %sw.epilog +-; CHECK-NEXT: move $a0, $zero +-; CHECK-NEXT: st.d $a0, $fp, -24 +-; CHECK-NEXT: b .LBB0_7 +-; CHECK-NEXT: .LBB0_7: # %return +-; CHECK-NEXT: ld.d $a0, $fp, -24 +-; CHECK-NEXT: ld.d $fp, $sp, 32 # 8-byte Folded Reload +-; CHECK-NEXT: ld.d $ra, $sp, 40 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 48 +-; CHECK-NEXT: ret +-entry: +- %retval = alloca ptr, align 8 +- %i.addr = alloca i32, align 4 +- store i32 %i, ptr %i.addr, align 4 +- %0 = load i32, ptr @calls, align 4 +- %inc = add nsw i32 %0, 1 +- store i32 %inc, ptr @calls, align 4 +- %cmp = icmp eq i32 %0, 0 +- br i1 %cmp, label %if.then, label %if.end +- +-if.then: +- %1 = call ptr @llvm.returnaddress(i32 0) +- store ptr %1, ptr %retval, align 8 +- br label %return +- +-if.end: +- %2 = load i32, ptr %i.addr, align 4 +- switch i32 %2, label %sw.epilog [ +- i32 1, label %sw.bb +- i32 0, label %sw.bb1 +- ] +- +-sw.bb: +- store ptr @f, ptr %retval, align 8 +- br label %return +- +-sw.bb1: +- %3 = call ptr @llvm.returnaddress(i32 0) +- store ptr %3, ptr %retval, align 8 +- br label %return +- +-sw.epilog: +- store ptr null, ptr %retval, align 8 +- br label %return +- +-return: +- %4 = load ptr, ptr %retval, align 8 +- ret ptr %4 +-} +diff --git a/llvm/test/CodeGen/LoongArch/spill-reload-cfr.ll b/llvm/test/CodeGen/LoongArch/spill-reload-cfr.ll +deleted file mode 100644 +index 63407ad00..000000000 +--- a/llvm/test/CodeGen/LoongArch/spill-reload-cfr.ll ++++ /dev/null +@@ -1,89 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64 +- +-;; Check the $fcc* register is spilled before funtion call and then reloaded. +-declare void @foo() +- +-define i1 @load_store_fcc_reg(float %a, i1 %c) { +-; LA32-LABEL: load_store_fcc_reg: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -32 +-; LA32-NEXT: .cfi_def_cfa_offset 32 +-; LA32-NEXT: st.w $ra, $sp, 28 # 4-byte Folded Spill +-; LA32-NEXT: st.w $fp, $sp, 24 # 4-byte Folded Spill +-; LA32-NEXT: fst.d $fs0, $sp, 16 # 8-byte Folded Spill +-; LA32-NEXT: fst.d $fs1, $sp, 8 # 8-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: .cfi_offset 22, -8 +-; LA32-NEXT: .cfi_offset 56, -16 +-; LA32-NEXT: .cfi_offset 57, -24 +-; LA32-NEXT: move $fp, $a0 +-; LA32-NEXT: fmov.s $fs0, $fa0 +-; LA32-NEXT: movgr2fr.w $fs1, $zero +-; LA32-NEXT: fcmp.cult.s $fcc0, $fs1, $fa0 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: st.w $a0, $sp, 4 +-; LA32-NEXT: bl %plt(foo) +-; LA32-NEXT: ld.w $a0, $sp, 4 +-; LA32-NEXT: movgr2cf $fcc0, $a0 +-; LA32-NEXT: bcnez $fcc0, .LBB0_2 +-; LA32-NEXT: # %bb.1: # %if.then +-; LA32-NEXT: move $a0, $fp +-; LA32-NEXT: b .LBB0_3 +-; LA32-NEXT: .LBB0_2: # %if.else +-; LA32-NEXT: fcmp.cle.s $fcc0, $fs0, $fs1 +-; LA32-NEXT: movcf2gr $a0, $fcc0 +-; LA32-NEXT: .LBB0_3: # %if.then +-; LA32-NEXT: fld.d $fs1, $sp, 8 # 8-byte Folded Reload +-; LA32-NEXT: fld.d $fs0, $sp, 16 # 8-byte Folded Reload +-; LA32-NEXT: ld.w $fp, $sp, 24 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $ra, $sp, 28 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 32 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: load_store_fcc_reg: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -48 +-; LA64-NEXT: .cfi_def_cfa_offset 48 +-; LA64-NEXT: st.d $ra, $sp, 40 # 8-byte Folded Spill +-; LA64-NEXT: st.d $fp, $sp, 32 # 8-byte Folded Spill +-; LA64-NEXT: fst.d $fs0, $sp, 24 # 8-byte Folded Spill +-; LA64-NEXT: fst.d $fs1, $sp, 16 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: .cfi_offset 22, -16 +-; LA64-NEXT: .cfi_offset 56, -24 +-; LA64-NEXT: .cfi_offset 57, -32 +-; LA64-NEXT: move $fp, $a0 +-; LA64-NEXT: fmov.s $fs0, $fa0 +-; LA64-NEXT: movgr2fr.w $fs1, $zero +-; LA64-NEXT: fcmp.cult.s $fcc0, $fs1, $fa0 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: st.d $a0, $sp, 8 +-; LA64-NEXT: bl %plt(foo) +-; LA64-NEXT: ld.d $a0, $sp, 8 +-; LA64-NEXT: movgr2cf $fcc0, $a0 +-; LA64-NEXT: bcnez $fcc0, .LBB0_2 +-; LA64-NEXT: # %bb.1: # %if.then +-; LA64-NEXT: move $a0, $fp +-; LA64-NEXT: b .LBB0_3 +-; LA64-NEXT: .LBB0_2: # %if.else +-; LA64-NEXT: fcmp.cle.s $fcc0, $fs0, $fs1 +-; LA64-NEXT: movcf2gr $a0, $fcc0 +-; LA64-NEXT: .LBB0_3: # %if.then +-; LA64-NEXT: fld.d $fs1, $sp, 16 # 8-byte Folded Reload +-; LA64-NEXT: fld.d $fs0, $sp, 24 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $fp, $sp, 32 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $ra, $sp, 40 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 48 +-; LA64-NEXT: ret +- %cmp = fcmp ole float %a, 0.000000e+00 +- call void @foo() +- br i1 %cmp, label %if.then, label %if.else +- +-if.then: +- ret i1 %c +- +-if.else: +- ret i1 %cmp +-} +diff --git a/llvm/test/CodeGen/LoongArch/split-sp-adjust.ll b/llvm/test/CodeGen/LoongArch/split-sp-adjust.ll +deleted file mode 100644 +index 821733663..000000000 +--- a/llvm/test/CodeGen/LoongArch/split-sp-adjust.ll ++++ /dev/null +@@ -1,46 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s \ +-; RUN: | FileCheck %s +- +-;; The stack size is 2048 and the SP adjustment will be split. +-define i32 @SplitSP() nounwind { +-; CHECK-LABEL: SplitSP: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: addi.d $sp, $sp, -2032 +-; CHECK-NEXT: st.d $ra, $sp, 2024 # 8-byte Folded Spill +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: addi.d $a0, $sp, 12 +-; CHECK-NEXT: bl %plt(foo) +-; CHECK-NEXT: move $a0, $zero +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ld.d $ra, $sp, 2024 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 2032 +-; CHECK-NEXT: ret +-entry: +- %xx = alloca [2028 x i8], align 1 +- %0 = getelementptr inbounds [2028 x i8], ptr %xx, i32 0, i32 0 +- %call = call i32 @foo(ptr nonnull %0) +- ret i32 0 +-} +- +-;; The stack size is 2032 and the SP adjustment will not be split. +-;; 2016 + 8(RA) + 8(emergency spill slot) = 2032 +-define i32 @NoSplitSP() nounwind { +-; CHECK-LABEL: NoSplitSP: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: addi.d $sp, $sp, -2032 +-; CHECK-NEXT: st.d $ra, $sp, 2024 # 8-byte Folded Spill +-; CHECK-NEXT: addi.d $a0, $sp, 8 +-; CHECK-NEXT: bl %plt(foo) +-; CHECK-NEXT: move $a0, $zero +-; CHECK-NEXT: ld.d $ra, $sp, 2024 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 2032 +-; CHECK-NEXT: ret +-entry: +- %xx = alloca [2016 x i8], align 1 +- %0 = getelementptr inbounds [2024 x i8], ptr %xx, i32 0, i32 0 +- %call = call i32 @foo(ptr nonnull %0) +- ret i32 0 +-} +- +-declare i32 @foo(ptr) +diff --git a/llvm/test/CodeGen/LoongArch/stack-realignment-with-variable-sized-objects.ll b/llvm/test/CodeGen/LoongArch/stack-realignment-with-variable-sized-objects.ll +deleted file mode 100644 +index 497ac065a..000000000 +--- a/llvm/test/CodeGen/LoongArch/stack-realignment-with-variable-sized-objects.ll ++++ /dev/null +@@ -1,69 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --verify-machineinstrs < %s \ +-; RUN: | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s \ +-; RUN: | FileCheck %s --check-prefix=LA64 +- +-declare void @callee(ptr, ptr) +- +-define void @caller(i32 %n) { +-; LA32-LABEL: caller: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -64 +-; LA32-NEXT: .cfi_def_cfa_offset 64 +-; LA32-NEXT: st.w $ra, $sp, 60 # 4-byte Folded Spill +-; LA32-NEXT: st.w $fp, $sp, 56 # 4-byte Folded Spill +-; LA32-NEXT: st.w $s8, $sp, 52 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: .cfi_offset 22, -8 +-; LA32-NEXT: .cfi_offset 31, -12 +-; LA32-NEXT: addi.w $fp, $sp, 64 +-; LA32-NEXT: .cfi_def_cfa 22, 0 +-; LA32-NEXT: bstrins.w $sp, $zero, 5, 0 +-; LA32-NEXT: move $s8, $sp +-; LA32-NEXT: addi.w $a0, $a0, 15 +-; LA32-NEXT: bstrins.w $a0, $zero, 3, 0 +-; LA32-NEXT: sub.w $a0, $sp, $a0 +-; LA32-NEXT: move $sp, $a0 +-; LA32-NEXT: addi.w $a1, $s8, 0 +-; LA32-NEXT: bl %plt(callee) +-; LA32-NEXT: addi.w $sp, $fp, -64 +-; LA32-NEXT: ld.w $s8, $sp, 52 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $fp, $sp, 56 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $ra, $sp, 60 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 64 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: caller: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -64 +-; LA64-NEXT: .cfi_def_cfa_offset 64 +-; LA64-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill +-; LA64-NEXT: st.d $fp, $sp, 48 # 8-byte Folded Spill +-; LA64-NEXT: st.d $s8, $sp, 40 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: .cfi_offset 22, -16 +-; LA64-NEXT: .cfi_offset 31, -24 +-; LA64-NEXT: addi.d $fp, $sp, 64 +-; LA64-NEXT: .cfi_def_cfa 22, 0 +-; LA64-NEXT: bstrins.d $sp, $zero, 5, 0 +-; LA64-NEXT: move $s8, $sp +-; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 +-; LA64-NEXT: addi.d $a0, $a0, 15 +-; LA64-NEXT: bstrpick.d $a0, $a0, 32, 4 +-; LA64-NEXT: slli.d $a0, $a0, 4 +-; LA64-NEXT: sub.d $a0, $sp, $a0 +-; LA64-NEXT: move $sp, $a0 +-; LA64-NEXT: addi.d $a1, $s8, 0 +-; LA64-NEXT: bl %plt(callee) +-; LA64-NEXT: addi.d $sp, $fp, -64 +-; LA64-NEXT: ld.d $s8, $sp, 40 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $fp, $sp, 48 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 64 +-; LA64-NEXT: ret +- %1 = alloca i8, i32 %n +- %2 = alloca i32, align 64 +- call void @callee(ptr %1, ptr %2) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/stack-realignment.ll b/llvm/test/CodeGen/LoongArch/stack-realignment.ll +deleted file mode 100644 +index ac1397a93..000000000 +--- a/llvm/test/CodeGen/LoongArch/stack-realignment.ll ++++ /dev/null +@@ -1,615 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --verify-machineinstrs < %s \ +-; RUN: | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s \ +-; RUN: | FileCheck %s --check-prefix=LA64 +- +-declare void @callee(ptr) +- +-define void @caller32() { +-; LA32-LABEL: caller32: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -32 +-; LA32-NEXT: .cfi_def_cfa_offset 32 +-; LA32-NEXT: st.w $ra, $sp, 28 # 4-byte Folded Spill +-; LA32-NEXT: st.w $fp, $sp, 24 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: .cfi_offset 22, -8 +-; LA32-NEXT: addi.w $fp, $sp, 32 +-; LA32-NEXT: .cfi_def_cfa 22, 0 +-; LA32-NEXT: bstrins.w $sp, $zero, 4, 0 +-; LA32-NEXT: addi.w $a0, $sp, 0 +-; LA32-NEXT: bl %plt(callee) +-; LA32-NEXT: addi.w $sp, $fp, -32 +-; LA32-NEXT: ld.w $fp, $sp, 24 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $ra, $sp, 28 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 32 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: caller32: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -32 +-; LA64-NEXT: .cfi_def_cfa_offset 32 +-; LA64-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill +-; LA64-NEXT: st.d $fp, $sp, 16 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: .cfi_offset 22, -16 +-; LA64-NEXT: addi.d $fp, $sp, 32 +-; LA64-NEXT: .cfi_def_cfa 22, 0 +-; LA64-NEXT: bstrins.d $sp, $zero, 4, 0 +-; LA64-NEXT: addi.d $a0, $sp, 0 +-; LA64-NEXT: bl %plt(callee) +-; LA64-NEXT: addi.d $sp, $fp, -32 +-; LA64-NEXT: ld.d $fp, $sp, 16 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 32 +-; LA64-NEXT: ret +- %1 = alloca i8, align 32 +- call void @callee(ptr %1) +- ret void +-} +- +-define void @caller_no_realign32() "no-realign-stack" { +-; LA32-LABEL: caller_no_realign32: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: addi.w $a0, $sp, 0 +-; LA32-NEXT: bl %plt(callee) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: caller_no_realign32: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: .cfi_def_cfa_offset 16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: addi.d $a0, $sp, 0 +-; LA64-NEXT: bl %plt(callee) +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %1 = alloca i8, align 32 +- call void @callee(ptr %1) +- ret void +-} +- +-define void @caller64() { +-; LA32-LABEL: caller64: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -64 +-; LA32-NEXT: .cfi_def_cfa_offset 64 +-; LA32-NEXT: st.w $ra, $sp, 60 # 4-byte Folded Spill +-; LA32-NEXT: st.w $fp, $sp, 56 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: .cfi_offset 22, -8 +-; LA32-NEXT: addi.w $fp, $sp, 64 +-; LA32-NEXT: .cfi_def_cfa 22, 0 +-; LA32-NEXT: bstrins.w $sp, $zero, 5, 0 +-; LA32-NEXT: addi.w $a0, $sp, 0 +-; LA32-NEXT: bl %plt(callee) +-; LA32-NEXT: addi.w $sp, $fp, -64 +-; LA32-NEXT: ld.w $fp, $sp, 56 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $ra, $sp, 60 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 64 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: caller64: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -64 +-; LA64-NEXT: .cfi_def_cfa_offset 64 +-; LA64-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill +-; LA64-NEXT: st.d $fp, $sp, 48 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: .cfi_offset 22, -16 +-; LA64-NEXT: addi.d $fp, $sp, 64 +-; LA64-NEXT: .cfi_def_cfa 22, 0 +-; LA64-NEXT: bstrins.d $sp, $zero, 5, 0 +-; LA64-NEXT: addi.d $a0, $sp, 0 +-; LA64-NEXT: bl %plt(callee) +-; LA64-NEXT: addi.d $sp, $fp, -64 +-; LA64-NEXT: ld.d $fp, $sp, 48 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 64 +-; LA64-NEXT: ret +- %1 = alloca i8, align 64 +- call void @callee(ptr %1) +- ret void +-} +- +-define void @caller_no_realign64() "no-realign-stack" { +-; LA32-LABEL: caller_no_realign64: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: addi.w $a0, $sp, 0 +-; LA32-NEXT: bl %plt(callee) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: caller_no_realign64: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: .cfi_def_cfa_offset 16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: addi.d $a0, $sp, 0 +-; LA64-NEXT: bl %plt(callee) +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %1 = alloca i8, align 64 +- call void @callee(ptr %1) +- ret void +-} +- +-define void @caller128() { +-; LA32-LABEL: caller128: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -128 +-; LA32-NEXT: .cfi_def_cfa_offset 128 +-; LA32-NEXT: st.w $ra, $sp, 124 # 4-byte Folded Spill +-; LA32-NEXT: st.w $fp, $sp, 120 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: .cfi_offset 22, -8 +-; LA32-NEXT: addi.w $fp, $sp, 128 +-; LA32-NEXT: .cfi_def_cfa 22, 0 +-; LA32-NEXT: bstrins.w $sp, $zero, 6, 0 +-; LA32-NEXT: addi.w $a0, $sp, 0 +-; LA32-NEXT: bl %plt(callee) +-; LA32-NEXT: addi.w $sp, $fp, -128 +-; LA32-NEXT: ld.w $fp, $sp, 120 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $ra, $sp, 124 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 128 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: caller128: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -128 +-; LA64-NEXT: .cfi_def_cfa_offset 128 +-; LA64-NEXT: st.d $ra, $sp, 120 # 8-byte Folded Spill +-; LA64-NEXT: st.d $fp, $sp, 112 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: .cfi_offset 22, -16 +-; LA64-NEXT: addi.d $fp, $sp, 128 +-; LA64-NEXT: .cfi_def_cfa 22, 0 +-; LA64-NEXT: bstrins.d $sp, $zero, 6, 0 +-; LA64-NEXT: addi.d $a0, $sp, 0 +-; LA64-NEXT: bl %plt(callee) +-; LA64-NEXT: addi.d $sp, $fp, -128 +-; LA64-NEXT: ld.d $fp, $sp, 112 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $ra, $sp, 120 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 128 +-; LA64-NEXT: ret +- %1 = alloca i8, align 128 +- call void @callee(ptr %1) +- ret void +-} +- +-define void @caller_no_realign128() "no-realign-stack" { +-; LA32-LABEL: caller_no_realign128: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: addi.w $a0, $sp, 0 +-; LA32-NEXT: bl %plt(callee) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: caller_no_realign128: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: .cfi_def_cfa_offset 16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: addi.d $a0, $sp, 0 +-; LA64-NEXT: bl %plt(callee) +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %1 = alloca i8, align 128 +- call void @callee(ptr %1) +- ret void +-} +- +-define void @caller256() { +-; LA32-LABEL: caller256: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -256 +-; LA32-NEXT: .cfi_def_cfa_offset 256 +-; LA32-NEXT: st.w $ra, $sp, 252 # 4-byte Folded Spill +-; LA32-NEXT: st.w $fp, $sp, 248 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: .cfi_offset 22, -8 +-; LA32-NEXT: addi.w $fp, $sp, 256 +-; LA32-NEXT: .cfi_def_cfa 22, 0 +-; LA32-NEXT: bstrins.w $sp, $zero, 7, 0 +-; LA32-NEXT: addi.w $a0, $sp, 0 +-; LA32-NEXT: bl %plt(callee) +-; LA32-NEXT: addi.w $sp, $fp, -256 +-; LA32-NEXT: ld.w $fp, $sp, 248 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $ra, $sp, 252 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 256 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: caller256: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -256 +-; LA64-NEXT: .cfi_def_cfa_offset 256 +-; LA64-NEXT: st.d $ra, $sp, 248 # 8-byte Folded Spill +-; LA64-NEXT: st.d $fp, $sp, 240 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: .cfi_offset 22, -16 +-; LA64-NEXT: addi.d $fp, $sp, 256 +-; LA64-NEXT: .cfi_def_cfa 22, 0 +-; LA64-NEXT: bstrins.d $sp, $zero, 7, 0 +-; LA64-NEXT: addi.d $a0, $sp, 0 +-; LA64-NEXT: bl %plt(callee) +-; LA64-NEXT: addi.d $sp, $fp, -256 +-; LA64-NEXT: ld.d $fp, $sp, 240 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $ra, $sp, 248 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 256 +-; LA64-NEXT: ret +- %1 = alloca i8, align 256 +- call void @callee(ptr %1) +- ret void +-} +- +-define void @caller_no_realign256() "no-realign-stack" { +-; LA32-LABEL: caller_no_realign256: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: addi.w $a0, $sp, 0 +-; LA32-NEXT: bl %plt(callee) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: caller_no_realign256: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: .cfi_def_cfa_offset 16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: addi.d $a0, $sp, 0 +-; LA64-NEXT: bl %plt(callee) +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %1 = alloca i8, align 256 +- call void @callee(ptr %1) +- ret void +-} +- +-define void @caller512() { +-; LA32-LABEL: caller512: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -1024 +-; LA32-NEXT: .cfi_def_cfa_offset 1024 +-; LA32-NEXT: st.w $ra, $sp, 1020 # 4-byte Folded Spill +-; LA32-NEXT: st.w $fp, $sp, 1016 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: .cfi_offset 22, -8 +-; LA32-NEXT: addi.w $fp, $sp, 1024 +-; LA32-NEXT: .cfi_def_cfa 22, 0 +-; LA32-NEXT: bstrins.w $sp, $zero, 8, 0 +-; LA32-NEXT: addi.w $a0, $sp, 512 +-; LA32-NEXT: bl %plt(callee) +-; LA32-NEXT: addi.w $sp, $fp, -1024 +-; LA32-NEXT: ld.w $fp, $sp, 1016 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $ra, $sp, 1020 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 1024 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: caller512: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -1024 +-; LA64-NEXT: .cfi_def_cfa_offset 1024 +-; LA64-NEXT: st.d $ra, $sp, 1016 # 8-byte Folded Spill +-; LA64-NEXT: st.d $fp, $sp, 1008 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: .cfi_offset 22, -16 +-; LA64-NEXT: addi.d $fp, $sp, 1024 +-; LA64-NEXT: .cfi_def_cfa 22, 0 +-; LA64-NEXT: bstrins.d $sp, $zero, 8, 0 +-; LA64-NEXT: addi.d $a0, $sp, 512 +-; LA64-NEXT: bl %plt(callee) +-; LA64-NEXT: addi.d $sp, $fp, -1024 +-; LA64-NEXT: ld.d $fp, $sp, 1008 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $ra, $sp, 1016 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 1024 +-; LA64-NEXT: ret +- %1 = alloca i8, align 512 +- call void @callee(ptr %1) +- ret void +-} +- +-define void @caller_no_realign512() "no-realign-stack" { +-; LA32-LABEL: caller_no_realign512: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: addi.w $a0, $sp, 0 +-; LA32-NEXT: bl %plt(callee) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: caller_no_realign512: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: .cfi_def_cfa_offset 16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: addi.d $a0, $sp, 0 +-; LA64-NEXT: bl %plt(callee) +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %1 = alloca i8, align 512 +- call void @callee(ptr %1) +- ret void +-} +- +-define void @caller1024() { +-; LA32-LABEL: caller1024: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -2032 +-; LA32-NEXT: .cfi_def_cfa_offset 2032 +-; LA32-NEXT: st.w $ra, $sp, 2028 # 4-byte Folded Spill +-; LA32-NEXT: st.w $fp, $sp, 2024 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: .cfi_offset 22, -8 +-; LA32-NEXT: addi.w $fp, $sp, 2032 +-; LA32-NEXT: .cfi_def_cfa 22, 0 +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: bstrins.w $sp, $zero, 9, 0 +-; LA32-NEXT: addi.w $a0, $sp, 1024 +-; LA32-NEXT: bl %plt(callee) +-; LA32-NEXT: addi.w $sp, $fp, -2048 +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ld.w $fp, $sp, 2024 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $ra, $sp, 2028 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 2032 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: caller1024: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -2032 +-; LA64-NEXT: .cfi_def_cfa_offset 2032 +-; LA64-NEXT: st.d $ra, $sp, 2024 # 8-byte Folded Spill +-; LA64-NEXT: st.d $fp, $sp, 2016 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: .cfi_offset 22, -16 +-; LA64-NEXT: addi.d $fp, $sp, 2032 +-; LA64-NEXT: .cfi_def_cfa 22, 0 +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: bstrins.d $sp, $zero, 9, 0 +-; LA64-NEXT: addi.d $a0, $sp, 1024 +-; LA64-NEXT: bl %plt(callee) +-; LA64-NEXT: addi.d $sp, $fp, -2048 +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ld.d $fp, $sp, 2016 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $ra, $sp, 2024 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 2032 +-; LA64-NEXT: ret +- %1 = alloca i8, align 1024 +- call void @callee(ptr %1) +- ret void +-} +- +-define void @caller_no_realign1024() "no-realign-stack" { +-; LA32-LABEL: caller_no_realign1024: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: addi.w $a0, $sp, 0 +-; LA32-NEXT: bl %plt(callee) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: caller_no_realign1024: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: .cfi_def_cfa_offset 16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: addi.d $a0, $sp, 0 +-; LA64-NEXT: bl %plt(callee) +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %1 = alloca i8, align 1024 +- call void @callee(ptr %1) +- ret void +-} +- +-define void @caller2048() { +-; LA32-LABEL: caller2048: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -2032 +-; LA32-NEXT: .cfi_def_cfa_offset 2032 +-; LA32-NEXT: st.w $ra, $sp, 2028 # 4-byte Folded Spill +-; LA32-NEXT: st.w $fp, $sp, 2024 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: .cfi_offset 22, -8 +-; LA32-NEXT: addi.w $fp, $sp, 2032 +-; LA32-NEXT: .cfi_def_cfa 22, 0 +-; LA32-NEXT: addi.w $sp, $sp, -2048 +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: bstrins.w $sp, $zero, 10, 0 +-; LA32-NEXT: ori $a0, $zero, 2048 +-; LA32-NEXT: add.w $a0, $sp, $a0 +-; LA32-NEXT: bl %plt(callee) +-; LA32-NEXT: lu12i.w $a0, 1 +-; LA32-NEXT: sub.w $sp, $fp, $a0 +-; LA32-NEXT: addi.w $sp, $sp, 2032 +-; LA32-NEXT: addi.w $sp, $sp, 32 +-; LA32-NEXT: ld.w $fp, $sp, 2024 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $ra, $sp, 2028 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 2032 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: caller2048: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -2032 +-; LA64-NEXT: .cfi_def_cfa_offset 2032 +-; LA64-NEXT: st.d $ra, $sp, 2024 # 8-byte Folded Spill +-; LA64-NEXT: st.d $fp, $sp, 2016 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: .cfi_offset 22, -16 +-; LA64-NEXT: addi.d $fp, $sp, 2032 +-; LA64-NEXT: .cfi_def_cfa 22, 0 +-; LA64-NEXT: addi.d $sp, $sp, -2048 +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: bstrins.d $sp, $zero, 10, 0 +-; LA64-NEXT: ori $a0, $zero, 2048 +-; LA64-NEXT: add.d $a0, $sp, $a0 +-; LA64-NEXT: bl %plt(callee) +-; LA64-NEXT: lu12i.w $a0, 1 +-; LA64-NEXT: sub.d $sp, $fp, $a0 +-; LA64-NEXT: addi.d $sp, $sp, 2032 +-; LA64-NEXT: addi.d $sp, $sp, 32 +-; LA64-NEXT: ld.d $fp, $sp, 2016 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $ra, $sp, 2024 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 2032 +-; LA64-NEXT: ret +- %1 = alloca i8, align 2048 +- call void @callee(ptr %1) +- ret void +-} +- +-define void @caller_no_realign2048() "no-realign-stack" { +-; LA32-LABEL: caller_no_realign2048: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: addi.w $a0, $sp, 0 +-; LA32-NEXT: bl %plt(callee) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: caller_no_realign2048: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: .cfi_def_cfa_offset 16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: addi.d $a0, $sp, 0 +-; LA64-NEXT: bl %plt(callee) +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %1 = alloca i8, align 2048 +- call void @callee(ptr %1) +- ret void +-} +- +-define void @caller4096() { +-; LA32-LABEL: caller4096: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -2032 +-; LA32-NEXT: .cfi_def_cfa_offset 2032 +-; LA32-NEXT: st.w $ra, $sp, 2028 # 4-byte Folded Spill +-; LA32-NEXT: st.w $fp, $sp, 2024 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: .cfi_offset 22, -8 +-; LA32-NEXT: addi.w $fp, $sp, 2032 +-; LA32-NEXT: .cfi_def_cfa 22, 0 +-; LA32-NEXT: lu12i.w $a0, 1 +-; LA32-NEXT: ori $a0, $a0, 2064 +-; LA32-NEXT: sub.w $sp, $sp, $a0 +-; LA32-NEXT: bstrins.w $sp, $zero, 11, 0 +-; LA32-NEXT: lu12i.w $a0, 1 +-; LA32-NEXT: add.w $a0, $sp, $a0 +-; LA32-NEXT: bl %plt(callee) +-; LA32-NEXT: lu12i.w $a0, 2 +-; LA32-NEXT: sub.w $sp, $fp, $a0 +-; LA32-NEXT: lu12i.w $a0, 1 +-; LA32-NEXT: ori $a0, $a0, 2064 +-; LA32-NEXT: add.w $sp, $sp, $a0 +-; LA32-NEXT: ld.w $fp, $sp, 2024 # 4-byte Folded Reload +-; LA32-NEXT: ld.w $ra, $sp, 2028 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 2032 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: caller4096: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -2032 +-; LA64-NEXT: .cfi_def_cfa_offset 2032 +-; LA64-NEXT: st.d $ra, $sp, 2024 # 8-byte Folded Spill +-; LA64-NEXT: st.d $fp, $sp, 2016 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: .cfi_offset 22, -16 +-; LA64-NEXT: addi.d $fp, $sp, 2032 +-; LA64-NEXT: .cfi_def_cfa 22, 0 +-; LA64-NEXT: lu12i.w $a0, 1 +-; LA64-NEXT: ori $a0, $a0, 2064 +-; LA64-NEXT: sub.d $sp, $sp, $a0 +-; LA64-NEXT: bstrins.d $sp, $zero, 11, 0 +-; LA64-NEXT: lu12i.w $a0, 1 +-; LA64-NEXT: add.d $a0, $sp, $a0 +-; LA64-NEXT: bl %plt(callee) +-; LA64-NEXT: lu12i.w $a0, 2 +-; LA64-NEXT: sub.d $sp, $fp, $a0 +-; LA64-NEXT: lu12i.w $a0, 1 +-; LA64-NEXT: ori $a0, $a0, 2064 +-; LA64-NEXT: add.d $sp, $sp, $a0 +-; LA64-NEXT: ld.d $fp, $sp, 2016 # 8-byte Folded Reload +-; LA64-NEXT: ld.d $ra, $sp, 2024 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 2032 +-; LA64-NEXT: ret +- %1 = alloca i8, align 4096 +- call void @callee(ptr %1) +- ret void +-} +- +-define void @caller_no_realign4096() "no-realign-stack" { +-; LA32-LABEL: caller_no_realign4096: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: addi.w $a0, $sp, 0 +-; LA32-NEXT: bl %plt(callee) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: caller_no_realign4096: +-; LA64: # %bb.0: +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: .cfi_def_cfa_offset 16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: addi.d $a0, $sp, 0 +-; LA64-NEXT: bl %plt(callee) +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +- %1 = alloca i8, align 4096 +- call void @callee(ptr %1) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/stptr.ll b/llvm/test/CodeGen/LoongArch/stptr.ll +index cc198f9c2..0a54e0f8f 100644 +--- a/llvm/test/CodeGen/LoongArch/stptr.ll ++++ b/llvm/test/CodeGen/LoongArch/stptr.ll +@@ -1,112 +1,52 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 ++; Check whether st.w/st.d/stptr.w/stptr.d/stx.w/stx.d instructions are properly generated ++; RUN: llc -march=loongarch64 -o - %s | FileCheck %s + +-;; Check that stptr.w is not emitted for small offsets. +-define void @stptr_w_too_small_offset(ptr %p, i32 signext %val) nounwind { +-; LA32-LABEL: stptr_w_too_small_offset: +-; LA32: # %bb.0: +-; LA32-NEXT: st.w $a1, $a0, 2044 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: stptr_w_too_small_offset: +-; LA64: # %bb.0: +-; LA64-NEXT: st.w $a1, $a0, 2044 +-; LA64-NEXT: ret +- %addr = getelementptr inbounds i32, ptr %p, i64 511 +- store i32 %val, ptr %addr, align 4 ++define void @st_w(i32* %p, i32 signext %val) { ++; CHECK: st.w $r5, $r4, 2044 ++; CHECK: jr $ra ++ %addr = getelementptr inbounds i32, i32* %p, i64 511 ++ store i32 %val, i32* %addr, align 4 + ret void + } + +-;; Check that stptr.w is emitted for applicable offsets. +-define void @stptr_w(ptr %p, i32 signext %val) nounwind { +-; LA32-LABEL: stptr_w: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $a0, 2047 +-; LA32-NEXT: addi.w $a0, $a0, 1 +-; LA32-NEXT: st.w $a1, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: stptr_w: +-; LA64: # %bb.0: +-; LA64-NEXT: stptr.w $a1, $a0, 2048 +-; LA64-NEXT: ret +- %addr = getelementptr inbounds i32, ptr %p, i64 512 +- store i32 %val, ptr %addr, align 4 ++define void @stptr_w(i32* %p, i32 signext %val) { ++; CHECK: stptr.w $r5, $r4, 2048 ++; CHECK: jr $ra ++ %addr = getelementptr inbounds i32, i32* %p, i64 512 ++ store i32 %val, i32* %addr, align 4 + ret void + } + +-;; Check that stptr.w is not emitted for out-of-range offsets. +-define void @stptr_w_too_big_offset(ptr %p, i32 signext %val) nounwind { +-; LA32-LABEL: stptr_w_too_big_offset: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a2, 8 +-; LA32-NEXT: add.w $a0, $a0, $a2 +-; LA32-NEXT: st.w $a1, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: stptr_w_too_big_offset: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 8 +-; LA64-NEXT: stx.w $a1, $a0, $a2 +-; LA64-NEXT: ret +- %addr = getelementptr inbounds i32, ptr %p, i64 8192 +- store i32 %val, ptr %addr, align 4 ++define void @stx_w(i32* %p, i32 signext %val) { ++; CHECK: lu12i.w $r[[REG:[0-9]+]], 8 ++; CHECK: stx.w $r5, $r4, $r[[REG:[0-9]+]] ++; CHECK: jr $ra ++ %addr = getelementptr inbounds i32, i32* %p, i64 8192 ++ store i32 %val, i32* %addr, align 4 + ret void + } + +-;; Check that stptr.d is not emitted for small offsets. +-define void @stptr_d_too_small_offset(ptr %p, i64 %val) nounwind { +-; LA32-LABEL: stptr_d_too_small_offset: +-; LA32: # %bb.0: +-; LA32-NEXT: st.w $a2, $a0, 2044 +-; LA32-NEXT: st.w $a1, $a0, 2040 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: stptr_d_too_small_offset: +-; LA64: # %bb.0: +-; LA64-NEXT: st.d $a1, $a0, 2040 +-; LA64-NEXT: ret +- %addr = getelementptr inbounds i64, ptr %p, i64 255 +- store i64 %val, ptr %addr, align 8 ++define void @st_d(i64* %p, i64 %val) { ++; CHECK: st.d $r5, $r4, 2040 ++; CHECK: jr $ra ++ %addr = getelementptr inbounds i64, i64* %p, i64 255 ++ store i64 %val, i64* %addr, align 8 + ret void + } + +-;; Check that stptr.d is emitted for applicable offsets. +-define void @stptr_d(ptr %p, i64 %val) nounwind { +-; LA32-LABEL: stptr_d: +-; LA32: # %bb.0: +-; LA32-NEXT: addi.w $a0, $a0, 2047 +-; LA32-NEXT: addi.w $a0, $a0, 1 +-; LA32-NEXT: st.w $a2, $a0, 4 +-; LA32-NEXT: st.w $a1, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: stptr_d: +-; LA64: # %bb.0: +-; LA64-NEXT: stptr.d $a1, $a0, 2048 +-; LA64-NEXT: ret +- %addr = getelementptr inbounds i64, ptr %p, i64 256 +- store i64 %val, ptr %addr, align 8 ++define void @stptr_d(i64* %p, i64 %val) { ++; CHECK: stptr.d $r5, $r4, 2048 ++; CHECK: jr $ra ++ %addr = getelementptr inbounds i64, i64* %p, i64 256 ++ store i64 %val, i64* %addr, align 8 + ret void + } + +-;; Check that stptr.d is not emitted for out-of-range offsets. +-define void @stptr_d_too_big_offset(ptr %p, i64 %val) nounwind { +-; LA32-LABEL: stptr_d_too_big_offset: +-; LA32: # %bb.0: +-; LA32-NEXT: lu12i.w $a3, 8 +-; LA32-NEXT: add.w $a0, $a0, $a3 +-; LA32-NEXT: st.w $a2, $a0, 4 +-; LA32-NEXT: st.w $a1, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: stptr_d_too_big_offset: +-; LA64: # %bb.0: +-; LA64-NEXT: lu12i.w $a2, 8 +-; LA64-NEXT: stx.d $a1, $a0, $a2 +-; LA64-NEXT: ret +- %addr = getelementptr inbounds i64, ptr %p, i64 4096 +- store i64 %val, ptr %addr, align 8 ++define void @stx_d(i64* %p, i64 %val) { ++; CHECK: lu12i.w $r[[REG:[0-9]+]], 8 ++; CHECK: stx.d $r5, $r4, $r[[REG:[0-9]+]] ++; CHECK: jr $ra ++ %addr = getelementptr inbounds i64, i64* %p, i64 4096 ++ store i64 %val, i64* %addr, align 8 + ret void + } +diff --git a/llvm/test/CodeGen/LoongArch/tail-calls.ll b/llvm/test/CodeGen/LoongArch/tail-calls.ll +deleted file mode 100644 +index 8f11e0343..000000000 +--- a/llvm/test/CodeGen/LoongArch/tail-calls.ll ++++ /dev/null +@@ -1,188 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s +- +-;; Perform tail call optimization for global address. +-declare i32 @callee_tail(i32 %i) +-define i32 @caller_tail(i32 %i) nounwind { +-; CHECK-LABEL: caller_tail: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: b %plt(callee_tail) +-entry: +- %r = tail call i32 @callee_tail(i32 %i) +- ret i32 %r +-} +- +-;; Perform tail call optimization for external symbol. +-;; Bytes copied should be large enough, otherwise the memcpy call would be optimized to multiple ld/st insns. +-@dest = global [2 x i8] zeroinitializer +-declare void @llvm.memcpy.p0i8.p0i8.i32(ptr, ptr, i32, i1) +-define void @caller_extern(ptr %src) optsize { +-; CHECK-LABEL: caller_extern: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: move $a1, $a0 +-; CHECK-NEXT: pcalau12i $a0, %got_pc_hi20(dest) +-; CHECK-NEXT: ld.d $a0, $a0, %got_pc_lo12(dest) +-; CHECK-NEXT: ori $a2, $zero, 33 +-; CHECK-NEXT: b %plt(memcpy) +-entry: +- tail call void @llvm.memcpy.p0i8.p0i8.i32(ptr getelementptr inbounds ([2 x i8], ptr @dest, i32 0, i32 0), ptr %src, i32 33, i1 false) +- ret void +-} +- +-;; Perform indirect tail call optimization (for function pointer call). +-declare void @callee_indirect1() +-declare void @callee_indirect2() +-define void @caller_indirect_tail(i32 %a) nounwind { +-; CHECK-LABEL: caller_indirect_tail: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: addi.w $a0, $a0, 0 +-; CHECK-NEXT: sltui $a0, $a0, 1 +-; CHECK-NEXT: pcalau12i $a1, %got_pc_hi20(callee_indirect2) +-; CHECK-NEXT: ld.d $a1, $a1, %got_pc_lo12(callee_indirect2) +-; CHECK-NEXT: masknez $a1, $a1, $a0 +-; CHECK-NEXT: pcalau12i $a2, %got_pc_hi20(callee_indirect1) +-; CHECK-NEXT: ld.d $a2, $a2, %got_pc_lo12(callee_indirect1) +-; CHECK-NEXT: maskeqz $a0, $a2, $a0 +-; CHECK-NEXT: or $a0, $a0, $a1 +-; CHECK-NEXT: jr $a0 +-entry: +- %tobool = icmp eq i32 %a, 0 +- %callee = select i1 %tobool, ptr @callee_indirect1, ptr @callee_indirect2 +- tail call void %callee() +- ret void +-} +- +-;; Do not tail call optimize functions with varargs passed by stack. +-declare i32 @callee_varargs(i32, ...) +-define void @caller_varargs(i32 %a, i32 %b) nounwind { +-; CHECK-LABEL: caller_varargs: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $a0, $sp, 0 +-; CHECK-NEXT: move $a2, $a1 +-; CHECK-NEXT: move $a3, $a0 +-; CHECK-NEXT: move $a4, $a0 +-; CHECK-NEXT: move $a5, $a1 +-; CHECK-NEXT: move $a6, $a1 +-; CHECK-NEXT: move $a7, $a0 +-; CHECK-NEXT: bl %plt(callee_varargs) +-; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +-entry: +- %call = tail call i32 (i32, ...) @callee_varargs(i32 %a, i32 %b, i32 %b, i32 %a, i32 %a, i32 %b, i32 %b, i32 %a, i32 %a) +- ret void +-} +- +-;; Do not tail call optimize if stack is used to pass parameters. +-declare i32 @callee_args(i32 %a, i32 %b, i32 %c, i32 %dd, i32 %e, i32 %ff, i32 %g, i32 %h, i32 %i) +-define i32 @caller_args(i32 %a, i32 %b, i32 %c, i32 %dd, i32 %e, i32 %ff, i32 %g, i32 %h, i32 %i) nounwind { +-; CHECK-LABEL: caller_args: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; CHECK-NEXT: ld.d $t0, $sp, 16 +-; CHECK-NEXT: st.d $t0, $sp, 0 +-; CHECK-NEXT: bl %plt(callee_args) +-; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +-entry: +- %r = tail call i32 @callee_args(i32 %a, i32 %b, i32 %c, i32 %dd, i32 %e, i32 %ff, i32 %g, i32 %h, i32 %i) +- ret i32 %r +-} +- +-;; Do not tail call optimize if parameters need to be passed indirectly. +-declare i32 @callee_indirect_args(i256 %a) +-define void @caller_indirect_args() nounwind { +-; CHECK-LABEL: caller_indirect_args: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: addi.d $sp, $sp, -48 +-; CHECK-NEXT: st.d $ra, $sp, 40 # 8-byte Folded Spill +-; CHECK-NEXT: st.d $zero, $sp, 24 +-; CHECK-NEXT: st.d $zero, $sp, 16 +-; CHECK-NEXT: st.d $zero, $sp, 8 +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: st.d $a0, $sp, 0 +-; CHECK-NEXT: addi.d $a0, $sp, 0 +-; CHECK-NEXT: bl %plt(callee_indirect_args) +-; CHECK-NEXT: ld.d $ra, $sp, 40 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 48 +-; CHECK-NEXT: ret +-entry: +- %call = tail call i32 @callee_indirect_args(i256 1) +- ret void +-} +- +-;; Do not tail call optimize if byval parameters need to be passed. +-declare i32 @callee_byval(ptr byval(ptr) %a) +-define i32 @caller_byval() nounwind { +-; CHECK-LABEL: caller_byval: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: addi.d $sp, $sp, -32 +-; CHECK-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill +-; CHECK-NEXT: ld.d $a0, $sp, 16 +-; CHECK-NEXT: st.d $a0, $sp, 8 +-; CHECK-NEXT: addi.d $a0, $sp, 8 +-; CHECK-NEXT: bl %plt(callee_byval) +-; CHECK-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 32 +-; CHECK-NEXT: ret +-entry: +- %a = alloca ptr +- %r = tail call i32 @callee_byval(ptr byval(ptr) %a) +- ret i32 %r +-} +- +-;; Do not tail call optimize if callee uses structret semantics. +-%struct.A = type { i32 } +-@a = global %struct.A zeroinitializer +- +-declare void @callee_struct(ptr sret(%struct.A) %a) +-define void @caller_nostruct() nounwind { +-; CHECK-LABEL: caller_nostruct: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; CHECK-NEXT: pcalau12i $a0, %got_pc_hi20(a) +-; CHECK-NEXT: ld.d $a0, $a0, %got_pc_lo12(a) +-; CHECK-NEXT: bl %plt(callee_struct) +-; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +-entry: +- tail call void @callee_struct(ptr sret(%struct.A) @a) +- ret void +-} +- +-;; Do not tail call optimize if caller uses structret semantics. +-declare void @callee_nostruct() +-define void @caller_struct(ptr sret(%struct.A) %a) nounwind { +-; CHECK-LABEL: caller_struct: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; CHECK-NEXT: bl %plt(callee_nostruct) +-; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +-entry: +- tail call void @callee_nostruct() +- ret void +-} +- +-;; Do not tail call optimize if disabled. +-define i32 @disable_tail_calls(i32 %i) nounwind "disable-tail-calls"="true" { +-; CHECK-LABEL: disable_tail_calls: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: addi.d $sp, $sp, -16 +-; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; CHECK-NEXT: bl %plt(callee_tail) +-; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; CHECK-NEXT: addi.d $sp, $sp, 16 +-; CHECK-NEXT: ret +-entry: +- %rv = tail call i32 @callee_tail(i32 %i) +- ret i32 %rv +-} +diff --git a/llvm/test/CodeGen/LoongArch/tailcall-R.ll b/llvm/test/CodeGen/LoongArch/tailcall-R.ll +new file mode 100644 +index 000000000..2445e32ea +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/tailcall-R.ll +@@ -0,0 +1,62 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -relocation-model=pic < %s | FileCheck %s ++ ++@errors = external local_unnamed_addr global i32, align 4 ++ ++define signext i32 @compare(i8* %x, i8* %y) { ++; CHECK-LABEL: compare: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: addi.d $sp, $sp, -32 ++; CHECK-NEXT: .cfi_def_cfa_offset 32 ++; CHECK-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r23, $sp, 16 # 8-byte Folded Spill ++; CHECK-NEXT: .cfi_offset 1, -8 ++; CHECK-NEXT: .cfi_offset 23, -16 ++; CHECK-NEXT: ld.w $r23, $r5, 0 ++; CHECK-NEXT: ld.d $r6, $r4, 8 ++; CHECK-NEXT: beqz $r23, .LBB0_3 ++; CHECK-NEXT: # %bb.1: # %land.lhs.true ++; CHECK-NEXT: ld.w $r4, $r4, 0 ++; CHECK-NEXT: st.d $r6, $sp, 8 # 8-byte Folded Spill ++; CHECK-NEXT: ld.d $r5, $sp, 8 # 8-byte Folded Reload ++; CHECK-NEXT: jirl $ra, $r5, 0 ++; CHECK-NEXT: ld.d $r6, $sp, 8 # 8-byte Folded Reload ++; CHECK-NEXT: beqz $r4, .LBB0_3 ++; CHECK-NEXT: # %bb.2: # %if.then ++; CHECK-NEXT: la.got $r4, errors ++; CHECK-NEXT: # la expanded slot ++; CHECK-NEXT: ld.w $r5, $r4, 0 ++; CHECK-NEXT: addi.w $r5, $r5, 1 ++; CHECK-NEXT: st.w $r5, $r4, 0 ++; CHECK-NEXT: .LBB0_3: # %if.end ++; CHECK-NEXT: move $r4, $r23 ++; CHECK-NEXT: ld.d $r23, $sp, 16 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 32 ++; CHECK-NEXT: jr $r6 ++entry: ++ %compare = getelementptr inbounds i8, i8* %x, i64 8 ++ %0 = bitcast i8* %compare to i32 (i32)** ++ %1 = load i32 (i32)*, i32 (i32)** %0, align 8 ++ %elt = bitcast i8* %y to i32* ++ %2 = load i32, i32* %elt, align 8 ++ %cmp = icmp eq i32 %2, 0 ++ br i1 %cmp, label %if.end, label %land.lhs.true ++ ++land.lhs.true: ; preds = %entry ++ %elt3 = bitcast i8* %x to i32* ++ %3 = load i32, i32* %elt3, align 8 ++ %call4 = tail call signext i32 %1(i32 signext %3) ++ %cmp5 = icmp eq i32 %call4, 0 ++ br i1 %cmp5, label %if.end, label %if.then ++ ++if.then: ; preds = %land.lhs.true ++ %4 = load i32, i32* @errors, align 4 ++ %inc = add nsw i32 %4, 1 ++ store i32 %inc, i32* @errors, align 4 ++ br label %if.end ++ ++if.end: ; preds = %if.then, %land.lhs.true, %entry ++ %call6 = tail call signext i32 %1(i32 signext %2) ++ ret i32 %call6 ++} +diff --git a/llvm/test/CodeGen/LoongArch/tailcall-check.ll b/llvm/test/CodeGen/LoongArch/tailcall-check.ll +new file mode 100644 +index 000000000..2b5902d69 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/tailcall-check.ll +@@ -0,0 +1,155 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -relocation-model=pic < %s | FileCheck %s ++ ++; Perform tail call optimization for global address. ++declare i32 @callee_tail(i32 %i) ++define i32 @caller_tail(i32 %i) { ++; CHECK-LABEL: caller_tail: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: b callee_tail ++entry: ++ %r = tail call i32 @callee_tail(i32 %i) ++ ret i32 %r ++} ++ ++ ++; Do not tail call optimize functions with varargs. ++declare i32 @callee_varargs(i32, ...) ++define void @caller_varargs(i32 %a, i32 %b) { ++; CHECK-LABEL: caller_varargs: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: addi.d $sp, $sp, -16 ++; CHECK-NEXT: .cfi_def_cfa_offset 16 ++; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill ++; CHECK-NEXT: .cfi_offset 1, -8 ++; CHECK-NEXT: move $r6, $r5 ++; CHECK-NEXT: move $r7, $r4 ++; CHECK-NEXT: bl callee_varargs ++; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 16 ++; CHECK-NEXT: jr $ra ++entry: ++ %call = tail call i32 (i32, ...) @callee_varargs(i32 %a, i32 %b, i32 %b, i32 %a) ++ ret void ++} ++ ++ ++; Do not tail call optimize if stack is used to pass parameters. ++declare i32 @callee_args(i32 %a, i32 %b, i32 %c, i32 %dd, i32 %e, i32 %ff, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n) ++define i32 @caller_args(i32 %a, i32 %b, i32 %c, i32 %dd, i32 %e, i32 %ff, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n) { ++; CHECK-LABEL: caller_args: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: addi.d $sp, $sp, -64 ++; CHECK-NEXT: .cfi_def_cfa_offset 64 ++; CHECK-NEXT: st.d $ra, $sp, 56 # 8-byte Folded Spill ++; CHECK-NEXT: .cfi_offset 1, -8 ++; CHECK-NEXT: ld.d $r12, $sp, 64 ++; CHECK-NEXT: ld.d $r13, $sp, 72 ++; CHECK-NEXT: ld.d $r14, $sp, 80 ++; CHECK-NEXT: ld.d $r15, $sp, 88 ++; CHECK-NEXT: ld.d $r16, $sp, 96 ++; CHECK-NEXT: ld.d $r17, $sp, 104 ++; CHECK-NEXT: st.d $r17, $sp, 40 ++; CHECK-NEXT: st.d $r16, $sp, 32 ++; CHECK-NEXT: st.d $r15, $sp, 24 ++; CHECK-NEXT: st.d $r14, $sp, 16 ++; CHECK-NEXT: st.d $r13, $sp, 8 ++; CHECK-NEXT: st.d $r12, $sp, 0 ++; CHECK-NEXT: bl callee_args ++; CHECK-NEXT: ld.d $ra, $sp, 56 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 64 ++; CHECK-NEXT: jr $ra ++entry: ++ %r = tail call i32 @callee_args(i32 %a, i32 %b, i32 %c, i32 %dd, i32 %e, i32 %ff, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n) ++ ret i32 %r ++} ++ ++ ++; Do not tail call optimize for exception-handling functions. ++declare void @callee_interrupt() ++define void @caller_interrupt() #0 { ++; CHECK-LABEL: caller_interrupt: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: addi.d $sp, $sp, -16 ++; CHECK-NEXT: .cfi_def_cfa_offset 16 ++; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill ++; CHECK-NEXT: .cfi_offset 1, -8 ++; CHECK-NEXT: bl callee_interrupt ++; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 16 ++; CHECK-NEXT: jr $ra ++entry: ++ tail call void @callee_interrupt() ++ ret void ++} ++attributes #0 = { "interrupt"="machine" } ++ ++ ++; Do not tail call optimize functions with byval parameters. ++declare i32 @callee_byval(i32** byval(i32*) %a) ++define i32 @caller_byval() { ++; CHECK-LABEL: caller_byval: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: addi.d $sp, $sp, -32 ++; CHECK-NEXT: .cfi_def_cfa_offset 32 ++; CHECK-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill ++; CHECK-NEXT: .cfi_offset 1, -8 ++; CHECK-NEXT: ld.d $r4, $sp, 16 ++; CHECK-NEXT: st.d $r4, $sp, 0 ++; CHECK-NEXT: bl callee_byval ++; CHECK-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 32 ++; CHECK-NEXT: jr $ra ++entry: ++ %a = alloca i32* ++ %r = tail call i32 @callee_byval(i32** byval(i32*) %a) ++ ret i32 %r ++} ++ ++ ++; Do not tail call optimize if callee uses structret semantics. ++%struct.A = type { i32 } ++@a = global %struct.A zeroinitializer ++ ++declare void @callee_struct(%struct.A* sret(%struct.A) %a) ++define void @caller_nostruct() { ++; CHECK-LABEL: caller_nostruct: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: addi.d $sp, $sp, -16 ++; CHECK-NEXT: .cfi_def_cfa_offset 16 ++; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill ++; CHECK-NEXT: .cfi_offset 1, -8 ++; CHECK-NEXT: la.got $r4, a ++; CHECK-NEXT: # la expanded slot ++; CHECK-NEXT: bl callee_struct ++; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 16 ++; CHECK-NEXT: jr $ra ++entry: ++ tail call void @callee_struct(%struct.A* sret(%struct.A) @a) ++ ret void ++} ++ ++ ++; Do not tail call optimize if caller uses structret semantics. ++declare void @callee_nostruct() ++define void @caller_struct(%struct.A* sret(%struct.A) %a) { ++; CHECK-LABEL: caller_struct: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: addi.d $sp, $sp, -16 ++; CHECK-NEXT: .cfi_def_cfa_offset 16 ++; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill ++; CHECK-NEXT: st.d $r23, $sp, 0 # 8-byte Folded Spill ++; CHECK-NEXT: .cfi_offset 1, -8 ++; CHECK-NEXT: .cfi_offset 23, -16 ++; CHECK-NEXT: move $r23, $r4 ++; CHECK-NEXT: bl callee_nostruct ++; CHECK-NEXT: move $r4, $r23 ++; CHECK-NEXT: ld.d $r23, $sp, 0 # 8-byte Folded Reload ++; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ++; CHECK-NEXT: addi.d $sp, $sp, 16 ++; CHECK-NEXT: jr $ra ++entry: ++ tail call void @callee_nostruct() ++ ret void ++} +diff --git a/llvm/test/CodeGen/LoongArch/tailcall-mem.ll b/llvm/test/CodeGen/LoongArch/tailcall-mem.ll +new file mode 100644 +index 000000000..68ddaa899 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/tailcall-mem.ll +@@ -0,0 +1,35 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -relocation-model=pic < %s | FileCheck %s ++ ++ ++define void @tail_memcpy(i8* %p, i8* %q, i32 %n) { ++; CHECK-LABEL: tail_memcpy: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: b memcpy ++entry: ++ tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %p, i8* %q, i32 %n, i1 false) ++ ret void ++} ++ ++define void @tail_memmove(i8* %p, i8* %q, i32 %n) { ++; CHECK-LABEL: tail_memmove: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: b memmove ++entry: ++ tail call void @llvm.memmove.p0i8.p0i8.i32(i8* %p, i8* %q, i32 %n, i1 false) ++ ret void ++} ++ ++define void @tail_memset(i8* %p, i8 %c, i32 %n) { ++; CHECK-LABEL: tail_memset: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: b memset ++entry: ++ tail call void @llvm.memset.p0i8.i32(i8* %p, i8 %c, i32 %n, i1 false) ++ ret void ++} ++ ++declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i1) ++declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i1) ++declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i1) ++ +diff --git a/llvm/test/CodeGen/LoongArch/tailcall.ll b/llvm/test/CodeGen/LoongArch/tailcall.ll +new file mode 100644 +index 000000000..984df2cb6 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/tailcall.ll +@@ -0,0 +1,13 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -relocation-model=pic < %s | FileCheck %s ++ ++define void @f() { ++; CHECK-LABEL: f: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: b foo ++entry: ++ tail call void bitcast (void (...)* @foo to void ()*)() ++ ret void ++} ++ ++declare void @foo(...) +diff --git a/llvm/test/CodeGen/LoongArch/target-abi-from-triple-edge-cases.ll b/llvm/test/CodeGen/LoongArch/target-abi-from-triple-edge-cases.ll +deleted file mode 100644 +index 1d5ed089c..000000000 +--- a/llvm/test/CodeGen/LoongArch/target-abi-from-triple-edge-cases.ll ++++ /dev/null +@@ -1,74 +0,0 @@ +-;; Check that an unknown --target-abi is ignored and the triple-implied ABI is +-;; used. +-; RUN: llc --mtriple=loongarch32-linux-gnu --target-abi=foo --mattr=+d < %s 2>&1 \ +-; RUN: | FileCheck %s --check-prefixes=ILP32D,UNKNOWN +-; RUN: llc --mtriple=loongarch64-linux-gnu --target-abi=foo --mattr=+d < %s 2>&1 \ +-; RUN: | FileCheck %s --check-prefixes=LP64D,UNKNOWN +- +-; UNKNOWN: 'foo' is not a recognized ABI for this target, ignoring and using triple-implied ABI +- +-;; Check that --target-abi takes precedence over triple-supplied ABI modifiers. +-; RUN: llc --mtriple=loongarch32-linux-gnusf --target-abi=ilp32d --mattr=+d < %s 2>&1 \ +-; RUN: | FileCheck %s --check-prefixes=ILP32D,CONFLICT-ILP32D +-; RUN: llc --mtriple=loongarch64-linux-gnusf --target-abi=lp64d --mattr=+d < %s 2>&1 \ +-; RUN: | FileCheck %s --check-prefixes=LP64D,CONFLICT-LP64D +- +-; CONFLICT-ILP32D: warning: triple-implied ABI conflicts with provided target-abi 'ilp32d', using target-abi +-; CONFLICT-LP64D: warning: triple-implied ABI conflicts with provided target-abi 'lp64d', using target-abi +- +-;; Check that no warning is reported when there is no environment component in +-;; triple-supplied ABI modifiers and --target-abi is used. +-; RUN: llc --mtriple=loongarch64-linux --target-abi=lp64d --mattr=+d < %s 2>&1 \ +-; RUN: | FileCheck %s --check-prefixes=LP64D,NO-WARNING +- +-; NO-WARNING-NOT: warning: triple-implied ABI conflicts with provided target-abi 'lp64d', using target-abi +- +-;; Check that ILP32-on-LA64 and LP64-on-LA32 combinations are handled properly. +-; RUN: llc --mtriple=loongarch64 --target-abi=ilp32d --mattr=+d < %s 2>&1 \ +-; RUN: | FileCheck %s --check-prefixes=LP64D,32ON64 +-; RUN: llc --mtriple=loongarch32 --target-abi=lp64d --mattr=+d < %s 2>&1 \ +-; RUN: | FileCheck %s --check-prefixes=ILP32D,64ON32 +- +-; 32ON64: 32-bit ABIs are not supported for 64-bit targets, ignoring target-abi and using triple-implied ABI +-; 64ON32: 64-bit ABIs are not supported for 32-bit targets, ignoring target-abi and using triple-implied ABI +- +-define float @f(float %a) { +-; ILP32D-LABEL: f: +-; ILP32D: # %bb.0: +-; ILP32D-NEXT: addi.w $a0, $zero, 1 +-; ILP32D-NEXT: movgr2fr.w $fa1, $a0 +-; ILP32D-NEXT: ffint.s.w $fa1, $fa1 +-; ILP32D-NEXT: fadd.s $fa0, $fa0, $fa1 +-; ILP32D-NEXT: ret +-; +-; LP64D-LABEL: f: +-; LP64D: # %bb.0: +-; LP64D-NEXT: addi.w $a0, $zero, 1 +-; LP64D-NEXT: movgr2fr.w $fa1, $a0 +-; LP64D-NEXT: ffint.s.w $fa1, $fa1 +-; LP64D-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LP64D-NEXT: ret +- %1 = fadd float %a, 1.0 +- ret float %1 +-} +- +-define double @g(double %a) { +-; ILP32D-LABEL: g: +-; ILP32D: # %bb.0: +-; ILP32D-NEXT: addi.w $a0, $zero, 1 +-; ILP32D-NEXT: movgr2fr.w $fa1, $a0 +-; ILP32D-NEXT: ffint.s.w $fa1, $fa1 +-; ILP32D-NEXT: fcvt.d.s $fa1, $fa1 +-; ILP32D-NEXT: fadd.d $fa0, $fa0, $fa1 +-; ILP32D-NEXT: ret +-; +-; LP64D-LABEL: g: +-; LP64D: # %bb.0: +-; LP64D-NEXT: addi.d $a0, $zero, 1 +-; LP64D-NEXT: movgr2fr.d $fa1, $a0 +-; LP64D-NEXT: ffint.d.l $fa1, $fa1 +-; LP64D-NEXT: fadd.d $fa0, $fa0, $fa1 +-; LP64D-NEXT: ret +- %1 = fadd double %a, 1.0 +- ret double %1 +-} +diff --git a/llvm/test/CodeGen/LoongArch/target-abi-from-triple.ll b/llvm/test/CodeGen/LoongArch/target-abi-from-triple.ll +deleted file mode 100644 +index 0aca33903..000000000 +--- a/llvm/test/CodeGen/LoongArch/target-abi-from-triple.ll ++++ /dev/null +@@ -1,49 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +- +-;; Check that the correct ABI is chosen based on the triple given. +-;; TODO: enable the S and F ABIs once support is wired up. +-; RUN: llc --mtriple=loongarch32-linux-gnuf64 --mattr=+d < %s \ +-; RUN: | FileCheck %s --check-prefix=ILP32D +-; RUN: llc --mtriple=loongarch64-linux-gnuf64 --mattr=+d < %s \ +-; RUN: | FileCheck %s --check-prefix=LP64D +- +-define float @f(float %a) { +-; ILP32D-LABEL: f: +-; ILP32D: # %bb.0: +-; ILP32D-NEXT: addi.w $a0, $zero, 1 +-; ILP32D-NEXT: movgr2fr.w $fa1, $a0 +-; ILP32D-NEXT: ffint.s.w $fa1, $fa1 +-; ILP32D-NEXT: fadd.s $fa0, $fa0, $fa1 +-; ILP32D-NEXT: ret +-; +-; LP64D-LABEL: f: +-; LP64D: # %bb.0: +-; LP64D-NEXT: addi.w $a0, $zero, 1 +-; LP64D-NEXT: movgr2fr.w $fa1, $a0 +-; LP64D-NEXT: ffint.s.w $fa1, $fa1 +-; LP64D-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LP64D-NEXT: ret +- %1 = fadd float %a, 1.0 +- ret float %1 +-} +- +-define double @g(double %a) { +-; ILP32D-LABEL: g: +-; ILP32D: # %bb.0: +-; ILP32D-NEXT: addi.w $a0, $zero, 1 +-; ILP32D-NEXT: movgr2fr.w $fa1, $a0 +-; ILP32D-NEXT: ffint.s.w $fa1, $fa1 +-; ILP32D-NEXT: fcvt.d.s $fa1, $fa1 +-; ILP32D-NEXT: fadd.d $fa0, $fa0, $fa1 +-; ILP32D-NEXT: ret +-; +-; LP64D-LABEL: g: +-; LP64D: # %bb.0: +-; LP64D-NEXT: addi.d $a0, $zero, 1 +-; LP64D-NEXT: movgr2fr.d $fa1, $a0 +-; LP64D-NEXT: ffint.d.l $fa1, $fa1 +-; LP64D-NEXT: fadd.d $fa0, $fa0, $fa1 +-; LP64D-NEXT: ret +- %1 = fadd double %a, 1.0 +- ret double %1 +-} +diff --git a/llvm/test/CodeGen/LoongArch/target_support.ll b/llvm/test/CodeGen/LoongArch/target_support.ll +deleted file mode 100644 +index b7796e633..000000000 +--- a/llvm/test/CodeGen/LoongArch/target_support.ll ++++ /dev/null +@@ -1,3 +0,0 @@ +-; RUN: llc --version | FileCheck %s +-; CHECK: loongarch32 - 32-bit LoongArch +-; CHECK: loongarch64 - 64-bit LoongArch +diff --git a/llvm/test/CodeGen/LoongArch/test_bl_fixupkind.mir b/llvm/test/CodeGen/LoongArch/test_bl_fixupkind.mir +deleted file mode 100644 +index 70cd5fb8d..000000000 +--- a/llvm/test/CodeGen/LoongArch/test_bl_fixupkind.mir ++++ /dev/null +@@ -1,62 +0,0 @@ +-# RUN: llc --mtriple=loongarch64 --filetype=obj %s -o - | \ +-# RUN: llvm-objdump -d - | FileCheck %s +- +-# REQUIRES: asserts +- +-## Check that bl can get fixupkind correctly, whether BL contains +-## target-flags(loongarch-call) or not. +- +---- | +- target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128" +- target triple = "loongarch64" +- +- define dso_local void @test_bl_fixupkind_with_flag() { +- ; CHECK-LABEL: test_bl_fixupkind_with_flag +- ; CHECK: addi.d $sp, $sp, -16 +- ; CHECK-NEXT: st.d $ra, $sp, 8 +- ; CHECK-NEXT: bl 0 +- ; CHECK-NEXT: ld.d $ra, $sp, 8 +- ; CHECK-NEXT: addi.d $sp, $sp, 16 +- ; CHECK-NEXT: ret +- entry: +- call void @foo() +- ret void +- } +- +- define dso_local void @test_bl_fixupkind_without_flag() { +- ; CHECK-LABEL: test_bl_fixupkind_without_flag +- ; CHECK: addi.d $sp, $sp, -16 +- ; CHECK-NEXT: st.d $ra, $sp, 8 +- ; CHECK-NEXT: bl 0 +- ; CHECK-NEXT: ld.d $ra, $sp, 8 +- ; CHECK-NEXT: addi.d $sp, $sp, 16 +- ; CHECK-NEXT: ret +- entry: +- call void @foo() +- ret void +- } +- +- declare dso_local void @foo(...) +-... +---- +-name: test_bl_fixupkind_with_flag +-tracksRegLiveness: true +-body: | +- bb.0.entry: +- ADJCALLSTACKDOWN 0, 0, implicit-def dead $r3, implicit $r3 +- BL target-flags(loongarch-call) @foo, csr_ilp32d_lp64d, implicit-def $r1, implicit-def dead $r1, implicit-def $r3 +- ADJCALLSTACKUP 0, 0, implicit-def dead $r3, implicit $r3 +- PseudoRET +- +-... +---- +-name: test_bl_fixupkind_without_flag +-tracksRegLiveness: true +-body: | +- bb.0.entry: +- ADJCALLSTACKDOWN 0, 0, implicit-def dead $r3, implicit $r3 +- BL @foo, csr_ilp32d_lp64d, implicit-def $r1, implicit-def dead $r1, implicit-def $r3 +- ADJCALLSTACKUP 0, 0, implicit-def dead $r3, implicit $r3 +- PseudoRET +- +-... +diff --git a/llvm/test/CodeGen/LoongArch/thread-pointer.ll b/llvm/test/CodeGen/LoongArch/thread-pointer.ll +index 805709e61..06a5886c4 100644 +--- a/llvm/test/CodeGen/LoongArch/thread-pointer.ll ++++ b/llvm/test/CodeGen/LoongArch/thread-pointer.ll +@@ -1,14 +1,9 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc < %s --mtriple=loongarch32 | FileCheck %s +-; RUN: llc < %s --mtriple=loongarch64 | FileCheck %s ++; RUN: llc -march=loongarch64 < %s | FileCheck %s + +-declare ptr @llvm.thread.pointer() ++declare i8* @llvm.thread.pointer() nounwind readnone + +-define ptr @thread_pointer() nounwind { +-; CHECK-LABEL: thread_pointer: +-; CHECK: # %bb.0: +-; CHECK-NEXT: move $a0, $tp +-; CHECK-NEXT: ret +- %1 = tail call ptr @llvm.thread.pointer() +- ret ptr %1 ++define i8* @thread_pointer() { ++; CHECK: move $r4, $tp ++ %1 = tail call i8* @llvm.thread.pointer() ++ ret i8* %1 + } +diff --git a/llvm/test/CodeGen/LoongArch/tls-models.ll b/llvm/test/CodeGen/LoongArch/tls-models.ll +deleted file mode 100644 +index 3994df1da..000000000 +--- a/llvm/test/CodeGen/LoongArch/tls-models.ll ++++ /dev/null +@@ -1,264 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --relocation-model=pic < %s | FileCheck %s --check-prefix=LA32PIC +-; RUN: llc --mtriple=loongarch64 --relocation-model=pic < %s | FileCheck %s --check-prefix=LA64PIC +-; RUN: llc --mtriple=loongarch64 --code-model=large --relocation-model=pic < %s | FileCheck %s --check-prefix=LA64LARGEPIC +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32NOPIC +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64NOPIC +-; RUN: llc --mtriple=loongarch64 --code-model=large < %s | FileCheck %s --check-prefix=LA64LARGENOPIC +- +-;; Check that TLS symbols are lowered correctly based on the specified +-;; model. Make sure they're external to avoid them all being optimised to Local +-;; Exec for the executable. +- +-@unspecified = external thread_local global i32 +-@ld = external thread_local(localdynamic) global i32 +-@ie = external thread_local(initialexec) global i32 +-@le = external thread_local(localexec) global i32 +- +-;; No model specified (global dynamic) +- +-define ptr @f1() nounwind { +-; LA32PIC-LABEL: f1: +-; LA32PIC: # %bb.0: # %entry +-; LA32PIC-NEXT: addi.w $sp, $sp, -16 +-; LA32PIC-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32PIC-NEXT: pcalau12i $a0, %gd_pc_hi20(unspecified) +-; LA32PIC-NEXT: addi.w $a0, $a0, %got_pc_lo12(unspecified) +-; LA32PIC-NEXT: bl %plt(__tls_get_addr) +-; LA32PIC-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32PIC-NEXT: addi.w $sp, $sp, 16 +-; LA32PIC-NEXT: ret +-; +-; LA64PIC-LABEL: f1: +-; LA64PIC: # %bb.0: # %entry +-; LA64PIC-NEXT: addi.d $sp, $sp, -16 +-; LA64PIC-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64PIC-NEXT: pcalau12i $a0, %gd_pc_hi20(unspecified) +-; LA64PIC-NEXT: addi.d $a0, $a0, %got_pc_lo12(unspecified) +-; LA64PIC-NEXT: bl %plt(__tls_get_addr) +-; LA64PIC-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64PIC-NEXT: addi.d $sp, $sp, 16 +-; LA64PIC-NEXT: ret +-; +-; LA64LARGEPIC-LABEL: f1: +-; LA64LARGEPIC: # %bb.0: # %entry +-; LA64LARGEPIC-NEXT: addi.d $sp, $sp, -16 +-; LA64LARGEPIC-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64LARGEPIC-NEXT: pcalau12i $a0, %gd_pc_hi20(unspecified) +-; LA64LARGEPIC-NEXT: addi.d $t8, $zero, %got_pc_lo12(unspecified) +-; LA64LARGEPIC-NEXT: lu32i.d $t8, %got64_pc_lo20(unspecified) +-; LA64LARGEPIC-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(unspecified) +-; LA64LARGEPIC-NEXT: add.d $a0, $t8, $a0 +-; LA64LARGEPIC-NEXT: pcalau12i $ra, %pc_hi20(__tls_get_addr) +-; LA64LARGEPIC-NEXT: addi.d $t8, $zero, %pc_lo12(__tls_get_addr) +-; LA64LARGEPIC-NEXT: lu32i.d $t8, %pc64_lo20(__tls_get_addr) +-; LA64LARGEPIC-NEXT: lu52i.d $t8, $t8, %pc64_hi12(__tls_get_addr) +-; LA64LARGEPIC-NEXT: add.d $ra, $t8, $ra +-; LA64LARGEPIC-NEXT: jirl $ra, $ra, 0 +-; LA64LARGEPIC-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64LARGEPIC-NEXT: addi.d $sp, $sp, 16 +-; LA64LARGEPIC-NEXT: ret +-; +-; LA32NOPIC-LABEL: f1: +-; LA32NOPIC: # %bb.0: # %entry +-; LA32NOPIC-NEXT: pcalau12i $a0, %ie_pc_hi20(unspecified) +-; LA32NOPIC-NEXT: ld.w $a0, $a0, %ie_pc_lo12(unspecified) +-; LA32NOPIC-NEXT: add.w $a0, $a0, $tp +-; LA32NOPIC-NEXT: ret +-; +-; LA64NOPIC-LABEL: f1: +-; LA64NOPIC: # %bb.0: # %entry +-; LA64NOPIC-NEXT: pcalau12i $a0, %ie_pc_hi20(unspecified) +-; LA64NOPIC-NEXT: ld.d $a0, $a0, %ie_pc_lo12(unspecified) +-; LA64NOPIC-NEXT: add.d $a0, $a0, $tp +-; LA64NOPIC-NEXT: ret +-; +-; LA64LARGENOPIC-LABEL: f1: +-; LA64LARGENOPIC: # %bb.0: # %entry +-; LA64LARGENOPIC-NEXT: pcalau12i $a0, %ie_pc_hi20(unspecified) +-; LA64LARGENOPIC-NEXT: addi.d $t8, $zero, %ie_pc_lo12(unspecified) +-; LA64LARGENOPIC-NEXT: lu32i.d $t8, %ie64_pc_lo20(unspecified) +-; LA64LARGENOPIC-NEXT: lu52i.d $t8, $t8, %ie64_pc_hi12(unspecified) +-; LA64LARGENOPIC-NEXT: ldx.d $a0, $t8, $a0 +-; LA64LARGENOPIC-NEXT: add.d $a0, $a0, $tp +-; LA64LARGENOPIC-NEXT: ret +-entry: +- ret ptr @unspecified +-} +- +-;; localdynamic specified +- +-define ptr @f2() nounwind { +-; LA32PIC-LABEL: f2: +-; LA32PIC: # %bb.0: # %entry +-; LA32PIC-NEXT: addi.w $sp, $sp, -16 +-; LA32PIC-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32PIC-NEXT: pcalau12i $a0, %ld_pc_hi20(ld) +-; LA32PIC-NEXT: addi.w $a0, $a0, %got_pc_lo12(ld) +-; LA32PIC-NEXT: bl %plt(__tls_get_addr) +-; LA32PIC-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32PIC-NEXT: addi.w $sp, $sp, 16 +-; LA32PIC-NEXT: ret +-; +-; LA64PIC-LABEL: f2: +-; LA64PIC: # %bb.0: # %entry +-; LA64PIC-NEXT: addi.d $sp, $sp, -16 +-; LA64PIC-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64PIC-NEXT: pcalau12i $a0, %ld_pc_hi20(ld) +-; LA64PIC-NEXT: addi.d $a0, $a0, %got_pc_lo12(ld) +-; LA64PIC-NEXT: bl %plt(__tls_get_addr) +-; LA64PIC-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64PIC-NEXT: addi.d $sp, $sp, 16 +-; LA64PIC-NEXT: ret +-; +-; LA64LARGEPIC-LABEL: f2: +-; LA64LARGEPIC: # %bb.0: # %entry +-; LA64LARGEPIC-NEXT: addi.d $sp, $sp, -16 +-; LA64LARGEPIC-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64LARGEPIC-NEXT: pcalau12i $a0, %ld_pc_hi20(ld) +-; LA64LARGEPIC-NEXT: addi.d $t8, $zero, %got_pc_lo12(ld) +-; LA64LARGEPIC-NEXT: lu32i.d $t8, %got64_pc_lo20(ld) +-; LA64LARGEPIC-NEXT: lu52i.d $t8, $t8, %got64_pc_hi12(ld) +-; LA64LARGEPIC-NEXT: add.d $a0, $t8, $a0 +-; LA64LARGEPIC-NEXT: pcalau12i $ra, %pc_hi20(__tls_get_addr) +-; LA64LARGEPIC-NEXT: addi.d $t8, $zero, %pc_lo12(__tls_get_addr) +-; LA64LARGEPIC-NEXT: lu32i.d $t8, %pc64_lo20(__tls_get_addr) +-; LA64LARGEPIC-NEXT: lu52i.d $t8, $t8, %pc64_hi12(__tls_get_addr) +-; LA64LARGEPIC-NEXT: add.d $ra, $t8, $ra +-; LA64LARGEPIC-NEXT: jirl $ra, $ra, 0 +-; LA64LARGEPIC-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64LARGEPIC-NEXT: addi.d $sp, $sp, 16 +-; LA64LARGEPIC-NEXT: ret +-; +-; LA32NOPIC-LABEL: f2: +-; LA32NOPIC: # %bb.0: # %entry +-; LA32NOPIC-NEXT: pcalau12i $a0, %ie_pc_hi20(ld) +-; LA32NOPIC-NEXT: ld.w $a0, $a0, %ie_pc_lo12(ld) +-; LA32NOPIC-NEXT: add.w $a0, $a0, $tp +-; LA32NOPIC-NEXT: ret +-; +-; LA64NOPIC-LABEL: f2: +-; LA64NOPIC: # %bb.0: # %entry +-; LA64NOPIC-NEXT: pcalau12i $a0, %ie_pc_hi20(ld) +-; LA64NOPIC-NEXT: ld.d $a0, $a0, %ie_pc_lo12(ld) +-; LA64NOPIC-NEXT: add.d $a0, $a0, $tp +-; LA64NOPIC-NEXT: ret +-; +-; LA64LARGENOPIC-LABEL: f2: +-; LA64LARGENOPIC: # %bb.0: # %entry +-; LA64LARGENOPIC-NEXT: pcalau12i $a0, %ie_pc_hi20(ld) +-; LA64LARGENOPIC-NEXT: addi.d $t8, $zero, %ie_pc_lo12(ld) +-; LA64LARGENOPIC-NEXT: lu32i.d $t8, %ie64_pc_lo20(ld) +-; LA64LARGENOPIC-NEXT: lu52i.d $t8, $t8, %ie64_pc_hi12(ld) +-; LA64LARGENOPIC-NEXT: ldx.d $a0, $t8, $a0 +-; LA64LARGENOPIC-NEXT: add.d $a0, $a0, $tp +-; LA64LARGENOPIC-NEXT: ret +-entry: +- ret ptr @ld +-} +- +-;; initialexec specified +- +-define ptr @f3() nounwind { +-; LA32PIC-LABEL: f3: +-; LA32PIC: # %bb.0: # %entry +-; LA32PIC-NEXT: pcalau12i $a0, %ie_pc_hi20(ie) +-; LA32PIC-NEXT: ld.w $a0, $a0, %ie_pc_lo12(ie) +-; LA32PIC-NEXT: add.w $a0, $a0, $tp +-; LA32PIC-NEXT: ret +-; +-; LA64PIC-LABEL: f3: +-; LA64PIC: # %bb.0: # %entry +-; LA64PIC-NEXT: pcalau12i $a0, %ie_pc_hi20(ie) +-; LA64PIC-NEXT: ld.d $a0, $a0, %ie_pc_lo12(ie) +-; LA64PIC-NEXT: add.d $a0, $a0, $tp +-; LA64PIC-NEXT: ret +-; +-; LA64LARGEPIC-LABEL: f3: +-; LA64LARGEPIC: # %bb.0: # %entry +-; LA64LARGEPIC-NEXT: pcalau12i $a0, %ie_pc_hi20(ie) +-; LA64LARGEPIC-NEXT: addi.d $t8, $zero, %ie_pc_lo12(ie) +-; LA64LARGEPIC-NEXT: lu32i.d $t8, %ie64_pc_lo20(ie) +-; LA64LARGEPIC-NEXT: lu52i.d $t8, $t8, %ie64_pc_hi12(ie) +-; LA64LARGEPIC-NEXT: ldx.d $a0, $t8, $a0 +-; LA64LARGEPIC-NEXT: add.d $a0, $a0, $tp +-; LA64LARGEPIC-NEXT: ret +-; +-; LA32NOPIC-LABEL: f3: +-; LA32NOPIC: # %bb.0: # %entry +-; LA32NOPIC-NEXT: pcalau12i $a0, %ie_pc_hi20(ie) +-; LA32NOPIC-NEXT: ld.w $a0, $a0, %ie_pc_lo12(ie) +-; LA32NOPIC-NEXT: add.w $a0, $a0, $tp +-; LA32NOPIC-NEXT: ret +-; +-; LA64NOPIC-LABEL: f3: +-; LA64NOPIC: # %bb.0: # %entry +-; LA64NOPIC-NEXT: pcalau12i $a0, %ie_pc_hi20(ie) +-; LA64NOPIC-NEXT: ld.d $a0, $a0, %ie_pc_lo12(ie) +-; LA64NOPIC-NEXT: add.d $a0, $a0, $tp +-; LA64NOPIC-NEXT: ret +-; +-; LA64LARGENOPIC-LABEL: f3: +-; LA64LARGENOPIC: # %bb.0: # %entry +-; LA64LARGENOPIC-NEXT: pcalau12i $a0, %ie_pc_hi20(ie) +-; LA64LARGENOPIC-NEXT: addi.d $t8, $zero, %ie_pc_lo12(ie) +-; LA64LARGENOPIC-NEXT: lu32i.d $t8, %ie64_pc_lo20(ie) +-; LA64LARGENOPIC-NEXT: lu52i.d $t8, $t8, %ie64_pc_hi12(ie) +-; LA64LARGENOPIC-NEXT: ldx.d $a0, $t8, $a0 +-; LA64LARGENOPIC-NEXT: add.d $a0, $a0, $tp +-; LA64LARGENOPIC-NEXT: ret +-entry: +- ret ptr @ie +-} +- +-;; localexec specified +- +-define ptr @f4() nounwind { +-; LA32PIC-LABEL: f4: +-; LA32PIC: # %bb.0: # %entry +-; LA32PIC-NEXT: lu12i.w $a0, %le_hi20(le) +-; LA32PIC-NEXT: ori $a0, $a0, %le_lo12(le) +-; LA32PIC-NEXT: add.w $a0, $a0, $tp +-; LA32PIC-NEXT: ret +-; +-; LA64PIC-LABEL: f4: +-; LA64PIC: # %bb.0: # %entry +-; LA64PIC-NEXT: lu12i.w $a0, %le_hi20(le) +-; LA64PIC-NEXT: ori $a0, $a0, %le_lo12(le) +-; LA64PIC-NEXT: add.d $a0, $a0, $tp +-; LA64PIC-NEXT: ret +-; +-; LA64LARGEPIC-LABEL: f4: +-; LA64LARGEPIC: # %bb.0: # %entry +-; LA64LARGEPIC-NEXT: lu12i.w $a0, %le_hi20(le) +-; LA64LARGEPIC-NEXT: ori $a0, $a0, %le_lo12(le) +-; LA64LARGEPIC-NEXT: lu32i.d $a0, %le64_lo20(le) +-; LA64LARGEPIC-NEXT: lu52i.d $a0, $a0, %le64_hi12(le) +-; LA64LARGEPIC-NEXT: add.d $a0, $a0, $tp +-; LA64LARGEPIC-NEXT: ret +-; +-; LA32NOPIC-LABEL: f4: +-; LA32NOPIC: # %bb.0: # %entry +-; LA32NOPIC-NEXT: lu12i.w $a0, %le_hi20(le) +-; LA32NOPIC-NEXT: ori $a0, $a0, %le_lo12(le) +-; LA32NOPIC-NEXT: add.w $a0, $a0, $tp +-; LA32NOPIC-NEXT: ret +-; +-; LA64NOPIC-LABEL: f4: +-; LA64NOPIC: # %bb.0: # %entry +-; LA64NOPIC-NEXT: lu12i.w $a0, %le_hi20(le) +-; LA64NOPIC-NEXT: ori $a0, $a0, %le_lo12(le) +-; LA64NOPIC-NEXT: add.d $a0, $a0, $tp +-; LA64NOPIC-NEXT: ret +-; +-; LA64LARGENOPIC-LABEL: f4: +-; LA64LARGENOPIC: # %bb.0: # %entry +-; LA64LARGENOPIC-NEXT: lu12i.w $a0, %le_hi20(le) +-; LA64LARGENOPIC-NEXT: ori $a0, $a0, %le_lo12(le) +-; LA64LARGENOPIC-NEXT: lu32i.d $a0, %le64_lo20(le) +-; LA64LARGENOPIC-NEXT: lu52i.d $a0, $a0, %le64_hi12(le) +-; LA64LARGENOPIC-NEXT: add.d $a0, $a0, $tp +-; LA64LARGENOPIC-NEXT: ret +-entry: +- ret ptr @le +-} +diff --git a/llvm/test/CodeGen/LoongArch/trap.ll b/llvm/test/CodeGen/LoongArch/trap.ll +index 718b99160..4a4b54438 100644 +--- a/llvm/test/CodeGen/LoongArch/trap.ll ++++ b/llvm/test/CodeGen/LoongArch/trap.ll +@@ -1,26 +1,13 @@ + ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --verify-machineinstrs < %s | FileCheck %s +-; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s | FileCheck %s +- +-;; Verify that we lower @llvm.trap() and @llvm.debugtrap() correctly. +- +-declare void @llvm.trap() +-declare void @llvm.debugtrap() ++; RUN: llc -march=loongarch64 < %s | FileCheck %s + + define void @test_trap() nounwind { + ; CHECK-LABEL: test_trap: + ; CHECK: # %bb.0: +-; CHECK-NEXT: amswap.w $zero, $ra, $zero +-; CHECK-NEXT: ret +- tail call void @llvm.trap() +- ret void +-} +- +-define void @test_debugtrap() nounwind { +-; CHECK-LABEL: test_debugtrap: +-; CHECK: # %bb.0: + ; CHECK-NEXT: break 0 +-; CHECK-NEXT: ret +- tail call void @llvm.debugtrap() ++; CHECK-NEXT: jr $ra ++ call void @llvm.trap() + ret void + } ++ ++declare void @llvm.trap() +diff --git a/llvm/test/CodeGen/LoongArch/trunc.ll b/llvm/test/CodeGen/LoongArch/trunc.ll +new file mode 100644 +index 000000000..d1b5a3a14 +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/trunc.ll +@@ -0,0 +1,108 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 < %s | FileCheck %s ++ ++define signext i32 @foo1(i64 %a, i64 %b) { ++; CHECK-LABEL: foo1: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: add.w $r4, $r5, $r4 ++; CHECK-NEXT: jr $ra ++entry: ++ %conv = trunc i64 %a to i32 ++ %conv1 = trunc i64 %b to i32 ++ %add = add nsw i32 %conv1, %conv ++ ret i32 %add ++} ++ ++define signext i32 @foo2(i64 %a, i64 %b) { ++; CHECK-LABEL: foo2: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: sub.w $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %conv = trunc i64 %a to i32 ++ %conv1 = trunc i64 %b to i32 ++ %sub = sub nsw i32 %conv, %conv1 ++ ret i32 %sub ++} ++ ++define signext i32 @foo3(i64 %a, i64 %b) { ++; CHECK-LABEL: foo3: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: sll.w $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %conv = trunc i64 %a to i32 ++ %conv1 = trunc i64 %b to i32 ++ %shl = shl i32 %conv, %conv1 ++ ret i32 %shl ++} ++ ++define signext i32 @foo4(i64 %a, i64 %b) { ++; CHECK-LABEL: foo4: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: srl.w $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %conv = trunc i64 %a to i32 ++ %conv1 = trunc i64 %b to i32 ++ %shr = lshr i32 %conv, %conv1 ++ ret i32 %shr ++} ++ ++define signext i32 @foo5(i64 %a, i64 %b) { ++; CHECK-LABEL: foo5: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: mul.w $r4, $r5, $r4 ++; CHECK-NEXT: jr $ra ++entry: ++ %conv = trunc i64 %a to i32 ++ %conv1 = trunc i64 %b to i32 ++ %mul = mul nsw i32 %conv1, %conv ++ ret i32 %mul ++} ++ ++define signext i32 @foo6(i64 %a, i64 %b) { ++; CHECK-LABEL: foo6: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: sra.w $r4, $r4, $r5 ++; CHECK-NEXT: jr $ra ++entry: ++ %conv = trunc i64 %a to i32 ++ %conv1 = trunc i64 %b to i32 ++ %shr = ashr i32 %conv, %conv1 ++ ret i32 %shr ++} ++ ++define signext i32 @sdiv(i64 %a, i64 %b) { ++; CHECK-LABEL: sdiv: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: div.w $r4, $r4, $r5 ++; CHECK-NEXT: bne $r5, $zero, 8 ++; CHECK-NEXT: break 7 ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++entry: ++ %conv = trunc i64 %a to i32 ++ %conv1 = trunc i64 %b to i32 ++ %div = sdiv i32 %conv, %conv1 ++ ret i32 %div ++} ++ ++define signext i32 @udiv(i64 %a, i64 %b) { ++; CHECK-LABEL: udiv: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: slli.w $r5, $r5, 0 ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: div.wu $r4, $r4, $r5 ++; CHECK-NEXT: bne $r5, $zero, 8 ++; CHECK-NEXT: break 7 ++; CHECK-NEXT: slli.w $r4, $r4, 0 ++; CHECK-NEXT: jr $ra ++entry: ++ %conv = trunc i64 %a to i32 ++ %conv1 = trunc i64 %b to i32 ++ %div = udiv i32 %conv, %conv1 ++ ret i32 %div ++} +diff --git a/llvm/test/CodeGen/LoongArch/unaligned-access.ll b/llvm/test/CodeGen/LoongArch/unaligned-access.ll +deleted file mode 100644 +index 871c17f06..000000000 +--- a/llvm/test/CodeGen/LoongArch/unaligned-access.ll ++++ /dev/null +@@ -1,72 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 +- +-;; Test the ual feature which is similar to AArch64/arm64-strict-align.ll. +- +-; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32-ALIGNED +-; RUN: llc --mtriple=loongarch32 --mattr=+ual < %s | FileCheck %s --check-prefix=LA32-UNALIGNED +-; RUN: llc --mtriple=loongarch32 --mattr=-ual < %s | FileCheck %s --check-prefix=LA32-ALIGNED +- +-; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64-UNALIGNED +-; RUN: llc --mtriple=loongarch64 --mattr=+ual < %s | FileCheck %s --check-prefix=LA64-UNALIGNED +-; RUN: llc --mtriple=loongarch64 --mattr=-ual < %s | FileCheck %s --check-prefix=LA64-ALIGNED +- +-define i32 @f0(ptr %p) nounwind { +-; LA32-ALIGNED-LABEL: f0: +-; LA32-ALIGNED: # %bb.0: +-; LA32-ALIGNED-NEXT: ld.hu $a1, $a0, 0 +-; LA32-ALIGNED-NEXT: ld.hu $a0, $a0, 2 +-; LA32-ALIGNED-NEXT: slli.w $a0, $a0, 16 +-; LA32-ALIGNED-NEXT: or $a0, $a0, $a1 +-; LA32-ALIGNED-NEXT: ret +-; +-; LA32-UNALIGNED-LABEL: f0: +-; LA32-UNALIGNED: # %bb.0: +-; LA32-UNALIGNED-NEXT: ld.w $a0, $a0, 0 +-; LA32-UNALIGNED-NEXT: ret +-; +-; LA64-UNALIGNED-LABEL: f0: +-; LA64-UNALIGNED: # %bb.0: +-; LA64-UNALIGNED-NEXT: ld.w $a0, $a0, 0 +-; LA64-UNALIGNED-NEXT: ret +-; +-; LA64-ALIGNED-LABEL: f0: +-; LA64-ALIGNED: # %bb.0: +-; LA64-ALIGNED-NEXT: ld.hu $a1, $a0, 0 +-; LA64-ALIGNED-NEXT: ld.h $a0, $a0, 2 +-; LA64-ALIGNED-NEXT: slli.d $a0, $a0, 16 +-; LA64-ALIGNED-NEXT: or $a0, $a0, $a1 +-; LA64-ALIGNED-NEXT: ret +- %tmp = load i32, ptr %p, align 2 +- ret i32 %tmp +-} +- +-define i64 @f1(ptr %p) nounwind { +-; LA32-ALIGNED-LABEL: f1: +-; LA32-ALIGNED: # %bb.0: +-; LA32-ALIGNED-NEXT: ld.w $a2, $a0, 0 +-; LA32-ALIGNED-NEXT: ld.w $a1, $a0, 4 +-; LA32-ALIGNED-NEXT: move $a0, $a2 +-; LA32-ALIGNED-NEXT: ret +-; +-; LA32-UNALIGNED-LABEL: f1: +-; LA32-UNALIGNED: # %bb.0: +-; LA32-UNALIGNED-NEXT: ld.w $a2, $a0, 0 +-; LA32-UNALIGNED-NEXT: ld.w $a1, $a0, 4 +-; LA32-UNALIGNED-NEXT: move $a0, $a2 +-; LA32-UNALIGNED-NEXT: ret +-; +-; LA64-UNALIGNED-LABEL: f1: +-; LA64-UNALIGNED: # %bb.0: +-; LA64-UNALIGNED-NEXT: ld.d $a0, $a0, 0 +-; LA64-UNALIGNED-NEXT: ret +-; +-; LA64-ALIGNED-LABEL: f1: +-; LA64-ALIGNED: # %bb.0: +-; LA64-ALIGNED-NEXT: ld.wu $a1, $a0, 0 +-; LA64-ALIGNED-NEXT: ld.wu $a0, $a0, 4 +-; LA64-ALIGNED-NEXT: slli.d $a0, $a0, 32 +-; LA64-ALIGNED-NEXT: or $a0, $a0, $a1 +-; LA64-ALIGNED-NEXT: ret +- %tmp = load i64, ptr %p, align 4 +- ret i64 %tmp +-} +diff --git a/llvm/test/CodeGen/LoongArch/unaligned-memcpy-inline.ll b/llvm/test/CodeGen/LoongArch/unaligned-memcpy-inline.ll +deleted file mode 100644 +index 37afe7e3e..000000000 +--- a/llvm/test/CodeGen/LoongArch/unaligned-memcpy-inline.ll ++++ /dev/null +@@ -1,97 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 +- +-;; Test how memcpy is optimized when ual is turned off which is similar to AArch64/arm64-misaligned-memcpy-inline.ll. +- +-; RUN: llc --mtriple=loongarch32 --mattr=-ual < %s | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 --mattr=-ual < %s | FileCheck %s --check-prefix=LA64 +- +-;; Small (16 bytes here) unaligned memcpy() should be a function call if +-;; ual is turned off. +-define void @t0(ptr %out, ptr %in) { +-; LA32-LABEL: t0: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: addi.w $sp, $sp, -16 +-; LA32-NEXT: .cfi_def_cfa_offset 16 +-; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32-NEXT: .cfi_offset 1, -4 +-; LA32-NEXT: ori $a2, $zero, 16 +-; LA32-NEXT: bl %plt(memcpy) +-; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32-NEXT: addi.w $sp, $sp, 16 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: t0: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: addi.d $sp, $sp, -16 +-; LA64-NEXT: .cfi_def_cfa_offset 16 +-; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-NEXT: .cfi_offset 1, -8 +-; LA64-NEXT: ori $a2, $zero, 16 +-; LA64-NEXT: bl %plt(memcpy) +-; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-NEXT: addi.d $sp, $sp, 16 +-; LA64-NEXT: ret +-entry: +- call void @llvm.memcpy.p0.p0.i64(ptr %out, ptr %in, i64 16, i1 false) +- ret void +-} +- +-;; Small (16 bytes here) aligned memcpy() should be inlined even if +-;; ual is turned off. +-define void @t1(ptr align 8 %out, ptr align 8 %in) { +-; LA32-LABEL: t1: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: ld.w $a2, $a1, 12 +-; LA32-NEXT: st.w $a2, $a0, 12 +-; LA32-NEXT: ld.w $a2, $a1, 8 +-; LA32-NEXT: st.w $a2, $a0, 8 +-; LA32-NEXT: ld.w $a2, $a1, 4 +-; LA32-NEXT: st.w $a2, $a0, 4 +-; LA32-NEXT: ld.w $a1, $a1, 0 +-; LA32-NEXT: st.w $a1, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: t1: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ld.d $a2, $a1, 8 +-; LA64-NEXT: st.d $a2, $a0, 8 +-; LA64-NEXT: ld.d $a1, $a1, 0 +-; LA64-NEXT: st.d $a1, $a0, 0 +-; LA64-NEXT: ret +-entry: +- call void @llvm.memcpy.p0.p0.i64(ptr align 8 %out, ptr align 8 %in, i64 16, i1 false) +- ret void +-} +- +-;; Tiny (4 bytes here) unaligned memcpy() should be inlined with byte sized +-;; loads and stores if ual is turned off. +-define void @t2(ptr %out, ptr %in) { +-; LA32-LABEL: t2: +-; LA32: # %bb.0: # %entry +-; LA32-NEXT: ld.b $a2, $a1, 3 +-; LA32-NEXT: st.b $a2, $a0, 3 +-; LA32-NEXT: ld.b $a2, $a1, 2 +-; LA32-NEXT: st.b $a2, $a0, 2 +-; LA32-NEXT: ld.b $a2, $a1, 1 +-; LA32-NEXT: st.b $a2, $a0, 1 +-; LA32-NEXT: ld.b $a1, $a1, 0 +-; LA32-NEXT: st.b $a1, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: t2: +-; LA64: # %bb.0: # %entry +-; LA64-NEXT: ld.b $a2, $a1, 3 +-; LA64-NEXT: st.b $a2, $a0, 3 +-; LA64-NEXT: ld.b $a2, $a1, 2 +-; LA64-NEXT: st.b $a2, $a0, 2 +-; LA64-NEXT: ld.b $a2, $a1, 1 +-; LA64-NEXT: st.b $a2, $a0, 1 +-; LA64-NEXT: ld.b $a1, $a1, 0 +-; LA64-NEXT: st.b $a1, $a0, 0 +-; LA64-NEXT: ret +-entry: +- call void @llvm.memcpy.p0.p0.i64(ptr %out, ptr %in, i64 4, i1 false) +- ret void +-} +- +-declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture readonly, i64, i1) +diff --git a/llvm/test/CodeGen/LoongArch/unalignment.ll b/llvm/test/CodeGen/LoongArch/unalignment.ll +new file mode 100644 +index 000000000..d468a361f +--- /dev/null ++++ b/llvm/test/CodeGen/LoongArch/unalignment.ll +@@ -0,0 +1,72 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -march=loongarch64 -o - %s | FileCheck -check-prefix=UNALIGNED %s ++; RUN: llc -march=loongarch64 -mattr=+unaligned-access -o - %s | FileCheck -check-prefix=UNALIGNED %s ++; RUN: llc -march=loongarch64 -mattr=-unaligned-access -o - %s | FileCheck -check-prefix=ALIGNED %s ++ ++define i32 @i32_load(i32* %p) { ++; UNALIGNED-LABEL: i32_load: ++; UNALIGNED: # %bb.0: ++; UNALIGNED-NEXT: ld.w $r4, $r4, 0 ++; UNALIGNED-NEXT: jr $ra ++; ++; ALIGNED-LABEL: i32_load: ++; ALIGNED: # %bb.0: ++; ALIGNED-NEXT: ld.hu $r5, $r4, 0 ++; ALIGNED-NEXT: ld.hu $r4, $r4, 2 ++; ALIGNED-NEXT: slli.w $r4, $r4, 16 ++; ALIGNED-NEXT: or $r4, $r4, $r5 ++; ALIGNED-NEXT: jr $ra ++ %tmp = load i32, i32* %p, align 2 ++ ret i32 %tmp ++} ++ ++define signext i32 @i32_sextload(i32* %p) { ++; UNALIGNED-LABEL: i32_sextload: ++; UNALIGNED: # %bb.0: ++; UNALIGNED-NEXT: ld.w $r4, $r4, 0 ++; UNALIGNED-NEXT: jr $ra ++; ++; ALIGNED-LABEL: i32_sextload: ++; ALIGNED: # %bb.0: ++; ALIGNED-NEXT: ld.hu $r5, $r4, 0 ++; ALIGNED-NEXT: ld.h $r4, $r4, 2 ++; ALIGNED-NEXT: slli.d $r4, $r4, 16 ++; ALIGNED-NEXT: or $r4, $r4, $r5 ++; ALIGNED-NEXT: jr $ra ++ %tmp = load i32, i32* %p, align 2 ++ ret i32 %tmp ++} ++ ++define zeroext i32 @i32_zextload(i32* %p) { ++; UNALIGNED-LABEL: i32_zextload: ++; UNALIGNED: # %bb.0: ++; UNALIGNED-NEXT: ld.wu $r4, $r4, 0 ++; UNALIGNED-NEXT: jr $ra ++; ++; ALIGNED-LABEL: i32_zextload: ++; ALIGNED: # %bb.0: ++; ALIGNED-NEXT: ld.hu $r5, $r4, 0 ++; ALIGNED-NEXT: ld.hu $r4, $r4, 2 ++; ALIGNED-NEXT: slli.d $r4, $r4, 16 ++; ALIGNED-NEXT: or $r4, $r4, $r5 ++; ALIGNED-NEXT: jr $ra ++ %tmp = load i32, i32* %p, align 2 ++ ret i32 %tmp ++} ++ ++define i64 @i64_load(i64* %p) { ++; UNALIGNED-LABEL: i64_load: ++; UNALIGNED: # %bb.0: ++; UNALIGNED-NEXT: ld.d $r4, $r4, 0 ++; UNALIGNED-NEXT: jr $ra ++; ++; ALIGNED-LABEL: i64_load: ++; ALIGNED: # %bb.0: ++; ALIGNED-NEXT: ld.wu $r5, $r4, 0 ++; ALIGNED-NEXT: ld.wu $r4, $r4, 4 ++; ALIGNED-NEXT: slli.d $r4, $r4, 32 ++; ALIGNED-NEXT: or $r4, $r4, $r5 ++; ALIGNED-NEXT: jr $ra ++ %tmp = load i64, i64* %p, align 4 ++ ret i64 %tmp ++} +diff --git a/llvm/test/CodeGen/LoongArch/vararg.ll b/llvm/test/CodeGen/LoongArch/vararg.ll +deleted file mode 100644 +index a377628c3..000000000 +--- a/llvm/test/CodeGen/LoongArch/vararg.ll ++++ /dev/null +@@ -1,354 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch64 --mattr=+d --target-abi=lp64d < %s \ +-; RUN: | FileCheck --check-prefix=LA64-FPELIM %s +-; RUN: llc --mtriple=loongarch64 --mattr=+d --target-abi=lp64d < %s \ +-; RUN: --frame-pointer=all < %s \ +-; RUN: | FileCheck --check-prefix=LA64-WITHFP %s +- +-declare void @llvm.va_start(ptr) +-declare void @llvm.va_end(ptr) +- +-declare void @notdead(ptr) +- +-define i64 @va1(ptr %fmt, ...) { +-; LA64-FPELIM-LABEL: va1: +-; LA64-FPELIM: # %bb.0: +-; LA64-FPELIM-NEXT: addi.d $sp, $sp, -80 +-; LA64-FPELIM-NEXT: .cfi_def_cfa_offset 80 +-; LA64-FPELIM-NEXT: move $a0, $a1 +-; LA64-FPELIM-NEXT: st.d $a7, $sp, 72 +-; LA64-FPELIM-NEXT: st.d $a6, $sp, 64 +-; LA64-FPELIM-NEXT: st.d $a5, $sp, 56 +-; LA64-FPELIM-NEXT: st.d $a4, $sp, 48 +-; LA64-FPELIM-NEXT: st.d $a3, $sp, 40 +-; LA64-FPELIM-NEXT: st.d $a2, $sp, 32 +-; LA64-FPELIM-NEXT: addi.d $a1, $sp, 32 +-; LA64-FPELIM-NEXT: st.d $a1, $sp, 8 +-; LA64-FPELIM-NEXT: st.d $a0, $sp, 24 +-; LA64-FPELIM-NEXT: addi.d $sp, $sp, 80 +-; LA64-FPELIM-NEXT: ret +-; +-; LA64-WITHFP-LABEL: va1: +-; LA64-WITHFP: # %bb.0: +-; LA64-WITHFP-NEXT: addi.d $sp, $sp, -96 +-; LA64-WITHFP-NEXT: .cfi_def_cfa_offset 96 +-; LA64-WITHFP-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill +-; LA64-WITHFP-NEXT: st.d $fp, $sp, 16 # 8-byte Folded Spill +-; LA64-WITHFP-NEXT: .cfi_offset 1, -72 +-; LA64-WITHFP-NEXT: .cfi_offset 22, -80 +-; LA64-WITHFP-NEXT: addi.d $fp, $sp, 32 +-; LA64-WITHFP-NEXT: .cfi_def_cfa 22, 64 +-; LA64-WITHFP-NEXT: move $a0, $a1 +-; LA64-WITHFP-NEXT: st.d $a7, $fp, 56 +-; LA64-WITHFP-NEXT: st.d $a6, $fp, 48 +-; LA64-WITHFP-NEXT: st.d $a5, $fp, 40 +-; LA64-WITHFP-NEXT: st.d $a4, $fp, 32 +-; LA64-WITHFP-NEXT: st.d $a3, $fp, 24 +-; LA64-WITHFP-NEXT: st.d $a2, $fp, 16 +-; LA64-WITHFP-NEXT: addi.d $a1, $fp, 16 +-; LA64-WITHFP-NEXT: st.d $a1, $fp, -24 +-; LA64-WITHFP-NEXT: st.d $a0, $fp, 8 +-; LA64-WITHFP-NEXT: ld.d $fp, $sp, 16 # 8-byte Folded Reload +-; LA64-WITHFP-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload +-; LA64-WITHFP-NEXT: addi.d $sp, $sp, 96 +-; LA64-WITHFP-NEXT: ret +- %va = alloca ptr, align 8 +- call void @llvm.va_start(ptr %va) +- %argp.cur = load ptr, ptr %va, align 8 +- %argp.next = getelementptr inbounds i64, ptr %argp.cur, i32 1 +- store ptr %argp.next, ptr %va, align 8 +- %1 = load i64, ptr %argp.cur, align 8 +- call void @llvm.va_end(ptr %va) +- ret i64 %1 +-} +- +-define i64 @va1_va_arg(ptr %fmt, ...) nounwind { +-; LA64-FPELIM-LABEL: va1_va_arg: +-; LA64-FPELIM: # %bb.0: +-; LA64-FPELIM-NEXT: addi.d $sp, $sp, -80 +-; LA64-FPELIM-NEXT: move $a0, $a1 +-; LA64-FPELIM-NEXT: st.d $a7, $sp, 72 +-; LA64-FPELIM-NEXT: st.d $a6, $sp, 64 +-; LA64-FPELIM-NEXT: st.d $a5, $sp, 56 +-; LA64-FPELIM-NEXT: st.d $a4, $sp, 48 +-; LA64-FPELIM-NEXT: st.d $a3, $sp, 40 +-; LA64-FPELIM-NEXT: st.d $a2, $sp, 32 +-; LA64-FPELIM-NEXT: addi.d $a1, $sp, 32 +-; LA64-FPELIM-NEXT: st.d $a1, $sp, 8 +-; LA64-FPELIM-NEXT: st.d $a0, $sp, 24 +-; LA64-FPELIM-NEXT: addi.d $sp, $sp, 80 +-; LA64-FPELIM-NEXT: ret +-; +-; LA64-WITHFP-LABEL: va1_va_arg: +-; LA64-WITHFP: # %bb.0: +-; LA64-WITHFP-NEXT: addi.d $sp, $sp, -96 +-; LA64-WITHFP-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill +-; LA64-WITHFP-NEXT: st.d $fp, $sp, 16 # 8-byte Folded Spill +-; LA64-WITHFP-NEXT: addi.d $fp, $sp, 32 +-; LA64-WITHFP-NEXT: move $a0, $a1 +-; LA64-WITHFP-NEXT: st.d $a7, $fp, 56 +-; LA64-WITHFP-NEXT: st.d $a6, $fp, 48 +-; LA64-WITHFP-NEXT: st.d $a5, $fp, 40 +-; LA64-WITHFP-NEXT: st.d $a4, $fp, 32 +-; LA64-WITHFP-NEXT: st.d $a3, $fp, 24 +-; LA64-WITHFP-NEXT: st.d $a2, $fp, 16 +-; LA64-WITHFP-NEXT: addi.d $a1, $fp, 16 +-; LA64-WITHFP-NEXT: st.d $a1, $fp, -24 +-; LA64-WITHFP-NEXT: st.d $a0, $fp, 8 +-; LA64-WITHFP-NEXT: ld.d $fp, $sp, 16 # 8-byte Folded Reload +-; LA64-WITHFP-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload +-; LA64-WITHFP-NEXT: addi.d $sp, $sp, 96 +-; LA64-WITHFP-NEXT: ret +- %va = alloca ptr, align 8 +- call void @llvm.va_start(ptr %va) +- %1 = va_arg ptr %va, i64 +- call void @llvm.va_end(ptr %va) +- ret i64 %1 +-} +- +-;; Ensure the adjustment when restoring the stack pointer using the frame +-;; pointer is correct +- +-define i64 @va1_va_arg_alloca(ptr %fmt, ...) nounwind { +-; LA64-FPELIM-LABEL: va1_va_arg_alloca: +-; LA64-FPELIM: # %bb.0: +-; LA64-FPELIM-NEXT: addi.d $sp, $sp, -96 +-; LA64-FPELIM-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill +-; LA64-FPELIM-NEXT: st.d $fp, $sp, 16 # 8-byte Folded Spill +-; LA64-FPELIM-NEXT: st.d $s0, $sp, 8 # 8-byte Folded Spill +-; LA64-FPELIM-NEXT: addi.d $fp, $sp, 32 +-; LA64-FPELIM-NEXT: move $s0, $a1 +-; LA64-FPELIM-NEXT: st.d $a7, $fp, 56 +-; LA64-FPELIM-NEXT: st.d $a6, $fp, 48 +-; LA64-FPELIM-NEXT: st.d $a5, $fp, 40 +-; LA64-FPELIM-NEXT: st.d $a4, $fp, 32 +-; LA64-FPELIM-NEXT: st.d $a3, $fp, 24 +-; LA64-FPELIM-NEXT: st.d $a2, $fp, 16 +-; LA64-FPELIM-NEXT: addi.d $a0, $fp, 16 +-; LA64-FPELIM-NEXT: st.d $a0, $fp, -32 +-; LA64-FPELIM-NEXT: st.d $a1, $fp, 8 +-; LA64-FPELIM-NEXT: addi.d $a0, $a1, 15 +-; LA64-FPELIM-NEXT: bstrins.d $a0, $zero, 3, 0 +-; LA64-FPELIM-NEXT: sub.d $a0, $sp, $a0 +-; LA64-FPELIM-NEXT: move $sp, $a0 +-; LA64-FPELIM-NEXT: bl %plt(notdead) +-; LA64-FPELIM-NEXT: move $a0, $s0 +-; LA64-FPELIM-NEXT: addi.d $sp, $fp, -32 +-; LA64-FPELIM-NEXT: ld.d $s0, $sp, 8 # 8-byte Folded Reload +-; LA64-FPELIM-NEXT: ld.d $fp, $sp, 16 # 8-byte Folded Reload +-; LA64-FPELIM-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload +-; LA64-FPELIM-NEXT: addi.d $sp, $sp, 96 +-; LA64-FPELIM-NEXT: ret +-; +-; LA64-WITHFP-LABEL: va1_va_arg_alloca: +-; LA64-WITHFP: # %bb.0: +-; LA64-WITHFP-NEXT: addi.d $sp, $sp, -96 +-; LA64-WITHFP-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill +-; LA64-WITHFP-NEXT: st.d $fp, $sp, 16 # 8-byte Folded Spill +-; LA64-WITHFP-NEXT: st.d $s0, $sp, 8 # 8-byte Folded Spill +-; LA64-WITHFP-NEXT: addi.d $fp, $sp, 32 +-; LA64-WITHFP-NEXT: move $s0, $a1 +-; LA64-WITHFP-NEXT: st.d $a7, $fp, 56 +-; LA64-WITHFP-NEXT: st.d $a6, $fp, 48 +-; LA64-WITHFP-NEXT: st.d $a5, $fp, 40 +-; LA64-WITHFP-NEXT: st.d $a4, $fp, 32 +-; LA64-WITHFP-NEXT: st.d $a3, $fp, 24 +-; LA64-WITHFP-NEXT: st.d $a2, $fp, 16 +-; LA64-WITHFP-NEXT: addi.d $a0, $fp, 16 +-; LA64-WITHFP-NEXT: st.d $a0, $fp, -32 +-; LA64-WITHFP-NEXT: st.d $a1, $fp, 8 +-; LA64-WITHFP-NEXT: addi.d $a0, $a1, 15 +-; LA64-WITHFP-NEXT: bstrins.d $a0, $zero, 3, 0 +-; LA64-WITHFP-NEXT: sub.d $a0, $sp, $a0 +-; LA64-WITHFP-NEXT: move $sp, $a0 +-; LA64-WITHFP-NEXT: bl %plt(notdead) +-; LA64-WITHFP-NEXT: move $a0, $s0 +-; LA64-WITHFP-NEXT: addi.d $sp, $fp, -32 +-; LA64-WITHFP-NEXT: ld.d $s0, $sp, 8 # 8-byte Folded Reload +-; LA64-WITHFP-NEXT: ld.d $fp, $sp, 16 # 8-byte Folded Reload +-; LA64-WITHFP-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload +-; LA64-WITHFP-NEXT: addi.d $sp, $sp, 96 +-; LA64-WITHFP-NEXT: ret +- %va = alloca ptr, align 8 +- call void @llvm.va_start(ptr %va) +- %1 = va_arg ptr %va, i64 +- %2 = alloca i8, i64 %1 +- call void @notdead(ptr %2) +- call void @llvm.va_end(ptr %va) +- ret i64 %1 +-} +- +-define void @va1_caller() nounwind { +-; LA64-FPELIM-LABEL: va1_caller: +-; LA64-FPELIM: # %bb.0: +-; LA64-FPELIM-NEXT: addi.d $sp, $sp, -16 +-; LA64-FPELIM-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-FPELIM-NEXT: lu52i.d $a1, $zero, 1023 +-; LA64-FPELIM-NEXT: ori $a2, $zero, 2 +-; LA64-FPELIM-NEXT: bl %plt(va1) +-; LA64-FPELIM-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-FPELIM-NEXT: addi.d $sp, $sp, 16 +-; LA64-FPELIM-NEXT: ret +-; +-; LA64-WITHFP-LABEL: va1_caller: +-; LA64-WITHFP: # %bb.0: +-; LA64-WITHFP-NEXT: addi.d $sp, $sp, -16 +-; LA64-WITHFP-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-WITHFP-NEXT: st.d $fp, $sp, 0 # 8-byte Folded Spill +-; LA64-WITHFP-NEXT: addi.d $fp, $sp, 16 +-; LA64-WITHFP-NEXT: lu52i.d $a1, $zero, 1023 +-; LA64-WITHFP-NEXT: ori $a2, $zero, 2 +-; LA64-WITHFP-NEXT: bl %plt(va1) +-; LA64-WITHFP-NEXT: ld.d $fp, $sp, 0 # 8-byte Folded Reload +-; LA64-WITHFP-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-WITHFP-NEXT: addi.d $sp, $sp, 16 +-; LA64-WITHFP-NEXT: ret +- %1 = call i64 (ptr, ...) @va1(ptr undef, double 1.0, i64 2) +- ret void +-} +- +-;; Ensure a named 2*GRLen argument is passed in a1 and a2, while the +-;; vararg long double is passed in a4 and a5 (rather than a3 and a4) +- +-declare i64 @va_aligned_register(i64 %a, i128 %b, ...) +- +-define void @va_aligned_register_caller() nounwind { +-; LA64-FPELIM-LABEL: va_aligned_register_caller: +-; LA64-FPELIM: # %bb.0: +-; LA64-FPELIM-NEXT: addi.d $sp, $sp, -16 +-; LA64-FPELIM-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-FPELIM-NEXT: lu12i.w $a0, 335544 +-; LA64-FPELIM-NEXT: ori $a0, $a0, 1311 +-; LA64-FPELIM-NEXT: lu32i.d $a0, 335544 +-; LA64-FPELIM-NEXT: lu52i.d $a4, $a0, -328 +-; LA64-FPELIM-NEXT: lu12i.w $a0, -503317 +-; LA64-FPELIM-NEXT: ori $a0, $a0, 2129 +-; LA64-FPELIM-NEXT: lu32i.d $a0, 37355 +-; LA64-FPELIM-NEXT: lu52i.d $a5, $a0, 1024 +-; LA64-FPELIM-NEXT: ori $a0, $zero, 2 +-; LA64-FPELIM-NEXT: ori $a1, $zero, 1111 +-; LA64-FPELIM-NEXT: move $a2, $zero +-; LA64-FPELIM-NEXT: bl %plt(va_aligned_register) +-; LA64-FPELIM-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-FPELIM-NEXT: addi.d $sp, $sp, 16 +-; LA64-FPELIM-NEXT: ret +-; +-; LA64-WITHFP-LABEL: va_aligned_register_caller: +-; LA64-WITHFP: # %bb.0: +-; LA64-WITHFP-NEXT: addi.d $sp, $sp, -16 +-; LA64-WITHFP-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +-; LA64-WITHFP-NEXT: st.d $fp, $sp, 0 # 8-byte Folded Spill +-; LA64-WITHFP-NEXT: addi.d $fp, $sp, 16 +-; LA64-WITHFP-NEXT: lu12i.w $a0, 335544 +-; LA64-WITHFP-NEXT: ori $a0, $a0, 1311 +-; LA64-WITHFP-NEXT: lu32i.d $a0, 335544 +-; LA64-WITHFP-NEXT: lu52i.d $a4, $a0, -328 +-; LA64-WITHFP-NEXT: lu12i.w $a0, -503317 +-; LA64-WITHFP-NEXT: ori $a0, $a0, 2129 +-; LA64-WITHFP-NEXT: lu32i.d $a0, 37355 +-; LA64-WITHFP-NEXT: lu52i.d $a5, $a0, 1024 +-; LA64-WITHFP-NEXT: ori $a0, $zero, 2 +-; LA64-WITHFP-NEXT: ori $a1, $zero, 1111 +-; LA64-WITHFP-NEXT: move $a2, $zero +-; LA64-WITHFP-NEXT: bl %plt(va_aligned_register) +-; LA64-WITHFP-NEXT: ld.d $fp, $sp, 0 # 8-byte Folded Reload +-; LA64-WITHFP-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +-; LA64-WITHFP-NEXT: addi.d $sp, $sp, 16 +-; LA64-WITHFP-NEXT: ret +- %1 = call i64 (i64, i128, ...) @va_aligned_register(i64 2, i128 1111, +- fp128 0xLEB851EB851EB851F400091EB851EB851) +- ret void +-} +- +-;; Check 2*GRLen values are aligned appropriately when passed on the stack +-;; in a vararg call +- +-declare i32 @va_aligned_stack_callee(i32, ...) +- +-define void @va_aligned_stack_caller() nounwind { +-; LA64-FPELIM-LABEL: va_aligned_stack_caller: +-; LA64-FPELIM: # %bb.0: +-; LA64-FPELIM-NEXT: addi.d $sp, $sp, -112 +-; LA64-FPELIM-NEXT: st.d $ra, $sp, 104 # 8-byte Folded Spill +-; LA64-FPELIM-NEXT: ori $a0, $zero, 17 +-; LA64-FPELIM-NEXT: st.d $a0, $sp, 48 +-; LA64-FPELIM-NEXT: ori $a0, $zero, 16 +-; LA64-FPELIM-NEXT: st.d $a0, $sp, 40 +-; LA64-FPELIM-NEXT: ori $a0, $zero, 15 +-; LA64-FPELIM-NEXT: st.d $a0, $sp, 32 +-; LA64-FPELIM-NEXT: ori $a0, $zero, 14 +-; LA64-FPELIM-NEXT: st.d $a0, $sp, 0 +-; LA64-FPELIM-NEXT: lu12i.w $a0, -503317 +-; LA64-FPELIM-NEXT: ori $a0, $a0, 2129 +-; LA64-FPELIM-NEXT: lu32i.d $a0, 37355 +-; LA64-FPELIM-NEXT: lu52i.d $a0, $a0, 1024 +-; LA64-FPELIM-NEXT: st.d $a0, $sp, 24 +-; LA64-FPELIM-NEXT: lu12i.w $a0, 335544 +-; LA64-FPELIM-NEXT: ori $a0, $a0, 1311 +-; LA64-FPELIM-NEXT: lu32i.d $a0, 335544 +-; LA64-FPELIM-NEXT: lu52i.d $a0, $a0, -328 +-; LA64-FPELIM-NEXT: st.d $a0, $sp, 16 +-; LA64-FPELIM-NEXT: ori $a0, $zero, 1000 +-; LA64-FPELIM-NEXT: st.d $a0, $sp, 64 +-; LA64-FPELIM-NEXT: st.d $zero, $sp, 88 +-; LA64-FPELIM-NEXT: st.d $zero, $sp, 80 +-; LA64-FPELIM-NEXT: st.d $zero, $sp, 72 +-; LA64-FPELIM-NEXT: ori $a1, $zero, 11 +-; LA64-FPELIM-NEXT: addi.d $a2, $sp, 64 +-; LA64-FPELIM-NEXT: ori $a3, $zero, 12 +-; LA64-FPELIM-NEXT: ori $a4, $zero, 13 +-; LA64-FPELIM-NEXT: ori $a0, $zero, 1 +-; LA64-FPELIM-NEXT: move $a6, $zero +-; LA64-FPELIM-NEXT: move $a7, $a0 +-; LA64-FPELIM-NEXT: bl %plt(va_aligned_stack_callee) +-; LA64-FPELIM-NEXT: ld.d $ra, $sp, 104 # 8-byte Folded Reload +-; LA64-FPELIM-NEXT: addi.d $sp, $sp, 112 +-; LA64-FPELIM-NEXT: ret +-; +-; LA64-WITHFP-LABEL: va_aligned_stack_caller: +-; LA64-WITHFP: # %bb.0: +-; LA64-WITHFP-NEXT: addi.d $sp, $sp, -112 +-; LA64-WITHFP-NEXT: st.d $ra, $sp, 104 # 8-byte Folded Spill +-; LA64-WITHFP-NEXT: st.d $fp, $sp, 96 # 8-byte Folded Spill +-; LA64-WITHFP-NEXT: addi.d $fp, $sp, 112 +-; LA64-WITHFP-NEXT: ori $a0, $zero, 17 +-; LA64-WITHFP-NEXT: st.d $a0, $sp, 48 +-; LA64-WITHFP-NEXT: ori $a0, $zero, 16 +-; LA64-WITHFP-NEXT: st.d $a0, $sp, 40 +-; LA64-WITHFP-NEXT: ori $a0, $zero, 15 +-; LA64-WITHFP-NEXT: st.d $a0, $sp, 32 +-; LA64-WITHFP-NEXT: ori $a0, $zero, 14 +-; LA64-WITHFP-NEXT: st.d $a0, $sp, 0 +-; LA64-WITHFP-NEXT: lu12i.w $a0, -503317 +-; LA64-WITHFP-NEXT: ori $a0, $a0, 2129 +-; LA64-WITHFP-NEXT: lu32i.d $a0, 37355 +-; LA64-WITHFP-NEXT: lu52i.d $a0, $a0, 1024 +-; LA64-WITHFP-NEXT: st.d $a0, $sp, 24 +-; LA64-WITHFP-NEXT: lu12i.w $a0, 335544 +-; LA64-WITHFP-NEXT: ori $a0, $a0, 1311 +-; LA64-WITHFP-NEXT: lu32i.d $a0, 335544 +-; LA64-WITHFP-NEXT: lu52i.d $a0, $a0, -328 +-; LA64-WITHFP-NEXT: st.d $a0, $sp, 16 +-; LA64-WITHFP-NEXT: ori $a0, $zero, 1000 +-; LA64-WITHFP-NEXT: st.d $a0, $fp, -48 +-; LA64-WITHFP-NEXT: st.d $zero, $fp, -24 +-; LA64-WITHFP-NEXT: st.d $zero, $fp, -32 +-; LA64-WITHFP-NEXT: st.d $zero, $fp, -40 +-; LA64-WITHFP-NEXT: ori $a1, $zero, 11 +-; LA64-WITHFP-NEXT: addi.d $a2, $fp, -48 +-; LA64-WITHFP-NEXT: ori $a3, $zero, 12 +-; LA64-WITHFP-NEXT: ori $a4, $zero, 13 +-; LA64-WITHFP-NEXT: ori $a0, $zero, 1 +-; LA64-WITHFP-NEXT: move $a6, $zero +-; LA64-WITHFP-NEXT: move $a7, $a0 +-; LA64-WITHFP-NEXT: bl %plt(va_aligned_stack_callee) +-; LA64-WITHFP-NEXT: ld.d $fp, $sp, 96 # 8-byte Folded Reload +-; LA64-WITHFP-NEXT: ld.d $ra, $sp, 104 # 8-byte Folded Reload +-; LA64-WITHFP-NEXT: addi.d $sp, $sp, 112 +-; LA64-WITHFP-NEXT: ret +- %1 = call i32 (i32, ...) @va_aligned_stack_callee(i32 1, i32 11, +- i256 1000, i32 12, i32 13, i128 18446744073709551616, i32 14, +- fp128 0xLEB851EB851EB851F400091EB851EB851, i64 15, +- [2 x i64] [i64 16, i64 17]) +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/vector-fp-imm.ll b/llvm/test/CodeGen/LoongArch/vector-fp-imm.ll +deleted file mode 100644 +index 8009866d3..000000000 +--- a/llvm/test/CodeGen/LoongArch/vector-fp-imm.ll ++++ /dev/null +@@ -1,895 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --mtriple=loongarch32 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA32F +-; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32D +-; RUN: llc --mtriple=loongarch64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA64F +-; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64D +- +-;; TODO: Merge the offset of address calculation into the offset field of instructions. +- +-%f2 = type <2 x float> +-%f4 = type <4 x float> +-%f8 = type <8 x float> +-%d2 = type <2 x double> +-%d4 = type <4 x double> +-%d8 = type <8 x double> +- +-define void @test_zero(ptr %P, ptr %S) nounwind { +-; LA32F-LABEL: test_zero: +-; LA32F: # %bb.0: +-; LA32F-NEXT: fld.s $fa0, $a0, 12 +-; LA32F-NEXT: movgr2fr.w $fa1, $zero +-; LA32F-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA32F-NEXT: fst.s $fa0, $a1, 12 +-; LA32F-NEXT: fld.s $fa0, $a0, 8 +-; LA32F-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA32F-NEXT: fst.s $fa0, $a1, 8 +-; LA32F-NEXT: fld.s $fa0, $a0, 4 +-; LA32F-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA32F-NEXT: fst.s $fa0, $a1, 4 +-; LA32F-NEXT: fld.s $fa0, $a0, 0 +-; LA32F-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA32F-NEXT: fst.s $fa0, $a1, 0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: test_zero: +-; LA32D: # %bb.0: +-; LA32D-NEXT: fld.s $fa0, $a0, 12 +-; LA32D-NEXT: movgr2fr.w $fa1, $zero +-; LA32D-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA32D-NEXT: fst.s $fa0, $a1, 12 +-; LA32D-NEXT: fld.s $fa0, $a0, 8 +-; LA32D-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA32D-NEXT: fst.s $fa0, $a1, 8 +-; LA32D-NEXT: fld.s $fa0, $a0, 4 +-; LA32D-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA32D-NEXT: fst.s $fa0, $a1, 4 +-; LA32D-NEXT: fld.s $fa0, $a0, 0 +-; LA32D-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA32D-NEXT: fst.s $fa0, $a1, 0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: test_zero: +-; LA64F: # %bb.0: +-; LA64F-NEXT: fld.s $fa0, $a0, 12 +-; LA64F-NEXT: movgr2fr.w $fa1, $zero +-; LA64F-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA64F-NEXT: fst.s $fa0, $a1, 12 +-; LA64F-NEXT: fld.s $fa0, $a0, 8 +-; LA64F-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA64F-NEXT: fst.s $fa0, $a1, 8 +-; LA64F-NEXT: fld.s $fa0, $a0, 4 +-; LA64F-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA64F-NEXT: fst.s $fa0, $a1, 4 +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA64F-NEXT: fst.s $fa0, $a1, 0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: test_zero: +-; LA64D: # %bb.0: +-; LA64D-NEXT: fld.s $fa0, $a0, 12 +-; LA64D-NEXT: movgr2fr.w $fa1, $zero +-; LA64D-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA64D-NEXT: fst.s $fa0, $a1, 12 +-; LA64D-NEXT: fld.s $fa0, $a0, 8 +-; LA64D-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA64D-NEXT: fst.s $fa0, $a1, 8 +-; LA64D-NEXT: fld.s $fa0, $a0, 4 +-; LA64D-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA64D-NEXT: fst.s $fa0, $a1, 4 +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA64D-NEXT: fst.s $fa0, $a1, 0 +-; LA64D-NEXT: ret +- %p = load %f4, ptr %P +- %R = fadd %f4 %p, zeroinitializer +- store %f4 %R, ptr %S +- ret void +-} +- +-define void @test_f2(ptr %P, ptr %S) nounwind { +-; LA32F-LABEL: test_f2: +-; LA32F: # %bb.0: +-; LA32F-NEXT: pcalau12i $a2, %pc_hi20(.LCPI1_0) +-; LA32F-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI1_0) +-; LA32F-NEXT: fld.s $fa0, $a2, 0 +-; LA32F-NEXT: fld.s $fa1, $a0, 4 +-; LA32F-NEXT: fadd.s $fa0, $fa1, $fa0 +-; LA32F-NEXT: fst.s $fa0, $a1, 4 +-; LA32F-NEXT: fld.s $fa0, $a0, 0 +-; LA32F-NEXT: addi.w $a0, $zero, 1 +-; LA32F-NEXT: movgr2fr.w $fa1, $a0 +-; LA32F-NEXT: ffint.s.w $fa1, $fa1 +-; LA32F-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA32F-NEXT: fst.s $fa0, $a1, 0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: test_f2: +-; LA32D: # %bb.0: +-; LA32D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI1_0) +-; LA32D-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI1_0) +-; LA32D-NEXT: fld.s $fa0, $a2, 0 +-; LA32D-NEXT: fld.s $fa1, $a0, 4 +-; LA32D-NEXT: fadd.s $fa0, $fa1, $fa0 +-; LA32D-NEXT: fst.s $fa0, $a1, 4 +-; LA32D-NEXT: fld.s $fa0, $a0, 0 +-; LA32D-NEXT: addi.w $a0, $zero, 1 +-; LA32D-NEXT: movgr2fr.w $fa1, $a0 +-; LA32D-NEXT: ffint.s.w $fa1, $fa1 +-; LA32D-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA32D-NEXT: fst.s $fa0, $a1, 0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: test_f2: +-; LA64F: # %bb.0: +-; LA64F-NEXT: pcalau12i $a2, %pc_hi20(.LCPI1_0) +-; LA64F-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI1_0) +-; LA64F-NEXT: fld.s $fa0, $a2, 0 +-; LA64F-NEXT: fld.s $fa1, $a0, 4 +-; LA64F-NEXT: fadd.s $fa0, $fa1, $fa0 +-; LA64F-NEXT: fst.s $fa0, $a1, 4 +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: addi.w $a0, $zero, 1 +-; LA64F-NEXT: movgr2fr.w $fa1, $a0 +-; LA64F-NEXT: ffint.s.w $fa1, $fa1 +-; LA64F-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA64F-NEXT: fst.s $fa0, $a1, 0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: test_f2: +-; LA64D: # %bb.0: +-; LA64D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI1_0) +-; LA64D-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI1_0) +-; LA64D-NEXT: fld.s $fa0, $a2, 0 +-; LA64D-NEXT: fld.s $fa1, $a0, 4 +-; LA64D-NEXT: fadd.s $fa0, $fa1, $fa0 +-; LA64D-NEXT: fst.s $fa0, $a1, 4 +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: addi.w $a0, $zero, 1 +-; LA64D-NEXT: movgr2fr.w $fa1, $a0 +-; LA64D-NEXT: ffint.s.w $fa1, $fa1 +-; LA64D-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA64D-NEXT: fst.s $fa0, $a1, 0 +-; LA64D-NEXT: ret +- %p = load %f2, ptr %P +- %R = fadd %f2 %p, < float 1.000000e+00, float 2.000000e+00 > +- store %f2 %R, ptr %S +- ret void +-} +- +-define void @test_f4(ptr %P, ptr %S) nounwind { +-; LA32F-LABEL: test_f4: +-; LA32F: # %bb.0: +-; LA32F-NEXT: pcalau12i $a2, %pc_hi20(.LCPI2_0) +-; LA32F-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI2_0) +-; LA32F-NEXT: fld.s $fa0, $a2, 0 +-; LA32F-NEXT: fld.s $fa1, $a0, 4 +-; LA32F-NEXT: fadd.s $fa0, $fa1, $fa0 +-; LA32F-NEXT: pcalau12i $a2, %pc_hi20(.LCPI2_1) +-; LA32F-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI2_1) +-; LA32F-NEXT: fld.s $fa1, $a2, 0 +-; LA32F-NEXT: fld.s $fa2, $a0, 8 +-; LA32F-NEXT: fadd.s $fa1, $fa2, $fa1 +-; LA32F-NEXT: pcalau12i $a2, %pc_hi20(.LCPI2_2) +-; LA32F-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI2_2) +-; LA32F-NEXT: fld.s $fa2, $a2, 0 +-; LA32F-NEXT: fld.s $fa3, $a0, 12 +-; LA32F-NEXT: fadd.s $fa2, $fa3, $fa2 +-; LA32F-NEXT: fst.s $fa2, $a1, 12 +-; LA32F-NEXT: fst.s $fa1, $a1, 8 +-; LA32F-NEXT: fst.s $fa0, $a1, 4 +-; LA32F-NEXT: fld.s $fa0, $a0, 0 +-; LA32F-NEXT: addi.w $a0, $zero, 1 +-; LA32F-NEXT: movgr2fr.w $fa1, $a0 +-; LA32F-NEXT: ffint.s.w $fa1, $fa1 +-; LA32F-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA32F-NEXT: fst.s $fa0, $a1, 0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: test_f4: +-; LA32D: # %bb.0: +-; LA32D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI2_0) +-; LA32D-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI2_0) +-; LA32D-NEXT: fld.s $fa0, $a2, 0 +-; LA32D-NEXT: fld.s $fa1, $a0, 4 +-; LA32D-NEXT: fadd.s $fa0, $fa1, $fa0 +-; LA32D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI2_1) +-; LA32D-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI2_1) +-; LA32D-NEXT: fld.s $fa1, $a2, 0 +-; LA32D-NEXT: fld.s $fa2, $a0, 8 +-; LA32D-NEXT: fadd.s $fa1, $fa2, $fa1 +-; LA32D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI2_2) +-; LA32D-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI2_2) +-; LA32D-NEXT: fld.s $fa2, $a2, 0 +-; LA32D-NEXT: fld.s $fa3, $a0, 12 +-; LA32D-NEXT: fadd.s $fa2, $fa3, $fa2 +-; LA32D-NEXT: fst.s $fa2, $a1, 12 +-; LA32D-NEXT: fst.s $fa1, $a1, 8 +-; LA32D-NEXT: fst.s $fa0, $a1, 4 +-; LA32D-NEXT: fld.s $fa0, $a0, 0 +-; LA32D-NEXT: addi.w $a0, $zero, 1 +-; LA32D-NEXT: movgr2fr.w $fa1, $a0 +-; LA32D-NEXT: ffint.s.w $fa1, $fa1 +-; LA32D-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA32D-NEXT: fst.s $fa0, $a1, 0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: test_f4: +-; LA64F: # %bb.0: +-; LA64F-NEXT: pcalau12i $a2, %pc_hi20(.LCPI2_0) +-; LA64F-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI2_0) +-; LA64F-NEXT: fld.s $fa0, $a2, 0 +-; LA64F-NEXT: fld.s $fa1, $a0, 4 +-; LA64F-NEXT: fadd.s $fa0, $fa1, $fa0 +-; LA64F-NEXT: pcalau12i $a2, %pc_hi20(.LCPI2_1) +-; LA64F-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI2_1) +-; LA64F-NEXT: fld.s $fa1, $a2, 0 +-; LA64F-NEXT: fld.s $fa2, $a0, 8 +-; LA64F-NEXT: fadd.s $fa1, $fa2, $fa1 +-; LA64F-NEXT: pcalau12i $a2, %pc_hi20(.LCPI2_2) +-; LA64F-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI2_2) +-; LA64F-NEXT: fld.s $fa2, $a2, 0 +-; LA64F-NEXT: fld.s $fa3, $a0, 12 +-; LA64F-NEXT: fadd.s $fa2, $fa3, $fa2 +-; LA64F-NEXT: fst.s $fa2, $a1, 12 +-; LA64F-NEXT: fst.s $fa1, $a1, 8 +-; LA64F-NEXT: fst.s $fa0, $a1, 4 +-; LA64F-NEXT: fld.s $fa0, $a0, 0 +-; LA64F-NEXT: addi.w $a0, $zero, 1 +-; LA64F-NEXT: movgr2fr.w $fa1, $a0 +-; LA64F-NEXT: ffint.s.w $fa1, $fa1 +-; LA64F-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA64F-NEXT: fst.s $fa0, $a1, 0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: test_f4: +-; LA64D: # %bb.0: +-; LA64D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI2_0) +-; LA64D-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI2_0) +-; LA64D-NEXT: fld.s $fa0, $a2, 0 +-; LA64D-NEXT: fld.s $fa1, $a0, 4 +-; LA64D-NEXT: fadd.s $fa0, $fa1, $fa0 +-; LA64D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI2_1) +-; LA64D-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI2_1) +-; LA64D-NEXT: fld.s $fa1, $a2, 0 +-; LA64D-NEXT: fld.s $fa2, $a0, 8 +-; LA64D-NEXT: fadd.s $fa1, $fa2, $fa1 +-; LA64D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI2_2) +-; LA64D-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI2_2) +-; LA64D-NEXT: fld.s $fa2, $a2, 0 +-; LA64D-NEXT: fld.s $fa3, $a0, 12 +-; LA64D-NEXT: fadd.s $fa2, $fa3, $fa2 +-; LA64D-NEXT: fst.s $fa2, $a1, 12 +-; LA64D-NEXT: fst.s $fa1, $a1, 8 +-; LA64D-NEXT: fst.s $fa0, $a1, 4 +-; LA64D-NEXT: fld.s $fa0, $a0, 0 +-; LA64D-NEXT: addi.w $a0, $zero, 1 +-; LA64D-NEXT: movgr2fr.w $fa1, $a0 +-; LA64D-NEXT: ffint.s.w $fa1, $fa1 +-; LA64D-NEXT: fadd.s $fa0, $fa0, $fa1 +-; LA64D-NEXT: fst.s $fa0, $a1, 0 +-; LA64D-NEXT: ret +- %p = load %f4, ptr %P +- %R = fadd %f4 %p, < float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00 > +- store %f4 %R, ptr %S +- ret void +-} +- +-define void @test_f8(ptr %P, ptr %S) nounwind { +-; LA32F-LABEL: test_f8: +-; LA32F: # %bb.0: +-; LA32F-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_0) +-; LA32F-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI3_0) +-; LA32F-NEXT: fld.s $fa0, $a2, 0 +-; LA32F-NEXT: fld.s $fa1, $a0, 4 +-; LA32F-NEXT: fadd.s $fa1, $fa1, $fa0 +-; LA32F-NEXT: fld.s $fa2, $a0, 20 +-; LA32F-NEXT: fadd.s $fa0, $fa2, $fa0 +-; LA32F-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_1) +-; LA32F-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI3_1) +-; LA32F-NEXT: fld.s $fa2, $a2, 0 +-; LA32F-NEXT: fld.s $fa3, $a0, 8 +-; LA32F-NEXT: fadd.s $fa3, $fa3, $fa2 +-; LA32F-NEXT: fld.s $fa4, $a0, 24 +-; LA32F-NEXT: fadd.s $fa2, $fa4, $fa2 +-; LA32F-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_2) +-; LA32F-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI3_2) +-; LA32F-NEXT: fld.s $fa4, $a2, 0 +-; LA32F-NEXT: fld.s $fa5, $a0, 12 +-; LA32F-NEXT: fadd.s $fa5, $fa5, $fa4 +-; LA32F-NEXT: fld.s $fa6, $a0, 28 +-; LA32F-NEXT: fadd.s $fa4, $fa6, $fa4 +-; LA32F-NEXT: fst.s $fa4, $a1, 28 +-; LA32F-NEXT: fst.s $fa2, $a1, 24 +-; LA32F-NEXT: fst.s $fa0, $a1, 20 +-; LA32F-NEXT: fst.s $fa5, $a1, 12 +-; LA32F-NEXT: fst.s $fa3, $a1, 8 +-; LA32F-NEXT: fst.s $fa1, $a1, 4 +-; LA32F-NEXT: addi.w $a2, $zero, 1 +-; LA32F-NEXT: movgr2fr.w $fa0, $a2 +-; LA32F-NEXT: ffint.s.w $fa0, $fa0 +-; LA32F-NEXT: fld.s $fa1, $a0, 16 +-; LA32F-NEXT: fadd.s $fa1, $fa1, $fa0 +-; LA32F-NEXT: fst.s $fa1, $a1, 16 +-; LA32F-NEXT: fld.s $fa1, $a0, 0 +-; LA32F-NEXT: fadd.s $fa0, $fa1, $fa0 +-; LA32F-NEXT: fst.s $fa0, $a1, 0 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: test_f8: +-; LA32D: # %bb.0: +-; LA32D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_0) +-; LA32D-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI3_0) +-; LA32D-NEXT: fld.s $fa0, $a2, 0 +-; LA32D-NEXT: fld.s $fa1, $a0, 4 +-; LA32D-NEXT: fadd.s $fa1, $fa1, $fa0 +-; LA32D-NEXT: fld.s $fa2, $a0, 20 +-; LA32D-NEXT: fadd.s $fa0, $fa2, $fa0 +-; LA32D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_1) +-; LA32D-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI3_1) +-; LA32D-NEXT: fld.s $fa2, $a2, 0 +-; LA32D-NEXT: fld.s $fa3, $a0, 8 +-; LA32D-NEXT: fadd.s $fa3, $fa3, $fa2 +-; LA32D-NEXT: fld.s $fa4, $a0, 24 +-; LA32D-NEXT: fadd.s $fa2, $fa4, $fa2 +-; LA32D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_2) +-; LA32D-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI3_2) +-; LA32D-NEXT: fld.s $fa4, $a2, 0 +-; LA32D-NEXT: fld.s $fa5, $a0, 12 +-; LA32D-NEXT: fadd.s $fa5, $fa5, $fa4 +-; LA32D-NEXT: fld.s $fa6, $a0, 28 +-; LA32D-NEXT: fadd.s $fa4, $fa6, $fa4 +-; LA32D-NEXT: fst.s $fa4, $a1, 28 +-; LA32D-NEXT: fst.s $fa2, $a1, 24 +-; LA32D-NEXT: fst.s $fa0, $a1, 20 +-; LA32D-NEXT: fst.s $fa5, $a1, 12 +-; LA32D-NEXT: fst.s $fa3, $a1, 8 +-; LA32D-NEXT: fst.s $fa1, $a1, 4 +-; LA32D-NEXT: addi.w $a2, $zero, 1 +-; LA32D-NEXT: movgr2fr.w $fa0, $a2 +-; LA32D-NEXT: ffint.s.w $fa0, $fa0 +-; LA32D-NEXT: fld.s $fa1, $a0, 16 +-; LA32D-NEXT: fadd.s $fa1, $fa1, $fa0 +-; LA32D-NEXT: fst.s $fa1, $a1, 16 +-; LA32D-NEXT: fld.s $fa1, $a0, 0 +-; LA32D-NEXT: fadd.s $fa0, $fa1, $fa0 +-; LA32D-NEXT: fst.s $fa0, $a1, 0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: test_f8: +-; LA64F: # %bb.0: +-; LA64F-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_0) +-; LA64F-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI3_0) +-; LA64F-NEXT: fld.s $fa0, $a2, 0 +-; LA64F-NEXT: fld.s $fa1, $a0, 4 +-; LA64F-NEXT: fadd.s $fa1, $fa1, $fa0 +-; LA64F-NEXT: fld.s $fa2, $a0, 20 +-; LA64F-NEXT: fadd.s $fa0, $fa2, $fa0 +-; LA64F-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_1) +-; LA64F-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI3_1) +-; LA64F-NEXT: fld.s $fa2, $a2, 0 +-; LA64F-NEXT: fld.s $fa3, $a0, 8 +-; LA64F-NEXT: fadd.s $fa3, $fa3, $fa2 +-; LA64F-NEXT: fld.s $fa4, $a0, 24 +-; LA64F-NEXT: fadd.s $fa2, $fa4, $fa2 +-; LA64F-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_2) +-; LA64F-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI3_2) +-; LA64F-NEXT: fld.s $fa4, $a2, 0 +-; LA64F-NEXT: fld.s $fa5, $a0, 12 +-; LA64F-NEXT: fadd.s $fa5, $fa5, $fa4 +-; LA64F-NEXT: fld.s $fa6, $a0, 28 +-; LA64F-NEXT: fadd.s $fa4, $fa6, $fa4 +-; LA64F-NEXT: fst.s $fa4, $a1, 28 +-; LA64F-NEXT: fst.s $fa2, $a1, 24 +-; LA64F-NEXT: fst.s $fa0, $a1, 20 +-; LA64F-NEXT: fst.s $fa5, $a1, 12 +-; LA64F-NEXT: fst.s $fa3, $a1, 8 +-; LA64F-NEXT: fst.s $fa1, $a1, 4 +-; LA64F-NEXT: addi.w $a2, $zero, 1 +-; LA64F-NEXT: movgr2fr.w $fa0, $a2 +-; LA64F-NEXT: ffint.s.w $fa0, $fa0 +-; LA64F-NEXT: fld.s $fa1, $a0, 16 +-; LA64F-NEXT: fadd.s $fa1, $fa1, $fa0 +-; LA64F-NEXT: fst.s $fa1, $a1, 16 +-; LA64F-NEXT: fld.s $fa1, $a0, 0 +-; LA64F-NEXT: fadd.s $fa0, $fa1, $fa0 +-; LA64F-NEXT: fst.s $fa0, $a1, 0 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: test_f8: +-; LA64D: # %bb.0: +-; LA64D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_0) +-; LA64D-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI3_0) +-; LA64D-NEXT: fld.s $fa0, $a2, 0 +-; LA64D-NEXT: fld.s $fa1, $a0, 4 +-; LA64D-NEXT: fadd.s $fa1, $fa1, $fa0 +-; LA64D-NEXT: fld.s $fa2, $a0, 20 +-; LA64D-NEXT: fadd.s $fa0, $fa2, $fa0 +-; LA64D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_1) +-; LA64D-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI3_1) +-; LA64D-NEXT: fld.s $fa2, $a2, 0 +-; LA64D-NEXT: fld.s $fa3, $a0, 8 +-; LA64D-NEXT: fadd.s $fa3, $fa3, $fa2 +-; LA64D-NEXT: fld.s $fa4, $a0, 24 +-; LA64D-NEXT: fadd.s $fa2, $fa4, $fa2 +-; LA64D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_2) +-; LA64D-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI3_2) +-; LA64D-NEXT: fld.s $fa4, $a2, 0 +-; LA64D-NEXT: fld.s $fa5, $a0, 12 +-; LA64D-NEXT: fadd.s $fa5, $fa5, $fa4 +-; LA64D-NEXT: fld.s $fa6, $a0, 28 +-; LA64D-NEXT: fadd.s $fa4, $fa6, $fa4 +-; LA64D-NEXT: fst.s $fa4, $a1, 28 +-; LA64D-NEXT: fst.s $fa2, $a1, 24 +-; LA64D-NEXT: fst.s $fa0, $a1, 20 +-; LA64D-NEXT: fst.s $fa5, $a1, 12 +-; LA64D-NEXT: fst.s $fa3, $a1, 8 +-; LA64D-NEXT: fst.s $fa1, $a1, 4 +-; LA64D-NEXT: addi.w $a2, $zero, 1 +-; LA64D-NEXT: movgr2fr.w $fa0, $a2 +-; LA64D-NEXT: ffint.s.w $fa0, $fa0 +-; LA64D-NEXT: fld.s $fa1, $a0, 16 +-; LA64D-NEXT: fadd.s $fa1, $fa1, $fa0 +-; LA64D-NEXT: fst.s $fa1, $a1, 16 +-; LA64D-NEXT: fld.s $fa1, $a0, 0 +-; LA64D-NEXT: fadd.s $fa0, $fa1, $fa0 +-; LA64D-NEXT: fst.s $fa0, $a1, 0 +-; LA64D-NEXT: ret +- %p = load %f8, ptr %P +- %R = fadd %f8 %p, < float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00, float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00 > +- store %f8 %R, ptr %S +- ret void +-} +- +-define void @test_d2(ptr %P, ptr %S) nounwind { +-; LA32F-LABEL: test_d2: +-; LA32F: # %bb.0: +-; LA32F-NEXT: addi.w $sp, $sp, -16 +-; LA32F-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32F-NEXT: st.w $fp, $sp, 8 # 4-byte Folded Spill +-; LA32F-NEXT: st.w $s0, $sp, 4 # 4-byte Folded Spill +-; LA32F-NEXT: move $fp, $a1 +-; LA32F-NEXT: move $s0, $a0 +-; LA32F-NEXT: ld.w $a0, $a0, 8 +-; LA32F-NEXT: ld.w $a1, $s0, 12 +-; LA32F-NEXT: lu12i.w $a3, 262144 +-; LA32F-NEXT: move $a2, $zero +-; LA32F-NEXT: bl %plt(__adddf3) +-; LA32F-NEXT: st.w $a0, $fp, 8 +-; LA32F-NEXT: st.w $a1, $fp, 12 +-; LA32F-NEXT: ld.w $a0, $s0, 0 +-; LA32F-NEXT: ld.w $a1, $s0, 4 +-; LA32F-NEXT: lu12i.w $a3, 261888 +-; LA32F-NEXT: move $a2, $zero +-; LA32F-NEXT: bl %plt(__adddf3) +-; LA32F-NEXT: st.w $a0, $fp, 0 +-; LA32F-NEXT: st.w $a1, $fp, 4 +-; LA32F-NEXT: ld.w $s0, $sp, 4 # 4-byte Folded Reload +-; LA32F-NEXT: ld.w $fp, $sp, 8 # 4-byte Folded Reload +-; LA32F-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32F-NEXT: addi.w $sp, $sp, 16 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: test_d2: +-; LA32D: # %bb.0: +-; LA32D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI4_0) +-; LA32D-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI4_0) +-; LA32D-NEXT: fld.d $fa0, $a2, 0 +-; LA32D-NEXT: fld.d $fa1, $a0, 8 +-; LA32D-NEXT: fadd.d $fa0, $fa1, $fa0 +-; LA32D-NEXT: fst.d $fa0, $a1, 8 +-; LA32D-NEXT: fld.d $fa0, $a0, 0 +-; LA32D-NEXT: addi.w $a0, $zero, 1 +-; LA32D-NEXT: movgr2fr.w $fa1, $a0 +-; LA32D-NEXT: ffint.s.w $fa1, $fa1 +-; LA32D-NEXT: fcvt.d.s $fa1, $fa1 +-; LA32D-NEXT: fadd.d $fa0, $fa0, $fa1 +-; LA32D-NEXT: fst.d $fa0, $a1, 0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: test_d2: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -32 +-; LA64F-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 16 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 8 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a1 +-; LA64F-NEXT: move $s0, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 8 +-; LA64F-NEXT: lu52i.d $a1, $zero, 1024 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $fp, 8 +-; LA64F-NEXT: ld.d $a0, $s0, 0 +-; LA64F-NEXT: lu52i.d $a1, $zero, 1023 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $fp, 0 +-; LA64F-NEXT: ld.d $s0, $sp, 8 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 16 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 32 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: test_d2: +-; LA64D: # %bb.0: +-; LA64D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI4_0) +-; LA64D-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI4_0) +-; LA64D-NEXT: fld.d $fa0, $a2, 0 +-; LA64D-NEXT: fld.d $fa1, $a0, 8 +-; LA64D-NEXT: fadd.d $fa0, $fa1, $fa0 +-; LA64D-NEXT: fst.d $fa0, $a1, 8 +-; LA64D-NEXT: fld.d $fa0, $a0, 0 +-; LA64D-NEXT: addi.d $a0, $zero, 1 +-; LA64D-NEXT: movgr2fr.d $fa1, $a0 +-; LA64D-NEXT: ffint.d.l $fa1, $fa1 +-; LA64D-NEXT: fadd.d $fa0, $fa0, $fa1 +-; LA64D-NEXT: fst.d $fa0, $a1, 0 +-; LA64D-NEXT: ret +- %p = load %d2, ptr %P +- %R = fadd %d2 %p, < double 1.000000e+00, double 2.000000e+00 > +- store %d2 %R, ptr %S +- ret void +-} +- +-define void @test_d4(ptr %P, ptr %S) nounwind { +-; LA32F-LABEL: test_d4: +-; LA32F: # %bb.0: +-; LA32F-NEXT: addi.w $sp, $sp, -16 +-; LA32F-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +-; LA32F-NEXT: st.w $fp, $sp, 8 # 4-byte Folded Spill +-; LA32F-NEXT: st.w $s0, $sp, 4 # 4-byte Folded Spill +-; LA32F-NEXT: move $fp, $a1 +-; LA32F-NEXT: move $s0, $a0 +-; LA32F-NEXT: ld.w $a0, $a0, 24 +-; LA32F-NEXT: ld.w $a1, $s0, 28 +-; LA32F-NEXT: lu12i.w $a3, 262400 +-; LA32F-NEXT: move $a2, $zero +-; LA32F-NEXT: bl %plt(__adddf3) +-; LA32F-NEXT: st.w $a0, $fp, 24 +-; LA32F-NEXT: st.w $a1, $fp, 28 +-; LA32F-NEXT: ld.w $a0, $s0, 16 +-; LA32F-NEXT: ld.w $a1, $s0, 20 +-; LA32F-NEXT: lu12i.w $a3, 262272 +-; LA32F-NEXT: move $a2, $zero +-; LA32F-NEXT: bl %plt(__adddf3) +-; LA32F-NEXT: st.w $a0, $fp, 16 +-; LA32F-NEXT: st.w $a1, $fp, 20 +-; LA32F-NEXT: ld.w $a0, $s0, 8 +-; LA32F-NEXT: ld.w $a1, $s0, 12 +-; LA32F-NEXT: lu12i.w $a3, 262144 +-; LA32F-NEXT: move $a2, $zero +-; LA32F-NEXT: bl %plt(__adddf3) +-; LA32F-NEXT: st.w $a0, $fp, 8 +-; LA32F-NEXT: st.w $a1, $fp, 12 +-; LA32F-NEXT: ld.w $a0, $s0, 0 +-; LA32F-NEXT: ld.w $a1, $s0, 4 +-; LA32F-NEXT: lu12i.w $a3, 261888 +-; LA32F-NEXT: move $a2, $zero +-; LA32F-NEXT: bl %plt(__adddf3) +-; LA32F-NEXT: st.w $a0, $fp, 0 +-; LA32F-NEXT: st.w $a1, $fp, 4 +-; LA32F-NEXT: ld.w $s0, $sp, 4 # 4-byte Folded Reload +-; LA32F-NEXT: ld.w $fp, $sp, 8 # 4-byte Folded Reload +-; LA32F-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +-; LA32F-NEXT: addi.w $sp, $sp, 16 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: test_d4: +-; LA32D: # %bb.0: +-; LA32D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI5_0) +-; LA32D-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI5_0) +-; LA32D-NEXT: fld.d $fa0, $a2, 0 +-; LA32D-NEXT: fld.d $fa1, $a0, 8 +-; LA32D-NEXT: fadd.d $fa0, $fa1, $fa0 +-; LA32D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI5_1) +-; LA32D-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI5_1) +-; LA32D-NEXT: fld.d $fa1, $a2, 0 +-; LA32D-NEXT: fld.d $fa2, $a0, 16 +-; LA32D-NEXT: fadd.d $fa1, $fa2, $fa1 +-; LA32D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI5_2) +-; LA32D-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI5_2) +-; LA32D-NEXT: fld.d $fa2, $a2, 0 +-; LA32D-NEXT: fld.d $fa3, $a0, 24 +-; LA32D-NEXT: fadd.d $fa2, $fa3, $fa2 +-; LA32D-NEXT: fst.d $fa2, $a1, 24 +-; LA32D-NEXT: fst.d $fa1, $a1, 16 +-; LA32D-NEXT: fst.d $fa0, $a1, 8 +-; LA32D-NEXT: fld.d $fa0, $a0, 0 +-; LA32D-NEXT: addi.w $a0, $zero, 1 +-; LA32D-NEXT: movgr2fr.w $fa1, $a0 +-; LA32D-NEXT: ffint.s.w $fa1, $fa1 +-; LA32D-NEXT: fcvt.d.s $fa1, $fa1 +-; LA32D-NEXT: fadd.d $fa0, $fa0, $fa1 +-; LA32D-NEXT: fst.d $fa0, $a1, 0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: test_d4: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -32 +-; LA64F-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 16 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 8 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a1 +-; LA64F-NEXT: move $s0, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 24 +-; LA64F-NEXT: lu52i.d $a1, $zero, 1025 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $fp, 24 +-; LA64F-NEXT: ld.d $a0, $s0, 8 +-; LA64F-NEXT: lu52i.d $a1, $zero, 1024 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $fp, 8 +-; LA64F-NEXT: ld.d $a0, $s0, 0 +-; LA64F-NEXT: lu52i.d $a1, $zero, 1023 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $fp, 0 +-; LA64F-NEXT: ld.d $a0, $s0, 16 +-; LA64F-NEXT: ori $a1, $zero, 0 +-; LA64F-NEXT: lu32i.d $a1, -524288 +-; LA64F-NEXT: lu52i.d $a1, $a1, 1024 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $fp, 16 +-; LA64F-NEXT: ld.d $s0, $sp, 8 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 16 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 32 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: test_d4: +-; LA64D: # %bb.0: +-; LA64D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI5_0) +-; LA64D-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI5_0) +-; LA64D-NEXT: fld.d $fa0, $a2, 0 +-; LA64D-NEXT: fld.d $fa1, $a0, 8 +-; LA64D-NEXT: fadd.d $fa0, $fa1, $fa0 +-; LA64D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI5_1) +-; LA64D-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI5_1) +-; LA64D-NEXT: fld.d $fa1, $a2, 0 +-; LA64D-NEXT: fld.d $fa2, $a0, 16 +-; LA64D-NEXT: fadd.d $fa1, $fa2, $fa1 +-; LA64D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI5_2) +-; LA64D-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI5_2) +-; LA64D-NEXT: fld.d $fa2, $a2, 0 +-; LA64D-NEXT: fld.d $fa3, $a0, 24 +-; LA64D-NEXT: fadd.d $fa2, $fa3, $fa2 +-; LA64D-NEXT: fst.d $fa2, $a1, 24 +-; LA64D-NEXT: fst.d $fa1, $a1, 16 +-; LA64D-NEXT: fst.d $fa0, $a1, 8 +-; LA64D-NEXT: fld.d $fa0, $a0, 0 +-; LA64D-NEXT: addi.d $a0, $zero, 1 +-; LA64D-NEXT: movgr2fr.d $fa1, $a0 +-; LA64D-NEXT: ffint.d.l $fa1, $fa1 +-; LA64D-NEXT: fadd.d $fa0, $fa0, $fa1 +-; LA64D-NEXT: fst.d $fa0, $a1, 0 +-; LA64D-NEXT: ret +- %p = load %d4, ptr %P +- %R = fadd %d4 %p, < double 1.000000e+00, double 2.000000e+00, double 3.000000e+00, double 4.000000e+00 > +- store %d4 %R, ptr %S +- ret void +-} +- +-define void @test_d8(ptr %P, ptr %S) nounwind { +-; LA32F-LABEL: test_d8: +-; LA32F: # %bb.0: +-; LA32F-NEXT: addi.w $sp, $sp, -32 +-; LA32F-NEXT: st.w $ra, $sp, 28 # 4-byte Folded Spill +-; LA32F-NEXT: st.w $fp, $sp, 24 # 4-byte Folded Spill +-; LA32F-NEXT: st.w $s0, $sp, 20 # 4-byte Folded Spill +-; LA32F-NEXT: st.w $s1, $sp, 16 # 4-byte Folded Spill +-; LA32F-NEXT: st.w $s2, $sp, 12 # 4-byte Folded Spill +-; LA32F-NEXT: st.w $s3, $sp, 8 # 4-byte Folded Spill +-; LA32F-NEXT: st.w $s4, $sp, 4 # 4-byte Folded Spill +-; LA32F-NEXT: move $fp, $a1 +-; LA32F-NEXT: move $s0, $a0 +-; LA32F-NEXT: ld.w $a0, $a0, 56 +-; LA32F-NEXT: ld.w $a1, $s0, 60 +-; LA32F-NEXT: lu12i.w $s1, 262400 +-; LA32F-NEXT: move $a2, $zero +-; LA32F-NEXT: move $a3, $s1 +-; LA32F-NEXT: bl %plt(__adddf3) +-; LA32F-NEXT: st.w $a0, $fp, 56 +-; LA32F-NEXT: st.w $a1, $fp, 60 +-; LA32F-NEXT: ld.w $a0, $s0, 48 +-; LA32F-NEXT: ld.w $a1, $s0, 52 +-; LA32F-NEXT: lu12i.w $s2, 262272 +-; LA32F-NEXT: move $a2, $zero +-; LA32F-NEXT: move $a3, $s2 +-; LA32F-NEXT: bl %plt(__adddf3) +-; LA32F-NEXT: st.w $a0, $fp, 48 +-; LA32F-NEXT: st.w $a1, $fp, 52 +-; LA32F-NEXT: ld.w $a0, $s0, 40 +-; LA32F-NEXT: ld.w $a1, $s0, 44 +-; LA32F-NEXT: lu12i.w $s3, 262144 +-; LA32F-NEXT: move $a2, $zero +-; LA32F-NEXT: move $a3, $s3 +-; LA32F-NEXT: bl %plt(__adddf3) +-; LA32F-NEXT: st.w $a0, $fp, 40 +-; LA32F-NEXT: st.w $a1, $fp, 44 +-; LA32F-NEXT: ld.w $a0, $s0, 32 +-; LA32F-NEXT: ld.w $a1, $s0, 36 +-; LA32F-NEXT: lu12i.w $s4, 261888 +-; LA32F-NEXT: move $a2, $zero +-; LA32F-NEXT: move $a3, $s4 +-; LA32F-NEXT: bl %plt(__adddf3) +-; LA32F-NEXT: st.w $a0, $fp, 32 +-; LA32F-NEXT: st.w $a1, $fp, 36 +-; LA32F-NEXT: ld.w $a0, $s0, 24 +-; LA32F-NEXT: ld.w $a1, $s0, 28 +-; LA32F-NEXT: move $a2, $zero +-; LA32F-NEXT: move $a3, $s1 +-; LA32F-NEXT: bl %plt(__adddf3) +-; LA32F-NEXT: st.w $a0, $fp, 24 +-; LA32F-NEXT: st.w $a1, $fp, 28 +-; LA32F-NEXT: ld.w $a0, $s0, 16 +-; LA32F-NEXT: ld.w $a1, $s0, 20 +-; LA32F-NEXT: move $a2, $zero +-; LA32F-NEXT: move $a3, $s2 +-; LA32F-NEXT: bl %plt(__adddf3) +-; LA32F-NEXT: st.w $a0, $fp, 16 +-; LA32F-NEXT: st.w $a1, $fp, 20 +-; LA32F-NEXT: ld.w $a0, $s0, 8 +-; LA32F-NEXT: ld.w $a1, $s0, 12 +-; LA32F-NEXT: move $a2, $zero +-; LA32F-NEXT: move $a3, $s3 +-; LA32F-NEXT: bl %plt(__adddf3) +-; LA32F-NEXT: st.w $a0, $fp, 8 +-; LA32F-NEXT: st.w $a1, $fp, 12 +-; LA32F-NEXT: ld.w $a0, $s0, 0 +-; LA32F-NEXT: ld.w $a1, $s0, 4 +-; LA32F-NEXT: move $a2, $zero +-; LA32F-NEXT: move $a3, $s4 +-; LA32F-NEXT: bl %plt(__adddf3) +-; LA32F-NEXT: st.w $a0, $fp, 0 +-; LA32F-NEXT: st.w $a1, $fp, 4 +-; LA32F-NEXT: ld.w $s4, $sp, 4 # 4-byte Folded Reload +-; LA32F-NEXT: ld.w $s3, $sp, 8 # 4-byte Folded Reload +-; LA32F-NEXT: ld.w $s2, $sp, 12 # 4-byte Folded Reload +-; LA32F-NEXT: ld.w $s1, $sp, 16 # 4-byte Folded Reload +-; LA32F-NEXT: ld.w $s0, $sp, 20 # 4-byte Folded Reload +-; LA32F-NEXT: ld.w $fp, $sp, 24 # 4-byte Folded Reload +-; LA32F-NEXT: ld.w $ra, $sp, 28 # 4-byte Folded Reload +-; LA32F-NEXT: addi.w $sp, $sp, 32 +-; LA32F-NEXT: ret +-; +-; LA32D-LABEL: test_d8: +-; LA32D: # %bb.0: +-; LA32D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI6_0) +-; LA32D-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI6_0) +-; LA32D-NEXT: fld.d $fa0, $a2, 0 +-; LA32D-NEXT: fld.d $fa1, $a0, 8 +-; LA32D-NEXT: fadd.d $fa1, $fa1, $fa0 +-; LA32D-NEXT: fld.d $fa2, $a0, 40 +-; LA32D-NEXT: fadd.d $fa0, $fa2, $fa0 +-; LA32D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI6_1) +-; LA32D-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI6_1) +-; LA32D-NEXT: fld.d $fa2, $a2, 0 +-; LA32D-NEXT: fld.d $fa3, $a0, 16 +-; LA32D-NEXT: fadd.d $fa3, $fa3, $fa2 +-; LA32D-NEXT: fld.d $fa4, $a0, 48 +-; LA32D-NEXT: fadd.d $fa2, $fa4, $fa2 +-; LA32D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI6_2) +-; LA32D-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI6_2) +-; LA32D-NEXT: fld.d $fa4, $a2, 0 +-; LA32D-NEXT: fld.d $fa5, $a0, 24 +-; LA32D-NEXT: fadd.d $fa5, $fa5, $fa4 +-; LA32D-NEXT: fld.d $fa6, $a0, 56 +-; LA32D-NEXT: fadd.d $fa4, $fa6, $fa4 +-; LA32D-NEXT: fst.d $fa4, $a1, 56 +-; LA32D-NEXT: fst.d $fa2, $a1, 48 +-; LA32D-NEXT: fst.d $fa0, $a1, 40 +-; LA32D-NEXT: fst.d $fa5, $a1, 24 +-; LA32D-NEXT: fst.d $fa3, $a1, 16 +-; LA32D-NEXT: fst.d $fa1, $a1, 8 +-; LA32D-NEXT: addi.w $a2, $zero, 1 +-; LA32D-NEXT: movgr2fr.w $fa0, $a2 +-; LA32D-NEXT: ffint.s.w $fa0, $fa0 +-; LA32D-NEXT: fcvt.d.s $fa0, $fa0 +-; LA32D-NEXT: fld.d $fa1, $a0, 32 +-; LA32D-NEXT: fadd.d $fa1, $fa1, $fa0 +-; LA32D-NEXT: fst.d $fa1, $a1, 32 +-; LA32D-NEXT: fld.d $fa1, $a0, 0 +-; LA32D-NEXT: fadd.d $fa0, $fa1, $fa0 +-; LA32D-NEXT: fst.d $fa0, $a1, 0 +-; LA32D-NEXT: ret +-; +-; LA64F-LABEL: test_d8: +-; LA64F: # %bb.0: +-; LA64F-NEXT: addi.d $sp, $sp, -48 +-; LA64F-NEXT: st.d $ra, $sp, 40 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $fp, $sp, 32 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s0, $sp, 24 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s1, $sp, 16 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s2, $sp, 8 # 8-byte Folded Spill +-; LA64F-NEXT: st.d $s3, $sp, 0 # 8-byte Folded Spill +-; LA64F-NEXT: move $fp, $a1 +-; LA64F-NEXT: move $s0, $a0 +-; LA64F-NEXT: ld.d $a0, $a0, 56 +-; LA64F-NEXT: lu52i.d $s1, $zero, 1025 +-; LA64F-NEXT: move $a1, $s1 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $fp, 56 +-; LA64F-NEXT: ld.d $a0, $s0, 40 +-; LA64F-NEXT: lu52i.d $s2, $zero, 1024 +-; LA64F-NEXT: move $a1, $s2 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $fp, 40 +-; LA64F-NEXT: ld.d $a0, $s0, 32 +-; LA64F-NEXT: lu52i.d $s3, $zero, 1023 +-; LA64F-NEXT: move $a1, $s3 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $fp, 32 +-; LA64F-NEXT: ld.d $a0, $s0, 24 +-; LA64F-NEXT: move $a1, $s1 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $fp, 24 +-; LA64F-NEXT: ld.d $a0, $s0, 8 +-; LA64F-NEXT: move $a1, $s2 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $fp, 8 +-; LA64F-NEXT: ld.d $a0, $s0, 0 +-; LA64F-NEXT: move $a1, $s3 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $fp, 0 +-; LA64F-NEXT: ori $a0, $zero, 0 +-; LA64F-NEXT: lu32i.d $a0, -524288 +-; LA64F-NEXT: lu52i.d $s1, $a0, 1024 +-; LA64F-NEXT: ld.d $a0, $s0, 48 +-; LA64F-NEXT: move $a1, $s1 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $fp, 48 +-; LA64F-NEXT: ld.d $a0, $s0, 16 +-; LA64F-NEXT: move $a1, $s1 +-; LA64F-NEXT: bl %plt(__adddf3) +-; LA64F-NEXT: st.d $a0, $fp, 16 +-; LA64F-NEXT: ld.d $s3, $sp, 0 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s2, $sp, 8 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s1, $sp, 16 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $s0, $sp, 24 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $fp, $sp, 32 # 8-byte Folded Reload +-; LA64F-NEXT: ld.d $ra, $sp, 40 # 8-byte Folded Reload +-; LA64F-NEXT: addi.d $sp, $sp, 48 +-; LA64F-NEXT: ret +-; +-; LA64D-LABEL: test_d8: +-; LA64D: # %bb.0: +-; LA64D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI6_0) +-; LA64D-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI6_0) +-; LA64D-NEXT: fld.d $fa0, $a2, 0 +-; LA64D-NEXT: fld.d $fa1, $a0, 8 +-; LA64D-NEXT: fadd.d $fa1, $fa1, $fa0 +-; LA64D-NEXT: fld.d $fa2, $a0, 40 +-; LA64D-NEXT: fadd.d $fa0, $fa2, $fa0 +-; LA64D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI6_1) +-; LA64D-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI6_1) +-; LA64D-NEXT: fld.d $fa2, $a2, 0 +-; LA64D-NEXT: fld.d $fa3, $a0, 16 +-; LA64D-NEXT: fadd.d $fa3, $fa3, $fa2 +-; LA64D-NEXT: fld.d $fa4, $a0, 48 +-; LA64D-NEXT: fadd.d $fa2, $fa4, $fa2 +-; LA64D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI6_2) +-; LA64D-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI6_2) +-; LA64D-NEXT: fld.d $fa4, $a2, 0 +-; LA64D-NEXT: fld.d $fa5, $a0, 24 +-; LA64D-NEXT: fadd.d $fa5, $fa5, $fa4 +-; LA64D-NEXT: fld.d $fa6, $a0, 56 +-; LA64D-NEXT: fadd.d $fa4, $fa6, $fa4 +-; LA64D-NEXT: fst.d $fa4, $a1, 56 +-; LA64D-NEXT: fst.d $fa2, $a1, 48 +-; LA64D-NEXT: fst.d $fa0, $a1, 40 +-; LA64D-NEXT: fst.d $fa5, $a1, 24 +-; LA64D-NEXT: fst.d $fa3, $a1, 16 +-; LA64D-NEXT: fst.d $fa1, $a1, 8 +-; LA64D-NEXT: addi.d $a2, $zero, 1 +-; LA64D-NEXT: movgr2fr.d $fa0, $a2 +-; LA64D-NEXT: ffint.d.l $fa0, $fa0 +-; LA64D-NEXT: fld.d $fa1, $a0, 32 +-; LA64D-NEXT: fadd.d $fa1, $fa1, $fa0 +-; LA64D-NEXT: fst.d $fa1, $a1, 32 +-; LA64D-NEXT: fld.d $fa1, $a0, 0 +-; LA64D-NEXT: fadd.d $fa0, $fa1, $fa0 +-; LA64D-NEXT: fst.d $fa0, $a1, 0 +-; LA64D-NEXT: ret +- %p = load %d8, ptr %P +- %R = fadd %d8 %p, < double 1.000000e+00, double 2.000000e+00, double 3.000000e+00, double 4.000000e+00, double 1.000000e+00, double 2.000000e+00, double 3.000000e+00, double 4.000000e+00 > +- store %d8 %R, ptr %S +- ret void +-} +diff --git a/llvm/test/CodeGen/LoongArch/xray-attribute-instrumentation.ll b/llvm/test/CodeGen/LoongArch/xray-attribute-instrumentation.ll +deleted file mode 100644 +index 09442216c..000000000 +--- a/llvm/test/CodeGen/LoongArch/xray-attribute-instrumentation.ll ++++ /dev/null +@@ -1,56 +0,0 @@ +-; RUN: llc --mtriple=loongarch64 %s -o - | FileCheck %s +-; RUN: llc --mtriple=loongarch64 -filetype=obj %s -o %t +-; RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=RELOC +- +-define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always" { +-; CHECK-LABEL: foo: +-; CHECK-LABEL: .Lfunc_begin0: +-; CHECK: .p2align 2 +-; CHECK-LABEL: .Lxray_sled_begin0: +-; CHECK-NEXT: b .Lxray_sled_end0 +-; CHECK-COUNT-11: nop +-; CHECK-LABEL: .Lxray_sled_end0: +- ret i32 0 +-; CHECK-LABEL: .Lxray_sled_begin1: +-; CHECK-NEXT: b .Lxray_sled_end1 +-; CHECK-COUNT-11: nop +-; CHECK-NEXT: .Lxray_sled_end1: +-; CHECK-NEXT: ret +-; CHECK-NEXT: .Lfunc_end0: +-} +- +-; CHECK-LABEL: .section xray_instr_map +-; CHECK-NEXT: .Lxray_sleds_start0: +-; CHECK-NEXT: [[TMP:.Ltmp[0-9]+]]: +-; CHECK-NEXT: .dword .Lxray_sled_begin0-[[TMP]] +-; CHECK-NEXT: .dword .Lfunc_begin0-([[TMP]]+8) +-; CHECK-NEXT: .byte 0x00 +-; CHECK-NEXT: .byte 0x01 +-; CHECK-NEXT: .byte 0x02 +-; CHECK-NEXT: .space 13 +-; CHECK-NEXT: [[TMP:.Ltmp[0-9]+]]: +-; CHECK-NEXT: .dword .Lxray_sled_begin1-[[TMP]] +-; CHECK-NEXT: .dword .Lfunc_begin0-([[TMP]]+8) +-; CHECK-NEXT: .byte 0x01 +-; CHECK-NEXT: .byte 0x01 +-; CHECK-NEXT: .byte 0x02 +-; CHECK-NEXT: .space 13 +-; CHECK-NEXT: .Lxray_sleds_end0: +- +-; CHECK-LABEL: .section xray_fn_idx +-; CHECK: [[IDX:.Lxray_fn_idx[0-9]+]]: +-; CHECK: .dword .Lxray_sleds_start0-[[IDX]] +-; CHECK-NEXT: .dword 2 +- +-; RELOC: Section ([[#]]) .relaxray_instr_map { +-; RELOC-NEXT: 0x0 R_LARCH_64_PCREL .text 0x0 +-; RELOC-NEXT: 0x8 R_LARCH_64_PCREL .text 0x0 +-; RELOC-NEXT: 0x20 R_LARCH_64_PCREL .text 0x34 +-; RELOC-NEXT: 0x28 R_LARCH_64_PCREL .text 0x0 +-; RELOC-NEXT: } +-; RELOC-NEXT: Section ([[#]]) .relaxray_fn_idx { +-; RELOC-NEXT: 0x0 R_LARCH_64_PCREL xray_instr_map 0x0 +-; RELOC-NEXT: } +-; RELOC-NEXT: Section ([[#]]) .rela.eh_frame { +-; RELOC-NEXT: 0x1C R_LARCH_32_PCREL .text 0x0 +-; RELOC-NEXT: } +diff --git a/llvm/test/CodeGen/LoongArch/zext-with-load-is-free.ll b/llvm/test/CodeGen/LoongArch/zext-with-load-is-free.ll +deleted file mode 100644 +index d05a0c745..000000000 +--- a/llvm/test/CodeGen/LoongArch/zext-with-load-is-free.ll ++++ /dev/null +@@ -1,40 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +-; RUN: llc --mtriple=loongarch32 -verify-machineinstrs < %s \ +-; RUN: | FileCheck %s --check-prefix=LA32 +-; RUN: llc --mtriple=loongarch64 -verify-machineinstrs < %s \ +-; RUN: | FileCheck %s --check-prefix=LA64 +- +-define zeroext i8 @test_zext_i8(ptr %p) nounwind { +-; LA32-LABEL: test_zext_i8: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.bu $a0, $a0, 0 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_zext_i8: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.bu $a0, $a0, 0 +-; LA64-NEXT: ret +- %a = load i8, ptr %p, align 1 +- br label %exit +-exit: +- ret i8 %a +-} +- +-define zeroext i16 @test_zext_i16(ptr %p) nounwind { +-; LA32-LABEL: test_zext_i16: +-; LA32: # %bb.0: +-; LA32-NEXT: ld.bu $a1, $a0, 0 +-; LA32-NEXT: ld.bu $a0, $a0, 1 +-; LA32-NEXT: slli.w $a0, $a0, 8 +-; LA32-NEXT: or $a0, $a0, $a1 +-; LA32-NEXT: ret +-; +-; LA64-LABEL: test_zext_i16: +-; LA64: # %bb.0: +-; LA64-NEXT: ld.hu $a0, $a0, 0 +-; LA64-NEXT: ret +- %a = load i16, ptr %p, align 1 +- br label %exit +-exit: +- ret i16 %a +-} +diff --git a/llvm/test/CodeGen/M68k/pipeline.ll b/llvm/test/CodeGen/M68k/pipeline.ll +index dfaa149b7..ed00f3fe0 100644 +--- a/llvm/test/CodeGen/M68k/pipeline.ll ++++ b/llvm/test/CodeGen/M68k/pipeline.ll +@@ -136,6 +136,5 @@ + ; CHECK-NEXT: Machine Sanitizer Binary Metadata + ; CHECK-NEXT: Lazy Machine Block Frequency Analysis + ; CHECK-NEXT: Machine Optimization Remark Emitter +-; CHECK-NEXT: Stack Frame Layout Analysis + ; CHECK-NEXT: M68k Assembly Printer + ; CHECK-NEXT: Free MachineFunction +diff --git a/llvm/test/CodeGen/Mips/atomic-fix-loongson3-llsc.ll b/llvm/test/CodeGen/Mips/atomic-fix-loongson3-llsc.ll +new file mode 100644 +index 000000000..97b7472f6 +--- /dev/null ++++ b/llvm/test/CodeGen/Mips/atomic-fix-loongson3-llsc.ll +@@ -0,0 +1,7548 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mipsel-unknown-linux-gnu --disable-machine-licm -mcpu=mips32 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: FileCheck %s -check-prefix=MIPS32 ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mipsel-unknown-linux-gnu -O0 --disable-machine-licm -mcpu=mips32 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: FileCheck %s -check-prefix=MIPS32O0 ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mipsel-unknown-linux-gnu --disable-machine-licm -mcpu=mips32r2 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: FileCheck %s -check-prefix=MIPS32R2 ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mipsel-unknown-linux-gnu --disable-machine-licm -mcpu=mips32r6 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: FileCheck %s -check-prefix=MIPS32R6 ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mipsel-unknown-linux-gnu -O0 --disable-machine-licm -mcpu=mips32r6 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: FileCheck %s -check-prefix=MIPS32R6O0 ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips4 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: FileCheck %s -check-prefix=MIPS4 ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips64 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: FileCheck %s -check-prefix=MIPS64 ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips64r2 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: FileCheck %s -check-prefix=MIPS64R2 ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips64r6 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: FileCheck %s -check-prefix=MIPS64R6 ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mips64-unknown-linux-gnu -O0 -mcpu=mips64r6 -relocation-model=pic -verify-machineinstrs -verify-machineinstrs < %s | \ ++; RUN: FileCheck %s -check-prefix=MIPS64R6O0 ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mipsel-unknown-linux-gnu --disable-machine-licm -mcpu=mips32r2 -mattr=micromips -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: FileCheck %s -check-prefix=MM32 ++ ++; We want to verify the produced code is well formed all optimization levels, the rest of the tests which ensure correctness. ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mipsel-unknown-linux-gnu -O1 --disable-machine-licm -mcpu=mips32 -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s --check-prefix=O1 ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mipsel-unknown-linux-gnu -O2 --disable-machine-licm -mcpu=mips32 -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s --check-prefix=O2 ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mipsel-unknown-linux-gnu -O3 --disable-machine-licm -mcpu=mips32 -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s --check-prefix=O3 ++ ++; Keep one big-endian check so that we don't reduce testing, but don't add more ++; since endianness doesn't affect the body of the atomic operations. ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mips-unknown-linux-gnu --disable-machine-licm -mcpu=mips32 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: FileCheck %s -check-prefix=MIPS32EB ++ ++@x = common global i32 0, align 4 ++ ++define i32 @AtomicLoadAdd32(i32 signext %incr) nounwind { ++; MIPS32-LABEL: AtomicLoadAdd32: ++; MIPS32: # %bb.0: # %entry ++; MIPS32-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32-NEXT: addu $1, $2, $25 ++; MIPS32-NEXT: lw $1, %got(x)($1) ++; MIPS32-NEXT: $BB0_1: # %entry ++; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32-NEXT: ll $2, 0($1) ++; MIPS32-NEXT: addu $3, $2, $4 ++; MIPS32-NEXT: sc $3, 0($1) ++; MIPS32-NEXT: beqz $3, $BB0_1 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: # %bb.2: # %entry ++; MIPS32-NEXT: jr $ra ++; MIPS32-NEXT: nop ++; ++; MIPS32O0-LABEL: AtomicLoadAdd32: ++; MIPS32O0: # %bb.0: # %entry ++; MIPS32O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32O0-NEXT: addu $1, $2, $25 ++; MIPS32O0-NEXT: lw $3, %got(x)($1) ++; MIPS32O0-NEXT: $BB0_1: # %entry ++; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32O0-NEXT: ll $2, 0($3) ++; MIPS32O0-NEXT: addu $1, $2, $4 ++; MIPS32O0-NEXT: sc $1, 0($3) ++; MIPS32O0-NEXT: beqz $1, $BB0_1 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: # %bb.2: # %entry ++; MIPS32O0-NEXT: jr $ra ++; MIPS32O0-NEXT: nop ++; ++; MIPS32R2-LABEL: AtomicLoadAdd32: ++; MIPS32R2: # %bb.0: # %entry ++; MIPS32R2-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R2-NEXT: addu $1, $2, $25 ++; MIPS32R2-NEXT: lw $1, %got(x)($1) ++; MIPS32R2-NEXT: $BB0_1: # %entry ++; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R2-NEXT: ll $2, 0($1) ++; MIPS32R2-NEXT: addu $3, $2, $4 ++; MIPS32R2-NEXT: sc $3, 0($1) ++; MIPS32R2-NEXT: beqz $3, $BB0_1 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: # %bb.2: # %entry ++; MIPS32R2-NEXT: jr $ra ++; MIPS32R2-NEXT: nop ++; ++; MIPS32R6-LABEL: AtomicLoadAdd32: ++; MIPS32R6: # %bb.0: # %entry ++; MIPS32R6-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6-NEXT: addu $1, $2, $25 ++; MIPS32R6-NEXT: lw $1, %got(x)($1) ++; MIPS32R6-NEXT: $BB0_1: # %entry ++; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6-NEXT: ll $2, 0($1) ++; MIPS32R6-NEXT: addu $3, $2, $4 ++; MIPS32R6-NEXT: sc $3, 0($1) ++; MIPS32R6-NEXT: beqzc $3, $BB0_1 ++; MIPS32R6-NEXT: nop ++; MIPS32R6-NEXT: # %bb.2: # %entry ++; MIPS32R6-NEXT: jrc $ra ++; ++; MIPS32R6O0-LABEL: AtomicLoadAdd32: ++; MIPS32R6O0: # %bb.0: # %entry ++; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6O0-NEXT: addu $1, $2, $25 ++; MIPS32R6O0-NEXT: lw $3, %got(x)($1) ++; MIPS32R6O0-NEXT: $BB0_1: # %entry ++; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6O0-NEXT: ll $2, 0($3) ++; MIPS32R6O0-NEXT: addu $1, $2, $4 ++; MIPS32R6O0-NEXT: sc $1, 0($3) ++; MIPS32R6O0-NEXT: beqzc $1, $BB0_1 ++; MIPS32R6O0-NEXT: nop ++; MIPS32R6O0-NEXT: # %bb.2: # %entry ++; MIPS32R6O0-NEXT: jrc $ra ++; ++; MIPS4-LABEL: AtomicLoadAdd32: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd32))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd32))) ++; MIPS4-NEXT: ld $1, %got_disp(x)($1) ++; MIPS4-NEXT: .LBB0_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: ll $2, 0($1) ++; MIPS4-NEXT: addu $3, $2, $4 ++; MIPS4-NEXT: sc $3, 0($1) ++; MIPS4-NEXT: beqz $3, .LBB0_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: nop ++; ++; MIPS64-LABEL: AtomicLoadAdd32: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd32))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd32))) ++; MIPS64-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64-NEXT: .LBB0_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: ll $2, 0($1) ++; MIPS64-NEXT: addu $3, $2, $4 ++; MIPS64-NEXT: sc $3, 0($1) ++; MIPS64-NEXT: beqz $3, .LBB0_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: nop ++; ++; MIPS64R2-LABEL: AtomicLoadAdd32: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd32))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd32))) ++; MIPS64R2-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R2-NEXT: .LBB0_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: ll $2, 0($1) ++; MIPS64R2-NEXT: addu $3, $2, $4 ++; MIPS64R2-NEXT: sc $3, 0($1) ++; MIPS64R2-NEXT: beqz $3, .LBB0_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: nop ++; ++; MIPS64R6-LABEL: AtomicLoadAdd32: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd32))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd32))) ++; MIPS64R6-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R6-NEXT: .LBB0_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: ll $2, 0($1) ++; MIPS64R6-NEXT: addu $3, $2, $4 ++; MIPS64R6-NEXT: sc $3, 0($1) ++; MIPS64R6-NEXT: beqzc $3, .LBB0_1 ++; MIPS64R6-NEXT: nop ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: jrc $ra ++; ++; MIPS64R6O0-LABEL: AtomicLoadAdd32: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd32))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd32))) ++; MIPS64R6O0-NEXT: # kill: def $a0 killed $a0 killed $a0_64 ++; MIPS64R6O0-NEXT: ld $3, %got_disp(x)($1) ++; MIPS64R6O0-NEXT: .LBB0_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: ll $2, 0($3) ++; MIPS64R6O0-NEXT: addu $1, $2, $4 ++; MIPS64R6O0-NEXT: sc $1, 0($3) ++; MIPS64R6O0-NEXT: beqzc $1, .LBB0_1 ++; MIPS64R6O0-NEXT: nop ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; MM32-LABEL: AtomicLoadAdd32: ++; MM32: # %bb.0: # %entry ++; MM32-NEXT: lui $2, %hi(_gp_disp) ++; MM32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MM32-NEXT: addu $2, $2, $25 ++; MM32-NEXT: lw $1, %got(x)($2) ++; MM32-NEXT: $BB0_1: # %entry ++; MM32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MM32-NEXT: ll $2, 0($1) ++; MM32-NEXT: addu16 $3, $2, $4 ++; MM32-NEXT: sc $3, 0($1) ++; MM32-NEXT: beqzc $3, $BB0_1 ++; MM32-NEXT: # %bb.2: # %entry ++; MM32-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicLoadAdd32: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $2, %hi(_gp_disp) ++; O1-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O1-NEXT: addu $1, $2, $25 ++; O1-NEXT: lw $1, %got(x)($1) ++; O1-NEXT: $BB0_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: ll $2, 0($1) ++; O1-NEXT: addu $3, $2, $4 ++; O1-NEXT: sc $3, 0($1) ++; O1-NEXT: beqz $3, $BB0_1 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: jr $ra ++; O1-NEXT: nop ++; ++; O2-LABEL: AtomicLoadAdd32: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $2, %hi(_gp_disp) ++; O2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O2-NEXT: addu $1, $2, $25 ++; O2-NEXT: lw $1, %got(x)($1) ++; O2-NEXT: $BB0_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: ll $2, 0($1) ++; O2-NEXT: addu $3, $2, $4 ++; O2-NEXT: sc $3, 0($1) ++; O2-NEXT: beqz $3, $BB0_1 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: jr $ra ++; O2-NEXT: nop ++; ++; O3-LABEL: AtomicLoadAdd32: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $2, %hi(_gp_disp) ++; O3-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O3-NEXT: addu $1, $2, $25 ++; O3-NEXT: lw $1, %got(x)($1) ++; O3-NEXT: $BB0_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: ll $2, 0($1) ++; O3-NEXT: addu $3, $2, $4 ++; O3-NEXT: sc $3, 0($1) ++; O3-NEXT: beqz $3, $BB0_1 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: jr $ra ++; O3-NEXT: nop ++; ++; MIPS32EB-LABEL: AtomicLoadAdd32: ++; MIPS32EB: # %bb.0: # %entry ++; MIPS32EB-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32EB-NEXT: addu $1, $2, $25 ++; MIPS32EB-NEXT: lw $1, %got(x)($1) ++; MIPS32EB-NEXT: $BB0_1: # %entry ++; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32EB-NEXT: ll $2, 0($1) ++; MIPS32EB-NEXT: addu $3, $2, $4 ++; MIPS32EB-NEXT: sc $3, 0($1) ++; MIPS32EB-NEXT: beqz $3, $BB0_1 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: # %bb.2: # %entry ++; MIPS32EB-NEXT: jr $ra ++; MIPS32EB-NEXT: nop ++entry: ++ %0 = atomicrmw add ptr @x, i32 %incr monotonic ++ ret i32 %0 ++ ++} ++ ++define i32 @AtomicLoadSub32(i32 signext %incr) nounwind { ++; MIPS32-LABEL: AtomicLoadSub32: ++; MIPS32: # %bb.0: # %entry ++; MIPS32-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32-NEXT: addu $1, $2, $25 ++; MIPS32-NEXT: lw $1, %got(x)($1) ++; MIPS32-NEXT: $BB1_1: # %entry ++; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32-NEXT: ll $2, 0($1) ++; MIPS32-NEXT: subu $3, $2, $4 ++; MIPS32-NEXT: sc $3, 0($1) ++; MIPS32-NEXT: beqz $3, $BB1_1 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: # %bb.2: # %entry ++; MIPS32-NEXT: jr $ra ++; MIPS32-NEXT: nop ++; ++; MIPS32O0-LABEL: AtomicLoadSub32: ++; MIPS32O0: # %bb.0: # %entry ++; MIPS32O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32O0-NEXT: addu $1, $2, $25 ++; MIPS32O0-NEXT: lw $3, %got(x)($1) ++; MIPS32O0-NEXT: $BB1_1: # %entry ++; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32O0-NEXT: ll $2, 0($3) ++; MIPS32O0-NEXT: subu $1, $2, $4 ++; MIPS32O0-NEXT: sc $1, 0($3) ++; MIPS32O0-NEXT: beqz $1, $BB1_1 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: # %bb.2: # %entry ++; MIPS32O0-NEXT: jr $ra ++; MIPS32O0-NEXT: nop ++; ++; MIPS32R2-LABEL: AtomicLoadSub32: ++; MIPS32R2: # %bb.0: # %entry ++; MIPS32R2-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R2-NEXT: addu $1, $2, $25 ++; MIPS32R2-NEXT: lw $1, %got(x)($1) ++; MIPS32R2-NEXT: $BB1_1: # %entry ++; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R2-NEXT: ll $2, 0($1) ++; MIPS32R2-NEXT: subu $3, $2, $4 ++; MIPS32R2-NEXT: sc $3, 0($1) ++; MIPS32R2-NEXT: beqz $3, $BB1_1 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: # %bb.2: # %entry ++; MIPS32R2-NEXT: jr $ra ++; MIPS32R2-NEXT: nop ++; ++; MIPS32R6-LABEL: AtomicLoadSub32: ++; MIPS32R6: # %bb.0: # %entry ++; MIPS32R6-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6-NEXT: addu $1, $2, $25 ++; MIPS32R6-NEXT: lw $1, %got(x)($1) ++; MIPS32R6-NEXT: $BB1_1: # %entry ++; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6-NEXT: ll $2, 0($1) ++; MIPS32R6-NEXT: subu $3, $2, $4 ++; MIPS32R6-NEXT: sc $3, 0($1) ++; MIPS32R6-NEXT: beqzc $3, $BB1_1 ++; MIPS32R6-NEXT: nop ++; MIPS32R6-NEXT: # %bb.2: # %entry ++; MIPS32R6-NEXT: jrc $ra ++; ++; MIPS32R6O0-LABEL: AtomicLoadSub32: ++; MIPS32R6O0: # %bb.0: # %entry ++; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6O0-NEXT: addu $1, $2, $25 ++; MIPS32R6O0-NEXT: lw $3, %got(x)($1) ++; MIPS32R6O0-NEXT: $BB1_1: # %entry ++; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6O0-NEXT: ll $2, 0($3) ++; MIPS32R6O0-NEXT: subu $1, $2, $4 ++; MIPS32R6O0-NEXT: sc $1, 0($3) ++; MIPS32R6O0-NEXT: beqzc $1, $BB1_1 ++; MIPS32R6O0-NEXT: nop ++; MIPS32R6O0-NEXT: # %bb.2: # %entry ++; MIPS32R6O0-NEXT: jrc $ra ++; ++; MIPS4-LABEL: AtomicLoadSub32: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadSub32))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadSub32))) ++; MIPS4-NEXT: ld $1, %got_disp(x)($1) ++; MIPS4-NEXT: .LBB1_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: ll $2, 0($1) ++; MIPS4-NEXT: subu $3, $2, $4 ++; MIPS4-NEXT: sc $3, 0($1) ++; MIPS4-NEXT: beqz $3, .LBB1_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: nop ++; ++; MIPS64-LABEL: AtomicLoadSub32: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadSub32))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadSub32))) ++; MIPS64-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64-NEXT: .LBB1_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: ll $2, 0($1) ++; MIPS64-NEXT: subu $3, $2, $4 ++; MIPS64-NEXT: sc $3, 0($1) ++; MIPS64-NEXT: beqz $3, .LBB1_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: nop ++; ++; MIPS64R2-LABEL: AtomicLoadSub32: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadSub32))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadSub32))) ++; MIPS64R2-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R2-NEXT: .LBB1_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: ll $2, 0($1) ++; MIPS64R2-NEXT: subu $3, $2, $4 ++; MIPS64R2-NEXT: sc $3, 0($1) ++; MIPS64R2-NEXT: beqz $3, .LBB1_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: nop ++; ++; MIPS64R6-LABEL: AtomicLoadSub32: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadSub32))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadSub32))) ++; MIPS64R6-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R6-NEXT: .LBB1_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: ll $2, 0($1) ++; MIPS64R6-NEXT: subu $3, $2, $4 ++; MIPS64R6-NEXT: sc $3, 0($1) ++; MIPS64R6-NEXT: beqzc $3, .LBB1_1 ++; MIPS64R6-NEXT: nop ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: jrc $ra ++; ++; MIPS64R6O0-LABEL: AtomicLoadSub32: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadSub32))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadSub32))) ++; MIPS64R6O0-NEXT: # kill: def $a0 killed $a0 killed $a0_64 ++; MIPS64R6O0-NEXT: ld $3, %got_disp(x)($1) ++; MIPS64R6O0-NEXT: .LBB1_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: ll $2, 0($3) ++; MIPS64R6O0-NEXT: subu $1, $2, $4 ++; MIPS64R6O0-NEXT: sc $1, 0($3) ++; MIPS64R6O0-NEXT: beqzc $1, .LBB1_1 ++; MIPS64R6O0-NEXT: nop ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; MM32-LABEL: AtomicLoadSub32: ++; MM32: # %bb.0: # %entry ++; MM32-NEXT: lui $2, %hi(_gp_disp) ++; MM32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MM32-NEXT: addu $2, $2, $25 ++; MM32-NEXT: lw $1, %got(x)($2) ++; MM32-NEXT: $BB1_1: # %entry ++; MM32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MM32-NEXT: ll $2, 0($1) ++; MM32-NEXT: subu16 $3, $2, $4 ++; MM32-NEXT: sc $3, 0($1) ++; MM32-NEXT: beqzc $3, $BB1_1 ++; MM32-NEXT: # %bb.2: # %entry ++; MM32-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicLoadSub32: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $2, %hi(_gp_disp) ++; O1-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O1-NEXT: addu $1, $2, $25 ++; O1-NEXT: lw $1, %got(x)($1) ++; O1-NEXT: $BB1_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: ll $2, 0($1) ++; O1-NEXT: subu $3, $2, $4 ++; O1-NEXT: sc $3, 0($1) ++; O1-NEXT: beqz $3, $BB1_1 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: jr $ra ++; O1-NEXT: nop ++; ++; O2-LABEL: AtomicLoadSub32: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $2, %hi(_gp_disp) ++; O2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O2-NEXT: addu $1, $2, $25 ++; O2-NEXT: lw $1, %got(x)($1) ++; O2-NEXT: $BB1_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: ll $2, 0($1) ++; O2-NEXT: subu $3, $2, $4 ++; O2-NEXT: sc $3, 0($1) ++; O2-NEXT: beqz $3, $BB1_1 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: jr $ra ++; O2-NEXT: nop ++; ++; O3-LABEL: AtomicLoadSub32: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $2, %hi(_gp_disp) ++; O3-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O3-NEXT: addu $1, $2, $25 ++; O3-NEXT: lw $1, %got(x)($1) ++; O3-NEXT: $BB1_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: ll $2, 0($1) ++; O3-NEXT: subu $3, $2, $4 ++; O3-NEXT: sc $3, 0($1) ++; O3-NEXT: beqz $3, $BB1_1 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: jr $ra ++; O3-NEXT: nop ++; ++; MIPS32EB-LABEL: AtomicLoadSub32: ++; MIPS32EB: # %bb.0: # %entry ++; MIPS32EB-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32EB-NEXT: addu $1, $2, $25 ++; MIPS32EB-NEXT: lw $1, %got(x)($1) ++; MIPS32EB-NEXT: $BB1_1: # %entry ++; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32EB-NEXT: ll $2, 0($1) ++; MIPS32EB-NEXT: subu $3, $2, $4 ++; MIPS32EB-NEXT: sc $3, 0($1) ++; MIPS32EB-NEXT: beqz $3, $BB1_1 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: # %bb.2: # %entry ++; MIPS32EB-NEXT: jr $ra ++; MIPS32EB-NEXT: nop ++entry: ++ %0 = atomicrmw sub ptr @x, i32 %incr monotonic ++ ret i32 %0 ++ ++} ++ ++define i32 @AtomicLoadXor32(i32 signext %incr) nounwind { ++; MIPS32-LABEL: AtomicLoadXor32: ++; MIPS32: # %bb.0: # %entry ++; MIPS32-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32-NEXT: addu $1, $2, $25 ++; MIPS32-NEXT: lw $1, %got(x)($1) ++; MIPS32-NEXT: $BB2_1: # %entry ++; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32-NEXT: ll $2, 0($1) ++; MIPS32-NEXT: xor $3, $2, $4 ++; MIPS32-NEXT: sc $3, 0($1) ++; MIPS32-NEXT: beqz $3, $BB2_1 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: # %bb.2: # %entry ++; MIPS32-NEXT: jr $ra ++; MIPS32-NEXT: nop ++; ++; MIPS32O0-LABEL: AtomicLoadXor32: ++; MIPS32O0: # %bb.0: # %entry ++; MIPS32O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32O0-NEXT: addu $1, $2, $25 ++; MIPS32O0-NEXT: lw $3, %got(x)($1) ++; MIPS32O0-NEXT: $BB2_1: # %entry ++; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32O0-NEXT: ll $2, 0($3) ++; MIPS32O0-NEXT: xor $1, $2, $4 ++; MIPS32O0-NEXT: sc $1, 0($3) ++; MIPS32O0-NEXT: beqz $1, $BB2_1 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: # %bb.2: # %entry ++; MIPS32O0-NEXT: jr $ra ++; MIPS32O0-NEXT: nop ++; ++; MIPS32R2-LABEL: AtomicLoadXor32: ++; MIPS32R2: # %bb.0: # %entry ++; MIPS32R2-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R2-NEXT: addu $1, $2, $25 ++; MIPS32R2-NEXT: lw $1, %got(x)($1) ++; MIPS32R2-NEXT: $BB2_1: # %entry ++; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R2-NEXT: ll $2, 0($1) ++; MIPS32R2-NEXT: xor $3, $2, $4 ++; MIPS32R2-NEXT: sc $3, 0($1) ++; MIPS32R2-NEXT: beqz $3, $BB2_1 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: # %bb.2: # %entry ++; MIPS32R2-NEXT: jr $ra ++; MIPS32R2-NEXT: nop ++; ++; MIPS32R6-LABEL: AtomicLoadXor32: ++; MIPS32R6: # %bb.0: # %entry ++; MIPS32R6-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6-NEXT: addu $1, $2, $25 ++; MIPS32R6-NEXT: lw $1, %got(x)($1) ++; MIPS32R6-NEXT: $BB2_1: # %entry ++; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6-NEXT: ll $2, 0($1) ++; MIPS32R6-NEXT: xor $3, $2, $4 ++; MIPS32R6-NEXT: sc $3, 0($1) ++; MIPS32R6-NEXT: beqzc $3, $BB2_1 ++; MIPS32R6-NEXT: nop ++; MIPS32R6-NEXT: # %bb.2: # %entry ++; MIPS32R6-NEXT: jrc $ra ++; ++; MIPS32R6O0-LABEL: AtomicLoadXor32: ++; MIPS32R6O0: # %bb.0: # %entry ++; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6O0-NEXT: addu $1, $2, $25 ++; MIPS32R6O0-NEXT: lw $3, %got(x)($1) ++; MIPS32R6O0-NEXT: $BB2_1: # %entry ++; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6O0-NEXT: ll $2, 0($3) ++; MIPS32R6O0-NEXT: xor $1, $2, $4 ++; MIPS32R6O0-NEXT: sc $1, 0($3) ++; MIPS32R6O0-NEXT: beqzc $1, $BB2_1 ++; MIPS32R6O0-NEXT: nop ++; MIPS32R6O0-NEXT: # %bb.2: # %entry ++; MIPS32R6O0-NEXT: jrc $ra ++; ++; MIPS4-LABEL: AtomicLoadXor32: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadXor32))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadXor32))) ++; MIPS4-NEXT: ld $1, %got_disp(x)($1) ++; MIPS4-NEXT: .LBB2_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: ll $2, 0($1) ++; MIPS4-NEXT: xor $3, $2, $4 ++; MIPS4-NEXT: sc $3, 0($1) ++; MIPS4-NEXT: beqz $3, .LBB2_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: nop ++; ++; MIPS64-LABEL: AtomicLoadXor32: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadXor32))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadXor32))) ++; MIPS64-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64-NEXT: .LBB2_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: ll $2, 0($1) ++; MIPS64-NEXT: xor $3, $2, $4 ++; MIPS64-NEXT: sc $3, 0($1) ++; MIPS64-NEXT: beqz $3, .LBB2_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: nop ++; ++; MIPS64R2-LABEL: AtomicLoadXor32: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadXor32))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadXor32))) ++; MIPS64R2-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R2-NEXT: .LBB2_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: ll $2, 0($1) ++; MIPS64R2-NEXT: xor $3, $2, $4 ++; MIPS64R2-NEXT: sc $3, 0($1) ++; MIPS64R2-NEXT: beqz $3, .LBB2_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: nop ++; ++; MIPS64R6-LABEL: AtomicLoadXor32: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadXor32))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadXor32))) ++; MIPS64R6-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R6-NEXT: .LBB2_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: ll $2, 0($1) ++; MIPS64R6-NEXT: xor $3, $2, $4 ++; MIPS64R6-NEXT: sc $3, 0($1) ++; MIPS64R6-NEXT: beqzc $3, .LBB2_1 ++; MIPS64R6-NEXT: nop ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: jrc $ra ++; ++; MIPS64R6O0-LABEL: AtomicLoadXor32: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadXor32))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadXor32))) ++; MIPS64R6O0-NEXT: # kill: def $a0 killed $a0 killed $a0_64 ++; MIPS64R6O0-NEXT: ld $3, %got_disp(x)($1) ++; MIPS64R6O0-NEXT: .LBB2_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: ll $2, 0($3) ++; MIPS64R6O0-NEXT: xor $1, $2, $4 ++; MIPS64R6O0-NEXT: sc $1, 0($3) ++; MIPS64R6O0-NEXT: beqzc $1, .LBB2_1 ++; MIPS64R6O0-NEXT: nop ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; MM32-LABEL: AtomicLoadXor32: ++; MM32: # %bb.0: # %entry ++; MM32-NEXT: lui $2, %hi(_gp_disp) ++; MM32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MM32-NEXT: addu $2, $2, $25 ++; MM32-NEXT: lw $1, %got(x)($2) ++; MM32-NEXT: $BB2_1: # %entry ++; MM32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MM32-NEXT: ll $2, 0($1) ++; MM32-NEXT: xor $3, $2, $4 ++; MM32-NEXT: sc $3, 0($1) ++; MM32-NEXT: beqzc $3, $BB2_1 ++; MM32-NEXT: # %bb.2: # %entry ++; MM32-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicLoadXor32: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $2, %hi(_gp_disp) ++; O1-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O1-NEXT: addu $1, $2, $25 ++; O1-NEXT: lw $1, %got(x)($1) ++; O1-NEXT: $BB2_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: ll $2, 0($1) ++; O1-NEXT: xor $3, $2, $4 ++; O1-NEXT: sc $3, 0($1) ++; O1-NEXT: beqz $3, $BB2_1 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: jr $ra ++; O1-NEXT: nop ++; ++; O2-LABEL: AtomicLoadXor32: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $2, %hi(_gp_disp) ++; O2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O2-NEXT: addu $1, $2, $25 ++; O2-NEXT: lw $1, %got(x)($1) ++; O2-NEXT: $BB2_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: ll $2, 0($1) ++; O2-NEXT: xor $3, $2, $4 ++; O2-NEXT: sc $3, 0($1) ++; O2-NEXT: beqz $3, $BB2_1 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: jr $ra ++; O2-NEXT: nop ++; ++; O3-LABEL: AtomicLoadXor32: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $2, %hi(_gp_disp) ++; O3-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O3-NEXT: addu $1, $2, $25 ++; O3-NEXT: lw $1, %got(x)($1) ++; O3-NEXT: $BB2_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: ll $2, 0($1) ++; O3-NEXT: xor $3, $2, $4 ++; O3-NEXT: sc $3, 0($1) ++; O3-NEXT: beqz $3, $BB2_1 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: jr $ra ++; O3-NEXT: nop ++; ++; MIPS32EB-LABEL: AtomicLoadXor32: ++; MIPS32EB: # %bb.0: # %entry ++; MIPS32EB-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32EB-NEXT: addu $1, $2, $25 ++; MIPS32EB-NEXT: lw $1, %got(x)($1) ++; MIPS32EB-NEXT: $BB2_1: # %entry ++; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32EB-NEXT: ll $2, 0($1) ++; MIPS32EB-NEXT: xor $3, $2, $4 ++; MIPS32EB-NEXT: sc $3, 0($1) ++; MIPS32EB-NEXT: beqz $3, $BB2_1 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: # %bb.2: # %entry ++; MIPS32EB-NEXT: jr $ra ++; MIPS32EB-NEXT: nop ++entry: ++ %0 = atomicrmw xor ptr @x, i32 %incr monotonic ++ ret i32 %0 ++} ++ ++define i32 @AtomicLoadOr32(i32 signext %incr) nounwind { ++; MIPS32-LABEL: AtomicLoadOr32: ++; MIPS32: # %bb.0: # %entry ++; MIPS32-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32-NEXT: addu $1, $2, $25 ++; MIPS32-NEXT: lw $1, %got(x)($1) ++; MIPS32-NEXT: $BB3_1: # %entry ++; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32-NEXT: ll $2, 0($1) ++; MIPS32-NEXT: or $3, $2, $4 ++; MIPS32-NEXT: sc $3, 0($1) ++; MIPS32-NEXT: beqz $3, $BB3_1 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: # %bb.2: # %entry ++; MIPS32-NEXT: jr $ra ++; MIPS32-NEXT: nop ++; ++; MIPS32O0-LABEL: AtomicLoadOr32: ++; MIPS32O0: # %bb.0: # %entry ++; MIPS32O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32O0-NEXT: addu $1, $2, $25 ++; MIPS32O0-NEXT: lw $3, %got(x)($1) ++; MIPS32O0-NEXT: $BB3_1: # %entry ++; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32O0-NEXT: ll $2, 0($3) ++; MIPS32O0-NEXT: or $1, $2, $4 ++; MIPS32O0-NEXT: sc $1, 0($3) ++; MIPS32O0-NEXT: beqz $1, $BB3_1 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: # %bb.2: # %entry ++; MIPS32O0-NEXT: jr $ra ++; MIPS32O0-NEXT: nop ++; ++; MIPS32R2-LABEL: AtomicLoadOr32: ++; MIPS32R2: # %bb.0: # %entry ++; MIPS32R2-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R2-NEXT: addu $1, $2, $25 ++; MIPS32R2-NEXT: lw $1, %got(x)($1) ++; MIPS32R2-NEXT: $BB3_1: # %entry ++; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R2-NEXT: ll $2, 0($1) ++; MIPS32R2-NEXT: or $3, $2, $4 ++; MIPS32R2-NEXT: sc $3, 0($1) ++; MIPS32R2-NEXT: beqz $3, $BB3_1 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: # %bb.2: # %entry ++; MIPS32R2-NEXT: jr $ra ++; MIPS32R2-NEXT: nop ++; ++; MIPS32R6-LABEL: AtomicLoadOr32: ++; MIPS32R6: # %bb.0: # %entry ++; MIPS32R6-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6-NEXT: addu $1, $2, $25 ++; MIPS32R6-NEXT: lw $1, %got(x)($1) ++; MIPS32R6-NEXT: $BB3_1: # %entry ++; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6-NEXT: ll $2, 0($1) ++; MIPS32R6-NEXT: or $3, $2, $4 ++; MIPS32R6-NEXT: sc $3, 0($1) ++; MIPS32R6-NEXT: beqzc $3, $BB3_1 ++; MIPS32R6-NEXT: nop ++; MIPS32R6-NEXT: # %bb.2: # %entry ++; MIPS32R6-NEXT: jrc $ra ++; ++; MIPS32R6O0-LABEL: AtomicLoadOr32: ++; MIPS32R6O0: # %bb.0: # %entry ++; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6O0-NEXT: addu $1, $2, $25 ++; MIPS32R6O0-NEXT: lw $3, %got(x)($1) ++; MIPS32R6O0-NEXT: $BB3_1: # %entry ++; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6O0-NEXT: ll $2, 0($3) ++; MIPS32R6O0-NEXT: or $1, $2, $4 ++; MIPS32R6O0-NEXT: sc $1, 0($3) ++; MIPS32R6O0-NEXT: beqzc $1, $BB3_1 ++; MIPS32R6O0-NEXT: nop ++; MIPS32R6O0-NEXT: # %bb.2: # %entry ++; MIPS32R6O0-NEXT: jrc $ra ++; ++; MIPS4-LABEL: AtomicLoadOr32: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadOr32))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadOr32))) ++; MIPS4-NEXT: ld $1, %got_disp(x)($1) ++; MIPS4-NEXT: .LBB3_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: ll $2, 0($1) ++; MIPS4-NEXT: or $3, $2, $4 ++; MIPS4-NEXT: sc $3, 0($1) ++; MIPS4-NEXT: beqz $3, .LBB3_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: nop ++; ++; MIPS64-LABEL: AtomicLoadOr32: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadOr32))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadOr32))) ++; MIPS64-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64-NEXT: .LBB3_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: ll $2, 0($1) ++; MIPS64-NEXT: or $3, $2, $4 ++; MIPS64-NEXT: sc $3, 0($1) ++; MIPS64-NEXT: beqz $3, .LBB3_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: nop ++; ++; MIPS64R2-LABEL: AtomicLoadOr32: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadOr32))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadOr32))) ++; MIPS64R2-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R2-NEXT: .LBB3_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: ll $2, 0($1) ++; MIPS64R2-NEXT: or $3, $2, $4 ++; MIPS64R2-NEXT: sc $3, 0($1) ++; MIPS64R2-NEXT: beqz $3, .LBB3_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: nop ++; ++; MIPS64R6-LABEL: AtomicLoadOr32: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadOr32))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadOr32))) ++; MIPS64R6-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R6-NEXT: .LBB3_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: ll $2, 0($1) ++; MIPS64R6-NEXT: or $3, $2, $4 ++; MIPS64R6-NEXT: sc $3, 0($1) ++; MIPS64R6-NEXT: beqzc $3, .LBB3_1 ++; MIPS64R6-NEXT: nop ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: jrc $ra ++; ++; MIPS64R6O0-LABEL: AtomicLoadOr32: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadOr32))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadOr32))) ++; MIPS64R6O0-NEXT: # kill: def $a0 killed $a0 killed $a0_64 ++; MIPS64R6O0-NEXT: ld $3, %got_disp(x)($1) ++; MIPS64R6O0-NEXT: .LBB3_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: ll $2, 0($3) ++; MIPS64R6O0-NEXT: or $1, $2, $4 ++; MIPS64R6O0-NEXT: sc $1, 0($3) ++; MIPS64R6O0-NEXT: beqzc $1, .LBB3_1 ++; MIPS64R6O0-NEXT: nop ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; MM32-LABEL: AtomicLoadOr32: ++; MM32: # %bb.0: # %entry ++; MM32-NEXT: lui $2, %hi(_gp_disp) ++; MM32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MM32-NEXT: addu $2, $2, $25 ++; MM32-NEXT: lw $1, %got(x)($2) ++; MM32-NEXT: $BB3_1: # %entry ++; MM32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MM32-NEXT: ll $2, 0($1) ++; MM32-NEXT: or $3, $2, $4 ++; MM32-NEXT: sc $3, 0($1) ++; MM32-NEXT: beqzc $3, $BB3_1 ++; MM32-NEXT: # %bb.2: # %entry ++; MM32-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicLoadOr32: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $2, %hi(_gp_disp) ++; O1-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O1-NEXT: addu $1, $2, $25 ++; O1-NEXT: lw $1, %got(x)($1) ++; O1-NEXT: $BB3_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: ll $2, 0($1) ++; O1-NEXT: or $3, $2, $4 ++; O1-NEXT: sc $3, 0($1) ++; O1-NEXT: beqz $3, $BB3_1 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: jr $ra ++; O1-NEXT: nop ++; ++; O2-LABEL: AtomicLoadOr32: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $2, %hi(_gp_disp) ++; O2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O2-NEXT: addu $1, $2, $25 ++; O2-NEXT: lw $1, %got(x)($1) ++; O2-NEXT: $BB3_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: ll $2, 0($1) ++; O2-NEXT: or $3, $2, $4 ++; O2-NEXT: sc $3, 0($1) ++; O2-NEXT: beqz $3, $BB3_1 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: jr $ra ++; O2-NEXT: nop ++; ++; O3-LABEL: AtomicLoadOr32: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $2, %hi(_gp_disp) ++; O3-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O3-NEXT: addu $1, $2, $25 ++; O3-NEXT: lw $1, %got(x)($1) ++; O3-NEXT: $BB3_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: ll $2, 0($1) ++; O3-NEXT: or $3, $2, $4 ++; O3-NEXT: sc $3, 0($1) ++; O3-NEXT: beqz $3, $BB3_1 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: jr $ra ++; O3-NEXT: nop ++; ++; MIPS32EB-LABEL: AtomicLoadOr32: ++; MIPS32EB: # %bb.0: # %entry ++; MIPS32EB-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32EB-NEXT: addu $1, $2, $25 ++; MIPS32EB-NEXT: lw $1, %got(x)($1) ++; MIPS32EB-NEXT: $BB3_1: # %entry ++; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32EB-NEXT: ll $2, 0($1) ++; MIPS32EB-NEXT: or $3, $2, $4 ++; MIPS32EB-NEXT: sc $3, 0($1) ++; MIPS32EB-NEXT: beqz $3, $BB3_1 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: # %bb.2: # %entry ++; MIPS32EB-NEXT: jr $ra ++; MIPS32EB-NEXT: nop ++entry: ++ %0 = atomicrmw or ptr @x, i32 %incr monotonic ++ ret i32 %0 ++} ++ ++define i32 @AtomicLoadAnd32(i32 signext %incr) nounwind { ++; MIPS32-LABEL: AtomicLoadAnd32: ++; MIPS32: # %bb.0: # %entry ++; MIPS32-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32-NEXT: addu $1, $2, $25 ++; MIPS32-NEXT: lw $1, %got(x)($1) ++; MIPS32-NEXT: $BB4_1: # %entry ++; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32-NEXT: ll $2, 0($1) ++; MIPS32-NEXT: and $3, $2, $4 ++; MIPS32-NEXT: sc $3, 0($1) ++; MIPS32-NEXT: beqz $3, $BB4_1 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: # %bb.2: # %entry ++; MIPS32-NEXT: jr $ra ++; MIPS32-NEXT: nop ++; ++; MIPS32O0-LABEL: AtomicLoadAnd32: ++; MIPS32O0: # %bb.0: # %entry ++; MIPS32O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32O0-NEXT: addu $1, $2, $25 ++; MIPS32O0-NEXT: lw $3, %got(x)($1) ++; MIPS32O0-NEXT: $BB4_1: # %entry ++; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32O0-NEXT: ll $2, 0($3) ++; MIPS32O0-NEXT: and $1, $2, $4 ++; MIPS32O0-NEXT: sc $1, 0($3) ++; MIPS32O0-NEXT: beqz $1, $BB4_1 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: # %bb.2: # %entry ++; MIPS32O0-NEXT: jr $ra ++; MIPS32O0-NEXT: nop ++; ++; MIPS32R2-LABEL: AtomicLoadAnd32: ++; MIPS32R2: # %bb.0: # %entry ++; MIPS32R2-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R2-NEXT: addu $1, $2, $25 ++; MIPS32R2-NEXT: lw $1, %got(x)($1) ++; MIPS32R2-NEXT: $BB4_1: # %entry ++; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R2-NEXT: ll $2, 0($1) ++; MIPS32R2-NEXT: and $3, $2, $4 ++; MIPS32R2-NEXT: sc $3, 0($1) ++; MIPS32R2-NEXT: beqz $3, $BB4_1 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: # %bb.2: # %entry ++; MIPS32R2-NEXT: jr $ra ++; MIPS32R2-NEXT: nop ++; ++; MIPS32R6-LABEL: AtomicLoadAnd32: ++; MIPS32R6: # %bb.0: # %entry ++; MIPS32R6-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6-NEXT: addu $1, $2, $25 ++; MIPS32R6-NEXT: lw $1, %got(x)($1) ++; MIPS32R6-NEXT: $BB4_1: # %entry ++; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6-NEXT: ll $2, 0($1) ++; MIPS32R6-NEXT: and $3, $2, $4 ++; MIPS32R6-NEXT: sc $3, 0($1) ++; MIPS32R6-NEXT: beqzc $3, $BB4_1 ++; MIPS32R6-NEXT: nop ++; MIPS32R6-NEXT: # %bb.2: # %entry ++; MIPS32R6-NEXT: jrc $ra ++; ++; MIPS32R6O0-LABEL: AtomicLoadAnd32: ++; MIPS32R6O0: # %bb.0: # %entry ++; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6O0-NEXT: addu $1, $2, $25 ++; MIPS32R6O0-NEXT: lw $3, %got(x)($1) ++; MIPS32R6O0-NEXT: $BB4_1: # %entry ++; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6O0-NEXT: ll $2, 0($3) ++; MIPS32R6O0-NEXT: and $1, $2, $4 ++; MIPS32R6O0-NEXT: sc $1, 0($3) ++; MIPS32R6O0-NEXT: beqzc $1, $BB4_1 ++; MIPS32R6O0-NEXT: nop ++; MIPS32R6O0-NEXT: # %bb.2: # %entry ++; MIPS32R6O0-NEXT: jrc $ra ++; ++; MIPS4-LABEL: AtomicLoadAnd32: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAnd32))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAnd32))) ++; MIPS4-NEXT: ld $1, %got_disp(x)($1) ++; MIPS4-NEXT: .LBB4_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: ll $2, 0($1) ++; MIPS4-NEXT: and $3, $2, $4 ++; MIPS4-NEXT: sc $3, 0($1) ++; MIPS4-NEXT: beqz $3, .LBB4_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: nop ++; ++; MIPS64-LABEL: AtomicLoadAnd32: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAnd32))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAnd32))) ++; MIPS64-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64-NEXT: .LBB4_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: ll $2, 0($1) ++; MIPS64-NEXT: and $3, $2, $4 ++; MIPS64-NEXT: sc $3, 0($1) ++; MIPS64-NEXT: beqz $3, .LBB4_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: nop ++; ++; MIPS64R2-LABEL: AtomicLoadAnd32: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAnd32))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAnd32))) ++; MIPS64R2-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R2-NEXT: .LBB4_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: ll $2, 0($1) ++; MIPS64R2-NEXT: and $3, $2, $4 ++; MIPS64R2-NEXT: sc $3, 0($1) ++; MIPS64R2-NEXT: beqz $3, .LBB4_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: nop ++; ++; MIPS64R6-LABEL: AtomicLoadAnd32: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAnd32))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAnd32))) ++; MIPS64R6-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R6-NEXT: .LBB4_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: ll $2, 0($1) ++; MIPS64R6-NEXT: and $3, $2, $4 ++; MIPS64R6-NEXT: sc $3, 0($1) ++; MIPS64R6-NEXT: beqzc $3, .LBB4_1 ++; MIPS64R6-NEXT: nop ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: jrc $ra ++; ++; MIPS64R6O0-LABEL: AtomicLoadAnd32: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAnd32))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAnd32))) ++; MIPS64R6O0-NEXT: # kill: def $a0 killed $a0 killed $a0_64 ++; MIPS64R6O0-NEXT: ld $3, %got_disp(x)($1) ++; MIPS64R6O0-NEXT: .LBB4_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: ll $2, 0($3) ++; MIPS64R6O0-NEXT: and $1, $2, $4 ++; MIPS64R6O0-NEXT: sc $1, 0($3) ++; MIPS64R6O0-NEXT: beqzc $1, .LBB4_1 ++; MIPS64R6O0-NEXT: nop ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; MM32-LABEL: AtomicLoadAnd32: ++; MM32: # %bb.0: # %entry ++; MM32-NEXT: lui $2, %hi(_gp_disp) ++; MM32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MM32-NEXT: addu $2, $2, $25 ++; MM32-NEXT: lw $1, %got(x)($2) ++; MM32-NEXT: $BB4_1: # %entry ++; MM32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MM32-NEXT: ll $2, 0($1) ++; MM32-NEXT: and $3, $2, $4 ++; MM32-NEXT: sc $3, 0($1) ++; MM32-NEXT: beqzc $3, $BB4_1 ++; MM32-NEXT: # %bb.2: # %entry ++; MM32-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicLoadAnd32: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $2, %hi(_gp_disp) ++; O1-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O1-NEXT: addu $1, $2, $25 ++; O1-NEXT: lw $1, %got(x)($1) ++; O1-NEXT: $BB4_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: ll $2, 0($1) ++; O1-NEXT: and $3, $2, $4 ++; O1-NEXT: sc $3, 0($1) ++; O1-NEXT: beqz $3, $BB4_1 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: jr $ra ++; O1-NEXT: nop ++; ++; O2-LABEL: AtomicLoadAnd32: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $2, %hi(_gp_disp) ++; O2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O2-NEXT: addu $1, $2, $25 ++; O2-NEXT: lw $1, %got(x)($1) ++; O2-NEXT: $BB4_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: ll $2, 0($1) ++; O2-NEXT: and $3, $2, $4 ++; O2-NEXT: sc $3, 0($1) ++; O2-NEXT: beqz $3, $BB4_1 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: jr $ra ++; O2-NEXT: nop ++; ++; O3-LABEL: AtomicLoadAnd32: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $2, %hi(_gp_disp) ++; O3-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O3-NEXT: addu $1, $2, $25 ++; O3-NEXT: lw $1, %got(x)($1) ++; O3-NEXT: $BB4_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: ll $2, 0($1) ++; O3-NEXT: and $3, $2, $4 ++; O3-NEXT: sc $3, 0($1) ++; O3-NEXT: beqz $3, $BB4_1 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: jr $ra ++; O3-NEXT: nop ++; ++; MIPS32EB-LABEL: AtomicLoadAnd32: ++; MIPS32EB: # %bb.0: # %entry ++; MIPS32EB-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32EB-NEXT: addu $1, $2, $25 ++; MIPS32EB-NEXT: lw $1, %got(x)($1) ++; MIPS32EB-NEXT: $BB4_1: # %entry ++; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32EB-NEXT: ll $2, 0($1) ++; MIPS32EB-NEXT: and $3, $2, $4 ++; MIPS32EB-NEXT: sc $3, 0($1) ++; MIPS32EB-NEXT: beqz $3, $BB4_1 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: # %bb.2: # %entry ++; MIPS32EB-NEXT: jr $ra ++; MIPS32EB-NEXT: nop ++entry: ++ %0 = atomicrmw and ptr @x, i32 %incr monotonic ++ ret i32 %0 ++} ++ ++define i32 @AtomicLoadNand32(i32 signext %incr) nounwind { ++; MIPS32-LABEL: AtomicLoadNand32: ++; MIPS32: # %bb.0: # %entry ++; MIPS32-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32-NEXT: addu $1, $2, $25 ++; MIPS32-NEXT: lw $1, %got(x)($1) ++; MIPS32-NEXT: $BB5_1: # %entry ++; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32-NEXT: ll $2, 0($1) ++; MIPS32-NEXT: and $3, $2, $4 ++; MIPS32-NEXT: nor $3, $zero, $3 ++; MIPS32-NEXT: sc $3, 0($1) ++; MIPS32-NEXT: beqz $3, $BB5_1 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: # %bb.2: # %entry ++; MIPS32-NEXT: jr $ra ++; MIPS32-NEXT: nop ++; ++; MIPS32O0-LABEL: AtomicLoadNand32: ++; MIPS32O0: # %bb.0: # %entry ++; MIPS32O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32O0-NEXT: addu $1, $2, $25 ++; MIPS32O0-NEXT: lw $3, %got(x)($1) ++; MIPS32O0-NEXT: $BB5_1: # %entry ++; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32O0-NEXT: ll $2, 0($3) ++; MIPS32O0-NEXT: and $1, $2, $4 ++; MIPS32O0-NEXT: nor $1, $zero, $1 ++; MIPS32O0-NEXT: sc $1, 0($3) ++; MIPS32O0-NEXT: beqz $1, $BB5_1 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: # %bb.2: # %entry ++; MIPS32O0-NEXT: jr $ra ++; MIPS32O0-NEXT: nop ++; ++; MIPS32R2-LABEL: AtomicLoadNand32: ++; MIPS32R2: # %bb.0: # %entry ++; MIPS32R2-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R2-NEXT: addu $1, $2, $25 ++; MIPS32R2-NEXT: lw $1, %got(x)($1) ++; MIPS32R2-NEXT: $BB5_1: # %entry ++; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R2-NEXT: ll $2, 0($1) ++; MIPS32R2-NEXT: and $3, $2, $4 ++; MIPS32R2-NEXT: nor $3, $zero, $3 ++; MIPS32R2-NEXT: sc $3, 0($1) ++; MIPS32R2-NEXT: beqz $3, $BB5_1 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: # %bb.2: # %entry ++; MIPS32R2-NEXT: jr $ra ++; MIPS32R2-NEXT: nop ++; ++; MIPS32R6-LABEL: AtomicLoadNand32: ++; MIPS32R6: # %bb.0: # %entry ++; MIPS32R6-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6-NEXT: addu $1, $2, $25 ++; MIPS32R6-NEXT: lw $1, %got(x)($1) ++; MIPS32R6-NEXT: $BB5_1: # %entry ++; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6-NEXT: ll $2, 0($1) ++; MIPS32R6-NEXT: and $3, $2, $4 ++; MIPS32R6-NEXT: nor $3, $zero, $3 ++; MIPS32R6-NEXT: sc $3, 0($1) ++; MIPS32R6-NEXT: beqzc $3, $BB5_1 ++; MIPS32R6-NEXT: nop ++; MIPS32R6-NEXT: # %bb.2: # %entry ++; MIPS32R6-NEXT: jrc $ra ++; ++; MIPS32R6O0-LABEL: AtomicLoadNand32: ++; MIPS32R6O0: # %bb.0: # %entry ++; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6O0-NEXT: addu $1, $2, $25 ++; MIPS32R6O0-NEXT: lw $3, %got(x)($1) ++; MIPS32R6O0-NEXT: $BB5_1: # %entry ++; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6O0-NEXT: ll $2, 0($3) ++; MIPS32R6O0-NEXT: and $1, $2, $4 ++; MIPS32R6O0-NEXT: nor $1, $zero, $1 ++; MIPS32R6O0-NEXT: sc $1, 0($3) ++; MIPS32R6O0-NEXT: beqzc $1, $BB5_1 ++; MIPS32R6O0-NEXT: nop ++; MIPS32R6O0-NEXT: # %bb.2: # %entry ++; MIPS32R6O0-NEXT: jrc $ra ++; ++; MIPS4-LABEL: AtomicLoadNand32: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadNand32))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadNand32))) ++; MIPS4-NEXT: ld $1, %got_disp(x)($1) ++; MIPS4-NEXT: .LBB5_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: ll $2, 0($1) ++; MIPS4-NEXT: and $3, $2, $4 ++; MIPS4-NEXT: nor $3, $zero, $3 ++; MIPS4-NEXT: sc $3, 0($1) ++; MIPS4-NEXT: beqz $3, .LBB5_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: nop ++; ++; MIPS64-LABEL: AtomicLoadNand32: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadNand32))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadNand32))) ++; MIPS64-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64-NEXT: .LBB5_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: ll $2, 0($1) ++; MIPS64-NEXT: and $3, $2, $4 ++; MIPS64-NEXT: nor $3, $zero, $3 ++; MIPS64-NEXT: sc $3, 0($1) ++; MIPS64-NEXT: beqz $3, .LBB5_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: nop ++; ++; MIPS64R2-LABEL: AtomicLoadNand32: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadNand32))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadNand32))) ++; MIPS64R2-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R2-NEXT: .LBB5_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: ll $2, 0($1) ++; MIPS64R2-NEXT: and $3, $2, $4 ++; MIPS64R2-NEXT: nor $3, $zero, $3 ++; MIPS64R2-NEXT: sc $3, 0($1) ++; MIPS64R2-NEXT: beqz $3, .LBB5_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: nop ++; ++; MIPS64R6-LABEL: AtomicLoadNand32: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadNand32))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadNand32))) ++; MIPS64R6-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R6-NEXT: .LBB5_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: ll $2, 0($1) ++; MIPS64R6-NEXT: and $3, $2, $4 ++; MIPS64R6-NEXT: nor $3, $zero, $3 ++; MIPS64R6-NEXT: sc $3, 0($1) ++; MIPS64R6-NEXT: beqzc $3, .LBB5_1 ++; MIPS64R6-NEXT: nop ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: jrc $ra ++; ++; MIPS64R6O0-LABEL: AtomicLoadNand32: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadNand32))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadNand32))) ++; MIPS64R6O0-NEXT: # kill: def $a0 killed $a0 killed $a0_64 ++; MIPS64R6O0-NEXT: ld $3, %got_disp(x)($1) ++; MIPS64R6O0-NEXT: .LBB5_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: ll $2, 0($3) ++; MIPS64R6O0-NEXT: and $1, $2, $4 ++; MIPS64R6O0-NEXT: nor $1, $zero, $1 ++; MIPS64R6O0-NEXT: sc $1, 0($3) ++; MIPS64R6O0-NEXT: beqzc $1, .LBB5_1 ++; MIPS64R6O0-NEXT: nop ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; MM32-LABEL: AtomicLoadNand32: ++; MM32: # %bb.0: # %entry ++; MM32-NEXT: lui $2, %hi(_gp_disp) ++; MM32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MM32-NEXT: addu $2, $2, $25 ++; MM32-NEXT: lw $1, %got(x)($2) ++; MM32-NEXT: $BB5_1: # %entry ++; MM32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MM32-NEXT: ll $2, 0($1) ++; MM32-NEXT: and $3, $2, $4 ++; MM32-NEXT: nor $3, $zero, $3 ++; MM32-NEXT: sc $3, 0($1) ++; MM32-NEXT: beqzc $3, $BB5_1 ++; MM32-NEXT: # %bb.2: # %entry ++; MM32-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicLoadNand32: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $2, %hi(_gp_disp) ++; O1-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O1-NEXT: addu $1, $2, $25 ++; O1-NEXT: lw $1, %got(x)($1) ++; O1-NEXT: $BB5_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: ll $2, 0($1) ++; O1-NEXT: and $3, $2, $4 ++; O1-NEXT: nor $3, $zero, $3 ++; O1-NEXT: sc $3, 0($1) ++; O1-NEXT: beqz $3, $BB5_1 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: jr $ra ++; O1-NEXT: nop ++; ++; O2-LABEL: AtomicLoadNand32: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $2, %hi(_gp_disp) ++; O2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O2-NEXT: addu $1, $2, $25 ++; O2-NEXT: lw $1, %got(x)($1) ++; O2-NEXT: $BB5_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: ll $2, 0($1) ++; O2-NEXT: and $3, $2, $4 ++; O2-NEXT: nor $3, $zero, $3 ++; O2-NEXT: sc $3, 0($1) ++; O2-NEXT: beqz $3, $BB5_1 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: jr $ra ++; O2-NEXT: nop ++; ++; O3-LABEL: AtomicLoadNand32: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $2, %hi(_gp_disp) ++; O3-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O3-NEXT: addu $1, $2, $25 ++; O3-NEXT: lw $1, %got(x)($1) ++; O3-NEXT: $BB5_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: ll $2, 0($1) ++; O3-NEXT: and $3, $2, $4 ++; O3-NEXT: nor $3, $zero, $3 ++; O3-NEXT: sc $3, 0($1) ++; O3-NEXT: beqz $3, $BB5_1 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: jr $ra ++; O3-NEXT: nop ++; ++; MIPS32EB-LABEL: AtomicLoadNand32: ++; MIPS32EB: # %bb.0: # %entry ++; MIPS32EB-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32EB-NEXT: addu $1, $2, $25 ++; MIPS32EB-NEXT: lw $1, %got(x)($1) ++; MIPS32EB-NEXT: $BB5_1: # %entry ++; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32EB-NEXT: ll $2, 0($1) ++; MIPS32EB-NEXT: and $3, $2, $4 ++; MIPS32EB-NEXT: nor $3, $zero, $3 ++; MIPS32EB-NEXT: sc $3, 0($1) ++; MIPS32EB-NEXT: beqz $3, $BB5_1 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: # %bb.2: # %entry ++; MIPS32EB-NEXT: jr $ra ++; MIPS32EB-NEXT: nop ++entry: ++ %0 = atomicrmw nand ptr @x, i32 %incr monotonic ++ ret i32 %0 ++ ++} ++ ++define i32 @AtomicSwap32(i32 signext %newval) nounwind { ++; MIPS32-LABEL: AtomicSwap32: ++; MIPS32: # %bb.0: # %entry ++; MIPS32-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32-NEXT: addiu $sp, $sp, -8 ++; MIPS32-NEXT: addu $1, $2, $25 ++; MIPS32-NEXT: sw $4, 4($sp) ++; MIPS32-NEXT: lw $1, %got(x)($1) ++; MIPS32-NEXT: $BB6_1: # %entry ++; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32-NEXT: ll $2, 0($1) ++; MIPS32-NEXT: move $3, $4 ++; MIPS32-NEXT: sc $3, 0($1) ++; MIPS32-NEXT: beqz $3, $BB6_1 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: # %bb.2: # %entry ++; MIPS32-NEXT: jr $ra ++; MIPS32-NEXT: addiu $sp, $sp, 8 ++; ++; MIPS32O0-LABEL: AtomicSwap32: ++; MIPS32O0: # %bb.0: # %entry ++; MIPS32O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32O0-NEXT: addiu $sp, $sp, -8 ++; MIPS32O0-NEXT: addu $1, $2, $25 ++; MIPS32O0-NEXT: sw $4, 4($sp) ++; MIPS32O0-NEXT: lw $4, 4($sp) ++; MIPS32O0-NEXT: lw $3, %got(x)($1) ++; MIPS32O0-NEXT: $BB6_1: # %entry ++; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32O0-NEXT: ll $2, 0($3) ++; MIPS32O0-NEXT: move $1, $4 ++; MIPS32O0-NEXT: sc $1, 0($3) ++; MIPS32O0-NEXT: beqz $1, $BB6_1 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: # %bb.2: # %entry ++; MIPS32O0-NEXT: addiu $sp, $sp, 8 ++; MIPS32O0-NEXT: jr $ra ++; MIPS32O0-NEXT: nop ++; ++; MIPS32R2-LABEL: AtomicSwap32: ++; MIPS32R2: # %bb.0: # %entry ++; MIPS32R2-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R2-NEXT: addiu $sp, $sp, -8 ++; MIPS32R2-NEXT: addu $1, $2, $25 ++; MIPS32R2-NEXT: sw $4, 4($sp) ++; MIPS32R2-NEXT: lw $1, %got(x)($1) ++; MIPS32R2-NEXT: $BB6_1: # %entry ++; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R2-NEXT: ll $2, 0($1) ++; MIPS32R2-NEXT: move $3, $4 ++; MIPS32R2-NEXT: sc $3, 0($1) ++; MIPS32R2-NEXT: beqz $3, $BB6_1 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: # %bb.2: # %entry ++; MIPS32R2-NEXT: jr $ra ++; MIPS32R2-NEXT: addiu $sp, $sp, 8 ++; ++; MIPS32R6-LABEL: AtomicSwap32: ++; MIPS32R6: # %bb.0: # %entry ++; MIPS32R6-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6-NEXT: addiu $sp, $sp, -8 ++; MIPS32R6-NEXT: addu $1, $2, $25 ++; MIPS32R6-NEXT: sw $4, 4($sp) ++; MIPS32R6-NEXT: lw $1, %got(x)($1) ++; MIPS32R6-NEXT: $BB6_1: # %entry ++; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6-NEXT: ll $2, 0($1) ++; MIPS32R6-NEXT: move $3, $4 ++; MIPS32R6-NEXT: sc $3, 0($1) ++; MIPS32R6-NEXT: beqzc $3, $BB6_1 ++; MIPS32R6-NEXT: nop ++; MIPS32R6-NEXT: # %bb.2: # %entry ++; MIPS32R6-NEXT: jr $ra ++; MIPS32R6-NEXT: addiu $sp, $sp, 8 ++; ++; MIPS32R6O0-LABEL: AtomicSwap32: ++; MIPS32R6O0: # %bb.0: # %entry ++; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $sp, $sp, -8 ++; MIPS32R6O0-NEXT: addu $1, $2, $25 ++; MIPS32R6O0-NEXT: sw $4, 4($sp) ++; MIPS32R6O0-NEXT: lw $4, 4($sp) ++; MIPS32R6O0-NEXT: lw $3, %got(x)($1) ++; MIPS32R6O0-NEXT: $BB6_1: # %entry ++; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6O0-NEXT: ll $2, 0($3) ++; MIPS32R6O0-NEXT: move $1, $4 ++; MIPS32R6O0-NEXT: sc $1, 0($3) ++; MIPS32R6O0-NEXT: beqzc $1, $BB6_1 ++; MIPS32R6O0-NEXT: # %bb.2: # %entry ++; MIPS32R6O0-NEXT: addiu $sp, $sp, 8 ++; MIPS32R6O0-NEXT: jrc $ra ++; ++; MIPS4-LABEL: AtomicSwap32: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: daddiu $sp, $sp, -16 ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicSwap32))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicSwap32))) ++; MIPS4-NEXT: sw $4, 12($sp) ++; MIPS4-NEXT: ld $1, %got_disp(x)($1) ++; MIPS4-NEXT: .LBB6_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: ll $2, 0($1) ++; MIPS4-NEXT: move $3, $4 ++; MIPS4-NEXT: sc $3, 0($1) ++; MIPS4-NEXT: beqz $3, .LBB6_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: daddiu $sp, $sp, 16 ++; ++; MIPS64-LABEL: AtomicSwap32: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: daddiu $sp, $sp, -16 ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicSwap32))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicSwap32))) ++; MIPS64-NEXT: sw $4, 12($sp) ++; MIPS64-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64-NEXT: .LBB6_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: ll $2, 0($1) ++; MIPS64-NEXT: move $3, $4 ++; MIPS64-NEXT: sc $3, 0($1) ++; MIPS64-NEXT: beqz $3, .LBB6_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: daddiu $sp, $sp, 16 ++; ++; MIPS64R2-LABEL: AtomicSwap32: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: daddiu $sp, $sp, -16 ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicSwap32))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicSwap32))) ++; MIPS64R2-NEXT: sw $4, 12($sp) ++; MIPS64R2-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R2-NEXT: .LBB6_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: ll $2, 0($1) ++; MIPS64R2-NEXT: move $3, $4 ++; MIPS64R2-NEXT: sc $3, 0($1) ++; MIPS64R2-NEXT: beqz $3, .LBB6_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: daddiu $sp, $sp, 16 ++; ++; MIPS64R6-LABEL: AtomicSwap32: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: daddiu $sp, $sp, -16 ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicSwap32))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicSwap32))) ++; MIPS64R6-NEXT: sw $4, 12($sp) ++; MIPS64R6-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R6-NEXT: .LBB6_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: ll $2, 0($1) ++; MIPS64R6-NEXT: move $3, $4 ++; MIPS64R6-NEXT: sc $3, 0($1) ++; MIPS64R6-NEXT: beqzc $3, .LBB6_1 ++; MIPS64R6-NEXT: nop ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: jr $ra ++; MIPS64R6-NEXT: daddiu $sp, $sp, 16 ++; ++; MIPS64R6O0-LABEL: AtomicSwap32: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, -16 ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicSwap32))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicSwap32))) ++; MIPS64R6O0-NEXT: move $2, $4 ++; MIPS64R6O0-NEXT: sw $2, 12($sp) ++; MIPS64R6O0-NEXT: lw $4, 12($sp) ++; MIPS64R6O0-NEXT: ld $3, %got_disp(x)($1) ++; MIPS64R6O0-NEXT: .LBB6_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: ll $2, 0($3) ++; MIPS64R6O0-NEXT: move $1, $4 ++; MIPS64R6O0-NEXT: sc $1, 0($3) ++; MIPS64R6O0-NEXT: beqzc $1, .LBB6_1 ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, 16 ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; MM32-LABEL: AtomicSwap32: ++; MM32: # %bb.0: # %entry ++; MM32-NEXT: lui $2, %hi(_gp_disp) ++; MM32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MM32-NEXT: addiu $sp, $sp, -8 ++; MM32-NEXT: addu $2, $2, $25 ++; MM32-NEXT: sw $4, 4($sp) ++; MM32-NEXT: lw $1, %got(x)($2) ++; MM32-NEXT: $BB6_1: # %entry ++; MM32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MM32-NEXT: ll $2, 0($1) ++; MM32-NEXT: or $3, $4, $zero ++; MM32-NEXT: sc $3, 0($1) ++; MM32-NEXT: beqzc $3, $BB6_1 ++; MM32-NEXT: # %bb.2: # %entry ++; MM32-NEXT: addiusp 8 ++; MM32-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicSwap32: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $2, %hi(_gp_disp) ++; O1-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O1-NEXT: addiu $sp, $sp, -8 ++; O1-NEXT: addu $1, $2, $25 ++; O1-NEXT: sw $4, 4($sp) ++; O1-NEXT: lw $1, %got(x)($1) ++; O1-NEXT: $BB6_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: ll $2, 0($1) ++; O1-NEXT: move $3, $4 ++; O1-NEXT: sc $3, 0($1) ++; O1-NEXT: beqz $3, $BB6_1 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: jr $ra ++; O1-NEXT: addiu $sp, $sp, 8 ++; ++; O2-LABEL: AtomicSwap32: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $2, %hi(_gp_disp) ++; O2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O2-NEXT: addiu $sp, $sp, -8 ++; O2-NEXT: addu $1, $2, $25 ++; O2-NEXT: sw $4, 4($sp) ++; O2-NEXT: lw $1, %got(x)($1) ++; O2-NEXT: $BB6_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: ll $2, 0($1) ++; O2-NEXT: move $3, $4 ++; O2-NEXT: sc $3, 0($1) ++; O2-NEXT: beqz $3, $BB6_1 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: jr $ra ++; O2-NEXT: addiu $sp, $sp, 8 ++; ++; O3-LABEL: AtomicSwap32: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $2, %hi(_gp_disp) ++; O3-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O3-NEXT: addiu $sp, $sp, -8 ++; O3-NEXT: addu $1, $2, $25 ++; O3-NEXT: sw $4, 4($sp) ++; O3-NEXT: lw $1, %got(x)($1) ++; O3-NEXT: $BB6_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: ll $2, 0($1) ++; O3-NEXT: move $3, $4 ++; O3-NEXT: sc $3, 0($1) ++; O3-NEXT: beqz $3, $BB6_1 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: jr $ra ++; O3-NEXT: addiu $sp, $sp, 8 ++; ++; MIPS32EB-LABEL: AtomicSwap32: ++; MIPS32EB: # %bb.0: # %entry ++; MIPS32EB-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32EB-NEXT: addiu $sp, $sp, -8 ++; MIPS32EB-NEXT: addu $1, $2, $25 ++; MIPS32EB-NEXT: sw $4, 4($sp) ++; MIPS32EB-NEXT: lw $1, %got(x)($1) ++; MIPS32EB-NEXT: $BB6_1: # %entry ++; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32EB-NEXT: ll $2, 0($1) ++; MIPS32EB-NEXT: move $3, $4 ++; MIPS32EB-NEXT: sc $3, 0($1) ++; MIPS32EB-NEXT: beqz $3, $BB6_1 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: # %bb.2: # %entry ++; MIPS32EB-NEXT: jr $ra ++; MIPS32EB-NEXT: addiu $sp, $sp, 8 ++entry: ++ %newval.addr = alloca i32, align 4 ++ store i32 %newval, ptr %newval.addr, align 4 ++ %tmp = load i32, ptr %newval.addr, align 4 ++ %0 = atomicrmw xchg ptr @x, i32 %tmp monotonic ++ ret i32 %0 ++ ++} ++ ++define i32 @AtomicCmpSwap32(i32 signext %oldval, i32 signext %newval) nounwind { ++; MIPS32-LABEL: AtomicCmpSwap32: ++; MIPS32: # %bb.0: # %entry ++; MIPS32-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32-NEXT: addiu $sp, $sp, -8 ++; MIPS32-NEXT: addu $1, $2, $25 ++; MIPS32-NEXT: sw $5, 4($sp) ++; MIPS32-NEXT: lw $1, %got(x)($1) ++; MIPS32-NEXT: $BB7_1: # %entry ++; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32-NEXT: ll $2, 0($1) ++; MIPS32-NEXT: bne $2, $4, $BB7_3 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: # %bb.2: # %entry ++; MIPS32-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; MIPS32-NEXT: move $3, $5 ++; MIPS32-NEXT: sc $3, 0($1) ++; MIPS32-NEXT: beqz $3, $BB7_1 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: $BB7_3: # %entry ++; MIPS32-NEXT: sync ++; MIPS32-NEXT: jr $ra ++; MIPS32-NEXT: addiu $sp, $sp, 8 ++; ++; MIPS32O0-LABEL: AtomicCmpSwap32: ++; MIPS32O0: # %bb.0: # %entry ++; MIPS32O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32O0-NEXT: addiu $sp, $sp, -8 ++; MIPS32O0-NEXT: addu $1, $2, $25 ++; MIPS32O0-NEXT: sw $5, 4($sp) ++; MIPS32O0-NEXT: lw $6, 4($sp) ++; MIPS32O0-NEXT: lw $3, %got(x)($1) ++; MIPS32O0-NEXT: move $5, $4 ++; MIPS32O0-NEXT: $BB7_1: # %entry ++; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32O0-NEXT: ll $2, 0($3) ++; MIPS32O0-NEXT: bne $2, $5, $BB7_3 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: # %bb.2: # %entry ++; MIPS32O0-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; MIPS32O0-NEXT: move $1, $6 ++; MIPS32O0-NEXT: sc $1, 0($3) ++; MIPS32O0-NEXT: beqz $1, $BB7_1 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: $BB7_3: # %entry ++; MIPS32O0-NEXT: sync ++; MIPS32O0-NEXT: xor $1, $2, $4 ++; MIPS32O0-NEXT: sltiu $1, $1, 1 ++; MIPS32O0-NEXT: addiu $sp, $sp, 8 ++; MIPS32O0-NEXT: jr $ra ++; MIPS32O0-NEXT: nop ++; ++; MIPS32R2-LABEL: AtomicCmpSwap32: ++; MIPS32R2: # %bb.0: # %entry ++; MIPS32R2-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R2-NEXT: addiu $sp, $sp, -8 ++; MIPS32R2-NEXT: addu $1, $2, $25 ++; MIPS32R2-NEXT: sw $5, 4($sp) ++; MIPS32R2-NEXT: lw $1, %got(x)($1) ++; MIPS32R2-NEXT: $BB7_1: # %entry ++; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R2-NEXT: ll $2, 0($1) ++; MIPS32R2-NEXT: bne $2, $4, $BB7_3 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: # %bb.2: # %entry ++; MIPS32R2-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; MIPS32R2-NEXT: move $3, $5 ++; MIPS32R2-NEXT: sc $3, 0($1) ++; MIPS32R2-NEXT: beqz $3, $BB7_1 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: $BB7_3: # %entry ++; MIPS32R2-NEXT: sync ++; MIPS32R2-NEXT: jr $ra ++; MIPS32R2-NEXT: addiu $sp, $sp, 8 ++; ++; MIPS32R6-LABEL: AtomicCmpSwap32: ++; MIPS32R6: # %bb.0: # %entry ++; MIPS32R6-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6-NEXT: addiu $sp, $sp, -8 ++; MIPS32R6-NEXT: addu $1, $2, $25 ++; MIPS32R6-NEXT: sw $5, 4($sp) ++; MIPS32R6-NEXT: lw $1, %got(x)($1) ++; MIPS32R6-NEXT: $BB7_1: # %entry ++; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6-NEXT: ll $2, 0($1) ++; MIPS32R6-NEXT: bnec $2, $4, $BB7_3 ++; MIPS32R6-NEXT: # %bb.2: # %entry ++; MIPS32R6-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; MIPS32R6-NEXT: move $3, $5 ++; MIPS32R6-NEXT: sc $3, 0($1) ++; MIPS32R6-NEXT: beqzc $3, $BB7_1 ++; MIPS32R6-NEXT: $BB7_3: # %entry ++; MIPS32R6-NEXT: sync ++; MIPS32R6-NEXT: jr $ra ++; MIPS32R6-NEXT: addiu $sp, $sp, 8 ++; ++; MIPS32R6O0-LABEL: AtomicCmpSwap32: ++; MIPS32R6O0: # %bb.0: # %entry ++; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $sp, $sp, -8 ++; MIPS32R6O0-NEXT: addu $1, $2, $25 ++; MIPS32R6O0-NEXT: sw $5, 4($sp) ++; MIPS32R6O0-NEXT: lw $5, 4($sp) ++; MIPS32R6O0-NEXT: lw $3, %got(x)($1) ++; MIPS32R6O0-NEXT: $BB7_1: # %entry ++; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6O0-NEXT: ll $2, 0($3) ++; MIPS32R6O0-NEXT: bnec $2, $4, $BB7_3 ++; MIPS32R6O0-NEXT: # %bb.2: # %entry ++; MIPS32R6O0-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; MIPS32R6O0-NEXT: move $1, $5 ++; MIPS32R6O0-NEXT: sc $1, 0($3) ++; MIPS32R6O0-NEXT: beqzc $1, $BB7_1 ++; MIPS32R6O0-NEXT: $BB7_3: # %entry ++; MIPS32R6O0-NEXT: sync ++; MIPS32R6O0-NEXT: addiu $sp, $sp, 8 ++; MIPS32R6O0-NEXT: jrc $ra ++; ++; MIPS4-LABEL: AtomicCmpSwap32: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: daddiu $sp, $sp, -16 ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicCmpSwap32))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicCmpSwap32))) ++; MIPS4-NEXT: sw $5, 12($sp) ++; MIPS4-NEXT: ld $1, %got_disp(x)($1) ++; MIPS4-NEXT: .LBB7_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: ll $2, 0($1) ++; MIPS4-NEXT: bne $2, $4, .LBB7_3 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; MIPS4-NEXT: move $3, $5 ++; MIPS4-NEXT: sc $3, 0($1) ++; MIPS4-NEXT: beqz $3, .LBB7_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: .LBB7_3: # %entry ++; MIPS4-NEXT: sync ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: daddiu $sp, $sp, 16 ++; ++; MIPS64-LABEL: AtomicCmpSwap32: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: daddiu $sp, $sp, -16 ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicCmpSwap32))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicCmpSwap32))) ++; MIPS64-NEXT: sw $5, 12($sp) ++; MIPS64-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64-NEXT: .LBB7_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: ll $2, 0($1) ++; MIPS64-NEXT: bne $2, $4, .LBB7_3 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; MIPS64-NEXT: move $3, $5 ++; MIPS64-NEXT: sc $3, 0($1) ++; MIPS64-NEXT: beqz $3, .LBB7_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: .LBB7_3: # %entry ++; MIPS64-NEXT: sync ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: daddiu $sp, $sp, 16 ++; ++; MIPS64R2-LABEL: AtomicCmpSwap32: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: daddiu $sp, $sp, -16 ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicCmpSwap32))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicCmpSwap32))) ++; MIPS64R2-NEXT: sw $5, 12($sp) ++; MIPS64R2-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R2-NEXT: .LBB7_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: ll $2, 0($1) ++; MIPS64R2-NEXT: bne $2, $4, .LBB7_3 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; MIPS64R2-NEXT: move $3, $5 ++; MIPS64R2-NEXT: sc $3, 0($1) ++; MIPS64R2-NEXT: beqz $3, .LBB7_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: .LBB7_3: # %entry ++; MIPS64R2-NEXT: sync ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: daddiu $sp, $sp, 16 ++; ++; MIPS64R6-LABEL: AtomicCmpSwap32: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: daddiu $sp, $sp, -16 ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicCmpSwap32))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicCmpSwap32))) ++; MIPS64R6-NEXT: sw $5, 12($sp) ++; MIPS64R6-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R6-NEXT: .LBB7_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: ll $2, 0($1) ++; MIPS64R6-NEXT: bnec $2, $4, .LBB7_3 ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; MIPS64R6-NEXT: move $3, $5 ++; MIPS64R6-NEXT: sc $3, 0($1) ++; MIPS64R6-NEXT: beqzc $3, .LBB7_1 ++; MIPS64R6-NEXT: .LBB7_3: # %entry ++; MIPS64R6-NEXT: sync ++; MIPS64R6-NEXT: jr $ra ++; MIPS64R6-NEXT: daddiu $sp, $sp, 16 ++; ++; MIPS64R6O0-LABEL: AtomicCmpSwap32: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, -16 ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicCmpSwap32))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicCmpSwap32))) ++; MIPS64R6O0-NEXT: # kill: def $a0 killed $a0 killed $a0_64 ++; MIPS64R6O0-NEXT: move $2, $5 ++; MIPS64R6O0-NEXT: sw $2, 12($sp) ++; MIPS64R6O0-NEXT: lw $5, 12($sp) ++; MIPS64R6O0-NEXT: ld $3, %got_disp(x)($1) ++; MIPS64R6O0-NEXT: .LBB7_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: ll $2, 0($3) ++; MIPS64R6O0-NEXT: bnec $2, $4, .LBB7_3 ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; MIPS64R6O0-NEXT: move $1, $5 ++; MIPS64R6O0-NEXT: sc $1, 0($3) ++; MIPS64R6O0-NEXT: beqzc $1, .LBB7_1 ++; MIPS64R6O0-NEXT: .LBB7_3: # %entry ++; MIPS64R6O0-NEXT: sync ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, 16 ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; MM32-LABEL: AtomicCmpSwap32: ++; MM32: # %bb.0: # %entry ++; MM32-NEXT: lui $2, %hi(_gp_disp) ++; MM32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MM32-NEXT: addiu $sp, $sp, -8 ++; MM32-NEXT: addu $2, $2, $25 ++; MM32-NEXT: sw $5, 4($sp) ++; MM32-NEXT: lw $1, %got(x)($2) ++; MM32-NEXT: $BB7_1: # %entry ++; MM32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MM32-NEXT: ll $2, 0($1) ++; MM32-NEXT: bne $2, $4, $BB7_3 ++; MM32-NEXT: nop ++; MM32-NEXT: # %bb.2: # %entry ++; MM32-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; MM32-NEXT: move $3, $5 ++; MM32-NEXT: sc $3, 0($1) ++; MM32-NEXT: beqzc $3, $BB7_1 ++; MM32-NEXT: $BB7_3: # %entry ++; MM32-NEXT: sync 0 ++; MM32-NEXT: addiusp 8 ++; MM32-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicCmpSwap32: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $2, %hi(_gp_disp) ++; O1-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O1-NEXT: addiu $sp, $sp, -8 ++; O1-NEXT: addu $1, $2, $25 ++; O1-NEXT: sw $5, 4($sp) ++; O1-NEXT: lw $1, %got(x)($1) ++; O1-NEXT: $BB7_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: ll $2, 0($1) ++; O1-NEXT: bne $2, $4, $BB7_3 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; O1-NEXT: move $3, $5 ++; O1-NEXT: sc $3, 0($1) ++; O1-NEXT: beqz $3, $BB7_1 ++; O1-NEXT: nop ++; O1-NEXT: $BB7_3: # %entry ++; O1-NEXT: sync ++; O1-NEXT: jr $ra ++; O1-NEXT: addiu $sp, $sp, 8 ++; ++; O2-LABEL: AtomicCmpSwap32: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $2, %hi(_gp_disp) ++; O2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O2-NEXT: addiu $sp, $sp, -8 ++; O2-NEXT: addu $1, $2, $25 ++; O2-NEXT: sw $5, 4($sp) ++; O2-NEXT: lw $1, %got(x)($1) ++; O2-NEXT: $BB7_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: ll $2, 0($1) ++; O2-NEXT: bne $2, $4, $BB7_3 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; O2-NEXT: move $3, $5 ++; O2-NEXT: sc $3, 0($1) ++; O2-NEXT: beqz $3, $BB7_1 ++; O2-NEXT: nop ++; O2-NEXT: $BB7_3: # %entry ++; O2-NEXT: sync ++; O2-NEXT: jr $ra ++; O2-NEXT: addiu $sp, $sp, 8 ++; ++; O3-LABEL: AtomicCmpSwap32: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $2, %hi(_gp_disp) ++; O3-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O3-NEXT: addiu $sp, $sp, -8 ++; O3-NEXT: addu $1, $2, $25 ++; O3-NEXT: sw $5, 4($sp) ++; O3-NEXT: lw $1, %got(x)($1) ++; O3-NEXT: $BB7_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: ll $2, 0($1) ++; O3-NEXT: bne $2, $4, $BB7_3 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; O3-NEXT: move $3, $5 ++; O3-NEXT: sc $3, 0($1) ++; O3-NEXT: beqz $3, $BB7_1 ++; O3-NEXT: nop ++; O3-NEXT: $BB7_3: # %entry ++; O3-NEXT: sync ++; O3-NEXT: jr $ra ++; O3-NEXT: addiu $sp, $sp, 8 ++; ++; MIPS32EB-LABEL: AtomicCmpSwap32: ++; MIPS32EB: # %bb.0: # %entry ++; MIPS32EB-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32EB-NEXT: addiu $sp, $sp, -8 ++; MIPS32EB-NEXT: addu $1, $2, $25 ++; MIPS32EB-NEXT: sw $5, 4($sp) ++; MIPS32EB-NEXT: lw $1, %got(x)($1) ++; MIPS32EB-NEXT: $BB7_1: # %entry ++; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32EB-NEXT: ll $2, 0($1) ++; MIPS32EB-NEXT: bne $2, $4, $BB7_3 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: # %bb.2: # %entry ++; MIPS32EB-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; MIPS32EB-NEXT: move $3, $5 ++; MIPS32EB-NEXT: sc $3, 0($1) ++; MIPS32EB-NEXT: beqz $3, $BB7_1 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: $BB7_3: # %entry ++; MIPS32EB-NEXT: sync ++; MIPS32EB-NEXT: jr $ra ++; MIPS32EB-NEXT: addiu $sp, $sp, 8 ++entry: ++ %newval.addr = alloca i32, align 4 ++ store i32 %newval, ptr %newval.addr, align 4 ++ %tmp = load i32, ptr %newval.addr, align 4 ++ %0 = cmpxchg ptr @x, i32 %oldval, i32 %tmp monotonic monotonic ++ %1 = extractvalue { i32, i1 } %0, 0 ++ ret i32 %1 ++ ++} ++ ++@y = common global i8 0, align 1 ++ ++define signext i8 @AtomicLoadAdd8(i8 signext %incr) nounwind { ++; MIPS32-LABEL: AtomicLoadAdd8: ++; MIPS32: # %bb.0: # %entry ++; MIPS32-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32-NEXT: addu $1, $2, $25 ++; MIPS32-NEXT: lw $1, %got(y)($1) ++; MIPS32-NEXT: addiu $2, $zero, -4 ++; MIPS32-NEXT: and $3, $1, $2 ++; MIPS32-NEXT: andi $1, $1, 3 ++; MIPS32-NEXT: sll $1, $1, 3 ++; MIPS32-NEXT: ori $2, $zero, 255 ++; MIPS32-NEXT: sllv $5, $2, $1 ++; MIPS32-NEXT: nor $6, $zero, $5 ++; MIPS32-NEXT: sllv $4, $4, $1 ++; MIPS32-NEXT: $BB8_1: # %entry ++; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32-NEXT: ll $7, 0($3) ++; MIPS32-NEXT: addu $8, $7, $4 ++; MIPS32-NEXT: and $8, $8, $5 ++; MIPS32-NEXT: and $9, $7, $6 ++; MIPS32-NEXT: or $9, $9, $8 ++; MIPS32-NEXT: sc $9, 0($3) ++; MIPS32-NEXT: beqz $9, $BB8_1 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: # %bb.2: # %entry ++; MIPS32-NEXT: and $2, $7, $5 ++; MIPS32-NEXT: srlv $2, $2, $1 ++; MIPS32-NEXT: sll $2, $2, 24 ++; MIPS32-NEXT: sra $2, $2, 24 ++; MIPS32-NEXT: # %bb.3: # %entry ++; MIPS32-NEXT: jr $ra ++; MIPS32-NEXT: nop ++; ++; MIPS32O0-LABEL: AtomicLoadAdd8: ++; MIPS32O0: # %bb.0: # %entry ++; MIPS32O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32O0-NEXT: addiu $sp, $sp, -8 ++; MIPS32O0-NEXT: addu $1, $2, $25 ++; MIPS32O0-NEXT: lw $1, %got(y)($1) ++; MIPS32O0-NEXT: addiu $2, $zero, -4 ++; MIPS32O0-NEXT: and $5, $1, $2 ++; MIPS32O0-NEXT: andi $1, $1, 3 ++; MIPS32O0-NEXT: sll $9, $1, 3 ++; MIPS32O0-NEXT: ori $1, $zero, 255 ++; MIPS32O0-NEXT: sllv $7, $1, $9 ++; MIPS32O0-NEXT: nor $8, $zero, $7 ++; MIPS32O0-NEXT: sllv $6, $4, $9 ++; MIPS32O0-NEXT: $BB8_1: # %entry ++; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32O0-NEXT: ll $2, 0($5) ++; MIPS32O0-NEXT: addu $3, $2, $6 ++; MIPS32O0-NEXT: and $3, $3, $7 ++; MIPS32O0-NEXT: and $4, $2, $8 ++; MIPS32O0-NEXT: or $4, $4, $3 ++; MIPS32O0-NEXT: sc $4, 0($5) ++; MIPS32O0-NEXT: beqz $4, $BB8_1 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: # %bb.2: # %entry ++; MIPS32O0-NEXT: and $1, $2, $7 ++; MIPS32O0-NEXT: srlv $1, $1, $9 ++; MIPS32O0-NEXT: sll $1, $1, 24 ++; MIPS32O0-NEXT: sra $1, $1, 24 ++; MIPS32O0-NEXT: # %bb.3: # %entry ++; MIPS32O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ++; MIPS32O0-NEXT: # %bb.4: # %entry ++; MIPS32O0-NEXT: lw $1, 4($sp) # 4-byte Folded Reload ++; MIPS32O0-NEXT: sll $1, $1, 24 ++; MIPS32O0-NEXT: sra $2, $1, 24 ++; MIPS32O0-NEXT: addiu $sp, $sp, 8 ++; MIPS32O0-NEXT: jr $ra ++; MIPS32O0-NEXT: nop ++; ++; MIPS32R2-LABEL: AtomicLoadAdd8: ++; MIPS32R2: # %bb.0: # %entry ++; MIPS32R2-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R2-NEXT: addu $1, $2, $25 ++; MIPS32R2-NEXT: lw $1, %got(y)($1) ++; MIPS32R2-NEXT: addiu $2, $zero, -4 ++; MIPS32R2-NEXT: and $3, $1, $2 ++; MIPS32R2-NEXT: andi $1, $1, 3 ++; MIPS32R2-NEXT: sll $1, $1, 3 ++; MIPS32R2-NEXT: ori $2, $zero, 255 ++; MIPS32R2-NEXT: sllv $5, $2, $1 ++; MIPS32R2-NEXT: nor $6, $zero, $5 ++; MIPS32R2-NEXT: sllv $4, $4, $1 ++; MIPS32R2-NEXT: $BB8_1: # %entry ++; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R2-NEXT: ll $7, 0($3) ++; MIPS32R2-NEXT: addu $8, $7, $4 ++; MIPS32R2-NEXT: and $8, $8, $5 ++; MIPS32R2-NEXT: and $9, $7, $6 ++; MIPS32R2-NEXT: or $9, $9, $8 ++; MIPS32R2-NEXT: sc $9, 0($3) ++; MIPS32R2-NEXT: beqz $9, $BB8_1 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: # %bb.2: # %entry ++; MIPS32R2-NEXT: and $2, $7, $5 ++; MIPS32R2-NEXT: srlv $2, $2, $1 ++; MIPS32R2-NEXT: seb $2, $2 ++; MIPS32R2-NEXT: # %bb.3: # %entry ++; MIPS32R2-NEXT: jr $ra ++; MIPS32R2-NEXT: nop ++; ++; MIPS32R6-LABEL: AtomicLoadAdd8: ++; MIPS32R6: # %bb.0: # %entry ++; MIPS32R6-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6-NEXT: addu $1, $2, $25 ++; MIPS32R6-NEXT: lw $1, %got(y)($1) ++; MIPS32R6-NEXT: addiu $2, $zero, -4 ++; MIPS32R6-NEXT: and $3, $1, $2 ++; MIPS32R6-NEXT: andi $1, $1, 3 ++; MIPS32R6-NEXT: sll $1, $1, 3 ++; MIPS32R6-NEXT: ori $2, $zero, 255 ++; MIPS32R6-NEXT: sllv $5, $2, $1 ++; MIPS32R6-NEXT: nor $6, $zero, $5 ++; MIPS32R6-NEXT: sllv $4, $4, $1 ++; MIPS32R6-NEXT: $BB8_1: # %entry ++; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6-NEXT: ll $7, 0($3) ++; MIPS32R6-NEXT: addu $8, $7, $4 ++; MIPS32R6-NEXT: and $8, $8, $5 ++; MIPS32R6-NEXT: and $9, $7, $6 ++; MIPS32R6-NEXT: or $9, $9, $8 ++; MIPS32R6-NEXT: sc $9, 0($3) ++; MIPS32R6-NEXT: beqzc $9, $BB8_1 ++; MIPS32R6-NEXT: # %bb.2: # %entry ++; MIPS32R6-NEXT: and $2, $7, $5 ++; MIPS32R6-NEXT: srlv $2, $2, $1 ++; MIPS32R6-NEXT: seb $2, $2 ++; MIPS32R6-NEXT: # %bb.3: # %entry ++; MIPS32R6-NEXT: jrc $ra ++; ++; MIPS32R6O0-LABEL: AtomicLoadAdd8: ++; MIPS32R6O0: # %bb.0: # %entry ++; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $sp, $sp, -8 ++; MIPS32R6O0-NEXT: addu $1, $2, $25 ++; MIPS32R6O0-NEXT: # kill: def $v0 killed $a0 ++; MIPS32R6O0-NEXT: lw $1, %got(y)($1) ++; MIPS32R6O0-NEXT: addiu $2, $zero, -4 ++; MIPS32R6O0-NEXT: and $5, $1, $2 ++; MIPS32R6O0-NEXT: andi $1, $1, 3 ++; MIPS32R6O0-NEXT: sll $9, $1, 3 ++; MIPS32R6O0-NEXT: ori $1, $zero, 255 ++; MIPS32R6O0-NEXT: sllv $7, $1, $9 ++; MIPS32R6O0-NEXT: nor $8, $zero, $7 ++; MIPS32R6O0-NEXT: sllv $6, $4, $9 ++; MIPS32R6O0-NEXT: $BB8_1: # %entry ++; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6O0-NEXT: ll $2, 0($5) ++; MIPS32R6O0-NEXT: addu $3, $2, $6 ++; MIPS32R6O0-NEXT: and $3, $3, $7 ++; MIPS32R6O0-NEXT: and $4, $2, $8 ++; MIPS32R6O0-NEXT: or $4, $4, $3 ++; MIPS32R6O0-NEXT: sc $4, 0($5) ++; MIPS32R6O0-NEXT: beqzc $4, $BB8_1 ++; MIPS32R6O0-NEXT: # %bb.2: # %entry ++; MIPS32R6O0-NEXT: and $1, $2, $7 ++; MIPS32R6O0-NEXT: srlv $1, $1, $9 ++; MIPS32R6O0-NEXT: seb $1, $1 ++; MIPS32R6O0-NEXT: # %bb.3: # %entry ++; MIPS32R6O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ++; MIPS32R6O0-NEXT: # %bb.4: # %entry ++; MIPS32R6O0-NEXT: lw $2, 4($sp) # 4-byte Folded Reload ++; MIPS32R6O0-NEXT: addiu $sp, $sp, 8 ++; MIPS32R6O0-NEXT: jrc $ra ++; ++; MIPS4-LABEL: AtomicLoadAdd8: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd8))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd8))) ++; MIPS4-NEXT: ld $1, %got_disp(y)($1) ++; MIPS4-NEXT: daddiu $2, $zero, -4 ++; MIPS4-NEXT: and $3, $1, $2 ++; MIPS4-NEXT: andi $1, $1, 3 ++; MIPS4-NEXT: sll $1, $1, 3 ++; MIPS4-NEXT: ori $2, $zero, 255 ++; MIPS4-NEXT: sllv $5, $2, $1 ++; MIPS4-NEXT: nor $6, $zero, $5 ++; MIPS4-NEXT: sllv $4, $4, $1 ++; MIPS4-NEXT: .LBB8_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: ll $7, 0($3) ++; MIPS4-NEXT: addu $8, $7, $4 ++; MIPS4-NEXT: and $8, $8, $5 ++; MIPS4-NEXT: and $9, $7, $6 ++; MIPS4-NEXT: or $9, $9, $8 ++; MIPS4-NEXT: sc $9, 0($3) ++; MIPS4-NEXT: beqz $9, .LBB8_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: and $2, $7, $5 ++; MIPS4-NEXT: srlv $2, $2, $1 ++; MIPS4-NEXT: sll $2, $2, 24 ++; MIPS4-NEXT: sra $2, $2, 24 ++; MIPS4-NEXT: # %bb.3: # %entry ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: nop ++; ++; MIPS64-LABEL: AtomicLoadAdd8: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd8))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd8))) ++; MIPS64-NEXT: ld $1, %got_disp(y)($1) ++; MIPS64-NEXT: daddiu $2, $zero, -4 ++; MIPS64-NEXT: and $3, $1, $2 ++; MIPS64-NEXT: andi $1, $1, 3 ++; MIPS64-NEXT: sll $1, $1, 3 ++; MIPS64-NEXT: ori $2, $zero, 255 ++; MIPS64-NEXT: sllv $5, $2, $1 ++; MIPS64-NEXT: nor $6, $zero, $5 ++; MIPS64-NEXT: sllv $4, $4, $1 ++; MIPS64-NEXT: .LBB8_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: ll $7, 0($3) ++; MIPS64-NEXT: addu $8, $7, $4 ++; MIPS64-NEXT: and $8, $8, $5 ++; MIPS64-NEXT: and $9, $7, $6 ++; MIPS64-NEXT: or $9, $9, $8 ++; MIPS64-NEXT: sc $9, 0($3) ++; MIPS64-NEXT: beqz $9, .LBB8_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: and $2, $7, $5 ++; MIPS64-NEXT: srlv $2, $2, $1 ++; MIPS64-NEXT: sll $2, $2, 24 ++; MIPS64-NEXT: sra $2, $2, 24 ++; MIPS64-NEXT: # %bb.3: # %entry ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: nop ++; ++; MIPS64R2-LABEL: AtomicLoadAdd8: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd8))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd8))) ++; MIPS64R2-NEXT: ld $1, %got_disp(y)($1) ++; MIPS64R2-NEXT: daddiu $2, $zero, -4 ++; MIPS64R2-NEXT: and $3, $1, $2 ++; MIPS64R2-NEXT: andi $1, $1, 3 ++; MIPS64R2-NEXT: sll $1, $1, 3 ++; MIPS64R2-NEXT: ori $2, $zero, 255 ++; MIPS64R2-NEXT: sllv $5, $2, $1 ++; MIPS64R2-NEXT: nor $6, $zero, $5 ++; MIPS64R2-NEXT: sllv $4, $4, $1 ++; MIPS64R2-NEXT: .LBB8_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: ll $7, 0($3) ++; MIPS64R2-NEXT: addu $8, $7, $4 ++; MIPS64R2-NEXT: and $8, $8, $5 ++; MIPS64R2-NEXT: and $9, $7, $6 ++; MIPS64R2-NEXT: or $9, $9, $8 ++; MIPS64R2-NEXT: sc $9, 0($3) ++; MIPS64R2-NEXT: beqz $9, .LBB8_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: and $2, $7, $5 ++; MIPS64R2-NEXT: srlv $2, $2, $1 ++; MIPS64R2-NEXT: seb $2, $2 ++; MIPS64R2-NEXT: # %bb.3: # %entry ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: nop ++; ++; MIPS64R6-LABEL: AtomicLoadAdd8: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd8))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd8))) ++; MIPS64R6-NEXT: ld $1, %got_disp(y)($1) ++; MIPS64R6-NEXT: daddiu $2, $zero, -4 ++; MIPS64R6-NEXT: and $3, $1, $2 ++; MIPS64R6-NEXT: andi $1, $1, 3 ++; MIPS64R6-NEXT: sll $1, $1, 3 ++; MIPS64R6-NEXT: ori $2, $zero, 255 ++; MIPS64R6-NEXT: sllv $5, $2, $1 ++; MIPS64R6-NEXT: nor $6, $zero, $5 ++; MIPS64R6-NEXT: sllv $4, $4, $1 ++; MIPS64R6-NEXT: .LBB8_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: ll $7, 0($3) ++; MIPS64R6-NEXT: addu $8, $7, $4 ++; MIPS64R6-NEXT: and $8, $8, $5 ++; MIPS64R6-NEXT: and $9, $7, $6 ++; MIPS64R6-NEXT: or $9, $9, $8 ++; MIPS64R6-NEXT: sc $9, 0($3) ++; MIPS64R6-NEXT: beqzc $9, .LBB8_1 ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: and $2, $7, $5 ++; MIPS64R6-NEXT: srlv $2, $2, $1 ++; MIPS64R6-NEXT: seb $2, $2 ++; MIPS64R6-NEXT: # %bb.3: # %entry ++; MIPS64R6-NEXT: jrc $ra ++; ++; MIPS64R6O0-LABEL: AtomicLoadAdd8: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, -16 ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd8))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $2, $1, %lo(%neg(%gp_rel(AtomicLoadAdd8))) ++; MIPS64R6O0-NEXT: move $1, $4 ++; MIPS64R6O0-NEXT: ld $2, %got_disp(y)($2) ++; MIPS64R6O0-NEXT: daddiu $3, $zero, -4 ++; MIPS64R6O0-NEXT: and $5, $2, $3 ++; MIPS64R6O0-NEXT: andi $2, $2, 3 ++; MIPS64R6O0-NEXT: xori $2, $2, 3 ++; MIPS64R6O0-NEXT: sll $9, $2, 3 ++; MIPS64R6O0-NEXT: ori $2, $zero, 255 ++; MIPS64R6O0-NEXT: sllv $7, $2, $9 ++; MIPS64R6O0-NEXT: nor $8, $zero, $7 ++; MIPS64R6O0-NEXT: sllv $6, $1, $9 ++; MIPS64R6O0-NEXT: .LBB8_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: ll $2, 0($5) ++; MIPS64R6O0-NEXT: addu $3, $2, $6 ++; MIPS64R6O0-NEXT: and $3, $3, $7 ++; MIPS64R6O0-NEXT: and $4, $2, $8 ++; MIPS64R6O0-NEXT: or $4, $4, $3 ++; MIPS64R6O0-NEXT: sc $4, 0($5) ++; MIPS64R6O0-NEXT: beqzc $4, .LBB8_1 ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: and $1, $2, $7 ++; MIPS64R6O0-NEXT: srlv $1, $1, $9 ++; MIPS64R6O0-NEXT: seb $1, $1 ++; MIPS64R6O0-NEXT: # %bb.3: # %entry ++; MIPS64R6O0-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ++; MIPS64R6O0-NEXT: # %bb.4: # %entry ++; MIPS64R6O0-NEXT: lw $2, 12($sp) # 4-byte Folded Reload ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, 16 ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; MM32-LABEL: AtomicLoadAdd8: ++; MM32: # %bb.0: # %entry ++; MM32-NEXT: lui $2, %hi(_gp_disp) ++; MM32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MM32-NEXT: addu $2, $2, $25 ++; MM32-NEXT: lw $1, %got(y)($2) ++; MM32-NEXT: addiu $2, $zero, -4 ++; MM32-NEXT: and $3, $1, $2 ++; MM32-NEXT: andi $1, $1, 3 ++; MM32-NEXT: sll $1, $1, 3 ++; MM32-NEXT: ori $2, $zero, 255 ++; MM32-NEXT: sllv $5, $2, $1 ++; MM32-NEXT: nor $6, $zero, $5 ++; MM32-NEXT: sllv $4, $4, $1 ++; MM32-NEXT: $BB8_1: # %entry ++; MM32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MM32-NEXT: ll $7, 0($3) ++; MM32-NEXT: addu $8, $7, $4 ++; MM32-NEXT: and $8, $8, $5 ++; MM32-NEXT: and $9, $7, $6 ++; MM32-NEXT: or $9, $9, $8 ++; MM32-NEXT: sc $9, 0($3) ++; MM32-NEXT: beqzc $9, $BB8_1 ++; MM32-NEXT: # %bb.2: # %entry ++; MM32-NEXT: and $2, $7, $5 ++; MM32-NEXT: srlv $2, $2, $1 ++; MM32-NEXT: seb $2, $2 ++; MM32-NEXT: # %bb.3: # %entry ++; MM32-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicLoadAdd8: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $2, %hi(_gp_disp) ++; O1-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O1-NEXT: addu $1, $2, $25 ++; O1-NEXT: lw $1, %got(y)($1) ++; O1-NEXT: addiu $2, $zero, -4 ++; O1-NEXT: and $3, $1, $2 ++; O1-NEXT: andi $1, $1, 3 ++; O1-NEXT: sll $1, $1, 3 ++; O1-NEXT: ori $2, $zero, 255 ++; O1-NEXT: sllv $5, $2, $1 ++; O1-NEXT: nor $6, $zero, $5 ++; O1-NEXT: sllv $4, $4, $1 ++; O1-NEXT: $BB8_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: ll $7, 0($3) ++; O1-NEXT: addu $8, $7, $4 ++; O1-NEXT: and $8, $8, $5 ++; O1-NEXT: and $9, $7, $6 ++; O1-NEXT: or $9, $9, $8 ++; O1-NEXT: sc $9, 0($3) ++; O1-NEXT: beqz $9, $BB8_1 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: and $2, $7, $5 ++; O1-NEXT: srlv $2, $2, $1 ++; O1-NEXT: sll $2, $2, 24 ++; O1-NEXT: sra $2, $2, 24 ++; O1-NEXT: # %bb.3: # %entry ++; O1-NEXT: jr $ra ++; O1-NEXT: nop ++; ++; O2-LABEL: AtomicLoadAdd8: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $2, %hi(_gp_disp) ++; O2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O2-NEXT: addu $1, $2, $25 ++; O2-NEXT: lw $1, %got(y)($1) ++; O2-NEXT: addiu $2, $zero, -4 ++; O2-NEXT: and $3, $1, $2 ++; O2-NEXT: andi $1, $1, 3 ++; O2-NEXT: sll $1, $1, 3 ++; O2-NEXT: ori $2, $zero, 255 ++; O2-NEXT: sllv $5, $2, $1 ++; O2-NEXT: nor $6, $zero, $5 ++; O2-NEXT: sllv $4, $4, $1 ++; O2-NEXT: $BB8_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: ll $7, 0($3) ++; O2-NEXT: addu $8, $7, $4 ++; O2-NEXT: and $8, $8, $5 ++; O2-NEXT: and $9, $7, $6 ++; O2-NEXT: or $9, $9, $8 ++; O2-NEXT: sc $9, 0($3) ++; O2-NEXT: beqz $9, $BB8_1 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: and $2, $7, $5 ++; O2-NEXT: srlv $2, $2, $1 ++; O2-NEXT: sll $2, $2, 24 ++; O2-NEXT: sra $2, $2, 24 ++; O2-NEXT: # %bb.3: # %entry ++; O2-NEXT: jr $ra ++; O2-NEXT: nop ++; ++; O3-LABEL: AtomicLoadAdd8: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $2, %hi(_gp_disp) ++; O3-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O3-NEXT: addu $1, $2, $25 ++; O3-NEXT: addiu $2, $zero, -4 ++; O3-NEXT: lw $1, %got(y)($1) ++; O3-NEXT: and $3, $1, $2 ++; O3-NEXT: andi $1, $1, 3 ++; O3-NEXT: ori $2, $zero, 255 ++; O3-NEXT: sll $1, $1, 3 ++; O3-NEXT: sllv $5, $2, $1 ++; O3-NEXT: sllv $4, $4, $1 ++; O3-NEXT: nor $6, $zero, $5 ++; O3-NEXT: $BB8_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: ll $7, 0($3) ++; O3-NEXT: addu $8, $7, $4 ++; O3-NEXT: and $8, $8, $5 ++; O3-NEXT: and $9, $7, $6 ++; O3-NEXT: or $9, $9, $8 ++; O3-NEXT: sc $9, 0($3) ++; O3-NEXT: beqz $9, $BB8_1 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: and $2, $7, $5 ++; O3-NEXT: srlv $2, $2, $1 ++; O3-NEXT: sll $2, $2, 24 ++; O3-NEXT: sra $2, $2, 24 ++; O3-NEXT: # %bb.3: # %entry ++; O3-NEXT: jr $ra ++; O3-NEXT: nop ++; ++; MIPS32EB-LABEL: AtomicLoadAdd8: ++; MIPS32EB: # %bb.0: # %entry ++; MIPS32EB-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32EB-NEXT: addu $1, $2, $25 ++; MIPS32EB-NEXT: lw $1, %got(y)($1) ++; MIPS32EB-NEXT: addiu $2, $zero, -4 ++; MIPS32EB-NEXT: and $3, $1, $2 ++; MIPS32EB-NEXT: andi $1, $1, 3 ++; MIPS32EB-NEXT: xori $1, $1, 3 ++; MIPS32EB-NEXT: sll $1, $1, 3 ++; MIPS32EB-NEXT: ori $2, $zero, 255 ++; MIPS32EB-NEXT: sllv $5, $2, $1 ++; MIPS32EB-NEXT: nor $6, $zero, $5 ++; MIPS32EB-NEXT: sllv $4, $4, $1 ++; MIPS32EB-NEXT: $BB8_1: # %entry ++; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32EB-NEXT: ll $7, 0($3) ++; MIPS32EB-NEXT: addu $8, $7, $4 ++; MIPS32EB-NEXT: and $8, $8, $5 ++; MIPS32EB-NEXT: and $9, $7, $6 ++; MIPS32EB-NEXT: or $9, $9, $8 ++; MIPS32EB-NEXT: sc $9, 0($3) ++; MIPS32EB-NEXT: beqz $9, $BB8_1 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: # %bb.2: # %entry ++; MIPS32EB-NEXT: and $2, $7, $5 ++; MIPS32EB-NEXT: srlv $2, $2, $1 ++; MIPS32EB-NEXT: sll $2, $2, 24 ++; MIPS32EB-NEXT: sra $2, $2, 24 ++; MIPS32EB-NEXT: # %bb.3: # %entry ++; MIPS32EB-NEXT: jr $ra ++; MIPS32EB-NEXT: nop ++entry: ++ %0 = atomicrmw add ptr @y, i8 %incr monotonic ++ ret i8 %0 ++} ++ ++define signext i8 @AtomicLoadSub8(i8 signext %incr) nounwind { ++; MIPS32-LABEL: AtomicLoadSub8: ++; MIPS32: # %bb.0: # %entry ++; MIPS32-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32-NEXT: addu $1, $2, $25 ++; MIPS32-NEXT: lw $1, %got(y)($1) ++; MIPS32-NEXT: addiu $2, $zero, -4 ++; MIPS32-NEXT: and $3, $1, $2 ++; MIPS32-NEXT: andi $1, $1, 3 ++; MIPS32-NEXT: sll $1, $1, 3 ++; MIPS32-NEXT: ori $2, $zero, 255 ++; MIPS32-NEXT: sllv $5, $2, $1 ++; MIPS32-NEXT: nor $6, $zero, $5 ++; MIPS32-NEXT: sllv $4, $4, $1 ++; MIPS32-NEXT: $BB9_1: # %entry ++; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32-NEXT: ll $7, 0($3) ++; MIPS32-NEXT: subu $8, $7, $4 ++; MIPS32-NEXT: and $8, $8, $5 ++; MIPS32-NEXT: and $9, $7, $6 ++; MIPS32-NEXT: or $9, $9, $8 ++; MIPS32-NEXT: sc $9, 0($3) ++; MIPS32-NEXT: beqz $9, $BB9_1 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: # %bb.2: # %entry ++; MIPS32-NEXT: and $2, $7, $5 ++; MIPS32-NEXT: srlv $2, $2, $1 ++; MIPS32-NEXT: sll $2, $2, 24 ++; MIPS32-NEXT: sra $2, $2, 24 ++; MIPS32-NEXT: # %bb.3: # %entry ++; MIPS32-NEXT: jr $ra ++; MIPS32-NEXT: nop ++; ++; MIPS32O0-LABEL: AtomicLoadSub8: ++; MIPS32O0: # %bb.0: # %entry ++; MIPS32O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32O0-NEXT: addiu $sp, $sp, -8 ++; MIPS32O0-NEXT: addu $1, $2, $25 ++; MIPS32O0-NEXT: lw $1, %got(y)($1) ++; MIPS32O0-NEXT: addiu $2, $zero, -4 ++; MIPS32O0-NEXT: and $5, $1, $2 ++; MIPS32O0-NEXT: andi $1, $1, 3 ++; MIPS32O0-NEXT: sll $9, $1, 3 ++; MIPS32O0-NEXT: ori $1, $zero, 255 ++; MIPS32O0-NEXT: sllv $7, $1, $9 ++; MIPS32O0-NEXT: nor $8, $zero, $7 ++; MIPS32O0-NEXT: sllv $6, $4, $9 ++; MIPS32O0-NEXT: $BB9_1: # %entry ++; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32O0-NEXT: ll $2, 0($5) ++; MIPS32O0-NEXT: subu $3, $2, $6 ++; MIPS32O0-NEXT: and $3, $3, $7 ++; MIPS32O0-NEXT: and $4, $2, $8 ++; MIPS32O0-NEXT: or $4, $4, $3 ++; MIPS32O0-NEXT: sc $4, 0($5) ++; MIPS32O0-NEXT: beqz $4, $BB9_1 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: # %bb.2: # %entry ++; MIPS32O0-NEXT: and $1, $2, $7 ++; MIPS32O0-NEXT: srlv $1, $1, $9 ++; MIPS32O0-NEXT: sll $1, $1, 24 ++; MIPS32O0-NEXT: sra $1, $1, 24 ++; MIPS32O0-NEXT: # %bb.3: # %entry ++; MIPS32O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ++; MIPS32O0-NEXT: # %bb.4: # %entry ++; MIPS32O0-NEXT: lw $1, 4($sp) # 4-byte Folded Reload ++; MIPS32O0-NEXT: sll $1, $1, 24 ++; MIPS32O0-NEXT: sra $2, $1, 24 ++; MIPS32O0-NEXT: addiu $sp, $sp, 8 ++; MIPS32O0-NEXT: jr $ra ++; MIPS32O0-NEXT: nop ++; ++; MIPS32R2-LABEL: AtomicLoadSub8: ++; MIPS32R2: # %bb.0: # %entry ++; MIPS32R2-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R2-NEXT: addu $1, $2, $25 ++; MIPS32R2-NEXT: lw $1, %got(y)($1) ++; MIPS32R2-NEXT: addiu $2, $zero, -4 ++; MIPS32R2-NEXT: and $3, $1, $2 ++; MIPS32R2-NEXT: andi $1, $1, 3 ++; MIPS32R2-NEXT: sll $1, $1, 3 ++; MIPS32R2-NEXT: ori $2, $zero, 255 ++; MIPS32R2-NEXT: sllv $5, $2, $1 ++; MIPS32R2-NEXT: nor $6, $zero, $5 ++; MIPS32R2-NEXT: sllv $4, $4, $1 ++; MIPS32R2-NEXT: $BB9_1: # %entry ++; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R2-NEXT: ll $7, 0($3) ++; MIPS32R2-NEXT: subu $8, $7, $4 ++; MIPS32R2-NEXT: and $8, $8, $5 ++; MIPS32R2-NEXT: and $9, $7, $6 ++; MIPS32R2-NEXT: or $9, $9, $8 ++; MIPS32R2-NEXT: sc $9, 0($3) ++; MIPS32R2-NEXT: beqz $9, $BB9_1 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: # %bb.2: # %entry ++; MIPS32R2-NEXT: and $2, $7, $5 ++; MIPS32R2-NEXT: srlv $2, $2, $1 ++; MIPS32R2-NEXT: seb $2, $2 ++; MIPS32R2-NEXT: # %bb.3: # %entry ++; MIPS32R2-NEXT: jr $ra ++; MIPS32R2-NEXT: nop ++; ++; MIPS32R6-LABEL: AtomicLoadSub8: ++; MIPS32R6: # %bb.0: # %entry ++; MIPS32R6-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6-NEXT: addu $1, $2, $25 ++; MIPS32R6-NEXT: lw $1, %got(y)($1) ++; MIPS32R6-NEXT: addiu $2, $zero, -4 ++; MIPS32R6-NEXT: and $3, $1, $2 ++; MIPS32R6-NEXT: andi $1, $1, 3 ++; MIPS32R6-NEXT: sll $1, $1, 3 ++; MIPS32R6-NEXT: ori $2, $zero, 255 ++; MIPS32R6-NEXT: sllv $5, $2, $1 ++; MIPS32R6-NEXT: nor $6, $zero, $5 ++; MIPS32R6-NEXT: sllv $4, $4, $1 ++; MIPS32R6-NEXT: $BB9_1: # %entry ++; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6-NEXT: ll $7, 0($3) ++; MIPS32R6-NEXT: subu $8, $7, $4 ++; MIPS32R6-NEXT: and $8, $8, $5 ++; MIPS32R6-NEXT: and $9, $7, $6 ++; MIPS32R6-NEXT: or $9, $9, $8 ++; MIPS32R6-NEXT: sc $9, 0($3) ++; MIPS32R6-NEXT: beqzc $9, $BB9_1 ++; MIPS32R6-NEXT: # %bb.2: # %entry ++; MIPS32R6-NEXT: and $2, $7, $5 ++; MIPS32R6-NEXT: srlv $2, $2, $1 ++; MIPS32R6-NEXT: seb $2, $2 ++; MIPS32R6-NEXT: # %bb.3: # %entry ++; MIPS32R6-NEXT: jrc $ra ++; ++; MIPS32R6O0-LABEL: AtomicLoadSub8: ++; MIPS32R6O0: # %bb.0: # %entry ++; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $sp, $sp, -8 ++; MIPS32R6O0-NEXT: addu $1, $2, $25 ++; MIPS32R6O0-NEXT: # kill: def $v0 killed $a0 ++; MIPS32R6O0-NEXT: lw $1, %got(y)($1) ++; MIPS32R6O0-NEXT: addiu $2, $zero, -4 ++; MIPS32R6O0-NEXT: and $5, $1, $2 ++; MIPS32R6O0-NEXT: andi $1, $1, 3 ++; MIPS32R6O0-NEXT: sll $9, $1, 3 ++; MIPS32R6O0-NEXT: ori $1, $zero, 255 ++; MIPS32R6O0-NEXT: sllv $7, $1, $9 ++; MIPS32R6O0-NEXT: nor $8, $zero, $7 ++; MIPS32R6O0-NEXT: sllv $6, $4, $9 ++; MIPS32R6O0-NEXT: $BB9_1: # %entry ++; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6O0-NEXT: ll $2, 0($5) ++; MIPS32R6O0-NEXT: subu $3, $2, $6 ++; MIPS32R6O0-NEXT: and $3, $3, $7 ++; MIPS32R6O0-NEXT: and $4, $2, $8 ++; MIPS32R6O0-NEXT: or $4, $4, $3 ++; MIPS32R6O0-NEXT: sc $4, 0($5) ++; MIPS32R6O0-NEXT: beqzc $4, $BB9_1 ++; MIPS32R6O0-NEXT: # %bb.2: # %entry ++; MIPS32R6O0-NEXT: and $1, $2, $7 ++; MIPS32R6O0-NEXT: srlv $1, $1, $9 ++; MIPS32R6O0-NEXT: seb $1, $1 ++; MIPS32R6O0-NEXT: # %bb.3: # %entry ++; MIPS32R6O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ++; MIPS32R6O0-NEXT: # %bb.4: # %entry ++; MIPS32R6O0-NEXT: lw $2, 4($sp) # 4-byte Folded Reload ++; MIPS32R6O0-NEXT: addiu $sp, $sp, 8 ++; MIPS32R6O0-NEXT: jrc $ra ++; ++; MIPS4-LABEL: AtomicLoadSub8: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadSub8))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadSub8))) ++; MIPS4-NEXT: ld $1, %got_disp(y)($1) ++; MIPS4-NEXT: daddiu $2, $zero, -4 ++; MIPS4-NEXT: and $3, $1, $2 ++; MIPS4-NEXT: andi $1, $1, 3 ++; MIPS4-NEXT: sll $1, $1, 3 ++; MIPS4-NEXT: ori $2, $zero, 255 ++; MIPS4-NEXT: sllv $5, $2, $1 ++; MIPS4-NEXT: nor $6, $zero, $5 ++; MIPS4-NEXT: sllv $4, $4, $1 ++; MIPS4-NEXT: .LBB9_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: ll $7, 0($3) ++; MIPS4-NEXT: subu $8, $7, $4 ++; MIPS4-NEXT: and $8, $8, $5 ++; MIPS4-NEXT: and $9, $7, $6 ++; MIPS4-NEXT: or $9, $9, $8 ++; MIPS4-NEXT: sc $9, 0($3) ++; MIPS4-NEXT: beqz $9, .LBB9_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: and $2, $7, $5 ++; MIPS4-NEXT: srlv $2, $2, $1 ++; MIPS4-NEXT: sll $2, $2, 24 ++; MIPS4-NEXT: sra $2, $2, 24 ++; MIPS4-NEXT: # %bb.3: # %entry ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: nop ++; ++; MIPS64-LABEL: AtomicLoadSub8: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadSub8))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadSub8))) ++; MIPS64-NEXT: ld $1, %got_disp(y)($1) ++; MIPS64-NEXT: daddiu $2, $zero, -4 ++; MIPS64-NEXT: and $3, $1, $2 ++; MIPS64-NEXT: andi $1, $1, 3 ++; MIPS64-NEXT: sll $1, $1, 3 ++; MIPS64-NEXT: ori $2, $zero, 255 ++; MIPS64-NEXT: sllv $5, $2, $1 ++; MIPS64-NEXT: nor $6, $zero, $5 ++; MIPS64-NEXT: sllv $4, $4, $1 ++; MIPS64-NEXT: .LBB9_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: ll $7, 0($3) ++; MIPS64-NEXT: subu $8, $7, $4 ++; MIPS64-NEXT: and $8, $8, $5 ++; MIPS64-NEXT: and $9, $7, $6 ++; MIPS64-NEXT: or $9, $9, $8 ++; MIPS64-NEXT: sc $9, 0($3) ++; MIPS64-NEXT: beqz $9, .LBB9_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: and $2, $7, $5 ++; MIPS64-NEXT: srlv $2, $2, $1 ++; MIPS64-NEXT: sll $2, $2, 24 ++; MIPS64-NEXT: sra $2, $2, 24 ++; MIPS64-NEXT: # %bb.3: # %entry ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: nop ++; ++; MIPS64R2-LABEL: AtomicLoadSub8: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadSub8))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadSub8))) ++; MIPS64R2-NEXT: ld $1, %got_disp(y)($1) ++; MIPS64R2-NEXT: daddiu $2, $zero, -4 ++; MIPS64R2-NEXT: and $3, $1, $2 ++; MIPS64R2-NEXT: andi $1, $1, 3 ++; MIPS64R2-NEXT: sll $1, $1, 3 ++; MIPS64R2-NEXT: ori $2, $zero, 255 ++; MIPS64R2-NEXT: sllv $5, $2, $1 ++; MIPS64R2-NEXT: nor $6, $zero, $5 ++; MIPS64R2-NEXT: sllv $4, $4, $1 ++; MIPS64R2-NEXT: .LBB9_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: ll $7, 0($3) ++; MIPS64R2-NEXT: subu $8, $7, $4 ++; MIPS64R2-NEXT: and $8, $8, $5 ++; MIPS64R2-NEXT: and $9, $7, $6 ++; MIPS64R2-NEXT: or $9, $9, $8 ++; MIPS64R2-NEXT: sc $9, 0($3) ++; MIPS64R2-NEXT: beqz $9, .LBB9_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: and $2, $7, $5 ++; MIPS64R2-NEXT: srlv $2, $2, $1 ++; MIPS64R2-NEXT: seb $2, $2 ++; MIPS64R2-NEXT: # %bb.3: # %entry ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: nop ++; ++; MIPS64R6-LABEL: AtomicLoadSub8: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadSub8))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadSub8))) ++; MIPS64R6-NEXT: ld $1, %got_disp(y)($1) ++; MIPS64R6-NEXT: daddiu $2, $zero, -4 ++; MIPS64R6-NEXT: and $3, $1, $2 ++; MIPS64R6-NEXT: andi $1, $1, 3 ++; MIPS64R6-NEXT: sll $1, $1, 3 ++; MIPS64R6-NEXT: ori $2, $zero, 255 ++; MIPS64R6-NEXT: sllv $5, $2, $1 ++; MIPS64R6-NEXT: nor $6, $zero, $5 ++; MIPS64R6-NEXT: sllv $4, $4, $1 ++; MIPS64R6-NEXT: .LBB9_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: ll $7, 0($3) ++; MIPS64R6-NEXT: subu $8, $7, $4 ++; MIPS64R6-NEXT: and $8, $8, $5 ++; MIPS64R6-NEXT: and $9, $7, $6 ++; MIPS64R6-NEXT: or $9, $9, $8 ++; MIPS64R6-NEXT: sc $9, 0($3) ++; MIPS64R6-NEXT: beqzc $9, .LBB9_1 ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: and $2, $7, $5 ++; MIPS64R6-NEXT: srlv $2, $2, $1 ++; MIPS64R6-NEXT: seb $2, $2 ++; MIPS64R6-NEXT: # %bb.3: # %entry ++; MIPS64R6-NEXT: jrc $ra ++; ++; MIPS64R6O0-LABEL: AtomicLoadSub8: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, -16 ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadSub8))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $2, $1, %lo(%neg(%gp_rel(AtomicLoadSub8))) ++; MIPS64R6O0-NEXT: move $1, $4 ++; MIPS64R6O0-NEXT: ld $2, %got_disp(y)($2) ++; MIPS64R6O0-NEXT: daddiu $3, $zero, -4 ++; MIPS64R6O0-NEXT: and $5, $2, $3 ++; MIPS64R6O0-NEXT: andi $2, $2, 3 ++; MIPS64R6O0-NEXT: xori $2, $2, 3 ++; MIPS64R6O0-NEXT: sll $9, $2, 3 ++; MIPS64R6O0-NEXT: ori $2, $zero, 255 ++; MIPS64R6O0-NEXT: sllv $7, $2, $9 ++; MIPS64R6O0-NEXT: nor $8, $zero, $7 ++; MIPS64R6O0-NEXT: sllv $6, $1, $9 ++; MIPS64R6O0-NEXT: .LBB9_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: ll $2, 0($5) ++; MIPS64R6O0-NEXT: subu $3, $2, $6 ++; MIPS64R6O0-NEXT: and $3, $3, $7 ++; MIPS64R6O0-NEXT: and $4, $2, $8 ++; MIPS64R6O0-NEXT: or $4, $4, $3 ++; MIPS64R6O0-NEXT: sc $4, 0($5) ++; MIPS64R6O0-NEXT: beqzc $4, .LBB9_1 ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: and $1, $2, $7 ++; MIPS64R6O0-NEXT: srlv $1, $1, $9 ++; MIPS64R6O0-NEXT: seb $1, $1 ++; MIPS64R6O0-NEXT: # %bb.3: # %entry ++; MIPS64R6O0-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ++; MIPS64R6O0-NEXT: # %bb.4: # %entry ++; MIPS64R6O0-NEXT: lw $2, 12($sp) # 4-byte Folded Reload ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, 16 ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; MM32-LABEL: AtomicLoadSub8: ++; MM32: # %bb.0: # %entry ++; MM32-NEXT: lui $2, %hi(_gp_disp) ++; MM32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MM32-NEXT: addu $2, $2, $25 ++; MM32-NEXT: lw $1, %got(y)($2) ++; MM32-NEXT: addiu $2, $zero, -4 ++; MM32-NEXT: and $3, $1, $2 ++; MM32-NEXT: andi $1, $1, 3 ++; MM32-NEXT: sll $1, $1, 3 ++; MM32-NEXT: ori $2, $zero, 255 ++; MM32-NEXT: sllv $5, $2, $1 ++; MM32-NEXT: nor $6, $zero, $5 ++; MM32-NEXT: sllv $4, $4, $1 ++; MM32-NEXT: $BB9_1: # %entry ++; MM32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MM32-NEXT: ll $7, 0($3) ++; MM32-NEXT: subu $8, $7, $4 ++; MM32-NEXT: and $8, $8, $5 ++; MM32-NEXT: and $9, $7, $6 ++; MM32-NEXT: or $9, $9, $8 ++; MM32-NEXT: sc $9, 0($3) ++; MM32-NEXT: beqzc $9, $BB9_1 ++; MM32-NEXT: # %bb.2: # %entry ++; MM32-NEXT: and $2, $7, $5 ++; MM32-NEXT: srlv $2, $2, $1 ++; MM32-NEXT: seb $2, $2 ++; MM32-NEXT: # %bb.3: # %entry ++; MM32-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicLoadSub8: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $2, %hi(_gp_disp) ++; O1-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O1-NEXT: addu $1, $2, $25 ++; O1-NEXT: lw $1, %got(y)($1) ++; O1-NEXT: addiu $2, $zero, -4 ++; O1-NEXT: and $3, $1, $2 ++; O1-NEXT: andi $1, $1, 3 ++; O1-NEXT: sll $1, $1, 3 ++; O1-NEXT: ori $2, $zero, 255 ++; O1-NEXT: sllv $5, $2, $1 ++; O1-NEXT: nor $6, $zero, $5 ++; O1-NEXT: sllv $4, $4, $1 ++; O1-NEXT: $BB9_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: ll $7, 0($3) ++; O1-NEXT: subu $8, $7, $4 ++; O1-NEXT: and $8, $8, $5 ++; O1-NEXT: and $9, $7, $6 ++; O1-NEXT: or $9, $9, $8 ++; O1-NEXT: sc $9, 0($3) ++; O1-NEXT: beqz $9, $BB9_1 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: and $2, $7, $5 ++; O1-NEXT: srlv $2, $2, $1 ++; O1-NEXT: sll $2, $2, 24 ++; O1-NEXT: sra $2, $2, 24 ++; O1-NEXT: # %bb.3: # %entry ++; O1-NEXT: jr $ra ++; O1-NEXT: nop ++; ++; O2-LABEL: AtomicLoadSub8: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $2, %hi(_gp_disp) ++; O2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O2-NEXT: addu $1, $2, $25 ++; O2-NEXT: lw $1, %got(y)($1) ++; O2-NEXT: addiu $2, $zero, -4 ++; O2-NEXT: and $3, $1, $2 ++; O2-NEXT: andi $1, $1, 3 ++; O2-NEXT: sll $1, $1, 3 ++; O2-NEXT: ori $2, $zero, 255 ++; O2-NEXT: sllv $5, $2, $1 ++; O2-NEXT: nor $6, $zero, $5 ++; O2-NEXT: sllv $4, $4, $1 ++; O2-NEXT: $BB9_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: ll $7, 0($3) ++; O2-NEXT: subu $8, $7, $4 ++; O2-NEXT: and $8, $8, $5 ++; O2-NEXT: and $9, $7, $6 ++; O2-NEXT: or $9, $9, $8 ++; O2-NEXT: sc $9, 0($3) ++; O2-NEXT: beqz $9, $BB9_1 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: and $2, $7, $5 ++; O2-NEXT: srlv $2, $2, $1 ++; O2-NEXT: sll $2, $2, 24 ++; O2-NEXT: sra $2, $2, 24 ++; O2-NEXT: # %bb.3: # %entry ++; O2-NEXT: jr $ra ++; O2-NEXT: nop ++; ++; O3-LABEL: AtomicLoadSub8: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $2, %hi(_gp_disp) ++; O3-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O3-NEXT: addu $1, $2, $25 ++; O3-NEXT: addiu $2, $zero, -4 ++; O3-NEXT: lw $1, %got(y)($1) ++; O3-NEXT: and $3, $1, $2 ++; O3-NEXT: andi $1, $1, 3 ++; O3-NEXT: ori $2, $zero, 255 ++; O3-NEXT: sll $1, $1, 3 ++; O3-NEXT: sllv $5, $2, $1 ++; O3-NEXT: sllv $4, $4, $1 ++; O3-NEXT: nor $6, $zero, $5 ++; O3-NEXT: $BB9_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: ll $7, 0($3) ++; O3-NEXT: subu $8, $7, $4 ++; O3-NEXT: and $8, $8, $5 ++; O3-NEXT: and $9, $7, $6 ++; O3-NEXT: or $9, $9, $8 ++; O3-NEXT: sc $9, 0($3) ++; O3-NEXT: beqz $9, $BB9_1 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: and $2, $7, $5 ++; O3-NEXT: srlv $2, $2, $1 ++; O3-NEXT: sll $2, $2, 24 ++; O3-NEXT: sra $2, $2, 24 ++; O3-NEXT: # %bb.3: # %entry ++; O3-NEXT: jr $ra ++; O3-NEXT: nop ++; ++; MIPS32EB-LABEL: AtomicLoadSub8: ++; MIPS32EB: # %bb.0: # %entry ++; MIPS32EB-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32EB-NEXT: addu $1, $2, $25 ++; MIPS32EB-NEXT: lw $1, %got(y)($1) ++; MIPS32EB-NEXT: addiu $2, $zero, -4 ++; MIPS32EB-NEXT: and $3, $1, $2 ++; MIPS32EB-NEXT: andi $1, $1, 3 ++; MIPS32EB-NEXT: xori $1, $1, 3 ++; MIPS32EB-NEXT: sll $1, $1, 3 ++; MIPS32EB-NEXT: ori $2, $zero, 255 ++; MIPS32EB-NEXT: sllv $5, $2, $1 ++; MIPS32EB-NEXT: nor $6, $zero, $5 ++; MIPS32EB-NEXT: sllv $4, $4, $1 ++; MIPS32EB-NEXT: $BB9_1: # %entry ++; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32EB-NEXT: ll $7, 0($3) ++; MIPS32EB-NEXT: subu $8, $7, $4 ++; MIPS32EB-NEXT: and $8, $8, $5 ++; MIPS32EB-NEXT: and $9, $7, $6 ++; MIPS32EB-NEXT: or $9, $9, $8 ++; MIPS32EB-NEXT: sc $9, 0($3) ++; MIPS32EB-NEXT: beqz $9, $BB9_1 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: # %bb.2: # %entry ++; MIPS32EB-NEXT: and $2, $7, $5 ++; MIPS32EB-NEXT: srlv $2, $2, $1 ++; MIPS32EB-NEXT: sll $2, $2, 24 ++; MIPS32EB-NEXT: sra $2, $2, 24 ++; MIPS32EB-NEXT: # %bb.3: # %entry ++; MIPS32EB-NEXT: jr $ra ++; MIPS32EB-NEXT: nop ++entry: ++ %0 = atomicrmw sub ptr @y, i8 %incr monotonic ++ ret i8 %0 ++ ++} ++ ++define signext i8 @AtomicLoadNand8(i8 signext %incr) nounwind { ++; MIPS32-LABEL: AtomicLoadNand8: ++; MIPS32: # %bb.0: # %entry ++; MIPS32-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32-NEXT: addu $1, $2, $25 ++; MIPS32-NEXT: lw $1, %got(y)($1) ++; MIPS32-NEXT: addiu $2, $zero, -4 ++; MIPS32-NEXT: and $3, $1, $2 ++; MIPS32-NEXT: andi $1, $1, 3 ++; MIPS32-NEXT: sll $1, $1, 3 ++; MIPS32-NEXT: ori $2, $zero, 255 ++; MIPS32-NEXT: sllv $5, $2, $1 ++; MIPS32-NEXT: nor $6, $zero, $5 ++; MIPS32-NEXT: sllv $4, $4, $1 ++; MIPS32-NEXT: $BB10_1: # %entry ++; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32-NEXT: ll $7, 0($3) ++; MIPS32-NEXT: and $8, $7, $4 ++; MIPS32-NEXT: nor $8, $zero, $8 ++; MIPS32-NEXT: and $8, $8, $5 ++; MIPS32-NEXT: and $9, $7, $6 ++; MIPS32-NEXT: or $9, $9, $8 ++; MIPS32-NEXT: sc $9, 0($3) ++; MIPS32-NEXT: beqz $9, $BB10_1 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: # %bb.2: # %entry ++; MIPS32-NEXT: and $2, $7, $5 ++; MIPS32-NEXT: srlv $2, $2, $1 ++; MIPS32-NEXT: sll $2, $2, 24 ++; MIPS32-NEXT: sra $2, $2, 24 ++; MIPS32-NEXT: # %bb.3: # %entry ++; MIPS32-NEXT: jr $ra ++; MIPS32-NEXT: nop ++; ++; MIPS32O0-LABEL: AtomicLoadNand8: ++; MIPS32O0: # %bb.0: # %entry ++; MIPS32O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32O0-NEXT: addiu $sp, $sp, -8 ++; MIPS32O0-NEXT: addu $1, $2, $25 ++; MIPS32O0-NEXT: lw $1, %got(y)($1) ++; MIPS32O0-NEXT: addiu $2, $zero, -4 ++; MIPS32O0-NEXT: and $5, $1, $2 ++; MIPS32O0-NEXT: andi $1, $1, 3 ++; MIPS32O0-NEXT: sll $9, $1, 3 ++; MIPS32O0-NEXT: ori $1, $zero, 255 ++; MIPS32O0-NEXT: sllv $7, $1, $9 ++; MIPS32O0-NEXT: nor $8, $zero, $7 ++; MIPS32O0-NEXT: sllv $6, $4, $9 ++; MIPS32O0-NEXT: $BB10_1: # %entry ++; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32O0-NEXT: ll $2, 0($5) ++; MIPS32O0-NEXT: and $3, $2, $6 ++; MIPS32O0-NEXT: nor $3, $zero, $3 ++; MIPS32O0-NEXT: and $3, $3, $7 ++; MIPS32O0-NEXT: and $4, $2, $8 ++; MIPS32O0-NEXT: or $4, $4, $3 ++; MIPS32O0-NEXT: sc $4, 0($5) ++; MIPS32O0-NEXT: beqz $4, $BB10_1 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: # %bb.2: # %entry ++; MIPS32O0-NEXT: and $1, $2, $7 ++; MIPS32O0-NEXT: srlv $1, $1, $9 ++; MIPS32O0-NEXT: sll $1, $1, 24 ++; MIPS32O0-NEXT: sra $1, $1, 24 ++; MIPS32O0-NEXT: # %bb.3: # %entry ++; MIPS32O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ++; MIPS32O0-NEXT: # %bb.4: # %entry ++; MIPS32O0-NEXT: lw $1, 4($sp) # 4-byte Folded Reload ++; MIPS32O0-NEXT: sll $1, $1, 24 ++; MIPS32O0-NEXT: sra $2, $1, 24 ++; MIPS32O0-NEXT: addiu $sp, $sp, 8 ++; MIPS32O0-NEXT: jr $ra ++; MIPS32O0-NEXT: nop ++; ++; MIPS32R2-LABEL: AtomicLoadNand8: ++; MIPS32R2: # %bb.0: # %entry ++; MIPS32R2-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R2-NEXT: addu $1, $2, $25 ++; MIPS32R2-NEXT: lw $1, %got(y)($1) ++; MIPS32R2-NEXT: addiu $2, $zero, -4 ++; MIPS32R2-NEXT: and $3, $1, $2 ++; MIPS32R2-NEXT: andi $1, $1, 3 ++; MIPS32R2-NEXT: sll $1, $1, 3 ++; MIPS32R2-NEXT: ori $2, $zero, 255 ++; MIPS32R2-NEXT: sllv $5, $2, $1 ++; MIPS32R2-NEXT: nor $6, $zero, $5 ++; MIPS32R2-NEXT: sllv $4, $4, $1 ++; MIPS32R2-NEXT: $BB10_1: # %entry ++; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R2-NEXT: ll $7, 0($3) ++; MIPS32R2-NEXT: and $8, $7, $4 ++; MIPS32R2-NEXT: nor $8, $zero, $8 ++; MIPS32R2-NEXT: and $8, $8, $5 ++; MIPS32R2-NEXT: and $9, $7, $6 ++; MIPS32R2-NEXT: or $9, $9, $8 ++; MIPS32R2-NEXT: sc $9, 0($3) ++; MIPS32R2-NEXT: beqz $9, $BB10_1 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: # %bb.2: # %entry ++; MIPS32R2-NEXT: and $2, $7, $5 ++; MIPS32R2-NEXT: srlv $2, $2, $1 ++; MIPS32R2-NEXT: seb $2, $2 ++; MIPS32R2-NEXT: # %bb.3: # %entry ++; MIPS32R2-NEXT: jr $ra ++; MIPS32R2-NEXT: nop ++; ++; MIPS32R6-LABEL: AtomicLoadNand8: ++; MIPS32R6: # %bb.0: # %entry ++; MIPS32R6-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6-NEXT: addu $1, $2, $25 ++; MIPS32R6-NEXT: lw $1, %got(y)($1) ++; MIPS32R6-NEXT: addiu $2, $zero, -4 ++; MIPS32R6-NEXT: and $3, $1, $2 ++; MIPS32R6-NEXT: andi $1, $1, 3 ++; MIPS32R6-NEXT: sll $1, $1, 3 ++; MIPS32R6-NEXT: ori $2, $zero, 255 ++; MIPS32R6-NEXT: sllv $5, $2, $1 ++; MIPS32R6-NEXT: nor $6, $zero, $5 ++; MIPS32R6-NEXT: sllv $4, $4, $1 ++; MIPS32R6-NEXT: $BB10_1: # %entry ++; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6-NEXT: ll $7, 0($3) ++; MIPS32R6-NEXT: and $8, $7, $4 ++; MIPS32R6-NEXT: nor $8, $zero, $8 ++; MIPS32R6-NEXT: and $8, $8, $5 ++; MIPS32R6-NEXT: and $9, $7, $6 ++; MIPS32R6-NEXT: or $9, $9, $8 ++; MIPS32R6-NEXT: sc $9, 0($3) ++; MIPS32R6-NEXT: beqzc $9, $BB10_1 ++; MIPS32R6-NEXT: # %bb.2: # %entry ++; MIPS32R6-NEXT: and $2, $7, $5 ++; MIPS32R6-NEXT: srlv $2, $2, $1 ++; MIPS32R6-NEXT: seb $2, $2 ++; MIPS32R6-NEXT: # %bb.3: # %entry ++; MIPS32R6-NEXT: jrc $ra ++; ++; MIPS32R6O0-LABEL: AtomicLoadNand8: ++; MIPS32R6O0: # %bb.0: # %entry ++; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $sp, $sp, -8 ++; MIPS32R6O0-NEXT: addu $1, $2, $25 ++; MIPS32R6O0-NEXT: # kill: def $v0 killed $a0 ++; MIPS32R6O0-NEXT: lw $1, %got(y)($1) ++; MIPS32R6O0-NEXT: addiu $2, $zero, -4 ++; MIPS32R6O0-NEXT: and $5, $1, $2 ++; MIPS32R6O0-NEXT: andi $1, $1, 3 ++; MIPS32R6O0-NEXT: sll $9, $1, 3 ++; MIPS32R6O0-NEXT: ori $1, $zero, 255 ++; MIPS32R6O0-NEXT: sllv $7, $1, $9 ++; MIPS32R6O0-NEXT: nor $8, $zero, $7 ++; MIPS32R6O0-NEXT: sllv $6, $4, $9 ++; MIPS32R6O0-NEXT: $BB10_1: # %entry ++; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6O0-NEXT: ll $2, 0($5) ++; MIPS32R6O0-NEXT: and $3, $2, $6 ++; MIPS32R6O0-NEXT: nor $3, $zero, $3 ++; MIPS32R6O0-NEXT: and $3, $3, $7 ++; MIPS32R6O0-NEXT: and $4, $2, $8 ++; MIPS32R6O0-NEXT: or $4, $4, $3 ++; MIPS32R6O0-NEXT: sc $4, 0($5) ++; MIPS32R6O0-NEXT: beqzc $4, $BB10_1 ++; MIPS32R6O0-NEXT: # %bb.2: # %entry ++; MIPS32R6O0-NEXT: and $1, $2, $7 ++; MIPS32R6O0-NEXT: srlv $1, $1, $9 ++; MIPS32R6O0-NEXT: seb $1, $1 ++; MIPS32R6O0-NEXT: # %bb.3: # %entry ++; MIPS32R6O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ++; MIPS32R6O0-NEXT: # %bb.4: # %entry ++; MIPS32R6O0-NEXT: lw $2, 4($sp) # 4-byte Folded Reload ++; MIPS32R6O0-NEXT: addiu $sp, $sp, 8 ++; MIPS32R6O0-NEXT: jrc $ra ++; ++; MIPS4-LABEL: AtomicLoadNand8: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadNand8))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadNand8))) ++; MIPS4-NEXT: ld $1, %got_disp(y)($1) ++; MIPS4-NEXT: daddiu $2, $zero, -4 ++; MIPS4-NEXT: and $3, $1, $2 ++; MIPS4-NEXT: andi $1, $1, 3 ++; MIPS4-NEXT: sll $1, $1, 3 ++; MIPS4-NEXT: ori $2, $zero, 255 ++; MIPS4-NEXT: sllv $5, $2, $1 ++; MIPS4-NEXT: nor $6, $zero, $5 ++; MIPS4-NEXT: sllv $4, $4, $1 ++; MIPS4-NEXT: .LBB10_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: ll $7, 0($3) ++; MIPS4-NEXT: and $8, $7, $4 ++; MIPS4-NEXT: nor $8, $zero, $8 ++; MIPS4-NEXT: and $8, $8, $5 ++; MIPS4-NEXT: and $9, $7, $6 ++; MIPS4-NEXT: or $9, $9, $8 ++; MIPS4-NEXT: sc $9, 0($3) ++; MIPS4-NEXT: beqz $9, .LBB10_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: and $2, $7, $5 ++; MIPS4-NEXT: srlv $2, $2, $1 ++; MIPS4-NEXT: sll $2, $2, 24 ++; MIPS4-NEXT: sra $2, $2, 24 ++; MIPS4-NEXT: # %bb.3: # %entry ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: nop ++; ++; MIPS64-LABEL: AtomicLoadNand8: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadNand8))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadNand8))) ++; MIPS64-NEXT: ld $1, %got_disp(y)($1) ++; MIPS64-NEXT: daddiu $2, $zero, -4 ++; MIPS64-NEXT: and $3, $1, $2 ++; MIPS64-NEXT: andi $1, $1, 3 ++; MIPS64-NEXT: sll $1, $1, 3 ++; MIPS64-NEXT: ori $2, $zero, 255 ++; MIPS64-NEXT: sllv $5, $2, $1 ++; MIPS64-NEXT: nor $6, $zero, $5 ++; MIPS64-NEXT: sllv $4, $4, $1 ++; MIPS64-NEXT: .LBB10_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: ll $7, 0($3) ++; MIPS64-NEXT: and $8, $7, $4 ++; MIPS64-NEXT: nor $8, $zero, $8 ++; MIPS64-NEXT: and $8, $8, $5 ++; MIPS64-NEXT: and $9, $7, $6 ++; MIPS64-NEXT: or $9, $9, $8 ++; MIPS64-NEXT: sc $9, 0($3) ++; MIPS64-NEXT: beqz $9, .LBB10_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: and $2, $7, $5 ++; MIPS64-NEXT: srlv $2, $2, $1 ++; MIPS64-NEXT: sll $2, $2, 24 ++; MIPS64-NEXT: sra $2, $2, 24 ++; MIPS64-NEXT: # %bb.3: # %entry ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: nop ++; ++; MIPS64R2-LABEL: AtomicLoadNand8: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadNand8))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadNand8))) ++; MIPS64R2-NEXT: ld $1, %got_disp(y)($1) ++; MIPS64R2-NEXT: daddiu $2, $zero, -4 ++; MIPS64R2-NEXT: and $3, $1, $2 ++; MIPS64R2-NEXT: andi $1, $1, 3 ++; MIPS64R2-NEXT: sll $1, $1, 3 ++; MIPS64R2-NEXT: ori $2, $zero, 255 ++; MIPS64R2-NEXT: sllv $5, $2, $1 ++; MIPS64R2-NEXT: nor $6, $zero, $5 ++; MIPS64R2-NEXT: sllv $4, $4, $1 ++; MIPS64R2-NEXT: .LBB10_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: ll $7, 0($3) ++; MIPS64R2-NEXT: and $8, $7, $4 ++; MIPS64R2-NEXT: nor $8, $zero, $8 ++; MIPS64R2-NEXT: and $8, $8, $5 ++; MIPS64R2-NEXT: and $9, $7, $6 ++; MIPS64R2-NEXT: or $9, $9, $8 ++; MIPS64R2-NEXT: sc $9, 0($3) ++; MIPS64R2-NEXT: beqz $9, .LBB10_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: and $2, $7, $5 ++; MIPS64R2-NEXT: srlv $2, $2, $1 ++; MIPS64R2-NEXT: seb $2, $2 ++; MIPS64R2-NEXT: # %bb.3: # %entry ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: nop ++; ++; MIPS64R6-LABEL: AtomicLoadNand8: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadNand8))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadNand8))) ++; MIPS64R6-NEXT: ld $1, %got_disp(y)($1) ++; MIPS64R6-NEXT: daddiu $2, $zero, -4 ++; MIPS64R6-NEXT: and $3, $1, $2 ++; MIPS64R6-NEXT: andi $1, $1, 3 ++; MIPS64R6-NEXT: sll $1, $1, 3 ++; MIPS64R6-NEXT: ori $2, $zero, 255 ++; MIPS64R6-NEXT: sllv $5, $2, $1 ++; MIPS64R6-NEXT: nor $6, $zero, $5 ++; MIPS64R6-NEXT: sllv $4, $4, $1 ++; MIPS64R6-NEXT: .LBB10_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: ll $7, 0($3) ++; MIPS64R6-NEXT: and $8, $7, $4 ++; MIPS64R6-NEXT: nor $8, $zero, $8 ++; MIPS64R6-NEXT: and $8, $8, $5 ++; MIPS64R6-NEXT: and $9, $7, $6 ++; MIPS64R6-NEXT: or $9, $9, $8 ++; MIPS64R6-NEXT: sc $9, 0($3) ++; MIPS64R6-NEXT: beqzc $9, .LBB10_1 ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: and $2, $7, $5 ++; MIPS64R6-NEXT: srlv $2, $2, $1 ++; MIPS64R6-NEXT: seb $2, $2 ++; MIPS64R6-NEXT: # %bb.3: # %entry ++; MIPS64R6-NEXT: jrc $ra ++; ++; MIPS64R6O0-LABEL: AtomicLoadNand8: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, -16 ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadNand8))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $2, $1, %lo(%neg(%gp_rel(AtomicLoadNand8))) ++; MIPS64R6O0-NEXT: move $1, $4 ++; MIPS64R6O0-NEXT: ld $2, %got_disp(y)($2) ++; MIPS64R6O0-NEXT: daddiu $3, $zero, -4 ++; MIPS64R6O0-NEXT: and $5, $2, $3 ++; MIPS64R6O0-NEXT: andi $2, $2, 3 ++; MIPS64R6O0-NEXT: xori $2, $2, 3 ++; MIPS64R6O0-NEXT: sll $9, $2, 3 ++; MIPS64R6O0-NEXT: ori $2, $zero, 255 ++; MIPS64R6O0-NEXT: sllv $7, $2, $9 ++; MIPS64R6O0-NEXT: nor $8, $zero, $7 ++; MIPS64R6O0-NEXT: sllv $6, $1, $9 ++; MIPS64R6O0-NEXT: .LBB10_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: ll $2, 0($5) ++; MIPS64R6O0-NEXT: and $3, $2, $6 ++; MIPS64R6O0-NEXT: nor $3, $zero, $3 ++; MIPS64R6O0-NEXT: and $3, $3, $7 ++; MIPS64R6O0-NEXT: and $4, $2, $8 ++; MIPS64R6O0-NEXT: or $4, $4, $3 ++; MIPS64R6O0-NEXT: sc $4, 0($5) ++; MIPS64R6O0-NEXT: beqzc $4, .LBB10_1 ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: and $1, $2, $7 ++; MIPS64R6O0-NEXT: srlv $1, $1, $9 ++; MIPS64R6O0-NEXT: seb $1, $1 ++; MIPS64R6O0-NEXT: # %bb.3: # %entry ++; MIPS64R6O0-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ++; MIPS64R6O0-NEXT: # %bb.4: # %entry ++; MIPS64R6O0-NEXT: lw $2, 12($sp) # 4-byte Folded Reload ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, 16 ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; MM32-LABEL: AtomicLoadNand8: ++; MM32: # %bb.0: # %entry ++; MM32-NEXT: lui $2, %hi(_gp_disp) ++; MM32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MM32-NEXT: addu $2, $2, $25 ++; MM32-NEXT: lw $1, %got(y)($2) ++; MM32-NEXT: addiu $2, $zero, -4 ++; MM32-NEXT: and $3, $1, $2 ++; MM32-NEXT: andi $1, $1, 3 ++; MM32-NEXT: sll $1, $1, 3 ++; MM32-NEXT: ori $2, $zero, 255 ++; MM32-NEXT: sllv $5, $2, $1 ++; MM32-NEXT: nor $6, $zero, $5 ++; MM32-NEXT: sllv $4, $4, $1 ++; MM32-NEXT: $BB10_1: # %entry ++; MM32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MM32-NEXT: ll $7, 0($3) ++; MM32-NEXT: and $8, $7, $4 ++; MM32-NEXT: nor $8, $zero, $8 ++; MM32-NEXT: and $8, $8, $5 ++; MM32-NEXT: and $9, $7, $6 ++; MM32-NEXT: or $9, $9, $8 ++; MM32-NEXT: sc $9, 0($3) ++; MM32-NEXT: beqzc $9, $BB10_1 ++; MM32-NEXT: # %bb.2: # %entry ++; MM32-NEXT: and $2, $7, $5 ++; MM32-NEXT: srlv $2, $2, $1 ++; MM32-NEXT: seb $2, $2 ++; MM32-NEXT: # %bb.3: # %entry ++; MM32-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicLoadNand8: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $2, %hi(_gp_disp) ++; O1-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O1-NEXT: addu $1, $2, $25 ++; O1-NEXT: lw $1, %got(y)($1) ++; O1-NEXT: addiu $2, $zero, -4 ++; O1-NEXT: and $3, $1, $2 ++; O1-NEXT: andi $1, $1, 3 ++; O1-NEXT: sll $1, $1, 3 ++; O1-NEXT: ori $2, $zero, 255 ++; O1-NEXT: sllv $5, $2, $1 ++; O1-NEXT: nor $6, $zero, $5 ++; O1-NEXT: sllv $4, $4, $1 ++; O1-NEXT: $BB10_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: ll $7, 0($3) ++; O1-NEXT: and $8, $7, $4 ++; O1-NEXT: nor $8, $zero, $8 ++; O1-NEXT: and $8, $8, $5 ++; O1-NEXT: and $9, $7, $6 ++; O1-NEXT: or $9, $9, $8 ++; O1-NEXT: sc $9, 0($3) ++; O1-NEXT: beqz $9, $BB10_1 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: and $2, $7, $5 ++; O1-NEXT: srlv $2, $2, $1 ++; O1-NEXT: sll $2, $2, 24 ++; O1-NEXT: sra $2, $2, 24 ++; O1-NEXT: # %bb.3: # %entry ++; O1-NEXT: jr $ra ++; O1-NEXT: nop ++; ++; O2-LABEL: AtomicLoadNand8: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $2, %hi(_gp_disp) ++; O2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O2-NEXT: addu $1, $2, $25 ++; O2-NEXT: lw $1, %got(y)($1) ++; O2-NEXT: addiu $2, $zero, -4 ++; O2-NEXT: and $3, $1, $2 ++; O2-NEXT: andi $1, $1, 3 ++; O2-NEXT: sll $1, $1, 3 ++; O2-NEXT: ori $2, $zero, 255 ++; O2-NEXT: sllv $5, $2, $1 ++; O2-NEXT: nor $6, $zero, $5 ++; O2-NEXT: sllv $4, $4, $1 ++; O2-NEXT: $BB10_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: ll $7, 0($3) ++; O2-NEXT: and $8, $7, $4 ++; O2-NEXT: nor $8, $zero, $8 ++; O2-NEXT: and $8, $8, $5 ++; O2-NEXT: and $9, $7, $6 ++; O2-NEXT: or $9, $9, $8 ++; O2-NEXT: sc $9, 0($3) ++; O2-NEXT: beqz $9, $BB10_1 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: and $2, $7, $5 ++; O2-NEXT: srlv $2, $2, $1 ++; O2-NEXT: sll $2, $2, 24 ++; O2-NEXT: sra $2, $2, 24 ++; O2-NEXT: # %bb.3: # %entry ++; O2-NEXT: jr $ra ++; O2-NEXT: nop ++; ++; O3-LABEL: AtomicLoadNand8: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $2, %hi(_gp_disp) ++; O3-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O3-NEXT: addu $1, $2, $25 ++; O3-NEXT: addiu $2, $zero, -4 ++; O3-NEXT: lw $1, %got(y)($1) ++; O3-NEXT: and $3, $1, $2 ++; O3-NEXT: andi $1, $1, 3 ++; O3-NEXT: ori $2, $zero, 255 ++; O3-NEXT: sll $1, $1, 3 ++; O3-NEXT: sllv $5, $2, $1 ++; O3-NEXT: sllv $4, $4, $1 ++; O3-NEXT: nor $6, $zero, $5 ++; O3-NEXT: $BB10_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: ll $7, 0($3) ++; O3-NEXT: and $8, $7, $4 ++; O3-NEXT: nor $8, $zero, $8 ++; O3-NEXT: and $8, $8, $5 ++; O3-NEXT: and $9, $7, $6 ++; O3-NEXT: or $9, $9, $8 ++; O3-NEXT: sc $9, 0($3) ++; O3-NEXT: beqz $9, $BB10_1 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: and $2, $7, $5 ++; O3-NEXT: srlv $2, $2, $1 ++; O3-NEXT: sll $2, $2, 24 ++; O3-NEXT: sra $2, $2, 24 ++; O3-NEXT: # %bb.3: # %entry ++; O3-NEXT: jr $ra ++; O3-NEXT: nop ++; ++; MIPS32EB-LABEL: AtomicLoadNand8: ++; MIPS32EB: # %bb.0: # %entry ++; MIPS32EB-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32EB-NEXT: addu $1, $2, $25 ++; MIPS32EB-NEXT: lw $1, %got(y)($1) ++; MIPS32EB-NEXT: addiu $2, $zero, -4 ++; MIPS32EB-NEXT: and $3, $1, $2 ++; MIPS32EB-NEXT: andi $1, $1, 3 ++; MIPS32EB-NEXT: xori $1, $1, 3 ++; MIPS32EB-NEXT: sll $1, $1, 3 ++; MIPS32EB-NEXT: ori $2, $zero, 255 ++; MIPS32EB-NEXT: sllv $5, $2, $1 ++; MIPS32EB-NEXT: nor $6, $zero, $5 ++; MIPS32EB-NEXT: sllv $4, $4, $1 ++; MIPS32EB-NEXT: $BB10_1: # %entry ++; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32EB-NEXT: ll $7, 0($3) ++; MIPS32EB-NEXT: and $8, $7, $4 ++; MIPS32EB-NEXT: nor $8, $zero, $8 ++; MIPS32EB-NEXT: and $8, $8, $5 ++; MIPS32EB-NEXT: and $9, $7, $6 ++; MIPS32EB-NEXT: or $9, $9, $8 ++; MIPS32EB-NEXT: sc $9, 0($3) ++; MIPS32EB-NEXT: beqz $9, $BB10_1 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: # %bb.2: # %entry ++; MIPS32EB-NEXT: and $2, $7, $5 ++; MIPS32EB-NEXT: srlv $2, $2, $1 ++; MIPS32EB-NEXT: sll $2, $2, 24 ++; MIPS32EB-NEXT: sra $2, $2, 24 ++; MIPS32EB-NEXT: # %bb.3: # %entry ++; MIPS32EB-NEXT: jr $ra ++; MIPS32EB-NEXT: nop ++entry: ++ %0 = atomicrmw nand ptr @y, i8 %incr monotonic ++ ret i8 %0 ++ ++} ++ ++define signext i8 @AtomicSwap8(i8 signext %newval) nounwind { ++; MIPS32-LABEL: AtomicSwap8: ++; MIPS32: # %bb.0: # %entry ++; MIPS32-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32-NEXT: addu $1, $2, $25 ++; MIPS32-NEXT: lw $1, %got(y)($1) ++; MIPS32-NEXT: addiu $2, $zero, -4 ++; MIPS32-NEXT: and $3, $1, $2 ++; MIPS32-NEXT: andi $1, $1, 3 ++; MIPS32-NEXT: sll $1, $1, 3 ++; MIPS32-NEXT: ori $2, $zero, 255 ++; MIPS32-NEXT: sllv $5, $2, $1 ++; MIPS32-NEXT: nor $6, $zero, $5 ++; MIPS32-NEXT: sllv $4, $4, $1 ++; MIPS32-NEXT: $BB11_1: # %entry ++; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32-NEXT: ll $7, 0($3) ++; MIPS32-NEXT: and $8, $4, $5 ++; MIPS32-NEXT: and $9, $7, $6 ++; MIPS32-NEXT: or $9, $9, $8 ++; MIPS32-NEXT: sc $9, 0($3) ++; MIPS32-NEXT: beqz $9, $BB11_1 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: # %bb.2: # %entry ++; MIPS32-NEXT: and $2, $7, $5 ++; MIPS32-NEXT: srlv $2, $2, $1 ++; MIPS32-NEXT: sll $2, $2, 24 ++; MIPS32-NEXT: sra $2, $2, 24 ++; MIPS32-NEXT: # %bb.3: # %entry ++; MIPS32-NEXT: jr $ra ++; MIPS32-NEXT: nop ++; ++; MIPS32O0-LABEL: AtomicSwap8: ++; MIPS32O0: # %bb.0: # %entry ++; MIPS32O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32O0-NEXT: addiu $sp, $sp, -8 ++; MIPS32O0-NEXT: addu $1, $2, $25 ++; MIPS32O0-NEXT: lw $1, %got(y)($1) ++; MIPS32O0-NEXT: addiu $2, $zero, -4 ++; MIPS32O0-NEXT: and $5, $1, $2 ++; MIPS32O0-NEXT: andi $1, $1, 3 ++; MIPS32O0-NEXT: sll $9, $1, 3 ++; MIPS32O0-NEXT: ori $1, $zero, 255 ++; MIPS32O0-NEXT: sllv $7, $1, $9 ++; MIPS32O0-NEXT: nor $8, $zero, $7 ++; MIPS32O0-NEXT: sllv $6, $4, $9 ++; MIPS32O0-NEXT: $BB11_1: # %entry ++; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32O0-NEXT: ll $2, 0($5) ++; MIPS32O0-NEXT: and $3, $6, $7 ++; MIPS32O0-NEXT: and $4, $2, $8 ++; MIPS32O0-NEXT: or $4, $4, $3 ++; MIPS32O0-NEXT: sc $4, 0($5) ++; MIPS32O0-NEXT: beqz $4, $BB11_1 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: # %bb.2: # %entry ++; MIPS32O0-NEXT: and $1, $2, $7 ++; MIPS32O0-NEXT: srlv $1, $1, $9 ++; MIPS32O0-NEXT: sll $1, $1, 24 ++; MIPS32O0-NEXT: sra $1, $1, 24 ++; MIPS32O0-NEXT: # %bb.3: # %entry ++; MIPS32O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ++; MIPS32O0-NEXT: # %bb.4: # %entry ++; MIPS32O0-NEXT: lw $1, 4($sp) # 4-byte Folded Reload ++; MIPS32O0-NEXT: sll $1, $1, 24 ++; MIPS32O0-NEXT: sra $2, $1, 24 ++; MIPS32O0-NEXT: addiu $sp, $sp, 8 ++; MIPS32O0-NEXT: jr $ra ++; MIPS32O0-NEXT: nop ++; ++; MIPS32R2-LABEL: AtomicSwap8: ++; MIPS32R2: # %bb.0: # %entry ++; MIPS32R2-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R2-NEXT: addu $1, $2, $25 ++; MIPS32R2-NEXT: lw $1, %got(y)($1) ++; MIPS32R2-NEXT: addiu $2, $zero, -4 ++; MIPS32R2-NEXT: and $3, $1, $2 ++; MIPS32R2-NEXT: andi $1, $1, 3 ++; MIPS32R2-NEXT: sll $1, $1, 3 ++; MIPS32R2-NEXT: ori $2, $zero, 255 ++; MIPS32R2-NEXT: sllv $5, $2, $1 ++; MIPS32R2-NEXT: nor $6, $zero, $5 ++; MIPS32R2-NEXT: sllv $4, $4, $1 ++; MIPS32R2-NEXT: $BB11_1: # %entry ++; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R2-NEXT: ll $7, 0($3) ++; MIPS32R2-NEXT: and $8, $4, $5 ++; MIPS32R2-NEXT: and $9, $7, $6 ++; MIPS32R2-NEXT: or $9, $9, $8 ++; MIPS32R2-NEXT: sc $9, 0($3) ++; MIPS32R2-NEXT: beqz $9, $BB11_1 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: # %bb.2: # %entry ++; MIPS32R2-NEXT: and $2, $7, $5 ++; MIPS32R2-NEXT: srlv $2, $2, $1 ++; MIPS32R2-NEXT: seb $2, $2 ++; MIPS32R2-NEXT: # %bb.3: # %entry ++; MIPS32R2-NEXT: jr $ra ++; MIPS32R2-NEXT: nop ++; ++; MIPS32R6-LABEL: AtomicSwap8: ++; MIPS32R6: # %bb.0: # %entry ++; MIPS32R6-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6-NEXT: addu $1, $2, $25 ++; MIPS32R6-NEXT: lw $1, %got(y)($1) ++; MIPS32R6-NEXT: addiu $2, $zero, -4 ++; MIPS32R6-NEXT: and $3, $1, $2 ++; MIPS32R6-NEXT: andi $1, $1, 3 ++; MIPS32R6-NEXT: sll $1, $1, 3 ++; MIPS32R6-NEXT: ori $2, $zero, 255 ++; MIPS32R6-NEXT: sllv $5, $2, $1 ++; MIPS32R6-NEXT: nor $6, $zero, $5 ++; MIPS32R6-NEXT: sllv $4, $4, $1 ++; MIPS32R6-NEXT: $BB11_1: # %entry ++; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6-NEXT: ll $7, 0($3) ++; MIPS32R6-NEXT: and $8, $4, $5 ++; MIPS32R6-NEXT: and $9, $7, $6 ++; MIPS32R6-NEXT: or $9, $9, $8 ++; MIPS32R6-NEXT: sc $9, 0($3) ++; MIPS32R6-NEXT: beqzc $9, $BB11_1 ++; MIPS32R6-NEXT: # %bb.2: # %entry ++; MIPS32R6-NEXT: and $2, $7, $5 ++; MIPS32R6-NEXT: srlv $2, $2, $1 ++; MIPS32R6-NEXT: seb $2, $2 ++; MIPS32R6-NEXT: # %bb.3: # %entry ++; MIPS32R6-NEXT: jrc $ra ++; ++; MIPS32R6O0-LABEL: AtomicSwap8: ++; MIPS32R6O0: # %bb.0: # %entry ++; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $sp, $sp, -8 ++; MIPS32R6O0-NEXT: addu $1, $2, $25 ++; MIPS32R6O0-NEXT: # kill: def $v0 killed $a0 ++; MIPS32R6O0-NEXT: lw $1, %got(y)($1) ++; MIPS32R6O0-NEXT: addiu $2, $zero, -4 ++; MIPS32R6O0-NEXT: and $5, $1, $2 ++; MIPS32R6O0-NEXT: andi $1, $1, 3 ++; MIPS32R6O0-NEXT: sll $9, $1, 3 ++; MIPS32R6O0-NEXT: ori $1, $zero, 255 ++; MIPS32R6O0-NEXT: sllv $7, $1, $9 ++; MIPS32R6O0-NEXT: nor $8, $zero, $7 ++; MIPS32R6O0-NEXT: sllv $6, $4, $9 ++; MIPS32R6O0-NEXT: $BB11_1: # %entry ++; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6O0-NEXT: ll $2, 0($5) ++; MIPS32R6O0-NEXT: and $3, $6, $7 ++; MIPS32R6O0-NEXT: and $4, $2, $8 ++; MIPS32R6O0-NEXT: or $4, $4, $3 ++; MIPS32R6O0-NEXT: sc $4, 0($5) ++; MIPS32R6O0-NEXT: beqzc $4, $BB11_1 ++; MIPS32R6O0-NEXT: # %bb.2: # %entry ++; MIPS32R6O0-NEXT: and $1, $2, $7 ++; MIPS32R6O0-NEXT: srlv $1, $1, $9 ++; MIPS32R6O0-NEXT: seb $1, $1 ++; MIPS32R6O0-NEXT: # %bb.3: # %entry ++; MIPS32R6O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ++; MIPS32R6O0-NEXT: # %bb.4: # %entry ++; MIPS32R6O0-NEXT: lw $2, 4($sp) # 4-byte Folded Reload ++; MIPS32R6O0-NEXT: addiu $sp, $sp, 8 ++; MIPS32R6O0-NEXT: jrc $ra ++; ++; MIPS4-LABEL: AtomicSwap8: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicSwap8))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicSwap8))) ++; MIPS4-NEXT: ld $1, %got_disp(y)($1) ++; MIPS4-NEXT: daddiu $2, $zero, -4 ++; MIPS4-NEXT: and $3, $1, $2 ++; MIPS4-NEXT: andi $1, $1, 3 ++; MIPS4-NEXT: sll $1, $1, 3 ++; MIPS4-NEXT: ori $2, $zero, 255 ++; MIPS4-NEXT: sllv $5, $2, $1 ++; MIPS4-NEXT: nor $6, $zero, $5 ++; MIPS4-NEXT: sllv $4, $4, $1 ++; MIPS4-NEXT: .LBB11_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: ll $7, 0($3) ++; MIPS4-NEXT: and $8, $4, $5 ++; MIPS4-NEXT: and $9, $7, $6 ++; MIPS4-NEXT: or $9, $9, $8 ++; MIPS4-NEXT: sc $9, 0($3) ++; MIPS4-NEXT: beqz $9, .LBB11_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: and $2, $7, $5 ++; MIPS4-NEXT: srlv $2, $2, $1 ++; MIPS4-NEXT: sll $2, $2, 24 ++; MIPS4-NEXT: sra $2, $2, 24 ++; MIPS4-NEXT: # %bb.3: # %entry ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: nop ++; ++; MIPS64-LABEL: AtomicSwap8: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicSwap8))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicSwap8))) ++; MIPS64-NEXT: ld $1, %got_disp(y)($1) ++; MIPS64-NEXT: daddiu $2, $zero, -4 ++; MIPS64-NEXT: and $3, $1, $2 ++; MIPS64-NEXT: andi $1, $1, 3 ++; MIPS64-NEXT: sll $1, $1, 3 ++; MIPS64-NEXT: ori $2, $zero, 255 ++; MIPS64-NEXT: sllv $5, $2, $1 ++; MIPS64-NEXT: nor $6, $zero, $5 ++; MIPS64-NEXT: sllv $4, $4, $1 ++; MIPS64-NEXT: .LBB11_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: ll $7, 0($3) ++; MIPS64-NEXT: and $8, $4, $5 ++; MIPS64-NEXT: and $9, $7, $6 ++; MIPS64-NEXT: or $9, $9, $8 ++; MIPS64-NEXT: sc $9, 0($3) ++; MIPS64-NEXT: beqz $9, .LBB11_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: and $2, $7, $5 ++; MIPS64-NEXT: srlv $2, $2, $1 ++; MIPS64-NEXT: sll $2, $2, 24 ++; MIPS64-NEXT: sra $2, $2, 24 ++; MIPS64-NEXT: # %bb.3: # %entry ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: nop ++; ++; MIPS64R2-LABEL: AtomicSwap8: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicSwap8))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicSwap8))) ++; MIPS64R2-NEXT: ld $1, %got_disp(y)($1) ++; MIPS64R2-NEXT: daddiu $2, $zero, -4 ++; MIPS64R2-NEXT: and $3, $1, $2 ++; MIPS64R2-NEXT: andi $1, $1, 3 ++; MIPS64R2-NEXT: sll $1, $1, 3 ++; MIPS64R2-NEXT: ori $2, $zero, 255 ++; MIPS64R2-NEXT: sllv $5, $2, $1 ++; MIPS64R2-NEXT: nor $6, $zero, $5 ++; MIPS64R2-NEXT: sllv $4, $4, $1 ++; MIPS64R2-NEXT: .LBB11_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: ll $7, 0($3) ++; MIPS64R2-NEXT: and $8, $4, $5 ++; MIPS64R2-NEXT: and $9, $7, $6 ++; MIPS64R2-NEXT: or $9, $9, $8 ++; MIPS64R2-NEXT: sc $9, 0($3) ++; MIPS64R2-NEXT: beqz $9, .LBB11_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: and $2, $7, $5 ++; MIPS64R2-NEXT: srlv $2, $2, $1 ++; MIPS64R2-NEXT: seb $2, $2 ++; MIPS64R2-NEXT: # %bb.3: # %entry ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: nop ++; ++; MIPS64R6-LABEL: AtomicSwap8: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicSwap8))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicSwap8))) ++; MIPS64R6-NEXT: ld $1, %got_disp(y)($1) ++; MIPS64R6-NEXT: daddiu $2, $zero, -4 ++; MIPS64R6-NEXT: and $3, $1, $2 ++; MIPS64R6-NEXT: andi $1, $1, 3 ++; MIPS64R6-NEXT: sll $1, $1, 3 ++; MIPS64R6-NEXT: ori $2, $zero, 255 ++; MIPS64R6-NEXT: sllv $5, $2, $1 ++; MIPS64R6-NEXT: nor $6, $zero, $5 ++; MIPS64R6-NEXT: sllv $4, $4, $1 ++; MIPS64R6-NEXT: .LBB11_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: ll $7, 0($3) ++; MIPS64R6-NEXT: and $8, $4, $5 ++; MIPS64R6-NEXT: and $9, $7, $6 ++; MIPS64R6-NEXT: or $9, $9, $8 ++; MIPS64R6-NEXT: sc $9, 0($3) ++; MIPS64R6-NEXT: beqzc $9, .LBB11_1 ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: and $2, $7, $5 ++; MIPS64R6-NEXT: srlv $2, $2, $1 ++; MIPS64R6-NEXT: seb $2, $2 ++; MIPS64R6-NEXT: # %bb.3: # %entry ++; MIPS64R6-NEXT: jrc $ra ++; ++; MIPS64R6O0-LABEL: AtomicSwap8: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, -16 ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicSwap8))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $2, $1, %lo(%neg(%gp_rel(AtomicSwap8))) ++; MIPS64R6O0-NEXT: move $1, $4 ++; MIPS64R6O0-NEXT: ld $2, %got_disp(y)($2) ++; MIPS64R6O0-NEXT: daddiu $3, $zero, -4 ++; MIPS64R6O0-NEXT: and $5, $2, $3 ++; MIPS64R6O0-NEXT: andi $2, $2, 3 ++; MIPS64R6O0-NEXT: xori $2, $2, 3 ++; MIPS64R6O0-NEXT: sll $9, $2, 3 ++; MIPS64R6O0-NEXT: ori $2, $zero, 255 ++; MIPS64R6O0-NEXT: sllv $7, $2, $9 ++; MIPS64R6O0-NEXT: nor $8, $zero, $7 ++; MIPS64R6O0-NEXT: sllv $6, $1, $9 ++; MIPS64R6O0-NEXT: .LBB11_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: ll $2, 0($5) ++; MIPS64R6O0-NEXT: and $3, $6, $7 ++; MIPS64R6O0-NEXT: and $4, $2, $8 ++; MIPS64R6O0-NEXT: or $4, $4, $3 ++; MIPS64R6O0-NEXT: sc $4, 0($5) ++; MIPS64R6O0-NEXT: beqzc $4, .LBB11_1 ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: and $1, $2, $7 ++; MIPS64R6O0-NEXT: srlv $1, $1, $9 ++; MIPS64R6O0-NEXT: seb $1, $1 ++; MIPS64R6O0-NEXT: # %bb.3: # %entry ++; MIPS64R6O0-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ++; MIPS64R6O0-NEXT: # %bb.4: # %entry ++; MIPS64R6O0-NEXT: lw $2, 12($sp) # 4-byte Folded Reload ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, 16 ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; MM32-LABEL: AtomicSwap8: ++; MM32: # %bb.0: # %entry ++; MM32-NEXT: lui $2, %hi(_gp_disp) ++; MM32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MM32-NEXT: addu $2, $2, $25 ++; MM32-NEXT: lw $1, %got(y)($2) ++; MM32-NEXT: addiu $2, $zero, -4 ++; MM32-NEXT: and $3, $1, $2 ++; MM32-NEXT: andi $1, $1, 3 ++; MM32-NEXT: sll $1, $1, 3 ++; MM32-NEXT: ori $2, $zero, 255 ++; MM32-NEXT: sllv $5, $2, $1 ++; MM32-NEXT: nor $6, $zero, $5 ++; MM32-NEXT: sllv $4, $4, $1 ++; MM32-NEXT: $BB11_1: # %entry ++; MM32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MM32-NEXT: ll $7, 0($3) ++; MM32-NEXT: and $8, $4, $5 ++; MM32-NEXT: and $9, $7, $6 ++; MM32-NEXT: or $9, $9, $8 ++; MM32-NEXT: sc $9, 0($3) ++; MM32-NEXT: beqzc $9, $BB11_1 ++; MM32-NEXT: # %bb.2: # %entry ++; MM32-NEXT: and $2, $7, $5 ++; MM32-NEXT: srlv $2, $2, $1 ++; MM32-NEXT: seb $2, $2 ++; MM32-NEXT: # %bb.3: # %entry ++; MM32-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicSwap8: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $2, %hi(_gp_disp) ++; O1-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O1-NEXT: addu $1, $2, $25 ++; O1-NEXT: lw $1, %got(y)($1) ++; O1-NEXT: addiu $2, $zero, -4 ++; O1-NEXT: and $3, $1, $2 ++; O1-NEXT: andi $1, $1, 3 ++; O1-NEXT: sll $1, $1, 3 ++; O1-NEXT: ori $2, $zero, 255 ++; O1-NEXT: sllv $5, $2, $1 ++; O1-NEXT: nor $6, $zero, $5 ++; O1-NEXT: sllv $4, $4, $1 ++; O1-NEXT: $BB11_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: ll $7, 0($3) ++; O1-NEXT: and $8, $4, $5 ++; O1-NEXT: and $9, $7, $6 ++; O1-NEXT: or $9, $9, $8 ++; O1-NEXT: sc $9, 0($3) ++; O1-NEXT: beqz $9, $BB11_1 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: and $2, $7, $5 ++; O1-NEXT: srlv $2, $2, $1 ++; O1-NEXT: sll $2, $2, 24 ++; O1-NEXT: sra $2, $2, 24 ++; O1-NEXT: # %bb.3: # %entry ++; O1-NEXT: jr $ra ++; O1-NEXT: nop ++; ++; O2-LABEL: AtomicSwap8: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $2, %hi(_gp_disp) ++; O2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O2-NEXT: addu $1, $2, $25 ++; O2-NEXT: lw $1, %got(y)($1) ++; O2-NEXT: addiu $2, $zero, -4 ++; O2-NEXT: and $3, $1, $2 ++; O2-NEXT: andi $1, $1, 3 ++; O2-NEXT: sll $1, $1, 3 ++; O2-NEXT: ori $2, $zero, 255 ++; O2-NEXT: sllv $5, $2, $1 ++; O2-NEXT: nor $6, $zero, $5 ++; O2-NEXT: sllv $4, $4, $1 ++; O2-NEXT: $BB11_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: ll $7, 0($3) ++; O2-NEXT: and $8, $4, $5 ++; O2-NEXT: and $9, $7, $6 ++; O2-NEXT: or $9, $9, $8 ++; O2-NEXT: sc $9, 0($3) ++; O2-NEXT: beqz $9, $BB11_1 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: and $2, $7, $5 ++; O2-NEXT: srlv $2, $2, $1 ++; O2-NEXT: sll $2, $2, 24 ++; O2-NEXT: sra $2, $2, 24 ++; O2-NEXT: # %bb.3: # %entry ++; O2-NEXT: jr $ra ++; O2-NEXT: nop ++; ++; O3-LABEL: AtomicSwap8: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $2, %hi(_gp_disp) ++; O3-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O3-NEXT: addu $1, $2, $25 ++; O3-NEXT: addiu $2, $zero, -4 ++; O3-NEXT: lw $1, %got(y)($1) ++; O3-NEXT: and $3, $1, $2 ++; O3-NEXT: andi $1, $1, 3 ++; O3-NEXT: ori $2, $zero, 255 ++; O3-NEXT: sll $1, $1, 3 ++; O3-NEXT: sllv $5, $2, $1 ++; O3-NEXT: sllv $4, $4, $1 ++; O3-NEXT: nor $6, $zero, $5 ++; O3-NEXT: $BB11_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: ll $7, 0($3) ++; O3-NEXT: and $8, $4, $5 ++; O3-NEXT: and $9, $7, $6 ++; O3-NEXT: or $9, $9, $8 ++; O3-NEXT: sc $9, 0($3) ++; O3-NEXT: beqz $9, $BB11_1 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: and $2, $7, $5 ++; O3-NEXT: srlv $2, $2, $1 ++; O3-NEXT: sll $2, $2, 24 ++; O3-NEXT: sra $2, $2, 24 ++; O3-NEXT: # %bb.3: # %entry ++; O3-NEXT: jr $ra ++; O3-NEXT: nop ++; ++; MIPS32EB-LABEL: AtomicSwap8: ++; MIPS32EB: # %bb.0: # %entry ++; MIPS32EB-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32EB-NEXT: addu $1, $2, $25 ++; MIPS32EB-NEXT: lw $1, %got(y)($1) ++; MIPS32EB-NEXT: addiu $2, $zero, -4 ++; MIPS32EB-NEXT: and $3, $1, $2 ++; MIPS32EB-NEXT: andi $1, $1, 3 ++; MIPS32EB-NEXT: xori $1, $1, 3 ++; MIPS32EB-NEXT: sll $1, $1, 3 ++; MIPS32EB-NEXT: ori $2, $zero, 255 ++; MIPS32EB-NEXT: sllv $5, $2, $1 ++; MIPS32EB-NEXT: nor $6, $zero, $5 ++; MIPS32EB-NEXT: sllv $4, $4, $1 ++; MIPS32EB-NEXT: $BB11_1: # %entry ++; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32EB-NEXT: ll $7, 0($3) ++; MIPS32EB-NEXT: and $8, $4, $5 ++; MIPS32EB-NEXT: and $9, $7, $6 ++; MIPS32EB-NEXT: or $9, $9, $8 ++; MIPS32EB-NEXT: sc $9, 0($3) ++; MIPS32EB-NEXT: beqz $9, $BB11_1 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: # %bb.2: # %entry ++; MIPS32EB-NEXT: and $2, $7, $5 ++; MIPS32EB-NEXT: srlv $2, $2, $1 ++; MIPS32EB-NEXT: sll $2, $2, 24 ++; MIPS32EB-NEXT: sra $2, $2, 24 ++; MIPS32EB-NEXT: # %bb.3: # %entry ++; MIPS32EB-NEXT: jr $ra ++; MIPS32EB-NEXT: nop ++entry: ++ %0 = atomicrmw xchg ptr @y, i8 %newval monotonic ++ ret i8 %0 ++} ++ ++define signext i8 @AtomicCmpSwap8(i8 signext %oldval, i8 signext %newval) nounwind { ++; MIPS32-LABEL: AtomicCmpSwap8: ++; MIPS32: # %bb.0: # %entry ++; MIPS32-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32-NEXT: addu $1, $2, $25 ++; MIPS32-NEXT: lw $1, %got(y)($1) ++; MIPS32-NEXT: addiu $2, $zero, -4 ++; MIPS32-NEXT: and $3, $1, $2 ++; MIPS32-NEXT: andi $1, $1, 3 ++; MIPS32-NEXT: sll $1, $1, 3 ++; MIPS32-NEXT: ori $2, $zero, 255 ++; MIPS32-NEXT: sllv $6, $2, $1 ++; MIPS32-NEXT: nor $7, $zero, $6 ++; MIPS32-NEXT: andi $2, $4, 255 ++; MIPS32-NEXT: sllv $4, $2, $1 ++; MIPS32-NEXT: andi $2, $5, 255 ++; MIPS32-NEXT: sllv $5, $2, $1 ++; MIPS32-NEXT: $BB12_1: # %entry ++; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32-NEXT: ll $8, 0($3) ++; MIPS32-NEXT: and $9, $8, $6 ++; MIPS32-NEXT: bne $9, $4, $BB12_3 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: # %bb.2: # %entry ++; MIPS32-NEXT: # in Loop: Header=BB12_1 Depth=1 ++; MIPS32-NEXT: and $8, $8, $7 ++; MIPS32-NEXT: or $8, $8, $5 ++; MIPS32-NEXT: sc $8, 0($3) ++; MIPS32-NEXT: beqz $8, $BB12_1 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: $BB12_3: # %entry ++; MIPS32-NEXT: sync ++; MIPS32-NEXT: srlv $2, $9, $1 ++; MIPS32-NEXT: sll $2, $2, 24 ++; MIPS32-NEXT: sra $2, $2, 24 ++; MIPS32-NEXT: # %bb.4: # %entry ++; MIPS32-NEXT: jr $ra ++; MIPS32-NEXT: nop ++; ++; MIPS32O0-LABEL: AtomicCmpSwap8: ++; MIPS32O0: # %bb.0: # %entry ++; MIPS32O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32O0-NEXT: addiu $sp, $sp, -8 ++; MIPS32O0-NEXT: addu $3, $2, $25 ++; MIPS32O0-NEXT: move $1, $5 ++; MIPS32O0-NEXT: move $2, $4 ++; MIPS32O0-NEXT: lw $3, %got(y)($3) ++; MIPS32O0-NEXT: addiu $4, $zero, -4 ++; MIPS32O0-NEXT: and $4, $3, $4 ++; MIPS32O0-NEXT: andi $3, $3, 3 ++; MIPS32O0-NEXT: sll $9, $3, 3 ++; MIPS32O0-NEXT: ori $3, $zero, 255 ++; MIPS32O0-NEXT: sllv $5, $3, $9 ++; MIPS32O0-NEXT: nor $7, $zero, $5 ++; MIPS32O0-NEXT: andi $2, $2, 255 ++; MIPS32O0-NEXT: sllv $6, $2, $9 ++; MIPS32O0-NEXT: andi $1, $1, 255 ++; MIPS32O0-NEXT: sllv $8, $1, $9 ++; MIPS32O0-NEXT: $BB12_1: # %entry ++; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32O0-NEXT: ll $2, 0($4) ++; MIPS32O0-NEXT: and $3, $2, $5 ++; MIPS32O0-NEXT: bne $3, $6, $BB12_3 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: # %bb.2: # %entry ++; MIPS32O0-NEXT: # in Loop: Header=BB12_1 Depth=1 ++; MIPS32O0-NEXT: and $2, $2, $7 ++; MIPS32O0-NEXT: or $2, $2, $8 ++; MIPS32O0-NEXT: sc $2, 0($4) ++; MIPS32O0-NEXT: beqz $2, $BB12_1 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: $BB12_3: # %entry ++; MIPS32O0-NEXT: sync ++; MIPS32O0-NEXT: srlv $1, $3, $9 ++; MIPS32O0-NEXT: sll $1, $1, 24 ++; MIPS32O0-NEXT: sra $1, $1, 24 ++; MIPS32O0-NEXT: # %bb.4: # %entry ++; MIPS32O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ++; MIPS32O0-NEXT: # %bb.5: # %entry ++; MIPS32O0-NEXT: lw $1, 4($sp) # 4-byte Folded Reload ++; MIPS32O0-NEXT: sll $1, $1, 24 ++; MIPS32O0-NEXT: sra $2, $1, 24 ++; MIPS32O0-NEXT: addiu $sp, $sp, 8 ++; MIPS32O0-NEXT: jr $ra ++; MIPS32O0-NEXT: nop ++; ++; MIPS32R2-LABEL: AtomicCmpSwap8: ++; MIPS32R2: # %bb.0: # %entry ++; MIPS32R2-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R2-NEXT: addu $1, $2, $25 ++; MIPS32R2-NEXT: lw $1, %got(y)($1) ++; MIPS32R2-NEXT: addiu $2, $zero, -4 ++; MIPS32R2-NEXT: and $3, $1, $2 ++; MIPS32R2-NEXT: andi $1, $1, 3 ++; MIPS32R2-NEXT: sll $1, $1, 3 ++; MIPS32R2-NEXT: ori $2, $zero, 255 ++; MIPS32R2-NEXT: sllv $6, $2, $1 ++; MIPS32R2-NEXT: nor $7, $zero, $6 ++; MIPS32R2-NEXT: andi $2, $4, 255 ++; MIPS32R2-NEXT: sllv $4, $2, $1 ++; MIPS32R2-NEXT: andi $2, $5, 255 ++; MIPS32R2-NEXT: sllv $5, $2, $1 ++; MIPS32R2-NEXT: $BB12_1: # %entry ++; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R2-NEXT: ll $8, 0($3) ++; MIPS32R2-NEXT: and $9, $8, $6 ++; MIPS32R2-NEXT: bne $9, $4, $BB12_3 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: # %bb.2: # %entry ++; MIPS32R2-NEXT: # in Loop: Header=BB12_1 Depth=1 ++; MIPS32R2-NEXT: and $8, $8, $7 ++; MIPS32R2-NEXT: or $8, $8, $5 ++; MIPS32R2-NEXT: sc $8, 0($3) ++; MIPS32R2-NEXT: beqz $8, $BB12_1 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: $BB12_3: # %entry ++; MIPS32R2-NEXT: sync ++; MIPS32R2-NEXT: srlv $2, $9, $1 ++; MIPS32R2-NEXT: seb $2, $2 ++; MIPS32R2-NEXT: # %bb.4: # %entry ++; MIPS32R2-NEXT: jr $ra ++; MIPS32R2-NEXT: nop ++; ++; MIPS32R6-LABEL: AtomicCmpSwap8: ++; MIPS32R6: # %bb.0: # %entry ++; MIPS32R6-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6-NEXT: addu $1, $2, $25 ++; MIPS32R6-NEXT: lw $1, %got(y)($1) ++; MIPS32R6-NEXT: addiu $2, $zero, -4 ++; MIPS32R6-NEXT: and $3, $1, $2 ++; MIPS32R6-NEXT: andi $1, $1, 3 ++; MIPS32R6-NEXT: sll $1, $1, 3 ++; MIPS32R6-NEXT: ori $2, $zero, 255 ++; MIPS32R6-NEXT: sllv $6, $2, $1 ++; MIPS32R6-NEXT: nor $7, $zero, $6 ++; MIPS32R6-NEXT: andi $2, $4, 255 ++; MIPS32R6-NEXT: sllv $4, $2, $1 ++; MIPS32R6-NEXT: andi $2, $5, 255 ++; MIPS32R6-NEXT: sllv $5, $2, $1 ++; MIPS32R6-NEXT: $BB12_1: # %entry ++; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6-NEXT: ll $8, 0($3) ++; MIPS32R6-NEXT: and $9, $8, $6 ++; MIPS32R6-NEXT: bnec $9, $4, $BB12_3 ++; MIPS32R6-NEXT: # %bb.2: # %entry ++; MIPS32R6-NEXT: # in Loop: Header=BB12_1 Depth=1 ++; MIPS32R6-NEXT: and $8, $8, $7 ++; MIPS32R6-NEXT: or $8, $8, $5 ++; MIPS32R6-NEXT: sc $8, 0($3) ++; MIPS32R6-NEXT: beqzc $8, $BB12_1 ++; MIPS32R6-NEXT: $BB12_3: # %entry ++; MIPS32R6-NEXT: sync ++; MIPS32R6-NEXT: srlv $2, $9, $1 ++; MIPS32R6-NEXT: seb $2, $2 ++; MIPS32R6-NEXT: # %bb.4: # %entry ++; MIPS32R6-NEXT: jrc $ra ++; ++; MIPS32R6O0-LABEL: AtomicCmpSwap8: ++; MIPS32R6O0: # %bb.0: # %entry ++; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $sp, $sp, -8 ++; MIPS32R6O0-NEXT: addu $3, $2, $25 ++; MIPS32R6O0-NEXT: move $1, $5 ++; MIPS32R6O0-NEXT: move $2, $4 ++; MIPS32R6O0-NEXT: # kill: def $a1 killed $at ++; MIPS32R6O0-NEXT: # kill: def $a0 killed $v0 ++; MIPS32R6O0-NEXT: lw $3, %got(y)($3) ++; MIPS32R6O0-NEXT: addiu $4, $zero, -4 ++; MIPS32R6O0-NEXT: and $4, $3, $4 ++; MIPS32R6O0-NEXT: andi $3, $3, 3 ++; MIPS32R6O0-NEXT: sll $9, $3, 3 ++; MIPS32R6O0-NEXT: ori $3, $zero, 255 ++; MIPS32R6O0-NEXT: sllv $5, $3, $9 ++; MIPS32R6O0-NEXT: nor $7, $zero, $5 ++; MIPS32R6O0-NEXT: andi $2, $2, 255 ++; MIPS32R6O0-NEXT: sllv $6, $2, $9 ++; MIPS32R6O0-NEXT: andi $1, $1, 255 ++; MIPS32R6O0-NEXT: sllv $8, $1, $9 ++; MIPS32R6O0-NEXT: $BB12_1: # %entry ++; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6O0-NEXT: ll $2, 0($4) ++; MIPS32R6O0-NEXT: and $3, $2, $5 ++; MIPS32R6O0-NEXT: bnec $3, $6, $BB12_3 ++; MIPS32R6O0-NEXT: # %bb.2: # %entry ++; MIPS32R6O0-NEXT: # in Loop: Header=BB12_1 Depth=1 ++; MIPS32R6O0-NEXT: and $2, $2, $7 ++; MIPS32R6O0-NEXT: or $2, $2, $8 ++; MIPS32R6O0-NEXT: sc $2, 0($4) ++; MIPS32R6O0-NEXT: beqzc $2, $BB12_1 ++; MIPS32R6O0-NEXT: $BB12_3: # %entry ++; MIPS32R6O0-NEXT: sync ++; MIPS32R6O0-NEXT: srlv $1, $3, $9 ++; MIPS32R6O0-NEXT: seb $1, $1 ++; MIPS32R6O0-NEXT: # %bb.4: # %entry ++; MIPS32R6O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ++; MIPS32R6O0-NEXT: # %bb.5: # %entry ++; MIPS32R6O0-NEXT: lw $2, 4($sp) # 4-byte Folded Reload ++; MIPS32R6O0-NEXT: addiu $sp, $sp, 8 ++; MIPS32R6O0-NEXT: jrc $ra ++; ++; MIPS4-LABEL: AtomicCmpSwap8: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicCmpSwap8))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicCmpSwap8))) ++; MIPS4-NEXT: ld $1, %got_disp(y)($1) ++; MIPS4-NEXT: daddiu $2, $zero, -4 ++; MIPS4-NEXT: and $3, $1, $2 ++; MIPS4-NEXT: andi $1, $1, 3 ++; MIPS4-NEXT: sll $1, $1, 3 ++; MIPS4-NEXT: ori $2, $zero, 255 ++; MIPS4-NEXT: sllv $6, $2, $1 ++; MIPS4-NEXT: nor $7, $zero, $6 ++; MIPS4-NEXT: andi $2, $4, 255 ++; MIPS4-NEXT: sllv $4, $2, $1 ++; MIPS4-NEXT: andi $2, $5, 255 ++; MIPS4-NEXT: sllv $5, $2, $1 ++; MIPS4-NEXT: .LBB12_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: ll $8, 0($3) ++; MIPS4-NEXT: and $9, $8, $6 ++; MIPS4-NEXT: bne $9, $4, .LBB12_3 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: # in Loop: Header=BB12_1 Depth=1 ++; MIPS4-NEXT: and $8, $8, $7 ++; MIPS4-NEXT: or $8, $8, $5 ++; MIPS4-NEXT: sc $8, 0($3) ++; MIPS4-NEXT: beqz $8, .LBB12_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: .LBB12_3: # %entry ++; MIPS4-NEXT: sync ++; MIPS4-NEXT: srlv $2, $9, $1 ++; MIPS4-NEXT: sll $2, $2, 24 ++; MIPS4-NEXT: sra $2, $2, 24 ++; MIPS4-NEXT: # %bb.4: # %entry ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: nop ++; ++; MIPS64-LABEL: AtomicCmpSwap8: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicCmpSwap8))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicCmpSwap8))) ++; MIPS64-NEXT: ld $1, %got_disp(y)($1) ++; MIPS64-NEXT: daddiu $2, $zero, -4 ++; MIPS64-NEXT: and $3, $1, $2 ++; MIPS64-NEXT: andi $1, $1, 3 ++; MIPS64-NEXT: sll $1, $1, 3 ++; MIPS64-NEXT: ori $2, $zero, 255 ++; MIPS64-NEXT: sllv $6, $2, $1 ++; MIPS64-NEXT: nor $7, $zero, $6 ++; MIPS64-NEXT: andi $2, $4, 255 ++; MIPS64-NEXT: sllv $4, $2, $1 ++; MIPS64-NEXT: andi $2, $5, 255 ++; MIPS64-NEXT: sllv $5, $2, $1 ++; MIPS64-NEXT: .LBB12_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: ll $8, 0($3) ++; MIPS64-NEXT: and $9, $8, $6 ++; MIPS64-NEXT: bne $9, $4, .LBB12_3 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: # in Loop: Header=BB12_1 Depth=1 ++; MIPS64-NEXT: and $8, $8, $7 ++; MIPS64-NEXT: or $8, $8, $5 ++; MIPS64-NEXT: sc $8, 0($3) ++; MIPS64-NEXT: beqz $8, .LBB12_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: .LBB12_3: # %entry ++; MIPS64-NEXT: sync ++; MIPS64-NEXT: srlv $2, $9, $1 ++; MIPS64-NEXT: sll $2, $2, 24 ++; MIPS64-NEXT: sra $2, $2, 24 ++; MIPS64-NEXT: # %bb.4: # %entry ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: nop ++; ++; MIPS64R2-LABEL: AtomicCmpSwap8: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicCmpSwap8))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicCmpSwap8))) ++; MIPS64R2-NEXT: ld $1, %got_disp(y)($1) ++; MIPS64R2-NEXT: daddiu $2, $zero, -4 ++; MIPS64R2-NEXT: and $3, $1, $2 ++; MIPS64R2-NEXT: andi $1, $1, 3 ++; MIPS64R2-NEXT: sll $1, $1, 3 ++; MIPS64R2-NEXT: ori $2, $zero, 255 ++; MIPS64R2-NEXT: sllv $6, $2, $1 ++; MIPS64R2-NEXT: nor $7, $zero, $6 ++; MIPS64R2-NEXT: andi $2, $4, 255 ++; MIPS64R2-NEXT: sllv $4, $2, $1 ++; MIPS64R2-NEXT: andi $2, $5, 255 ++; MIPS64R2-NEXT: sllv $5, $2, $1 ++; MIPS64R2-NEXT: .LBB12_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: ll $8, 0($3) ++; MIPS64R2-NEXT: and $9, $8, $6 ++; MIPS64R2-NEXT: bne $9, $4, .LBB12_3 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: # in Loop: Header=BB12_1 Depth=1 ++; MIPS64R2-NEXT: and $8, $8, $7 ++; MIPS64R2-NEXT: or $8, $8, $5 ++; MIPS64R2-NEXT: sc $8, 0($3) ++; MIPS64R2-NEXT: beqz $8, .LBB12_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: .LBB12_3: # %entry ++; MIPS64R2-NEXT: sync ++; MIPS64R2-NEXT: srlv $2, $9, $1 ++; MIPS64R2-NEXT: seb $2, $2 ++; MIPS64R2-NEXT: # %bb.4: # %entry ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: nop ++; ++; MIPS64R6-LABEL: AtomicCmpSwap8: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicCmpSwap8))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicCmpSwap8))) ++; MIPS64R6-NEXT: ld $1, %got_disp(y)($1) ++; MIPS64R6-NEXT: daddiu $2, $zero, -4 ++; MIPS64R6-NEXT: and $3, $1, $2 ++; MIPS64R6-NEXT: andi $1, $1, 3 ++; MIPS64R6-NEXT: sll $1, $1, 3 ++; MIPS64R6-NEXT: ori $2, $zero, 255 ++; MIPS64R6-NEXT: sllv $6, $2, $1 ++; MIPS64R6-NEXT: nor $7, $zero, $6 ++; MIPS64R6-NEXT: andi $2, $4, 255 ++; MIPS64R6-NEXT: sllv $4, $2, $1 ++; MIPS64R6-NEXT: andi $2, $5, 255 ++; MIPS64R6-NEXT: sllv $5, $2, $1 ++; MIPS64R6-NEXT: .LBB12_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: ll $8, 0($3) ++; MIPS64R6-NEXT: and $9, $8, $6 ++; MIPS64R6-NEXT: bnec $9, $4, .LBB12_3 ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: # in Loop: Header=BB12_1 Depth=1 ++; MIPS64R6-NEXT: and $8, $8, $7 ++; MIPS64R6-NEXT: or $8, $8, $5 ++; MIPS64R6-NEXT: sc $8, 0($3) ++; MIPS64R6-NEXT: beqzc $8, .LBB12_1 ++; MIPS64R6-NEXT: .LBB12_3: # %entry ++; MIPS64R6-NEXT: sync ++; MIPS64R6-NEXT: srlv $2, $9, $1 ++; MIPS64R6-NEXT: seb $2, $2 ++; MIPS64R6-NEXT: # %bb.4: # %entry ++; MIPS64R6-NEXT: jrc $ra ++; ++; MIPS64R6O0-LABEL: AtomicCmpSwap8: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, -16 ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicCmpSwap8))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $3, $1, %lo(%neg(%gp_rel(AtomicCmpSwap8))) ++; MIPS64R6O0-NEXT: move $1, $5 ++; MIPS64R6O0-NEXT: move $2, $4 ++; MIPS64R6O0-NEXT: ld $3, %got_disp(y)($3) ++; MIPS64R6O0-NEXT: daddiu $4, $zero, -4 ++; MIPS64R6O0-NEXT: and $4, $3, $4 ++; MIPS64R6O0-NEXT: andi $3, $3, 3 ++; MIPS64R6O0-NEXT: xori $3, $3, 3 ++; MIPS64R6O0-NEXT: sll $9, $3, 3 ++; MIPS64R6O0-NEXT: ori $3, $zero, 255 ++; MIPS64R6O0-NEXT: sllv $5, $3, $9 ++; MIPS64R6O0-NEXT: nor $7, $zero, $5 ++; MIPS64R6O0-NEXT: andi $2, $2, 255 ++; MIPS64R6O0-NEXT: sllv $6, $2, $9 ++; MIPS64R6O0-NEXT: andi $1, $1, 255 ++; MIPS64R6O0-NEXT: sllv $8, $1, $9 ++; MIPS64R6O0-NEXT: .LBB12_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: ll $2, 0($4) ++; MIPS64R6O0-NEXT: and $3, $2, $5 ++; MIPS64R6O0-NEXT: bnec $3, $6, .LBB12_3 ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: # in Loop: Header=BB12_1 Depth=1 ++; MIPS64R6O0-NEXT: and $2, $2, $7 ++; MIPS64R6O0-NEXT: or $2, $2, $8 ++; MIPS64R6O0-NEXT: sc $2, 0($4) ++; MIPS64R6O0-NEXT: beqzc $2, .LBB12_1 ++; MIPS64R6O0-NEXT: .LBB12_3: # %entry ++; MIPS64R6O0-NEXT: sync ++; MIPS64R6O0-NEXT: srlv $1, $3, $9 ++; MIPS64R6O0-NEXT: seb $1, $1 ++; MIPS64R6O0-NEXT: # %bb.4: # %entry ++; MIPS64R6O0-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ++; MIPS64R6O0-NEXT: # %bb.5: # %entry ++; MIPS64R6O0-NEXT: lw $2, 12($sp) # 4-byte Folded Reload ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, 16 ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; MM32-LABEL: AtomicCmpSwap8: ++; MM32: # %bb.0: # %entry ++; MM32-NEXT: lui $2, %hi(_gp_disp) ++; MM32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MM32-NEXT: addu $2, $2, $25 ++; MM32-NEXT: lw $1, %got(y)($2) ++; MM32-NEXT: addiu $2, $zero, -4 ++; MM32-NEXT: and $3, $1, $2 ++; MM32-NEXT: andi $1, $1, 3 ++; MM32-NEXT: sll $1, $1, 3 ++; MM32-NEXT: ori $2, $zero, 255 ++; MM32-NEXT: sllv $6, $2, $1 ++; MM32-NEXT: nor $7, $zero, $6 ++; MM32-NEXT: andi $2, $4, 255 ++; MM32-NEXT: sllv $4, $2, $1 ++; MM32-NEXT: andi $2, $5, 255 ++; MM32-NEXT: sllv $5, $2, $1 ++; MM32-NEXT: $BB12_1: # %entry ++; MM32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MM32-NEXT: ll $8, 0($3) ++; MM32-NEXT: and $9, $8, $6 ++; MM32-NEXT: bne $9, $4, $BB12_3 ++; MM32-NEXT: nop ++; MM32-NEXT: # %bb.2: # %entry ++; MM32-NEXT: # in Loop: Header=BB12_1 Depth=1 ++; MM32-NEXT: and $8, $8, $7 ++; MM32-NEXT: or $8, $8, $5 ++; MM32-NEXT: sc $8, 0($3) ++; MM32-NEXT: beqzc $8, $BB12_1 ++; MM32-NEXT: $BB12_3: # %entry ++; MM32-NEXT: sync 0 ++; MM32-NEXT: srlv $2, $9, $1 ++; MM32-NEXT: seb $2, $2 ++; MM32-NEXT: # %bb.4: # %entry ++; MM32-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicCmpSwap8: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $2, %hi(_gp_disp) ++; O1-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O1-NEXT: addu $1, $2, $25 ++; O1-NEXT: lw $1, %got(y)($1) ++; O1-NEXT: addiu $2, $zero, -4 ++; O1-NEXT: and $3, $1, $2 ++; O1-NEXT: andi $1, $1, 3 ++; O1-NEXT: sll $1, $1, 3 ++; O1-NEXT: ori $2, $zero, 255 ++; O1-NEXT: sllv $6, $2, $1 ++; O1-NEXT: nor $7, $zero, $6 ++; O1-NEXT: andi $2, $4, 255 ++; O1-NEXT: sllv $4, $2, $1 ++; O1-NEXT: andi $2, $5, 255 ++; O1-NEXT: sllv $5, $2, $1 ++; O1-NEXT: $BB12_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: ll $8, 0($3) ++; O1-NEXT: and $9, $8, $6 ++; O1-NEXT: bne $9, $4, $BB12_3 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: # in Loop: Header=BB12_1 Depth=1 ++; O1-NEXT: and $8, $8, $7 ++; O1-NEXT: or $8, $8, $5 ++; O1-NEXT: sc $8, 0($3) ++; O1-NEXT: beqz $8, $BB12_1 ++; O1-NEXT: nop ++; O1-NEXT: $BB12_3: # %entry ++; O1-NEXT: sync ++; O1-NEXT: srlv $2, $9, $1 ++; O1-NEXT: sll $2, $2, 24 ++; O1-NEXT: sra $2, $2, 24 ++; O1-NEXT: # %bb.4: # %entry ++; O1-NEXT: jr $ra ++; O1-NEXT: nop ++; ++; O2-LABEL: AtomicCmpSwap8: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $2, %hi(_gp_disp) ++; O2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O2-NEXT: addu $1, $2, $25 ++; O2-NEXT: lw $1, %got(y)($1) ++; O2-NEXT: addiu $2, $zero, -4 ++; O2-NEXT: and $3, $1, $2 ++; O2-NEXT: andi $1, $1, 3 ++; O2-NEXT: sll $1, $1, 3 ++; O2-NEXT: ori $2, $zero, 255 ++; O2-NEXT: sllv $6, $2, $1 ++; O2-NEXT: nor $7, $zero, $6 ++; O2-NEXT: andi $2, $4, 255 ++; O2-NEXT: sllv $4, $2, $1 ++; O2-NEXT: andi $2, $5, 255 ++; O2-NEXT: sllv $5, $2, $1 ++; O2-NEXT: $BB12_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: ll $8, 0($3) ++; O2-NEXT: and $9, $8, $6 ++; O2-NEXT: bne $9, $4, $BB12_3 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: # in Loop: Header=BB12_1 Depth=1 ++; O2-NEXT: and $8, $8, $7 ++; O2-NEXT: or $8, $8, $5 ++; O2-NEXT: sc $8, 0($3) ++; O2-NEXT: beqz $8, $BB12_1 ++; O2-NEXT: nop ++; O2-NEXT: $BB12_3: # %entry ++; O2-NEXT: sync ++; O2-NEXT: srlv $2, $9, $1 ++; O2-NEXT: sll $2, $2, 24 ++; O2-NEXT: sra $2, $2, 24 ++; O2-NEXT: # %bb.4: # %entry ++; O2-NEXT: jr $ra ++; O2-NEXT: nop ++; ++; O3-LABEL: AtomicCmpSwap8: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $2, %hi(_gp_disp) ++; O3-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O3-NEXT: addu $1, $2, $25 ++; O3-NEXT: addiu $2, $zero, -4 ++; O3-NEXT: lw $1, %got(y)($1) ++; O3-NEXT: and $3, $1, $2 ++; O3-NEXT: andi $1, $1, 3 ++; O3-NEXT: ori $2, $zero, 255 ++; O3-NEXT: sll $1, $1, 3 ++; O3-NEXT: sllv $6, $2, $1 ++; O3-NEXT: andi $2, $4, 255 ++; O3-NEXT: sllv $4, $2, $1 ++; O3-NEXT: andi $2, $5, 255 ++; O3-NEXT: nor $7, $zero, $6 ++; O3-NEXT: sllv $5, $2, $1 ++; O3-NEXT: $BB12_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: ll $8, 0($3) ++; O3-NEXT: and $9, $8, $6 ++; O3-NEXT: bne $9, $4, $BB12_3 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: # in Loop: Header=BB12_1 Depth=1 ++; O3-NEXT: and $8, $8, $7 ++; O3-NEXT: or $8, $8, $5 ++; O3-NEXT: sc $8, 0($3) ++; O3-NEXT: beqz $8, $BB12_1 ++; O3-NEXT: nop ++; O3-NEXT: $BB12_3: # %entry ++; O3-NEXT: sync ++; O3-NEXT: srlv $2, $9, $1 ++; O3-NEXT: sll $2, $2, 24 ++; O3-NEXT: sra $2, $2, 24 ++; O3-NEXT: # %bb.4: # %entry ++; O3-NEXT: jr $ra ++; O3-NEXT: nop ++; ++; MIPS32EB-LABEL: AtomicCmpSwap8: ++; MIPS32EB: # %bb.0: # %entry ++; MIPS32EB-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32EB-NEXT: addu $1, $2, $25 ++; MIPS32EB-NEXT: lw $1, %got(y)($1) ++; MIPS32EB-NEXT: addiu $2, $zero, -4 ++; MIPS32EB-NEXT: and $3, $1, $2 ++; MIPS32EB-NEXT: andi $1, $1, 3 ++; MIPS32EB-NEXT: xori $1, $1, 3 ++; MIPS32EB-NEXT: sll $1, $1, 3 ++; MIPS32EB-NEXT: ori $2, $zero, 255 ++; MIPS32EB-NEXT: sllv $6, $2, $1 ++; MIPS32EB-NEXT: nor $7, $zero, $6 ++; MIPS32EB-NEXT: andi $2, $4, 255 ++; MIPS32EB-NEXT: sllv $4, $2, $1 ++; MIPS32EB-NEXT: andi $2, $5, 255 ++; MIPS32EB-NEXT: sllv $5, $2, $1 ++; MIPS32EB-NEXT: $BB12_1: # %entry ++; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32EB-NEXT: ll $8, 0($3) ++; MIPS32EB-NEXT: and $9, $8, $6 ++; MIPS32EB-NEXT: bne $9, $4, $BB12_3 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: # %bb.2: # %entry ++; MIPS32EB-NEXT: # in Loop: Header=BB12_1 Depth=1 ++; MIPS32EB-NEXT: and $8, $8, $7 ++; MIPS32EB-NEXT: or $8, $8, $5 ++; MIPS32EB-NEXT: sc $8, 0($3) ++; MIPS32EB-NEXT: beqz $8, $BB12_1 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: $BB12_3: # %entry ++; MIPS32EB-NEXT: sync ++; MIPS32EB-NEXT: srlv $2, $9, $1 ++; MIPS32EB-NEXT: sll $2, $2, 24 ++; MIPS32EB-NEXT: sra $2, $2, 24 ++; MIPS32EB-NEXT: # %bb.4: # %entry ++; MIPS32EB-NEXT: jr $ra ++; MIPS32EB-NEXT: nop ++entry: ++ %pair0 = cmpxchg ptr @y, i8 %oldval, i8 %newval monotonic monotonic ++ %0 = extractvalue { i8, i1 } %pair0, 0 ++ ret i8 %0 ++} ++ ++define i1 @AtomicCmpSwapRes8(ptr %ptr, i8 signext %oldval, i8 signext %newval) nounwind { ++; MIPS32-LABEL: AtomicCmpSwapRes8: ++; MIPS32: # %bb.0: # %entry ++; MIPS32-NEXT: addiu $1, $zero, -4 ++; MIPS32-NEXT: and $2, $4, $1 ++; MIPS32-NEXT: andi $1, $4, 3 ++; MIPS32-NEXT: sll $3, $1, 3 ++; MIPS32-NEXT: ori $1, $zero, 255 ++; MIPS32-NEXT: sllv $4, $1, $3 ++; MIPS32-NEXT: nor $7, $zero, $4 ++; MIPS32-NEXT: andi $1, $5, 255 ++; MIPS32-NEXT: sllv $8, $1, $3 ++; MIPS32-NEXT: andi $1, $6, 255 ++; MIPS32-NEXT: sllv $6, $1, $3 ++; MIPS32-NEXT: $BB13_1: # %entry ++; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32-NEXT: ll $9, 0($2) ++; MIPS32-NEXT: and $10, $9, $4 ++; MIPS32-NEXT: bne $10, $8, $BB13_3 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: # %bb.2: # %entry ++; MIPS32-NEXT: # in Loop: Header=BB13_1 Depth=1 ++; MIPS32-NEXT: and $9, $9, $7 ++; MIPS32-NEXT: or $9, $9, $6 ++; MIPS32-NEXT: sc $9, 0($2) ++; MIPS32-NEXT: beqz $9, $BB13_1 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: $BB13_3: # %entry ++; MIPS32-NEXT: sync ++; MIPS32-NEXT: srlv $1, $10, $3 ++; MIPS32-NEXT: sll $1, $1, 24 ++; MIPS32-NEXT: sra $1, $1, 24 ++; MIPS32-NEXT: # %bb.4: # %entry ++; MIPS32-NEXT: xor $1, $1, $5 ++; MIPS32-NEXT: jr $ra ++; MIPS32-NEXT: sltiu $2, $1, 1 ++; ++; MIPS32O0-LABEL: AtomicCmpSwapRes8: ++; MIPS32O0: # %bb.0: # %entry ++; MIPS32O0-NEXT: addiu $sp, $sp, -8 ++; MIPS32O0-NEXT: move $1, $6 ++; MIPS32O0-NEXT: move $2, $5 ++; MIPS32O0-NEXT: move $3, $4 ++; MIPS32O0-NEXT: sw $2, 0($sp) # 4-byte Folded Spill ++; MIPS32O0-NEXT: addiu $4, $zero, -4 ++; MIPS32O0-NEXT: and $4, $3, $4 ++; MIPS32O0-NEXT: andi $3, $3, 3 ++; MIPS32O0-NEXT: sll $9, $3, 3 ++; MIPS32O0-NEXT: ori $3, $zero, 255 ++; MIPS32O0-NEXT: sllv $5, $3, $9 ++; MIPS32O0-NEXT: nor $7, $zero, $5 ++; MIPS32O0-NEXT: andi $2, $2, 255 ++; MIPS32O0-NEXT: sllv $6, $2, $9 ++; MIPS32O0-NEXT: andi $1, $1, 255 ++; MIPS32O0-NEXT: sllv $8, $1, $9 ++; MIPS32O0-NEXT: $BB13_1: # %entry ++; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32O0-NEXT: ll $2, 0($4) ++; MIPS32O0-NEXT: and $3, $2, $5 ++; MIPS32O0-NEXT: bne $3, $6, $BB13_3 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: # %bb.2: # %entry ++; MIPS32O0-NEXT: # in Loop: Header=BB13_1 Depth=1 ++; MIPS32O0-NEXT: and $2, $2, $7 ++; MIPS32O0-NEXT: or $2, $2, $8 ++; MIPS32O0-NEXT: sc $2, 0($4) ++; MIPS32O0-NEXT: beqz $2, $BB13_1 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: $BB13_3: # %entry ++; MIPS32O0-NEXT: sync ++; MIPS32O0-NEXT: srlv $1, $3, $9 ++; MIPS32O0-NEXT: sll $1, $1, 24 ++; MIPS32O0-NEXT: sra $1, $1, 24 ++; MIPS32O0-NEXT: # %bb.4: # %entry ++; MIPS32O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ++; MIPS32O0-NEXT: # %bb.5: # %entry ++; MIPS32O0-NEXT: lw $1, 4($sp) # 4-byte Folded Reload ++; MIPS32O0-NEXT: lw $2, 0($sp) # 4-byte Folded Reload ++; MIPS32O0-NEXT: sll $2, $2, 24 ++; MIPS32O0-NEXT: sra $2, $2, 24 ++; MIPS32O0-NEXT: xor $1, $1, $2 ++; MIPS32O0-NEXT: sltiu $2, $1, 1 ++; MIPS32O0-NEXT: addiu $sp, $sp, 8 ++; MIPS32O0-NEXT: jr $ra ++; MIPS32O0-NEXT: nop ++; ++; MIPS32R2-LABEL: AtomicCmpSwapRes8: ++; MIPS32R2: # %bb.0: # %entry ++; MIPS32R2-NEXT: addiu $1, $zero, -4 ++; MIPS32R2-NEXT: and $2, $4, $1 ++; MIPS32R2-NEXT: andi $1, $4, 3 ++; MIPS32R2-NEXT: sll $3, $1, 3 ++; MIPS32R2-NEXT: ori $1, $zero, 255 ++; MIPS32R2-NEXT: sllv $4, $1, $3 ++; MIPS32R2-NEXT: nor $7, $zero, $4 ++; MIPS32R2-NEXT: andi $1, $5, 255 ++; MIPS32R2-NEXT: sllv $8, $1, $3 ++; MIPS32R2-NEXT: andi $1, $6, 255 ++; MIPS32R2-NEXT: sllv $6, $1, $3 ++; MIPS32R2-NEXT: $BB13_1: # %entry ++; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R2-NEXT: ll $9, 0($2) ++; MIPS32R2-NEXT: and $10, $9, $4 ++; MIPS32R2-NEXT: bne $10, $8, $BB13_3 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: # %bb.2: # %entry ++; MIPS32R2-NEXT: # in Loop: Header=BB13_1 Depth=1 ++; MIPS32R2-NEXT: and $9, $9, $7 ++; MIPS32R2-NEXT: or $9, $9, $6 ++; MIPS32R2-NEXT: sc $9, 0($2) ++; MIPS32R2-NEXT: beqz $9, $BB13_1 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: $BB13_3: # %entry ++; MIPS32R2-NEXT: sync ++; MIPS32R2-NEXT: srlv $1, $10, $3 ++; MIPS32R2-NEXT: seb $1, $1 ++; MIPS32R2-NEXT: # %bb.4: # %entry ++; MIPS32R2-NEXT: xor $1, $1, $5 ++; MIPS32R2-NEXT: jr $ra ++; MIPS32R2-NEXT: sltiu $2, $1, 1 ++; ++; MIPS32R6-LABEL: AtomicCmpSwapRes8: ++; MIPS32R6: # %bb.0: # %entry ++; MIPS32R6-NEXT: addiu $1, $zero, -4 ++; MIPS32R6-NEXT: and $2, $4, $1 ++; MIPS32R6-NEXT: andi $1, $4, 3 ++; MIPS32R6-NEXT: sll $3, $1, 3 ++; MIPS32R6-NEXT: ori $1, $zero, 255 ++; MIPS32R6-NEXT: sllv $4, $1, $3 ++; MIPS32R6-NEXT: nor $7, $zero, $4 ++; MIPS32R6-NEXT: andi $1, $5, 255 ++; MIPS32R6-NEXT: sllv $8, $1, $3 ++; MIPS32R6-NEXT: andi $1, $6, 255 ++; MIPS32R6-NEXT: sllv $6, $1, $3 ++; MIPS32R6-NEXT: $BB13_1: # %entry ++; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6-NEXT: ll $9, 0($2) ++; MIPS32R6-NEXT: and $10, $9, $4 ++; MIPS32R6-NEXT: bnec $10, $8, $BB13_3 ++; MIPS32R6-NEXT: # %bb.2: # %entry ++; MIPS32R6-NEXT: # in Loop: Header=BB13_1 Depth=1 ++; MIPS32R6-NEXT: and $9, $9, $7 ++; MIPS32R6-NEXT: or $9, $9, $6 ++; MIPS32R6-NEXT: sc $9, 0($2) ++; MIPS32R6-NEXT: beqzc $9, $BB13_1 ++; MIPS32R6-NEXT: $BB13_3: # %entry ++; MIPS32R6-NEXT: sync ++; MIPS32R6-NEXT: srlv $1, $10, $3 ++; MIPS32R6-NEXT: seb $1, $1 ++; MIPS32R6-NEXT: # %bb.4: # %entry ++; MIPS32R6-NEXT: xor $1, $1, $5 ++; MIPS32R6-NEXT: jr $ra ++; MIPS32R6-NEXT: sltiu $2, $1, 1 ++; ++; MIPS32R6O0-LABEL: AtomicCmpSwapRes8: ++; MIPS32R6O0: # %bb.0: # %entry ++; MIPS32R6O0-NEXT: addiu $sp, $sp, -8 ++; MIPS32R6O0-NEXT: move $1, $6 ++; MIPS32R6O0-NEXT: move $2, $5 ++; MIPS32R6O0-NEXT: sw $2, 0($sp) # 4-byte Folded Spill ++; MIPS32R6O0-NEXT: move $3, $4 ++; MIPS32R6O0-NEXT: # kill: def $a2 killed $at ++; MIPS32R6O0-NEXT: # kill: def $a1 killed $v0 ++; MIPS32R6O0-NEXT: addiu $4, $zero, -4 ++; MIPS32R6O0-NEXT: and $4, $3, $4 ++; MIPS32R6O0-NEXT: andi $3, $3, 3 ++; MIPS32R6O0-NEXT: sll $9, $3, 3 ++; MIPS32R6O0-NEXT: ori $3, $zero, 255 ++; MIPS32R6O0-NEXT: sllv $5, $3, $9 ++; MIPS32R6O0-NEXT: nor $7, $zero, $5 ++; MIPS32R6O0-NEXT: andi $2, $2, 255 ++; MIPS32R6O0-NEXT: sllv $6, $2, $9 ++; MIPS32R6O0-NEXT: andi $1, $1, 255 ++; MIPS32R6O0-NEXT: sllv $8, $1, $9 ++; MIPS32R6O0-NEXT: $BB13_1: # %entry ++; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6O0-NEXT: ll $2, 0($4) ++; MIPS32R6O0-NEXT: and $3, $2, $5 ++; MIPS32R6O0-NEXT: bnec $3, $6, $BB13_3 ++; MIPS32R6O0-NEXT: # %bb.2: # %entry ++; MIPS32R6O0-NEXT: # in Loop: Header=BB13_1 Depth=1 ++; MIPS32R6O0-NEXT: and $2, $2, $7 ++; MIPS32R6O0-NEXT: or $2, $2, $8 ++; MIPS32R6O0-NEXT: sc $2, 0($4) ++; MIPS32R6O0-NEXT: beqzc $2, $BB13_1 ++; MIPS32R6O0-NEXT: $BB13_3: # %entry ++; MIPS32R6O0-NEXT: sync ++; MIPS32R6O0-NEXT: srlv $1, $3, $9 ++; MIPS32R6O0-NEXT: seb $1, $1 ++; MIPS32R6O0-NEXT: # %bb.4: # %entry ++; MIPS32R6O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ++; MIPS32R6O0-NEXT: # %bb.5: # %entry ++; MIPS32R6O0-NEXT: lw $1, 4($sp) # 4-byte Folded Reload ++; MIPS32R6O0-NEXT: lw $2, 0($sp) # 4-byte Folded Reload ++; MIPS32R6O0-NEXT: xor $1, $1, $2 ++; MIPS32R6O0-NEXT: sltiu $2, $1, 1 ++; MIPS32R6O0-NEXT: addiu $sp, $sp, 8 ++; MIPS32R6O0-NEXT: jrc $ra ++; ++; MIPS4-LABEL: AtomicCmpSwapRes8: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: daddiu $1, $zero, -4 ++; MIPS4-NEXT: and $2, $4, $1 ++; MIPS4-NEXT: andi $1, $4, 3 ++; MIPS4-NEXT: sll $3, $1, 3 ++; MIPS4-NEXT: ori $1, $zero, 255 ++; MIPS4-NEXT: sllv $4, $1, $3 ++; MIPS4-NEXT: nor $7, $zero, $4 ++; MIPS4-NEXT: andi $1, $5, 255 ++; MIPS4-NEXT: sllv $8, $1, $3 ++; MIPS4-NEXT: andi $1, $6, 255 ++; MIPS4-NEXT: sllv $6, $1, $3 ++; MIPS4-NEXT: .LBB13_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: ll $9, 0($2) ++; MIPS4-NEXT: and $10, $9, $4 ++; MIPS4-NEXT: bne $10, $8, .LBB13_3 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: # in Loop: Header=BB13_1 Depth=1 ++; MIPS4-NEXT: and $9, $9, $7 ++; MIPS4-NEXT: or $9, $9, $6 ++; MIPS4-NEXT: sc $9, 0($2) ++; MIPS4-NEXT: beqz $9, .LBB13_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: .LBB13_3: # %entry ++; MIPS4-NEXT: sync ++; MIPS4-NEXT: srlv $1, $10, $3 ++; MIPS4-NEXT: sll $1, $1, 24 ++; MIPS4-NEXT: sra $1, $1, 24 ++; MIPS4-NEXT: # %bb.4: # %entry ++; MIPS4-NEXT: xor $1, $1, $5 ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: sltiu $2, $1, 1 ++; ++; MIPS64-LABEL: AtomicCmpSwapRes8: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: daddiu $1, $zero, -4 ++; MIPS64-NEXT: and $2, $4, $1 ++; MIPS64-NEXT: andi $1, $4, 3 ++; MIPS64-NEXT: sll $3, $1, 3 ++; MIPS64-NEXT: ori $1, $zero, 255 ++; MIPS64-NEXT: sllv $4, $1, $3 ++; MIPS64-NEXT: nor $7, $zero, $4 ++; MIPS64-NEXT: andi $1, $5, 255 ++; MIPS64-NEXT: sllv $8, $1, $3 ++; MIPS64-NEXT: andi $1, $6, 255 ++; MIPS64-NEXT: sllv $6, $1, $3 ++; MIPS64-NEXT: .LBB13_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: ll $9, 0($2) ++; MIPS64-NEXT: and $10, $9, $4 ++; MIPS64-NEXT: bne $10, $8, .LBB13_3 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: # in Loop: Header=BB13_1 Depth=1 ++; MIPS64-NEXT: and $9, $9, $7 ++; MIPS64-NEXT: or $9, $9, $6 ++; MIPS64-NEXT: sc $9, 0($2) ++; MIPS64-NEXT: beqz $9, .LBB13_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: .LBB13_3: # %entry ++; MIPS64-NEXT: sync ++; MIPS64-NEXT: srlv $1, $10, $3 ++; MIPS64-NEXT: sll $1, $1, 24 ++; MIPS64-NEXT: sra $1, $1, 24 ++; MIPS64-NEXT: # %bb.4: # %entry ++; MIPS64-NEXT: xor $1, $1, $5 ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: sltiu $2, $1, 1 ++; ++; MIPS64R2-LABEL: AtomicCmpSwapRes8: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: daddiu $1, $zero, -4 ++; MIPS64R2-NEXT: and $2, $4, $1 ++; MIPS64R2-NEXT: andi $1, $4, 3 ++; MIPS64R2-NEXT: sll $3, $1, 3 ++; MIPS64R2-NEXT: ori $1, $zero, 255 ++; MIPS64R2-NEXT: sllv $4, $1, $3 ++; MIPS64R2-NEXT: nor $7, $zero, $4 ++; MIPS64R2-NEXT: andi $1, $5, 255 ++; MIPS64R2-NEXT: sllv $8, $1, $3 ++; MIPS64R2-NEXT: andi $1, $6, 255 ++; MIPS64R2-NEXT: sllv $6, $1, $3 ++; MIPS64R2-NEXT: .LBB13_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: ll $9, 0($2) ++; MIPS64R2-NEXT: and $10, $9, $4 ++; MIPS64R2-NEXT: bne $10, $8, .LBB13_3 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: # in Loop: Header=BB13_1 Depth=1 ++; MIPS64R2-NEXT: and $9, $9, $7 ++; MIPS64R2-NEXT: or $9, $9, $6 ++; MIPS64R2-NEXT: sc $9, 0($2) ++; MIPS64R2-NEXT: beqz $9, .LBB13_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: .LBB13_3: # %entry ++; MIPS64R2-NEXT: sync ++; MIPS64R2-NEXT: srlv $1, $10, $3 ++; MIPS64R2-NEXT: seb $1, $1 ++; MIPS64R2-NEXT: # %bb.4: # %entry ++; MIPS64R2-NEXT: xor $1, $1, $5 ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: sltiu $2, $1, 1 ++; ++; MIPS64R6-LABEL: AtomicCmpSwapRes8: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: daddiu $1, $zero, -4 ++; MIPS64R6-NEXT: and $2, $4, $1 ++; MIPS64R6-NEXT: andi $1, $4, 3 ++; MIPS64R6-NEXT: sll $3, $1, 3 ++; MIPS64R6-NEXT: ori $1, $zero, 255 ++; MIPS64R6-NEXT: sllv $4, $1, $3 ++; MIPS64R6-NEXT: nor $7, $zero, $4 ++; MIPS64R6-NEXT: andi $1, $5, 255 ++; MIPS64R6-NEXT: sllv $8, $1, $3 ++; MIPS64R6-NEXT: andi $1, $6, 255 ++; MIPS64R6-NEXT: sllv $6, $1, $3 ++; MIPS64R6-NEXT: .LBB13_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: ll $9, 0($2) ++; MIPS64R6-NEXT: and $10, $9, $4 ++; MIPS64R6-NEXT: bnec $10, $8, .LBB13_3 ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: # in Loop: Header=BB13_1 Depth=1 ++; MIPS64R6-NEXT: and $9, $9, $7 ++; MIPS64R6-NEXT: or $9, $9, $6 ++; MIPS64R6-NEXT: sc $9, 0($2) ++; MIPS64R6-NEXT: beqzc $9, .LBB13_1 ++; MIPS64R6-NEXT: .LBB13_3: # %entry ++; MIPS64R6-NEXT: sync ++; MIPS64R6-NEXT: srlv $1, $10, $3 ++; MIPS64R6-NEXT: seb $1, $1 ++; MIPS64R6-NEXT: # %bb.4: # %entry ++; MIPS64R6-NEXT: xor $1, $1, $5 ++; MIPS64R6-NEXT: jr $ra ++; MIPS64R6-NEXT: sltiu $2, $1, 1 ++; ++; MIPS64R6O0-LABEL: AtomicCmpSwapRes8: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, -16 ++; MIPS64R6O0-NEXT: move $3, $4 ++; MIPS64R6O0-NEXT: move $1, $6 ++; MIPS64R6O0-NEXT: move $2, $5 ++; MIPS64R6O0-NEXT: sw $2, 8($sp) # 4-byte Folded Spill ++; MIPS64R6O0-NEXT: daddiu $4, $zero, -4 ++; MIPS64R6O0-NEXT: and $4, $3, $4 ++; MIPS64R6O0-NEXT: andi $3, $3, 3 ++; MIPS64R6O0-NEXT: xori $3, $3, 3 ++; MIPS64R6O0-NEXT: sll $9, $3, 3 ++; MIPS64R6O0-NEXT: ori $3, $zero, 255 ++; MIPS64R6O0-NEXT: sllv $5, $3, $9 ++; MIPS64R6O0-NEXT: nor $7, $zero, $5 ++; MIPS64R6O0-NEXT: andi $2, $2, 255 ++; MIPS64R6O0-NEXT: sllv $6, $2, $9 ++; MIPS64R6O0-NEXT: andi $1, $1, 255 ++; MIPS64R6O0-NEXT: sllv $8, $1, $9 ++; MIPS64R6O0-NEXT: .LBB13_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: ll $2, 0($4) ++; MIPS64R6O0-NEXT: and $3, $2, $5 ++; MIPS64R6O0-NEXT: bnec $3, $6, .LBB13_3 ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: # in Loop: Header=BB13_1 Depth=1 ++; MIPS64R6O0-NEXT: and $2, $2, $7 ++; MIPS64R6O0-NEXT: or $2, $2, $8 ++; MIPS64R6O0-NEXT: sc $2, 0($4) ++; MIPS64R6O0-NEXT: beqzc $2, .LBB13_1 ++; MIPS64R6O0-NEXT: .LBB13_3: # %entry ++; MIPS64R6O0-NEXT: sync ++; MIPS64R6O0-NEXT: srlv $1, $3, $9 ++; MIPS64R6O0-NEXT: seb $1, $1 ++; MIPS64R6O0-NEXT: # %bb.4: # %entry ++; MIPS64R6O0-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ++; MIPS64R6O0-NEXT: # %bb.5: # %entry ++; MIPS64R6O0-NEXT: lw $1, 12($sp) # 4-byte Folded Reload ++; MIPS64R6O0-NEXT: lw $2, 8($sp) # 4-byte Folded Reload ++; MIPS64R6O0-NEXT: xor $1, $1, $2 ++; MIPS64R6O0-NEXT: sltiu $2, $1, 1 ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, 16 ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; MM32-LABEL: AtomicCmpSwapRes8: ++; MM32: # %bb.0: # %entry ++; MM32-NEXT: addiu $1, $zero, -4 ++; MM32-NEXT: and $2, $4, $1 ++; MM32-NEXT: andi $1, $4, 3 ++; MM32-NEXT: sll $3, $1, 3 ++; MM32-NEXT: ori $1, $zero, 255 ++; MM32-NEXT: sllv $4, $1, $3 ++; MM32-NEXT: nor $7, $zero, $4 ++; MM32-NEXT: andi $1, $5, 255 ++; MM32-NEXT: sllv $8, $1, $3 ++; MM32-NEXT: andi $1, $6, 255 ++; MM32-NEXT: sllv $6, $1, $3 ++; MM32-NEXT: $BB13_1: # %entry ++; MM32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MM32-NEXT: ll $9, 0($2) ++; MM32-NEXT: and $10, $9, $4 ++; MM32-NEXT: bne $10, $8, $BB13_3 ++; MM32-NEXT: nop ++; MM32-NEXT: # %bb.2: # %entry ++; MM32-NEXT: # in Loop: Header=BB13_1 Depth=1 ++; MM32-NEXT: and $9, $9, $7 ++; MM32-NEXT: or $9, $9, $6 ++; MM32-NEXT: sc $9, 0($2) ++; MM32-NEXT: beqzc $9, $BB13_1 ++; MM32-NEXT: $BB13_3: # %entry ++; MM32-NEXT: sync 0 ++; MM32-NEXT: srlv $1, $10, $3 ++; MM32-NEXT: seb $1, $1 ++; MM32-NEXT: # %bb.4: # %entry ++; MM32-NEXT: xor $1, $1, $5 ++; MM32-NEXT: jr $ra ++; MM32-NEXT: sltiu $2, $1, 1 ++; ++; O1-LABEL: AtomicCmpSwapRes8: ++; O1: # %bb.0: # %entry ++; O1-NEXT: addiu $1, $zero, -4 ++; O1-NEXT: and $2, $4, $1 ++; O1-NEXT: andi $1, $4, 3 ++; O1-NEXT: sll $3, $1, 3 ++; O1-NEXT: ori $1, $zero, 255 ++; O1-NEXT: sllv $4, $1, $3 ++; O1-NEXT: nor $7, $zero, $4 ++; O1-NEXT: andi $1, $5, 255 ++; O1-NEXT: sllv $8, $1, $3 ++; O1-NEXT: andi $1, $6, 255 ++; O1-NEXT: sllv $6, $1, $3 ++; O1-NEXT: $BB13_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: ll $9, 0($2) ++; O1-NEXT: and $10, $9, $4 ++; O1-NEXT: bne $10, $8, $BB13_3 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: # in Loop: Header=BB13_1 Depth=1 ++; O1-NEXT: and $9, $9, $7 ++; O1-NEXT: or $9, $9, $6 ++; O1-NEXT: sc $9, 0($2) ++; O1-NEXT: beqz $9, $BB13_1 ++; O1-NEXT: nop ++; O1-NEXT: $BB13_3: # %entry ++; O1-NEXT: sync ++; O1-NEXT: srlv $1, $10, $3 ++; O1-NEXT: sll $1, $1, 24 ++; O1-NEXT: sra $1, $1, 24 ++; O1-NEXT: # %bb.4: # %entry ++; O1-NEXT: xor $1, $1, $5 ++; O1-NEXT: jr $ra ++; O1-NEXT: sltiu $2, $1, 1 ++; ++; O2-LABEL: AtomicCmpSwapRes8: ++; O2: # %bb.0: # %entry ++; O2-NEXT: addiu $1, $zero, -4 ++; O2-NEXT: and $2, $4, $1 ++; O2-NEXT: andi $1, $4, 3 ++; O2-NEXT: sll $3, $1, 3 ++; O2-NEXT: ori $1, $zero, 255 ++; O2-NEXT: sllv $4, $1, $3 ++; O2-NEXT: nor $7, $zero, $4 ++; O2-NEXT: andi $1, $5, 255 ++; O2-NEXT: sllv $8, $1, $3 ++; O2-NEXT: andi $1, $6, 255 ++; O2-NEXT: sllv $6, $1, $3 ++; O2-NEXT: $BB13_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: ll $9, 0($2) ++; O2-NEXT: and $10, $9, $4 ++; O2-NEXT: bne $10, $8, $BB13_3 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: # in Loop: Header=BB13_1 Depth=1 ++; O2-NEXT: and $9, $9, $7 ++; O2-NEXT: or $9, $9, $6 ++; O2-NEXT: sc $9, 0($2) ++; O2-NEXT: beqz $9, $BB13_1 ++; O2-NEXT: nop ++; O2-NEXT: $BB13_3: # %entry ++; O2-NEXT: sync ++; O2-NEXT: srlv $1, $10, $3 ++; O2-NEXT: sll $1, $1, 24 ++; O2-NEXT: sra $1, $1, 24 ++; O2-NEXT: # %bb.4: # %entry ++; O2-NEXT: xor $1, $1, $5 ++; O2-NEXT: jr $ra ++; O2-NEXT: sltiu $2, $1, 1 ++; ++; O3-LABEL: AtomicCmpSwapRes8: ++; O3: # %bb.0: # %entry ++; O3-NEXT: addiu $1, $zero, -4 ++; O3-NEXT: and $2, $4, $1 ++; O3-NEXT: andi $1, $4, 3 ++; O3-NEXT: sll $3, $1, 3 ++; O3-NEXT: ori $1, $zero, 255 ++; O3-NEXT: sllv $4, $1, $3 ++; O3-NEXT: andi $1, $5, 255 ++; O3-NEXT: sllv $8, $1, $3 ++; O3-NEXT: andi $1, $6, 255 ++; O3-NEXT: nor $7, $zero, $4 ++; O3-NEXT: sllv $6, $1, $3 ++; O3-NEXT: $BB13_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: ll $9, 0($2) ++; O3-NEXT: and $10, $9, $4 ++; O3-NEXT: bne $10, $8, $BB13_3 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: # in Loop: Header=BB13_1 Depth=1 ++; O3-NEXT: and $9, $9, $7 ++; O3-NEXT: or $9, $9, $6 ++; O3-NEXT: sc $9, 0($2) ++; O3-NEXT: beqz $9, $BB13_1 ++; O3-NEXT: nop ++; O3-NEXT: $BB13_3: # %entry ++; O3-NEXT: sync ++; O3-NEXT: srlv $1, $10, $3 ++; O3-NEXT: sll $1, $1, 24 ++; O3-NEXT: sra $1, $1, 24 ++; O3-NEXT: # %bb.4: # %entry ++; O3-NEXT: xor $1, $1, $5 ++; O3-NEXT: jr $ra ++; O3-NEXT: sltiu $2, $1, 1 ++; ++; MIPS32EB-LABEL: AtomicCmpSwapRes8: ++; MIPS32EB: # %bb.0: # %entry ++; MIPS32EB-NEXT: addiu $1, $zero, -4 ++; MIPS32EB-NEXT: and $2, $4, $1 ++; MIPS32EB-NEXT: andi $1, $4, 3 ++; MIPS32EB-NEXT: xori $1, $1, 3 ++; MIPS32EB-NEXT: sll $3, $1, 3 ++; MIPS32EB-NEXT: ori $1, $zero, 255 ++; MIPS32EB-NEXT: sllv $4, $1, $3 ++; MIPS32EB-NEXT: nor $7, $zero, $4 ++; MIPS32EB-NEXT: andi $1, $5, 255 ++; MIPS32EB-NEXT: sllv $8, $1, $3 ++; MIPS32EB-NEXT: andi $1, $6, 255 ++; MIPS32EB-NEXT: sllv $6, $1, $3 ++; MIPS32EB-NEXT: $BB13_1: # %entry ++; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32EB-NEXT: ll $9, 0($2) ++; MIPS32EB-NEXT: and $10, $9, $4 ++; MIPS32EB-NEXT: bne $10, $8, $BB13_3 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: # %bb.2: # %entry ++; MIPS32EB-NEXT: # in Loop: Header=BB13_1 Depth=1 ++; MIPS32EB-NEXT: and $9, $9, $7 ++; MIPS32EB-NEXT: or $9, $9, $6 ++; MIPS32EB-NEXT: sc $9, 0($2) ++; MIPS32EB-NEXT: beqz $9, $BB13_1 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: $BB13_3: # %entry ++; MIPS32EB-NEXT: sync ++; MIPS32EB-NEXT: srlv $1, $10, $3 ++; MIPS32EB-NEXT: sll $1, $1, 24 ++; MIPS32EB-NEXT: sra $1, $1, 24 ++; MIPS32EB-NEXT: # %bb.4: # %entry ++; MIPS32EB-NEXT: xor $1, $1, $5 ++; MIPS32EB-NEXT: jr $ra ++; MIPS32EB-NEXT: sltiu $2, $1, 1 ++entry: ++ %0 = cmpxchg ptr %ptr, i8 %oldval, i8 %newval monotonic monotonic ++ %1 = extractvalue { i8, i1 } %0, 1 ++ ret i1 %1 ++; FIXME: -march=mips produces a redundant sign extension here... ++; FIXME: ...Leading to this split check. ++ ++} ++ ++; Check one i16 so that we cover the seh sign extend ++@z = common global i16 0, align 1 ++ ++define signext i16 @AtomicLoadAdd16(i16 signext %incr) nounwind { ++; MIPS32-LABEL: AtomicLoadAdd16: ++; MIPS32: # %bb.0: # %entry ++; MIPS32-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32-NEXT: addu $1, $2, $25 ++; MIPS32-NEXT: lw $1, %got(z)($1) ++; MIPS32-NEXT: addiu $2, $zero, -4 ++; MIPS32-NEXT: and $3, $1, $2 ++; MIPS32-NEXT: andi $1, $1, 3 ++; MIPS32-NEXT: sll $1, $1, 3 ++; MIPS32-NEXT: ori $2, $zero, 65535 ++; MIPS32-NEXT: sllv $5, $2, $1 ++; MIPS32-NEXT: nor $6, $zero, $5 ++; MIPS32-NEXT: sllv $4, $4, $1 ++; MIPS32-NEXT: $BB14_1: # %entry ++; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32-NEXT: ll $7, 0($3) ++; MIPS32-NEXT: addu $8, $7, $4 ++; MIPS32-NEXT: and $8, $8, $5 ++; MIPS32-NEXT: and $9, $7, $6 ++; MIPS32-NEXT: or $9, $9, $8 ++; MIPS32-NEXT: sc $9, 0($3) ++; MIPS32-NEXT: beqz $9, $BB14_1 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: # %bb.2: # %entry ++; MIPS32-NEXT: and $2, $7, $5 ++; MIPS32-NEXT: srlv $2, $2, $1 ++; MIPS32-NEXT: sll $2, $2, 16 ++; MIPS32-NEXT: sra $2, $2, 16 ++; MIPS32-NEXT: # %bb.3: # %entry ++; MIPS32-NEXT: jr $ra ++; MIPS32-NEXT: nop ++; ++; MIPS32O0-LABEL: AtomicLoadAdd16: ++; MIPS32O0: # %bb.0: # %entry ++; MIPS32O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32O0-NEXT: addiu $sp, $sp, -8 ++; MIPS32O0-NEXT: addu $1, $2, $25 ++; MIPS32O0-NEXT: lw $1, %got(z)($1) ++; MIPS32O0-NEXT: addiu $2, $zero, -4 ++; MIPS32O0-NEXT: and $5, $1, $2 ++; MIPS32O0-NEXT: andi $1, $1, 3 ++; MIPS32O0-NEXT: sll $9, $1, 3 ++; MIPS32O0-NEXT: ori $1, $zero, 65535 ++; MIPS32O0-NEXT: sllv $7, $1, $9 ++; MIPS32O0-NEXT: nor $8, $zero, $7 ++; MIPS32O0-NEXT: sllv $6, $4, $9 ++; MIPS32O0-NEXT: $BB14_1: # %entry ++; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32O0-NEXT: ll $2, 0($5) ++; MIPS32O0-NEXT: addu $3, $2, $6 ++; MIPS32O0-NEXT: and $3, $3, $7 ++; MIPS32O0-NEXT: and $4, $2, $8 ++; MIPS32O0-NEXT: or $4, $4, $3 ++; MIPS32O0-NEXT: sc $4, 0($5) ++; MIPS32O0-NEXT: beqz $4, $BB14_1 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: # %bb.2: # %entry ++; MIPS32O0-NEXT: and $1, $2, $7 ++; MIPS32O0-NEXT: srlv $1, $1, $9 ++; MIPS32O0-NEXT: sll $1, $1, 16 ++; MIPS32O0-NEXT: sra $1, $1, 16 ++; MIPS32O0-NEXT: # %bb.3: # %entry ++; MIPS32O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ++; MIPS32O0-NEXT: # %bb.4: # %entry ++; MIPS32O0-NEXT: lw $1, 4($sp) # 4-byte Folded Reload ++; MIPS32O0-NEXT: sll $1, $1, 16 ++; MIPS32O0-NEXT: sra $2, $1, 16 ++; MIPS32O0-NEXT: addiu $sp, $sp, 8 ++; MIPS32O0-NEXT: jr $ra ++; MIPS32O0-NEXT: nop ++; ++; MIPS32R2-LABEL: AtomicLoadAdd16: ++; MIPS32R2: # %bb.0: # %entry ++; MIPS32R2-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R2-NEXT: addu $1, $2, $25 ++; MIPS32R2-NEXT: lw $1, %got(z)($1) ++; MIPS32R2-NEXT: addiu $2, $zero, -4 ++; MIPS32R2-NEXT: and $3, $1, $2 ++; MIPS32R2-NEXT: andi $1, $1, 3 ++; MIPS32R2-NEXT: sll $1, $1, 3 ++; MIPS32R2-NEXT: ori $2, $zero, 65535 ++; MIPS32R2-NEXT: sllv $5, $2, $1 ++; MIPS32R2-NEXT: nor $6, $zero, $5 ++; MIPS32R2-NEXT: sllv $4, $4, $1 ++; MIPS32R2-NEXT: $BB14_1: # %entry ++; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R2-NEXT: ll $7, 0($3) ++; MIPS32R2-NEXT: addu $8, $7, $4 ++; MIPS32R2-NEXT: and $8, $8, $5 ++; MIPS32R2-NEXT: and $9, $7, $6 ++; MIPS32R2-NEXT: or $9, $9, $8 ++; MIPS32R2-NEXT: sc $9, 0($3) ++; MIPS32R2-NEXT: beqz $9, $BB14_1 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: # %bb.2: # %entry ++; MIPS32R2-NEXT: and $2, $7, $5 ++; MIPS32R2-NEXT: srlv $2, $2, $1 ++; MIPS32R2-NEXT: seh $2, $2 ++; MIPS32R2-NEXT: # %bb.3: # %entry ++; MIPS32R2-NEXT: jr $ra ++; MIPS32R2-NEXT: nop ++; ++; MIPS32R6-LABEL: AtomicLoadAdd16: ++; MIPS32R6: # %bb.0: # %entry ++; MIPS32R6-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6-NEXT: addu $1, $2, $25 ++; MIPS32R6-NEXT: lw $1, %got(z)($1) ++; MIPS32R6-NEXT: addiu $2, $zero, -4 ++; MIPS32R6-NEXT: and $3, $1, $2 ++; MIPS32R6-NEXT: andi $1, $1, 3 ++; MIPS32R6-NEXT: sll $1, $1, 3 ++; MIPS32R6-NEXT: ori $2, $zero, 65535 ++; MIPS32R6-NEXT: sllv $5, $2, $1 ++; MIPS32R6-NEXT: nor $6, $zero, $5 ++; MIPS32R6-NEXT: sllv $4, $4, $1 ++; MIPS32R6-NEXT: $BB14_1: # %entry ++; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6-NEXT: ll $7, 0($3) ++; MIPS32R6-NEXT: addu $8, $7, $4 ++; MIPS32R6-NEXT: and $8, $8, $5 ++; MIPS32R6-NEXT: and $9, $7, $6 ++; MIPS32R6-NEXT: or $9, $9, $8 ++; MIPS32R6-NEXT: sc $9, 0($3) ++; MIPS32R6-NEXT: beqzc $9, $BB14_1 ++; MIPS32R6-NEXT: # %bb.2: # %entry ++; MIPS32R6-NEXT: and $2, $7, $5 ++; MIPS32R6-NEXT: srlv $2, $2, $1 ++; MIPS32R6-NEXT: seh $2, $2 ++; MIPS32R6-NEXT: # %bb.3: # %entry ++; MIPS32R6-NEXT: jrc $ra ++; ++; MIPS32R6O0-LABEL: AtomicLoadAdd16: ++; MIPS32R6O0: # %bb.0: # %entry ++; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $sp, $sp, -8 ++; MIPS32R6O0-NEXT: addu $1, $2, $25 ++; MIPS32R6O0-NEXT: # kill: def $v0 killed $a0 ++; MIPS32R6O0-NEXT: lw $1, %got(z)($1) ++; MIPS32R6O0-NEXT: addiu $2, $zero, -4 ++; MIPS32R6O0-NEXT: and $5, $1, $2 ++; MIPS32R6O0-NEXT: andi $1, $1, 3 ++; MIPS32R6O0-NEXT: sll $9, $1, 3 ++; MIPS32R6O0-NEXT: ori $1, $zero, 65535 ++; MIPS32R6O0-NEXT: sllv $7, $1, $9 ++; MIPS32R6O0-NEXT: nor $8, $zero, $7 ++; MIPS32R6O0-NEXT: sllv $6, $4, $9 ++; MIPS32R6O0-NEXT: $BB14_1: # %entry ++; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6O0-NEXT: ll $2, 0($5) ++; MIPS32R6O0-NEXT: addu $3, $2, $6 ++; MIPS32R6O0-NEXT: and $3, $3, $7 ++; MIPS32R6O0-NEXT: and $4, $2, $8 ++; MIPS32R6O0-NEXT: or $4, $4, $3 ++; MIPS32R6O0-NEXT: sc $4, 0($5) ++; MIPS32R6O0-NEXT: beqzc $4, $BB14_1 ++; MIPS32R6O0-NEXT: # %bb.2: # %entry ++; MIPS32R6O0-NEXT: and $1, $2, $7 ++; MIPS32R6O0-NEXT: srlv $1, $1, $9 ++; MIPS32R6O0-NEXT: seh $1, $1 ++; MIPS32R6O0-NEXT: # %bb.3: # %entry ++; MIPS32R6O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ++; MIPS32R6O0-NEXT: # %bb.4: # %entry ++; MIPS32R6O0-NEXT: lw $2, 4($sp) # 4-byte Folded Reload ++; MIPS32R6O0-NEXT: addiu $sp, $sp, 8 ++; MIPS32R6O0-NEXT: jrc $ra ++; ++; MIPS4-LABEL: AtomicLoadAdd16: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd16))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd16))) ++; MIPS4-NEXT: ld $1, %got_disp(z)($1) ++; MIPS4-NEXT: daddiu $2, $zero, -4 ++; MIPS4-NEXT: and $3, $1, $2 ++; MIPS4-NEXT: andi $1, $1, 3 ++; MIPS4-NEXT: sll $1, $1, 3 ++; MIPS4-NEXT: ori $2, $zero, 65535 ++; MIPS4-NEXT: sllv $5, $2, $1 ++; MIPS4-NEXT: nor $6, $zero, $5 ++; MIPS4-NEXT: sllv $4, $4, $1 ++; MIPS4-NEXT: .LBB14_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: ll $7, 0($3) ++; MIPS4-NEXT: addu $8, $7, $4 ++; MIPS4-NEXT: and $8, $8, $5 ++; MIPS4-NEXT: and $9, $7, $6 ++; MIPS4-NEXT: or $9, $9, $8 ++; MIPS4-NEXT: sc $9, 0($3) ++; MIPS4-NEXT: beqz $9, .LBB14_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: and $2, $7, $5 ++; MIPS4-NEXT: srlv $2, $2, $1 ++; MIPS4-NEXT: sll $2, $2, 16 ++; MIPS4-NEXT: sra $2, $2, 16 ++; MIPS4-NEXT: # %bb.3: # %entry ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: nop ++; ++; MIPS64-LABEL: AtomicLoadAdd16: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd16))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd16))) ++; MIPS64-NEXT: ld $1, %got_disp(z)($1) ++; MIPS64-NEXT: daddiu $2, $zero, -4 ++; MIPS64-NEXT: and $3, $1, $2 ++; MIPS64-NEXT: andi $1, $1, 3 ++; MIPS64-NEXT: sll $1, $1, 3 ++; MIPS64-NEXT: ori $2, $zero, 65535 ++; MIPS64-NEXT: sllv $5, $2, $1 ++; MIPS64-NEXT: nor $6, $zero, $5 ++; MIPS64-NEXT: sllv $4, $4, $1 ++; MIPS64-NEXT: .LBB14_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: ll $7, 0($3) ++; MIPS64-NEXT: addu $8, $7, $4 ++; MIPS64-NEXT: and $8, $8, $5 ++; MIPS64-NEXT: and $9, $7, $6 ++; MIPS64-NEXT: or $9, $9, $8 ++; MIPS64-NEXT: sc $9, 0($3) ++; MIPS64-NEXT: beqz $9, .LBB14_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: and $2, $7, $5 ++; MIPS64-NEXT: srlv $2, $2, $1 ++; MIPS64-NEXT: sll $2, $2, 16 ++; MIPS64-NEXT: sra $2, $2, 16 ++; MIPS64-NEXT: # %bb.3: # %entry ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: nop ++; ++; MIPS64R2-LABEL: AtomicLoadAdd16: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd16))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd16))) ++; MIPS64R2-NEXT: ld $1, %got_disp(z)($1) ++; MIPS64R2-NEXT: daddiu $2, $zero, -4 ++; MIPS64R2-NEXT: and $3, $1, $2 ++; MIPS64R2-NEXT: andi $1, $1, 3 ++; MIPS64R2-NEXT: sll $1, $1, 3 ++; MIPS64R2-NEXT: ori $2, $zero, 65535 ++; MIPS64R2-NEXT: sllv $5, $2, $1 ++; MIPS64R2-NEXT: nor $6, $zero, $5 ++; MIPS64R2-NEXT: sllv $4, $4, $1 ++; MIPS64R2-NEXT: .LBB14_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: ll $7, 0($3) ++; MIPS64R2-NEXT: addu $8, $7, $4 ++; MIPS64R2-NEXT: and $8, $8, $5 ++; MIPS64R2-NEXT: and $9, $7, $6 ++; MIPS64R2-NEXT: or $9, $9, $8 ++; MIPS64R2-NEXT: sc $9, 0($3) ++; MIPS64R2-NEXT: beqz $9, .LBB14_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: and $2, $7, $5 ++; MIPS64R2-NEXT: srlv $2, $2, $1 ++; MIPS64R2-NEXT: seh $2, $2 ++; MIPS64R2-NEXT: # %bb.3: # %entry ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: nop ++; ++; MIPS64R6-LABEL: AtomicLoadAdd16: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd16))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd16))) ++; MIPS64R6-NEXT: ld $1, %got_disp(z)($1) ++; MIPS64R6-NEXT: daddiu $2, $zero, -4 ++; MIPS64R6-NEXT: and $3, $1, $2 ++; MIPS64R6-NEXT: andi $1, $1, 3 ++; MIPS64R6-NEXT: sll $1, $1, 3 ++; MIPS64R6-NEXT: ori $2, $zero, 65535 ++; MIPS64R6-NEXT: sllv $5, $2, $1 ++; MIPS64R6-NEXT: nor $6, $zero, $5 ++; MIPS64R6-NEXT: sllv $4, $4, $1 ++; MIPS64R6-NEXT: .LBB14_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: ll $7, 0($3) ++; MIPS64R6-NEXT: addu $8, $7, $4 ++; MIPS64R6-NEXT: and $8, $8, $5 ++; MIPS64R6-NEXT: and $9, $7, $6 ++; MIPS64R6-NEXT: or $9, $9, $8 ++; MIPS64R6-NEXT: sc $9, 0($3) ++; MIPS64R6-NEXT: beqzc $9, .LBB14_1 ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: and $2, $7, $5 ++; MIPS64R6-NEXT: srlv $2, $2, $1 ++; MIPS64R6-NEXT: seh $2, $2 ++; MIPS64R6-NEXT: # %bb.3: # %entry ++; MIPS64R6-NEXT: jrc $ra ++; ++; MIPS64R6O0-LABEL: AtomicLoadAdd16: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, -16 ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd16))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $2, $1, %lo(%neg(%gp_rel(AtomicLoadAdd16))) ++; MIPS64R6O0-NEXT: move $1, $4 ++; MIPS64R6O0-NEXT: ld $2, %got_disp(z)($2) ++; MIPS64R6O0-NEXT: daddiu $3, $zero, -4 ++; MIPS64R6O0-NEXT: and $5, $2, $3 ++; MIPS64R6O0-NEXT: andi $2, $2, 3 ++; MIPS64R6O0-NEXT: xori $2, $2, 2 ++; MIPS64R6O0-NEXT: sll $9, $2, 3 ++; MIPS64R6O0-NEXT: ori $2, $zero, 65535 ++; MIPS64R6O0-NEXT: sllv $7, $2, $9 ++; MIPS64R6O0-NEXT: nor $8, $zero, $7 ++; MIPS64R6O0-NEXT: sllv $6, $1, $9 ++; MIPS64R6O0-NEXT: .LBB14_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: ll $2, 0($5) ++; MIPS64R6O0-NEXT: addu $3, $2, $6 ++; MIPS64R6O0-NEXT: and $3, $3, $7 ++; MIPS64R6O0-NEXT: and $4, $2, $8 ++; MIPS64R6O0-NEXT: or $4, $4, $3 ++; MIPS64R6O0-NEXT: sc $4, 0($5) ++; MIPS64R6O0-NEXT: beqzc $4, .LBB14_1 ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: and $1, $2, $7 ++; MIPS64R6O0-NEXT: srlv $1, $1, $9 ++; MIPS64R6O0-NEXT: seh $1, $1 ++; MIPS64R6O0-NEXT: # %bb.3: # %entry ++; MIPS64R6O0-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ++; MIPS64R6O0-NEXT: # %bb.4: # %entry ++; MIPS64R6O0-NEXT: lw $2, 12($sp) # 4-byte Folded Reload ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, 16 ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; MM32-LABEL: AtomicLoadAdd16: ++; MM32: # %bb.0: # %entry ++; MM32-NEXT: lui $2, %hi(_gp_disp) ++; MM32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MM32-NEXT: addu $2, $2, $25 ++; MM32-NEXT: lw $1, %got(z)($2) ++; MM32-NEXT: addiu $2, $zero, -4 ++; MM32-NEXT: and $3, $1, $2 ++; MM32-NEXT: andi $1, $1, 3 ++; MM32-NEXT: sll $1, $1, 3 ++; MM32-NEXT: ori $2, $zero, 65535 ++; MM32-NEXT: sllv $5, $2, $1 ++; MM32-NEXT: nor $6, $zero, $5 ++; MM32-NEXT: sllv $4, $4, $1 ++; MM32-NEXT: $BB14_1: # %entry ++; MM32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MM32-NEXT: ll $7, 0($3) ++; MM32-NEXT: addu $8, $7, $4 ++; MM32-NEXT: and $8, $8, $5 ++; MM32-NEXT: and $9, $7, $6 ++; MM32-NEXT: or $9, $9, $8 ++; MM32-NEXT: sc $9, 0($3) ++; MM32-NEXT: beqzc $9, $BB14_1 ++; MM32-NEXT: # %bb.2: # %entry ++; MM32-NEXT: and $2, $7, $5 ++; MM32-NEXT: srlv $2, $2, $1 ++; MM32-NEXT: seh $2, $2 ++; MM32-NEXT: # %bb.3: # %entry ++; MM32-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicLoadAdd16: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $2, %hi(_gp_disp) ++; O1-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O1-NEXT: addu $1, $2, $25 ++; O1-NEXT: lw $1, %got(z)($1) ++; O1-NEXT: addiu $2, $zero, -4 ++; O1-NEXT: and $3, $1, $2 ++; O1-NEXT: andi $1, $1, 3 ++; O1-NEXT: sll $1, $1, 3 ++; O1-NEXT: ori $2, $zero, 65535 ++; O1-NEXT: sllv $5, $2, $1 ++; O1-NEXT: nor $6, $zero, $5 ++; O1-NEXT: sllv $4, $4, $1 ++; O1-NEXT: $BB14_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: ll $7, 0($3) ++; O1-NEXT: addu $8, $7, $4 ++; O1-NEXT: and $8, $8, $5 ++; O1-NEXT: and $9, $7, $6 ++; O1-NEXT: or $9, $9, $8 ++; O1-NEXT: sc $9, 0($3) ++; O1-NEXT: beqz $9, $BB14_1 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: and $2, $7, $5 ++; O1-NEXT: srlv $2, $2, $1 ++; O1-NEXT: sll $2, $2, 16 ++; O1-NEXT: sra $2, $2, 16 ++; O1-NEXT: # %bb.3: # %entry ++; O1-NEXT: jr $ra ++; O1-NEXT: nop ++; ++; O2-LABEL: AtomicLoadAdd16: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $2, %hi(_gp_disp) ++; O2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O2-NEXT: addu $1, $2, $25 ++; O2-NEXT: lw $1, %got(z)($1) ++; O2-NEXT: addiu $2, $zero, -4 ++; O2-NEXT: and $3, $1, $2 ++; O2-NEXT: andi $1, $1, 3 ++; O2-NEXT: sll $1, $1, 3 ++; O2-NEXT: ori $2, $zero, 65535 ++; O2-NEXT: sllv $5, $2, $1 ++; O2-NEXT: nor $6, $zero, $5 ++; O2-NEXT: sllv $4, $4, $1 ++; O2-NEXT: $BB14_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: ll $7, 0($3) ++; O2-NEXT: addu $8, $7, $4 ++; O2-NEXT: and $8, $8, $5 ++; O2-NEXT: and $9, $7, $6 ++; O2-NEXT: or $9, $9, $8 ++; O2-NEXT: sc $9, 0($3) ++; O2-NEXT: beqz $9, $BB14_1 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: and $2, $7, $5 ++; O2-NEXT: srlv $2, $2, $1 ++; O2-NEXT: sll $2, $2, 16 ++; O2-NEXT: sra $2, $2, 16 ++; O2-NEXT: # %bb.3: # %entry ++; O2-NEXT: jr $ra ++; O2-NEXT: nop ++; ++; O3-LABEL: AtomicLoadAdd16: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $2, %hi(_gp_disp) ++; O3-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O3-NEXT: addu $1, $2, $25 ++; O3-NEXT: addiu $2, $zero, -4 ++; O3-NEXT: lw $1, %got(z)($1) ++; O3-NEXT: and $3, $1, $2 ++; O3-NEXT: andi $1, $1, 3 ++; O3-NEXT: ori $2, $zero, 65535 ++; O3-NEXT: sll $1, $1, 3 ++; O3-NEXT: sllv $5, $2, $1 ++; O3-NEXT: sllv $4, $4, $1 ++; O3-NEXT: nor $6, $zero, $5 ++; O3-NEXT: $BB14_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: ll $7, 0($3) ++; O3-NEXT: addu $8, $7, $4 ++; O3-NEXT: and $8, $8, $5 ++; O3-NEXT: and $9, $7, $6 ++; O3-NEXT: or $9, $9, $8 ++; O3-NEXT: sc $9, 0($3) ++; O3-NEXT: beqz $9, $BB14_1 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: and $2, $7, $5 ++; O3-NEXT: srlv $2, $2, $1 ++; O3-NEXT: sll $2, $2, 16 ++; O3-NEXT: sra $2, $2, 16 ++; O3-NEXT: # %bb.3: # %entry ++; O3-NEXT: jr $ra ++; O3-NEXT: nop ++; ++; MIPS32EB-LABEL: AtomicLoadAdd16: ++; MIPS32EB: # %bb.0: # %entry ++; MIPS32EB-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32EB-NEXT: addu $1, $2, $25 ++; MIPS32EB-NEXT: lw $1, %got(z)($1) ++; MIPS32EB-NEXT: addiu $2, $zero, -4 ++; MIPS32EB-NEXT: and $3, $1, $2 ++; MIPS32EB-NEXT: andi $1, $1, 3 ++; MIPS32EB-NEXT: xori $1, $1, 2 ++; MIPS32EB-NEXT: sll $1, $1, 3 ++; MIPS32EB-NEXT: ori $2, $zero, 65535 ++; MIPS32EB-NEXT: sllv $5, $2, $1 ++; MIPS32EB-NEXT: nor $6, $zero, $5 ++; MIPS32EB-NEXT: sllv $4, $4, $1 ++; MIPS32EB-NEXT: $BB14_1: # %entry ++; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32EB-NEXT: ll $7, 0($3) ++; MIPS32EB-NEXT: addu $8, $7, $4 ++; MIPS32EB-NEXT: and $8, $8, $5 ++; MIPS32EB-NEXT: and $9, $7, $6 ++; MIPS32EB-NEXT: or $9, $9, $8 ++; MIPS32EB-NEXT: sc $9, 0($3) ++; MIPS32EB-NEXT: beqz $9, $BB14_1 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: # %bb.2: # %entry ++; MIPS32EB-NEXT: and $2, $7, $5 ++; MIPS32EB-NEXT: srlv $2, $2, $1 ++; MIPS32EB-NEXT: sll $2, $2, 16 ++; MIPS32EB-NEXT: sra $2, $2, 16 ++; MIPS32EB-NEXT: # %bb.3: # %entry ++; MIPS32EB-NEXT: jr $ra ++; MIPS32EB-NEXT: nop ++entry: ++ %0 = atomicrmw add ptr @z, i16 %incr monotonic ++ ret i16 %0 ++ ++} ++ ++; Test that the i16 return value from cmpxchg is recognised as signed, ++; so that setCC doesn't end up comparing an unsigned value to a signed ++; value. ++; The rest of the functions here are testing the atomic expansion, so ++; we just match the end of the function. ++define {i16, i1} @foo(ptr %addr, i16 %l, i16 %r, i16 %new) { ++; MIPS32-LABEL: foo: ++; MIPS32: # %bb.0: ++; MIPS32-NEXT: addu $1, $5, $6 ++; MIPS32-NEXT: sync ++; MIPS32-NEXT: addiu $2, $zero, -4 ++; MIPS32-NEXT: and $3, $4, $2 ++; MIPS32-NEXT: andi $2, $4, 3 ++; MIPS32-NEXT: sll $4, $2, 3 ++; MIPS32-NEXT: ori $2, $zero, 65535 ++; MIPS32-NEXT: sllv $5, $2, $4 ++; MIPS32-NEXT: nor $6, $zero, $5 ++; MIPS32-NEXT: andi $2, $1, 65535 ++; MIPS32-NEXT: sllv $8, $2, $4 ++; MIPS32-NEXT: andi $2, $7, 65535 ++; MIPS32-NEXT: sllv $7, $2, $4 ++; MIPS32-NEXT: $BB15_1: # =>This Inner Loop Header: Depth=1 ++; MIPS32-NEXT: ll $9, 0($3) ++; MIPS32-NEXT: and $10, $9, $5 ++; MIPS32-NEXT: bne $10, $8, $BB15_3 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1 ++; MIPS32-NEXT: and $9, $9, $6 ++; MIPS32-NEXT: or $9, $9, $7 ++; MIPS32-NEXT: sc $9, 0($3) ++; MIPS32-NEXT: beqz $9, $BB15_1 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: $BB15_3: ++; MIPS32-NEXT: sync ++; MIPS32-NEXT: srlv $2, $10, $4 ++; MIPS32-NEXT: sll $2, $2, 16 ++; MIPS32-NEXT: sra $2, $2, 16 ++; MIPS32-NEXT: # %bb.4: ++; MIPS32-NEXT: sll $1, $1, 16 ++; MIPS32-NEXT: sra $1, $1, 16 ++; MIPS32-NEXT: xor $1, $2, $1 ++; MIPS32-NEXT: sltiu $3, $1, 1 ++; MIPS32-NEXT: sync ++; MIPS32-NEXT: jr $ra ++; MIPS32-NEXT: nop ++; ++; MIPS32O0-LABEL: foo: ++; MIPS32O0: # %bb.0: ++; MIPS32O0-NEXT: addiu $sp, $sp, -8 ++; MIPS32O0-NEXT: .cfi_def_cfa_offset 8 ++; MIPS32O0-NEXT: move $1, $7 ++; MIPS32O0-NEXT: move $3, $4 ++; MIPS32O0-NEXT: addu $2, $5, $6 ++; MIPS32O0-NEXT: sw $2, 0($sp) # 4-byte Folded Spill ++; MIPS32O0-NEXT: sync ++; MIPS32O0-NEXT: addiu $4, $zero, -4 ++; MIPS32O0-NEXT: and $4, $3, $4 ++; MIPS32O0-NEXT: andi $3, $3, 3 ++; MIPS32O0-NEXT: sll $9, $3, 3 ++; MIPS32O0-NEXT: ori $3, $zero, 65535 ++; MIPS32O0-NEXT: sllv $5, $3, $9 ++; MIPS32O0-NEXT: nor $7, $zero, $5 ++; MIPS32O0-NEXT: andi $2, $2, 65535 ++; MIPS32O0-NEXT: sllv $6, $2, $9 ++; MIPS32O0-NEXT: andi $1, $1, 65535 ++; MIPS32O0-NEXT: sllv $8, $1, $9 ++; MIPS32O0-NEXT: $BB15_1: # =>This Inner Loop Header: Depth=1 ++; MIPS32O0-NEXT: ll $2, 0($4) ++; MIPS32O0-NEXT: and $3, $2, $5 ++; MIPS32O0-NEXT: bne $3, $6, $BB15_3 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1 ++; MIPS32O0-NEXT: and $2, $2, $7 ++; MIPS32O0-NEXT: or $2, $2, $8 ++; MIPS32O0-NEXT: sc $2, 0($4) ++; MIPS32O0-NEXT: beqz $2, $BB15_1 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: $BB15_3: ++; MIPS32O0-NEXT: sync ++; MIPS32O0-NEXT: srlv $1, $3, $9 ++; MIPS32O0-NEXT: sll $1, $1, 16 ++; MIPS32O0-NEXT: sra $1, $1, 16 ++; MIPS32O0-NEXT: # %bb.4: ++; MIPS32O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ++; MIPS32O0-NEXT: # %bb.5: ++; MIPS32O0-NEXT: lw $2, 4($sp) # 4-byte Folded Reload ++; MIPS32O0-NEXT: lw $1, 0($sp) # 4-byte Folded Reload ++; MIPS32O0-NEXT: sll $1, $1, 16 ++; MIPS32O0-NEXT: sra $1, $1, 16 ++; MIPS32O0-NEXT: xor $1, $2, $1 ++; MIPS32O0-NEXT: sltiu $3, $1, 1 ++; MIPS32O0-NEXT: sync ++; MIPS32O0-NEXT: addiu $sp, $sp, 8 ++; MIPS32O0-NEXT: jr $ra ++; MIPS32O0-NEXT: nop ++; ++; MIPS32R2-LABEL: foo: ++; MIPS32R2: # %bb.0: ++; MIPS32R2-NEXT: addu $1, $5, $6 ++; MIPS32R2-NEXT: sync ++; MIPS32R2-NEXT: addiu $2, $zero, -4 ++; MIPS32R2-NEXT: and $3, $4, $2 ++; MIPS32R2-NEXT: andi $2, $4, 3 ++; MIPS32R2-NEXT: sll $4, $2, 3 ++; MIPS32R2-NEXT: ori $2, $zero, 65535 ++; MIPS32R2-NEXT: sllv $5, $2, $4 ++; MIPS32R2-NEXT: nor $6, $zero, $5 ++; MIPS32R2-NEXT: andi $2, $1, 65535 ++; MIPS32R2-NEXT: sllv $8, $2, $4 ++; MIPS32R2-NEXT: andi $2, $7, 65535 ++; MIPS32R2-NEXT: sllv $7, $2, $4 ++; MIPS32R2-NEXT: $BB15_1: # =>This Inner Loop Header: Depth=1 ++; MIPS32R2-NEXT: ll $9, 0($3) ++; MIPS32R2-NEXT: and $10, $9, $5 ++; MIPS32R2-NEXT: bne $10, $8, $BB15_3 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1 ++; MIPS32R2-NEXT: and $9, $9, $6 ++; MIPS32R2-NEXT: or $9, $9, $7 ++; MIPS32R2-NEXT: sc $9, 0($3) ++; MIPS32R2-NEXT: beqz $9, $BB15_1 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: $BB15_3: ++; MIPS32R2-NEXT: sync ++; MIPS32R2-NEXT: srlv $2, $10, $4 ++; MIPS32R2-NEXT: seh $2, $2 ++; MIPS32R2-NEXT: # %bb.4: ++; MIPS32R2-NEXT: seh $1, $1 ++; MIPS32R2-NEXT: xor $1, $2, $1 ++; MIPS32R2-NEXT: sltiu $3, $1, 1 ++; MIPS32R2-NEXT: sync ++; MIPS32R2-NEXT: jr $ra ++; MIPS32R2-NEXT: nop ++; ++; MIPS32R6-LABEL: foo: ++; MIPS32R6: # %bb.0: ++; MIPS32R6-NEXT: addu $1, $5, $6 ++; MIPS32R6-NEXT: sync ++; MIPS32R6-NEXT: addiu $2, $zero, -4 ++; MIPS32R6-NEXT: and $3, $4, $2 ++; MIPS32R6-NEXT: andi $2, $4, 3 ++; MIPS32R6-NEXT: sll $4, $2, 3 ++; MIPS32R6-NEXT: ori $2, $zero, 65535 ++; MIPS32R6-NEXT: sllv $5, $2, $4 ++; MIPS32R6-NEXT: nor $6, $zero, $5 ++; MIPS32R6-NEXT: andi $2, $1, 65535 ++; MIPS32R6-NEXT: sllv $8, $2, $4 ++; MIPS32R6-NEXT: andi $2, $7, 65535 ++; MIPS32R6-NEXT: sllv $7, $2, $4 ++; MIPS32R6-NEXT: $BB15_1: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6-NEXT: ll $9, 0($3) ++; MIPS32R6-NEXT: and $10, $9, $5 ++; MIPS32R6-NEXT: bnec $10, $8, $BB15_3 ++; MIPS32R6-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1 ++; MIPS32R6-NEXT: and $9, $9, $6 ++; MIPS32R6-NEXT: or $9, $9, $7 ++; MIPS32R6-NEXT: sc $9, 0($3) ++; MIPS32R6-NEXT: beqzc $9, $BB15_1 ++; MIPS32R6-NEXT: $BB15_3: ++; MIPS32R6-NEXT: sync ++; MIPS32R6-NEXT: srlv $2, $10, $4 ++; MIPS32R6-NEXT: seh $2, $2 ++; MIPS32R6-NEXT: # %bb.4: ++; MIPS32R6-NEXT: seh $1, $1 ++; MIPS32R6-NEXT: xor $1, $2, $1 ++; MIPS32R6-NEXT: sltiu $3, $1, 1 ++; MIPS32R6-NEXT: sync ++; MIPS32R6-NEXT: jrc $ra ++; ++; MIPS32R6O0-LABEL: foo: ++; MIPS32R6O0: # %bb.0: ++; MIPS32R6O0-NEXT: addiu $sp, $sp, -8 ++; MIPS32R6O0-NEXT: .cfi_def_cfa_offset 8 ++; MIPS32R6O0-NEXT: move $1, $7 ++; MIPS32R6O0-NEXT: move $3, $4 ++; MIPS32R6O0-NEXT: # kill: def $a3 killed $at ++; MIPS32R6O0-NEXT: # kill: def $v0 killed $a2 ++; MIPS32R6O0-NEXT: # kill: def $v0 killed $a1 ++; MIPS32R6O0-NEXT: addu $2, $5, $6 ++; MIPS32R6O0-NEXT: sw $2, 0($sp) # 4-byte Folded Spill ++; MIPS32R6O0-NEXT: sync ++; MIPS32R6O0-NEXT: addiu $4, $zero, -4 ++; MIPS32R6O0-NEXT: and $4, $3, $4 ++; MIPS32R6O0-NEXT: andi $3, $3, 3 ++; MIPS32R6O0-NEXT: sll $9, $3, 3 ++; MIPS32R6O0-NEXT: ori $3, $zero, 65535 ++; MIPS32R6O0-NEXT: sllv $5, $3, $9 ++; MIPS32R6O0-NEXT: nor $7, $zero, $5 ++; MIPS32R6O0-NEXT: andi $2, $2, 65535 ++; MIPS32R6O0-NEXT: sllv $6, $2, $9 ++; MIPS32R6O0-NEXT: andi $1, $1, 65535 ++; MIPS32R6O0-NEXT: sllv $8, $1, $9 ++; MIPS32R6O0-NEXT: $BB15_1: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6O0-NEXT: ll $2, 0($4) ++; MIPS32R6O0-NEXT: and $3, $2, $5 ++; MIPS32R6O0-NEXT: bnec $3, $6, $BB15_3 ++; MIPS32R6O0-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1 ++; MIPS32R6O0-NEXT: and $2, $2, $7 ++; MIPS32R6O0-NEXT: or $2, $2, $8 ++; MIPS32R6O0-NEXT: sc $2, 0($4) ++; MIPS32R6O0-NEXT: beqzc $2, $BB15_1 ++; MIPS32R6O0-NEXT: $BB15_3: ++; MIPS32R6O0-NEXT: sync ++; MIPS32R6O0-NEXT: srlv $1, $3, $9 ++; MIPS32R6O0-NEXT: seh $1, $1 ++; MIPS32R6O0-NEXT: # %bb.4: ++; MIPS32R6O0-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ++; MIPS32R6O0-NEXT: # %bb.5: ++; MIPS32R6O0-NEXT: lw $2, 4($sp) # 4-byte Folded Reload ++; MIPS32R6O0-NEXT: lw $1, 0($sp) # 4-byte Folded Reload ++; MIPS32R6O0-NEXT: seh $1, $1 ++; MIPS32R6O0-NEXT: xor $1, $2, $1 ++; MIPS32R6O0-NEXT: sltiu $3, $1, 1 ++; MIPS32R6O0-NEXT: sync ++; MIPS32R6O0-NEXT: addiu $sp, $sp, 8 ++; MIPS32R6O0-NEXT: jrc $ra ++; ++; MIPS4-LABEL: foo: ++; MIPS4: # %bb.0: ++; MIPS4-NEXT: sll $1, $6, 0 ++; MIPS4-NEXT: sll $2, $5, 0 ++; MIPS4-NEXT: addu $1, $2, $1 ++; MIPS4-NEXT: sync ++; MIPS4-NEXT: sll $2, $7, 0 ++; MIPS4-NEXT: daddiu $3, $zero, -4 ++; MIPS4-NEXT: and $3, $4, $3 ++; MIPS4-NEXT: andi $4, $4, 3 ++; MIPS4-NEXT: sll $4, $4, 3 ++; MIPS4-NEXT: ori $5, $zero, 65535 ++; MIPS4-NEXT: sllv $5, $5, $4 ++; MIPS4-NEXT: nor $6, $zero, $5 ++; MIPS4-NEXT: andi $7, $1, 65535 ++; MIPS4-NEXT: sllv $7, $7, $4 ++; MIPS4-NEXT: andi $2, $2, 65535 ++; MIPS4-NEXT: sllv $8, $2, $4 ++; MIPS4-NEXT: .LBB15_1: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: ll $9, 0($3) ++; MIPS4-NEXT: and $10, $9, $5 ++; MIPS4-NEXT: bne $10, $7, .LBB15_3 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1 ++; MIPS4-NEXT: and $9, $9, $6 ++; MIPS4-NEXT: or $9, $9, $8 ++; MIPS4-NEXT: sc $9, 0($3) ++; MIPS4-NEXT: beqz $9, .LBB15_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: .LBB15_3: ++; MIPS4-NEXT: sync ++; MIPS4-NEXT: srlv $2, $10, $4 ++; MIPS4-NEXT: sll $2, $2, 16 ++; MIPS4-NEXT: sra $2, $2, 16 ++; MIPS4-NEXT: # %bb.4: ++; MIPS4-NEXT: sll $1, $1, 16 ++; MIPS4-NEXT: sra $1, $1, 16 ++; MIPS4-NEXT: xor $1, $2, $1 ++; MIPS4-NEXT: sltiu $3, $1, 1 ++; MIPS4-NEXT: sync ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: nop ++; ++; MIPS64-LABEL: foo: ++; MIPS64: # %bb.0: ++; MIPS64-NEXT: sll $1, $6, 0 ++; MIPS64-NEXT: sll $2, $5, 0 ++; MIPS64-NEXT: addu $1, $2, $1 ++; MIPS64-NEXT: sync ++; MIPS64-NEXT: sll $2, $7, 0 ++; MIPS64-NEXT: daddiu $3, $zero, -4 ++; MIPS64-NEXT: and $3, $4, $3 ++; MIPS64-NEXT: andi $4, $4, 3 ++; MIPS64-NEXT: sll $4, $4, 3 ++; MIPS64-NEXT: ori $5, $zero, 65535 ++; MIPS64-NEXT: sllv $5, $5, $4 ++; MIPS64-NEXT: nor $6, $zero, $5 ++; MIPS64-NEXT: andi $7, $1, 65535 ++; MIPS64-NEXT: sllv $7, $7, $4 ++; MIPS64-NEXT: andi $2, $2, 65535 ++; MIPS64-NEXT: sllv $8, $2, $4 ++; MIPS64-NEXT: .LBB15_1: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: ll $9, 0($3) ++; MIPS64-NEXT: and $10, $9, $5 ++; MIPS64-NEXT: bne $10, $7, .LBB15_3 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1 ++; MIPS64-NEXT: and $9, $9, $6 ++; MIPS64-NEXT: or $9, $9, $8 ++; MIPS64-NEXT: sc $9, 0($3) ++; MIPS64-NEXT: beqz $9, .LBB15_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: .LBB15_3: ++; MIPS64-NEXT: sync ++; MIPS64-NEXT: srlv $2, $10, $4 ++; MIPS64-NEXT: sll $2, $2, 16 ++; MIPS64-NEXT: sra $2, $2, 16 ++; MIPS64-NEXT: # %bb.4: ++; MIPS64-NEXT: sll $1, $1, 16 ++; MIPS64-NEXT: sra $1, $1, 16 ++; MIPS64-NEXT: xor $1, $2, $1 ++; MIPS64-NEXT: sltiu $3, $1, 1 ++; MIPS64-NEXT: sync ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: nop ++; ++; MIPS64R2-LABEL: foo: ++; MIPS64R2: # %bb.0: ++; MIPS64R2-NEXT: sll $1, $6, 0 ++; MIPS64R2-NEXT: sll $2, $5, 0 ++; MIPS64R2-NEXT: addu $1, $2, $1 ++; MIPS64R2-NEXT: sync ++; MIPS64R2-NEXT: sll $2, $7, 0 ++; MIPS64R2-NEXT: daddiu $3, $zero, -4 ++; MIPS64R2-NEXT: and $3, $4, $3 ++; MIPS64R2-NEXT: andi $4, $4, 3 ++; MIPS64R2-NEXT: sll $4, $4, 3 ++; MIPS64R2-NEXT: ori $5, $zero, 65535 ++; MIPS64R2-NEXT: sllv $5, $5, $4 ++; MIPS64R2-NEXT: nor $6, $zero, $5 ++; MIPS64R2-NEXT: andi $7, $1, 65535 ++; MIPS64R2-NEXT: sllv $7, $7, $4 ++; MIPS64R2-NEXT: andi $2, $2, 65535 ++; MIPS64R2-NEXT: sllv $8, $2, $4 ++; MIPS64R2-NEXT: .LBB15_1: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: ll $9, 0($3) ++; MIPS64R2-NEXT: and $10, $9, $5 ++; MIPS64R2-NEXT: bne $10, $7, .LBB15_3 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1 ++; MIPS64R2-NEXT: and $9, $9, $6 ++; MIPS64R2-NEXT: or $9, $9, $8 ++; MIPS64R2-NEXT: sc $9, 0($3) ++; MIPS64R2-NEXT: beqz $9, .LBB15_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: .LBB15_3: ++; MIPS64R2-NEXT: sync ++; MIPS64R2-NEXT: srlv $2, $10, $4 ++; MIPS64R2-NEXT: seh $2, $2 ++; MIPS64R2-NEXT: # %bb.4: ++; MIPS64R2-NEXT: seh $1, $1 ++; MIPS64R2-NEXT: xor $1, $2, $1 ++; MIPS64R2-NEXT: sltiu $3, $1, 1 ++; MIPS64R2-NEXT: sync ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: nop ++; ++; MIPS64R6-LABEL: foo: ++; MIPS64R6: # %bb.0: ++; MIPS64R6-NEXT: sll $1, $6, 0 ++; MIPS64R6-NEXT: sll $2, $5, 0 ++; MIPS64R6-NEXT: addu $1, $2, $1 ++; MIPS64R6-NEXT: sync ++; MIPS64R6-NEXT: sll $2, $7, 0 ++; MIPS64R6-NEXT: daddiu $3, $zero, -4 ++; MIPS64R6-NEXT: and $3, $4, $3 ++; MIPS64R6-NEXT: andi $4, $4, 3 ++; MIPS64R6-NEXT: sll $4, $4, 3 ++; MIPS64R6-NEXT: ori $5, $zero, 65535 ++; MIPS64R6-NEXT: sllv $5, $5, $4 ++; MIPS64R6-NEXT: nor $6, $zero, $5 ++; MIPS64R6-NEXT: andi $7, $1, 65535 ++; MIPS64R6-NEXT: sllv $7, $7, $4 ++; MIPS64R6-NEXT: andi $2, $2, 65535 ++; MIPS64R6-NEXT: sllv $8, $2, $4 ++; MIPS64R6-NEXT: .LBB15_1: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: ll $9, 0($3) ++; MIPS64R6-NEXT: and $10, $9, $5 ++; MIPS64R6-NEXT: bnec $10, $7, .LBB15_3 ++; MIPS64R6-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1 ++; MIPS64R6-NEXT: and $9, $9, $6 ++; MIPS64R6-NEXT: or $9, $9, $8 ++; MIPS64R6-NEXT: sc $9, 0($3) ++; MIPS64R6-NEXT: beqzc $9, .LBB15_1 ++; MIPS64R6-NEXT: .LBB15_3: ++; MIPS64R6-NEXT: sync ++; MIPS64R6-NEXT: srlv $2, $10, $4 ++; MIPS64R6-NEXT: seh $2, $2 ++; MIPS64R6-NEXT: # %bb.4: ++; MIPS64R6-NEXT: seh $1, $1 ++; MIPS64R6-NEXT: xor $1, $2, $1 ++; MIPS64R6-NEXT: sltiu $3, $1, 1 ++; MIPS64R6-NEXT: sync ++; MIPS64R6-NEXT: jrc $ra ++; ++; MIPS64R6O0-LABEL: foo: ++; MIPS64R6O0: # %bb.0: ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, -16 ++; MIPS64R6O0-NEXT: .cfi_def_cfa_offset 16 ++; MIPS64R6O0-NEXT: move $3, $4 ++; MIPS64R6O0-NEXT: move $1, $7 ++; MIPS64R6O0-NEXT: sll $1, $1, 0 ++; MIPS64R6O0-NEXT: move $2, $6 ++; MIPS64R6O0-NEXT: sll $4, $2, 0 ++; MIPS64R6O0-NEXT: move $2, $5 ++; MIPS64R6O0-NEXT: sll $2, $2, 0 ++; MIPS64R6O0-NEXT: addu $2, $2, $4 ++; MIPS64R6O0-NEXT: sw $2, 8($sp) # 4-byte Folded Spill ++; MIPS64R6O0-NEXT: sync ++; MIPS64R6O0-NEXT: daddiu $4, $zero, -4 ++; MIPS64R6O0-NEXT: and $4, $3, $4 ++; MIPS64R6O0-NEXT: andi $3, $3, 3 ++; MIPS64R6O0-NEXT: xori $3, $3, 2 ++; MIPS64R6O0-NEXT: sll $9, $3, 3 ++; MIPS64R6O0-NEXT: ori $3, $zero, 65535 ++; MIPS64R6O0-NEXT: sllv $5, $3, $9 ++; MIPS64R6O0-NEXT: nor $7, $zero, $5 ++; MIPS64R6O0-NEXT: andi $2, $2, 65535 ++; MIPS64R6O0-NEXT: sllv $6, $2, $9 ++; MIPS64R6O0-NEXT: andi $1, $1, 65535 ++; MIPS64R6O0-NEXT: sllv $8, $1, $9 ++; MIPS64R6O0-NEXT: .LBB15_1: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: ll $2, 0($4) ++; MIPS64R6O0-NEXT: and $3, $2, $5 ++; MIPS64R6O0-NEXT: bnec $3, $6, .LBB15_3 ++; MIPS64R6O0-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1 ++; MIPS64R6O0-NEXT: and $2, $2, $7 ++; MIPS64R6O0-NEXT: or $2, $2, $8 ++; MIPS64R6O0-NEXT: sc $2, 0($4) ++; MIPS64R6O0-NEXT: beqzc $2, .LBB15_1 ++; MIPS64R6O0-NEXT: .LBB15_3: ++; MIPS64R6O0-NEXT: sync ++; MIPS64R6O0-NEXT: srlv $1, $3, $9 ++; MIPS64R6O0-NEXT: seh $1, $1 ++; MIPS64R6O0-NEXT: # %bb.4: ++; MIPS64R6O0-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ++; MIPS64R6O0-NEXT: # %bb.5: ++; MIPS64R6O0-NEXT: lw $2, 12($sp) # 4-byte Folded Reload ++; MIPS64R6O0-NEXT: lw $1, 8($sp) # 4-byte Folded Reload ++; MIPS64R6O0-NEXT: seh $1, $1 ++; MIPS64R6O0-NEXT: xor $1, $2, $1 ++; MIPS64R6O0-NEXT: sltiu $3, $1, 1 ++; MIPS64R6O0-NEXT: sync ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, 16 ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; MM32-LABEL: foo: ++; MM32: # %bb.0: ++; MM32-NEXT: addu16 $3, $5, $6 ++; MM32-NEXT: sync ++; MM32-NEXT: addiu $1, $zero, -4 ++; MM32-NEXT: and $1, $4, $1 ++; MM32-NEXT: andi $2, $4, 3 ++; MM32-NEXT: sll $4, $2, 3 ++; MM32-NEXT: ori $2, $zero, 65535 ++; MM32-NEXT: sllv $5, $2, $4 ++; MM32-NEXT: nor $6, $zero, $5 ++; MM32-NEXT: andi $2, $3, 65535 ++; MM32-NEXT: sllv $8, $2, $4 ++; MM32-NEXT: andi $2, $7, 65535 ++; MM32-NEXT: sllv $7, $2, $4 ++; MM32-NEXT: $BB15_1: # =>This Inner Loop Header: Depth=1 ++; MM32-NEXT: ll $9, 0($1) ++; MM32-NEXT: and $10, $9, $5 ++; MM32-NEXT: bne $10, $8, $BB15_3 ++; MM32-NEXT: nop ++; MM32-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1 ++; MM32-NEXT: and $9, $9, $6 ++; MM32-NEXT: or $9, $9, $7 ++; MM32-NEXT: sc $9, 0($1) ++; MM32-NEXT: beqzc $9, $BB15_1 ++; MM32-NEXT: $BB15_3: ++; MM32-NEXT: sync 0 ++; MM32-NEXT: srlv $2, $10, $4 ++; MM32-NEXT: seh $2, $2 ++; MM32-NEXT: # %bb.4: ++; MM32-NEXT: seh $1, $3 ++; MM32-NEXT: xor $1, $2, $1 ++; MM32-NEXT: sltiu $3, $1, 1 ++; MM32-NEXT: sync ++; MM32-NEXT: jrc $ra ++; ++; O1-LABEL: foo: ++; O1: # %bb.0: ++; O1-NEXT: addu $1, $5, $6 ++; O1-NEXT: sync ++; O1-NEXT: addiu $2, $zero, -4 ++; O1-NEXT: and $3, $4, $2 ++; O1-NEXT: andi $2, $4, 3 ++; O1-NEXT: sll $4, $2, 3 ++; O1-NEXT: ori $2, $zero, 65535 ++; O1-NEXT: sllv $5, $2, $4 ++; O1-NEXT: nor $6, $zero, $5 ++; O1-NEXT: andi $2, $1, 65535 ++; O1-NEXT: sllv $8, $2, $4 ++; O1-NEXT: andi $2, $7, 65535 ++; O1-NEXT: sllv $7, $2, $4 ++; O1-NEXT: $BB15_1: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: ll $9, 0($3) ++; O1-NEXT: and $10, $9, $5 ++; O1-NEXT: bne $10, $8, $BB15_3 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1 ++; O1-NEXT: and $9, $9, $6 ++; O1-NEXT: or $9, $9, $7 ++; O1-NEXT: sc $9, 0($3) ++; O1-NEXT: beqz $9, $BB15_1 ++; O1-NEXT: nop ++; O1-NEXT: $BB15_3: ++; O1-NEXT: sync ++; O1-NEXT: srlv $2, $10, $4 ++; O1-NEXT: sll $2, $2, 16 ++; O1-NEXT: sra $2, $2, 16 ++; O1-NEXT: # %bb.4: ++; O1-NEXT: sll $1, $1, 16 ++; O1-NEXT: sra $1, $1, 16 ++; O1-NEXT: xor $1, $2, $1 ++; O1-NEXT: sltiu $3, $1, 1 ++; O1-NEXT: sync ++; O1-NEXT: jr $ra ++; O1-NEXT: nop ++; ++; O2-LABEL: foo: ++; O2: # %bb.0: ++; O2-NEXT: addu $1, $5, $6 ++; O2-NEXT: sync ++; O2-NEXT: addiu $2, $zero, -4 ++; O2-NEXT: and $3, $4, $2 ++; O2-NEXT: andi $2, $4, 3 ++; O2-NEXT: sll $4, $2, 3 ++; O2-NEXT: ori $2, $zero, 65535 ++; O2-NEXT: sllv $5, $2, $4 ++; O2-NEXT: nor $6, $zero, $5 ++; O2-NEXT: andi $2, $1, 65535 ++; O2-NEXT: sllv $8, $2, $4 ++; O2-NEXT: andi $2, $7, 65535 ++; O2-NEXT: sllv $7, $2, $4 ++; O2-NEXT: $BB15_1: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: ll $9, 0($3) ++; O2-NEXT: and $10, $9, $5 ++; O2-NEXT: bne $10, $8, $BB15_3 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1 ++; O2-NEXT: and $9, $9, $6 ++; O2-NEXT: or $9, $9, $7 ++; O2-NEXT: sc $9, 0($3) ++; O2-NEXT: beqz $9, $BB15_1 ++; O2-NEXT: nop ++; O2-NEXT: $BB15_3: ++; O2-NEXT: sync ++; O2-NEXT: srlv $2, $10, $4 ++; O2-NEXT: sll $2, $2, 16 ++; O2-NEXT: sra $2, $2, 16 ++; O2-NEXT: # %bb.4: ++; O2-NEXT: sll $1, $1, 16 ++; O2-NEXT: sra $1, $1, 16 ++; O2-NEXT: xor $1, $2, $1 ++; O2-NEXT: sltiu $3, $1, 1 ++; O2-NEXT: sync ++; O2-NEXT: jr $ra ++; O2-NEXT: nop ++; ++; O3-LABEL: foo: ++; O3: # %bb.0: ++; O3-NEXT: addiu $2, $zero, -4 ++; O3-NEXT: addu $1, $5, $6 ++; O3-NEXT: sync ++; O3-NEXT: and $3, $4, $2 ++; O3-NEXT: andi $2, $4, 3 ++; O3-NEXT: sll $4, $2, 3 ++; O3-NEXT: ori $2, $zero, 65535 ++; O3-NEXT: sllv $5, $2, $4 ++; O3-NEXT: andi $2, $1, 65535 ++; O3-NEXT: sll $1, $1, 16 ++; O3-NEXT: sllv $8, $2, $4 ++; O3-NEXT: andi $2, $7, 65535 ++; O3-NEXT: nor $6, $zero, $5 ++; O3-NEXT: sra $1, $1, 16 ++; O3-NEXT: sllv $7, $2, $4 ++; O3-NEXT: $BB15_1: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: ll $9, 0($3) ++; O3-NEXT: and $10, $9, $5 ++; O3-NEXT: bne $10, $8, $BB15_3 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1 ++; O3-NEXT: and $9, $9, $6 ++; O3-NEXT: or $9, $9, $7 ++; O3-NEXT: sc $9, 0($3) ++; O3-NEXT: beqz $9, $BB15_1 ++; O3-NEXT: nop ++; O3-NEXT: $BB15_3: ++; O3-NEXT: sync ++; O3-NEXT: srlv $2, $10, $4 ++; O3-NEXT: sll $2, $2, 16 ++; O3-NEXT: sra $2, $2, 16 ++; O3-NEXT: # %bb.4: ++; O3-NEXT: sync ++; O3-NEXT: xor $1, $2, $1 ++; O3-NEXT: jr $ra ++; O3-NEXT: sltiu $3, $1, 1 ++; ++; MIPS32EB-LABEL: foo: ++; MIPS32EB: # %bb.0: ++; MIPS32EB-NEXT: addu $1, $5, $6 ++; MIPS32EB-NEXT: sync ++; MIPS32EB-NEXT: addiu $2, $zero, -4 ++; MIPS32EB-NEXT: and $3, $4, $2 ++; MIPS32EB-NEXT: andi $2, $4, 3 ++; MIPS32EB-NEXT: xori $2, $2, 2 ++; MIPS32EB-NEXT: sll $4, $2, 3 ++; MIPS32EB-NEXT: ori $2, $zero, 65535 ++; MIPS32EB-NEXT: sllv $5, $2, $4 ++; MIPS32EB-NEXT: nor $6, $zero, $5 ++; MIPS32EB-NEXT: andi $2, $1, 65535 ++; MIPS32EB-NEXT: sllv $8, $2, $4 ++; MIPS32EB-NEXT: andi $2, $7, 65535 ++; MIPS32EB-NEXT: sllv $7, $2, $4 ++; MIPS32EB-NEXT: $BB15_1: # =>This Inner Loop Header: Depth=1 ++; MIPS32EB-NEXT: ll $9, 0($3) ++; MIPS32EB-NEXT: and $10, $9, $5 ++; MIPS32EB-NEXT: bne $10, $8, $BB15_3 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: # %bb.2: # in Loop: Header=BB15_1 Depth=1 ++; MIPS32EB-NEXT: and $9, $9, $6 ++; MIPS32EB-NEXT: or $9, $9, $7 ++; MIPS32EB-NEXT: sc $9, 0($3) ++; MIPS32EB-NEXT: beqz $9, $BB15_1 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: $BB15_3: ++; MIPS32EB-NEXT: sync ++; MIPS32EB-NEXT: srlv $2, $10, $4 ++; MIPS32EB-NEXT: sll $2, $2, 16 ++; MIPS32EB-NEXT: sra $2, $2, 16 ++; MIPS32EB-NEXT: # %bb.4: ++; MIPS32EB-NEXT: sll $1, $1, 16 ++; MIPS32EB-NEXT: sra $1, $1, 16 ++; MIPS32EB-NEXT: xor $1, $2, $1 ++; MIPS32EB-NEXT: sltiu $3, $1, 1 ++; MIPS32EB-NEXT: sync ++; MIPS32EB-NEXT: jr $ra ++; MIPS32EB-NEXT: nop ++ %desired = add i16 %l, %r ++ %res = cmpxchg ptr %addr, i16 %desired, i16 %new seq_cst seq_cst ++ ret {i16, i1} %res ++} ++ ++@countsint = common global i32 0, align 4 ++ ++define i32 @CheckSync(i32 signext %v) nounwind noinline { ++; MIPS32-LABEL: CheckSync: ++; MIPS32: # %bb.0: # %entry ++; MIPS32-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32-NEXT: addu $1, $2, $25 ++; MIPS32-NEXT: sync ++; MIPS32-NEXT: lw $1, %got(countsint)($1) ++; MIPS32-NEXT: $BB16_1: # %entry ++; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32-NEXT: ll $2, 0($1) ++; MIPS32-NEXT: addu $3, $2, $4 ++; MIPS32-NEXT: sc $3, 0($1) ++; MIPS32-NEXT: beqz $3, $BB16_1 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: # %bb.2: # %entry ++; MIPS32-NEXT: sync ++; MIPS32-NEXT: jr $ra ++; MIPS32-NEXT: nop ++; ++; MIPS32O0-LABEL: CheckSync: ++; MIPS32O0: # %bb.0: # %entry ++; MIPS32O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32O0-NEXT: addu $1, $2, $25 ++; MIPS32O0-NEXT: sync ++; MIPS32O0-NEXT: lw $3, %got(countsint)($1) ++; MIPS32O0-NEXT: $BB16_1: # %entry ++; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32O0-NEXT: ll $2, 0($3) ++; MIPS32O0-NEXT: addu $1, $2, $4 ++; MIPS32O0-NEXT: sc $1, 0($3) ++; MIPS32O0-NEXT: beqz $1, $BB16_1 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: # %bb.2: # %entry ++; MIPS32O0-NEXT: sync ++; MIPS32O0-NEXT: jr $ra ++; MIPS32O0-NEXT: nop ++; ++; MIPS32R2-LABEL: CheckSync: ++; MIPS32R2: # %bb.0: # %entry ++; MIPS32R2-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R2-NEXT: addu $1, $2, $25 ++; MIPS32R2-NEXT: sync ++; MIPS32R2-NEXT: lw $1, %got(countsint)($1) ++; MIPS32R2-NEXT: $BB16_1: # %entry ++; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R2-NEXT: ll $2, 0($1) ++; MIPS32R2-NEXT: addu $3, $2, $4 ++; MIPS32R2-NEXT: sc $3, 0($1) ++; MIPS32R2-NEXT: beqz $3, $BB16_1 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: # %bb.2: # %entry ++; MIPS32R2-NEXT: sync ++; MIPS32R2-NEXT: jr $ra ++; MIPS32R2-NEXT: nop ++; ++; MIPS32R6-LABEL: CheckSync: ++; MIPS32R6: # %bb.0: # %entry ++; MIPS32R6-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6-NEXT: addu $1, $2, $25 ++; MIPS32R6-NEXT: sync ++; MIPS32R6-NEXT: lw $1, %got(countsint)($1) ++; MIPS32R6-NEXT: $BB16_1: # %entry ++; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6-NEXT: ll $2, 0($1) ++; MIPS32R6-NEXT: addu $3, $2, $4 ++; MIPS32R6-NEXT: sc $3, 0($1) ++; MIPS32R6-NEXT: beqzc $3, $BB16_1 ++; MIPS32R6-NEXT: # %bb.2: # %entry ++; MIPS32R6-NEXT: sync ++; MIPS32R6-NEXT: jrc $ra ++; ++; MIPS32R6O0-LABEL: CheckSync: ++; MIPS32R6O0: # %bb.0: # %entry ++; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6O0-NEXT: addu $1, $2, $25 ++; MIPS32R6O0-NEXT: sync ++; MIPS32R6O0-NEXT: lw $3, %got(countsint)($1) ++; MIPS32R6O0-NEXT: $BB16_1: # %entry ++; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6O0-NEXT: ll $2, 0($3) ++; MIPS32R6O0-NEXT: addu $1, $2, $4 ++; MIPS32R6O0-NEXT: sc $1, 0($3) ++; MIPS32R6O0-NEXT: beqzc $1, $BB16_1 ++; MIPS32R6O0-NEXT: # %bb.2: # %entry ++; MIPS32R6O0-NEXT: sync ++; MIPS32R6O0-NEXT: jrc $ra ++; ++; MIPS4-LABEL: CheckSync: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(CheckSync))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(CheckSync))) ++; MIPS4-NEXT: sync ++; MIPS4-NEXT: ld $1, %got_disp(countsint)($1) ++; MIPS4-NEXT: .LBB16_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: ll $2, 0($1) ++; MIPS4-NEXT: addu $3, $2, $4 ++; MIPS4-NEXT: sc $3, 0($1) ++; MIPS4-NEXT: beqz $3, .LBB16_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: sync ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: nop ++; ++; MIPS64-LABEL: CheckSync: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(CheckSync))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(CheckSync))) ++; MIPS64-NEXT: sync ++; MIPS64-NEXT: ld $1, %got_disp(countsint)($1) ++; MIPS64-NEXT: .LBB16_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: ll $2, 0($1) ++; MIPS64-NEXT: addu $3, $2, $4 ++; MIPS64-NEXT: sc $3, 0($1) ++; MIPS64-NEXT: beqz $3, .LBB16_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: sync ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: nop ++; ++; MIPS64R2-LABEL: CheckSync: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(CheckSync))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(CheckSync))) ++; MIPS64R2-NEXT: sync ++; MIPS64R2-NEXT: ld $1, %got_disp(countsint)($1) ++; MIPS64R2-NEXT: .LBB16_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: ll $2, 0($1) ++; MIPS64R2-NEXT: addu $3, $2, $4 ++; MIPS64R2-NEXT: sc $3, 0($1) ++; MIPS64R2-NEXT: beqz $3, .LBB16_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: sync ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: nop ++; ++; MIPS64R6-LABEL: CheckSync: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(CheckSync))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(CheckSync))) ++; MIPS64R6-NEXT: sync ++; MIPS64R6-NEXT: ld $1, %got_disp(countsint)($1) ++; MIPS64R6-NEXT: .LBB16_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: ll $2, 0($1) ++; MIPS64R6-NEXT: addu $3, $2, $4 ++; MIPS64R6-NEXT: sc $3, 0($1) ++; MIPS64R6-NEXT: beqzc $3, .LBB16_1 ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: sync ++; MIPS64R6-NEXT: jrc $ra ++; ++; MIPS64R6O0-LABEL: CheckSync: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(CheckSync))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(CheckSync))) ++; MIPS64R6O0-NEXT: # kill: def $a0 killed $a0 killed $a0_64 ++; MIPS64R6O0-NEXT: sync ++; MIPS64R6O0-NEXT: ld $3, %got_disp(countsint)($1) ++; MIPS64R6O0-NEXT: .LBB16_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: ll $2, 0($3) ++; MIPS64R6O0-NEXT: addu $1, $2, $4 ++; MIPS64R6O0-NEXT: sc $1, 0($3) ++; MIPS64R6O0-NEXT: beqzc $1, .LBB16_1 ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: sync ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; MM32-LABEL: CheckSync: ++; MM32: # %bb.0: # %entry ++; MM32-NEXT: lui $2, %hi(_gp_disp) ++; MM32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MM32-NEXT: addu $2, $2, $25 ++; MM32-NEXT: sync ++; MM32-NEXT: lw $1, %got(countsint)($2) ++; MM32-NEXT: $BB16_1: # %entry ++; MM32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MM32-NEXT: ll $2, 0($1) ++; MM32-NEXT: addu16 $3, $2, $4 ++; MM32-NEXT: sc $3, 0($1) ++; MM32-NEXT: beqzc $3, $BB16_1 ++; MM32-NEXT: # %bb.2: # %entry ++; MM32-NEXT: sync ++; MM32-NEXT: jrc $ra ++; ++; O1-LABEL: CheckSync: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $2, %hi(_gp_disp) ++; O1-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O1-NEXT: addu $1, $2, $25 ++; O1-NEXT: sync ++; O1-NEXT: lw $1, %got(countsint)($1) ++; O1-NEXT: $BB16_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: ll $2, 0($1) ++; O1-NEXT: addu $3, $2, $4 ++; O1-NEXT: sc $3, 0($1) ++; O1-NEXT: beqz $3, $BB16_1 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: sync ++; O1-NEXT: jr $ra ++; O1-NEXT: nop ++; ++; O2-LABEL: CheckSync: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $2, %hi(_gp_disp) ++; O2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O2-NEXT: addu $1, $2, $25 ++; O2-NEXT: sync ++; O2-NEXT: lw $1, %got(countsint)($1) ++; O2-NEXT: $BB16_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: ll $2, 0($1) ++; O2-NEXT: addu $3, $2, $4 ++; O2-NEXT: sc $3, 0($1) ++; O2-NEXT: beqz $3, $BB16_1 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: sync ++; O2-NEXT: jr $ra ++; O2-NEXT: nop ++; ++; O3-LABEL: CheckSync: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $2, %hi(_gp_disp) ++; O3-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O3-NEXT: addu $1, $2, $25 ++; O3-NEXT: sync ++; O3-NEXT: lw $1, %got(countsint)($1) ++; O3-NEXT: $BB16_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: ll $2, 0($1) ++; O3-NEXT: addu $3, $2, $4 ++; O3-NEXT: sc $3, 0($1) ++; O3-NEXT: beqz $3, $BB16_1 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: sync ++; O3-NEXT: jr $ra ++; O3-NEXT: nop ++; ++; MIPS32EB-LABEL: CheckSync: ++; MIPS32EB: # %bb.0: # %entry ++; MIPS32EB-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32EB-NEXT: addu $1, $2, $25 ++; MIPS32EB-NEXT: sync ++; MIPS32EB-NEXT: lw $1, %got(countsint)($1) ++; MIPS32EB-NEXT: $BB16_1: # %entry ++; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32EB-NEXT: ll $2, 0($1) ++; MIPS32EB-NEXT: addu $3, $2, $4 ++; MIPS32EB-NEXT: sc $3, 0($1) ++; MIPS32EB-NEXT: beqz $3, $BB16_1 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: # %bb.2: # %entry ++; MIPS32EB-NEXT: sync ++; MIPS32EB-NEXT: jr $ra ++; MIPS32EB-NEXT: nop ++entry: ++ %0 = atomicrmw add ptr @countsint, i32 %v seq_cst ++ ret i32 %0 ++} ++ ++; make sure that this assertion in ++; TwoAddressInstructionPass::TryInstructionTransform does not fail: ++; ++; line 1203: assert(TargetRegisterInfo::isVirtualRegister(regB) && ++; ++; it failed when MipsDAGToDAGISel::ReplaceUsesWithZeroReg replaced an ++; operand of an atomic instruction with register $zero. ++@a = external global i32 ++ ++define i32 @zeroreg() nounwind { ++; MIPS32-LABEL: zeroreg: ++; MIPS32: # %bb.0: # %entry ++; MIPS32-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32-NEXT: addu $1, $2, $25 ++; MIPS32-NEXT: sync ++; MIPS32-NEXT: addiu $2, $zero, 0 ++; MIPS32-NEXT: addiu $3, $zero, 1 ++; MIPS32-NEXT: lw $1, %got(a)($1) ++; MIPS32-NEXT: $BB17_1: # %entry ++; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32-NEXT: ll $4, 0($1) ++; MIPS32-NEXT: bne $4, $3, $BB17_3 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: # %bb.2: # %entry ++; MIPS32-NEXT: # in Loop: Header=BB17_1 Depth=1 ++; MIPS32-NEXT: move $5, $2 ++; MIPS32-NEXT: sc $5, 0($1) ++; MIPS32-NEXT: beqz $5, $BB17_1 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: $BB17_3: # %entry ++; MIPS32-NEXT: xor $1, $4, $3 ++; MIPS32-NEXT: sltiu $2, $1, 1 ++; MIPS32-NEXT: sync ++; MIPS32-NEXT: jr $ra ++; MIPS32-NEXT: nop ++; ++; MIPS32O0-LABEL: zeroreg: ++; MIPS32O0: # %bb.0: # %entry ++; MIPS32O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32O0-NEXT: addu $1, $2, $25 ++; MIPS32O0-NEXT: sync ++; MIPS32O0-NEXT: lw $4, %got(a)($1) ++; MIPS32O0-NEXT: addiu $6, $zero, 0 ++; MIPS32O0-NEXT: addiu $2, $zero, 1 ++; MIPS32O0-NEXT: move $5, $2 ++; MIPS32O0-NEXT: $BB17_1: # %entry ++; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32O0-NEXT: ll $1, 0($4) ++; MIPS32O0-NEXT: bne $1, $5, $BB17_3 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: # %bb.2: # %entry ++; MIPS32O0-NEXT: # in Loop: Header=BB17_1 Depth=1 ++; MIPS32O0-NEXT: move $3, $6 ++; MIPS32O0-NEXT: sc $3, 0($4) ++; MIPS32O0-NEXT: beqz $3, $BB17_1 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: $BB17_3: # %entry ++; MIPS32O0-NEXT: xor $2, $1, $2 ++; MIPS32O0-NEXT: sltiu $2, $2, 1 ++; MIPS32O0-NEXT: sync ++; MIPS32O0-NEXT: addiu $2, $zero, 1 ++; MIPS32O0-NEXT: xor $1, $1, $2 ++; MIPS32O0-NEXT: sltiu $1, $1, 1 ++; MIPS32O0-NEXT: andi $2, $1, 1 ++; MIPS32O0-NEXT: jr $ra ++; MIPS32O0-NEXT: nop ++; ++; MIPS32R2-LABEL: zeroreg: ++; MIPS32R2: # %bb.0: # %entry ++; MIPS32R2-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R2-NEXT: addu $1, $2, $25 ++; MIPS32R2-NEXT: sync ++; MIPS32R2-NEXT: addiu $2, $zero, 0 ++; MIPS32R2-NEXT: addiu $3, $zero, 1 ++; MIPS32R2-NEXT: lw $1, %got(a)($1) ++; MIPS32R2-NEXT: $BB17_1: # %entry ++; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R2-NEXT: ll $4, 0($1) ++; MIPS32R2-NEXT: bne $4, $3, $BB17_3 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: # %bb.2: # %entry ++; MIPS32R2-NEXT: # in Loop: Header=BB17_1 Depth=1 ++; MIPS32R2-NEXT: move $5, $2 ++; MIPS32R2-NEXT: sc $5, 0($1) ++; MIPS32R2-NEXT: beqz $5, $BB17_1 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: $BB17_3: # %entry ++; MIPS32R2-NEXT: xor $1, $4, $3 ++; MIPS32R2-NEXT: sltiu $2, $1, 1 ++; MIPS32R2-NEXT: sync ++; MIPS32R2-NEXT: jr $ra ++; MIPS32R2-NEXT: nop ++; ++; MIPS32R6-LABEL: zeroreg: ++; MIPS32R6: # %bb.0: # %entry ++; MIPS32R6-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6-NEXT: addu $1, $2, $25 ++; MIPS32R6-NEXT: sync ++; MIPS32R6-NEXT: addiu $2, $zero, 0 ++; MIPS32R6-NEXT: addiu $3, $zero, 1 ++; MIPS32R6-NEXT: lw $1, %got(a)($1) ++; MIPS32R6-NEXT: $BB17_1: # %entry ++; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6-NEXT: ll $4, 0($1) ++; MIPS32R6-NEXT: bnec $4, $3, $BB17_3 ++; MIPS32R6-NEXT: # %bb.2: # %entry ++; MIPS32R6-NEXT: # in Loop: Header=BB17_1 Depth=1 ++; MIPS32R6-NEXT: move $5, $2 ++; MIPS32R6-NEXT: sc $5, 0($1) ++; MIPS32R6-NEXT: beqzc $5, $BB17_1 ++; MIPS32R6-NEXT: $BB17_3: # %entry ++; MIPS32R6-NEXT: xor $1, $4, $3 ++; MIPS32R6-NEXT: sltiu $2, $1, 1 ++; MIPS32R6-NEXT: sync ++; MIPS32R6-NEXT: jrc $ra ++; ++; MIPS32R6O0-LABEL: zeroreg: ++; MIPS32R6O0: # %bb.0: # %entry ++; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6O0-NEXT: addu $1, $2, $25 ++; MIPS32R6O0-NEXT: sync ++; MIPS32R6O0-NEXT: lw $4, %got(a)($1) ++; MIPS32R6O0-NEXT: addiu $6, $zero, 0 ++; MIPS32R6O0-NEXT: addiu $2, $zero, 1 ++; MIPS32R6O0-NEXT: move $5, $2 ++; MIPS32R6O0-NEXT: $BB17_1: # %entry ++; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6O0-NEXT: ll $1, 0($4) ++; MIPS32R6O0-NEXT: bnec $1, $5, $BB17_3 ++; MIPS32R6O0-NEXT: # %bb.2: # %entry ++; MIPS32R6O0-NEXT: # in Loop: Header=BB17_1 Depth=1 ++; MIPS32R6O0-NEXT: move $3, $6 ++; MIPS32R6O0-NEXT: sc $3, 0($4) ++; MIPS32R6O0-NEXT: beqzc $3, $BB17_1 ++; MIPS32R6O0-NEXT: $BB17_3: # %entry ++; MIPS32R6O0-NEXT: xor $1, $1, $2 ++; MIPS32R6O0-NEXT: sltiu $2, $1, 1 ++; MIPS32R6O0-NEXT: sync ++; MIPS32R6O0-NEXT: jrc $ra ++; ++; MIPS4-LABEL: zeroreg: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(zeroreg))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(zeroreg))) ++; MIPS4-NEXT: sync ++; MIPS4-NEXT: addiu $2, $zero, 0 ++; MIPS4-NEXT: addiu $3, $zero, 1 ++; MIPS4-NEXT: ld $1, %got_disp(a)($1) ++; MIPS4-NEXT: .LBB17_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: ll $4, 0($1) ++; MIPS4-NEXT: bne $4, $3, .LBB17_3 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: # in Loop: Header=BB17_1 Depth=1 ++; MIPS4-NEXT: move $5, $2 ++; MIPS4-NEXT: sc $5, 0($1) ++; MIPS4-NEXT: beqz $5, .LBB17_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: .LBB17_3: # %entry ++; MIPS4-NEXT: xor $1, $4, $3 ++; MIPS4-NEXT: sltiu $2, $1, 1 ++; MIPS4-NEXT: sync ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: nop ++; ++; MIPS64-LABEL: zeroreg: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(zeroreg))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(zeroreg))) ++; MIPS64-NEXT: sync ++; MIPS64-NEXT: addiu $2, $zero, 0 ++; MIPS64-NEXT: addiu $3, $zero, 1 ++; MIPS64-NEXT: ld $1, %got_disp(a)($1) ++; MIPS64-NEXT: .LBB17_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: ll $4, 0($1) ++; MIPS64-NEXT: bne $4, $3, .LBB17_3 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: # in Loop: Header=BB17_1 Depth=1 ++; MIPS64-NEXT: move $5, $2 ++; MIPS64-NEXT: sc $5, 0($1) ++; MIPS64-NEXT: beqz $5, .LBB17_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: .LBB17_3: # %entry ++; MIPS64-NEXT: xor $1, $4, $3 ++; MIPS64-NEXT: sltiu $2, $1, 1 ++; MIPS64-NEXT: sync ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: nop ++; ++; MIPS64R2-LABEL: zeroreg: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(zeroreg))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(zeroreg))) ++; MIPS64R2-NEXT: sync ++; MIPS64R2-NEXT: addiu $2, $zero, 0 ++; MIPS64R2-NEXT: addiu $3, $zero, 1 ++; MIPS64R2-NEXT: ld $1, %got_disp(a)($1) ++; MIPS64R2-NEXT: .LBB17_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: ll $4, 0($1) ++; MIPS64R2-NEXT: bne $4, $3, .LBB17_3 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: # in Loop: Header=BB17_1 Depth=1 ++; MIPS64R2-NEXT: move $5, $2 ++; MIPS64R2-NEXT: sc $5, 0($1) ++; MIPS64R2-NEXT: beqz $5, .LBB17_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: .LBB17_3: # %entry ++; MIPS64R2-NEXT: xor $1, $4, $3 ++; MIPS64R2-NEXT: sltiu $2, $1, 1 ++; MIPS64R2-NEXT: sync ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: nop ++; ++; MIPS64R6-LABEL: zeroreg: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(zeroreg))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(zeroreg))) ++; MIPS64R6-NEXT: sync ++; MIPS64R6-NEXT: addiu $2, $zero, 0 ++; MIPS64R6-NEXT: addiu $3, $zero, 1 ++; MIPS64R6-NEXT: ld $1, %got_disp(a)($1) ++; MIPS64R6-NEXT: .LBB17_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: ll $4, 0($1) ++; MIPS64R6-NEXT: bnec $4, $3, .LBB17_3 ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: # in Loop: Header=BB17_1 Depth=1 ++; MIPS64R6-NEXT: move $5, $2 ++; MIPS64R6-NEXT: sc $5, 0($1) ++; MIPS64R6-NEXT: beqzc $5, .LBB17_1 ++; MIPS64R6-NEXT: .LBB17_3: # %entry ++; MIPS64R6-NEXT: xor $1, $4, $3 ++; MIPS64R6-NEXT: sltiu $2, $1, 1 ++; MIPS64R6-NEXT: sync ++; MIPS64R6-NEXT: jrc $ra ++; ++; MIPS64R6O0-LABEL: zeroreg: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(zeroreg))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(zeroreg))) ++; MIPS64R6O0-NEXT: sync ++; MIPS64R6O0-NEXT: ld $4, %got_disp(a)($1) ++; MIPS64R6O0-NEXT: addiu $6, $zero, 0 ++; MIPS64R6O0-NEXT: addiu $2, $zero, 1 ++; MIPS64R6O0-NEXT: move $5, $2 ++; MIPS64R6O0-NEXT: .LBB17_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: ll $1, 0($4) ++; MIPS64R6O0-NEXT: bnec $1, $5, .LBB17_3 ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: # in Loop: Header=BB17_1 Depth=1 ++; MIPS64R6O0-NEXT: move $3, $6 ++; MIPS64R6O0-NEXT: sc $3, 0($4) ++; MIPS64R6O0-NEXT: beqzc $3, .LBB17_1 ++; MIPS64R6O0-NEXT: .LBB17_3: # %entry ++; MIPS64R6O0-NEXT: xor $1, $1, $2 ++; MIPS64R6O0-NEXT: sltiu $2, $1, 1 ++; MIPS64R6O0-NEXT: sync ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; MM32-LABEL: zeroreg: ++; MM32: # %bb.0: # %entry ++; MM32-NEXT: lui $2, %hi(_gp_disp) ++; MM32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MM32-NEXT: addu $2, $2, $25 ++; MM32-NEXT: sync ++; MM32-NEXT: li16 $3, 0 ++; MM32-NEXT: li16 $4, 1 ++; MM32-NEXT: lw $1, %got(a)($2) ++; MM32-NEXT: $BB17_1: # %entry ++; MM32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MM32-NEXT: ll $2, 0($1) ++; MM32-NEXT: bne $2, $4, $BB17_3 ++; MM32-NEXT: nop ++; MM32-NEXT: # %bb.2: # %entry ++; MM32-NEXT: # in Loop: Header=BB17_1 Depth=1 ++; MM32-NEXT: move $5, $3 ++; MM32-NEXT: sc $5, 0($1) ++; MM32-NEXT: beqzc $5, $BB17_1 ++; MM32-NEXT: $BB17_3: # %entry ++; MM32-NEXT: sync 0 ++; MM32-NEXT: xor $1, $2, $4 ++; MM32-NEXT: sltiu $2, $1, 1 ++; MM32-NEXT: sync ++; MM32-NEXT: jrc $ra ++; ++; O1-LABEL: zeroreg: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $2, %hi(_gp_disp) ++; O1-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O1-NEXT: addu $1, $2, $25 ++; O1-NEXT: sync ++; O1-NEXT: addiu $2, $zero, 0 ++; O1-NEXT: addiu $3, $zero, 1 ++; O1-NEXT: lw $1, %got(a)($1) ++; O1-NEXT: $BB17_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: ll $4, 0($1) ++; O1-NEXT: bne $4, $3, $BB17_3 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: # in Loop: Header=BB17_1 Depth=1 ++; O1-NEXT: move $5, $2 ++; O1-NEXT: sc $5, 0($1) ++; O1-NEXT: beqz $5, $BB17_1 ++; O1-NEXT: nop ++; O1-NEXT: $BB17_3: # %entry ++; O1-NEXT: xor $1, $4, $3 ++; O1-NEXT: sltiu $2, $1, 1 ++; O1-NEXT: sync ++; O1-NEXT: jr $ra ++; O1-NEXT: nop ++; ++; O2-LABEL: zeroreg: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $2, %hi(_gp_disp) ++; O2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O2-NEXT: addu $1, $2, $25 ++; O2-NEXT: sync ++; O2-NEXT: addiu $2, $zero, 0 ++; O2-NEXT: addiu $3, $zero, 1 ++; O2-NEXT: lw $1, %got(a)($1) ++; O2-NEXT: $BB17_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: ll $4, 0($1) ++; O2-NEXT: bne $4, $3, $BB17_3 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: # in Loop: Header=BB17_1 Depth=1 ++; O2-NEXT: move $5, $2 ++; O2-NEXT: sc $5, 0($1) ++; O2-NEXT: beqz $5, $BB17_1 ++; O2-NEXT: nop ++; O2-NEXT: $BB17_3: # %entry ++; O2-NEXT: xor $1, $4, $3 ++; O2-NEXT: sltiu $2, $1, 1 ++; O2-NEXT: sync ++; O2-NEXT: jr $ra ++; O2-NEXT: nop ++; ++; O3-LABEL: zeroreg: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $2, %hi(_gp_disp) ++; O3-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O3-NEXT: addu $1, $2, $25 ++; O3-NEXT: addiu $2, $zero, 0 ++; O3-NEXT: addiu $3, $zero, 1 ++; O3-NEXT: sync ++; O3-NEXT: lw $1, %got(a)($1) ++; O3-NEXT: $BB17_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: ll $4, 0($1) ++; O3-NEXT: bne $4, $3, $BB17_3 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: # in Loop: Header=BB17_1 Depth=1 ++; O3-NEXT: move $5, $2 ++; O3-NEXT: sc $5, 0($1) ++; O3-NEXT: beqz $5, $BB17_1 ++; O3-NEXT: nop ++; O3-NEXT: $BB17_3: # %entry ++; O3-NEXT: sync ++; O3-NEXT: xor $1, $4, $3 ++; O3-NEXT: jr $ra ++; O3-NEXT: sltiu $2, $1, 1 ++; ++; MIPS32EB-LABEL: zeroreg: ++; MIPS32EB: # %bb.0: # %entry ++; MIPS32EB-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32EB-NEXT: addu $1, $2, $25 ++; MIPS32EB-NEXT: sync ++; MIPS32EB-NEXT: addiu $2, $zero, 0 ++; MIPS32EB-NEXT: addiu $3, $zero, 1 ++; MIPS32EB-NEXT: lw $1, %got(a)($1) ++; MIPS32EB-NEXT: $BB17_1: # %entry ++; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32EB-NEXT: ll $4, 0($1) ++; MIPS32EB-NEXT: bne $4, $3, $BB17_3 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: # %bb.2: # %entry ++; MIPS32EB-NEXT: # in Loop: Header=BB17_1 Depth=1 ++; MIPS32EB-NEXT: move $5, $2 ++; MIPS32EB-NEXT: sc $5, 0($1) ++; MIPS32EB-NEXT: beqz $5, $BB17_1 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: $BB17_3: # %entry ++; MIPS32EB-NEXT: xor $1, $4, $3 ++; MIPS32EB-NEXT: sltiu $2, $1, 1 ++; MIPS32EB-NEXT: sync ++; MIPS32EB-NEXT: jr $ra ++; MIPS32EB-NEXT: nop ++entry: ++ %pair0 = cmpxchg ptr @a, i32 1, i32 0 seq_cst seq_cst ++ %0 = extractvalue { i32, i1 } %pair0, 0 ++ %1 = icmp eq i32 %0, 1 ++ %conv = zext i1 %1 to i32 ++ ret i32 %conv ++} ++ ++; Check that MIPS32R6 has the correct offset range. ++; FIXME: At the moment, we don't seem to do addr+offset for any atomic load/store. ++define i32 @AtomicLoadAdd32_OffGt9Bit(i32 signext %incr) nounwind { ++; MIPS32-LABEL: AtomicLoadAdd32_OffGt9Bit: ++; MIPS32: # %bb.0: # %entry ++; MIPS32-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32-NEXT: addu $1, $2, $25 ++; MIPS32-NEXT: lw $1, %got(x)($1) ++; MIPS32-NEXT: addiu $1, $1, 1024 ++; MIPS32-NEXT: $BB18_1: # %entry ++; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32-NEXT: ll $2, 0($1) ++; MIPS32-NEXT: addu $3, $2, $4 ++; MIPS32-NEXT: sc $3, 0($1) ++; MIPS32-NEXT: beqz $3, $BB18_1 ++; MIPS32-NEXT: nop ++; MIPS32-NEXT: # %bb.2: # %entry ++; MIPS32-NEXT: jr $ra ++; MIPS32-NEXT: nop ++; ++; MIPS32O0-LABEL: AtomicLoadAdd32_OffGt9Bit: ++; MIPS32O0: # %bb.0: # %entry ++; MIPS32O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32O0-NEXT: addu $1, $2, $25 ++; MIPS32O0-NEXT: lw $1, %got(x)($1) ++; MIPS32O0-NEXT: addiu $3, $1, 1024 ++; MIPS32O0-NEXT: $BB18_1: # %entry ++; MIPS32O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32O0-NEXT: ll $2, 0($3) ++; MIPS32O0-NEXT: addu $1, $2, $4 ++; MIPS32O0-NEXT: sc $1, 0($3) ++; MIPS32O0-NEXT: beqz $1, $BB18_1 ++; MIPS32O0-NEXT: nop ++; MIPS32O0-NEXT: # %bb.2: # %entry ++; MIPS32O0-NEXT: jr $ra ++; MIPS32O0-NEXT: nop ++; ++; MIPS32R2-LABEL: AtomicLoadAdd32_OffGt9Bit: ++; MIPS32R2: # %bb.0: # %entry ++; MIPS32R2-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R2-NEXT: addu $1, $2, $25 ++; MIPS32R2-NEXT: lw $1, %got(x)($1) ++; MIPS32R2-NEXT: addiu $1, $1, 1024 ++; MIPS32R2-NEXT: $BB18_1: # %entry ++; MIPS32R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R2-NEXT: ll $2, 0($1) ++; MIPS32R2-NEXT: addu $3, $2, $4 ++; MIPS32R2-NEXT: sc $3, 0($1) ++; MIPS32R2-NEXT: beqz $3, $BB18_1 ++; MIPS32R2-NEXT: nop ++; MIPS32R2-NEXT: # %bb.2: # %entry ++; MIPS32R2-NEXT: jr $ra ++; MIPS32R2-NEXT: nop ++; ++; MIPS32R6-LABEL: AtomicLoadAdd32_OffGt9Bit: ++; MIPS32R6: # %bb.0: # %entry ++; MIPS32R6-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6-NEXT: addu $1, $2, $25 ++; MIPS32R6-NEXT: lw $1, %got(x)($1) ++; MIPS32R6-NEXT: addiu $1, $1, 1024 ++; MIPS32R6-NEXT: $BB18_1: # %entry ++; MIPS32R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6-NEXT: ll $2, 0($1) ++; MIPS32R6-NEXT: addu $3, $2, $4 ++; MIPS32R6-NEXT: sc $3, 0($1) ++; MIPS32R6-NEXT: beqzc $3, $BB18_1 ++; MIPS32R6-NEXT: nop ++; MIPS32R6-NEXT: # %bb.2: # %entry ++; MIPS32R6-NEXT: jrc $ra ++; ++; MIPS32R6O0-LABEL: AtomicLoadAdd32_OffGt9Bit: ++; MIPS32R6O0: # %bb.0: # %entry ++; MIPS32R6O0-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32R6O0-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32R6O0-NEXT: addu $1, $2, $25 ++; MIPS32R6O0-NEXT: lw $1, %got(x)($1) ++; MIPS32R6O0-NEXT: addiu $3, $1, 1024 ++; MIPS32R6O0-NEXT: $BB18_1: # %entry ++; MIPS32R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32R6O0-NEXT: ll $2, 0($3) ++; MIPS32R6O0-NEXT: addu $1, $2, $4 ++; MIPS32R6O0-NEXT: sc $1, 0($3) ++; MIPS32R6O0-NEXT: beqzc $1, $BB18_1 ++; MIPS32R6O0-NEXT: nop ++; MIPS32R6O0-NEXT: # %bb.2: # %entry ++; MIPS32R6O0-NEXT: jrc $ra ++; ++; MIPS4-LABEL: AtomicLoadAdd32_OffGt9Bit: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd32_OffGt9Bit))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd32_OffGt9Bit))) ++; MIPS4-NEXT: ld $1, %got_disp(x)($1) ++; MIPS4-NEXT: daddiu $1, $1, 1024 ++; MIPS4-NEXT: .LBB18_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: ll $2, 0($1) ++; MIPS4-NEXT: addu $3, $2, $4 ++; MIPS4-NEXT: sc $3, 0($1) ++; MIPS4-NEXT: beqz $3, .LBB18_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: nop ++; ++; MIPS64-LABEL: AtomicLoadAdd32_OffGt9Bit: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd32_OffGt9Bit))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd32_OffGt9Bit))) ++; MIPS64-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64-NEXT: daddiu $1, $1, 1024 ++; MIPS64-NEXT: .LBB18_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: ll $2, 0($1) ++; MIPS64-NEXT: addu $3, $2, $4 ++; MIPS64-NEXT: sc $3, 0($1) ++; MIPS64-NEXT: beqz $3, .LBB18_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: nop ++; ++; MIPS64R2-LABEL: AtomicLoadAdd32_OffGt9Bit: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd32_OffGt9Bit))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd32_OffGt9Bit))) ++; MIPS64R2-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R2-NEXT: daddiu $1, $1, 1024 ++; MIPS64R2-NEXT: .LBB18_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: ll $2, 0($1) ++; MIPS64R2-NEXT: addu $3, $2, $4 ++; MIPS64R2-NEXT: sc $3, 0($1) ++; MIPS64R2-NEXT: beqz $3, .LBB18_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: nop ++; ++; MIPS64R6-LABEL: AtomicLoadAdd32_OffGt9Bit: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd32_OffGt9Bit))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd32_OffGt9Bit))) ++; MIPS64R6-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R6-NEXT: daddiu $1, $1, 1024 ++; MIPS64R6-NEXT: .LBB18_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: ll $2, 0($1) ++; MIPS64R6-NEXT: addu $3, $2, $4 ++; MIPS64R6-NEXT: sc $3, 0($1) ++; MIPS64R6-NEXT: beqzc $3, .LBB18_1 ++; MIPS64R6-NEXT: nop ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: jrc $ra ++; ++; MIPS64R6O0-LABEL: AtomicLoadAdd32_OffGt9Bit: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd32_OffGt9Bit))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd32_OffGt9Bit))) ++; MIPS64R6O0-NEXT: # kill: def $a0 killed $a0 killed $a0_64 ++; MIPS64R6O0-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R6O0-NEXT: daddiu $3, $1, 1024 ++; MIPS64R6O0-NEXT: .LBB18_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: ll $2, 0($3) ++; MIPS64R6O0-NEXT: addu $1, $2, $4 ++; MIPS64R6O0-NEXT: sc $1, 0($3) ++; MIPS64R6O0-NEXT: beqzc $1, .LBB18_1 ++; MIPS64R6O0-NEXT: nop ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; MM32-LABEL: AtomicLoadAdd32_OffGt9Bit: ++; MM32: # %bb.0: # %entry ++; MM32-NEXT: lui $2, %hi(_gp_disp) ++; MM32-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MM32-NEXT: addu $2, $2, $25 ++; MM32-NEXT: lw $1, %got(x)($2) ++; MM32-NEXT: addiu $1, $1, 1024 ++; MM32-NEXT: $BB18_1: # %entry ++; MM32-NEXT: # =>This Inner Loop Header: Depth=1 ++; MM32-NEXT: ll $2, 0($1) ++; MM32-NEXT: addu16 $3, $2, $4 ++; MM32-NEXT: sc $3, 0($1) ++; MM32-NEXT: beqzc $3, $BB18_1 ++; MM32-NEXT: # %bb.2: # %entry ++; MM32-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicLoadAdd32_OffGt9Bit: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $2, %hi(_gp_disp) ++; O1-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O1-NEXT: addu $1, $2, $25 ++; O1-NEXT: lw $1, %got(x)($1) ++; O1-NEXT: addiu $1, $1, 1024 ++; O1-NEXT: $BB18_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: ll $2, 0($1) ++; O1-NEXT: addu $3, $2, $4 ++; O1-NEXT: sc $3, 0($1) ++; O1-NEXT: beqz $3, $BB18_1 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: jr $ra ++; O1-NEXT: nop ++; ++; O2-LABEL: AtomicLoadAdd32_OffGt9Bit: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $2, %hi(_gp_disp) ++; O2-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O2-NEXT: addu $1, $2, $25 ++; O2-NEXT: lw $1, %got(x)($1) ++; O2-NEXT: addiu $1, $1, 1024 ++; O2-NEXT: $BB18_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: ll $2, 0($1) ++; O2-NEXT: addu $3, $2, $4 ++; O2-NEXT: sc $3, 0($1) ++; O2-NEXT: beqz $3, $BB18_1 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: jr $ra ++; O2-NEXT: nop ++; ++; O3-LABEL: AtomicLoadAdd32_OffGt9Bit: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $2, %hi(_gp_disp) ++; O3-NEXT: addiu $2, $2, %lo(_gp_disp) ++; O3-NEXT: addu $1, $2, $25 ++; O3-NEXT: lw $1, %got(x)($1) ++; O3-NEXT: addiu $1, $1, 1024 ++; O3-NEXT: $BB18_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: ll $2, 0($1) ++; O3-NEXT: addu $3, $2, $4 ++; O3-NEXT: sc $3, 0($1) ++; O3-NEXT: beqz $3, $BB18_1 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: jr $ra ++; O3-NEXT: nop ++; ++; MIPS32EB-LABEL: AtomicLoadAdd32_OffGt9Bit: ++; MIPS32EB: # %bb.0: # %entry ++; MIPS32EB-NEXT: lui $2, %hi(_gp_disp) ++; MIPS32EB-NEXT: addiu $2, $2, %lo(_gp_disp) ++; MIPS32EB-NEXT: addu $1, $2, $25 ++; MIPS32EB-NEXT: lw $1, %got(x)($1) ++; MIPS32EB-NEXT: addiu $1, $1, 1024 ++; MIPS32EB-NEXT: $BB18_1: # %entry ++; MIPS32EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS32EB-NEXT: ll $2, 0($1) ++; MIPS32EB-NEXT: addu $3, $2, $4 ++; MIPS32EB-NEXT: sc $3, 0($1) ++; MIPS32EB-NEXT: beqz $3, $BB18_1 ++; MIPS32EB-NEXT: nop ++; MIPS32EB-NEXT: # %bb.2: # %entry ++; MIPS32EB-NEXT: jr $ra ++; MIPS32EB-NEXT: nop ++entry: ++ %0 = atomicrmw add ptr getelementptr(i32, ptr @x, i32 256), i32 %incr monotonic ++ ret i32 %0 ++ ++} +diff --git a/llvm/test/CodeGen/Mips/atomic.ll b/llvm/test/CodeGen/Mips/atomic.ll +index eaf99cc70..fbb5353a4 100644 +--- a/llvm/test/CodeGen/Mips/atomic.ll ++++ b/llvm/test/CodeGen/Mips/atomic.ll +@@ -1,35 +1,35 @@ + ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc -mtriple=mipsel-unknown-linux-gnu --disable-machine-licm -mcpu=mips32 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mipsel-unknown-linux-gnu --disable-machine-licm -mcpu=mips32 -relocation-model=pic -verify-machineinstrs < %s | \ + ; RUN: FileCheck %s -check-prefix=MIPS32 +-; RUN: llc -mtriple=mipsel-unknown-linux-gnu -O0 --disable-machine-licm -mcpu=mips32 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mipsel-unknown-linux-gnu -O0 --disable-machine-licm -mcpu=mips32 -relocation-model=pic -verify-machineinstrs < %s | \ + ; RUN: FileCheck %s -check-prefix=MIPS32O0 +-; RUN: llc -mtriple=mipsel-unknown-linux-gnu --disable-machine-licm -mcpu=mips32r2 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mipsel-unknown-linux-gnu --disable-machine-licm -mcpu=mips32r2 -relocation-model=pic -verify-machineinstrs < %s | \ + ; RUN: FileCheck %s -check-prefix=MIPS32R2 +-; RUN: llc -mtriple=mipsel-unknown-linux-gnu --disable-machine-licm -mcpu=mips32r6 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mipsel-unknown-linux-gnu --disable-machine-licm -mcpu=mips32r6 -relocation-model=pic -verify-machineinstrs < %s | \ + ; RUN: FileCheck %s -check-prefix=MIPS32R6 +-; RUN: llc -mtriple=mipsel-unknown-linux-gnu -O0 --disable-machine-licm -mcpu=mips32r6 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mipsel-unknown-linux-gnu -O0 --disable-machine-licm -mcpu=mips32r6 -relocation-model=pic -verify-machineinstrs < %s | \ + ; RUN: FileCheck %s -check-prefix=MIPS32R6O0 +-; RUN: llc -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips4 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips4 -relocation-model=pic -verify-machineinstrs < %s | \ + ; RUN: FileCheck %s -check-prefix=MIPS4 +-; RUN: llc -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips64 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips64 -relocation-model=pic -verify-machineinstrs < %s | \ + ; RUN: FileCheck %s -check-prefix=MIPS64 +-; RUN: llc -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips64r2 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips64r2 -relocation-model=pic -verify-machineinstrs < %s | \ + ; RUN: FileCheck %s -check-prefix=MIPS64R2 +-; RUN: llc -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips64r6 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips64r6 -relocation-model=pic -verify-machineinstrs < %s | \ + ; RUN: FileCheck %s -check-prefix=MIPS64R6 +-; RUN: llc -mtriple=mips64-unknown-linux-gnu -O0 -mcpu=mips64r6 -relocation-model=pic -verify-machineinstrs -verify-machineinstrs < %s | \ ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mips64-unknown-linux-gnu -O0 -mcpu=mips64r6 -relocation-model=pic -verify-machineinstrs -verify-machineinstrs < %s | \ + ; RUN: FileCheck %s -check-prefix=MIPS64R6O0 +-; RUN: llc -mtriple=mipsel-unknown-linux-gnu --disable-machine-licm -mcpu=mips32r2 -mattr=micromips -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mipsel-unknown-linux-gnu --disable-machine-licm -mcpu=mips32r2 -mattr=micromips -relocation-model=pic -verify-machineinstrs < %s | \ + ; RUN: FileCheck %s -check-prefix=MM32 + + ; We want to verify the produced code is well formed all optimization levels, the rest of the tests which ensure correctness. +-; RUN: llc -mtriple=mipsel-unknown-linux-gnu -O1 --disable-machine-licm -mcpu=mips32 -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s --check-prefix=O1 +-; RUN: llc -mtriple=mipsel-unknown-linux-gnu -O2 --disable-machine-licm -mcpu=mips32 -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s --check-prefix=O2 +-; RUN: llc -mtriple=mipsel-unknown-linux-gnu -O3 --disable-machine-licm -mcpu=mips32 -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s --check-prefix=O3 ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mipsel-unknown-linux-gnu -O1 --disable-machine-licm -mcpu=mips32 -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s --check-prefix=O1 ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mipsel-unknown-linux-gnu -O2 --disable-machine-licm -mcpu=mips32 -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s --check-prefix=O2 ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mipsel-unknown-linux-gnu -O3 --disable-machine-licm -mcpu=mips32 -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s --check-prefix=O3 + + ; Keep one big-endian check so that we don't reduce testing, but don't add more + ; since endianness doesn't affect the body of the atomic operations. +-; RUN: llc -mtriple=mips-unknown-linux-gnu --disable-machine-licm -mcpu=mips32 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mips-unknown-linux-gnu --disable-machine-licm -mcpu=mips32 -relocation-model=pic -verify-machineinstrs < %s | \ + ; RUN: FileCheck %s -check-prefix=MIPS32EB + + @x = common global i32 0, align 4 +diff --git a/llvm/test/CodeGen/Mips/atomic64-fix-loongson3-llsc.ll b/llvm/test/CodeGen/Mips/atomic64-fix-loongson3-llsc.ll +new file mode 100644 +index 000000000..0d06bbaaf +--- /dev/null ++++ b/llvm/test/CodeGen/Mips/atomic64-fix-loongson3-llsc.ll +@@ -0,0 +1,1377 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips4 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: FileCheck %s -check-prefix=MIPS4 ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips64 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: FileCheck %s -check-prefix=MIPS64 ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips64r2 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: FileCheck %s -check-prefix=MIPS64R2 ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips64r6 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: FileCheck %s -check-prefix=MIPS64R6 ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mips64-unknown-linux-gnu -O0 -mcpu=mips64r6 -relocation-model=pic -verify-machineinstrs -verify-machineinstrs < %s | \ ++; RUN: FileCheck %s -check-prefix=MIPS64R6O0 ++ ++; We want to verify the produced code is well formed all optimization levels, the rest of the test which ensure correctness. ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mips64el-unknown-linux-gnu -O1 --disable-machine-licm -mcpu=mips64 -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s --check-prefix=O1 ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mips64el-unknown-linux-gnu -O2 --disable-machine-licm -mcpu=mips64 -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s --check-prefix=O2 ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mips64el-unknown-linux-gnu -O3 --disable-machine-licm -mcpu=mips64 -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s --check-prefix=O3 ++ ++; Keep one big-endian check so that we don't reduce testing, but don't add more ++; since endianness doesn't affect the body of the atomic operations. ++; RUN: llc -mips-fix-loongson3-llsc=1 -mtriple=mips64-unknown-linux-gnu --disable-machine-licm -mcpu=mips64 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: FileCheck %s -check-prefix=MIPS64EB ++ ++@x = common global i64 0, align 4 ++ ++define i64 @AtomicLoadAdd(i64 signext %incr) nounwind { ++; MIPS4-LABEL: AtomicLoadAdd: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd))) ++; MIPS4-NEXT: ld $1, %got_disp(x)($1) ++; MIPS4-NEXT: .LBB0_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: lld $2, 0($1) ++; MIPS4-NEXT: daddu $3, $2, $4 ++; MIPS4-NEXT: scd $3, 0($1) ++; MIPS4-NEXT: beqz $3, .LBB0_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: nop ++; ++; MIPS64-LABEL: AtomicLoadAdd: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd))) ++; MIPS64-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64-NEXT: .LBB0_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: lld $2, 0($1) ++; MIPS64-NEXT: daddu $3, $2, $4 ++; MIPS64-NEXT: scd $3, 0($1) ++; MIPS64-NEXT: beqz $3, .LBB0_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: nop ++; ++; MIPS64R2-LABEL: AtomicLoadAdd: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd))) ++; MIPS64R2-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R2-NEXT: .LBB0_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: lld $2, 0($1) ++; MIPS64R2-NEXT: daddu $3, $2, $4 ++; MIPS64R2-NEXT: scd $3, 0($1) ++; MIPS64R2-NEXT: beqz $3, .LBB0_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: nop ++; ++; MIPS64R6-LABEL: AtomicLoadAdd: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd))) ++; MIPS64R6-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R6-NEXT: .LBB0_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: lld $2, 0($1) ++; MIPS64R6-NEXT: daddu $3, $2, $4 ++; MIPS64R6-NEXT: scd $3, 0($1) ++; MIPS64R6-NEXT: beqzc $3, .LBB0_1 ++; MIPS64R6-NEXT: nop ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: jrc $ra ++; ++; MIPS64R6O0-LABEL: AtomicLoadAdd: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd))) ++; MIPS64R6O0-NEXT: ld $3, %got_disp(x)($1) ++; MIPS64R6O0-NEXT: .LBB0_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: lld $2, 0($3) ++; MIPS64R6O0-NEXT: daddu $1, $2, $4 ++; MIPS64R6O0-NEXT: scd $1, 0($3) ++; MIPS64R6O0-NEXT: beqzc $1, .LBB0_1 ++; MIPS64R6O0-NEXT: nop ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicLoadAdd: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd))) ++; O1-NEXT: daddu $1, $1, $25 ++; O1-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd))) ++; O1-NEXT: ld $1, %got_disp(x)($1) ++; O1-NEXT: .LBB0_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: lld $2, 0($1) ++; O1-NEXT: daddu $3, $2, $4 ++; O1-NEXT: scd $3, 0($1) ++; O1-NEXT: beqz $3, .LBB0_1 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: jr $ra ++; O1-NEXT: nop ++; ++; O2-LABEL: AtomicLoadAdd: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd))) ++; O2-NEXT: daddu $1, $1, $25 ++; O2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd))) ++; O2-NEXT: ld $1, %got_disp(x)($1) ++; O2-NEXT: .LBB0_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: lld $2, 0($1) ++; O2-NEXT: daddu $3, $2, $4 ++; O2-NEXT: scd $3, 0($1) ++; O2-NEXT: beqz $3, .LBB0_1 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: jr $ra ++; O2-NEXT: nop ++; ++; O3-LABEL: AtomicLoadAdd: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd))) ++; O3-NEXT: daddu $1, $1, $25 ++; O3-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd))) ++; O3-NEXT: ld $1, %got_disp(x)($1) ++; O3-NEXT: .LBB0_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: lld $2, 0($1) ++; O3-NEXT: daddu $3, $2, $4 ++; O3-NEXT: scd $3, 0($1) ++; O3-NEXT: beqz $3, .LBB0_1 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: jr $ra ++; O3-NEXT: nop ++; ++; MIPS64EB-LABEL: AtomicLoadAdd: ++; MIPS64EB: # %bb.0: # %entry ++; MIPS64EB-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAdd))) ++; MIPS64EB-NEXT: daddu $1, $1, $25 ++; MIPS64EB-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAdd))) ++; MIPS64EB-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64EB-NEXT: .LBB0_1: # %entry ++; MIPS64EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64EB-NEXT: lld $2, 0($1) ++; MIPS64EB-NEXT: daddu $3, $2, $4 ++; MIPS64EB-NEXT: scd $3, 0($1) ++; MIPS64EB-NEXT: beqz $3, .LBB0_1 ++; MIPS64EB-NEXT: nop ++; MIPS64EB-NEXT: # %bb.2: # %entry ++; MIPS64EB-NEXT: jr $ra ++; MIPS64EB-NEXT: nop ++entry: ++ %0 = atomicrmw add ptr @x, i64 %incr monotonic ++ ret i64 %0 ++ ++} ++ ++define i64 @AtomicLoadSub(i64 signext %incr) nounwind { ++; MIPS4-LABEL: AtomicLoadSub: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadSub))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadSub))) ++; MIPS4-NEXT: ld $1, %got_disp(x)($1) ++; MIPS4-NEXT: .LBB1_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: lld $2, 0($1) ++; MIPS4-NEXT: dsubu $3, $2, $4 ++; MIPS4-NEXT: scd $3, 0($1) ++; MIPS4-NEXT: beqz $3, .LBB1_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: nop ++; ++; MIPS64-LABEL: AtomicLoadSub: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadSub))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadSub))) ++; MIPS64-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64-NEXT: .LBB1_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: lld $2, 0($1) ++; MIPS64-NEXT: dsubu $3, $2, $4 ++; MIPS64-NEXT: scd $3, 0($1) ++; MIPS64-NEXT: beqz $3, .LBB1_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: nop ++; ++; MIPS64R2-LABEL: AtomicLoadSub: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadSub))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadSub))) ++; MIPS64R2-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R2-NEXT: .LBB1_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: lld $2, 0($1) ++; MIPS64R2-NEXT: dsubu $3, $2, $4 ++; MIPS64R2-NEXT: scd $3, 0($1) ++; MIPS64R2-NEXT: beqz $3, .LBB1_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: nop ++; ++; MIPS64R6-LABEL: AtomicLoadSub: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadSub))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadSub))) ++; MIPS64R6-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R6-NEXT: .LBB1_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: lld $2, 0($1) ++; MIPS64R6-NEXT: dsubu $3, $2, $4 ++; MIPS64R6-NEXT: scd $3, 0($1) ++; MIPS64R6-NEXT: beqzc $3, .LBB1_1 ++; MIPS64R6-NEXT: nop ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: jrc $ra ++; ++; MIPS64R6O0-LABEL: AtomicLoadSub: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadSub))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadSub))) ++; MIPS64R6O0-NEXT: ld $3, %got_disp(x)($1) ++; MIPS64R6O0-NEXT: .LBB1_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: lld $2, 0($3) ++; MIPS64R6O0-NEXT: dsubu $1, $2, $4 ++; MIPS64R6O0-NEXT: scd $1, 0($3) ++; MIPS64R6O0-NEXT: beqzc $1, .LBB1_1 ++; MIPS64R6O0-NEXT: nop ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicLoadSub: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadSub))) ++; O1-NEXT: daddu $1, $1, $25 ++; O1-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadSub))) ++; O1-NEXT: ld $1, %got_disp(x)($1) ++; O1-NEXT: .LBB1_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: lld $2, 0($1) ++; O1-NEXT: dsubu $3, $2, $4 ++; O1-NEXT: scd $3, 0($1) ++; O1-NEXT: beqz $3, .LBB1_1 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: jr $ra ++; O1-NEXT: nop ++; ++; O2-LABEL: AtomicLoadSub: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadSub))) ++; O2-NEXT: daddu $1, $1, $25 ++; O2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadSub))) ++; O2-NEXT: ld $1, %got_disp(x)($1) ++; O2-NEXT: .LBB1_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: lld $2, 0($1) ++; O2-NEXT: dsubu $3, $2, $4 ++; O2-NEXT: scd $3, 0($1) ++; O2-NEXT: beqz $3, .LBB1_1 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: jr $ra ++; O2-NEXT: nop ++; ++; O3-LABEL: AtomicLoadSub: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadSub))) ++; O3-NEXT: daddu $1, $1, $25 ++; O3-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadSub))) ++; O3-NEXT: ld $1, %got_disp(x)($1) ++; O3-NEXT: .LBB1_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: lld $2, 0($1) ++; O3-NEXT: dsubu $3, $2, $4 ++; O3-NEXT: scd $3, 0($1) ++; O3-NEXT: beqz $3, .LBB1_1 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: jr $ra ++; O3-NEXT: nop ++; ++; MIPS64EB-LABEL: AtomicLoadSub: ++; MIPS64EB: # %bb.0: # %entry ++; MIPS64EB-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadSub))) ++; MIPS64EB-NEXT: daddu $1, $1, $25 ++; MIPS64EB-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadSub))) ++; MIPS64EB-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64EB-NEXT: .LBB1_1: # %entry ++; MIPS64EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64EB-NEXT: lld $2, 0($1) ++; MIPS64EB-NEXT: dsubu $3, $2, $4 ++; MIPS64EB-NEXT: scd $3, 0($1) ++; MIPS64EB-NEXT: beqz $3, .LBB1_1 ++; MIPS64EB-NEXT: nop ++; MIPS64EB-NEXT: # %bb.2: # %entry ++; MIPS64EB-NEXT: jr $ra ++; MIPS64EB-NEXT: nop ++entry: ++ %0 = atomicrmw sub ptr @x, i64 %incr monotonic ++ ret i64 %0 ++ ++} ++ ++define i64 @AtomicLoadAnd(i64 signext %incr) nounwind { ++; MIPS4-LABEL: AtomicLoadAnd: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAnd))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAnd))) ++; MIPS4-NEXT: ld $1, %got_disp(x)($1) ++; MIPS4-NEXT: .LBB2_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: lld $2, 0($1) ++; MIPS4-NEXT: and $3, $2, $4 ++; MIPS4-NEXT: scd $3, 0($1) ++; MIPS4-NEXT: beqz $3, .LBB2_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: nop ++; ++; MIPS64-LABEL: AtomicLoadAnd: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAnd))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAnd))) ++; MIPS64-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64-NEXT: .LBB2_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: lld $2, 0($1) ++; MIPS64-NEXT: and $3, $2, $4 ++; MIPS64-NEXT: scd $3, 0($1) ++; MIPS64-NEXT: beqz $3, .LBB2_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: nop ++; ++; MIPS64R2-LABEL: AtomicLoadAnd: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAnd))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAnd))) ++; MIPS64R2-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R2-NEXT: .LBB2_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: lld $2, 0($1) ++; MIPS64R2-NEXT: and $3, $2, $4 ++; MIPS64R2-NEXT: scd $3, 0($1) ++; MIPS64R2-NEXT: beqz $3, .LBB2_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: nop ++; ++; MIPS64R6-LABEL: AtomicLoadAnd: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAnd))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAnd))) ++; MIPS64R6-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R6-NEXT: .LBB2_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: lld $2, 0($1) ++; MIPS64R6-NEXT: and $3, $2, $4 ++; MIPS64R6-NEXT: scd $3, 0($1) ++; MIPS64R6-NEXT: beqzc $3, .LBB2_1 ++; MIPS64R6-NEXT: nop ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: jrc $ra ++; ++; MIPS64R6O0-LABEL: AtomicLoadAnd: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAnd))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAnd))) ++; MIPS64R6O0-NEXT: ld $3, %got_disp(x)($1) ++; MIPS64R6O0-NEXT: .LBB2_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: lld $2, 0($3) ++; MIPS64R6O0-NEXT: and $1, $2, $4 ++; MIPS64R6O0-NEXT: scd $1, 0($3) ++; MIPS64R6O0-NEXT: beqzc $1, .LBB2_1 ++; MIPS64R6O0-NEXT: nop ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicLoadAnd: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAnd))) ++; O1-NEXT: daddu $1, $1, $25 ++; O1-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAnd))) ++; O1-NEXT: ld $1, %got_disp(x)($1) ++; O1-NEXT: .LBB2_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: lld $2, 0($1) ++; O1-NEXT: and $3, $2, $4 ++; O1-NEXT: scd $3, 0($1) ++; O1-NEXT: beqz $3, .LBB2_1 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: jr $ra ++; O1-NEXT: nop ++; ++; O2-LABEL: AtomicLoadAnd: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAnd))) ++; O2-NEXT: daddu $1, $1, $25 ++; O2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAnd))) ++; O2-NEXT: ld $1, %got_disp(x)($1) ++; O2-NEXT: .LBB2_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: lld $2, 0($1) ++; O2-NEXT: and $3, $2, $4 ++; O2-NEXT: scd $3, 0($1) ++; O2-NEXT: beqz $3, .LBB2_1 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: jr $ra ++; O2-NEXT: nop ++; ++; O3-LABEL: AtomicLoadAnd: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAnd))) ++; O3-NEXT: daddu $1, $1, $25 ++; O3-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAnd))) ++; O3-NEXT: ld $1, %got_disp(x)($1) ++; O3-NEXT: .LBB2_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: lld $2, 0($1) ++; O3-NEXT: and $3, $2, $4 ++; O3-NEXT: scd $3, 0($1) ++; O3-NEXT: beqz $3, .LBB2_1 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: jr $ra ++; O3-NEXT: nop ++; ++; MIPS64EB-LABEL: AtomicLoadAnd: ++; MIPS64EB: # %bb.0: # %entry ++; MIPS64EB-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadAnd))) ++; MIPS64EB-NEXT: daddu $1, $1, $25 ++; MIPS64EB-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadAnd))) ++; MIPS64EB-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64EB-NEXT: .LBB2_1: # %entry ++; MIPS64EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64EB-NEXT: lld $2, 0($1) ++; MIPS64EB-NEXT: and $3, $2, $4 ++; MIPS64EB-NEXT: scd $3, 0($1) ++; MIPS64EB-NEXT: beqz $3, .LBB2_1 ++; MIPS64EB-NEXT: nop ++; MIPS64EB-NEXT: # %bb.2: # %entry ++; MIPS64EB-NEXT: jr $ra ++; MIPS64EB-NEXT: nop ++entry: ++ %0 = atomicrmw and ptr @x, i64 %incr monotonic ++ ret i64 %0 ++ ++} ++ ++define i64 @AtomicLoadOr(i64 signext %incr) nounwind { ++; MIPS4-LABEL: AtomicLoadOr: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadOr))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadOr))) ++; MIPS4-NEXT: ld $1, %got_disp(x)($1) ++; MIPS4-NEXT: .LBB3_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: lld $2, 0($1) ++; MIPS4-NEXT: or $3, $2, $4 ++; MIPS4-NEXT: scd $3, 0($1) ++; MIPS4-NEXT: beqz $3, .LBB3_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: nop ++; ++; MIPS64-LABEL: AtomicLoadOr: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadOr))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadOr))) ++; MIPS64-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64-NEXT: .LBB3_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: lld $2, 0($1) ++; MIPS64-NEXT: or $3, $2, $4 ++; MIPS64-NEXT: scd $3, 0($1) ++; MIPS64-NEXT: beqz $3, .LBB3_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: nop ++; ++; MIPS64R2-LABEL: AtomicLoadOr: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadOr))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadOr))) ++; MIPS64R2-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R2-NEXT: .LBB3_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: lld $2, 0($1) ++; MIPS64R2-NEXT: or $3, $2, $4 ++; MIPS64R2-NEXT: scd $3, 0($1) ++; MIPS64R2-NEXT: beqz $3, .LBB3_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: nop ++; ++; MIPS64R6-LABEL: AtomicLoadOr: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadOr))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadOr))) ++; MIPS64R6-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R6-NEXT: .LBB3_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: lld $2, 0($1) ++; MIPS64R6-NEXT: or $3, $2, $4 ++; MIPS64R6-NEXT: scd $3, 0($1) ++; MIPS64R6-NEXT: beqzc $3, .LBB3_1 ++; MIPS64R6-NEXT: nop ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: jrc $ra ++; ++; MIPS64R6O0-LABEL: AtomicLoadOr: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadOr))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadOr))) ++; MIPS64R6O0-NEXT: ld $3, %got_disp(x)($1) ++; MIPS64R6O0-NEXT: .LBB3_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: lld $2, 0($3) ++; MIPS64R6O0-NEXT: or $1, $2, $4 ++; MIPS64R6O0-NEXT: scd $1, 0($3) ++; MIPS64R6O0-NEXT: beqzc $1, .LBB3_1 ++; MIPS64R6O0-NEXT: nop ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicLoadOr: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadOr))) ++; O1-NEXT: daddu $1, $1, $25 ++; O1-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadOr))) ++; O1-NEXT: ld $1, %got_disp(x)($1) ++; O1-NEXT: .LBB3_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: lld $2, 0($1) ++; O1-NEXT: or $3, $2, $4 ++; O1-NEXT: scd $3, 0($1) ++; O1-NEXT: beqz $3, .LBB3_1 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: jr $ra ++; O1-NEXT: nop ++; ++; O2-LABEL: AtomicLoadOr: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadOr))) ++; O2-NEXT: daddu $1, $1, $25 ++; O2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadOr))) ++; O2-NEXT: ld $1, %got_disp(x)($1) ++; O2-NEXT: .LBB3_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: lld $2, 0($1) ++; O2-NEXT: or $3, $2, $4 ++; O2-NEXT: scd $3, 0($1) ++; O2-NEXT: beqz $3, .LBB3_1 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: jr $ra ++; O2-NEXT: nop ++; ++; O3-LABEL: AtomicLoadOr: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadOr))) ++; O3-NEXT: daddu $1, $1, $25 ++; O3-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadOr))) ++; O3-NEXT: ld $1, %got_disp(x)($1) ++; O3-NEXT: .LBB3_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: lld $2, 0($1) ++; O3-NEXT: or $3, $2, $4 ++; O3-NEXT: scd $3, 0($1) ++; O3-NEXT: beqz $3, .LBB3_1 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: jr $ra ++; O3-NEXT: nop ++; ++; MIPS64EB-LABEL: AtomicLoadOr: ++; MIPS64EB: # %bb.0: # %entry ++; MIPS64EB-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadOr))) ++; MIPS64EB-NEXT: daddu $1, $1, $25 ++; MIPS64EB-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadOr))) ++; MIPS64EB-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64EB-NEXT: .LBB3_1: # %entry ++; MIPS64EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64EB-NEXT: lld $2, 0($1) ++; MIPS64EB-NEXT: or $3, $2, $4 ++; MIPS64EB-NEXT: scd $3, 0($1) ++; MIPS64EB-NEXT: beqz $3, .LBB3_1 ++; MIPS64EB-NEXT: nop ++; MIPS64EB-NEXT: # %bb.2: # %entry ++; MIPS64EB-NEXT: jr $ra ++; MIPS64EB-NEXT: nop ++entry: ++ %0 = atomicrmw or ptr @x, i64 %incr monotonic ++ ret i64 %0 ++ ++} ++ ++define i64 @AtomicLoadXor(i64 signext %incr) nounwind { ++; MIPS4-LABEL: AtomicLoadXor: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadXor))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadXor))) ++; MIPS4-NEXT: ld $1, %got_disp(x)($1) ++; MIPS4-NEXT: .LBB4_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: lld $2, 0($1) ++; MIPS4-NEXT: xor $3, $2, $4 ++; MIPS4-NEXT: scd $3, 0($1) ++; MIPS4-NEXT: beqz $3, .LBB4_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: nop ++; ++; MIPS64-LABEL: AtomicLoadXor: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadXor))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadXor))) ++; MIPS64-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64-NEXT: .LBB4_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: lld $2, 0($1) ++; MIPS64-NEXT: xor $3, $2, $4 ++; MIPS64-NEXT: scd $3, 0($1) ++; MIPS64-NEXT: beqz $3, .LBB4_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: nop ++; ++; MIPS64R2-LABEL: AtomicLoadXor: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadXor))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadXor))) ++; MIPS64R2-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R2-NEXT: .LBB4_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: lld $2, 0($1) ++; MIPS64R2-NEXT: xor $3, $2, $4 ++; MIPS64R2-NEXT: scd $3, 0($1) ++; MIPS64R2-NEXT: beqz $3, .LBB4_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: nop ++; ++; MIPS64R6-LABEL: AtomicLoadXor: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadXor))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadXor))) ++; MIPS64R6-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R6-NEXT: .LBB4_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: lld $2, 0($1) ++; MIPS64R6-NEXT: xor $3, $2, $4 ++; MIPS64R6-NEXT: scd $3, 0($1) ++; MIPS64R6-NEXT: beqzc $3, .LBB4_1 ++; MIPS64R6-NEXT: nop ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: jrc $ra ++; ++; MIPS64R6O0-LABEL: AtomicLoadXor: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadXor))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadXor))) ++; MIPS64R6O0-NEXT: ld $3, %got_disp(x)($1) ++; MIPS64R6O0-NEXT: .LBB4_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: lld $2, 0($3) ++; MIPS64R6O0-NEXT: xor $1, $2, $4 ++; MIPS64R6O0-NEXT: scd $1, 0($3) ++; MIPS64R6O0-NEXT: beqzc $1, .LBB4_1 ++; MIPS64R6O0-NEXT: nop ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicLoadXor: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadXor))) ++; O1-NEXT: daddu $1, $1, $25 ++; O1-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadXor))) ++; O1-NEXT: ld $1, %got_disp(x)($1) ++; O1-NEXT: .LBB4_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: lld $2, 0($1) ++; O1-NEXT: xor $3, $2, $4 ++; O1-NEXT: scd $3, 0($1) ++; O1-NEXT: beqz $3, .LBB4_1 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: jr $ra ++; O1-NEXT: nop ++; ++; O2-LABEL: AtomicLoadXor: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadXor))) ++; O2-NEXT: daddu $1, $1, $25 ++; O2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadXor))) ++; O2-NEXT: ld $1, %got_disp(x)($1) ++; O2-NEXT: .LBB4_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: lld $2, 0($1) ++; O2-NEXT: xor $3, $2, $4 ++; O2-NEXT: scd $3, 0($1) ++; O2-NEXT: beqz $3, .LBB4_1 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: jr $ra ++; O2-NEXT: nop ++; ++; O3-LABEL: AtomicLoadXor: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadXor))) ++; O3-NEXT: daddu $1, $1, $25 ++; O3-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadXor))) ++; O3-NEXT: ld $1, %got_disp(x)($1) ++; O3-NEXT: .LBB4_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: lld $2, 0($1) ++; O3-NEXT: xor $3, $2, $4 ++; O3-NEXT: scd $3, 0($1) ++; O3-NEXT: beqz $3, .LBB4_1 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: jr $ra ++; O3-NEXT: nop ++; ++; MIPS64EB-LABEL: AtomicLoadXor: ++; MIPS64EB: # %bb.0: # %entry ++; MIPS64EB-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadXor))) ++; MIPS64EB-NEXT: daddu $1, $1, $25 ++; MIPS64EB-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadXor))) ++; MIPS64EB-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64EB-NEXT: .LBB4_1: # %entry ++; MIPS64EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64EB-NEXT: lld $2, 0($1) ++; MIPS64EB-NEXT: xor $3, $2, $4 ++; MIPS64EB-NEXT: scd $3, 0($1) ++; MIPS64EB-NEXT: beqz $3, .LBB4_1 ++; MIPS64EB-NEXT: nop ++; MIPS64EB-NEXT: # %bb.2: # %entry ++; MIPS64EB-NEXT: jr $ra ++; MIPS64EB-NEXT: nop ++entry: ++ %0 = atomicrmw xor ptr @x, i64 %incr monotonic ++ ret i64 %0 ++ ++} ++ ++define i64 @AtomicLoadNand(i64 signext %incr) nounwind { ++; MIPS4-LABEL: AtomicLoadNand: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadNand))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadNand))) ++; MIPS4-NEXT: ld $1, %got_disp(x)($1) ++; MIPS4-NEXT: .LBB5_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: lld $2, 0($1) ++; MIPS4-NEXT: and $3, $2, $4 ++; MIPS4-NEXT: nor $3, $zero, $3 ++; MIPS4-NEXT: scd $3, 0($1) ++; MIPS4-NEXT: beqz $3, .LBB5_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: nop ++; ++; MIPS64-LABEL: AtomicLoadNand: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadNand))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadNand))) ++; MIPS64-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64-NEXT: .LBB5_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: lld $2, 0($1) ++; MIPS64-NEXT: and $3, $2, $4 ++; MIPS64-NEXT: nor $3, $zero, $3 ++; MIPS64-NEXT: scd $3, 0($1) ++; MIPS64-NEXT: beqz $3, .LBB5_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: nop ++; ++; MIPS64R2-LABEL: AtomicLoadNand: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadNand))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadNand))) ++; MIPS64R2-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R2-NEXT: .LBB5_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: lld $2, 0($1) ++; MIPS64R2-NEXT: and $3, $2, $4 ++; MIPS64R2-NEXT: nor $3, $zero, $3 ++; MIPS64R2-NEXT: scd $3, 0($1) ++; MIPS64R2-NEXT: beqz $3, .LBB5_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: nop ++; ++; MIPS64R6-LABEL: AtomicLoadNand: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadNand))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadNand))) ++; MIPS64R6-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R6-NEXT: .LBB5_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: lld $2, 0($1) ++; MIPS64R6-NEXT: and $3, $2, $4 ++; MIPS64R6-NEXT: nor $3, $zero, $3 ++; MIPS64R6-NEXT: scd $3, 0($1) ++; MIPS64R6-NEXT: beqzc $3, .LBB5_1 ++; MIPS64R6-NEXT: nop ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: jrc $ra ++; ++; MIPS64R6O0-LABEL: AtomicLoadNand: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadNand))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadNand))) ++; MIPS64R6O0-NEXT: ld $3, %got_disp(x)($1) ++; MIPS64R6O0-NEXT: .LBB5_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: lld $2, 0($3) ++; MIPS64R6O0-NEXT: and $1, $2, $4 ++; MIPS64R6O0-NEXT: nor $1, $zero, $1 ++; MIPS64R6O0-NEXT: scd $1, 0($3) ++; MIPS64R6O0-NEXT: beqzc $1, .LBB5_1 ++; MIPS64R6O0-NEXT: nop ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicLoadNand: ++; O1: # %bb.0: # %entry ++; O1-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadNand))) ++; O1-NEXT: daddu $1, $1, $25 ++; O1-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadNand))) ++; O1-NEXT: ld $1, %got_disp(x)($1) ++; O1-NEXT: .LBB5_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: lld $2, 0($1) ++; O1-NEXT: and $3, $2, $4 ++; O1-NEXT: nor $3, $zero, $3 ++; O1-NEXT: scd $3, 0($1) ++; O1-NEXT: beqz $3, .LBB5_1 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: jr $ra ++; O1-NEXT: nop ++; ++; O2-LABEL: AtomicLoadNand: ++; O2: # %bb.0: # %entry ++; O2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadNand))) ++; O2-NEXT: daddu $1, $1, $25 ++; O2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadNand))) ++; O2-NEXT: ld $1, %got_disp(x)($1) ++; O2-NEXT: .LBB5_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: lld $2, 0($1) ++; O2-NEXT: and $3, $2, $4 ++; O2-NEXT: nor $3, $zero, $3 ++; O2-NEXT: scd $3, 0($1) ++; O2-NEXT: beqz $3, .LBB5_1 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: jr $ra ++; O2-NEXT: nop ++; ++; O3-LABEL: AtomicLoadNand: ++; O3: # %bb.0: # %entry ++; O3-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadNand))) ++; O3-NEXT: daddu $1, $1, $25 ++; O3-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadNand))) ++; O3-NEXT: ld $1, %got_disp(x)($1) ++; O3-NEXT: .LBB5_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: lld $2, 0($1) ++; O3-NEXT: and $3, $2, $4 ++; O3-NEXT: nor $3, $zero, $3 ++; O3-NEXT: scd $3, 0($1) ++; O3-NEXT: beqz $3, .LBB5_1 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: jr $ra ++; O3-NEXT: nop ++; ++; MIPS64EB-LABEL: AtomicLoadNand: ++; MIPS64EB: # %bb.0: # %entry ++; MIPS64EB-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicLoadNand))) ++; MIPS64EB-NEXT: daddu $1, $1, $25 ++; MIPS64EB-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicLoadNand))) ++; MIPS64EB-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64EB-NEXT: .LBB5_1: # %entry ++; MIPS64EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64EB-NEXT: lld $2, 0($1) ++; MIPS64EB-NEXT: and $3, $2, $4 ++; MIPS64EB-NEXT: nor $3, $zero, $3 ++; MIPS64EB-NEXT: scd $3, 0($1) ++; MIPS64EB-NEXT: beqz $3, .LBB5_1 ++; MIPS64EB-NEXT: nop ++; MIPS64EB-NEXT: # %bb.2: # %entry ++; MIPS64EB-NEXT: jr $ra ++; MIPS64EB-NEXT: nop ++entry: ++ %0 = atomicrmw nand ptr @x, i64 %incr monotonic ++ ret i64 %0 ++ ++} ++ ++define i64 @AtomicSwap64(i64 signext %newval) nounwind { ++; MIPS4-LABEL: AtomicSwap64: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: daddiu $sp, $sp, -16 ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicSwap64))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicSwap64))) ++; MIPS4-NEXT: sd $4, 8($sp) ++; MIPS4-NEXT: ld $1, %got_disp(x)($1) ++; MIPS4-NEXT: .LBB6_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: lld $2, 0($1) ++; MIPS4-NEXT: move $3, $4 ++; MIPS4-NEXT: scd $3, 0($1) ++; MIPS4-NEXT: beqz $3, .LBB6_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: daddiu $sp, $sp, 16 ++; ++; MIPS64-LABEL: AtomicSwap64: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: daddiu $sp, $sp, -16 ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicSwap64))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicSwap64))) ++; MIPS64-NEXT: sd $4, 8($sp) ++; MIPS64-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64-NEXT: .LBB6_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: lld $2, 0($1) ++; MIPS64-NEXT: move $3, $4 ++; MIPS64-NEXT: scd $3, 0($1) ++; MIPS64-NEXT: beqz $3, .LBB6_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: daddiu $sp, $sp, 16 ++; ++; MIPS64R2-LABEL: AtomicSwap64: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: daddiu $sp, $sp, -16 ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicSwap64))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicSwap64))) ++; MIPS64R2-NEXT: sd $4, 8($sp) ++; MIPS64R2-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R2-NEXT: .LBB6_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: lld $2, 0($1) ++; MIPS64R2-NEXT: move $3, $4 ++; MIPS64R2-NEXT: scd $3, 0($1) ++; MIPS64R2-NEXT: beqz $3, .LBB6_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: daddiu $sp, $sp, 16 ++; ++; MIPS64R6-LABEL: AtomicSwap64: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: daddiu $sp, $sp, -16 ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicSwap64))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicSwap64))) ++; MIPS64R6-NEXT: sd $4, 8($sp) ++; MIPS64R6-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R6-NEXT: .LBB6_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: lld $2, 0($1) ++; MIPS64R6-NEXT: move $3, $4 ++; MIPS64R6-NEXT: scd $3, 0($1) ++; MIPS64R6-NEXT: beqzc $3, .LBB6_1 ++; MIPS64R6-NEXT: nop ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: jr $ra ++; MIPS64R6-NEXT: daddiu $sp, $sp, 16 ++; ++; MIPS64R6O0-LABEL: AtomicSwap64: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, -16 ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicSwap64))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicSwap64))) ++; MIPS64R6O0-NEXT: sd $4, 8($sp) ++; MIPS64R6O0-NEXT: ld $4, 8($sp) ++; MIPS64R6O0-NEXT: ld $3, %got_disp(x)($1) ++; MIPS64R6O0-NEXT: .LBB6_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: lld $2, 0($3) ++; MIPS64R6O0-NEXT: move $1, $4 ++; MIPS64R6O0-NEXT: scd $1, 0($3) ++; MIPS64R6O0-NEXT: beqzc $1, .LBB6_1 ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, 16 ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicSwap64: ++; O1: # %bb.0: # %entry ++; O1-NEXT: daddiu $sp, $sp, -16 ++; O1-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicSwap64))) ++; O1-NEXT: daddu $1, $1, $25 ++; O1-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicSwap64))) ++; O1-NEXT: sd $4, 8($sp) ++; O1-NEXT: ld $1, %got_disp(x)($1) ++; O1-NEXT: .LBB6_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: lld $2, 0($1) ++; O1-NEXT: move $3, $4 ++; O1-NEXT: scd $3, 0($1) ++; O1-NEXT: beqz $3, .LBB6_1 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: jr $ra ++; O1-NEXT: daddiu $sp, $sp, 16 ++; ++; O2-LABEL: AtomicSwap64: ++; O2: # %bb.0: # %entry ++; O2-NEXT: daddiu $sp, $sp, -16 ++; O2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicSwap64))) ++; O2-NEXT: daddu $1, $1, $25 ++; O2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicSwap64))) ++; O2-NEXT: sd $4, 8($sp) ++; O2-NEXT: ld $1, %got_disp(x)($1) ++; O2-NEXT: .LBB6_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: lld $2, 0($1) ++; O2-NEXT: move $3, $4 ++; O2-NEXT: scd $3, 0($1) ++; O2-NEXT: beqz $3, .LBB6_1 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: jr $ra ++; O2-NEXT: daddiu $sp, $sp, 16 ++; ++; O3-LABEL: AtomicSwap64: ++; O3: # %bb.0: # %entry ++; O3-NEXT: daddiu $sp, $sp, -16 ++; O3-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicSwap64))) ++; O3-NEXT: sd $4, 8($sp) ++; O3-NEXT: daddu $1, $1, $25 ++; O3-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicSwap64))) ++; O3-NEXT: ld $1, %got_disp(x)($1) ++; O3-NEXT: .LBB6_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: lld $2, 0($1) ++; O3-NEXT: move $3, $4 ++; O3-NEXT: scd $3, 0($1) ++; O3-NEXT: beqz $3, .LBB6_1 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: jr $ra ++; O3-NEXT: daddiu $sp, $sp, 16 ++; ++; MIPS64EB-LABEL: AtomicSwap64: ++; MIPS64EB: # %bb.0: # %entry ++; MIPS64EB-NEXT: daddiu $sp, $sp, -16 ++; MIPS64EB-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicSwap64))) ++; MIPS64EB-NEXT: daddu $1, $1, $25 ++; MIPS64EB-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicSwap64))) ++; MIPS64EB-NEXT: sd $4, 8($sp) ++; MIPS64EB-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64EB-NEXT: .LBB6_1: # %entry ++; MIPS64EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64EB-NEXT: lld $2, 0($1) ++; MIPS64EB-NEXT: move $3, $4 ++; MIPS64EB-NEXT: scd $3, 0($1) ++; MIPS64EB-NEXT: beqz $3, .LBB6_1 ++; MIPS64EB-NEXT: nop ++; MIPS64EB-NEXT: # %bb.2: # %entry ++; MIPS64EB-NEXT: jr $ra ++; MIPS64EB-NEXT: daddiu $sp, $sp, 16 ++entry: ++ %newval.addr = alloca i64, align 8 ++ store i64 %newval, ptr %newval.addr, align 4 ++ %tmp = load i64, ptr %newval.addr, align 4 ++ %0 = atomicrmw xchg ptr @x, i64 %tmp monotonic ++ ret i64 %0 ++ ++} ++ ++define i64 @AtomicCmpSwap64(i64 signext %oldval, i64 signext %newval) nounwind { ++; MIPS4-LABEL: AtomicCmpSwap64: ++; MIPS4: # %bb.0: # %entry ++; MIPS4-NEXT: daddiu $sp, $sp, -16 ++; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicCmpSwap64))) ++; MIPS4-NEXT: daddu $1, $1, $25 ++; MIPS4-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicCmpSwap64))) ++; MIPS4-NEXT: sd $5, 8($sp) ++; MIPS4-NEXT: ld $1, %got_disp(x)($1) ++; MIPS4-NEXT: .LBB7_1: # %entry ++; MIPS4-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS4-NEXT: lld $2, 0($1) ++; MIPS4-NEXT: bne $2, $4, .LBB7_3 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: # %bb.2: # %entry ++; MIPS4-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; MIPS4-NEXT: move $3, $5 ++; MIPS4-NEXT: scd $3, 0($1) ++; MIPS4-NEXT: beqz $3, .LBB7_1 ++; MIPS4-NEXT: nop ++; MIPS4-NEXT: .LBB7_3: # %entry ++; MIPS4-NEXT: sync ++; MIPS4-NEXT: jr $ra ++; MIPS4-NEXT: daddiu $sp, $sp, 16 ++; ++; MIPS64-LABEL: AtomicCmpSwap64: ++; MIPS64: # %bb.0: # %entry ++; MIPS64-NEXT: daddiu $sp, $sp, -16 ++; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicCmpSwap64))) ++; MIPS64-NEXT: daddu $1, $1, $25 ++; MIPS64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicCmpSwap64))) ++; MIPS64-NEXT: sd $5, 8($sp) ++; MIPS64-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64-NEXT: .LBB7_1: # %entry ++; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64-NEXT: lld $2, 0($1) ++; MIPS64-NEXT: bne $2, $4, .LBB7_3 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: # %bb.2: # %entry ++; MIPS64-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; MIPS64-NEXT: move $3, $5 ++; MIPS64-NEXT: scd $3, 0($1) ++; MIPS64-NEXT: beqz $3, .LBB7_1 ++; MIPS64-NEXT: nop ++; MIPS64-NEXT: .LBB7_3: # %entry ++; MIPS64-NEXT: sync ++; MIPS64-NEXT: jr $ra ++; MIPS64-NEXT: daddiu $sp, $sp, 16 ++; ++; MIPS64R2-LABEL: AtomicCmpSwap64: ++; MIPS64R2: # %bb.0: # %entry ++; MIPS64R2-NEXT: daddiu $sp, $sp, -16 ++; MIPS64R2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicCmpSwap64))) ++; MIPS64R2-NEXT: daddu $1, $1, $25 ++; MIPS64R2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicCmpSwap64))) ++; MIPS64R2-NEXT: sd $5, 8($sp) ++; MIPS64R2-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R2-NEXT: .LBB7_1: # %entry ++; MIPS64R2-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R2-NEXT: lld $2, 0($1) ++; MIPS64R2-NEXT: bne $2, $4, .LBB7_3 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: # %bb.2: # %entry ++; MIPS64R2-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; MIPS64R2-NEXT: move $3, $5 ++; MIPS64R2-NEXT: scd $3, 0($1) ++; MIPS64R2-NEXT: beqz $3, .LBB7_1 ++; MIPS64R2-NEXT: nop ++; MIPS64R2-NEXT: .LBB7_3: # %entry ++; MIPS64R2-NEXT: sync ++; MIPS64R2-NEXT: jr $ra ++; MIPS64R2-NEXT: daddiu $sp, $sp, 16 ++; ++; MIPS64R6-LABEL: AtomicCmpSwap64: ++; MIPS64R6: # %bb.0: # %entry ++; MIPS64R6-NEXT: daddiu $sp, $sp, -16 ++; MIPS64R6-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicCmpSwap64))) ++; MIPS64R6-NEXT: daddu $1, $1, $25 ++; MIPS64R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicCmpSwap64))) ++; MIPS64R6-NEXT: sd $5, 8($sp) ++; MIPS64R6-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64R6-NEXT: .LBB7_1: # %entry ++; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6-NEXT: lld $2, 0($1) ++; MIPS64R6-NEXT: bnec $2, $4, .LBB7_3 ++; MIPS64R6-NEXT: # %bb.2: # %entry ++; MIPS64R6-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; MIPS64R6-NEXT: move $3, $5 ++; MIPS64R6-NEXT: scd $3, 0($1) ++; MIPS64R6-NEXT: beqzc $3, .LBB7_1 ++; MIPS64R6-NEXT: .LBB7_3: # %entry ++; MIPS64R6-NEXT: sync ++; MIPS64R6-NEXT: jr $ra ++; MIPS64R6-NEXT: daddiu $sp, $sp, 16 ++; ++; MIPS64R6O0-LABEL: AtomicCmpSwap64: ++; MIPS64R6O0: # %bb.0: # %entry ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, -16 ++; MIPS64R6O0-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicCmpSwap64))) ++; MIPS64R6O0-NEXT: daddu $1, $1, $25 ++; MIPS64R6O0-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicCmpSwap64))) ++; MIPS64R6O0-NEXT: sd $5, 8($sp) ++; MIPS64R6O0-NEXT: ld $5, 8($sp) ++; MIPS64R6O0-NEXT: ld $3, %got_disp(x)($1) ++; MIPS64R6O0-NEXT: .LBB7_1: # %entry ++; MIPS64R6O0-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64R6O0-NEXT: lld $2, 0($3) ++; MIPS64R6O0-NEXT: bnec $2, $4, .LBB7_3 ++; MIPS64R6O0-NEXT: # %bb.2: # %entry ++; MIPS64R6O0-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; MIPS64R6O0-NEXT: move $1, $5 ++; MIPS64R6O0-NEXT: scd $1, 0($3) ++; MIPS64R6O0-NEXT: beqzc $1, .LBB7_1 ++; MIPS64R6O0-NEXT: .LBB7_3: # %entry ++; MIPS64R6O0-NEXT: sync ++; MIPS64R6O0-NEXT: daddiu $sp, $sp, 16 ++; MIPS64R6O0-NEXT: jrc $ra ++; ++; O1-LABEL: AtomicCmpSwap64: ++; O1: # %bb.0: # %entry ++; O1-NEXT: daddiu $sp, $sp, -16 ++; O1-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicCmpSwap64))) ++; O1-NEXT: daddu $1, $1, $25 ++; O1-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicCmpSwap64))) ++; O1-NEXT: sd $5, 8($sp) ++; O1-NEXT: ld $1, %got_disp(x)($1) ++; O1-NEXT: .LBB7_1: # %entry ++; O1-NEXT: # =>This Inner Loop Header: Depth=1 ++; O1-NEXT: lld $2, 0($1) ++; O1-NEXT: bne $2, $4, .LBB7_3 ++; O1-NEXT: nop ++; O1-NEXT: # %bb.2: # %entry ++; O1-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; O1-NEXT: move $3, $5 ++; O1-NEXT: scd $3, 0($1) ++; O1-NEXT: beqz $3, .LBB7_1 ++; O1-NEXT: nop ++; O1-NEXT: .LBB7_3: # %entry ++; O1-NEXT: sync ++; O1-NEXT: jr $ra ++; O1-NEXT: daddiu $sp, $sp, 16 ++; ++; O2-LABEL: AtomicCmpSwap64: ++; O2: # %bb.0: # %entry ++; O2-NEXT: daddiu $sp, $sp, -16 ++; O2-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicCmpSwap64))) ++; O2-NEXT: daddu $1, $1, $25 ++; O2-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicCmpSwap64))) ++; O2-NEXT: sd $5, 8($sp) ++; O2-NEXT: ld $1, %got_disp(x)($1) ++; O2-NEXT: .LBB7_1: # %entry ++; O2-NEXT: # =>This Inner Loop Header: Depth=1 ++; O2-NEXT: lld $2, 0($1) ++; O2-NEXT: bne $2, $4, .LBB7_3 ++; O2-NEXT: nop ++; O2-NEXT: # %bb.2: # %entry ++; O2-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; O2-NEXT: move $3, $5 ++; O2-NEXT: scd $3, 0($1) ++; O2-NEXT: beqz $3, .LBB7_1 ++; O2-NEXT: nop ++; O2-NEXT: .LBB7_3: # %entry ++; O2-NEXT: sync ++; O2-NEXT: jr $ra ++; O2-NEXT: daddiu $sp, $sp, 16 ++; ++; O3-LABEL: AtomicCmpSwap64: ++; O3: # %bb.0: # %entry ++; O3-NEXT: daddiu $sp, $sp, -16 ++; O3-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicCmpSwap64))) ++; O3-NEXT: sd $5, 8($sp) ++; O3-NEXT: daddu $1, $1, $25 ++; O3-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicCmpSwap64))) ++; O3-NEXT: ld $1, %got_disp(x)($1) ++; O3-NEXT: .LBB7_1: # %entry ++; O3-NEXT: # =>This Inner Loop Header: Depth=1 ++; O3-NEXT: lld $2, 0($1) ++; O3-NEXT: bne $2, $4, .LBB7_3 ++; O3-NEXT: nop ++; O3-NEXT: # %bb.2: # %entry ++; O3-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; O3-NEXT: move $3, $5 ++; O3-NEXT: scd $3, 0($1) ++; O3-NEXT: beqz $3, .LBB7_1 ++; O3-NEXT: nop ++; O3-NEXT: .LBB7_3: # %entry ++; O3-NEXT: sync ++; O3-NEXT: jr $ra ++; O3-NEXT: daddiu $sp, $sp, 16 ++; ++; MIPS64EB-LABEL: AtomicCmpSwap64: ++; MIPS64EB: # %bb.0: # %entry ++; MIPS64EB-NEXT: daddiu $sp, $sp, -16 ++; MIPS64EB-NEXT: lui $1, %hi(%neg(%gp_rel(AtomicCmpSwap64))) ++; MIPS64EB-NEXT: daddu $1, $1, $25 ++; MIPS64EB-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(AtomicCmpSwap64))) ++; MIPS64EB-NEXT: sd $5, 8($sp) ++; MIPS64EB-NEXT: ld $1, %got_disp(x)($1) ++; MIPS64EB-NEXT: .LBB7_1: # %entry ++; MIPS64EB-NEXT: # =>This Inner Loop Header: Depth=1 ++; MIPS64EB-NEXT: lld $2, 0($1) ++; MIPS64EB-NEXT: bne $2, $4, .LBB7_3 ++; MIPS64EB-NEXT: nop ++; MIPS64EB-NEXT: # %bb.2: # %entry ++; MIPS64EB-NEXT: # in Loop: Header=BB7_1 Depth=1 ++; MIPS64EB-NEXT: move $3, $5 ++; MIPS64EB-NEXT: scd $3, 0($1) ++; MIPS64EB-NEXT: beqz $3, .LBB7_1 ++; MIPS64EB-NEXT: nop ++; MIPS64EB-NEXT: .LBB7_3: # %entry ++; MIPS64EB-NEXT: sync ++; MIPS64EB-NEXT: jr $ra ++; MIPS64EB-NEXT: daddiu $sp, $sp, 16 ++entry: ++ %newval.addr = alloca i64, align 8 ++ store i64 %newval, ptr %newval.addr, align 4 ++ %tmp = load i64, ptr %newval.addr, align 4 ++ %0 = cmpxchg ptr @x, i64 %oldval, i64 %tmp monotonic monotonic ++ %1 = extractvalue { i64, i1 } %0, 0 ++ ret i64 %1 ++ ++} +diff --git a/llvm/test/CodeGen/Mips/atomic64.ll b/llvm/test/CodeGen/Mips/atomic64.ll +index 8d9c1ca86..9371073a5 100644 +--- a/llvm/test/CodeGen/Mips/atomic64.ll ++++ b/llvm/test/CodeGen/Mips/atomic64.ll +@@ -1,23 +1,23 @@ + ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips4 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips4 -relocation-model=pic -verify-machineinstrs < %s | \ + ; RUN: FileCheck %s -check-prefix=MIPS4 +-; RUN: llc -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips64 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips64 -relocation-model=pic -verify-machineinstrs < %s | \ + ; RUN: FileCheck %s -check-prefix=MIPS64 +-; RUN: llc -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips64r2 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips64r2 -relocation-model=pic -verify-machineinstrs < %s | \ + ; RUN: FileCheck %s -check-prefix=MIPS64R2 +-; RUN: llc -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips64r6 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mips64el-unknown-linux-gnu --disable-machine-licm -mcpu=mips64r6 -relocation-model=pic -verify-machineinstrs < %s | \ + ; RUN: FileCheck %s -check-prefix=MIPS64R6 +-; RUN: llc -mtriple=mips64-unknown-linux-gnu -O0 -mcpu=mips64r6 -relocation-model=pic -verify-machineinstrs -verify-machineinstrs < %s | \ ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mips64-unknown-linux-gnu -O0 -mcpu=mips64r6 -relocation-model=pic -verify-machineinstrs -verify-machineinstrs < %s | \ + ; RUN: FileCheck %s -check-prefix=MIPS64R6O0 + + ; We want to verify the produced code is well formed all optimization levels, the rest of the test which ensure correctness. +-; RUN: llc -mtriple=mips64el-unknown-linux-gnu -O1 --disable-machine-licm -mcpu=mips64 -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s --check-prefix=O1 +-; RUN: llc -mtriple=mips64el-unknown-linux-gnu -O2 --disable-machine-licm -mcpu=mips64 -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s --check-prefix=O2 +-; RUN: llc -mtriple=mips64el-unknown-linux-gnu -O3 --disable-machine-licm -mcpu=mips64 -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s --check-prefix=O3 ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mips64el-unknown-linux-gnu -O1 --disable-machine-licm -mcpu=mips64 -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s --check-prefix=O1 ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mips64el-unknown-linux-gnu -O2 --disable-machine-licm -mcpu=mips64 -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s --check-prefix=O2 ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mips64el-unknown-linux-gnu -O3 --disable-machine-licm -mcpu=mips64 -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s --check-prefix=O3 + + ; Keep one big-endian check so that we don't reduce testing, but don't add more + ; since endianness doesn't affect the body of the atomic operations. +-; RUN: llc -mtriple=mips64-unknown-linux-gnu --disable-machine-licm -mcpu=mips64 -relocation-model=pic -verify-machineinstrs < %s | \ ++; RUN: llc -mips-fix-loongson3-llsc=0 -mtriple=mips64-unknown-linux-gnu --disable-machine-licm -mcpu=mips64 -relocation-model=pic -verify-machineinstrs < %s | \ + ; RUN: FileCheck %s -check-prefix=MIPS64EB + + @x = common global i64 0, align 4 +diff --git a/llvm/test/CodeGen/Mips/madd-msub.ll b/llvm/test/CodeGen/Mips/madd-msub.ll +index 9f7145685..3a6fd68e9 100644 +--- a/llvm/test/CodeGen/Mips/madd-msub.ll ++++ b/llvm/test/CodeGen/Mips/madd-msub.ll +@@ -42,22 +42,22 @@ define i64 @madd1(i32 %a, i32 %b, i32 %c) nounwind readnone { + ; + ; 64-LABEL: madd1: + ; 64: # %bb.0: # %entry +-; 64-NEXT: sll $4, $4, 0 +-; 64-NEXT: sll $5, $5, 0 +-; 64-NEXT: dmult $5, $4 ++; 64-NEXT: sll $1, $4, 0 ++; 64-NEXT: sll $2, $5, 0 ++; 64-NEXT: dmult $2, $1 + ; 64-NEXT: mflo $1 +-; 64-NEXT: sll $6, $6, 0 ++; 64-NEXT: sll $2, $6, 0 + ; 64-NEXT: jr $ra +-; 64-NEXT: daddu $2, $1, $6 ++; 64-NEXT: daddu $2, $1, $2 + ; + ; 64R6-LABEL: madd1: + ; 64R6: # %bb.0: # %entry +-; 64R6-NEXT: sll $4, $4, 0 +-; 64R6-NEXT: sll $5, $5, 0 +-; 64R6-NEXT: dmul $1, $5, $4 +-; 64R6-NEXT: sll $6, $6, 0 ++; 64R6-NEXT: sll $1, $4, 0 ++; 64R6-NEXT: sll $2, $5, 0 ++; 64R6-NEXT: dmul $1, $2, $1 ++; 64R6-NEXT: sll $2, $6, 0 + ; 64R6-NEXT: jr $ra +-; 64R6-NEXT: daddu $2, $1, $6 ++; 64R6-NEXT: daddu $2, $1, $2 + ; + ; 16-LABEL: madd1: + ; 16: # %bb.0: # %entry +@@ -173,18 +173,18 @@ define i64 @madd3(i32 %a, i32 %b, i64 %c) nounwind readnone { + ; + ; 64-LABEL: madd3: + ; 64: # %bb.0: # %entry +-; 64-NEXT: sll $4, $4, 0 +-; 64-NEXT: sll $5, $5, 0 +-; 64-NEXT: dmult $5, $4 ++; 64-NEXT: sll $1, $4, 0 ++; 64-NEXT: sll $2, $5, 0 ++; 64-NEXT: dmult $2, $1 + ; 64-NEXT: mflo $1 + ; 64-NEXT: jr $ra + ; 64-NEXT: daddu $2, $1, $6 + ; + ; 64R6-LABEL: madd3: + ; 64R6: # %bb.0: # %entry +-; 64R6-NEXT: sll $4, $4, 0 +-; 64R6-NEXT: sll $5, $5, 0 +-; 64R6-NEXT: dmul $1, $5, $4 ++; 64R6-NEXT: sll $1, $4, 0 ++; 64R6-NEXT: sll $2, $5, 0 ++; 64R6-NEXT: dmul $1, $2, $1 + ; 64R6-NEXT: jr $ra + ; 64R6-NEXT: daddu $2, $1, $6 + ; +@@ -291,22 +291,22 @@ define i64 @msub1(i32 %a, i32 %b, i32 %c) nounwind readnone { + ; + ; 64-LABEL: msub1: + ; 64: # %bb.0: # %entry +-; 64-NEXT: sll $4, $4, 0 +-; 64-NEXT: sll $5, $5, 0 +-; 64-NEXT: dmult $5, $4 ++; 64-NEXT: sll $1, $4, 0 ++; 64-NEXT: sll $2, $5, 0 ++; 64-NEXT: dmult $2, $1 + ; 64-NEXT: mflo $1 +-; 64-NEXT: sll $6, $6, 0 ++; 64-NEXT: sll $2, $6, 0 + ; 64-NEXT: jr $ra +-; 64-NEXT: dsubu $2, $6, $1 ++; 64-NEXT: dsubu $2, $2, $1 + ; + ; 64R6-LABEL: msub1: + ; 64R6: # %bb.0: # %entry +-; 64R6-NEXT: sll $4, $4, 0 +-; 64R6-NEXT: sll $5, $5, 0 +-; 64R6-NEXT: dmul $1, $5, $4 +-; 64R6-NEXT: sll $6, $6, 0 ++; 64R6-NEXT: sll $1, $4, 0 ++; 64R6-NEXT: sll $2, $5, 0 ++; 64R6-NEXT: dmul $1, $2, $1 ++; 64R6-NEXT: sll $2, $6, 0 + ; 64R6-NEXT: jr $ra +-; 64R6-NEXT: dsubu $2, $6, $1 ++; 64R6-NEXT: dsubu $2, $2, $1 + ; + ; 16-LABEL: msub1: + ; 16: # %bb.0: # %entry +@@ -424,18 +424,18 @@ define i64 @msub3(i32 %a, i32 %b, i64 %c) nounwind readnone { + ; + ; 64-LABEL: msub3: + ; 64: # %bb.0: # %entry +-; 64-NEXT: sll $4, $4, 0 +-; 64-NEXT: sll $5, $5, 0 +-; 64-NEXT: dmult $5, $4 ++; 64-NEXT: sll $1, $4, 0 ++; 64-NEXT: sll $2, $5, 0 ++; 64-NEXT: dmult $2, $1 + ; 64-NEXT: mflo $1 + ; 64-NEXT: jr $ra + ; 64-NEXT: dsubu $2, $6, $1 + ; + ; 64R6-LABEL: msub3: + ; 64R6: # %bb.0: # %entry +-; 64R6-NEXT: sll $4, $4, 0 +-; 64R6-NEXT: sll $5, $5, 0 +-; 64R6-NEXT: dmul $1, $5, $4 ++; 64R6-NEXT: sll $1, $4, 0 ++; 64R6-NEXT: sll $2, $5, 0 ++; 64R6-NEXT: dmul $1, $2, $1 + ; 64R6-NEXT: jr $ra + ; 64R6-NEXT: dsubu $2, $6, $1 + ; +@@ -546,22 +546,22 @@ define i64 @msub5(i32 %a, i32 %b, i32 %c) { + ; + ; 64-LABEL: msub5: + ; 64: # %bb.0: # %entry +-; 64-NEXT: sll $4, $4, 0 +-; 64-NEXT: sll $5, $5, 0 +-; 64-NEXT: dmult $5, $4 ++; 64-NEXT: sll $1, $4, 0 ++; 64-NEXT: sll $2, $5, 0 ++; 64-NEXT: dmult $2, $1 + ; 64-NEXT: mflo $1 +-; 64-NEXT: sll $6, $6, 0 ++; 64-NEXT: sll $2, $6, 0 + ; 64-NEXT: jr $ra +-; 64-NEXT: dsubu $2, $1, $6 ++; 64-NEXT: dsubu $2, $1, $2 + ; + ; 64R6-LABEL: msub5: + ; 64R6: # %bb.0: # %entry +-; 64R6-NEXT: sll $4, $4, 0 +-; 64R6-NEXT: sll $5, $5, 0 +-; 64R6-NEXT: dmul $1, $5, $4 +-; 64R6-NEXT: sll $6, $6, 0 ++; 64R6-NEXT: sll $1, $4, 0 ++; 64R6-NEXT: sll $2, $5, 0 ++; 64R6-NEXT: dmul $1, $2, $1 ++; 64R6-NEXT: sll $2, $6, 0 + ; 64R6-NEXT: jr $ra +-; 64R6-NEXT: dsubu $2, $1, $6 ++; 64R6-NEXT: dsubu $2, $1, $2 + ; + ; 16-LABEL: msub5: + ; 16: # %bb.0: # %entry +diff --git a/llvm/test/DebugInfo/LoongArch/dwarf-loongarch-relocs.ll b/llvm/test/DebugInfo/LoongArch/dwarf-loongarch-relocs.ll +deleted file mode 100644 +index 07443a62b..000000000 +--- a/llvm/test/DebugInfo/LoongArch/dwarf-loongarch-relocs.ll ++++ /dev/null +@@ -1,137 +0,0 @@ +-; RUN: llc --filetype=obj --mtriple=loongarch64 --mattr=-relax %s -o %t.o +-; RUN: llvm-readobj -r %t.o | FileCheck --check-prefixes=RELOCS-BOTH,RELOCS-NORL %s +-; RUN: llvm-objdump --source %t.o | FileCheck --check-prefixes=SOURCE,SOURCE-NORL %s +-; RUN: llvm-dwarfdump --debug-info --debug-line %t.o | FileCheck --check-prefixes=DWARF,DWARF-NORL %s +- +-; RUN: llc --filetype=obj --mtriple=loongarch64 --mattr=+relax %s -o %t.r.o +-; RUN: llvm-readobj -r %t.r.o | FileCheck --check-prefixes=RELOCS-BOTH,RELOCS-ENRL %s +-; RUN: llvm-objdump --source %t.r.o | FileCheck --check-prefixes=SOURCE,SOURCE-ENRL %s +-; RUN: llvm-dwarfdump --debug-info --debug-line %t.r.o | FileCheck --check-prefixes=DWARF,DWARF-ENRL %s +- +-; RELOCS-BOTH: Relocations [ +-; RELOCS-BOTH-NEXT: Section ({{.*}}) .rela.text { +-; RELOCS-NORL-NEXT: 0x14 R_LARCH_PCALA_HI20 sym 0x0 +-; RELOCS-NORL-NEXT: 0x18 R_LARCH_PCALA_LO12 sym 0x0 +-; RELOCS-ENRL-NEXT: 0x0 R_LARCH_ALIGN .Lla-relax-align0 0x5 +-; RELOCS-ENRL-NEXT: 0x30 R_LARCH_PCALA_HI20 sym 0x0 +-; RELOCS-ENRL-NEXT: 0x30 R_LARCH_RELAX - 0x0 +-; RELOCS-ENRL-NEXT: 0x34 R_LARCH_PCALA_LO12 sym 0x0 +-; RELOCS-ENRL-NEXT: 0x34 R_LARCH_RELAX - 0x0 +-; RELOCS-BOTH-NEXT: } +-; RELOCS-BOTH: Section ({{.*}}) .rela.debug_frame { +-; RELOCS-NORL-NEXT: 0x1C R_LARCH_32 .debug_frame 0x0 +-; RELOCS-NORL-NEXT: 0x20 R_LARCH_64 .text 0x0 +-; RELOCS-ENRL-NEXT: 0x1C R_LARCH_32 0x0 +-; RELOCS-ENRL-NEXT: 0x20 R_LARCH_64 0x0 +-; RELOCS-ENRL-NEXT: 0x28 R_LARCH_ADD64 0x0 +-; RELOCS-ENRL-NEXT: 0x28 R_LARCH_SUB64 0x0 +-; RELOCS-ENRL-NEXT: 0x3F R_LARCH_ADD6 0x0 +-; RELOCS-ENRL-NEXT: 0x3F R_LARCH_SUB6 0x0 +-; RELOCS-BOTH-NEXT: } +-; RELOCS-BOTH: Section ({{.*}}) .rela.debug_line { +-; RELOCS-BOTH-NEXT: 0x22 R_LARCH_32 .debug_line_str 0x0 +-; RELOCS-BOTH-NEXT: 0x31 R_LARCH_32 .debug_line_str 0x2 +-; RELOCS-BOTH-NEXT: 0x46 R_LARCH_32 .debug_line_str 0x1B +-; RELOCS-NORL-NEXT: 0x4F R_LARCH_64 .text 0x0 +-; RELOCS-ENRL-NEXT: 0x4F R_LARCH_64 0x0 +-; RELOCS-ENRL-NEXT: 0x5F R_LARCH_ADD16 0x0 +-; RELOCS-ENRL-NEXT: 0x5F R_LARCH_SUB16 0x0 +-; RELOCS-BOTH-NEXT: } +-; RELOCS-BOTH-NEXT: ] +- +-; SOURCE-NORL: 0000000000000000 : +-; SOURCE-ENRL: 000000000000001c : +-; SOURCE: ; { +-; SOURCE: ; asm volatile( +-; SOURCE: ; return 0; +- +-; DWARF: DW_AT_producer ("clang") +-; DWARF: DW_AT_name ("dwarf-loongarch-relocs.c") +-; DWARF: DW_AT_comp_dir (".") +-; DWARF: DW_AT_name ("foo") +-; DWARF-NEXT: DW_AT_decl_file ("{{.*}}dwarf-loongarch-relocs.c") +-; DWARF-NEXT: DW_AT_decl_line (1) +-; DWARF-NEXT: DW_AT_type (0x00000032 "int") +-; DWARF: DW_AT_name ("int") +-; DWARF-NEXT: DW_AT_encoding (DW_ATE_signed) +-; DWARF-NEXT: DW_AT_byte_size (0x04) +-; DWARF: .debug_line contents: +-; DWARF-NEXT: debug_line[0x00000000] +-; DWARF-NEXT: Line table prologue: +-; DWARF-NEXT: total_length: {{.*}} +-; DWARF-NEXT: format: DWARF32 +-; DWARF-NEXT: version: 5 +-; DWARF-NEXT: address_size: 8 +-; DWARF-NEXT: seg_select_size: 0 +-; DWARF-NEXT: prologue_length: 0x0000003e +-; DWARF-NEXT: min_inst_length: 1 +-; DWARF-NEXT: max_ops_per_inst: 1 +-; DWARF-NEXT: default_is_stmt: 1 +-; DWARF-NEXT: line_base: -5 +-; DWARF-NEXT: line_range: 14 +-; DWARF-NEXT: opcode_base: 13 +-; DWARF-NEXT: standard_opcode_lengths[DW_LNS_copy] = 0 +-; DWARF-NEXT: standard_opcode_lengths[DW_LNS_advance_pc] = 1 +-; DWARF-NEXT: standard_opcode_lengths[DW_LNS_advance_line] = 1 +-; DWARF-NEXT: standard_opcode_lengths[DW_LNS_set_file] = 1 +-; DWARF-NEXT: standard_opcode_lengths[DW_LNS_set_column] = 1 +-; DWARF-NEXT: standard_opcode_lengths[DW_LNS_negate_stmt] = 0 +-; DWARF-NEXT: standard_opcode_lengths[DW_LNS_set_basic_block] = 0 +-; DWARF-NEXT: standard_opcode_lengths[DW_LNS_const_add_pc] = 0 +-; DWARF-NEXT: standard_opcode_lengths[DW_LNS_fixed_advance_pc] = 1 +-; DWARF-NEXT: standard_opcode_lengths[DW_LNS_set_prologue_end] = 0 +-; DWARF-NEXT: standard_opcode_lengths[DW_LNS_set_epilogue_begin] = 0 +-; DWARF-NEXT: standard_opcode_lengths[DW_LNS_set_isa] = 1 +-; DWARF-NEXT: include_directories[ 0] = "." +-; DWARF-NEXT: file_names[ 0]: +-; DWARF-NEXT: name: "dwarf-loongarch-relocs.c" +-; DWARF-NEXT: dir_index: 0 +-; DWARF-NEXT: md5_checksum: f44d6d71bc4da58b4abe338ca507c007 +-; DWARF-NEXT: source: "{{.*}}" +-; DWARF-EMPTY: +-; DWARF-NEXT: Address Line Column File ISA Discriminator OpIndex Flags +-; DWARF-NEXT: ------------------ ------ ------ ------ --- ------------- ------- ------------- +-; DWARF-NORL-NEXT: 0x0000000000000000 2 0 0 0 0 0 is_stmt +-; DWARF-NORL-NEXT: 0x0000000000000010 3 3 0 0 0 0 is_stmt prologue_end +-; DWARF-NORL-NEXT: 0x0000000000000020 10 3 0 0 0 0 is_stmt +-; DWARF-NORL-NEXT: 0x000000000000002c 10 3 0 0 0 0 epilogue_begin +-; DWARF-NORL-NEXT: 0x0000000000000034 10 3 0 0 0 0 end_sequence +-; DWARF-ENRL-NEXT: 0x000000000000001c 2 0 0 0 0 0 is_stmt +-; DWARF-ENRL-NEXT: 0x000000000000002c 3 3 0 0 0 0 is_stmt prologue_end +-; DWARF-ENRL-NEXT: 0x000000000000003c 10 3 0 0 0 0 is_stmt +-; DWARF-ENRL-NEXT: 0x0000000000000048 10 3 0 0 0 0 epilogue_begin +-; DWARF-ENRL-NEXT: 0x0000000000000050 10 3 0 0 0 0 end_sequence +- +-; ModuleID = 'dwarf-loongarch-relocs.c' +-source_filename = "dwarf-loongarch-relocs.c" +-target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128" +-target triple = "loongarch64" +- +-; Function Attrs: noinline nounwind optnone +-define dso_local signext i32 @foo() #0 !dbg !8 { +- call void asm sideeffect ".cfi_remember_state\0A\09.cfi_adjust_cfa_offset 16\0A\09nop\0A\09la.pcrel $$t0, sym\0A\09nop\0A\09.cfi_restore_state\0A\09", ""() #1, !dbg !12, !srcloc !13 +- ret i32 0, !dbg !14 +-} +- +-attributes #0 = { noinline nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="loongarch64" "target-features"="+64bit,+d,+f,+ual" } +-attributes #1 = { nounwind } +- +-!llvm.dbg.cu = !{!0} +-!llvm.module.flags = !{!2, !3, !4, !5, !6} +-!llvm.ident = !{!7} +- +-!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +-!1 = !DIFile(filename: "dwarf-loongarch-relocs.c", directory: ".", checksumkind: CSK_MD5, checksum: "f44d6d71bc4da58b4abe338ca507c007", source: "int foo()\0A{\0A asm volatile(\0A \22.cfi_remember_state\\n\\t\22\0A \22.cfi_adjust_cfa_offset 16\\n\\t\22\0A \22nop\\n\\t\22\0A \22la.pcrel $t0, sym\\n\\t\22\0A \22nop\\n\\t\22\0A \22.cfi_restore_state\\n\\t\22);\0A return 0;\0A}\0A") +-!2 = !{i32 7, !"Dwarf Version", i32 5} +-!3 = !{i32 2, !"Debug Info Version", i32 3} +-!4 = !{i32 1, !"wchar_size", i32 4} +-!5 = !{i32 7, !"direct-access-external-data", i32 0} +-!6 = !{i32 7, !"frame-pointer", i32 2} +-!7 = !{!"clang"} +-!8 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !9, scopeLine: 2, spFlags: DISPFlagDefinition, unit: !0) +-!9 = !DISubroutineType(types: !10) +-!10 = !{!11} +-!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +-!12 = !DILocation(line: 3, column: 3, scope: !8) +-!13 = !{i64 34, i64 56, i64 92, i64 106, i64 134, i64 148, i64 177} +-!14 = !DILocation(line: 10, column: 3, scope: !8) +diff --git a/llvm/test/DebugInfo/LoongArch/lit.local.cfg b/llvm/test/DebugInfo/LoongArch/lit.local.cfg +deleted file mode 100644 +index 77becb8ee..000000000 +--- a/llvm/test/DebugInfo/LoongArch/lit.local.cfg ++++ /dev/null +@@ -1,2 +0,0 @@ +-if "LoongArch" not in config.root.targets: +- config.unsupported = True +diff --git a/llvm/test/DebugInfo/Symbolize/ELF/loongarch-empty-name-symbol.s b/llvm/test/DebugInfo/Symbolize/ELF/loongarch-empty-name-symbol.s +new file mode 100644 +index 000000000..ea58521cb +--- /dev/null ++++ b/llvm/test/DebugInfo/Symbolize/ELF/loongarch-empty-name-symbol.s +@@ -0,0 +1,26 @@ ++# REQUIRES: loongarch-registered-target ++## Ignore empty name symbols. ++ ++# RUN: llvm-mc -filetype=obj -triple=loongarch64 %s -o %t ++# RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=SYM ++ ++# SYM: 0000000000000004 0 NOTYPE LOCAL DEFAULT [[#]] {{$}} ++# SYM: 0000000000000000 0 NOTYPE GLOBAL DEFAULT [[#]] foo ++ ++## Make sure we test at an address larger than or equal to an empty name symbol. ++# RUN: llvm-symbolizer --obj=%t 0 4 | FileCheck %s ++ ++# CHECK: foo ++# CHECK-NEXT: ??:0:0 ++# CHECK-EMPTY: ++# CHECK-NEXT: foo ++# CHECK-NEXT: ??:0:0 ++ ++.globl foo ++foo: ++ nop ++ .file 1 "/tmp" "a.s" ++ .loc 1 1 0 ++ nop ++ ++.section .debug_line,"",@progbits +diff --git a/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_loongarch32_relocations.s b/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_loongarch32_relocations.s +deleted file mode 100644 +index 23f6acc30..000000000 +--- a/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_loongarch32_relocations.s ++++ /dev/null +@@ -1,113 +0,0 @@ +-# RUN: rm -rf %t && mkdir -p %t +-# RUN: llvm-mc --triple=loongarch32 --filetype=obj -o %t/elf_reloc.o %s +-# RUN: llvm-jitlink --noexec \ +-# RUN: --abs external_data=0xdeadbeef \ +-# RUN: --abs external_func=0xcafef00d \ +-# RUN: --check %s %t/elf_reloc.o +- .text +- +- .globl main +- .p2align 2 +- .type main,@function +-main: +- ret +- +- .size main, .-main +- +-## Check R_LARCH_B26 relocation of a local function call. +- +-# jitlink-check: decode_operand(local_func_call26, 0)[27:0] = \ +-# jitlink-check: (local_func - local_func_call26)[27:0] +-# jitlink-check: decode_operand(local_func_jump26, 0)[27:0] = \ +-# jitlink-check: (local_func - local_func_jump26)[27:0] +- .globl local_func +- .p2align 2 +- .type local_func,@function +-local_func: +- ret +- .size local_func, .-local_func +- +- .globl local_func_call26 +- .p2align 2 +-local_func_call26: +- bl local_func +- .size local_func_call26, .-local_func_call26 +- +- .globl local_func_jump26 +- .p2align 2 +-local_func_jump26: +- b local_func +- .size local_func_jump26, .-local_func_jump26 +- +-## Check R_LARCH_PCALA_HI20 / R_LARCH_PCALA_LO12 relocation of a local symbol. +- +-# jitlink-check: decode_operand(test_pcalau12i_pcrel, 1)[19:0] = \ +-# jitlink-check: (named_data - test_pcalau12i_pcrel)[31:12] + \ +-# jitlink-check: named_data[11:11] +-# jitlink-check: decode_operand(test_addi_pcrel_lo12, 2)[11:0] = \ +-# jitlink-check: (named_data)[11:0] +- .globl test_pcalau12i_pcrel +- .p2align 2 +-test_pcalau12i_pcrel: +- pcalau12i $a0, %pc_hi20(named_data) +- .size test_pcalau12i_pcrel, .-test_pcalau12i_pcrel +- +- .globl test_addi_pcrel_lo12 +- .p2align 2 +-test_addi_pcrel_lo12: +- addi.w $a0, $a0, %pc_lo12(named_data) +- .size test_addi_pcrel_lo12, .-test_addi_pcrel_lo12 +- +-## Check that calls/jumps to external functions trigger the generation of stubs +-## and GOT entries. +- +-# jitlink-check: *{4}(got_addr(elf_reloc.o, external_func)) = external_func +-# jitlink-check: decode_operand(test_external_call, 0) = \ +-# jitlink-check: (stub_addr(elf_reloc.o, external_func) - \ +-# jitlink-check: test_external_call)[27:0] +-# jitlink-check: decode_operand(test_external_jump, 0) = \ +-# jitlink-check: (stub_addr(elf_reloc.o, external_func) - \ +-# jitlink-check: test_external_jump)[27:0] +- .globl test_external_call +- .p2align 2 +-test_external_call: +- bl external_func +- .size test_external_call, .-test_external_call +- +- .globl test_external_jump +- .p2align 2 +-test_external_jump: +- b external_func +- .size test_external_jump, .-test_external_jump +- +-## Check R_LARCH_GOT_PC_HI20 / R_LARCH_GOT_PC_LO12 handling with a reference to +-## an external symbol. Validate both the reference to the GOT entry, and also +-## the content of the GOT entry. +- +-# jitlink-check: *{4}(got_addr(elf_reloc.o, external_data)) = external_data +-# jitlink-check: decode_operand(test_gotpage_external, 1)[19:0] = \ +-# jitlink-check: (got_addr(elf_reloc.o, external_data)[31:12] - \ +-# jitlink-check: test_gotpage_external[31:12] + \ +-# jitlink-check: got_addr(elf_reloc.o, external_data)[11:11])[19:0] +-# jitlink-check: decode_operand(test_gotoffset12_external, 2)[11:0] = \ +-# jitlink-check: got_addr(elf_reloc.o, external_data)[11:0] +- .globl test_gotpage_external +- .p2align 2 +-test_gotpage_external: +- pcalau12i $a0, %got_pc_hi20(external_data) +- .size test_gotpage_external, .-test_gotpage_external +- +- .globl test_gotoffset12_external +- .p2align 2 +-test_gotoffset12_external: +- ld.w $a0, $a0, %got_pc_lo12(external_data) +- .size test_gotoffset12_external, .-test_gotoffset12_external +- +- +- .globl named_data +- .p2align 4 +- .type named_data,@object +-named_data: +- .quad 0x2222222222222222 +- .quad 0x3333333333333333 +- .size named_data, .-named_data +diff --git a/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_loongarch64_ehframe.s b/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_loongarch64_ehframe.s +deleted file mode 100644 +index 3eb3cba11..000000000 +--- a/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_loongarch64_ehframe.s ++++ /dev/null +@@ -1,69 +0,0 @@ +-# REQUIRES: asserts +-# RUN: llvm-mc --triple=loongarch64-linux-gnu --filetype=obj -o %t %s +-# RUN: llvm-jitlink --noexec --phony-externals --debug-only=jitlink %t 2>&1 | \ +-# RUN: FileCheck %s +- +-## Check that splitting of eh-frame sections works. +- +-# CHECK: DWARFRecordSectionSplitter: Processing .eh_frame... +-# CHECK: Processing block at +-# CHECK: Processing CFI record at +-# CHECK: Extracted {{.*}} section = .eh_frame +-# CHECK: Processing CFI record at +-# CHECK: Extracted {{.*}} section = .eh_frame +-# CHECK: EHFrameEdgeFixer: Processing .eh_frame in "{{.*}}"... +-# CHECK: Processing block at +-# CHECK: Record is CIE +-# CHECK: Processing block at +-# CHECK: Record is FDE +-# CHECK: Adding edge at {{.*}} to CIE at: {{.*}} +-# CHECK: Existing edge at {{.*}} to PC begin at {{.*}} +-# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}} +-# CHECK: Processing block at +-# CHECK: Record is FDE +-# CHECK: Adding edge at {{.*}} to CIE at: {{.*}} +-# CHECK: Existing edge at {{.*}} to PC begin at {{.*}} +-# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}} +- +- .text +- .globl main +- .p2align 2 +- .type main,@function +-main: +- .cfi_startproc +- addi.d $sp, $sp, -16 +- .cfi_def_cfa_offset 16 +- st.d $ra, $sp, 8 +- .cfi_offset 1, -8 +- ori $a0, $zero, 4 +- bl %plt(__cxa_allocate_exception) +- ori $a1, $zero, 5 +- st.w $a1, $a0, 0 +- pcalau12i $a1, %got_pc_hi20(_ZTIi) +- ld.d $a1, $a1, %got_pc_lo12(_ZTIi) +- move $a2, $zero +- bl %plt(__cxa_throw) +-.main_end: +- .size main, .main_end-main +- .cfi_endproc +- +- .globl dup +- .p2align 2 +- .type main,@function +-dup: +- .cfi_startproc +- addi.d $sp, $sp, -16 +- .cfi_def_cfa_offset 16 +- st.d $ra, $sp, 8 +- .cfi_offset 1, -8 +- ori $a0, $zero, 4 +- bl %plt(__cxa_allocate_exception) +- ori $a1, $zero, 5 +- st.w $a1, $a0, 0 +- pcalau12i $a1, %got_pc_hi20(_ZTIi) +- ld.d $a1, $a1, %got_pc_lo12(_ZTIi) +- move $a2, $zero +- bl %plt(__cxa_throw) +-.dup_end: +- .size main, .dup_end-dup +- .cfi_endproc +diff --git a/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_loongarch64_relocations.s b/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_loongarch64_relocations.s +deleted file mode 100644 +index 74eb8118d..000000000 +--- a/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_loongarch64_relocations.s ++++ /dev/null +@@ -1,113 +0,0 @@ +-# RUN: rm -rf %t && mkdir -p %t +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj -o %t/elf_reloc.o %s +-# RUN: llvm-jitlink --noexec \ +-# RUN: --abs external_data=0xdeadbeef \ +-# RUN: --abs external_func=0xcafef00d \ +-# RUN: --check %s %t/elf_reloc.o +- .text +- +- .globl main +- .p2align 2 +- .type main,@function +-main: +- ret +- +- .size main, .-main +- +-## Check R_LARCH_B26 relocation of a local function call. +- +-# jitlink-check: decode_operand(local_func_call26, 0)[27:0] = \ +-# jitlink-check: (local_func - local_func_call26)[27:0] +-# jitlink-check: decode_operand(local_func_jump26, 0)[27:0] = \ +-# jitlink-check: (local_func - local_func_jump26)[27:0] +- .globl local_func +- .p2align 2 +- .type local_func,@function +-local_func: +- ret +- .size local_func, .-local_func +- +- .globl local_func_call26 +- .p2align 2 +-local_func_call26: +- bl local_func +- .size local_func_call26, .-local_func_call26 +- +- .globl local_func_jump26 +- .p2align 2 +-local_func_jump26: +- b local_func +- .size local_func_jump26, .-local_func_jump26 +- +-## Check R_LARCH_PCALA_HI20 / R_LARCH_PCALA_LO12 relocation of a local symbol. +- +-# jitlink-check: decode_operand(test_pcalau12i_pcrel, 1)[19:0] = \ +-# jitlink-check: (named_data - test_pcalau12i_pcrel)[31:12] + \ +-# jitlink-check: named_data[11:11] +-# jitlink-check: decode_operand(test_addi_pcrel_lo12, 2)[11:0] = \ +-# jitlink-check: (named_data)[11:0] +- .globl test_pcalau12i_pcrel +- .p2align 2 +-test_pcalau12i_pcrel: +- pcalau12i $a0, %pc_hi20(named_data) +- .size test_pcalau12i_pcrel, .-test_pcalau12i_pcrel +- +- .globl test_addi_pcrel_lo12 +- .p2align 2 +-test_addi_pcrel_lo12: +- addi.d $a0, $a0, %pc_lo12(named_data) +- .size test_addi_pcrel_lo12, .-test_addi_pcrel_lo12 +- +-## Check that calls/jumps to external functions trigger the generation of stubs +-## and GOT entries. +- +-# jitlink-check: *{8}(got_addr(elf_reloc.o, external_func)) = external_func +-# jitlink-check: decode_operand(test_external_call, 0) = \ +-# jitlink-check: (stub_addr(elf_reloc.o, external_func) - \ +-# jitlink-check: test_external_call)[27:0] +-# jitlink-check: decode_operand(test_external_jump, 0) = \ +-# jitlink-check: (stub_addr(elf_reloc.o, external_func) - \ +-# jitlink-check: test_external_jump)[27:0] +- .globl test_external_call +- .p2align 2 +-test_external_call: +- bl external_func +- .size test_external_call, .-test_external_call +- +- .globl test_external_jump +- .p2align 2 +-test_external_jump: +- b external_func +- .size test_external_jump, .-test_external_jump +- +-## Check R_LARCH_GOT_PC_HI20 / R_LARCH_GOT_PC_LO12 handling with a reference to +-## an external symbol. Validate both the reference to the GOT entry, and also +-## the content of the GOT entry. +- +-# jitlink-check: *{8}(got_addr(elf_reloc.o, external_data)) = external_data +-# jitlink-check: decode_operand(test_gotpage_external, 1)[19:0] = \ +-# jitlink-check: (got_addr(elf_reloc.o, external_data)[31:12] - \ +-# jitlink-check: test_gotpage_external[31:12] + \ +-# jitlink-check: got_addr(elf_reloc.o, external_data)[11:11])[19:0] +-# jitlink-check: decode_operand(test_gotoffset12_external, 2)[11:0] = \ +-# jitlink-check: got_addr(elf_reloc.o, external_data)[11:0] +- .globl test_gotpage_external +- .p2align 2 +-test_gotpage_external: +- pcalau12i $a0, %got_pc_hi20(external_data) +- .size test_gotpage_external, .-test_gotpage_external +- +- .globl test_gotoffset12_external +- .p2align 2 +-test_gotoffset12_external: +- ld.d $a0, $a0, %got_pc_lo12(external_data) +- .size test_gotoffset12_external, .-test_gotoffset12_external +- +- +- .globl named_data +- .p2align 4 +- .type named_data,@object +-named_data: +- .quad 0x2222222222222222 +- .quad 0x3333333333333333 +- .size named_data, .-named_data +diff --git a/llvm/test/ExecutionEngine/JITLink/LoongArch/lit.local.cfg b/llvm/test/ExecutionEngine/JITLink/LoongArch/lit.local.cfg +deleted file mode 100644 +index cc24278ac..000000000 +--- a/llvm/test/ExecutionEngine/JITLink/LoongArch/lit.local.cfg ++++ /dev/null +@@ -1,2 +0,0 @@ +-if not "LoongArch" in config.root.targets: +- config.unsupported = True +diff --git a/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_GOTAndStubsOptimization.s b/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_GOTAndStubsOptimization.s +index caeae4fa4..56f391b7d 100644 +--- a/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_GOTAndStubsOptimization.s ++++ b/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_GOTAndStubsOptimization.s +@@ -1,3 +1,4 @@ ++# UNSUPPORTED: loongarch64 + # RUN: rm -rf %t && mkdir -p %t + # RUN: llvm-mc -triple=x86_64-apple-macos10.9 -filetype=obj \ + # RUN: -o %t/helper.o %S/Inputs/MachO_GOTAndStubsOptimizationHelper.s +diff --git a/llvm/test/ExecutionEngine/MCJIT/lit.local.cfg b/llvm/test/ExecutionEngine/MCJIT/lit.local.cfg +index 46a3ff9d3..86c31b064 100644 +--- a/llvm/test/ExecutionEngine/MCJIT/lit.local.cfg ++++ b/llvm/test/ExecutionEngine/MCJIT/lit.local.cfg +@@ -7,6 +7,7 @@ if not ( + | ("Mips" in targets) + | ("PowerPC" in targets) + | ("SystemZ" in targets) ++ | ("LoongArch" in targets) + ): + config.unsupported = True + +@@ -25,6 +26,7 @@ if root.host_arch not in [ + "ppc64", + "ppc64le", + "SystemZ", ++ "loongarch64", + ]: + config.unsupported = True + +diff --git a/llvm/test/ExecutionEngine/MCJIT/remote/cross-module-a.ll b/llvm/test/ExecutionEngine/MCJIT/remote/cross-module-a.ll +index 646881ee2..da4492330 100644 +--- a/llvm/test/ExecutionEngine/MCJIT/remote/cross-module-a.ll ++++ b/llvm/test/ExecutionEngine/MCJIT/remote/cross-module-a.ll +@@ -1,3 +1,4 @@ ++;UNSUPPORTED: target=loongarch64{{.*}} + ; RUN: %lli -jit-kind=mcjit -extra-module=%p/Inputs/cross-module-b.ll -disable-lazy-compilation=true -remote-mcjit -mcjit-remote-process=lli-child-target%exeext %s > /dev/null + ; XFAIL: target={{.*-windows-(gnu|msvc)}} + ; REQUIRES: thread_support +diff --git a/llvm/test/ExecutionEngine/MCJIT/remote/eh.ll b/llvm/test/ExecutionEngine/MCJIT/remote/eh.ll +index b094ec239..c9f2aabab 100644 +--- a/llvm/test/ExecutionEngine/MCJIT/remote/eh.ll ++++ b/llvm/test/ExecutionEngine/MCJIT/remote/eh.ll +@@ -1,3 +1,4 @@ ++;UNSUPPORTED: target=loongarch64{{.*}} + ; REQUIRES: cxx-shared-library + ; RUN: %lli -jit-kind=mcjit -remote-mcjit -mcjit-remote-process=lli-child-target%exeext %s + ; XFAIL: target=arm{{.*}}, target={{.*-(cygwin|windows-msvc|windows-gnu)}} +diff --git a/llvm/test/ExecutionEngine/MCJIT/remote/simpletest-remote.ll b/llvm/test/ExecutionEngine/MCJIT/remote/simpletest-remote.ll +index 4042b3158..3dcf69c29 100644 +--- a/llvm/test/ExecutionEngine/MCJIT/remote/simpletest-remote.ll ++++ b/llvm/test/ExecutionEngine/MCJIT/remote/simpletest-remote.ll +@@ -1,3 +1,4 @@ ++;UNSUPPORTED: target=loongarch64{{.*}} + ; RUN: %lli -jit-kind=mcjit -remote-mcjit -mcjit-remote-process=lli-child-target%exeext %s > /dev/null + ; XFAIL: target={{.*-windows-(gnu|msvc)}} + ; REQUIRES: thread_support +diff --git a/llvm/test/ExecutionEngine/MCJIT/remote/stubs-remote.ll b/llvm/test/ExecutionEngine/MCJIT/remote/stubs-remote.ll +index 43e61f120..fb86c0180 100644 +--- a/llvm/test/ExecutionEngine/MCJIT/remote/stubs-remote.ll ++++ b/llvm/test/ExecutionEngine/MCJIT/remote/stubs-remote.ll +@@ -1,3 +1,4 @@ ++;UNSUPPORTED: target=loongarch64{{.*}} + ; RUN: %lli -jit-kind=mcjit -remote-mcjit -disable-lazy-compilation=false -mcjit-remote-process=lli-child-target%exeext %s + ; XFAIL: target={{.*-windows-(gnu|msvc)}} + ; REQUIRES: thread_support +diff --git a/llvm/test/ExecutionEngine/MCJIT/remote/test-common-symbols-remote.ll b/llvm/test/ExecutionEngine/MCJIT/remote/test-common-symbols-remote.ll +index d9a8d85ef..f6adc8f0b 100644 +--- a/llvm/test/ExecutionEngine/MCJIT/remote/test-common-symbols-remote.ll ++++ b/llvm/test/ExecutionEngine/MCJIT/remote/test-common-symbols-remote.ll +@@ -1,3 +1,4 @@ ++;UNSUPPORTED: target=loongarch64{{.*}} + ; RUN: %lli -jit-kind=mcjit -remote-mcjit -O0 -disable-lazy-compilation=false -mcjit-remote-process=lli-child-target%exeext %s + ; XFAIL: target={{.*-windows-(gnu|msvc)}} + ; REQUIRES: thread_support +diff --git a/llvm/test/ExecutionEngine/MCJIT/remote/test-fp-no-external-funcs-remote.ll b/llvm/test/ExecutionEngine/MCJIT/remote/test-fp-no-external-funcs-remote.ll +index 73e66d3eb..a3e8a4ffa 100644 +--- a/llvm/test/ExecutionEngine/MCJIT/remote/test-fp-no-external-funcs-remote.ll ++++ b/llvm/test/ExecutionEngine/MCJIT/remote/test-fp-no-external-funcs-remote.ll +@@ -1,3 +1,4 @@ ++;UNSUPPORTED: target=loongarch64{{.*}} + ; RUN: %lli -jit-kind=mcjit -remote-mcjit -mcjit-remote-process=lli-child-target%exeext %s > /dev/null + ; XFAIL: target={{.*-windows-(gnu|msvc)}} + ; REQUIRES: thread_support +diff --git a/llvm/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-remote.ll b/llvm/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-remote.ll +index 71617e096..63694f3c0 100644 +--- a/llvm/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-remote.ll ++++ b/llvm/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-remote.ll +@@ -1,3 +1,4 @@ ++;UNSUPPORTED: target=loongarch64{{.*}} + ; RUN: %lli -jit-kind=mcjit -remote-mcjit -mcjit-remote-process=lli-child-target%exeext %s > /dev/null + ; XFAIL: target={{.*-windows-(gnu|msvc)}} + ; REQUIRES: thread_support +diff --git a/llvm/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-sm-pic.ll b/llvm/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-sm-pic.ll +index c2c79a9d8..77eb192f1 100644 +--- a/llvm/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-sm-pic.ll ++++ b/llvm/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-sm-pic.ll +@@ -1,3 +1,4 @@ ++;UNSUPPORTED: target=loongarch64{{.*}} + ; RUN: %lli -jit-kind=mcjit -remote-mcjit -mcjit-remote-process=lli-child-target%exeext \ + ; RUN: -relocation-model=pic -code-model=small %s > /dev/null + ; XFAIL: target={{(mips|mipsel)-.*}}, target={{(aarch64|arm).*}}, target={{(i686|i386).*}} +diff --git a/llvm/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-remote.ll b/llvm/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-remote.ll +index 18e6b0319..abf2a5a27 100644 +--- a/llvm/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-remote.ll ++++ b/llvm/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-remote.ll +@@ -1,3 +1,4 @@ ++;UNSUPPORTED: target=loongarch64{{.*}} + ; RUN: %lli -jit-kind=mcjit -remote-mcjit -O0 -mcjit-remote-process=lli-child-target%exeext %s + ; XFAIL: target={{.*-windows-(gnu|msvc)}} + ; REQUIRES: thread_support +diff --git a/llvm/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-sm-pic.ll b/llvm/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-sm-pic.ll +index db88cbb4f..97148b37c 100644 +--- a/llvm/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-sm-pic.ll ++++ b/llvm/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-sm-pic.ll +@@ -1,3 +1,4 @@ ++;UNSUPPORTED: target=loongarch64{{.*}} + ; RUN: %lli -jit-kind=mcjit -remote-mcjit -mcjit-remote-process=lli-child-target%exeext \ + ; RUN: -O0 -relocation-model=pic -code-model=small %s + ; XFAIL: target={{(mips|mipsel)-.*}}, target={{(aarch64|arm).*}}, target={{(i686|i386).*}} +diff --git a/llvm/test/ExecutionEngine/OrcLazy/emulated-tls.ll b/llvm/test/ExecutionEngine/OrcLazy/emulated-tls.ll +index a70bc5f4c..052070f33 100644 +--- a/llvm/test/ExecutionEngine/OrcLazy/emulated-tls.ll ++++ b/llvm/test/ExecutionEngine/OrcLazy/emulated-tls.ll +@@ -1,6 +1,3 @@ +-; LoongArch does not support emulated tls. +-; UNSUPPORTED: target=loongarch{{.*}} +- + ; RUN: not lli -no-process-syms -lljit-platform=Inactive -emulated-tls \ + ; RUN: -jit-kind=orc-lazy %s 2>&1 | FileCheck %s + ; +diff --git a/llvm/test/ExecutionEngine/OrcLazy/lit.local.cfg b/llvm/test/ExecutionEngine/OrcLazy/lit.local.cfg +index cbd7c5440..4b0e1d6c7 100644 +--- a/llvm/test/ExecutionEngine/OrcLazy/lit.local.cfg ++++ b/llvm/test/ExecutionEngine/OrcLazy/lit.local.cfg +@@ -8,8 +8,7 @@ if config.root.host_arch not in [ + "mips", + "mipsel", + "mips64", +- "mips64el", +- "loongarch64", ++ "mips64el" + ]: + config.unsupported = True + +diff --git a/llvm/test/ExecutionEngine/RuntimeDyld/LoongArch/hello-g.ll b/llvm/test/ExecutionEngine/RuntimeDyld/LoongArch/hello-g.ll +new file mode 100644 +index 000000000..0a920808d +--- /dev/null ++++ b/llvm/test/ExecutionEngine/RuntimeDyld/LoongArch/hello-g.ll +@@ -0,0 +1,33 @@ ++; REQUIRES: asserts ++; RUN: %lli --jit-kind=mcjit %s > /dev/null ++@.str = private unnamed_addr constant [7 x i8] c"hello\0A\00", align 1 ++ ++; Function Attrs: noinline nounwind optnone ++define signext i32 @main() !dbg !8 { ++entry: ++ %retval = alloca i32, align 4 ++ store i32 0, i32* %retval, align 4 ++ %call = call signext i32 (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i64 0, i64 0)), !dbg !12 ++ ret i32 0, !dbg !13 ++} ++ ++declare signext i32 @printf(i8*, ...) ++ ++!llvm.dbg.cu = !{!0} ++!llvm.module.flags = !{!3, !4, !5, !6} ++!llvm.ident = !{!7} ++ ++!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) ++!1 = !DIFile(filename: "hello.c", directory: "/") ++!2 = !{} ++!3 = !{i32 7, !"Dwarf Version", i32 4} ++!4 = !{i32 2, !"Debug Info Version", i32 3} ++!5 = !{i32 1, !"wchar_size", i32 4} ++!6 = !{i32 7, !"PIC Level", i32 1} ++!7 = !{!"clang version 10.0.1"} ++!8 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 3, type: !9, scopeLine: 4, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2) ++!9 = !DISubroutineType(types: !10) ++!10 = !{!11} ++!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) ++!12 = !DILocation(line: 5, column: 3, scope: !8) ++!13 = !DILocation(line: 6, column: 3, scope: !8) +diff --git a/llvm/test/ExecutionEngine/RuntimeDyld/LoongArch/lit.local.cfg b/llvm/test/ExecutionEngine/RuntimeDyld/LoongArch/lit.local.cfg +new file mode 100644 +index 000000000..2b5a4893e +--- /dev/null ++++ b/llvm/test/ExecutionEngine/RuntimeDyld/LoongArch/lit.local.cfg +@@ -0,0 +1,2 @@ ++if not 'LoongArch' in config.root.targets: ++ config.unsupported = True +diff --git a/llvm/test/ExecutionEngine/frem.ll b/llvm/test/ExecutionEngine/frem.ll +index d33e4fca8..b8739c249 100644 +--- a/llvm/test/ExecutionEngine/frem.ll ++++ b/llvm/test/ExecutionEngine/frem.ll +@@ -1,6 +1,3 @@ +-; LoongArch does not support mcjit. +-; UNSUPPORTED: target=loongarch{{.*}} +- + ; LLI.exe used to crash on Windows\X86 when certain single precession + ; floating point intrinsics (defined as macros) are used. + ; This unit test guards against the failure. +diff --git a/llvm/test/ExecutionEngine/mov64zext32.ll b/llvm/test/ExecutionEngine/mov64zext32.ll +index 43bd0fb2f..bba1a1987 100644 +--- a/llvm/test/ExecutionEngine/mov64zext32.ll ++++ b/llvm/test/ExecutionEngine/mov64zext32.ll +@@ -1,6 +1,3 @@ +-; LoongArch does not support mcjit. +-; UNSUPPORTED: target=loongarch{{.*}} +- + ; RUN: %lli -jit-kind=mcjit %s > /dev/null + ; RUN: %lli %s > /dev/null + +diff --git a/llvm/test/ExecutionEngine/test-interp-vec-arithm_float.ll b/llvm/test/ExecutionEngine/test-interp-vec-arithm_float.ll +index 99d95791c..6f784265a 100644 +--- a/llvm/test/ExecutionEngine/test-interp-vec-arithm_float.ll ++++ b/llvm/test/ExecutionEngine/test-interp-vec-arithm_float.ll +@@ -1,6 +1,3 @@ +-; LoongArch does not support mcjit. +-; UNSUPPORTED: target=loongarch{{.*}} +- + ; RUN: %lli -jit-kind=mcjit %s > /dev/null + ; RUN: %lli %s > /dev/null + +diff --git a/llvm/test/ExecutionEngine/test-interp-vec-arithm_int.ll b/llvm/test/ExecutionEngine/test-interp-vec-arithm_int.ll +index 2e5592d4d..6896af83c 100644 +--- a/llvm/test/ExecutionEngine/test-interp-vec-arithm_int.ll ++++ b/llvm/test/ExecutionEngine/test-interp-vec-arithm_int.ll +@@ -1,6 +1,3 @@ +-; LoongArch does not support mcjit. +-; UNSUPPORTED: target=loongarch{{.*}} +- + ; RUN: %lli -jit-kind=mcjit %s > /dev/null + ; RUN: %lli %s > /dev/null + +diff --git a/llvm/test/ExecutionEngine/test-interp-vec-logical.ll b/llvm/test/ExecutionEngine/test-interp-vec-logical.ll +index 1e11659b1..f654120ea 100644 +--- a/llvm/test/ExecutionEngine/test-interp-vec-logical.ll ++++ b/llvm/test/ExecutionEngine/test-interp-vec-logical.ll +@@ -1,6 +1,3 @@ +-; LoongArch does not support mcjit. +-; UNSUPPORTED: target=loongarch{{.*}} +- + ; RUN: %lli -jit-kind=mcjit %s > /dev/null + ; RUN: %lli %s > /dev/null + +diff --git a/llvm/test/ExecutionEngine/test-interp-vec-setcond-fp.ll b/llvm/test/ExecutionEngine/test-interp-vec-setcond-fp.ll +index e919550de..84bdec1cf 100644 +--- a/llvm/test/ExecutionEngine/test-interp-vec-setcond-fp.ll ++++ b/llvm/test/ExecutionEngine/test-interp-vec-setcond-fp.ll +@@ -1,6 +1,3 @@ +-; LoongArch does not support mcjit. +-; UNSUPPORTED: target=loongarch{{.*}} +- + ; RUN: %lli -jit-kind=mcjit %s > /dev/null + ; RUN: %lli %s > /dev/null + +diff --git a/llvm/test/ExecutionEngine/test-interp-vec-setcond-int.ll b/llvm/test/ExecutionEngine/test-interp-vec-setcond-int.ll +index 9862d6af1..5a20fc4f1 100644 +--- a/llvm/test/ExecutionEngine/test-interp-vec-setcond-int.ll ++++ b/llvm/test/ExecutionEngine/test-interp-vec-setcond-int.ll +@@ -1,6 +1,3 @@ +-; LoongArch does not support mcjit. +-; UNSUPPORTED: target=loongarch{{.*}} +- + ; RUN: %lli -jit-kind=mcjit %s > /dev/null + ; RUN: %lli %s > /dev/null + +diff --git a/llvm/test/Instrumentation/MemorySanitizer/LoongArch/vararg-loongarch64.ll b/llvm/test/Instrumentation/MemorySanitizer/LoongArch/vararg-loongarch64.ll +deleted file mode 100644 +index 8a4ab5958..000000000 +--- a/llvm/test/Instrumentation/MemorySanitizer/LoongArch/vararg-loongarch64.ll ++++ /dev/null +@@ -1,78 +0,0 @@ +-; RUN: opt < %s -S -passes=msan 2>&1 | FileCheck %s +- +-target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128" +-target triple = "loongarch64-unknown-linux-gnu" +- +-;; First, check allocation of the save area. +-declare void @llvm.lifetime.start.p0(i64, ptr nocapture) #1 +-declare void @llvm.va_start(ptr) #2 +-declare void @llvm.va_end(ptr) #2 +-declare void @llvm.lifetime.end.p0(i64, ptr nocapture) #1 +-define i32 @foo(i32 %guard, ...) { +-; CHECK-LABEL: @foo +-; CHECK: [[TMP1:%.*]] = load {{.*}} @__msan_va_arg_overflow_size_tls +-; CHECK: [[TMP2:%.*]] = add i64 0, [[TMP1]] +-; CHECK: [[TMP3:%.*]] = alloca {{.*}} [[TMP2]] +-; CHECK: call void @llvm.memset.p0.i64(ptr align 8 [[TMP3]], i8 0, i64 [[TMP2]], i1 false) +-; CHECK: [[TMP4:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP2]], i64 800) +-; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[TMP3]], ptr align 8 @__msan_va_arg_tls, i64 [[TMP4]], i1 false) +-; +- %vl = alloca ptr, align 8 +- call void @llvm.lifetime.start.p0(i64 32, ptr %vl) +- call void @llvm.va_start(ptr %vl) +- call void @llvm.va_end(ptr %vl) +- call void @llvm.lifetime.end.p0(i64 32, ptr %vl) +- ret i32 0 +-} +- +-;; Save the incoming shadow value from the arguments in the __msan_va_arg_tls +-;; array. +-define i32 @bar() { +-; CHECK-LABEL: @bar +-; CHECK: store i32 0, ptr @__msan_va_arg_tls, align 8 +-; CHECK: store i64 0, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_va_arg_tls to i64), i64 8) to ptr), align 8 +-; CHECK: store i64 0, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_va_arg_tls to i64), i64 16) to ptr), align 8 +-; CHECK: store {{.*}} 24, {{.*}} @__msan_va_arg_overflow_size_tls +-; +- %1 = call i32 (i32, ...) @foo(i32 0, i32 1, i64 2, double 3.000000e+00) +- ret i32 %1 +-} +- +-;; Check multiple fixed arguments. +-declare i32 @foo2(i32 %g1, i32 %g2, ...) +-define i32 @bar2() { +-; CHECK-LABEL: @bar2 +-; CHECK: store i64 0, ptr @__msan_va_arg_tls, align 8 +-; CHECK: store i64 0, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_va_arg_tls to i64), i64 8) to ptr), align 8 +-; CHECK: store {{.*}} 16, {{.*}} @__msan_va_arg_overflow_size_tls +-; +- %1 = call i32 (i32, i32, ...) @foo2(i32 0, i32 1, i64 2, double 3.000000e+00) +- ret i32 %1 +-} +- +-;; Test that MSan doesn't generate code overflowing __msan_va_arg_tls when too many arguments are +-;; passed to a variadic function. +-declare i64 @sum(i64 %n, ...) +-define dso_local i64 @many_args() { +-;; If the size of __msan_va_arg_tls changes the second argument of `add` must also be changed. +-; CHECK-LABEL: @many_args +-; CHECK: i64 add (i64 ptrtoint (ptr @__msan_va_arg_tls to i64), i64 792) +-; CHECK-NOT: i64 add (i64 ptrtoint (ptr @__msan_va_arg_tls to i64), i64 800) +-; +-entry: +- %ret = call i64 (i64, ...) @sum(i64 120, +- i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, +- i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, +- i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, +- i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, +- i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, +- i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, +- i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, +- i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, +- i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, +- i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, +- i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, +- i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1 +- ) +- ret i64 %ret +-} +diff --git a/llvm/test/Instrumentation/MemorySanitizer/LoongArch/vararg.ll b/llvm/test/Instrumentation/MemorySanitizer/LoongArch/vararg.ll +deleted file mode 100644 +index dcbe2a242..000000000 +--- a/llvm/test/Instrumentation/MemorySanitizer/LoongArch/vararg.ll ++++ /dev/null +@@ -1,14 +0,0 @@ +-; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 +-; Test that code using va_start can be compiled on LoongArch. +- +-target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128" +-target triple = "loongarch64-unknown-linux-gnu" +- +-define void @VaStart(ptr %s, ...) { +-entry: +- %vl = alloca ptr, align 4 +- call void @llvm.va_start(ptr %vl) +- ret void +-} +- +-declare void @llvm.va_start(ptr) +diff --git a/llvm/test/MC/Disassembler/LoongArch/lit.local.cfg b/llvm/test/MC/Disassembler/LoongArch/lit.local.cfg +new file mode 100644 +index 000000000..6223fc691 +--- /dev/null ++++ b/llvm/test/MC/Disassembler/LoongArch/lit.local.cfg +@@ -0,0 +1,3 @@ ++if not 'LoongArch' in config.root.targets: ++ config.unsupported = True ++ +diff --git a/llvm/test/MC/Disassembler/LoongArch/simd.txt b/llvm/test/MC/Disassembler/LoongArch/simd.txt +new file mode 100644 +index 000000000..90da1700a +--- /dev/null ++++ b/llvm/test/MC/Disassembler/LoongArch/simd.txt +@@ -0,0 +1,1361 @@ ++# RUN: llvm-mc --disassemble %s -triple=loongarch64-unknown-linux -mattr=+lsx,+lasx | FileCheck %s ++ ++0xcf 0x2a 0x19 0x09 # CHECK: vfmadd.s $vr15, $vr22, $vr10, $vr18 ++0x01 0x30 0x25 0x09 # CHECK: vfmadd.d $vr1, $vr0, $vr12, $vr10 ++0x50 0x36 0x54 0x09 # CHECK: vfmsub.s $vr16, $vr18, $vr13, $vr8 ++0xb9 0x05 0x6a 0x09 # CHECK: vfmsub.d $vr25, $vr13, $vr1, $vr20 ++0x56 0x44 0x9b 0x09 # CHECK: vfnmadd.s $vr22, $vr2, $vr17, $vr22 ++0xbc 0x0b 0xa7 0x09 # CHECK: vfnmadd.d $vr28, $vr29, $vr2, $vr14 ++0x93 0x44 0xdc 0x09 # CHECK: vfnmsub.s $vr19, $vr4, $vr17, $vr24 ++0xd8 0x72 0xef 0x09 # CHECK: vfnmsub.d $vr24, $vr22, $vr28, $vr30 ++0x8f 0xa7 0x17 0x0a # CHECK: xvfmadd.s $xr15, $xr28, $xr9, $xr15 ++0x05 0x33 0x25 0x0a # CHECK: xvfmadd.d $xr5, $xr24, $xr12, $xr10 ++0x14 0x6c 0x5d 0x0a # CHECK: xvfmsub.s $xr20, $xr0, $xr27, $xr26 ++0x0d 0x65 0x6d 0x0a # CHECK: xvfmsub.d $xr13, $xr8, $xr25, $xr26 ++0xce 0x59 0x94 0x0a # CHECK: xvfnmadd.s $xr14, $xr14, $xr22, $xr8 ++0x39 0x02 0xa2 0x0a # CHECK: xvfnmadd.d $xr25, $xr17, $xr0, $xr4 ++0x6b 0x80 0xd5 0x0a # CHECK: xvfnmsub.s $xr11, $xr3, $xr0, $xr11 ++0x62 0x60 0xeb 0x0a # CHECK: xvfnmsub.d $xr2, $xr3, $xr24, $xr22 ++0xfa 0x6d 0x52 0x0c # CHECK: vfcmp.ceq.s $vr26, $vr15, $vr27 ++0xb5 0x06 0x62 0x0c # CHECK: vfcmp.ceq.d $vr21, $vr21, $vr1 ++0x28 0x4d 0x92 0x0c # CHECK: xvfcmp.ceq.s $xr8, $xr9, $xr19 ++0x19 0x72 0xa2 0x0c # CHECK: xvfcmp.ceq.d $xr25, $xr16, $xr28 ++0xf4 0xf6 0x14 0x0d # CHECK: vbitsel.v $vr20, $vr23, $vr29, $vr9 ++0x47 0xf3 0x2b 0x0d # CHECK: xvbitsel.v $xr7, $xr26, $xr28, $xr23 ++0x8b 0x9c 0x54 0x0d # CHECK: vshuf.b $vr11, $vr4, $vr7, $vr9 ++0xb0 0x2a 0x66 0x0d # CHECK: xvshuf.b $xr16, $xr21, $xr10, $xr12 ++0x3c 0x0b 0x38 0x2c # CHECK: vld $vr28, $r25, -510 ++0xdc 0x3d 0x48 0x2c # CHECK: vst $vr28, $r14, 527 ++0xcb 0x00 0x88 0x2c # CHECK: xvld $xr11, $r6, 512 ++0xed 0xfc 0xd2 0x2c # CHECK: xvst $xr13, $r7, 1215 ++0x28 0xfd 0x14 0x30 # CHECK: vldrepl.d $vr8, $r9, -1544 ++0x22 0xd9 0x2e 0x30 # CHECK: vldrepl.w $vr2, $r9, -296 ++0xfc 0xfa 0x41 0x30 # CHECK: vldrepl.h $vr28, $r23, 252 ++0x25 0xad 0xb4 0x30 # CHECK: vldrepl.b $vr5, $r9, -725 ++0x57 0x57 0x15 0x31 # CHECK: vstelm.d $vr23, $r26, 680, 1 ++0xfe 0x8e 0x26 0x31 # CHECK: vstelm.w $vr30, $r23, -372, 1 ++0xcb 0x3c 0x5c 0x31 # CHECK: vstelm.h $vr11, $r6, 30, 7 ++0xe3 0xb1 0xb8 0x31 # CHECK: vstelm.b $vr3, $r15, 44, 14 ++0x18 0xa5 0x11 0x32 # CHECK: xvldrepl.d $xr24, $r8, 840 ++0x0e 0xef 0x21 0x32 # CHECK: xvldrepl.w $xr14, $r24, 492 ++0x32 0x49 0x46 0x32 # CHECK: xvldrepl.h $xr18, $r9, 804 ++0xa6 0xaf 0x8c 0x32 # CHECK: xvldrepl.b $xr6, $r29, 811 ++0x75 0x94 0x13 0x33 # CHECK: xvstelm.d $xr21, $sp, -216, 0 ++0xbf 0xab 0x21 0x33 # CHECK: xvstelm.w $xr31, $r29, 424, 0 ++0xee 0xb4 0x50 0x33 # CHECK: xvstelm.h $xr14, $r7, 90, 4 ++0x15 0xef 0xa3 0x33 # CHECK: xvstelm.b $xr21, $r24, -5, 8 ++0x9d 0x78 0x40 0x38 # CHECK: vldx $vr29, $r4, $r30 ++0x9f 0x77 0x44 0x38 # CHECK: vstx $vr31, $r28, $r29 ++0xc8 0x63 0x48 0x38 # CHECK: xvldx $xr8, $r30, $r24 ++0x22 0x75 0x4c 0x38 # CHECK: xvstx $xr2, $r9, $r29 ++0x5c 0x5f 0x00 0x70 # CHECK: vseq.b $vr28, $vr26, $vr23 ++0x2a 0x94 0x00 0x70 # CHECK: vseq.h $vr10, $vr1, $vr5 ++0x63 0x47 0x01 0x70 # CHECK: vseq.w $vr3, $vr27, $vr17 ++0x65 0x8c 0x01 0x70 # CHECK: vseq.d $vr5, $vr3, $vr3 ++0x3d 0x1d 0x02 0x70 # CHECK: vsle.b $vr29, $vr9, $vr7 ++0x05 0xa7 0x02 0x70 # CHECK: vsle.h $vr5, $vr24, $vr9 ++0xd1 0x53 0x03 0x70 # CHECK: vsle.w $vr17, $vr30, $vr20 ++0xdb 0xb4 0x03 0x70 # CHECK: vsle.d $vr27, $vr6, $vr13 ++0x7e 0x29 0x04 0x70 # CHECK: vsle.bu $vr30, $vr11, $vr10 ++0xb3 0xff 0x04 0x70 # CHECK: vsle.hu $vr19, $vr29, $vr31 ++0x50 0x52 0x05 0x70 # CHECK: vsle.wu $vr16, $vr18, $vr20 ++0x3f 0xa2 0x05 0x70 # CHECK: vsle.du $vr31, $vr17, $vr8 ++0xfa 0x14 0x06 0x70 # CHECK: vslt.b $vr26, $vr7, $vr5 ++0x4e 0xd0 0x06 0x70 # CHECK: vslt.h $vr14, $vr2, $vr20 ++0xae 0x64 0x07 0x70 # CHECK: vslt.w $vr14, $vr5, $vr25 ++0x3a 0xe5 0x07 0x70 # CHECK: vslt.d $vr26, $vr9, $vr25 ++0x5f 0x3a 0x08 0x70 # CHECK: vslt.bu $vr31, $vr18, $vr14 ++0xe5 0x95 0x08 0x70 # CHECK: vslt.hu $vr5, $vr15, $vr5 ++0x9f 0x37 0x09 0x70 # CHECK: vslt.wu $vr31, $vr28, $vr13 ++0x6b 0xda 0x09 0x70 # CHECK: vslt.du $vr11, $vr19, $vr22 ++0x9a 0x7e 0x0a 0x70 # CHECK: vadd.b $vr26, $vr20, $vr31 ++0x2b 0xf7 0x0a 0x70 # CHECK: vadd.h $vr11, $vr25, $vr29 ++0x27 0x37 0x0b 0x70 # CHECK: vadd.w $vr7, $vr25, $vr13 ++0xb0 0xc1 0x0b 0x70 # CHECK: vadd.d $vr16, $vr13, $vr16 ++0x6c 0x54 0x0c 0x70 # CHECK: vsub.b $vr12, $vr3, $vr21 ++0xaf 0xe5 0x0c 0x70 # CHECK: vsub.h $vr15, $vr13, $vr25 ++0x14 0x66 0x0d 0x70 # CHECK: vsub.w $vr20, $vr16, $vr25 ++0x73 0x9c 0x0d 0x70 # CHECK: vsub.d $vr19, $vr3, $vr7 ++0xce 0x17 0x46 0x70 # CHECK: vsadd.b $vr14, $vr30, $vr5 ++0x2a 0xbc 0x46 0x70 # CHECK: vsadd.h $vr10, $vr1, $vr15 ++0xf3 0x2b 0x47 0x70 # CHECK: vsadd.w $vr19, $vr31, $vr10 ++0x7a 0xf2 0x47 0x70 # CHECK: vsadd.d $vr26, $vr19, $vr28 ++0x78 0x1c 0x48 0x70 # CHECK: vssub.b $vr24, $vr3, $vr7 ++0x9f 0xe0 0x48 0x70 # CHECK: vssub.h $vr31, $vr4, $vr24 ++0x7d 0x33 0x49 0x70 # CHECK: vssub.w $vr29, $vr27, $vr12 ++0x17 0xa6 0x49 0x70 # CHECK: vssub.d $vr23, $vr16, $vr9 ++0xba 0x13 0x4a 0x70 # CHECK: vsadd.bu $vr26, $vr29, $vr4 ++0xef 0xa4 0x4a 0x70 # CHECK: vsadd.hu $vr15, $vr7, $vr9 ++0x4d 0x42 0x4b 0x70 # CHECK: vsadd.wu $vr13, $vr18, $vr16 ++0xa4 0x80 0x4b 0x70 # CHECK: vsadd.du $vr4, $vr5, $vr0 ++0x3b 0x36 0x4c 0x70 # CHECK: vssub.bu $vr27, $vr17, $vr13 ++0x05 0x85 0x4c 0x70 # CHECK: vssub.hu $vr5, $vr8, $vr1 ++0x0e 0x59 0x4d 0x70 # CHECK: vssub.wu $vr14, $vr8, $vr22 ++0x31 0xa1 0x4d 0x70 # CHECK: vssub.du $vr17, $vr9, $vr8 ++0x77 0x0a 0x54 0x70 # CHECK: vhaddw.h.b $vr23, $vr19, $vr2 ++0x1a 0xea 0x54 0x70 # CHECK: vhaddw.w.h $vr26, $vr16, $vr26 ++0xe0 0x6f 0x55 0x70 # CHECK: vhaddw.d.w $vr0, $vr31, $vr27 ++0xb9 0xe5 0x55 0x70 # CHECK: vhaddw.q.d $vr25, $vr13, $vr25 ++0xe9 0x16 0x56 0x70 # CHECK: vhsubw.h.b $vr9, $vr23, $vr5 ++0xaf 0xeb 0x56 0x70 # CHECK: vhsubw.w.h $vr15, $vr29, $vr26 ++0x80 0x4b 0x57 0x70 # CHECK: vhsubw.d.w $vr0, $vr28, $vr18 ++0x2e 0xa3 0x57 0x70 # CHECK: vhsubw.q.d $vr14, $vr25, $vr8 ++0x01 0x56 0x58 0x70 # CHECK: vhaddw.hu.bu $vr1, $vr16, $vr21 ++0xbc 0xf6 0x58 0x70 # CHECK: vhaddw.wu.hu $vr28, $vr21, $vr29 ++0x9d 0x42 0x59 0x70 # CHECK: vhaddw.du.wu $vr29, $vr20, $vr16 ++0x42 0xf1 0x59 0x70 # CHECK: vhaddw.qu.du $vr2, $vr10, $vr28 ++0x7f 0x78 0x5a 0x70 # CHECK: vhsubw.hu.bu $vr31, $vr3, $vr30 ++0x25 0xad 0x5a 0x70 # CHECK: vhsubw.wu.hu $vr5, $vr9, $vr11 ++0xf7 0x5b 0x5b 0x70 # CHECK: vhsubw.du.wu $vr23, $vr31, $vr22 ++0x84 0xcb 0x5b 0x70 # CHECK: vhsubw.qu.du $vr4, $vr28, $vr18 ++0xb2 0x2d 0x5c 0x70 # CHECK: vadda.b $vr18, $vr13, $vr11 ++0xd1 0xb1 0x5c 0x70 # CHECK: vadda.h $vr17, $vr14, $vr12 ++0x76 0x0d 0x5d 0x70 # CHECK: vadda.w $vr22, $vr11, $vr3 ++0x18 0xbf 0x5d 0x70 # CHECK: vadda.d $vr24, $vr24, $vr15 ++0x77 0x46 0x60 0x70 # CHECK: vabsd.b $vr23, $vr19, $vr17 ++0xee 0xb7 0x60 0x70 # CHECK: vabsd.h $vr14, $vr31, $vr13 ++0x38 0x24 0x61 0x70 # CHECK: vabsd.w $vr24, $vr1, $vr9 ++0x9f 0x82 0x61 0x70 # CHECK: vabsd.d $vr31, $vr20, $vr0 ++0x97 0x75 0x62 0x70 # CHECK: vabsd.bu $vr23, $vr12, $vr29 ++0x72 0x86 0x62 0x70 # CHECK: vabsd.hu $vr18, $vr19, $vr1 ++0xad 0x72 0x63 0x70 # CHECK: vabsd.wu $vr13, $vr21, $vr28 ++0x50 0xaf 0x63 0x70 # CHECK: vabsd.du $vr16, $vr26, $vr11 ++0xa1 0x6e 0x64 0x70 # CHECK: vavg.b $vr1, $vr21, $vr27 ++0x54 0xbf 0x64 0x70 # CHECK: vavg.h $vr20, $vr26, $vr15 ++0x5d 0x0e 0x65 0x70 # CHECK: vavg.w $vr29, $vr18, $vr3 ++0xf3 0xfd 0x65 0x70 # CHECK: vavg.d $vr19, $vr15, $vr31 ++0x6b 0x45 0x66 0x70 # CHECK: vavg.bu $vr11, $vr11, $vr17 ++0x9e 0xb7 0x66 0x70 # CHECK: vavg.hu $vr30, $vr28, $vr13 ++0xe7 0x28 0x67 0x70 # CHECK: vavg.wu $vr7, $vr7, $vr10 ++0xf9 0xb0 0x67 0x70 # CHECK: vavg.du $vr25, $vr7, $vr12 ++0xbd 0x1d 0x68 0x70 # CHECK: vavgr.b $vr29, $vr13, $vr7 ++0x85 0xcf 0x68 0x70 # CHECK: vavgr.h $vr5, $vr28, $vr19 ++0xf3 0x39 0x69 0x70 # CHECK: vavgr.w $vr19, $vr15, $vr14 ++0x03 0x88 0x69 0x70 # CHECK: vavgr.d $vr3, $vr0, $vr2 ++0x77 0x7d 0x6a 0x70 # CHECK: vavgr.bu $vr23, $vr11, $vr31 ++0x79 0xa2 0x6a 0x70 # CHECK: vavgr.hu $vr25, $vr19, $vr8 ++0x3e 0x33 0x6b 0x70 # CHECK: vavgr.wu $vr30, $vr25, $vr12 ++0x99 0xe6 0x6b 0x70 # CHECK: vavgr.du $vr25, $vr20, $vr25 ++0x5c 0x6b 0x70 0x70 # CHECK: vmax.b $vr28, $vr26, $vr26 ++0xa8 0xad 0x70 0x70 # CHECK: vmax.h $vr8, $vr13, $vr11 ++0x95 0x7f 0x71 0x70 # CHECK: vmax.w $vr21, $vr28, $vr31 ++0xc1 0xeb 0x71 0x70 # CHECK: vmax.d $vr1, $vr30, $vr26 ++0xca 0x25 0x72 0x70 # CHECK: vmin.b $vr10, $vr14, $vr9 ++0x6a 0xd5 0x72 0x70 # CHECK: vmin.h $vr10, $vr11, $vr21 ++0x1a 0x30 0x73 0x70 # CHECK: vmin.w $vr26, $vr0, $vr12 ++0x53 0x82 0x73 0x70 # CHECK: vmin.d $vr19, $vr18, $vr0 ++0x22 0x73 0x74 0x70 # CHECK: vmax.bu $vr2, $vr25, $vr28 ++0xc9 0xfa 0x74 0x70 # CHECK: vmax.hu $vr9, $vr22, $vr30 ++0x35 0x6f 0x75 0x70 # CHECK: vmax.wu $vr21, $vr25, $vr27 ++0xc3 0xe5 0x75 0x70 # CHECK: vmax.du $vr3, $vr14, $vr25 ++0xf8 0x6c 0x76 0x70 # CHECK: vmin.bu $vr24, $vr7, $vr27 ++0x92 0xf7 0x76 0x70 # CHECK: vmin.hu $vr18, $vr28, $vr29 ++0x9a 0x08 0x77 0x70 # CHECK: vmin.wu $vr26, $vr4, $vr2 ++0x0d 0x90 0x77 0x70 # CHECK: vmin.du $vr13, $vr0, $vr4 ++0xa1 0x5e 0x84 0x70 # CHECK: vmul.b $vr1, $vr21, $vr23 ++0xa9 0xe6 0x84 0x70 # CHECK: vmul.h $vr9, $vr21, $vr25 ++0x10 0x71 0x85 0x70 # CHECK: vmul.w $vr16, $vr8, $vr28 ++0x24 0xae 0x85 0x70 # CHECK: vmul.d $vr4, $vr17, $vr11 ++0x0c 0x23 0x86 0x70 # CHECK: vmuh.b $vr12, $vr24, $vr8 ++0xa6 0xe2 0x86 0x70 # CHECK: vmuh.h $vr6, $vr21, $vr24 ++0xab 0x7b 0x87 0x70 # CHECK: vmuh.w $vr11, $vr29, $vr30 ++0x21 0xe6 0x87 0x70 # CHECK: vmuh.d $vr1, $vr17, $vr25 ++0xbd 0x2b 0x88 0x70 # CHECK: vmuh.bu $vr29, $vr29, $vr10 ++0x38 0xd5 0x88 0x70 # CHECK: vmuh.hu $vr24, $vr9, $vr21 ++0x8f 0x4e 0x89 0x70 # CHECK: vmuh.wu $vr15, $vr20, $vr19 ++0x80 0x87 0x89 0x70 # CHECK: vmuh.du $vr0, $vr28, $vr1 ++0x1b 0x10 0xa8 0x70 # CHECK: vmadd.b $vr27, $vr0, $vr4 ++0x93 0xf2 0xa8 0x70 # CHECK: vmadd.h $vr19, $vr20, $vr28 ++0xef 0x0c 0xa9 0x70 # CHECK: vmadd.w $vr15, $vr7, $vr3 ++0x39 0xfb 0xa9 0x70 # CHECK: vmadd.d $vr25, $vr25, $vr30 ++0x38 0x6b 0xaa 0x70 # CHECK: vmsub.b $vr24, $vr25, $vr26 ++0x0c 0xb4 0xaa 0x70 # CHECK: vmsub.h $vr12, $vr0, $vr13 ++0x1a 0x62 0xab 0x70 # CHECK: vmsub.w $vr26, $vr16, $vr24 ++0x4d 0xa1 0xab 0x70 # CHECK: vmsub.d $vr13, $vr10, $vr8 ++0x92 0x57 0xe0 0x70 # CHECK: vdiv.b $vr18, $vr28, $vr21 ++0x11 0x87 0xe0 0x70 # CHECK: vdiv.h $vr17, $vr24, $vr1 ++0x43 0x59 0xe1 0x70 # CHECK: vdiv.w $vr3, $vr10, $vr22 ++0xaf 0xa1 0xe1 0x70 # CHECK: vdiv.d $vr15, $vr13, $vr8 ++0x33 0x53 0xe2 0x70 # CHECK: vmod.b $vr19, $vr25, $vr20 ++0x02 0xdb 0xe2 0x70 # CHECK: vmod.h $vr2, $vr24, $vr22 ++0x5f 0x02 0xe3 0x70 # CHECK: vmod.w $vr31, $vr18, $vr0 ++0x1f 0x88 0xe3 0x70 # CHECK: vmod.d $vr31, $vr0, $vr2 ++0x8f 0x0c 0xe4 0x70 # CHECK: vdiv.bu $vr15, $vr4, $vr3 ++0xf1 0xf4 0xe4 0x70 # CHECK: vdiv.hu $vr17, $vr7, $vr29 ++0x5b 0x0d 0xe5 0x70 # CHECK: vdiv.wu $vr27, $vr10, $vr3 ++0x08 0xeb 0xe5 0x70 # CHECK: vdiv.du $vr8, $vr24, $vr26 ++0xca 0x62 0xe6 0x70 # CHECK: vmod.bu $vr10, $vr22, $vr24 ++0xf3 0xe3 0xe6 0x70 # CHECK: vmod.hu $vr19, $vr31, $vr24 ++0x1a 0x37 0xe7 0x70 # CHECK: vmod.wu $vr26, $vr24, $vr13 ++0x74 0xaa 0xe7 0x70 # CHECK: vmod.du $vr20, $vr19, $vr10 ++0x5c 0x7a 0xe8 0x70 # CHECK: vsll.b $vr28, $vr18, $vr30 ++0x96 0xf8 0xe8 0x70 # CHECK: vsll.h $vr22, $vr4, $vr30 ++0x21 0x23 0xe9 0x70 # CHECK: vsll.w $vr1, $vr25, $vr8 ++0x5f 0xbe 0xe9 0x70 # CHECK: vsll.d $vr31, $vr18, $vr15 ++0x85 0x41 0xea 0x70 # CHECK: vsrl.b $vr5, $vr12, $vr16 ++0xa9 0xf0 0xea 0x70 # CHECK: vsrl.h $vr9, $vr5, $vr28 ++0x1e 0x06 0xeb 0x70 # CHECK: vsrl.w $vr30, $vr16, $vr1 ++0xfc 0xee 0xeb 0x70 # CHECK: vsrl.d $vr28, $vr23, $vr27 ++0x2f 0x66 0xec 0x70 # CHECK: vsra.b $vr15, $vr17, $vr25 ++0x00 0x95 0xec 0x70 # CHECK: vsra.h $vr0, $vr8, $vr5 ++0x3d 0x1d 0xed 0x70 # CHECK: vsra.w $vr29, $vr9, $vr7 ++0x76 0xcc 0xed 0x70 # CHECK: vsra.d $vr22, $vr3, $vr19 ++0x08 0x22 0xee 0x70 # CHECK: vrotr.b $vr8, $vr16, $vr8 ++0xae 0xac 0xee 0x70 # CHECK: vrotr.h $vr14, $vr5, $vr11 ++0x91 0x67 0xef 0x70 # CHECK: vrotr.w $vr17, $vr28, $vr25 ++0x92 0xcf 0xef 0x70 # CHECK: vrotr.d $vr18, $vr28, $vr19 ++0x61 0x47 0xf0 0x70 # CHECK: vsrlr.b $vr1, $vr27, $vr17 ++0xda 0xa9 0xf0 0x70 # CHECK: vsrlr.h $vr26, $vr14, $vr10 ++0xa3 0x63 0xf1 0x70 # CHECK: vsrlr.w $vr3, $vr29, $vr24 ++0x97 0xa8 0xf1 0x70 # CHECK: vsrlr.d $vr23, $vr4, $vr10 ++0x59 0x54 0xf2 0x70 # CHECK: vsrar.b $vr25, $vr2, $vr21 ++0x64 0xd1 0xf2 0x70 # CHECK: vsrar.h $vr4, $vr11, $vr20 ++0xab 0x76 0xf3 0x70 # CHECK: vsrar.w $vr11, $vr21, $vr29 ++0xbd 0x88 0xf3 0x70 # CHECK: vsrar.d $vr29, $vr5, $vr2 ++0xd8 0xf5 0xf4 0x70 # CHECK: vsrln.b.h $vr24, $vr14, $vr29 ++0xda 0x42 0xf5 0x70 # CHECK: vsrln.h.w $vr26, $vr22, $vr16 ++0xf1 0x8b 0xf5 0x70 # CHECK: vsrln.w.d $vr17, $vr31, $vr2 ++0x1f 0xdc 0xf6 0x70 # CHECK: vsran.b.h $vr31, $vr0, $vr23 ++0x94 0x75 0xf7 0x70 # CHECK: vsran.h.w $vr20, $vr12, $vr29 ++0x22 0x88 0xf7 0x70 # CHECK: vsran.w.d $vr2, $vr1, $vr2 ++0x93 0x83 0xf8 0x70 # CHECK: vsrlrn.b.h $vr19, $vr28, $vr0 ++0xb7 0x3b 0xf9 0x70 # CHECK: vsrlrn.h.w $vr23, $vr29, $vr14 ++0x45 0x97 0xf9 0x70 # CHECK: vsrlrn.w.d $vr5, $vr26, $vr5 ++0xf1 0x9d 0xfa 0x70 # CHECK: vsrarn.b.h $vr17, $vr15, $vr7 ++0x4c 0x75 0xfb 0x70 # CHECK: vsrarn.h.w $vr12, $vr10, $vr29 ++0x58 0xef 0xfb 0x70 # CHECK: vsrarn.w.d $vr24, $vr26, $vr27 ++0x81 0xb9 0xfc 0x70 # CHECK: vssrln.b.h $vr1, $vr12, $vr14 ++0x0b 0x49 0xfd 0x70 # CHECK: vssrln.h.w $vr11, $vr8, $vr18 ++0xff 0x99 0xfd 0x70 # CHECK: vssrln.w.d $vr31, $vr15, $vr6 ++0xad 0xe0 0xfe 0x70 # CHECK: vssran.b.h $vr13, $vr5, $vr24 ++0x44 0x1f 0xff 0x70 # CHECK: vssran.h.w $vr4, $vr26, $vr7 ++0x59 0x99 0xff 0x70 # CHECK: vssran.w.d $vr25, $vr10, $vr6 ++0x9c 0x9b 0x00 0x71 # CHECK: vssrlrn.b.h $vr28, $vr28, $vr6 ++0xef 0x46 0x01 0x71 # CHECK: vssrlrn.h.w $vr15, $vr23, $vr17 ++0x2c 0x89 0x01 0x71 # CHECK: vssrlrn.w.d $vr12, $vr9, $vr2 ++0x21 0xc7 0x02 0x71 # CHECK: vssrarn.b.h $vr1, $vr25, $vr17 ++0x23 0x5d 0x03 0x71 # CHECK: vssrarn.h.w $vr3, $vr9, $vr23 ++0x2e 0xed 0x03 0x71 # CHECK: vssrarn.w.d $vr14, $vr9, $vr27 ++0x10 0xbf 0x04 0x71 # CHECK: vssrln.bu.h $vr16, $vr24, $vr15 ++0xf5 0x7a 0x05 0x71 # CHECK: vssrln.hu.w $vr21, $vr23, $vr30 ++0x0c 0xf9 0x05 0x71 # CHECK: vssrln.wu.d $vr12, $vr8, $vr30 ++0x45 0xb2 0x06 0x71 # CHECK: vssran.bu.h $vr5, $vr18, $vr12 ++0xe0 0x70 0x07 0x71 # CHECK: vssran.hu.w $vr0, $vr7, $vr28 ++0x65 0xa1 0x07 0x71 # CHECK: vssran.wu.d $vr5, $vr11, $vr8 ++0x32 0x8f 0x08 0x71 # CHECK: vssrlrn.bu.h $vr18, $vr25, $vr3 ++0x33 0x50 0x09 0x71 # CHECK: vssrlrn.hu.w $vr19, $vr1, $vr20 ++0xc6 0xcb 0x09 0x71 # CHECK: vssrlrn.wu.d $vr6, $vr30, $vr18 ++0xac 0x8d 0x0a 0x71 # CHECK: vssrarn.bu.h $vr12, $vr13, $vr3 ++0xb2 0x50 0x0b 0x71 # CHECK: vssrarn.hu.w $vr18, $vr5, $vr20 ++0x17 0xd5 0x0b 0x71 # CHECK: vssrarn.wu.d $vr23, $vr8, $vr21 ++0x4e 0x7c 0x0c 0x71 # CHECK: vbitclr.b $vr14, $vr2, $vr31 ++0x31 0xa3 0x0c 0x71 # CHECK: vbitclr.h $vr17, $vr25, $vr8 ++0x72 0x0d 0x0d 0x71 # CHECK: vbitclr.w $vr18, $vr11, $vr3 ++0xff 0xf5 0x0d 0x71 # CHECK: vbitclr.d $vr31, $vr15, $vr29 ++0xa8 0x43 0x0e 0x71 # CHECK: vbitset.b $vr8, $vr29, $vr16 ++0x25 0xc6 0x0e 0x71 # CHECK: vbitset.h $vr5, $vr17, $vr17 ++0x65 0x16 0x0f 0x71 # CHECK: vbitset.w $vr5, $vr19, $vr5 ++0x65 0xab 0x0f 0x71 # CHECK: vbitset.d $vr5, $vr27, $vr10 ++0xb0 0x20 0x10 0x71 # CHECK: vbitrev.b $vr16, $vr5, $vr8 ++0xac 0xb3 0x10 0x71 # CHECK: vbitrev.h $vr12, $vr29, $vr12 ++0xc3 0x39 0x11 0x71 # CHECK: vbitrev.w $vr3, $vr14, $vr14 ++0x7f 0xbb 0x11 0x71 # CHECK: vbitrev.d $vr31, $vr27, $vr14 ++0x16 0x4f 0x16 0x71 # CHECK: vpackev.b $vr22, $vr24, $vr19 ++0x5c 0xc8 0x16 0x71 # CHECK: vpackev.h $vr28, $vr2, $vr18 ++0x75 0x10 0x17 0x71 # CHECK: vpackev.w $vr21, $vr3, $vr4 ++0xb8 0xae 0x17 0x71 # CHECK: vpackev.d $vr24, $vr21, $vr11 ++0xec 0x6b 0x18 0x71 # CHECK: vpackod.b $vr12, $vr31, $vr26 ++0x79 0xc0 0x18 0x71 # CHECK: vpackod.h $vr25, $vr3, $vr16 ++0x55 0x3e 0x19 0x71 # CHECK: vpackod.w $vr21, $vr18, $vr15 ++0x62 0x80 0x19 0x71 # CHECK: vpackod.d $vr2, $vr3, $vr0 ++0x08 0x71 0x1a 0x71 # CHECK: vilvl.b $vr8, $vr8, $vr28 ++0x14 0xfc 0x1a 0x71 # CHECK: vilvl.h $vr20, $vr0, $vr31 ++0x4b 0x45 0x1b 0x71 # CHECK: vilvl.w $vr11, $vr10, $vr17 ++0xe7 0x84 0x1b 0x71 # CHECK: vilvl.d $vr7, $vr7, $vr1 ++0x6b 0x05 0x1c 0x71 # CHECK: vilvh.b $vr11, $vr11, $vr1 ++0xe0 0xb7 0x1c 0x71 # CHECK: vilvh.h $vr0, $vr31, $vr13 ++0xbc 0x1e 0x1d 0x71 # CHECK: vilvh.w $vr28, $vr21, $vr7 ++0x77 0xcc 0x1d 0x71 # CHECK: vilvh.d $vr23, $vr3, $vr19 ++0xa1 0x22 0x1e 0x71 # CHECK: vpickev.b $vr1, $vr21, $vr8 ++0x30 0xa4 0x1e 0x71 # CHECK: vpickev.h $vr16, $vr1, $vr9 ++0xad 0x11 0x1f 0x71 # CHECK: vpickev.w $vr13, $vr13, $vr4 ++0xcb 0xfb 0x1f 0x71 # CHECK: vpickev.d $vr11, $vr30, $vr30 ++0x67 0x35 0x20 0x71 # CHECK: vpickod.b $vr7, $vr11, $vr13 ++0x72 0x84 0x20 0x71 # CHECK: vpickod.h $vr18, $vr3, $vr1 ++0x03 0x4e 0x21 0x71 # CHECK: vpickod.w $vr3, $vr16, $vr19 ++0xac 0xd5 0x21 0x71 # CHECK: vpickod.d $vr12, $vr13, $vr21 ++0x2f 0x4e 0x22 0x71 # CHECK: vreplve.b $vr15, $vr17, $r19 ++0xee 0x92 0x22 0x71 # CHECK: vreplve.h $vr14, $vr23, $r4 ++0x7d 0x6e 0x23 0x71 # CHECK: vreplve.w $vr29, $vr19, $r27 ++0x8d 0xd2 0x23 0x71 # CHECK: vreplve.d $vr13, $vr20, $r20 ++0x59 0x54 0x26 0x71 # CHECK: vand.v $vr25, $vr2, $vr21 ++0x64 0xc3 0x26 0x71 # CHECK: vor.v $vr4, $vr27, $vr16 ++0x3e 0x13 0x27 0x71 # CHECK: vxor.v $vr30, $vr25, $vr4 ++0x49 0xd8 0x27 0x71 # CHECK: vnor.v $vr9, $vr2, $vr22 ++0x54 0x13 0x28 0x71 # CHECK: vandn.v $vr20, $vr26, $vr4 ++0xa6 0xfa 0x28 0x71 # CHECK: vorn.v $vr6, $vr21, $vr30 ++0x2b 0x35 0x2b 0x71 # CHECK: vfrstp.b $vr11, $vr9, $vr13 ++0x55 0xdb 0x2b 0x71 # CHECK: vfrstp.h $vr21, $vr26, $vr22 ++0xe9 0x40 0x2d 0x71 # CHECK: vadd.q $vr9, $vr7, $vr16 ++0x22 0xc0 0x2d 0x71 # CHECK: vsub.q $vr2, $vr1, $vr16 ++0x42 0x38 0x2e 0x71 # CHECK: vsigncov.b $vr2, $vr2, $vr14 ++0xb5 0xb6 0x2e 0x71 # CHECK: vsigncov.h $vr21, $vr21, $vr13 ++0xf5 0x14 0x2f 0x71 # CHECK: vsigncov.w $vr21, $vr7, $vr5 ++0x4a 0x8d 0x2f 0x71 # CHECK: vsigncov.d $vr10, $vr10, $vr3 ++0x8a 0x84 0x30 0x71 # CHECK: vfadd.s $vr10, $vr4, $vr1 ++0x6f 0x0b 0x31 0x71 # CHECK: vfadd.d $vr15, $vr27, $vr2 ++0x0e 0xa6 0x32 0x71 # CHECK: vfsub.s $vr14, $vr16, $vr9 ++0x24 0x20 0x33 0x71 # CHECK: vfsub.d $vr4, $vr1, $vr8 ++0x40 0x9a 0x38 0x71 # CHECK: vfmul.s $vr0, $vr18, $vr6 ++0xfb 0x7b 0x39 0x71 # CHECK: vfmul.d $vr27, $vr31, $vr30 ++0xe3 0x98 0x3a 0x71 # CHECK: vfdiv.s $vr3, $vr7, $vr6 ++0xd0 0x78 0x3b 0x71 # CHECK: vfdiv.d $vr16, $vr6, $vr30 ++0xd2 0xa3 0x3c 0x71 # CHECK: vfmax.s $vr18, $vr30, $vr8 ++0x13 0x61 0x3d 0x71 # CHECK: vfmax.d $vr19, $vr8, $vr24 ++0x58 0x9b 0x3e 0x71 # CHECK: vfmin.s $vr24, $vr26, $vr6 ++0x30 0x07 0x3f 0x71 # CHECK: vfmin.d $vr16, $vr25, $vr1 ++0xe8 0xb8 0x40 0x71 # CHECK: vfmaxa.s $vr8, $vr7, $vr14 ++0x0a 0x11 0x41 0x71 # CHECK: vfmaxa.d $vr10, $vr8, $vr4 ++0xd0 0xc8 0x42 0x71 # CHECK: vfmina.s $vr16, $vr6, $vr18 ++0xfa 0x38 0x43 0x71 # CHECK: vfmina.d $vr26, $vr7, $vr14 ++0x9e 0x60 0x46 0x71 # CHECK: vfcvt.h.s $vr30, $vr4, $vr24 ++0x30 0x92 0x46 0x71 # CHECK: vfcvt.s.d $vr16, $vr17, $vr4 ++0xf9 0x2a 0x48 0x71 # CHECK: vffint.s.l $vr25, $vr23, $vr10 ++0xc9 0xee 0x49 0x71 # CHECK: vftint.w.d $vr9, $vr22, $vr27 ++0x5f 0x75 0x4a 0x71 # CHECK: vftintrm.w.d $vr31, $vr10, $vr29 ++0xb7 0xbd 0x4a 0x71 # CHECK: vftintrp.w.d $vr23, $vr13, $vr15 ++0x32 0x19 0x4b 0x71 # CHECK: vftintrz.w.d $vr18, $vr9, $vr6 ++0x95 0xf9 0x4b 0x71 # CHECK: vftintrne.w.d $vr21, $vr12, $vr30 ++0x63 0x89 0x7a 0x71 # CHECK: vshuf.h $vr3, $vr11, $vr2 ++0x95 0x74 0x7b 0x71 # CHECK: vshuf.w $vr21, $vr4, $vr29 ++0xeb 0xca 0x7b 0x71 # CHECK: vshuf.d $vr11, $vr23, $vr18 ++0xdb 0x1d 0x80 0x72 # CHECK: vseqi.b $vr27, $vr14, 7 ++0x77 0xeb 0x80 0x72 # CHECK: vseqi.h $vr23, $vr27, -6 ++0x08 0x41 0x81 0x72 # CHECK: vseqi.w $vr8, $vr8, -16 ++0xab 0x94 0x81 0x72 # CHECK: vseqi.d $vr11, $vr5, 5 ++0x68 0x1f 0x82 0x72 # CHECK: vslei.b $vr8, $vr27, 7 ++0xbb 0xef 0x82 0x72 # CHECK: vslei.h $vr27, $vr29, -5 ++0xb7 0x75 0x83 0x72 # CHECK: vslei.w $vr23, $vr13, -3 ++0xe5 0xe1 0x83 0x72 # CHECK: vslei.d $vr5, $vr15, -8 ++0x5d 0x25 0x84 0x72 # CHECK: vslei.bu $vr29, $vr10, 9 ++0x5d 0xae 0x84 0x72 # CHECK: vslei.hu $vr29, $vr18, 11 ++0x28 0x08 0x85 0x72 # CHECK: vslei.wu $vr8, $vr1, 2 ++0xb0 0xa8 0x85 0x72 # CHECK: vslei.du $vr16, $vr5, 10 ++0x88 0x78 0x86 0x72 # CHECK: vslti.b $vr8, $vr4, -2 ++0xfa 0xc8 0x86 0x72 # CHECK: vslti.h $vr26, $vr7, -14 ++0x1c 0x31 0x87 0x72 # CHECK: vslti.w $vr28, $vr8, 12 ++0x64 0xa7 0x87 0x72 # CHECK: vslti.d $vr4, $vr27, 9 ++0xca 0x49 0x88 0x72 # CHECK: vslti.bu $vr10, $vr14, 18 ++0x9c 0xfb 0x88 0x72 # CHECK: vslti.hu $vr28, $vr28, 30 ++0x6f 0x6f 0x89 0x72 # CHECK: vslti.wu $vr15, $vr27, 27 ++0x3e 0xce 0x89 0x72 # CHECK: vslti.du $vr30, $vr17, 19 ++0x26 0x48 0x8a 0x72 # CHECK: vaddi.bu $vr6, $vr1, 18 ++0xcc 0x95 0x8a 0x72 # CHECK: vaddi.hu $vr12, $vr14, 5 ++0x1c 0x68 0x8b 0x72 # CHECK: vaddi.wu $vr28, $vr0, 26 ++0xaa 0x88 0x8b 0x72 # CHECK: vaddi.du $vr10, $vr5, 2 ++0x96 0x0b 0x8c 0x72 # CHECK: vsubi.bu $vr22, $vr28, 2 ++0xc0 0xfe 0x8c 0x72 # CHECK: vsubi.hu $vr0, $vr22, 31 ++0xd4 0x14 0x8d 0x72 # CHECK: vsubi.wu $vr20, $vr6, 5 ++0x72 0x85 0x8d 0x72 # CHECK: vsubi.du $vr18, $vr11, 1 ++0x44 0x13 0x8e 0x72 # CHECK: vbsll.v $vr4, $vr26, 4 ++0xe7 0xbf 0x8e 0x72 # CHECK: vbsrl.v $vr7, $vr31, 15 ++0xf3 0x39 0x90 0x72 # CHECK: vmaxi.b $vr19, $vr15, 14 ++0x79 0xd0 0x90 0x72 # CHECK: vmaxi.h $vr25, $vr3, -12 ++0x34 0x17 0x91 0x72 # CHECK: vmaxi.w $vr20, $vr25, 5 ++0x49 0xb1 0x91 0x72 # CHECK: vmaxi.d $vr9, $vr10, 12 ++0xbe 0x72 0x92 0x72 # CHECK: vmini.b $vr30, $vr21, -4 ++0x8b 0xf7 0x92 0x72 # CHECK: vmini.h $vr11, $vr28, -3 ++0x26 0x5f 0x93 0x72 # CHECK: vmini.w $vr6, $vr25, -9 ++0x1c 0x89 0x93 0x72 # CHECK: vmini.d $vr28, $vr8, 2 ++0x0d 0x4f 0x94 0x72 # CHECK: vmaxi.bu $vr13, $vr24, 19 ++0x23 0xd8 0x94 0x72 # CHECK: vmaxi.hu $vr3, $vr1, 22 ++0x61 0x5c 0x95 0x72 # CHECK: vmaxi.wu $vr1, $vr3, 23 ++0x46 0xd6 0x95 0x72 # CHECK: vmaxi.du $vr6, $vr18, 21 ++0x4a 0x50 0x96 0x72 # CHECK: vmini.bu $vr10, $vr2, 20 ++0x31 0xbe 0x96 0x72 # CHECK: vmini.hu $vr17, $vr17, 15 ++0x7a 0x5f 0x97 0x72 # CHECK: vmini.wu $vr26, $vr27, 23 ++0x6c 0xa3 0x97 0x72 # CHECK: vmini.du $vr12, $vr27, 8 ++0x1a 0x25 0x9a 0x72 # CHECK: vfrstpi.b $vr26, $vr8, 9 ++0x50 0xd0 0x9a 0x72 # CHECK: vfrstpi.h $vr16, $vr2, 20 ++0x25 0x02 0x9c 0x72 # CHECK: vclo.b $vr5, $vr17 ++0x88 0x04 0x9c 0x72 # CHECK: vclo.h $vr8, $vr4 ++0xa1 0x09 0x9c 0x72 # CHECK: vclo.w $vr1, $vr13 ++0xe0 0x0e 0x9c 0x72 # CHECK: vclo.d $vr0, $vr23 ++0x24 0x13 0x9c 0x72 # CHECK: vclz.b $vr4, $vr25 ++0x21 0x17 0x9c 0x72 # CHECK: vclz.h $vr1, $vr25 ++0xa1 0x18 0x9c 0x72 # CHECK: vclz.w $vr1, $vr5 ++0x30 0x1e 0x9c 0x72 # CHECK: vclz.d $vr16, $vr17 ++0x64 0x20 0x9c 0x72 # CHECK: vpcnt.b $vr4, $vr3 ++0x2f 0x26 0x9c 0x72 # CHECK: vpcnt.h $vr15, $vr17 ++0x0d 0x29 0x9c 0x72 # CHECK: vpcnt.w $vr13, $vr8 ++0x00 0x2d 0x9c 0x72 # CHECK: vpcnt.d $vr0, $vr8 ++0x0e 0x33 0x9c 0x72 # CHECK: vneg.b $vr14, $vr24 ++0xf8 0x34 0x9c 0x72 # CHECK: vneg.h $vr24, $vr7 ++0xb3 0x38 0x9c 0x72 # CHECK: vneg.w $vr19, $vr5 ++0x83 0x3f 0x9c 0x72 # CHECK: vneg.d $vr3, $vr28 ++0x3f 0x43 0x9c 0x72 # CHECK: vmskltz.b $vr31, $vr25 ++0x89 0x46 0x9c 0x72 # CHECK: vmskltz.h $vr9, $vr20 ++0x56 0x4b 0x9c 0x72 # CHECK: vmskltz.w $vr22, $vr26 ++0x5c 0x4d 0x9c 0x72 # CHECK: vmskltz.d $vr28, $vr10 ++0xa7 0x50 0x9c 0x72 # CHECK: vmskgez.b $vr7, $vr5 ++0x94 0x61 0x9c 0x72 # CHECK: vmsknz.b $vr20, $vr12 ++0xc5 0x99 0x9c 0x72 # CHECK: vseteqz.v $fcc5, $vr14 ++0x02 0x9d 0x9c 0x72 # CHECK: vsetnez.v $fcc2, $vr8 ++0x80 0xa2 0x9c 0x72 # CHECK: vsetanyeqz.b $fcc0, $vr20 ++0x04 0xa6 0x9c 0x72 # CHECK: vsetanyeqz.h $fcc4, $vr16 ++0x47 0xa8 0x9c 0x72 # CHECK: vsetanyeqz.w $fcc7, $vr2 ++0x84 0xad 0x9c 0x72 # CHECK: vsetanyeqz.d $fcc4, $vr12 ++0x07 0xb0 0x9c 0x72 # CHECK: vsetallnez.b $fcc7, $vr0 ++0x62 0xb5 0x9c 0x72 # CHECK: vsetallnez.h $fcc2, $vr11 ++0x26 0xbb 0x9c 0x72 # CHECK: vsetallnez.w $fcc6, $vr25 ++0xe7 0xbf 0x9c 0x72 # CHECK: vsetallnez.d $fcc7, $vr31 ++0x8e 0xc7 0x9c 0x72 # CHECK: vflogb.s $vr14, $vr28 ++0x3d 0xc9 0x9c 0x72 # CHECK: vflogb.d $vr29, $vr9 ++0xa3 0xd5 0x9c 0x72 # CHECK: vfclass.s $vr3, $vr13 ++0xe5 0xd9 0x9c 0x72 # CHECK: vfclass.d $vr5, $vr15 ++0x73 0xe7 0x9c 0x72 # CHECK: vfsqrt.s $vr19, $vr27 ++0x7f 0xe8 0x9c 0x72 # CHECK: vfsqrt.d $vr31, $vr3 ++0x18 0xf6 0x9c 0x72 # CHECK: vfrecip.s $vr24, $vr16 ++0x77 0xfa 0x9c 0x72 # CHECK: vfrecip.d $vr23, $vr19 ++0xf2 0x05 0x9d 0x72 # CHECK: vfrsqrt.s $vr18, $vr15 ++0xf2 0x0b 0x9d 0x72 # CHECK: vfrsqrt.d $vr18, $vr31 ++0x7a 0x35 0x9d 0x72 # CHECK: vfrint.s $vr26, $vr11 ++0x58 0x3a 0x9d 0x72 # CHECK: vfrint.d $vr24, $vr18 ++0x65 0x44 0x9d 0x72 # CHECK: vfrintrm.s $vr5, $vr3 ++0x57 0x49 0x9d 0x72 # CHECK: vfrintrm.d $vr23, $vr10 ++0x54 0x54 0x9d 0x72 # CHECK: vfrintrp.s $vr20, $vr2 ++0x3e 0x5a 0x9d 0x72 # CHECK: vfrintrp.d $vr30, $vr17 ++0xd3 0x64 0x9d 0x72 # CHECK: vfrintrz.s $vr19, $vr6 ++0x50 0x6a 0x9d 0x72 # CHECK: vfrintrz.d $vr16, $vr18 ++0x08 0x77 0x9d 0x72 # CHECK: vfrintrne.s $vr8, $vr24 ++0xa6 0x78 0x9d 0x72 # CHECK: vfrintrne.d $vr6, $vr5 ++0xc4 0xe8 0x9d 0x72 # CHECK: vfcvtl.s.h $vr4, $vr6 ++0xf0 0xec 0x9d 0x72 # CHECK: vfcvth.s.h $vr16, $vr7 ++0x50 0xf1 0x9d 0x72 # CHECK: vfcvtl.d.s $vr16, $vr10 ++0x3c 0xf7 0x9d 0x72 # CHECK: vfcvth.d.s $vr28, $vr25 ++0x1c 0x02 0x9e 0x72 # CHECK: vffint.s.w $vr28, $vr16 ++0xe4 0x07 0x9e 0x72 # CHECK: vffint.s.wu $vr4, $vr31 ++0x32 0x0b 0x9e 0x72 # CHECK: vffint.d.l $vr18, $vr25 ++0x38 0x0e 0x9e 0x72 # CHECK: vffint.d.lu $vr24, $vr17 ++0x62 0x13 0x9e 0x72 # CHECK: vffintl.d.w $vr2, $vr27 ++0x04 0x16 0x9e 0x72 # CHECK: vffinth.d.w $vr4, $vr16 ++0x11 0x30 0x9e 0x72 # CHECK: vftint.w.s $vr17, $vr0 ++0x57 0x36 0x9e 0x72 # CHECK: vftint.l.d $vr23, $vr18 ++0x97 0x38 0x9e 0x72 # CHECK: vftintrm.w.s $vr23, $vr4 ++0xde 0x3d 0x9e 0x72 # CHECK: vftintrm.l.d $vr30, $vr14 ++0x07 0x40 0x9e 0x72 # CHECK: vftintrp.w.s $vr7, $vr0 ++0x9c 0x46 0x9e 0x72 # CHECK: vftintrp.l.d $vr28, $vr20 ++0xfc 0x4b 0x9e 0x72 # CHECK: vftintrz.w.s $vr28, $vr31 ++0x12 0x4c 0x9e 0x72 # CHECK: vftintrz.l.d $vr18, $vr0 ++0x2e 0x52 0x9e 0x72 # CHECK: vftintrne.w.s $vr14, $vr17 ++0x56 0x56 0x9e 0x72 # CHECK: vftintrne.l.d $vr22, $vr18 ++0x3a 0x5b 0x9e 0x72 # CHECK: vftint.wu.s $vr26, $vr25 ++0x69 0x5f 0x9e 0x72 # CHECK: vftint.lu.d $vr9, $vr27 ++0xda 0x72 0x9e 0x72 # CHECK: vftintrz.wu.s $vr26, $vr22 ++0x9d 0x76 0x9e 0x72 # CHECK: vftintrz.lu.d $vr29, $vr20 ++0x36 0x80 0x9e 0x72 # CHECK: vftintl.l.s $vr22, $vr1 ++0x0d 0x87 0x9e 0x72 # CHECK: vftinth.l.s $vr13, $vr24 ++0x68 0x8b 0x9e 0x72 # CHECK: vftintrml.l.s $vr8, $vr27 ++0x92 0x8f 0x9e 0x72 # CHECK: vftintrmh.l.s $vr18, $vr28 ++0x9b 0x93 0x9e 0x72 # CHECK: vftintrpl.l.s $vr27, $vr28 ++0xf4 0x94 0x9e 0x72 # CHECK: vftintrph.l.s $vr20, $vr7 ++0x46 0x98 0x9e 0x72 # CHECK: vftintrzl.l.s $vr6, $vr2 ++0xd5 0x9c 0x9e 0x72 # CHECK: vftintrzh.l.s $vr21, $vr6 ++0x79 0xa0 0x9e 0x72 # CHECK: vftintrnel.l.s $vr25, $vr3 ++0xa7 0xa4 0x9e 0x72 # CHECK: vftintrneh.l.s $vr7, $vr5 ++0x49 0xe0 0x9e 0x72 # CHECK: vexth.h.b $vr9, $vr2 ++0x64 0xe7 0x9e 0x72 # CHECK: vexth.w.h $vr4, $vr27 ++0x37 0xe8 0x9e 0x72 # CHECK: vexth.d.w $vr23, $vr1 ++0xcf 0xec 0x9e 0x72 # CHECK: vexth.q.d $vr15, $vr6 ++0x43 0xf0 0x9e 0x72 # CHECK: vexth.hu.bu $vr3, $vr2 ++0x5f 0xf7 0x9e 0x72 # CHECK: vexth.wu.hu $vr31, $vr26 ++0xea 0xfb 0x9e 0x72 # CHECK: vexth.du.wu $vr10, $vr31 ++0x1c 0xfd 0x9e 0x72 # CHECK: vexth.qu.du $vr28, $vr8 ++0x6f 0x00 0x9f 0x72 # CHECK: vreplgr2vr.b $vr15, $sp ++0xea 0x06 0x9f 0x72 # CHECK: vreplgr2vr.h $vr10, $r23 ++0x19 0x0a 0x9f 0x72 # CHECK: vreplgr2vr.w $vr25, $r16 ++0xfb 0x0c 0x9f 0x72 # CHECK: vreplgr2vr.d $vr27, $r7 ++0x18 0x3f 0xa0 0x72 # CHECK: vrotri.b $vr24, $vr24, 7 ++0xa1 0x40 0xa0 0x72 # CHECK: vrotri.h $vr1, $vr5, 0 ++0x0a 0xb1 0xa0 0x72 # CHECK: vrotri.w $vr10, $vr8, 12 ++0xbe 0xab 0xa1 0x72 # CHECK: vrotri.d $vr30, $vr29, 42 ++0x01 0x2e 0xa4 0x72 # CHECK: vsrlri.b $vr1, $vr16, 3 ++0xbc 0x46 0xa4 0x72 # CHECK: vsrlri.h $vr28, $vr21, 1 ++0x92 0xbc 0xa4 0x72 # CHECK: vsrlri.w $vr18, $vr4, 15 ++0x7e 0x4c 0xa5 0x72 # CHECK: vsrlri.d $vr30, $vr3, 19 ++0x0d 0x3c 0xa8 0x72 # CHECK: vsrari.b $vr13, $vr0, 7 ++0x31 0x59 0xa8 0x72 # CHECK: vsrari.h $vr17, $vr9, 6 ++0x83 0x9b 0xa8 0x72 # CHECK: vsrari.w $vr3, $vr28, 6 ++0x44 0x88 0xa9 0x72 # CHECK: vsrari.d $vr4, $vr2, 34 ++0x08 0x91 0xeb 0x72 # CHECK: vinsgr2vr.b $vr8, $r8, 4 ++0xed 0xc4 0xeb 0x72 # CHECK: vinsgr2vr.h $vr13, $r7, 1 ++0xc4 0xec 0xeb 0x72 # CHECK: vinsgr2vr.w $vr4, $r6, 3 ++0xf7 0xf3 0xeb 0x72 # CHECK: vinsgr2vr.d $vr23, $r31, 0 ++0x18 0xaa 0xef 0x72 # CHECK: vpickve2gr.b $r24, $vr16, 10 ++0x31 0xcf 0xef 0x72 # CHECK: vpickve2gr.h $r17, $vr25, 3 ++0x9e 0xeb 0xef 0x72 # CHECK: vpickve2gr.w $r30, $vr28, 2 ++0x39 0xf5 0xef 0x72 # CHECK: vpickve2gr.d $r25, $vr9, 1 ++0xdf 0x89 0xf3 0x72 # CHECK: vpickve2gr.bu $r31, $vr14, 2 ++0x2c 0xd8 0xf3 0x72 # CHECK: vpickve2gr.hu $r12, $vr1, 6 ++0x2a 0xe6 0xf3 0x72 # CHECK: vpickve2gr.wu $r10, $vr17, 1 ++0x1a 0xf5 0xf3 0x72 # CHECK: vpickve2gr.du $r26, $vr8, 1 ++0xc3 0xb0 0xf7 0x72 # CHECK: vreplvei.b $vr3, $vr6, 12 ++0xb6 0xdf 0xf7 0x72 # CHECK: vreplvei.h $vr22, $vr29, 7 ++0x51 0xe7 0xf7 0x72 # CHECK: vreplvei.w $vr17, $vr26, 1 ++0x20 0xf6 0xf7 0x72 # CHECK: vreplvei.d $vr0, $vr17, 1 ++0xd9 0x29 0x08 0x73 # CHECK: vsllwil.h.b $vr25, $vr14, 2 ++0xb8 0x44 0x08 0x73 # CHECK: vsllwil.w.h $vr24, $vr5, 1 ++0xd9 0xa1 0x08 0x73 # CHECK: vsllwil.d.w $vr25, $vr14, 8 ++0xc3 0x02 0x09 0x73 # CHECK: vextl.q.d $vr3, $vr22 ++0x2b 0x2f 0x0c 0x73 # CHECK: vsllwil.hu.bu $vr11, $vr25, 3 ++0x42 0x6b 0x0c 0x73 # CHECK: vsllwil.wu.hu $vr2, $vr26, 10 ++0x32 0xf1 0x0c 0x73 # CHECK: vsllwil.du.wu $vr18, $vr9, 28 ++0x2d 0x03 0x0d 0x73 # CHECK: vextl.qu.du $vr13, $vr25 ++0x1d 0x3b 0x10 0x73 # CHECK: vbitclri.b $vr29, $vr24, 6 ++0xfb 0x55 0x10 0x73 # CHECK: vbitclri.h $vr27, $vr15, 5 ++0x4b 0xa1 0x10 0x73 # CHECK: vbitclri.w $vr11, $vr10, 8 ++0xe4 0x3c 0x11 0x73 # CHECK: vbitclri.d $vr4, $vr7, 15 ++0x98 0x2e 0x14 0x73 # CHECK: vbitseti.b $vr24, $vr20, 3 ++0x06 0x61 0x14 0x73 # CHECK: vbitseti.h $vr6, $vr8, 8 ++0x35 0xe1 0x14 0x73 # CHECK: vbitseti.w $vr21, $vr9, 24 ++0x5c 0x7a 0x15 0x73 # CHECK: vbitseti.d $vr28, $vr18, 30 ++0xf3 0x23 0x18 0x73 # CHECK: vbitrevi.b $vr19, $vr31, 0 ++0x32 0x40 0x18 0x73 # CHECK: vbitrevi.h $vr18, $vr1, 0 ++0xd9 0xc8 0x18 0x73 # CHECK: vbitrevi.w $vr25, $vr6, 18 ++0x68 0x5b 0x19 0x73 # CHECK: vbitrevi.d $vr8, $vr27, 22 ++0x95 0x2b 0x24 0x73 # CHECK: vsat.b $vr21, $vr28, 2 ++0xa6 0x70 0x24 0x73 # CHECK: vsat.h $vr6, $vr5, 12 ++0xc3 0xc3 0x24 0x73 # CHECK: vsat.w $vr3, $vr30, 16 ++0xe0 0x63 0x25 0x73 # CHECK: vsat.d $vr0, $vr31, 24 ++0x94 0x2a 0x28 0x73 # CHECK: vsat.bu $vr20, $vr20, 2 ++0xc8 0x70 0x28 0x73 # CHECK: vsat.hu $vr8, $vr6, 12 ++0x92 0xea 0x28 0x73 # CHECK: vsat.wu $vr18, $vr20, 26 ++0xca 0x84 0x29 0x73 # CHECK: vsat.du $vr10, $vr6, 33 ++0x64 0x2e 0x2c 0x73 # CHECK: vslli.b $vr4, $vr19, 3 ++0xe3 0x7a 0x2c 0x73 # CHECK: vslli.h $vr3, $vr23, 14 ++0xb6 0x9a 0x2c 0x73 # CHECK: vslli.w $vr22, $vr21, 6 ++0xf7 0x91 0x2d 0x73 # CHECK: vslli.d $vr23, $vr15, 36 ++0x25 0x33 0x30 0x73 # CHECK: vsrli.b $vr5, $vr25, 4 ++0xc9 0x65 0x30 0x73 # CHECK: vsrli.h $vr9, $vr14, 9 ++0x07 0xb3 0x30 0x73 # CHECK: vsrli.w $vr7, $vr24, 12 ++0x4f 0xfe 0x31 0x73 # CHECK: vsrli.d $vr15, $vr18, 63 ++0x26 0x2c 0x34 0x73 # CHECK: vsrai.b $vr6, $vr1, 3 ++0xa7 0x4f 0x34 0x73 # CHECK: vsrai.h $vr7, $vr29, 3 ++0x7f 0xf7 0x34 0x73 # CHECK: vsrai.w $vr31, $vr27, 29 ++0xdc 0xe3 0x35 0x73 # CHECK: vsrai.d $vr28, $vr30, 56 ++0x42 0x4b 0x40 0x73 # CHECK: vsrlni.b.h $vr2, $vr26, 2 ++0xdf 0x8d 0x40 0x73 # CHECK: vsrlni.h.w $vr31, $vr14, 3 ++0x93 0x84 0x41 0x73 # CHECK: vsrlni.w.d $vr19, $vr4, 33 ++0x7f 0xfc 0x42 0x73 # CHECK: vsrlni.d.q $vr31, $vr3, 63 ++0x5a 0x42 0x44 0x73 # CHECK: vsrlrni.b.h $vr26, $vr18, 0 ++0xd2 0x96 0x44 0x73 # CHECK: vsrlrni.h.w $vr18, $vr22, 5 ++0x78 0x55 0x45 0x73 # CHECK: vsrlrni.w.d $vr24, $vr11, 21 ++0x66 0x95 0x46 0x73 # CHECK: vsrlrni.d.q $vr6, $vr11, 37 ++0xa3 0x56 0x48 0x73 # CHECK: vssrlni.b.h $vr3, $vr21, 5 ++0x26 0xc0 0x48 0x73 # CHECK: vssrlni.h.w $vr6, $vr1, 16 ++0xa4 0x6e 0x49 0x73 # CHECK: vssrlni.w.d $vr4, $vr21, 27 ++0x48 0x7a 0x4b 0x73 # CHECK: vssrlni.d.q $vr8, $vr18, 94 ++0x46 0x54 0x4c 0x73 # CHECK: vssrlni.bu.h $vr6, $vr2, 5 ++0xbd 0x8b 0x4c 0x73 # CHECK: vssrlni.hu.w $vr29, $vr29, 2 ++0x9c 0xbe 0x4d 0x73 # CHECK: vssrlni.wu.d $vr28, $vr20, 47 ++0x56 0x49 0x4f 0x73 # CHECK: vssrlni.du.q $vr22, $vr10, 82 ++0x31 0x6b 0x50 0x73 # CHECK: vssrlrni.b.h $vr17, $vr25, 10 ++0xb5 0x83 0x50 0x73 # CHECK: vssrlrni.h.w $vr21, $vr29, 0 ++0xe9 0xfd 0x51 0x73 # CHECK: vssrlrni.w.d $vr9, $vr15, 63 ++0x24 0xd4 0x53 0x73 # CHECK: vssrlrni.d.q $vr4, $vr1, 117 ++0xb9 0x4d 0x54 0x73 # CHECK: vssrlrni.bu.h $vr25, $vr13, 3 ++0x9e 0x9f 0x54 0x73 # CHECK: vssrlrni.hu.w $vr30, $vr28, 7 ++0x70 0x2f 0x55 0x73 # CHECK: vssrlrni.wu.d $vr16, $vr27, 11 ++0xb4 0xfd 0x56 0x73 # CHECK: vssrlrni.du.q $vr20, $vr13, 63 ++0x23 0x53 0x58 0x73 # CHECK: vsrani.b.h $vr3, $vr25, 4 ++0xac 0xc5 0x58 0x73 # CHECK: vsrani.h.w $vr12, $vr13, 17 ++0xc2 0x64 0x59 0x73 # CHECK: vsrani.w.d $vr2, $vr6, 25 ++0x0c 0xa5 0x5b 0x73 # CHECK: vsrani.d.q $vr12, $vr8, 105 ++0xbb 0x4a 0x5c 0x73 # CHECK: vsrarni.b.h $vr27, $vr21, 2 ++0x6d 0x80 0x5c 0x73 # CHECK: vsrarni.h.w $vr13, $vr3, 0 ++0xe9 0xab 0x5d 0x73 # CHECK: vsrarni.w.d $vr9, $vr31, 42 ++0xb9 0xec 0x5e 0x73 # CHECK: vsrarni.d.q $vr25, $vr5, 59 ++0xe8 0x70 0x60 0x73 # CHECK: vssrani.b.h $vr8, $vr7, 12 ++0x55 0xfa 0x60 0x73 # CHECK: vssrani.h.w $vr21, $vr18, 30 ++0xf7 0xcc 0x61 0x73 # CHECK: vssrani.w.d $vr23, $vr7, 51 ++0xcc 0x21 0x62 0x73 # CHECK: vssrani.d.q $vr12, $vr14, 8 ++0xb3 0x70 0x64 0x73 # CHECK: vssrani.bu.h $vr19, $vr5, 12 ++0x3b 0xbf 0x64 0x73 # CHECK: vssrani.hu.w $vr27, $vr25, 15 ++0x98 0xab 0x65 0x73 # CHECK: vssrani.wu.d $vr24, $vr28, 42 ++0xe4 0xfe 0x66 0x73 # CHECK: vssrani.du.q $vr4, $vr23, 63 ++0x1a 0x41 0x68 0x73 # CHECK: vssrarni.b.h $vr26, $vr8, 0 ++0x64 0xe4 0x68 0x73 # CHECK: vssrarni.h.w $vr4, $vr3, 25 ++0x20 0x4f 0x69 0x73 # CHECK: vssrarni.w.d $vr0, $vr25, 19 ++0x74 0xa9 0x6b 0x73 # CHECK: vssrarni.d.q $vr20, $vr11, 106 ++0x99 0x67 0x6c 0x73 # CHECK: vssrarni.bu.h $vr25, $vr28, 9 ++0xf4 0xb2 0x6c 0x73 # CHECK: vssrarni.hu.w $vr20, $vr23, 12 ++0xfc 0xea 0x6d 0x73 # CHECK: vssrarni.wu.d $vr28, $vr23, 58 ++0xc1 0x75 0x6f 0x73 # CHECK: vssrarni.du.q $vr1, $vr14, 93 ++0x6f 0x1f 0x80 0x73 # CHECK: vextrins.d $vr15, $vr27, 7 ++0x13 0x4c 0x86 0x73 # CHECK: vextrins.w $vr19, $vr0, 147 ++0x3d 0x15 0x89 0x73 # CHECK: vextrins.h $vr29, $vr9, 69 ++0xa0 0x5e 0x8c 0x73 # CHECK: vextrins.b $vr0, $vr21, 23 ++0x53 0xf1 0x92 0x73 # CHECK: vshuf4i.b $vr19, $vr10, 188 ++0x2f 0x2c 0x96 0x73 # CHECK: vshuf4i.h $vr15, $vr1, 139 ++0xa3 0x08 0x9a 0x73 # CHECK: vshuf4i.w $vr3, $vr5, 130 ++0xa8 0x0f 0x9e 0x73 # CHECK: vshuf4i.d $vr8, $vr29, 131 ++0x30 0xa3 0xc6 0x73 # CHECK: vbitseli.b $vr16, $vr25, 168 ++0xe4 0xe6 0xd1 0x73 # CHECK: vandi.b $vr4, $vr23, 121 ++0x47 0xf1 0xd6 0x73 # CHECK: vori.b $vr7, $vr10, 188 ++0x49 0x63 0xdb 0x73 # CHECK: vxori.b $vr9, $vr26, 216 ++0x84 0x6f 0xdf 0x73 # CHECK: vnori.b $vr4, $vr28, 219 ++0x56 0x2c 0xe2 0x73 # CHECK: vldi $vr22, -3742 ++0xae 0x43 0xe4 0x73 # CHECK: vpermi.w $vr14, $vr29, 16 ++0xeb 0x56 0x00 0x74 # CHECK: xvseq.b $xr11, $xr23, $xr21 ++0x46 0xed 0x00 0x74 # CHECK: xvseq.h $xr6, $xr10, $xr27 ++0x73 0x57 0x01 0x74 # CHECK: xvseq.w $xr19, $xr27, $xr21 ++0x92 0x88 0x01 0x74 # CHECK: xvseq.d $xr18, $xr4, $xr2 ++0x53 0x15 0x02 0x74 # CHECK: xvsle.b $xr19, $xr10, $xr5 ++0x2a 0xbb 0x02 0x74 # CHECK: xvsle.h $xr10, $xr25, $xr14 ++0xf1 0x4a 0x03 0x74 # CHECK: xvsle.w $xr17, $xr23, $xr18 ++0xef 0xa4 0x03 0x74 # CHECK: xvsle.d $xr15, $xr7, $xr9 ++0xc5 0x3d 0x04 0x74 # CHECK: xvsle.bu $xr5, $xr14, $xr15 ++0x29 0xe7 0x04 0x74 # CHECK: xvsle.hu $xr9, $xr25, $xr25 ++0xfc 0x43 0x05 0x74 # CHECK: xvsle.wu $xr28, $xr31, $xr16 ++0x11 0xe3 0x05 0x74 # CHECK: xvsle.du $xr17, $xr24, $xr24 ++0x92 0x67 0x06 0x74 # CHECK: xvslt.b $xr18, $xr28, $xr25 ++0xdd 0x88 0x06 0x74 # CHECK: xvslt.h $xr29, $xr6, $xr2 ++0x4e 0x15 0x07 0x74 # CHECK: xvslt.w $xr14, $xr10, $xr5 ++0xd3 0xbf 0x07 0x74 # CHECK: xvslt.d $xr19, $xr30, $xr15 ++0xce 0x6c 0x08 0x74 # CHECK: xvslt.bu $xr14, $xr6, $xr27 ++0x5b 0x97 0x08 0x74 # CHECK: xvslt.hu $xr27, $xr26, $xr5 ++0x26 0x29 0x09 0x74 # CHECK: xvslt.wu $xr6, $xr9, $xr10 ++0x8d 0xf1 0x09 0x74 # CHECK: xvslt.du $xr13, $xr12, $xr28 ++0xc0 0x0c 0x0a 0x74 # CHECK: xvadd.b $xr0, $xr6, $xr3 ++0x68 0xa9 0x0a 0x74 # CHECK: xvadd.h $xr8, $xr11, $xr10 ++0xc5 0x54 0x0b 0x74 # CHECK: xvadd.w $xr5, $xr6, $xr21 ++0xa4 0xaa 0x0b 0x74 # CHECK: xvadd.d $xr4, $xr21, $xr10 ++0x10 0x78 0x0c 0x74 # CHECK: xvsub.b $xr16, $xr0, $xr30 ++0x7c 0xc9 0x0c 0x74 # CHECK: xvsub.h $xr28, $xr11, $xr18 ++0x4d 0x34 0x0d 0x74 # CHECK: xvsub.w $xr13, $xr2, $xr13 ++0x20 0xd7 0x0d 0x74 # CHECK: xvsub.d $xr0, $xr25, $xr21 ++0xc8 0x2f 0x1e 0x74 # CHECK: xvaddwev.h.b $xr8, $xr30, $xr11 ++0xca 0x97 0x1e 0x74 # CHECK: xvaddwev.w.h $xr10, $xr30, $xr5 ++0x34 0x07 0x1f 0x74 # CHECK: xvaddwev.d.w $xr20, $xr25, $xr1 ++0x16 0xe3 0x1f 0x74 # CHECK: xvaddwev.q.d $xr22, $xr24, $xr24 ++0x21 0x07 0x20 0x74 # CHECK: xvsubwev.h.b $xr1, $xr25, $xr1 ++0xc4 0xaf 0x20 0x74 # CHECK: xvsubwev.w.h $xr4, $xr30, $xr11 ++0x46 0x48 0x21 0x74 # CHECK: xvsubwev.d.w $xr6, $xr2, $xr18 ++0x60 0xfd 0x21 0x74 # CHECK: xvsubwev.q.d $xr0, $xr11, $xr31 ++0x84 0x64 0x22 0x74 # CHECK: xvaddwod.h.b $xr4, $xr4, $xr25 ++0x2c 0xf7 0x22 0x74 # CHECK: xvaddwod.w.h $xr12, $xr25, $xr29 ++0xd0 0x4e 0x23 0x74 # CHECK: xvaddwod.d.w $xr16, $xr22, $xr19 ++0x37 0xbb 0x23 0x74 # CHECK: xvaddwod.q.d $xr23, $xr25, $xr14 ++0x01 0x22 0x24 0x74 # CHECK: xvsubwod.h.b $xr1, $xr16, $xr8 ++0x65 0xa1 0x24 0x74 # CHECK: xvsubwod.w.h $xr5, $xr11, $xr8 ++0xf4 0x00 0x25 0x74 # CHECK: xvsubwod.d.w $xr20, $xr7, $xr0 ++0xf1 0xd2 0x25 0x74 # CHECK: xvsubwod.q.d $xr17, $xr23, $xr20 ++0x4f 0x7d 0x2e 0x74 # CHECK: xvaddwev.h.bu $xr15, $xr10, $xr31 ++0x15 0xf3 0x2e 0x74 # CHECK: xvaddwev.w.hu $xr21, $xr24, $xr28 ++0xe9 0x3b 0x2f 0x74 # CHECK: xvaddwev.d.wu $xr9, $xr31, $xr14 ++0x39 0xa0 0x2f 0x74 # CHECK: xvaddwev.q.du $xr25, $xr1, $xr8 ++0xfe 0x37 0x30 0x74 # CHECK: xvsubwev.h.bu $xr30, $xr31, $xr13 ++0x81 0x87 0x30 0x74 # CHECK: xvsubwev.w.hu $xr1, $xr28, $xr1 ++0xfd 0x76 0x31 0x74 # CHECK: xvsubwev.d.wu $xr29, $xr23, $xr29 ++0x0d 0xee 0x31 0x74 # CHECK: xvsubwev.q.du $xr13, $xr16, $xr27 ++0xad 0x0b 0x32 0x74 # CHECK: xvaddwod.h.bu $xr13, $xr29, $xr2 ++0x4e 0xb5 0x32 0x74 # CHECK: xvaddwod.w.hu $xr14, $xr10, $xr13 ++0x5e 0x2b 0x33 0x74 # CHECK: xvaddwod.d.wu $xr30, $xr26, $xr10 ++0xa2 0x81 0x33 0x74 # CHECK: xvaddwod.q.du $xr2, $xr13, $xr0 ++0xc6 0x16 0x34 0x74 # CHECK: xvsubwod.h.bu $xr6, $xr22, $xr5 ++0xb3 0xa2 0x34 0x74 # CHECK: xvsubwod.w.hu $xr19, $xr21, $xr8 ++0x70 0x79 0x35 0x74 # CHECK: xvsubwod.d.wu $xr16, $xr11, $xr30 ++0x41 0xa7 0x35 0x74 # CHECK: xvsubwod.q.du $xr1, $xr26, $xr9 ++0xa5 0x09 0x3e 0x74 # CHECK: xvaddwev.h.bu.b $xr5, $xr13, $xr2 ++0xb1 0xd2 0x3e 0x74 # CHECK: xvaddwev.w.hu.h $xr17, $xr21, $xr20 ++0x6b 0x4f 0x3f 0x74 # CHECK: xvaddwev.d.wu.w $xr11, $xr27, $xr19 ++0xb4 0xf6 0x3f 0x74 # CHECK: xvaddwev.q.du.d $xr20, $xr21, $xr29 ++0xc1 0x38 0x40 0x74 # CHECK: xvaddwod.h.bu.b $xr1, $xr6, $xr14 ++0xa7 0xaf 0x40 0x74 # CHECK: xvaddwod.w.hu.h $xr7, $xr29, $xr11 ++0x50 0x39 0x41 0x74 # CHECK: xvaddwod.d.wu.w $xr16, $xr10, $xr14 ++0x6a 0xdd 0x41 0x74 # CHECK: xvaddwod.q.du.d $xr10, $xr11, $xr23 ++0x58 0x71 0x46 0x74 # CHECK: xvsadd.b $xr24, $xr10, $xr28 ++0x53 0xc6 0x46 0x74 # CHECK: xvsadd.h $xr19, $xr18, $xr17 ++0xc2 0x30 0x47 0x74 # CHECK: xvsadd.w $xr2, $xr6, $xr12 ++0x4f 0xf6 0x47 0x74 # CHECK: xvsadd.d $xr15, $xr18, $xr29 ++0xaf 0x43 0x48 0x74 # CHECK: xvssub.b $xr15, $xr29, $xr16 ++0x7c 0xa4 0x48 0x74 # CHECK: xvssub.h $xr28, $xr3, $xr9 ++0x88 0x3e 0x49 0x74 # CHECK: xvssub.w $xr8, $xr20, $xr15 ++0x17 0xcd 0x49 0x74 # CHECK: xvssub.d $xr23, $xr8, $xr19 ++0x8c 0x40 0x4a 0x74 # CHECK: xvsadd.bu $xr12, $xr4, $xr16 ++0x49 0xd3 0x4a 0x74 # CHECK: xvsadd.hu $xr9, $xr26, $xr20 ++0xfe 0x71 0x4b 0x74 # CHECK: xvsadd.wu $xr30, $xr15, $xr28 ++0xaf 0xf1 0x4b 0x74 # CHECK: xvsadd.du $xr15, $xr13, $xr28 ++0x6a 0x3c 0x4c 0x74 # CHECK: xvssub.bu $xr10, $xr3, $xr15 ++0x80 0x89 0x4c 0x74 # CHECK: xvssub.hu $xr0, $xr12, $xr2 ++0x5e 0x5d 0x4d 0x74 # CHECK: xvssub.wu $xr30, $xr10, $xr23 ++0xc9 0xbb 0x4d 0x74 # CHECK: xvssub.du $xr9, $xr30, $xr14 ++0xb9 0x48 0x54 0x74 # CHECK: xvhaddw.h.b $xr25, $xr5, $xr18 ++0x87 0xce 0x54 0x74 # CHECK: xvhaddw.w.h $xr7, $xr20, $xr19 ++0xb7 0x10 0x55 0x74 # CHECK: xvhaddw.d.w $xr23, $xr5, $xr4 ++0xf1 0xe4 0x55 0x74 # CHECK: xvhaddw.q.d $xr17, $xr7, $xr25 ++0x5d 0x4e 0x56 0x74 # CHECK: xvhsubw.h.b $xr29, $xr18, $xr19 ++0x9e 0x8f 0x56 0x74 # CHECK: xvhsubw.w.h $xr30, $xr28, $xr3 ++0x25 0x35 0x57 0x74 # CHECK: xvhsubw.d.w $xr5, $xr9, $xr13 ++0x94 0xf5 0x57 0x74 # CHECK: xvhsubw.q.d $xr20, $xr12, $xr29 ++0x4b 0x1d 0x58 0x74 # CHECK: xvhaddw.hu.bu $xr11, $xr10, $xr7 ++0xb0 0xd6 0x58 0x74 # CHECK: xvhaddw.wu.hu $xr16, $xr21, $xr21 ++0xf1 0x23 0x59 0x74 # CHECK: xvhaddw.du.wu $xr17, $xr31, $xr8 ++0x82 0xac 0x59 0x74 # CHECK: xvhaddw.qu.du $xr2, $xr4, $xr11 ++0xd5 0x21 0x5a 0x74 # CHECK: xvhsubw.hu.bu $xr21, $xr14, $xr8 ++0x19 0xec 0x5a 0x74 # CHECK: xvhsubw.wu.hu $xr25, $xr0, $xr27 ++0x04 0x7a 0x5b 0x74 # CHECK: xvhsubw.du.wu $xr4, $xr16, $xr30 ++0x2b 0x99 0x5b 0x74 # CHECK: xvhsubw.qu.du $xr11, $xr9, $xr6 ++0xae 0x6a 0x5c 0x74 # CHECK: xvadda.b $xr14, $xr21, $xr26 ++0xd5 0xd7 0x5c 0x74 # CHECK: xvadda.h $xr21, $xr30, $xr21 ++0x7f 0x4e 0x5d 0x74 # CHECK: xvadda.w $xr31, $xr19, $xr19 ++0x89 0xfc 0x5d 0x74 # CHECK: xvadda.d $xr9, $xr4, $xr31 ++0x74 0x36 0x60 0x74 # CHECK: xvabsd.b $xr20, $xr19, $xr13 ++0xf4 0xa8 0x60 0x74 # CHECK: xvabsd.h $xr20, $xr7, $xr10 ++0xf7 0x03 0x61 0x74 # CHECK: xvabsd.w $xr23, $xr31, $xr0 ++0x27 0xba 0x61 0x74 # CHECK: xvabsd.d $xr7, $xr17, $xr14 ++0xec 0x1a 0x62 0x74 # CHECK: xvabsd.bu $xr12, $xr23, $xr6 ++0xd0 0xcf 0x62 0x74 # CHECK: xvabsd.hu $xr16, $xr30, $xr19 ++0xb3 0x68 0x63 0x74 # CHECK: xvabsd.wu $xr19, $xr5, $xr26 ++0x80 0x9d 0x63 0x74 # CHECK: xvabsd.du $xr0, $xr12, $xr7 ++0xf7 0x67 0x64 0x74 # CHECK: xvavg.b $xr23, $xr31, $xr25 ++0x5b 0xec 0x64 0x74 # CHECK: xvavg.h $xr27, $xr2, $xr27 ++0x14 0x40 0x65 0x74 # CHECK: xvavg.w $xr20, $xr0, $xr16 ++0x2d 0xa9 0x65 0x74 # CHECK: xvavg.d $xr13, $xr9, $xr10 ++0xdf 0x13 0x66 0x74 # CHECK: xvavg.bu $xr31, $xr30, $xr4 ++0x36 0x96 0x66 0x74 # CHECK: xvavg.hu $xr22, $xr17, $xr5 ++0xb5 0x47 0x67 0x74 # CHECK: xvavg.wu $xr21, $xr29, $xr17 ++0xab 0xf4 0x67 0x74 # CHECK: xvavg.du $xr11, $xr5, $xr29 ++0xb7 0x35 0x68 0x74 # CHECK: xvavgr.b $xr23, $xr13, $xr13 ++0x9e 0xfe 0x68 0x74 # CHECK: xvavgr.h $xr30, $xr20, $xr31 ++0x9d 0x27 0x69 0x74 # CHECK: xvavgr.w $xr29, $xr28, $xr9 ++0x95 0xa2 0x69 0x74 # CHECK: xvavgr.d $xr21, $xr20, $xr8 ++0x20 0x11 0x6a 0x74 # CHECK: xvavgr.bu $xr0, $xr9, $xr4 ++0x03 0xec 0x6a 0x74 # CHECK: xvavgr.hu $xr3, $xr0, $xr27 ++0xc2 0x57 0x6b 0x74 # CHECK: xvavgr.wu $xr2, $xr30, $xr21 ++0xb6 0xc6 0x6b 0x74 # CHECK: xvavgr.du $xr22, $xr21, $xr17 ++0x81 0x4e 0x70 0x74 # CHECK: xvmax.b $xr1, $xr20, $xr19 ++0x20 0xba 0x70 0x74 # CHECK: xvmax.h $xr0, $xr17, $xr14 ++0x00 0x41 0x71 0x74 # CHECK: xvmax.w $xr0, $xr8, $xr16 ++0xf0 0xc2 0x71 0x74 # CHECK: xvmax.d $xr16, $xr23, $xr16 ++0xd4 0x38 0x72 0x74 # CHECK: xvmin.b $xr20, $xr6, $xr14 ++0x64 0xe0 0x72 0x74 # CHECK: xvmin.h $xr4, $xr3, $xr24 ++0x45 0x5c 0x73 0x74 # CHECK: xvmin.w $xr5, $xr2, $xr23 ++0xff 0xea 0x73 0x74 # CHECK: xvmin.d $xr31, $xr23, $xr26 ++0xae 0x0d 0x74 0x74 # CHECK: xvmax.bu $xr14, $xr13, $xr3 ++0x36 0x92 0x74 0x74 # CHECK: xvmax.hu $xr22, $xr17, $xr4 ++0xb1 0x75 0x75 0x74 # CHECK: xvmax.wu $xr17, $xr13, $xr29 ++0x4d 0x80 0x75 0x74 # CHECK: xvmax.du $xr13, $xr2, $xr0 ++0xf2 0x6f 0x76 0x74 # CHECK: xvmin.bu $xr18, $xr31, $xr27 ++0x42 0xb9 0x76 0x74 # CHECK: xvmin.hu $xr2, $xr10, $xr14 ++0x1f 0x69 0x77 0x74 # CHECK: xvmin.wu $xr31, $xr8, $xr26 ++0x4c 0xa7 0x77 0x74 # CHECK: xvmin.du $xr12, $xr26, $xr9 ++0x5a 0x0c 0x84 0x74 # CHECK: xvmul.b $xr26, $xr2, $xr3 ++0xb0 0x97 0x84 0x74 # CHECK: xvmul.h $xr16, $xr29, $xr5 ++0x33 0x0c 0x85 0x74 # CHECK: xvmul.w $xr19, $xr1, $xr3 ++0xef 0x81 0x85 0x74 # CHECK: xvmul.d $xr15, $xr15, $xr0 ++0x89 0x25 0x86 0x74 # CHECK: xvmuh.b $xr9, $xr12, $xr9 ++0xe8 0xc2 0x86 0x74 # CHECK: xvmuh.h $xr8, $xr23, $xr16 ++0xdd 0x2c 0x87 0x74 # CHECK: xvmuh.w $xr29, $xr6, $xr11 ++0x43 0x9e 0x87 0x74 # CHECK: xvmuh.d $xr3, $xr18, $xr7 ++0xe3 0x4c 0x88 0x74 # CHECK: xvmuh.bu $xr3, $xr7, $xr19 ++0x2d 0xc8 0x88 0x74 # CHECK: xvmuh.hu $xr13, $xr1, $xr18 ++0xaf 0x42 0x89 0x74 # CHECK: xvmuh.wu $xr15, $xr21, $xr16 ++0x4b 0xcd 0x89 0x74 # CHECK: xvmuh.du $xr11, $xr10, $xr19 ++0x84 0x25 0x90 0x74 # CHECK: xvmulwev.h.b $xr4, $xr12, $xr9 ++0x6a 0xd0 0x90 0x74 # CHECK: xvmulwev.w.h $xr10, $xr3, $xr20 ++0xc4 0x4a 0x91 0x74 # CHECK: xvmulwev.d.w $xr4, $xr22, $xr18 ++0xb4 0xee 0x91 0x74 # CHECK: xvmulwev.q.d $xr20, $xr21, $xr27 ++0xe5 0x00 0x92 0x74 # CHECK: xvmulwod.h.b $xr5, $xr7, $xr0 ++0x93 0xaf 0x92 0x74 # CHECK: xvmulwod.w.h $xr19, $xr28, $xr11 ++0xf3 0x40 0x93 0x74 # CHECK: xvmulwod.d.w $xr19, $xr7, $xr16 ++0x8b 0xb5 0x93 0x74 # CHECK: xvmulwod.q.d $xr11, $xr12, $xr13 ++0x56 0x04 0x98 0x74 # CHECK: xvmulwev.h.bu $xr22, $xr2, $xr1 ++0x62 0x90 0x98 0x74 # CHECK: xvmulwev.w.hu $xr2, $xr3, $xr4 ++0x82 0x65 0x99 0x74 # CHECK: xvmulwev.d.wu $xr2, $xr12, $xr25 ++0xb6 0xc7 0x99 0x74 # CHECK: xvmulwev.q.du $xr22, $xr29, $xr17 ++0x29 0x01 0x9a 0x74 # CHECK: xvmulwod.h.bu $xr9, $xr9, $xr0 ++0x54 0xc0 0x9a 0x74 # CHECK: xvmulwod.w.hu $xr20, $xr2, $xr16 ++0x61 0x61 0x9b 0x74 # CHECK: xvmulwod.d.wu $xr1, $xr11, $xr24 ++0x53 0xd8 0x9b 0x74 # CHECK: xvmulwod.q.du $xr19, $xr2, $xr22 ++0xb6 0x63 0xa0 0x74 # CHECK: xvmulwev.h.bu.b $xr22, $xr29, $xr24 ++0xc1 0xae 0xa0 0x74 # CHECK: xvmulwev.w.hu.h $xr1, $xr22, $xr11 ++0x8c 0x31 0xa1 0x74 # CHECK: xvmulwev.d.wu.w $xr12, $xr12, $xr12 ++0x20 0xde 0xa1 0x74 # CHECK: xvmulwev.q.du.d $xr0, $xr17, $xr23 ++0x1a 0x5e 0xa2 0x74 # CHECK: xvmulwod.h.bu.b $xr26, $xr16, $xr23 ++0x9f 0xa5 0xa2 0x74 # CHECK: xvmulwod.w.hu.h $xr31, $xr12, $xr9 ++0x75 0x4f 0xa3 0x74 # CHECK: xvmulwod.d.wu.w $xr21, $xr27, $xr19 ++0xa7 0xac 0xa3 0x74 # CHECK: xvmulwod.q.du.d $xr7, $xr5, $xr11 ++0x76 0x3d 0xa8 0x74 # CHECK: xvmadd.b $xr22, $xr11, $xr15 ++0xc3 0xe7 0xa8 0x74 # CHECK: xvmadd.h $xr3, $xr30, $xr25 ++0x41 0x16 0xa9 0x74 # CHECK: xvmadd.w $xr1, $xr18, $xr5 ++0xb0 0xae 0xa9 0x74 # CHECK: xvmadd.d $xr16, $xr21, $xr11 ++0x8b 0x29 0xaa 0x74 # CHECK: xvmsub.b $xr11, $xr12, $xr10 ++0x70 0x85 0xaa 0x74 # CHECK: xvmsub.h $xr16, $xr11, $xr1 ++0xaf 0x56 0xab 0x74 # CHECK: xvmsub.w $xr15, $xr21, $xr21 ++0x6c 0x91 0xab 0x74 # CHECK: xvmsub.d $xr12, $xr11, $xr4 ++0xf5 0x18 0xac 0x74 # CHECK: xvmaddwev.h.b $xr21, $xr7, $xr6 ++0xb0 0xb7 0xac 0x74 # CHECK: xvmaddwev.w.h $xr16, $xr29, $xr13 ++0x27 0x7b 0xad 0x74 # CHECK: xvmaddwev.d.w $xr7, $xr25, $xr30 ++0x73 0xa0 0xad 0x74 # CHECK: xvmaddwev.q.d $xr19, $xr3, $xr8 ++0x74 0x33 0xae 0x74 # CHECK: xvmaddwod.h.b $xr20, $xr27, $xr12 ++0xa0 0xb6 0xae 0x74 # CHECK: xvmaddwod.w.h $xr0, $xr21, $xr13 ++0xb9 0x7d 0xaf 0x74 # CHECK: xvmaddwod.d.w $xr25, $xr13, $xr31 ++0x5a 0xc3 0xaf 0x74 # CHECK: xvmaddwod.q.d $xr26, $xr26, $xr16 ++0x52 0x57 0xb4 0x74 # CHECK: xvmaddwev.h.bu $xr18, $xr26, $xr21 ++0x0e 0x96 0xb4 0x74 # CHECK: xvmaddwev.w.hu $xr14, $xr16, $xr5 ++0xb3 0x53 0xb5 0x74 # CHECK: xvmaddwev.d.wu $xr19, $xr29, $xr20 ++0xaf 0xc7 0xb5 0x74 # CHECK: xvmaddwev.q.du $xr15, $xr29, $xr17 ++0x4d 0x07 0xb6 0x74 # CHECK: xvmaddwod.h.bu $xr13, $xr26, $xr1 ++0x2f 0xc3 0xb6 0x74 # CHECK: xvmaddwod.w.hu $xr15, $xr25, $xr16 ++0x97 0x24 0xb7 0x74 # CHECK: xvmaddwod.d.wu $xr23, $xr4, $xr9 ++0xdd 0xc6 0xb7 0x74 # CHECK: xvmaddwod.q.du $xr29, $xr22, $xr17 ++0x37 0x18 0xbc 0x74 # CHECK: xvmaddwev.h.bu.b $xr23, $xr1, $xr6 ++0x64 0xb3 0xbc 0x74 # CHECK: xvmaddwev.w.hu.h $xr4, $xr27, $xr12 ++0x40 0x14 0xbd 0x74 # CHECK: xvmaddwev.d.wu.w $xr0, $xr2, $xr5 ++0xe9 0x87 0xbd 0x74 # CHECK: xvmaddwev.q.du.d $xr9, $xr31, $xr1 ++0x69 0x52 0xbe 0x74 # CHECK: xvmaddwod.h.bu.b $xr9, $xr19, $xr20 ++0xa7 0xb4 0xbe 0x74 # CHECK: xvmaddwod.w.hu.h $xr7, $xr5, $xr13 ++0x6a 0x07 0xbf 0x74 # CHECK: xvmaddwod.d.wu.w $xr10, $xr27, $xr1 ++0x79 0x82 0xbf 0x74 # CHECK: xvmaddwod.q.du.d $xr25, $xr19, $xr0 ++0xe3 0x0b 0xe0 0x74 # CHECK: xvdiv.b $xr3, $xr31, $xr2 ++0x81 0xc5 0xe0 0x74 # CHECK: xvdiv.h $xr1, $xr12, $xr17 ++0x0d 0x30 0xe1 0x74 # CHECK: xvdiv.w $xr13, $xr0, $xr12 ++0xb1 0xac 0xe1 0x74 # CHECK: xvdiv.d $xr17, $xr5, $xr11 ++0x36 0x06 0xe2 0x74 # CHECK: xvmod.b $xr22, $xr17, $xr1 ++0xbc 0xb0 0xe2 0x74 # CHECK: xvmod.h $xr28, $xr5, $xr12 ++0x7d 0x3a 0xe3 0x74 # CHECK: xvmod.w $xr29, $xr19, $xr14 ++0x11 0x99 0xe3 0x74 # CHECK: xvmod.d $xr17, $xr8, $xr6 ++0xd7 0x08 0xe4 0x74 # CHECK: xvdiv.bu $xr23, $xr6, $xr2 ++0xe9 0x83 0xe4 0x74 # CHECK: xvdiv.hu $xr9, $xr31, $xr0 ++0x2f 0x10 0xe5 0x74 # CHECK: xvdiv.wu $xr15, $xr1, $xr4 ++0xae 0xaf 0xe5 0x74 # CHECK: xvdiv.du $xr14, $xr29, $xr11 ++0x84 0x7d 0xe6 0x74 # CHECK: xvmod.bu $xr4, $xr12, $xr31 ++0x96 0xad 0xe6 0x74 # CHECK: xvmod.hu $xr22, $xr12, $xr11 ++0xf5 0x2a 0xe7 0x74 # CHECK: xvmod.wu $xr21, $xr23, $xr10 ++0xb5 0xfe 0xe7 0x74 # CHECK: xvmod.du $xr21, $xr21, $xr31 ++0x50 0x2d 0xe8 0x74 # CHECK: xvsll.b $xr16, $xr10, $xr11 ++0x4c 0xed 0xe8 0x74 # CHECK: xvsll.h $xr12, $xr10, $xr27 ++0x5e 0x68 0xe9 0x74 # CHECK: xvsll.w $xr30, $xr2, $xr26 ++0xa8 0xc6 0xe9 0x74 # CHECK: xvsll.d $xr8, $xr21, $xr17 ++0x1b 0x4b 0xea 0x74 # CHECK: xvsrl.b $xr27, $xr24, $xr18 ++0xf1 0xe3 0xea 0x74 # CHECK: xvsrl.h $xr17, $xr31, $xr24 ++0x65 0x10 0xeb 0x74 # CHECK: xvsrl.w $xr5, $xr3, $xr4 ++0xd5 0xa0 0xeb 0x74 # CHECK: xvsrl.d $xr21, $xr6, $xr8 ++0x9c 0x57 0xec 0x74 # CHECK: xvsra.b $xr28, $xr28, $xr21 ++0x93 0xe8 0xec 0x74 # CHECK: xvsra.h $xr19, $xr4, $xr26 ++0x8d 0x06 0xed 0x74 # CHECK: xvsra.w $xr13, $xr20, $xr1 ++0x00 0xc9 0xed 0x74 # CHECK: xvsra.d $xr0, $xr8, $xr18 ++0xc8 0x73 0xee 0x74 # CHECK: xvrotr.b $xr8, $xr30, $xr28 ++0x71 0x82 0xee 0x74 # CHECK: xvrotr.h $xr17, $xr19, $xr0 ++0x8f 0x5f 0xef 0x74 # CHECK: xvrotr.w $xr15, $xr28, $xr23 ++0x5f 0xd4 0xef 0x74 # CHECK: xvrotr.d $xr31, $xr2, $xr21 ++0x54 0x2f 0xf0 0x74 # CHECK: xvsrlr.b $xr20, $xr26, $xr11 ++0x4d 0x9e 0xf0 0x74 # CHECK: xvsrlr.h $xr13, $xr18, $xr7 ++0x3c 0x0c 0xf1 0x74 # CHECK: xvsrlr.w $xr28, $xr1, $xr3 ++0x66 0xb8 0xf1 0x74 # CHECK: xvsrlr.d $xr6, $xr3, $xr14 ++0x0a 0x45 0xf2 0x74 # CHECK: xvsrar.b $xr10, $xr8, $xr17 ++0x5f 0xac 0xf2 0x74 # CHECK: xvsrar.h $xr31, $xr2, $xr11 ++0x0d 0x15 0xf3 0x74 # CHECK: xvsrar.w $xr13, $xr8, $xr5 ++0x4c 0x82 0xf3 0x74 # CHECK: xvsrar.d $xr12, $xr18, $xr0 ++0xcf 0xbc 0xf4 0x74 # CHECK: xvsrln.b.h $xr15, $xr6, $xr15 ++0x76 0x46 0xf5 0x74 # CHECK: xvsrln.h.w $xr22, $xr19, $xr17 ++0xe4 0x94 0xf5 0x74 # CHECK: xvsrln.w.d $xr4, $xr7, $xr5 ++0x63 0xde 0xf6 0x74 # CHECK: xvsran.b.h $xr3, $xr19, $xr23 ++0xd0 0x04 0xf7 0x74 # CHECK: xvsran.h.w $xr16, $xr6, $xr1 ++0x1b 0x82 0xf7 0x74 # CHECK: xvsran.w.d $xr27, $xr16, $xr0 ++0x22 0xa5 0xf8 0x74 # CHECK: xvsrlrn.b.h $xr2, $xr9, $xr9 ++0x70 0x4d 0xf9 0x74 # CHECK: xvsrlrn.h.w $xr16, $xr11, $xr19 ++0x3d 0xbf 0xf9 0x74 # CHECK: xvsrlrn.w.d $xr29, $xr25, $xr15 ++0x8d 0xb6 0xfa 0x74 # CHECK: xvsrarn.b.h $xr13, $xr20, $xr13 ++0xcd 0x06 0xfb 0x74 # CHECK: xvsrarn.h.w $xr13, $xr22, $xr1 ++0x8d 0x89 0xfb 0x74 # CHECK: xvsrarn.w.d $xr13, $xr12, $xr2 ++0x73 0xaa 0xfc 0x74 # CHECK: xvssrln.b.h $xr19, $xr19, $xr10 ++0x0c 0x47 0xfd 0x74 # CHECK: xvssrln.h.w $xr12, $xr24, $xr17 ++0xc7 0xbb 0xfd 0x74 # CHECK: xvssrln.w.d $xr7, $xr30, $xr14 ++0x26 0xdd 0xfe 0x74 # CHECK: xvssran.b.h $xr6, $xr9, $xr23 ++0x2d 0x09 0xff 0x74 # CHECK: xvssran.h.w $xr13, $xr9, $xr2 ++0x52 0x87 0xff 0x74 # CHECK: xvssran.w.d $xr18, $xr26, $xr1 ++0x38 0xde 0x00 0x75 # CHECK: xvssrlrn.b.h $xr24, $xr17, $xr23 ++0x8a 0x21 0x01 0x75 # CHECK: xvssrlrn.h.w $xr10, $xr12, $xr8 ++0x7e 0x9b 0x01 0x75 # CHECK: xvssrlrn.w.d $xr30, $xr27, $xr6 ++0x74 0xff 0x02 0x75 # CHECK: xvssrarn.b.h $xr20, $xr27, $xr31 ++0xf8 0x5e 0x03 0x75 # CHECK: xvssrarn.h.w $xr24, $xr23, $xr23 ++0xa8 0xe7 0x03 0x75 # CHECK: xvssrarn.w.d $xr8, $xr29, $xr25 ++0x8e 0xc4 0x04 0x75 # CHECK: xvssrln.bu.h $xr14, $xr4, $xr17 ++0x9c 0x2a 0x05 0x75 # CHECK: xvssrln.hu.w $xr28, $xr20, $xr10 ++0x0a 0xd1 0x05 0x75 # CHECK: xvssrln.wu.d $xr10, $xr8, $xr20 ++0x92 0xdf 0x06 0x75 # CHECK: xvssran.bu.h $xr18, $xr28, $xr23 ++0x79 0x62 0x07 0x75 # CHECK: xvssran.hu.w $xr25, $xr19, $xr24 ++0xb0 0xcb 0x07 0x75 # CHECK: xvssran.wu.d $xr16, $xr29, $xr18 ++0x62 0xba 0x08 0x75 # CHECK: xvssrlrn.bu.h $xr2, $xr19, $xr14 ++0x06 0x48 0x09 0x75 # CHECK: xvssrlrn.hu.w $xr6, $xr0, $xr18 ++0x9e 0xfc 0x09 0x75 # CHECK: xvssrlrn.wu.d $xr30, $xr4, $xr31 ++0x90 0xa3 0x0a 0x75 # CHECK: xvssrarn.bu.h $xr16, $xr28, $xr8 ++0x4b 0x18 0x0b 0x75 # CHECK: xvssrarn.hu.w $xr11, $xr2, $xr6 ++0xd6 0xb0 0x0b 0x75 # CHECK: xvssrarn.wu.d $xr22, $xr6, $xr12 ++0x04 0x42 0x0c 0x75 # CHECK: xvbitclr.b $xr4, $xr16, $xr16 ++0xf0 0xeb 0x0c 0x75 # CHECK: xvbitclr.h $xr16, $xr31, $xr26 ++0x58 0x50 0x0d 0x75 # CHECK: xvbitclr.w $xr24, $xr2, $xr20 ++0x92 0xf9 0x0d 0x75 # CHECK: xvbitclr.d $xr18, $xr12, $xr30 ++0x7a 0x5f 0x0e 0x75 # CHECK: xvbitset.b $xr26, $xr27, $xr23 ++0x73 0xae 0x0e 0x75 # CHECK: xvbitset.h $xr19, $xr19, $xr11 ++0x27 0x49 0x0f 0x75 # CHECK: xvbitset.w $xr7, $xr9, $xr18 ++0xc6 0x8f 0x0f 0x75 # CHECK: xvbitset.d $xr6, $xr30, $xr3 ++0xbe 0x1d 0x10 0x75 # CHECK: xvbitrev.b $xr30, $xr13, $xr7 ++0x6c 0xa0 0x10 0x75 # CHECK: xvbitrev.h $xr12, $xr3, $xr8 ++0x88 0x52 0x11 0x75 # CHECK: xvbitrev.w $xr8, $xr20, $xr20 ++0xfc 0xc4 0x11 0x75 # CHECK: xvbitrev.d $xr28, $xr7, $xr17 ++0x5d 0x32 0x16 0x75 # CHECK: xvpackev.b $xr29, $xr18, $xr12 ++0x66 0xc5 0x16 0x75 # CHECK: xvpackev.h $xr6, $xr11, $xr17 ++0x42 0x78 0x17 0x75 # CHECK: xvpackev.w $xr2, $xr2, $xr30 ++0xfa 0xd5 0x17 0x75 # CHECK: xvpackev.d $xr26, $xr15, $xr21 ++0x33 0x46 0x18 0x75 # CHECK: xvpackod.b $xr19, $xr17, $xr17 ++0x0f 0x8d 0x18 0x75 # CHECK: xvpackod.h $xr15, $xr8, $xr3 ++0xed 0x31 0x19 0x75 # CHECK: xvpackod.w $xr13, $xr15, $xr12 ++0x65 0xe8 0x19 0x75 # CHECK: xvpackod.d $xr5, $xr3, $xr26 ++0x3b 0x05 0x1a 0x75 # CHECK: xvilvl.b $xr27, $xr9, $xr1 ++0x1d 0x85 0x1a 0x75 # CHECK: xvilvl.h $xr29, $xr8, $xr1 ++0x09 0x1d 0x1b 0x75 # CHECK: xvilvl.w $xr9, $xr8, $xr7 ++0xf9 0xc8 0x1b 0x75 # CHECK: xvilvl.d $xr25, $xr7, $xr18 ++0x07 0x6b 0x1c 0x75 # CHECK: xvilvh.b $xr7, $xr24, $xr26 ++0x86 0xf2 0x1c 0x75 # CHECK: xvilvh.h $xr6, $xr20, $xr28 ++0xad 0x30 0x1d 0x75 # CHECK: xvilvh.w $xr13, $xr5, $xr12 ++0xa1 0xfe 0x1d 0x75 # CHECK: xvilvh.d $xr1, $xr21, $xr31 ++0xb1 0x7d 0x1e 0x75 # CHECK: xvpickev.b $xr17, $xr13, $xr31 ++0x04 0xb9 0x1e 0x75 # CHECK: xvpickev.h $xr4, $xr8, $xr14 ++0x0a 0x2d 0x1f 0x75 # CHECK: xvpickev.w $xr10, $xr8, $xr11 ++0x9a 0xa2 0x1f 0x75 # CHECK: xvpickev.d $xr26, $xr20, $xr8 ++0xb3 0x6e 0x20 0x75 # CHECK: xvpickod.b $xr19, $xr21, $xr27 ++0xbc 0xcc 0x20 0x75 # CHECK: xvpickod.h $xr28, $xr5, $xr19 ++0x55 0x5a 0x21 0x75 # CHECK: xvpickod.w $xr21, $xr18, $xr22 ++0xfc 0xc8 0x21 0x75 # CHECK: xvpickod.d $xr28, $xr7, $xr18 ++0x86 0x66 0x22 0x75 # CHECK: xvreplve.b $xr6, $xr20, $r25 ++0xfb 0xb8 0x22 0x75 # CHECK: xvreplve.h $xr27, $xr7, $r14 ++0x81 0x3c 0x23 0x75 # CHECK: xvreplve.w $xr1, $xr4, $r15 ++0x8c 0xc1 0x23 0x75 # CHECK: xvreplve.d $xr12, $xr12, $r16 ++0x61 0x74 0x26 0x75 # CHECK: xvand.v $xr1, $xr3, $xr29 ++0x77 0xd1 0x26 0x75 # CHECK: xvor.v $xr23, $xr11, $xr20 ++0x3f 0x78 0x27 0x75 # CHECK: xvxor.v $xr31, $xr1, $xr30 ++0x5d 0xb7 0x27 0x75 # CHECK: xvnor.v $xr29, $xr26, $xr13 ++0xc9 0x01 0x28 0x75 # CHECK: xvandn.v $xr9, $xr14, $xr0 ++0x19 0xb1 0x28 0x75 # CHECK: xvorn.v $xr25, $xr8, $xr12 ++0x55 0x6b 0x2b 0x75 # CHECK: xvfrstp.b $xr21, $xr26, $xr26 ++0x24 0x8a 0x2b 0x75 # CHECK: xvfrstp.h $xr4, $xr17, $xr2 ++0x9d 0x47 0x2d 0x75 # CHECK: xvadd.q $xr29, $xr28, $xr17 ++0x5d 0xec 0x2d 0x75 # CHECK: xvsub.q $xr29, $xr2, $xr27 ++0x92 0x1f 0x2e 0x75 # CHECK: xvsigncov.b $xr18, $xr28, $xr7 ++0x92 0xc5 0x2e 0x75 # CHECK: xvsigncov.h $xr18, $xr12, $xr17 ++0x3a 0x00 0x2f 0x75 # CHECK: xvsigncov.w $xr26, $xr1, $xr0 ++0x6a 0xbb 0x2f 0x75 # CHECK: xvsigncov.d $xr10, $xr27, $xr14 ++0x2f 0xa3 0x30 0x75 # CHECK: xvfadd.s $xr15, $xr25, $xr8 ++0xd3 0x54 0x31 0x75 # CHECK: xvfadd.d $xr19, $xr6, $xr21 ++0xda 0x98 0x32 0x75 # CHECK: xvfsub.s $xr26, $xr6, $xr6 ++0x09 0x54 0x33 0x75 # CHECK: xvfsub.d $xr9, $xr0, $xr21 ++0x06 0xb9 0x38 0x75 # CHECK: xvfmul.s $xr6, $xr8, $xr14 ++0xab 0x6a 0x39 0x75 # CHECK: xvfmul.d $xr11, $xr21, $xr26 ++0xeb 0x98 0x3a 0x75 # CHECK: xvfdiv.s $xr11, $xr7, $xr6 ++0x40 0x13 0x3b 0x75 # CHECK: xvfdiv.d $xr0, $xr26, $xr4 ++0x27 0x91 0x3c 0x75 # CHECK: xvfmax.s $xr7, $xr9, $xr4 ++0x40 0x53 0x3d 0x75 # CHECK: xvfmax.d $xr0, $xr26, $xr20 ++0x48 0xe9 0x3e 0x75 # CHECK: xvfmin.s $xr8, $xr10, $xr26 ++0xc2 0x66 0x3f 0x75 # CHECK: xvfmin.d $xr2, $xr22, $xr25 ++0x91 0x84 0x40 0x75 # CHECK: xvfmaxa.s $xr17, $xr4, $xr1 ++0xfb 0x26 0x41 0x75 # CHECK: xvfmaxa.d $xr27, $xr23, $xr9 ++0x75 0xec 0x42 0x75 # CHECK: xvfmina.s $xr21, $xr3, $xr27 ++0xc7 0x10 0x43 0x75 # CHECK: xvfmina.d $xr7, $xr6, $xr4 ++0x49 0x51 0x46 0x75 # CHECK: xvfcvt.h.s $xr9, $xr10, $xr20 ++0xe5 0xd6 0x46 0x75 # CHECK: xvfcvt.s.d $xr5, $xr23, $xr21 ++0x1c 0x2b 0x48 0x75 # CHECK: xvffint.s.l $xr28, $xr24, $xr10 ++0x06 0x87 0x49 0x75 # CHECK: xvftint.w.d $xr6, $xr24, $xr1 ++0x5b 0x7b 0x4a 0x75 # CHECK: xvftintrm.w.d $xr27, $xr26, $xr30 ++0x9f 0x85 0x4a 0x75 # CHECK: xvftintrp.w.d $xr31, $xr12, $xr1 ++0xab 0x56 0x4b 0x75 # CHECK: xvftintrz.w.d $xr11, $xr21, $xr21 ++0x0f 0xf1 0x4b 0x75 # CHECK: xvftintrne.w.d $xr15, $xr8, $xr28 ++0xb4 0x8e 0x7a 0x75 # CHECK: xvshuf.h $xr20, $xr21, $xr3 ++0x56 0x7c 0x7b 0x75 # CHECK: xvshuf.w $xr22, $xr2, $xr31 ++0x6f 0xe8 0x7b 0x75 # CHECK: xvshuf.d $xr15, $xr3, $xr26 ++0xf5 0x62 0x7d 0x75 # CHECK: xvperm.w $xr21, $xr23, $xr24 ++0xbc 0x04 0x80 0x76 # CHECK: xvseqi.b $xr28, $xr5, 1 ++0x33 0xed 0x80 0x76 # CHECK: xvseqi.h $xr19, $xr9, -5 ++0x48 0x7a 0x81 0x76 # CHECK: xvseqi.w $xr8, $xr18, -2 ++0xc2 0xf2 0x81 0x76 # CHECK: xvseqi.d $xr2, $xr22, -4 ++0xa4 0x5a 0x82 0x76 # CHECK: xvslei.b $xr4, $xr21, -10 ++0x91 0xd2 0x82 0x76 # CHECK: xvslei.h $xr17, $xr20, -12 ++0x89 0x66 0x83 0x76 # CHECK: xvslei.w $xr9, $xr20, -7 ++0xd3 0xab 0x83 0x76 # CHECK: xvslei.d $xr19, $xr30, 10 ++0x44 0x07 0x84 0x76 # CHECK: xvslei.bu $xr4, $xr26, 1 ++0x0b 0x91 0x84 0x76 # CHECK: xvslei.hu $xr11, $xr8, 4 ++0x92 0x7d 0x85 0x76 # CHECK: xvslei.wu $xr18, $xr12, 31 ++0xfe 0xe8 0x85 0x76 # CHECK: xvslei.du $xr30, $xr7, 26 ++0xab 0x0b 0x86 0x76 # CHECK: xvslti.b $xr11, $xr29, 2 ++0x66 0xa3 0x86 0x76 # CHECK: xvslti.h $xr6, $xr27, 8 ++0xf5 0x06 0x87 0x76 # CHECK: xvslti.w $xr21, $xr23, 1 ++0xf2 0xef 0x87 0x76 # CHECK: xvslti.d $xr18, $xr31, -5 ++0x9b 0x45 0x88 0x76 # CHECK: xvslti.bu $xr27, $xr12, 17 ++0xd2 0xb1 0x88 0x76 # CHECK: xvslti.hu $xr18, $xr14, 12 ++0x84 0x39 0x89 0x76 # CHECK: xvslti.wu $xr4, $xr12, 14 ++0x1a 0xe0 0x89 0x76 # CHECK: xvslti.du $xr26, $xr0, 24 ++0x5e 0x14 0x8a 0x76 # CHECK: xvaddi.bu $xr30, $xr2, 5 ++0x36 0xa6 0x8a 0x76 # CHECK: xvaddi.hu $xr22, $xr17, 9 ++0x43 0x77 0x8b 0x76 # CHECK: xvaddi.wu $xr3, $xr26, 29 ++0x80 0xfa 0x8b 0x76 # CHECK: xvaddi.du $xr0, $xr20, 30 ++0x80 0x1e 0x8c 0x76 # CHECK: xvsubi.bu $xr0, $xr20, 7 ++0x04 0xcb 0x8c 0x76 # CHECK: xvsubi.hu $xr4, $xr24, 18 ++0x41 0x6b 0x8d 0x76 # CHECK: xvsubi.wu $xr1, $xr26, 26 ++0x89 0xa3 0x8d 0x76 # CHECK: xvsubi.du $xr9, $xr28, 8 ++0xa0 0x22 0x8e 0x76 # CHECK: xvbsll.v $xr0, $xr21, 8 ++0x04 0xf1 0x8e 0x76 # CHECK: xvbsrl.v $xr4, $xr8, 28 ++0x28 0x48 0x90 0x76 # CHECK: xvmaxi.b $xr8, $xr1, -14 ++0x93 0xc1 0x90 0x76 # CHECK: xvmaxi.h $xr19, $xr12, -16 ++0x3b 0x14 0x91 0x76 # CHECK: xvmaxi.w $xr27, $xr1, 5 ++0xe6 0x8c 0x91 0x76 # CHECK: xvmaxi.d $xr6, $xr7, 3 ++0xca 0x14 0x92 0x76 # CHECK: xvmini.b $xr10, $xr6, 5 ++0x48 0xd2 0x92 0x76 # CHECK: xvmini.h $xr8, $xr18, -12 ++0xbf 0x65 0x93 0x76 # CHECK: xvmini.w $xr31, $xr13, -7 ++0x6f 0xa7 0x93 0x76 # CHECK: xvmini.d $xr15, $xr27, 9 ++0x25 0x5a 0x94 0x76 # CHECK: xvmaxi.bu $xr5, $xr17, 22 ++0x66 0x90 0x94 0x76 # CHECK: xvmaxi.hu $xr6, $xr3, 4 ++0x9a 0x45 0x95 0x76 # CHECK: xvmaxi.wu $xr26, $xr12, 17 ++0x7e 0xf9 0x95 0x76 # CHECK: xvmaxi.du $xr30, $xr11, 30 ++0x0f 0x1d 0x96 0x76 # CHECK: xvmini.bu $xr15, $xr8, 7 ++0x32 0x87 0x96 0x76 # CHECK: xvmini.hu $xr18, $xr25, 1 ++0x90 0x03 0x97 0x76 # CHECK: xvmini.wu $xr16, $xr28, 0 ++0x6a 0xf6 0x97 0x76 # CHECK: xvmini.du $xr10, $xr19, 29 ++0x28 0x0b 0x9a 0x76 # CHECK: xvfrstpi.b $xr8, $xr25, 2 ++0x7c 0xea 0x9a 0x76 # CHECK: xvfrstpi.h $xr28, $xr19, 26 ++0x02 0x01 0x9c 0x76 # CHECK: xvclo.b $xr2, $xr8 ++0x2a 0x05 0x9c 0x76 # CHECK: xvclo.h $xr10, $xr9 ++0xe2 0x0b 0x9c 0x76 # CHECK: xvclo.w $xr2, $xr31 ++0x15 0x0f 0x9c 0x76 # CHECK: xvclo.d $xr21, $xr24 ++0x0d 0x13 0x9c 0x76 # CHECK: xvclz.b $xr13, $xr24 ++0xe4 0x17 0x9c 0x76 # CHECK: xvclz.h $xr4, $xr31 ++0x27 0x18 0x9c 0x76 # CHECK: xvclz.w $xr7, $xr1 ++0xcd 0x1e 0x9c 0x76 # CHECK: xvclz.d $xr13, $xr22 ++0x49 0x23 0x9c 0x76 # CHECK: xvpcnt.b $xr9, $xr26 ++0x6a 0x24 0x9c 0x76 # CHECK: xvpcnt.h $xr10, $xr3 ++0xf8 0x28 0x9c 0x76 # CHECK: xvpcnt.w $xr24, $xr7 ++0x05 0x2d 0x9c 0x76 # CHECK: xvpcnt.d $xr5, $xr8 ++0x73 0x31 0x9c 0x76 # CHECK: xvneg.b $xr19, $xr11 ++0xb5 0x36 0x9c 0x76 # CHECK: xvneg.h $xr21, $xr21 ++0x33 0x3a 0x9c 0x76 # CHECK: xvneg.w $xr19, $xr17 ++0xbf 0x3f 0x9c 0x76 # CHECK: xvneg.d $xr31, $xr29 ++0x76 0x43 0x9c 0x76 # CHECK: xvmskltz.b $xr22, $xr27 ++0x05 0x44 0x9c 0x76 # CHECK: xvmskltz.h $xr5, $xr0 ++0x98 0x4b 0x9c 0x76 # CHECK: xvmskltz.w $xr24, $xr28 ++0x59 0x4c 0x9c 0x76 # CHECK: xvmskltz.d $xr25, $xr2 ++0xde 0x53 0x9c 0x76 # CHECK: xvmskgez.b $xr30, $xr30 ++0x85 0x62 0x9c 0x76 # CHECK: xvmsknz.b $xr5, $xr20 ++0x21 0x9b 0x9c 0x76 # CHECK: xvseteqz.v $fcc1, $xr25 ++0xa5 0x9d 0x9c 0x76 # CHECK: xvsetnez.v $fcc5, $xr13 ++0x80 0xa0 0x9c 0x76 # CHECK: xvsetanyeqz.b $fcc0, $xr4 ++0xe0 0xa7 0x9c 0x76 # CHECK: xvsetanyeqz.h $fcc0, $xr31 ++0xc2 0xab 0x9c 0x76 # CHECK: xvsetanyeqz.w $fcc2, $xr30 ++0xe3 0xaf 0x9c 0x76 # CHECK: xvsetanyeqz.d $fcc3, $xr31 ++0xa1 0xb2 0x9c 0x76 # CHECK: xvsetallnez.b $fcc1, $xr21 ++0xa0 0xb6 0x9c 0x76 # CHECK: xvsetallnez.h $fcc0, $xr21 ++0x00 0xb8 0x9c 0x76 # CHECK: xvsetallnez.w $fcc0, $xr0 ++0xe1 0xbf 0x9c 0x76 # CHECK: xvsetallnez.d $fcc1, $xr31 ++0x95 0xc4 0x9c 0x76 # CHECK: xvflogb.s $xr21, $xr4 ++0x88 0xca 0x9c 0x76 # CHECK: xvflogb.d $xr8, $xr20 ++0xaf 0xd7 0x9c 0x76 # CHECK: xvfclass.s $xr15, $xr29 ++0xc7 0xd9 0x9c 0x76 # CHECK: xvfclass.d $xr7, $xr14 ++0x7c 0xe6 0x9c 0x76 # CHECK: xvfsqrt.s $xr28, $xr19 ++0xeb 0xeb 0x9c 0x76 # CHECK: xvfsqrt.d $xr11, $xr31 ++0xe6 0xf6 0x9c 0x76 # CHECK: xvfrecip.s $xr6, $xr23 ++0x00 0xfb 0x9c 0x76 # CHECK: xvfrecip.d $xr0, $xr24 ++0x08 0x06 0x9d 0x76 # CHECK: xvfrsqrt.s $xr8, $xr16 ++0x2f 0x0a 0x9d 0x76 # CHECK: xvfrsqrt.d $xr15, $xr17 ++0x24 0x37 0x9d 0x76 # CHECK: xvfrint.s $xr4, $xr25 ++0x81 0x3a 0x9d 0x76 # CHECK: xvfrint.d $xr1, $xr20 ++0x1d 0x46 0x9d 0x76 # CHECK: xvfrintrm.s $xr29, $xr16 ++0x44 0x49 0x9d 0x76 # CHECK: xvfrintrm.d $xr4, $xr10 ++0xed 0x57 0x9d 0x76 # CHECK: xvfrintrp.s $xr13, $xr31 ++0x74 0x59 0x9d 0x76 # CHECK: xvfrintrp.d $xr20, $xr11 ++0xbb 0x65 0x9d 0x76 # CHECK: xvfrintrz.s $xr27, $xr13 ++0x31 0x6b 0x9d 0x76 # CHECK: xvfrintrz.d $xr17, $xr25 ++0x0e 0x75 0x9d 0x76 # CHECK: xvfrintrne.s $xr14, $xr8 ++0x57 0x7b 0x9d 0x76 # CHECK: xvfrintrne.d $xr23, $xr26 ++0xe4 0xea 0x9d 0x76 # CHECK: xvfcvtl.s.h $xr4, $xr23 ++0x6e 0xed 0x9d 0x76 # CHECK: xvfcvth.s.h $xr14, $xr11 ++0xfa 0xf3 0x9d 0x76 # CHECK: xvfcvtl.d.s $xr26, $xr31 ++0x8d 0xf7 0x9d 0x76 # CHECK: xvfcvth.d.s $xr13, $xr28 ++0x8e 0x03 0x9e 0x76 # CHECK: xvffint.s.w $xr14, $xr28 ++0x00 0x05 0x9e 0x76 # CHECK: xvffint.s.wu $xr0, $xr8 ++0x65 0x0b 0x9e 0x76 # CHECK: xvffint.d.l $xr5, $xr27 ++0x5d 0x0e 0x9e 0x76 # CHECK: xvffint.d.lu $xr29, $xr18 ++0x89 0x12 0x9e 0x76 # CHECK: xvffintl.d.w $xr9, $xr20 ++0xab 0x15 0x9e 0x76 # CHECK: xvffinth.d.w $xr11, $xr13 ++0x86 0x30 0x9e 0x76 # CHECK: xvftint.w.s $xr6, $xr4 ++0xcb 0x36 0x9e 0x76 # CHECK: xvftint.l.d $xr11, $xr22 ++0xb4 0x3a 0x9e 0x76 # CHECK: xvftintrm.w.s $xr20, $xr21 ++0x7c 0x3f 0x9e 0x76 # CHECK: xvftintrm.l.d $xr28, $xr27 ++0x0e 0x42 0x9e 0x76 # CHECK: xvftintrp.w.s $xr14, $xr16 ++0x2e 0x47 0x9e 0x76 # CHECK: xvftintrp.l.d $xr14, $xr25 ++0xc5 0x4b 0x9e 0x76 # CHECK: xvftintrz.w.s $xr5, $xr30 ++0x6b 0x4e 0x9e 0x76 # CHECK: xvftintrz.l.d $xr11, $xr19 ++0xfb 0x52 0x9e 0x76 # CHECK: xvftintrne.w.s $xr27, $xr23 ++0xbb 0x55 0x9e 0x76 # CHECK: xvftintrne.l.d $xr27, $xr13 ++0x5c 0x58 0x9e 0x76 # CHECK: xvftint.wu.s $xr28, $xr2 ++0x9b 0x5d 0x9e 0x76 # CHECK: xvftint.lu.d $xr27, $xr12 ++0xb5 0x73 0x9e 0x76 # CHECK: xvftintrz.wu.s $xr21, $xr29 ++0x53 0x74 0x9e 0x76 # CHECK: xvftintrz.lu.d $xr19, $xr2 ++0x42 0x82 0x9e 0x76 # CHECK: xvftintl.l.s $xr2, $xr18 ++0xc8 0x87 0x9e 0x76 # CHECK: xvftinth.l.s $xr8, $xr30 ++0x2d 0x8a 0x9e 0x76 # CHECK: xvftintrml.l.s $xr13, $xr17 ++0x5e 0x8f 0x9e 0x76 # CHECK: xvftintrmh.l.s $xr30, $xr26 ++0x4b 0x93 0x9e 0x76 # CHECK: xvftintrpl.l.s $xr11, $xr26 ++0x7e 0x95 0x9e 0x76 # CHECK: xvftintrph.l.s $xr30, $xr11 ++0xf9 0x98 0x9e 0x76 # CHECK: xvftintrzl.l.s $xr25, $xr7 ++0xac 0x9c 0x9e 0x76 # CHECK: xvftintrzh.l.s $xr12, $xr5 ++0x08 0xa3 0x9e 0x76 # CHECK: xvftintrnel.l.s $xr8, $xr24 ++0x19 0xa7 0x9e 0x76 # CHECK: xvftintrneh.l.s $xr25, $xr24 ++0xb7 0xe0 0x9e 0x76 # CHECK: xvexth.h.b $xr23, $xr5 ++0xd9 0xe4 0x9e 0x76 # CHECK: xvexth.w.h $xr25, $xr6 ++0x67 0xeb 0x9e 0x76 # CHECK: xvexth.d.w $xr7, $xr27 ++0x4e 0xed 0x9e 0x76 # CHECK: xvexth.q.d $xr14, $xr10 ++0xa0 0xf2 0x9e 0x76 # CHECK: xvexth.hu.bu $xr0, $xr21 ++0xcf 0xf6 0x9e 0x76 # CHECK: xvexth.wu.hu $xr15, $xr22 ++0xf8 0xf9 0x9e 0x76 # CHECK: xvexth.du.wu $xr24, $xr15 ++0x44 0xfc 0x9e 0x76 # CHECK: xvexth.qu.du $xr4, $xr2 ++0xd5 0x00 0x9f 0x76 # CHECK: xvreplgr2vr.b $xr21, $r6 ++0x2b 0x04 0x9f 0x76 # CHECK: xvreplgr2vr.h $xr11, $ra ++0xcd 0x0a 0x9f 0x76 # CHECK: xvreplgr2vr.w $xr13, $r22 ++0x29 0x0e 0x9f 0x76 # CHECK: xvreplgr2vr.d $xr9, $r17 ++0x12 0x12 0x9f 0x76 # CHECK: vext2xv.h.b $xr18, $xr16 ++0xe3 0x16 0x9f 0x76 # CHECK: vext2xv.w.b $xr3, $xr23 ++0x1e 0x1a 0x9f 0x76 # CHECK: vext2xv.d.b $xr30, $xr16 ++0xfc 0x1e 0x9f 0x76 # CHECK: vext2xv.w.h $xr28, $xr23 ++0x24 0x20 0x9f 0x76 # CHECK: vext2xv.d.h $xr4, $xr1 ++0x97 0x25 0x9f 0x76 # CHECK: vext2xv.d.w $xr23, $xr12 ++0xa0 0x28 0x9f 0x76 # CHECK: vext2xv.hu.bu $xr0, $xr5 ++0x81 0x2c 0x9f 0x76 # CHECK: vext2xv.wu.bu $xr1, $xr4 ++0x71 0x31 0x9f 0x76 # CHECK: vext2xv.du.bu $xr17, $xr11 ++0x1c 0x34 0x9f 0x76 # CHECK: vext2xv.wu.hu $xr28, $xr0 ++0x3a 0x3b 0x9f 0x76 # CHECK: vext2xv.du.hu $xr26, $xr25 ++0xdd 0x3d 0x9f 0x76 # CHECK: vext2xv.du.wu $xr29, $xr14 ++0xc3 0xb6 0x9f 0x76 # CHECK: xvhseli.d $xr3, $xr22, 13 ++0xc0 0x29 0xa0 0x76 # CHECK: xvrotri.b $xr0, $xr14, 2 ++0xe0 0x6c 0xa0 0x76 # CHECK: xvrotri.h $xr0, $xr7, 11 ++0x38 0x8c 0xa0 0x76 # CHECK: xvrotri.w $xr24, $xr1, 3 ++0xff 0x40 0xa1 0x76 # CHECK: xvrotri.d $xr31, $xr7, 16 ++0x74 0x26 0xa4 0x76 # CHECK: xvsrlri.b $xr20, $xr19, 1 ++0x3c 0x6c 0xa4 0x76 # CHECK: xvsrlri.h $xr28, $xr1, 11 ++0x59 0xec 0xa4 0x76 # CHECK: xvsrlri.w $xr25, $xr2, 27 ++0x3d 0x19 0xa5 0x76 # CHECK: xvsrlri.d $xr29, $xr9, 6 ++0xa7 0x28 0xa8 0x76 # CHECK: xvsrari.b $xr7, $xr5, 2 ++0x40 0x65 0xa8 0x76 # CHECK: xvsrari.h $xr0, $xr10, 9 ++0x11 0xab 0xa8 0x76 # CHECK: xvsrari.w $xr17, $xr24, 10 ++0xc7 0x99 0xa9 0x76 # CHECK: xvsrari.d $xr7, $xr14, 38 ++0xe5 0xc7 0xeb 0x76 # CHECK: xvinsgr2vr.w $xr5, $r31, 1 ++0x45 0xe7 0xeb 0x76 # CHECK: xvinsgr2vr.d $xr5, $r26, 1 ++0x92 0xcb 0xef 0x76 # CHECK: xvpickve2gr.w $r18, $xr28, 2 ++0x54 0xe5 0xef 0x76 # CHECK: xvpickve2gr.d $r20, $xr10, 1 ++0x89 0xd9 0xf3 0x76 # CHECK: xvpickve2gr.wu $r9, $xr12, 6 ++0xa9 0xe9 0xf3 0x76 # CHECK: xvpickve2gr.du $r9, $xr13, 2 ++0xc1 0x97 0xf7 0x76 # CHECK: xvrepl128vei.b $xr1, $xr30, 5 ++0xad 0xdd 0xf7 0x76 # CHECK: xvrepl128vei.h $xr13, $xr13, 7 ++0xa7 0xe9 0xf7 0x76 # CHECK: xvrepl128vei.w $xr7, $xr13, 2 ++0xe2 0xf7 0xf7 0x76 # CHECK: xvrepl128vei.d $xr2, $xr31, 1 ++0xa4 0xcd 0xff 0x76 # CHECK: xvinsve0.w $xr4, $xr13, 3 ++0x3b 0xe3 0xff 0x76 # CHECK: xvinsve0.d $xr27, $xr25, 0 ++0x7d 0xde 0x03 0x77 # CHECK: xvpickve.w $xr29, $xr19, 7 ++0x13 0xee 0x03 0x77 # CHECK: xvpickve.d $xr19, $xr16, 3 ++0xa5 0x00 0x07 0x77 # CHECK: xvreplve0.b $xr5, $xr5 ++0x0e 0x83 0x07 0x77 # CHECK: xvreplve0.h $xr14, $xr24 ++0xaf 0xc1 0x07 0x77 # CHECK: xvreplve0.w $xr15, $xr13 ++0x94 0xe2 0x07 0x77 # CHECK: xvreplve0.d $xr20, $xr20 ++0x45 0xf1 0x07 0x77 # CHECK: xvreplve0.q $xr5, $xr10 ++0x1f 0x2c 0x08 0x77 # CHECK: xvsllwil.h.b $xr31, $xr0, 3 ++0x15 0x5f 0x08 0x77 # CHECK: xvsllwil.w.h $xr21, $xr24, 7 ++0x1a 0xcb 0x08 0x77 # CHECK: xvsllwil.d.w $xr26, $xr24, 18 ++0xc5 0x00 0x09 0x77 # CHECK: xvextl.q.d $xr5, $xr6 ++0xed 0x3b 0x0c 0x77 # CHECK: xvsllwil.hu.bu $xr13, $xr31, 6 ++0x93 0x62 0x0c 0x77 # CHECK: xvsllwil.wu.hu $xr19, $xr20, 8 ++0xae 0x89 0x0c 0x77 # CHECK: xvsllwil.du.wu $xr14, $xr13, 2 ++0xea 0x00 0x0d 0x77 # CHECK: xvextl.qu.du $xr10, $xr7 ++0xbf 0x36 0x10 0x77 # CHECK: xvbitclri.b $xr31, $xr21, 5 ++0x9a 0x48 0x10 0x77 # CHECK: xvbitclri.h $xr26, $xr4, 2 ++0x35 0xbf 0x10 0x77 # CHECK: xvbitclri.w $xr21, $xr25, 15 ++0x0e 0xfc 0x11 0x77 # CHECK: xvbitclri.d $xr14, $xr0, 63 ++0x30 0x34 0x14 0x77 # CHECK: xvbitseti.b $xr16, $xr1, 5 ++0xd3 0x4f 0x14 0x77 # CHECK: xvbitseti.h $xr19, $xr30, 3 ++0xd2 0xee 0x14 0x77 # CHECK: xvbitseti.w $xr18, $xr22, 27 ++0x2f 0xa0 0x15 0x77 # CHECK: xvbitseti.d $xr15, $xr1, 40 ++0xb7 0x20 0x18 0x77 # CHECK: xvbitrevi.b $xr23, $xr5, 0 ++0x45 0x5c 0x18 0x77 # CHECK: xvbitrevi.h $xr5, $xr2, 7 ++0xd7 0xb0 0x18 0x77 # CHECK: xvbitrevi.w $xr23, $xr6, 12 ++0xd2 0x85 0x19 0x77 # CHECK: xvbitrevi.d $xr18, $xr14, 33 ++0x5b 0x33 0x24 0x77 # CHECK: xvsat.b $xr27, $xr26, 4 ++0xa4 0x56 0x24 0x77 # CHECK: xvsat.h $xr4, $xr21, 5 ++0x7d 0xab 0x24 0x77 # CHECK: xvsat.w $xr29, $xr27, 10 ++0x0e 0xf0 0x25 0x77 # CHECK: xvsat.d $xr14, $xr0, 60 ++0x3f 0x2f 0x28 0x77 # CHECK: xvsat.bu $xr31, $xr25, 3 ++0x91 0x78 0x28 0x77 # CHECK: xvsat.hu $xr17, $xr4, 14 ++0x31 0x92 0x28 0x77 # CHECK: xvsat.wu $xr17, $xr17, 4 ++0x0b 0xac 0x29 0x77 # CHECK: xvsat.du $xr11, $xr0, 43 ++0x18 0x2b 0x2c 0x77 # CHECK: xvslli.b $xr24, $xr24, 2 ++0x37 0x5d 0x2c 0x77 # CHECK: xvslli.h $xr23, $xr9, 7 ++0x8d 0xc1 0x2c 0x77 # CHECK: xvslli.w $xr13, $xr12, 16 ++0xcb 0x46 0x2d 0x77 # CHECK: xvslli.d $xr11, $xr22, 17 ++0xc9 0x25 0x30 0x77 # CHECK: xvsrli.b $xr9, $xr14, 1 ++0x96 0x7e 0x30 0x77 # CHECK: xvsrli.h $xr22, $xr20, 15 ++0xc5 0xd3 0x30 0x77 # CHECK: xvsrli.w $xr5, $xr30, 20 ++0x01 0xea 0x31 0x77 # CHECK: xvsrli.d $xr1, $xr16, 58 ++0xd2 0x28 0x34 0x77 # CHECK: xvsrai.b $xr18, $xr6, 2 ++0x15 0x72 0x34 0x77 # CHECK: xvsrai.h $xr21, $xr16, 12 ++0x2d 0xc6 0x34 0x77 # CHECK: xvsrai.w $xr13, $xr17, 17 ++0x83 0xcd 0x35 0x77 # CHECK: xvsrai.d $xr3, $xr12, 51 ++0xe1 0x50 0x40 0x77 # CHECK: xvsrlni.b.h $xr1, $xr7, 4 ++0xb0 0xe6 0x40 0x77 # CHECK: xvsrlni.h.w $xr16, $xr21, 25 ++0x4d 0xc1 0x41 0x77 # CHECK: xvsrlni.w.d $xr13, $xr10, 48 ++0x91 0xf9 0x43 0x77 # CHECK: xvsrlni.d.q $xr17, $xr12, 126 ++0x71 0x7e 0x44 0x77 # CHECK: xvsrlrni.b.h $xr17, $xr19, 15 ++0x15 0xbb 0x44 0x77 # CHECK: xvsrlrni.h.w $xr21, $xr24, 14 ++0xf4 0x0f 0x45 0x77 # CHECK: xvsrlrni.w.d $xr20, $xr31, 3 ++0x1c 0x33 0x47 0x77 # CHECK: xvsrlrni.d.q $xr28, $xr24, 76 ++0xfa 0x5c 0x48 0x77 # CHECK: xvssrlni.b.h $xr26, $xr7, 7 ++0x9b 0xe7 0x48 0x77 # CHECK: xvssrlni.h.w $xr27, $xr28, 25 ++0x04 0x41 0x49 0x77 # CHECK: xvssrlni.w.d $xr4, $xr8, 16 ++0x2e 0x52 0x4b 0x77 # CHECK: xvssrlni.d.q $xr14, $xr17, 84 ++0xd1 0x48 0x4c 0x77 # CHECK: xvssrlni.bu.h $xr17, $xr6, 2 ++0x46 0x8f 0x4c 0x77 # CHECK: xvssrlni.hu.w $xr6, $xr26, 3 ++0x4a 0xda 0x4d 0x77 # CHECK: xvssrlni.wu.d $xr10, $xr18, 54 ++0x5d 0x1b 0x4f 0x77 # CHECK: xvssrlni.du.q $xr29, $xr26, 70 ++0x26 0x59 0x50 0x77 # CHECK: xvssrlrni.b.h $xr6, $xr9, 6 ++0x16 0x85 0x50 0x77 # CHECK: xvssrlrni.h.w $xr22, $xr8, 1 ++0x3c 0x71 0x51 0x77 # CHECK: xvssrlrni.w.d $xr28, $xr9, 28 ++0x74 0xa3 0x53 0x77 # CHECK: xvssrlrni.d.q $xr20, $xr27, 104 ++0x99 0x70 0x54 0x77 # CHECK: xvssrlrni.bu.h $xr25, $xr4, 12 ++0xb5 0x97 0x54 0x77 # CHECK: xvssrlrni.hu.w $xr21, $xr29, 5 ++0x01 0xda 0x55 0x77 # CHECK: xvssrlrni.wu.d $xr1, $xr16, 54 ++0xfd 0x64 0x56 0x77 # CHECK: xvssrlrni.du.q $xr29, $xr7, 25 ++0x30 0x53 0x58 0x77 # CHECK: xvsrani.b.h $xr16, $xr25, 4 ++0x4d 0x99 0x58 0x77 # CHECK: xvsrani.h.w $xr13, $xr10, 6 ++0xa7 0xd6 0x59 0x77 # CHECK: xvsrani.w.d $xr7, $xr21, 53 ++0x5a 0xde 0x5a 0x77 # CHECK: xvsrani.d.q $xr26, $xr18, 55 ++0xb1 0x6e 0x5c 0x77 # CHECK: xvsrarni.b.h $xr17, $xr21, 11 ++0xcf 0x8b 0x5c 0x77 # CHECK: xvsrarni.h.w $xr15, $xr30, 2 ++0x77 0x7d 0x5d 0x77 # CHECK: xvsrarni.w.d $xr23, $xr11, 31 ++0x36 0x43 0x5e 0x77 # CHECK: xvsrarni.d.q $xr22, $xr25, 16 ++0x93 0x6a 0x60 0x77 # CHECK: xvssrani.b.h $xr19, $xr20, 10 ++0x39 0xd9 0x60 0x77 # CHECK: xvssrani.h.w $xr25, $xr9, 22 ++0x57 0x1c 0x61 0x77 # CHECK: xvssrani.w.d $xr23, $xr2, 7 ++0x06 0xfd 0x63 0x77 # CHECK: xvssrani.d.q $xr6, $xr8, 127 ++0xdb 0x55 0x64 0x77 # CHECK: xvssrani.bu.h $xr27, $xr14, 5 ++0x2e 0xd0 0x64 0x77 # CHECK: xvssrani.hu.w $xr14, $xr1, 20 ++0x8a 0xec 0x65 0x77 # CHECK: xvssrani.wu.d $xr10, $xr4, 59 ++0x31 0x48 0x67 0x77 # CHECK: xvssrani.du.q $xr17, $xr1, 82 ++0x5b 0x7e 0x68 0x77 # CHECK: xvssrarni.b.h $xr27, $xr18, 15 ++0x70 0xbc 0x68 0x77 # CHECK: xvssrarni.h.w $xr16, $xr3, 15 ++0x3a 0x4b 0x69 0x77 # CHECK: xvssrarni.w.d $xr26, $xr25, 18 ++0x3c 0x03 0x6a 0x77 # CHECK: xvssrarni.d.q $xr28, $xr25, 0 ++0x81 0x61 0x6c 0x77 # CHECK: xvssrarni.bu.h $xr1, $xr12, 8 ++0x63 0xff 0x6c 0x77 # CHECK: xvssrarni.hu.w $xr3, $xr27, 31 ++0x78 0xd3 0x6d 0x77 # CHECK: xvssrarni.wu.d $xr24, $xr27, 52 ++0x65 0xc0 0x6f 0x77 # CHECK: xvssrarni.du.q $xr5, $xr3, 112 ++0x35 0x8f 0x82 0x77 # CHECK: xvextrins.d $xr21, $xr25, 163 ++0x33 0x72 0x84 0x77 # CHECK: xvextrins.w $xr19, $xr17, 28 ++0xfe 0x3c 0x89 0x77 # CHECK: xvextrins.h $xr30, $xr7, 79 ++0xe1 0x4b 0x8f 0x77 # CHECK: xvextrins.b $xr1, $xr31, 210 ++0xc3 0x52 0x92 0x77 # CHECK: xvshuf4i.b $xr3, $xr22, 148 ++0xc2 0x8a 0x94 0x77 # CHECK: xvshuf4i.h $xr2, $xr22, 34 ++0x7f 0x96 0x9a 0x77 # CHECK: xvshuf4i.w $xr31, $xr19, 165 ++0x3f 0x3a 0x9c 0x77 # CHECK: xvshuf4i.d $xr31, $xr17, 14 ++0x1b 0x40 0xc5 0x77 # CHECK: xvbitseli.b $xr27, $xr0, 80 ++0x57 0x64 0xd2 0x77 # CHECK: xvandi.b $xr23, $xr2, 153 ++0x9b 0xf3 0xd6 0x77 # CHECK: xvori.b $xr27, $xr28, 188 ++0x3c 0xf8 0xdb 0x77 # CHECK: xvxori.b $xr28, $xr1, 254 ++0x44 0x90 0xdc 0x77 # CHECK: xvnori.b $xr4, $xr2, 36 ++0x1a 0xc2 0xe2 0x77 # CHECK: xvldi $xr26, -2544 ++0x16 0xa3 0xe6 0x77 # CHECK: xvpermi.w $xr22, $xr24, 168 ++0xee 0x23 0xea 0x77 # CHECK: xvpermi.d $xr14, $xr31, 136 ++0xdc 0x4d 0xef 0x77 # CHECK: xvpermi.q $xr28, $xr14, 211 ++0xe0 0x7f 0x1e 0x70 # CHECK: vaddwev.h.b $vr0, $vr31, $vr31 ++0x83 0xdc 0x1e 0x70 # CHECK: vaddwev.w.h $vr3, $vr4, $vr23 ++0x5e 0x2f 0x1f 0x70 # CHECK: vaddwev.d.w $vr30, $vr26, $vr11 ++0xb9 0xb7 0x1f 0x70 # CHECK: vaddwev.q.d $vr25, $vr29, $vr13 ++0x8b 0x07 0x20 0x70 # CHECK: vsubwev.h.b $vr11, $vr28, $vr1 ++0xe9 0x95 0x20 0x70 # CHECK: vsubwev.w.h $vr9, $vr15, $vr5 ++0x31 0x29 0x21 0x70 # CHECK: vsubwev.d.w $vr17, $vr9, $vr10 ++0x5a 0xae 0x21 0x70 # CHECK: vsubwev.q.d $vr26, $vr18, $vr11 ++0x67 0x49 0x22 0x70 # CHECK: vaddwod.h.b $vr7, $vr11, $vr18 ++0xe0 0xb0 0x22 0x70 # CHECK: vaddwod.w.h $vr0, $vr7, $vr12 ++0x7e 0x43 0x23 0x70 # CHECK: vaddwod.d.w $vr30, $vr27, $vr16 ++0x82 0xf6 0x23 0x70 # CHECK: vaddwod.q.d $vr2, $vr20, $vr29 ++0xfa 0x4c 0x24 0x70 # CHECK: vsubwod.h.b $vr26, $vr7, $vr19 ++0x73 0xac 0x24 0x70 # CHECK: vsubwod.w.h $vr19, $vr3, $vr11 ++0x9f 0x33 0x25 0x70 # CHECK: vsubwod.d.w $vr31, $vr28, $vr12 ++0x01 0xc3 0x25 0x70 # CHECK: vsubwod.q.d $vr1, $vr24, $vr16 ++0xa3 0x77 0x2e 0x70 # CHECK: vaddwev.h.bu $vr3, $vr29, $vr29 ++0xea 0xa9 0x2e 0x70 # CHECK: vaddwev.w.hu $vr10, $vr15, $vr10 ++0xb8 0x13 0x2f 0x70 # CHECK: vaddwev.d.wu $vr24, $vr29, $vr4 ++0xf1 0x82 0x2f 0x70 # CHECK: vaddwev.q.du $vr17, $vr23, $vr0 ++0x79 0x51 0x30 0x70 # CHECK: vsubwev.h.bu $vr25, $vr11, $vr20 ++0xf1 0xd1 0x30 0x70 # CHECK: vsubwev.w.hu $vr17, $vr15, $vr20 ++0x2a 0x17 0x31 0x70 # CHECK: vsubwev.d.wu $vr10, $vr25, $vr5 ++0x7d 0xa0 0x31 0x70 # CHECK: vsubwev.q.du $vr29, $vr3, $vr8 ++0x0a 0x64 0x32 0x70 # CHECK: vaddwod.h.bu $vr10, $vr0, $vr25 ++0x62 0xdf 0x32 0x70 # CHECK: vaddwod.w.hu $vr2, $vr27, $vr23 ++0x02 0x58 0x33 0x70 # CHECK: vaddwod.d.wu $vr2, $vr0, $vr22 ++0x40 0x8c 0x33 0x70 # CHECK: vaddwod.q.du $vr0, $vr2, $vr3 ++0xee 0x0f 0x34 0x70 # CHECK: vsubwod.h.bu $vr14, $vr31, $vr3 ++0x55 0x9c 0x34 0x70 # CHECK: vsubwod.w.hu $vr21, $vr2, $vr7 ++0x0b 0x49 0x35 0x70 # CHECK: vsubwod.d.wu $vr11, $vr8, $vr18 ++0x9e 0x82 0x35 0x70 # CHECK: vsubwod.q.du $vr30, $vr20, $vr0 ++0x93 0x47 0x3e 0x70 # CHECK: vaddwev.h.bu.b $vr19, $vr28, $vr17 ++0xee 0xf9 0x3e 0x70 # CHECK: vaddwev.w.hu.h $vr14, $vr15, $vr30 ++0xef 0x28 0x3f 0x70 # CHECK: vaddwev.d.wu.w $vr15, $vr7, $vr10 ++0xd3 0xf9 0x3f 0x70 # CHECK: vaddwev.q.du.d $vr19, $vr14, $vr30 ++0x4f 0x22 0x40 0x70 # CHECK: vaddwod.h.bu.b $vr15, $vr18, $vr8 ++0x73 0x9b 0x40 0x70 # CHECK: vaddwod.w.hu.h $vr19, $vr27, $vr6 ++0x67 0x3d 0x41 0x70 # CHECK: vaddwod.d.wu.w $vr7, $vr11, $vr15 ++0x00 0xe8 0x41 0x70 # CHECK: vaddwod.q.du.d $vr0, $vr0, $vr26 ++0x78 0x56 0x90 0x70 # CHECK: vmulwev.h.b $vr24, $vr19, $vr21 ++0xcd 0xca 0x90 0x70 # CHECK: vmulwev.w.h $vr13, $vr22, $vr18 ++0xd8 0x36 0x91 0x70 # CHECK: vmulwev.d.w $vr24, $vr22, $vr13 ++0xc4 0xfa 0x91 0x70 # CHECK: vmulwev.q.d $vr4, $vr22, $vr30 ++0x56 0x63 0x92 0x70 # CHECK: vmulwod.h.b $vr22, $vr26, $vr24 ++0x91 0x91 0x92 0x70 # CHECK: vmulwod.w.h $vr17, $vr12, $vr4 ++0xf0 0x69 0x93 0x70 # CHECK: vmulwod.d.w $vr16, $vr15, $vr26 ++0x03 0x96 0x93 0x70 # CHECK: vmulwod.q.d $vr3, $vr16, $vr5 ++0x7f 0x4e 0x98 0x70 # CHECK: vmulwev.h.bu $vr31, $vr19, $vr19 ++0xf6 0x97 0x98 0x70 # CHECK: vmulwev.w.hu $vr22, $vr31, $vr5 ++0x80 0x78 0x99 0x70 # CHECK: vmulwev.d.wu $vr0, $vr4, $vr30 ++0x7f 0xd0 0x99 0x70 # CHECK: vmulwev.q.du $vr31, $vr3, $vr20 ++0xf9 0x34 0x9a 0x70 # CHECK: vmulwod.h.bu $vr25, $vr7, $vr13 ++0x81 0xb1 0x9a 0x70 # CHECK: vmulwod.w.hu $vr1, $vr12, $vr12 ++0xef 0x79 0x9b 0x70 # CHECK: vmulwod.d.wu $vr15, $vr15, $vr30 ++0x8d 0x9b 0x9b 0x70 # CHECK: vmulwod.q.du $vr13, $vr28, $vr6 ++0x48 0x0f 0xa0 0x70 # CHECK: vmulwev.h.bu.b $vr8, $vr26, $vr3 ++0x2a 0x87 0xa0 0x70 # CHECK: vmulwev.w.hu.h $vr10, $vr25, $vr1 ++0x09 0x4c 0xa1 0x70 # CHECK: vmulwev.d.wu.w $vr9, $vr0, $vr19 ++0x0d 0xdf 0xa1 0x70 # CHECK: vmulwev.q.du.d $vr13, $vr24, $vr23 ++0x14 0x38 0xa2 0x70 # CHECK: vmulwod.h.bu.b $vr20, $vr0, $vr14 ++0x90 0x8e 0xa2 0x70 # CHECK: vmulwod.w.hu.h $vr16, $vr20, $vr3 ++0xe5 0x6e 0xa3 0x70 # CHECK: vmulwod.d.wu.w $vr5, $vr23, $vr27 ++0xde 0xf7 0xa3 0x70 # CHECK: vmulwod.q.du.d $vr30, $vr30, $vr29 ++0x12 0x20 0xac 0x70 # CHECK: vmaddwev.h.b $vr18, $vr0, $vr8 ++0xdd 0x9e 0xac 0x70 # CHECK: vmaddwev.w.h $vr29, $vr22, $vr7 ++0xbc 0x7d 0xad 0x70 # CHECK: vmaddwev.d.w $vr28, $vr13, $vr31 ++0x65 0xb4 0xad 0x70 # CHECK: vmaddwev.q.d $vr5, $vr3, $vr13 ++0x24 0x24 0xae 0x70 # CHECK: vmaddwod.h.b $vr4, $vr1, $vr9 ++0x3a 0xe1 0xae 0x70 # CHECK: vmaddwod.w.h $vr26, $vr9, $vr24 ++0x7e 0x34 0xaf 0x70 # CHECK: vmaddwod.d.w $vr30, $vr3, $vr13 ++0xaf 0xf5 0xaf 0x70 # CHECK: vmaddwod.q.d $vr15, $vr13, $vr29 ++0x98 0x16 0xb4 0x70 # CHECK: vmaddwev.h.bu $vr24, $vr20, $vr5 ++0x83 0xa0 0xb4 0x70 # CHECK: vmaddwev.w.hu $vr3, $vr4, $vr8 ++0x7b 0x12 0xb5 0x70 # CHECK: vmaddwev.d.wu $vr27, $vr19, $vr4 ++0x7c 0xf7 0xb5 0x70 # CHECK: vmaddwev.q.du $vr28, $vr27, $vr29 ++0x85 0x6a 0xb6 0x70 # CHECK: vmaddwod.h.bu $vr5, $vr20, $vr26 ++0xd5 0xab 0xb6 0x70 # CHECK: vmaddwod.w.hu $vr21, $vr30, $vr10 ++0x67 0x51 0xb7 0x70 # CHECK: vmaddwod.d.wu $vr7, $vr11, $vr20 ++0x5e 0xe2 0xb7 0x70 # CHECK: vmaddwod.q.du $vr30, $vr18, $vr24 ++0x24 0x10 0xbc 0x70 # CHECK: vmaddwev.h.bu.b $vr4, $vr1, $vr4 ++0x79 0xbd 0xbc 0x70 # CHECK: vmaddwev.w.hu.h $vr25, $vr11, $vr15 ++0x0a 0x52 0xbd 0x70 # CHECK: vmaddwev.d.wu.w $vr10, $vr16, $vr20 ++0x96 0xde 0xbd 0x70 # CHECK: vmaddwev.q.du.d $vr22, $vr20, $vr23 ++0x3f 0x6f 0xbe 0x70 # CHECK: vmaddwod.h.bu.b $vr31, $vr25, $vr27 ++0x48 0xe2 0xbe 0x70 # CHECK: vmaddwod.w.hu.h $vr8, $vr18, $vr24 ++0xb2 0x29 0xbf 0x70 # CHECK: vmaddwod.d.wu.w $vr18, $vr13, $vr10 ++0xaa 0xbc 0xbf 0x70 # CHECK: vmaddwod.q.du.d $vr10, $vr5, $vr15 +diff --git a/llvm/test/MC/LoongArch/Basic/Float/d-arith.s b/llvm/test/MC/LoongArch/Basic/Float/d-arith.s +deleted file mode 100644 +index 8e19d2e34..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Float/d-arith.s ++++ /dev/null +@@ -1,107 +0,0 @@ +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +- +-## Support for the 'D' extension implies support for 'F' +-# ASM-AND-OBJ: fadd.s $fs5, $ft7, $fs1 +-# ASM: encoding: [0xfd,0xe5,0x00,0x01] +-fadd.s $fs5, $ft7, $fs1 +- +-# ASM-AND-OBJ: fadd.d $fs1, $fa7, $ft5 +-# ASM: encoding: [0xf9,0x34,0x01,0x01] +-fadd.d $fs1, $fa7, $ft5 +- +-# ASM-AND-OBJ: fsub.d $fs5, $fa1, $ft10 +-# ASM: encoding: [0x3d,0x48,0x03,0x01] +-fsub.d $fs5, $fa1, $ft10 +- +-# ASM-AND-OBJ: fmul.d $fa4, $fs6, $fa7 +-# ASM: encoding: [0xc4,0x1f,0x05,0x01] +-fmul.d $fa4, $fs6, $fa7 +- +-# ASM-AND-OBJ: fdiv.d $fa3, $fs1, $fs4 +-# ASM: encoding: [0x23,0x73,0x07,0x01] +-fdiv.d $fa3, $fs1, $fs4 +- +-# ASM-AND-OBJ: fmadd.d $ft13, $fs0, $fs4, $fs0 +-# ASM: encoding: [0x15,0x73,0x2c,0x08] +-fmadd.d $ft13, $fs0, $fs4, $fs0 +- +-# ASM-AND-OBJ: fmsub.d $fa6, $ft10, $ft12, $fs3 +-# ASM: encoding: [0x46,0xd2,0x6d,0x08] +-fmsub.d $fa6, $ft10, $ft12, $fs3 +- +-# ASM-AND-OBJ: fnmadd.d $fs1, $ft5, $ft11, $fs6 +-# ASM: encoding: [0xb9,0x4d,0xaf,0x08] +-fnmadd.d $fs1, $ft5, $ft11, $fs6 +- +-# ASM-AND-OBJ: fnmsub.d $fs6, $fs2, $fa7, $fs0 +-# ASM: encoding: [0x5e,0x1f,0xec,0x08] +-fnmsub.d $fs6, $fs2, $fa7, $fs0 +- +-# ASM-AND-OBJ: fmax.d $ft3, $fs2, $ft5 +-# ASM: encoding: [0x4b,0x37,0x09,0x01] +-fmax.d $ft3, $fs2, $ft5 +- +-# ASM-AND-OBJ: fmin.d $fa1, $ft5, $fs3 +-# ASM: encoding: [0xa1,0x6d,0x0b,0x01] +-fmin.d $fa1, $ft5, $fs3 +- +-# ASM-AND-OBJ: fmaxa.d $fs0, $ft5, $fa4 +-# ASM: encoding: [0xb8,0x11,0x0d,0x01] +-fmaxa.d $fs0, $ft5, $fa4 +- +-# ASM-AND-OBJ: fmina.d $ft10, $ft2, $fa0 +-# ASM: encoding: [0x52,0x01,0x0f,0x01] +-fmina.d $ft10, $ft2, $fa0 +- +-# ASM-AND-OBJ: fabs.d $ft15, $fa3 +-# ASM: encoding: [0x77,0x08,0x14,0x01] +-fabs.d $ft15, $fa3 +- +-# ASM-AND-OBJ: fneg.d $ft3, $fs2 +-# ASM: encoding: [0x4b,0x1b,0x14,0x01] +-fneg.d $ft3, $fs2 +- +-# ASM-AND-OBJ: fsqrt.d $fa2, $ft3 +-# ASM: encoding: [0x62,0x49,0x14,0x01] +-fsqrt.d $fa2, $ft3 +- +-# ASM-AND-OBJ: frecip.d $fs3, $fs3 +-# ASM: encoding: [0x7b,0x5b,0x14,0x01] +-frecip.d $fs3, $fs3 +- +-# ASM-AND-OBJ: frecipe.d $fa0, $fa0 +-# ASM: encoding: [0x00,0x78,0x14,0x01] +-frecipe.d $fa0, $fa0 +- +-# ASM-AND-OBJ: frsqrt.d $ft14, $fa3 +-# ASM: encoding: [0x76,0x68,0x14,0x01] +-frsqrt.d $ft14, $fa3 +- +-# ASM-AND-OBJ: frsqrte.d $fa1, $fa1 +-# ASM: encoding: [0x21,0x88,0x14,0x01] +-frsqrte.d $fa1, $fa1 +- +-# ASM-AND-OBJ: fscaleb.d $ft4, $ft6, $fs2 +-# ASM: encoding: [0xcc,0x69,0x11,0x01] +-fscaleb.d $ft4, $ft6, $fs2 +- +-# ASM-AND-OBJ: flogb.d $ft13, $fs5 +-# ASM: encoding: [0xb5,0x2b,0x14,0x01] +-flogb.d $ft13, $fs5 +- +-# ASM-AND-OBJ: fcopysign.d $ft8, $fs2, $fa6 +-# ASM: encoding: [0x50,0x1b,0x13,0x01] +-fcopysign.d $ft8, $fs2, $fa6 +- +-# ASM-AND-OBJ: fclass.d $ft11, $fa2 +-# ASM: encoding: [0x53,0x38,0x14,0x01] +-fclass.d $ft11, $fa2 +diff --git a/llvm/test/MC/LoongArch/Basic/Float/d-bound-check.s b/llvm/test/MC/LoongArch/Basic/Float/d-bound-check.s +deleted file mode 100644 +index 414d1329c..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Float/d-bound-check.s ++++ /dev/null +@@ -1,31 +0,0 @@ +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +- +-## Support for the 'D' extension implies support for 'F' +-# ASM-AND-OBJ: fldgt.s $fa3, $s4, $t1 +-# ASM: encoding: [0x63,0x37,0x74,0x38] +-fldgt.s $fa3, $s4, $t1 +- +-# ASM-AND-OBJ: fldgt.d $fs2, $a1, $s8 +-# ASM: encoding: [0xba,0xfc,0x74,0x38] +-fldgt.d $fs2, $a1, $s8 +- +-# ASM-AND-OBJ: fldle.d $fa3, $t3, $fp +-# ASM: encoding: [0xe3,0xd9,0x75,0x38] +-fldle.d $fa3, $t3, $fp +- +-# ASM-AND-OBJ: fstgt.d $ft5, $a7, $s3 +-# ASM: encoding: [0x6d,0xe9,0x76,0x38] +-fstgt.d $ft5, $a7, $s3 +- +-# ASM-AND-OBJ: fstle.d $ft10, $a5, $t1 +-# ASM: encoding: [0x32,0xb5,0x77,0x38] +-fstle.d $ft10, $a5, $t1 +diff --git a/llvm/test/MC/LoongArch/Basic/Float/d-branch.s b/llvm/test/MC/LoongArch/Basic/Float/d-branch.s +deleted file mode 100644 +index 06198d8e4..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Float/d-branch.s ++++ /dev/null +@@ -1,15 +0,0 @@ +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +- +-## Support for the 'D' extension implies support for 'F' +-# ASM-AND-OBJ: bceqz $fcc6, 12 +-# ASM: encoding: [0xc0,0x0c,0x00,0x48] +-bceqz $fcc6, 12 +diff --git a/llvm/test/MC/LoongArch/Basic/Float/d-comp.s b/llvm/test/MC/LoongArch/Basic/Float/d-comp.s +deleted file mode 100644 +index 19abebd9d..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Float/d-comp.s ++++ /dev/null +@@ -1,103 +0,0 @@ +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +- +-## Support for the 'D' extension implies support for 'F' +-# ASM-AND-OBJ: fcmp.caf.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x10,0x0c] +-fcmp.caf.s $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.caf.d $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x20,0x0c] +-fcmp.caf.d $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.cun.d $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x24,0x0c] +-fcmp.cun.d $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.ceq.d $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x22,0x0c] +-fcmp.ceq.d $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.cueq.d $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x26,0x0c] +-fcmp.cueq.d $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.clt.d $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x21,0x0c] +-fcmp.clt.d $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.cult.d $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x25,0x0c] +-fcmp.cult.d $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.cle.d $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x23,0x0c] +-fcmp.cle.d $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.cule.d $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x27,0x0c] +-fcmp.cule.d $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.cne.d $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x28,0x0c] +-fcmp.cne.d $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.cor.d $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x2a,0x0c] +-fcmp.cor.d $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.cune.d $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x2c,0x0c] +-fcmp.cune.d $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.saf.d $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x84,0x20,0x0c] +-fcmp.saf.d $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.sun.d $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x84,0x24,0x0c] +-fcmp.sun.d $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.seq.d $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x84,0x22,0x0c] +-fcmp.seq.d $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.sueq.d $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x84,0x26,0x0c] +-fcmp.sueq.d $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.slt.d $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x84,0x21,0x0c] +-fcmp.slt.d $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.sult.d $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x84,0x25,0x0c] +-fcmp.sult.d $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.sle.d $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x84,0x23,0x0c] +-fcmp.sle.d $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.sule.d $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x84,0x27,0x0c] +-fcmp.sule.d $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.sne.d $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x84,0x28,0x0c] +-fcmp.sne.d $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.sor.d $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x84,0x2a,0x0c] +-fcmp.sor.d $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.sune.d $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x84,0x2c,0x0c] +-fcmp.sune.d $fcc0, $fa0, $fa1 +diff --git a/llvm/test/MC/LoongArch/Basic/Float/d-conv.s b/llvm/test/MC/LoongArch/Basic/Float/d-conv.s +deleted file mode 100644 +index 2d6eae98d..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Float/d-conv.s ++++ /dev/null +@@ -1,99 +0,0 @@ +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +- +-## Support for the 'D' extension implies support for 'F' +-# ASM-AND-OBJ: frint.s $fa5, $ft9 +-# ASM: encoding: [0x25,0x46,0x1e,0x01] +-frint.s $fa5, $ft9 +- +-# ASM-AND-OBJ: fcvt.s.d $ft4, $ft11 +-# ASM: encoding: [0x6c,0x1a,0x19,0x01] +-fcvt.s.d $ft4, $ft11 +- +-# ASM-AND-OBJ: fcvt.d.s $ft2, $fa6 +-# ASM: encoding: [0xca,0x24,0x19,0x01] +-fcvt.d.s $ft2, $fa6 +- +-# ASM-AND-OBJ: ffint.s.l $fa6, $fa5 +-# ASM: encoding: [0xa6,0x18,0x1d,0x01] +-ffint.s.l $fa6, $fa5 +- +-# ASM-AND-OBJ: ffint.d.w $fs0, $ft10 +-# ASM: encoding: [0x58,0x22,0x1d,0x01] +-ffint.d.w $fs0, $ft10 +- +-# ASM-AND-OBJ: ffint.d.l $ft15, $fs2 +-# ASM: encoding: [0x57,0x2b,0x1d,0x01] +-ffint.d.l $ft15, $fs2 +- +-# ASM-AND-OBJ: ftint.w.d $fa3, $ft6 +-# ASM: encoding: [0xc3,0x09,0x1b,0x01] +-ftint.w.d $fa3, $ft6 +- +-# ASM-AND-OBJ: ftint.l.s $fs7, $fs0 +-# ASM: encoding: [0x1f,0x27,0x1b,0x01] +-ftint.l.s $fs7, $fs0 +- +-# ASM-AND-OBJ: ftint.l.d $ft8, $fs0 +-# ASM: encoding: [0x10,0x2b,0x1b,0x01] +-ftint.l.d $ft8, $fs0 +- +-# ASM-AND-OBJ: ftintrm.w.d $fa7, $ft0 +-# ASM: encoding: [0x07,0x09,0x1a,0x01] +-ftintrm.w.d $fa7, $ft0 +- +-# ASM-AND-OBJ: ftintrm.l.s $fs0, $ft2 +-# ASM: encoding: [0x58,0x25,0x1a,0x01] +-ftintrm.l.s $fs0, $ft2 +- +-# ASM-AND-OBJ: ftintrm.l.d $ft1, $ft1 +-# ASM: encoding: [0x29,0x29,0x1a,0x01] +-ftintrm.l.d $ft1, $ft1 +- +-# ASM-AND-OBJ: ftintrp.w.d $ft4, $fa3 +-# ASM: encoding: [0x6c,0x48,0x1a,0x01] +-ftintrp.w.d $ft4, $fa3 +- +-# ASM-AND-OBJ: ftintrp.l.s $fa0, $ft8 +-# ASM: encoding: [0x00,0x66,0x1a,0x01] +-ftintrp.l.s $fa0, $ft8 +- +-# ASM-AND-OBJ: ftintrp.l.d $fa4, $fs5 +-# ASM: encoding: [0xa4,0x6b,0x1a,0x01] +-ftintrp.l.d $fa4, $fs5 +- +-# ASM-AND-OBJ: ftintrz.w.d $fs1, $fs0 +-# ASM: encoding: [0x19,0x8b,0x1a,0x01] +-ftintrz.w.d $fs1, $fs0 +- +-# ASM-AND-OBJ: ftintrz.l.s $ft15, $fa5 +-# ASM: encoding: [0xb7,0xa4,0x1a,0x01] +-ftintrz.l.s $ft15, $fa5 +- +-# ASM-AND-OBJ: ftintrz.l.d $fa3, $ft2 +-# ASM: encoding: [0x43,0xa9,0x1a,0x01] +-ftintrz.l.d $fa3, $ft2 +- +-# ASM-AND-OBJ: ftintrne.w.d $fs7, $ft4 +-# ASM: encoding: [0x9f,0xc9,0x1a,0x01] +-ftintrne.w.d $fs7, $ft4 +- +-# ASM-AND-OBJ: ftintrne.l.s $ft14, $fs3 +-# ASM: encoding: [0x76,0xe7,0x1a,0x01] +-ftintrne.l.s $ft14, $fs3 +- +-# ASM-AND-OBJ: ftintrne.l.d $fs4, $fa6 +-# ASM: encoding: [0xdc,0xe8,0x1a,0x01] +-ftintrne.l.d $fs4, $fa6 +- +-# ASM-AND-OBJ: frint.d $fs5, $fa2 +-# ASM: encoding: [0x5d,0x48,0x1e,0x01] +-frint.d $fs5, $fa2 +diff --git a/llvm/test/MC/LoongArch/Basic/Float/d-invalid.s b/llvm/test/MC/LoongArch/Basic/Float/d-invalid.s +deleted file mode 100644 +index 255fd839e..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Float/d-invalid.s ++++ /dev/null +@@ -1,7 +0,0 @@ +-# RUN: not llvm-mc --triple=loongarch32 %s 2>&1 | FileCheck %s +- +-# CHECK: :[[#@LINE+1]]:1: error: instruction requires the following: LA64 Basic Integer and Privilege Instruction Set +-movgr2fr.d $fa0, $a0 +- +-# CHECK: :[[#@LINE+1]]:1: error: instruction requires the following: LA64 Basic Integer and Privilege Instruction Set +-movfr2gr.d $a0, $fa0 +diff --git a/llvm/test/MC/LoongArch/Basic/Float/d-memory.s b/llvm/test/MC/LoongArch/Basic/Float/d-memory.s +deleted file mode 100644 +index bce4563de..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Float/d-memory.s ++++ /dev/null +@@ -1,31 +0,0 @@ +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +- +-## Support for the 'D' extension implies support for 'F' +-# ASM-AND-OBJ: fld.s $ft15, $t3, 250 +-# ASM: encoding: [0xf7,0xe9,0x03,0x2b] +-fld.s $ft15, $t3, 250 +- +-# ASM-AND-OBJ: fld.d $ft14, $t5, 114 +-# ASM: encoding: [0x36,0xca,0x81,0x2b] +-fld.d $ft14, $t5, 114 +- +-# ASM-AND-OBJ: fst.d $fs4, $a3, 198 +-# ASM: encoding: [0xfc,0x18,0xc3,0x2b] +-fst.d $fs4, $a3, 198 +- +-# ASM-AND-OBJ: fldx.d $fs3, $t1, $s8 +-# ASM: encoding: [0xbb,0x7d,0x34,0x38] +-fldx.d $fs3, $t1, $s8 +- +-# ASM-AND-OBJ: fstx.d $fa6, $t3, $t5 +-# ASM: encoding: [0xe6,0x45,0x3c,0x38] +-fstx.d $fa6, $t3, $t5 +diff --git a/llvm/test/MC/LoongArch/Basic/Float/d-move.s b/llvm/test/MC/LoongArch/Basic/Float/d-move.s +deleted file mode 100644 +index afe8a51ec..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Float/d-move.s ++++ /dev/null +@@ -1,39 +0,0 @@ +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding --defsym=LA64=1 \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM,ASM-AND-OBJ64,ASM64 %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj --defsym=LA64=1 \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM-AND-OBJ64 %s +- +-## Support for the 'D' extension implies support for 'F' +-# ASM-AND-OBJ: fmov.s $ft5, $ft15 +-# ASM: encoding: [0xed,0x96,0x14,0x01] +-fmov.s $ft5, $ft15 +- +-# ASM-AND-OBJ: fmov.d $fs6, $ft1 +-# ASM: encoding: [0x3e,0x99,0x14,0x01] +-fmov.d $fs6, $ft1 +- +-# ASM-AND-OBJ: fsel $ft10, $ft12, $ft13, $fcc4 +-# ASM: encoding: [0x92,0x56,0x02,0x0d] +-fsel $ft10, $ft12, $ft13, $fcc4 +- +-# ASM-AND-OBJ64: movgr2frh.w $ft15, $s3 +-# ASM64: encoding: [0x57,0xaf,0x14,0x01] +-movgr2frh.w $ft15, $s3 +- +-.ifdef LA64 +- +-# ASM-AND-OBJ64: movgr2fr.d $fs6, $a7 +-# ASM64: encoding: [0x7e,0xa9,0x14,0x01] +-movgr2fr.d $fs6, $a7 +- +-# ASM-AND-OBJ64: movfr2gr.d $s3, $ft9 +-# ASM64: encoding: [0x3a,0xba,0x14,0x01] +-movfr2gr.d $s3, $ft9 +- +-.endif +diff --git a/llvm/test/MC/LoongArch/Basic/Float/f-arith.s b/llvm/test/MC/LoongArch/Basic/Float/f-arith.s +deleted file mode 100644 +index c32151adb..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Float/f-arith.s ++++ /dev/null +@@ -1,102 +0,0 @@ +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +- +-# ASM-AND-OBJ: fadd.s $fs5, $ft7, $fs1 +-# ASM: encoding: [0xfd,0xe5,0x00,0x01] +-fadd.s $fs5, $ft7, $fs1 +- +-# ASM-AND-OBJ: fsub.s $ft6, $fa6, $fs7 +-# ASM: encoding: [0xce,0xfc,0x02,0x01] +-fsub.s $ft6, $fa6, $fs7 +- +-# ASM-AND-OBJ: fmul.s $fa0, $fa7, $ft9 +-# ASM: encoding: [0xe0,0xc4,0x04,0x01] +-fmul.s $fa0, $fa7, $ft9 +- +-# ASM-AND-OBJ: fdiv.s $ft12, $fs0, $ft11 +-# ASM: encoding: [0x14,0xcf,0x06,0x01] +-fdiv.s $ft12, $fs0, $ft11 +- +-# ASM-AND-OBJ: fmadd.s $fa3, $ft8, $fa3, $ft7 +-# ASM: encoding: [0x03,0x8e,0x17,0x08] +-fmadd.s $fa3, $ft8, $fa3, $ft7 +- +-# ASM-AND-OBJ: fmsub.s $ft15, $ft3, $ft13, $fa4 +-# ASM: encoding: [0x77,0x55,0x52,0x08] +-fmsub.s $ft15, $ft3, $ft13, $fa4 +- +-# ASM-AND-OBJ: fnmadd.s $fs5, $fa1, $fs0, $ft12 +-# ASM: encoding: [0x3d,0x60,0x9a,0x08] +-fnmadd.s $fs5, $fa1, $fs0, $ft12 +- +-# ASM-AND-OBJ: fnmsub.s $ft0, $fa4, $fs0, $fs1 +-# ASM: encoding: [0x88,0xe0,0xdc,0x08] +-fnmsub.s $ft0, $fa4, $fs0, $fs1 +- +-# ASM-AND-OBJ: fmax.s $ft14, $fa6, $fs3 +-# ASM: encoding: [0xd6,0xec,0x08,0x01] +-fmax.s $ft14, $fa6, $fs3 +- +-# ASM-AND-OBJ: fmin.s $ft6, $ft2, $ft11 +-# ASM: encoding: [0x4e,0xcd,0x0a,0x01] +-fmin.s $ft6, $ft2, $ft11 +- +-# ASM-AND-OBJ: fmaxa.s $ft1, $fs3, $fs7 +-# ASM: encoding: [0x69,0xff,0x0c,0x01] +-fmaxa.s $ft1, $fs3, $fs7 +- +-# ASM-AND-OBJ: fmina.s $ft7, $ft10, $fa1 +-# ASM: encoding: [0x4f,0x86,0x0e,0x01] +-fmina.s $ft7, $ft10, $fa1 +- +-# ASM-AND-OBJ: fabs.s $fs4, $ft4 +-# ASM: encoding: [0x9c,0x05,0x14,0x01] +-fabs.s $fs4, $ft4 +- +-# ASM-AND-OBJ: fneg.s $ft13, $fs0 +-# ASM: encoding: [0x15,0x17,0x14,0x01] +-fneg.s $ft13, $fs0 +- +-# ASM-AND-OBJ: fsqrt.s $fs3, $ft10 +-# ASM: encoding: [0x5b,0x46,0x14,0x01] +-fsqrt.s $fs3, $ft10 +- +-# ASM-AND-OBJ: frecip.s $ft9, $fs3 +-# ASM: encoding: [0x71,0x57,0x14,0x01] +-frecip.s $ft9, $fs3 +- +-# ASM-AND-OBJ: frecipe.s $fa0, $fa0 +-# ASM: encoding: [0x00,0x74,0x14,0x01] +-frecipe.s $fa0, $fa0 +- +-# ASM-AND-OBJ: frsqrt.s $fs1, $ft4 +-# ASM: encoding: [0x99,0x65,0x14,0x01] +-frsqrt.s $fs1, $ft4 +- +-# ASM-AND-OBJ: frsqrte.s $fa1, $fa1 +-# ASM: encoding: [0x21,0x84,0x14,0x01] +-frsqrte.s $fa1, $fa1 +- +-# ASM-AND-OBJ: fscaleb.s $ft13, $ft15, $fa6 +-# ASM: encoding: [0xf5,0x9a,0x10,0x01] +-fscaleb.s $ft13, $ft15, $fa6 +- +-# ASM-AND-OBJ: flogb.s $fs7, $ft15 +-# ASM: encoding: [0xff,0x26,0x14,0x01] +-flogb.s $fs7, $ft15 +- +-# ASM-AND-OBJ: fcopysign.s $ft5, $fs0, $ft15 +-# ASM: encoding: [0x0d,0xdf,0x12,0x01] +-fcopysign.s $ft5, $fs0, $ft15 +- +-# ASM-AND-OBJ: fclass.s $ft12, $ft1 +-# ASM: encoding: [0x34,0x35,0x14,0x01] +-fclass.s $ft12, $ft1 +diff --git a/llvm/test/MC/LoongArch/Basic/Float/f-bound-check.s b/llvm/test/MC/LoongArch/Basic/Float/f-bound-check.s +deleted file mode 100644 +index 4b56bebf3..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Float/f-bound-check.s ++++ /dev/null +@@ -1,26 +0,0 @@ +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +- +-# ASM-AND-OBJ: fldgt.s $fa3, $s4, $t1 +-# ASM: encoding: [0x63,0x37,0x74,0x38] +-fldgt.s $fa3, $s4, $t1 +- +-# ASM-AND-OBJ: fldle.s $fs0, $s6, $t5 +-# ASM: encoding: [0xb8,0x47,0x75,0x38] +-fldle.s $fs0, $s6, $t5 +- +-# ASM-AND-OBJ: fstgt.s $fs7, $t1, $s7 +-# ASM: encoding: [0xbf,0x79,0x76,0x38] +-fstgt.s $fs7, $t1, $s7 +- +-# ASM-AND-OBJ: fstle.s $ft5, $t1, $a3 +-# ASM: encoding: [0xad,0x1d,0x77,0x38] +-fstle.s $ft5, $t1, $a3 +diff --git a/llvm/test/MC/LoongArch/Basic/Float/f-branch.s b/llvm/test/MC/LoongArch/Basic/Float/f-branch.s +deleted file mode 100644 +index 2ac63cdc7..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Float/f-branch.s ++++ /dev/null +@@ -1,18 +0,0 @@ +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +- +-# ASM-AND-OBJ: bceqz $fcc6, 12 +-# ASM: encoding: [0xc0,0x0c,0x00,0x48] +-bceqz $fcc6, 12 +- +-# ASM-AND-OBJ: bcnez $fcc6, 72 +-# ASM: encoding: [0xc0,0x49,0x00,0x48] +-bcnez $fcc6, 72 +diff --git a/llvm/test/MC/LoongArch/Basic/Float/f-comp.s b/llvm/test/MC/LoongArch/Basic/Float/f-comp.s +deleted file mode 100644 +index 221bea21c..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Float/f-comp.s ++++ /dev/null +@@ -1,98 +0,0 @@ +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +- +-# ASM-AND-OBJ: fcmp.caf.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x10,0x0c] +-fcmp.caf.s $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.cun.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x14,0x0c] +-fcmp.cun.s $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.ceq.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x12,0x0c] +-fcmp.ceq.s $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.cueq.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x16,0x0c] +-fcmp.cueq.s $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.clt.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x11,0x0c] +-fcmp.clt.s $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.cult.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x15,0x0c] +-fcmp.cult.s $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.cle.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x13,0x0c] +-fcmp.cle.s $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.cule.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x17,0x0c] +-fcmp.cule.s $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.cne.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x18,0x0c] +-fcmp.cne.s $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.cor.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x1a,0x0c] +-fcmp.cor.s $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.cune.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x04,0x1c,0x0c] +-fcmp.cune.s $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.saf.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x84,0x10,0x0c] +-fcmp.saf.s $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.sun.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x84,0x14,0x0c] +-fcmp.sun.s $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.seq.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x84,0x12,0x0c] +-fcmp.seq.s $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.sueq.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x84,0x16,0x0c] +-fcmp.sueq.s $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.slt.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x84,0x11,0x0c] +-fcmp.slt.s $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.sult.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x84,0x15,0x0c] +-fcmp.sult.s $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.sle.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x84,0x13,0x0c] +-fcmp.sle.s $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.sule.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x84,0x17,0x0c] +-fcmp.sule.s $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.sne.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x84,0x18,0x0c] +-fcmp.sne.s $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.sor.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x84,0x1a,0x0c] +-fcmp.sor.s $fcc0, $fa0, $fa1 +- +-# ASM-AND-OBJ: fcmp.sune.s $fcc0, $fa0, $fa1 +-# ASM: encoding: [0x00,0x84,0x1c,0x0c] +-fcmp.sune.s $fcc0, $fa0, $fa1 +diff --git a/llvm/test/MC/LoongArch/Basic/Float/f-conv.s b/llvm/test/MC/LoongArch/Basic/Float/f-conv.s +deleted file mode 100644 +index b68c472cd..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Float/f-conv.s ++++ /dev/null +@@ -1,38 +0,0 @@ +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +- +-# ASM-AND-OBJ: ffint.s.w $fs6, $fa5 +-# ASM: encoding: [0xbe,0x10,0x1d,0x01] +-ffint.s.w $fs6, $fa5 +- +-# ASM-AND-OBJ: ftint.w.s $ft13, $ft5 +-# ASM: encoding: [0xb5,0x05,0x1b,0x01] +-ftint.w.s $ft13, $ft5 +- +-# ASM-AND-OBJ: ftintrm.w.s $ft8, $ft8 +-# ASM: encoding: [0x10,0x06,0x1a,0x01] +-ftintrm.w.s $ft8, $ft8 +- +-# ASM-AND-OBJ: ftintrp.w.s $ft6, $fs7 +-# ASM: encoding: [0xee,0x47,0x1a,0x01] +-ftintrp.w.s $ft6, $fs7 +- +-# ASM-AND-OBJ: ftintrz.w.s $fa4, $fs5 +-# ASM: encoding: [0xa4,0x87,0x1a,0x01] +-ftintrz.w.s $fa4, $fs5 +- +-# ASM-AND-OBJ: ftintrne.w.s $fa4, $ft9 +-# ASM: encoding: [0x24,0xc6,0x1a,0x01] +-ftintrne.w.s $fa4, $ft9 +- +-# ASM-AND-OBJ: frint.s $fa5, $ft9 +-# ASM: encoding: [0x25,0x46,0x1e,0x01] +-frint.s $fa5, $ft9 +diff --git a/llvm/test/MC/LoongArch/Basic/Float/f-memory.s b/llvm/test/MC/LoongArch/Basic/Float/f-memory.s +deleted file mode 100644 +index 935deb3eb..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Float/f-memory.s ++++ /dev/null +@@ -1,26 +0,0 @@ +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +- +-# ASM-AND-OBJ: fld.s $ft15, $t3, 250 +-# ASM: encoding: [0xf7,0xe9,0x03,0x2b] +-fld.s $ft15, $t3, 250 +- +-# ASM-AND-OBJ: fst.s $fs6, $t7, 230 +-# ASM: encoding: [0x7e,0x9a,0x43,0x2b] +-fst.s $fs6, $t7, 230 +- +-# ASM-AND-OBJ: fldx.s $fa1, $t3, $t7 +-# ASM: encoding: [0xe1,0x4d,0x30,0x38] +-fldx.s $fa1, $t3, $t7 +- +-# ASM-AND-OBJ: fstx.s $fs2, $sp, $fp +-# ASM: encoding: [0x7a,0x58,0x38,0x38] +-fstx.s $fs2, $sp, $fp +diff --git a/llvm/test/MC/LoongArch/Basic/Float/f-move.s b/llvm/test/MC/LoongArch/Basic/Float/f-move.s +deleted file mode 100644 +index ed6d68f43..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Float/f-move.s ++++ /dev/null +@@ -1,74 +0,0 @@ +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=ASM-AND-OBJ,ASM %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj \ +-# RUN: | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=ASM-AND-OBJ %s +- +-# ASM-AND-OBJ: fmov.s $ft5, $ft15 +-# ASM: encoding: [0xed,0x96,0x14,0x01] +-fmov.s $ft5, $ft15 +- +-# ASM-AND-OBJ: fsel $ft10, $ft12, $ft13, $fcc4 +-# ASM: encoding: [0x92,0x56,0x02,0x0d] +-fsel $ft10, $ft12, $ft13, $fcc4 +- +-# ASM-AND-OBJ: movgr2fr.w $fa6, $tp +-# ASM: encoding: [0x46,0xa4,0x14,0x01] +-movgr2fr.w $fa6, $tp +- +-# ASM-AND-OBJ: movfr2gr.s $a6, $ft14 +-# ASM: encoding: [0xca,0xb6,0x14,0x01] +-movfr2gr.s $a6, $ft14 +- +-# ASM-AND-OBJ: movgr2fcsr $fcsr0, $a0 +-# ASM: encoding: [0x80,0xc0,0x14,0x01] +-movgr2fcsr $fcsr0, $a0 +- +-# ASM-AND-OBJ: movfcsr2gr $a0, $fcsr0 +-# ASM: encoding: [0x04,0xc8,0x14,0x01] +-movfcsr2gr $a0, $fcsr0 +- +-# ASM-AND-OBJ: movgr2fcsr $fcsr1, $a0 +-# ASM: encoding: [0x81,0xc0,0x14,0x01] +-movgr2fcsr $fcsr1, $a0 +- +-# ASM-AND-OBJ: movfcsr2gr $a0, $fcsr1 +-# ASM: encoding: [0x24,0xc8,0x14,0x01] +-movfcsr2gr $a0, $fcsr1 +- +-# ASM-AND-OBJ: movgr2fcsr $fcsr2, $a0 +-# ASM: encoding: [0x82,0xc0,0x14,0x01] +-movgr2fcsr $fcsr2, $a0 +- +-# ASM-AND-OBJ: movfcsr2gr $a0, $fcsr2 +-# ASM: encoding: [0x44,0xc8,0x14,0x01] +-movfcsr2gr $a0, $fcsr2 +- +-# ASM-AND-OBJ: movgr2fcsr $fcsr3, $a0 +-# ASM: encoding: [0x83,0xc0,0x14,0x01] +-movgr2fcsr $fcsr3, $a0 +- +-# ASM-AND-OBJ: movfcsr2gr $a0, $fcsr3 +-# ASM: encoding: [0x64,0xc8,0x14,0x01] +-movfcsr2gr $a0, $fcsr3 +- +-# ASM-AND-OBJ: movfr2cf $fcc4, $ft3 +-# ASM: encoding: [0x64,0xd1,0x14,0x01] +-movfr2cf $fcc4, $ft3 +- +-# ASM-AND-OBJ: movcf2fr $ft8, $fcc0 +-# ASM: encoding: [0x10,0xd4,0x14,0x01] +-movcf2fr $ft8, $fcc0 +- +-# ASM-AND-OBJ: movgr2cf $fcc5, $ra +-# ASM: encoding: [0x25,0xd8,0x14,0x01] +-movgr2cf $fcc5, $ra +- +-# ASM-AND-OBJ: movcf2gr $r21, $fcc7 +-# ASM: encoding: [0xf5,0xdc,0x14,0x01] +-movcf2gr $r21, $fcc7 +diff --git a/llvm/test/MC/LoongArch/Basic/Integer/arith.s b/llvm/test/MC/LoongArch/Basic/Integer/arith.s +deleted file mode 100644 +index bfb3a4c11..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Integer/arith.s ++++ /dev/null +@@ -1,212 +0,0 @@ +-## Test valid arithmetic operation instructions +- +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding --defsym=LA64=1 \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ,CHECK64-ASM,CHECK64-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj --defsym=LA64=1 | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ,CHECK64-ASM-AND-OBJ %s +- +-############################################################# +-## Instructions for both loongarch32 and loongarch64 +-############################################################# +- +-# CHECK-ASM-AND-OBJ: add.w $a5, $ra, $s8 +-# CHECK-ASM: encoding: [0x29,0x7c,0x10,0x00] +-add.w $a5, $ra, $s8 +- +-# CHECK-ASM-AND-OBJ: sub.w $r21, $s2, $t7 +-# CHECK-ASM: encoding: [0x35,0x4f,0x11,0x00] +-sub.w $r21, $s2, $t7 +- +-# CHECK-ASM-AND-OBJ: addi.w $a1, $a3, 246 +-# CHECK-ASM: encoding: [0xe5,0xd8,0x83,0x02] +-addi.w $a1, $a3, 246 +- +-# CHECK-ASM-AND-OBJ: alsl.w $tp, $t5, $tp, 4 +-# CHECK-ASM: encoding: [0x22,0x8a,0x05,0x00] +-alsl.w $tp, $t5, $tp, 4 +- +-# CHECK-ASM-AND-OBJ: lu12i.w $t4, 49 +-# CHECK-ASM: encoding: [0x30,0x06,0x00,0x14] +-lu12i.w $t4, 49 +- +-# CHECK-ASM-AND-OBJ: lu12i.w $a0, -1 +-# CHECK-ASM: encoding: [0xe4,0xff,0xff,0x15] +-lu12i.w $a0, -1 +- +-# CHECK-ASM-AND-OBJ: slt $s6, $s3, $tp +-# CHECK-ASM: encoding: [0x5d,0x0b,0x12,0x00] +-slt $s6, $s3, $tp +- +-# CHECK-ASM-AND-OBJ: sltu $a7, $r21, $s6 +-# CHECK-ASM: encoding: [0xab,0xf6,0x12,0x00] +-sltu $a7, $r21, $s6 +- +-# CHECK-ASM-AND-OBJ: slti $s4, $ra, 235 +-# CHECK-ASM: encoding: [0x3b,0xac,0x03,0x02] +-slti $s4, $ra, 235 +- +-# CHECK-ASM-AND-OBJ: sltui $zero, $a4, 162 +-# CHECK-ASM: encoding: [0x00,0x89,0x42,0x02] +-sltui $zero, $a4, 162 +- +-# CHECK-ASM-AND-OBJ: pcaddi $a5, 187 +-# CHECK-ASM: encoding: [0x69,0x17,0x00,0x18] +-pcaddi $a5, 187 +- +-# CHECK-ASM-AND-OBJ: pcaddu12i $zero, 37 +-# CHECK-ASM: encoding: [0xa0,0x04,0x00,0x1c] +-pcaddu12i $zero, 37 +- +-# CHECK-ASM-AND-OBJ: pcalau12i $a6, 89 +-# CHECK-ASM: encoding: [0x2a,0x0b,0x00,0x1a] +-pcalau12i $a6, 89 +- +-# CHECK-ASM-AND-OBJ: and $t7, $s8, $ra +-# CHECK-ASM: encoding: [0xf3,0x87,0x14,0x00] +-and $t7, $s8, $ra +- +-# CHECK-ASM-AND-OBJ: or $t5, $t4, $s7 +-# CHECK-ASM: encoding: [0x11,0x7a,0x15,0x00] +-or $t5, $t4, $s7 +- +-# CHECK-ASM-AND-OBJ: nor $a1, $t6, $a1 +-# CHECK-ASM: encoding: [0x45,0x16,0x14,0x00] +-nor $a1, $t6, $a1 +- +-# CHECK-ASM-AND-OBJ: xor $t3, $t7, $a4 +-# CHECK-ASM: encoding: [0x6f,0xa2,0x15,0x00] +-xor $t3, $t7, $a4 +- +-# CHECK-ASM-AND-OBJ: andn $s5, $s2, $a1 +-# CHECK-ASM: encoding: [0x3c,0x97,0x16,0x00] +-andn $s5, $s2, $a1 +- +-# CHECK-ASM-AND-OBJ: orn $tp, $sp, $s2 +-# CHECK-ASM: encoding: [0x62,0x64,0x16,0x00] +-orn $tp, $sp, $s2 +- +-# CHECK-ASM-AND-OBJ: andi $s2, $zero, 106 +-# CHECK-ASM: encoding: [0x19,0xa8,0x41,0x03] +-andi $s2, $zero, 106 +- +-# CHECK-ASM-AND-OBJ: ori $t5, $a1, 47 +-# CHECK-ASM: encoding: [0xb1,0xbc,0x80,0x03] +-ori $t5, $a1, 47 +- +-# CHECK-ASM-AND-OBJ: xori $t6, $s0, 99 +-# CHECK-ASM: encoding: [0xf2,0x8e,0xc1,0x03] +-xori $t6, $s0, 99 +- +-# CHECK-ASM-AND-OBJ: mul.w $a0, $t6, $sp +-# CHECK-ASM: encoding: [0x44,0x0e,0x1c,0x00] +-mul.w $a0, $t6, $sp +- +-# CHECK-ASM-AND-OBJ: mulh.w $s4, $s0, $zero +-# CHECK-ASM: encoding: [0xfb,0x82,0x1c,0x00] +-mulh.w $s4, $s0, $zero +- +-# CHECK-ASM-AND-OBJ: mulh.wu $a6, $t5, $s1 +-# CHECK-ASM: encoding: [0x2a,0x62,0x1d,0x00] +-mulh.wu $a6, $t5, $s1 +- +-# CHECK-ASM-AND-OBJ: div.w $s7, $t1, $s2 +-# CHECK-ASM: encoding: [0xbe,0x65,0x20,0x00] +-div.w $s7, $t1, $s2 +- +-# CHECK-ASM-AND-OBJ: mod.w $ra, $s3, $a6 +-# CHECK-ASM: encoding: [0x41,0xab,0x20,0x00] +-mod.w $ra, $s3, $a6 +- +-# CHECK-ASM-AND-OBJ: div.wu $t7, $s0, $zero +-# CHECK-ASM: encoding: [0xf3,0x02,0x21,0x00] +-div.wu $t7, $s0, $zero +- +-# CHECK-ASM-AND-OBJ: mod.wu $s4, $a5, $t5 +-# CHECK-ASM: encoding: [0x3b,0xc5,0x21,0x00] +-mod.wu $s4, $a5, $t5 +- +- +-############################################################# +-## Instructions only for loongarch64 +-############################################################# +- +-.ifdef LA64 +- +-# CHECK64-ASM-AND-OBJ: add.d $tp, $t6, $s4 +-# CHECK64-ASM: encoding: [0x42,0xee,0x10,0x00] +-add.d $tp, $t6, $s4 +- +-# CHECK64-ASM-AND-OBJ: sub.d $a3, $t0, $a3 +-# CHECK64-ASM: encoding: [0x87,0x9d,0x11,0x00] +-sub.d $a3, $t0, $a3 +- +-# CHECK64-ASM-AND-OBJ: addi.d $s5, $a2, 75 +-# CHECK64-ASM: encoding: [0xdc,0x2c,0xc1,0x02] +-addi.d $s5, $a2, 75 +- +-# CHECK64-ASM-AND-OBJ: addu16i.d $a5, $s0, 23 +-# CHECK64-ASM: encoding: [0xe9,0x5e,0x00,0x10] +-addu16i.d $a5, $s0, 23 +- +-# CHECK64-ASM-AND-OBJ: alsl.wu $t7, $a4, $s2, 1 +-# CHECK64-ASM: encoding: [0x13,0x65,0x06,0x00] +-alsl.wu $t7, $a4, $s2, 1 +- +-# CHECK64-ASM-AND-OBJ: alsl.d $t5, $a7, $a1, 3 +-# CHECK64-ASM: encoding: [0x71,0x15,0x2d,0x00] +-alsl.d $t5, $a7, $a1, 3 +- +-# CHECK64-ASM-AND-OBJ: lu32i.d $sp, 196 +-# CHECK64-ASM: encoding: [0x83,0x18,0x00,0x16] +-lu32i.d $sp, 196 +- +-# CHECK64-ASM-AND-OBJ: lu52i.d $t1, $a0, 195 +-# CHECK64-ASM: encoding: [0x8d,0x0c,0x03,0x03] +-lu52i.d $t1, $a0, 195 +- +-# CHECK64-ASM-AND-OBJ: pcaddu18i $t0, 26 +-# CHECK64-ASM: encoding: [0x4c,0x03,0x00,0x1e] +-pcaddu18i $t0, 26 +- +-# CHECK64-ASM-AND-OBJ: mul.d $ra, $t2, $s1 +-# CHECK64-ASM: encoding: [0xc1,0xe1,0x1d,0x00] +-mul.d $ra, $t2, $s1 +- +-# CHECK64-ASM-AND-OBJ: mulh.d $s5, $ra, $s4 +-# CHECK64-ASM: encoding: [0x3c,0x6c,0x1e,0x00] +-mulh.d $s5, $ra, $s4 +- +-# CHECK64-ASM-AND-OBJ: mulh.du $t1, $s4, $s6 +-# CHECK64-ASM: encoding: [0x6d,0xf7,0x1e,0x00] +-mulh.du $t1, $s4, $s6 +- +-# CHECK64-ASM-AND-OBJ: mulw.d.w $s4, $a2, $t5 +-# CHECK64-ASM: encoding: [0xdb,0x44,0x1f,0x00] +-mulw.d.w $s4, $a2, $t5 +- +-# CHECK64-ASM-AND-OBJ: mulw.d.wu $t5, $fp, $s7 +-# CHECK64-ASM: encoding: [0xd1,0xfa,0x1f,0x00] +-mulw.d.wu $t5, $fp, $s7 +- +-# CHECK64-ASM-AND-OBJ: div.d $s0, $a2, $r21 +-# CHECK64-ASM: encoding: [0xd7,0x54,0x22,0x00] +-div.d $s0, $a2, $r21 +- +-# CHECK64-ASM-AND-OBJ: mod.d $t4, $sp, $t3 +-# CHECK64-ASM: encoding: [0x70,0xbc,0x22,0x00] +-mod.d $t4, $sp, $t3 +- +-# CHECK64-ASM-AND-OBJ: div.du $s8, $s1, $t2 +-# CHECK64-ASM: encoding: [0x1f,0x3b,0x23,0x00] +-div.du $s8, $s1, $t2 +- +-# CHECK64-ASM-AND-OBJ: mod.du $s2, $s0, $s1 +-# CHECK64-ASM: encoding: [0xf9,0xe2,0x23,0x00] +-mod.du $s2, $s0, $s1 +- +-.endif +- +diff --git a/llvm/test/MC/LoongArch/Basic/Integer/atomic.s b/llvm/test/MC/LoongArch/Basic/Integer/atomic.s +deleted file mode 100644 +index 69acdeef9..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Integer/atomic.s ++++ /dev/null +@@ -1,289 +0,0 @@ +-## Test valid atomic memory access instructions. +- +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding --defsym=LA64=1 \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ,CHECK64-ASM,CHECK64-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj --defsym=LA64=1 | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ,CHECK64-ASM-AND-OBJ %s +- +-############################################################# +-## Instructions for both loongarch32 and loongarch64 +-############################################################# +- +-# CHECK-ASM-AND-OBJ: ll.w $tp, $s4, 220 +-# CHECK-ASM: encoding: [0x62,0xdf,0x00,0x20] +-ll.w $tp, $s4, 220 +- +-# CHECK-ASM-AND-OBJ: sc.w $t7, $t2, 56 +-# CHECK-ASM: encoding: [0xd3,0x39,0x00,0x21] +-sc.w $t7, $t2, 56 +- +-# CHECK-ASM-AND-OBJ: llacq.w $t1, $t2 +-# CHECK-ASM: encoding: [0xcd,0x81,0x57,0x38] +-llacq.w $t1, $t2 +- +-# CHECK-ASM-AND-OBJ: screl.w $t1, $t2 +-# CHECK-ASM: encoding: [0xcd,0x85,0x57,0x38] +-screl.w $t1, $t2 +- +- +- +-############################################################# +-## Instructions only for loongarch64 +-############################################################# +- +-.ifdef LA64 +- +-# CHECK64-ASM-AND-OBJ: amswap.b $a2, $t0, $s1 +-# CHECK64-ASM: encoding: [0x06,0x33,0x5c,0x38] +-amswap.b $a2, $t0, $s1, 0 +- +-# CHECK64-ASM-AND-OBJ: amswap.h $a2, $t0, $s1 +-# CHECK64-ASM: encoding: [0x06,0xb3,0x5c,0x38] +-amswap.h $a2, $t0, $s1, 0 +- +-# CHECK64-ASM-AND-OBJ: amswap.w $a2, $t0, $s1 +-# CHECK64-ASM: encoding: [0x06,0x33,0x60,0x38] +-amswap.w $a2, $t0, $s1, 0 +- +-# CHECK64-ASM-AND-OBJ: amswap.w $zero, $t0, $zero +-# CHECK64-ASM: encoding: [0x00,0x30,0x60,0x38] +-amswap.w $zero, $t0, $zero +- +-# CHECK64-ASM-AND-OBJ: amadd_db.w $zero, $zero, $a1 +-# CHECK64-ASM: encoding: [0xa0,0x00,0x6a,0x38] +-amadd_db.w $zero, $zero, $a1 +- +-# CHECK64-ASM-AND-OBJ: amswap.b $a2, $t0, $s1 +-# CHECK64-ASM: encoding: [0x06,0x33,0x5c,0x38] +-amswap.b $a2, $t0, $s1 +- +-# CHECK64-ASM-AND-OBJ: amswap.h $a2, $t0, $s1 +-# CHECK64-ASM: encoding: [0x06,0xb3,0x5c,0x38] +-amswap.h $a2, $t0, $s1 +- +-# CHECK64-ASM-AND-OBJ: amswap.w $a2, $t0, $s1 +-# CHECK64-ASM: encoding: [0x06,0x33,0x60,0x38] +-amswap.w $a2, $t0, $s1 +- +-# CHECK64-ASM-AND-OBJ: amswap.d $tp, $t2, $fp +-# CHECK64-ASM: encoding: [0xc2,0xba,0x60,0x38] +-amswap.d $tp, $t2, $fp +- +-# CHECK64-ASM-AND-OBJ: amadd.b $a4, $t0, $r21 +-# CHECK64-ASM: encoding: [0xa8,0x32,0x5d,0x38] +-amadd.b $a4, $t0, $r21 +- +-# CHECK64-ASM-AND-OBJ: amadd.h $a1, $t5, $s6 +-# CHECK64-ASM: encoding: [0xa5,0xc7,0x5d,0x38] +-amadd.h $a1, $t5, $s6 +- +-# CHECK64-ASM-AND-OBJ: amadd.w $a4, $t0, $r21 +-# CHECK64-ASM: encoding: [0xa8,0x32,0x61,0x38] +-amadd.w $a4, $t0, $r21 +- +-# CHECK64-ASM-AND-OBJ: amadd.d $a1, $t5, $s6 +-# CHECK64-ASM: encoding: [0xa5,0xc7,0x61,0x38] +-amadd.d $a1, $t5, $s6 +- +-# CHECK64-ASM-AND-OBJ: amand.w $a0, $t7, $fp +-# CHECK64-ASM: encoding: [0xc4,0x4e,0x62,0x38] +-amand.w $a0, $t7, $fp +- +-# CHECK64-ASM-AND-OBJ: amand.d $a6, $t6, $s6 +-# CHECK64-ASM: encoding: [0xaa,0xcb,0x62,0x38] +-amand.d $a6, $t6, $s6 +- +-# CHECK64-ASM-AND-OBJ: amor.w $a2, $t4, $s0 +-# CHECK64-ASM: encoding: [0xe6,0x42,0x63,0x38] +-amor.w $a2, $t4, $s0 +- +-# CHECK64-ASM-AND-OBJ: amor.d $sp, $t4, $s1 +-# CHECK64-ASM: encoding: [0x03,0xc3,0x63,0x38] +-amor.d $sp, $t4, $s1 +- +-# CHECK64-ASM-AND-OBJ: amxor.w $tp, $t3, $s0 +-# CHECK64-ASM: encoding: [0xe2,0x3e,0x64,0x38] +-amxor.w $tp, $t3, $s0 +- +-# CHECK64-ASM-AND-OBJ: amxor.d $a4, $t8, $s5 +-# CHECK64-ASM: encoding: [0x88,0xd3,0x64,0x38] +-amxor.d $a4, $t8, $s5 +- +-# CHECK64-ASM-AND-OBJ: ammax.w $ra, $a7, $s0 +-# CHECK64-ASM: encoding: [0xe1,0x2e,0x65,0x38] +-ammax.w $ra, $a7, $s0 +- +-# CHECK64-ASM-AND-OBJ: ammax.d $a5, $t8, $s4 +-# CHECK64-ASM: encoding: [0x69,0xd3,0x65,0x38] +-ammax.d $a5, $t8, $s4 +- +-# CHECK64-ASM-AND-OBJ: ammin.w $a5, $t2, $s0 +-# CHECK64-ASM: encoding: [0xe9,0x3a,0x66,0x38] +-ammin.w $a5, $t2, $s0 +- +-# CHECK64-ASM-AND-OBJ: ammin.d $a5, $t1, $fp +-# CHECK64-ASM: encoding: [0xc9,0xb6,0x66,0x38] +-ammin.d $a5, $t1, $fp +- +-# CHECK64-ASM-AND-OBJ: ammax.wu $a5, $a7, $fp +-# CHECK64-ASM: encoding: [0xc9,0x2e,0x67,0x38] +-ammax.wu $a5, $a7, $fp +- +-# CHECK64-ASM-AND-OBJ: ammax.du $a2, $t4, $s2 +-# CHECK64-ASM: encoding: [0x26,0xc3,0x67,0x38] +-ammax.du $a2, $t4, $s2 +- +-# CHECK64-ASM-AND-OBJ: ammin.wu $a4, $t6, $s7 +-# CHECK64-ASM: encoding: [0xc8,0x4b,0x68,0x38] +-ammin.wu $a4, $t6, $s7 +- +-# CHECK64-ASM-AND-OBJ: ammin.du $a3, $t4, $s2 +-# CHECK64-ASM: encoding: [0x27,0xc3,0x68,0x38] +-ammin.du $a3, $t4, $s2 +- +-# CHECK64-ASM-AND-OBJ: amswap_db.b $a2, $t0, $s1 +-# CHECK64-ASM: encoding: [0x06,0x33,0x5e,0x38] +-amswap_db.b $a2, $t0, $s1 +- +-# CHECK64-ASM-AND-OBJ: amswap_db.h $tp, $t2, $fp +-# CHECK64-ASM: encoding: [0xc2,0xba,0x5e,0x38] +-amswap_db.h $tp, $t2, $fp +- +-# CHECK64-ASM-AND-OBJ: amswap_db.w $a2, $t0, $s1 +-# CHECK64-ASM: encoding: [0x06,0x33,0x69,0x38] +-amswap_db.w $a2, $t0, $s1 +- +-# CHECK64-ASM-AND-OBJ: amswap_db.d $tp, $t2, $fp +-# CHECK64-ASM: encoding: [0xc2,0xba,0x69,0x38] +-amswap_db.d $tp, $t2, $fp +- +-# CHECK64-ASM-AND-OBJ: amadd_db.b $zero, $zero, $a1 +-# CHECK64-ASM: encoding: [0xa0,0x00,0x5f,0x38] +-amadd_db.b $zero, $zero, $a1 +- +-# CHECK64-ASM-AND-OBJ: amadd_db.h $a4, $t0, $r21 +-# CHECK64-ASM: encoding: [0xa8,0xb2,0x5f,0x38] +-amadd_db.h $a4, $t0, $r21 +- +-# CHECK64-ASM-AND-OBJ: amadd_db.w $a4, $t0, $r21 +-# CHECK64-ASM: encoding: [0xa8,0x32,0x6a,0x38] +-amadd_db.w $a4, $t0, $r21 +- +-# CHECK64-ASM-AND-OBJ: amadd_db.d $a1, $t5, $s6 +-# CHECK64-ASM: encoding: [0xa5,0xc7,0x6a,0x38] +-amadd_db.d $a1, $t5, $s6 +- +-# CHECK64-ASM-AND-OBJ: amand_db.w $a0, $t7, $fp +-# CHECK64-ASM: encoding: [0xc4,0x4e,0x6b,0x38] +-amand_db.w $a0, $t7, $fp +- +-# CHECK64-ASM-AND-OBJ: amand_db.d $a6, $t6, $s6 +-# CHECK64-ASM: encoding: [0xaa,0xcb,0x6b,0x38] +-amand_db.d $a6, $t6, $s6 +- +-# CHECK64-ASM-AND-OBJ: amor_db.w $a2, $t4, $s0 +-# CHECK64-ASM: encoding: [0xe6,0x42,0x6c,0x38] +-amor_db.w $a2, $t4, $s0 +- +-# CHECK64-ASM-AND-OBJ: amor_db.d $sp, $t4, $s1 +-# CHECK64-ASM: encoding: [0x03,0xc3,0x6c,0x38] +-amor_db.d $sp, $t4, $s1 +- +-# CHECK64-ASM-AND-OBJ: amxor_db.w $tp, $t3, $s0 +-# CHECK64-ASM: encoding: [0xe2,0x3e,0x6d,0x38] +-amxor_db.w $tp, $t3, $s0 +- +-# CHECK64-ASM-AND-OBJ: amxor_db.d $a4, $t8, $s5 +-# CHECK64-ASM: encoding: [0x88,0xd3,0x6d,0x38] +-amxor_db.d $a4, $t8, $s5 +- +-# CHECK64-ASM-AND-OBJ: ammax_db.w $ra, $a7, $s0 +-# CHECK64-ASM: encoding: [0xe1,0x2e,0x6e,0x38] +-ammax_db.w $ra, $a7, $s0 +- +-# CHECK64-ASM-AND-OBJ: ammax_db.d $a5, $t8, $s4 +-# CHECK64-ASM: encoding: [0x69,0xd3,0x6e,0x38] +-ammax_db.d $a5, $t8, $s4 +- +-# CHECK64-ASM-AND-OBJ: ammin_db.w $a5, $t2, $s0 +-# CHECK64-ASM: encoding: [0xe9,0x3a,0x6f,0x38] +-ammin_db.w $a5, $t2, $s0 +- +-# CHECK64-ASM-AND-OBJ: ammin_db.d $a5, $t1, $fp +-# CHECK64-ASM: encoding: [0xc9,0xb6,0x6f,0x38] +-ammin_db.d $a5, $t1, $fp +- +-# CHECK64-ASM-AND-OBJ: ammax_db.wu $a5, $a7, $fp +-# CHECK64-ASM: encoding: [0xc9,0x2e,0x70,0x38] +-ammax_db.wu $a5, $a7, $fp +- +-# CHECK64-ASM-AND-OBJ: ammax_db.du $a2, $t4, $s2 +-# CHECK64-ASM: encoding: [0x26,0xc3,0x70,0x38] +-ammax_db.du $a2, $t4, $s2 +- +-# CHECK64-ASM-AND-OBJ: ammin_db.wu $a4, $t6, $s7 +-# CHECK64-ASM: encoding: [0xc8,0x4b,0x71,0x38] +-ammin_db.wu $a4, $t6, $s7 +- +-# CHECK64-ASM-AND-OBJ: ammin_db.du $a3, $t4, $s2 +-# CHECK64-ASM: encoding: [0x27,0xc3,0x71,0x38] +-ammin_db.du $a3, $t4, $s2 +- +-# CHECK64-ASM-AND-OBJ: amcas.b $t1, $t2, $t3 +-# CHECK64-ASM: encoding: [0xed,0x39,0x58,0x38] +-amcas.b $t1, $t2, $t3 +- +-# CHECK64-ASM-AND-OBJ: amcas.h $t1, $t2, $t3 +-# CHECK64-ASM: encoding: [0xed,0xb9,0x58,0x38] +-amcas.h $t1, $t2, $t3 +- +-# CHECK64-ASM-AND-OBJ: amcas.w $t1, $t2, $t3 +-# CHECK64-ASM: encoding: [0xed,0x39,0x59,0x38] +-amcas.w $t1, $t2, $t3 +- +-# CHECK64-ASM-AND-OBJ: amcas.d $t1, $t2, $t3 +-# CHECK64-ASM: encoding: [0xed,0xb9,0x59,0x38] +-amcas.d $t1, $t2, $t3 +- +-# CHECK64-ASM-AND-OBJ: amcas_db.b $t1, $t2, $t3 +-# CHECK64-ASM: encoding: [0xed,0x39,0x5a,0x38] +-amcas_db.b $t1, $t2, $t3 +- +-# CHECK64-ASM-AND-OBJ: amcas_db.h $t1, $t2, $t3 +-# CHECK64-ASM: encoding: [0xed,0xb9,0x5a,0x38] +-amcas_db.h $t1, $t2, $t3 +- +-# CHECK64-ASM-AND-OBJ: amcas_db.w $t1, $t2, $t3 +-# CHECK64-ASM: encoding: [0xed,0x39,0x5b,0x38] +-amcas_db.w $t1, $t2, $t3 +- +-# CHECK64-ASM-AND-OBJ: amcas_db.d $t1, $t2, $t3 +-# CHECK64-ASM: encoding: [0xed,0xb9,0x5b,0x38] +-amcas_db.d $t1, $t2, $t3 +- +-# CHECK64-ASM-AND-OBJ: ll.d $s2, $s4, 16 +-# CHECK64-ASM: encoding: [0x79,0x13,0x00,0x22] +-ll.d $s2, $s4, 16 +- +-# CHECK64-ASM-AND-OBJ: sc.d $t5, $t5, 244 +-# CHECK64-ASM: encoding: [0x31,0xf6,0x00,0x23] +-sc.d $t5, $t5, 244 +- +-# CHECK64-ASM-AND-OBJ: sc.q $t7, $t2, $t5 +-# CHECK64-ASM: encoding: [0x33,0x3a,0x57,0x38] +-sc.q $t7, $t2, $t5 +- +-# CHECK64-ASM-AND-OBJ: llacq.d $t1, $t2 +-# CHECK64-ASM: encoding: [0xcd,0x89,0x57,0x38] +-llacq.d $t1, $t2 +- +-# CHECK64-ASM-AND-OBJ: screl.d $t1, $t2 +-# CHECK64-ASM: encoding: [0xcd,0x8d,0x57,0x38] +-screl.d $t1, $t2 +- +-.endif +- +diff --git a/llvm/test/MC/LoongArch/Basic/Integer/barrier.s b/llvm/test/MC/LoongArch/Basic/Integer/barrier.s +deleted file mode 100644 +index a9462fc38..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Integer/barrier.s ++++ /dev/null +@@ -1,19 +0,0 @@ +-## Test valid barrier instructions. +- +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ %s +- +-# CHECK-ASM-AND-OBJ: dbar 0 +-# CHECK-ASM: encoding: [0x00,0x00,0x72,0x38] +-dbar 0 +- +-# CHECK-ASM-AND-OBJ: ibar 0 +-# CHECK-ASM: encoding: [0x00,0x80,0x72,0x38] +-ibar 0 +- +diff --git a/llvm/test/MC/LoongArch/Basic/Integer/bit-manipu.s b/llvm/test/MC/LoongArch/Basic/Integer/bit-manipu.s +deleted file mode 100644 +index 3cbe90611..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Integer/bit-manipu.s ++++ /dev/null +@@ -1,136 +0,0 @@ +-## Test valid bit manipulation instructions. +- +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding --defsym=LA64=1 \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ,CHECK64-ASM,CHECK64-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj --defsym=LA64=1 | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ,CHECK64-ASM-AND-OBJ %s +- +-############################################################# +-## Instructions for both loongarch32 and loongarch64 +-############################################################# +- +-# CHECK-ASM: ext.w.b $t8, $t6 +-# CHECK-ASM: encoding: [0x54,0x5e,0x00,0x00] +-ext.w.b $t8, $t6 +- +-# CHECK-ASM: ext.w.h $s0, $s0 +-# CHECK-ASM: encoding: [0xf7,0x5a,0x00,0x00] +-ext.w.h $s0, $s0 +- +-# CHECK-ASM-AND-OBJ: clo.w $ra, $sp +-# CHECK-ASM: encoding: [0x61,0x10,0x00,0x00] +-clo.w $ra, $sp +- +-# CHECK-ASM-AND-OBJ: clz.w $a3, $a6 +-# CHECK-ASM: encoding: [0x47,0x15,0x00,0x00] +-clz.w $a3, $a6 +- +-# CHECK-ASM-AND-OBJ: cto.w $tp, $a2 +-# CHECK-ASM: encoding: [0xc2,0x18,0x00,0x00] +-cto.w $tp, $a2 +- +-# CHECK-ASM-AND-OBJ: ctz.w $a1, $fp +-# CHECK-ASM: encoding: [0xc5,0x1e,0x00,0x00] +-ctz.w $a1, $fp +- +-# CHECK-ASM-AND-OBJ: bytepick.w $s6, $zero, $t4, 0 +-# CHECK-ASM: encoding: [0x1d,0x40,0x08,0x00] +-bytepick.w $s6, $zero, $t4, 0 +- +-# CHECK-ASM-AND-OBJ: revb.2h $t8, $a7 +-# CHECK-ASM: encoding: [0x74,0x31,0x00,0x00] +-revb.2h $t8, $a7 +- +-# CHECK-ASM-AND-OBJ: bitrev.4b $r21, $s4 +-# CHECK-ASM: encoding: [0x75,0x4b,0x00,0x00] +-bitrev.4b $r21, $s4 +- +-# CHECK-ASM-AND-OBJ: bitrev.w $s2, $a1 +-# CHECK-ASM: encoding: [0xb9,0x50,0x00,0x00] +-bitrev.w $s2, $a1 +- +-# CHECK-ASM-AND-OBJ: bstrins.w $a4, $a7, 7, 2 +-# CHECK-ASM: encoding: [0x68,0x09,0x67,0x00] +-bstrins.w $a4, $a7, 7, 2 +- +-# CHECK-ASM-AND-OBJ: bstrpick.w $ra, $a5, 10, 4 +-# CHECK-ASM: encoding: [0x21,0x91,0x6a,0x00] +-bstrpick.w $ra, $a5, 10, 4 +- +-# CHECK-ASM-AND-OBJ: maskeqz $t8, $a7, $t6 +-# CHECK-ASM: encoding: [0x74,0x49,0x13,0x00] +-maskeqz $t8, $a7, $t6 +- +-# CHECK-ASM-AND-OBJ: masknez $t8, $t1, $s3 +-# CHECK-ASM: encoding: [0xb4,0xe9,0x13,0x00] +-masknez $t8, $t1, $s3 +- +- +-############################################################# +-## Instructions only for loongarch64 +-############################################################# +- +-.ifdef LA64 +- +-# CHECK64-ASM-AND-OBJ: clo.d $s6, $ra +-# CHECK64-ASM: encoding: [0x3d,0x20,0x00,0x00] +-clo.d $s6, $ra +- +-# CHECK64-ASM-AND-OBJ: clz.d $s3, $s3 +-# CHECK64-ASM: encoding: [0x5a,0x27,0x00,0x00] +-clz.d $s3, $s3 +- +-# CHECK64-ASM-AND-OBJ: cto.d $t6, $t8 +-# CHECK64-ASM: encoding: [0x92,0x2a,0x00,0x00] +-cto.d $t6, $t8 +- +-# CHECK64-ASM-AND-OBJ: ctz.d $t5, $a6 +-# CHECK64-ASM: encoding: [0x51,0x2d,0x00,0x00] +-ctz.d $t5, $a6 +- +-# CHECK64-ASM-AND-OBJ: bytepick.d $t3, $t5, $t8, 4 +-# CHECK64-ASM: encoding: [0x2f,0x52,0x0e,0x00] +-bytepick.d $t3, $t5, $t8, 4 +- +-# CHECK64-ASM-AND-OBJ: revb.4h $t1, $t7 +-# CHECK64-ASM: encoding: [0x6d,0x36,0x00,0x00] +-revb.4h $t1, $t7 +- +-# CHECK64-ASM-AND-OBJ: revb.2w $s5, $s4 +-# CHECK64-ASM: encoding: [0x7c,0x3b,0x00,0x00] +-revb.2w $s5, $s4 +- +-# CHECK64-ASM-AND-OBJ: revb.d $zero, $s0 +-# CHECK64-ASM: encoding: [0xe0,0x3e,0x00,0x00] +-revb.d $zero, $s0 +- +-# CHECK64-ASM-AND-OBJ: revh.2w $s5, $a6 +-# CHECK64-ASM: encoding: [0x5c,0x41,0x00,0x00] +-revh.2w $s5, $a6 +- +-# CHECK64-ASM-AND-OBJ: revh.d $a5, $a3 +-# CHECK64-ASM: encoding: [0xe9,0x44,0x00,0x00] +-revh.d $a5, $a3 +- +-# CHECK64-ASM-AND-OBJ: bitrev.8b $t1, $s2 +-# CHECK64-ASM: encoding: [0x2d,0x4f,0x00,0x00] +-bitrev.8b $t1, $s2 +- +-# CHECK64-ASM-AND-OBJ: bitrev.d $t7, $s0 +-# CHECK64-ASM: encoding: [0xf3,0x56,0x00,0x00] +-bitrev.d $t7, $s0 +- +-# CHECK64-ASM-AND-OBJ: bstrins.d $a4, $a7, 7, 2 +-# CHECK64-ASM: encoding: [0x68,0x09,0x87,0x00] +-bstrins.d $a4, $a7, 7, 2 +- +-# CHECK64-ASM-AND-OBJ: bstrpick.d $s8, $s4, 39, 22 +-# CHECK64-ASM: encoding: [0x7f,0x5b,0xe7,0x00] +-bstrpick.d $s8, $s4, 39, 22 +- +-.endif +- +diff --git a/llvm/test/MC/LoongArch/Basic/Integer/bit-shift.s b/llvm/test/MC/LoongArch/Basic/Integer/bit-shift.s +deleted file mode 100644 +index 4b8f00a70..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Integer/bit-shift.s ++++ /dev/null +@@ -1,88 +0,0 @@ +-## Test valid bit shift instructions. +- +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding --defsym=LA64=1 \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ,CHECK64-ASM,CHECK64-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj --defsym=LA64=1 | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ,CHECK64-ASM-AND-OBJ %s +- +-############################################################# +-## Instructions for both loongarch32 and loongarch64 +-############################################################# +- +-# CHECK-ASM-AND-OBJ: sll.w $s1, $s4, $s0 +-# CHECK-ASM: encoding: [0x78,0x5f,0x17,0x00] +-sll.w $s1, $s4, $s0 +- +-# CHECK-ASM-AND-OBJ: srl.w $s8, $t5, $a3 +-# CHECK-ASM: encoding: [0x3f,0x9e,0x17,0x00] +-srl.w $s8, $t5, $a3 +- +-# CHECK-ASM-AND-OBJ: sra.w $t0, $s5, $a6 +-# CHECK-ASM: encoding: [0x8c,0x2b,0x18,0x00] +-sra.w $t0, $s5, $a6 +- +-# CHECK-ASM-AND-OBJ: rotr.w $ra, $s3, $t6 +-# CHECK-ASM: encoding: [0x41,0x4b,0x1b,0x00] +-rotr.w $ra, $s3, $t6 +- +-# CHECK-ASM-AND-OBJ: slli.w $s3, $t6, 0 +-# CHECK-ASM: encoding: [0x5a,0x82,0x40,0x00] +-slli.w $s3, $t6, 0 +- +-# CHECK-ASM-AND-OBJ: srli.w $a6, $t2, 30 +-# CHECK-ASM: encoding: [0xca,0xf9,0x44,0x00] +-srli.w $a6, $t2, 30 +- +-# CHECK-ASM-AND-OBJ: srai.w $a4, $t5, 24 +-# CHECK-ASM: encoding: [0x28,0xe2,0x48,0x00] +-srai.w $a4, $t5, 24 +- +-# CHECK-ASM-AND-OBJ: rotri.w $s0, $t8, 23 +-# CHECK-ASM: encoding: [0x97,0xde,0x4c,0x00] +-rotri.w $s0, $t8, 23 +- +- +-############################################################# +-## Instructions only for loongarch64 +-############################################################# +- +-.ifdef LA64 +- +-# CHECK64-ASM-AND-OBJ: sll.d $t8, $t3, $sp +-# CHECK64-ASM: encoding: [0xf4,0x8d,0x18,0x00] +-sll.d $t8, $t3, $sp +- +-# CHECK64-ASM-AND-OBJ: srl.d $t2, $s2, $zero +-# CHECK64-ASM: encoding: [0x2e,0x03,0x19,0x00] +-srl.d $t2, $s2, $zero +- +-# CHECK64-ASM-AND-OBJ: sra.d $a3, $fp, $s8 +-# CHECK64-ASM: encoding: [0xc7,0xfe,0x19,0x00] +-sra.d $a3, $fp, $s8 +- +-# CHECK64-ASM-AND-OBJ: rotr.d $s8, $sp, $ra +-# CHECK64-ASM: encoding: [0x7f,0x84,0x1b,0x00] +-rotr.d $s8, $sp, $ra +- +-# CHECK64-ASM-AND-OBJ: slli.d $a6, $s8, 39 +-# CHECK64-ASM: encoding: [0xea,0x9f,0x41,0x00] +-slli.d $a6, $s8, 39 +- +-# CHECK64-ASM-AND-OBJ: srli.d $s8, $fp, 38 +-# CHECK64-ASM: encoding: [0xdf,0x9a,0x45,0x00] +-srli.d $s8, $fp, 38 +- +-# CHECK64-ASM-AND-OBJ: srai.d $a5, $r21, 27 +-# CHECK64-ASM: encoding: [0xa9,0x6e,0x49,0x00] +-srai.d $a5, $r21, 27 +- +-# CHECK64-ASM-AND-OBJ: rotri.d $s6, $zero, 7 +-# CHECK64-ASM: encoding: [0x1d,0x1c,0x4d,0x00] +-rotri.d $s6, $zero, 7 +- +-.endif +- +diff --git a/llvm/test/MC/LoongArch/Basic/Integer/bound-check.s b/llvm/test/MC/LoongArch/Basic/Integer/bound-check.s +deleted file mode 100644 +index cfb7e4ba8..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Integer/bound-check.s ++++ /dev/null +@@ -1,71 +0,0 @@ +-## Test valid boundary check memory access instructions. +- +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +- +-# CHECK-ASM-AND-OBJ: ldgt.b $a2, $a2, $s6 +-# CHECK-ASM: encoding: [0xc6,0x74,0x78,0x38] +-ldgt.b $a2, $a2, $s6 +- +-# CHECK-ASM-AND-OBJ: ldgt.h $a1, $s8, $ra +-# CHECK-ASM: encoding: [0xe5,0x87,0x78,0x38] +-ldgt.h $a1, $s8, $ra +- +-# CHECK-ASM-AND-OBJ: ldgt.w $t3, $s3, $a4 +-# CHECK-ASM: encoding: [0x4f,0x23,0x79,0x38] +-ldgt.w $t3, $s3, $a4 +- +-# CHECK-ASM-AND-OBJ: ldgt.d $s0, $s2, $s8 +-# CHECK-ASM: encoding: [0x37,0xff,0x79,0x38] +-ldgt.d $s0, $s2, $s8 +- +-# CHECK-ASM-AND-OBJ: ldle.b $a5, $t0, $t3 +-# CHECK-ASM: encoding: [0x89,0x3d,0x7a,0x38] +-ldle.b $a5, $t0, $t3 +- +-# CHECK-ASM-AND-OBJ: ldle.h $a7, $a7, $s0 +-# CHECK-ASM: encoding: [0x6b,0xdd,0x7a,0x38] +-ldle.h $a7, $a7, $s0 +- +-# CHECK-ASM-AND-OBJ: ldle.w $s1, $tp, $tp +-# CHECK-ASM: encoding: [0x58,0x08,0x7b,0x38] +-ldle.w $s1, $tp, $tp +- +-# CHECK-ASM-AND-OBJ: ldle.d $t8, $t3, $t4 +-# CHECK-ASM: encoding: [0xf4,0xc1,0x7b,0x38] +-ldle.d $t8, $t3, $t4 +- +-# CHECK-ASM-AND-OBJ: stgt.b $s4, $t7, $t8 +-# CHECK-ASM: encoding: [0x7b,0x52,0x7c,0x38] +-stgt.b $s4, $t7, $t8 +- +-# CHECK-ASM-AND-OBJ: stgt.h $t4, $a0, $a2 +-# CHECK-ASM: encoding: [0x90,0x98,0x7c,0x38] +-stgt.h $t4, $a0, $a2 +- +-# CHECK-ASM-AND-OBJ: stgt.w $s8, $s5, $t2 +-# CHECK-ASM: encoding: [0x9f,0x3b,0x7d,0x38] +-stgt.w $s8, $s5, $t2 +- +-# CHECK-ASM-AND-OBJ: stgt.d $s7, $r21, $s1 +-# CHECK-ASM: encoding: [0xbe,0xe2,0x7d,0x38] +-stgt.d $s7, $r21, $s1 +- +-# CHECK-ASM-AND-OBJ: stle.b $a6, $a0, $t4 +-# CHECK-ASM: encoding: [0x8a,0x40,0x7e,0x38] +-stle.b $a6, $a0, $t4 +- +-# CHECK-ASM-AND-OBJ: stle.h $t5, $t5, $r21 +-# CHECK-ASM: encoding: [0x31,0xd6,0x7e,0x38] +-stle.h $t5, $t5, $r21 +- +-# CHECK-ASM-AND-OBJ: stle.w $s0, $s5, $s6 +-# CHECK-ASM: encoding: [0x97,0x77,0x7f,0x38] +-stle.w $s0, $s5, $s6 +- +-# CHECK-ASM-AND-OBJ: stle.d $s2, $s1, $s6 +-# CHECK-ASM: encoding: [0x19,0xf7,0x7f,0x38] +-stle.d $s2, $s1, $s6 +- +diff --git a/llvm/test/MC/LoongArch/Basic/Integer/branch.s b/llvm/test/MC/LoongArch/Basic/Integer/branch.s +deleted file mode 100644 +index c4e8edf81..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Integer/branch.s ++++ /dev/null +@@ -1,55 +0,0 @@ +-## Test valid branch instructions. +- +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +- +-# CHECK-ASM-AND-OBJ: beq $a6, $a3, 176 +-# CHECK-ASM: encoding: [0x47,0xb1,0x00,0x58] +-beq $a6, $a3, 176 +- +-# CHECK-ASM-AND-OBJ: bne $s2, $ra, 136 +-# CHECK-ASM: encoding: [0x21,0x8b,0x00,0x5c] +-bne $s2, $ra, 136 +- +-# CHECK-ASM-AND-OBJ: blt $t3, $s7, 168 +-# CHECK-ASM: encoding: [0xfe,0xa9,0x00,0x60] +-blt $t3, $s7, 168 +- +-# CHECK-ASM-AND-OBJ: bge $t0, $t3, 148 +-# CHECK-ASM: encoding: [0x8f,0x95,0x00,0x64] +-bge $t0, $t3, 148 +- +-# CHECK-ASM-AND-OBJ: bltu $t5, $a1, 4 +-# CHECK-ASM: encoding: [0x25,0x06,0x00,0x68] +-bltu $t5, $a1, 4 +- +-# CHECK-ASM-AND-OBJ: bgeu $a2, $s0, 140 +-# CHECK-ASM: encoding: [0xd7,0x8c,0x00,0x6c] +-bgeu $a2, $s0, 140 +- +-# CHECK-ASM-AND-OBJ: beqz $a5, 96 +-# CHECK-ASM: encoding: [0x20,0x61,0x00,0x40] +-beqz $a5, 96 +- +-# CHECK-ASM-AND-OBJ: bnez $sp, 212 +-# CHECK-ASM: encoding: [0x60,0xd4,0x00,0x44] +-bnez $sp, 212 +- +-# CHECK-ASM-AND-OBJ: b 248 +-# CHECK-ASM: encoding: [0x00,0xf8,0x00,0x50] +-b 248 +- +-# CHECK-ASM-AND-OBJ: bl 236 +-# CHECK-ASM: encoding: [0x00,0xec,0x00,0x54] +-bl 236 +- +-# CHECK-ASM-AND-OBJ: jirl $ra, $a0, 4 +-# CHECK-ASM: encoding: [0x81,0x04,0x00,0x4c] +-jirl $ra, $a0, 4 +- +diff --git a/llvm/test/MC/LoongArch/Basic/Integer/crc.s b/llvm/test/MC/LoongArch/Basic/Integer/crc.s +deleted file mode 100644 +index e57134d60..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Integer/crc.s ++++ /dev/null +@@ -1,39 +0,0 @@ +-## Test valid CRC check instructions. +- +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +- +-# CHECK-ASM-AND-OBJ: crc.w.b.w $s1, $a3, $tp +-# CHECK-ASM: encoding: [0xf8,0x08,0x24,0x00] +-crc.w.b.w $s1, $a3, $tp +- +-# CHECK-ASM-AND-OBJ: crc.w.h.w $s8, $a6, $t6 +-# CHECK-ASM: encoding: [0x5f,0xc9,0x24,0x00] +-crc.w.h.w $s8, $a6, $t6 +- +-# CHECK-ASM-AND-OBJ: crc.w.w.w $s5, $a2, $a6 +-# CHECK-ASM: encoding: [0xdc,0x28,0x25,0x00] +-crc.w.w.w $s5, $a2, $a6 +- +-# CHECK-ASM-AND-OBJ: crc.w.d.w $s5, $a7, $s8 +-# CHECK-ASM: encoding: [0x7c,0xfd,0x25,0x00] +-crc.w.d.w $s5, $a7, $s8 +- +-# CHECK-ASM-AND-OBJ: crcc.w.b.w $t3, $t6, $sp +-# CHECK-ASM: encoding: [0x4f,0x0e,0x26,0x00] +-crcc.w.b.w $t3, $t6, $sp +- +-# CHECK-ASM-AND-OBJ: crcc.w.h.w $r21, $s6, $t6 +-# CHECK-ASM: encoding: [0xb5,0xcb,0x26,0x00] +-crcc.w.h.w $r21, $s6, $t6 +- +-# CHECK-ASM-AND-OBJ: crcc.w.w.w $t5, $t2, $t1 +-# CHECK-ASM: encoding: [0xd1,0x35,0x27,0x00] +-crcc.w.w.w $t5, $t2, $t1 +- +-# CHECK-ASM-AND-OBJ: crcc.w.d.w $s7, $r21, $s4 +-# CHECK-ASM: encoding: [0xbe,0xee,0x27,0x00] +-crcc.w.d.w $s7, $r21, $s4 +- +diff --git a/llvm/test/MC/LoongArch/Basic/Integer/invalid-dis.s b/llvm/test/MC/LoongArch/Basic/Integer/invalid-dis.s +deleted file mode 100644 +index 5aa79ca80..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Integer/invalid-dis.s ++++ /dev/null +@@ -1,10 +0,0 @@ +-# Test that disassembler rejects data smaller than 4 bytes. +- +-# RUN: llvm-mc --filetype=obj --triple=loongarch32 < %s \ +-# RUN: | llvm-objdump -d - | FileCheck %s +-# RUN: llvm-mc --filetype=obj --triple=loongarch64 < %s \ +-# RUN: | llvm-objdump -d - | FileCheck %s +- +-# CHECK: 11 +-# CHECK: 22 +-.2byte 0x2211 +diff --git a/llvm/test/MC/LoongArch/Basic/Integer/invalid.s b/llvm/test/MC/LoongArch/Basic/Integer/invalid.s +deleted file mode 100644 +index 958d5cab6..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Integer/invalid.s ++++ /dev/null +@@ -1,193 +0,0 @@ +-## Test invalid instructions on both loongarch32 and loongarch64 target. +- +-# RUN: not llvm-mc --triple=loongarch32 %s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK64 +-# RUN: not llvm-mc --triple=loongarch64 %s 2>&1 --defsym=LA64=1 | FileCheck %s +- +-## Out of range immediates +-## uimm2 +-bytepick.w $a0, $a0, $a0, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 3] +-bytepick.w $a0, $a0, $a0, 4 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 3] +- +-## uimm2_plus1 +-alsl.w $a0, $a0, $a0, 0 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [1, 4] +-alsl.w $a0, $a0, $a0, 5 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [1, 4] +- +-## uimm5 +-slli.w $a0, $a0, -1 +-# CHECK: :[[#@LINE-1]]:18: error: immediate must be an integer in the range [0, 31] +-srli.w $a0, $a0, -1 +-# CHECK: :[[#@LINE-1]]:18: error: immediate must be an integer in the range [0, 31] +-srai.w $a0, $a0, 32 +-# CHECK: :[[#@LINE-1]]:18: error: immediate must be an integer in the range [0, 31] +-rotri.w $a0, $a0, 32 +-# CHECK: :[[#@LINE-1]]:19: error: immediate must be an integer in the range [0, 31] +-bstrins.w $a0, $a0, 31, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +-bstrpick.w $a0, $a0, 32, 0 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +-preld -1, $a0, 0 +-# CHECK: :[[#@LINE-1]]:7: error: immediate must be an integer in the range [0, 31] +-preld 32, $a0, 0 +-# CHECK: :[[#@LINE-1]]:7: error: immediate must be an integer in the range [0, 31] +- +-## uimm12 +-andi $a0, $a0, -1 +-# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [0, 4095] +-xori $a0, $a0, 4096 +-# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [0, 4095] +- +-## uimm12_ori +-ori $a0, $a0, 4096 +-# CHECK: :[[#@LINE-1]]:15: error: operand must be a symbol with modifier (e.g. %abs_lo12) or an integer in the range [0, 4095] +- +-## simm12 +-slti $a0, $a0, -2049 +-# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-2048, 2047] +-sltui $a0, $a0, 2048 +-# CHECK: :[[#@LINE-1]]:17: error: immediate must be an integer in the range [-2048, 2047] +-preld 0, $a0, 2048 +-# CHECK: :[[#@LINE-1]]:15: error: immediate must be an integer in the range [-2048, 2047] +- +-## simm12_addlike +-addi.w $a0, $a0, -2049 +-# CHECK: :[[#@LINE-1]]:18: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] +-ld.b $a0, $a0, 2048 +-# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] +-ld.h $a0, $a0, 2048 +-# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] +-ld.w $a0, $a0, 2048 +-# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] +-ld.bu $a0, $a0, -2049 +-# CHECK: :[[#@LINE-1]]:17: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] +-ld.hu $a0, $a0, -2049 +-# CHECK: :[[#@LINE-1]]:17: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] +-st.b $a0, $a0, 2048 +-# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] +-st.h $a0, $a0, 2048 +-# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] +-st.w $a0, $a0, -2049 +-# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] +- +-## simm14_lsl2 +-ll.w $a0, $a0, -32772 +-# CHECK: :[[#@LINE-1]]:16: error: immediate must be a multiple of 4 in the range [-32768, 32764] +-ll.w $a0, $a0, -32769 +-# CHECK: :[[#@LINE-1]]:16: error: immediate must be a multiple of 4 in the range [-32768, 32764] +-sc.w $a0, $a0, 32767 +-# CHECK: :[[#@LINE-1]]:16: error: immediate must be a multiple of 4 in the range [-32768, 32764] +-sc.w $a0, $a0, 32768 +-# CHECK: :[[#@LINE-1]]:16: error: immediate must be a multiple of 4 in the range [-32768, 32764] +- +-## simm16_lsl2 +-beq $a0, $a0, -0x20004 +-# CHECK: :[[#@LINE-1]]:15: error: operand must be a symbol with modifier (e.g. %b16) or an integer in the range [-131072, 131068] +-bne $a0, $a0, -0x20004 +-# CHECK: :[[#@LINE-1]]:15: error: operand must be a symbol with modifier (e.g. %b16) or an integer in the range [-131072, 131068] +-blt $a0, $a0, -0x1FFFF +-# CHECK: :[[#@LINE-1]]:15: error: operand must be a symbol with modifier (e.g. %b16) or an integer in the range [-131072, 131068] +-bge $a0, $a0, -0x1FFFF +-# CHECK: :[[#@LINE-1]]:15: error: operand must be a symbol with modifier (e.g. %b16) or an integer in the range [-131072, 131068] +-bltu $a0, $a0, 0x1FFFF +-# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %b16) or an integer in the range [-131072, 131068] +-bgeu $a0, $a0, 0x1FFFF +-# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %b16) or an integer in the range [-131072, 131068] +-jirl $a0, $a0, 0x20000 +-# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %b16) or an integer in the range [-131072, 131068] +- +-## simm20 +-pcaddi $a0, -0x80001 +-# CHECK: :[[#@LINE-1]]:13: error: immediate must be an integer in the range [-524288, 524287] +-pcaddu12i $a0, 0x80000 +-# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-524288, 524287] +- +-## simm20_lu12iw +-lu12i.w $a0, -0x80001 +-# CHECK: :[[#@LINE-1]]:14: error: operand must be a symbol with modifier (e.g. %abs_hi20) or an integer in the range [-524288, 524287] +- +-## simm20_pcalau12i +-pcalau12i $a0, 0x80000 +-# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %pc_hi20) or an integer in the range [-524288, 524287] +- +-## simm21_lsl2 +-beqz $a0, -0x400001 +-# CHECK: :[[#@LINE-1]]:11: error: operand must be a symbol with modifier (e.g. %b21) or an integer in the range [-4194304, 4194300] +-bnez $a0, -0x3FFFFF +-# CHECK: :[[#@LINE-1]]:11: error: operand must be a symbol with modifier (e.g. %b21) or an integer in the range [-4194304, 4194300] +-beqz $a0, 0x3FFFFF +-# CHECK: :[[#@LINE-1]]:11: error: operand must be a symbol with modifier (e.g. %b21) or an integer in the range [-4194304, 4194300] +-bnez $a0, 0x400000 +-# CHECK: :[[#@LINE-1]]:11: error: operand must be a symbol with modifier (e.g. %b21) or an integer in the range [-4194304, 4194300] +- +-## simm26_lsl2 +-b -0x8000001 +-# CHECK: :[[#@LINE-1]]:3: error: operand must be a bare symbol name or an immediate must be a multiple of 4 in the range [-134217728, 134217724] +-b 0x1 +-# CHECK: :[[#@LINE-1]]:3: error: operand must be a bare symbol name or an immediate must be a multiple of 4 in the range [-134217728, 134217724] +-bl 0x7FFFFFF +-# CHECK: :[[#@LINE-1]]:4: error: operand must be a bare symbol name or an immediate must be a multiple of 4 in the range [-134217728, 134217724] +-bl 0x8000000 +-# CHECK: :[[#@LINE-1]]:4: error: operand must be a bare symbol name or an immediate must be a multiple of 4 in the range [-134217728, 134217724] +- +-## Invalid mnemonics +-nori $a0, $a0, 0 +-# CHECK: :[[#@LINE-1]]:1: error: unrecognized instruction mnemonic +-andni $a0, $a0, 0 +-# CHECK: :[[#@LINE-1]]:1: error: unrecognized instruction mnemonic +-orni $a0, $a0, 0 +-# CHECK: :[[#@LINE-1]]:1: error: unrecognized instruction mnemonic +- +-## Invalid register names +-add.w $foo, $a0, $a0 +-# CHECK: :[[#@LINE-1]]:8: error: invalid operand for instruction +-sub.w $a8, $a0, $a0 +-# CHECK: :[[#@LINE-1]]:8: error: invalid operand for instruction +-addi.w $x0, $a0, 0 +-# CHECK: :[[#@LINE-1]]:9: error: invalid operand for instruction +-alsl.w $t9, $a0, $a0, 1 +-# CHECK: :[[#@LINE-1]]:9: error: invalid operand for instruction +-lu12i.w $s10, 0 +-# CHECK: :[[#@LINE-1]]:10: error: invalid operand for instruction +- +-.ifndef LA64 +-## LoongArch64 mnemonics +-add.d $a0, $a0, $a0 +-# CHECK64: :[[#@LINE-1]]:1: error: instruction requires the following: LA64 Basic Integer and Privilege Instruction Set +-addi.d $a0, $a0, 0 +-# CHECK64: :[[#@LINE-1]]:1: error: instruction requires the following: LA64 Basic Integer and Privilege Instruction Set +-.endif +- +-## Invalid operand types +-slt $a0, $a0, 0 +-# CHECK: :[[#@LINE-1]]:15: error: invalid operand for instruction +-slti $a0, 0, 0 +-# CHECK: :[[#@LINE-1]]:11: error: invalid operand for instruction +- +-## Too many operands +-andi $a0, $a0, 0, 0 +-# CHECK: :[[#@LINE-1]]:19: error: invalid operand for instruction +- +-## Too few operands +-and $a0, $a0 +-# CHECK: :[[#@LINE-1]]:1: error: too few operands for instruction +-andi $a0, $a0 +-# CHECK: :[[#@LINE-1]]:1: error: too few operands for instruction +- +-## Instructions outside the base integer ISA +-## TODO: Test instructions in LSX/LASX/LBT/LVZ after their introduction. +- +-## Using floating point registers when integer registers are expected +-sll.w $a0, $a0, $fa0 +-# CHECK: :[[#@LINE-1]]:18: error: invalid operand for instruction +- +-## msbw < lsbw +-# CHECK: :[[#@LINE+1]]:21: error: msb is less than lsb +-bstrins.w $a0, $a0, 1, 2 +-# CHECK: ^~~~ +- +-# CHECK: :[[#@LINE+1]]:22: error: msb is less than lsb +-bstrpick.w $a0, $a0, 30, 31 +-# CHECK: ^~~~~~ +diff --git a/llvm/test/MC/LoongArch/Basic/Integer/invalid64.s b/llvm/test/MC/LoongArch/Basic/Integer/invalid64.s +deleted file mode 100644 +index 1c1c658ad..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Integer/invalid64.s ++++ /dev/null +@@ -1,93 +0,0 @@ +-## Test invalid instructions on loongarch64 target. +- +-# RUN: not llvm-mc --triple=loongarch64 %s 2>&1 | FileCheck %s +- +-## Out of range immediates +-## uimm2_plus1 +-alsl.wu $a0, $a0, $a0, 0 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [1, 4] +-alsl.d $a0, $a0, $a0, 5 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [1, 4] +- +-## uimm3 +-bytepick.d $a0, $a0, $a0, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 7] +-bytepick.d $a0, $a0, $a0, 8 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 7] +- +-## uimm6 +-slli.d $a0, $a0, -1 +-# CHECK: :[[#@LINE-1]]:18: error: immediate must be an integer in the range [0, 63] +-srli.d $a0, $a0, -1 +-# CHECK: :[[#@LINE-1]]:18: error: immediate must be an integer in the range [0, 63] +-srai.d $a0, $a0, 64 +-# CHECK: :[[#@LINE-1]]:18: error: immediate must be an integer in the range [0, 63] +-rotri.d $a0, $a0, 64 +-# CHECK: :[[#@LINE-1]]:19: error: immediate must be an integer in the range [0, 63] +-bstrins.d $a0, $a0, 63, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 63] +-bstrpick.d $a0, $a0, 64, 0 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 63] +- +-## simm12_addlike +-addi.d $a0, $a0, -2049 +-# CHECK: :[[#@LINE-1]]:18: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] +-ld.wu $a0, $a0, 2048 +-# CHECK: :[[#@LINE-1]]:17: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] +-ld.d $a0, $a0, 2048 +-# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] +-st.d $a0, $a0, 2048 +-# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] +- +-## simm12_lu52id +-lu52i.d $a0, $a0, 2048 +-# CHECK-LA64: :[[#@LINE-1]]:19: error: operand must be a symbol with modifier (e.g. %pc64_hi12) or an integer in the range [-2048, 2047] +- +-## simm14_lsl2 +-ldptr.w $a0, $a0, -32772 +-# CHECK: :[[#@LINE-1]]:19: error: immediate must be a multiple of 4 in the range [-32768, 32764] +-ldptr.d $a0, $a0, -32772 +-# CHECK: :[[#@LINE-1]]:19: error: immediate must be a multiple of 4 in the range [-32768, 32764] +-stptr.w $a0, $a0, -32769 +-# CHECK: :[[#@LINE-1]]:19: error: immediate must be a multiple of 4 in the range [-32768, 32764] +-stptr.d $a0, $a0, -32769 +-# CHECK: :[[#@LINE-1]]:19: error: immediate must be a multiple of 4 in the range [-32768, 32764] +-ll.w $a0, $a0, 32767 +-# CHECK: :[[#@LINE-1]]:16: error: immediate must be a multiple of 4 in the range [-32768, 32764] +-sc.w $a0, $a0, 32768 +-# CHECK: :[[#@LINE-1]]:16: error: immediate must be a multiple of 4 in the range [-32768, 32764] +- +-## simm16 +-addu16i.d $a0, $a0, -32769 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-32768, 32767] +-addu16i.d $a0, $a0, 32768 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-32768, 32767] +- +-## simm20 +-pcaddu18i $a0, 0x80000 +-# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %call36) or an integer in the range [-524288, 524287] +- +-## simm20_lu32id +-lu32i.d $a0, 0x80000 +-# CHECK-LA64: :[[#@LINE-1]]:14: error: operand must be a symbol with modifier (e.g. %abs64_lo20) or an integer in the range [-524288, 524287] +- +-## msbd < lsbd +-# CHECK: :[[#@LINE+1]]:21: error: msb is less than lsb +-bstrins.d $a0, $a0, 1, 2 +-# CHECK: ^~~~ +- +-# CHECK: :[[#@LINE+1]]:22: error: msb is less than lsb +-bstrpick.d $a0, $a0, 32, 63 +-# CHECK: ^~~~~~ +- +-# CHECK: :[[#@LINE+1]]:10: error: $rd must be different from both $rk and $rj +-amadd.d $a0, $a0, $a0 +-# CHECK: :[[#@LINE+1]]:10: error: $rd must be different from both $rk and $rj +-ammin.w $a0, $a0, $a1 +-# CHECK: :[[#@LINE+1]]:10: error: $rd must be different from both $rk and $rj +-amxor.w $a0, $a1, $a0 +- +-# CHECK: :[[#@LINE+1]]:24: error: expected optional integer offset +-amadd.d $a0, $a1, $a2, $a3 +-# CHECK: :[[#@LINE+1]]:24: error: optional integer offset must be 0 +-amadd.d $a0, $a1, $a2, 1 +diff --git a/llvm/test/MC/LoongArch/Basic/Integer/memory.s b/llvm/test/MC/LoongArch/Basic/Integer/memory.s +deleted file mode 100644 +index 1d363d44d..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Integer/memory.s ++++ /dev/null +@@ -1,132 +0,0 @@ +-## Test valid memory access instructions. +- +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding --defsym=LA64=1 \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ,CHECK64-ASM,CHECK64-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj --defsym=LA64=1 | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ,CHECK64-ASM-AND-OBJ %s +- +-############################################################# +-## Instructions for both loongarch32 and loongarch64 +-############################################################# +- +-# CHECK-ASM-AND-OBJ: ld.b $s1, $a4, 21 +-# CHECK-ASM: encoding: [0x18,0x55,0x00,0x28] +-ld.b $s1, $a4, 21 +- +-# CHECK-ASM-AND-OBJ: ld.h $a3, $t6, 80 +-# CHECK-ASM: encoding: [0x47,0x42,0x41,0x28] +-ld.h $a3, $t6, 80 +- +-# CHECK-ASM-AND-OBJ: ld.w $t6, $s3, 92 +-# CHECK-ASM: encoding: [0x52,0x73,0x81,0x28] +-ld.w $t6, $s3, 92 +- +-# CHECK-ASM-AND-OBJ: ld.bu $t1, $t1, 150 +-# CHECK-ASM: encoding: [0xad,0x59,0x02,0x2a] +-ld.bu $t1, $t1, 150 +- +-# CHECK-ASM-AND-OBJ: ld.hu $t6, $s6, 198 +-# CHECK-ASM: encoding: [0xb2,0x1b,0x43,0x2a] +-ld.hu $t6, $s6, 198 +- +-# CHECK-ASM-AND-OBJ: st.b $sp, $a3, 95 +-# CHECK-ASM: encoding: [0xe3,0x7c,0x01,0x29] +-st.b $sp, $a3, 95 +- +-# CHECK-ASM-AND-OBJ: st.h $s2, $t4, 122 +-# CHECK-ASM: encoding: [0x19,0xea,0x41,0x29] +-st.h $s2, $t4, 122 +- +-# CHECK-ASM-AND-OBJ: st.w $t1, $t1, 175 +-# CHECK-ASM: encoding: [0xad,0xbd,0x82,0x29] +-st.w $t1, $t1, 175 +- +-# CHECK-ASM-AND-OBJ: preld 10, $zero, 23 +-# CHECK-ASM: encoding: [0x0a,0x5c,0xc0,0x2a] +-preld 10, $zero, 23 +- +- +-############################################################# +-## Instructions only for loongarch64 +-############################################################# +- +-.ifdef LA64 +- +-# CHECK64-ASM-AND-OBJ: ld.wu $t2, $t7, 31 +-# CHECK64-ASM: encoding: [0x6e,0x7e,0x80,0x2a] +-ld.wu $t2, $t7, 31 +- +-# CHECK: ld.d $t6, $t8, 159 +-# CHECK: encoding: [0x92,0x7e,0xc2,0x28] +-ld.d $t6, $t8, 159 +- +-# CHECK64-ASM-AND-OBJ: st.d $s7, $s7, 60 +-# CHECK64-ASM: encoding: [0xde,0xf3,0xc0,0x29] +-st.d $s7, $s7, 60 +- +-# CHECK64-ASM-AND-OBJ: ldx.b $s1, $ra, $tp +-# CHECK64-ASM: encoding: [0x38,0x08,0x00,0x38] +-ldx.b $s1, $ra, $tp +- +-# CHECK64-ASM-AND-OBJ: ldx.h $fp, $fp, $t5 +-# CHECK64-ASM: encoding: [0xd6,0x46,0x04,0x38] +-ldx.h $fp, $fp, $t5 +- +-# CHECK64-ASM-AND-OBJ: ldx.w $s2, $a7, $s0 +-# CHECK64-ASM: encoding: [0x79,0x5d,0x08,0x38] +-ldx.w $s2, $a7, $s0 +- +-# CHECK64-ASM-AND-OBJ: ldx.d $t6, $s0, $t8 +-# CHECK64-ASM: encoding: [0xf2,0x52,0x0c,0x38] +-ldx.d $t6, $s0, $t8 +- +-# CHECK64-ASM-AND-OBJ: ldx.bu $a7, $a5, $a5 +-# CHECK64-ASM: encoding: [0x2b,0x25,0x20,0x38] +-ldx.bu $a7, $a5, $a5 +- +-# CHECK64-ASM-AND-OBJ: ldx.hu $fp, $s0, $s4 +-# CHECK64-ASM: encoding: [0xf6,0x6e,0x24,0x38] +-ldx.hu $fp, $s0, $s4 +- +-# CHECK64-ASM-AND-OBJ: ldx.wu $a4, $s1, $s5 +-# CHECK64-ASM: encoding: [0x08,0x73,0x28,0x38] +-ldx.wu $a4, $s1, $s5 +- +-# CHECK64-ASM-AND-OBJ: stx.b $t7, $ra, $sp +-# CHECK64-ASM: encoding: [0x33,0x0c,0x10,0x38] +-stx.b $t7, $ra, $sp +- +-# CHECK64-ASM-AND-OBJ: stx.h $zero, $s5, $s3 +-# CHECK64-ASM: encoding: [0x80,0x6b,0x14,0x38] +-stx.h $zero, $s5, $s3 +- +-# CHECK64-ASM-AND-OBJ: stx.w $a3, $a0, $s8 +-# CHECK64-ASM: encoding: [0x87,0x7c,0x18,0x38] +-stx.w $a3, $a0, $s8 +- +-# CHECK64-ASM-AND-OBJ: stx.d $a3, $s8, $a6 +-# CHECK64-ASM: encoding: [0xe7,0x2b,0x1c,0x38] +-stx.d $a3, $s8, $a6 +- +-# CHECK64-ASM-AND-OBJ: ldptr.w $s3, $a2, 60 +-# CHECK64-ASM: encoding: [0xda,0x3c,0x00,0x24] +-ldptr.w $s3, $a2, 60 +- +-# CHECK64-ASM-AND-OBJ: ldptr.d $a1, $s6, 244 +-# CHECK64-ASM: encoding: [0xa5,0xf7,0x00,0x26] +-ldptr.d $a1, $s6, 244 +- +-# CHECK64-ASM-AND-OBJ: stptr.w $s5, $a1, 216 +-# CHECK64-ASM: encoding: [0xbc,0xd8,0x00,0x25] +-stptr.w $s5, $a1, 216 +- +-# CHECK64-ASM-AND-OBJ: stptr.d $t2, $s1, 196 +-# CHECK64-ASM: encoding: [0x0e,0xc7,0x00,0x27] +-stptr.d $t2, $s1, 196 +- +-.endif +- +diff --git a/llvm/test/MC/LoongArch/Basic/Integer/misc.s b/llvm/test/MC/LoongArch/Basic/Integer/misc.s +deleted file mode 100644 +index 182d1da9b..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Integer/misc.s ++++ /dev/null +@@ -1,56 +0,0 @@ +-## Test valid misc instructions. +- +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding --defsym=LA64=1 \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ,CHECK64-ASM,CHECK64-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj --defsym=LA64=1 | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ,CHECK64-ASM-AND-OBJ %s +- +-############################################################# +-## Instructions for both loongarch32 and loongarch64 +-############################################################# +- +-# CHECK-ASM-AND-OBJ: syscall 100 +-# CHECK-ASM: encoding: [0x64,0x00,0x2b,0x00] +-syscall 100 +- +-# CHECK-ASM-AND-OBJ: break 199 +-# CHECK-ASM: encoding: [0xc7,0x00,0x2a,0x00] +-break 199 +- +-# CHECK-ASM-AND-OBJ: rdtimel.w $s1, $a0 +-# CHECK-ASM: encoding: [0x98,0x60,0x00,0x00] +-rdtimel.w $s1, $a0 +- +-# CHECK-ASM-AND-OBJ: rdtimeh.w $a7, $a1 +-# CHECK-ASM: encoding: [0xab,0x64,0x00,0x00] +-rdtimeh.w $a7, $a1 +- +-# CHECK-ASM-AND-OBJ: cpucfg $sp, $a4 +-# CHECK-ASM: encoding: [0x03,0x6d,0x00,0x00] +-cpucfg $sp, $a4 +- +- +-############################################################# +-## Instructions only for loongarch64 +-############################################################# +- +-.ifdef LA64 +- +-# CHECK64-ASM-AND-OBJ: asrtle.d $t0, $t5 +-# CHECK64-ASM: encoding: [0x80,0x45,0x01,0x00] +-asrtle.d $t0, $t5 +- +-# CHECK64-ASM-AND-OBJ: asrtgt.d $t8, $t8 +-# CHECK64-ASM: encoding: [0x80,0xd2,0x01,0x00] +-asrtgt.d $t8, $t8 +- +-# CHECK64-ASM-AND-OBJ: rdtime.d $tp, $t3 +-# CHECK64-ASM: encoding: [0xe2,0x69,0x00,0x00] +-rdtime.d $tp, $t3 +- +-.endif +- +diff --git a/llvm/test/MC/LoongArch/Basic/Integer/pseudos.s b/llvm/test/MC/LoongArch/Basic/Integer/pseudos.s +deleted file mode 100644 +index e718982f3..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Integer/pseudos.s ++++ /dev/null +@@ -1,18 +0,0 @@ +-## Test valid pseudo instructions +- +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +- +-# CHECK-ASM-AND-OBJ: nop +-# CHECK-ASM: encoding: [0x00,0x00,0x40,0x03] +-nop +- +-# CHECK-ASM-AND-OBJ: move $a4, $a5 +-# CHECK-ASM: encoding: [0x28,0x01,0x15,0x00] +-move $a4, $a5 +diff --git a/llvm/test/MC/LoongArch/Basic/Privilege/invalid.s b/llvm/test/MC/LoongArch/Basic/Privilege/invalid.s +deleted file mode 100644 +index 80d7c3049..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Privilege/invalid.s ++++ /dev/null +@@ -1,18 +0,0 @@ +-# RUN: not llvm-mc --triple=loongarch32 %s 2>&1 | FileCheck %s --check-prefixes=ERR,ERR32 +-# RUN: not llvm-mc --triple=loongarch64 %s 2>&1 | FileCheck %s --check-prefix=ERR +- +-## csrxchg: rj != 0,1 +-csrxchg $a0, $zero, 0 +-# ERR: :[[#@LINE-1]]:15: error: must not be $r0 or $r1 +-csrxchg $a0, $ra, 0 +-# ERR: :[[#@LINE-1]]:15: error: must not be $r0 or $r1 +- +-## LoongArch64 mnemonics +-iocsrrd.d $a0, $a1 +-# ERR32: :[[#@LINE-1]]:1: error: instruction requires the following: LA64 Basic Integer and Privilege Instruction Set +-iocsrwr.d $a0, $a1 +-# ERR32: :[[#@LINE-1]]:1: error: instruction requires the following: LA64 Basic Integer and Privilege Instruction Set +- +-## uimm8 +-lddir $a0, $a0, 0x1ff +-# CHECK: :[[#@LINE-1]]:17: error: immediate must be an integer in the range [0, 255] +diff --git a/llvm/test/MC/LoongArch/Basic/Privilege/valid.s b/llvm/test/MC/LoongArch/Basic/Privilege/valid.s +deleted file mode 100644 +index 1d5ca6866..000000000 +--- a/llvm/test/MC/LoongArch/Basic/Privilege/valid.s ++++ /dev/null +@@ -1,118 +0,0 @@ +-## Test valid privilege instructions +- +-# RUN: llvm-mc %s --triple=loongarch32 --show-encoding \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --show-encoding --defsym=LA64=1 \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ,CHECK64-ASM,CHECK64-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch32 --filetype=obj | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +-# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj --defsym=LA64=1 | llvm-objdump -d - \ +-# RUN: | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ,CHECK64-ASM-AND-OBJ %s +- +-############################################################# +-## Instructions for both loongarch32 and loongarch64 +-############################################################# +- +-# CHECK-ASM-AND-OBJ: csrrd $s3, 30 +-# CHECK-ASM: encoding: [0x1a,0x78,0x00,0x04] +-csrrd $s3, 30 +- +-# CHECK-ASM-AND-OBJ: csrwr $s1, 194 +-# CHECK-ASM: encoding: [0x38,0x08,0x03,0x04] +-csrwr $s1, 194 +- +-# CHECK-ASM-AND-OBJ: csrxchg $a2, $s4, 214 +-# CHECK-ASM: encoding: [0x66,0x5b,0x03,0x04] +-csrxchg $a2, $s4, 214 +- +-# CHECK-ASM-AND-OBJ: iocsrrd.b $s3, $s1 +-# CHECK-ASM: encoding: [0x1a,0x03,0x48,0x06] +-iocsrrd.b $s3, $s1 +- +-# CHECK-ASM-AND-OBJ: iocsrrd.h $a1, $s4 +-# CHECK-ASM: encoding: [0x65,0x07,0x48,0x06] +-iocsrrd.h $a1, $s4 +- +-# CHECK-ASM-AND-OBJ: iocsrrd.w $a6, $t8 +-# CHECK-ASM: encoding: [0x8a,0x0a,0x48,0x06] +-iocsrrd.w $a6, $t8 +- +-# CHECK-ASM-AND-OBJ: iocsrwr.b $a0, $s0 +-# CHECK-ASM: encoding: [0xe4,0x12,0x48,0x06] +-iocsrwr.b $a0, $s0 +- +-# CHECK-ASM-AND-OBJ: iocsrwr.h $a7, $zero +-# CHECK-ASM: encoding: [0x0b,0x14,0x48,0x06] +-iocsrwr.h $a7, $zero +- +-# CHECK-ASM-AND-OBJ: iocsrwr.w $t8, $s3 +-# CHECK-ASM: encoding: [0x54,0x1b,0x48,0x06] +-iocsrwr.w $t8, $s3 +- +-# CHECK-ASM-AND-OBJ: cacop 0, $a6, 27 +-# CHECK-ASM: encoding: [0x40,0x6d,0x00,0x06] +-cacop 0, $a6, 27 +- +-# CHECK-ASM-AND-OBJ: tlbclr +-# CHECK-ASM: encoding: [0x00,0x20,0x48,0x06] +-tlbclr +- +-# CHECK-ASM-AND-OBJ: tlbflush +-# CHECK-ASM: encoding: [0x00,0x24,0x48,0x06] +-tlbflush +- +-# CHECK-ASM-AND-OBJ: tlbsrch +-# CHECK-ASM: encoding: [0x00,0x28,0x48,0x06] +-tlbsrch +- +-# CHECK-ASM-AND-OBJ: tlbrd +-# CHECK-ASM: encoding: [0x00,0x2c,0x48,0x06] +-tlbrd +- +-# CHECK-ASM-AND-OBJ: tlbwr +-# CHECK-ASM: encoding: [0x00,0x30,0x48,0x06] +-tlbwr +- +-# CHECK-ASM-AND-OBJ: tlbfill +-# CHECK-ASM: encoding: [0x00,0x34,0x48,0x06] +-tlbfill +- +-# CHECK-ASM-AND-OBJ: invtlb 16, $s6, $s2 +-# CHECK-ASM: encoding: [0xb0,0xe7,0x49,0x06] +-invtlb 16, $s6, $s2 +- +-# CHECK-ASM-AND-OBJ: lddir $t0, $s7, 92 +-# CHECK-ASM: encoding: [0xcc,0x73,0x41,0x06] +-lddir $t0, $s7, 92 +- +-# CHECK-ASM-AND-OBJ: ldpte $t6, 200 +-# CHECK-ASM: encoding: [0x40,0x22,0x47,0x06] +-ldpte $t6, 200 +- +-# CHECK-ASM-AND-OBJ: ertn +-# CHECK-ASM: encoding: [0x00,0x38,0x48,0x06] +-ertn +- +-# CHECK-ASM-AND-OBJ: dbcl 201 +-# CHECK-ASM: encoding: [0xc9,0x80,0x2a,0x00] +-dbcl 201 +- +-# CHECK-ASM-AND-OBJ: idle 204 +-# CHECK-ASM: encoding: [0xcc,0x80,0x48,0x06] +-idle 204 +- +-############################################################# +-## Instructions only for loongarch64 +-############################################################# +- +-.ifdef LA64 +- +-# CHECK64-ASM-AND-OBJ: iocsrrd.d $t5, $s2 +-# CHECK64-ASM: encoding: [0x31,0x0f,0x48,0x06] +-iocsrrd.d $t5, $s2 +- +-# CHECK64-ASM-AND-OBJ: iocsrwr.d $t8, $a3 +-# CHECK64-ASM: encoding: [0xf4,0x1c,0x48,0x06] +-iocsrwr.d $t8, $a3 +- +-.endif +diff --git a/llvm/test/MC/LoongArch/Directives/cfi.s b/llvm/test/MC/LoongArch/Directives/cfi.s +deleted file mode 100644 +index 7101fc907..000000000 +--- a/llvm/test/MC/LoongArch/Directives/cfi.s ++++ /dev/null +@@ -1,34 +0,0 @@ +-## Test cfi directives. +- +-# RUN: llvm-mc %s --triple=loongarch32 | FileCheck %s +-# RUN: llvm-mc %s --triple=loongarch64 | FileCheck %s +-# RUN: not llvm-mc --triple=loongarch32 --defsym=ERR=1 < %s 2>&1 \ +-# RUN: | FileCheck %s --check-prefix=CHECK-ERR +-# RUN: not llvm-mc --triple=loongarch64 --defsym=ERR=1 < %s 2>&1 \ +-# RUN: | FileCheck %s --check-prefix=CHECK-ERR +- +-# CHECK: .cfi_startproc +-.cfi_startproc +-# CHECK-NEXT: .cfi_offset 0, 0 +-.cfi_offset 0, 0 +-# CHECK-NEXT: .cfi_offset 9, 8 +-.cfi_offset 9, 8 +-# CHECK-NEXT: .cfi_offset 31, 16 +-.cfi_offset 31, 16 +-# CHECK-NEXT: .cfi_endproc +-.cfi_endproc +- +-.ifdef ERR +-.cfi_startproc +-# CHECK-ERR: :[[#@LINE+1]]:13: error: invalid register number +-.cfi_offset -22, -8 +-# CHECK-ERR: :[[#@LINE+1]]:13: error: invalid register number +-.cfi_offset fp, -8 +-# CHECK-ERR: :[[#@LINE+1]]:13: error: invalid register number +-.cfi_offset $22, -8 +-# CHECK-ERR: :[[#@LINE+1]]:13: error: invalid register number +-.cfi_offset $r22, -8 +-# CHECK-ERR: :[[#@LINE+1]]:13: error: invalid register number +-.cfi_offset $fp, -8 +-.cfi_endproc +-.endif +diff --git a/llvm/test/MC/LoongArch/Directives/data.s b/llvm/test/MC/LoongArch/Directives/data.s +deleted file mode 100644 +index e3c66d10b..000000000 +--- a/llvm/test/MC/LoongArch/Directives/data.s ++++ /dev/null +@@ -1,102 +0,0 @@ +-## Test data directives. +-# RUN: llvm-mc --triple=loongarch32 < %s \ +-# RUN: | FileCheck --check-prefix=CHECK-ASM %s +-# RUN: llvm-mc --triple=loongarch64 < %s \ +-# RUN: | FileCheck --check-prefix=CHECK-ASM %s +-# RUN: llvm-mc --triple=loongarch32 --filetype=obj < %s | llvm-objdump -s - \ +-# RUN: | FileCheck --check-prefix=CHECK-DATA %s +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj < %s | llvm-objdump -s - \ +-# RUN: | FileCheck --check-prefix=CHECK-DATA %s +-# RUN: not llvm-mc --triple=loongarch32 --defsym=ERR=1 < %s 2>&1 \ +-# RUN: | FileCheck %s --check-prefix=CHECK-ERR +-# RUN: not llvm-mc --triple=loongarch64 --defsym=ERR=1 < %s 2>&1 \ +-# RUN: | FileCheck %s --check-prefix=CHECK-ERR +- +-.data +- +-# CHECK-ASM: .byte 0 +-# CHECK-ASM-NEXT: .byte 1 +-# CHECK-ASM-NEXT: .byte 171 +-# CHECK-ASM-NEXT: .byte 255 +-# CHECK-DATA: Contents of section .data: +-# CHECK-DATA-NEXT: 0000 0001abff 0100ffff 0100ffff 0100ffff +-.byte 0 +-.byte 1 +-.byte 0xab +-.byte 0xff +- +-# CHECK-ASM: .half 1 +-# CHECK-ASM-NEXT: .half 65535 +-.half 0x1 +-.half 0xffff +- +-# CHECK-ASM: .half 1 +-# CHECK-ASM-NEXT: .half 65535 +-.2byte 0x1 +-.2byte 0xffff +- +-# CHECK-ASM: .half 1 +-# CHECK-ASM-NEXT: .half 65535 +-.short 0x1 +-.short 0xffff +- +-# CHECK-ASM: .half 0 +-# CHECK-ASM-NEXT: .half 1 +-# CHECK-ASM-NEXT: .half 4660 +-# CHECK-ASM-NEXT: .half 65535 +-# CHECK-DATA-NEXT: 0010 00000100 3412ffff 01000000 ffffffff +-.hword 0 +-.hword 0x1 +-.hword 0x1234 +-.hword 0xffff +- +-# CHECK-ASM: .word 1 +-# CHECK-ASM-NEXT: .word 4294967295 +-.word 0x1 +-.word 0xffffffff +- +-# CHECK-ASM: .word 1 +-# CHECK-ASM-NEXT: .word 4294967295 +-# CHECK-DATA-NEXT: 0020 01000000 ffffffff 01000000 ffffffff +-.long 0x1 +-.long 0xffffffff +- +-# CHECK-ASM: .word 1 +-# CHECK-ASM-NEXT: .word 4294967295 +-.4byte 0x1 +-.4byte 0xffffffff +- +-# CHECK-ASM: .dword 1 +-# CHECK-ASM-NEXT: .dword 1234605616436508552 +-# CHECK-DATA-NEXT: 0030 01000000 00000000 88776655 44332211 +-.dword 0x1 +-.dword 0x1122334455667788 +- +-# CHECK-ASM: .dword 1 +-# CHECK-ASM-NEXT: .dword 1234605616436508552 +-# CHECK-DATA-NEXT: 0040 01000000 00000000 88776655 44332211 +-.8byte 0x1 +-.8byte 0x1122334455667788 +- +-.ifdef ERR +-# CHECK-ERR: :[[#@LINE+1]]:7: error: out of range literal value +-.byte 0xffa +-# CHECK-ERR: :[[#@LINE+1]]:7: error: out of range literal value +-.half 0xffffa +-# CHECK-ERR: :[[#@LINE+1]]:8: error: out of range literal value +-.short 0xffffa +-# CHECK-ERR: :[[#@LINE+1]]:8: error: out of range literal value +-.hword 0xffffa +-# CHECK-ERR: :[[#@LINE+1]]:8: error: out of range literal value +-.2byte 0xffffa +-# CHECK-ERR: :[[#@LINE+1]]:7: error: out of range literal value +-.word 0xffffffffa +-# CHECK-ERR: :[[#@LINE+1]]:7: error: out of range literal value +-.long 0xffffffffa +-# CHECK-ERR: :[[#@LINE+1]]:8: error: out of range literal value +-.4byte 0xffffffffa +-# CHECK-ERR: :[[#@LINE+1]]:8: error: literal value out of range for directive +-.dword 0xffffffffffffffffa +-# CHECK-ERR: :[[#@LINE+1]]:8: error: literal value out of range for directive +-.8byte 0xffffffffffffffffa +-.endif +diff --git a/llvm/test/MC/LoongArch/Macros/aliases-br.s b/llvm/test/MC/LoongArch/Macros/aliases-br.s +deleted file mode 100644 +index e8d85bdec..000000000 +--- a/llvm/test/MC/LoongArch/Macros/aliases-br.s ++++ /dev/null +@@ -1,18 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 %s | FileCheck %s +- +-bgt $a1, $a0, 16 +-# CHECK: blt $a0, $a1, 16 +-bgtu $a1, $a0, 16 +-# CHECK-NEXT: bltu $a0, $a1, 16 +-ble $a1, $a0, 16 +-# CHECK-NEXT: bge $a0, $a1, 16 +-bleu $a1, $a0, 16 +-# CHECK-NEXT: bgeu $a0, $a1, 16 +-bltz $a0, 16 +-# CHECK-NEXT: blt $a0, $zero, 16 +-bgtz $a0, 16 +-# CHECK-NEXT: blt $zero, $a0, 16 +-blez $a0, 16 +-# CHECK-NEXT: bge $zero, $a0, 16 +-bgez $a0, 16 +-# CHECK-NEXT: bge $a0, $zero, 16 +diff --git a/llvm/test/MC/LoongArch/Macros/aliases-la-bad.s b/llvm/test/MC/LoongArch/Macros/aliases-la-bad.s +deleted file mode 100644 +index d371ec239..000000000 +--- a/llvm/test/MC/LoongArch/Macros/aliases-la-bad.s ++++ /dev/null +@@ -1,10 +0,0 @@ +-# RUN: not llvm-mc --triple=loongarch64 %s 2>&1 | FileCheck %s +- +-la $a0, $a1, sym +-# CHECK: :[[#@LINE-1]]:10: error: operand must be a bare symbol name +- +-la $a0, 1 +-# CHECK: :[[#@LINE-1]]:9: error: operand must be a bare symbol name +- +-la.global $a0, $a1, 1 +-# CHECK: :[[#@LINE-1]]:21: error: operand must be a bare symbol name +diff --git a/llvm/test/MC/LoongArch/Macros/aliases-la.s b/llvm/test/MC/LoongArch/Macros/aliases-la.s +deleted file mode 100644 +index dd5a4d474..000000000 +--- a/llvm/test/MC/LoongArch/Macros/aliases-la.s ++++ /dev/null +@@ -1,74 +0,0 @@ +-## Test la/la.global/la.local expand to different instructions sequence under +-## different features. +- +-# RUN: llvm-mc --triple=loongarch64 %s \ +-# RUN: | FileCheck %s --check-prefix=NORMAL +-# RUN: llvm-mc --triple=loongarch64 --mattr=+la-global-with-pcrel < %s \ +-# RUN: | FileCheck %s --check-prefix=GTOPCR +-# RUN: llvm-mc --triple=loongarch64 --mattr=+la-global-with-abs < %s \ +-# RUN: | FileCheck %s --check-prefix=GTOABS +-# RUN: llvm-mc --triple=loongarch64 --mattr=+la-local-with-abs < %s \ +-# RUN: | FileCheck %s --check-prefix=LTOABS +- +-la $a0, sym +-# NORMAL: pcalau12i $a0, %got_pc_hi20(sym) +-# NORMAL-NEXT: ld.d $a0, $a0, %got_pc_lo12(sym) +- +-# GTOPCR: pcalau12i $a0, %pc_hi20(sym) +-# GTOPCR-NEXT: addi.d $a0, $a0, %pc_lo12(sym) +- +-# GTOABS: lu12i.w $a0, %abs_hi20(sym) +-# GTOABS-NEXT: ori $a0, $a0, %abs_lo12(sym) +-# GTOABS-NEXT: lu32i.d $a0, %abs64_lo20(sym) +-# GTOABS-NEXT: lu52i.d $a0, $a0, %abs64_hi12(sym) +- +-la.global $a0, sym_global +-# NORMAL: pcalau12i $a0, %got_pc_hi20(sym_global) +-# NORMAL-NEXT: ld.d $a0, $a0, %got_pc_lo12(sym_global) +- +-# GTOPCR: pcalau12i $a0, %pc_hi20(sym_global) +-# GTOPCR-NEXT: addi.d $a0, $a0, %pc_lo12(sym_global) +- +-# GTOABS: lu12i.w $a0, %abs_hi20(sym_global) +-# GTOABS-NEXT: ori $a0, $a0, %abs_lo12(sym_global) +-# GTOABS-NEXT: lu32i.d $a0, %abs64_lo20(sym_global) +-# GTOABS-NEXT: lu52i.d $a0, $a0, %abs64_hi12(sym_global) +- +-la.global $a0, $a1, sym_global_large +-# NORMAL: pcalau12i $a0, %got_pc_hi20(sym_global_large) +-# NORMAL-NEXT: addi.d $a1, $zero, %got_pc_lo12(sym_global_large) +-# NORMAL-NEXT: lu32i.d $a1, %got64_pc_lo20(sym_global_large) +-# NORMAL-NEXT: lu52i.d $a1, $a1, %got64_pc_hi12(sym_global_large) +-# NORMAL-NEXT: ldx.d $a0, $a0, $a1 +- +-# GTOPCR: pcalau12i $a0, %pc_hi20(sym_global_large) +-# GTOPCR-NEXT: addi.d $a1, $zero, %pc_lo12(sym_global_large) +-# GTOPCR-NEXT: lu32i.d $a1, %pc64_lo20(sym_global_large) +-# GTOPCR-NEXT: lu52i.d $a1, $a1, %pc64_hi12(sym_global_large) +-# GTOPCR-NEXT: add.d $a0, $a0, $a1 +- +-# GTOABS: lu12i.w $a0, %abs_hi20(sym_global_large) +-# GTOABS-NEXT: ori $a0, $a0, %abs_lo12(sym_global_large) +-# GTOABS-NEXT: lu32i.d $a0, %abs64_lo20(sym_global_large) +-# GTOABS-NEXT: lu52i.d $a0, $a0, %abs64_hi12(sym_global_large) +- +-la.local $a0, sym_local +-# NORMAL: pcalau12i $a0, %pc_hi20(sym_local) +-# NORMAL-NEXT: addi.d $a0, $a0, %pc_lo12(sym_local) +- +-# LTOABS: lu12i.w $a0, %abs_hi20(sym_local) +-# LTOABS-NEXT: ori $a0, $a0, %abs_lo12(sym_local) +-# LTOABS-NEXT: lu32i.d $a0, %abs64_lo20(sym_local) +-# LTOABS-NEXT: lu52i.d $a0, $a0, %abs64_hi12(sym_local) +- +-la.local $a0, $a1, sym_local_large +-# NORMAL: pcalau12i $a0, %pc_hi20(sym_local_large) +-# NORMAL-NEXT: addi.d $a1, $zero, %pc_lo12(sym_local_large) +-# NORMAL-NEXT: lu32i.d $a1, %pc64_lo20(sym_local_large) +-# NORMAL-NEXT: lu52i.d $a1, $a1, %pc64_hi12(sym_local_large) +-# NORMAL-NEXT: add.d $a0, $a0, $a1 +- +-# LTOABS: lu12i.w $a0, %abs_hi20(sym_local_large) +-# LTOABS-NEXT: ori $a0, $a0, %abs_lo12(sym_local_large) +-# LTOABS-NEXT: lu32i.d $a0, %abs64_lo20(sym_local_large) +-# LTOABS-NEXT: lu52i.d $a0, $a0, %abs64_hi12(sym_local_large) +diff --git a/llvm/test/MC/LoongArch/Macros/macros-call.s b/llvm/test/MC/LoongArch/Macros/macros-call.s +deleted file mode 100644 +index a648a3978..000000000 +--- a/llvm/test/MC/LoongArch/Macros/macros-call.s ++++ /dev/null +@@ -1,9 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 %s | FileCheck %s +- +-call36 sym_call +-# CHECK: pcaddu18i $ra, %call36(sym_call) +-# CHECK-NEXT: jirl $ra, $ra, 0 +- +-tail36 $t0, sym_tail +-# CHECK: pcaddu18i $t0, %call36(sym_tail) +-# CHECK-NEXT: jr $t0 +diff --git a/llvm/test/MC/LoongArch/Macros/macros-la-bad.s b/llvm/test/MC/LoongArch/Macros/macros-la-bad.s +deleted file mode 100644 +index 03c6355e4..000000000 +--- a/llvm/test/MC/LoongArch/Macros/macros-la-bad.s ++++ /dev/null +@@ -1,13 +0,0 @@ +-# RUN: not llvm-mc --triple=loongarch64 %s 2>&1 | FileCheck %s +- +-la.got $a0, 1 +-# CHECK: :[[#@LINE-1]]:13: error: operand must be a bare symbol name +- +-la.pcrel $a0, $a1, 1 +-# CHECK: :[[#@LINE-1]]:20: error: operand must be a bare symbol name +- +-la.abs $a0, $a1, sym +-# CHECK: :[[#@LINE-1]]:14: error: operand must be a bare symbol name +- +-la.pcrel $a0, $a0, sym +-# CHECK: :[[#@LINE-1]]:11: error: $rd must be different from $rj +diff --git a/llvm/test/MC/LoongArch/Macros/macros-la.s b/llvm/test/MC/LoongArch/Macros/macros-la.s +deleted file mode 100644 +index 1a1d12d7d..000000000 +--- a/llvm/test/MC/LoongArch/Macros/macros-la.s ++++ /dev/null +@@ -1,128 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 %s | FileCheck %s +-# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=-relax %s -o %t +-# RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=RELOC +-# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o %t.relax +-# RUN: llvm-readobj -r %t.relax | FileCheck %s --check-prefixes=RELOC,RELAX +- +-# RELOC: Relocations [ +-# RELOC-NEXT: Section ({{.*}}) .rela.text { +- +-la.abs $a0, sym_abs +-# CHECK: lu12i.w $a0, %abs_hi20(sym_abs) +-# CHECK-NEXT: ori $a0, $a0, %abs_lo12(sym_abs) +-# CHECK-NEXT: lu32i.d $a0, %abs64_lo20(sym_abs) +-# CHECK-NEXT: lu52i.d $a0, $a0, %abs64_hi12(sym_abs) +-# CHECK-EMPTY: +-# RELOC-NEXT: R_LARCH_ABS_HI20 sym_abs 0x0 +-# RELOC-NEXT: R_LARCH_ABS_LO12 sym_abs 0x0 +-# RELOC-NEXT: R_LARCH_ABS64_LO20 sym_abs 0x0 +-# RELOC-NEXT: R_LARCH_ABS64_HI12 sym_abs 0x0 +- +-la.pcrel $a0, sym_pcrel +-# CHECK-NEXT: pcalau12i $a0, %pc_hi20(sym_pcrel) +-# CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(sym_pcrel) +-# CHECK-EMPTY: +-# RELOC-NEXT: R_LARCH_PCALA_HI20 sym_pcrel 0x0 +-# RELAX-NEXT: R_LARCH_RELAX - 0x0 +-# RELOC-NEXT: R_LARCH_PCALA_LO12 sym_pcrel 0x0 +-# RELAX-NEXT: R_LARCH_RELAX - 0x0 +- +-la.pcrel $a0, $a1, sym_pcrel_large +-# CHECK-NEXT: pcalau12i $a0, %pc_hi20(sym_pcrel_large) +-# CHECK-NEXT: addi.d $a1, $zero, %pc_lo12(sym_pcrel_large) +-# CHECK-NEXT: lu32i.d $a1, %pc64_lo20(sym_pcrel_large) +-# CHECK-NEXT: lu52i.d $a1, $a1, %pc64_hi12(sym_pcrel_large) +-# CHECK-NEXT: add.d $a0, $a0, $a1 +-# CHECK-EMPTY: +-# RELOC-NEXT: R_LARCH_PCALA_HI20 sym_pcrel_large 0x0 +-# RELOC-NEXT: R_LARCH_PCALA_LO12 sym_pcrel_large 0x0 +-# RELOC-NEXT: R_LARCH_PCALA64_LO20 sym_pcrel_large 0x0 +-# RELOC-NEXT: R_LARCH_PCALA64_HI12 sym_pcrel_large 0x0 +- +-la.got $a0, sym_got +-# CHECK-NEXT: pcalau12i $a0, %got_pc_hi20(sym_got) +-# CHECK-NEXT: ld.d $a0, $a0, %got_pc_lo12(sym_got) +-# CHECK-EMPTY: +-# RELOC-NEXT: R_LARCH_GOT_PC_HI20 sym_got 0x0 +-# RELAX-NEXT: R_LARCH_RELAX - 0x0 +-# RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_got 0x0 +-# RELAX-NEXT: R_LARCH_RELAX - 0x0 +- +-la.got $a0, $a1, sym_got_large +-# CHECK-NEXT: pcalau12i $a0, %got_pc_hi20(sym_got_large) +-# CHECK-NEXT: addi.d $a1, $zero, %got_pc_lo12(sym_got_large) +-# CHECK-NEXT: lu32i.d $a1, %got64_pc_lo20(sym_got_large) +-# CHECK-NEXT: lu52i.d $a1, $a1, %got64_pc_hi12(sym_got_large) +-# CHECK-NEXT: ldx.d $a0, $a0, $a1 +-# CHECK-EMPTY: +-# RELOC-NEXT: R_LARCH_GOT_PC_HI20 sym_got_large 0x0 +-# RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_got_large 0x0 +-# RELOC-NEXT: R_LARCH_GOT64_PC_LO20 sym_got_large 0x0 +-# RELOC-NEXT: R_LARCH_GOT64_PC_HI12 sym_got_large 0x0 +- +-la.tls.le $a0, sym_le +-# CHECK-NEXT: lu12i.w $a0, %le_hi20(sym_le) +-# CHECK-NEXT: ori $a0, $a0, %le_lo12(sym_le) +-# CHECK-EMPTY: +-# RELOC-NEXT: R_LARCH_TLS_LE_HI20 sym_le 0x0 +-# RELOC-NEXT: R_LARCH_TLS_LE_LO12 sym_le 0x0 +- +-la.tls.ie $a0, sym_ie +-# CHECK-NEXT: pcalau12i $a0, %ie_pc_hi20(sym_ie) +-# CHECK-NEXT: ld.d $a0, $a0, %ie_pc_lo12(sym_ie) +-# CHECK-EMPTY: +-# RELOC-NEXT: R_LARCH_TLS_IE_PC_HI20 sym_ie 0x0 +-# RELOC-NEXT: R_LARCH_TLS_IE_PC_LO12 sym_ie 0x0 +- +-la.tls.ie $a0, $a1, sym_ie_large +-# CHECK-NEXT: pcalau12i $a0, %ie_pc_hi20(sym_ie_large) +-# CHECK-NEXT: addi.d $a1, $zero, %ie_pc_lo12(sym_ie_large) +-# CHECK-NEXT: lu32i.d $a1, %ie64_pc_lo20(sym_ie_large) +-# CHECK-NEXT: lu52i.d $a1, $a1, %ie64_pc_hi12(sym_ie_large) +-# CHECK-NEXT: ldx.d $a0, $a0, $a1 +-# CHECK-EMPTY: +-# RELOC-NEXT: R_LARCH_TLS_IE_PC_HI20 sym_ie_large 0x0 +-# RELOC-NEXT: R_LARCH_TLS_IE_PC_LO12 sym_ie_large 0x0 +-# RELOC-NEXT: R_LARCH_TLS_IE64_PC_LO20 sym_ie_large 0x0 +-# RELOC-NEXT: R_LARCH_TLS_IE64_PC_HI12 sym_ie_large 0x0 +- +-la.tls.ld $a0, sym_ld +-# CHECK-NEXT: pcalau12i $a0, %ld_pc_hi20(sym_ld) +-# CHECK-NEXT: addi.d $a0, $a0, %got_pc_lo12(sym_ld) +-# CHECK-EMPTY: +-# RELOC-NEXT: R_LARCH_TLS_LD_PC_HI20 sym_ld 0x0 +-# RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_ld 0x0 +- +-la.tls.ld $a0, $a1, sym_ld_large +-# CHECK-NEXT: pcalau12i $a0, %ld_pc_hi20(sym_ld_large) +-# CHECK-NEXT: addi.d $a1, $zero, %got_pc_lo12(sym_ld_large) +-# CHECK-NEXT: lu32i.d $a1, %got64_pc_lo20(sym_ld_large) +-# CHECK-NEXT: lu52i.d $a1, $a1, %got64_pc_hi12(sym_ld_large) +-# CHECK-NEXT: add.d $a0, $a0, $a1 +-# CHECK-EMPTY: +-# RELOC-NEXT: R_LARCH_TLS_LD_PC_HI20 sym_ld_large 0x0 +-# RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_ld_large 0x0 +-# RELOC-NEXT: R_LARCH_GOT64_PC_LO20 sym_ld_large 0x0 +-# RELOC-NEXT: R_LARCH_GOT64_PC_HI12 sym_ld_large 0x0 +- +-la.tls.gd $a0, sym_gd +-# CHECK-NEXT: pcalau12i $a0, %gd_pc_hi20(sym_gd) +-# CHECK-NEXT: addi.d $a0, $a0, %got_pc_lo12(sym_gd) +-# CHECK-EMPTY: +-# RELOC-NEXT: R_LARCH_TLS_GD_PC_HI20 sym_gd 0x0 +-# RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_gd 0x0 +- +-la.tls.gd $a0, $a1, sym_gd_large +-# CHECK-NEXT: pcalau12i $a0, %gd_pc_hi20(sym_gd_large) +-# CHECK-NEXT: addi.d $a1, $zero, %got_pc_lo12(sym_gd_large) +-# CHECK-NEXT: lu32i.d $a1, %got64_pc_lo20(sym_gd_large) +-# CHECK-NEXT: lu52i.d $a1, $a1, %got64_pc_hi12(sym_gd_large) +-# CHECK-NEXT: add.d $a0, $a0, $a1 +-# CHECK-EMPTY: +-# RELOC-NEXT: R_LARCH_TLS_GD_PC_HI20 sym_gd_large 0x0 +-# RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_gd_large 0x0 +-# RELOC-NEXT: R_LARCH_GOT64_PC_LO20 sym_gd_large 0x0 +-# RELOC-NEXT: R_LARCH_GOT64_PC_HI12 sym_gd_large 0x0 +- +-# RELOC-NEXT: } +-# RELOC-NEXT: ] +diff --git a/llvm/test/MC/LoongArch/Macros/macros-li-bad.s b/llvm/test/MC/LoongArch/Macros/macros-li-bad.s +deleted file mode 100644 +index 194b86bfe..000000000 +--- a/llvm/test/MC/LoongArch/Macros/macros-li-bad.s ++++ /dev/null +@@ -1,7 +0,0 @@ +-# RUN: not llvm-mc --triple=loongarch64 %s 2>&1 | FileCheck %s +- +-li.w $a0, 0x100000000 +-# CHECK: :[[#@LINE-1]]:11: error: operand must be a 32 bit immediate +- +-li.d $a0, 0x10000000000000000 +-# CHECK: :[[#@LINE-1]]:11: error: unknown operand +diff --git a/llvm/test/MC/LoongArch/Macros/macros-li.s b/llvm/test/MC/LoongArch/Macros/macros-li.s +deleted file mode 100644 +index 994aa439e..000000000 +--- a/llvm/test/MC/LoongArch/Macros/macros-li.s ++++ /dev/null +@@ -1,90 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 %s | FileCheck %s +- +-li.w $a0, 0x0 +-# CHECK: ori $a0, $zero, 0 +-li.d $a0, 0x0 +-# CHECK-NEXT: ori $a0, $zero, 0 +- +-li.w $a0, 0xfff +-# CHECK: ori $a0, $zero, 4095 +-li.d $a0, 0xfff +-# CHECK-NEXT: ori $a0, $zero, 4095 +- +-li.w $a0, 0x7ffff000 +-# CHECK: lu12i.w $a0, 524287 +-li.d $a0, 0x7ffff000 +-# CHECK-NEXT: lu12i.w $a0, 524287 +- +-li.w $a0, 0x80000000 +-# CHECK: lu12i.w $a0, -524288 +-li.d $a0, 0x80000000 +-# CHECK-NEXT: lu12i.w $a0, -524288 +-# CHECK-NEXT: lu32i.d $a0, 0 +- +-li.w $a0, 0xfffff800 +-# CHECK: addi.w $a0, $zero, -2048 +-li.d $a0, 0xfffff800 +-# CHECK-NEXT: addi.w $a0, $zero, -2048 +-# CHECK-NEXT: lu32i.d $a0, 0 +- +-li.w $a0, 0xfffffffffffff800 +-# CHECK: addi.w $a0, $zero, -2048 +-li.d $a0, 0xfffffffffffff800 +-# CHECK-NEXT: addi.w $a0, $zero, -2048 +- +-li.w $a0, 0xffffffff80000800 +-# CHECK: lu12i.w $a0, -524288 +-# CHECK-NEXT: ori $a0, $a0, 2048 +-li.d $a0, 0xffffffff80000800 +-# CHECK-NEXT: lu12i.w $a0, -524288 +-# CHECK-NEXT: ori $a0, $a0, 2048 +- +-li.d $a0, 0x7ffff00000800 +-# CHECK: ori $a0, $zero, 2048 +-# CHECK-NEXT: lu32i.d $a0, 524287 +- +-li.d $a0, 0x8000000000fff +-# CHECK: ori $a0, $zero, 4095 +-# CHECK-NEXT: lu32i.d $a0, -524288 +-# CHECK-NEXT: lu52i.d $a0, $a0, 0 +- +-li.d $a0, 0x8000080000800 +-# CHECK: lu12i.w $a0, -524288 +-# CHECK-NEXT: ori $a0, $a0, 2048 +-# CHECK-NEXT: lu32i.d $a0, -524288 +-# CHECK-NEXT: lu52i.d $a0, $a0, 0 +- +-li.d $a0, 0x80000fffff800 +-# CHECK: addi.w $a0, $zero, -2048 +-# CHECK-NEXT: lu32i.d $a0, -524288 +-# CHECK-NEXT: lu52i.d $a0, $a0, 0 +- +-li.d $a0, 0xffffffffff000 +-# CHECK: lu12i.w $a0, -1 +-# CHECK-NEXT: lu52i.d $a0, $a0, 0 +- +-li.d $a0, 0xffffffffff800 +-# CHECK: addi.w $a0, $zero, -2048 +-# CHECK-NEXT: lu52i.d $a0, $a0, 0 +- +-li.d $a0, 0x7ff0000000000000 +-# CHECK: lu52i.d $a0, $zero, 2047 +- +-li.d $a0, 0x7ff0000080000000 +-# CHECK: lu12i.w $a0, -524288 +-# CHECK-NEXT: lu32i.d $a0, 0 +-# CHECK-NEXT: lu52i.d $a0, $a0, 2047 +- +-li.d $a0, 0x7fffffff800007ff +-# CHECK: lu12i.w $a0, -524288 +-# CHECK-NEXT: ori $a0, $a0, 2047 +-# CHECK-NEXT: lu52i.d $a0, $a0, 2047 +- +-li.d $a0, 0xfff0000000000fff +-# CHECK: ori $a0, $zero, 4095 +-# CHECK-NEXT: lu52i.d $a0, $a0, -1 +- +-li.d $a0, 0xffffffff7ffff800 +-# CHECK: lu12i.w $a0, 524287 +-# CHECK-NEXT: ori $a0, $a0, 2048 +-# CHECK-NEXT: lu32i.d $a0, -1 +diff --git a/llvm/test/MC/LoongArch/Misc/aligned-nops.s b/llvm/test/MC/LoongArch/Misc/aligned-nops.s +deleted file mode 100644 +index 8554b4998..000000000 +--- a/llvm/test/MC/LoongArch/Misc/aligned-nops.s ++++ /dev/null +@@ -1,15 +0,0 @@ +-# RUN: llvm-mc --filetype=obj --triple=loongarch64 < %s \ +-# RUN: | llvm-objdump -d - | FileCheck %s +- +-# func1 and func2 are 8 byte alignment but the func1's size is 4. +-# So assembler will insert a nop to make sure 8 byte alignment. +- +-.text +- +-.p2align 3 +-func1: +- addi.d $sp, $sp, -16 +-# CHECK: addi.d $sp, $sp, -16 +-# CHECK-NEXT: nop +-.p2align 3 +-func2: +diff --git a/llvm/test/MC/LoongArch/Misc/cfi-advance.s b/llvm/test/MC/LoongArch/Misc/cfi-advance.s +deleted file mode 100644 +index 662c43e6b..000000000 +--- a/llvm/test/MC/LoongArch/Misc/cfi-advance.s ++++ /dev/null +@@ -1,27 +0,0 @@ +-# RUN: llvm-mc --filetype=obj --triple=loongarch64 -mattr=-relax %s -o %t.o +-# RUN: llvm-readobj -r %t.o | FileCheck --check-prefix=RELOC %s +-# RUN: llvm-dwarfdump --debug-frame %t.o | FileCheck --check-prefix=DWARFDUMP %s +- +-# RELOC: Relocations [ +-# RELOC-NEXT: .rela.eh_frame { +-# RELOC-NEXT: 0x1C R_LARCH_32_PCREL .text 0x0 +-# RELOC-NEXT: } +-# RELOC-NEXT: ] +-# DWARFDUMP: DW_CFA_advance_loc: 4 +-# DWARFDUMP-NEXT: DW_CFA_def_cfa_offset: +8 +-# DWARFDUMP-NEXT: DW_CFA_advance_loc: 8 +-# DWARFDUMP-NEXT: DW_CFA_def_cfa_offset: +8 +- +- .text +- .globl test +- .p2align 2 +- .type test,@function +-test: +- .cfi_startproc +- nop +- .cfi_def_cfa_offset 8 +- .p2align 3 +- nop +- .cfi_def_cfa_offset 8 +- nop +- .cfi_endproc +diff --git a/llvm/test/MC/LoongArch/Misc/numeric-reg-names.s b/llvm/test/MC/LoongArch/Misc/numeric-reg-names.s +deleted file mode 100644 +index b724e4742..000000000 +--- a/llvm/test/MC/LoongArch/Misc/numeric-reg-names.s ++++ /dev/null +@@ -1,64 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch32 --mattr=+f --loongarch-numeric-reg %s \ +-# RUN: | FileCheck %s +-# RUN: llvm-mc --triple=loongarch32 --mattr=+f -M numeric %s \ +-# RUN: | FileCheck %s +-# RUN: llvm-mc --triple=loongarch32 --mattr=+f --filetype=obj %s -o %t.32 +-# RUN: llvm-objdump -d -M numeric %t.32 | FileCheck %s +-# RUN: llvm-mc --triple=loongarch64 --mattr=+f --loongarch-numeric-reg %s \ +-# RUN: | FileCheck %s +-# RUN: llvm-mc --triple=loongarch64 --mattr=+f -M numeric %s \ +-# RUN: | FileCheck %s +-# RUN: llvm-mc --triple=loongarch64 --mattr=+f --filetype=obj %s -o %t.64 +-# RUN: llvm-objdump -d -M numeric %t.64 | FileCheck %s +- +-addi.w $zero, $ra, 1 +-addi.w $tp, $sp, 1 +-addi.w $a0, $a1, 1 +-addi.w $a2, $a3, 1 +-addi.w $a4, $a5, 1 +-addi.w $a6, $a7, 1 +-addi.w $t0, $t1, 1 +-addi.w $t2, $t3, 1 +-addi.w $t4, $t5, 1 +-addi.w $t6, $t7, 1 +-addi.w $t8, $r21, 1 +-addi.w $fp, $s0, 1 +-addi.w $s1, $s2, 1 +-addi.w $s3, $s4, 1 +-addi.w $s5, $s6, 1 +-addi.w $s7, $s8, 1 +- +-# CHECK: addi.w $r0, $r1, 1 +-# CHECK-NEXT: addi.w $r2, $r3, 1 +-# CHECK-NEXT: addi.w $r4, $r5, 1 +-# CHECK-NEXT: addi.w $r6, $r7, 1 +-# CHECK-NEXT: addi.w $r8, $r9, 1 +-# CHECK-NEXT: addi.w $r10, $r11, 1 +-# CHECK-NEXT: addi.w $r12, $r13, 1 +-# CHECK-NEXT: addi.w $r14, $r15, 1 +-# CHECK-NEXT: addi.w $r16, $r17, 1 +-# CHECK-NEXT: addi.w $r18, $r19, 1 +-# CHECK-NEXT: addi.w $r20, $r21, 1 +-# CHECK-NEXT: addi.w $r22, $r23, 1 +-# CHECK-NEXT: addi.w $r24, $r25, 1 +-# CHECK-NEXT: addi.w $r26, $r27, 1 +-# CHECK-NEXT: addi.w $r28, $r29, 1 +-# CHECK-NEXT: addi.w $r30, $r31, 1 +- +-fmadd.s $fa0, $fa1, $fa2, $fa3 +-fmadd.s $fa4, $fa5, $fa6, $fa7 +-fmadd.s $ft0, $ft1, $ft2, $ft3 +-fmadd.s $ft4, $ft5, $ft6, $ft7 +-fmadd.s $ft8, $ft9, $ft10, $ft11 +-fmadd.s $ft12, $ft13, $ft14, $ft15 +-fmadd.s $fs0, $fs1, $fs2, $fs3 +-fmadd.s $fs4, $fs5, $fs6, $fs7 +- +-# CHECK: fmadd.s $f0, $f1, $f2, $f3 +-# CHECK-NEXT: fmadd.s $f4, $f5, $f6, $f7 +-# CHECK-NEXT: fmadd.s $f8, $f9, $f10, $f11 +-# CHECK-NEXT: fmadd.s $f12, $f13, $f14, $f15 +-# CHECK-NEXT: fmadd.s $f16, $f17, $f18, $f19 +-# CHECK-NEXT: fmadd.s $f20, $f21, $f22, $f23 +-# CHECK-NEXT: fmadd.s $f24, $f25, $f26, $f27 +-# CHECK-NEXT: fmadd.s $f28, $f29, $f30, $f31 +diff --git a/llvm/test/MC/LoongArch/Misc/subsection.s b/llvm/test/MC/LoongArch/Misc/subsection.s +deleted file mode 100644 +index 566a2408d..000000000 +--- a/llvm/test/MC/LoongArch/Misc/subsection.s ++++ /dev/null +@@ -1,38 +0,0 @@ +-# RUN: not llvm-mc --filetype=obj --triple=loongarch64 --mattr=-relax %s -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERR,NORELAX --implicit-check-not=error: +-# RUN: not llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERR,RELAX --implicit-check-not=error: +- +-a: +- nop +-b: +- la.pcrel $t0, a +-c: +- nop +-d: +- +-.data +-## Positive subsection numbers +-## With relaxation, report an error as c-b is not an assemble-time constant. +-# RELAX: :[[#@LINE+1]]:14: error: cannot evaluate subsection number +-.subsection c-b +-# RELAX: :[[#@LINE+1]]:14: error: cannot evaluate subsection number +-.subsection d-b +-# RELAX: :[[#@LINE+1]]:14: error: cannot evaluate subsection number +-.subsection c-a +- +-.subsection b-a +-.subsection d-c +- +-## Negative subsection numbers +-# NORELAX: :[[#@LINE+2]]:14: error: subsection number -8 is not within [0,2147483647] +-# RELAX: :[[#@LINE+1]]:14: error: cannot evaluate subsection number +-.subsection b-c +-# NORELAX: :[[#@LINE+2]]:14: error: subsection number -12 is not within [0,2147483647] +-# RELAX: :[[#@LINE+1]]:14: error: cannot evaluate subsection number +-.subsection b-d +-# NORELAX: :[[#@LINE+2]]:14: error: subsection number -12 is not within [0,2147483647] +-# RELAX: :[[#@LINE+1]]:14: error: cannot evaluate subsection number +-.subsection a-c +-# ERR: :[[#@LINE+1]]:14: error: subsection number -4 is not within [0,2147483647] +-.subsection a-b +-# ERR: :[[#@LINE+1]]:14: error: subsection number -4 is not within [0,2147483647] +-.subsection c-d +diff --git a/llvm/test/MC/LoongArch/Misc/tls-symbols.s b/llvm/test/MC/LoongArch/Misc/tls-symbols.s +deleted file mode 100644 +index 2f91cbe00..000000000 +--- a/llvm/test/MC/LoongArch/Misc/tls-symbols.s ++++ /dev/null +@@ -1,79 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s -o %t +-# RUN: llvm-readobj -s %t | FileCheck %s +- +-lu12i.w $a1, %gd_hi20(gd_abs) +-# CHECK: Symbol { +-# CHECK: Name: gd_abs +-# CHECK-NEXT: Value: 0x0 +-# CHECK-NEXT: Size: 0 +-# CHECK-NEXT: Binding: Global +-# CHECK-NEXT: Type: TLS +-# CHECK-NEXT: Other: 0 +-# CHECK-NEXT: Section: Undefined +-# CHECK-NEXT: } +- +-pcalau12i $a1, %gd_pc_hi20(gd_pcrel) +-# CHECK-NEXT: Symbol { +-# CHECK-NEXT: Name: gd_pcrel +-# CHECK-NEXT: Value: 0x0 +-# CHECK-NEXT: Size: 0 +-# CHECK-NEXT: Binding: Global +-# CHECK-NEXT: Type: TLS +-# CHECK-NEXT: Other: 0 +-# CHECK-NEXT: Section: Undefined +-# CHECK-NEXT: } +- +-lu12i.w $a1, %ld_hi20(ld_abs) +-# CHECK-NEXT: Symbol { +-# CHECK-NEXT: Name: ld_abs +-# CHECK-NEXT: Value: 0x0 +-# CHECK-NEXT: Size: 0 +-# CHECK-NEXT: Binding: Global +-# CHECK-NEXT: Type: TLS +-# CHECK-NEXT: Other: 0 +-# CHECK-NEXT: Section: Undefined +-# CHECK-NEXT: } +- +-pcalau12i $a1, %ld_pc_hi20(ld_pcrel) +-# CHECK-NEXT: Symbol { +-# CHECK-NEXT: Name: ld_pcrel +-# CHECK-NEXT: Value: 0x0 +-# CHECK-NEXT: Size: 0 +-# CHECK-NEXT: Binding: Global +-# CHECK-NEXT: Type: TLS +-# CHECK-NEXT: Other: 0 +-# CHECK-NEXT: Section: Undefined +-# CHECK-NEXT: } +- +-lu12i.w $a1, %ie_hi20(ie_abs) +-# CHECK-NEXT: Symbol { +-# CHECK-NEXT: Name: ie_abs +-# CHECK-NEXT: Value: 0x0 +-# CHECK-NEXT: Size: 0 +-# CHECK-NEXT: Binding: Global +-# CHECK-NEXT: Type: TLS +-# CHECK-NEXT: Other: 0 +-# CHECK-NEXT: Section: Undefined +-# CHECK-NEXT: } +- +-pcalau12i $a1, %ie_pc_hi20(ie_pcrel) +-# CHECK-NEXT: Symbol { +-# CHECK-NEXT: Name: ie_pcrel +-# CHECK-NEXT: Value: 0x0 +-# CHECK-NEXT: Size: 0 +-# CHECK-NEXT: Binding: Global +-# CHECK-NEXT: Type: TLS +-# CHECK-NEXT: Other: 0 +-# CHECK-NEXT: Section: Undefined +-# CHECK-NEXT: } +- +-lu12i.w $a1, %le_hi20(le) +-# CHECK-NEXT: Symbol { +-# CHECK-NEXT: Name: le +-# CHECK-NEXT: Value: 0x0 +-# CHECK-NEXT: Size: 0 +-# CHECK-NEXT: Binding: Global +-# CHECK-NEXT: Type: TLS +-# CHECK-NEXT: Other: 0 +-# CHECK-NEXT: Section: Undefined +-# CHECK-NEXT: } +diff --git a/llvm/test/MC/LoongArch/Misc/unaligned-nops.s b/llvm/test/MC/LoongArch/Misc/unaligned-nops.s +deleted file mode 100644 +index 5a515dc9e..000000000 +--- a/llvm/test/MC/LoongArch/Misc/unaligned-nops.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s -o %t +-# RUN: llvm-objdump -d %t | FileCheck %s +- +-# CHECK: 01 00 00 00 +-# CHECK-NEXT: 00 00 40 03 nop +-.byte 1 +-.p2align 3 +-foo: +diff --git a/llvm/test/MC/LoongArch/Relocations/align-non-executable.s b/llvm/test/MC/LoongArch/Relocations/align-non-executable.s +deleted file mode 100644 +index 47834acd9..000000000 +--- a/llvm/test/MC/LoongArch/Relocations/align-non-executable.s ++++ /dev/null +@@ -1,27 +0,0 @@ +-## A label difference separated by an alignment directive, when the +-## referenced symbols are in a non-executable section with instructions, +-## should generate ADD/SUB relocations. +-## https://github.com/llvm/llvm-project/pull/76552 +- +-# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s \ +-# RUN: | llvm-readobj -r - | FileCheck --check-prefixes=CHECK,RELAX %s +-# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=-relax %s \ +-# RUN: | llvm-readobj -r - | FileCheck %s +- +-.section ".dummy", "a" +-.L1: +- la.pcrel $t0, sym +-.p2align 3 +-.L2: +-.dword .L2 - .L1 +- +-# CHECK: Relocations [ +-# CHECK-NEXT: Section ({{.*}}) .rela.dummy { +-# CHECK-NEXT: 0x0 R_LARCH_PCALA_HI20 sym 0x0 +-# RELAX-NEXT: 0x0 R_LARCH_RELAX - 0x0 +-# CHECK-NEXT: 0x4 R_LARCH_PCALA_LO12 sym 0x0 +-# RELAX-NEXT: 0x4 R_LARCH_RELAX - 0x0 +-# RELAX-NEXT: 0x8 R_LARCH_ADD64 .L2 0x0 +-# RELAX-NEXT: 0x8 R_LARCH_SUB64 .L1 0x0 +-# CHECK-NEXT: } +-# CHECK-NEXT: ] +diff --git a/llvm/test/MC/LoongArch/Relocations/fde-reloc.s b/llvm/test/MC/LoongArch/Relocations/fde-reloc.s +deleted file mode 100644 +index 990e07c7f..000000000 +--- a/llvm/test/MC/LoongArch/Relocations/fde-reloc.s ++++ /dev/null +@@ -1,14 +0,0 @@ +-# RUN: llvm-mc --filetype=obj --triple=loongarch64 < %s \ +-# RUN: | llvm-readobj -r - | FileCheck %s +- +-## Ensure that the eh_frame records the symbolic difference with +-## the R_LARCH_32_PCREL relocation. +- +-func: +- .cfi_startproc +- ret +- .cfi_endproc +- +-# CHECK: Section (4) .rela.eh_frame { +-# CHECK-NEXT: 0x1C R_LARCH_32_PCREL .text 0x0 +-# CHECK-NEXT: } +diff --git a/llvm/test/MC/LoongArch/Relocations/fixups-diagnostics.s b/llvm/test/MC/LoongArch/Relocations/fixups-diagnostics.s +deleted file mode 100644 +index c72eef7cd..000000000 +--- a/llvm/test/MC/LoongArch/Relocations/fixups-diagnostics.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: not llvm-mc --triple=loongarch64 --filetype=obj %s -o /dev/null 2>&1 | FileCheck %s +- +- beq $a0, $a1, unaligned # CHECK: :[[#@LINE]]:3: error: fixup value must be 4-byte aligned +- beqz $a0, unaligned # CHECK: :[[#@LINE]]:3: error: fixup value must be 4-byte aligned +- b unaligned # CHECK: :[[#@LINE]]:3: error: fixup value must be 4-byte aligned +- .byte 0 +-unaligned: +- .byte 0 +- .byte 0 +- .byte 0 +- +- beq $a0, $a1, out_of_range_b18 # CHECK: :[[#@LINE]]:3: error: fixup value out of range [-131072, 131071] +- .space 1<<18 +-out_of_range_b18: +- beqz $a0, out_of_range_b23 # CHECK: :[[#@LINE]]:3: error: fixup value out of range [-4194304, 4194303] +- .space 1<<23 +-out_of_range_b23: +- b out_of_range_b28 # CHECK: :[[#@LINE]]:3: error: fixup value out of range [-134217728, 134217727] +- .space 1<<28 +-out_of_range_b28: +diff --git a/llvm/test/MC/LoongArch/Relocations/fixups-invalid.s b/llvm/test/MC/LoongArch/Relocations/fixups-invalid.s +deleted file mode 100644 +index 8251a71d7..000000000 +--- a/llvm/test/MC/LoongArch/Relocations/fixups-invalid.s ++++ /dev/null +@@ -1,7 +0,0 @@ +-# RUN: not llvm-mc --filetype=obj %s --triple=loongarch32 -o /dev/null 2>&1 \ +-# RUN: | FileCheck %s +-# RUN: not llvm-mc --filetype=obj %s --triple=loongarch64 -o /dev/null 2>&1 \ +-# RUN: | FileCheck %s +- +-.byte foo # CHECK: [[#@LINE]]:7: error: 1-byte data relocations not supported +-.2byte foo # CHECK: [[#@LINE]]:8: error: 2-byte data relocations not supported +diff --git a/llvm/test/MC/LoongArch/Relocations/fixups.s b/llvm/test/MC/LoongArch/Relocations/fixups.s +deleted file mode 100644 +index cdb38c09d..000000000 +--- a/llvm/test/MC/LoongArch/Relocations/fixups.s ++++ /dev/null +@@ -1,67 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 %s --show-encoding \ +-# RUN: | FileCheck --check-prefix=CHECK-FIXUP %s +-# RUN: llvm-mc --filetype=obj --triple=loongarch64 %s \ +-# RUN: | llvm-objdump -d - | FileCheck --check-prefix=CHECK-INSTR %s +-# RUN: llvm-mc --filetype=obj --triple=loongarch64 %s \ +-# RUN: | llvm-readobj -r - | FileCheck --check-prefix=CHECK-REL %s +- +-## Checks that fixups that can be resolved within the same object file are +-## applied correctly. +- +-.LBB0: +-lu12i.w $t1, %abs_hi20(val) +-# CHECK-FIXUP: fixup A - offset: 0, value: %abs_hi20(val), kind: fixup_loongarch_abs_hi20 +-# CHECK-INSTR: lu12i.w $t1, 74565 +- +-ori $t1, $t1, %abs_lo12(val) +-# CHECK-FIXUP: fixup A - offset: 0, value: %abs_lo12(val), kind: fixup_loongarch_abs_lo12 +-# CHECK-INSTR: ori $t1, $t1, 1656 +- +-b .LBB0 +-# CHECK-FIXUP: fixup A - offset: 0, value: .LBB0, kind: fixup_loongarch_b26 +-# CHECK-INSTR: b -8 +-b .LBB2 +-# CHECK-FIXUP: fixup A - offset: 0, value: .LBB2, kind: fixup_loongarch_b26 +-# CHECK-INSTR: b 331004 +-beq $a0, $a1, .LBB0 +-# CHECK-FIXUP: fixup A - offset: 0, value: .LBB0, kind: fixup_loongarch_b16 +-# CHECK-INSTR: beq $a0, $a1, -16 +-blt $a0, $a1, .LBB1 +-# CHECK-FIXUP: fixup A - offset: 0, value: .LBB1, kind: fixup_loongarch_b16 +-# CHECK-INSTR: blt $a0, $a1, 1116 +-beqz $a0, .LBB0 +-# CHECK-FIXUP: fixup A - offset: 0, value: .LBB0, kind: fixup_loongarch_b21 +-# CHECK-INSTR: beqz $a0, -24 +-bnez $a0, .LBB1 +-# CHECK-FIXUP: fixup A - offset: 0, value: .LBB1, kind: fixup_loongarch_b21 +-# CHECK-INSTR: bnez $a0, 1108 +- +-.fill 1104 +- +-.LBB1: +- +-.fill 329876 +-nop +-.LBB2: +- +-.set val, 0x12345678 +- +-# CHECK-REL-NOT: R_LARCH +- +-## Testing the function call offset could resolved by assembler +-## when the function and the callsite within the same compile unit. +-func: +-.fill 100 +-bl func +-# CHECK-FIXUP: fixup A - offset: 0, value: func, kind: fixup_loongarch_b26 +-# CHECK-INSTR: bl -100 +- +-.fill 10000 +-bl func +-# CHECK-FIXUP: fixup A - offset: 0, value: func, kind: fixup_loongarch_b26 +-# CHECK-INSTR: bl -10104 +- +-.fill 20888 +-bl func +-# CHECK-FIXUP: fixup A - offset: 0, value: func, kind: fixup_loongarch_b26 +-# CHECK-INSTR: bl -30996 +diff --git a/llvm/test/MC/LoongArch/Relocations/leb128.s b/llvm/test/MC/LoongArch/Relocations/leb128.s +deleted file mode 100644 +index 7a96ec551..000000000 +--- a/llvm/test/MC/LoongArch/Relocations/leb128.s ++++ /dev/null +@@ -1,72 +0,0 @@ +-# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=-relax %s -o %t +-# RUN: llvm-readobj -r -x .alloc_w %t | FileCheck --check-prefixes=CHECK,NORELAX %s +-# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o %t.relax +-# RUN: llvm-readobj -r -x .alloc_w %t.relax | FileCheck --check-prefixes=CHECK,RELAX %s +- +-# RUN: not llvm-mc --filetype=obj --triple=loongarch64 --mattr=-relax --defsym ERR=1 %s -o /dev/null 2>&1 | \ +-# RUN: FileCheck %s --check-prefix=ERR +-# RUN: not llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax --defsym ERR=1 %s -o /dev/null 2>&1 | \ +-# RUN: FileCheck %s --check-prefix=ERR +- +-# CHECK: Relocations [ +-# CHECK-NEXT: .rela.alloc_w { +-# RELAX-NEXT: 0x0 R_LARCH_ADD_ULEB128 w1 0x0 +-# RELAX-NEXT: 0x0 R_LARCH_SUB_ULEB128 w 0x0 +-# RELAX-NEXT: 0x1 R_LARCH_ADD_ULEB128 w2 0x0 +-# RELAX-NEXT: 0x1 R_LARCH_SUB_ULEB128 w1 0x0 +-# CHECK-NEXT: 0x2 R_LARCH_PCALA_HI20 foo 0x0 +-# RELAX-NEXT: 0x2 R_LARCH_RELAX - 0x0 +-# CHECK-NEXT: 0x6 R_LARCH_PCALA_LO12 foo 0x0 +-# RELAX-NEXT: 0x6 R_LARCH_RELAX - 0x0 +-# RELAX-NEXT: 0xA R_LARCH_ADD_ULEB128 w2 0x0 +-# RELAX-NEXT: 0xA R_LARCH_SUB_ULEB128 w1 0x0 +-# RELAX-NEXT: 0xB R_LARCH_ADD_ULEB128 w2 0x78 +-# RELAX-NEXT: 0xB R_LARCH_SUB_ULEB128 w1 0x0 +-# RELAX-NEXT: 0xD R_LARCH_ADD_ULEB128 w1 0x0 +-# RELAX-NEXT: 0xD R_LARCH_SUB_ULEB128 w2 0x0 +-# RELAX-NEXT: 0x17 R_LARCH_ADD_ULEB128 w3 0x6F +-# RELAX-NEXT: 0x17 R_LARCH_SUB_ULEB128 w2 0x0 +-# RELAX-NEXT: 0x18 R_LARCH_ADD_ULEB128 w3 0x71 +-# RELAX-NEXT: 0x18 R_LARCH_SUB_ULEB128 w2 0x0 +-# CHECK-NEXT: } +-# CHECK-NEXT: ] +- +-# CHECK: Hex dump of section '.alloc_w': +-# NORELAX-NEXT: 0x00000000 02080c00 001a8c01 c0020880 01f8ffff +-# NORELAX-NEXT: 0x00000010 ffffffff ffff017f 8101 +-# RELAX-NEXT: 0x00000000 00000c00 001a8c01 c0020080 00808080 +-# RELAX-NEXT: 0x00000010 80808080 80800000 8000 +- +-.section .alloc_w,"ax",@progbits; w: +-.uleb128 w1-w # w1 is later defined in the same section +-.uleb128 w2-w1 # w1 and w2 are separated by a linker relaxable instruction +-w1: +- la.pcrel $t0, foo +-w2: +-.uleb128 w2-w1 # 0x08 +-.uleb128 w2-w1+120 # 0x0180 +-.uleb128 -(w2-w1) # 0x01fffffffffffffffff8 +-.uleb128 w3-w2+111 # 0x7f +-.uleb128 w3-w2+113 # 0x0181 +-w3: +- +-.ifdef ERR +-# ERR: :[[#@LINE+1]]:16: error: .uleb128 expression is not absolute +-.uleb128 extern-w # extern is undefined +-# ERR: :[[#@LINE+1]]:11: error: .uleb128 expression is not absolute +-.uleb128 w-extern +-# ERR: :[[#@LINE+1]]:11: error: .uleb128 expression is not absolute +-.uleb128 x-w # x is later defined in another section +- +-.section .alloc_x,"aw",@progbits; x: +-# ERR: :[[#@LINE+1]]:11: error: .uleb128 expression is not absolute +-.uleb128 y-x +-.section .alloc_y,"aw",@progbits; y: +-# ERR: :[[#@LINE+1]]:11: error: .uleb128 expression is not absolute +-.uleb128 x-y +- +-# ERR: :[[#@LINE+1]]:10: error: .uleb128 expression is not absolute +-.uleb128 extern +-# ERR: :[[#@LINE+1]]:10: error: .uleb128 expression is not absolute +-.uleb128 y +-.endif +diff --git a/llvm/test/MC/LoongArch/Relocations/relax-addsub.s b/llvm/test/MC/LoongArch/Relocations/relax-addsub.s +deleted file mode 100644 +index 18e0ede5e..000000000 +--- a/llvm/test/MC/LoongArch/Relocations/relax-addsub.s ++++ /dev/null +@@ -1,107 +0,0 @@ +-# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=-relax %s \ +-# RUN: | llvm-readobj -r -x .data - | FileCheck %s --check-prefix=NORELAX +-# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s \ +-# RUN: | llvm-readobj -r -x .data - | FileCheck %s --check-prefix=RELAX +- +-# NORELAX: Relocations [ +-# NORELAX-NEXT: Section ({{.*}}) .rela.text { +-# NORELAX-NEXT: 0x10 R_LARCH_PCALA_HI20 .text 0x0 +-# NORELAX-NEXT: 0x14 R_LARCH_PCALA_LO12 .text 0x0 +-# NORELAX-NEXT: } +-# NORELAX-NEXT: Section ({{.*}}) .rela.data { +-# NORELAX-NEXT: 0x30 R_LARCH_ADD8 foo 0x0 +-# NORELAX-NEXT: 0x30 R_LARCH_SUB8 .text 0x10 +-# NORELAX-NEXT: 0x31 R_LARCH_ADD16 foo 0x0 +-# NORELAX-NEXT: 0x31 R_LARCH_SUB16 .text 0x10 +-# NORELAX-NEXT: 0x33 R_LARCH_ADD32 foo 0x0 +-# NORELAX-NEXT: 0x33 R_LARCH_SUB32 .text 0x10 +-# NORELAX-NEXT: 0x37 R_LARCH_ADD64 foo 0x0 +-# NORELAX-NEXT: 0x37 R_LARCH_SUB64 .text 0x10 +-# NORELAX-NEXT: } +-# NORELAX-NEXT: ] +- +-# NORELAX: Hex dump of section '.data': +-# NORELAX-NEXT: 0x00000000 04040004 00000004 00000000 00000004 +-# NORELAX-NEXT: 0x00000010 0c0c000c 0000000c 00000000 0000000c +-# NORELAX-NEXT: 0x00000020 08080008 00000008 00000000 00000008 +-# NORELAX-NEXT: 0x00000030 00000000 00000000 00000000 000000 +- +-# RELAX: Relocations [ +-# RELAX-NEXT: Section ({{.*}}) .rela.text { +-# RELAX-NEXT: 0x4 R_LARCH_ALIGN {{.*}} 0x4 +-# RELAX-NEXT: 0x10 R_LARCH_PCALA_HI20 .L1 0x0 +-# RELAX-NEXT: 0x10 R_LARCH_RELAX - 0x0 +-# RELAX-NEXT: 0x14 R_LARCH_PCALA_LO12 .L1 0x0 +-# RELAX-NEXT: 0x14 R_LARCH_RELAX - 0x0 +-# RELAX-NEXT: } +-# RELAX-NEXT: Section ({{.*}}) .rela.data { +-# RELAX-NEXT: 0x10 R_LARCH_ADD8 .L3 0x0 +-# RELAX-NEXT: 0x10 R_LARCH_SUB8 .L2 0x0 +-# RELAX-NEXT: 0x11 R_LARCH_ADD16 .L3 0x0 +-# RELAX-NEXT: 0x11 R_LARCH_SUB16 .L2 0x0 +-# RELAX-NEXT: 0x13 R_LARCH_ADD32 .L3 0x0 +-# RELAX-NEXT: 0x13 R_LARCH_SUB32 .L2 0x0 +-# RELAX-NEXT: 0x17 R_LARCH_ADD64 .L3 0x0 +-# RELAX-NEXT: 0x17 R_LARCH_SUB64 .L2 0x0 +-# RELAX-NEXT: 0x1F R_LARCH_ADD_ULEB128 .L3 0x0 +-# RELAX-NEXT: 0x1F R_LARCH_SUB_ULEB128 .L2 0x0 +-# RELAX-NEXT: 0x20 R_LARCH_ADD8 .L4 0x0 +-# RELAX-NEXT: 0x20 R_LARCH_SUB8 .L3 0x0 +-# RELAX-NEXT: 0x21 R_LARCH_ADD16 .L4 0x0 +-# RELAX-NEXT: 0x21 R_LARCH_SUB16 .L3 0x0 +-# RELAX-NEXT: 0x23 R_LARCH_ADD32 .L4 0x0 +-# RELAX-NEXT: 0x23 R_LARCH_SUB32 .L3 0x0 +-# RELAX-NEXT: 0x27 R_LARCH_ADD64 .L4 0x0 +-# RELAX-NEXT: 0x27 R_LARCH_SUB64 .L3 0x0 +-# RELAX-NEXT: 0x2F R_LARCH_ADD_ULEB128 .L4 0x0 +-# RELAX-NEXT: 0x2F R_LARCH_SUB_ULEB128 .L3 0x0 +-# RELAX-NEXT: 0x30 R_LARCH_ADD8 foo 0x0 +-# RELAX-NEXT: 0x30 R_LARCH_SUB8 .L3 0x0 +-# RELAX-NEXT: 0x31 R_LARCH_ADD16 foo 0x0 +-# RELAX-NEXT: 0x31 R_LARCH_SUB16 .L3 0x0 +-# RELAX-NEXT: 0x33 R_LARCH_ADD32 foo 0x0 +-# RELAX-NEXT: 0x33 R_LARCH_SUB32 .L3 0x0 +-# RELAX-NEXT: 0x37 R_LARCH_ADD64 foo 0x0 +-# RELAX-NEXT: 0x37 R_LARCH_SUB64 .L3 0x0 +-# RELAX-NEXT: } +-# RELAX-NEXT: ] +- +-# RELAX: Hex dump of section '.data': +-# RELAX-NEXT: 0x00000000 04040004 00000004 00000000 00000004 +-# RELAX-NEXT: 0x00000010 00000000 00000000 00000000 00000000 +-# RELAX-NEXT: 0x00000020 00000000 00000000 00000000 00000000 +-# RELAX-NEXT: 0x00000030 00000000 00000000 00000000 000000 +- +-.text +-.L1: +- nop +-.L2: +- .align 4 +-.L3: +- la.pcrel $t0, .L1 +-.L4: +- ret +- +-.data +-## Not emit relocs +-.byte .L2 - .L1 +-.short .L2 - .L1 +-.word .L2 - .L1 +-.dword .L2 - .L1 +-.uleb128 .L2 - .L1 +-## With relaxation, emit relocs because the .align makes the diff variable. +-.byte .L3 - .L2 +-.short .L3 - .L2 +-.word .L3 - .L2 +-.dword .L3 - .L2 +-.uleb128 .L3 - .L2 +-## With relaxation, emit relocs because the la.pcrel makes the diff variable. +-.byte .L4 - .L3 +-.short .L4 - .L3 +-.word .L4 - .L3 +-.dword .L4 - .L3 +-.uleb128 .L4 - .L3 +-.byte foo - .L3 +-.short foo - .L3 +-.word foo - .L3 +-.dword foo - .L3 +diff --git a/llvm/test/MC/LoongArch/Relocations/relax-align.s b/llvm/test/MC/LoongArch/Relocations/relax-align.s +deleted file mode 100644 +index 294fd9fb9..000000000 +--- a/llvm/test/MC/LoongArch/Relocations/relax-align.s ++++ /dev/null +@@ -1,79 +0,0 @@ +-## The file testing Nop insertion with R_LARCH_ALIGN for relaxation. +- +-# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=-relax %s -o %t +-# RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=INSTR +-# RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=RELOC +-# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o %t.r +-# RUN: llvm-objdump -d %t.r | FileCheck %s --check-prefixes=INSTR,RELAX-INSTR +-# RUN: llvm-readobj -r %t.r | FileCheck %s --check-prefixes=RELOC,RELAX-RELOC +- +-.text +-break 0 +-# INSTR: break 0 +- +-## Not emit R_LARCH_ALIGN if alignment directive is less than or equal to +-## minimum code alignment(a.k.a 4). +-.p2align 2 +-.p2align 1 +-.p2align 0 +- +-## Not emit instructions if max emit bytes less than min nop size. +-.p2align 4, , 2 +- +-## Not emit R_LARCH_ALIGN if alignment directive with specific padding value. +-## The behavior is the same as GNU assembler. +-break 1 +-.p2align 4, 1 +-# INSTR-NEXT: break 1 +-# INSTR-COUNT-2: 01 01 01 01 +- +-break 2 +-.p2align 4, 1, 12 +-# INSTR-NEXT: break 2 +-# INSTR-COUNT-3: 01 01 01 01 +- +-break 3 +-.p2align 4 +-# INSTR-NEXT: break 3 +-# INSTR-COUNT-3: nop +- +-break 4 +-.p2align 5 +-.p2align 4 +-# INSTR-NEXT: break 4 +-# INSTR-COUNT-3: nop +-# RELAX-INSTR-COUNT-7: nop +- +-break 5 +-.p2align 4, , 11 +-# INSTR-NEXT: break 5 +-# RELAX-INSTR-COUNT-3: nop +- +-break 6 +-## Not emit the third parameter. +-.p2align 4, , 12 +-# INSTR-NEXT: break 6 +-# INSTR-NEXT: nop +-# INSTR-NEXT: nop +-# RELAX-INSTR-NEXT: nop +- +-ret +-# INSNR-NEXT: ret +- +-## Test the symbol index is different from .text. +-.section .text2, "ax" +-.p2align 4 +-break 7 +- +-# RELOC: Relocations [ +-# RELAX-RELOC-NEXT: Section ({{.*}}) .rela.text { +-# RELAX-RELOC-NEXT: 0x24 R_LARCH_ALIGN .Lla-relax-align0 0x4 +-# RELAX-RELOC-NEXT: 0x34 R_LARCH_ALIGN .Lla-relax-align0 0x5 +-# RELAX-RELOC-NEXT: 0x50 R_LARCH_ALIGN .Lla-relax-align0 0x4 +-# RELAX-RELOC-NEXT: 0x60 R_LARCH_ALIGN .Lla-relax-align0 0xB04 +-# RELAX-RELOC-NEXT: 0x70 R_LARCH_ALIGN .Lla-relax-align0 0x4 +-# RELAX-RELOC-NEXT: } +-# RELAX-RELOC-NEXT: Section ({{.*}}) .rela.text2 { +-# RELAX-RELOC-NEXT: 0x0 R_LARCH_ALIGN .Lla-relax-align1 0x4 +-# RELAX-RELOC-NEXT: } +-# RELOC-NEXT: ] +diff --git a/llvm/test/MC/LoongArch/Relocations/relax-attr.s b/llvm/test/MC/LoongArch/Relocations/relax-attr.s +deleted file mode 100644 +index b1e648d85..000000000 +--- a/llvm/test/MC/LoongArch/Relocations/relax-attr.s ++++ /dev/null +@@ -1,32 +0,0 @@ +-# RUN: llvm-mc --filetype=obj --triple=loongarch64 %s -o %t +-# RUN: llvm-readobj -r %t | FileCheck %s +-# RUN: llvm-mc --filetype=obj --triple=loongarch64 -mattr=+relax %s -o %t +-# RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=CHECKR +- +-# CHECK: Relocations [ +-# CHECK-NEXT: Section ({{.*}}) .rela.data { +-# CHECK-NEXT: 0x0 R_LARCH_64 .text 0x4 +-# CHECK-NEXT: } +-# CHECK-NEXT: ] +- +-# CHECKR: Relocations [ +-# CHECKR-NEXT: Section ({{.*}}) .rela.text { +-# CHECKR-NEXT: 0x8 R_LARCH_B21 .L1 0x0 +-# CHECKR-NEXT: 0xC R_LARCH_B16 .L1 0x0 +-# CHECKR-NEXT: 0x10 R_LARCH_B26 .L1 0x0 +-# CHECKR-NEXT: } +-# CHECKR-NEXT: Section ({{.*}}) .rela.data { +-# CHECKR-NEXT: 0x0 R_LARCH_64 .L1 0x0 +-# CHECKR-NEXT: } +-# CHECKR-NEXT: ] +- +-.text +- nop +-.L1: +- nop +- beqz $a0, .L1 +- blt $a0, $a1, .L1 +- b .L1 +- +-.data +-.dword .L1 +diff --git a/llvm/test/MC/LoongArch/Relocations/reloc-directive.s b/llvm/test/MC/LoongArch/Relocations/reloc-directive.s +deleted file mode 100644 +index f900f17c0..000000000 +--- a/llvm/test/MC/LoongArch/Relocations/reloc-directive.s ++++ /dev/null +@@ -1,46 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 %s | FileCheck --check-prefix=PRINT %s +-# RUN: llvm-mc --filetype=obj --triple=loongarch64 %s \ +-# RUN: | llvm-readobj -r - | FileCheck %s +- +-# PRINT: .reloc 8, R_LARCH_NONE, .data +-# PRINT: .reloc 4, R_LARCH_NONE, foo+4 +-# PRINT: .reloc 0, R_LARCH_NONE, 8 +-# PRINT: .reloc 0, R_LARCH_32, .data+2 +-# PRINT: .reloc 0, R_LARCH_TLS_DTPMOD32, foo+3 +-# PRINT: .reloc 0, R_LARCH_IRELATIVE, 5 +-# PRINT: .reloc 0, BFD_RELOC_NONE, 9 +-# PRINT-NEXT: .reloc 0, BFD_RELOC_32, 9 +-# PRINT-NEXT: .reloc 0, BFD_RELOC_64, 9 +- +-.text +- ret +- nop +- nop +- .reloc 8, R_LARCH_NONE, .data +- .reloc 4, R_LARCH_NONE, foo+4 +- .reloc 0, R_LARCH_NONE, 8 +- +- .reloc 0, R_LARCH_32, .data+2 +- .reloc 0, R_LARCH_TLS_DTPMOD32, foo+3 +- .reloc 0, R_LARCH_IRELATIVE, 5 +- +- .reloc 0, BFD_RELOC_NONE, 9 +- .reloc 0, BFD_RELOC_32, 9 +- .reloc 0, BFD_RELOC_64, 9 +- +-.data +-.globl foo +-foo: +- .word 0 +- .word 0 +- .word 0 +- +-# CHECK: 0x8 R_LARCH_NONE .data 0x0 +-# CHECK-NEXT: 0x4 R_LARCH_NONE foo 0x4 +-# CHECK-NEXT: 0x0 R_LARCH_NONE - 0x8 +-# CHECK-NEXT: 0x0 R_LARCH_32 .data 0x2 +-# CHECK-NEXT: 0x0 R_LARCH_TLS_DTPMOD32 foo 0x3 +-# CHECK-NEXT: 0x0 R_LARCH_IRELATIVE - 0x5 +-# CHECK-NEXT: 0x0 R_LARCH_NONE - 0x9 +-# CHECK-NEXT: 0x0 R_LARCH_32 - 0x9 +-# CHECK-NEXT: 0x0 R_LARCH_64 - 0x9 +diff --git a/llvm/test/MC/LoongArch/Relocations/relocations.s b/llvm/test/MC/LoongArch/Relocations/relocations.s +deleted file mode 100644 +index bec71e103..000000000 +--- a/llvm/test/MC/LoongArch/Relocations/relocations.s ++++ /dev/null +@@ -1,225 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 < %s --show-encoding \ +-# RUN: | FileCheck --check-prefixes=INSTR,FIXUP %s +-# RUN: llvm-mc --filetype=obj --triple=loongarch64 < %s \ +-# RUN: | llvm-readobj -r - | FileCheck --check-prefix=RELOC %s +- +-## Check prefixes: +-## RELOC - Check the relocation in the object. +-## FIXUP - Check the fixup on the instruction. +-## INSTR - Check the instruction is handled properly by the ASMPrinter. +- +-.long foo +-# RELOC: R_LARCH_32 foo +- +-.quad foo +-# RELOC: R_LARCH_64 foo +- +-bne $t1, $t2, %b16(foo) +-# RELOC: R_LARCH_B16 +-# INSTR: bne $t1, $t2, %b16(foo) +-# FIXUP: fixup A - offset: 0, value: %b16(foo), kind: fixup_loongarch_b16 +- +-bnez $t1, %b21(foo) +-# RELOC: R_LARCH_B21 +-# INSTR: bnez $t1, %b21(foo) +-# FIXUP: fixup A - offset: 0, value: %b21(foo), kind: fixup_loongarch_b21 +- +-bl %plt(foo) +-# RELOC: R_LARCH_B26 +-# INSTR: bl %plt(foo) +-# FIXUP: fixup A - offset: 0, value: %plt(foo), kind: fixup_loongarch_b26 +- +-bl foo +-# RELOC: R_LARCH_B26 +-# INSTR: bl foo +-# FIXUP: fixup A - offset: 0, value: foo, kind: fixup_loongarch_b26 +- +-lu12i.w $t1, %abs_hi20(foo) +-# RELOC: R_LARCH_ABS_HI20 foo 0x0 +-# INSTR: lu12i.w $t1, %abs_hi20(foo) +-# FIXUP: fixup A - offset: 0, value: %abs_hi20(foo), kind: fixup_loongarch_abs_hi20 +- +-ori $t1, $t1, %abs_lo12(foo) +-# RELOC: R_LARCH_ABS_LO12 foo 0x0 +-# INSTR: ori $t1, $t1, %abs_lo12(foo) +-# FIXUP: fixup A - offset: 0, value: %abs_lo12(foo), kind: fixup_loongarch_abs_lo12 +- +-lu32i.d $t1, %abs64_lo20(foo) +-# RELOC: R_LARCH_ABS64_LO20 foo 0x0 +-# INSTR: lu32i.d $t1, %abs64_lo20(foo) +-# FIXUP: fixup A - offset: 0, value: %abs64_lo20(foo), kind: fixup_loongarch_abs64_lo20 +- +-lu52i.d $t1, $t1, %abs64_hi12(foo) +-# RELOC: R_LARCH_ABS64_HI12 foo 0x0 +-# INSTR: lu52i.d $t1, $t1, %abs64_hi12(foo) +-# FIXUP: fixup A - offset: 0, value: %abs64_hi12(foo), kind: fixup_loongarch_abs64_hi12 +- +-pcalau12i $t1, %pc_hi20(foo) +-# RELOC: R_LARCH_PCALA_HI20 foo 0x0 +-# INSTR: pcalau12i $t1, %pc_hi20(foo) +-# FIXUP: fixup A - offset: 0, value: %pc_hi20(foo), kind: FK_NONE +- +-pcalau12i $t1, %pc_hi20(foo+4) +-# RELOC: R_LARCH_PCALA_HI20 foo 0x4 +-# INSTR: pcalau12i $t1, %pc_hi20(foo+4) +-# FIXUP: fixup A - offset: 0, value: %pc_hi20(foo+4), kind: FK_NONE +- +-addi.d $t1, $t1, %pc_lo12(foo) +-# RELOC: R_LARCH_PCALA_LO12 foo 0x0 +-# INSTR: addi.d $t1, $t1, %pc_lo12(foo) +-# FIXUP: fixup A - offset: 0, value: %pc_lo12(foo), kind: FK_NONE +- +-addi.d $t1, $t1, %pc_lo12(foo+4) +-# RELOC: R_LARCH_PCALA_LO12 foo 0x4 +-# INSTR: addi.d $t1, $t1, %pc_lo12(foo+4) +-# FIXUP: fixup A - offset: 0, value: %pc_lo12(foo+4), kind: FK_NONE +- +-jirl $zero, $t1, %pc_lo12(foo) +-# RELOC: R_LARCH_PCALA_LO12 foo 0x0 +-# INSTR: jirl $zero, $t1, %pc_lo12(foo) +-# FIXUP: fixup A - offset: 0, value: %pc_lo12(foo), kind: FK_NONE +- +-st.b $t1, $a2, %pc_lo12(foo) +-# RELOC: R_LARCH_PCALA_LO12 foo 0x0 +-# INSTR: st.b $t1, $a2, %pc_lo12(foo) +-# FIXUP: fixup A - offset: 0, value: %pc_lo12(foo), kind: FK_NONE +- +-st.b $t1, $a2, %pc_lo12(foo+4) +-# RELOC: R_LARCH_PCALA_LO12 foo 0x4 +-# INSTR: st.b $t1, $a2, %pc_lo12(foo+4) +-# FIXUP: fixup A - offset: 0, value: %pc_lo12(foo+4), kind: FK_NONE +- +-lu32i.d $t1, %pc64_lo20(foo) +-# RELOC: R_LARCH_PCALA64_LO20 foo 0x0 +-# INSTR: lu32i.d $t1, %pc64_lo20(foo) +-# FIXUP: fixup A - offset: 0, value: %pc64_lo20(foo), kind: FK_NONE +- +-lu52i.d $t1, $t1, %pc64_hi12(foo) +-# RELOC: R_LARCH_PCALA64_HI12 foo 0x0 +-# INSTR: lu52i.d $t1, $t1, %pc64_hi12(foo) +-# FIXUP: fixup A - offset: 0, value: %pc64_hi12(foo), kind: FK_NONE +- +-pcalau12i $t1, %got_pc_hi20(foo) +-# RELOC: R_LARCH_GOT_PC_HI20 foo 0x0 +-# INSTR: pcalau12i $t1, %got_pc_hi20(foo) +-# FIXUP: fixup A - offset: 0, value: %got_pc_hi20(foo), kind: FK_NONE +- +-ld.d $t1, $a2, %got_pc_lo12(foo) +-# RELOC: R_LARCH_GOT_PC_LO12 foo 0x0 +-# INSTR: ld.d $t1, $a2, %got_pc_lo12(foo) +-# FIXUP: fixup A - offset: 0, value: %got_pc_lo12(foo), kind: FK_NONE +- +-lu32i.d $t1, %got64_pc_lo20(foo) +-# RELOC: R_LARCH_GOT64_PC_LO20 foo 0x0 +-# INSTR: lu32i.d $t1, %got64_pc_lo20(foo) +-# FIXUP: fixup A - offset: 0, value: %got64_pc_lo20(foo), kind: FK_NONE +- +-lu52i.d $t1, $t1, %got64_pc_hi12(foo) +-# RELOC: R_LARCH_GOT64_PC_HI12 foo 0x0 +-# INSTR: lu52i.d $t1, $t1, %got64_pc_hi12(foo) +-# FIXUP: fixup A - offset: 0, value: %got64_pc_hi12(foo), kind: FK_NONE +- +-lu12i.w $t1, %got_hi20(foo) +-# RELOC: R_LARCH_GOT_HI20 foo 0x0 +-# INSTR: lu12i.w $t1, %got_hi20(foo) +-# FIXUP: fixup A - offset: 0, value: %got_hi20(foo), kind: FK_NONE +- +-ori $t1, $a2, %got_lo12(foo) +-# RELOC: R_LARCH_GOT_LO12 foo 0x0 +-# INSTR: ori $t1, $a2, %got_lo12(foo) +-# FIXUP: fixup A - offset: 0, value: %got_lo12(foo), kind: FK_NONE +- +-lu32i.d $t1, %got64_lo20(foo) +-# RELOC: R_LARCH_GOT64_LO20 foo 0x0 +-# INSTR: lu32i.d $t1, %got64_lo20(foo) +-# FIXUP: fixup A - offset: 0, value: %got64_lo20(foo), kind: FK_NONE +- +-lu52i.d $t1, $t1, %got64_hi12(foo) +-# RELOC: R_LARCH_GOT64_HI12 foo 0x0 +-# INSTR: lu52i.d $t1, $t1, %got64_hi12(foo) +-# FIXUP: fixup A - offset: 0, value: %got64_hi12(foo), kind: FK_NONE +- +-lu12i.w $t1, %le_hi20(foo) +-# RELOC: R_LARCH_TLS_LE_HI20 foo 0x0 +-# INSTR: lu12i.w $t1, %le_hi20(foo) +-# FIXUP: fixup A - offset: 0, value: %le_hi20(foo), kind: fixup_loongarch_tls_le_hi20 +- +-ori $t1, $a2, %le_lo12(foo) +-# RELOC: R_LARCH_TLS_LE_LO12 foo 0x0 +-# INSTR: ori $t1, $a2, %le_lo12(foo) +-# FIXUP: fixup A - offset: 0, value: %le_lo12(foo), kind: fixup_loongarch_tls_le_lo12 +- +-lu32i.d $t1, %le64_lo20(foo) +-# RELOC: R_LARCH_TLS_LE64_LO20 foo 0x0 +-# INSTR: lu32i.d $t1, %le64_lo20(foo) +-# FIXUP: fixup A - offset: 0, value: %le64_lo20(foo), kind: fixup_loongarch_tls_le64_lo20 +- +-lu52i.d $t1, $t1, %le64_hi12(foo) +-# RELOC: R_LARCH_TLS_LE64_HI12 foo 0x0 +-# INSTR: lu52i.d $t1, $t1, %le64_hi12(foo) +-# FIXUP: fixup A - offset: 0, value: %le64_hi12(foo), kind: fixup_loongarch_tls_le64_hi12 +- +-pcalau12i $t1, %ie_pc_hi20(foo) +-# RELOC: R_LARCH_TLS_IE_PC_HI20 foo 0x0 +-# INSTR: pcalau12i $t1, %ie_pc_hi20(foo) +-# FIXUP: fixup A - offset: 0, value: %ie_pc_hi20(foo), kind: FK_NONE +- +-ld.d $t1, $a2, %ie_pc_lo12(foo) +-# RELOC: R_LARCH_TLS_IE_PC_LO12 foo 0x0 +-# INSTR: ld.d $t1, $a2, %ie_pc_lo12(foo) +-# FIXUP: fixup A - offset: 0, value: %ie_pc_lo12(foo), kind: FK_NONE +- +-lu32i.d $t1, %ie64_pc_lo20(foo) +-# RELOC: R_LARCH_TLS_IE64_PC_LO20 foo 0x0 +-# INSTR: lu32i.d $t1, %ie64_pc_lo20(foo) +-# FIXUP: fixup A - offset: 0, value: %ie64_pc_lo20(foo), kind: FK_NONE +- +-lu52i.d $t1, $t1, %ie64_pc_hi12(foo) +-# RELOC: R_LARCH_TLS_IE64_PC_HI12 foo 0x0 +-# INSTR: lu52i.d $t1, $t1, %ie64_pc_hi12(foo) +-# FIXUP: fixup A - offset: 0, value: %ie64_pc_hi12(foo), kind: FK_NONE +- +-lu12i.w $t1, %ie_hi20(foo) +-# RELOC: R_LARCH_TLS_IE_HI20 foo 0x0 +-# INSTR: lu12i.w $t1, %ie_hi20(foo) +-# FIXUP: fixup A - offset: 0, value: %ie_hi20(foo), kind: FK_NONE +- +-ori $t1, $a2, %ie_lo12(foo) +-# RELOC: R_LARCH_TLS_IE_LO12 foo 0x0 +-# INSTR: ori $t1, $a2, %ie_lo12(foo) +-# FIXUP: fixup A - offset: 0, value: %ie_lo12(foo), kind: FK_NONE +- +-lu32i.d $t1, %ie64_lo20(foo) +-# RELOC: R_LARCH_TLS_IE64_LO20 foo 0x0 +-# INSTR: lu32i.d $t1, %ie64_lo20(foo) +-# FIXUP: fixup A - offset: 0, value: %ie64_lo20(foo), kind: FK_NONE +- +-lu52i.d $t1, $t1, %ie64_hi12(foo) +-# RELOC: R_LARCH_TLS_IE64_HI12 foo 0x0 +-# INSTR: lu52i.d $t1, $t1, %ie64_hi12(foo) +-# FIXUP: fixup A - offset: 0, value: %ie64_hi12(foo), kind: FK_NONE +- +-pcalau12i $t1, %ld_pc_hi20(foo) +-# RELOC: R_LARCH_TLS_LD_PC_HI20 foo 0x0 +-# INSTR: pcalau12i $t1, %ld_pc_hi20(foo) +-# FIXUP: fixup A - offset: 0, value: %ld_pc_hi20(foo), kind: FK_NONE +- +-lu12i.w $t1, %ld_hi20(foo) +-# RELOC: R_LARCH_TLS_LD_HI20 foo 0x0 +-# INSTR: lu12i.w $t1, %ld_hi20(foo) +-# FIXUP: fixup A - offset: 0, value: %ld_hi20(foo), kind: FK_NONE +- +-pcalau12i $t1, %gd_pc_hi20(foo) +-# RELOC: R_LARCH_TLS_GD_PC_HI20 foo 0x0 +-# INSTR: pcalau12i $t1, %gd_pc_hi20(foo) +-# FIXUP: fixup A - offset: 0, value: %gd_pc_hi20(foo), kind: FK_NONE +- +-lu12i.w $t1, %gd_hi20(foo) +-# RELOC: R_LARCH_TLS_GD_HI20 foo 0x0 +-# INSTR: lu12i.w $t1, %gd_hi20(foo) +-# FIXUP: fixup A - offset: 0, value: %gd_hi20(foo), kind: FK_NONE +- +-pcaddu18i $t1, %call36(foo) +-# RELOC: R_LARCH_CALL36 foo 0x0 +-# INSTR: pcaddu18i $t1, %call36(foo) +-# FIXUP: fixup A - offset: 0, value: %call36(foo), kind: FK_NONE +diff --git a/llvm/test/MC/LoongArch/Relocations/sub-expr.s b/llvm/test/MC/LoongArch/Relocations/sub-expr.s +deleted file mode 100644 +index 0179e1027..000000000 +--- a/llvm/test/MC/LoongArch/Relocations/sub-expr.s ++++ /dev/null +@@ -1,28 +0,0 @@ +-# RUN: llvm-mc --filetype=obj --triple=loongarch64 %s -o %t +-# RUN: llvm-readobj -r %t | FileCheck %s +- +-## Check that subtraction expressions emit R_LARCH_32_PCREL and R_LARCH_64_PCREL relocations. +- +-## TODO: 1- or 2-byte data relocations are not supported for now. +- +-# CHECK: Relocations [ +-# CHECK-NEXT: Section ({{.*}}) .rela.data { +-# CHECK-NEXT: 0x0 R_LARCH_64_PCREL sx 0x0 +-# CHECK-NEXT: 0x8 R_LARCH_64_PCREL sy 0x0 +-# CHECK-NEXT: 0x10 R_LARCH_32_PCREL sx 0x0 +-# CHECK-NEXT: 0x14 R_LARCH_32_PCREL sy 0x0 +-# CHECK-NEXT: } +- +-.section sx,"a" +-x: +-nop +- +-.data +-.8byte x-. +-.8byte y-. +-.4byte x-. +-.4byte y-. +- +-.section sy,"a" +-y: +-nop +diff --git a/llvm/test/MC/LoongArch/aligned-nops.s b/llvm/test/MC/LoongArch/aligned-nops.s +new file mode 100644 +index 000000000..2ef26ac4b +--- /dev/null ++++ b/llvm/test/MC/LoongArch/aligned-nops.s +@@ -0,0 +1,25 @@ ++# RUN: llvm-mc -filetype=obj -triple loongarch64 < %s \ ++# RUN: | llvm-objdump -d - | FileCheck -check-prefix=CHECK-INST %s ++ ++# alpha and main are 8 byte alignment ++# but the alpha function's size is 4 ++# So assembler will insert a nop to make sure 8 byte alignment. ++ ++ .text ++ .p2align 3 ++ .type alpha,@function ++alpha: ++# BB#0: ++ addi.d $sp, $sp, -16 ++# CHECK-INST: nop ++.Lfunc_end0: ++ .size alpha, .Lfunc_end0-alpha ++ # -- End function ++ .globl main ++ .p2align 3 ++ .type main,@function ++main: # @main ++# BB#0: ++.Lfunc_end1: ++ .size main, .Lfunc_end1-main ++ # -- End function +diff --git a/llvm/test/MC/LoongArch/atomic-error.s b/llvm/test/MC/LoongArch/atomic-error.s +new file mode 100644 +index 000000000..7e61a5ba5 +--- /dev/null ++++ b/llvm/test/MC/LoongArch/atomic-error.s +@@ -0,0 +1,7 @@ ++# RUN: not llvm-mc --triple=loongarch64 %s 2>&1 | FileCheck %s ++ ++# CHECK: error: expected memory with constant 0 offset ++amadd_db.d $a1, $t5, $s6, 1 ++ ++# CHECK: error: unexpected token in argument list ++amadd_db.d $a1, $t5, $s6, a +diff --git a/llvm/test/MC/LoongArch/atomic.s b/llvm/test/MC/LoongArch/atomic.s +new file mode 100644 +index 000000000..10a406550 +--- /dev/null ++++ b/llvm/test/MC/LoongArch/atomic.s +@@ -0,0 +1,12 @@ ++# RUN: llvm-mc %s --triple=loongarch64 --show-encoding | \ ++# RUN: FileCheck --check-prefixes=ASM,ASM-AND-OBJ %s ++# RUN: llvm-mc %s --triple=loongarch64 --filetype=obj | llvm-objdump -d - | \ ++# RUN: FileCheck --check-prefixes=ASM-AND-OBJ %s ++ ++# ASM-AND-OBJ: amadd_db.d $r5, $r17, $r29, 0 ++# ASM: encoding: [0xa5,0xc7,0x6a,0x38] ++amadd_db.d $a1, $t5, $s6, 0 ++ ++# ASM-AND-OBJ: amadd_db.d $r5, $r17, $r29, 0 ++# ASM: encoding: [0xa5,0xc7,0x6a,0x38] ++amadd_db.d $a1, $t5, $s6 +diff --git a/llvm/test/MC/LoongArch/cgprofile.ll b/llvm/test/MC/LoongArch/cgprofile.ll +new file mode 100644 +index 000000000..686dd6a0a +--- /dev/null ++++ b/llvm/test/MC/LoongArch/cgprofile.ll +@@ -0,0 +1,63 @@ ++;; Copied from llvm/test/MC/ELF/cgprofile.ll but use different triple. ++ ++; RUN: llc -filetype=asm %s -o - --mtriple=loongarch64-linux-linux-gnu | FileCheck %s ++; RUN: llc -filetype=obj %s -o %t --mtriple=loongarch64-linux-linux-gnu ++; RUN: llvm-readobj -r --cg-profile %t | FileCheck %s --check-prefix=OBJ ++ ++declare void @b() ++ ++define void @a() { ++ call void @b() ++ ret void ++} ++ ++define void @freq(i1 %cond) { ++ br i1 %cond, label %A, label %B ++A: ++ call void @a(); ++ ret void ++B: ++ call void @b(); ++ ret void ++} ++ ++!llvm.module.flags = !{!0} ++ ++!0 = !{i32 5, !"CG Profile", !1} ++!1 = !{!2, !3, !4, !5} ++!2 = !{void ()* @a, void ()* @b, i64 32} ++!3 = !{void (i1)* @freq, void ()* @a, i64 11} ++!4 = !{void (i1)* @freq, void ()* @b, i64 20} ++!5 = !{void (i1)* @freq, null, i64 20} ++ ++; CHECK: .cg_profile a, b, 32 ++; CHECK: .cg_profile freq, a, 11 ++; CHECK: .cg_profile freq, b, 20 ++ ++; OBJ: Relocations [ ++; OBJ: Section ({{.*}}) .rel.llvm.call-graph-profile { ++; OBJ-NEXT: 0x0 R_LARCH_NONE a ++; OBJ-NEXT: 0x0 R_LARCH_NONE b ++; OBJ-NEXT: 0x8 R_LARCH_NONE freq ++; OBJ-NEXT: 0x8 R_LARCH_NONE a ++; OBJ-NEXT: 0x10 R_LARCH_NONE freq ++; OBJ-NEXT: 0x10 R_LARCH_NONE b ++; OBJ-NEXT: } ++ ++; OBJ: CGProfile [ ++; OBJ: CGProfileEntry { ++; OBJ: From: a ++; OBJ: To: b ++; OBJ: Weight: 32 ++; OBJ: } ++; OBJ: CGProfileEntry { ++; OBJ: From: freq ++; OBJ: To: a ++; OBJ: Weight: 11 ++; OBJ: } ++; OBJ: CGProfileEntry { ++; OBJ: From: freq ++; OBJ: To: b ++; OBJ: Weight: 20 ++; OBJ: } ++; OBJ:] +diff --git a/llvm/test/MC/LoongArch/cgprofile.s b/llvm/test/MC/LoongArch/cgprofile.s +new file mode 100644 +index 000000000..53f59e5d3 +--- /dev/null ++++ b/llvm/test/MC/LoongArch/cgprofile.s +@@ -0,0 +1,30 @@ ++## Copied from llvm/test/MC/ELF/cgprofile.s but use different triple. ++ ++# RUN: llvm-mc --filetype=obj --triple=loongarch64-linux-gnu %s -o - | llvm-readobj -r -S --symbols --sd --cg-profile - | FileCheck %s ++ ++ .section .test,"aw",@progbits ++a: .word b ++ ++ .cg_profile a, b, 32 ++ .cg_profile freq, a, 11 ++ .cg_profile late, late2, 20 ++ .cg_profile .L.local, b, 42 ++ ++ .globl late ++late: ++late2: .word 0 ++late3: ++.L.local: ++ ++# CHECK: Relocations [ ++# CHECK: Section ({{.*}}) .rel.llvm.call-graph-profile { ++# CHECK-NEXT: 0x0 R_LARCH_NONE a ++# CHECK-NEXT: 0x0 R_LARCH_NONE b ++# CHECK-NEXT: 0x8 R_LARCH_NONE freq ++# CHECK-NEXT: 0x8 R_LARCH_NONE a ++# CHECK-NEXT: 0x10 R_LARCH_NONE late ++# CHECK-NEXT: 0x10 R_LARCH_NONE late2 ++# CHECK-NEXT: 0x18 R_LARCH_NONE .test ++# CHECK-NEXT: 0x18 R_LARCH_NONE b ++# CHECK-NEXT: } ++# CHECK-NEXT: ] +diff --git a/llvm/test/MC/LoongArch/data_half.s b/llvm/test/MC/LoongArch/data_half.s +new file mode 100644 +index 000000000..a8efeaace +--- /dev/null ++++ b/llvm/test/MC/LoongArch/data_half.s +@@ -0,0 +1,13 @@ ++# RUN: llvm-mc --triple=loongarch64 < %s | FileCheck %s ++ ++.data ++ ++# CHECK: .half 1 ++# CHECK-NEXT: .half 65535 ++.half 0x1 ++.half 0xffff ++ ++# CHECK: .half 1 ++# CHECK-NEXT: .half 65535 ++.2byte 0x1 ++.2byte 0xffff +diff --git a/llvm/test/MC/LoongArch/fixups-expr.s b/llvm/test/MC/LoongArch/fixups-expr.s +new file mode 100644 +index 000000000..d35fe7e77 +--- /dev/null ++++ b/llvm/test/MC/LoongArch/fixups-expr.s +@@ -0,0 +1,40 @@ ++# RUN: llvm-mc --filetype=obj --triple=loongarch64 %s \ ++# RUN: | llvm-readobj -r - | FileCheck %s ++ ++# Check that subtraction expressions are emitted as two relocations ++ ++.globl G1 ++.globl G2 ++.L1: ++G1: ++nop ++.L2: ++G2: ++ ++.data ++.8byte .L2-.L1 # CHECK: 0x0 R_LARCH_ADD64 .L2 0x0 ++ # CHECK: 0x0 R_LARCH_SUB64 .L1 0x0 ++.8byte G2-G1 # CHECK: 0x8 R_LARCH_ADD64 G2 0x0 ++ # CHECK: 0x8 R_LARCH_SUB64 G1 0x0 ++.4byte .L2-.L1 # CHECK: 0x10 R_LARCH_ADD32 .L2 0x0 ++ # CHECK: 0x10 R_LARCH_SUB32 .L1 0x0 ++.4byte G2-G1 # CHECK: 0x14 R_LARCH_ADD32 G2 0x0 ++ # CHECK: 0x14 R_LARCH_SUB32 G1 0x0 ++.2byte .L2-.L1 # CHECK: 0x18 R_LARCH_ADD16 .L2 0x0 ++ # CHECK: 0x18 R_LARCH_SUB16 .L1 0x0 ++.2byte G2-G1 # CHECK: 0x1A R_LARCH_ADD16 G2 0x0 ++ # CHECK: 0x1A R_LARCH_SUB16 G1 0x0 ++.byte .L2-.L1 # CHECK: 0x1C R_LARCH_ADD8 .L2 0x0 ++ # CHECK: 0x1C R_LARCH_SUB8 .L1 0x0 ++.byte G2-G1 # CHECK: 0x1D R_LARCH_ADD8 G2 0x0 ++ # CHECK: 0x1D R_LARCH_SUB8 G1 0x0 ++ ++.section .rodata.str.1 ++.L.str: ++.asciz "string" ++ ++.rodata ++.Lreltable: ++.word .L.str-.Lreltable # CHECK: 0x0 R_LARCH_ADD32 .L.str 0x0 ++ # CHECK: 0x0 R_LARCH_SUB32 .Lreltable 0x0 ++ +diff --git a/llvm/test/MC/LoongArch/invalid.s b/llvm/test/MC/LoongArch/invalid.s +new file mode 100644 +index 000000000..e0fc7ce4b +--- /dev/null ++++ b/llvm/test/MC/LoongArch/invalid.s +@@ -0,0 +1,50 @@ ++# RUN: not llvm-mc %s -triple=loongarch64-unknown-linux-gnu 2>&1 | FileCheck %s ++.text ++csrxchg $r6, $r0, 214 # CHECK: :[[@LINE]]:1: error: invalid operand ($zero) for instruction ++csrxchg $r6, $r1, 214 # CHECK: :[[@LINE]]:1: error: invalid operand ($r1) for instruction ++ ++## out-of-bound immediate ++### simm16 << 2 ++beq $r10, $r7, -0x20000-4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++beq $r10, $r7, 0x1FFFC+4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++bne $r10, $r7, -0x20000-4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++bne $r10, $r7, 0x1FFFC+4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++blt $r10, $r7, -0x20000-4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++blt $r10, $r7, 0x1FFFC+4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++bge $r10, $r7, -0x20000-4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++bge $r10, $r7, 0x1FFFC+4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++bltu $r10, $r7, -0x20000-4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++bltu $r10, $r7, 0x1FFFC+4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++bgeu $r10, $r7, -0x20000-4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++bgeu $r10, $r7, 0x1FFFC+4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++### simm21 << 2 ++beqz $r9, -0x400000-4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++beqz $r9, 0x3FFFFC+4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++bnez $r9, -0x400000-4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++bnez $r9, 0x3FFFFC+4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++bceqz $fcc6, -0x400000-4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++bceqz $fcc6, 0x3FFFFC+4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++bcnez $fcc6, -0x400000-4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++bcnez $fcc6, 0x3FFFFC+4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++### simm26 << 2 ++b -0x8000000-4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++b 0x7FFFFFC+4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++bl -0x8000000-4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++bl 0x7FFFFFC+4 # CHECK: :[[@LINE]]:1: error: branch target out of range ++ ++## unaligned immediate ++### simm16 << 2 ++beq $r10, $r7, 0x1FFFC+1 # CHECK: :[[@LINE]]:1: error: branch to misaligned address ++bne $r10, $r7, 0x1FFFC+1 # CHECK: :[[@LINE]]:1: error: branch to misaligned address ++blt $r10, $r7, 0x1FFFC+1 # CHECK: :[[@LINE]]:1: error: branch to misaligned address ++bge $r10, $r7, 0x1FFFC+1 # CHECK: :[[@LINE]]:1: error: branch to misaligned address ++bltu $r10, $r7, 0x1FFFC+1 # CHECK: :[[@LINE]]:1: error: branch to misaligned address ++bgeu $r10, $r7, 0x1FFFC+1 # CHECK: :[[@LINE]]:1: error: branch to misaligned address ++### simm21 << 2 ++beqz $r9, 0x3FFFFC+1 # CHECK: :[[@LINE]]:1: error: branch to misaligned address ++bnez $r9, 0x3FFFFC+1 # CHECK: :[[@LINE]]:1: error: branch to misaligned address ++bceqz $fcc6, 0x3FFFFC+1 # CHECK: :[[@LINE]]:1: error: branch to misaligned address ++bcnez $fcc6, 0x3FFFFC+1 # CHECK: :[[@LINE]]:1: error: branch to misaligned address ++### simm26 << 2 ++b 0x7FFFFFC+1 # CHECK: :[[@LINE]]:1: error: branch to misaligned address ++bl 0x7FFFFFC+1 # CHECK: :[[@LINE]]:1: error: branch to misaligned address +diff --git a/llvm/test/MC/LoongArch/lasx/absd.s b/llvm/test/MC/LoongArch/lasx/absd.s +deleted file mode 100644 +index 9ac1bece8..000000000 +--- a/llvm/test/MC/LoongArch/lasx/absd.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvabsd.b $xr22, $xr1, $xr17 +-# CHECK-INST: xvabsd.b $xr22, $xr1, $xr17 +-# CHECK-ENCODING: encoding: [0x36,0x44,0x60,0x74] +- +-xvabsd.h $xr17, $xr24, $xr9 +-# CHECK-INST: xvabsd.h $xr17, $xr24, $xr9 +-# CHECK-ENCODING: encoding: [0x11,0xa7,0x60,0x74] +- +-xvabsd.w $xr28, $xr9, $xr29 +-# CHECK-INST: xvabsd.w $xr28, $xr9, $xr29 +-# CHECK-ENCODING: encoding: [0x3c,0x75,0x61,0x74] +- +-xvabsd.d $xr30, $xr23, $xr19 +-# CHECK-INST: xvabsd.d $xr30, $xr23, $xr19 +-# CHECK-ENCODING: encoding: [0xfe,0xce,0x61,0x74] +- +-xvabsd.bu $xr16, $xr4, $xr15 +-# CHECK-INST: xvabsd.bu $xr16, $xr4, $xr15 +-# CHECK-ENCODING: encoding: [0x90,0x3c,0x62,0x74] +- +-xvabsd.hu $xr13, $xr23, $xr27 +-# CHECK-INST: xvabsd.hu $xr13, $xr23, $xr27 +-# CHECK-ENCODING: encoding: [0xed,0xee,0x62,0x74] +- +-xvabsd.wu $xr31, $xr18, $xr15 +-# CHECK-INST: xvabsd.wu $xr31, $xr18, $xr15 +-# CHECK-ENCODING: encoding: [0x5f,0x3e,0x63,0x74] +- +-xvabsd.du $xr26, $xr10, $xr4 +-# CHECK-INST: xvabsd.du $xr26, $xr10, $xr4 +-# CHECK-ENCODING: encoding: [0x5a,0x91,0x63,0x74] +diff --git a/llvm/test/MC/LoongArch/lasx/add.s b/llvm/test/MC/LoongArch/lasx/add.s +deleted file mode 100644 +index b7f92ef82..000000000 +--- a/llvm/test/MC/LoongArch/lasx/add.s ++++ /dev/null +@@ -1,24 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvadd.b $xr20, $xr19, $xr5 +-# CHECK-INST: xvadd.b $xr20, $xr19, $xr5 +-# CHECK-ENCODING: encoding: [0x74,0x16,0x0a,0x74] +- +-xvadd.h $xr24, $xr7, $xr14 +-# CHECK-INST: xvadd.h $xr24, $xr7, $xr14 +-# CHECK-ENCODING: encoding: [0xf8,0xb8,0x0a,0x74] +- +-xvadd.w $xr19, $xr1, $xr21 +-# CHECK-INST: xvadd.w $xr19, $xr1, $xr21 +-# CHECK-ENCODING: encoding: [0x33,0x54,0x0b,0x74] +- +-xvadd.d $xr19, $xr6, $xr13 +-# CHECK-INST: xvadd.d $xr19, $xr6, $xr13 +-# CHECK-ENCODING: encoding: [0xd3,0xb4,0x0b,0x74] +- +-xvadd.q $xr4, $xr28, $xr6 +-# CHECK-INST: xvadd.q $xr4, $xr28, $xr6 +-# CHECK-ENCODING: encoding: [0x84,0x1b,0x2d,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/adda.s b/llvm/test/MC/LoongArch/lasx/adda.s +deleted file mode 100644 +index 849c56017..000000000 +--- a/llvm/test/MC/LoongArch/lasx/adda.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvadda.b $xr10, $xr24, $xr27 +-# CHECK-INST: xvadda.b $xr10, $xr24, $xr27 +-# CHECK-ENCODING: encoding: [0x0a,0x6f,0x5c,0x74] +- +-xvadda.h $xr0, $xr28, $xr29 +-# CHECK-INST: xvadda.h $xr0, $xr28, $xr29 +-# CHECK-ENCODING: encoding: [0x80,0xf7,0x5c,0x74] +- +-xvadda.w $xr31, $xr9, $xr9 +-# CHECK-INST: xvadda.w $xr31, $xr9, $xr9 +-# CHECK-ENCODING: encoding: [0x3f,0x25,0x5d,0x74] +- +-xvadda.d $xr10, $xr1, $xr25 +-# CHECK-INST: xvadda.d $xr10, $xr1, $xr25 +-# CHECK-ENCODING: encoding: [0x2a,0xe4,0x5d,0x74] +diff --git a/llvm/test/MC/LoongArch/lasx/addi.s b/llvm/test/MC/LoongArch/lasx/addi.s +deleted file mode 100644 +index 0bd5cd965..000000000 +--- a/llvm/test/MC/LoongArch/lasx/addi.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvaddi.bu $xr1, $xr22, 2 +-# CHECK-INST: xvaddi.bu $xr1, $xr22, 2 +-# CHECK-ENCODING: encoding: [0xc1,0x0a,0x8a,0x76] +- +-xvaddi.hu $xr3, $xr10, 29 +-# CHECK-INST: xvaddi.hu $xr3, $xr10, 29 +-# CHECK-ENCODING: encoding: [0x43,0xf5,0x8a,0x76] +- +-xvaddi.wu $xr5, $xr11, 3 +-# CHECK-INST: xvaddi.wu $xr5, $xr11, 3 +-# CHECK-ENCODING: encoding: [0x65,0x0d,0x8b,0x76] +- +-xvaddi.du $xr6, $xr0, 7 +-# CHECK-INST: xvaddi.du $xr6, $xr0, 7 +-# CHECK-ENCODING: encoding: [0x06,0x9c,0x8b,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/addw.s b/llvm/test/MC/LoongArch/lasx/addw.s +deleted file mode 100644 +index c9fb22a70..000000000 +--- a/llvm/test/MC/LoongArch/lasx/addw.s ++++ /dev/null +@@ -1,100 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvaddwev.h.b $xr23, $xr30, $xr4 +-# CHECK-INST: xvaddwev.h.b $xr23, $xr30, $xr4 +-# CHECK-ENCODING: encoding: [0xd7,0x13,0x1e,0x74] +- +-xvaddwev.w.h $xr20, $xr19, $xr31 +-# CHECK-INST: xvaddwev.w.h $xr20, $xr19, $xr31 +-# CHECK-ENCODING: encoding: [0x74,0xfe,0x1e,0x74] +- +-xvaddwev.d.w $xr8, $xr9, $xr25 +-# CHECK-INST: xvaddwev.d.w $xr8, $xr9, $xr25 +-# CHECK-ENCODING: encoding: [0x28,0x65,0x1f,0x74] +- +-xvaddwev.q.d $xr29, $xr22, $xr29 +-# CHECK-INST: xvaddwev.q.d $xr29, $xr22, $xr29 +-# CHECK-ENCODING: encoding: [0xdd,0xf6,0x1f,0x74] +- +-xvaddwev.h.bu $xr30, $xr13, $xr26 +-# CHECK-INST: xvaddwev.h.bu $xr30, $xr13, $xr26 +-# CHECK-ENCODING: encoding: [0xbe,0x69,0x2e,0x74] +- +-xvaddwev.w.hu $xr15, $xr31, $xr16 +-# CHECK-INST: xvaddwev.w.hu $xr15, $xr31, $xr16 +-# CHECK-ENCODING: encoding: [0xef,0xc3,0x2e,0x74] +- +-xvaddwev.d.wu $xr16, $xr16, $xr20 +-# CHECK-INST: xvaddwev.d.wu $xr16, $xr16, $xr20 +-# CHECK-ENCODING: encoding: [0x10,0x52,0x2f,0x74] +- +-xvaddwev.q.du $xr10, $xr18, $xr18 +-# CHECK-INST: xvaddwev.q.du $xr10, $xr18, $xr18 +-# CHECK-ENCODING: encoding: [0x4a,0xca,0x2f,0x74] +- +-xvaddwev.h.bu.b $xr3, $xr7, $xr9 +-# CHECK-INST: xvaddwev.h.bu.b $xr3, $xr7, $xr9 +-# CHECK-ENCODING: encoding: [0xe3,0x24,0x3e,0x74] +- +-xvaddwev.w.hu.h $xr26, $xr16, $xr27 +-# CHECK-INST: xvaddwev.w.hu.h $xr26, $xr16, $xr27 +-# CHECK-ENCODING: encoding: [0x1a,0xee,0x3e,0x74] +- +-xvaddwev.d.wu.w $xr0, $xr13, $xr8 +-# CHECK-INST: xvaddwev.d.wu.w $xr0, $xr13, $xr8 +-# CHECK-ENCODING: encoding: [0xa0,0x21,0x3f,0x74] +- +-xvaddwev.q.du.d $xr19, $xr10, $xr3 +-# CHECK-INST: xvaddwev.q.du.d $xr19, $xr10, $xr3 +-# CHECK-ENCODING: encoding: [0x53,0x8d,0x3f,0x74] +- +-xvaddwod.h.b $xr14, $xr21, $xr24 +-# CHECK-INST: xvaddwod.h.b $xr14, $xr21, $xr24 +-# CHECK-ENCODING: encoding: [0xae,0x62,0x22,0x74] +- +-xvaddwod.w.h $xr19, $xr26, $xr23 +-# CHECK-INST: xvaddwod.w.h $xr19, $xr26, $xr23 +-# CHECK-ENCODING: encoding: [0x53,0xdf,0x22,0x74] +- +-xvaddwod.d.w $xr12, $xr9, $xr20 +-# CHECK-INST: xvaddwod.d.w $xr12, $xr9, $xr20 +-# CHECK-ENCODING: encoding: [0x2c,0x51,0x23,0x74] +- +-xvaddwod.q.d $xr11, $xr2, $xr8 +-# CHECK-INST: xvaddwod.q.d $xr11, $xr2, $xr8 +-# CHECK-ENCODING: encoding: [0x4b,0xa0,0x23,0x74] +- +-xvaddwod.h.bu $xr6, $xr6, $xr9 +-# CHECK-INST: xvaddwod.h.bu $xr6, $xr6, $xr9 +-# CHECK-ENCODING: encoding: [0xc6,0x24,0x32,0x74] +- +-xvaddwod.w.hu $xr1, $xr27, $xr25 +-# CHECK-INST: xvaddwod.w.hu $xr1, $xr27, $xr25 +-# CHECK-ENCODING: encoding: [0x61,0xe7,0x32,0x74] +- +-xvaddwod.d.wu $xr26, $xr19, $xr11 +-# CHECK-INST: xvaddwod.d.wu $xr26, $xr19, $xr11 +-# CHECK-ENCODING: encoding: [0x7a,0x2e,0x33,0x74] +- +-xvaddwod.q.du $xr21, $xr22, $xr8 +-# CHECK-INST: xvaddwod.q.du $xr21, $xr22, $xr8 +-# CHECK-ENCODING: encoding: [0xd5,0xa2,0x33,0x74] +- +-xvaddwod.h.bu.b $xr21, $xr26, $xr24 +-# CHECK-INST: xvaddwod.h.bu.b $xr21, $xr26, $xr24 +-# CHECK-ENCODING: encoding: [0x55,0x63,0x40,0x74] +- +-xvaddwod.w.hu.h $xr31, $xr6, $xr16 +-# CHECK-INST: xvaddwod.w.hu.h $xr31, $xr6, $xr16 +-# CHECK-ENCODING: encoding: [0xdf,0xc0,0x40,0x74] +- +-xvaddwod.d.wu.w $xr12, $xr28, $xr31 +-# CHECK-INST: xvaddwod.d.wu.w $xr12, $xr28, $xr31 +-# CHECK-ENCODING: encoding: [0x8c,0x7f,0x41,0x74] +- +-xvaddwod.q.du.d $xr29, $xr4, $xr12 +-# CHECK-INST: xvaddwod.q.du.d $xr29, $xr4, $xr12 +-# CHECK-ENCODING: encoding: [0x9d,0xb0,0x41,0x74] +diff --git a/llvm/test/MC/LoongArch/lasx/and.s b/llvm/test/MC/LoongArch/lasx/and.s +deleted file mode 100644 +index 8c865d342..000000000 +--- a/llvm/test/MC/LoongArch/lasx/and.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvand.v $xr14, $xr23, $xr19 +-# CHECK-INST: xvand.v $xr14, $xr23, $xr19 +-# CHECK-ENCODING: encoding: [0xee,0x4e,0x26,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/andi.s b/llvm/test/MC/LoongArch/lasx/andi.s +deleted file mode 100644 +index 6f198dcfd..000000000 +--- a/llvm/test/MC/LoongArch/lasx/andi.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvandi.b $xr11, $xr7, 66 +-# CHECK-INST: xvandi.b $xr11, $xr7, 66 +-# CHECK-ENCODING: encoding: [0xeb,0x08,0xd1,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/andn.s b/llvm/test/MC/LoongArch/lasx/andn.s +deleted file mode 100644 +index 815ecc373..000000000 +--- a/llvm/test/MC/LoongArch/lasx/andn.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvandn.v $xr3, $xr15, $xr3 +-# CHECK-INST: xvandn.v $xr3, $xr15, $xr3 +-# CHECK-ENCODING: encoding: [0xe3,0x0d,0x28,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/avg.s b/llvm/test/MC/LoongArch/lasx/avg.s +deleted file mode 100644 +index cdb2bd8cf..000000000 +--- a/llvm/test/MC/LoongArch/lasx/avg.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvavg.b $xr5, $xr30, $xr21 +-# CHECK-INST: xvavg.b $xr5, $xr30, $xr21 +-# CHECK-ENCODING: encoding: [0xc5,0x57,0x64,0x74] +- +-xvavg.h $xr18, $xr17, $xr21 +-# CHECK-INST: xvavg.h $xr18, $xr17, $xr21 +-# CHECK-ENCODING: encoding: [0x32,0xd6,0x64,0x74] +- +-xvavg.w $xr3, $xr23, $xr20 +-# CHECK-INST: xvavg.w $xr3, $xr23, $xr20 +-# CHECK-ENCODING: encoding: [0xe3,0x52,0x65,0x74] +- +-xvavg.d $xr27, $xr0, $xr27 +-# CHECK-INST: xvavg.d $xr27, $xr0, $xr27 +-# CHECK-ENCODING: encoding: [0x1b,0xec,0x65,0x74] +- +-xvavg.bu $xr11, $xr4, $xr16 +-# CHECK-INST: xvavg.bu $xr11, $xr4, $xr16 +-# CHECK-ENCODING: encoding: [0x8b,0x40,0x66,0x74] +- +-xvavg.hu $xr2, $xr1, $xr19 +-# CHECK-INST: xvavg.hu $xr2, $xr1, $xr19 +-# CHECK-ENCODING: encoding: [0x22,0xcc,0x66,0x74] +- +-xvavg.wu $xr27, $xr20, $xr27 +-# CHECK-INST: xvavg.wu $xr27, $xr20, $xr27 +-# CHECK-ENCODING: encoding: [0x9b,0x6e,0x67,0x74] +- +-xvavg.du $xr23, $xr20, $xr29 +-# CHECK-INST: xvavg.du $xr23, $xr20, $xr29 +-# CHECK-ENCODING: encoding: [0x97,0xf6,0x67,0x74] +diff --git a/llvm/test/MC/LoongArch/lasx/avgr.s b/llvm/test/MC/LoongArch/lasx/avgr.s +deleted file mode 100644 +index f28a48d24..000000000 +--- a/llvm/test/MC/LoongArch/lasx/avgr.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvavgr.b $xr29, $xr15, $xr7 +-# CHECK-INST: xvavgr.b $xr29, $xr15, $xr7 +-# CHECK-ENCODING: encoding: [0xfd,0x1d,0x68,0x74] +- +-xvavgr.h $xr0, $xr26, $xr15 +-# CHECK-INST: xvavgr.h $xr0, $xr26, $xr15 +-# CHECK-ENCODING: encoding: [0x40,0xbf,0x68,0x74] +- +-xvavgr.w $xr23, $xr0, $xr0 +-# CHECK-INST: xvavgr.w $xr23, $xr0, $xr0 +-# CHECK-ENCODING: encoding: [0x17,0x00,0x69,0x74] +- +-xvavgr.d $xr29, $xr23, $xr0 +-# CHECK-INST: xvavgr.d $xr29, $xr23, $xr0 +-# CHECK-ENCODING: encoding: [0xfd,0x82,0x69,0x74] +- +-xvavgr.bu $xr22, $xr2, $xr25 +-# CHECK-INST: xvavgr.bu $xr22, $xr2, $xr25 +-# CHECK-ENCODING: encoding: [0x56,0x64,0x6a,0x74] +- +-xvavgr.hu $xr25, $xr10, $xr21 +-# CHECK-INST: xvavgr.hu $xr25, $xr10, $xr21 +-# CHECK-ENCODING: encoding: [0x59,0xd5,0x6a,0x74] +- +-xvavgr.wu $xr17, $xr14, $xr3 +-# CHECK-INST: xvavgr.wu $xr17, $xr14, $xr3 +-# CHECK-ENCODING: encoding: [0xd1,0x0d,0x6b,0x74] +- +-xvavgr.du $xr2, $xr11, $xr13 +-# CHECK-INST: xvavgr.du $xr2, $xr11, $xr13 +-# CHECK-ENCODING: encoding: [0x62,0xb5,0x6b,0x74] +diff --git a/llvm/test/MC/LoongArch/lasx/bitclr.s b/llvm/test/MC/LoongArch/lasx/bitclr.s +deleted file mode 100644 +index 5cb47cdf3..000000000 +--- a/llvm/test/MC/LoongArch/lasx/bitclr.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvbitclr.b $xr24, $xr5, $xr14 +-# CHECK-INST: xvbitclr.b $xr24, $xr5, $xr14 +-# CHECK-ENCODING: encoding: [0xb8,0x38,0x0c,0x75] +- +-xvbitclr.h $xr30, $xr9, $xr13 +-# CHECK-INST: xvbitclr.h $xr30, $xr9, $xr13 +-# CHECK-ENCODING: encoding: [0x3e,0xb5,0x0c,0x75] +- +-xvbitclr.w $xr2, $xr3, $xr7 +-# CHECK-INST: xvbitclr.w $xr2, $xr3, $xr7 +-# CHECK-ENCODING: encoding: [0x62,0x1c,0x0d,0x75] +- +-xvbitclr.d $xr14, $xr5, $xr25 +-# CHECK-INST: xvbitclr.d $xr14, $xr5, $xr25 +-# CHECK-ENCODING: encoding: [0xae,0xe4,0x0d,0x75] +- +-xvbitclri.b $xr22, $xr26, 7 +-# CHECK-INST: xvbitclri.b $xr22, $xr26, 7 +-# CHECK-ENCODING: encoding: [0x56,0x3f,0x10,0x77] +- +-xvbitclri.h $xr2, $xr14, 13 +-# CHECK-INST: xvbitclri.h $xr2, $xr14, 13 +-# CHECK-ENCODING: encoding: [0xc2,0x75,0x10,0x77] +- +-xvbitclri.w $xr3, $xr2, 0 +-# CHECK-INST: xvbitclri.w $xr3, $xr2, 0 +-# CHECK-ENCODING: encoding: [0x43,0x80,0x10,0x77] +- +-xvbitclri.d $xr10, $xr12, 7 +-# CHECK-INST: xvbitclri.d $xr10, $xr12, 7 +-# CHECK-ENCODING: encoding: [0x8a,0x1d,0x11,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/bitrev.s b/llvm/test/MC/LoongArch/lasx/bitrev.s +deleted file mode 100644 +index aab31cd9d..000000000 +--- a/llvm/test/MC/LoongArch/lasx/bitrev.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvbitrev.b $xr16, $xr20, $xr3 +-# CHECK-INST: xvbitrev.b $xr16, $xr20, $xr3 +-# CHECK-ENCODING: encoding: [0x90,0x0e,0x10,0x75] +- +-xvbitrev.h $xr16, $xr3, $xr20 +-# CHECK-INST: xvbitrev.h $xr16, $xr3, $xr20 +-# CHECK-ENCODING: encoding: [0x70,0xd0,0x10,0x75] +- +-xvbitrev.w $xr24, $xr26, $xr23 +-# CHECK-INST: xvbitrev.w $xr24, $xr26, $xr23 +-# CHECK-ENCODING: encoding: [0x58,0x5f,0x11,0x75] +- +-xvbitrev.d $xr13, $xr1, $xr27 +-# CHECK-INST: xvbitrev.d $xr13, $xr1, $xr27 +-# CHECK-ENCODING: encoding: [0x2d,0xec,0x11,0x75] +- +-xvbitrevi.b $xr7, $xr11, 5 +-# CHECK-INST: xvbitrevi.b $xr7, $xr11, 5 +-# CHECK-ENCODING: encoding: [0x67,0x35,0x18,0x77] +- +-xvbitrevi.h $xr1, $xr5, 15 +-# CHECK-INST: xvbitrevi.h $xr1, $xr5, 15 +-# CHECK-ENCODING: encoding: [0xa1,0x7c,0x18,0x77] +- +-xvbitrevi.w $xr13, $xr21, 18 +-# CHECK-INST: xvbitrevi.w $xr13, $xr21, 18 +-# CHECK-ENCODING: encoding: [0xad,0xca,0x18,0x77] +- +-xvbitrevi.d $xr1, $xr3, 9 +-# CHECK-INST: xvbitrevi.d $xr1, $xr3, 9 +-# CHECK-ENCODING: encoding: [0x61,0x24,0x19,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/bitsel.s b/llvm/test/MC/LoongArch/lasx/bitsel.s +deleted file mode 100644 +index e61a4c277..000000000 +--- a/llvm/test/MC/LoongArch/lasx/bitsel.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvbitsel.v $xr18, $xr29, $xr15, $xr21 +-# CHECK-INST: xvbitsel.v $xr18, $xr29, $xr15, $xr21 +-# CHECK-ENCODING: encoding: [0xb2,0xbf,0x2a,0x0d] +diff --git a/llvm/test/MC/LoongArch/lasx/bitseli.s b/llvm/test/MC/LoongArch/lasx/bitseli.s +deleted file mode 100644 +index 18212e996..000000000 +--- a/llvm/test/MC/LoongArch/lasx/bitseli.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvbitseli.b $xr13, $xr21, 121 +-# CHECK-INST: xvbitseli.b $xr13, $xr21, 121 +-# CHECK-ENCODING: encoding: [0xad,0xe6,0xc5,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/bitset.s b/llvm/test/MC/LoongArch/lasx/bitset.s +deleted file mode 100644 +index 65eaef758..000000000 +--- a/llvm/test/MC/LoongArch/lasx/bitset.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvbitset.b $xr6, $xr16, $xr28 +-# CHECK-INST: xvbitset.b $xr6, $xr16, $xr28 +-# CHECK-ENCODING: encoding: [0x06,0x72,0x0e,0x75] +- +-xvbitset.h $xr5, $xr13, $xr31 +-# CHECK-INST: xvbitset.h $xr5, $xr13, $xr31 +-# CHECK-ENCODING: encoding: [0xa5,0xfd,0x0e,0x75] +- +-xvbitset.w $xr7, $xr28, $xr8 +-# CHECK-INST: xvbitset.w $xr7, $xr28, $xr8 +-# CHECK-ENCODING: encoding: [0x87,0x23,0x0f,0x75] +- +-xvbitset.d $xr4, $xr16, $xr12 +-# CHECK-INST: xvbitset.d $xr4, $xr16, $xr12 +-# CHECK-ENCODING: encoding: [0x04,0xb2,0x0f,0x75] +- +-xvbitseti.b $xr26, $xr3, 0 +-# CHECK-INST: xvbitseti.b $xr26, $xr3, 0 +-# CHECK-ENCODING: encoding: [0x7a,0x20,0x14,0x77] +- +-xvbitseti.h $xr9, $xr19, 9 +-# CHECK-INST: xvbitseti.h $xr9, $xr19, 9 +-# CHECK-ENCODING: encoding: [0x69,0x66,0x14,0x77] +- +-xvbitseti.w $xr12, $xr19, 2 +-# CHECK-INST: xvbitseti.w $xr12, $xr19, 2 +-# CHECK-ENCODING: encoding: [0x6c,0x8a,0x14,0x77] +- +-xvbitseti.d $xr20, $xr7, 2 +-# CHECK-INST: xvbitseti.d $xr20, $xr7, 2 +-# CHECK-ENCODING: encoding: [0xf4,0x08,0x15,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/bsll.s b/llvm/test/MC/LoongArch/lasx/bsll.s +deleted file mode 100644 +index 3eb829748..000000000 +--- a/llvm/test/MC/LoongArch/lasx/bsll.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvbsll.v $xr14, $xr21, 20 +-# CHECK-INST: xvbsll.v $xr14, $xr21, 20 +-# CHECK-ENCODING: encoding: [0xae,0x52,0x8e,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/bsrl.s b/llvm/test/MC/LoongArch/lasx/bsrl.s +deleted file mode 100644 +index 5481ca24f..000000000 +--- a/llvm/test/MC/LoongArch/lasx/bsrl.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvbsrl.v $xr4, $xr5, 29 +-# CHECK-INST: xvbsrl.v $xr4, $xr5, 29 +-# CHECK-ENCODING: encoding: [0xa4,0xf4,0x8e,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/clo.s b/llvm/test/MC/LoongArch/lasx/clo.s +deleted file mode 100644 +index 5b2b093de..000000000 +--- a/llvm/test/MC/LoongArch/lasx/clo.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvclo.b $xr9, $xr12 +-# CHECK-INST: xvclo.b $xr9, $xr12 +-# CHECK-ENCODING: encoding: [0x89,0x01,0x9c,0x76] +- +-xvclo.h $xr16, $xr14 +-# CHECK-INST: xvclo.h $xr16, $xr14 +-# CHECK-ENCODING: encoding: [0xd0,0x05,0x9c,0x76] +- +-xvclo.w $xr30, $xr18 +-# CHECK-INST: xvclo.w $xr30, $xr18 +-# CHECK-ENCODING: encoding: [0x5e,0x0a,0x9c,0x76] +- +-xvclo.d $xr31, $xr5 +-# CHECK-INST: xvclo.d $xr31, $xr5 +-# CHECK-ENCODING: encoding: [0xbf,0x0c,0x9c,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/clz.s b/llvm/test/MC/LoongArch/lasx/clz.s +deleted file mode 100644 +index b61b9193a..000000000 +--- a/llvm/test/MC/LoongArch/lasx/clz.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvclz.b $xr5, $xr6 +-# CHECK-INST: xvclz.b $xr5, $xr6 +-# CHECK-ENCODING: encoding: [0xc5,0x10,0x9c,0x76] +- +-xvclz.h $xr4, $xr7 +-# CHECK-INST: xvclz.h $xr4, $xr7 +-# CHECK-ENCODING: encoding: [0xe4,0x14,0x9c,0x76] +- +-xvclz.w $xr12, $xr0 +-# CHECK-INST: xvclz.w $xr12, $xr0 +-# CHECK-ENCODING: encoding: [0x0c,0x18,0x9c,0x76] +- +-xvclz.d $xr1, $xr0 +-# CHECK-INST: xvclz.d $xr1, $xr0 +-# CHECK-ENCODING: encoding: [0x01,0x1c,0x9c,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/div.s b/llvm/test/MC/LoongArch/lasx/div.s +deleted file mode 100644 +index c2d721d81..000000000 +--- a/llvm/test/MC/LoongArch/lasx/div.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvdiv.b $xr9, $xr25, $xr8 +-# CHECK-INST: xvdiv.b $xr9, $xr25, $xr8 +-# CHECK-ENCODING: encoding: [0x29,0x23,0xe0,0x74] +- +-xvdiv.h $xr18, $xr1, $xr27 +-# CHECK-INST: xvdiv.h $xr18, $xr1, $xr27 +-# CHECK-ENCODING: encoding: [0x32,0xec,0xe0,0x74] +- +-xvdiv.w $xr5, $xr26, $xr27 +-# CHECK-INST: xvdiv.w $xr5, $xr26, $xr27 +-# CHECK-ENCODING: encoding: [0x45,0x6f,0xe1,0x74] +- +-xvdiv.d $xr27, $xr26, $xr12 +-# CHECK-INST: xvdiv.d $xr27, $xr26, $xr12 +-# CHECK-ENCODING: encoding: [0x5b,0xb3,0xe1,0x74] +- +-xvdiv.bu $xr0, $xr22, $xr30 +-# CHECK-INST: xvdiv.bu $xr0, $xr22, $xr30 +-# CHECK-ENCODING: encoding: [0xc0,0x7a,0xe4,0x74] +- +-xvdiv.hu $xr31, $xr23, $xr25 +-# CHECK-INST: xvdiv.hu $xr31, $xr23, $xr25 +-# CHECK-ENCODING: encoding: [0xff,0xe6,0xe4,0x74] +- +-xvdiv.wu $xr1, $xr25, $xr7 +-# CHECK-INST: xvdiv.wu $xr1, $xr25, $xr7 +-# CHECK-ENCODING: encoding: [0x21,0x1f,0xe5,0x74] +- +-xvdiv.du $xr7, $xr25, $xr7 +-# CHECK-INST: xvdiv.du $xr7, $xr25, $xr7 +-# CHECK-ENCODING: encoding: [0x27,0x9f,0xe5,0x74] +diff --git a/llvm/test/MC/LoongArch/lasx/ext2xv.s b/llvm/test/MC/LoongArch/lasx/ext2xv.s +deleted file mode 100644 +index 98310657d..000000000 +--- a/llvm/test/MC/LoongArch/lasx/ext2xv.s ++++ /dev/null +@@ -1,52 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vext2xv.h.b $xr30, $xr19 +-# CHECK-INST: vext2xv.h.b $xr30, $xr19 +-# CHECK-ENCODING: encoding: [0x7e,0x12,0x9f,0x76] +- +-vext2xv.w.b $xr27, $xr5 +-# CHECK-INST: vext2xv.w.b $xr27, $xr5 +-# CHECK-ENCODING: encoding: [0xbb,0x14,0x9f,0x76] +- +-vext2xv.d.b $xr25, $xr25 +-# CHECK-INST: vext2xv.d.b $xr25, $xr25 +-# CHECK-ENCODING: encoding: [0x39,0x1b,0x9f,0x76] +- +-vext2xv.w.h $xr20, $xr20 +-# CHECK-INST: vext2xv.w.h $xr20, $xr20 +-# CHECK-ENCODING: encoding: [0x94,0x1e,0x9f,0x76] +- +-vext2xv.d.h $xr8, $xr19 +-# CHECK-INST: vext2xv.d.h $xr8, $xr19 +-# CHECK-ENCODING: encoding: [0x68,0x22,0x9f,0x76] +- +-vext2xv.d.w $xr4, $xr25 +-# CHECK-INST: vext2xv.d.w $xr4, $xr25 +-# CHECK-ENCODING: encoding: [0x24,0x27,0x9f,0x76] +- +-vext2xv.hu.bu $xr25, $xr12 +-# CHECK-INST: vext2xv.hu.bu $xr25, $xr12 +-# CHECK-ENCODING: encoding: [0x99,0x29,0x9f,0x76] +- +-vext2xv.wu.bu $xr31, $xr13 +-# CHECK-INST: vext2xv.wu.bu $xr31, $xr13 +-# CHECK-ENCODING: encoding: [0xbf,0x2d,0x9f,0x76] +- +-vext2xv.du.bu $xr12, $xr25 +-# CHECK-INST: vext2xv.du.bu $xr12, $xr25 +-# CHECK-ENCODING: encoding: [0x2c,0x33,0x9f,0x76] +- +-vext2xv.wu.hu $xr23, $xr12 +-# CHECK-INST: vext2xv.wu.hu $xr23, $xr12 +-# CHECK-ENCODING: encoding: [0x97,0x35,0x9f,0x76] +- +-vext2xv.du.hu $xr18, $xr6 +-# CHECK-INST: vext2xv.du.hu $xr18, $xr6 +-# CHECK-ENCODING: encoding: [0xd2,0x38,0x9f,0x76] +- +-vext2xv.du.wu $xr10, $xr21 +-# CHECK-INST: vext2xv.du.wu $xr10, $xr21 +-# CHECK-ENCODING: encoding: [0xaa,0x3e,0x9f,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/exth.s b/llvm/test/MC/LoongArch/lasx/exth.s +deleted file mode 100644 +index 1ce1e58e3..000000000 +--- a/llvm/test/MC/LoongArch/lasx/exth.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvexth.h.b $xr15, $xr10 +-# CHECK-INST: xvexth.h.b $xr15, $xr10 +-# CHECK-ENCODING: encoding: [0x4f,0xe1,0x9e,0x76] +- +-xvexth.w.h $xr26, $xr11 +-# CHECK-INST: xvexth.w.h $xr26, $xr11 +-# CHECK-ENCODING: encoding: [0x7a,0xe5,0x9e,0x76] +- +-xvexth.d.w $xr2, $xr27 +-# CHECK-INST: xvexth.d.w $xr2, $xr27 +-# CHECK-ENCODING: encoding: [0x62,0xeb,0x9e,0x76] +- +-xvexth.q.d $xr22, $xr25 +-# CHECK-INST: xvexth.q.d $xr22, $xr25 +-# CHECK-ENCODING: encoding: [0x36,0xef,0x9e,0x76] +- +-xvexth.hu.bu $xr21, $xr30 +-# CHECK-INST: xvexth.hu.bu $xr21, $xr30 +-# CHECK-ENCODING: encoding: [0xd5,0xf3,0x9e,0x76] +- +-xvexth.wu.hu $xr28, $xr11 +-# CHECK-INST: xvexth.wu.hu $xr28, $xr11 +-# CHECK-ENCODING: encoding: [0x7c,0xf5,0x9e,0x76] +- +-xvexth.du.wu $xr27, $xr25 +-# CHECK-INST: xvexth.du.wu $xr27, $xr25 +-# CHECK-ENCODING: encoding: [0x3b,0xfb,0x9e,0x76] +- +-xvexth.qu.du $xr16, $xr28 +-# CHECK-INST: xvexth.qu.du $xr16, $xr28 +-# CHECK-ENCODING: encoding: [0x90,0xff,0x9e,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/extl.s b/llvm/test/MC/LoongArch/lasx/extl.s +deleted file mode 100644 +index d6644e00c..000000000 +--- a/llvm/test/MC/LoongArch/lasx/extl.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvextl.q.d $xr29, $xr12 +-# CHECK-INST: xvextl.q.d $xr29, $xr12 +-# CHECK-ENCODING: encoding: [0x9d,0x01,0x09,0x77] +- +-xvextl.qu.du $xr27, $xr20 +-# CHECK-INST: xvextl.qu.du $xr27, $xr20 +-# CHECK-ENCODING: encoding: [0x9b,0x02,0x0d,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/extrins.s b/llvm/test/MC/LoongArch/lasx/extrins.s +deleted file mode 100644 +index 855571049..000000000 +--- a/llvm/test/MC/LoongArch/lasx/extrins.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvextrins.b $xr30, $xr23, 252 +-# CHECK-INST: xvextrins.b $xr30, $xr23, 252 +-# CHECK-ENCODING: encoding: [0xfe,0xf2,0x8f,0x77] +- +-xvextrins.h $xr0, $xr13, 200 +-# CHECK-INST: xvextrins.h $xr0, $xr13, 200 +-# CHECK-ENCODING: encoding: [0xa0,0x21,0x8b,0x77] +- +-xvextrins.w $xr14, $xr21, 152 +-# CHECK-INST: xvextrins.w $xr14, $xr21, 152 +-# CHECK-ENCODING: encoding: [0xae,0x62,0x86,0x77] +- +-xvextrins.d $xr31, $xr30, 135 +-# CHECK-INST: xvextrins.d $xr31, $xr30, 135 +-# CHECK-ENCODING: encoding: [0xdf,0x1f,0x82,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/fadd.s b/llvm/test/MC/LoongArch/lasx/fadd.s +deleted file mode 100644 +index e56beb91f..000000000 +--- a/llvm/test/MC/LoongArch/lasx/fadd.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvfadd.s $xr6, $xr21, $xr15 +-# CHECK-INST: xvfadd.s $xr6, $xr21, $xr15 +-# CHECK-ENCODING: encoding: [0xa6,0xbe,0x30,0x75] +- +-xvfadd.d $xr27, $xr8, $xr1 +-# CHECK-INST: xvfadd.d $xr27, $xr8, $xr1 +-# CHECK-ENCODING: encoding: [0x1b,0x05,0x31,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/fclass.s b/llvm/test/MC/LoongArch/lasx/fclass.s +deleted file mode 100644 +index 424f77be6..000000000 +--- a/llvm/test/MC/LoongArch/lasx/fclass.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvfclass.s $xr3, $xr7 +-# CHECK-INST: xvfclass.s $xr3, $xr7 +-# CHECK-ENCODING: encoding: [0xe3,0xd4,0x9c,0x76] +- +-xvfclass.d $xr22, $xr10 +-# CHECK-INST: xvfclass.d $xr22, $xr10 +-# CHECK-ENCODING: encoding: [0x56,0xd9,0x9c,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/fcmp.s b/llvm/test/MC/LoongArch/lasx/fcmp.s +deleted file mode 100644 +index 71759e7f3..000000000 +--- a/llvm/test/MC/LoongArch/lasx/fcmp.s ++++ /dev/null +@@ -1,180 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvfcmp.caf.s $xr1, $xr8, $xr31 +-# CHECK-INST: xvfcmp.caf.s $xr1, $xr8, $xr31 +-# CHECK-ENCODING: encoding: [0x01,0x7d,0x90,0x0c] +- +-xvfcmp.caf.d $xr19, $xr31, $xr20 +-# CHECK-INST: xvfcmp.caf.d $xr19, $xr31, $xr20 +-# CHECK-ENCODING: encoding: [0xf3,0x53,0xa0,0x0c] +- +-xvfcmp.cun.s $xr8, $xr9, $xr29 +-# CHECK-INST: xvfcmp.cun.s $xr8, $xr9, $xr29 +-# CHECK-ENCODING: encoding: [0x28,0x75,0x94,0x0c] +- +-xvfcmp.cun.d $xr19, $xr22, $xr28 +-# CHECK-INST: xvfcmp.cun.d $xr19, $xr22, $xr28 +-# CHECK-ENCODING: encoding: [0xd3,0x72,0xa4,0x0c] +- +-xvfcmp.ceq.s $xr0, $xr1, $xr0 +-# CHECK-INST: xvfcmp.ceq.s $xr0, $xr1, $xr0 +-# CHECK-ENCODING: encoding: [0x20,0x00,0x92,0x0c] +- +-xvfcmp.ceq.d $xr29, $xr23, $xr20 +-# CHECK-INST: xvfcmp.ceq.d $xr29, $xr23, $xr20 +-# CHECK-ENCODING: encoding: [0xfd,0x52,0xa2,0x0c] +- +-xvfcmp.cueq.s $xr5, $xr13, $xr31 +-# CHECK-INST: xvfcmp.cueq.s $xr5, $xr13, $xr31 +-# CHECK-ENCODING: encoding: [0xa5,0x7d,0x96,0x0c] +- +-xvfcmp.cueq.d $xr4, $xr22, $xr7 +-# CHECK-INST: xvfcmp.cueq.d $xr4, $xr22, $xr7 +-# CHECK-ENCODING: encoding: [0xc4,0x1e,0xa6,0x0c] +- +-xvfcmp.clt.s $xr4, $xr9, $xr1 +-# CHECK-INST: xvfcmp.clt.s $xr4, $xr9, $xr1 +-# CHECK-ENCODING: encoding: [0x24,0x05,0x91,0x0c] +- +-xvfcmp.clt.d $xr19, $xr4, $xr21 +-# CHECK-INST: xvfcmp.clt.d $xr19, $xr4, $xr21 +-# CHECK-ENCODING: encoding: [0x93,0x54,0xa1,0x0c] +- +-xvfcmp.cult.s $xr15, $xr17, $xr3 +-# CHECK-INST: xvfcmp.cult.s $xr15, $xr17, $xr3 +-# CHECK-ENCODING: encoding: [0x2f,0x0e,0x95,0x0c] +- +-xvfcmp.cult.d $xr20, $xr17, $xr6 +-# CHECK-INST: xvfcmp.cult.d $xr20, $xr17, $xr6 +-# CHECK-ENCODING: encoding: [0x34,0x1a,0xa5,0x0c] +- +-xvfcmp.cle.s $xr22, $xr22, $xr15 +-# CHECK-INST: xvfcmp.cle.s $xr22, $xr22, $xr15 +-# CHECK-ENCODING: encoding: [0xd6,0x3e,0x93,0x0c] +- +-xvfcmp.cle.d $xr21, $xr25, $xr12 +-# CHECK-INST: xvfcmp.cle.d $xr21, $xr25, $xr12 +-# CHECK-ENCODING: encoding: [0x35,0x33,0xa3,0x0c] +- +-xvfcmp.cule.s $xr1, $xr2, $xr29 +-# CHECK-INST: xvfcmp.cule.s $xr1, $xr2, $xr29 +-# CHECK-ENCODING: encoding: [0x41,0x74,0x97,0x0c] +- +-xvfcmp.cule.d $xr0, $xr5, $xr11 +-# CHECK-INST: xvfcmp.cule.d $xr0, $xr5, $xr11 +-# CHECK-ENCODING: encoding: [0xa0,0x2c,0xa7,0x0c] +- +-xvfcmp.cne.s $xr7, $xr17, $xr26 +-# CHECK-INST: xvfcmp.cne.s $xr7, $xr17, $xr26 +-# CHECK-ENCODING: encoding: [0x27,0x6a,0x98,0x0c] +- +-xvfcmp.cne.d $xr18, $xr25, $xr0 +-# CHECK-INST: xvfcmp.cne.d $xr18, $xr25, $xr0 +-# CHECK-ENCODING: encoding: [0x32,0x03,0xa8,0x0c] +- +-xvfcmp.cor.s $xr1, $xr2, $xr14 +-# CHECK-INST: xvfcmp.cor.s $xr1, $xr2, $xr14 +-# CHECK-ENCODING: encoding: [0x41,0x38,0x9a,0x0c] +- +-xvfcmp.cor.d $xr12, $xr19, $xr23 +-# CHECK-INST: xvfcmp.cor.d $xr12, $xr19, $xr23 +-# CHECK-ENCODING: encoding: [0x6c,0x5e,0xaa,0x0c] +- +-xvfcmp.cune.s $xr21, $xr17, $xr4 +-# CHECK-INST: xvfcmp.cune.s $xr21, $xr17, $xr4 +-# CHECK-ENCODING: encoding: [0x35,0x12,0x9c,0x0c] +- +-xvfcmp.cune.d $xr20, $xr30, $xr12 +-# CHECK-INST: xvfcmp.cune.d $xr20, $xr30, $xr12 +-# CHECK-ENCODING: encoding: [0xd4,0x33,0xac,0x0c] +- +-xvfcmp.saf.s $xr23, $xr11, $xr2 +-# CHECK-INST: xvfcmp.saf.s $xr23, $xr11, $xr2 +-# CHECK-ENCODING: encoding: [0x77,0x89,0x90,0x0c] +- +-xvfcmp.saf.d $xr7, $xr12, $xr7 +-# CHECK-INST: xvfcmp.saf.d $xr7, $xr12, $xr7 +-# CHECK-ENCODING: encoding: [0x87,0x9d,0xa0,0x0c] +- +-xvfcmp.sun.s $xr0, $xr7, $xr30 +-# CHECK-INST: xvfcmp.sun.s $xr0, $xr7, $xr30 +-# CHECK-ENCODING: encoding: [0xe0,0xf8,0x94,0x0c] +- +-xvfcmp.sun.d $xr4, $xr11, $xr30 +-# CHECK-INST: xvfcmp.sun.d $xr4, $xr11, $xr30 +-# CHECK-ENCODING: encoding: [0x64,0xf9,0xa4,0x0c] +- +-xvfcmp.seq.s $xr15, $xr23, $xr27 +-# CHECK-INST: xvfcmp.seq.s $xr15, $xr23, $xr27 +-# CHECK-ENCODING: encoding: [0xef,0xee,0x92,0x0c] +- +-xvfcmp.seq.d $xr15, $xr22, $xr3 +-# CHECK-INST: xvfcmp.seq.d $xr15, $xr22, $xr3 +-# CHECK-ENCODING: encoding: [0xcf,0x8e,0xa2,0x0c] +- +-xvfcmp.sueq.s $xr12, $xr26, $xr9 +-# CHECK-INST: xvfcmp.sueq.s $xr12, $xr26, $xr9 +-# CHECK-ENCODING: encoding: [0x4c,0xa7,0x96,0x0c] +- +-xvfcmp.sueq.d $xr5, $xr18, $xr17 +-# CHECK-INST: xvfcmp.sueq.d $xr5, $xr18, $xr17 +-# CHECK-ENCODING: encoding: [0x45,0xc6,0xa6,0x0c] +- +-xvfcmp.slt.s $xr25, $xr18, $xr31 +-# CHECK-INST: xvfcmp.slt.s $xr25, $xr18, $xr31 +-# CHECK-ENCODING: encoding: [0x59,0xfe,0x91,0x0c] +- +-xvfcmp.slt.d $xr17, $xr26, $xr24 +-# CHECK-INST: xvfcmp.slt.d $xr17, $xr26, $xr24 +-# CHECK-ENCODING: encoding: [0x51,0xe3,0xa1,0x0c] +- +-xvfcmp.sult.s $xr8, $xr15, $xr18 +-# CHECK-INST: xvfcmp.sult.s $xr8, $xr15, $xr18 +-# CHECK-ENCODING: encoding: [0xe8,0xc9,0x95,0x0c] +- +-xvfcmp.sult.d $xr4, $xr4, $xr5 +-# CHECK-INST: xvfcmp.sult.d $xr4, $xr4, $xr5 +-# CHECK-ENCODING: encoding: [0x84,0x94,0xa5,0x0c] +- +-xvfcmp.sle.s $xr1, $xr5, $xr16 +-# CHECK-INST: xvfcmp.sle.s $xr1, $xr5, $xr16 +-# CHECK-ENCODING: encoding: [0xa1,0xc0,0x93,0x0c] +- +-xvfcmp.sle.d $xr3, $xr1, $xr23 +-# CHECK-INST: xvfcmp.sle.d $xr3, $xr1, $xr23 +-# CHECK-ENCODING: encoding: [0x23,0xdc,0xa3,0x0c] +- +-xvfcmp.sule.s $xr23, $xr11, $xr1 +-# CHECK-INST: xvfcmp.sule.s $xr23, $xr11, $xr1 +-# CHECK-ENCODING: encoding: [0x77,0x85,0x97,0x0c] +- +-xvfcmp.sule.d $xr11, $xr10, $xr17 +-# CHECK-INST: xvfcmp.sule.d $xr11, $xr10, $xr17 +-# CHECK-ENCODING: encoding: [0x4b,0xc5,0xa7,0x0c] +- +-xvfcmp.sne.s $xr27, $xr12, $xr30 +-# CHECK-INST: xvfcmp.sne.s $xr27, $xr12, $xr30 +-# CHECK-ENCODING: encoding: [0x9b,0xf9,0x98,0x0c] +- +-xvfcmp.sne.d $xr20, $xr20, $xr17 +-# CHECK-INST: xvfcmp.sne.d $xr20, $xr20, $xr17 +-# CHECK-ENCODING: encoding: [0x94,0xc6,0xa8,0x0c] +- +-xvfcmp.sor.s $xr11, $xr13, $xr2 +-# CHECK-INST: xvfcmp.sor.s $xr11, $xr13, $xr2 +-# CHECK-ENCODING: encoding: [0xab,0x89,0x9a,0x0c] +- +-xvfcmp.sor.d $xr6, $xr28, $xr6 +-# CHECK-INST: xvfcmp.sor.d $xr6, $xr28, $xr6 +-# CHECK-ENCODING: encoding: [0x86,0x9b,0xaa,0x0c] +- +-xvfcmp.sune.s $xr11, $xr16, $xr8 +-# CHECK-INST: xvfcmp.sune.s $xr11, $xr16, $xr8 +-# CHECK-ENCODING: encoding: [0x0b,0xa2,0x9c,0x0c] +- +-xvfcmp.sune.d $xr30, $xr5, $xr27 +-# CHECK-INST: xvfcmp.sune.d $xr30, $xr5, $xr27 +-# CHECK-ENCODING: encoding: [0xbe,0xec,0xac,0x0c] +diff --git a/llvm/test/MC/LoongArch/lasx/fcvt.s b/llvm/test/MC/LoongArch/lasx/fcvt.s +deleted file mode 100644 +index da919bd37..000000000 +--- a/llvm/test/MC/LoongArch/lasx/fcvt.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvfcvt.h.s $xr9, $xr17, $xr23 +-# CHECK-INST: xvfcvt.h.s $xr9, $xr17, $xr23 +-# CHECK-ENCODING: encoding: [0x29,0x5e,0x46,0x75] +- +-xvfcvt.s.d $xr27, $xr10, $xr29 +-# CHECK-INST: xvfcvt.s.d $xr27, $xr10, $xr29 +-# CHECK-ENCODING: encoding: [0x5b,0xf5,0x46,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/fcvth.s b/llvm/test/MC/LoongArch/lasx/fcvth.s +deleted file mode 100644 +index 099d5dd46..000000000 +--- a/llvm/test/MC/LoongArch/lasx/fcvth.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvfcvth.s.h $xr9, $xr25 +-# CHECK-INST: xvfcvth.s.h $xr9, $xr25 +-# CHECK-ENCODING: encoding: [0x29,0xef,0x9d,0x76] +- +-xvfcvth.d.s $xr29, $xr17 +-# CHECK-INST: xvfcvth.d.s $xr29, $xr17 +-# CHECK-ENCODING: encoding: [0x3d,0xf6,0x9d,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/fcvtl.s b/llvm/test/MC/LoongArch/lasx/fcvtl.s +deleted file mode 100644 +index 2c9941cc6..000000000 +--- a/llvm/test/MC/LoongArch/lasx/fcvtl.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvfcvtl.s.h $xr16, $xr14 +-# CHECK-INST: xvfcvtl.s.h $xr16, $xr14 +-# CHECK-ENCODING: encoding: [0xd0,0xe9,0x9d,0x76] +- +-xvfcvtl.d.s $xr24, $xr5 +-# CHECK-INST: xvfcvtl.d.s $xr24, $xr5 +-# CHECK-ENCODING: encoding: [0xb8,0xf0,0x9d,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/fdiv.s b/llvm/test/MC/LoongArch/lasx/fdiv.s +deleted file mode 100644 +index 133690f94..000000000 +--- a/llvm/test/MC/LoongArch/lasx/fdiv.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvfdiv.s $xr29, $xr5, $xr12 +-# CHECK-INST: xvfdiv.s $xr29, $xr5, $xr12 +-# CHECK-ENCODING: encoding: [0xbd,0xb0,0x3a,0x75] +- +-xvfdiv.d $xr31, $xr10, $xr30 +-# CHECK-INST: xvfdiv.d $xr31, $xr10, $xr30 +-# CHECK-ENCODING: encoding: [0x5f,0x79,0x3b,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/ffint.s b/llvm/test/MC/LoongArch/lasx/ffint.s +deleted file mode 100644 +index 7cd663a43..000000000 +--- a/llvm/test/MC/LoongArch/lasx/ffint.s ++++ /dev/null +@@ -1,32 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvffint.s.w $xr3, $xr5 +-# CHECK-INST: xvffint.s.w $xr3, $xr5 +-# CHECK-ENCODING: encoding: [0xa3,0x00,0x9e,0x76] +- +-xvffint.d.l $xr5, $xr19 +-# CHECK-INST: xvffint.d.l $xr5, $xr19 +-# CHECK-ENCODING: encoding: [0x65,0x0a,0x9e,0x76] +- +-xvffint.s.wu $xr3, $xr28 +-# CHECK-INST: xvffint.s.wu $xr3, $xr28 +-# CHECK-ENCODING: encoding: [0x83,0x07,0x9e,0x76] +- +-xvffint.d.lu $xr31, $xr29 +-# CHECK-INST: xvffint.d.lu $xr31, $xr29 +-# CHECK-ENCODING: encoding: [0xbf,0x0f,0x9e,0x76] +- +-xvffintl.d.w $xr2, $xr7 +-# CHECK-INST: xvffintl.d.w $xr2, $xr7 +-# CHECK-ENCODING: encoding: [0xe2,0x10,0x9e,0x76] +- +-xvffinth.d.w $xr7, $xr28 +-# CHECK-INST: xvffinth.d.w $xr7, $xr28 +-# CHECK-ENCODING: encoding: [0x87,0x17,0x9e,0x76] +- +-xvffint.s.l $xr10, $xr27, $xr3 +-# CHECK-INST: xvffint.s.l $xr10, $xr27, $xr3 +-# CHECK-ENCODING: encoding: [0x6a,0x0f,0x48,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/flogb.s b/llvm/test/MC/LoongArch/lasx/flogb.s +deleted file mode 100644 +index cccf61856..000000000 +--- a/llvm/test/MC/LoongArch/lasx/flogb.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvflogb.s $xr17, $xr12 +-# CHECK-INST: xvflogb.s $xr17, $xr12 +-# CHECK-ENCODING: encoding: [0x91,0xc5,0x9c,0x76] +- +-xvflogb.d $xr26, $xr1 +-# CHECK-INST: xvflogb.d $xr26, $xr1 +-# CHECK-ENCODING: encoding: [0x3a,0xc8,0x9c,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/fmadd.s b/llvm/test/MC/LoongArch/lasx/fmadd.s +deleted file mode 100644 +index c4c330501..000000000 +--- a/llvm/test/MC/LoongArch/lasx/fmadd.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvfmadd.s $xr5, $xr31, $xr31, $xr27 +-# CHECK-INST: xvfmadd.s $xr5, $xr31, $xr31, $xr27 +-# CHECK-ENCODING: encoding: [0xe5,0xff,0x1d,0x0a] +- +-xvfmadd.d $xr9, $xr16, $xr31, $xr25 +-# CHECK-INST: xvfmadd.d $xr9, $xr16, $xr31, $xr25 +-# CHECK-ENCODING: encoding: [0x09,0xfe,0x2c,0x0a] +diff --git a/llvm/test/MC/LoongArch/lasx/fmax.s b/llvm/test/MC/LoongArch/lasx/fmax.s +deleted file mode 100644 +index a5f4f9018..000000000 +--- a/llvm/test/MC/LoongArch/lasx/fmax.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvfmax.s $xr29, $xr24, $xr8 +-# CHECK-INST: xvfmax.s $xr29, $xr24, $xr8 +-# CHECK-ENCODING: encoding: [0x1d,0xa3,0x3c,0x75] +- +-xvfmax.d $xr31, $xr25, $xr23 +-# CHECK-INST: xvfmax.d $xr31, $xr25, $xr23 +-# CHECK-ENCODING: encoding: [0x3f,0x5f,0x3d,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/fmaxa.s b/llvm/test/MC/LoongArch/lasx/fmaxa.s +deleted file mode 100644 +index 1181264e4..000000000 +--- a/llvm/test/MC/LoongArch/lasx/fmaxa.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvfmaxa.s $xr15, $xr18, $xr5 +-# CHECK-INST: xvfmaxa.s $xr15, $xr18, $xr5 +-# CHECK-ENCODING: encoding: [0x4f,0x96,0x40,0x75] +- +-xvfmaxa.d $xr2, $xr20, $xr29 +-# CHECK-INST: xvfmaxa.d $xr2, $xr20, $xr29 +-# CHECK-ENCODING: encoding: [0x82,0x76,0x41,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/fmin.s b/llvm/test/MC/LoongArch/lasx/fmin.s +deleted file mode 100644 +index 735cdd9ce..000000000 +--- a/llvm/test/MC/LoongArch/lasx/fmin.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvfmin.s $xr31, $xr5, $xr16 +-# CHECK-INST: xvfmin.s $xr31, $xr5, $xr16 +-# CHECK-ENCODING: encoding: [0xbf,0xc0,0x3e,0x75] +- +-xvfmin.d $xr13, $xr30, $xr25 +-# CHECK-INST: xvfmin.d $xr13, $xr30, $xr25 +-# CHECK-ENCODING: encoding: [0xcd,0x67,0x3f,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/fmina.s b/llvm/test/MC/LoongArch/lasx/fmina.s +deleted file mode 100644 +index fbfe44c94..000000000 +--- a/llvm/test/MC/LoongArch/lasx/fmina.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvfmina.s $xr29, $xr27, $xr17 +-# CHECK-INST: xvfmina.s $xr29, $xr27, $xr17 +-# CHECK-ENCODING: encoding: [0x7d,0xc7,0x42,0x75] +- +-xvfmina.d $xr12, $xr20, $xr18 +-# CHECK-INST: xvfmina.d $xr12, $xr20, $xr18 +-# CHECK-ENCODING: encoding: [0x8c,0x4a,0x43,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/fmsub.s b/llvm/test/MC/LoongArch/lasx/fmsub.s +deleted file mode 100644 +index 8291d2b75..000000000 +--- a/llvm/test/MC/LoongArch/lasx/fmsub.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvfmsub.s $xr17, $xr3, $xr3, $xr23 +-# CHECK-INST: xvfmsub.s $xr17, $xr3, $xr3, $xr23 +-# CHECK-ENCODING: encoding: [0x71,0x8c,0x5b,0x0a] +- +-xvfmsub.d $xr30, $xr15, $xr16, $xr14 +-# CHECK-INST: xvfmsub.d $xr30, $xr15, $xr16, $xr14 +-# CHECK-ENCODING: encoding: [0xfe,0x41,0x67,0x0a] +diff --git a/llvm/test/MC/LoongArch/lasx/fmul.s b/llvm/test/MC/LoongArch/lasx/fmul.s +deleted file mode 100644 +index bff577017..000000000 +--- a/llvm/test/MC/LoongArch/lasx/fmul.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvfmul.s $xr9, $xr14, $xr30 +-# CHECK-INST: xvfmul.s $xr9, $xr14, $xr30 +-# CHECK-ENCODING: encoding: [0xc9,0xf9,0x38,0x75] +- +-xvfmul.d $xr28, $xr26, $xr19 +-# CHECK-INST: xvfmul.d $xr28, $xr26, $xr19 +-# CHECK-ENCODING: encoding: [0x5c,0x4f,0x39,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/fnmadd.s b/llvm/test/MC/LoongArch/lasx/fnmadd.s +deleted file mode 100644 +index 04830c97c..000000000 +--- a/llvm/test/MC/LoongArch/lasx/fnmadd.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvfnmadd.s $xr14, $xr22, $xr23, $xr24 +-# CHECK-INST: xvfnmadd.s $xr14, $xr22, $xr23, $xr24 +-# CHECK-ENCODING: encoding: [0xce,0x5e,0x9c,0x0a] +- +-xvfnmadd.d $xr1, $xr30, $xr23, $xr12 +-# CHECK-INST: xvfnmadd.d $xr1, $xr30, $xr23, $xr12 +-# CHECK-ENCODING: encoding: [0xc1,0x5f,0xa6,0x0a] +diff --git a/llvm/test/MC/LoongArch/lasx/fnmsub.s b/llvm/test/MC/LoongArch/lasx/fnmsub.s +deleted file mode 100644 +index 6a749eb22..000000000 +--- a/llvm/test/MC/LoongArch/lasx/fnmsub.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvfnmsub.s $xr22, $xr5, $xr4, $xr11 +-# CHECK-INST: xvfnmsub.s $xr22, $xr5, $xr4, $xr11 +-# CHECK-ENCODING: encoding: [0xb6,0x90,0xd5,0x0a] +- +-xvfnmsub.d $xr8, $xr0, $xr29, $xr28 +-# CHECK-INST: xvfnmsub.d $xr8, $xr0, $xr29, $xr28 +-# CHECK-ENCODING: encoding: [0x08,0x74,0xee,0x0a] +diff --git a/llvm/test/MC/LoongArch/lasx/frecip.s b/llvm/test/MC/LoongArch/lasx/frecip.s +deleted file mode 100644 +index e95b03a96..000000000 +--- a/llvm/test/MC/LoongArch/lasx/frecip.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvfrecip.s $xr3, $xr16 +-# CHECK-INST: xvfrecip.s $xr3, $xr16 +-# CHECK-ENCODING: encoding: [0x03,0xf6,0x9c,0x76] +- +-xvfrecip.d $xr17, $xr24 +-# CHECK-INST: xvfrecip.d $xr17, $xr24 +-# CHECK-ENCODING: encoding: [0x11,0xfb,0x9c,0x76] +- +-xvfrecipe.s $xr3, $xr16 +-# CHECK-INST: xvfrecipe.s $xr3, $xr16 +-# CHECK-ENCODING: encoding: [0x03,0x16,0x9d,0x76] +- +-xvfrecipe.d $xr17, $xr24 +-# CHECK-INST: xvfrecipe.d $xr17, $xr24 +-# CHECK-ENCODING: encoding: [0x11,0x1b,0x9d,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/frint.s b/llvm/test/MC/LoongArch/lasx/frint.s +deleted file mode 100644 +index 03ab8684f..000000000 +--- a/llvm/test/MC/LoongArch/lasx/frint.s ++++ /dev/null +@@ -1,44 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvfrintrne.s $xr19, $xr17 +-# CHECK-INST: xvfrintrne.s $xr19, $xr17 +-# CHECK-ENCODING: encoding: [0x33,0x76,0x9d,0x76] +- +-xvfrintrne.d $xr12, $xr29 +-# CHECK-INST: xvfrintrne.d $xr12, $xr29 +-# CHECK-ENCODING: encoding: [0xac,0x7b,0x9d,0x76] +- +-xvfrintrz.s $xr10, $xr9 +-# CHECK-INST: xvfrintrz.s $xr10, $xr9 +-# CHECK-ENCODING: encoding: [0x2a,0x65,0x9d,0x76] +- +-xvfrintrz.d $xr29, $xr5 +-# CHECK-INST: xvfrintrz.d $xr29, $xr5 +-# CHECK-ENCODING: encoding: [0xbd,0x68,0x9d,0x76] +- +-xvfrintrp.s $xr26, $xr16 +-# CHECK-INST: xvfrintrp.s $xr26, $xr16 +-# CHECK-ENCODING: encoding: [0x1a,0x56,0x9d,0x76] +- +-xvfrintrp.d $xr1, $xr28 +-# CHECK-INST: xvfrintrp.d $xr1, $xr28 +-# CHECK-ENCODING: encoding: [0x81,0x5b,0x9d,0x76] +- +-xvfrintrm.s $xr27, $xr13 +-# CHECK-INST: xvfrintrm.s $xr27, $xr13 +-# CHECK-ENCODING: encoding: [0xbb,0x45,0x9d,0x76] +- +-xvfrintrm.d $xr14, $xr27 +-# CHECK-INST: xvfrintrm.d $xr14, $xr27 +-# CHECK-ENCODING: encoding: [0x6e,0x4b,0x9d,0x76] +- +-xvfrint.s $xr21, $xr24 +-# CHECK-INST: xvfrint.s $xr21, $xr24 +-# CHECK-ENCODING: encoding: [0x15,0x37,0x9d,0x76] +- +-xvfrint.d $xr31, $xr18 +-# CHECK-INST: xvfrint.d $xr31, $xr18 +-# CHECK-ENCODING: encoding: [0x5f,0x3a,0x9d,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/frsqrt.s b/llvm/test/MC/LoongArch/lasx/frsqrt.s +deleted file mode 100644 +index d1048f9ff..000000000 +--- a/llvm/test/MC/LoongArch/lasx/frsqrt.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvfrsqrt.s $xr31, $xr25 +-# CHECK-INST: xvfrsqrt.s $xr31, $xr25 +-# CHECK-ENCODING: encoding: [0x3f,0x07,0x9d,0x76] +- +-xvfrsqrt.d $xr14, $xr22 +-# CHECK-INST: xvfrsqrt.d $xr14, $xr22 +-# CHECK-ENCODING: encoding: [0xce,0x0a,0x9d,0x76] +- +-xvfrsqrte.s $xr31, $xr25 +-# CHECK-INST: xvfrsqrte.s $xr31, $xr25 +-# CHECK-ENCODING: encoding: [0x3f,0x27,0x9d,0x76] +- +-xvfrsqrte.d $xr14, $xr22 +-# CHECK-INST: xvfrsqrte.d $xr14, $xr22 +-# CHECK-ENCODING: encoding: [0xce,0x2a,0x9d,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/frstp.s b/llvm/test/MC/LoongArch/lasx/frstp.s +deleted file mode 100644 +index b76309f4b..000000000 +--- a/llvm/test/MC/LoongArch/lasx/frstp.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvfrstp.b $xr23, $xr18, $xr18 +-# CHECK-INST: xvfrstp.b $xr23, $xr18, $xr18 +-# CHECK-ENCODING: encoding: [0x57,0x4a,0x2b,0x75] +- +-xvfrstp.h $xr13, $xr30, $xr6 +-# CHECK-INST: xvfrstp.h $xr13, $xr30, $xr6 +-# CHECK-ENCODING: encoding: [0xcd,0x9b,0x2b,0x75] +- +-xvfrstpi.b $xr24, $xr28, 31 +-# CHECK-INST: xvfrstpi.b $xr24, $xr28, 31 +-# CHECK-ENCODING: encoding: [0x98,0x7f,0x9a,0x76] +- +-xvfrstpi.h $xr22, $xr24, 18 +-# CHECK-INST: xvfrstpi.h $xr22, $xr24, 18 +-# CHECK-ENCODING: encoding: [0x16,0xcb,0x9a,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/fsqrt.s b/llvm/test/MC/LoongArch/lasx/fsqrt.s +deleted file mode 100644 +index 6519ad298..000000000 +--- a/llvm/test/MC/LoongArch/lasx/fsqrt.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvfsqrt.s $xr4, $xr27 +-# CHECK-INST: xvfsqrt.s $xr4, $xr27 +-# CHECK-ENCODING: encoding: [0x64,0xe7,0x9c,0x76] +- +-xvfsqrt.d $xr26, $xr2 +-# CHECK-INST: xvfsqrt.d $xr26, $xr2 +-# CHECK-ENCODING: encoding: [0x5a,0xe8,0x9c,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/fsub.s b/llvm/test/MC/LoongArch/lasx/fsub.s +deleted file mode 100644 +index 47330258e..000000000 +--- a/llvm/test/MC/LoongArch/lasx/fsub.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvfsub.s $xr22, $xr0, $xr3 +-# CHECK-INST: xvfsub.s $xr22, $xr0, $xr3 +-# CHECK-ENCODING: encoding: [0x16,0x8c,0x32,0x75] +- +-xvfsub.d $xr4, $xr25, $xr15 +-# CHECK-INST: xvfsub.d $xr4, $xr25, $xr15 +-# CHECK-ENCODING: encoding: [0x24,0x3f,0x33,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/ftint.s b/llvm/test/MC/LoongArch/lasx/ftint.s +deleted file mode 100644 +index 0b263fe20..000000000 +--- a/llvm/test/MC/LoongArch/lasx/ftint.s ++++ /dev/null +@@ -1,120 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvftintrne.w.s $xr20, $xr13 +-# CHECK-INST: xvftintrne.w.s $xr20, $xr13 +-# CHECK-ENCODING: encoding: [0xb4,0x51,0x9e,0x76] +- +-xvftintrne.l.d $xr30, $xr14 +-# CHECK-INST: xvftintrne.l.d $xr30, $xr14 +-# CHECK-ENCODING: encoding: [0xde,0x55,0x9e,0x76] +- +-xvftintrz.w.s $xr14, $xr5 +-# CHECK-INST: xvftintrz.w.s $xr14, $xr5 +-# CHECK-ENCODING: encoding: [0xae,0x48,0x9e,0x76] +- +-xvftintrz.l.d $xr1, $xr26 +-# CHECK-INST: xvftintrz.l.d $xr1, $xr26 +-# CHECK-ENCODING: encoding: [0x41,0x4f,0x9e,0x76] +- +-xvftintrp.w.s $xr18, $xr1 +-# CHECK-INST: xvftintrp.w.s $xr18, $xr1 +-# CHECK-ENCODING: encoding: [0x32,0x40,0x9e,0x76] +- +-xvftintrp.l.d $xr10, $xr24 +-# CHECK-INST: xvftintrp.l.d $xr10, $xr24 +-# CHECK-ENCODING: encoding: [0x0a,0x47,0x9e,0x76] +- +-xvftintrm.w.s $xr8, $xr23 +-# CHECK-INST: xvftintrm.w.s $xr8, $xr23 +-# CHECK-ENCODING: encoding: [0xe8,0x3a,0x9e,0x76] +- +-xvftintrm.l.d $xr12, $xr17 +-# CHECK-INST: xvftintrm.l.d $xr12, $xr17 +-# CHECK-ENCODING: encoding: [0x2c,0x3e,0x9e,0x76] +- +-xvftint.w.s $xr11, $xr25 +-# CHECK-INST: xvftint.w.s $xr11, $xr25 +-# CHECK-ENCODING: encoding: [0x2b,0x33,0x9e,0x76] +- +-xvftint.l.d $xr7, $xr22 +-# CHECK-INST: xvftint.l.d $xr7, $xr22 +-# CHECK-ENCODING: encoding: [0xc7,0x36,0x9e,0x76] +- +-xvftintrz.wu.s $xr13, $xr19 +-# CHECK-INST: xvftintrz.wu.s $xr13, $xr19 +-# CHECK-ENCODING: encoding: [0x6d,0x72,0x9e,0x76] +- +-xvftintrz.lu.d $xr24, $xr3 +-# CHECK-INST: xvftintrz.lu.d $xr24, $xr3 +-# CHECK-ENCODING: encoding: [0x78,0x74,0x9e,0x76] +- +-xvftint.wu.s $xr14, $xr6 +-# CHECK-INST: xvftint.wu.s $xr14, $xr6 +-# CHECK-ENCODING: encoding: [0xce,0x58,0x9e,0x76] +- +-xvftint.lu.d $xr2, $xr2 +-# CHECK-INST: xvftint.lu.d $xr2, $xr2 +-# CHECK-ENCODING: encoding: [0x42,0x5c,0x9e,0x76] +- +-xvftintrne.w.d $xr13, $xr20, $xr5 +-# CHECK-INST: xvftintrne.w.d $xr13, $xr20, $xr5 +-# CHECK-ENCODING: encoding: [0x8d,0x96,0x4b,0x75] +- +-xvftintrz.w.d $xr13, $xr8, $xr27 +-# CHECK-INST: xvftintrz.w.d $xr13, $xr8, $xr27 +-# CHECK-ENCODING: encoding: [0x0d,0x6d,0x4b,0x75] +- +-xvftintrp.w.d $xr14, $xr26, $xr31 +-# CHECK-INST: xvftintrp.w.d $xr14, $xr26, $xr31 +-# CHECK-ENCODING: encoding: [0x4e,0xff,0x4a,0x75] +- +-xvftintrm.w.d $xr29, $xr23, $xr7 +-# CHECK-INST: xvftintrm.w.d $xr29, $xr23, $xr7 +-# CHECK-ENCODING: encoding: [0xfd,0x1e,0x4a,0x75] +- +-xvftint.w.d $xr7, $xr22, $xr29 +-# CHECK-INST: xvftint.w.d $xr7, $xr22, $xr29 +-# CHECK-ENCODING: encoding: [0xc7,0xf6,0x49,0x75] +- +-xvftintrnel.l.s $xr31, $xr28 +-# CHECK-INST: xvftintrnel.l.s $xr31, $xr28 +-# CHECK-ENCODING: encoding: [0x9f,0xa3,0x9e,0x76] +- +-xvftintrneh.l.s $xr16, $xr29 +-# CHECK-INST: xvftintrneh.l.s $xr16, $xr29 +-# CHECK-ENCODING: encoding: [0xb0,0xa7,0x9e,0x76] +- +-xvftintrzl.l.s $xr27, $xr29 +-# CHECK-INST: xvftintrzl.l.s $xr27, $xr29 +-# CHECK-ENCODING: encoding: [0xbb,0x9b,0x9e,0x76] +- +-xvftintrzh.l.s $xr14, $xr10 +-# CHECK-INST: xvftintrzh.l.s $xr14, $xr10 +-# CHECK-ENCODING: encoding: [0x4e,0x9d,0x9e,0x76] +- +-xvftintrpl.l.s $xr14, $xr0 +-# CHECK-INST: xvftintrpl.l.s $xr14, $xr0 +-# CHECK-ENCODING: encoding: [0x0e,0x90,0x9e,0x76] +- +-xvftintrph.l.s $xr23, $xr0 +-# CHECK-INST: xvftintrph.l.s $xr23, $xr0 +-# CHECK-ENCODING: encoding: [0x17,0x94,0x9e,0x76] +- +-xvftintrml.l.s $xr22, $xr15 +-# CHECK-INST: xvftintrml.l.s $xr22, $xr15 +-# CHECK-ENCODING: encoding: [0xf6,0x89,0x9e,0x76] +- +-xvftintrmh.l.s $xr10, $xr19 +-# CHECK-INST: xvftintrmh.l.s $xr10, $xr19 +-# CHECK-ENCODING: encoding: [0x6a,0x8e,0x9e,0x76] +- +-xvftintl.l.s $xr31, $xr11 +-# CHECK-INST: xvftintl.l.s $xr31, $xr11 +-# CHECK-ENCODING: encoding: [0x7f,0x81,0x9e,0x76] +- +-xvftinth.l.s $xr15, $xr5 +-# CHECK-INST: xvftinth.l.s $xr15, $xr5 +-# CHECK-ENCODING: encoding: [0xaf,0x84,0x9e,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/haddw.s b/llvm/test/MC/LoongArch/lasx/haddw.s +deleted file mode 100644 +index 639669e51..000000000 +--- a/llvm/test/MC/LoongArch/lasx/haddw.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvhaddw.h.b $xr31, $xr19, $xr29 +-# CHECK-INST: xvhaddw.h.b $xr31, $xr19, $xr29 +-# CHECK-ENCODING: encoding: [0x7f,0x76,0x54,0x74] +- +-xvhaddw.w.h $xr31, $xr16, $xr23 +-# CHECK-INST: xvhaddw.w.h $xr31, $xr16, $xr23 +-# CHECK-ENCODING: encoding: [0x1f,0xde,0x54,0x74] +- +-xvhaddw.d.w $xr30, $xr1, $xr24 +-# CHECK-INST: xvhaddw.d.w $xr30, $xr1, $xr24 +-# CHECK-ENCODING: encoding: [0x3e,0x60,0x55,0x74] +- +-xvhaddw.q.d $xr16, $xr15, $xr17 +-# CHECK-INST: xvhaddw.q.d $xr16, $xr15, $xr17 +-# CHECK-ENCODING: encoding: [0xf0,0xc5,0x55,0x74] +- +-xvhaddw.hu.bu $xr14, $xr17, $xr2 +-# CHECK-INST: xvhaddw.hu.bu $xr14, $xr17, $xr2 +-# CHECK-ENCODING: encoding: [0x2e,0x0a,0x58,0x74] +- +-xvhaddw.wu.hu $xr21, $xr2, $xr8 +-# CHECK-INST: xvhaddw.wu.hu $xr21, $xr2, $xr8 +-# CHECK-ENCODING: encoding: [0x55,0xa0,0x58,0x74] +- +-xvhaddw.du.wu $xr6, $xr24, $xr19 +-# CHECK-INST: xvhaddw.du.wu $xr6, $xr24, $xr19 +-# CHECK-ENCODING: encoding: [0x06,0x4f,0x59,0x74] +- +-xvhaddw.qu.du $xr10, $xr12, $xr13 +-# CHECK-INST: xvhaddw.qu.du $xr10, $xr12, $xr13 +-# CHECK-ENCODING: encoding: [0x8a,0xb5,0x59,0x74] +diff --git a/llvm/test/MC/LoongArch/lasx/hsubw.s b/llvm/test/MC/LoongArch/lasx/hsubw.s +deleted file mode 100644 +index 078812f33..000000000 +--- a/llvm/test/MC/LoongArch/lasx/hsubw.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvhsubw.h.b $xr22, $xr7, $xr16 +-# CHECK-INST: xvhsubw.h.b $xr22, $xr7, $xr16 +-# CHECK-ENCODING: encoding: [0xf6,0x40,0x56,0x74] +- +-xvhsubw.w.h $xr19, $xr8, $xr15 +-# CHECK-INST: xvhsubw.w.h $xr19, $xr8, $xr15 +-# CHECK-ENCODING: encoding: [0x13,0xbd,0x56,0x74] +- +-xvhsubw.d.w $xr30, $xr23, $xr19 +-# CHECK-INST: xvhsubw.d.w $xr30, $xr23, $xr19 +-# CHECK-ENCODING: encoding: [0xfe,0x4e,0x57,0x74] +- +-xvhsubw.q.d $xr20, $xr13, $xr28 +-# CHECK-INST: xvhsubw.q.d $xr20, $xr13, $xr28 +-# CHECK-ENCODING: encoding: [0xb4,0xf1,0x57,0x74] +- +-xvhsubw.hu.bu $xr10, $xr2, $xr16 +-# CHECK-INST: xvhsubw.hu.bu $xr10, $xr2, $xr16 +-# CHECK-ENCODING: encoding: [0x4a,0x40,0x5a,0x74] +- +-xvhsubw.wu.hu $xr1, $xr26, $xr18 +-# CHECK-INST: xvhsubw.wu.hu $xr1, $xr26, $xr18 +-# CHECK-ENCODING: encoding: [0x41,0xcb,0x5a,0x74] +- +-xvhsubw.du.wu $xr5, $xr23, $xr20 +-# CHECK-INST: xvhsubw.du.wu $xr5, $xr23, $xr20 +-# CHECK-ENCODING: encoding: [0xe5,0x52,0x5b,0x74] +- +-xvhsubw.qu.du $xr31, $xr4, $xr8 +-# CHECK-INST: xvhsubw.qu.du $xr31, $xr4, $xr8 +-# CHECK-ENCODING: encoding: [0x9f,0xa0,0x5b,0x74] +diff --git a/llvm/test/MC/LoongArch/lasx/ilv.s b/llvm/test/MC/LoongArch/lasx/ilv.s +deleted file mode 100644 +index ebdc8d851..000000000 +--- a/llvm/test/MC/LoongArch/lasx/ilv.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvilvl.b $xr29, $xr14, $xr0 +-# CHECK-INST: xvilvl.b $xr29, $xr14, $xr0 +-# CHECK-ENCODING: encoding: [0xdd,0x01,0x1a,0x75] +- +-xvilvl.h $xr30, $xr9, $xr21 +-# CHECK-INST: xvilvl.h $xr30, $xr9, $xr21 +-# CHECK-ENCODING: encoding: [0x3e,0xd5,0x1a,0x75] +- +-xvilvl.w $xr24, $xr22, $xr9 +-# CHECK-INST: xvilvl.w $xr24, $xr22, $xr9 +-# CHECK-ENCODING: encoding: [0xd8,0x26,0x1b,0x75] +- +-xvilvl.d $xr25, $xr20, $xr10 +-# CHECK-INST: xvilvl.d $xr25, $xr20, $xr10 +-# CHECK-ENCODING: encoding: [0x99,0xaa,0x1b,0x75] +- +-xvilvh.b $xr19, $xr22, $xr26 +-# CHECK-INST: xvilvh.b $xr19, $xr22, $xr26 +-# CHECK-ENCODING: encoding: [0xd3,0x6a,0x1c,0x75] +- +-xvilvh.h $xr10, $xr23, $xr7 +-# CHECK-INST: xvilvh.h $xr10, $xr23, $xr7 +-# CHECK-ENCODING: encoding: [0xea,0x9e,0x1c,0x75] +- +-xvilvh.w $xr5, $xr0, $xr30 +-# CHECK-INST: xvilvh.w $xr5, $xr0, $xr30 +-# CHECK-ENCODING: encoding: [0x05,0x78,0x1d,0x75] +- +-xvilvh.d $xr24, $xr2, $xr2 +-# CHECK-INST: xvilvh.d $xr24, $xr2, $xr2 +-# CHECK-ENCODING: encoding: [0x58,0x88,0x1d,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/insgr2vr.s b/llvm/test/MC/LoongArch/lasx/insgr2vr.s +deleted file mode 100644 +index 8c23c1543..000000000 +--- a/llvm/test/MC/LoongArch/lasx/insgr2vr.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvinsgr2vr.w $xr25, $r30, 7 +-# CHECK-INST: xvinsgr2vr.w $xr25, $s7, 7 +-# CHECK-ENCODING: encoding: [0xd9,0xdf,0xeb,0x76] +- +-xvinsgr2vr.d $xr27, $r21, 1 +-# CHECK-INST: xvinsgr2vr.d $xr27, $r21, 1 +-# CHECK-ENCODING: encoding: [0xbb,0xe6,0xeb,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/insve0.s b/llvm/test/MC/LoongArch/lasx/insve0.s +deleted file mode 100644 +index 5b77a23a2..000000000 +--- a/llvm/test/MC/LoongArch/lasx/insve0.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvinsve0.w $xr6, $xr1, 7 +-# CHECK-INST: xvinsve0.w $xr6, $xr1, 7 +-# CHECK-ENCODING: encoding: [0x26,0xdc,0xff,0x76] +- +-xvinsve0.d $xr28, $xr1, 0 +-# CHECK-INST: xvinsve0.d $xr28, $xr1, 0 +-# CHECK-ENCODING: encoding: [0x3c,0xe0,0xff,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/invalid-imm.s b/llvm/test/MC/LoongArch/lasx/invalid-imm.s +deleted file mode 100644 +index 6f64a6f87..000000000 +--- a/llvm/test/MC/LoongArch/lasx/invalid-imm.s ++++ /dev/null +@@ -1,1192 +0,0 @@ +-## Test out of range immediates which are used by lasx instructions. +- +-# RUN: not llvm-mc --triple=loongarch64 %s 2>&1 | FileCheck %s +- +-## uimm1 +-xvrepl128vei.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 1] +- +-xvrepl128vei.d $xr0, $xr1, 2 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 1] +- +-## uimm2 +-xvpickve.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 3] +- +-xvpickve.d $xr0, $xr1, 4 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 3] +- +-xvinsve0.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 3] +- +-xvinsve0.d $xr0, $xr1, 4 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 3] +- +-xvinsgr2vr.d $xr0, $a0, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 3] +- +-xvinsgr2vr.d $xr0, $a0, 4 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 3] +- +-xvpickve2gr.d $a0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 3] +- +-xvpickve2gr.d $a0, $xr1, 4 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 3] +- +-xvpickve2gr.du $a0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 3] +- +-xvpickve2gr.du $a0, $xr1, 4 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 3] +- +-xvstelm.d $xr0, $a0, 8, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 3] +- +-xvstelm.d $xr0, $a0, 8, 4 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 3] +- +-xvrepl128vei.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 3] +- +-xvrepl128vei.w $xr0, $xr1, 4 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 3] +- +-## uimm3 +-xvpickve.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 7] +- +-xvpickve.w $xr0, $xr1, 8 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 7] +- +-xvinsve0.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 7] +- +-xvinsve0.w $xr0, $xr1, 8 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 7] +- +-xvinsgr2vr.w $xr0, $a0, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 7] +- +-xvinsgr2vr.w $xr0, $a0, 8 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 7] +- +-xvpickve2gr.wu $a0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 7] +- +-xvpickve2gr.wu $a0, $xr1, 8 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 7] +- +-xvpickve2gr.w $a0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 7] +- +-xvpickve2gr.w $a0, $xr1, 8 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 7] +- +-xvstelm.w $xr0, $a0, 4, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 7] +- +-xvstelm.w $xr0, $a0, 4, 8 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 7] +- +-xvrepl128vei.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 7] +- +-xvrepl128vei.h $xr0, $xr1, 8 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 7] +- +-xvbitrevi.b $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 7] +- +-xvbitrevi.b $xr0, $xr1, 8 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 7] +- +-xvbitseti.b $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 7] +- +-xvbitseti.b $xr0, $xr1, 8 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 7] +- +-xvbitclri.b $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 7] +- +-xvbitclri.b $xr0, $xr1, 8 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 7] +- +-xvsrari.b $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 7] +- +-xvsrari.b $xr0, $xr1, 8 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 7] +- +-xvsrlri.b $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 7] +- +-xvsrlri.b $xr0, $xr1, 8 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 7] +- +-xvsllwil.hu.bu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 7] +- +-xvsllwil.hu.bu $xr0, $xr1, 8 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 7] +- +-xvsllwil.h.b $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 7] +- +-xvsllwil.h.b $xr0, $xr1, 8 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 7] +- +-xvrotri.b $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 7] +- +-xvrotri.b $xr0, $xr1, 8 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 7] +- +-xvsrai.b $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 7] +- +-xvsrai.b $xr0, $xr1, 8 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 7] +- +-xvsrli.b $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 7] +- +-xvsrli.b $xr0, $xr1, 8 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 7] +- +-xvslli.b $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 7] +- +-xvslli.b $xr0, $xr1, 8 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 7] +- +-xvsat.b $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 7] +- +-xvsat.b $xr0, $xr1, 8 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 7] +- +-xvsat.bu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 7] +- +-xvsat.bu $xr0, $xr1, 8 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 7] +- +-## uimm4 +-xvstelm.h $xr0, $a0, 2, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-xvstelm.h $xr0, $a0, 2, 16 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-xvrepl128vei.b $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 15] +- +-xvrepl128vei.b $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 15] +- +-xvbitrevi.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-xvbitrevi.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-xvbitseti.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-xvbitseti.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-xvbitclri.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-xvbitclri.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-xvssrarni.bu.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 15] +- +-xvssrarni.bu.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 15] +- +-xvssrlrni.bu.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 15] +- +-xvssrlrni.bu.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 15] +- +-xvssrarni.b.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 15] +- +-xvssrarni.b.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 15] +- +-xvssrlrni.b.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 15] +- +-xvssrlrni.b.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 15] +- +-xvssrani.bu.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 15] +- +-xvssrani.bu.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 15] +- +-xvssrlni.bu.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 15] +- +-xvssrlni.bu.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 15] +- +-xvssrani.b.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 15] +- +-xvssrani.b.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 15] +- +-xvssrlni.b.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 15] +- +-xvssrlni.b.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 15] +- +-xvsrarni.b.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 15] +- +-xvsrarni.b.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 15] +- +-xvsrlrni.b.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 15] +- +-xvsrlrni.b.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 15] +- +-xvsrani.b.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-xvsrani.b.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-xvsrlni.b.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-xvsrlni.b.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-xvsrari.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 15] +- +-xvsrari.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 15] +- +-xvsrlri.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 15] +- +-xvsrlri.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 15] +- +-xvsllwil.wu.hu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 15] +- +-xvsllwil.wu.hu $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 15] +- +-xvsllwil.w.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 15] +- +-xvsllwil.w.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 15] +- +-xvrotri.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 15] +- +-xvrotri.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 15] +- +-xvsrai.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 15] +- +-xvsrai.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 15] +- +-xvsrli.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 15] +- +-xvsrli.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 15] +- +-xvslli.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 15] +- +-xvslli.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 15] +- +-xvsat.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 15] +- +-xvsat.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 15] +- +-xvsat.hu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 15] +- +-xvsat.hu $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 15] +- +-## uimm5 +-xvstelm.b $xr0, $a0, 1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +- +-xvstelm.b $xr0, $a0, 1, 32 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +- +-xvbsrl.v $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-xvbsrl.v $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-xvbsll.v $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-xvbsll.v $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-xvslti.du $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvslti.du $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvslti.wu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvslti.wu $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvslti.hu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvslti.hu $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvslti.bu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvslti.bu $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvslei.du $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvslei.du $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvslei.wu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvslei.wu $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvslei.hu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvslei.hu $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvslei.bu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvslei.bu $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvfrstpi.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 31] +- +-xvfrstpi.h $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 31] +- +-xvfrstpi.b $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 31] +- +-xvfrstpi.b $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 31] +- +-xvbitrevi.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +- +-xvbitrevi.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +- +-xvbitseti.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +- +-xvbitseti.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +- +-xvbitclri.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +- +-xvbitclri.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +- +-xvssrarni.hu.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 31] +- +-xvssrarni.hu.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 31] +- +-xvssrlrni.hu.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 31] +- +-xvssrlrni.hu.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 31] +- +-xvssrarni.h.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 31] +- +-xvssrarni.h.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 31] +- +-xvssrlrni.h.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 31] +- +-xvssrlrni.h.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 31] +- +-xvssrani.hu.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 31] +- +-xvssrani.hu.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 31] +- +-xvssrlni.hu.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 31] +- +-xvssrlni.hu.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 31] +- +-xvssrani.h.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 31] +- +-xvssrani.h.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 31] +- +-xvssrlni.h.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 31] +- +-xvssrlni.h.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 31] +- +-xvsrarni.h.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 31] +- +-xvsrarni.h.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 31] +- +-xvsrlrni.h.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 31] +- +-xvsrlrni.h.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 31] +- +-xvsrani.h.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +- +-xvsrani.h.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +- +-xvsrlni.h.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +- +-xvsrlni.h.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +- +-xvsrari.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvsrari.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvsrlri.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvsrlri.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvsllwil.du.wu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 31] +- +-xvsllwil.du.wu $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 31] +- +-xvsllwil.d.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 31] +- +-xvsllwil.d.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 31] +- +-xvrotri.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvrotri.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvsrai.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-xvsrai.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-xvsrli.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-xvsrli.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-xvslli.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-xvslli.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-xvaddi.bu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvaddi.bu $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvaddi.hu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvaddi.hu $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvaddi.wu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvaddi.wu $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvaddi.du $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvaddi.du $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvsubi.bu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvsubi.bu $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvsubi.hu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvsubi.hu $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvsubi.wu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvsubi.wu $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvsubi.du $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvsubi.du $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvmaxi.bu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvmaxi.bu $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvmaxi.hu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvmaxi.hu $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvmaxi.wu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvmaxi.wu $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvmaxi.du $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvmaxi.du $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvmini.bu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvmini.bu $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvmini.hu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvmini.hu $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvmini.wu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvmini.wu $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvmini.du $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvmini.du $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-xvsat.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 31] +- +-xvsat.w $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 31] +- +-xvsat.wu $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-xvsat.wu $xr0, $xr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-## simm5 +-xvslti.d $xr0, $xr1, -17 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvslti.d $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvslti.w $xr0, $xr1, -17 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvslti.w $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvslti.h $xr0, $xr1, -17 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvslti.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvslti.b $xr0, $xr1, -17 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvslti.b $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvslei.d $xr0, $xr1, -17 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvslei.d $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvslei.w $xr0, $xr1, -17 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvslei.w $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvslei.h $xr0, $xr1, -17 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvslei.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvslei.b $xr0, $xr1, -17 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvslei.b $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvseqi.d $xr0, $xr1, -17 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvseqi.d $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvseqi.w $xr0, $xr1, -17 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvseqi.w $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvseqi.h $xr0, $xr1, -17 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvseqi.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvseqi.b $xr0, $xr1, -17 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvseqi.b $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvmaxi.b $xr0, $xr1, -17 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvmaxi.b $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvmaxi.h $xr0, $xr1, -17 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvmaxi.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvmaxi.w $xr0, $xr1, -17 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvmaxi.w $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvmaxi.d $xr0, $xr1, -17 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvmaxi.d $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvmini.b $xr0, $xr1, -17 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvmini.b $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvmini.h $xr0, $xr1, -17 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvmini.h $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvmini.w $xr0, $xr1, -17 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvmini.w $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvmini.d $xr0, $xr1, -17 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-xvmini.d $xr0, $xr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-16, 15] +- +-## uimm6 +-xvbitrevi.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 63] +- +-xvbitrevi.d $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 63] +- +-xvbitseti.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 63] +- +-xvbitseti.d $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 63] +- +-xvbitclri.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 63] +- +-xvbitclri.d $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 63] +- +-xvssrarni.wu.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 63] +- +-xvssrarni.wu.d $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 63] +- +-xvssrlrni.wu.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 63] +- +-xvssrlrni.wu.d $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 63] +- +-xvssrarni.w.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 63] +- +-xvssrarni.w.d $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 63] +- +-xvssrlrni.w.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 63] +- +-xvssrlrni.w.d $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 63] +- +-xvssrani.wu.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 63] +- +-xvssrani.wu.d $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 63] +- +-xvssrlni.wu.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 63] +- +-xvssrlni.wu.d $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 63] +- +-xvssrani.w.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 63] +- +-xvssrani.w.d $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 63] +- +-xvssrlni.w.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 63] +- +-xvssrlni.w.d $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 63] +- +-xvsrarni.w.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 63] +- +-xvsrarni.w.d $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 63] +- +-xvsrlrni.w.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 63] +- +-xvsrlrni.w.d $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 63] +- +-xvsrani.w.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 63] +- +-xvsrani.w.d $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 63] +- +-xvsrlni.w.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 63] +- +-xvsrlni.w.d $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 63] +- +-xvsrari.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 63] +- +-xvsrari.d $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 63] +- +-xvsrlri.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 63] +- +-xvsrlri.d $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 63] +- +-xvrotri.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 63] +- +-xvrotri.d $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 63] +- +-xvsrai.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 63] +- +-xvsrai.d $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 63] +- +-xvsrli.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 63] +- +-xvsrli.d $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 63] +- +-xvslli.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 63] +- +-xvslli.d $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 63] +- +-xvsat.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 63] +- +-xvsat.d $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 63] +- +-xvsat.du $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 63] +- +-xvsat.du $xr0, $xr1, 64 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 63] +- +-## uimm7 +-xvssrarni.du.q $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 127] +- +-xvssrarni.du.q $xr0, $xr1, 128 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 127] +- +-xvssrlrni.du.q $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 127] +- +-xvssrlrni.du.q $xr0, $xr1, 128 +-# CHECK: :[[#@LINE-1]]:28: error: immediate must be an integer in the range [0, 127] +- +-xvssrarni.d.q $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 127] +- +-xvssrarni.d.q $xr0, $xr1, 128 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 127] +- +-xvssrlrni.d.q $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 127] +- +-xvssrlrni.d.q $xr0, $xr1, 128 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 127] +- +-xvssrani.du.q $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 127] +- +-xvssrani.du.q $xr0, $xr1, 128 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 127] +- +-xvssrlni.du.q $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 127] +- +-xvssrlni.du.q $xr0, $xr1, 128 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 127] +- +-xvssrani.d.q $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 127] +- +-xvssrani.d.q $xr0, $xr1, 128 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 127] +- +-xvssrlni.d.q $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 127] +- +-xvssrlni.d.q $xr0, $xr1, 128 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 127] +- +-xvsrarni.d.q $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 127] +- +-xvsrarni.d.q $xr0, $xr1, 128 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 127] +- +-xvsrlrni.d.q $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 127] +- +-xvsrlrni.d.q $xr0, $xr1, 128 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 127] +- +-xvsrani.d.q $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 127] +- +-xvsrani.d.q $xr0, $xr1, 128 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 127] +- +-xvsrlni.d.q $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 127] +- +-xvsrlni.d.q $xr0, $xr1, 128 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 127] +- +-## uimm8 +-xvextrins.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 255] +- +-xvextrins.d $xr0, $xr1, 256 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 255] +- +-xvextrins.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 255] +- +-xvextrins.w $xr0, $xr1, 256 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 255] +- +-xvextrins.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 255] +- +-xvextrins.h $xr0, $xr1, 256 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 255] +- +-xvextrins.b $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 255] +- +-xvextrins.b $xr0, $xr1, 256 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 255] +- +-xvpermi.q $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 255] +- +-xvpermi.q $xr0, $xr1, 256 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 255] +- +-xvpermi.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 255] +- +-xvpermi.d $xr0, $xr1, 256 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 255] +- +-xvpermi.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 255] +- +-xvpermi.w $xr0, $xr1, 256 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 255] +- +-xvshuf4i.d $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 255] +- +-xvshuf4i.d $xr0, $xr1, 256 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 255] +- +-xvshuf4i.w $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 255] +- +-xvshuf4i.w $xr0, $xr1, 256 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 255] +- +-xvshuf4i.h $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 255] +- +-xvshuf4i.h $xr0, $xr1, 256 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 255] +- +-xvshuf4i.b $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 255] +- +-xvshuf4i.b $xr0, $xr1, 256 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 255] +- +-xvbitseli.b $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 255] +- +-xvbitseli.b $xr0, $xr1, 256 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 255] +- +-xvandi.b $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 255] +- +-xvandi.b $xr0, $xr1, 256 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 255] +- +-xvori.b $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 255] +- +-xvori.b $xr0, $xr1, 256 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 255] +- +-xvxori.b $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 255] +- +-xvxori.b $xr0, $xr1, 256 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 255] +- +-xvnori.b $xr0, $xr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 255] +- +-xvnori.b $xr0, $xr1, 256 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 255] +- +-## simm8 +-xvstelm.b $xr0, $a0, -129, 1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-128, 127] +- +-xvstelm.b $xr0, $a0, 128, 1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-128, 127] +- +-## simm8_lsl1 +-xvstelm.h $xr0, $a0, -258, 1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be a multiple of 2 in the range [-256, 254] +- +-xvstelm.h $xr0, $a0, 256, 1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be a multiple of 2 in the range [-256, 254] +- +-## simm8_lsl2 +-xvstelm.w $xr0, $a0, -516, 1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be a multiple of 4 in the range [-512, 508] +- +-xvstelm.w $xr0, $a0, 512, 1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be a multiple of 4 in the range [-512, 508] +- +-## simm8_lsl3 +-xvstelm.d $xr0, $a0, -1032, 1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be a multiple of 8 in the range [-1024, 1016] +- +-xvstelm.d $xr0, $a0, 1024, 1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be a multiple of 8 in the range [-1024, 1016] +- +-## simm9_lsl3 +-xvldrepl.d $xr0, $a0, -2056 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be a multiple of 8 in the range [-2048, 2040] +- +-xvldrepl.d $xr0, $a0, 2048 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be a multiple of 8 in the range [-2048, 2040] +- +-## simm10_lsl2 +-xvldrepl.w $xr0, $a0, -2052 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be a multiple of 4 in the range [-2048, 2044] +- +-xvldrepl.w $xr0, $a0, 2048 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be a multiple of 4 in the range [-2048, 2044] +- +-## simm10 +-xvrepli.b $xr0, -513 +-# CHECK: :[[#@LINE-1]]:17: error: immediate must be an integer in the range [-512, 511] +- +-xvrepli.b $xr0, 512 +-# CHECK: :[[#@LINE-1]]:17: error: immediate must be an integer in the range [-512, 511] +- +-xvrepli.h $xr0, -513 +-# CHECK: :[[#@LINE-1]]:17: error: immediate must be an integer in the range [-512, 511] +- +-xvrepli.h $xr0, 512 +-# CHECK: :[[#@LINE-1]]:17: error: immediate must be an integer in the range [-512, 511] +- +-xvrepli.w $xr0, -513 +-# CHECK: :[[#@LINE-1]]:17: error: immediate must be an integer in the range [-512, 511] +- +-xvrepli.w $xr0, 512 +-# CHECK: :[[#@LINE-1]]:17: error: immediate must be an integer in the range [-512, 511] +- +-xvrepli.d $xr0, -513 +-# CHECK: :[[#@LINE-1]]:17: error: immediate must be an integer in the range [-512, 511] +- +-xvrepli.d $xr0, 512 +-# CHECK: :[[#@LINE-1]]:17: error: immediate must be an integer in the range [-512, 511] +- +-## simm11_lsl1 +-xvldrepl.h $xr0, $a0, -2050 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be a multiple of 2 in the range [-2048, 2046] +- +-xvldrepl.h $xr0, $a0, 2048 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be a multiple of 2 in the range [-2048, 2046] +- +-## simm12 +-xvldrepl.b $xr0, $a0, -2049 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [-2048, 2047] +- +-xvldrepl.b $xr0, $a0, 2048 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [-2048, 2047] +- +-xvst $xr0, $a0, -2049 +-# CHECK: :[[#@LINE-1]]:17: error: immediate must be an integer in the range [-2048, 2047] +- +-xvst $xr0, $a0, 2048 +-# CHECK: :[[#@LINE-1]]:17: error: immediate must be an integer in the range [-2048, 2047] +- +-xvld $xr0, $a0, -2049 +-# CHECK: :[[#@LINE-1]]:17: error: immediate must be an integer in the range [-2048, 2047] +- +-xvld $xr0, $a0, 2048 +-# CHECK: :[[#@LINE-1]]:17: error: immediate must be an integer in the range [-2048, 2047] +- +-## simm13 +-xvldi $xr0, -4097 +-# CHECK: :[[#@LINE-1]]:13: error: immediate must be an integer in the range [-4096, 4095] +- +-xvldi $xr0, 4096 +-# CHECK: :[[#@LINE-1]]:13: error: immediate must be an integer in the range [-4096, 4095] +diff --git a/llvm/test/MC/LoongArch/lasx/ld.s b/llvm/test/MC/LoongArch/lasx/ld.s +deleted file mode 100644 +index 70db8d4f7..000000000 +--- a/llvm/test/MC/LoongArch/lasx/ld.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvld $xr3, $r3, -658 +-# CHECK-INST: xvld $xr3, $sp, -658 +-# CHECK-ENCODING: encoding: [0x63,0xb8,0xb5,0x2c] +- +-xvldx $xr23, $r9, $r14 +-# CHECK-INST: xvldx $xr23, $a5, $t2 +-# CHECK-ENCODING: encoding: [0x37,0x39,0x48,0x38] +diff --git a/llvm/test/MC/LoongArch/lasx/ldi.s b/llvm/test/MC/LoongArch/lasx/ldi.s +deleted file mode 100644 +index 5b4bd2dcd..000000000 +--- a/llvm/test/MC/LoongArch/lasx/ldi.s ++++ /dev/null +@@ -1,29 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-OBJ +- +-xvldi $xr31, 3206 +-# CHECK-INST: xvldi $xr31, 3206 +-# CHECK-ENCODING: encoding: [0xdf,0x90,0xe1,0x77] +-# CHECK-OBJ: vldi $xr31, 3206 +- +-xvrepli.b $xr26, -512 +-# CHECK-INST: vrepli.b $xr26, -512 +-# CHECK-ENCODING: encoding: [0x1a,0x40,0xe0,0x77] +-# CHECK-OBJ: vldi $xr26, 512 +- +-xvrepli.h $xr26, -512 +-# CHECK-INST: vrepli.h $xr26, -512 +-# CHECK-ENCODING: encoding: [0x1a,0xc0,0xe0,0x77] +-# CHECK-OBJ: vldi $xr26, 1536 +- +-xvrepli.w $xr26, -512 +-# CHECK-INST: vrepli.w $xr26, -512 +-# CHECK-ENCODING: encoding: [0x1a,0x40,0xe1,0x77] +-# CHECK-OBJ: vldi $xr26, 2560 +- +-xvrepli.d $xr26, -512 +-# CHECK-INST: vrepli.d $xr26, -512 +-# CHECK-ENCODING: encoding: [0x1a,0xc0,0xe1,0x77] +-# CHECK-OBJ: vldi $xr26, 3584 +diff --git a/llvm/test/MC/LoongArch/lasx/ldrepl.s b/llvm/test/MC/LoongArch/lasx/ldrepl.s +deleted file mode 100644 +index 3fd8ec406..000000000 +--- a/llvm/test/MC/LoongArch/lasx/ldrepl.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvldrepl.b $xr19, $r21, 1892 +-# CHECK-INST: xvldrepl.b $xr19, $r21, 1892 +-# CHECK-ENCODING: encoding: [0xb3,0x92,0x9d,0x32] +- +-xvldrepl.h $xr0, $r17, 1762 +-# CHECK-INST: xvldrepl.h $xr0, $t5, 1762 +-# CHECK-ENCODING: encoding: [0x20,0xc6,0x4d,0x32] +- +-xvldrepl.w $xr11, $r26, -1524 +-# CHECK-INST: xvldrepl.w $xr11, $s3, -1524 +-# CHECK-ENCODING: encoding: [0x4b,0x0f,0x2a,0x32] +- +-xvldrepl.d $xr28, $r12, 1976 +-# CHECK-INST: xvldrepl.d $xr28, $t0, 1976 +-# CHECK-ENCODING: encoding: [0x9c,0xdd,0x13,0x32] +diff --git a/llvm/test/MC/LoongArch/lasx/madd.s b/llvm/test/MC/LoongArch/lasx/madd.s +deleted file mode 100644 +index 8f6179373..000000000 +--- a/llvm/test/MC/LoongArch/lasx/madd.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvmadd.b $xr5, $xr31, $xr8 +-# CHECK-INST: xvmadd.b $xr5, $xr31, $xr8 +-# CHECK-ENCODING: encoding: [0xe5,0x23,0xa8,0x74] +- +-xvmadd.h $xr4, $xr0, $xr28 +-# CHECK-INST: xvmadd.h $xr4, $xr0, $xr28 +-# CHECK-ENCODING: encoding: [0x04,0xf0,0xa8,0x74] +- +-xvmadd.w $xr2, $xr13, $xr24 +-# CHECK-INST: xvmadd.w $xr2, $xr13, $xr24 +-# CHECK-ENCODING: encoding: [0xa2,0x61,0xa9,0x74] +- +-xvmadd.d $xr19, $xr8, $xr18 +-# CHECK-INST: xvmadd.d $xr19, $xr8, $xr18 +-# CHECK-ENCODING: encoding: [0x13,0xc9,0xa9,0x74] +diff --git a/llvm/test/MC/LoongArch/lasx/maddw.s b/llvm/test/MC/LoongArch/lasx/maddw.s +deleted file mode 100644 +index af873fb1a..000000000 +--- a/llvm/test/MC/LoongArch/lasx/maddw.s ++++ /dev/null +@@ -1,100 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvmaddwev.h.b $xr25, $xr15, $xr9 +-# CHECK-INST: xvmaddwev.h.b $xr25, $xr15, $xr9 +-# CHECK-ENCODING: encoding: [0xf9,0x25,0xac,0x74] +- +-xvmaddwev.w.h $xr26, $xr1, $xr0 +-# CHECK-INST: xvmaddwev.w.h $xr26, $xr1, $xr0 +-# CHECK-ENCODING: encoding: [0x3a,0x80,0xac,0x74] +- +-xvmaddwev.d.w $xr23, $xr24, $xr24 +-# CHECK-INST: xvmaddwev.d.w $xr23, $xr24, $xr24 +-# CHECK-ENCODING: encoding: [0x17,0x63,0xad,0x74] +- +-xvmaddwev.q.d $xr7, $xr9, $xr22 +-# CHECK-INST: xvmaddwev.q.d $xr7, $xr9, $xr22 +-# CHECK-ENCODING: encoding: [0x27,0xd9,0xad,0x74] +- +-xvmaddwev.h.bu $xr23, $xr13, $xr26 +-# CHECK-INST: xvmaddwev.h.bu $xr23, $xr13, $xr26 +-# CHECK-ENCODING: encoding: [0xb7,0x69,0xb4,0x74] +- +-xvmaddwev.w.hu $xr13, $xr3, $xr3 +-# CHECK-INST: xvmaddwev.w.hu $xr13, $xr3, $xr3 +-# CHECK-ENCODING: encoding: [0x6d,0x8c,0xb4,0x74] +- +-xvmaddwev.d.wu $xr29, $xr27, $xr28 +-# CHECK-INST: xvmaddwev.d.wu $xr29, $xr27, $xr28 +-# CHECK-ENCODING: encoding: [0x7d,0x73,0xb5,0x74] +- +-xvmaddwev.q.du $xr29, $xr10, $xr10 +-# CHECK-INST: xvmaddwev.q.du $xr29, $xr10, $xr10 +-# CHECK-ENCODING: encoding: [0x5d,0xa9,0xb5,0x74] +- +-xvmaddwev.h.bu.b $xr30, $xr26, $xr31 +-# CHECK-INST: xvmaddwev.h.bu.b $xr30, $xr26, $xr31 +-# CHECK-ENCODING: encoding: [0x5e,0x7f,0xbc,0x74] +- +-xvmaddwev.w.hu.h $xr6, $xr17, $xr31 +-# CHECK-INST: xvmaddwev.w.hu.h $xr6, $xr17, $xr31 +-# CHECK-ENCODING: encoding: [0x26,0xfe,0xbc,0x74] +- +-xvmaddwev.d.wu.w $xr10, $xr28, $xr2 +-# CHECK-INST: xvmaddwev.d.wu.w $xr10, $xr28, $xr2 +-# CHECK-ENCODING: encoding: [0x8a,0x0b,0xbd,0x74] +- +-xvmaddwev.q.du.d $xr16, $xr20, $xr24 +-# CHECK-INST: xvmaddwev.q.du.d $xr16, $xr20, $xr24 +-# CHECK-ENCODING: encoding: [0x90,0xe2,0xbd,0x74] +- +-xvmaddwod.h.b $xr16, $xr8, $xr18 +-# CHECK-INST: xvmaddwod.h.b $xr16, $xr8, $xr18 +-# CHECK-ENCODING: encoding: [0x10,0x49,0xae,0x74] +- +-xvmaddwod.w.h $xr11, $xr24, $xr14 +-# CHECK-INST: xvmaddwod.w.h $xr11, $xr24, $xr14 +-# CHECK-ENCODING: encoding: [0x0b,0xbb,0xae,0x74] +- +-xvmaddwod.d.w $xr0, $xr20, $xr13 +-# CHECK-INST: xvmaddwod.d.w $xr0, $xr20, $xr13 +-# CHECK-ENCODING: encoding: [0x80,0x36,0xaf,0x74] +- +-xvmaddwod.q.d $xr15, $xr23, $xr18 +-# CHECK-INST: xvmaddwod.q.d $xr15, $xr23, $xr18 +-# CHECK-ENCODING: encoding: [0xef,0xca,0xaf,0x74] +- +-xvmaddwod.h.bu $xr31, $xr23, $xr7 +-# CHECK-INST: xvmaddwod.h.bu $xr31, $xr23, $xr7 +-# CHECK-ENCODING: encoding: [0xff,0x1e,0xb6,0x74] +- +-xvmaddwod.w.hu $xr29, $xr16, $xr8 +-# CHECK-INST: xvmaddwod.w.hu $xr29, $xr16, $xr8 +-# CHECK-ENCODING: encoding: [0x1d,0xa2,0xb6,0x74] +- +-xvmaddwod.d.wu $xr23, $xr16, $xr11 +-# CHECK-INST: xvmaddwod.d.wu $xr23, $xr16, $xr11 +-# CHECK-ENCODING: encoding: [0x17,0x2e,0xb7,0x74] +- +-xvmaddwod.q.du $xr9, $xr10, $xr19 +-# CHECK-INST: xvmaddwod.q.du $xr9, $xr10, $xr19 +-# CHECK-ENCODING: encoding: [0x49,0xcd,0xb7,0x74] +- +-xvmaddwod.h.bu.b $xr27, $xr2, $xr11 +-# CHECK-INST: xvmaddwod.h.bu.b $xr27, $xr2, $xr11 +-# CHECK-ENCODING: encoding: [0x5b,0x2c,0xbe,0x74] +- +-xvmaddwod.w.hu.h $xr12, $xr24, $xr19 +-# CHECK-INST: xvmaddwod.w.hu.h $xr12, $xr24, $xr19 +-# CHECK-ENCODING: encoding: [0x0c,0xcf,0xbe,0x74] +- +-xvmaddwod.d.wu.w $xr11, $xr0, $xr14 +-# CHECK-INST: xvmaddwod.d.wu.w $xr11, $xr0, $xr14 +-# CHECK-ENCODING: encoding: [0x0b,0x38,0xbf,0x74] +- +-xvmaddwod.q.du.d $xr29, $xr19, $xr31 +-# CHECK-INST: xvmaddwod.q.du.d $xr29, $xr19, $xr31 +-# CHECK-ENCODING: encoding: [0x7d,0xfe,0xbf,0x74] +diff --git a/llvm/test/MC/LoongArch/lasx/max.s b/llvm/test/MC/LoongArch/lasx/max.s +deleted file mode 100644 +index 1ae100309..000000000 +--- a/llvm/test/MC/LoongArch/lasx/max.s ++++ /dev/null +@@ -1,68 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvmax.b $xr23, $xr8, $xr13 +-# CHECK-INST: xvmax.b $xr23, $xr8, $xr13 +-# CHECK-ENCODING: encoding: [0x17,0x35,0x70,0x74] +- +-xvmax.h $xr13, $xr18, $xr28 +-# CHECK-INST: xvmax.h $xr13, $xr18, $xr28 +-# CHECK-ENCODING: encoding: [0x4d,0xf2,0x70,0x74] +- +-xvmax.w $xr26, $xr1, $xr2 +-# CHECK-INST: xvmax.w $xr26, $xr1, $xr2 +-# CHECK-ENCODING: encoding: [0x3a,0x08,0x71,0x74] +- +-xvmax.d $xr2, $xr17, $xr13 +-# CHECK-INST: xvmax.d $xr2, $xr17, $xr13 +-# CHECK-ENCODING: encoding: [0x22,0xb6,0x71,0x74] +- +-xvmaxi.b $xr6, $xr7, 1 +-# CHECK-INST: xvmaxi.b $xr6, $xr7, 1 +-# CHECK-ENCODING: encoding: [0xe6,0x04,0x90,0x76] +- +-xvmaxi.h $xr24, $xr10, -7 +-# CHECK-INST: xvmaxi.h $xr24, $xr10, -7 +-# CHECK-ENCODING: encoding: [0x58,0xe5,0x90,0x76] +- +-xvmaxi.w $xr24, $xr18, -8 +-# CHECK-INST: xvmaxi.w $xr24, $xr18, -8 +-# CHECK-ENCODING: encoding: [0x58,0x62,0x91,0x76] +- +-xvmaxi.d $xr21, $xr5, -11 +-# CHECK-INST: xvmaxi.d $xr21, $xr5, -11 +-# CHECK-ENCODING: encoding: [0xb5,0xd4,0x91,0x76] +- +-xvmax.bu $xr29, $xr30, $xr11 +-# CHECK-INST: xvmax.bu $xr29, $xr30, $xr11 +-# CHECK-ENCODING: encoding: [0xdd,0x2f,0x74,0x74] +- +-xvmax.hu $xr4, $xr23, $xr27 +-# CHECK-INST: xvmax.hu $xr4, $xr23, $xr27 +-# CHECK-ENCODING: encoding: [0xe4,0xee,0x74,0x74] +- +-xvmax.wu $xr31, $xr0, $xr0 +-# CHECK-INST: xvmax.wu $xr31, $xr0, $xr0 +-# CHECK-ENCODING: encoding: [0x1f,0x00,0x75,0x74] +- +-xvmax.du $xr5, $xr22, $xr9 +-# CHECK-INST: xvmax.du $xr5, $xr22, $xr9 +-# CHECK-ENCODING: encoding: [0xc5,0xa6,0x75,0x74] +- +-xvmaxi.bu $xr12, $xr27, 28 +-# CHECK-INST: xvmaxi.bu $xr12, $xr27, 28 +-# CHECK-ENCODING: encoding: [0x6c,0x73,0x94,0x76] +- +-xvmaxi.hu $xr25, $xr4, 16 +-# CHECK-INST: xvmaxi.hu $xr25, $xr4, 16 +-# CHECK-ENCODING: encoding: [0x99,0xc0,0x94,0x76] +- +-xvmaxi.wu $xr27, $xr7, 21 +-# CHECK-INST: xvmaxi.wu $xr27, $xr7, 21 +-# CHECK-ENCODING: encoding: [0xfb,0x54,0x95,0x76] +- +-xvmaxi.du $xr31, $xr13, 9 +-# CHECK-INST: xvmaxi.du $xr31, $xr13, 9 +-# CHECK-ENCODING: encoding: [0xbf,0xa5,0x95,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/min.s b/llvm/test/MC/LoongArch/lasx/min.s +deleted file mode 100644 +index 170c11124..000000000 +--- a/llvm/test/MC/LoongArch/lasx/min.s ++++ /dev/null +@@ -1,68 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvmin.b $xr21, $xr26, $xr7 +-# CHECK-INST: xvmin.b $xr21, $xr26, $xr7 +-# CHECK-ENCODING: encoding: [0x55,0x1f,0x72,0x74] +- +-xvmin.h $xr29, $xr5, $xr9 +-# CHECK-INST: xvmin.h $xr29, $xr5, $xr9 +-# CHECK-ENCODING: encoding: [0xbd,0xa4,0x72,0x74] +- +-xvmin.w $xr31, $xr24, $xr20 +-# CHECK-INST: xvmin.w $xr31, $xr24, $xr20 +-# CHECK-ENCODING: encoding: [0x1f,0x53,0x73,0x74] +- +-xvmin.d $xr27, $xr27, $xr2 +-# CHECK-INST: xvmin.d $xr27, $xr27, $xr2 +-# CHECK-ENCODING: encoding: [0x7b,0x8b,0x73,0x74] +- +-xvmini.b $xr22, $xr17, 9 +-# CHECK-INST: xvmini.b $xr22, $xr17, 9 +-# CHECK-ENCODING: encoding: [0x36,0x26,0x92,0x76] +- +-xvmini.h $xr12, $xr23, -15 +-# CHECK-INST: xvmini.h $xr12, $xr23, -15 +-# CHECK-ENCODING: encoding: [0xec,0xc6,0x92,0x76] +- +-xvmini.w $xr1, $xr17, -13 +-# CHECK-INST: xvmini.w $xr1, $xr17, -13 +-# CHECK-ENCODING: encoding: [0x21,0x4e,0x93,0x76] +- +-xvmini.d $xr10, $xr31, 11 +-# CHECK-INST: xvmini.d $xr10, $xr31, 11 +-# CHECK-ENCODING: encoding: [0xea,0xaf,0x93,0x76] +- +-xvmin.bu $xr15, $xr16, $xr3 +-# CHECK-INST: xvmin.bu $xr15, $xr16, $xr3 +-# CHECK-ENCODING: encoding: [0x0f,0x0e,0x76,0x74] +- +-xvmin.hu $xr4, $xr31, $xr27 +-# CHECK-INST: xvmin.hu $xr4, $xr31, $xr27 +-# CHECK-ENCODING: encoding: [0xe4,0xef,0x76,0x74] +- +-xvmin.wu $xr15, $xr13, $xr28 +-# CHECK-INST: xvmin.wu $xr15, $xr13, $xr28 +-# CHECK-ENCODING: encoding: [0xaf,0x71,0x77,0x74] +- +-xvmin.du $xr27, $xr3, $xr5 +-# CHECK-INST: xvmin.du $xr27, $xr3, $xr5 +-# CHECK-ENCODING: encoding: [0x7b,0x94,0x77,0x74] +- +-xvmini.bu $xr6, $xr24, 7 +-# CHECK-INST: xvmini.bu $xr6, $xr24, 7 +-# CHECK-ENCODING: encoding: [0x06,0x1f,0x96,0x76] +- +-xvmini.hu $xr8, $xr5, 29 +-# CHECK-INST: xvmini.hu $xr8, $xr5, 29 +-# CHECK-ENCODING: encoding: [0xa8,0xf4,0x96,0x76] +- +-xvmini.wu $xr17, $xr13, 19 +-# CHECK-INST: xvmini.wu $xr17, $xr13, 19 +-# CHECK-ENCODING: encoding: [0xb1,0x4d,0x97,0x76] +- +-xvmini.du $xr16, $xr23, 30 +-# CHECK-INST: xvmini.du $xr16, $xr23, 30 +-# CHECK-ENCODING: encoding: [0xf0,0xfa,0x97,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/mod.s b/llvm/test/MC/LoongArch/lasx/mod.s +deleted file mode 100644 +index bdb458a8d..000000000 +--- a/llvm/test/MC/LoongArch/lasx/mod.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvmod.b $xr8, $xr3, $xr0 +-# CHECK-INST: xvmod.b $xr8, $xr3, $xr0 +-# CHECK-ENCODING: encoding: [0x68,0x00,0xe2,0x74] +- +-xvmod.h $xr2, $xr17, $xr28 +-# CHECK-INST: xvmod.h $xr2, $xr17, $xr28 +-# CHECK-ENCODING: encoding: [0x22,0xf2,0xe2,0x74] +- +-xvmod.w $xr14, $xr8, $xr13 +-# CHECK-INST: xvmod.w $xr14, $xr8, $xr13 +-# CHECK-ENCODING: encoding: [0x0e,0x35,0xe3,0x74] +- +-xvmod.d $xr11, $xr10, $xr18 +-# CHECK-INST: xvmod.d $xr11, $xr10, $xr18 +-# CHECK-ENCODING: encoding: [0x4b,0xc9,0xe3,0x74] +- +-xvmod.bu $xr16, $xr1, $xr26 +-# CHECK-INST: xvmod.bu $xr16, $xr1, $xr26 +-# CHECK-ENCODING: encoding: [0x30,0x68,0xe6,0x74] +- +-xvmod.hu $xr15, $xr13, $xr0 +-# CHECK-INST: xvmod.hu $xr15, $xr13, $xr0 +-# CHECK-ENCODING: encoding: [0xaf,0x81,0xe6,0x74] +- +-xvmod.wu $xr11, $xr19, $xr20 +-# CHECK-INST: xvmod.wu $xr11, $xr19, $xr20 +-# CHECK-ENCODING: encoding: [0x6b,0x52,0xe7,0x74] +- +-xvmod.du $xr14, $xr3, $xr6 +-# CHECK-INST: xvmod.du $xr14, $xr3, $xr6 +-# CHECK-ENCODING: encoding: [0x6e,0x98,0xe7,0x74] +diff --git a/llvm/test/MC/LoongArch/lasx/mskgez.s b/llvm/test/MC/LoongArch/lasx/mskgez.s +deleted file mode 100644 +index 347b2fed5..000000000 +--- a/llvm/test/MC/LoongArch/lasx/mskgez.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvmskgez.b $xr30, $xr5 +-# CHECK-INST: xvmskgez.b $xr30, $xr5 +-# CHECK-ENCODING: encoding: [0xbe,0x50,0x9c,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/mskltz.s b/llvm/test/MC/LoongArch/lasx/mskltz.s +deleted file mode 100644 +index 52dd411d0..000000000 +--- a/llvm/test/MC/LoongArch/lasx/mskltz.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvmskltz.b $xr14, $xr5 +-# CHECK-INST: xvmskltz.b $xr14, $xr5 +-# CHECK-ENCODING: encoding: [0xae,0x40,0x9c,0x76] +- +-xvmskltz.h $xr11, $xr25 +-# CHECK-INST: xvmskltz.h $xr11, $xr25 +-# CHECK-ENCODING: encoding: [0x2b,0x47,0x9c,0x76] +- +-xvmskltz.w $xr14, $xr27 +-# CHECK-INST: xvmskltz.w $xr14, $xr27 +-# CHECK-ENCODING: encoding: [0x6e,0x4b,0x9c,0x76] +- +-xvmskltz.d $xr7, $xr23 +-# CHECK-INST: xvmskltz.d $xr7, $xr23 +-# CHECK-ENCODING: encoding: [0xe7,0x4e,0x9c,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/msknz.s b/llvm/test/MC/LoongArch/lasx/msknz.s +deleted file mode 100644 +index 288c7e616..000000000 +--- a/llvm/test/MC/LoongArch/lasx/msknz.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvmsknz.b $xr22, $xr22 +-# CHECK-INST: xvmsknz.b $xr22, $xr22 +-# CHECK-ENCODING: encoding: [0xd6,0x62,0x9c,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/msub.s b/llvm/test/MC/LoongArch/lasx/msub.s +deleted file mode 100644 +index 72da08a74..000000000 +--- a/llvm/test/MC/LoongArch/lasx/msub.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvmsub.b $xr22, $xr20, $xr7 +-# CHECK-INST: xvmsub.b $xr22, $xr20, $xr7 +-# CHECK-ENCODING: encoding: [0x96,0x1e,0xaa,0x74] +- +-xvmsub.h $xr0, $xr18, $xr12 +-# CHECK-INST: xvmsub.h $xr0, $xr18, $xr12 +-# CHECK-ENCODING: encoding: [0x40,0xb2,0xaa,0x74] +- +-xvmsub.w $xr3, $xr22, $xr29 +-# CHECK-INST: xvmsub.w $xr3, $xr22, $xr29 +-# CHECK-ENCODING: encoding: [0xc3,0x76,0xab,0x74] +- +-xvmsub.d $xr11, $xr26, $xr2 +-# CHECK-INST: xvmsub.d $xr11, $xr26, $xr2 +-# CHECK-ENCODING: encoding: [0x4b,0x8b,0xab,0x74] +diff --git a/llvm/test/MC/LoongArch/lasx/muh.s b/llvm/test/MC/LoongArch/lasx/muh.s +deleted file mode 100644 +index 226a97a05..000000000 +--- a/llvm/test/MC/LoongArch/lasx/muh.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvmuh.b $xr4, $xr8, $xr4 +-# CHECK-INST: xvmuh.b $xr4, $xr8, $xr4 +-# CHECK-ENCODING: encoding: [0x04,0x11,0x86,0x74] +- +-xvmuh.h $xr5, $xr23, $xr26 +-# CHECK-INST: xvmuh.h $xr5, $xr23, $xr26 +-# CHECK-ENCODING: encoding: [0xe5,0xea,0x86,0x74] +- +-xvmuh.w $xr28, $xr3, $xr25 +-# CHECK-INST: xvmuh.w $xr28, $xr3, $xr25 +-# CHECK-ENCODING: encoding: [0x7c,0x64,0x87,0x74] +- +-xvmuh.d $xr6, $xr0, $xr9 +-# CHECK-INST: xvmuh.d $xr6, $xr0, $xr9 +-# CHECK-ENCODING: encoding: [0x06,0xa4,0x87,0x74] +- +-xvmuh.bu $xr15, $xr20, $xr24 +-# CHECK-INST: xvmuh.bu $xr15, $xr20, $xr24 +-# CHECK-ENCODING: encoding: [0x8f,0x62,0x88,0x74] +- +-xvmuh.hu $xr28, $xr12, $xr27 +-# CHECK-INST: xvmuh.hu $xr28, $xr12, $xr27 +-# CHECK-ENCODING: encoding: [0x9c,0xed,0x88,0x74] +- +-xvmuh.wu $xr25, $xr6, $xr10 +-# CHECK-INST: xvmuh.wu $xr25, $xr6, $xr10 +-# CHECK-ENCODING: encoding: [0xd9,0x28,0x89,0x74] +- +-xvmuh.du $xr19, $xr8, $xr31 +-# CHECK-INST: xvmuh.du $xr19, $xr8, $xr31 +-# CHECK-ENCODING: encoding: [0x13,0xfd,0x89,0x74] +diff --git a/llvm/test/MC/LoongArch/lasx/mul.s b/llvm/test/MC/LoongArch/lasx/mul.s +deleted file mode 100644 +index 8d24b6549..000000000 +--- a/llvm/test/MC/LoongArch/lasx/mul.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvmul.b $xr18, $xr7, $xr27 +-# CHECK-INST: xvmul.b $xr18, $xr7, $xr27 +-# CHECK-ENCODING: encoding: [0xf2,0x6c,0x84,0x74] +- +-xvmul.h $xr9, $xr23, $xr18 +-# CHECK-INST: xvmul.h $xr9, $xr23, $xr18 +-# CHECK-ENCODING: encoding: [0xe9,0xca,0x84,0x74] +- +-xvmul.w $xr21, $xr8, $xr27 +-# CHECK-INST: xvmul.w $xr21, $xr8, $xr27 +-# CHECK-ENCODING: encoding: [0x15,0x6d,0x85,0x74] +- +-xvmul.d $xr0, $xr15, $xr8 +-# CHECK-INST: xvmul.d $xr0, $xr15, $xr8 +-# CHECK-ENCODING: encoding: [0xe0,0xa1,0x85,0x74] +diff --git a/llvm/test/MC/LoongArch/lasx/mulw.s b/llvm/test/MC/LoongArch/lasx/mulw.s +deleted file mode 100644 +index 42aa23ba9..000000000 +--- a/llvm/test/MC/LoongArch/lasx/mulw.s ++++ /dev/null +@@ -1,100 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvmulwev.h.b $xr2, $xr7, $xr16 +-# CHECK-INST: xvmulwev.h.b $xr2, $xr7, $xr16 +-# CHECK-ENCODING: encoding: [0xe2,0x40,0x90,0x74] +- +-xvmulwev.w.h $xr12, $xr11, $xr6 +-# CHECK-INST: xvmulwev.w.h $xr12, $xr11, $xr6 +-# CHECK-ENCODING: encoding: [0x6c,0x99,0x90,0x74] +- +-xvmulwev.d.w $xr16, $xr24, $xr15 +-# CHECK-INST: xvmulwev.d.w $xr16, $xr24, $xr15 +-# CHECK-ENCODING: encoding: [0x10,0x3f,0x91,0x74] +- +-xvmulwev.q.d $xr17, $xr16, $xr4 +-# CHECK-INST: xvmulwev.q.d $xr17, $xr16, $xr4 +-# CHECK-ENCODING: encoding: [0x11,0x92,0x91,0x74] +- +-xvmulwev.h.bu $xr20, $xr7, $xr29 +-# CHECK-INST: xvmulwev.h.bu $xr20, $xr7, $xr29 +-# CHECK-ENCODING: encoding: [0xf4,0x74,0x98,0x74] +- +-xvmulwev.w.hu $xr13, $xr24, $xr17 +-# CHECK-INST: xvmulwev.w.hu $xr13, $xr24, $xr17 +-# CHECK-ENCODING: encoding: [0x0d,0xc7,0x98,0x74] +- +-xvmulwev.d.wu $xr1, $xr24, $xr30 +-# CHECK-INST: xvmulwev.d.wu $xr1, $xr24, $xr30 +-# CHECK-ENCODING: encoding: [0x01,0x7b,0x99,0x74] +- +-xvmulwev.q.du $xr1, $xr22, $xr27 +-# CHECK-INST: xvmulwev.q.du $xr1, $xr22, $xr27 +-# CHECK-ENCODING: encoding: [0xc1,0xee,0x99,0x74] +- +-xvmulwev.h.bu.b $xr13, $xr28, $xr12 +-# CHECK-INST: xvmulwev.h.bu.b $xr13, $xr28, $xr12 +-# CHECK-ENCODING: encoding: [0x8d,0x33,0xa0,0x74] +- +-xvmulwev.w.hu.h $xr27, $xr16, $xr7 +-# CHECK-INST: xvmulwev.w.hu.h $xr27, $xr16, $xr7 +-# CHECK-ENCODING: encoding: [0x1b,0x9e,0xa0,0x74] +- +-xvmulwev.d.wu.w $xr13, $xr7, $xr17 +-# CHECK-INST: xvmulwev.d.wu.w $xr13, $xr7, $xr17 +-# CHECK-ENCODING: encoding: [0xed,0x44,0xa1,0x74] +- +-xvmulwev.q.du.d $xr9, $xr20, $xr15 +-# CHECK-INST: xvmulwev.q.du.d $xr9, $xr20, $xr15 +-# CHECK-ENCODING: encoding: [0x89,0xbe,0xa1,0x74] +- +-xvmulwod.h.b $xr16, $xr18, $xr2 +-# CHECK-INST: xvmulwod.h.b $xr16, $xr18, $xr2 +-# CHECK-ENCODING: encoding: [0x50,0x0a,0x92,0x74] +- +-xvmulwod.w.h $xr30, $xr2, $xr23 +-# CHECK-INST: xvmulwod.w.h $xr30, $xr2, $xr23 +-# CHECK-ENCODING: encoding: [0x5e,0xdc,0x92,0x74] +- +-xvmulwod.d.w $xr30, $xr27, $xr8 +-# CHECK-INST: xvmulwod.d.w $xr30, $xr27, $xr8 +-# CHECK-ENCODING: encoding: [0x7e,0x23,0x93,0x74] +- +-xvmulwod.q.d $xr20, $xr21, $xr15 +-# CHECK-INST: xvmulwod.q.d $xr20, $xr21, $xr15 +-# CHECK-ENCODING: encoding: [0xb4,0xbe,0x93,0x74] +- +-xvmulwod.h.bu $xr19, $xr26, $xr7 +-# CHECK-INST: xvmulwod.h.bu $xr19, $xr26, $xr7 +-# CHECK-ENCODING: encoding: [0x53,0x1f,0x9a,0x74] +- +-xvmulwod.w.hu $xr14, $xr17, $xr6 +-# CHECK-INST: xvmulwod.w.hu $xr14, $xr17, $xr6 +-# CHECK-ENCODING: encoding: [0x2e,0x9a,0x9a,0x74] +- +-xvmulwod.d.wu $xr24, $xr22, $xr20 +-# CHECK-INST: xvmulwod.d.wu $xr24, $xr22, $xr20 +-# CHECK-ENCODING: encoding: [0xd8,0x52,0x9b,0x74] +- +-xvmulwod.q.du $xr28, $xr31, $xr7 +-# CHECK-INST: xvmulwod.q.du $xr28, $xr31, $xr7 +-# CHECK-ENCODING: encoding: [0xfc,0x9f,0x9b,0x74] +- +-xvmulwod.h.bu.b $xr24, $xr15, $xr28 +-# CHECK-INST: xvmulwod.h.bu.b $xr24, $xr15, $xr28 +-# CHECK-ENCODING: encoding: [0xf8,0x71,0xa2,0x74] +- +-xvmulwod.w.hu.h $xr24, $xr8, $xr1 +-# CHECK-INST: xvmulwod.w.hu.h $xr24, $xr8, $xr1 +-# CHECK-ENCODING: encoding: [0x18,0x85,0xa2,0x74] +- +-xvmulwod.d.wu.w $xr10, $xr3, $xr1 +-# CHECK-INST: xvmulwod.d.wu.w $xr10, $xr3, $xr1 +-# CHECK-ENCODING: encoding: [0x6a,0x04,0xa3,0x74] +- +-xvmulwod.q.du.d $xr15, $xr15, $xr2 +-# CHECK-INST: xvmulwod.q.du.d $xr15, $xr15, $xr2 +-# CHECK-ENCODING: encoding: [0xef,0x89,0xa3,0x74] +diff --git a/llvm/test/MC/LoongArch/lasx/neg.s b/llvm/test/MC/LoongArch/lasx/neg.s +deleted file mode 100644 +index 7db7de62e..000000000 +--- a/llvm/test/MC/LoongArch/lasx/neg.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvneg.b $xr23, $xr4 +-# CHECK-INST: xvneg.b $xr23, $xr4 +-# CHECK-ENCODING: encoding: [0x97,0x30,0x9c,0x76] +- +-xvneg.h $xr8, $xr14 +-# CHECK-INST: xvneg.h $xr8, $xr14 +-# CHECK-ENCODING: encoding: [0xc8,0x35,0x9c,0x76] +- +-xvneg.w $xr23, $xr14 +-# CHECK-INST: xvneg.w $xr23, $xr14 +-# CHECK-ENCODING: encoding: [0xd7,0x39,0x9c,0x76] +- +-xvneg.d $xr20, $xr17 +-# CHECK-INST: xvneg.d $xr20, $xr17 +-# CHECK-ENCODING: encoding: [0x34,0x3e,0x9c,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/nor.s b/llvm/test/MC/LoongArch/lasx/nor.s +deleted file mode 100644 +index 95ef446bf..000000000 +--- a/llvm/test/MC/LoongArch/lasx/nor.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvnor.v $xr4, $xr23, $xr3 +-# CHECK-INST: xvnor.v $xr4, $xr23, $xr3 +-# CHECK-ENCODING: encoding: [0xe4,0x8e,0x27,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/nori.s b/llvm/test/MC/LoongArch/lasx/nori.s +deleted file mode 100644 +index 42ea27d43..000000000 +--- a/llvm/test/MC/LoongArch/lasx/nori.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvnori.b $xr7, $xr1, 209 +-# CHECK-INST: xvnori.b $xr7, $xr1, 209 +-# CHECK-ENCODING: encoding: [0x27,0x44,0xdf,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/or.s b/llvm/test/MC/LoongArch/lasx/or.s +deleted file mode 100644 +index dd4c17600..000000000 +--- a/llvm/test/MC/LoongArch/lasx/or.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvor.v $xr6, $xr29, $xr21 +-# CHECK-INST: xvor.v $xr6, $xr29, $xr21 +-# CHECK-ENCODING: encoding: [0xa6,0xd7,0x26,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/ori.s b/llvm/test/MC/LoongArch/lasx/ori.s +deleted file mode 100644 +index 2b1e56a5c..000000000 +--- a/llvm/test/MC/LoongArch/lasx/ori.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvori.b $xr6, $xr2, 239 +-# CHECK-INST: xvori.b $xr6, $xr2, 239 +-# CHECK-ENCODING: encoding: [0x46,0xbc,0xd7,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/orn.s b/llvm/test/MC/LoongArch/lasx/orn.s +deleted file mode 100644 +index a318de257..000000000 +--- a/llvm/test/MC/LoongArch/lasx/orn.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvorn.v $xr17, $xr29, $xr5 +-# CHECK-INST: xvorn.v $xr17, $xr29, $xr5 +-# CHECK-ENCODING: encoding: [0xb1,0x97,0x28,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/pack.s b/llvm/test/MC/LoongArch/lasx/pack.s +deleted file mode 100644 +index bb71be4b0..000000000 +--- a/llvm/test/MC/LoongArch/lasx/pack.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvpackev.b $xr21, $xr2, $xr8 +-# CHECK-INST: xvpackev.b $xr21, $xr2, $xr8 +-# CHECK-ENCODING: encoding: [0x55,0x20,0x16,0x75] +- +-xvpackev.h $xr8, $xr18, $xr6 +-# CHECK-INST: xvpackev.h $xr8, $xr18, $xr6 +-# CHECK-ENCODING: encoding: [0x48,0x9a,0x16,0x75] +- +-xvpackev.w $xr0, $xr6, $xr30 +-# CHECK-INST: xvpackev.w $xr0, $xr6, $xr30 +-# CHECK-ENCODING: encoding: [0xc0,0x78,0x17,0x75] +- +-xvpackev.d $xr0, $xr9, $xr4 +-# CHECK-INST: xvpackev.d $xr0, $xr9, $xr4 +-# CHECK-ENCODING: encoding: [0x20,0x91,0x17,0x75] +- +-xvpackod.b $xr28, $xr29, $xr31 +-# CHECK-INST: xvpackod.b $xr28, $xr29, $xr31 +-# CHECK-ENCODING: encoding: [0xbc,0x7f,0x18,0x75] +- +-xvpackod.h $xr14, $xr10, $xr6 +-# CHECK-INST: xvpackod.h $xr14, $xr10, $xr6 +-# CHECK-ENCODING: encoding: [0x4e,0x99,0x18,0x75] +- +-xvpackod.w $xr22, $xr21, $xr2 +-# CHECK-INST: xvpackod.w $xr22, $xr21, $xr2 +-# CHECK-ENCODING: encoding: [0xb6,0x0a,0x19,0x75] +- +-xvpackod.d $xr18, $xr9, $xr2 +-# CHECK-INST: xvpackod.d $xr18, $xr9, $xr2 +-# CHECK-ENCODING: encoding: [0x32,0x89,0x19,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/pcnt.s b/llvm/test/MC/LoongArch/lasx/pcnt.s +deleted file mode 100644 +index 9f1786bec..000000000 +--- a/llvm/test/MC/LoongArch/lasx/pcnt.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvpcnt.b $xr8, $xr27 +-# CHECK-INST: xvpcnt.b $xr8, $xr27 +-# CHECK-ENCODING: encoding: [0x68,0x23,0x9c,0x76] +- +-xvpcnt.h $xr12, $xr4 +-# CHECK-INST: xvpcnt.h $xr12, $xr4 +-# CHECK-ENCODING: encoding: [0x8c,0x24,0x9c,0x76] +- +-xvpcnt.w $xr31, $xr23 +-# CHECK-INST: xvpcnt.w $xr31, $xr23 +-# CHECK-ENCODING: encoding: [0xff,0x2a,0x9c,0x76] +- +-xvpcnt.d $xr26, $xr12 +-# CHECK-INST: xvpcnt.d $xr26, $xr12 +-# CHECK-ENCODING: encoding: [0x9a,0x2d,0x9c,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/perm.s b/llvm/test/MC/LoongArch/lasx/perm.s +deleted file mode 100644 +index 85bef644c..000000000 +--- a/llvm/test/MC/LoongArch/lasx/perm.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvperm.w $xr24, $xr23, $xr16 +-# CHECK-INST: xvperm.w $xr24, $xr23, $xr16 +-# CHECK-ENCODING: encoding: [0xf8,0x42,0x7d,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/permi.s b/llvm/test/MC/LoongArch/lasx/permi.s +deleted file mode 100644 +index 4d925a86b..000000000 +--- a/llvm/test/MC/LoongArch/lasx/permi.s ++++ /dev/null +@@ -1,16 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvpermi.w $xr7, $xr12, 101 +-# CHECK-INST: xvpermi.w $xr7, $xr12, 101 +-# CHECK-ENCODING: encoding: [0x87,0x95,0xe5,0x77] +- +-xvpermi.d $xr17, $xr6, 131 +-# CHECK-INST: xvpermi.d $xr17, $xr6, 131 +-# CHECK-ENCODING: encoding: [0xd1,0x0c,0xea,0x77] +- +-xvpermi.q $xr10, $xr15, 184 +-# CHECK-INST: xvpermi.q $xr10, $xr15, 184 +-# CHECK-ENCODING: encoding: [0xea,0xe1,0xee,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/pick.s b/llvm/test/MC/LoongArch/lasx/pick.s +deleted file mode 100644 +index 7510d2088..000000000 +--- a/llvm/test/MC/LoongArch/lasx/pick.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvpickev.b $xr22, $xr27, $xr6 +-# CHECK-INST: xvpickev.b $xr22, $xr27, $xr6 +-# CHECK-ENCODING: encoding: [0x76,0x1b,0x1e,0x75] +- +-xvpickev.h $xr14, $xr11, $xr3 +-# CHECK-INST: xvpickev.h $xr14, $xr11, $xr3 +-# CHECK-ENCODING: encoding: [0x6e,0x8d,0x1e,0x75] +- +-xvpickev.w $xr30, $xr28, $xr13 +-# CHECK-INST: xvpickev.w $xr30, $xr28, $xr13 +-# CHECK-ENCODING: encoding: [0x9e,0x37,0x1f,0x75] +- +-xvpickev.d $xr1, $xr24, $xr9 +-# CHECK-INST: xvpickev.d $xr1, $xr24, $xr9 +-# CHECK-ENCODING: encoding: [0x01,0xa7,0x1f,0x75] +- +-xvpickod.b $xr14, $xr22, $xr15 +-# CHECK-INST: xvpickod.b $xr14, $xr22, $xr15 +-# CHECK-ENCODING: encoding: [0xce,0x3e,0x20,0x75] +- +-xvpickod.h $xr31, $xr21, $xr12 +-# CHECK-INST: xvpickod.h $xr31, $xr21, $xr12 +-# CHECK-ENCODING: encoding: [0xbf,0xb2,0x20,0x75] +- +-xvpickod.w $xr31, $xr0, $xr30 +-# CHECK-INST: xvpickod.w $xr31, $xr0, $xr30 +-# CHECK-ENCODING: encoding: [0x1f,0x78,0x21,0x75] +- +-xvpickod.d $xr10, $xr5, $xr16 +-# CHECK-INST: xvpickod.d $xr10, $xr5, $xr16 +-# CHECK-ENCODING: encoding: [0xaa,0xc0,0x21,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/pickve.s b/llvm/test/MC/LoongArch/lasx/pickve.s +deleted file mode 100644 +index 6f8c40bfa..000000000 +--- a/llvm/test/MC/LoongArch/lasx/pickve.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvpickve.w $xr25, $xr28, 1 +-# CHECK-INST: xvpickve.w $xr25, $xr28, 1 +-# CHECK-ENCODING: encoding: [0x99,0xc7,0x03,0x77] +- +-xvpickve.d $xr13, $xr1, 0 +-# CHECK-INST: xvpickve.d $xr13, $xr1, 0 +-# CHECK-ENCODING: encoding: [0x2d,0xe0,0x03,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/pickve2gr.s b/llvm/test/MC/LoongArch/lasx/pickve2gr.s +deleted file mode 100644 +index d378d4ff6..000000000 +--- a/llvm/test/MC/LoongArch/lasx/pickve2gr.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvpickve2gr.w $r14, $xr11, 6 +-# CHECK-INST: xvpickve2gr.w $t2, $xr11, 6 +-# CHECK-ENCODING: encoding: [0x6e,0xd9,0xef,0x76] +- +-xvpickve2gr.d $r8, $xr6, 0 +-# CHECK-INST: xvpickve2gr.d $a4, $xr6, 0 +-# CHECK-ENCODING: encoding: [0xc8,0xe0,0xef,0x76] +- +-xvpickve2gr.wu $r12, $xr1, 4 +-# CHECK-INST: xvpickve2gr.wu $t0, $xr1, 4 +-# CHECK-ENCODING: encoding: [0x2c,0xd0,0xf3,0x76] +- +-xvpickve2gr.du $r10, $xr8, 0 +-# CHECK-INST: xvpickve2gr.du $a6, $xr8, 0 +-# CHECK-ENCODING: encoding: [0x0a,0xe1,0xf3,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/repl128vei.s b/llvm/test/MC/LoongArch/lasx/repl128vei.s +deleted file mode 100644 +index 44f9b9596..000000000 +--- a/llvm/test/MC/LoongArch/lasx/repl128vei.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvrepl128vei.b $xr10, $xr19, 2 +-# CHECK-INST: xvrepl128vei.b $xr10, $xr19, 2 +-# CHECK-ENCODING: encoding: [0x6a,0x8a,0xf7,0x76] +- +-xvrepl128vei.h $xr6, $xr19, 2 +-# CHECK-INST: xvrepl128vei.h $xr6, $xr19, 2 +-# CHECK-ENCODING: encoding: [0x66,0xca,0xf7,0x76] +- +-xvrepl128vei.w $xr11, $xr13, 1 +-# CHECK-INST: xvrepl128vei.w $xr11, $xr13, 1 +-# CHECK-ENCODING: encoding: [0xab,0xe5,0xf7,0x76] +- +-xvrepl128vei.d $xr31, $xr23, 0 +-# CHECK-INST: xvrepl128vei.d $xr31, $xr23, 0 +-# CHECK-ENCODING: encoding: [0xff,0xf2,0xf7,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/replgr2vr.s b/llvm/test/MC/LoongArch/lasx/replgr2vr.s +deleted file mode 100644 +index d1584c3c0..000000000 +--- a/llvm/test/MC/LoongArch/lasx/replgr2vr.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvreplgr2vr.b $xr16, $r16 +-# CHECK-INST: xvreplgr2vr.b $xr16, $t4 +-# CHECK-ENCODING: encoding: [0x10,0x02,0x9f,0x76] +- +-xvreplgr2vr.h $xr7, $r22 +-# CHECK-INST: xvreplgr2vr.h $xr7, $fp +-# CHECK-ENCODING: encoding: [0xc7,0x06,0x9f,0x76] +- +-xvreplgr2vr.w $xr4, $r15 +-# CHECK-INST: xvreplgr2vr.w $xr4, $t3 +-# CHECK-ENCODING: encoding: [0xe4,0x09,0x9f,0x76] +- +-xvreplgr2vr.d $xr16, $r24 +-# CHECK-INST: xvreplgr2vr.d $xr16, $s1 +-# CHECK-ENCODING: encoding: [0x10,0x0f,0x9f,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/replve.s b/llvm/test/MC/LoongArch/lasx/replve.s +deleted file mode 100644 +index c0319a426..000000000 +--- a/llvm/test/MC/LoongArch/lasx/replve.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvreplve.b $xr20, $xr16, $r11 +-# CHECK-INST: xvreplve.b $xr20, $xr16, $a7 +-# CHECK-ENCODING: encoding: [0x14,0x2e,0x22,0x75] +- +-xvreplve.h $xr0, $xr21, $r24 +-# CHECK-INST: xvreplve.h $xr0, $xr21, $s1 +-# CHECK-ENCODING: encoding: [0xa0,0xe2,0x22,0x75] +- +-xvreplve.w $xr20, $xr18, $r18 +-# CHECK-INST: xvreplve.w $xr20, $xr18, $t6 +-# CHECK-ENCODING: encoding: [0x54,0x4a,0x23,0x75] +- +-xvreplve.d $xr4, $xr3, $r23 +-# CHECK-INST: xvreplve.d $xr4, $xr3, $s0 +-# CHECK-ENCODING: encoding: [0x64,0xdc,0x23,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/replve0.s b/llvm/test/MC/LoongArch/lasx/replve0.s +deleted file mode 100644 +index f3289a5c4..000000000 +--- a/llvm/test/MC/LoongArch/lasx/replve0.s ++++ /dev/null +@@ -1,24 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvreplve0.b $xr11, $xr20 +-# CHECK-INST: xvreplve0.b $xr11, $xr20 +-# CHECK-ENCODING: encoding: [0x8b,0x02,0x07,0x77] +- +-xvreplve0.h $xr13, $xr26 +-# CHECK-INST: xvreplve0.h $xr13, $xr26 +-# CHECK-ENCODING: encoding: [0x4d,0x83,0x07,0x77] +- +-xvreplve0.w $xr8, $xr12 +-# CHECK-INST: xvreplve0.w $xr8, $xr12 +-# CHECK-ENCODING: encoding: [0x88,0xc1,0x07,0x77] +- +-xvreplve0.d $xr20, $xr4 +-# CHECK-INST: xvreplve0.d $xr20, $xr4 +-# CHECK-ENCODING: encoding: [0x94,0xe0,0x07,0x77] +- +-xvreplve0.q $xr17, $xr20 +-# CHECK-INST: xvreplve0.q $xr17, $xr20 +-# CHECK-ENCODING: encoding: [0x91,0xf2,0x07,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/rotr.s b/llvm/test/MC/LoongArch/lasx/rotr.s +deleted file mode 100644 +index c6dec2da7..000000000 +--- a/llvm/test/MC/LoongArch/lasx/rotr.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvrotr.b $xr0, $xr6, $xr30 +-# CHECK-INST: xvrotr.b $xr0, $xr6, $xr30 +-# CHECK-ENCODING: encoding: [0xc0,0x78,0xee,0x74] +- +-xvrotr.h $xr19, $xr17, $xr10 +-# CHECK-INST: xvrotr.h $xr19, $xr17, $xr10 +-# CHECK-ENCODING: encoding: [0x33,0xaa,0xee,0x74] +- +-xvrotr.w $xr18, $xr2, $xr7 +-# CHECK-INST: xvrotr.w $xr18, $xr2, $xr7 +-# CHECK-ENCODING: encoding: [0x52,0x1c,0xef,0x74] +- +-xvrotr.d $xr11, $xr23, $xr11 +-# CHECK-INST: xvrotr.d $xr11, $xr23, $xr11 +-# CHECK-ENCODING: encoding: [0xeb,0xae,0xef,0x74] +- +-xvrotri.b $xr1, $xr5, 3 +-# CHECK-INST: xvrotri.b $xr1, $xr5, 3 +-# CHECK-ENCODING: encoding: [0xa1,0x2c,0xa0,0x76] +- +-xvrotri.h $xr1, $xr17, 3 +-# CHECK-INST: xvrotri.h $xr1, $xr17, 3 +-# CHECK-ENCODING: encoding: [0x21,0x4e,0xa0,0x76] +- +-xvrotri.w $xr25, $xr23, 19 +-# CHECK-INST: xvrotri.w $xr25, $xr23, 19 +-# CHECK-ENCODING: encoding: [0xf9,0xce,0xa0,0x76] +- +-xvrotri.d $xr7, $xr24, 37 +-# CHECK-INST: xvrotri.d $xr7, $xr24, 37 +-# CHECK-ENCODING: encoding: [0x07,0x97,0xa1,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/sadd.s b/llvm/test/MC/LoongArch/lasx/sadd.s +deleted file mode 100644 +index abc84aaf8..000000000 +--- a/llvm/test/MC/LoongArch/lasx/sadd.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsadd.b $xr27, $xr30, $xr22 +-# CHECK-INST: xvsadd.b $xr27, $xr30, $xr22 +-# CHECK-ENCODING: encoding: [0xdb,0x5b,0x46,0x74] +- +-xvsadd.h $xr29, $xr0, $xr1 +-# CHECK-INST: xvsadd.h $xr29, $xr0, $xr1 +-# CHECK-ENCODING: encoding: [0x1d,0x84,0x46,0x74] +- +-xvsadd.w $xr22, $xr28, $xr31 +-# CHECK-INST: xvsadd.w $xr22, $xr28, $xr31 +-# CHECK-ENCODING: encoding: [0x96,0x7f,0x47,0x74] +- +-xvsadd.d $xr5, $xr18, $xr26 +-# CHECK-INST: xvsadd.d $xr5, $xr18, $xr26 +-# CHECK-ENCODING: encoding: [0x45,0xea,0x47,0x74] +- +-xvsadd.bu $xr29, $xr20, $xr28 +-# CHECK-INST: xvsadd.bu $xr29, $xr20, $xr28 +-# CHECK-ENCODING: encoding: [0x9d,0x72,0x4a,0x74] +- +-xvsadd.hu $xr7, $xr16, $xr6 +-# CHECK-INST: xvsadd.hu $xr7, $xr16, $xr6 +-# CHECK-ENCODING: encoding: [0x07,0x9a,0x4a,0x74] +- +-xvsadd.wu $xr2, $xr10, $xr15 +-# CHECK-INST: xvsadd.wu $xr2, $xr10, $xr15 +-# CHECK-ENCODING: encoding: [0x42,0x3d,0x4b,0x74] +- +-xvsadd.du $xr18, $xr24, $xr14 +-# CHECK-INST: xvsadd.du $xr18, $xr24, $xr14 +-# CHECK-ENCODING: encoding: [0x12,0xbb,0x4b,0x74] +diff --git a/llvm/test/MC/LoongArch/lasx/sat.s b/llvm/test/MC/LoongArch/lasx/sat.s +deleted file mode 100644 +index 19b51ad1c..000000000 +--- a/llvm/test/MC/LoongArch/lasx/sat.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsat.b $xr22, $xr7, 2 +-# CHECK-INST: xvsat.b $xr22, $xr7, 2 +-# CHECK-ENCODING: encoding: [0xf6,0x28,0x24,0x77] +- +-xvsat.h $xr3, $xr0, 5 +-# CHECK-INST: xvsat.h $xr3, $xr0, 5 +-# CHECK-ENCODING: encoding: [0x03,0x54,0x24,0x77] +- +-xvsat.w $xr9, $xr16, 0 +-# CHECK-INST: xvsat.w $xr9, $xr16, 0 +-# CHECK-ENCODING: encoding: [0x09,0x82,0x24,0x77] +- +-xvsat.d $xr3, $xr8, 1 +-# CHECK-INST: xvsat.d $xr3, $xr8, 1 +-# CHECK-ENCODING: encoding: [0x03,0x05,0x25,0x77] +- +-xvsat.bu $xr6, $xr6, 4 +-# CHECK-INST: xvsat.bu $xr6, $xr6, 4 +-# CHECK-ENCODING: encoding: [0xc6,0x30,0x28,0x77] +- +-xvsat.hu $xr12, $xr25, 12 +-# CHECK-INST: xvsat.hu $xr12, $xr25, 12 +-# CHECK-ENCODING: encoding: [0x2c,0x73,0x28,0x77] +- +-xvsat.wu $xr20, $xr1, 3 +-# CHECK-INST: xvsat.wu $xr20, $xr1, 3 +-# CHECK-ENCODING: encoding: [0x34,0x8c,0x28,0x77] +- +-xvsat.du $xr5, $xr20, 7 +-# CHECK-INST: xvsat.du $xr5, $xr20, 7 +-# CHECK-ENCODING: encoding: [0x85,0x1e,0x29,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/seq.s b/llvm/test/MC/LoongArch/lasx/seq.s +deleted file mode 100644 +index ca1842206..000000000 +--- a/llvm/test/MC/LoongArch/lasx/seq.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvseq.b $xr3, $xr4, $xr19 +-# CHECK-INST: xvseq.b $xr3, $xr4, $xr19 +-# CHECK-ENCODING: encoding: [0x83,0x4c,0x00,0x74] +- +-xvseq.h $xr0, $xr21, $xr5 +-# CHECK-INST: xvseq.h $xr0, $xr21, $xr5 +-# CHECK-ENCODING: encoding: [0xa0,0x96,0x00,0x74] +- +-xvseq.w $xr6, $xr16, $xr19 +-# CHECK-INST: xvseq.w $xr6, $xr16, $xr19 +-# CHECK-ENCODING: encoding: [0x06,0x4e,0x01,0x74] +- +-xvseq.d $xr8, $xr13, $xr13 +-# CHECK-INST: xvseq.d $xr8, $xr13, $xr13 +-# CHECK-ENCODING: encoding: [0xa8,0xb5,0x01,0x74] +- +-xvseqi.b $xr12, $xr25, 0 +-# CHECK-INST: xvseqi.b $xr12, $xr25, 0 +-# CHECK-ENCODING: encoding: [0x2c,0x03,0x80,0x76] +- +-xvseqi.h $xr9, $xr4, 10 +-# CHECK-INST: xvseqi.h $xr9, $xr4, 10 +-# CHECK-ENCODING: encoding: [0x89,0xa8,0x80,0x76] +- +-xvseqi.w $xr25, $xr4, -12 +-# CHECK-INST: xvseqi.w $xr25, $xr4, -12 +-# CHECK-ENCODING: encoding: [0x99,0x50,0x81,0x76] +- +-xvseqi.d $xr11, $xr7, 7 +-# CHECK-INST: xvseqi.d $xr11, $xr7, 7 +-# CHECK-ENCODING: encoding: [0xeb,0x9c,0x81,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/set.s b/llvm/test/MC/LoongArch/lasx/set.s +deleted file mode 100644 +index ad49e4d91..000000000 +--- a/llvm/test/MC/LoongArch/lasx/set.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvseteqz.v $fcc7, $xr1 +-# CHECK-INST: xvseteqz.v $fcc7, $xr1 +-# CHECK-ENCODING: encoding: [0x27,0x98,0x9c,0x76] +- +-xvsetnez.v $fcc7, $xr13 +-# CHECK-INST: xvsetnez.v $fcc7, $xr13 +-# CHECK-ENCODING: encoding: [0xa7,0x9d,0x9c,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/setallnez.s b/llvm/test/MC/LoongArch/lasx/setallnez.s +deleted file mode 100644 +index d58bad5f4..000000000 +--- a/llvm/test/MC/LoongArch/lasx/setallnez.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsetallnez.b $fcc5, $xr29 +-# CHECK-INST: xvsetallnez.b $fcc5, $xr29 +-# CHECK-ENCODING: encoding: [0xa5,0xb3,0x9c,0x76] +- +-xvsetallnez.h $fcc5, $xr4 +-# CHECK-INST: xvsetallnez.h $fcc5, $xr4 +-# CHECK-ENCODING: encoding: [0x85,0xb4,0x9c,0x76] +- +-xvsetallnez.w $fcc4, $xr5 +-# CHECK-INST: xvsetallnez.w $fcc4, $xr5 +-# CHECK-ENCODING: encoding: [0xa4,0xb8,0x9c,0x76] +- +-xvsetallnez.d $fcc7, $xr20 +-# CHECK-INST: xvsetallnez.d $fcc7, $xr20 +-# CHECK-ENCODING: encoding: [0x87,0xbe,0x9c,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/setanyeqz.s b/llvm/test/MC/LoongArch/lasx/setanyeqz.s +deleted file mode 100644 +index d879dd0f2..000000000 +--- a/llvm/test/MC/LoongArch/lasx/setanyeqz.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsetanyeqz.b $fcc5, $xr8 +-# CHECK-INST: xvsetanyeqz.b $fcc5, $xr8 +-# CHECK-ENCODING: encoding: [0x05,0xa1,0x9c,0x76] +- +-xvsetanyeqz.h $fcc5, $xr20 +-# CHECK-INST: xvsetanyeqz.h $fcc5, $xr20 +-# CHECK-ENCODING: encoding: [0x85,0xa6,0x9c,0x76] +- +-xvsetanyeqz.w $fcc7, $xr6 +-# CHECK-INST: xvsetanyeqz.w $fcc7, $xr6 +-# CHECK-ENCODING: encoding: [0xc7,0xa8,0x9c,0x76] +- +-xvsetanyeqz.d $fcc6, $xr17 +-# CHECK-INST: xvsetanyeqz.d $fcc6, $xr17 +-# CHECK-ENCODING: encoding: [0x26,0xae,0x9c,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/shuf.s b/llvm/test/MC/LoongArch/lasx/shuf.s +deleted file mode 100644 +index d08039d54..000000000 +--- a/llvm/test/MC/LoongArch/lasx/shuf.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvshuf.b $xr20, $xr6, $xr11, $xr15 +-# CHECK-INST: xvshuf.b $xr20, $xr6, $xr11, $xr15 +-# CHECK-ENCODING: encoding: [0xd4,0xac,0x67,0x0d] +- +-xvshuf.h $xr29, $xr24, $xr1 +-# CHECK-INST: xvshuf.h $xr29, $xr24, $xr1 +-# CHECK-ENCODING: encoding: [0x1d,0x87,0x7a,0x75] +- +-xvshuf.w $xr15, $xr24, $xr29 +-# CHECK-INST: xvshuf.w $xr15, $xr24, $xr29 +-# CHECK-ENCODING: encoding: [0x0f,0x77,0x7b,0x75] +- +-xvshuf.d $xr27, $xr18, $xr15 +-# CHECK-INST: xvshuf.d $xr27, $xr18, $xr15 +-# CHECK-ENCODING: encoding: [0x5b,0xbe,0x7b,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/shuf4i.s b/llvm/test/MC/LoongArch/lasx/shuf4i.s +deleted file mode 100644 +index 73610e529..000000000 +--- a/llvm/test/MC/LoongArch/lasx/shuf4i.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvshuf4i.b $xr21, $xr28, 168 +-# CHECK-INST: xvshuf4i.b $xr21, $xr28, 168 +-# CHECK-ENCODING: encoding: [0x95,0xa3,0x92,0x77] +- +-xvshuf4i.h $xr18, $xr3, 22 +-# CHECK-INST: xvshuf4i.h $xr18, $xr3, 22 +-# CHECK-ENCODING: encoding: [0x72,0x58,0x94,0x77] +- +-xvshuf4i.w $xr0, $xr25, 82 +-# CHECK-INST: xvshuf4i.w $xr0, $xr25, 82 +-# CHECK-ENCODING: encoding: [0x20,0x4b,0x99,0x77] +- +-xvshuf4i.d $xr24, $xr4, 99 +-# CHECK-INST: xvshuf4i.d $xr24, $xr4, 99 +-# CHECK-ENCODING: encoding: [0x98,0x8c,0x9d,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/signcov.s b/llvm/test/MC/LoongArch/lasx/signcov.s +deleted file mode 100644 +index 9656f7d78..000000000 +--- a/llvm/test/MC/LoongArch/lasx/signcov.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsigncov.b $xr1, $xr24, $xr13 +-# CHECK-INST: xvsigncov.b $xr1, $xr24, $xr13 +-# CHECK-ENCODING: encoding: [0x01,0x37,0x2e,0x75] +- +-xvsigncov.h $xr8, $xr23, $xr14 +-# CHECK-INST: xvsigncov.h $xr8, $xr23, $xr14 +-# CHECK-ENCODING: encoding: [0xe8,0xba,0x2e,0x75] +- +-xvsigncov.w $xr3, $xr25, $xr10 +-# CHECK-INST: xvsigncov.w $xr3, $xr25, $xr10 +-# CHECK-ENCODING: encoding: [0x23,0x2b,0x2f,0x75] +- +-xvsigncov.d $xr26, $xr17, $xr31 +-# CHECK-INST: xvsigncov.d $xr26, $xr17, $xr31 +-# CHECK-ENCODING: encoding: [0x3a,0xfe,0x2f,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/sle.s b/llvm/test/MC/LoongArch/lasx/sle.s +deleted file mode 100644 +index 062eca5d1..000000000 +--- a/llvm/test/MC/LoongArch/lasx/sle.s ++++ /dev/null +@@ -1,68 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsle.b $xr24, $xr30, $xr29 +-# CHECK-INST: xvsle.b $xr24, $xr30, $xr29 +-# CHECK-ENCODING: encoding: [0xd8,0x77,0x02,0x74] +- +-xvsle.h $xr23, $xr13, $xr20 +-# CHECK-INST: xvsle.h $xr23, $xr13, $xr20 +-# CHECK-ENCODING: encoding: [0xb7,0xd1,0x02,0x74] +- +-xvsle.w $xr10, $xr31, $xr24 +-# CHECK-INST: xvsle.w $xr10, $xr31, $xr24 +-# CHECK-ENCODING: encoding: [0xea,0x63,0x03,0x74] +- +-xvsle.d $xr13, $xr26, $xr8 +-# CHECK-INST: xvsle.d $xr13, $xr26, $xr8 +-# CHECK-ENCODING: encoding: [0x4d,0xa3,0x03,0x74] +- +-xvslei.b $xr14, $xr11, -10 +-# CHECK-INST: xvslei.b $xr14, $xr11, -10 +-# CHECK-ENCODING: encoding: [0x6e,0x59,0x82,0x76] +- +-xvslei.h $xr2, $xr22, 15 +-# CHECK-INST: xvslei.h $xr2, $xr22, 15 +-# CHECK-ENCODING: encoding: [0xc2,0xbe,0x82,0x76] +- +-xvslei.w $xr3, $xr14, 12 +-# CHECK-INST: xvslei.w $xr3, $xr14, 12 +-# CHECK-ENCODING: encoding: [0xc3,0x31,0x83,0x76] +- +-xvslei.d $xr19, $xr30, 10 +-# CHECK-INST: xvslei.d $xr19, $xr30, 10 +-# CHECK-ENCODING: encoding: [0xd3,0xab,0x83,0x76] +- +-xvsle.bu $xr9, $xr27, $xr2 +-# CHECK-INST: xvsle.bu $xr9, $xr27, $xr2 +-# CHECK-ENCODING: encoding: [0x69,0x0b,0x04,0x74] +- +-xvsle.hu $xr29, $xr25, $xr22 +-# CHECK-INST: xvsle.hu $xr29, $xr25, $xr22 +-# CHECK-ENCODING: encoding: [0x3d,0xdb,0x04,0x74] +- +-xvsle.wu $xr16, $xr25, $xr14 +-# CHECK-INST: xvsle.wu $xr16, $xr25, $xr14 +-# CHECK-ENCODING: encoding: [0x30,0x3b,0x05,0x74] +- +-xvsle.du $xr5, $xr6, $xr18 +-# CHECK-INST: xvsle.du $xr5, $xr6, $xr18 +-# CHECK-ENCODING: encoding: [0xc5,0xc8,0x05,0x74] +- +-xvslei.bu $xr17, $xr26, 10 +-# CHECK-INST: xvslei.bu $xr17, $xr26, 10 +-# CHECK-ENCODING: encoding: [0x51,0x2b,0x84,0x76] +- +-xvslei.hu $xr20, $xr11, 18 +-# CHECK-INST: xvslei.hu $xr20, $xr11, 18 +-# CHECK-ENCODING: encoding: [0x74,0xc9,0x84,0x76] +- +-xvslei.wu $xr1, $xr29, 10 +-# CHECK-INST: xvslei.wu $xr1, $xr29, 10 +-# CHECK-ENCODING: encoding: [0xa1,0x2b,0x85,0x76] +- +-xvslei.du $xr25, $xr31, 24 +-# CHECK-INST: xvslei.du $xr25, $xr31, 24 +-# CHECK-ENCODING: encoding: [0xf9,0xe3,0x85,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/sll.s b/llvm/test/MC/LoongArch/lasx/sll.s +deleted file mode 100644 +index ef9d3e5c4..000000000 +--- a/llvm/test/MC/LoongArch/lasx/sll.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsll.b $xr8, $xr29, $xr9 +-# CHECK-INST: xvsll.b $xr8, $xr29, $xr9 +-# CHECK-ENCODING: encoding: [0xa8,0x27,0xe8,0x74] +- +-xvsll.h $xr21, $xr28, $xr29 +-# CHECK-INST: xvsll.h $xr21, $xr28, $xr29 +-# CHECK-ENCODING: encoding: [0x95,0xf7,0xe8,0x74] +- +-xvsll.w $xr17, $xr30, $xr10 +-# CHECK-INST: xvsll.w $xr17, $xr30, $xr10 +-# CHECK-ENCODING: encoding: [0xd1,0x2b,0xe9,0x74] +- +-xvsll.d $xr19, $xr6, $xr26 +-# CHECK-INST: xvsll.d $xr19, $xr6, $xr26 +-# CHECK-ENCODING: encoding: [0xd3,0xe8,0xe9,0x74] +- +-xvslli.b $xr25, $xr26, 1 +-# CHECK-INST: xvslli.b $xr25, $xr26, 1 +-# CHECK-ENCODING: encoding: [0x59,0x27,0x2c,0x77] +- +-xvslli.h $xr17, $xr28, 14 +-# CHECK-INST: xvslli.h $xr17, $xr28, 14 +-# CHECK-ENCODING: encoding: [0x91,0x7b,0x2c,0x77] +- +-xvslli.w $xr26, $xr31, 29 +-# CHECK-INST: xvslli.w $xr26, $xr31, 29 +-# CHECK-ENCODING: encoding: [0xfa,0xf7,0x2c,0x77] +- +-xvslli.d $xr10, $xr28, 46 +-# CHECK-INST: xvslli.d $xr10, $xr28, 46 +-# CHECK-ENCODING: encoding: [0x8a,0xbb,0x2d,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/sllwil.s b/llvm/test/MC/LoongArch/lasx/sllwil.s +deleted file mode 100644 +index 0e89ccf02..000000000 +--- a/llvm/test/MC/LoongArch/lasx/sllwil.s ++++ /dev/null +@@ -1,28 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsllwil.h.b $xr13, $xr21, 6 +-# CHECK-INST: xvsllwil.h.b $xr13, $xr21, 6 +-# CHECK-ENCODING: encoding: [0xad,0x3a,0x08,0x77] +- +-xvsllwil.w.h $xr20, $xr29, 0 +-# CHECK-INST: xvsllwil.w.h $xr20, $xr29, 0 +-# CHECK-ENCODING: encoding: [0xb4,0x43,0x08,0x77] +- +-xvsllwil.d.w $xr3, $xr20, 24 +-# CHECK-INST: xvsllwil.d.w $xr3, $xr20, 24 +-# CHECK-ENCODING: encoding: [0x83,0xe2,0x08,0x77] +- +-xvsllwil.hu.bu $xr15, $xr15, 6 +-# CHECK-INST: xvsllwil.hu.bu $xr15, $xr15, 6 +-# CHECK-ENCODING: encoding: [0xef,0x39,0x0c,0x77] +- +-xvsllwil.wu.hu $xr22, $xr29, 0 +-# CHECK-INST: xvsllwil.wu.hu $xr22, $xr29, 0 +-# CHECK-ENCODING: encoding: [0xb6,0x43,0x0c,0x77] +- +-xvsllwil.du.wu $xr3, $xr5, 31 +-# CHECK-INST: xvsllwil.du.wu $xr3, $xr5, 31 +-# CHECK-ENCODING: encoding: [0xa3,0xfc,0x0c,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/slt.s b/llvm/test/MC/LoongArch/lasx/slt.s +deleted file mode 100644 +index 40308a59f..000000000 +--- a/llvm/test/MC/LoongArch/lasx/slt.s ++++ /dev/null +@@ -1,68 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvslt.b $xr30, $xr31, $xr13 +-# CHECK-INST: xvslt.b $xr30, $xr31, $xr13 +-# CHECK-ENCODING: encoding: [0xfe,0x37,0x06,0x74] +- +-xvslt.h $xr19, $xr23, $xr0 +-# CHECK-INST: xvslt.h $xr19, $xr23, $xr0 +-# CHECK-ENCODING: encoding: [0xf3,0x82,0x06,0x74] +- +-xvslt.w $xr23, $xr26, $xr3 +-# CHECK-INST: xvslt.w $xr23, $xr26, $xr3 +-# CHECK-ENCODING: encoding: [0x57,0x0f,0x07,0x74] +- +-xvslt.d $xr3, $xr10, $xr31 +-# CHECK-INST: xvslt.d $xr3, $xr10, $xr31 +-# CHECK-ENCODING: encoding: [0x43,0xfd,0x07,0x74] +- +-xvslti.b $xr31, $xr27, 6 +-# CHECK-INST: xvslti.b $xr31, $xr27, 6 +-# CHECK-ENCODING: encoding: [0x7f,0x1b,0x86,0x76] +- +-xvslti.h $xr5, $xr19, 6 +-# CHECK-INST: xvslti.h $xr5, $xr19, 6 +-# CHECK-ENCODING: encoding: [0x65,0x9a,0x86,0x76] +- +-xvslti.w $xr20, $xr8, 11 +-# CHECK-INST: xvslti.w $xr20, $xr8, 11 +-# CHECK-ENCODING: encoding: [0x14,0x2d,0x87,0x76] +- +-xvslti.d $xr13, $xr18, 2 +-# CHECK-INST: xvslti.d $xr13, $xr18, 2 +-# CHECK-ENCODING: encoding: [0x4d,0x8a,0x87,0x76] +- +-xvslt.bu $xr20, $xr13, $xr29 +-# CHECK-INST: xvslt.bu $xr20, $xr13, $xr29 +-# CHECK-ENCODING: encoding: [0xb4,0x75,0x08,0x74] +- +-xvslt.hu $xr12, $xr29, $xr26 +-# CHECK-INST: xvslt.hu $xr12, $xr29, $xr26 +-# CHECK-ENCODING: encoding: [0xac,0xeb,0x08,0x74] +- +-xvslt.wu $xr26, $xr25, $xr31 +-# CHECK-INST: xvslt.wu $xr26, $xr25, $xr31 +-# CHECK-ENCODING: encoding: [0x3a,0x7f,0x09,0x74] +- +-xvslt.du $xr30, $xr20, $xr3 +-# CHECK-INST: xvslt.du $xr30, $xr20, $xr3 +-# CHECK-ENCODING: encoding: [0x9e,0x8e,0x09,0x74] +- +-xvslti.bu $xr1, $xr4, 2 +-# CHECK-INST: xvslti.bu $xr1, $xr4, 2 +-# CHECK-ENCODING: encoding: [0x81,0x08,0x88,0x76] +- +-xvslti.hu $xr0, $xr5, 20 +-# CHECK-INST: xvslti.hu $xr0, $xr5, 20 +-# CHECK-ENCODING: encoding: [0xa0,0xd0,0x88,0x76] +- +-xvslti.wu $xr0, $xr25, 24 +-# CHECK-INST: xvslti.wu $xr0, $xr25, 24 +-# CHECK-ENCODING: encoding: [0x20,0x63,0x89,0x76] +- +-xvslti.du $xr10, $xr5, 29 +-# CHECK-INST: xvslti.du $xr10, $xr5, 29 +-# CHECK-ENCODING: encoding: [0xaa,0xf4,0x89,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/sra.s b/llvm/test/MC/LoongArch/lasx/sra.s +deleted file mode 100644 +index f9bc842f1..000000000 +--- a/llvm/test/MC/LoongArch/lasx/sra.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsra.b $xr11, $xr2, $xr0 +-# CHECK-INST: xvsra.b $xr11, $xr2, $xr0 +-# CHECK-ENCODING: encoding: [0x4b,0x00,0xec,0x74] +- +-xvsra.h $xr17, $xr27, $xr6 +-# CHECK-INST: xvsra.h $xr17, $xr27, $xr6 +-# CHECK-ENCODING: encoding: [0x71,0x9b,0xec,0x74] +- +-xvsra.w $xr13, $xr12, $xr12 +-# CHECK-INST: xvsra.w $xr13, $xr12, $xr12 +-# CHECK-ENCODING: encoding: [0x8d,0x31,0xed,0x74] +- +-xvsra.d $xr6, $xr15, $xr1 +-# CHECK-INST: xvsra.d $xr6, $xr15, $xr1 +-# CHECK-ENCODING: encoding: [0xe6,0x85,0xed,0x74] +- +-xvsrai.b $xr16, $xr2, 3 +-# CHECK-INST: xvsrai.b $xr16, $xr2, 3 +-# CHECK-ENCODING: encoding: [0x50,0x2c,0x34,0x77] +- +-xvsrai.h $xr14, $xr3, 12 +-# CHECK-INST: xvsrai.h $xr14, $xr3, 12 +-# CHECK-ENCODING: encoding: [0x6e,0x70,0x34,0x77] +- +-xvsrai.w $xr17, $xr18, 21 +-# CHECK-INST: xvsrai.w $xr17, $xr18, 21 +-# CHECK-ENCODING: encoding: [0x51,0xd6,0x34,0x77] +- +-xvsrai.d $xr10, $xr20, 4 +-# CHECK-INST: xvsrai.d $xr10, $xr20, 4 +-# CHECK-ENCODING: encoding: [0x8a,0x12,0x35,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/sran.s b/llvm/test/MC/LoongArch/lasx/sran.s +deleted file mode 100644 +index 3e0613c12..000000000 +--- a/llvm/test/MC/LoongArch/lasx/sran.s ++++ /dev/null +@@ -1,16 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsran.b.h $xr30, $xr13, $xr3 +-# CHECK-INST: xvsran.b.h $xr30, $xr13, $xr3 +-# CHECK-ENCODING: encoding: [0xbe,0x8d,0xf6,0x74] +- +-xvsran.h.w $xr18, $xr26, $xr4 +-# CHECK-INST: xvsran.h.w $xr18, $xr26, $xr4 +-# CHECK-ENCODING: encoding: [0x52,0x13,0xf7,0x74] +- +-xvsran.w.d $xr27, $xr19, $xr21 +-# CHECK-INST: xvsran.w.d $xr27, $xr19, $xr21 +-# CHECK-ENCODING: encoding: [0x7b,0xd6,0xf7,0x74] +diff --git a/llvm/test/MC/LoongArch/lasx/srani.s b/llvm/test/MC/LoongArch/lasx/srani.s +deleted file mode 100644 +index e8d971367..000000000 +--- a/llvm/test/MC/LoongArch/lasx/srani.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsrani.b.h $xr14, $xr23, 15 +-# CHECK-INST: xvsrani.b.h $xr14, $xr23, 15 +-# CHECK-ENCODING: encoding: [0xee,0x7e,0x58,0x77] +- +-xvsrani.h.w $xr2, $xr8, 5 +-# CHECK-INST: xvsrani.h.w $xr2, $xr8, 5 +-# CHECK-ENCODING: encoding: [0x02,0x95,0x58,0x77] +- +-xvsrani.w.d $xr5, $xr11, 14 +-# CHECK-INST: xvsrani.w.d $xr5, $xr11, 14 +-# CHECK-ENCODING: encoding: [0x65,0x39,0x59,0x77] +- +-xvsrani.d.q $xr17, $xr7, 113 +-# CHECK-INST: xvsrani.d.q $xr17, $xr7, 113 +-# CHECK-ENCODING: encoding: [0xf1,0xc4,0x5b,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/srar.s b/llvm/test/MC/LoongArch/lasx/srar.s +deleted file mode 100644 +index c247c78ec..000000000 +--- a/llvm/test/MC/LoongArch/lasx/srar.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsrar.b $xr9, $xr18, $xr11 +-# CHECK-INST: xvsrar.b $xr9, $xr18, $xr11 +-# CHECK-ENCODING: encoding: [0x49,0x2e,0xf2,0x74] +- +-xvsrar.h $xr15, $xr26, $xr1 +-# CHECK-INST: xvsrar.h $xr15, $xr26, $xr1 +-# CHECK-ENCODING: encoding: [0x4f,0x87,0xf2,0x74] +- +-xvsrar.w $xr17, $xr19, $xr14 +-# CHECK-INST: xvsrar.w $xr17, $xr19, $xr14 +-# CHECK-ENCODING: encoding: [0x71,0x3a,0xf3,0x74] +- +-xvsrar.d $xr19, $xr15, $xr6 +-# CHECK-INST: xvsrar.d $xr19, $xr15, $xr6 +-# CHECK-ENCODING: encoding: [0xf3,0x99,0xf3,0x74] +- +-xvsrari.b $xr10, $xr28, 3 +-# CHECK-INST: xvsrari.b $xr10, $xr28, 3 +-# CHECK-ENCODING: encoding: [0x8a,0x2f,0xa8,0x76] +- +-xvsrari.h $xr28, $xr1, 14 +-# CHECK-INST: xvsrari.h $xr28, $xr1, 14 +-# CHECK-ENCODING: encoding: [0x3c,0x78,0xa8,0x76] +- +-xvsrari.w $xr13, $xr7, 12 +-# CHECK-INST: xvsrari.w $xr13, $xr7, 12 +-# CHECK-ENCODING: encoding: [0xed,0xb0,0xa8,0x76] +- +-xvsrari.d $xr29, $xr9, 8 +-# CHECK-INST: xvsrari.d $xr29, $xr9, 8 +-# CHECK-ENCODING: encoding: [0x3d,0x21,0xa9,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/srarn.s b/llvm/test/MC/LoongArch/lasx/srarn.s +deleted file mode 100644 +index e963f2e58..000000000 +--- a/llvm/test/MC/LoongArch/lasx/srarn.s ++++ /dev/null +@@ -1,16 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsrarn.b.h $xr18, $xr20, $xr15 +-# CHECK-INST: xvsrarn.b.h $xr18, $xr20, $xr15 +-# CHECK-ENCODING: encoding: [0x92,0xbe,0xfa,0x74] +- +-xvsrarn.h.w $xr12, $xr1, $xr4 +-# CHECK-INST: xvsrarn.h.w $xr12, $xr1, $xr4 +-# CHECK-ENCODING: encoding: [0x2c,0x10,0xfb,0x74] +- +-xvsrarn.w.d $xr9, $xr18, $xr26 +-# CHECK-INST: xvsrarn.w.d $xr9, $xr18, $xr26 +-# CHECK-ENCODING: encoding: [0x49,0xea,0xfb,0x74] +diff --git a/llvm/test/MC/LoongArch/lasx/srarni.s b/llvm/test/MC/LoongArch/lasx/srarni.s +deleted file mode 100644 +index eda38ef99..000000000 +--- a/llvm/test/MC/LoongArch/lasx/srarni.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsrarni.b.h $xr21, $xr31, 15 +-# CHECK-INST: xvsrarni.b.h $xr21, $xr31, 15 +-# CHECK-ENCODING: encoding: [0xf5,0x7f,0x5c,0x77] +- +-xvsrarni.h.w $xr4, $xr22, 25 +-# CHECK-INST: xvsrarni.h.w $xr4, $xr22, 25 +-# CHECK-ENCODING: encoding: [0xc4,0xe6,0x5c,0x77] +- +-xvsrarni.w.d $xr24, $xr8, 41 +-# CHECK-INST: xvsrarni.w.d $xr24, $xr8, 41 +-# CHECK-ENCODING: encoding: [0x18,0xa5,0x5d,0x77] +- +-xvsrarni.d.q $xr7, $xr5, 7 +-# CHECK-INST: xvsrarni.d.q $xr7, $xr5, 7 +-# CHECK-ENCODING: encoding: [0xa7,0x1c,0x5e,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/srl.s b/llvm/test/MC/LoongArch/lasx/srl.s +deleted file mode 100644 +index 0d0607d0f..000000000 +--- a/llvm/test/MC/LoongArch/lasx/srl.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsrl.b $xr20, $xr24, $xr29 +-# CHECK-INST: xvsrl.b $xr20, $xr24, $xr29 +-# CHECK-ENCODING: encoding: [0x14,0x77,0xea,0x74] +- +-xvsrl.h $xr11, $xr17, $xr31 +-# CHECK-INST: xvsrl.h $xr11, $xr17, $xr31 +-# CHECK-ENCODING: encoding: [0x2b,0xfe,0xea,0x74] +- +-xvsrl.w $xr2, $xr10, $xr8 +-# CHECK-INST: xvsrl.w $xr2, $xr10, $xr8 +-# CHECK-ENCODING: encoding: [0x42,0x21,0xeb,0x74] +- +-xvsrl.d $xr13, $xr30, $xr26 +-# CHECK-INST: xvsrl.d $xr13, $xr30, $xr26 +-# CHECK-ENCODING: encoding: [0xcd,0xeb,0xeb,0x74] +- +-xvsrli.b $xr29, $xr4, 3 +-# CHECK-INST: xvsrli.b $xr29, $xr4, 3 +-# CHECK-ENCODING: encoding: [0x9d,0x2c,0x30,0x77] +- +-xvsrli.h $xr28, $xr14, 12 +-# CHECK-INST: xvsrli.h $xr28, $xr14, 12 +-# CHECK-ENCODING: encoding: [0xdc,0x71,0x30,0x77] +- +-xvsrli.w $xr12, $xr18, 7 +-# CHECK-INST: xvsrli.w $xr12, $xr18, 7 +-# CHECK-ENCODING: encoding: [0x4c,0x9e,0x30,0x77] +- +-xvsrli.d $xr0, $xr4, 46 +-# CHECK-INST: xvsrli.d $xr0, $xr4, 46 +-# CHECK-ENCODING: encoding: [0x80,0xb8,0x31,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/srln.s b/llvm/test/MC/LoongArch/lasx/srln.s +deleted file mode 100644 +index af6249919..000000000 +--- a/llvm/test/MC/LoongArch/lasx/srln.s ++++ /dev/null +@@ -1,16 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsrln.b.h $xr7, $xr13, $xr5 +-# CHECK-INST: xvsrln.b.h $xr7, $xr13, $xr5 +-# CHECK-ENCODING: encoding: [0xa7,0x95,0xf4,0x74] +- +-xvsrln.h.w $xr6, $xr18, $xr5 +-# CHECK-INST: xvsrln.h.w $xr6, $xr18, $xr5 +-# CHECK-ENCODING: encoding: [0x46,0x16,0xf5,0x74] +- +-xvsrln.w.d $xr12, $xr12, $xr28 +-# CHECK-INST: xvsrln.w.d $xr12, $xr12, $xr28 +-# CHECK-ENCODING: encoding: [0x8c,0xf1,0xf5,0x74] +diff --git a/llvm/test/MC/LoongArch/lasx/srlni.s b/llvm/test/MC/LoongArch/lasx/srlni.s +deleted file mode 100644 +index 917c9a752..000000000 +--- a/llvm/test/MC/LoongArch/lasx/srlni.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsrlni.b.h $xr5, $xr8, 2 +-# CHECK-INST: xvsrlni.b.h $xr5, $xr8, 2 +-# CHECK-ENCODING: encoding: [0x05,0x49,0x40,0x77] +- +-xvsrlni.h.w $xr7, $xr4, 20 +-# CHECK-INST: xvsrlni.h.w $xr7, $xr4, 20 +-# CHECK-ENCODING: encoding: [0x87,0xd0,0x40,0x77] +- +-xvsrlni.w.d $xr30, $xr15, 17 +-# CHECK-INST: xvsrlni.w.d $xr30, $xr15, 17 +-# CHECK-ENCODING: encoding: [0xfe,0x45,0x41,0x77] +- +-xvsrlni.d.q $xr15, $xr28, 95 +-# CHECK-INST: xvsrlni.d.q $xr15, $xr28, 95 +-# CHECK-ENCODING: encoding: [0x8f,0x7f,0x43,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/srlr.s b/llvm/test/MC/LoongArch/lasx/srlr.s +deleted file mode 100644 +index d87cc2291..000000000 +--- a/llvm/test/MC/LoongArch/lasx/srlr.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsrlr.b $xr18, $xr11, $xr5 +-# CHECK-INST: xvsrlr.b $xr18, $xr11, $xr5 +-# CHECK-ENCODING: encoding: [0x72,0x15,0xf0,0x74] +- +-xvsrlr.h $xr31, $xr5, $xr21 +-# CHECK-INST: xvsrlr.h $xr31, $xr5, $xr21 +-# CHECK-ENCODING: encoding: [0xbf,0xd4,0xf0,0x74] +- +-xvsrlr.w $xr7, $xr5, $xr1 +-# CHECK-INST: xvsrlr.w $xr7, $xr5, $xr1 +-# CHECK-ENCODING: encoding: [0xa7,0x04,0xf1,0x74] +- +-xvsrlr.d $xr4, $xr27, $xr7 +-# CHECK-INST: xvsrlr.d $xr4, $xr27, $xr7 +-# CHECK-ENCODING: encoding: [0x64,0x9f,0xf1,0x74] +- +-xvsrlri.b $xr29, $xr30, 4 +-# CHECK-INST: xvsrlri.b $xr29, $xr30, 4 +-# CHECK-ENCODING: encoding: [0xdd,0x33,0xa4,0x76] +- +-xvsrlri.h $xr16, $xr6, 14 +-# CHECK-INST: xvsrlri.h $xr16, $xr6, 14 +-# CHECK-ENCODING: encoding: [0xd0,0x78,0xa4,0x76] +- +-xvsrlri.w $xr24, $xr10, 28 +-# CHECK-INST: xvsrlri.w $xr24, $xr10, 28 +-# CHECK-ENCODING: encoding: [0x58,0xf1,0xa4,0x76] +- +-xvsrlri.d $xr20, $xr20, 52 +-# CHECK-INST: xvsrlri.d $xr20, $xr20, 52 +-# CHECK-ENCODING: encoding: [0x94,0xd2,0xa5,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/srlrn.s b/llvm/test/MC/LoongArch/lasx/srlrn.s +deleted file mode 100644 +index 3a70d97bf..000000000 +--- a/llvm/test/MC/LoongArch/lasx/srlrn.s ++++ /dev/null +@@ -1,16 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsrlrn.b.h $xr4, $xr25, $xr26 +-# CHECK-INST: xvsrlrn.b.h $xr4, $xr25, $xr26 +-# CHECK-ENCODING: encoding: [0x24,0xeb,0xf8,0x74] +- +-xvsrlrn.h.w $xr17, $xr5, $xr1 +-# CHECK-INST: xvsrlrn.h.w $xr17, $xr5, $xr1 +-# CHECK-ENCODING: encoding: [0xb1,0x04,0xf9,0x74] +- +-xvsrlrn.w.d $xr29, $xr1, $xr17 +-# CHECK-INST: xvsrlrn.w.d $xr29, $xr1, $xr17 +-# CHECK-ENCODING: encoding: [0x3d,0xc4,0xf9,0x74] +diff --git a/llvm/test/MC/LoongArch/lasx/srlrni.s b/llvm/test/MC/LoongArch/lasx/srlrni.s +deleted file mode 100644 +index ccee17fb7..000000000 +--- a/llvm/test/MC/LoongArch/lasx/srlrni.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsrlrni.b.h $xr10, $xr17, 12 +-# CHECK-INST: xvsrlrni.b.h $xr10, $xr17, 12 +-# CHECK-ENCODING: encoding: [0x2a,0x72,0x44,0x77] +- +-xvsrlrni.h.w $xr22, $xr23, 13 +-# CHECK-INST: xvsrlrni.h.w $xr22, $xr23, 13 +-# CHECK-ENCODING: encoding: [0xf6,0xb6,0x44,0x77] +- +-xvsrlrni.w.d $xr18, $xr22, 58 +-# CHECK-INST: xvsrlrni.w.d $xr18, $xr22, 58 +-# CHECK-ENCODING: encoding: [0xd2,0xea,0x45,0x77] +- +-xvsrlrni.d.q $xr25, $xr8, 42 +-# CHECK-INST: xvsrlrni.d.q $xr25, $xr8, 42 +-# CHECK-ENCODING: encoding: [0x19,0xa9,0x46,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/ssran.s b/llvm/test/MC/LoongArch/lasx/ssran.s +deleted file mode 100644 +index fe6333e52..000000000 +--- a/llvm/test/MC/LoongArch/lasx/ssran.s ++++ /dev/null +@@ -1,28 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvssran.b.h $xr17, $xr4, $xr1 +-# CHECK-INST: xvssran.b.h $xr17, $xr4, $xr1 +-# CHECK-ENCODING: encoding: [0x91,0x84,0xfe,0x74] +- +-xvssran.h.w $xr28, $xr28, $xr13 +-# CHECK-INST: xvssran.h.w $xr28, $xr28, $xr13 +-# CHECK-ENCODING: encoding: [0x9c,0x37,0xff,0x74] +- +-xvssran.w.d $xr21, $xr1, $xr31 +-# CHECK-INST: xvssran.w.d $xr21, $xr1, $xr31 +-# CHECK-ENCODING: encoding: [0x35,0xfc,0xff,0x74] +- +-xvssran.bu.h $xr3, $xr12, $xr24 +-# CHECK-INST: xvssran.bu.h $xr3, $xr12, $xr24 +-# CHECK-ENCODING: encoding: [0x83,0xe1,0x06,0x75] +- +-xvssran.hu.w $xr25, $xr24, $xr1 +-# CHECK-INST: xvssran.hu.w $xr25, $xr24, $xr1 +-# CHECK-ENCODING: encoding: [0x19,0x07,0x07,0x75] +- +-xvssran.wu.d $xr30, $xr14, $xr10 +-# CHECK-INST: xvssran.wu.d $xr30, $xr14, $xr10 +-# CHECK-ENCODING: encoding: [0xde,0xa9,0x07,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/ssrani.s b/llvm/test/MC/LoongArch/lasx/ssrani.s +deleted file mode 100644 +index 0074b3141..000000000 +--- a/llvm/test/MC/LoongArch/lasx/ssrani.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvssrani.b.h $xr26, $xr22, 14 +-# CHECK-INST: xvssrani.b.h $xr26, $xr22, 14 +-# CHECK-ENCODING: encoding: [0xda,0x7a,0x60,0x77] +- +-xvssrani.h.w $xr19, $xr14, 26 +-# CHECK-INST: xvssrani.h.w $xr19, $xr14, 26 +-# CHECK-ENCODING: encoding: [0xd3,0xe9,0x60,0x77] +- +-xvssrani.w.d $xr1, $xr27, 27 +-# CHECK-INST: xvssrani.w.d $xr1, $xr27, 27 +-# CHECK-ENCODING: encoding: [0x61,0x6f,0x61,0x77] +- +-xvssrani.d.q $xr9, $xr10, 59 +-# CHECK-INST: xvssrani.d.q $xr9, $xr10, 59 +-# CHECK-ENCODING: encoding: [0x49,0xed,0x62,0x77] +- +-xvssrani.bu.h $xr6, $xr3, 10 +-# CHECK-INST: xvssrani.bu.h $xr6, $xr3, 10 +-# CHECK-ENCODING: encoding: [0x66,0x68,0x64,0x77] +- +-xvssrani.hu.w $xr20, $xr9, 6 +-# CHECK-INST: xvssrani.hu.w $xr20, $xr9, 6 +-# CHECK-ENCODING: encoding: [0x34,0x99,0x64,0x77] +- +-xvssrani.wu.d $xr24, $xr11, 8 +-# CHECK-INST: xvssrani.wu.d $xr24, $xr11, 8 +-# CHECK-ENCODING: encoding: [0x78,0x21,0x65,0x77] +- +-xvssrani.du.q $xr16, $xr2, 15 +-# CHECK-INST: xvssrani.du.q $xr16, $xr2, 15 +-# CHECK-ENCODING: encoding: [0x50,0x3c,0x66,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/ssrarn.s b/llvm/test/MC/LoongArch/lasx/ssrarn.s +deleted file mode 100644 +index 6024c6764..000000000 +--- a/llvm/test/MC/LoongArch/lasx/ssrarn.s ++++ /dev/null +@@ -1,28 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvssrarn.b.h $xr7, $xr13, $xr0 +-# CHECK-INST: xvssrarn.b.h $xr7, $xr13, $xr0 +-# CHECK-ENCODING: encoding: [0xa7,0x81,0x02,0x75] +- +-xvssrarn.h.w $xr22, $xr2, $xr14 +-# CHECK-INST: xvssrarn.h.w $xr22, $xr2, $xr14 +-# CHECK-ENCODING: encoding: [0x56,0x38,0x03,0x75] +- +-xvssrarn.w.d $xr13, $xr7, $xr16 +-# CHECK-INST: xvssrarn.w.d $xr13, $xr7, $xr16 +-# CHECK-ENCODING: encoding: [0xed,0xc0,0x03,0x75] +- +-xvssrarn.bu.h $xr4, $xr12, $xr2 +-# CHECK-INST: xvssrarn.bu.h $xr4, $xr12, $xr2 +-# CHECK-ENCODING: encoding: [0x84,0x89,0x0a,0x75] +- +-xvssrarn.hu.w $xr15, $xr24, $xr3 +-# CHECK-INST: xvssrarn.hu.w $xr15, $xr24, $xr3 +-# CHECK-ENCODING: encoding: [0x0f,0x0f,0x0b,0x75] +- +-xvssrarn.wu.d $xr30, $xr9, $xr8 +-# CHECK-INST: xvssrarn.wu.d $xr30, $xr9, $xr8 +-# CHECK-ENCODING: encoding: [0x3e,0xa1,0x0b,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/ssrarni.s b/llvm/test/MC/LoongArch/lasx/ssrarni.s +deleted file mode 100644 +index ee6cf9806..000000000 +--- a/llvm/test/MC/LoongArch/lasx/ssrarni.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvssrarni.b.h $xr0, $xr4, 13 +-# CHECK-INST: xvssrarni.b.h $xr0, $xr4, 13 +-# CHECK-ENCODING: encoding: [0x80,0x74,0x68,0x77] +- +-xvssrarni.h.w $xr8, $xr0, 9 +-# CHECK-INST: xvssrarni.h.w $xr8, $xr0, 9 +-# CHECK-ENCODING: encoding: [0x08,0xa4,0x68,0x77] +- +-xvssrarni.w.d $xr5, $xr5, 42 +-# CHECK-INST: xvssrarni.w.d $xr5, $xr5, 42 +-# CHECK-ENCODING: encoding: [0xa5,0xa8,0x69,0x77] +- +-xvssrarni.d.q $xr8, $xr31, 83 +-# CHECK-INST: xvssrarni.d.q $xr8, $xr31, 83 +-# CHECK-ENCODING: encoding: [0xe8,0x4f,0x6b,0x77] +- +-xvssrarni.bu.h $xr21, $xr19, 0 +-# CHECK-INST: xvssrarni.bu.h $xr21, $xr19, 0 +-# CHECK-ENCODING: encoding: [0x75,0x42,0x6c,0x77] +- +-xvssrarni.hu.w $xr22, $xr13, 1 +-# CHECK-INST: xvssrarni.hu.w $xr22, $xr13, 1 +-# CHECK-ENCODING: encoding: [0xb6,0x85,0x6c,0x77] +- +-xvssrarni.wu.d $xr21, $xr5, 26 +-# CHECK-INST: xvssrarni.wu.d $xr21, $xr5, 26 +-# CHECK-ENCODING: encoding: [0xb5,0x68,0x6d,0x77] +- +-xvssrarni.du.q $xr15, $xr14, 94 +-# CHECK-INST: xvssrarni.du.q $xr15, $xr14, 94 +-# CHECK-ENCODING: encoding: [0xcf,0x79,0x6f,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/ssrln.s b/llvm/test/MC/LoongArch/lasx/ssrln.s +deleted file mode 100644 +index 7df617819..000000000 +--- a/llvm/test/MC/LoongArch/lasx/ssrln.s ++++ /dev/null +@@ -1,28 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvssrln.b.h $xr24, $xr4, $xr4 +-# CHECK-INST: xvssrln.b.h $xr24, $xr4, $xr4 +-# CHECK-ENCODING: encoding: [0x98,0x90,0xfc,0x74] +- +-xvssrln.h.w $xr5, $xr15, $xr0 +-# CHECK-INST: xvssrln.h.w $xr5, $xr15, $xr0 +-# CHECK-ENCODING: encoding: [0xe5,0x01,0xfd,0x74] +- +-xvssrln.w.d $xr0, $xr25, $xr30 +-# CHECK-INST: xvssrln.w.d $xr0, $xr25, $xr30 +-# CHECK-ENCODING: encoding: [0x20,0xfb,0xfd,0x74] +- +-xvssrln.bu.h $xr26, $xr9, $xr26 +-# CHECK-INST: xvssrln.bu.h $xr26, $xr9, $xr26 +-# CHECK-ENCODING: encoding: [0x3a,0xe9,0x04,0x75] +- +-xvssrln.hu.w $xr7, $xr20, $xr1 +-# CHECK-INST: xvssrln.hu.w $xr7, $xr20, $xr1 +-# CHECK-ENCODING: encoding: [0x87,0x06,0x05,0x75] +- +-xvssrln.wu.d $xr15, $xr13, $xr20 +-# CHECK-INST: xvssrln.wu.d $xr15, $xr13, $xr20 +-# CHECK-ENCODING: encoding: [0xaf,0xd1,0x05,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/ssrlni.s b/llvm/test/MC/LoongArch/lasx/ssrlni.s +deleted file mode 100644 +index b8c6ca171..000000000 +--- a/llvm/test/MC/LoongArch/lasx/ssrlni.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvssrlni.b.h $xr19, $xr18, 9 +-# CHECK-INST: xvssrlni.b.h $xr19, $xr18, 9 +-# CHECK-ENCODING: encoding: [0x53,0x66,0x48,0x77] +- +-xvssrlni.h.w $xr29, $xr29, 3 +-# CHECK-INST: xvssrlni.h.w $xr29, $xr29, 3 +-# CHECK-ENCODING: encoding: [0xbd,0x8f,0x48,0x77] +- +-xvssrlni.w.d $xr9, $xr15, 43 +-# CHECK-INST: xvssrlni.w.d $xr9, $xr15, 43 +-# CHECK-ENCODING: encoding: [0xe9,0xad,0x49,0x77] +- +-xvssrlni.d.q $xr8, $xr11, 121 +-# CHECK-INST: xvssrlni.d.q $xr8, $xr11, 121 +-# CHECK-ENCODING: encoding: [0x68,0xe5,0x4b,0x77] +- +-xvssrlni.bu.h $xr25, $xr10, 5 +-# CHECK-INST: xvssrlni.bu.h $xr25, $xr10, 5 +-# CHECK-ENCODING: encoding: [0x59,0x55,0x4c,0x77] +- +-xvssrlni.hu.w $xr9, $xr18, 26 +-# CHECK-INST: xvssrlni.hu.w $xr9, $xr18, 26 +-# CHECK-ENCODING: encoding: [0x49,0xea,0x4c,0x77] +- +-xvssrlni.wu.d $xr20, $xr22, 13 +-# CHECK-INST: xvssrlni.wu.d $xr20, $xr22, 13 +-# CHECK-ENCODING: encoding: [0xd4,0x36,0x4d,0x77] +- +-xvssrlni.du.q $xr8, $xr4, 43 +-# CHECK-INST: xvssrlni.du.q $xr8, $xr4, 43 +-# CHECK-ENCODING: encoding: [0x88,0xac,0x4e,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/ssrlrn.s b/llvm/test/MC/LoongArch/lasx/ssrlrn.s +deleted file mode 100644 +index 410a28deb..000000000 +--- a/llvm/test/MC/LoongArch/lasx/ssrlrn.s ++++ /dev/null +@@ -1,28 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvssrlrn.b.h $xr8, $xr20, $xr18 +-# CHECK-INST: xvssrlrn.b.h $xr8, $xr20, $xr18 +-# CHECK-ENCODING: encoding: [0x88,0xca,0x00,0x75] +- +-xvssrlrn.h.w $xr2, $xr13, $xr19 +-# CHECK-INST: xvssrlrn.h.w $xr2, $xr13, $xr19 +-# CHECK-ENCODING: encoding: [0xa2,0x4d,0x01,0x75] +- +-xvssrlrn.w.d $xr24, $xr7, $xr5 +-# CHECK-INST: xvssrlrn.w.d $xr24, $xr7, $xr5 +-# CHECK-ENCODING: encoding: [0xf8,0x94,0x01,0x75] +- +-xvssrlrn.bu.h $xr15, $xr23, $xr18 +-# CHECK-INST: xvssrlrn.bu.h $xr15, $xr23, $xr18 +-# CHECK-ENCODING: encoding: [0xef,0xca,0x08,0x75] +- +-xvssrlrn.hu.w $xr22, $xr14, $xr16 +-# CHECK-INST: xvssrlrn.hu.w $xr22, $xr14, $xr16 +-# CHECK-ENCODING: encoding: [0xd6,0x41,0x09,0x75] +- +-xvssrlrn.wu.d $xr20, $xr28, $xr5 +-# CHECK-INST: xvssrlrn.wu.d $xr20, $xr28, $xr5 +-# CHECK-ENCODING: encoding: [0x94,0x97,0x09,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/ssrlrni.s b/llvm/test/MC/LoongArch/lasx/ssrlrni.s +deleted file mode 100644 +index c19626e54..000000000 +--- a/llvm/test/MC/LoongArch/lasx/ssrlrni.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvssrlrni.b.h $xr26, $xr26, 8 +-# CHECK-INST: xvssrlrni.b.h $xr26, $xr26, 8 +-# CHECK-ENCODING: encoding: [0x5a,0x63,0x50,0x77] +- +-xvssrlrni.h.w $xr6, $xr0, 19 +-# CHECK-INST: xvssrlrni.h.w $xr6, $xr0, 19 +-# CHECK-ENCODING: encoding: [0x06,0xcc,0x50,0x77] +- +-xvssrlrni.w.d $xr28, $xr15, 55 +-# CHECK-INST: xvssrlrni.w.d $xr28, $xr15, 55 +-# CHECK-ENCODING: encoding: [0xfc,0xdd,0x51,0x77] +- +-xvssrlrni.d.q $xr8, $xr16, 64 +-# CHECK-INST: xvssrlrni.d.q $xr8, $xr16, 64 +-# CHECK-ENCODING: encoding: [0x08,0x02,0x53,0x77] +- +-xvssrlrni.bu.h $xr23, $xr28, 3 +-# CHECK-INST: xvssrlrni.bu.h $xr23, $xr28, 3 +-# CHECK-ENCODING: encoding: [0x97,0x4f,0x54,0x77] +- +-xvssrlrni.hu.w $xr25, $xr10, 18 +-# CHECK-INST: xvssrlrni.hu.w $xr25, $xr10, 18 +-# CHECK-ENCODING: encoding: [0x59,0xc9,0x54,0x77] +- +-xvssrlrni.wu.d $xr16, $xr28, 15 +-# CHECK-INST: xvssrlrni.wu.d $xr16, $xr28, 15 +-# CHECK-ENCODING: encoding: [0x90,0x3f,0x55,0x77] +- +-xvssrlrni.du.q $xr18, $xr9, 44 +-# CHECK-INST: xvssrlrni.du.q $xr18, $xr9, 44 +-# CHECK-ENCODING: encoding: [0x32,0xb1,0x56,0x77] +diff --git a/llvm/test/MC/LoongArch/lasx/ssub.s b/llvm/test/MC/LoongArch/lasx/ssub.s +deleted file mode 100644 +index e5be5652b..000000000 +--- a/llvm/test/MC/LoongArch/lasx/ssub.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvssub.b $xr14, $xr19, $xr24 +-# CHECK-INST: xvssub.b $xr14, $xr19, $xr24 +-# CHECK-ENCODING: encoding: [0x6e,0x62,0x48,0x74] +- +-xvssub.h $xr13, $xr8, $xr19 +-# CHECK-INST: xvssub.h $xr13, $xr8, $xr19 +-# CHECK-ENCODING: encoding: [0x0d,0xcd,0x48,0x74] +- +-xvssub.w $xr28, $xr27, $xr28 +-# CHECK-INST: xvssub.w $xr28, $xr27, $xr28 +-# CHECK-ENCODING: encoding: [0x7c,0x73,0x49,0x74] +- +-xvssub.d $xr28, $xr16, $xr2 +-# CHECK-INST: xvssub.d $xr28, $xr16, $xr2 +-# CHECK-ENCODING: encoding: [0x1c,0x8a,0x49,0x74] +- +-xvssub.bu $xr11, $xr13, $xr17 +-# CHECK-INST: xvssub.bu $xr11, $xr13, $xr17 +-# CHECK-ENCODING: encoding: [0xab,0x45,0x4c,0x74] +- +-xvssub.hu $xr16, $xr10, $xr28 +-# CHECK-INST: xvssub.hu $xr16, $xr10, $xr28 +-# CHECK-ENCODING: encoding: [0x50,0xf1,0x4c,0x74] +- +-xvssub.wu $xr21, $xr0, $xr13 +-# CHECK-INST: xvssub.wu $xr21, $xr0, $xr13 +-# CHECK-ENCODING: encoding: [0x15,0x34,0x4d,0x74] +- +-xvssub.du $xr18, $xr26, $xr27 +-# CHECK-INST: xvssub.du $xr18, $xr26, $xr27 +-# CHECK-ENCODING: encoding: [0x52,0xef,0x4d,0x74] +diff --git a/llvm/test/MC/LoongArch/lasx/st.s b/llvm/test/MC/LoongArch/lasx/st.s +deleted file mode 100644 +index d1437e3ec..000000000 +--- a/llvm/test/MC/LoongArch/lasx/st.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvst $xr14, $r12, 943 +-# CHECK-INST: xvst $xr14, $t0, 943 +-# CHECK-ENCODING: encoding: [0x8e,0xbd,0xce,0x2c] +- +-xvstx $xr7, $r9, $r21 +-# CHECK-INST: xvstx $xr7, $a5, $r21 +-# CHECK-ENCODING: encoding: [0x27,0x55,0x4c,0x38] +diff --git a/llvm/test/MC/LoongArch/lasx/stelm.s b/llvm/test/MC/LoongArch/lasx/stelm.s +deleted file mode 100644 +index e19030a00..000000000 +--- a/llvm/test/MC/LoongArch/lasx/stelm.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvstelm.b $xr20, $r2, -105, 10 +-# CHECK-INST: xvstelm.b $xr20, $tp, -105, 10 +-# CHECK-ENCODING: encoding: [0x54,0x5c,0xaa,0x33] +- +-xvstelm.h $xr8, $r1, 160, 4 +-# CHECK-INST: xvstelm.h $xr8, $ra, 160, 4 +-# CHECK-ENCODING: encoding: [0x28,0x40,0x51,0x33] +- +-xvstelm.w $xr19, $r18, 412, 0 +-# CHECK-INST: xvstelm.w $xr19, $t6, 412, 0 +-# CHECK-ENCODING: encoding: [0x53,0x9e,0x21,0x33] +- +-xvstelm.d $xr22, $r30, 960, 3 +-# CHECK-INST: xvstelm.d $xr22, $s7, 960, 3 +-# CHECK-ENCODING: encoding: [0xd6,0xe3,0x1d,0x33] +diff --git a/llvm/test/MC/LoongArch/lasx/sub.s b/llvm/test/MC/LoongArch/lasx/sub.s +deleted file mode 100644 +index e100730d1..000000000 +--- a/llvm/test/MC/LoongArch/lasx/sub.s ++++ /dev/null +@@ -1,24 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsub.b $xr11, $xr28, $xr16 +-# CHECK-INST: xvsub.b $xr11, $xr28, $xr16 +-# CHECK-ENCODING: encoding: [0x8b,0x43,0x0c,0x74] +- +-xvsub.h $xr11, $xr3, $xr24 +-# CHECK-INST: xvsub.h $xr11, $xr3, $xr24 +-# CHECK-ENCODING: encoding: [0x6b,0xe0,0x0c,0x74] +- +-xvsub.w $xr14, $xr23, $xr6 +-# CHECK-INST: xvsub.w $xr14, $xr23, $xr6 +-# CHECK-ENCODING: encoding: [0xee,0x1a,0x0d,0x74] +- +-xvsub.d $xr5, $xr13, $xr7 +-# CHECK-INST: xvsub.d $xr5, $xr13, $xr7 +-# CHECK-ENCODING: encoding: [0xa5,0x9d,0x0d,0x74] +- +-xvsub.q $xr13, $xr26, $xr31 +-# CHECK-INST: xvsub.q $xr13, $xr26, $xr31 +-# CHECK-ENCODING: encoding: [0x4d,0xff,0x2d,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/subi.s b/llvm/test/MC/LoongArch/lasx/subi.s +deleted file mode 100644 +index 921fcf992..000000000 +--- a/llvm/test/MC/LoongArch/lasx/subi.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsubi.bu $xr18, $xr27, 1 +-# CHECK-INST: xvsubi.bu $xr18, $xr27, 1 +-# CHECK-ENCODING: encoding: [0x72,0x07,0x8c,0x76] +- +-xvsubi.hu $xr6, $xr23, 19 +-# CHECK-INST: xvsubi.hu $xr6, $xr23, 19 +-# CHECK-ENCODING: encoding: [0xe6,0xce,0x8c,0x76] +- +-xvsubi.wu $xr13, $xr3, 5 +-# CHECK-INST: xvsubi.wu $xr13, $xr3, 5 +-# CHECK-ENCODING: encoding: [0x6d,0x14,0x8d,0x76] +- +-xvsubi.du $xr26, $xr28, 14 +-# CHECK-INST: xvsubi.du $xr26, $xr28, 14 +-# CHECK-ENCODING: encoding: [0x9a,0xbb,0x8d,0x76] +diff --git a/llvm/test/MC/LoongArch/lasx/subw.s b/llvm/test/MC/LoongArch/lasx/subw.s +deleted file mode 100644 +index 666edfdae..000000000 +--- a/llvm/test/MC/LoongArch/lasx/subw.s ++++ /dev/null +@@ -1,68 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvsubwev.h.b $xr29, $xr1, $xr28 +-# CHECK-INST: xvsubwev.h.b $xr29, $xr1, $xr28 +-# CHECK-ENCODING: encoding: [0x3d,0x70,0x20,0x74] +- +-xvsubwev.w.h $xr24, $xr20, $xr31 +-# CHECK-INST: xvsubwev.w.h $xr24, $xr20, $xr31 +-# CHECK-ENCODING: encoding: [0x98,0xfe,0x20,0x74] +- +-xvsubwev.d.w $xr6, $xr4, $xr11 +-# CHECK-INST: xvsubwev.d.w $xr6, $xr4, $xr11 +-# CHECK-ENCODING: encoding: [0x86,0x2c,0x21,0x74] +- +-xvsubwev.q.d $xr27, $xr31, $xr13 +-# CHECK-INST: xvsubwev.q.d $xr27, $xr31, $xr13 +-# CHECK-ENCODING: encoding: [0xfb,0xb7,0x21,0x74] +- +-xvsubwev.h.bu $xr1, $xr20, $xr2 +-# CHECK-INST: xvsubwev.h.bu $xr1, $xr20, $xr2 +-# CHECK-ENCODING: encoding: [0x81,0x0a,0x30,0x74] +- +-xvsubwev.w.hu $xr19, $xr6, $xr12 +-# CHECK-INST: xvsubwev.w.hu $xr19, $xr6, $xr12 +-# CHECK-ENCODING: encoding: [0xd3,0xb0,0x30,0x74] +- +-xvsubwev.d.wu $xr31, $xr1, $xr23 +-# CHECK-INST: xvsubwev.d.wu $xr31, $xr1, $xr23 +-# CHECK-ENCODING: encoding: [0x3f,0x5c,0x31,0x74] +- +-xvsubwev.q.du $xr31, $xr28, $xr17 +-# CHECK-INST: xvsubwev.q.du $xr31, $xr28, $xr17 +-# CHECK-ENCODING: encoding: [0x9f,0xc7,0x31,0x74] +- +-xvsubwod.h.b $xr3, $xr9, $xr17 +-# CHECK-INST: xvsubwod.h.b $xr3, $xr9, $xr17 +-# CHECK-ENCODING: encoding: [0x23,0x45,0x24,0x74] +- +-xvsubwod.w.h $xr14, $xr5, $xr21 +-# CHECK-INST: xvsubwod.w.h $xr14, $xr5, $xr21 +-# CHECK-ENCODING: encoding: [0xae,0xd4,0x24,0x74] +- +-xvsubwod.d.w $xr8, $xr14, $xr3 +-# CHECK-INST: xvsubwod.d.w $xr8, $xr14, $xr3 +-# CHECK-ENCODING: encoding: [0xc8,0x0d,0x25,0x74] +- +-xvsubwod.q.d $xr24, $xr15, $xr18 +-# CHECK-INST: xvsubwod.q.d $xr24, $xr15, $xr18 +-# CHECK-ENCODING: encoding: [0xf8,0xc9,0x25,0x74] +- +-xvsubwod.h.bu $xr27, $xr2, $xr1 +-# CHECK-INST: xvsubwod.h.bu $xr27, $xr2, $xr1 +-# CHECK-ENCODING: encoding: [0x5b,0x04,0x34,0x74] +- +-xvsubwod.w.hu $xr19, $xr7, $xr22 +-# CHECK-INST: xvsubwod.w.hu $xr19, $xr7, $xr22 +-# CHECK-ENCODING: encoding: [0xf3,0xd8,0x34,0x74] +- +-xvsubwod.d.wu $xr1, $xr24, $xr26 +-# CHECK-INST: xvsubwod.d.wu $xr1, $xr24, $xr26 +-# CHECK-ENCODING: encoding: [0x01,0x6b,0x35,0x74] +- +-xvsubwod.q.du $xr29, $xr26, $xr7 +-# CHECK-INST: xvsubwod.q.du $xr29, $xr26, $xr7 +-# CHECK-ENCODING: encoding: [0x5d,0x9f,0x35,0x74] +diff --git a/llvm/test/MC/LoongArch/lasx/xor.s b/llvm/test/MC/LoongArch/lasx/xor.s +deleted file mode 100644 +index 511ad49b1..000000000 +--- a/llvm/test/MC/LoongArch/lasx/xor.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvxor.v $xr14, $xr26, $xr10 +-# CHECK-INST: xvxor.v $xr14, $xr26, $xr10 +-# CHECK-ENCODING: encoding: [0x4e,0x2b,0x27,0x75] +diff --git a/llvm/test/MC/LoongArch/lasx/xori.s b/llvm/test/MC/LoongArch/lasx/xori.s +deleted file mode 100644 +index e11dc0c81..000000000 +--- a/llvm/test/MC/LoongArch/lasx/xori.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-xvxori.b $xr26, $xr8, 149 +-# CHECK-INST: xvxori.b $xr26, $xr8, 149 +-# CHECK-ENCODING: encoding: [0x1a,0x55,0xda,0x77] +diff --git a/llvm/test/MC/LoongArch/lbt/arm-alu.s b/llvm/test/MC/LoongArch/lbt/arm-alu.s +deleted file mode 100644 +index 104a485e1..000000000 +--- a/llvm/test/MC/LoongArch/lbt/arm-alu.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-armadd.w $a0, $a1, 1 +-# CHECK-INST: armadd.w $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0x91,0x14,0x37,0x00] +- +-armsub.w $a0, $a1, 1 +-# CHECK-INST: armsub.w $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0x91,0x94,0x37,0x00] +- +-armadc.w $a0, $a1, 1 +-# CHECK-INST: armadc.w $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0x91,0x14,0x38,0x00] +- +-armsbc.w $a0, $a1, 1 +-# CHECK-INST: armsbc.w $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0x91,0x94,0x38,0x00] +- +-armand.w $a0, $a1, 1 +-# CHECK-INST: armand.w $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0x91,0x14,0x39,0x00] +- +-armor.w $a0, $a1, 1 +-# CHECK-INST: armor.w $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0x91,0x94,0x39,0x00] +- +-armxor.w $a0, $a1, 1 +-# CHECK-INST: armxor.w $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0x91,0x14,0x3a,0x00] +- +-armnot.w $a0, 1 +-# CHECK-INST: armnot.w $a0, 1 +-# CHECK-ENCODING: encoding: [0x9c,0xc4,0x3f,0x00] +diff --git a/llvm/test/MC/LoongArch/lbt/arm-jump.s b/llvm/test/MC/LoongArch/lbt/arm-jump.s +deleted file mode 100644 +index 2414068eb..000000000 +--- a/llvm/test/MC/LoongArch/lbt/arm-jump.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-setarmj $a0, 1 +-# CHECK-INST: setarmj $a0, 1 +-# CHECK-ENCODING: encoding: [0x04,0xc4,0x36,0x00] +diff --git a/llvm/test/MC/LoongArch/lbt/arm-mov.s b/llvm/test/MC/LoongArch/lbt/arm-mov.s +deleted file mode 100644 +index 995ff054f..000000000 +--- a/llvm/test/MC/LoongArch/lbt/arm-mov.s ++++ /dev/null +@@ -1,24 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-armmove $a0, $a1, 1 +-# CHECK-INST: armmove $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0xa4,0x44,0x36,0x00] +- +-armmov.w $a0, 1 +-# CHECK-INST: armmov.w $a0, 1 +-# CHECK-ENCODING: encoding: [0x9d,0xc4,0x3f,0x00] +- +-armmov.d $a0, 1 +-# CHECK-INST: armmov.d $a0, 1 +-# CHECK-ENCODING: encoding: [0x9e,0xc4,0x3f,0x00] +- +-armmfflag $a0, 1 +-# CHECK-INST: armmfflag $a0, 1 +-# CHECK-ENCODING: encoding: [0x44,0x04,0x5c,0x00] +- +-armmtflag $a0, 1 +-# CHECK-INST: armmtflag $a0, 1 +-# CHECK-ENCODING: encoding: [0x64,0x04,0x5c,0x00] +diff --git a/llvm/test/MC/LoongArch/lbt/arm-shift.s b/llvm/test/MC/LoongArch/lbt/arm-shift.s +deleted file mode 100644 +index b6b8bbf00..000000000 +--- a/llvm/test/MC/LoongArch/lbt/arm-shift.s ++++ /dev/null +@@ -1,40 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-armsll.w $a0, $a1, 1 +-# CHECK-INST: armsll.w $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0x91,0x94,0x3a,0x00] +- +-armsrl.w $a0, $a1, 1 +-# CHECK-INST: armsrl.w $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0x91,0x14,0x3b,0x00] +- +-armsra.w $a0, $a1, 1 +-# CHECK-INST: armsra.w $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0x91,0x94,0x3b,0x00] +- +-armrotr.w $a0, $a1, 1 +-# CHECK-INST: armrotr.w $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0x91,0x14,0x3c,0x00] +- +-armslli.w $a0, 1, 1 +-# CHECK-INST: armslli.w $a0, 1, 1 +-# CHECK-ENCODING: encoding: [0x91,0x84,0x3c,0x00] +- +-armsrli.w $a0, 1, 1 +-# CHECK-INST: armsrli.w $a0, 1, 1 +-# CHECK-ENCODING: encoding: [0x91,0x04,0x3d,0x00] +- +-armsrai.w $a0, 1, 1 +-# CHECK-INST: armsrai.w $a0, 1, 1 +-# CHECK-ENCODING: encoding: [0x91,0x84,0x3d,0x00] +- +-armrotri.w $a0, 1, 1 +-# CHECK-INST: armrotri.w $a0, 1, 1 +-# CHECK-ENCODING: encoding: [0x91,0x04,0x3e,0x00] +- +-armrrx.w $a0, 1 +-# CHECK-INST: armrrx.w $a0, 1 +-# CHECK-ENCODING: encoding: [0x9f,0xc4,0x3f,0x00] +diff --git a/llvm/test/MC/LoongArch/lbt/base.s b/llvm/test/MC/LoongArch/lbt/base.s +deleted file mode 100644 +index c02794326..000000000 +--- a/llvm/test/MC/LoongArch/lbt/base.s ++++ /dev/null +@@ -1,136 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-addu12i.w $a0, $a1, 1 +-# CHECK-INST: addu12i.w $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0xa4,0x04,0x29,0x00] +- +-addu12i.d $a0, $a1, 1 +-# CHECK-INST: addu12i.d $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0xa4,0x84,0x29,0x00] +- +-adc.b $a0, $a1, $a2 +-# CHECK-INST: adc.b $a0, $a1, $a2 +-# CHECK-ENCODING: encoding: [0xa4,0x18,0x30,0x00] +- +-adc.h $a0, $a1, $a2 +-# CHECK-INST: adc.h $a0, $a1, $a2 +-# CHECK-ENCODING: encoding: [0xa4,0x98,0x30,0x00] +- +-adc.w $a0, $a1, $a2 +-# CHECK-INST: adc.w $a0, $a1, $a2 +-# CHECK-ENCODING: encoding: [0xa4,0x18,0x31,0x00] +- +-adc.d $a0, $a1, $a2 +-# CHECK-INST: adc.d $a0, $a1, $a2 +-# CHECK-ENCODING: encoding: [0xa4,0x98,0x31,0x00] +- +-sbc.b $a0, $a1, $a2 +-# CHECK-INST: sbc.b $a0, $a1, $a2 +-# CHECK-ENCODING: encoding: [0xa4,0x18,0x32,0x00] +- +-sbc.h $a0, $a1, $a2 +-# CHECK-INST: sbc.h $a0, $a1, $a2 +-# CHECK-ENCODING: encoding: [0xa4,0x98,0x32,0x00] +- +-sbc.w $a0, $a1, $a2 +-# CHECK-INST: sbc.w $a0, $a1, $a2 +-# CHECK-ENCODING: encoding: [0xa4,0x18,0x33,0x00] +- +-sbc.d $a0, $a1, $a2 +-# CHECK-INST: sbc.d $a0, $a1, $a2 +-# CHECK-ENCODING: encoding: [0xa4,0x98,0x33,0x00] +- +-rotr.b $a0, $a1, $a2 +-# CHECK-INST: rotr.b $a0, $a1, $a2 +-# CHECK-ENCODING: encoding: [0xa4,0x18,0x1a,0x00] +- +-rotr.h $a0, $a1, $a2 +-# CHECK-INST: rotr.h $a0, $a1, $a2 +-# CHECK-ENCODING: encoding: [0xa4,0x98,0x1a,0x00] +- +-rotri.b $a0, $a1, 1 +-# CHECK-INST: rotri.b $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0xa4,0x24,0x4c,0x00] +- +-rotri.h $a0, $a1, 1 +-# CHECK-INST: rotri.h $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0xa4,0x44,0x4c,0x00] +- +-rcr.b $a0, $a1, $a2 +-# CHECK-INST: rcr.b $a0, $a1, $a2 +-# CHECK-ENCODING: encoding: [0xa4,0x18,0x34,0x00] +- +-rcr.h $a0, $a1, $a2 +-# CHECK-INST: rcr.h $a0, $a1, $a2 +-# CHECK-ENCODING: encoding: [0xa4,0x98,0x34,0x00] +- +-rcr.w $a0, $a1, $a2 +-# CHECK-INST: rcr.w $a0, $a1, $a2 +-# CHECK-ENCODING: encoding: [0xa4,0x18,0x35,0x00] +- +-rcr.d $a0, $a1, $a2 +-# CHECK-INST: rcr.d $a0, $a1, $a2 +-# CHECK-ENCODING: encoding: [0xa4,0x98,0x35,0x00] +- +-rcri.b $a0, $a1, 1 +-# CHECK-INST: rcri.b $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0xa4,0x24,0x50,0x00] +- +-rcri.h $a0, $a1, 1 +-# CHECK-INST: rcri.h $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0xa4,0x44,0x50,0x00] +- +-rcri.w $a0, $a1, 1 +-# CHECK-INST: rcri.w $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0xa4,0x84,0x50,0x00] +- +-rcri.d $a0, $a1, 1 +-# CHECK-INST: rcri.d $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0xa4,0x04,0x51,0x00] +- +-fcvt.ud.d $f0, $f1 +-# CHECK-INST: fcvt.ud.d $fa0, $fa1 +-# CHECK-ENCODING: encoding: [0x20,0xe4,0x14,0x01] +- +-fcvt.ld.d $f0, $f1 +-# CHECK-INST: fcvt.ld.d $fa0, $fa1 +-# CHECK-ENCODING: encoding: [0x20,0xe0,0x14,0x01] +- +-fcvt.d.ld $f0, $f1, $f2 +-# CHECK-INST: fcvt.d.ld $fa0, $fa1, $fa2 +-# CHECK-ENCODING: encoding: [0x20,0x08,0x15,0x01] +- +-ldl.d $a0, $a1, 1 +-# CHECK-INST: ldl.d $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0xa4,0x04,0x80,0x2e] +- +-ldl.w $a0, $a1, 1 +-# CHECK-INST: ldl.w $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0xa4,0x04,0x00,0x2e] +- +-ldr.w $a0, $a1, 1 +-# CHECK-INST: ldr.w $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0xa4,0x04,0x40,0x2e] +- +-ldr.d $a0, $a1, 1 +-# CHECK-INST: ldr.d $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0xa4,0x04,0xc0,0x2e] +- +-stl.w $a0, $a1, 1 +-# CHECK-INST: stl.w $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0xa4,0x04,0x00,0x2f] +- +-stl.d $a0, $a1, 1 +-# CHECK-INST: stl.d $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0xa4,0x04,0x80,0x2f] +- +-str.w $a0, $a1, 1 +-# CHECK-INST: str.w $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0xa4,0x04,0x40,0x2f] +- +-str.d $a0, $a1, 1 +-# CHECK-INST: str.d $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0xa4,0x04,0xc0,0x2f] +diff --git a/llvm/test/MC/LoongArch/lbt/scr.s b/llvm/test/MC/LoongArch/lbt/scr.s +deleted file mode 100644 +index eb706dd8d..000000000 +--- a/llvm/test/MC/LoongArch/lbt/scr.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-movgr2scr $scr0, $a1 +-# CHECK-INST: movgr2scr $scr0, $a1 +-# CHECK-ENCODING: encoding: [0xa0,0x08,0x00,0x00] +- +-movscr2gr $a0, $scr1 +-# CHECK-INST: movscr2gr $a0, $scr1 +-# CHECK-ENCODING: encoding: [0x24,0x0c,0x00,0x00] +- +-jiscr0 100 +-# CHECK-INST: jiscr0 100 +-# CHECK-ENCODING: encoding: [0x00,0x66,0x00,0x48] +- +-jiscr1 100 +-# CHECK-INST: jiscr1 100 +-# CHECK-ENCODING: encoding: [0x00,0x67,0x00,0x48] +diff --git a/llvm/test/MC/LoongArch/lbt/x86-alu.s b/llvm/test/MC/LoongArch/lbt/x86-alu.s +deleted file mode 100644 +index 95309f531..000000000 +--- a/llvm/test/MC/LoongArch/lbt/x86-alu.s ++++ /dev/null +@@ -1,196 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-x86adc.b $a0, $a1 +-# CHECK-INST: x86adc.b $a0, $a1 +-# CHECK-ENCODING: encoding: [0x8c,0x14,0x3f,0x00] +- +-x86adc.h $a0, $a1 +-# CHECK-INST: x86adc.h $a0, $a1 +-# CHECK-ENCODING: encoding: [0x8d,0x14,0x3f,0x00] +- +-x86adc.w $a0, $a1 +-# CHECK-INST: x86adc.w $a0, $a1 +-# CHECK-ENCODING: encoding: [0x8e,0x14,0x3f,0x00] +- +-x86adc.d $a0, $a1 +-# CHECK-INST: x86adc.d $a0, $a1 +-# CHECK-ENCODING: encoding: [0x8f,0x14,0x3f,0x00] +- +-x86add.b $a0, $a1 +-# CHECK-INST: x86add.b $a0, $a1 +-# CHECK-ENCODING: encoding: [0x84,0x14,0x3f,0x00] +- +-x86add.h $a0, $a1 +-# CHECK-INST: x86add.h $a0, $a1 +-# CHECK-ENCODING: encoding: [0x85,0x14,0x3f,0x00] +- +-x86add.w $a0, $a1 +-# CHECK-INST: x86add.w $a0, $a1 +-# CHECK-ENCODING: encoding: [0x86,0x14,0x3f,0x00] +- +-x86add.d $a0, $a1 +-# CHECK-INST: x86add.d $a0, $a1 +-# CHECK-ENCODING: encoding: [0x87,0x14,0x3f,0x00] +- +-x86add.wu $a0, $a1 +-# CHECK-INST: x86add.wu $a0, $a1 +-# CHECK-ENCODING: encoding: [0x80,0x14,0x3f,0x00] +- +-x86add.du $a0, $a1 +-# CHECK-INST: x86add.du $a0, $a1 +-# CHECK-ENCODING: encoding: [0x81,0x14,0x3f,0x00] +- +-x86inc.b $a0 +-# CHECK-INST: x86inc.b $a0 +-# CHECK-ENCODING: encoding: [0x80,0x80,0x00,0x00] +- +-x86inc.h $a0 +-# CHECK-INST: x86inc.h $a0 +-# CHECK-ENCODING: encoding: [0x81,0x80,0x00,0x00] +- +-x86inc.w $a0 +-# CHECK-INST: x86inc.w $a0 +-# CHECK-ENCODING: encoding: [0x82,0x80,0x00,0x00] +- +-x86inc.d $a0 +-# CHECK-INST: x86inc.d $a0 +-# CHECK-ENCODING: encoding: [0x83,0x80,0x00,0x00] +- +-x86sbc.b $a0, $a1 +-# CHECK-INST: x86sbc.b $a0, $a1 +-# CHECK-ENCODING: encoding: [0x90,0x14,0x3f,0x00] +- +-x86sbc.h $a0, $a1 +-# CHECK-INST: x86sbc.h $a0, $a1 +-# CHECK-ENCODING: encoding: [0x91,0x14,0x3f,0x00] +- +-x86sbc.w $a0, $a1 +-# CHECK-INST: x86sbc.w $a0, $a1 +-# CHECK-ENCODING: encoding: [0x92,0x14,0x3f,0x00] +- +-x86sbc.d $a0, $a1 +-# CHECK-INST: x86sbc.d $a0, $a1 +-# CHECK-ENCODING: encoding: [0x93,0x14,0x3f,0x00] +- +-x86sub.b $a0, $a1 +-# CHECK-INST: x86sub.b $a0, $a1 +-# CHECK-ENCODING: encoding: [0x88,0x14,0x3f,0x00] +- +-x86sub.h $a0, $a1 +-# CHECK-INST: x86sub.h $a0, $a1 +-# CHECK-ENCODING: encoding: [0x89,0x14,0x3f,0x00] +- +-x86sub.w $a0, $a1 +-# CHECK-INST: x86sub.w $a0, $a1 +-# CHECK-ENCODING: encoding: [0x8a,0x14,0x3f,0x00] +- +-x86sub.d $a0, $a1 +-# CHECK-INST: x86sub.d $a0, $a1 +-# CHECK-ENCODING: encoding: [0x8b,0x14,0x3f,0x00] +- +-x86sub.wu $a0, $a1 +-# CHECK-INST: x86sub.wu $a0, $a1 +-# CHECK-ENCODING: encoding: [0x82,0x14,0x3f,0x00] +- +-x86sub.du $a0, $a1 +-# CHECK-INST: x86sub.du $a0, $a1 +-# CHECK-ENCODING: encoding: [0x83,0x14,0x3f,0x00] +- +-x86dec.b $a0 +-# CHECK-INST: x86dec.b $a0 +-# CHECK-ENCODING: encoding: [0x84,0x80,0x00,0x00] +- +-x86dec.h $a0 +-# CHECK-INST: x86dec.h $a0 +-# CHECK-ENCODING: encoding: [0x85,0x80,0x00,0x00] +- +-x86dec.w $a0 +-# CHECK-INST: x86dec.w $a0 +-# CHECK-ENCODING: encoding: [0x86,0x80,0x00,0x00] +- +-x86dec.d $a0 +-# CHECK-INST: x86dec.d $a0 +-# CHECK-ENCODING: encoding: [0x87,0x80,0x00,0x00] +- +-x86and.b $a0, $a1 +-# CHECK-INST: x86and.b $a0, $a1 +-# CHECK-ENCODING: encoding: [0x90,0x94,0x3f,0x00] +- +-x86and.h $a0, $a1 +-# CHECK-INST: x86and.h $a0, $a1 +-# CHECK-ENCODING: encoding: [0x91,0x94,0x3f,0x00] +- +-x86and.w $a0, $a1 +-# CHECK-INST: x86and.w $a0, $a1 +-# CHECK-ENCODING: encoding: [0x92,0x94,0x3f,0x00] +- +-x86and.d $a0, $a1 +-# CHECK-INST: x86and.d $a0, $a1 +-# CHECK-ENCODING: encoding: [0x93,0x94,0x3f,0x00] +- +-x86or.b $a0, $a1 +-# CHECK-INST: x86or.b $a0, $a1 +-# CHECK-ENCODING: encoding: [0x94,0x94,0x3f,0x00] +- +-x86or.h $a0, $a1 +-# CHECK-INST: x86or.h $a0, $a1 +-# CHECK-ENCODING: encoding: [0x95,0x94,0x3f,0x00] +- +-x86or.w $a0, $a1 +-# CHECK-INST: x86or.w $a0, $a1 +-# CHECK-ENCODING: encoding: [0x96,0x94,0x3f,0x00] +- +-x86or.d $a0, $a1 +-# CHECK-INST: x86or.d $a0, $a1 +-# CHECK-ENCODING: encoding: [0x97,0x94,0x3f,0x00] +- +-x86xor.b $a0, $a1 +-# CHECK-INST: x86xor.b $a0, $a1 +-# CHECK-ENCODING: encoding: [0x98,0x94,0x3f,0x00] +- +-x86xor.h $a0, $a1 +-# CHECK-INST: x86xor.h $a0, $a1 +-# CHECK-ENCODING: encoding: [0x99,0x94,0x3f,0x00] +- +-x86xor.w $a0, $a1 +-# CHECK-INST: x86xor.w $a0, $a1 +-# CHECK-ENCODING: encoding: [0x9a,0x94,0x3f,0x00] +- +-x86xor.d $a0, $a1 +-# CHECK-INST: x86xor.d $a0, $a1 +-# CHECK-ENCODING: encoding: [0x9b,0x94,0x3f,0x00] +- +-x86mul.b $a0, $a1 +-# CHECK-INST: x86mul.b $a0, $a1 +-# CHECK-ENCODING: encoding: [0x80,0x94,0x3e,0x00] +- +-x86mul.h $a0, $a1 +-# CHECK-INST: x86mul.h $a0, $a1 +-# CHECK-ENCODING: encoding: [0x81,0x94,0x3e,0x00] +- +-x86mul.w $a0, $a1 +-# CHECK-INST: x86mul.w $a0, $a1 +-# CHECK-ENCODING: encoding: [0x82,0x94,0x3e,0x00] +- +-x86mul.d $a0, $a1 +-# CHECK-INST: x86mul.d $a0, $a1 +-# CHECK-ENCODING: encoding: [0x83,0x94,0x3e,0x00] +- +-x86mul.bu $a0, $a1 +-# CHECK-INST: x86mul.bu $a0, $a1 +-# CHECK-ENCODING: encoding: [0x84,0x94,0x3e,0x00] +- +-x86mul.hu $a0, $a1 +-# CHECK-INST: x86mul.hu $a0, $a1 +-# CHECK-ENCODING: encoding: [0x85,0x94,0x3e,0x00] +- +-x86mul.wu $a0, $a1 +-# CHECK-INST: x86mul.wu $a0, $a1 +-# CHECK-ENCODING: encoding: [0x86,0x94,0x3e,0x00] +- +-x86mul.du $a0, $a1 +-# CHECK-INST: x86mul.du $a0, $a1 +-# CHECK-ENCODING: encoding: [0x87,0x94,0x3e,0x00] +diff --git a/llvm/test/MC/LoongArch/lbt/x86-jump.s b/llvm/test/MC/LoongArch/lbt/x86-jump.s +deleted file mode 100644 +index 0bcb343ed..000000000 +--- a/llvm/test/MC/LoongArch/lbt/x86-jump.s ++++ /dev/null +@@ -1,16 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-setx86j $a0, 1 +-# CHECK-INST: setx86j $a0, 1 +-# CHECK-ENCODING: encoding: [0x04,0x84,0x36,0x00] +- +-setx86loope $a0, $a1 +-# CHECK-INST: setx86loope $a0, $a1 +-# CHECK-ENCODING: encoding: [0xa4,0x78,0x00,0x00] +- +-setx86loopne $a0, $a1 +-# CHECK-INST: setx86loopne $a0, $a1 +-# CHECK-ENCODING: encoding: [0xa4,0x7c,0x00,0x00] +diff --git a/llvm/test/MC/LoongArch/lbt/x86-misc.s b/llvm/test/MC/LoongArch/lbt/x86-misc.s +deleted file mode 100644 +index 8e4ad8ec1..000000000 +--- a/llvm/test/MC/LoongArch/lbt/x86-misc.s ++++ /dev/null +@@ -1,40 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-x86mfflag $a0, 1 +-# CHECK-INST: x86mfflag $a0, 1 +-# CHECK-ENCODING: encoding: [0x04,0x04,0x5c,0x00] +- +-x86mtflag $a0, 1 +-# CHECK-INST: x86mtflag $a0, 1 +-# CHECK-ENCODING: encoding: [0x24,0x04,0x5c,0x00] +- +-x86mftop $a0 +-# CHECK-INST: x86mftop $a0 +-# CHECK-ENCODING: encoding: [0x04,0x74,0x00,0x00] +- +-x86mttop 1 +-# CHECK-INST: x86mttop 1 +-# CHECK-ENCODING: encoding: [0x20,0x70,0x00,0x00] +- +-x86inctop +-# CHECK-INST: x86inctop +-# CHECK-ENCODING: encoding: [0x09,0x80,0x00,0x00] +- +-x86dectop +-# CHECK-INST: x86dectop +-# CHECK-ENCODING: encoding: [0x29,0x80,0x00,0x00] +- +-x86settm +-# CHECK-INST: x86settm +-# CHECK-ENCODING: encoding: [0x08,0x80,0x00,0x00] +- +-x86clrtm +-# CHECK-INST: x86clrtm +-# CHECK-ENCODING: encoding: [0x28,0x80,0x00,0x00] +- +-x86settag $a0, 1, 1 +-# CHECK-INST: x86settag $a0, 1, 1 +-# CHECK-ENCODING: encoding: [0x24,0x04,0x58,0x00] +diff --git a/llvm/test/MC/LoongArch/lbt/x86-shift.s b/llvm/test/MC/LoongArch/lbt/x86-shift.s +deleted file mode 100644 +index 61f0b8d07..000000000 +--- a/llvm/test/MC/LoongArch/lbt/x86-shift.s ++++ /dev/null +@@ -1,228 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-x86rcl.b $a0, $a1 +-# CHECK-INST: x86rcl.b $a0, $a1 +-# CHECK-ENCODING: encoding: [0x8c,0x94,0x3f,0x00] +- +-x86rcl.h $a0, $a1 +-# CHECK-INST: x86rcl.h $a0, $a1 +-# CHECK-ENCODING: encoding: [0x8d,0x94,0x3f,0x00] +- +-x86rcl.w $a0, $a1 +-# CHECK-INST: x86rcl.w $a0, $a1 +-# CHECK-ENCODING: encoding: [0x8e,0x94,0x3f,0x00] +- +-x86rcl.d $a0, $a1 +-# CHECK-INST: x86rcl.d $a0, $a1 +-# CHECK-ENCODING: encoding: [0x8f,0x94,0x3f,0x00] +- +-x86rcli.b $a0, 1 +-# CHECK-INST: x86rcli.b $a0, 1 +-# CHECK-ENCODING: encoding: [0x98,0x24,0x54,0x00] +- +-x86rcli.h $a0, 1 +-# CHECK-INST: x86rcli.h $a0, 1 +-# CHECK-ENCODING: encoding: [0x99,0x44,0x54,0x00] +- +-x86rcli.w $a0, 1 +-# CHECK-INST: x86rcli.w $a0, 1 +-# CHECK-ENCODING: encoding: [0x9a,0x84,0x54,0x00] +- +-x86rcli.d $a0, 1 +-# CHECK-INST: x86rcli.d $a0, 1 +-# CHECK-ENCODING: encoding: [0x9b,0x04,0x55,0x00] +- +-x86rcr.b $a0, $a1 +-# CHECK-INST: x86rcr.b $a0, $a1 +-# CHECK-ENCODING: encoding: [0x88,0x94,0x3f,0x00] +- +-x86rcr.h $a0, $a1 +-# CHECK-INST: x86rcr.h $a0, $a1 +-# CHECK-ENCODING: encoding: [0x89,0x94,0x3f,0x00] +- +-x86rcr.w $a0, $a1 +-# CHECK-INST: x86rcr.w $a0, $a1 +-# CHECK-ENCODING: encoding: [0x8a,0x94,0x3f,0x00] +- +-x86rcr.d $a0, $a1 +-# CHECK-INST: x86rcr.d $a0, $a1 +-# CHECK-ENCODING: encoding: [0x8b,0x94,0x3f,0x00] +- +-x86rcri.b $a0, 1 +-# CHECK-INST: x86rcri.b $a0, 1 +-# CHECK-ENCODING: encoding: [0x90,0x24,0x54,0x00] +- +-x86rcri.h $a0, 1 +-# CHECK-INST: x86rcri.h $a0, 1 +-# CHECK-ENCODING: encoding: [0x91,0x44,0x54,0x00] +- +-x86rcri.w $a0, 1 +-# CHECK-INST: x86rcri.w $a0, 1 +-# CHECK-ENCODING: encoding: [0x92,0x84,0x54,0x00] +- +-x86rcri.d $a0, 1 +-# CHECK-INST: x86rcri.d $a0, 1 +-# CHECK-ENCODING: encoding: [0x93,0x04,0x55,0x00] +- +-x86rotl.b $a0, $a1 +-# CHECK-INST: x86rotl.b $a0, $a1 +-# CHECK-ENCODING: encoding: [0x84,0x94,0x3f,0x00] +- +-x86rotl.h $a0, $a1 +-# CHECK-INST: x86rotl.h $a0, $a1 +-# CHECK-ENCODING: encoding: [0x85,0x94,0x3f,0x00] +- +-x86rotl.w $a0, $a1 +-# CHECK-INST: x86rotl.w $a0, $a1 +-# CHECK-ENCODING: encoding: [0x86,0x94,0x3f,0x00] +- +-x86rotl.d $a0, $a1 +-# CHECK-INST: x86rotl.d $a0, $a1 +-# CHECK-ENCODING: encoding: [0x87,0x94,0x3f,0x00] +- +-x86rotli.b $a0, 1 +-# CHECK-INST: x86rotli.b $a0, 1 +-# CHECK-ENCODING: encoding: [0x94,0x24,0x54,0x00] +- +-x86rotli.h $a0, 1 +-# CHECK-INST: x86rotli.h $a0, 1 +-# CHECK-ENCODING: encoding: [0x95,0x44,0x54,0x00] +- +-x86rotli.w $a0, 1 +-# CHECK-INST: x86rotli.w $a0, 1 +-# CHECK-ENCODING: encoding: [0x96,0x84,0x54,0x00] +- +-x86rotli.d $a0, 1 +-# CHECK-INST: x86rotli.d $a0, 1 +-# CHECK-ENCODING: encoding: [0x97,0x04,0x55,0x00] +- +-x86rotr.b $a0, $a1 +-# CHECK-INST: x86rotr.b $a0, $a1 +-# CHECK-ENCODING: encoding: [0x80,0x94,0x3f,0x00] +- +-x86rotr.h $a0, $a1 +-# CHECK-INST: x86rotr.h $a0, $a1 +-# CHECK-ENCODING: encoding: [0x81,0x94,0x3f,0x00] +- +-x86rotr.d $a0, $a1 +-# CHECK-INST: x86rotr.d $a0, $a1 +-# CHECK-ENCODING: encoding: [0x82,0x94,0x3f,0x00] +- +-x86rotr.w $a0, $a1 +-# CHECK-INST: x86rotr.w $a0, $a1 +-# CHECK-ENCODING: encoding: [0x83,0x94,0x3f,0x00] +- +-x86rotri.b $a0, 1 +-# CHECK-INST: x86rotri.b $a0, 1 +-# CHECK-ENCODING: encoding: [0x8c,0x24,0x54,0x00] +- +-x86rotri.h $a0, 1 +-# CHECK-INST: x86rotri.h $a0, 1 +-# CHECK-ENCODING: encoding: [0x8d,0x44,0x54,0x00] +- +-x86rotri.w $a0, 1 +-# CHECK-INST: x86rotri.w $a0, 1 +-# CHECK-ENCODING: encoding: [0x8e,0x84,0x54,0x00] +- +-x86rotri.d $a0, 1 +-# CHECK-INST: x86rotri.d $a0, 1 +-# CHECK-ENCODING: encoding: [0x8f,0x04,0x55,0x00] +- +-x86sll.b $a0, $a1 +-# CHECK-INST: x86sll.b $a0, $a1 +-# CHECK-ENCODING: encoding: [0x94,0x14,0x3f,0x00] +- +-x86sll.h $a0, $a1 +-# CHECK-INST: x86sll.h $a0, $a1 +-# CHECK-ENCODING: encoding: [0x95,0x14,0x3f,0x00] +- +-x86sll.w $a0, $a1 +-# CHECK-INST: x86sll.w $a0, $a1 +-# CHECK-ENCODING: encoding: [0x96,0x14,0x3f,0x00] +- +-x86sll.d $a0, $a1 +-# CHECK-INST: x86sll.d $a0, $a1 +-# CHECK-ENCODING: encoding: [0x97,0x14,0x3f,0x00] +- +-x86slli.b $a0, 1 +-# CHECK-INST: x86slli.b $a0, 1 +-# CHECK-ENCODING: encoding: [0x80,0x24,0x54,0x00] +- +-x86slli.h $a0, 1 +-# CHECK-INST: x86slli.h $a0, 1 +-# CHECK-ENCODING: encoding: [0x81,0x44,0x54,0x00] +- +-x86slli.w $a0, 1 +-# CHECK-INST: x86slli.w $a0, 1 +-# CHECK-ENCODING: encoding: [0x82,0x84,0x54,0x00] +- +-x86slli.d $a0, 1 +-# CHECK-INST: x86slli.d $a0, 1 +-# CHECK-ENCODING: encoding: [0x83,0x04,0x55,0x00] +- +-x86srl.b $a0, $a1 +-# CHECK-INST: x86srl.b $a0, $a1 +-# CHECK-ENCODING: encoding: [0x98,0x14,0x3f,0x00] +- +-x86srl.h $a0, $a1 +-# CHECK-INST: x86srl.h $a0, $a1 +-# CHECK-ENCODING: encoding: [0x99,0x14,0x3f,0x00] +- +-x86srl.w $a0, $a1 +-# CHECK-INST: x86srl.w $a0, $a1 +-# CHECK-ENCODING: encoding: [0x9a,0x14,0x3f,0x00] +- +-x86srl.d $a0, $a1 +-# CHECK-INST: x86srl.d $a0, $a1 +-# CHECK-ENCODING: encoding: [0x9b,0x14,0x3f,0x00] +- +-x86srli.b $a0, 1 +-# CHECK-INST: x86srli.b $a0, 1 +-# CHECK-ENCODING: encoding: [0x84,0x24,0x54,0x00] +- +-x86srli.h $a0, 1 +-# CHECK-INST: x86srli.h $a0, 1 +-# CHECK-ENCODING: encoding: [0x85,0x44,0x54,0x00] +- +-x86srli.w $a0, 1 +-# CHECK-INST: x86srli.w $a0, 1 +-# CHECK-ENCODING: encoding: [0x86,0x84,0x54,0x00] +- +-x86srli.d $a0, 1 +-# CHECK-INST: x86srli.d $a0, 1 +-# CHECK-ENCODING: encoding: [0x87,0x04,0x55,0x00] +- +-x86sra.b $a0, $a1 +-# CHECK-INST: x86sra.b $a0, $a1 +-# CHECK-ENCODING: encoding: [0x9c,0x14,0x3f,0x00] +- +-x86sra.h $a0, $a1 +-# CHECK-INST: x86sra.h $a0, $a1 +-# CHECK-ENCODING: encoding: [0x9d,0x14,0x3f,0x00] +- +-x86sra.w $a0, $a1 +-# CHECK-INST: x86sra.w $a0, $a1 +-# CHECK-ENCODING: encoding: [0x9e,0x14,0x3f,0x00] +- +-x86sra.d $a0, $a1 +-# CHECK-INST: x86sra.d $a0, $a1 +-# CHECK-ENCODING: encoding: [0x9f,0x14,0x3f,0x00] +- +-x86srai.b $a0, 1 +-# CHECK-INST: x86srai.b $a0, 1 +-# CHECK-ENCODING: encoding: [0x88,0x24,0x54,0x00] +- +-x86srai.h $a0, 1 +-# CHECK-INST: x86srai.h $a0, 1 +-# CHECK-ENCODING: encoding: [0x89,0x44,0x54,0x00] +- +-x86srai.w $a0, 1 +-# CHECK-INST: x86srai.w $a0, 1 +-# CHECK-ENCODING: encoding: [0x8a,0x84,0x54,0x00] +- +-x86srai.d $a0, 1 +-# CHECK-INST: x86srai.d $a0, 1 +-# CHECK-ENCODING: encoding: [0x8b,0x04,0x55,0x00] +diff --git a/llvm/test/MC/LoongArch/lit.local.cfg b/llvm/test/MC/LoongArch/lit.local.cfg +index cc24278ac..6223fc691 100644 +--- a/llvm/test/MC/LoongArch/lit.local.cfg ++++ b/llvm/test/MC/LoongArch/lit.local.cfg +@@ -1,2 +1,3 @@ +-if not "LoongArch" in config.root.targets: ++if not 'LoongArch' in config.root.targets: + config.unsupported = True ++ +diff --git a/llvm/test/MC/LoongArch/lsx/absd.s b/llvm/test/MC/LoongArch/lsx/absd.s +deleted file mode 100644 +index b203cab28..000000000 +--- a/llvm/test/MC/LoongArch/lsx/absd.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vabsd.b $vr14, $vr15, $vr12 +-# CHECK-INST: vabsd.b $vr14, $vr15, $vr12 +-# CHECK-ENCODING: encoding: [0xee,0x31,0x60,0x70] +- +-vabsd.h $vr7, $vr13, $vr10 +-# CHECK-INST: vabsd.h $vr7, $vr13, $vr10 +-# CHECK-ENCODING: encoding: [0xa7,0xa9,0x60,0x70] +- +-vabsd.w $vr5, $vr28, $vr29 +-# CHECK-INST: vabsd.w $vr5, $vr28, $vr29 +-# CHECK-ENCODING: encoding: [0x85,0x77,0x61,0x70] +- +-vabsd.d $vr7, $vr25, $vr5 +-# CHECK-INST: vabsd.d $vr7, $vr25, $vr5 +-# CHECK-ENCODING: encoding: [0x27,0x97,0x61,0x70] +- +-vabsd.bu $vr22, $vr16, $vr21 +-# CHECK-INST: vabsd.bu $vr22, $vr16, $vr21 +-# CHECK-ENCODING: encoding: [0x16,0x56,0x62,0x70] +- +-vabsd.hu $vr7, $vr29, $vr8 +-# CHECK-INST: vabsd.hu $vr7, $vr29, $vr8 +-# CHECK-ENCODING: encoding: [0xa7,0xa3,0x62,0x70] +- +-vabsd.wu $vr19, $vr31, $vr16 +-# CHECK-INST: vabsd.wu $vr19, $vr31, $vr16 +-# CHECK-ENCODING: encoding: [0xf3,0x43,0x63,0x70] +- +-vabsd.du $vr29, $vr31, $vr17 +-# CHECK-INST: vabsd.du $vr29, $vr31, $vr17 +-# CHECK-ENCODING: encoding: [0xfd,0xc7,0x63,0x70] +diff --git a/llvm/test/MC/LoongArch/lsx/add.s b/llvm/test/MC/LoongArch/lsx/add.s +deleted file mode 100644 +index fbc6c0fd5..000000000 +--- a/llvm/test/MC/LoongArch/lsx/add.s ++++ /dev/null +@@ -1,24 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vadd.b $vr11, $vr12, $vr8 +-# CHECK-INST: vadd.b $vr11, $vr12, $vr8 +-# CHECK-ENCODING: encoding: [0x8b,0x21,0x0a,0x70] +- +-vadd.h $vr22, $vr3, $vr4 +-# CHECK-INST: vadd.h $vr22, $vr3, $vr4 +-# CHECK-ENCODING: encoding: [0x76,0x90,0x0a,0x70] +- +-vadd.w $vr13, $vr16, $vr6 +-# CHECK-INST: vadd.w $vr13, $vr16, $vr6 +-# CHECK-ENCODING: encoding: [0x0d,0x1a,0x0b,0x70] +- +-vadd.d $vr12, $vr9, $vr3 +-# CHECK-INST: vadd.d $vr12, $vr9, $vr3 +-# CHECK-ENCODING: encoding: [0x2c,0x8d,0x0b,0x70] +- +-vadd.q $vr16, $vr15, $vr10 +-# CHECK-INST: vadd.q $vr16, $vr15, $vr10 +-# CHECK-ENCODING: encoding: [0xf0,0x29,0x2d,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/adda.s b/llvm/test/MC/LoongArch/lsx/adda.s +deleted file mode 100644 +index 31f073b05..000000000 +--- a/llvm/test/MC/LoongArch/lsx/adda.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vadda.b $vr7, $vr14, $vr21 +-# CHECK-INST: vadda.b $vr7, $vr14, $vr21 +-# CHECK-ENCODING: encoding: [0xc7,0x55,0x5c,0x70] +- +-vadda.h $vr19, $vr29, $vr2 +-# CHECK-INST: vadda.h $vr19, $vr29, $vr2 +-# CHECK-ENCODING: encoding: [0xb3,0x8b,0x5c,0x70] +- +-vadda.w $vr2, $vr23, $vr17 +-# CHECK-INST: vadda.w $vr2, $vr23, $vr17 +-# CHECK-ENCODING: encoding: [0xe2,0x46,0x5d,0x70] +- +-vadda.d $vr13, $vr18, $vr24 +-# CHECK-INST: vadda.d $vr13, $vr18, $vr24 +-# CHECK-ENCODING: encoding: [0x4d,0xe2,0x5d,0x70] +diff --git a/llvm/test/MC/LoongArch/lsx/addi.s b/llvm/test/MC/LoongArch/lsx/addi.s +deleted file mode 100644 +index 0e5795050..000000000 +--- a/llvm/test/MC/LoongArch/lsx/addi.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vaddi.bu $vr14, $vr3, 2 +-# CHECK-INST: vaddi.bu $vr14, $vr3, 2 +-# CHECK-ENCODING: encoding: [0x6e,0x08,0x8a,0x72] +- +-vaddi.hu $vr30, $vr27, 21 +-# CHECK-INST: vaddi.hu $vr30, $vr27, 21 +-# CHECK-ENCODING: encoding: [0x7e,0xd7,0x8a,0x72] +- +-vaddi.wu $vr16, $vr28, 27 +-# CHECK-INST: vaddi.wu $vr16, $vr28, 27 +-# CHECK-ENCODING: encoding: [0x90,0x6f,0x8b,0x72] +- +-vaddi.du $vr15, $vr8, 24 +-# CHECK-INST: vaddi.du $vr15, $vr8, 24 +-# CHECK-ENCODING: encoding: [0x0f,0xe1,0x8b,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/addw.s b/llvm/test/MC/LoongArch/lsx/addw.s +deleted file mode 100644 +index fbcc898da..000000000 +--- a/llvm/test/MC/LoongArch/lsx/addw.s ++++ /dev/null +@@ -1,100 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vaddwev.h.b $vr2, $vr23, $vr25 +-# CHECK-INST: vaddwev.h.b $vr2, $vr23, $vr25 +-# CHECK-ENCODING: encoding: [0xe2,0x66,0x1e,0x70] +- +-vaddwev.w.h $vr4, $vr8, $vr30 +-# CHECK-INST: vaddwev.w.h $vr4, $vr8, $vr30 +-# CHECK-ENCODING: encoding: [0x04,0xf9,0x1e,0x70] +- +-vaddwev.d.w $vr8, $vr31, $vr5 +-# CHECK-INST: vaddwev.d.w $vr8, $vr31, $vr5 +-# CHECK-ENCODING: encoding: [0xe8,0x17,0x1f,0x70] +- +-vaddwev.q.d $vr10, $vr10, $vr13 +-# CHECK-INST: vaddwev.q.d $vr10, $vr10, $vr13 +-# CHECK-ENCODING: encoding: [0x4a,0xb5,0x1f,0x70] +- +-vaddwev.h.bu $vr12, $vr24, $vr25 +-# CHECK-INST: vaddwev.h.bu $vr12, $vr24, $vr25 +-# CHECK-ENCODING: encoding: [0x0c,0x67,0x2e,0x70] +- +-vaddwev.w.hu $vr3, $vr9, $vr30 +-# CHECK-INST: vaddwev.w.hu $vr3, $vr9, $vr30 +-# CHECK-ENCODING: encoding: [0x23,0xf9,0x2e,0x70] +- +-vaddwev.d.wu $vr27, $vr10, $vr17 +-# CHECK-INST: vaddwev.d.wu $vr27, $vr10, $vr17 +-# CHECK-ENCODING: encoding: [0x5b,0x45,0x2f,0x70] +- +-vaddwev.q.du $vr25, $vr20, $vr14 +-# CHECK-INST: vaddwev.q.du $vr25, $vr20, $vr14 +-# CHECK-ENCODING: encoding: [0x99,0xba,0x2f,0x70] +- +-vaddwev.h.bu.b $vr5, $vr7, $vr16 +-# CHECK-INST: vaddwev.h.bu.b $vr5, $vr7, $vr16 +-# CHECK-ENCODING: encoding: [0xe5,0x40,0x3e,0x70] +- +-vaddwev.w.hu.h $vr15, $vr13, $vr29 +-# CHECK-INST: vaddwev.w.hu.h $vr15, $vr13, $vr29 +-# CHECK-ENCODING: encoding: [0xaf,0xf5,0x3e,0x70] +- +-vaddwev.d.wu.w $vr2, $vr6, $vr8 +-# CHECK-INST: vaddwev.d.wu.w $vr2, $vr6, $vr8 +-# CHECK-ENCODING: encoding: [0xc2,0x20,0x3f,0x70] +- +-vaddwev.q.du.d $vr19, $vr1, $vr12 +-# CHECK-INST: vaddwev.q.du.d $vr19, $vr1, $vr12 +-# CHECK-ENCODING: encoding: [0x33,0xb0,0x3f,0x70] +- +-vaddwod.h.b $vr31, $vr6, $vr9 +-# CHECK-INST: vaddwod.h.b $vr31, $vr6, $vr9 +-# CHECK-ENCODING: encoding: [0xdf,0x24,0x22,0x70] +- +-vaddwod.w.h $vr17, $vr31, $vr2 +-# CHECK-INST: vaddwod.w.h $vr17, $vr31, $vr2 +-# CHECK-ENCODING: encoding: [0xf1,0x8b,0x22,0x70] +- +-vaddwod.d.w $vr11, $vr15, $vr27 +-# CHECK-INST: vaddwod.d.w $vr11, $vr15, $vr27 +-# CHECK-ENCODING: encoding: [0xeb,0x6d,0x23,0x70] +- +-vaddwod.q.d $vr0, $vr26, $vr17 +-# CHECK-INST: vaddwod.q.d $vr0, $vr26, $vr17 +-# CHECK-ENCODING: encoding: [0x40,0xc7,0x23,0x70] +- +-vaddwod.h.bu $vr30, $vr15, $vr10 +-# CHECK-INST: vaddwod.h.bu $vr30, $vr15, $vr10 +-# CHECK-ENCODING: encoding: [0xfe,0x29,0x32,0x70] +- +-vaddwod.w.hu $vr24, $vr22, $vr1 +-# CHECK-INST: vaddwod.w.hu $vr24, $vr22, $vr1 +-# CHECK-ENCODING: encoding: [0xd8,0x86,0x32,0x70] +- +-vaddwod.d.wu $vr10, $vr25, $vr13 +-# CHECK-INST: vaddwod.d.wu $vr10, $vr25, $vr13 +-# CHECK-ENCODING: encoding: [0x2a,0x37,0x33,0x70] +- +-vaddwod.q.du $vr16, $vr23, $vr21 +-# CHECK-INST: vaddwod.q.du $vr16, $vr23, $vr21 +-# CHECK-ENCODING: encoding: [0xf0,0xd6,0x33,0x70] +- +-vaddwod.h.bu.b $vr30, $vr15, $vr2 +-# CHECK-INST: vaddwod.h.bu.b $vr30, $vr15, $vr2 +-# CHECK-ENCODING: encoding: [0xfe,0x09,0x40,0x70] +- +-vaddwod.w.hu.h $vr24, $vr30, $vr13 +-# CHECK-INST: vaddwod.w.hu.h $vr24, $vr30, $vr13 +-# CHECK-ENCODING: encoding: [0xd8,0xb7,0x40,0x70] +- +-vaddwod.d.wu.w $vr10, $vr26, $vr9 +-# CHECK-INST: vaddwod.d.wu.w $vr10, $vr26, $vr9 +-# CHECK-ENCODING: encoding: [0x4a,0x27,0x41,0x70] +- +-vaddwod.q.du.d $vr20, $vr9, $vr16 +-# CHECK-INST: vaddwod.q.du.d $vr20, $vr9, $vr16 +-# CHECK-ENCODING: encoding: [0x34,0xc1,0x41,0x70] +diff --git a/llvm/test/MC/LoongArch/lsx/and.s b/llvm/test/MC/LoongArch/lsx/and.s +deleted file mode 100644 +index f9688c39f..000000000 +--- a/llvm/test/MC/LoongArch/lsx/and.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vand.v $vr27, $vr30, $vr18 +-# CHECK-INST: vand.v $vr27, $vr30, $vr18 +-# CHECK-ENCODING: encoding: [0xdb,0x4b,0x26,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/andi.s b/llvm/test/MC/LoongArch/lsx/andi.s +deleted file mode 100644 +index 11732fbcb..000000000 +--- a/llvm/test/MC/LoongArch/lsx/andi.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vandi.b $vr10, $vr2, 181 +-# CHECK-INST: vandi.b $vr10, $vr2, 181 +-# CHECK-ENCODING: encoding: [0x4a,0xd4,0xd2,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/andn.s b/llvm/test/MC/LoongArch/lsx/andn.s +deleted file mode 100644 +index f682313b5..000000000 +--- a/llvm/test/MC/LoongArch/lsx/andn.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vandn.v $vr1, $vr26, $vr28 +-# CHECK-INST: vandn.v $vr1, $vr26, $vr28 +-# CHECK-ENCODING: encoding: [0x41,0x73,0x28,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/avg.s b/llvm/test/MC/LoongArch/lsx/avg.s +deleted file mode 100644 +index 31b3c4a0a..000000000 +--- a/llvm/test/MC/LoongArch/lsx/avg.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vavg.b $vr13, $vr3, $vr24 +-# CHECK-INST: vavg.b $vr13, $vr3, $vr24 +-# CHECK-ENCODING: encoding: [0x6d,0x60,0x64,0x70] +- +-vavg.h $vr3, $vr6, $vr20 +-# CHECK-INST: vavg.h $vr3, $vr6, $vr20 +-# CHECK-ENCODING: encoding: [0xc3,0xd0,0x64,0x70] +- +-vavg.w $vr21, $vr7, $vr20 +-# CHECK-INST: vavg.w $vr21, $vr7, $vr20 +-# CHECK-ENCODING: encoding: [0xf5,0x50,0x65,0x70] +- +-vavg.d $vr6, $vr22, $vr23 +-# CHECK-INST: vavg.d $vr6, $vr22, $vr23 +-# CHECK-ENCODING: encoding: [0xc6,0xde,0x65,0x70] +- +-vavg.bu $vr13, $vr30, $vr16 +-# CHECK-INST: vavg.bu $vr13, $vr30, $vr16 +-# CHECK-ENCODING: encoding: [0xcd,0x43,0x66,0x70] +- +-vavg.hu $vr0, $vr15, $vr23 +-# CHECK-INST: vavg.hu $vr0, $vr15, $vr23 +-# CHECK-ENCODING: encoding: [0xe0,0xdd,0x66,0x70] +- +-vavg.wu $vr0, $vr17, $vr9 +-# CHECK-INST: vavg.wu $vr0, $vr17, $vr9 +-# CHECK-ENCODING: encoding: [0x20,0x26,0x67,0x70] +- +-vavg.du $vr7, $vr22, $vr14 +-# CHECK-INST: vavg.du $vr7, $vr22, $vr14 +-# CHECK-ENCODING: encoding: [0xc7,0xba,0x67,0x70] +diff --git a/llvm/test/MC/LoongArch/lsx/avgr.s b/llvm/test/MC/LoongArch/lsx/avgr.s +deleted file mode 100644 +index 566feba6a..000000000 +--- a/llvm/test/MC/LoongArch/lsx/avgr.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vavgr.b $vr22, $vr3, $vr9 +-# CHECK-INST: vavgr.b $vr22, $vr3, $vr9 +-# CHECK-ENCODING: encoding: [0x76,0x24,0x68,0x70] +- +-vavgr.h $vr12, $vr2, $vr6 +-# CHECK-INST: vavgr.h $vr12, $vr2, $vr6 +-# CHECK-ENCODING: encoding: [0x4c,0x98,0x68,0x70] +- +-vavgr.w $vr16, $vr30, $vr13 +-# CHECK-INST: vavgr.w $vr16, $vr30, $vr13 +-# CHECK-ENCODING: encoding: [0xd0,0x37,0x69,0x70] +- +-vavgr.d $vr5, $vr18, $vr7 +-# CHECK-INST: vavgr.d $vr5, $vr18, $vr7 +-# CHECK-ENCODING: encoding: [0x45,0x9e,0x69,0x70] +- +-vavgr.bu $vr22, $vr5, $vr29 +-# CHECK-INST: vavgr.bu $vr22, $vr5, $vr29 +-# CHECK-ENCODING: encoding: [0xb6,0x74,0x6a,0x70] +- +-vavgr.hu $vr22, $vr23, $vr8 +-# CHECK-INST: vavgr.hu $vr22, $vr23, $vr8 +-# CHECK-ENCODING: encoding: [0xf6,0xa2,0x6a,0x70] +- +-vavgr.wu $vr10, $vr20, $vr21 +-# CHECK-INST: vavgr.wu $vr10, $vr20, $vr21 +-# CHECK-ENCODING: encoding: [0x8a,0x56,0x6b,0x70] +- +-vavgr.du $vr10, $vr28, $vr13 +-# CHECK-INST: vavgr.du $vr10, $vr28, $vr13 +-# CHECK-ENCODING: encoding: [0x8a,0xb7,0x6b,0x70] +diff --git a/llvm/test/MC/LoongArch/lsx/bitclr.s b/llvm/test/MC/LoongArch/lsx/bitclr.s +deleted file mode 100644 +index 227f90c2a..000000000 +--- a/llvm/test/MC/LoongArch/lsx/bitclr.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vbitclr.b $vr1, $vr0, $vr30 +-# CHECK-INST: vbitclr.b $vr1, $vr0, $vr30 +-# CHECK-ENCODING: encoding: [0x01,0x78,0x0c,0x71] +- +-vbitclr.h $vr27, $vr5, $vr28 +-# CHECK-INST: vbitclr.h $vr27, $vr5, $vr28 +-# CHECK-ENCODING: encoding: [0xbb,0xf0,0x0c,0x71] +- +-vbitclr.w $vr3, $vr30, $vr14 +-# CHECK-INST: vbitclr.w $vr3, $vr30, $vr14 +-# CHECK-ENCODING: encoding: [0xc3,0x3b,0x0d,0x71] +- +-vbitclr.d $vr25, $vr11, $vr4 +-# CHECK-INST: vbitclr.d $vr25, $vr11, $vr4 +-# CHECK-ENCODING: encoding: [0x79,0x91,0x0d,0x71] +- +-vbitclri.b $vr15, $vr25, 4 +-# CHECK-INST: vbitclri.b $vr15, $vr25, 4 +-# CHECK-ENCODING: encoding: [0x2f,0x33,0x10,0x73] +- +-vbitclri.h $vr24, $vr22, 1 +-# CHECK-INST: vbitclri.h $vr24, $vr22, 1 +-# CHECK-ENCODING: encoding: [0xd8,0x46,0x10,0x73] +- +-vbitclri.w $vr30, $vr20, 1 +-# CHECK-INST: vbitclri.w $vr30, $vr20, 1 +-# CHECK-ENCODING: encoding: [0x9e,0x86,0x10,0x73] +- +-vbitclri.d $vr5, $vr0, 16 +-# CHECK-INST: vbitclri.d $vr5, $vr0, 16 +-# CHECK-ENCODING: encoding: [0x05,0x40,0x11,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/bitrev.s b/llvm/test/MC/LoongArch/lsx/bitrev.s +deleted file mode 100644 +index 852500be5..000000000 +--- a/llvm/test/MC/LoongArch/lsx/bitrev.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vbitrev.b $vr4, $vr31, $vr10 +-# CHECK-INST: vbitrev.b $vr4, $vr31, $vr10 +-# CHECK-ENCODING: encoding: [0xe4,0x2b,0x10,0x71] +- +-vbitrev.h $vr19, $vr19, $vr16 +-# CHECK-INST: vbitrev.h $vr19, $vr19, $vr16 +-# CHECK-ENCODING: encoding: [0x73,0xc2,0x10,0x71] +- +-vbitrev.w $vr4, $vr18, $vr7 +-# CHECK-INST: vbitrev.w $vr4, $vr18, $vr7 +-# CHECK-ENCODING: encoding: [0x44,0x1e,0x11,0x71] +- +-vbitrev.d $vr17, $vr31, $vr0 +-# CHECK-INST: vbitrev.d $vr17, $vr31, $vr0 +-# CHECK-ENCODING: encoding: [0xf1,0x83,0x11,0x71] +- +-vbitrevi.b $vr9, $vr31, 7 +-# CHECK-INST: vbitrevi.b $vr9, $vr31, 7 +-# CHECK-ENCODING: encoding: [0xe9,0x3f,0x18,0x73] +- +-vbitrevi.h $vr4, $vr24, 8 +-# CHECK-INST: vbitrevi.h $vr4, $vr24, 8 +-# CHECK-ENCODING: encoding: [0x04,0x63,0x18,0x73] +- +-vbitrevi.w $vr17, $vr19, 2 +-# CHECK-INST: vbitrevi.w $vr17, $vr19, 2 +-# CHECK-ENCODING: encoding: [0x71,0x8a,0x18,0x73] +- +-vbitrevi.d $vr15, $vr7, 47 +-# CHECK-INST: vbitrevi.d $vr15, $vr7, 47 +-# CHECK-ENCODING: encoding: [0xef,0xbc,0x19,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/bitsel.s b/llvm/test/MC/LoongArch/lsx/bitsel.s +deleted file mode 100644 +index 54cce9647..000000000 +--- a/llvm/test/MC/LoongArch/lsx/bitsel.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vbitsel.v $vr2, $vr28, $vr6, $vr30 +-# CHECK-INST: vbitsel.v $vr2, $vr28, $vr6, $vr30 +-# CHECK-ENCODING: encoding: [0x82,0x1b,0x1f,0x0d] +diff --git a/llvm/test/MC/LoongArch/lsx/bitseli.s b/llvm/test/MC/LoongArch/lsx/bitseli.s +deleted file mode 100644 +index 6ca8a67d2..000000000 +--- a/llvm/test/MC/LoongArch/lsx/bitseli.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vbitseli.b $vr9, $vr0, 110 +-# CHECK-INST: vbitseli.b $vr9, $vr0, 110 +-# CHECK-ENCODING: encoding: [0x09,0xb8,0xc5,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/bitset.s b/llvm/test/MC/LoongArch/lsx/bitset.s +deleted file mode 100644 +index 3553fc07e..000000000 +--- a/llvm/test/MC/LoongArch/lsx/bitset.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vbitset.b $vr13, $vr27, $vr14 +-# CHECK-INST: vbitset.b $vr13, $vr27, $vr14 +-# CHECK-ENCODING: encoding: [0x6d,0x3b,0x0e,0x71] +- +-vbitset.h $vr24, $vr6, $vr3 +-# CHECK-INST: vbitset.h $vr24, $vr6, $vr3 +-# CHECK-ENCODING: encoding: [0xd8,0x8c,0x0e,0x71] +- +-vbitset.w $vr31, $vr0, $vr0 +-# CHECK-INST: vbitset.w $vr31, $vr0, $vr0 +-# CHECK-ENCODING: encoding: [0x1f,0x00,0x0f,0x71] +- +-vbitset.d $vr6, $vr15, $vr31 +-# CHECK-INST: vbitset.d $vr6, $vr15, $vr31 +-# CHECK-ENCODING: encoding: [0xe6,0xfd,0x0f,0x71] +- +-vbitseti.b $vr4, $vr3, 1 +-# CHECK-INST: vbitseti.b $vr4, $vr3, 1 +-# CHECK-ENCODING: encoding: [0x64,0x24,0x14,0x73] +- +-vbitseti.h $vr10, $vr20, 2 +-# CHECK-INST: vbitseti.h $vr10, $vr20, 2 +-# CHECK-ENCODING: encoding: [0x8a,0x4a,0x14,0x73] +- +-vbitseti.w $vr14, $vr16, 4 +-# CHECK-INST: vbitseti.w $vr14, $vr16, 4 +-# CHECK-ENCODING: encoding: [0x0e,0x92,0x14,0x73] +- +-vbitseti.d $vr10, $vr13, 25 +-# CHECK-INST: vbitseti.d $vr10, $vr13, 25 +-# CHECK-ENCODING: encoding: [0xaa,0x65,0x15,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/bsll.s b/llvm/test/MC/LoongArch/lsx/bsll.s +deleted file mode 100644 +index 24625180f..000000000 +--- a/llvm/test/MC/LoongArch/lsx/bsll.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vbsll.v $vr21, $vr1, 17 +-# CHECK-INST: vbsll.v $vr21, $vr1, 17 +-# CHECK-ENCODING: encoding: [0x35,0x44,0x8e,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/bsrl.s b/llvm/test/MC/LoongArch/lsx/bsrl.s +deleted file mode 100644 +index 2b9ab996b..000000000 +--- a/llvm/test/MC/LoongArch/lsx/bsrl.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vbsrl.v $vr14, $vr15, 24 +-# CHECK-INST: vbsrl.v $vr14, $vr15, 24 +-# CHECK-ENCODING: encoding: [0xee,0xe1,0x8e,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/clo.s b/llvm/test/MC/LoongArch/lsx/clo.s +deleted file mode 100644 +index de876176a..000000000 +--- a/llvm/test/MC/LoongArch/lsx/clo.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vclo.b $vr2, $vr0 +-# CHECK-INST: vclo.b $vr2, $vr0 +-# CHECK-ENCODING: encoding: [0x02,0x00,0x9c,0x72] +- +-vclo.h $vr23, $vr31 +-# CHECK-INST: vclo.h $vr23, $vr31 +-# CHECK-ENCODING: encoding: [0xf7,0x07,0x9c,0x72] +- +-vclo.w $vr7, $vr28 +-# CHECK-INST: vclo.w $vr7, $vr28 +-# CHECK-ENCODING: encoding: [0x87,0x0b,0x9c,0x72] +- +-vclo.d $vr5, $vr11 +-# CHECK-INST: vclo.d $vr5, $vr11 +-# CHECK-ENCODING: encoding: [0x65,0x0d,0x9c,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/clz.s b/llvm/test/MC/LoongArch/lsx/clz.s +deleted file mode 100644 +index de8c60310..000000000 +--- a/llvm/test/MC/LoongArch/lsx/clz.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vclz.b $vr22, $vr14 +-# CHECK-INST: vclz.b $vr22, $vr14 +-# CHECK-ENCODING: encoding: [0xd6,0x11,0x9c,0x72] +- +-vclz.h $vr16, $vr0 +-# CHECK-INST: vclz.h $vr16, $vr0 +-# CHECK-ENCODING: encoding: [0x10,0x14,0x9c,0x72] +- +-vclz.w $vr19, $vr19 +-# CHECK-INST: vclz.w $vr19, $vr19 +-# CHECK-ENCODING: encoding: [0x73,0x1a,0x9c,0x72] +- +-vclz.d $vr27, $vr14 +-# CHECK-INST: vclz.d $vr27, $vr14 +-# CHECK-ENCODING: encoding: [0xdb,0x1d,0x9c,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/div.s b/llvm/test/MC/LoongArch/lsx/div.s +deleted file mode 100644 +index 625c2a1b4..000000000 +--- a/llvm/test/MC/LoongArch/lsx/div.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vdiv.b $vr26, $vr17, $vr24 +-# CHECK-INST: vdiv.b $vr26, $vr17, $vr24 +-# CHECK-ENCODING: encoding: [0x3a,0x62,0xe0,0x70] +- +-vdiv.h $vr26, $vr23, $vr21 +-# CHECK-INST: vdiv.h $vr26, $vr23, $vr21 +-# CHECK-ENCODING: encoding: [0xfa,0xd6,0xe0,0x70] +- +-vdiv.w $vr1, $vr13, $vr10 +-# CHECK-INST: vdiv.w $vr1, $vr13, $vr10 +-# CHECK-ENCODING: encoding: [0xa1,0x29,0xe1,0x70] +- +-vdiv.d $vr4, $vr25, $vr21 +-# CHECK-INST: vdiv.d $vr4, $vr25, $vr21 +-# CHECK-ENCODING: encoding: [0x24,0xd7,0xe1,0x70] +- +-vdiv.bu $vr13, $vr13, $vr6 +-# CHECK-INST: vdiv.bu $vr13, $vr13, $vr6 +-# CHECK-ENCODING: encoding: [0xad,0x19,0xe4,0x70] +- +-vdiv.hu $vr1, $vr30, $vr5 +-# CHECK-INST: vdiv.hu $vr1, $vr30, $vr5 +-# CHECK-ENCODING: encoding: [0xc1,0x97,0xe4,0x70] +- +-vdiv.wu $vr27, $vr31, $vr20 +-# CHECK-INST: vdiv.wu $vr27, $vr31, $vr20 +-# CHECK-ENCODING: encoding: [0xfb,0x53,0xe5,0x70] +- +-vdiv.du $vr30, $vr0, $vr5 +-# CHECK-INST: vdiv.du $vr30, $vr0, $vr5 +-# CHECK-ENCODING: encoding: [0x1e,0x94,0xe5,0x70] +diff --git a/llvm/test/MC/LoongArch/lsx/exth.s b/llvm/test/MC/LoongArch/lsx/exth.s +deleted file mode 100644 +index 3a64bd927..000000000 +--- a/llvm/test/MC/LoongArch/lsx/exth.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vexth.h.b $vr9, $vr6 +-# CHECK-INST: vexth.h.b $vr9, $vr6 +-# CHECK-ENCODING: encoding: [0xc9,0xe0,0x9e,0x72] +- +-vexth.w.h $vr14, $vr19 +-# CHECK-INST: vexth.w.h $vr14, $vr19 +-# CHECK-ENCODING: encoding: [0x6e,0xe6,0x9e,0x72] +- +-vexth.d.w $vr1, $vr20 +-# CHECK-INST: vexth.d.w $vr1, $vr20 +-# CHECK-ENCODING: encoding: [0x81,0xea,0x9e,0x72] +- +-vexth.q.d $vr20, $vr10 +-# CHECK-INST: vexth.q.d $vr20, $vr10 +-# CHECK-ENCODING: encoding: [0x54,0xed,0x9e,0x72] +- +-vexth.hu.bu $vr5, $vr1 +-# CHECK-INST: vexth.hu.bu $vr5, $vr1 +-# CHECK-ENCODING: encoding: [0x25,0xf0,0x9e,0x72] +- +-vexth.wu.hu $vr17, $vr26 +-# CHECK-INST: vexth.wu.hu $vr17, $vr26 +-# CHECK-ENCODING: encoding: [0x51,0xf7,0x9e,0x72] +- +-vexth.du.wu $vr2, $vr7 +-# CHECK-INST: vexth.du.wu $vr2, $vr7 +-# CHECK-ENCODING: encoding: [0xe2,0xf8,0x9e,0x72] +- +-vexth.qu.du $vr19, $vr11 +-# CHECK-INST: vexth.qu.du $vr19, $vr11 +-# CHECK-ENCODING: encoding: [0x73,0xfd,0x9e,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/extl.s b/llvm/test/MC/LoongArch/lsx/extl.s +deleted file mode 100644 +index cce80e2f1..000000000 +--- a/llvm/test/MC/LoongArch/lsx/extl.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vextl.q.d $vr14, $vr20 +-# CHECK-INST: vextl.q.d $vr14, $vr20 +-# CHECK-ENCODING: encoding: [0x8e,0x02,0x09,0x73] +- +-vextl.qu.du $vr26, $vr26 +-# CHECK-INST: vextl.qu.du $vr26, $vr26 +-# CHECK-ENCODING: encoding: [0x5a,0x03,0x0d,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/extrins.s b/llvm/test/MC/LoongArch/lsx/extrins.s +deleted file mode 100644 +index ef279b7be..000000000 +--- a/llvm/test/MC/LoongArch/lsx/extrins.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vextrins.b $vr14, $vr19, 213 +-# CHECK-INST: vextrins.b $vr14, $vr19, 213 +-# CHECK-ENCODING: encoding: [0x6e,0x56,0x8f,0x73] +- +-vextrins.h $vr1, $vr6, 170 +-# CHECK-INST: vextrins.h $vr1, $vr6, 170 +-# CHECK-ENCODING: encoding: [0xc1,0xa8,0x8a,0x73] +- +-vextrins.w $vr9, $vr4, 189 +-# CHECK-INST: vextrins.w $vr9, $vr4, 189 +-# CHECK-ENCODING: encoding: [0x89,0xf4,0x86,0x73] +- +-vextrins.d $vr20, $vr25, 121 +-# CHECK-INST: vextrins.d $vr20, $vr25, 121 +-# CHECK-ENCODING: encoding: [0x34,0xe7,0x81,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/fadd.s b/llvm/test/MC/LoongArch/lsx/fadd.s +deleted file mode 100644 +index 55e67cf90..000000000 +--- a/llvm/test/MC/LoongArch/lsx/fadd.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vfadd.s $vr10, $vr2, $vr15 +-# CHECK-INST: vfadd.s $vr10, $vr2, $vr15 +-# CHECK-ENCODING: encoding: [0x4a,0xbc,0x30,0x71] +- +-vfadd.d $vr16, $vr1, $vr22 +-# CHECK-INST: vfadd.d $vr16, $vr1, $vr22 +-# CHECK-ENCODING: encoding: [0x30,0x58,0x31,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/fclass.s b/llvm/test/MC/LoongArch/lsx/fclass.s +deleted file mode 100644 +index 4f4ad1ef2..000000000 +--- a/llvm/test/MC/LoongArch/lsx/fclass.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vfclass.s $vr24, $vr26 +-# CHECK-INST: vfclass.s $vr24, $vr26 +-# CHECK-ENCODING: encoding: [0x58,0xd7,0x9c,0x72] +- +-vfclass.d $vr8, $vr17 +-# CHECK-INST: vfclass.d $vr8, $vr17 +-# CHECK-ENCODING: encoding: [0x28,0xda,0x9c,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/fcmp.s b/llvm/test/MC/LoongArch/lsx/fcmp.s +deleted file mode 100644 +index c7ea5bd04..000000000 +--- a/llvm/test/MC/LoongArch/lsx/fcmp.s ++++ /dev/null +@@ -1,180 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vfcmp.caf.s $vr25, $vr5, $vr4 +-# CHECK-INST: vfcmp.caf.s $vr25, $vr5, $vr4 +-# CHECK-ENCODING: encoding: [0xb9,0x10,0x50,0x0c] +- +-vfcmp.caf.d $vr14, $vr16, $vr23 +-# CHECK-INST: vfcmp.caf.d $vr14, $vr16, $vr23 +-# CHECK-ENCODING: encoding: [0x0e,0x5e,0x60,0x0c] +- +-vfcmp.cun.s $vr22, $vr15, $vr4 +-# CHECK-INST: vfcmp.cun.s $vr22, $vr15, $vr4 +-# CHECK-ENCODING: encoding: [0xf6,0x11,0x54,0x0c] +- +-vfcmp.cun.d $vr28, $vr27, $vr9 +-# CHECK-INST: vfcmp.cun.d $vr28, $vr27, $vr9 +-# CHECK-ENCODING: encoding: [0x7c,0x27,0x64,0x0c] +- +-vfcmp.ceq.s $vr20, $vr24, $vr29 +-# CHECK-INST: vfcmp.ceq.s $vr20, $vr24, $vr29 +-# CHECK-ENCODING: encoding: [0x14,0x77,0x52,0x0c] +- +-vfcmp.ceq.d $vr15, $vr23, $vr17 +-# CHECK-INST: vfcmp.ceq.d $vr15, $vr23, $vr17 +-# CHECK-ENCODING: encoding: [0xef,0x46,0x62,0x0c] +- +-vfcmp.cueq.s $vr26, $vr31, $vr19 +-# CHECK-INST: vfcmp.cueq.s $vr26, $vr31, $vr19 +-# CHECK-ENCODING: encoding: [0xfa,0x4f,0x56,0x0c] +- +-vfcmp.cueq.d $vr27, $vr10, $vr16 +-# CHECK-INST: vfcmp.cueq.d $vr27, $vr10, $vr16 +-# CHECK-ENCODING: encoding: [0x5b,0x41,0x66,0x0c] +- +-vfcmp.clt.s $vr6, $vr27, $vr2 +-# CHECK-INST: vfcmp.clt.s $vr6, $vr27, $vr2 +-# CHECK-ENCODING: encoding: [0x66,0x0b,0x51,0x0c] +- +-vfcmp.clt.d $vr11, $vr8, $vr6 +-# CHECK-INST: vfcmp.clt.d $vr11, $vr8, $vr6 +-# CHECK-ENCODING: encoding: [0x0b,0x19,0x61,0x0c] +- +-vfcmp.cult.s $vr1, $vr17, $vr2 +-# CHECK-INST: vfcmp.cult.s $vr1, $vr17, $vr2 +-# CHECK-ENCODING: encoding: [0x21,0x0a,0x55,0x0c] +- +-vfcmp.cult.d $vr11, $vr20, $vr7 +-# CHECK-INST: vfcmp.cult.d $vr11, $vr20, $vr7 +-# CHECK-ENCODING: encoding: [0x8b,0x1e,0x65,0x0c] +- +-vfcmp.cle.s $vr10, $vr20, $vr23 +-# CHECK-INST: vfcmp.cle.s $vr10, $vr20, $vr23 +-# CHECK-ENCODING: encoding: [0x8a,0x5e,0x53,0x0c] +- +-vfcmp.cle.d $vr1, $vr8, $vr18 +-# CHECK-INST: vfcmp.cle.d $vr1, $vr8, $vr18 +-# CHECK-ENCODING: encoding: [0x01,0x49,0x63,0x0c] +- +-vfcmp.cule.s $vr6, $vr15, $vr11 +-# CHECK-INST: vfcmp.cule.s $vr6, $vr15, $vr11 +-# CHECK-ENCODING: encoding: [0xe6,0x2d,0x57,0x0c] +- +-vfcmp.cule.d $vr11, $vr28, $vr30 +-# CHECK-INST: vfcmp.cule.d $vr11, $vr28, $vr30 +-# CHECK-ENCODING: encoding: [0x8b,0x7b,0x67,0x0c] +- +-vfcmp.cne.s $vr29, $vr28, $vr11 +-# CHECK-INST: vfcmp.cne.s $vr29, $vr28, $vr11 +-# CHECK-ENCODING: encoding: [0x9d,0x2f,0x58,0x0c] +- +-vfcmp.cne.d $vr20, $vr5, $vr7 +-# CHECK-INST: vfcmp.cne.d $vr20, $vr5, $vr7 +-# CHECK-ENCODING: encoding: [0xb4,0x1c,0x68,0x0c] +- +-vfcmp.cor.s $vr20, $vr17, $vr12 +-# CHECK-INST: vfcmp.cor.s $vr20, $vr17, $vr12 +-# CHECK-ENCODING: encoding: [0x34,0x32,0x5a,0x0c] +- +-vfcmp.cor.d $vr25, $vr10, $vr16 +-# CHECK-INST: vfcmp.cor.d $vr25, $vr10, $vr16 +-# CHECK-ENCODING: encoding: [0x59,0x41,0x6a,0x0c] +- +-vfcmp.cune.s $vr26, $vr7, $vr8 +-# CHECK-INST: vfcmp.cune.s $vr26, $vr7, $vr8 +-# CHECK-ENCODING: encoding: [0xfa,0x20,0x5c,0x0c] +- +-vfcmp.cune.d $vr13, $vr31, $vr3 +-# CHECK-INST: vfcmp.cune.d $vr13, $vr31, $vr3 +-# CHECK-ENCODING: encoding: [0xed,0x0f,0x6c,0x0c] +- +-vfcmp.saf.s $vr26, $vr25, $vr5 +-# CHECK-INST: vfcmp.saf.s $vr26, $vr25, $vr5 +-# CHECK-ENCODING: encoding: [0x3a,0x97,0x50,0x0c] +- +-vfcmp.saf.d $vr5, $vr29, $vr21 +-# CHECK-INST: vfcmp.saf.d $vr5, $vr29, $vr21 +-# CHECK-ENCODING: encoding: [0xa5,0xd7,0x60,0x0c] +- +-vfcmp.sun.s $vr2, $vr2, $vr11 +-# CHECK-INST: vfcmp.sun.s $vr2, $vr2, $vr11 +-# CHECK-ENCODING: encoding: [0x42,0xac,0x54,0x0c] +- +-vfcmp.sun.d $vr30, $vr23, $vr23 +-# CHECK-INST: vfcmp.sun.d $vr30, $vr23, $vr23 +-# CHECK-ENCODING: encoding: [0xfe,0xde,0x64,0x0c] +- +-vfcmp.seq.s $vr4, $vr24, $vr31 +-# CHECK-INST: vfcmp.seq.s $vr4, $vr24, $vr31 +-# CHECK-ENCODING: encoding: [0x04,0xff,0x52,0x0c] +- +-vfcmp.seq.d $vr28, $vr28, $vr5 +-# CHECK-INST: vfcmp.seq.d $vr28, $vr28, $vr5 +-# CHECK-ENCODING: encoding: [0x9c,0x97,0x62,0x0c] +- +-vfcmp.sueq.s $vr2, $vr25, $vr29 +-# CHECK-INST: vfcmp.sueq.s $vr2, $vr25, $vr29 +-# CHECK-ENCODING: encoding: [0x22,0xf7,0x56,0x0c] +- +-vfcmp.sueq.d $vr26, $vr16, $vr0 +-# CHECK-INST: vfcmp.sueq.d $vr26, $vr16, $vr0 +-# CHECK-ENCODING: encoding: [0x1a,0x82,0x66,0x0c] +- +-vfcmp.slt.s $vr8, $vr22, $vr5 +-# CHECK-INST: vfcmp.slt.s $vr8, $vr22, $vr5 +-# CHECK-ENCODING: encoding: [0xc8,0x96,0x51,0x0c] +- +-vfcmp.slt.d $vr13, $vr8, $vr22 +-# CHECK-INST: vfcmp.slt.d $vr13, $vr8, $vr22 +-# CHECK-ENCODING: encoding: [0x0d,0xd9,0x61,0x0c] +- +-vfcmp.sult.s $vr16, $vr4, $vr21 +-# CHECK-INST: vfcmp.sult.s $vr16, $vr4, $vr21 +-# CHECK-ENCODING: encoding: [0x90,0xd4,0x55,0x0c] +- +-vfcmp.sult.d $vr28, $vr14, $vr4 +-# CHECK-INST: vfcmp.sult.d $vr28, $vr14, $vr4 +-# CHECK-ENCODING: encoding: [0xdc,0x91,0x65,0x0c] +- +-vfcmp.sle.s $vr13, $vr21, $vr8 +-# CHECK-INST: vfcmp.sle.s $vr13, $vr21, $vr8 +-# CHECK-ENCODING: encoding: [0xad,0xa2,0x53,0x0c] +- +-vfcmp.sle.d $vr3, $vr18, $vr9 +-# CHECK-INST: vfcmp.sle.d $vr3, $vr18, $vr9 +-# CHECK-ENCODING: encoding: [0x43,0xa6,0x63,0x0c] +- +-vfcmp.sule.s $vr8, $vr23, $vr19 +-# CHECK-INST: vfcmp.sule.s $vr8, $vr23, $vr19 +-# CHECK-ENCODING: encoding: [0xe8,0xce,0x57,0x0c] +- +-vfcmp.sule.d $vr22, $vr17, $vr11 +-# CHECK-INST: vfcmp.sule.d $vr22, $vr17, $vr11 +-# CHECK-ENCODING: encoding: [0x36,0xae,0x67,0x0c] +- +-vfcmp.sne.s $vr17, $vr25, $vr6 +-# CHECK-INST: vfcmp.sne.s $vr17, $vr25, $vr6 +-# CHECK-ENCODING: encoding: [0x31,0x9b,0x58,0x0c] +- +-vfcmp.sne.d $vr3, $vr1, $vr28 +-# CHECK-INST: vfcmp.sne.d $vr3, $vr1, $vr28 +-# CHECK-ENCODING: encoding: [0x23,0xf0,0x68,0x0c] +- +-vfcmp.sor.s $vr31, $vr20, $vr11 +-# CHECK-INST: vfcmp.sor.s $vr31, $vr20, $vr11 +-# CHECK-ENCODING: encoding: [0x9f,0xae,0x5a,0x0c] +- +-vfcmp.sor.d $vr18, $vr4, $vr15 +-# CHECK-INST: vfcmp.sor.d $vr18, $vr4, $vr15 +-# CHECK-ENCODING: encoding: [0x92,0xbc,0x6a,0x0c] +- +-vfcmp.sune.s $vr16, $vr17, $vr15 +-# CHECK-INST: vfcmp.sune.s $vr16, $vr17, $vr15 +-# CHECK-ENCODING: encoding: [0x30,0xbe,0x5c,0x0c] +- +-vfcmp.sune.d $vr23, $vr1, $vr19 +-# CHECK-INST: vfcmp.sune.d $vr23, $vr1, $vr19 +-# CHECK-ENCODING: encoding: [0x37,0xcc,0x6c,0x0c] +diff --git a/llvm/test/MC/LoongArch/lsx/fcvt.s b/llvm/test/MC/LoongArch/lsx/fcvt.s +deleted file mode 100644 +index 30689a79f..000000000 +--- a/llvm/test/MC/LoongArch/lsx/fcvt.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vfcvt.h.s $vr30, $vr1, $vr30 +-# CHECK-INST: vfcvt.h.s $vr30, $vr1, $vr30 +-# CHECK-ENCODING: encoding: [0x3e,0x78,0x46,0x71] +- +-vfcvt.s.d $vr27, $vr11, $vr4 +-# CHECK-INST: vfcvt.s.d $vr27, $vr11, $vr4 +-# CHECK-ENCODING: encoding: [0x7b,0x91,0x46,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/fcvth.s b/llvm/test/MC/LoongArch/lsx/fcvth.s +deleted file mode 100644 +index 09d2dad65..000000000 +--- a/llvm/test/MC/LoongArch/lsx/fcvth.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vfcvth.s.h $vr7, $vr30 +-# CHECK-INST: vfcvth.s.h $vr7, $vr30 +-# CHECK-ENCODING: encoding: [0xc7,0xef,0x9d,0x72] +- +-vfcvth.d.s $vr15, $vr14 +-# CHECK-INST: vfcvth.d.s $vr15, $vr14 +-# CHECK-ENCODING: encoding: [0xcf,0xf5,0x9d,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/fcvtl.s b/llvm/test/MC/LoongArch/lsx/fcvtl.s +deleted file mode 100644 +index bb45be02c..000000000 +--- a/llvm/test/MC/LoongArch/lsx/fcvtl.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vfcvtl.s.h $vr26, $vr23 +-# CHECK-INST: vfcvtl.s.h $vr26, $vr23 +-# CHECK-ENCODING: encoding: [0xfa,0xea,0x9d,0x72] +- +-vfcvtl.d.s $vr3, $vr7 +-# CHECK-INST: vfcvtl.d.s $vr3, $vr7 +-# CHECK-ENCODING: encoding: [0xe3,0xf0,0x9d,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/fdiv.s b/llvm/test/MC/LoongArch/lsx/fdiv.s +deleted file mode 100644 +index cb3b536c6..000000000 +--- a/llvm/test/MC/LoongArch/lsx/fdiv.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vfdiv.s $vr27, $vr12, $vr26 +-# CHECK-INST: vfdiv.s $vr27, $vr12, $vr26 +-# CHECK-ENCODING: encoding: [0x9b,0xe9,0x3a,0x71] +- +-vfdiv.d $vr3, $vr1, $vr7 +-# CHECK-INST: vfdiv.d $vr3, $vr1, $vr7 +-# CHECK-ENCODING: encoding: [0x23,0x1c,0x3b,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/ffint.s b/llvm/test/MC/LoongArch/lsx/ffint.s +deleted file mode 100644 +index e6340d161..000000000 +--- a/llvm/test/MC/LoongArch/lsx/ffint.s ++++ /dev/null +@@ -1,32 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vffint.s.w $vr3, $vr0 +-# CHECK-INST: vffint.s.w $vr3, $vr0 +-# CHECK-ENCODING: encoding: [0x03,0x00,0x9e,0x72] +- +-vffint.d.l $vr2, $vr15 +-# CHECK-INST: vffint.d.l $vr2, $vr15 +-# CHECK-ENCODING: encoding: [0xe2,0x09,0x9e,0x72] +- +-vffint.s.wu $vr5, $vr9 +-# CHECK-INST: vffint.s.wu $vr5, $vr9 +-# CHECK-ENCODING: encoding: [0x25,0x05,0x9e,0x72] +- +-vffint.d.lu $vr6, $vr13 +-# CHECK-INST: vffint.d.lu $vr6, $vr13 +-# CHECK-ENCODING: encoding: [0xa6,0x0d,0x9e,0x72] +- +-vffintl.d.w $vr26, $vr1 +-# CHECK-INST: vffintl.d.w $vr26, $vr1 +-# CHECK-ENCODING: encoding: [0x3a,0x10,0x9e,0x72] +- +-vffinth.d.w $vr18, $vr21 +-# CHECK-INST: vffinth.d.w $vr18, $vr21 +-# CHECK-ENCODING: encoding: [0xb2,0x16,0x9e,0x72] +- +-vffint.s.l $vr29, $vr12, $vr7 +-# CHECK-INST: vffint.s.l $vr29, $vr12, $vr7 +-# CHECK-ENCODING: encoding: [0x9d,0x1d,0x48,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/flogb.s b/llvm/test/MC/LoongArch/lsx/flogb.s +deleted file mode 100644 +index 3c788b96f..000000000 +--- a/llvm/test/MC/LoongArch/lsx/flogb.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vflogb.s $vr12, $vr20 +-# CHECK-INST: vflogb.s $vr12, $vr20 +-# CHECK-ENCODING: encoding: [0x8c,0xc6,0x9c,0x72] +- +-vflogb.d $vr3, $vr29 +-# CHECK-INST: vflogb.d $vr3, $vr29 +-# CHECK-ENCODING: encoding: [0xa3,0xcb,0x9c,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/fmadd.s b/llvm/test/MC/LoongArch/lsx/fmadd.s +deleted file mode 100644 +index a31e12120..000000000 +--- a/llvm/test/MC/LoongArch/lsx/fmadd.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vfmadd.s $vr6, $vr7, $vr13, $vr24 +-# CHECK-INST: vfmadd.s $vr6, $vr7, $vr13, $vr24 +-# CHECK-ENCODING: encoding: [0xe6,0x34,0x1c,0x09] +- +-vfmadd.d $vr3, $vr28, $vr2, $vr21 +-# CHECK-INST: vfmadd.d $vr3, $vr28, $vr2, $vr21 +-# CHECK-ENCODING: encoding: [0x83,0x8b,0x2a,0x09] +diff --git a/llvm/test/MC/LoongArch/lsx/fmax.s b/llvm/test/MC/LoongArch/lsx/fmax.s +deleted file mode 100644 +index 8fcd32aeb..000000000 +--- a/llvm/test/MC/LoongArch/lsx/fmax.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vfmax.s $vr19, $vr25, $vr16 +-# CHECK-INST: vfmax.s $vr19, $vr25, $vr16 +-# CHECK-ENCODING: encoding: [0x33,0xc3,0x3c,0x71] +- +-vfmax.d $vr19, $vr21, $vr12 +-# CHECK-INST: vfmax.d $vr19, $vr21, $vr12 +-# CHECK-ENCODING: encoding: [0xb3,0x32,0x3d,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/fmaxa.s b/llvm/test/MC/LoongArch/lsx/fmaxa.s +deleted file mode 100644 +index 3e35c329d..000000000 +--- a/llvm/test/MC/LoongArch/lsx/fmaxa.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vfmaxa.s $vr2, $vr8, $vr1 +-# CHECK-INST: vfmaxa.s $vr2, $vr8, $vr1 +-# CHECK-ENCODING: encoding: [0x02,0x85,0x40,0x71] +- +-vfmaxa.d $vr1, $vr8, $vr28 +-# CHECK-INST: vfmaxa.d $vr1, $vr8, $vr28 +-# CHECK-ENCODING: encoding: [0x01,0x71,0x41,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/fmin.s b/llvm/test/MC/LoongArch/lsx/fmin.s +deleted file mode 100644 +index b398fe70d..000000000 +--- a/llvm/test/MC/LoongArch/lsx/fmin.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vfmin.s $vr18, $vr17, $vr1 +-# CHECK-INST: vfmin.s $vr18, $vr17, $vr1 +-# CHECK-ENCODING: encoding: [0x32,0x86,0x3e,0x71] +- +-vfmin.d $vr30, $vr12, $vr5 +-# CHECK-INST: vfmin.d $vr30, $vr12, $vr5 +-# CHECK-ENCODING: encoding: [0x9e,0x15,0x3f,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/fmina.s b/llvm/test/MC/LoongArch/lsx/fmina.s +deleted file mode 100644 +index d206819ae..000000000 +--- a/llvm/test/MC/LoongArch/lsx/fmina.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vfmina.s $vr20, $vr27, $vr20 +-# CHECK-INST: vfmina.s $vr20, $vr27, $vr20 +-# CHECK-ENCODING: encoding: [0x74,0xd3,0x42,0x71] +- +-vfmina.d $vr1, $vr26, $vr22 +-# CHECK-INST: vfmina.d $vr1, $vr26, $vr22 +-# CHECK-ENCODING: encoding: [0x41,0x5b,0x43,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/fmsub.s b/llvm/test/MC/LoongArch/lsx/fmsub.s +deleted file mode 100644 +index 84ce341de..000000000 +--- a/llvm/test/MC/LoongArch/lsx/fmsub.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vfmsub.s $vr25, $vr30, $vr4, $vr13 +-# CHECK-INST: vfmsub.s $vr25, $vr30, $vr4, $vr13 +-# CHECK-ENCODING: encoding: [0xd9,0x93,0x56,0x09] +- +-vfmsub.d $vr3, $vr1, $vr0, $vr19 +-# CHECK-INST: vfmsub.d $vr3, $vr1, $vr0, $vr19 +-# CHECK-ENCODING: encoding: [0x23,0x80,0x69,0x09] +diff --git a/llvm/test/MC/LoongArch/lsx/fmul.s b/llvm/test/MC/LoongArch/lsx/fmul.s +deleted file mode 100644 +index a409a6a40..000000000 +--- a/llvm/test/MC/LoongArch/lsx/fmul.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vfmul.s $vr16, $vr8, $vr17 +-# CHECK-INST: vfmul.s $vr16, $vr8, $vr17 +-# CHECK-ENCODING: encoding: [0x10,0xc5,0x38,0x71] +- +-vfmul.d $vr3, $vr6, $vr1 +-# CHECK-INST: vfmul.d $vr3, $vr6, $vr1 +-# CHECK-ENCODING: encoding: [0xc3,0x04,0x39,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/fnmadd.s b/llvm/test/MC/LoongArch/lsx/fnmadd.s +deleted file mode 100644 +index 1887d2688..000000000 +--- a/llvm/test/MC/LoongArch/lsx/fnmadd.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vfnmadd.s $vr26, $vr26, $vr13, $vr9 +-# CHECK-INST: vfnmadd.s $vr26, $vr26, $vr13, $vr9 +-# CHECK-ENCODING: encoding: [0x5a,0xb7,0x94,0x09] +- +-vfnmadd.d $vr12, $vr27, $vr31, $vr5 +-# CHECK-INST: vfnmadd.d $vr12, $vr27, $vr31, $vr5 +-# CHECK-ENCODING: encoding: [0x6c,0xff,0xa2,0x09] +diff --git a/llvm/test/MC/LoongArch/lsx/fnmsub.s b/llvm/test/MC/LoongArch/lsx/fnmsub.s +deleted file mode 100644 +index e1135d1b2..000000000 +--- a/llvm/test/MC/LoongArch/lsx/fnmsub.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vfnmsub.s $vr2, $vr21, $vr9, $vr2 +-# CHECK-INST: vfnmsub.s $vr2, $vr21, $vr9, $vr2 +-# CHECK-ENCODING: encoding: [0xa2,0x26,0xd1,0x09] +- +-vfnmsub.d $vr4, $vr12, $vr27, $vr19 +-# CHECK-INST: vfnmsub.d $vr4, $vr12, $vr27, $vr19 +-# CHECK-ENCODING: encoding: [0x84,0xed,0xe9,0x09] +diff --git a/llvm/test/MC/LoongArch/lsx/frecip.s b/llvm/test/MC/LoongArch/lsx/frecip.s +deleted file mode 100644 +index cd6d925e1..000000000 +--- a/llvm/test/MC/LoongArch/lsx/frecip.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vfrecip.s $vr29, $vr14 +-# CHECK-INST: vfrecip.s $vr29, $vr14 +-# CHECK-ENCODING: encoding: [0xdd,0xf5,0x9c,0x72] +- +-vfrecip.d $vr24, $vr9 +-# CHECK-INST: vfrecip.d $vr24, $vr9 +-# CHECK-ENCODING: encoding: [0x38,0xf9,0x9c,0x72] +- +-vfrecipe.s $vr29, $vr14 +-# CHECK-INST: vfrecipe.s $vr29, $vr14 +-# CHECK-ENCODING: encoding: [0xdd,0x15,0x9d,0x72] +- +-vfrecipe.d $vr24, $vr9 +-# CHECK-INST: vfrecipe.d $vr24, $vr9 +-# CHECK-ENCODING: encoding: [0x38,0x19,0x9d,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/frint.s b/llvm/test/MC/LoongArch/lsx/frint.s +deleted file mode 100644 +index 53a43a4d3..000000000 +--- a/llvm/test/MC/LoongArch/lsx/frint.s ++++ /dev/null +@@ -1,44 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vfrintrne.s $vr31, $vr2 +-# CHECK-INST: vfrintrne.s $vr31, $vr2 +-# CHECK-ENCODING: encoding: [0x5f,0x74,0x9d,0x72] +- +-vfrintrne.d $vr1, $vr30 +-# CHECK-INST: vfrintrne.d $vr1, $vr30 +-# CHECK-ENCODING: encoding: [0xc1,0x7b,0x9d,0x72] +- +-vfrintrz.s $vr16, $vr17 +-# CHECK-INST: vfrintrz.s $vr16, $vr17 +-# CHECK-ENCODING: encoding: [0x30,0x66,0x9d,0x72] +- +-vfrintrz.d $vr1, $vr31 +-# CHECK-INST: vfrintrz.d $vr1, $vr31 +-# CHECK-ENCODING: encoding: [0xe1,0x6b,0x9d,0x72] +- +-vfrintrp.s $vr11, $vr2 +-# CHECK-INST: vfrintrp.s $vr11, $vr2 +-# CHECK-ENCODING: encoding: [0x4b,0x54,0x9d,0x72] +- +-vfrintrp.d $vr30, $vr16 +-# CHECK-INST: vfrintrp.d $vr30, $vr16 +-# CHECK-ENCODING: encoding: [0x1e,0x5a,0x9d,0x72] +- +-vfrintrm.s $vr25, $vr23 +-# CHECK-INST: vfrintrm.s $vr25, $vr23 +-# CHECK-ENCODING: encoding: [0xf9,0x46,0x9d,0x72] +- +-vfrintrm.d $vr19, $vr11 +-# CHECK-INST: vfrintrm.d $vr19, $vr11 +-# CHECK-ENCODING: encoding: [0x73,0x49,0x9d,0x72] +- +-vfrint.s $vr22, $vr6 +-# CHECK-INST: vfrint.s $vr22, $vr6 +-# CHECK-ENCODING: encoding: [0xd6,0x34,0x9d,0x72] +- +-vfrint.d $vr26, $vr9 +-# CHECK-INST: vfrint.d $vr26, $vr9 +-# CHECK-ENCODING: encoding: [0x3a,0x39,0x9d,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/frsqrt.s b/llvm/test/MC/LoongArch/lsx/frsqrt.s +deleted file mode 100644 +index d8b9fc3d0..000000000 +--- a/llvm/test/MC/LoongArch/lsx/frsqrt.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vfrsqrt.s $vr19, $vr30 +-# CHECK-INST: vfrsqrt.s $vr19, $vr30 +-# CHECK-ENCODING: encoding: [0xd3,0x07,0x9d,0x72] +- +-vfrsqrt.d $vr1, $vr0 +-# CHECK-INST: vfrsqrt.d $vr1, $vr0 +-# CHECK-ENCODING: encoding: [0x01,0x08,0x9d,0x72] +- +-vfrsqrte.s $vr19, $vr30 +-# CHECK-INST: vfrsqrte.s $vr19, $vr30 +-# CHECK-ENCODING: encoding: [0xd3,0x27,0x9d,0x72] +- +-vfrsqrte.d $vr1, $vr0 +-# CHECK-INST: vfrsqrte.d $vr1, $vr0 +-# CHECK-ENCODING: encoding: [0x01,0x28,0x9d,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/frstp.s b/llvm/test/MC/LoongArch/lsx/frstp.s +deleted file mode 100644 +index 86bb31a1d..000000000 +--- a/llvm/test/MC/LoongArch/lsx/frstp.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vfrstp.b $vr30, $vr25, $vr1 +-# CHECK-INST: vfrstp.b $vr30, $vr25, $vr1 +-# CHECK-ENCODING: encoding: [0x3e,0x07,0x2b,0x71] +- +-vfrstp.h $vr22, $vr26, $vr21 +-# CHECK-INST: vfrstp.h $vr22, $vr26, $vr21 +-# CHECK-ENCODING: encoding: [0x56,0xd7,0x2b,0x71] +- +-vfrstpi.b $vr12, $vr8, 28 +-# CHECK-INST: vfrstpi.b $vr12, $vr8, 28 +-# CHECK-ENCODING: encoding: [0x0c,0x71,0x9a,0x72] +- +-vfrstpi.h $vr5, $vr28, 29 +-# CHECK-INST: vfrstpi.h $vr5, $vr28, 29 +-# CHECK-ENCODING: encoding: [0x85,0xf7,0x9a,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/fsqrt.s b/llvm/test/MC/LoongArch/lsx/fsqrt.s +deleted file mode 100644 +index a5df2416d..000000000 +--- a/llvm/test/MC/LoongArch/lsx/fsqrt.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vfsqrt.s $vr0, $vr3 +-# CHECK-INST: vfsqrt.s $vr0, $vr3 +-# CHECK-ENCODING: encoding: [0x60,0xe4,0x9c,0x72] +- +-vfsqrt.d $vr26, $vr9 +-# CHECK-INST: vfsqrt.d $vr26, $vr9 +-# CHECK-ENCODING: encoding: [0x3a,0xe9,0x9c,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/fsub.s b/llvm/test/MC/LoongArch/lsx/fsub.s +deleted file mode 100644 +index 30c363631..000000000 +--- a/llvm/test/MC/LoongArch/lsx/fsub.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vfsub.s $vr4, $vr9, $vr12 +-# CHECK-INST: vfsub.s $vr4, $vr9, $vr12 +-# CHECK-ENCODING: encoding: [0x24,0xb1,0x32,0x71] +- +-vfsub.d $vr12, $vr28, $vr27 +-# CHECK-INST: vfsub.d $vr12, $vr28, $vr27 +-# CHECK-ENCODING: encoding: [0x8c,0x6f,0x33,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/ftint.s b/llvm/test/MC/LoongArch/lsx/ftint.s +deleted file mode 100644 +index 9a50fddf8..000000000 +--- a/llvm/test/MC/LoongArch/lsx/ftint.s ++++ /dev/null +@@ -1,120 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vftintrne.w.s $vr25, $vr28 +-# CHECK-INST: vftintrne.w.s $vr25, $vr28 +-# CHECK-ENCODING: encoding: [0x99,0x53,0x9e,0x72] +- +-vftintrne.l.d $vr26, $vr27 +-# CHECK-INST: vftintrne.l.d $vr26, $vr27 +-# CHECK-ENCODING: encoding: [0x7a,0x57,0x9e,0x72] +- +-vftintrz.w.s $vr24, $vr29 +-# CHECK-INST: vftintrz.w.s $vr24, $vr29 +-# CHECK-ENCODING: encoding: [0xb8,0x4b,0x9e,0x72] +- +-vftintrz.l.d $vr17, $vr12 +-# CHECK-INST: vftintrz.l.d $vr17, $vr12 +-# CHECK-ENCODING: encoding: [0x91,0x4d,0x9e,0x72] +- +-vftintrp.w.s $vr1, $vr6 +-# CHECK-INST: vftintrp.w.s $vr1, $vr6 +-# CHECK-ENCODING: encoding: [0xc1,0x40,0x9e,0x72] +- +-vftintrp.l.d $vr8, $vr26 +-# CHECK-INST: vftintrp.l.d $vr8, $vr26 +-# CHECK-ENCODING: encoding: [0x48,0x47,0x9e,0x72] +- +-vftintrm.w.s $vr4, $vr30 +-# CHECK-INST: vftintrm.w.s $vr4, $vr30 +-# CHECK-ENCODING: encoding: [0xc4,0x3b,0x9e,0x72] +- +-vftintrm.l.d $vr18, $vr0 +-# CHECK-INST: vftintrm.l.d $vr18, $vr0 +-# CHECK-ENCODING: encoding: [0x12,0x3c,0x9e,0x72] +- +-vftint.w.s $vr0, $vr27 +-# CHECK-INST: vftint.w.s $vr0, $vr27 +-# CHECK-ENCODING: encoding: [0x60,0x33,0x9e,0x72] +- +-vftint.l.d $vr21, $vr22 +-# CHECK-INST: vftint.l.d $vr21, $vr22 +-# CHECK-ENCODING: encoding: [0xd5,0x36,0x9e,0x72] +- +-vftintrz.wu.s $vr8, $vr3 +-# CHECK-INST: vftintrz.wu.s $vr8, $vr3 +-# CHECK-ENCODING: encoding: [0x68,0x70,0x9e,0x72] +- +-vftintrz.lu.d $vr25, $vr9 +-# CHECK-INST: vftintrz.lu.d $vr25, $vr9 +-# CHECK-ENCODING: encoding: [0x39,0x75,0x9e,0x72] +- +-vftint.wu.s $vr8, $vr8 +-# CHECK-INST: vftint.wu.s $vr8, $vr8 +-# CHECK-ENCODING: encoding: [0x08,0x59,0x9e,0x72] +- +-vftint.lu.d $vr1, $vr17 +-# CHECK-INST: vftint.lu.d $vr1, $vr17 +-# CHECK-ENCODING: encoding: [0x21,0x5e,0x9e,0x72] +- +-vftintrne.w.d $vr4, $vr18, $vr18 +-# CHECK-INST: vftintrne.w.d $vr4, $vr18, $vr18 +-# CHECK-ENCODING: encoding: [0x44,0xca,0x4b,0x71] +- +-vftintrz.w.d $vr26, $vr18, $vr4 +-# CHECK-INST: vftintrz.w.d $vr26, $vr18, $vr4 +-# CHECK-ENCODING: encoding: [0x5a,0x12,0x4b,0x71] +- +-vftintrp.w.d $vr25, $vr0, $vr23 +-# CHECK-INST: vftintrp.w.d $vr25, $vr0, $vr23 +-# CHECK-ENCODING: encoding: [0x19,0xdc,0x4a,0x71] +- +-vftintrm.w.d $vr30, $vr25, $vr5 +-# CHECK-INST: vftintrm.w.d $vr30, $vr25, $vr5 +-# CHECK-ENCODING: encoding: [0x3e,0x17,0x4a,0x71] +- +-vftint.w.d $vr27, $vr28, $vr6 +-# CHECK-INST: vftint.w.d $vr27, $vr28, $vr6 +-# CHECK-ENCODING: encoding: [0x9b,0x9b,0x49,0x71] +- +-vftintrnel.l.s $vr7, $vr8 +-# CHECK-INST: vftintrnel.l.s $vr7, $vr8 +-# CHECK-ENCODING: encoding: [0x07,0xa1,0x9e,0x72] +- +-vftintrneh.l.s $vr21, $vr26 +-# CHECK-INST: vftintrneh.l.s $vr21, $vr26 +-# CHECK-ENCODING: encoding: [0x55,0xa7,0x9e,0x72] +- +-vftintrzl.l.s $vr21, $vr18 +-# CHECK-INST: vftintrzl.l.s $vr21, $vr18 +-# CHECK-ENCODING: encoding: [0x55,0x9a,0x9e,0x72] +- +-vftintrzh.l.s $vr22, $vr16 +-# CHECK-INST: vftintrzh.l.s $vr22, $vr16 +-# CHECK-ENCODING: encoding: [0x16,0x9e,0x9e,0x72] +- +-vftintrpl.l.s $vr25, $vr19 +-# CHECK-INST: vftintrpl.l.s $vr25, $vr19 +-# CHECK-ENCODING: encoding: [0x79,0x92,0x9e,0x72] +- +-vftintrph.l.s $vr11, $vr22 +-# CHECK-INST: vftintrph.l.s $vr11, $vr22 +-# CHECK-ENCODING: encoding: [0xcb,0x96,0x9e,0x72] +- +-vftintrml.l.s $vr6, $vr28 +-# CHECK-INST: vftintrml.l.s $vr6, $vr28 +-# CHECK-ENCODING: encoding: [0x86,0x8b,0x9e,0x72] +- +-vftintrmh.l.s $vr17, $vr11 +-# CHECK-INST: vftintrmh.l.s $vr17, $vr11 +-# CHECK-ENCODING: encoding: [0x71,0x8d,0x9e,0x72] +- +-vftintl.l.s $vr3, $vr28 +-# CHECK-INST: vftintl.l.s $vr3, $vr28 +-# CHECK-ENCODING: encoding: [0x83,0x83,0x9e,0x72] +- +-vftinth.l.s $vr11, $vr30 +-# CHECK-INST: vftinth.l.s $vr11, $vr30 +-# CHECK-ENCODING: encoding: [0xcb,0x87,0x9e,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/haddw.s b/llvm/test/MC/LoongArch/lsx/haddw.s +deleted file mode 100644 +index 1958941fa..000000000 +--- a/llvm/test/MC/LoongArch/lsx/haddw.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vhaddw.h.b $vr3, $vr14, $vr11 +-# CHECK-INST: vhaddw.h.b $vr3, $vr14, $vr11 +-# CHECK-ENCODING: encoding: [0xc3,0x2d,0x54,0x70] +- +-vhaddw.w.h $vr3, $vr9, $vr9 +-# CHECK-INST: vhaddw.w.h $vr3, $vr9, $vr9 +-# CHECK-ENCODING: encoding: [0x23,0xa5,0x54,0x70] +- +-vhaddw.d.w $vr7, $vr26, $vr6 +-# CHECK-INST: vhaddw.d.w $vr7, $vr26, $vr6 +-# CHECK-ENCODING: encoding: [0x47,0x1b,0x55,0x70] +- +-vhaddw.q.d $vr22, $vr25, $vr19 +-# CHECK-INST: vhaddw.q.d $vr22, $vr25, $vr19 +-# CHECK-ENCODING: encoding: [0x36,0xcf,0x55,0x70] +- +-vhaddw.hu.bu $vr8, $vr21, $vr21 +-# CHECK-INST: vhaddw.hu.bu $vr8, $vr21, $vr21 +-# CHECK-ENCODING: encoding: [0xa8,0x56,0x58,0x70] +- +-vhaddw.wu.hu $vr23, $vr23, $vr20 +-# CHECK-INST: vhaddw.wu.hu $vr23, $vr23, $vr20 +-# CHECK-ENCODING: encoding: [0xf7,0xd2,0x58,0x70] +- +-vhaddw.du.wu $vr13, $vr7, $vr6 +-# CHECK-INST: vhaddw.du.wu $vr13, $vr7, $vr6 +-# CHECK-ENCODING: encoding: [0xed,0x18,0x59,0x70] +- +-vhaddw.qu.du $vr19, $vr12, $vr6 +-# CHECK-INST: vhaddw.qu.du $vr19, $vr12, $vr6 +-# CHECK-ENCODING: encoding: [0x93,0x99,0x59,0x70] +diff --git a/llvm/test/MC/LoongArch/lsx/hsubw.s b/llvm/test/MC/LoongArch/lsx/hsubw.s +deleted file mode 100644 +index 933f5840b..000000000 +--- a/llvm/test/MC/LoongArch/lsx/hsubw.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vhsubw.h.b $vr24, $vr26, $vr16 +-# CHECK-INST: vhsubw.h.b $vr24, $vr26, $vr16 +-# CHECK-ENCODING: encoding: [0x58,0x43,0x56,0x70] +- +-vhsubw.w.h $vr5, $vr28, $vr12 +-# CHECK-INST: vhsubw.w.h $vr5, $vr28, $vr12 +-# CHECK-ENCODING: encoding: [0x85,0xb3,0x56,0x70] +- +-vhsubw.d.w $vr8, $vr5, $vr22 +-# CHECK-INST: vhsubw.d.w $vr8, $vr5, $vr22 +-# CHECK-ENCODING: encoding: [0xa8,0x58,0x57,0x70] +- +-vhsubw.q.d $vr21, $vr16, $vr14 +-# CHECK-INST: vhsubw.q.d $vr21, $vr16, $vr14 +-# CHECK-ENCODING: encoding: [0x15,0xba,0x57,0x70] +- +-vhsubw.hu.bu $vr12, $vr31, $vr30 +-# CHECK-INST: vhsubw.hu.bu $vr12, $vr31, $vr30 +-# CHECK-ENCODING: encoding: [0xec,0x7b,0x5a,0x70] +- +-vhsubw.wu.hu $vr18, $vr13, $vr31 +-# CHECK-INST: vhsubw.wu.hu $vr18, $vr13, $vr31 +-# CHECK-ENCODING: encoding: [0xb2,0xfd,0x5a,0x70] +- +-vhsubw.du.wu $vr0, $vr1, $vr2 +-# CHECK-INST: vhsubw.du.wu $vr0, $vr1, $vr2 +-# CHECK-ENCODING: encoding: [0x20,0x08,0x5b,0x70] +- +-vhsubw.qu.du $vr30, $vr31, $vr5 +-# CHECK-INST: vhsubw.qu.du $vr30, $vr31, $vr5 +-# CHECK-ENCODING: encoding: [0xfe,0x97,0x5b,0x70] +diff --git a/llvm/test/MC/LoongArch/lsx/ilv.s b/llvm/test/MC/LoongArch/lsx/ilv.s +deleted file mode 100644 +index 8775e1ce1..000000000 +--- a/llvm/test/MC/LoongArch/lsx/ilv.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vilvl.b $vr9, $vr30, $vr20 +-# CHECK-INST: vilvl.b $vr9, $vr30, $vr20 +-# CHECK-ENCODING: encoding: [0xc9,0x53,0x1a,0x71] +- +-vilvl.h $vr6, $vr19, $vr30 +-# CHECK-INST: vilvl.h $vr6, $vr19, $vr30 +-# CHECK-ENCODING: encoding: [0x66,0xfa,0x1a,0x71] +- +-vilvl.w $vr18, $vr3, $vr15 +-# CHECK-INST: vilvl.w $vr18, $vr3, $vr15 +-# CHECK-ENCODING: encoding: [0x72,0x3c,0x1b,0x71] +- +-vilvl.d $vr20, $vr22, $vr9 +-# CHECK-INST: vilvl.d $vr20, $vr22, $vr9 +-# CHECK-ENCODING: encoding: [0xd4,0xa6,0x1b,0x71] +- +-vilvh.b $vr14, $vr4, $vr12 +-# CHECK-INST: vilvh.b $vr14, $vr4, $vr12 +-# CHECK-ENCODING: encoding: [0x8e,0x30,0x1c,0x71] +- +-vilvh.h $vr2, $vr0, $vr6 +-# CHECK-INST: vilvh.h $vr2, $vr0, $vr6 +-# CHECK-ENCODING: encoding: [0x02,0x98,0x1c,0x71] +- +-vilvh.w $vr7, $vr27, $vr15 +-# CHECK-INST: vilvh.w $vr7, $vr27, $vr15 +-# CHECK-ENCODING: encoding: [0x67,0x3f,0x1d,0x71] +- +-vilvh.d $vr9, $vr25, $vr29 +-# CHECK-INST: vilvh.d $vr9, $vr25, $vr29 +-# CHECK-ENCODING: encoding: [0x29,0xf7,0x1d,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/insgr2vr.s b/llvm/test/MC/LoongArch/lsx/insgr2vr.s +deleted file mode 100644 +index b8b8fe7fb..000000000 +--- a/llvm/test/MC/LoongArch/lsx/insgr2vr.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vinsgr2vr.b $vr23, $r20, 2 +-# CHECK-INST: vinsgr2vr.b $vr23, $t8, 2 +-# CHECK-ENCODING: encoding: [0x97,0x8a,0xeb,0x72] +- +-vinsgr2vr.h $vr7, $r5, 7 +-# CHECK-INST: vinsgr2vr.h $vr7, $a1, 7 +-# CHECK-ENCODING: encoding: [0xa7,0xdc,0xeb,0x72] +- +-vinsgr2vr.w $vr8, $r6, 2 +-# CHECK-INST: vinsgr2vr.w $vr8, $a2, 2 +-# CHECK-ENCODING: encoding: [0xc8,0xe8,0xeb,0x72] +- +-vinsgr2vr.d $vr17, $r24, 1 +-# CHECK-INST: vinsgr2vr.d $vr17, $s1, 1 +-# CHECK-ENCODING: encoding: [0x11,0xf7,0xeb,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/invalid-imm.s b/llvm/test/MC/LoongArch/lsx/invalid-imm.s +deleted file mode 100644 +index c3f9aaa08..000000000 +--- a/llvm/test/MC/LoongArch/lsx/invalid-imm.s ++++ /dev/null +@@ -1,1192 +0,0 @@ +-## Test out of range immediates which are used by lsx instructions. +- +-# RUN: not llvm-mc --triple=loongarch64 %s 2>&1 | FileCheck %s +- +-## uimm1 +-vstelm.d $vr0, $a0, 8, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 1] +- +-vstelm.d $vr0, $a0, 8, 2 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 1] +- +-vreplvei.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 1] +- +-vreplvei.d $vr0, $vr1, 2 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 1] +- +-vpickve2gr.du $a0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 1] +- +-vpickve2gr.du $a0, $vr1, 2 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 1] +- +-vpickve2gr.d $a0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 1] +- +-vpickve2gr.d $a0, $vr1, 2 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 1] +- +-vinsgr2vr.d $vr0, $a0, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 1] +- +-vinsgr2vr.d $vr0, $a0, 2 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 1] +- +-## uimm2 +-vstelm.w $vr0, $a0, 4, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 3] +- +-vstelm.w $vr0, $a0, 4, 4 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 3] +- +-vreplvei.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 3] +- +-vreplvei.w $vr0, $vr1, 4 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 3] +- +-vpickve2gr.wu $a0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 3] +- +-vpickve2gr.wu $a0, $vr1, 4 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 3] +- +-vpickve2gr.w $a0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 3] +- +-vpickve2gr.w $a0, $vr1, 4 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 3] +- +-vinsgr2vr.w $vr0, $a0, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 3] +- +-vinsgr2vr.w $vr0, $a0, 4 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 3] +- +-## uimm3 +-vstelm.h $vr0, $a0, 2, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 7] +- +-vstelm.h $vr0, $a0, 2, 8 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 7] +- +-vreplvei.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 7] +- +-vreplvei.h $vr0, $vr1, 8 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 7] +- +-vpickve2gr.hu $a0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 7] +- +-vpickve2gr.hu $a0, $vr1, 8 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 7] +- +-vpickve2gr.h $a0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 7] +- +-vpickve2gr.h $a0, $vr1, 8 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 7] +- +-vinsgr2vr.h $vr0, $a0, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 7] +- +-vinsgr2vr.h $vr0, $a0, 8 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 7] +- +-vbitrevi.b $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 7] +- +-vbitrevi.b $vr0, $vr1, 8 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 7] +- +-vbitseti.b $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 7] +- +-vbitseti.b $vr0, $vr1, 8 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 7] +- +-vbitclri.b $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 7] +- +-vbitclri.b $vr0, $vr1, 8 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 7] +- +-vsrari.b $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 7] +- +-vsrari.b $vr0, $vr1, 8 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 7] +- +-vsrlri.b $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 7] +- +-vsrlri.b $vr0, $vr1, 8 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 7] +- +-vsllwil.hu.bu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 7] +- +-vsllwil.hu.bu $vr0, $vr1, 8 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 7] +- +-vsllwil.h.b $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 7] +- +-vsllwil.h.b $vr0, $vr1, 8 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 7] +- +-vrotri.b $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 7] +- +-vrotri.b $vr0, $vr1, 8 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 7] +- +-vsrai.b $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 7] +- +-vsrai.b $vr0, $vr1, 8 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 7] +- +-vsrli.b $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 7] +- +-vsrli.b $vr0, $vr1, 8 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 7] +- +-vslli.b $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 7] +- +-vslli.b $vr0, $vr1, 8 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 7] +- +-vsat.b $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:20: error: immediate must be an integer in the range [0, 7] +- +-vsat.b $vr0, $vr1, 8 +-# CHECK: :[[#@LINE-1]]:20: error: immediate must be an integer in the range [0, 7] +- +-vsat.bu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 7] +- +-vsat.bu $vr0, $vr1, 8 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 7] +- +-## uimm4 +-vstelm.b $vr0, $a0, 1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 15] +- +-vstelm.b $vr0, $a0, 1, 16 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 15] +- +-vreplvei.b $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 15] +- +-vreplvei.b $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 15] +- +-vpickve2gr.bu $a0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 15] +- +-vpickve2gr.bu $a0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 15] +- +-vpickve2gr.b $a0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-vpickve2gr.b $a0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-vinsgr2vr.b $vr0, $a0, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 15] +- +-vinsgr2vr.b $vr0, $a0, 16 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 15] +- +-vbitrevi.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 15] +- +-vbitrevi.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 15] +- +-vbitseti.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 15] +- +-vbitseti.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 15] +- +-vbitclri.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 15] +- +-vbitclri.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 15] +- +-vssrarni.bu.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 15] +- +-vssrarni.bu.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 15] +- +-vssrlrni.bu.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 15] +- +-vssrlrni.bu.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 15] +- +-vssrarni.b.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 15] +- +-vssrarni.b.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 15] +- +-vssrlrni.b.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 15] +- +-vssrlrni.b.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 15] +- +-vssrani.bu.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 15] +- +-vssrani.bu.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 15] +- +-vssrlni.bu.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 15] +- +-vssrlni.bu.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 15] +- +-vssrani.b.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-vssrani.b.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-vssrlni.b.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-vssrlni.b.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-vsrarni.b.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-vsrarni.b.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-vsrlrni.b.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-vsrlrni.b.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-vsrani.b.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 15] +- +-vsrani.b.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 15] +- +-vsrlni.b.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 15] +- +-vsrlni.b.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 15] +- +-vsrari.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 15] +- +-vsrari.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 15] +- +-vsrlri.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 15] +- +-vsrlri.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 15] +- +-vsllwil.wu.hu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 15] +- +-vsllwil.wu.hu $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 15] +- +-vsllwil.w.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-vsllwil.w.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 15] +- +-vrotri.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 15] +- +-vrotri.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 15] +- +-vsrai.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 15] +- +-vsrai.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 15] +- +-vsrli.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 15] +- +-vsrli.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 15] +- +-vslli.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 15] +- +-vslli.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 15] +- +-vsat.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:20: error: immediate must be an integer in the range [0, 15] +- +-vsat.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:20: error: immediate must be an integer in the range [0, 15] +- +-vsat.hu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 15] +- +-vsat.hu $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 15] +- +-## uimm5 +-vbsrl.v $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 31] +- +-vbsrl.v $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 31] +- +-vbsll.v $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 31] +- +-vbsll.v $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 31] +- +-vslti.du $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vslti.du $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vslti.wu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vslti.wu $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vslti.hu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vslti.hu $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vslti.bu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vslti.bu $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vslei.du $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vslei.du $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vslei.wu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vslei.wu $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vslei.hu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vslei.hu $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vslei.bu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vslei.bu $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vfrstpi.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-vfrstpi.h $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-vfrstpi.b $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-vfrstpi.b $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 31] +- +-vbitrevi.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 31] +- +-vbitrevi.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 31] +- +-vbitseti.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 31] +- +-vbitseti.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 31] +- +-vbitclri.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 31] +- +-vbitclri.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 31] +- +-vssrarni.hu.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 31] +- +-vssrarni.hu.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 31] +- +-vssrlrni.hu.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 31] +- +-vssrlrni.hu.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 31] +- +-vssrarni.h.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 31] +- +-vssrarni.h.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 31] +- +-vssrlrni.h.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 31] +- +-vssrlrni.h.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 31] +- +-vssrani.hu.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 31] +- +-vssrani.hu.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 31] +- +-vssrlni.hu.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 31] +- +-vssrlni.hu.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 31] +- +-vssrani.h.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +- +-vssrani.h.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +- +-vssrlni.h.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +- +-vssrlni.h.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +- +-vsrarni.h.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +- +-vsrarni.h.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +- +-vsrlrni.h.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +- +-vsrlrni.h.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +- +-vsrani.h.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 31] +- +-vsrani.h.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 31] +- +-vsrlni.h.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 31] +- +-vsrlni.h.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 31] +- +-vsrari.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vsrari.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vsrlri.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vsrlri.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vsllwil.du.wu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 31] +- +-vsllwil.du.wu $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 31] +- +-vsllwil.d.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +- +-vsllwil.d.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 31] +- +-vrotri.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vrotri.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vsrai.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 31] +- +-vsrai.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 31] +- +-vsrli.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 31] +- +-vsrli.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 31] +- +-vslli.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 31] +- +-vslli.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 31] +- +-vaddi.bu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vaddi.bu $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vaddi.hu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vaddi.hu $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vaddi.wu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vaddi.wu $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vaddi.du $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vaddi.du $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vsubi.bu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vsubi.bu $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vsubi.hu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vsubi.hu $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vsubi.wu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vsubi.wu $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vsubi.du $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vsubi.du $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vmaxi.bu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vmaxi.bu $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vmaxi.hu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vmaxi.hu $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vmaxi.wu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vmaxi.wu $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vmaxi.du $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vmaxi.du $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vmini.bu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vmini.bu $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vmini.hu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vmini.hu $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vmini.wu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vmini.wu $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vmini.du $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vmini.du $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 31] +- +-vsat.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:20: error: immediate must be an integer in the range [0, 31] +- +-vsat.w $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:20: error: immediate must be an integer in the range [0, 31] +- +-vsat.wu $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 31] +- +-vsat.wu $vr0, $vr1, 32 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 31] +- +-## simm5 +-vslti.d $vr0, $vr1, -17 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vslti.d $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vslti.w $vr0, $vr1, -17 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vslti.w $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vslti.h $vr0, $vr1, -17 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vslti.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vslti.b $vr0, $vr1, -17 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vslti.b $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vslei.d $vr0, $vr1, -17 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vslei.d $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vslei.w $vr0, $vr1, -17 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vslei.w $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vslei.h $vr0, $vr1, -17 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vslei.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vslei.b $vr0, $vr1, -17 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vslei.b $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vseqi.d $vr0, $vr1, -17 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vseqi.d $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vseqi.w $vr0, $vr1, -17 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vseqi.w $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vseqi.h $vr0, $vr1, -17 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vseqi.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vseqi.b $vr0, $vr1, -17 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vseqi.b $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vmaxi.b $vr0, $vr1, -17 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vmaxi.b $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vmaxi.h $vr0, $vr1, -17 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vmaxi.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vmaxi.w $vr0, $vr1, -17 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vmaxi.w $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vmaxi.d $vr0, $vr1, -17 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vmaxi.d $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vmini.b $vr0, $vr1, -17 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vmini.b $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vmini.h $vr0, $vr1, -17 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vmini.h $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vmini.w $vr0, $vr1, -17 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vmini.w $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vmini.d $vr0, $vr1, -17 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-vmini.d $vr0, $vr1, 16 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-16, 15] +- +-## uimm6 +-vbitrevi.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 63] +- +-vbitrevi.d $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 63] +- +-vbitseti.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 63] +- +-vbitseti.d $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 63] +- +-vbitclri.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 63] +- +-vbitclri.d $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 63] +- +-vssrarni.wu.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 63] +- +-vssrarni.wu.d $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 63] +- +-vssrlrni.wu.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 63] +- +-vssrlrni.wu.d $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 63] +- +-vssrarni.w.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 63] +- +-vssrarni.w.d $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 63] +- +-vssrlrni.w.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 63] +- +-vssrlrni.w.d $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 63] +- +-vssrani.wu.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 63] +- +-vssrani.wu.d $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 63] +- +-vssrlni.wu.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 63] +- +-vssrlni.wu.d $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 63] +- +-vssrani.w.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 63] +- +-vssrani.w.d $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 63] +- +-vssrlni.w.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 63] +- +-vssrlni.w.d $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 63] +- +-vsrarni.w.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 63] +- +-vsrarni.w.d $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 63] +- +-vsrlrni.w.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 63] +- +-vsrlrni.w.d $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 63] +- +-vsrani.w.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 63] +- +-vsrani.w.d $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 63] +- +-vsrlni.w.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 63] +- +-vsrlni.w.d $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 63] +- +-vsrari.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 63] +- +-vsrari.d $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 63] +- +-vsrlri.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 63] +- +-vsrlri.d $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 63] +- +-vrotri.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 63] +- +-vrotri.d $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 63] +- +-vsrai.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 63] +- +-vsrai.d $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 63] +- +-vsrli.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 63] +- +-vsrli.d $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 63] +- +-vslli.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 63] +- +-vslli.d $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 63] +- +-vsat.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:20: error: immediate must be an integer in the range [0, 63] +- +-vsat.d $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:20: error: immediate must be an integer in the range [0, 63] +- +-vsat.du $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 63] +- +-vsat.du $vr0, $vr1, 64 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 63] +- +-## uimm7 +-vssrarni.du.q $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 127] +- +-vssrarni.du.q $vr0, $vr1, 128 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 127] +- +-vssrlrni.du.q $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 127] +- +-vssrlrni.du.q $vr0, $vr1, 128 +-# CHECK: :[[#@LINE-1]]:27: error: immediate must be an integer in the range [0, 127] +- +-vssrarni.d.q $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 127] +- +-vssrarni.d.q $vr0, $vr1, 128 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 127] +- +-vssrlrni.d.q $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 127] +- +-vssrlrni.d.q $vr0, $vr1, 128 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 127] +- +-vssrani.du.q $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 127] +- +-vssrani.du.q $vr0, $vr1, 128 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 127] +- +-vssrlni.du.q $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 127] +- +-vssrlni.du.q $vr0, $vr1, 128 +-# CHECK: :[[#@LINE-1]]:26: error: immediate must be an integer in the range [0, 127] +- +-vssrani.d.q $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 127] +- +-vssrani.d.q $vr0, $vr1, 128 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 127] +- +-vssrlni.d.q $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 127] +- +-vssrlni.d.q $vr0, $vr1, 128 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 127] +- +-vsrarni.d.q $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 127] +- +-vsrarni.d.q $vr0, $vr1, 128 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 127] +- +-vsrlrni.d.q $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 127] +- +-vsrlrni.d.q $vr0, $vr1, 128 +-# CHECK: :[[#@LINE-1]]:25: error: immediate must be an integer in the range [0, 127] +- +-vsrani.d.q $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 127] +- +-vsrani.d.q $vr0, $vr1, 128 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 127] +- +-vsrlni.d.q $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 127] +- +-vsrlni.d.q $vr0, $vr1, 128 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 127] +- +-## uimm8 +-vextrins.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 255] +- +-vextrins.d $vr0, $vr1, 256 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 255] +- +-vextrins.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 255] +- +-vextrins.w $vr0, $vr1, 256 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 255] +- +-vextrins.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 255] +- +-vextrins.h $vr0, $vr1, 256 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 255] +- +-vextrins.b $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 255] +- +-vextrins.b $vr0, $vr1, 256 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 255] +- +-vpermi.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 255] +- +-vpermi.w $vr0, $vr1, 256 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [0, 255] +- +-vshuf4i.d $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 255] +- +-vshuf4i.d $vr0, $vr1, 256 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 255] +- +-vshuf4i.w $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 255] +- +-vshuf4i.w $vr0, $vr1, 256 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 255] +- +-vshuf4i.h $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 255] +- +-vshuf4i.h $vr0, $vr1, 256 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 255] +- +-vshuf4i.b $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 255] +- +-vshuf4i.b $vr0, $vr1, 256 +-# CHECK: :[[#@LINE-1]]:23: error: immediate must be an integer in the range [0, 255] +- +-vbitseli.b $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 255] +- +-vbitseli.b $vr0, $vr1, 256 +-# CHECK: :[[#@LINE-1]]:24: error: immediate must be an integer in the range [0, 255] +- +-vandi.b $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 255] +- +-vandi.b $vr0, $vr1, 256 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 255] +- +-vori.b $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:20: error: immediate must be an integer in the range [0, 255] +- +-vori.b $vr0, $vr1, 256 +-# CHECK: :[[#@LINE-1]]:20: error: immediate must be an integer in the range [0, 255] +- +-vxori.b $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 255] +- +-vxori.b $vr0, $vr1, 256 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 255] +- +-vnori.b $vr0, $vr1, -1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 255] +- +-vnori.b $vr0, $vr1, 256 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [0, 255] +- +-## simm8 +-vstelm.b $vr0, $a0, -129, 1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-128, 127] +- +-vstelm.b $vr0, $a0, 128, 1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be an integer in the range [-128, 127] +- +-## simm8_lsl1 +-vstelm.h $vr0, $a0, -258, 1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be a multiple of 2 in the range [-256, 254] +- +-vstelm.h $vr0, $a0, 256, 1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be a multiple of 2 in the range [-256, 254] +- +-## simm8_lsl2 +-vstelm.w $vr0, $a0, -516, 1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be a multiple of 4 in the range [-512, 508] +- +-vstelm.w $vr0, $a0, 512, 1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be a multiple of 4 in the range [-512, 508] +- +-## simm8_lsl3 +-vstelm.d $vr0, $a0, -1032, 1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be a multiple of 8 in the range [-1024, 1016] +- +-vstelm.d $vr0, $a0, 1024, 1 +-# CHECK: :[[#@LINE-1]]:21: error: immediate must be a multiple of 8 in the range [-1024, 1016] +- +-## simm9_lsl3 +-vldrepl.d $vr0, $a0, -2056 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be a multiple of 8 in the range [-2048, 2040] +- +-vldrepl.d $vr0, $a0, 2048 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be a multiple of 8 in the range [-2048, 2040] +- +-## simm10_lsl2 +-vldrepl.w $vr0, $a0, -2052 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be a multiple of 4 in the range [-2048, 2044] +- +-vldrepl.w $vr0, $a0, 2048 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be a multiple of 4 in the range [-2048, 2044] +- +-## simm10 +-vrepli.b $vr0, -513 +-# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-512, 511] +- +-vrepli.b $vr0, 512 +-# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-512, 511] +- +-vrepli.h $vr0, -513 +-# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-512, 511] +- +-vrepli.h $vr0, 512 +-# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-512, 511] +- +-vrepli.w $vr0, -513 +-# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-512, 511] +- +-vrepli.w $vr0, 512 +-# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-512, 511] +- +-vrepli.d $vr0, -513 +-# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-512, 511] +- +-vrepli.d $vr0, 512 +-# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-512, 511] +- +-## simm11_lsl1 +-vldrepl.h $vr0, $a0, -2050 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be a multiple of 2 in the range [-2048, 2046] +- +-vldrepl.h $vr0, $a0, 2048 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be a multiple of 2 in the range [-2048, 2046] +- +-## simm12 +-vldrepl.b $vr0, $a0, -2049 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-2048, 2047] +- +-vldrepl.b $vr0, $a0, 2048 +-# CHECK: :[[#@LINE-1]]:22: error: immediate must be an integer in the range [-2048, 2047] +- +-vst $vr0, $a0, -2049 +-# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-2048, 2047] +- +-vst $vr0, $a0, 2048 +-# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-2048, 2047] +- +-vld $vr0, $a0, -2049 +-# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-2048, 2047] +- +-vld $vr0, $a0, 2048 +-# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-2048, 2047] +- +-## simm13 +-vldi $vr0, -4097 +-# CHECK: :[[#@LINE-1]]:12: error: immediate must be an integer in the range [-4096, 4095] +- +-vldi $vr0, 4096 +-# CHECK: :[[#@LINE-1]]:12: error: immediate must be an integer in the range [-4096, 4095] +diff --git a/llvm/test/MC/LoongArch/lsx/ld.s b/llvm/test/MC/LoongArch/lsx/ld.s +deleted file mode 100644 +index 642c842eb..000000000 +--- a/llvm/test/MC/LoongArch/lsx/ld.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vld $vr0, $r12, -536 +-# CHECK-INST: vld $vr0, $t0, -536 +-# CHECK-ENCODING: encoding: [0x80,0xa1,0x37,0x2c] +- +-vldx $vr21, $r14, $r20 +-# CHECK-INST: vldx $vr21, $t2, $t8 +-# CHECK-ENCODING: encoding: [0xd5,0x51,0x40,0x38] +diff --git a/llvm/test/MC/LoongArch/lsx/ldi.s b/llvm/test/MC/LoongArch/lsx/ldi.s +deleted file mode 100644 +index 59a1c2b27..000000000 +--- a/llvm/test/MC/LoongArch/lsx/ldi.s ++++ /dev/null +@@ -1,29 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-OBJ +- +-vldi $vr26, -3212 +-# CHECK-INST: vldi $vr26, -3212 +-# CHECK-ENCODING: encoding: [0x9a,0x6e,0xe2,0x73] +-# CHECK-OBJ: vldi $vr26, -3212 +- +-vrepli.b $vr26, -512 +-# CHECK-INST: vrepli.b $vr26, -512 +-# CHECK-ENCODING: encoding: [0x1a,0x40,0xe0,0x73] +-# CHECK-OBJ: vldi $vr26, 512 +- +-vrepli.h $vr26, -512 +-# CHECK-INST: vrepli.h $vr26, -512 +-# CHECK-ENCODING: encoding: [0x1a,0xc0,0xe0,0x73] +-# CHECK-OBJ: vldi $vr26, 1536 +- +-vrepli.w $vr26, -512 +-# CHECK-INST: vrepli.w $vr26, -512 +-# CHECK-ENCODING: encoding: [0x1a,0x40,0xe1,0x73] +-# CHECK-OBJ: vldi $vr26, 2560 +- +-vrepli.d $vr26, -512 +-# CHECK-INST: vrepli.d $vr26, -512 +-# CHECK-ENCODING: encoding: [0x1a,0xc0,0xe1,0x73] +-# CHECK-OBJ: vldi $vr26, 3584 +diff --git a/llvm/test/MC/LoongArch/lsx/ldrepl.s b/llvm/test/MC/LoongArch/lsx/ldrepl.s +deleted file mode 100644 +index 75830ae20..000000000 +--- a/llvm/test/MC/LoongArch/lsx/ldrepl.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vldrepl.b $vr3, $r3, -1553 +-# CHECK-INST: vldrepl.b $vr3, $sp, -1553 +-# CHECK-ENCODING: encoding: [0x63,0xbc,0xa7,0x30] +- +-vldrepl.h $vr23, $r22, 172 +-# CHECK-INST: vldrepl.h $vr23, $fp, 172 +-# CHECK-ENCODING: encoding: [0xd7,0x5a,0x41,0x30] +- +-vldrepl.w $vr12, $r27, -1304 +-# CHECK-INST: vldrepl.w $vr12, $s4, -1304 +-# CHECK-ENCODING: encoding: [0x6c,0xeb,0x2a,0x30] +- +-vldrepl.d $vr7, $r31, -1376 +-# CHECK-INST: vldrepl.d $vr7, $s8, -1376 +-# CHECK-ENCODING: encoding: [0xe7,0x53,0x15,0x30] +diff --git a/llvm/test/MC/LoongArch/lsx/madd.s b/llvm/test/MC/LoongArch/lsx/madd.s +deleted file mode 100644 +index 9ae6500c2..000000000 +--- a/llvm/test/MC/LoongArch/lsx/madd.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vmadd.b $vr13, $vr5, $vr10 +-# CHECK-INST: vmadd.b $vr13, $vr5, $vr10 +-# CHECK-ENCODING: encoding: [0xad,0x28,0xa8,0x70] +- +-vmadd.h $vr11, $vr15, $vr8 +-# CHECK-INST: vmadd.h $vr11, $vr15, $vr8 +-# CHECK-ENCODING: encoding: [0xeb,0xa1,0xa8,0x70] +- +-vmadd.w $vr5, $vr17, $vr16 +-# CHECK-INST: vmadd.w $vr5, $vr17, $vr16 +-# CHECK-ENCODING: encoding: [0x25,0x42,0xa9,0x70] +- +-vmadd.d $vr29, $vr11, $vr12 +-# CHECK-INST: vmadd.d $vr29, $vr11, $vr12 +-# CHECK-ENCODING: encoding: [0x7d,0xb1,0xa9,0x70] +diff --git a/llvm/test/MC/LoongArch/lsx/maddw.s b/llvm/test/MC/LoongArch/lsx/maddw.s +deleted file mode 100644 +index f346ea786..000000000 +--- a/llvm/test/MC/LoongArch/lsx/maddw.s ++++ /dev/null +@@ -1,100 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vmaddwev.h.b $vr20, $vr27, $vr19 +-# CHECK-INST: vmaddwev.h.b $vr20, $vr27, $vr19 +-# CHECK-ENCODING: encoding: [0x74,0x4f,0xac,0x70] +- +-vmaddwev.w.h $vr6, $vr21, $vr19 +-# CHECK-INST: vmaddwev.w.h $vr6, $vr21, $vr19 +-# CHECK-ENCODING: encoding: [0xa6,0xce,0xac,0x70] +- +-vmaddwev.d.w $vr9, $vr20, $vr22 +-# CHECK-INST: vmaddwev.d.w $vr9, $vr20, $vr22 +-# CHECK-ENCODING: encoding: [0x89,0x5a,0xad,0x70] +- +-vmaddwev.q.d $vr11, $vr22, $vr5 +-# CHECK-INST: vmaddwev.q.d $vr11, $vr22, $vr5 +-# CHECK-ENCODING: encoding: [0xcb,0x96,0xad,0x70] +- +-vmaddwev.h.bu $vr7, $vr24, $vr12 +-# CHECK-INST: vmaddwev.h.bu $vr7, $vr24, $vr12 +-# CHECK-ENCODING: encoding: [0x07,0x33,0xb4,0x70] +- +-vmaddwev.w.hu $vr14, $vr10, $vr2 +-# CHECK-INST: vmaddwev.w.hu $vr14, $vr10, $vr2 +-# CHECK-ENCODING: encoding: [0x4e,0x89,0xb4,0x70] +- +-vmaddwev.d.wu $vr25, $vr22, $vr30 +-# CHECK-INST: vmaddwev.d.wu $vr25, $vr22, $vr30 +-# CHECK-ENCODING: encoding: [0xd9,0x7a,0xb5,0x70] +- +-vmaddwev.q.du $vr4, $vr5, $vr10 +-# CHECK-INST: vmaddwev.q.du $vr4, $vr5, $vr10 +-# CHECK-ENCODING: encoding: [0xa4,0xa8,0xb5,0x70] +- +-vmaddwev.h.bu.b $vr13, $vr17, $vr6 +-# CHECK-INST: vmaddwev.h.bu.b $vr13, $vr17, $vr6 +-# CHECK-ENCODING: encoding: [0x2d,0x1a,0xbc,0x70] +- +-vmaddwev.w.hu.h $vr1, $vr29, $vr13 +-# CHECK-INST: vmaddwev.w.hu.h $vr1, $vr29, $vr13 +-# CHECK-ENCODING: encoding: [0xa1,0xb7,0xbc,0x70] +- +-vmaddwev.d.wu.w $vr5, $vr13, $vr10 +-# CHECK-INST: vmaddwev.d.wu.w $vr5, $vr13, $vr10 +-# CHECK-ENCODING: encoding: [0xa5,0x29,0xbd,0x70] +- +-vmaddwev.q.du.d $vr16, $vr0, $vr26 +-# CHECK-INST: vmaddwev.q.du.d $vr16, $vr0, $vr26 +-# CHECK-ENCODING: encoding: [0x10,0xe8,0xbd,0x70] +- +-vmaddwod.h.b $vr29, $vr28, $vr11 +-# CHECK-INST: vmaddwod.h.b $vr29, $vr28, $vr11 +-# CHECK-ENCODING: encoding: [0x9d,0x2f,0xae,0x70] +- +-vmaddwod.w.h $vr10, $vr5, $vr29 +-# CHECK-INST: vmaddwod.w.h $vr10, $vr5, $vr29 +-# CHECK-ENCODING: encoding: [0xaa,0xf4,0xae,0x70] +- +-vmaddwod.d.w $vr16, $vr7, $vr26 +-# CHECK-INST: vmaddwod.d.w $vr16, $vr7, $vr26 +-# CHECK-ENCODING: encoding: [0xf0,0x68,0xaf,0x70] +- +-vmaddwod.q.d $vr1, $vr4, $vr7 +-# CHECK-INST: vmaddwod.q.d $vr1, $vr4, $vr7 +-# CHECK-ENCODING: encoding: [0x81,0x9c,0xaf,0x70] +- +-vmaddwod.h.bu $vr9, $vr28, $vr19 +-# CHECK-INST: vmaddwod.h.bu $vr9, $vr28, $vr19 +-# CHECK-ENCODING: encoding: [0x89,0x4f,0xb6,0x70] +- +-vmaddwod.w.hu $vr4, $vr6, $vr19 +-# CHECK-INST: vmaddwod.w.hu $vr4, $vr6, $vr19 +-# CHECK-ENCODING: encoding: [0xc4,0xcc,0xb6,0x70] +- +-vmaddwod.d.wu $vr2, $vr26, $vr26 +-# CHECK-INST: vmaddwod.d.wu $vr2, $vr26, $vr26 +-# CHECK-ENCODING: encoding: [0x42,0x6b,0xb7,0x70] +- +-vmaddwod.q.du $vr9, $vr18, $vr31 +-# CHECK-INST: vmaddwod.q.du $vr9, $vr18, $vr31 +-# CHECK-ENCODING: encoding: [0x49,0xfe,0xb7,0x70] +- +-vmaddwod.h.bu.b $vr22, $vr3, $vr25 +-# CHECK-INST: vmaddwod.h.bu.b $vr22, $vr3, $vr25 +-# CHECK-ENCODING: encoding: [0x76,0x64,0xbe,0x70] +- +-vmaddwod.w.hu.h $vr17, $vr20, $vr22 +-# CHECK-INST: vmaddwod.w.hu.h $vr17, $vr20, $vr22 +-# CHECK-ENCODING: encoding: [0x91,0xda,0xbe,0x70] +- +-vmaddwod.d.wu.w $vr21, $vr14, $vr6 +-# CHECK-INST: vmaddwod.d.wu.w $vr21, $vr14, $vr6 +-# CHECK-ENCODING: encoding: [0xd5,0x19,0xbf,0x70] +- +-vmaddwod.q.du.d $vr8, $vr15, $vr11 +-# CHECK-INST: vmaddwod.q.du.d $vr8, $vr15, $vr11 +-# CHECK-ENCODING: encoding: [0xe8,0xad,0xbf,0x70] +diff --git a/llvm/test/MC/LoongArch/lsx/max.s b/llvm/test/MC/LoongArch/lsx/max.s +deleted file mode 100644 +index 2761f6913..000000000 +--- a/llvm/test/MC/LoongArch/lsx/max.s ++++ /dev/null +@@ -1,68 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vmax.b $vr6, $vr21, $vr16 +-# CHECK-INST: vmax.b $vr6, $vr21, $vr16 +-# CHECK-ENCODING: encoding: [0xa6,0x42,0x70,0x70] +- +-vmax.h $vr9, $vr28, $vr16 +-# CHECK-INST: vmax.h $vr9, $vr28, $vr16 +-# CHECK-ENCODING: encoding: [0x89,0xc3,0x70,0x70] +- +-vmax.w $vr6, $vr0, $vr9 +-# CHECK-INST: vmax.w $vr6, $vr0, $vr9 +-# CHECK-ENCODING: encoding: [0x06,0x24,0x71,0x70] +- +-vmax.d $vr26, $vr3, $vr0 +-# CHECK-INST: vmax.d $vr26, $vr3, $vr0 +-# CHECK-ENCODING: encoding: [0x7a,0x80,0x71,0x70] +- +-vmaxi.b $vr2, $vr21, -8 +-# CHECK-INST: vmaxi.b $vr2, $vr21, -8 +-# CHECK-ENCODING: encoding: [0xa2,0x62,0x90,0x72] +- +-vmaxi.h $vr2, $vr21, -2 +-# CHECK-INST: vmaxi.h $vr2, $vr21, -2 +-# CHECK-ENCODING: encoding: [0xa2,0xfa,0x90,0x72] +- +-vmaxi.w $vr26, $vr21, -9 +-# CHECK-INST: vmaxi.w $vr26, $vr21, -9 +-# CHECK-ENCODING: encoding: [0xba,0x5e,0x91,0x72] +- +-vmaxi.d $vr30, $vr28, -2 +-# CHECK-INST: vmaxi.d $vr30, $vr28, -2 +-# CHECK-ENCODING: encoding: [0x9e,0xfb,0x91,0x72] +- +-vmax.bu $vr8, $vr7, $vr7 +-# CHECK-INST: vmax.bu $vr8, $vr7, $vr7 +-# CHECK-ENCODING: encoding: [0xe8,0x1c,0x74,0x70] +- +-vmax.hu $vr21, $vr10, $vr11 +-# CHECK-INST: vmax.hu $vr21, $vr10, $vr11 +-# CHECK-ENCODING: encoding: [0x55,0xad,0x74,0x70] +- +-vmax.wu $vr24, $vr13, $vr25 +-# CHECK-INST: vmax.wu $vr24, $vr13, $vr25 +-# CHECK-ENCODING: encoding: [0xb8,0x65,0x75,0x70] +- +-vmax.du $vr23, $vr11, $vr14 +-# CHECK-INST: vmax.du $vr23, $vr11, $vr14 +-# CHECK-ENCODING: encoding: [0x77,0xb9,0x75,0x70] +- +-vmaxi.bu $vr2, $vr9, 18 +-# CHECK-INST: vmaxi.bu $vr2, $vr9, 18 +-# CHECK-ENCODING: encoding: [0x22,0x49,0x94,0x72] +- +-vmaxi.hu $vr11, $vr23, 18 +-# CHECK-INST: vmaxi.hu $vr11, $vr23, 18 +-# CHECK-ENCODING: encoding: [0xeb,0xca,0x94,0x72] +- +-vmaxi.wu $vr15, $vr0, 29 +-# CHECK-INST: vmaxi.wu $vr15, $vr0, 29 +-# CHECK-ENCODING: encoding: [0x0f,0x74,0x95,0x72] +- +-vmaxi.du $vr20, $vr1, 14 +-# CHECK-INST: vmaxi.du $vr20, $vr1, 14 +-# CHECK-ENCODING: encoding: [0x34,0xb8,0x95,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/min.s b/llvm/test/MC/LoongArch/lsx/min.s +deleted file mode 100644 +index 7843f95ea..000000000 +--- a/llvm/test/MC/LoongArch/lsx/min.s ++++ /dev/null +@@ -1,68 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vmin.b $vr24, $vr31, $vr5 +-# CHECK-INST: vmin.b $vr24, $vr31, $vr5 +-# CHECK-ENCODING: encoding: [0xf8,0x17,0x72,0x70] +- +-vmin.h $vr8, $vr17, $vr29 +-# CHECK-INST: vmin.h $vr8, $vr17, $vr29 +-# CHECK-ENCODING: encoding: [0x28,0xf6,0x72,0x70] +- +-vmin.w $vr6, $vr31, $vr20 +-# CHECK-INST: vmin.w $vr6, $vr31, $vr20 +-# CHECK-ENCODING: encoding: [0xe6,0x53,0x73,0x70] +- +-vmin.d $vr5, $vr11, $vr14 +-# CHECK-INST: vmin.d $vr5, $vr11, $vr14 +-# CHECK-ENCODING: encoding: [0x65,0xb9,0x73,0x70] +- +-vmini.b $vr8, $vr28, 0 +-# CHECK-INST: vmini.b $vr8, $vr28, 0 +-# CHECK-ENCODING: encoding: [0x88,0x03,0x92,0x72] +- +-vmini.h $vr12, $vr12, 0 +-# CHECK-INST: vmini.h $vr12, $vr12, 0 +-# CHECK-ENCODING: encoding: [0x8c,0x81,0x92,0x72] +- +-vmini.w $vr17, $vr1, 4 +-# CHECK-INST: vmini.w $vr17, $vr1, 4 +-# CHECK-ENCODING: encoding: [0x31,0x10,0x93,0x72] +- +-vmini.d $vr13, $vr2, -14 +-# CHECK-INST: vmini.d $vr13, $vr2, -14 +-# CHECK-ENCODING: encoding: [0x4d,0xc8,0x93,0x72] +- +-vmin.bu $vr30, $vr13, $vr11 +-# CHECK-INST: vmin.bu $vr30, $vr13, $vr11 +-# CHECK-ENCODING: encoding: [0xbe,0x2d,0x76,0x70] +- +-vmin.hu $vr13, $vr10, $vr17 +-# CHECK-INST: vmin.hu $vr13, $vr10, $vr17 +-# CHECK-ENCODING: encoding: [0x4d,0xc5,0x76,0x70] +- +-vmin.wu $vr29, $vr10, $vr27 +-# CHECK-INST: vmin.wu $vr29, $vr10, $vr27 +-# CHECK-ENCODING: encoding: [0x5d,0x6d,0x77,0x70] +- +-vmin.du $vr8, $vr1, $vr16 +-# CHECK-INST: vmin.du $vr8, $vr1, $vr16 +-# CHECK-ENCODING: encoding: [0x28,0xc0,0x77,0x70] +- +-vmini.bu $vr16, $vr22, 4 +-# CHECK-INST: vmini.bu $vr16, $vr22, 4 +-# CHECK-ENCODING: encoding: [0xd0,0x12,0x96,0x72] +- +-vmini.hu $vr1, $vr24, 20 +-# CHECK-INST: vmini.hu $vr1, $vr24, 20 +-# CHECK-ENCODING: encoding: [0x01,0xd3,0x96,0x72] +- +-vmini.wu $vr15, $vr5, 9 +-# CHECK-INST: vmini.wu $vr15, $vr5, 9 +-# CHECK-ENCODING: encoding: [0xaf,0x24,0x97,0x72] +- +-vmini.du $vr31, $vr8, 25 +-# CHECK-INST: vmini.du $vr31, $vr8, 25 +-# CHECK-ENCODING: encoding: [0x1f,0xe5,0x97,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/mod.s b/llvm/test/MC/LoongArch/lsx/mod.s +deleted file mode 100644 +index 1033e8056..000000000 +--- a/llvm/test/MC/LoongArch/lsx/mod.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vmod.b $vr28, $vr30, $vr25 +-# CHECK-INST: vmod.b $vr28, $vr30, $vr25 +-# CHECK-ENCODING: encoding: [0xdc,0x67,0xe2,0x70] +- +-vmod.h $vr18, $vr31, $vr26 +-# CHECK-INST: vmod.h $vr18, $vr31, $vr26 +-# CHECK-ENCODING: encoding: [0xf2,0xeb,0xe2,0x70] +- +-vmod.w $vr16, $vr20, $vr1 +-# CHECK-INST: vmod.w $vr16, $vr20, $vr1 +-# CHECK-ENCODING: encoding: [0x90,0x06,0xe3,0x70] +- +-vmod.d $vr26, $vr27, $vr13 +-# CHECK-INST: vmod.d $vr26, $vr27, $vr13 +-# CHECK-ENCODING: encoding: [0x7a,0xb7,0xe3,0x70] +- +-vmod.bu $vr19, $vr8, $vr11 +-# CHECK-INST: vmod.bu $vr19, $vr8, $vr11 +-# CHECK-ENCODING: encoding: [0x13,0x2d,0xe6,0x70] +- +-vmod.hu $vr14, $vr21, $vr9 +-# CHECK-INST: vmod.hu $vr14, $vr21, $vr9 +-# CHECK-ENCODING: encoding: [0xae,0xa6,0xe6,0x70] +- +-vmod.wu $vr19, $vr0, $vr5 +-# CHECK-INST: vmod.wu $vr19, $vr0, $vr5 +-# CHECK-ENCODING: encoding: [0x13,0x14,0xe7,0x70] +- +-vmod.du $vr12, $vr18, $vr31 +-# CHECK-INST: vmod.du $vr12, $vr18, $vr31 +-# CHECK-ENCODING: encoding: [0x4c,0xfe,0xe7,0x70] +diff --git a/llvm/test/MC/LoongArch/lsx/mskgez.s b/llvm/test/MC/LoongArch/lsx/mskgez.s +deleted file mode 100644 +index 0112d06e8..000000000 +--- a/llvm/test/MC/LoongArch/lsx/mskgez.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vmskgez.b $vr13, $vr0 +-# CHECK-INST: vmskgez.b $vr13, $vr0 +-# CHECK-ENCODING: encoding: [0x0d,0x50,0x9c,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/mskltz.s b/llvm/test/MC/LoongArch/lsx/mskltz.s +deleted file mode 100644 +index 8f68faad1..000000000 +--- a/llvm/test/MC/LoongArch/lsx/mskltz.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vmskltz.b $vr17, $vr20 +-# CHECK-INST: vmskltz.b $vr17, $vr20 +-# CHECK-ENCODING: encoding: [0x91,0x42,0x9c,0x72] +- +-vmskltz.h $vr23, $vr1 +-# CHECK-INST: vmskltz.h $vr23, $vr1 +-# CHECK-ENCODING: encoding: [0x37,0x44,0x9c,0x72] +- +-vmskltz.w $vr3, $vr16 +-# CHECK-INST: vmskltz.w $vr3, $vr16 +-# CHECK-ENCODING: encoding: [0x03,0x4a,0x9c,0x72] +- +-vmskltz.d $vr1, $vr26 +-# CHECK-INST: vmskltz.d $vr1, $vr26 +-# CHECK-ENCODING: encoding: [0x41,0x4f,0x9c,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/msknz.s b/llvm/test/MC/LoongArch/lsx/msknz.s +deleted file mode 100644 +index 3805e8830..000000000 +--- a/llvm/test/MC/LoongArch/lsx/msknz.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vmsknz.b $vr20, $vr21 +-# CHECK-INST: vmsknz.b $vr20, $vr21 +-# CHECK-ENCODING: encoding: [0xb4,0x62,0x9c,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/msub.s b/llvm/test/MC/LoongArch/lsx/msub.s +deleted file mode 100644 +index f3e7e7153..000000000 +--- a/llvm/test/MC/LoongArch/lsx/msub.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vmsub.b $vr19, $vr20, $vr12 +-# CHECK-INST: vmsub.b $vr19, $vr20, $vr12 +-# CHECK-ENCODING: encoding: [0x93,0x32,0xaa,0x70] +- +-vmsub.h $vr1, $vr9, $vr22 +-# CHECK-INST: vmsub.h $vr1, $vr9, $vr22 +-# CHECK-ENCODING: encoding: [0x21,0xd9,0xaa,0x70] +- +-vmsub.w $vr10, $vr2, $vr13 +-# CHECK-INST: vmsub.w $vr10, $vr2, $vr13 +-# CHECK-ENCODING: encoding: [0x4a,0x34,0xab,0x70] +- +-vmsub.d $vr28, $vr31, $vr6 +-# CHECK-INST: vmsub.d $vr28, $vr31, $vr6 +-# CHECK-ENCODING: encoding: [0xfc,0x9b,0xab,0x70] +diff --git a/llvm/test/MC/LoongArch/lsx/muh.s b/llvm/test/MC/LoongArch/lsx/muh.s +deleted file mode 100644 +index b20648040..000000000 +--- a/llvm/test/MC/LoongArch/lsx/muh.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vmuh.b $vr23, $vr18, $vr21 +-# CHECK-INST: vmuh.b $vr23, $vr18, $vr21 +-# CHECK-ENCODING: encoding: [0x57,0x56,0x86,0x70] +- +-vmuh.h $vr25, $vr18, $vr5 +-# CHECK-INST: vmuh.h $vr25, $vr18, $vr5 +-# CHECK-ENCODING: encoding: [0x59,0x96,0x86,0x70] +- +-vmuh.w $vr6, $vr9, $vr14 +-# CHECK-INST: vmuh.w $vr6, $vr9, $vr14 +-# CHECK-ENCODING: encoding: [0x26,0x39,0x87,0x70] +- +-vmuh.d $vr31, $vr21, $vr8 +-# CHECK-INST: vmuh.d $vr31, $vr21, $vr8 +-# CHECK-ENCODING: encoding: [0xbf,0xa2,0x87,0x70] +- +-vmuh.bu $vr11, $vr26, $vr7 +-# CHECK-INST: vmuh.bu $vr11, $vr26, $vr7 +-# CHECK-ENCODING: encoding: [0x4b,0x1f,0x88,0x70] +- +-vmuh.hu $vr27, $vr4, $vr28 +-# CHECK-INST: vmuh.hu $vr27, $vr4, $vr28 +-# CHECK-ENCODING: encoding: [0x9b,0xf0,0x88,0x70] +- +-vmuh.wu $vr28, $vr21, $vr28 +-# CHECK-INST: vmuh.wu $vr28, $vr21, $vr28 +-# CHECK-ENCODING: encoding: [0xbc,0x72,0x89,0x70] +- +-vmuh.du $vr25, $vr3, $vr4 +-# CHECK-INST: vmuh.du $vr25, $vr3, $vr4 +-# CHECK-ENCODING: encoding: [0x79,0x90,0x89,0x70] +diff --git a/llvm/test/MC/LoongArch/lsx/mul.s b/llvm/test/MC/LoongArch/lsx/mul.s +deleted file mode 100644 +index 7ddfc64cc..000000000 +--- a/llvm/test/MC/LoongArch/lsx/mul.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vmul.b $vr25, $vr30, $vr7 +-# CHECK-INST: vmul.b $vr25, $vr30, $vr7 +-# CHECK-ENCODING: encoding: [0xd9,0x1f,0x84,0x70] +- +-vmul.h $vr16, $vr1, $vr26 +-# CHECK-INST: vmul.h $vr16, $vr1, $vr26 +-# CHECK-ENCODING: encoding: [0x30,0xe8,0x84,0x70] +- +-vmul.w $vr24, $vr22, $vr29 +-# CHECK-INST: vmul.w $vr24, $vr22, $vr29 +-# CHECK-ENCODING: encoding: [0xd8,0x76,0x85,0x70] +- +-vmul.d $vr27, $vr16, $vr25 +-# CHECK-INST: vmul.d $vr27, $vr16, $vr25 +-# CHECK-ENCODING: encoding: [0x1b,0xe6,0x85,0x70] +diff --git a/llvm/test/MC/LoongArch/lsx/mulw.s b/llvm/test/MC/LoongArch/lsx/mulw.s +deleted file mode 100644 +index 9228e2e6f..000000000 +--- a/llvm/test/MC/LoongArch/lsx/mulw.s ++++ /dev/null +@@ -1,100 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vmulwev.h.b $vr5, $vr6, $vr0 +-# CHECK-INST: vmulwev.h.b $vr5, $vr6, $vr0 +-# CHECK-ENCODING: encoding: [0xc5,0x00,0x90,0x70] +- +-vmulwev.w.h $vr4, $vr25, $vr2 +-# CHECK-INST: vmulwev.w.h $vr4, $vr25, $vr2 +-# CHECK-ENCODING: encoding: [0x24,0x8b,0x90,0x70] +- +-vmulwev.d.w $vr30, $vr28, $vr27 +-# CHECK-INST: vmulwev.d.w $vr30, $vr28, $vr27 +-# CHECK-ENCODING: encoding: [0x9e,0x6f,0x91,0x70] +- +-vmulwev.q.d $vr2, $vr1, $vr27 +-# CHECK-INST: vmulwev.q.d $vr2, $vr1, $vr27 +-# CHECK-ENCODING: encoding: [0x22,0xec,0x91,0x70] +- +-vmulwev.h.bu $vr10, $vr9, $vr4 +-# CHECK-INST: vmulwev.h.bu $vr10, $vr9, $vr4 +-# CHECK-ENCODING: encoding: [0x2a,0x11,0x98,0x70] +- +-vmulwev.w.hu $vr20, $vr31, $vr28 +-# CHECK-INST: vmulwev.w.hu $vr20, $vr31, $vr28 +-# CHECK-ENCODING: encoding: [0xf4,0xf3,0x98,0x70] +- +-vmulwev.d.wu $vr4, $vr6, $vr21 +-# CHECK-INST: vmulwev.d.wu $vr4, $vr6, $vr21 +-# CHECK-ENCODING: encoding: [0xc4,0x54,0x99,0x70] +- +-vmulwev.q.du $vr15, $vr21, $vr30 +-# CHECK-INST: vmulwev.q.du $vr15, $vr21, $vr30 +-# CHECK-ENCODING: encoding: [0xaf,0xfa,0x99,0x70] +- +-vmulwev.h.bu.b $vr29, $vr24, $vr15 +-# CHECK-INST: vmulwev.h.bu.b $vr29, $vr24, $vr15 +-# CHECK-ENCODING: encoding: [0x1d,0x3f,0xa0,0x70] +- +-vmulwev.w.hu.h $vr2, $vr28, $vr31 +-# CHECK-INST: vmulwev.w.hu.h $vr2, $vr28, $vr31 +-# CHECK-ENCODING: encoding: [0x82,0xff,0xa0,0x70] +- +-vmulwev.d.wu.w $vr12, $vr23, $vr6 +-# CHECK-INST: vmulwev.d.wu.w $vr12, $vr23, $vr6 +-# CHECK-ENCODING: encoding: [0xec,0x1a,0xa1,0x70] +- +-vmulwev.q.du.d $vr17, $vr9, $vr13 +-# CHECK-INST: vmulwev.q.du.d $vr17, $vr9, $vr13 +-# CHECK-ENCODING: encoding: [0x31,0xb5,0xa1,0x70] +- +-vmulwod.h.b $vr17, $vr0, $vr16 +-# CHECK-INST: vmulwod.h.b $vr17, $vr0, $vr16 +-# CHECK-ENCODING: encoding: [0x11,0x40,0x92,0x70] +- +-vmulwod.w.h $vr29, $vr5, $vr20 +-# CHECK-INST: vmulwod.w.h $vr29, $vr5, $vr20 +-# CHECK-ENCODING: encoding: [0xbd,0xd0,0x92,0x70] +- +-vmulwod.d.w $vr7, $vr26, $vr6 +-# CHECK-INST: vmulwod.d.w $vr7, $vr26, $vr6 +-# CHECK-ENCODING: encoding: [0x47,0x1b,0x93,0x70] +- +-vmulwod.q.d $vr13, $vr25, $vr30 +-# CHECK-INST: vmulwod.q.d $vr13, $vr25, $vr30 +-# CHECK-ENCODING: encoding: [0x2d,0xfb,0x93,0x70] +- +-vmulwod.h.bu $vr29, $vr20, $vr10 +-# CHECK-INST: vmulwod.h.bu $vr29, $vr20, $vr10 +-# CHECK-ENCODING: encoding: [0x9d,0x2a,0x9a,0x70] +- +-vmulwod.w.hu $vr31, $vr4, $vr25 +-# CHECK-INST: vmulwod.w.hu $vr31, $vr4, $vr25 +-# CHECK-ENCODING: encoding: [0x9f,0xe4,0x9a,0x70] +- +-vmulwod.d.wu $vr7, $vr26, $vr16 +-# CHECK-INST: vmulwod.d.wu $vr7, $vr26, $vr16 +-# CHECK-ENCODING: encoding: [0x47,0x43,0x9b,0x70] +- +-vmulwod.q.du $vr25, $vr10, $vr4 +-# CHECK-INST: vmulwod.q.du $vr25, $vr10, $vr4 +-# CHECK-ENCODING: encoding: [0x59,0x91,0x9b,0x70] +- +-vmulwod.h.bu.b $vr6, $vr25, $vr11 +-# CHECK-INST: vmulwod.h.bu.b $vr6, $vr25, $vr11 +-# CHECK-ENCODING: encoding: [0x26,0x2f,0xa2,0x70] +- +-vmulwod.w.hu.h $vr18, $vr25, $vr31 +-# CHECK-INST: vmulwod.w.hu.h $vr18, $vr25, $vr31 +-# CHECK-ENCODING: encoding: [0x32,0xff,0xa2,0x70] +- +-vmulwod.d.wu.w $vr10, $vr28, $vr26 +-# CHECK-INST: vmulwod.d.wu.w $vr10, $vr28, $vr26 +-# CHECK-ENCODING: encoding: [0x8a,0x6b,0xa3,0x70] +- +-vmulwod.q.du.d $vr30, $vr23, $vr17 +-# CHECK-INST: vmulwod.q.du.d $vr30, $vr23, $vr17 +-# CHECK-ENCODING: encoding: [0xfe,0xc6,0xa3,0x70] +diff --git a/llvm/test/MC/LoongArch/lsx/neg.s b/llvm/test/MC/LoongArch/lsx/neg.s +deleted file mode 100644 +index 34a6d9751..000000000 +--- a/llvm/test/MC/LoongArch/lsx/neg.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vneg.b $vr11, $vr29 +-# CHECK-INST: vneg.b $vr11, $vr29 +-# CHECK-ENCODING: encoding: [0xab,0x33,0x9c,0x72] +- +-vneg.h $vr14, $vr4 +-# CHECK-INST: vneg.h $vr14, $vr4 +-# CHECK-ENCODING: encoding: [0x8e,0x34,0x9c,0x72] +- +-vneg.w $vr4, $vr0 +-# CHECK-INST: vneg.w $vr4, $vr0 +-# CHECK-ENCODING: encoding: [0x04,0x38,0x9c,0x72] +- +-vneg.d $vr0, $vr5 +-# CHECK-INST: vneg.d $vr0, $vr5 +-# CHECK-ENCODING: encoding: [0xa0,0x3c,0x9c,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/nor.s b/llvm/test/MC/LoongArch/lsx/nor.s +deleted file mode 100644 +index a74074f09..000000000 +--- a/llvm/test/MC/LoongArch/lsx/nor.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vnor.v $vr18, $vr5, $vr29 +-# CHECK-INST: vnor.v $vr18, $vr5, $vr29 +-# CHECK-ENCODING: encoding: [0xb2,0xf4,0x27,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/nori.s b/llvm/test/MC/LoongArch/lsx/nori.s +deleted file mode 100644 +index 7693568df..000000000 +--- a/llvm/test/MC/LoongArch/lsx/nori.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vnori.b $vr8, $vr16, 186 +-# CHECK-INST: vnori.b $vr8, $vr16, 186 +-# CHECK-ENCODING: encoding: [0x08,0xea,0xde,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/or.s b/llvm/test/MC/LoongArch/lsx/or.s +deleted file mode 100644 +index c349eac2a..000000000 +--- a/llvm/test/MC/LoongArch/lsx/or.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vor.v $vr9, $vr18, $vr24 +-# CHECK-INST: vor.v $vr9, $vr18, $vr24 +-# CHECK-ENCODING: encoding: [0x49,0xe2,0x26,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/ori.s b/llvm/test/MC/LoongArch/lsx/ori.s +deleted file mode 100644 +index def8fbb9c..000000000 +--- a/llvm/test/MC/LoongArch/lsx/ori.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vori.b $vr23, $vr3, 252 +-# CHECK-INST: vori.b $vr23, $vr3, 252 +-# CHECK-ENCODING: encoding: [0x77,0xf0,0xd7,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/orn.s b/llvm/test/MC/LoongArch/lsx/orn.s +deleted file mode 100644 +index 60864e9a3..000000000 +--- a/llvm/test/MC/LoongArch/lsx/orn.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vorn.v $vr11, $vr20, $vr17 +-# CHECK-INST: vorn.v $vr11, $vr20, $vr17 +-# CHECK-ENCODING: encoding: [0x8b,0xc6,0x28,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/pack.s b/llvm/test/MC/LoongArch/lsx/pack.s +deleted file mode 100644 +index 4d9b8b3f2..000000000 +--- a/llvm/test/MC/LoongArch/lsx/pack.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vpackev.b $vr1, $vr27, $vr16 +-# CHECK-INST: vpackev.b $vr1, $vr27, $vr16 +-# CHECK-ENCODING: encoding: [0x61,0x43,0x16,0x71] +- +-vpackev.h $vr0, $vr3, $vr25 +-# CHECK-INST: vpackev.h $vr0, $vr3, $vr25 +-# CHECK-ENCODING: encoding: [0x60,0xe4,0x16,0x71] +- +-vpackev.w $vr10, $vr4, $vr29 +-# CHECK-INST: vpackev.w $vr10, $vr4, $vr29 +-# CHECK-ENCODING: encoding: [0x8a,0x74,0x17,0x71] +- +-vpackev.d $vr28, $vr6, $vr7 +-# CHECK-INST: vpackev.d $vr28, $vr6, $vr7 +-# CHECK-ENCODING: encoding: [0xdc,0x9c,0x17,0x71] +- +-vpackod.b $vr14, $vr13, $vr7 +-# CHECK-INST: vpackod.b $vr14, $vr13, $vr7 +-# CHECK-ENCODING: encoding: [0xae,0x1d,0x18,0x71] +- +-vpackod.h $vr28, $vr5, $vr7 +-# CHECK-INST: vpackod.h $vr28, $vr5, $vr7 +-# CHECK-ENCODING: encoding: [0xbc,0x9c,0x18,0x71] +- +-vpackod.w $vr15, $vr11, $vr17 +-# CHECK-INST: vpackod.w $vr15, $vr11, $vr17 +-# CHECK-ENCODING: encoding: [0x6f,0x45,0x19,0x71] +- +-vpackod.d $vr12, $vr15, $vr0 +-# CHECK-INST: vpackod.d $vr12, $vr15, $vr0 +-# CHECK-ENCODING: encoding: [0xec,0x81,0x19,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/pcnt.s b/llvm/test/MC/LoongArch/lsx/pcnt.s +deleted file mode 100644 +index ee896aee8..000000000 +--- a/llvm/test/MC/LoongArch/lsx/pcnt.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vpcnt.b $vr2, $vr7 +-# CHECK-INST: vpcnt.b $vr2, $vr7 +-# CHECK-ENCODING: encoding: [0xe2,0x20,0x9c,0x72] +- +-vpcnt.h $vr23, $vr25 +-# CHECK-INST: vpcnt.h $vr23, $vr25 +-# CHECK-ENCODING: encoding: [0x37,0x27,0x9c,0x72] +- +-vpcnt.w $vr17, $vr24 +-# CHECK-INST: vpcnt.w $vr17, $vr24 +-# CHECK-ENCODING: encoding: [0x11,0x2b,0x9c,0x72] +- +-vpcnt.d $vr4, $vr13 +-# CHECK-INST: vpcnt.d $vr4, $vr13 +-# CHECK-ENCODING: encoding: [0xa4,0x2d,0x9c,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/permi.s b/llvm/test/MC/LoongArch/lsx/permi.s +deleted file mode 100644 +index 3b4e1a554..000000000 +--- a/llvm/test/MC/LoongArch/lsx/permi.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vpermi.w $vr2, $vr22, 219 +-# CHECK-INST: vpermi.w $vr2, $vr22, 219 +-# CHECK-ENCODING: encoding: [0xc2,0x6e,0xe7,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/pick.s b/llvm/test/MC/LoongArch/lsx/pick.s +deleted file mode 100644 +index f54c6226f..000000000 +--- a/llvm/test/MC/LoongArch/lsx/pick.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vpickev.b $vr8, $vr13, $vr23 +-# CHECK-INST: vpickev.b $vr8, $vr13, $vr23 +-# CHECK-ENCODING: encoding: [0xa8,0x5d,0x1e,0x71] +- +-vpickev.h $vr11, $vr18, $vr19 +-# CHECK-INST: vpickev.h $vr11, $vr18, $vr19 +-# CHECK-ENCODING: encoding: [0x4b,0xce,0x1e,0x71] +- +-vpickev.w $vr16, $vr31, $vr30 +-# CHECK-INST: vpickev.w $vr16, $vr31, $vr30 +-# CHECK-ENCODING: encoding: [0xf0,0x7b,0x1f,0x71] +- +-vpickev.d $vr1, $vr28, $vr8 +-# CHECK-INST: vpickev.d $vr1, $vr28, $vr8 +-# CHECK-ENCODING: encoding: [0x81,0xa3,0x1f,0x71] +- +-vpickod.b $vr29, $vr28, $vr28 +-# CHECK-INST: vpickod.b $vr29, $vr28, $vr28 +-# CHECK-ENCODING: encoding: [0x9d,0x73,0x20,0x71] +- +-vpickod.h $vr5, $vr5, $vr1 +-# CHECK-INST: vpickod.h $vr5, $vr5, $vr1 +-# CHECK-ENCODING: encoding: [0xa5,0x84,0x20,0x71] +- +-vpickod.w $vr18, $vr8, $vr22 +-# CHECK-INST: vpickod.w $vr18, $vr8, $vr22 +-# CHECK-ENCODING: encoding: [0x12,0x59,0x21,0x71] +- +-vpickod.d $vr5, $vr5, $vr22 +-# CHECK-INST: vpickod.d $vr5, $vr5, $vr22 +-# CHECK-ENCODING: encoding: [0xa5,0xd8,0x21,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/pickve2gr.s b/llvm/test/MC/LoongArch/lsx/pickve2gr.s +deleted file mode 100644 +index 7a28e8104..000000000 +--- a/llvm/test/MC/LoongArch/lsx/pickve2gr.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vpickve2gr.b $r18, $vr1, 1 +-# CHECK-INST: vpickve2gr.b $t6, $vr1, 1 +-# CHECK-ENCODING: encoding: [0x32,0x84,0xef,0x72] +- +-vpickve2gr.h $r2, $vr5, 3 +-# CHECK-INST: vpickve2gr.h $tp, $vr5, 3 +-# CHECK-ENCODING: encoding: [0xa2,0xcc,0xef,0x72] +- +-vpickve2gr.w $r3, $vr11, 2 +-# CHECK-INST: vpickve2gr.w $sp, $vr11, 2 +-# CHECK-ENCODING: encoding: [0x63,0xe9,0xef,0x72] +- +-vpickve2gr.d $r26, $vr1, 1 +-# CHECK-INST: vpickve2gr.d $s3, $vr1, 1 +-# CHECK-ENCODING: encoding: [0x3a,0xf4,0xef,0x72] +- +-vpickve2gr.bu $r28, $vr14, 6 +-# CHECK-INST: vpickve2gr.bu $s5, $vr14, 6 +-# CHECK-ENCODING: encoding: [0xdc,0x99,0xf3,0x72] +- +-vpickve2gr.hu $r7, $vr6, 7 +-# CHECK-INST: vpickve2gr.hu $a3, $vr6, 7 +-# CHECK-ENCODING: encoding: [0xc7,0xdc,0xf3,0x72] +- +-vpickve2gr.wu $r11, $vr30, 1 +-# CHECK-INST: vpickve2gr.wu $a7, $vr30, 1 +-# CHECK-ENCODING: encoding: [0xcb,0xe7,0xf3,0x72] +- +-vpickve2gr.du $r13, $vr5, 0 +-# CHECK-INST: vpickve2gr.du $t1, $vr5, 0 +-# CHECK-ENCODING: encoding: [0xad,0xf0,0xf3,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/replgr2vr.s b/llvm/test/MC/LoongArch/lsx/replgr2vr.s +deleted file mode 100644 +index 5e5c04886..000000000 +--- a/llvm/test/MC/LoongArch/lsx/replgr2vr.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vreplgr2vr.b $vr30, $r27 +-# CHECK-INST: vreplgr2vr.b $vr30, $s4 +-# CHECK-ENCODING: encoding: [0x7e,0x03,0x9f,0x72] +- +-vreplgr2vr.h $vr6, $r1 +-# CHECK-INST: vreplgr2vr.h $vr6, $ra +-# CHECK-ENCODING: encoding: [0x26,0x04,0x9f,0x72] +- +-vreplgr2vr.w $vr23, $r9 +-# CHECK-INST: vreplgr2vr.w $vr23, $a5 +-# CHECK-ENCODING: encoding: [0x37,0x09,0x9f,0x72] +- +-vreplgr2vr.d $vr17, $r14 +-# CHECK-INST: vreplgr2vr.d $vr17, $t2 +-# CHECK-ENCODING: encoding: [0xd1,0x0d,0x9f,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/replve.s b/llvm/test/MC/LoongArch/lsx/replve.s +deleted file mode 100644 +index b9943acb3..000000000 +--- a/llvm/test/MC/LoongArch/lsx/replve.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vreplve.b $vr10, $vr31, $r20 +-# CHECK-INST: vreplve.b $vr10, $vr31, $t8 +-# CHECK-ENCODING: encoding: [0xea,0x53,0x22,0x71] +- +-vreplve.h $vr8, $vr3, $r30 +-# CHECK-INST: vreplve.h $vr8, $vr3, $s7 +-# CHECK-ENCODING: encoding: [0x68,0xf8,0x22,0x71] +- +-vreplve.w $vr5, $vr1, $r20 +-# CHECK-INST: vreplve.w $vr5, $vr1, $t8 +-# CHECK-ENCODING: encoding: [0x25,0x50,0x23,0x71] +- +-vreplve.d $vr11, $vr15, $r30 +-# CHECK-INST: vreplve.d $vr11, $vr15, $s7 +-# CHECK-ENCODING: encoding: [0xeb,0xf9,0x23,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/replvei.s b/llvm/test/MC/LoongArch/lsx/replvei.s +deleted file mode 100644 +index dd1ce0f96..000000000 +--- a/llvm/test/MC/LoongArch/lsx/replvei.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vreplvei.b $vr23, $vr3, 3 +-# CHECK-INST: vreplvei.b $vr23, $vr3, 3 +-# CHECK-ENCODING: encoding: [0x77,0x8c,0xf7,0x72] +- +-vreplvei.h $vr27, $vr16, 0 +-# CHECK-INST: vreplvei.h $vr27, $vr16, 0 +-# CHECK-ENCODING: encoding: [0x1b,0xc2,0xf7,0x72] +- +-vreplvei.w $vr18, $vr23, 3 +-# CHECK-INST: vreplvei.w $vr18, $vr23, 3 +-# CHECK-ENCODING: encoding: [0xf2,0xee,0xf7,0x72] +- +-vreplvei.d $vr15, $vr12, 1 +-# CHECK-INST: vreplvei.d $vr15, $vr12, 1 +-# CHECK-ENCODING: encoding: [0x8f,0xf5,0xf7,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/rotr.s b/llvm/test/MC/LoongArch/lsx/rotr.s +deleted file mode 100644 +index 101405e5b..000000000 +--- a/llvm/test/MC/LoongArch/lsx/rotr.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vrotr.b $vr15, $vr25, $vr30 +-# CHECK-INST: vrotr.b $vr15, $vr25, $vr30 +-# CHECK-ENCODING: encoding: [0x2f,0x7b,0xee,0x70] +- +-vrotr.h $vr5, $vr23, $vr14 +-# CHECK-INST: vrotr.h $vr5, $vr23, $vr14 +-# CHECK-ENCODING: encoding: [0xe5,0xba,0xee,0x70] +- +-vrotr.w $vr27, $vr0, $vr7 +-# CHECK-INST: vrotr.w $vr27, $vr0, $vr7 +-# CHECK-ENCODING: encoding: [0x1b,0x1c,0xef,0x70] +- +-vrotr.d $vr2, $vr3, $vr21 +-# CHECK-INST: vrotr.d $vr2, $vr3, $vr21 +-# CHECK-ENCODING: encoding: [0x62,0xd4,0xef,0x70] +- +-vrotri.b $vr17, $vr22, 5 +-# CHECK-INST: vrotri.b $vr17, $vr22, 5 +-# CHECK-ENCODING: encoding: [0xd1,0x36,0xa0,0x72] +- +-vrotri.h $vr27, $vr20, 10 +-# CHECK-INST: vrotri.h $vr27, $vr20, 10 +-# CHECK-ENCODING: encoding: [0x9b,0x6a,0xa0,0x72] +- +-vrotri.w $vr21, $vr24, 14 +-# CHECK-INST: vrotri.w $vr21, $vr24, 14 +-# CHECK-ENCODING: encoding: [0x15,0xbb,0xa0,0x72] +- +-vrotri.d $vr25, $vr23, 14 +-# CHECK-INST: vrotri.d $vr25, $vr23, 14 +-# CHECK-ENCODING: encoding: [0xf9,0x3a,0xa1,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/sadd.s b/llvm/test/MC/LoongArch/lsx/sadd.s +deleted file mode 100644 +index 9709a8a8e..000000000 +--- a/llvm/test/MC/LoongArch/lsx/sadd.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsadd.b $vr29, $vr30, $vr11 +-# CHECK-INST: vsadd.b $vr29, $vr30, $vr11 +-# CHECK-ENCODING: encoding: [0xdd,0x2f,0x46,0x70] +- +-vsadd.h $vr1, $vr2, $vr29 +-# CHECK-INST: vsadd.h $vr1, $vr2, $vr29 +-# CHECK-ENCODING: encoding: [0x41,0xf4,0x46,0x70] +- +-vsadd.w $vr19, $vr28, $vr28 +-# CHECK-INST: vsadd.w $vr19, $vr28, $vr28 +-# CHECK-ENCODING: encoding: [0x93,0x73,0x47,0x70] +- +-vsadd.d $vr19, $vr30, $vr20 +-# CHECK-INST: vsadd.d $vr19, $vr30, $vr20 +-# CHECK-ENCODING: encoding: [0xd3,0xd3,0x47,0x70] +- +-vsadd.bu $vr22, $vr22, $vr16 +-# CHECK-INST: vsadd.bu $vr22, $vr22, $vr16 +-# CHECK-ENCODING: encoding: [0xd6,0x42,0x4a,0x70] +- +-vsadd.hu $vr0, $vr16, $vr8 +-# CHECK-INST: vsadd.hu $vr0, $vr16, $vr8 +-# CHECK-ENCODING: encoding: [0x00,0xa2,0x4a,0x70] +- +-vsadd.wu $vr9, $vr23, $vr24 +-# CHECK-INST: vsadd.wu $vr9, $vr23, $vr24 +-# CHECK-ENCODING: encoding: [0xe9,0x62,0x4b,0x70] +- +-vsadd.du $vr28, $vr11, $vr30 +-# CHECK-INST: vsadd.du $vr28, $vr11, $vr30 +-# CHECK-ENCODING: encoding: [0x7c,0xf9,0x4b,0x70] +diff --git a/llvm/test/MC/LoongArch/lsx/sat.s b/llvm/test/MC/LoongArch/lsx/sat.s +deleted file mode 100644 +index 677e7fc5a..000000000 +--- a/llvm/test/MC/LoongArch/lsx/sat.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsat.b $vr29, $vr0, 1 +-# CHECK-INST: vsat.b $vr29, $vr0, 1 +-# CHECK-ENCODING: encoding: [0x1d,0x24,0x24,0x73] +- +-vsat.h $vr4, $vr13, 13 +-# CHECK-INST: vsat.h $vr4, $vr13, 13 +-# CHECK-ENCODING: encoding: [0xa4,0x75,0x24,0x73] +- +-vsat.w $vr6, $vr29, 19 +-# CHECK-INST: vsat.w $vr6, $vr29, 19 +-# CHECK-ENCODING: encoding: [0xa6,0xcf,0x24,0x73] +- +-vsat.d $vr22, $vr6, 54 +-# CHECK-INST: vsat.d $vr22, $vr6, 54 +-# CHECK-ENCODING: encoding: [0xd6,0xd8,0x25,0x73] +- +-vsat.bu $vr17, $vr8, 6 +-# CHECK-INST: vsat.bu $vr17, $vr8, 6 +-# CHECK-ENCODING: encoding: [0x11,0x39,0x28,0x73] +- +-vsat.hu $vr2, $vr14, 2 +-# CHECK-INST: vsat.hu $vr2, $vr14, 2 +-# CHECK-ENCODING: encoding: [0xc2,0x49,0x28,0x73] +- +-vsat.wu $vr1, $vr28, 19 +-# CHECK-INST: vsat.wu $vr1, $vr28, 19 +-# CHECK-ENCODING: encoding: [0x81,0xcf,0x28,0x73] +- +-vsat.du $vr25, $vr6, 59 +-# CHECK-INST: vsat.du $vr25, $vr6, 59 +-# CHECK-ENCODING: encoding: [0xd9,0xec,0x29,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/seq.s b/llvm/test/MC/LoongArch/lsx/seq.s +deleted file mode 100644 +index 764c94ef6..000000000 +--- a/llvm/test/MC/LoongArch/lsx/seq.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vseq.b $vr15, $vr30, $vr24 +-# CHECK-INST: vseq.b $vr15, $vr30, $vr24 +-# CHECK-ENCODING: encoding: [0xcf,0x63,0x00,0x70] +- +-vseq.h $vr7, $vr4, $vr22 +-# CHECK-INST: vseq.h $vr7, $vr4, $vr22 +-# CHECK-ENCODING: encoding: [0x87,0xd8,0x00,0x70] +- +-vseq.w $vr4, $vr15, $vr28 +-# CHECK-INST: vseq.w $vr4, $vr15, $vr28 +-# CHECK-ENCODING: encoding: [0xe4,0x71,0x01,0x70] +- +-vseq.d $vr29, $vr26, $vr22 +-# CHECK-INST: vseq.d $vr29, $vr26, $vr22 +-# CHECK-ENCODING: encoding: [0x5d,0xdb,0x01,0x70] +- +-vseqi.b $vr19, $vr30, 14 +-# CHECK-INST: vseqi.b $vr19, $vr30, 14 +-# CHECK-ENCODING: encoding: [0xd3,0x3b,0x80,0x72] +- +-vseqi.h $vr15, $vr2, 15 +-# CHECK-INST: vseqi.h $vr15, $vr2, 15 +-# CHECK-ENCODING: encoding: [0x4f,0xbc,0x80,0x72] +- +-vseqi.w $vr27, $vr23, -10 +-# CHECK-INST: vseqi.w $vr27, $vr23, -10 +-# CHECK-ENCODING: encoding: [0xfb,0x5a,0x81,0x72] +- +-vseqi.d $vr6, $vr12, -2 +-# CHECK-INST: vseqi.d $vr6, $vr12, -2 +-# CHECK-ENCODING: encoding: [0x86,0xf9,0x81,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/set.s b/llvm/test/MC/LoongArch/lsx/set.s +deleted file mode 100644 +index bd2cfb57a..000000000 +--- a/llvm/test/MC/LoongArch/lsx/set.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vseteqz.v $fcc0, $vr13 +-# CHECK-INST: vseteqz.v $fcc0, $vr13 +-# CHECK-ENCODING: encoding: [0xa0,0x99,0x9c,0x72] +- +-vsetnez.v $fcc7, $vr14 +-# CHECK-INST: vsetnez.v $fcc7, $vr14 +-# CHECK-ENCODING: encoding: [0xc7,0x9d,0x9c,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/setallnez.s b/llvm/test/MC/LoongArch/lsx/setallnez.s +deleted file mode 100644 +index 8ca6f1497..000000000 +--- a/llvm/test/MC/LoongArch/lsx/setallnez.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsetallnez.b $fcc2, $vr8 +-# CHECK-INST: vsetallnez.b $fcc2, $vr8 +-# CHECK-ENCODING: encoding: [0x02,0xb1,0x9c,0x72] +- +-vsetallnez.h $fcc0, $vr26 +-# CHECK-INST: vsetallnez.h $fcc0, $vr26 +-# CHECK-ENCODING: encoding: [0x40,0xb7,0x9c,0x72] +- +-vsetallnez.w $fcc6, $vr17 +-# CHECK-INST: vsetallnez.w $fcc6, $vr17 +-# CHECK-ENCODING: encoding: [0x26,0xba,0x9c,0x72] +- +-vsetallnez.d $fcc0, $vr27 +-# CHECK-INST: vsetallnez.d $fcc0, $vr27 +-# CHECK-ENCODING: encoding: [0x60,0xbf,0x9c,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/setanyeqz.s b/llvm/test/MC/LoongArch/lsx/setanyeqz.s +deleted file mode 100644 +index 6dbd4f170..000000000 +--- a/llvm/test/MC/LoongArch/lsx/setanyeqz.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsetanyeqz.b $fcc3, $vr4 +-# CHECK-INST: vsetanyeqz.b $fcc3, $vr4 +-# CHECK-ENCODING: encoding: [0x83,0xa0,0x9c,0x72] +- +-vsetanyeqz.h $fcc2, $vr15 +-# CHECK-INST: vsetanyeqz.h $fcc2, $vr15 +-# CHECK-ENCODING: encoding: [0xe2,0xa5,0x9c,0x72] +- +-vsetanyeqz.w $fcc4, $vr0 +-# CHECK-INST: vsetanyeqz.w $fcc4, $vr0 +-# CHECK-ENCODING: encoding: [0x04,0xa8,0x9c,0x72] +- +-vsetanyeqz.d $fcc3, $vr7 +-# CHECK-INST: vsetanyeqz.d $fcc3, $vr7 +-# CHECK-ENCODING: encoding: [0xe3,0xac,0x9c,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/shuf.s b/llvm/test/MC/LoongArch/lsx/shuf.s +deleted file mode 100644 +index 0e73aba22..000000000 +--- a/llvm/test/MC/LoongArch/lsx/shuf.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vshuf.b $vr27, $vr17, $vr31, $vr28 +-# CHECK-INST: vshuf.b $vr27, $vr17, $vr31, $vr28 +-# CHECK-ENCODING: encoding: [0x3b,0x7e,0x5e,0x0d] +- +-vshuf.h $vr21, $vr10, $vr31 +-# CHECK-INST: vshuf.h $vr21, $vr10, $vr31 +-# CHECK-ENCODING: encoding: [0x55,0xfd,0x7a,0x71] +- +-vshuf.w $vr18, $vr17, $vr23 +-# CHECK-INST: vshuf.w $vr18, $vr17, $vr23 +-# CHECK-ENCODING: encoding: [0x32,0x5e,0x7b,0x71] +- +-vshuf.d $vr4, $vr24, $vr11 +-# CHECK-INST: vshuf.d $vr4, $vr24, $vr11 +-# CHECK-ENCODING: encoding: [0x04,0xaf,0x7b,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/shuf4i.s b/llvm/test/MC/LoongArch/lsx/shuf4i.s +deleted file mode 100644 +index d22e2956c..000000000 +--- a/llvm/test/MC/LoongArch/lsx/shuf4i.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vshuf4i.b $vr30, $vr14, 72 +-# CHECK-INST: vshuf4i.b $vr30, $vr14, 72 +-# CHECK-ENCODING: encoding: [0xde,0x21,0x91,0x73] +- +-vshuf4i.h $vr13, $vr4, 222 +-# CHECK-INST: vshuf4i.h $vr13, $vr4, 222 +-# CHECK-ENCODING: encoding: [0x8d,0x78,0x97,0x73] +- +-vshuf4i.w $vr17, $vr8, 74 +-# CHECK-INST: vshuf4i.w $vr17, $vr8, 74 +-# CHECK-ENCODING: encoding: [0x11,0x29,0x99,0x73] +- +-vshuf4i.d $vr11, $vr6, 157 +-# CHECK-INST: vshuf4i.d $vr11, $vr6, 157 +-# CHECK-ENCODING: encoding: [0xcb,0x74,0x9e,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/signcov.s b/llvm/test/MC/LoongArch/lsx/signcov.s +deleted file mode 100644 +index 343a46f3e..000000000 +--- a/llvm/test/MC/LoongArch/lsx/signcov.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsigncov.b $vr11, $vr3, $vr7 +-# CHECK-INST: vsigncov.b $vr11, $vr3, $vr7 +-# CHECK-ENCODING: encoding: [0x6b,0x1c,0x2e,0x71] +- +-vsigncov.h $vr8, $vr29, $vr1 +-# CHECK-INST: vsigncov.h $vr8, $vr29, $vr1 +-# CHECK-ENCODING: encoding: [0xa8,0x87,0x2e,0x71] +- +-vsigncov.w $vr28, $vr13, $vr21 +-# CHECK-INST: vsigncov.w $vr28, $vr13, $vr21 +-# CHECK-ENCODING: encoding: [0xbc,0x55,0x2f,0x71] +- +-vsigncov.d $vr22, $vr20, $vr0 +-# CHECK-INST: vsigncov.d $vr22, $vr20, $vr0 +-# CHECK-ENCODING: encoding: [0x96,0x82,0x2f,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/sle.s b/llvm/test/MC/LoongArch/lsx/sle.s +deleted file mode 100644 +index cf86e6329..000000000 +--- a/llvm/test/MC/LoongArch/lsx/sle.s ++++ /dev/null +@@ -1,68 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsle.b $vr4, $vr30, $vr18 +-# CHECK-INST: vsle.b $vr4, $vr30, $vr18 +-# CHECK-ENCODING: encoding: [0xc4,0x4b,0x02,0x70] +- +-vsle.h $vr3, $vr13, $vr12 +-# CHECK-INST: vsle.h $vr3, $vr13, $vr12 +-# CHECK-ENCODING: encoding: [0xa3,0xb1,0x02,0x70] +- +-vsle.w $vr21, $vr17, $vr20 +-# CHECK-INST: vsle.w $vr21, $vr17, $vr20 +-# CHECK-ENCODING: encoding: [0x35,0x52,0x03,0x70] +- +-vsle.d $vr22, $vr0, $vr28 +-# CHECK-INST: vsle.d $vr22, $vr0, $vr28 +-# CHECK-ENCODING: encoding: [0x16,0xf0,0x03,0x70] +- +-vslei.b $vr8, $vr11, 4 +-# CHECK-INST: vslei.b $vr8, $vr11, 4 +-# CHECK-ENCODING: encoding: [0x68,0x11,0x82,0x72] +- +-vslei.h $vr15, $vr22, 0 +-# CHECK-INST: vslei.h $vr15, $vr22, 0 +-# CHECK-ENCODING: encoding: [0xcf,0x82,0x82,0x72] +- +-vslei.w $vr23, $vr17, 12 +-# CHECK-INST: vslei.w $vr23, $vr17, 12 +-# CHECK-ENCODING: encoding: [0x37,0x32,0x83,0x72] +- +-vslei.d $vr11, $vr18, -12 +-# CHECK-INST: vslei.d $vr11, $vr18, -12 +-# CHECK-ENCODING: encoding: [0x4b,0xd2,0x83,0x72] +- +-vsle.bu $vr20, $vr11, $vr31 +-# CHECK-INST: vsle.bu $vr20, $vr11, $vr31 +-# CHECK-ENCODING: encoding: [0x74,0x7d,0x04,0x70] +- +-vsle.hu $vr5, $vr6, $vr7 +-# CHECK-INST: vsle.hu $vr5, $vr6, $vr7 +-# CHECK-ENCODING: encoding: [0xc5,0x9c,0x04,0x70] +- +-vsle.wu $vr15, $vr14, $vr22 +-# CHECK-INST: vsle.wu $vr15, $vr14, $vr22 +-# CHECK-ENCODING: encoding: [0xcf,0x59,0x05,0x70] +- +-vsle.du $vr0, $vr29, $vr17 +-# CHECK-INST: vsle.du $vr0, $vr29, $vr17 +-# CHECK-ENCODING: encoding: [0xa0,0xc7,0x05,0x70] +- +-vslei.bu $vr12, $vr27, 12 +-# CHECK-INST: vslei.bu $vr12, $vr27, 12 +-# CHECK-ENCODING: encoding: [0x6c,0x33,0x84,0x72] +- +-vslei.hu $vr22, $vr31, 12 +-# CHECK-INST: vslei.hu $vr22, $vr31, 12 +-# CHECK-ENCODING: encoding: [0xf6,0xb3,0x84,0x72] +- +-vslei.wu $vr19, $vr18, 21 +-# CHECK-INST: vslei.wu $vr19, $vr18, 21 +-# CHECK-ENCODING: encoding: [0x53,0x56,0x85,0x72] +- +-vslei.du $vr19, $vr14, 26 +-# CHECK-INST: vslei.du $vr19, $vr14, 26 +-# CHECK-ENCODING: encoding: [0xd3,0xe9,0x85,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/sll.s b/llvm/test/MC/LoongArch/lsx/sll.s +deleted file mode 100644 +index e443abeef..000000000 +--- a/llvm/test/MC/LoongArch/lsx/sll.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsll.b $vr31, $vr13, $vr5 +-# CHECK-INST: vsll.b $vr31, $vr13, $vr5 +-# CHECK-ENCODING: encoding: [0xbf,0x15,0xe8,0x70] +- +-vsll.h $vr31, $vr1, $vr4 +-# CHECK-INST: vsll.h $vr31, $vr1, $vr4 +-# CHECK-ENCODING: encoding: [0x3f,0x90,0xe8,0x70] +- +-vsll.w $vr8, $vr19, $vr19 +-# CHECK-INST: vsll.w $vr8, $vr19, $vr19 +-# CHECK-ENCODING: encoding: [0x68,0x4e,0xe9,0x70] +- +-vsll.d $vr6, $vr25, $vr6 +-# CHECK-INST: vsll.d $vr6, $vr25, $vr6 +-# CHECK-ENCODING: encoding: [0x26,0x9b,0xe9,0x70] +- +-vslli.b $vr6, $vr7, 2 +-# CHECK-INST: vslli.b $vr6, $vr7, 2 +-# CHECK-ENCODING: encoding: [0xe6,0x28,0x2c,0x73] +- +-vslli.h $vr6, $vr4, 10 +-# CHECK-INST: vslli.h $vr6, $vr4, 10 +-# CHECK-ENCODING: encoding: [0x86,0x68,0x2c,0x73] +- +-vslli.w $vr3, $vr13, 17 +-# CHECK-INST: vslli.w $vr3, $vr13, 17 +-# CHECK-ENCODING: encoding: [0xa3,0xc5,0x2c,0x73] +- +-vslli.d $vr24, $vr11, 38 +-# CHECK-INST: vslli.d $vr24, $vr11, 38 +-# CHECK-ENCODING: encoding: [0x78,0x99,0x2d,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/sllwil.s b/llvm/test/MC/LoongArch/lsx/sllwil.s +deleted file mode 100644 +index 3aec8d63a..000000000 +--- a/llvm/test/MC/LoongArch/lsx/sllwil.s ++++ /dev/null +@@ -1,28 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsllwil.h.b $vr7, $vr6, 3 +-# CHECK-INST: vsllwil.h.b $vr7, $vr6, 3 +-# CHECK-ENCODING: encoding: [0xc7,0x2c,0x08,0x73] +- +-vsllwil.w.h $vr6, $vr5, 8 +-# CHECK-INST: vsllwil.w.h $vr6, $vr5, 8 +-# CHECK-ENCODING: encoding: [0xa6,0x60,0x08,0x73] +- +-vsllwil.d.w $vr15, $vr1, 22 +-# CHECK-INST: vsllwil.d.w $vr15, $vr1, 22 +-# CHECK-ENCODING: encoding: [0x2f,0xd8,0x08,0x73] +- +-vsllwil.hu.bu $vr13, $vr4, 4 +-# CHECK-INST: vsllwil.hu.bu $vr13, $vr4, 4 +-# CHECK-ENCODING: encoding: [0x8d,0x30,0x0c,0x73] +- +-vsllwil.wu.hu $vr1, $vr4, 3 +-# CHECK-INST: vsllwil.wu.hu $vr1, $vr4, 3 +-# CHECK-ENCODING: encoding: [0x81,0x4c,0x0c,0x73] +- +-vsllwil.du.wu $vr18, $vr29, 25 +-# CHECK-INST: vsllwil.du.wu $vr18, $vr29, 25 +-# CHECK-ENCODING: encoding: [0xb2,0xe7,0x0c,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/slt.s b/llvm/test/MC/LoongArch/lsx/slt.s +deleted file mode 100644 +index 86034324d..000000000 +--- a/llvm/test/MC/LoongArch/lsx/slt.s ++++ /dev/null +@@ -1,68 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vslt.b $vr24, $vr23, $vr26 +-# CHECK-INST: vslt.b $vr24, $vr23, $vr26 +-# CHECK-ENCODING: encoding: [0xf8,0x6a,0x06,0x70] +- +-vslt.h $vr23, $vr4, $vr6 +-# CHECK-INST: vslt.h $vr23, $vr4, $vr6 +-# CHECK-ENCODING: encoding: [0x97,0x98,0x06,0x70] +- +-vslt.w $vr30, $vr25, $vr1 +-# CHECK-INST: vslt.w $vr30, $vr25, $vr1 +-# CHECK-ENCODING: encoding: [0x3e,0x07,0x07,0x70] +- +-vslt.d $vr25, $vr22, $vr15 +-# CHECK-INST: vslt.d $vr25, $vr22, $vr15 +-# CHECK-ENCODING: encoding: [0xd9,0xbe,0x07,0x70] +- +-vslti.b $vr11, $vr12, -10 +-# CHECK-INST: vslti.b $vr11, $vr12, -10 +-# CHECK-ENCODING: encoding: [0x8b,0x59,0x86,0x72] +- +-vslti.h $vr20, $vr12, -8 +-# CHECK-INST: vslti.h $vr20, $vr12, -8 +-# CHECK-ENCODING: encoding: [0x94,0xe1,0x86,0x72] +- +-vslti.w $vr20, $vr27, 0 +-# CHECK-INST: vslti.w $vr20, $vr27, 0 +-# CHECK-ENCODING: encoding: [0x74,0x03,0x87,0x72] +- +-vslti.d $vr19, $vr18, 4 +-# CHECK-INST: vslti.d $vr19, $vr18, 4 +-# CHECK-ENCODING: encoding: [0x53,0x92,0x87,0x72] +- +-vslt.bu $vr5, $vr30, $vr28 +-# CHECK-INST: vslt.bu $vr5, $vr30, $vr28 +-# CHECK-ENCODING: encoding: [0xc5,0x73,0x08,0x70] +- +-vslt.hu $vr13, $vr28, $vr23 +-# CHECK-INST: vslt.hu $vr13, $vr28, $vr23 +-# CHECK-ENCODING: encoding: [0x8d,0xdf,0x08,0x70] +- +-vslt.wu $vr20, $vr28, $vr1 +-# CHECK-INST: vslt.wu $vr20, $vr28, $vr1 +-# CHECK-ENCODING: encoding: [0x94,0x07,0x09,0x70] +- +-vslt.du $vr6, $vr6, $vr5 +-# CHECK-INST: vslt.du $vr6, $vr6, $vr5 +-# CHECK-ENCODING: encoding: [0xc6,0x94,0x09,0x70] +- +-vslti.bu $vr9, $vr29, 23 +-# CHECK-INST: vslti.bu $vr9, $vr29, 23 +-# CHECK-ENCODING: encoding: [0xa9,0x5f,0x88,0x72] +- +-vslti.hu $vr28, $vr13, 6 +-# CHECK-INST: vslti.hu $vr28, $vr13, 6 +-# CHECK-ENCODING: encoding: [0xbc,0x99,0x88,0x72] +- +-vslti.wu $vr11, $vr9, 12 +-# CHECK-INST: vslti.wu $vr11, $vr9, 12 +-# CHECK-ENCODING: encoding: [0x2b,0x31,0x89,0x72] +- +-vslti.du $vr23, $vr30, 21 +-# CHECK-INST: vslti.du $vr23, $vr30, 21 +-# CHECK-ENCODING: encoding: [0xd7,0xd7,0x89,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/sra.s b/llvm/test/MC/LoongArch/lsx/sra.s +deleted file mode 100644 +index 3220a4159..000000000 +--- a/llvm/test/MC/LoongArch/lsx/sra.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsra.b $vr30, $vr9, $vr11 +-# CHECK-INST: vsra.b $vr30, $vr9, $vr11 +-# CHECK-ENCODING: encoding: [0x3e,0x2d,0xec,0x70] +- +-vsra.h $vr20, $vr17, $vr26 +-# CHECK-INST: vsra.h $vr20, $vr17, $vr26 +-# CHECK-ENCODING: encoding: [0x34,0xea,0xec,0x70] +- +-vsra.w $vr12, $vr21, $vr15 +-# CHECK-INST: vsra.w $vr12, $vr21, $vr15 +-# CHECK-ENCODING: encoding: [0xac,0x3e,0xed,0x70] +- +-vsra.d $vr8, $vr8, $vr11 +-# CHECK-INST: vsra.d $vr8, $vr8, $vr11 +-# CHECK-ENCODING: encoding: [0x08,0xad,0xed,0x70] +- +-vsrai.b $vr9, $vr0, 4 +-# CHECK-INST: vsrai.b $vr9, $vr0, 4 +-# CHECK-ENCODING: encoding: [0x09,0x30,0x34,0x73] +- +-vsrai.h $vr1, $vr8, 6 +-# CHECK-INST: vsrai.h $vr1, $vr8, 6 +-# CHECK-ENCODING: encoding: [0x01,0x59,0x34,0x73] +- +-vsrai.w $vr20, $vr30, 14 +-# CHECK-INST: vsrai.w $vr20, $vr30, 14 +-# CHECK-ENCODING: encoding: [0xd4,0xbb,0x34,0x73] +- +-vsrai.d $vr0, $vr21, 12 +-# CHECK-INST: vsrai.d $vr0, $vr21, 12 +-# CHECK-ENCODING: encoding: [0xa0,0x32,0x35,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/sran.s b/llvm/test/MC/LoongArch/lsx/sran.s +deleted file mode 100644 +index 595a5be90..000000000 +--- a/llvm/test/MC/LoongArch/lsx/sran.s ++++ /dev/null +@@ -1,16 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsran.b.h $vr25, $vr2, $vr31 +-# CHECK-INST: vsran.b.h $vr25, $vr2, $vr31 +-# CHECK-ENCODING: encoding: [0x59,0xfc,0xf6,0x70] +- +-vsran.h.w $vr31, $vr10, $vr3 +-# CHECK-INST: vsran.h.w $vr31, $vr10, $vr3 +-# CHECK-ENCODING: encoding: [0x5f,0x0d,0xf7,0x70] +- +-vsran.w.d $vr8, $vr3, $vr12 +-# CHECK-INST: vsran.w.d $vr8, $vr3, $vr12 +-# CHECK-ENCODING: encoding: [0x68,0xb0,0xf7,0x70] +diff --git a/llvm/test/MC/LoongArch/lsx/srani.s b/llvm/test/MC/LoongArch/lsx/srani.s +deleted file mode 100644 +index f28d72807..000000000 +--- a/llvm/test/MC/LoongArch/lsx/srani.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsrani.b.h $vr3, $vr0, 9 +-# CHECK-INST: vsrani.b.h $vr3, $vr0, 9 +-# CHECK-ENCODING: encoding: [0x03,0x64,0x58,0x73] +- +-vsrani.h.w $vr4, $vr3, 26 +-# CHECK-INST: vsrani.h.w $vr4, $vr3, 26 +-# CHECK-ENCODING: encoding: [0x64,0xe8,0x58,0x73] +- +-vsrani.w.d $vr8, $vr27, 52 +-# CHECK-INST: vsrani.w.d $vr8, $vr27, 52 +-# CHECK-ENCODING: encoding: [0x68,0xd3,0x59,0x73] +- +-vsrani.d.q $vr21, $vr24, 28 +-# CHECK-INST: vsrani.d.q $vr21, $vr24, 28 +-# CHECK-ENCODING: encoding: [0x15,0x73,0x5a,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/srar.s b/llvm/test/MC/LoongArch/lsx/srar.s +deleted file mode 100644 +index b62bda203..000000000 +--- a/llvm/test/MC/LoongArch/lsx/srar.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsrar.b $vr5, $vr31, $vr9 +-# CHECK-INST: vsrar.b $vr5, $vr31, $vr9 +-# CHECK-ENCODING: encoding: [0xe5,0x27,0xf2,0x70] +- +-vsrar.h $vr30, $vr23, $vr30 +-# CHECK-INST: vsrar.h $vr30, $vr23, $vr30 +-# CHECK-ENCODING: encoding: [0xfe,0xfa,0xf2,0x70] +- +-vsrar.w $vr22, $vr8, $vr1 +-# CHECK-INST: vsrar.w $vr22, $vr8, $vr1 +-# CHECK-ENCODING: encoding: [0x16,0x05,0xf3,0x70] +- +-vsrar.d $vr17, $vr1, $vr5 +-# CHECK-INST: vsrar.d $vr17, $vr1, $vr5 +-# CHECK-ENCODING: encoding: [0x31,0x94,0xf3,0x70] +- +-vsrari.b $vr11, $vr24, 5 +-# CHECK-INST: vsrari.b $vr11, $vr24, 5 +-# CHECK-ENCODING: encoding: [0x0b,0x37,0xa8,0x72] +- +-vsrari.h $vr24, $vr0, 7 +-# CHECK-INST: vsrari.h $vr24, $vr0, 7 +-# CHECK-ENCODING: encoding: [0x18,0x5c,0xa8,0x72] +- +-vsrari.w $vr16, $vr0, 0 +-# CHECK-INST: vsrari.w $vr16, $vr0, 0 +-# CHECK-ENCODING: encoding: [0x10,0x80,0xa8,0x72] +- +-vsrari.d $vr16, $vr13, 63 +-# CHECK-INST: vsrari.d $vr16, $vr13, 63 +-# CHECK-ENCODING: encoding: [0xb0,0xfd,0xa9,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/srarn.s b/llvm/test/MC/LoongArch/lsx/srarn.s +deleted file mode 100644 +index 665f722d6..000000000 +--- a/llvm/test/MC/LoongArch/lsx/srarn.s ++++ /dev/null +@@ -1,16 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsrarn.b.h $vr19, $vr23, $vr21 +-# CHECK-INST: vsrarn.b.h $vr19, $vr23, $vr21 +-# CHECK-ENCODING: encoding: [0xf3,0xd6,0xfa,0x70] +- +-vsrarn.h.w $vr18, $vr6, $vr7 +-# CHECK-INST: vsrarn.h.w $vr18, $vr6, $vr7 +-# CHECK-ENCODING: encoding: [0xd2,0x1c,0xfb,0x70] +- +-vsrarn.w.d $vr2, $vr11, $vr5 +-# CHECK-INST: vsrarn.w.d $vr2, $vr11, $vr5 +-# CHECK-ENCODING: encoding: [0x62,0x95,0xfb,0x70] +diff --git a/llvm/test/MC/LoongArch/lsx/srarni.s b/llvm/test/MC/LoongArch/lsx/srarni.s +deleted file mode 100644 +index 356d071a6..000000000 +--- a/llvm/test/MC/LoongArch/lsx/srarni.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsrarni.b.h $vr29, $vr20, 5 +-# CHECK-INST: vsrarni.b.h $vr29, $vr20, 5 +-# CHECK-ENCODING: encoding: [0x9d,0x56,0x5c,0x73] +- +-vsrarni.h.w $vr3, $vr29, 14 +-# CHECK-INST: vsrarni.h.w $vr3, $vr29, 14 +-# CHECK-ENCODING: encoding: [0xa3,0xbb,0x5c,0x73] +- +-vsrarni.w.d $vr14, $vr19, 10 +-# CHECK-INST: vsrarni.w.d $vr14, $vr19, 10 +-# CHECK-ENCODING: encoding: [0x6e,0x2a,0x5d,0x73] +- +-vsrarni.d.q $vr22, $vr27, 38 +-# CHECK-INST: vsrarni.d.q $vr22, $vr27, 38 +-# CHECK-ENCODING: encoding: [0x76,0x9b,0x5e,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/srl.s b/llvm/test/MC/LoongArch/lsx/srl.s +deleted file mode 100644 +index d6d806bfb..000000000 +--- a/llvm/test/MC/LoongArch/lsx/srl.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsrl.b $vr20, $vr7, $vr27 +-# CHECK-INST: vsrl.b $vr20, $vr7, $vr27 +-# CHECK-ENCODING: encoding: [0xf4,0x6c,0xea,0x70] +- +-vsrl.h $vr31, $vr5, $vr31 +-# CHECK-INST: vsrl.h $vr31, $vr5, $vr31 +-# CHECK-ENCODING: encoding: [0xbf,0xfc,0xea,0x70] +- +-vsrl.w $vr31, $vr0, $vr6 +-# CHECK-INST: vsrl.w $vr31, $vr0, $vr6 +-# CHECK-ENCODING: encoding: [0x1f,0x18,0xeb,0x70] +- +-vsrl.d $vr6, $vr8, $vr7 +-# CHECK-INST: vsrl.d $vr6, $vr8, $vr7 +-# CHECK-ENCODING: encoding: [0x06,0x9d,0xeb,0x70] +- +-vsrli.b $vr17, $vr8, 6 +-# CHECK-INST: vsrli.b $vr17, $vr8, 6 +-# CHECK-ENCODING: encoding: [0x11,0x39,0x30,0x73] +- +-vsrli.h $vr3, $vr31, 2 +-# CHECK-INST: vsrli.h $vr3, $vr31, 2 +-# CHECK-ENCODING: encoding: [0xe3,0x4b,0x30,0x73] +- +-vsrli.w $vr17, $vr5, 0 +-# CHECK-INST: vsrli.w $vr17, $vr5, 0 +-# CHECK-ENCODING: encoding: [0xb1,0x80,0x30,0x73] +- +-vsrli.d $vr16, $vr22, 34 +-# CHECK-INST: vsrli.d $vr16, $vr22, 34 +-# CHECK-ENCODING: encoding: [0xd0,0x8a,0x31,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/srln.s b/llvm/test/MC/LoongArch/lsx/srln.s +deleted file mode 100644 +index 55b1f1b92..000000000 +--- a/llvm/test/MC/LoongArch/lsx/srln.s ++++ /dev/null +@@ -1,16 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsrln.b.h $vr29, $vr28, $vr27 +-# CHECK-INST: vsrln.b.h $vr29, $vr28, $vr27 +-# CHECK-ENCODING: encoding: [0x9d,0xef,0xf4,0x70] +- +-vsrln.h.w $vr18, $vr17, $vr0 +-# CHECK-INST: vsrln.h.w $vr18, $vr17, $vr0 +-# CHECK-ENCODING: encoding: [0x32,0x02,0xf5,0x70] +- +-vsrln.w.d $vr16, $vr5, $vr19 +-# CHECK-INST: vsrln.w.d $vr16, $vr5, $vr19 +-# CHECK-ENCODING: encoding: [0xb0,0xcc,0xf5,0x70] +diff --git a/llvm/test/MC/LoongArch/lsx/srlni.s b/llvm/test/MC/LoongArch/lsx/srlni.s +deleted file mode 100644 +index 97c7831e8..000000000 +--- a/llvm/test/MC/LoongArch/lsx/srlni.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsrlni.b.h $vr15, $vr25, 9 +-# CHECK-INST: vsrlni.b.h $vr15, $vr25, 9 +-# CHECK-ENCODING: encoding: [0x2f,0x67,0x40,0x73] +- +-vsrlni.h.w $vr3, $vr0, 8 +-# CHECK-INST: vsrlni.h.w $vr3, $vr0, 8 +-# CHECK-ENCODING: encoding: [0x03,0xa0,0x40,0x73] +- +-vsrlni.w.d $vr19, $vr26, 51 +-# CHECK-INST: vsrlni.w.d $vr19, $vr26, 51 +-# CHECK-ENCODING: encoding: [0x53,0xcf,0x41,0x73] +- +-vsrlni.d.q $vr10, $vr18, 60 +-# CHECK-INST: vsrlni.d.q $vr10, $vr18, 60 +-# CHECK-ENCODING: encoding: [0x4a,0xf2,0x42,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/srlr.s b/llvm/test/MC/LoongArch/lsx/srlr.s +deleted file mode 100644 +index b78c178b5..000000000 +--- a/llvm/test/MC/LoongArch/lsx/srlr.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsrlr.b $vr27, $vr1, $vr6 +-# CHECK-INST: vsrlr.b $vr27, $vr1, $vr6 +-# CHECK-ENCODING: encoding: [0x3b,0x18,0xf0,0x70] +- +-vsrlr.h $vr31, $vr18, $vr2 +-# CHECK-INST: vsrlr.h $vr31, $vr18, $vr2 +-# CHECK-ENCODING: encoding: [0x5f,0x8a,0xf0,0x70] +- +-vsrlr.w $vr21, $vr29, $vr30 +-# CHECK-INST: vsrlr.w $vr21, $vr29, $vr30 +-# CHECK-ENCODING: encoding: [0xb5,0x7b,0xf1,0x70] +- +-vsrlr.d $vr4, $vr3, $vr30 +-# CHECK-INST: vsrlr.d $vr4, $vr3, $vr30 +-# CHECK-ENCODING: encoding: [0x64,0xf8,0xf1,0x70] +- +-vsrlri.b $vr20, $vr24, 6 +-# CHECK-INST: vsrlri.b $vr20, $vr24, 6 +-# CHECK-ENCODING: encoding: [0x14,0x3b,0xa4,0x72] +- +-vsrlri.h $vr23, $vr22, 4 +-# CHECK-INST: vsrlri.h $vr23, $vr22, 4 +-# CHECK-ENCODING: encoding: [0xd7,0x52,0xa4,0x72] +- +-vsrlri.w $vr19, $vr8, 1 +-# CHECK-INST: vsrlri.w $vr19, $vr8, 1 +-# CHECK-ENCODING: encoding: [0x13,0x85,0xa4,0x72] +- +-vsrlri.d $vr18, $vr30, 51 +-# CHECK-INST: vsrlri.d $vr18, $vr30, 51 +-# CHECK-ENCODING: encoding: [0xd2,0xcf,0xa5,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/srlrn.s b/llvm/test/MC/LoongArch/lsx/srlrn.s +deleted file mode 100644 +index a00cc80df..000000000 +--- a/llvm/test/MC/LoongArch/lsx/srlrn.s ++++ /dev/null +@@ -1,16 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsrlrn.b.h $vr10, $vr18, $vr11 +-# CHECK-INST: vsrlrn.b.h $vr10, $vr18, $vr11 +-# CHECK-ENCODING: encoding: [0x4a,0xae,0xf8,0x70] +- +-vsrlrn.h.w $vr28, $vr15, $vr22 +-# CHECK-INST: vsrlrn.h.w $vr28, $vr15, $vr22 +-# CHECK-ENCODING: encoding: [0xfc,0x59,0xf9,0x70] +- +-vsrlrn.w.d $vr19, $vr7, $vr26 +-# CHECK-INST: vsrlrn.w.d $vr19, $vr7, $vr26 +-# CHECK-ENCODING: encoding: [0xf3,0xe8,0xf9,0x70] +diff --git a/llvm/test/MC/LoongArch/lsx/srlrni.s b/llvm/test/MC/LoongArch/lsx/srlrni.s +deleted file mode 100644 +index 361914b44..000000000 +--- a/llvm/test/MC/LoongArch/lsx/srlrni.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsrlrni.b.h $vr15, $vr5, 3 +-# CHECK-INST: vsrlrni.b.h $vr15, $vr5, 3 +-# CHECK-ENCODING: encoding: [0xaf,0x4c,0x44,0x73] +- +-vsrlrni.h.w $vr28, $vr27, 1 +-# CHECK-INST: vsrlrni.h.w $vr28, $vr27, 1 +-# CHECK-ENCODING: encoding: [0x7c,0x87,0x44,0x73] +- +-vsrlrni.w.d $vr3, $vr25, 56 +-# CHECK-INST: vsrlrni.w.d $vr3, $vr25, 56 +-# CHECK-ENCODING: encoding: [0x23,0xe3,0x45,0x73] +- +-vsrlrni.d.q $vr4, $vr16, 13 +-# CHECK-INST: vsrlrni.d.q $vr4, $vr16, 13 +-# CHECK-ENCODING: encoding: [0x04,0x36,0x46,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/ssran.s b/llvm/test/MC/LoongArch/lsx/ssran.s +deleted file mode 100644 +index fefbd29a2..000000000 +--- a/llvm/test/MC/LoongArch/lsx/ssran.s ++++ /dev/null +@@ -1,28 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vssran.b.h $vr26, $vr26, $vr18 +-# CHECK-INST: vssran.b.h $vr26, $vr26, $vr18 +-# CHECK-ENCODING: encoding: [0x5a,0xcb,0xfe,0x70] +- +-vssran.h.w $vr21, $vr14, $vr11 +-# CHECK-INST: vssran.h.w $vr21, $vr14, $vr11 +-# CHECK-ENCODING: encoding: [0xd5,0x2d,0xff,0x70] +- +-vssran.w.d $vr4, $vr21, $vr11 +-# CHECK-INST: vssran.w.d $vr4, $vr21, $vr11 +-# CHECK-ENCODING: encoding: [0xa4,0xae,0xff,0x70] +- +-vssran.bu.h $vr10, $vr30, $vr19 +-# CHECK-INST: vssran.bu.h $vr10, $vr30, $vr19 +-# CHECK-ENCODING: encoding: [0xca,0xcf,0x06,0x71] +- +-vssran.hu.w $vr7, $vr8, $vr20 +-# CHECK-INST: vssran.hu.w $vr7, $vr8, $vr20 +-# CHECK-ENCODING: encoding: [0x07,0x51,0x07,0x71] +- +-vssran.wu.d $vr10, $vr21, $vr0 +-# CHECK-INST: vssran.wu.d $vr10, $vr21, $vr0 +-# CHECK-ENCODING: encoding: [0xaa,0x82,0x07,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/ssrani.s b/llvm/test/MC/LoongArch/lsx/ssrani.s +deleted file mode 100644 +index 20ac1cbad..000000000 +--- a/llvm/test/MC/LoongArch/lsx/ssrani.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vssrani.b.h $vr3, $vr12, 10 +-# CHECK-INST: vssrani.b.h $vr3, $vr12, 10 +-# CHECK-ENCODING: encoding: [0x83,0x69,0x60,0x73] +- +-vssrani.h.w $vr3, $vr25, 0 +-# CHECK-INST: vssrani.h.w $vr3, $vr25, 0 +-# CHECK-ENCODING: encoding: [0x23,0x83,0x60,0x73] +- +-vssrani.w.d $vr12, $vr19, 43 +-# CHECK-INST: vssrani.w.d $vr12, $vr19, 43 +-# CHECK-ENCODING: encoding: [0x6c,0xae,0x61,0x73] +- +-vssrani.d.q $vr25, $vr8, 13 +-# CHECK-INST: vssrani.d.q $vr25, $vr8, 13 +-# CHECK-ENCODING: encoding: [0x19,0x35,0x62,0x73] +- +-vssrani.bu.h $vr26, $vr16, 12 +-# CHECK-INST: vssrani.bu.h $vr26, $vr16, 12 +-# CHECK-ENCODING: encoding: [0x1a,0x72,0x64,0x73] +- +-vssrani.hu.w $vr31, $vr6, 28 +-# CHECK-INST: vssrani.hu.w $vr31, $vr6, 28 +-# CHECK-ENCODING: encoding: [0xdf,0xf0,0x64,0x73] +- +-vssrani.wu.d $vr29, $vr25, 2 +-# CHECK-INST: vssrani.wu.d $vr29, $vr25, 2 +-# CHECK-ENCODING: encoding: [0x3d,0x0b,0x65,0x73] +- +-vssrani.du.q $vr22, $vr27, 71 +-# CHECK-INST: vssrani.du.q $vr22, $vr27, 71 +-# CHECK-ENCODING: encoding: [0x76,0x1f,0x67,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/ssrarn.s b/llvm/test/MC/LoongArch/lsx/ssrarn.s +deleted file mode 100644 +index 8157423b2..000000000 +--- a/llvm/test/MC/LoongArch/lsx/ssrarn.s ++++ /dev/null +@@ -1,28 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vssrarn.b.h $vr27, $vr29, $vr23 +-# CHECK-INST: vssrarn.b.h $vr27, $vr29, $vr23 +-# CHECK-ENCODING: encoding: [0xbb,0xdf,0x02,0x71] +- +-vssrarn.h.w $vr13, $vr17, $vr0 +-# CHECK-INST: vssrarn.h.w $vr13, $vr17, $vr0 +-# CHECK-ENCODING: encoding: [0x2d,0x02,0x03,0x71] +- +-vssrarn.w.d $vr5, $vr11, $vr16 +-# CHECK-INST: vssrarn.w.d $vr5, $vr11, $vr16 +-# CHECK-ENCODING: encoding: [0x65,0xc1,0x03,0x71] +- +-vssrarn.bu.h $vr18, $vr10, $vr13 +-# CHECK-INST: vssrarn.bu.h $vr18, $vr10, $vr13 +-# CHECK-ENCODING: encoding: [0x52,0xb5,0x0a,0x71] +- +-vssrarn.hu.w $vr5, $vr25, $vr16 +-# CHECK-INST: vssrarn.hu.w $vr5, $vr25, $vr16 +-# CHECK-ENCODING: encoding: [0x25,0x43,0x0b,0x71] +- +-vssrarn.wu.d $vr6, $vr23, $vr30 +-# CHECK-INST: vssrarn.wu.d $vr6, $vr23, $vr30 +-# CHECK-ENCODING: encoding: [0xe6,0xfa,0x0b,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/ssrarni.s b/llvm/test/MC/LoongArch/lsx/ssrarni.s +deleted file mode 100644 +index 9a33f6711..000000000 +--- a/llvm/test/MC/LoongArch/lsx/ssrarni.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vssrarni.b.h $vr3, $vr9, 2 +-# CHECK-INST: vssrarni.b.h $vr3, $vr9, 2 +-# CHECK-ENCODING: encoding: [0x23,0x49,0x68,0x73] +- +-vssrarni.h.w $vr21, $vr17, 8 +-# CHECK-INST: vssrarni.h.w $vr21, $vr17, 8 +-# CHECK-ENCODING: encoding: [0x35,0xa2,0x68,0x73] +- +-vssrarni.w.d $vr7, $vr6, 5 +-# CHECK-INST: vssrarni.w.d $vr7, $vr6, 5 +-# CHECK-ENCODING: encoding: [0xc7,0x14,0x69,0x73] +- +-vssrarni.d.q $vr4, $vr22, 90 +-# CHECK-INST: vssrarni.d.q $vr4, $vr22, 90 +-# CHECK-ENCODING: encoding: [0xc4,0x6a,0x6b,0x73] +- +-vssrarni.bu.h $vr25, $vr0, 9 +-# CHECK-INST: vssrarni.bu.h $vr25, $vr0, 9 +-# CHECK-ENCODING: encoding: [0x19,0x64,0x6c,0x73] +- +-vssrarni.hu.w $vr5, $vr2, 24 +-# CHECK-INST: vssrarni.hu.w $vr5, $vr2, 24 +-# CHECK-ENCODING: encoding: [0x45,0xe0,0x6c,0x73] +- +-vssrarni.wu.d $vr23, $vr29, 25 +-# CHECK-INST: vssrarni.wu.d $vr23, $vr29, 25 +-# CHECK-ENCODING: encoding: [0xb7,0x67,0x6d,0x73] +- +-vssrarni.du.q $vr2, $vr12, 106 +-# CHECK-INST: vssrarni.du.q $vr2, $vr12, 106 +-# CHECK-ENCODING: encoding: [0x82,0xa9,0x6f,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/ssrln.s b/llvm/test/MC/LoongArch/lsx/ssrln.s +deleted file mode 100644 +index 1b00e3b54..000000000 +--- a/llvm/test/MC/LoongArch/lsx/ssrln.s ++++ /dev/null +@@ -1,28 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vssrln.b.h $vr20, $vr5, $vr20 +-# CHECK-INST: vssrln.b.h $vr20, $vr5, $vr20 +-# CHECK-ENCODING: encoding: [0xb4,0xd0,0xfc,0x70] +- +-vssrln.h.w $vr0, $vr21, $vr2 +-# CHECK-INST: vssrln.h.w $vr0, $vr21, $vr2 +-# CHECK-ENCODING: encoding: [0xa0,0x0a,0xfd,0x70] +- +-vssrln.w.d $vr16, $vr6, $vr3 +-# CHECK-INST: vssrln.w.d $vr16, $vr6, $vr3 +-# CHECK-ENCODING: encoding: [0xd0,0x8c,0xfd,0x70] +- +-vssrln.bu.h $vr6, $vr30, $vr9 +-# CHECK-INST: vssrln.bu.h $vr6, $vr30, $vr9 +-# CHECK-ENCODING: encoding: [0xc6,0xa7,0x04,0x71] +- +-vssrln.hu.w $vr2, $vr8, $vr3 +-# CHECK-INST: vssrln.hu.w $vr2, $vr8, $vr3 +-# CHECK-ENCODING: encoding: [0x02,0x0d,0x05,0x71] +- +-vssrln.wu.d $vr28, $vr28, $vr5 +-# CHECK-INST: vssrln.wu.d $vr28, $vr28, $vr5 +-# CHECK-ENCODING: encoding: [0x9c,0x97,0x05,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/ssrlni.s b/llvm/test/MC/LoongArch/lsx/ssrlni.s +deleted file mode 100644 +index eb630b3d6..000000000 +--- a/llvm/test/MC/LoongArch/lsx/ssrlni.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vssrlni.b.h $vr2, $vr23, 5 +-# CHECK-INST: vssrlni.b.h $vr2, $vr23, 5 +-# CHECK-ENCODING: encoding: [0xe2,0x56,0x48,0x73] +- +-vssrlni.h.w $vr15, $vr20, 12 +-# CHECK-INST: vssrlni.h.w $vr15, $vr20, 12 +-# CHECK-ENCODING: encoding: [0x8f,0xb2,0x48,0x73] +- +-vssrlni.w.d $vr27, $vr9, 7 +-# CHECK-INST: vssrlni.w.d $vr27, $vr9, 7 +-# CHECK-ENCODING: encoding: [0x3b,0x1d,0x49,0x73] +- +-vssrlni.d.q $vr10, $vr2, 4 +-# CHECK-INST: vssrlni.d.q $vr10, $vr2, 4 +-# CHECK-ENCODING: encoding: [0x4a,0x10,0x4a,0x73] +- +-vssrlni.bu.h $vr19, $vr3, 2 +-# CHECK-INST: vssrlni.bu.h $vr19, $vr3, 2 +-# CHECK-ENCODING: encoding: [0x73,0x48,0x4c,0x73] +- +-vssrlni.hu.w $vr31, $vr19, 1 +-# CHECK-INST: vssrlni.hu.w $vr31, $vr19, 1 +-# CHECK-ENCODING: encoding: [0x7f,0x86,0x4c,0x73] +- +-vssrlni.wu.d $vr13, $vr27, 6 +-# CHECK-INST: vssrlni.wu.d $vr13, $vr27, 6 +-# CHECK-ENCODING: encoding: [0x6d,0x1b,0x4d,0x73] +- +-vssrlni.du.q $vr11, $vr30, 32 +-# CHECK-INST: vssrlni.du.q $vr11, $vr30, 32 +-# CHECK-ENCODING: encoding: [0xcb,0x83,0x4e,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/ssrlrn.s b/llvm/test/MC/LoongArch/lsx/ssrlrn.s +deleted file mode 100644 +index e0eeb3ac2..000000000 +--- a/llvm/test/MC/LoongArch/lsx/ssrlrn.s ++++ /dev/null +@@ -1,28 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vssrlrn.b.h $vr28, $vr3, $vr15 +-# CHECK-INST: vssrlrn.b.h $vr28, $vr3, $vr15 +-# CHECK-ENCODING: encoding: [0x7c,0xbc,0x00,0x71] +- +-vssrlrn.h.w $vr22, $vr0, $vr9 +-# CHECK-INST: vssrlrn.h.w $vr22, $vr0, $vr9 +-# CHECK-ENCODING: encoding: [0x16,0x24,0x01,0x71] +- +-vssrlrn.w.d $vr6, $vr14, $vr21 +-# CHECK-INST: vssrlrn.w.d $vr6, $vr14, $vr21 +-# CHECK-ENCODING: encoding: [0xc6,0xd5,0x01,0x71] +- +-vssrlrn.bu.h $vr10, $vr24, $vr12 +-# CHECK-INST: vssrlrn.bu.h $vr10, $vr24, $vr12 +-# CHECK-ENCODING: encoding: [0x0a,0xb3,0x08,0x71] +- +-vssrlrn.hu.w $vr29, $vr6, $vr1 +-# CHECK-INST: vssrlrn.hu.w $vr29, $vr6, $vr1 +-# CHECK-ENCODING: encoding: [0xdd,0x04,0x09,0x71] +- +-vssrlrn.wu.d $vr2, $vr23, $vr7 +-# CHECK-INST: vssrlrn.wu.d $vr2, $vr23, $vr7 +-# CHECK-ENCODING: encoding: [0xe2,0x9e,0x09,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/ssrlrni.s b/llvm/test/MC/LoongArch/lsx/ssrlrni.s +deleted file mode 100644 +index 3c5c25fda..000000000 +--- a/llvm/test/MC/LoongArch/lsx/ssrlrni.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vssrlrni.b.h $vr18, $vr21, 6 +-# CHECK-INST: vssrlrni.b.h $vr18, $vr21, 6 +-# CHECK-ENCODING: encoding: [0xb2,0x5a,0x50,0x73] +- +-vssrlrni.h.w $vr7, $vr12, 9 +-# CHECK-INST: vssrlrni.h.w $vr7, $vr12, 9 +-# CHECK-ENCODING: encoding: [0x87,0xa5,0x50,0x73] +- +-vssrlrni.w.d $vr10, $vr14, 63 +-# CHECK-INST: vssrlrni.w.d $vr10, $vr14, 63 +-# CHECK-ENCODING: encoding: [0xca,0xfd,0x51,0x73] +- +-vssrlrni.d.q $vr12, $vr26, 68 +-# CHECK-INST: vssrlrni.d.q $vr12, $vr26, 68 +-# CHECK-ENCODING: encoding: [0x4c,0x13,0x53,0x73] +- +-vssrlrni.bu.h $vr22, $vr24, 1 +-# CHECK-INST: vssrlrni.bu.h $vr22, $vr24, 1 +-# CHECK-ENCODING: encoding: [0x16,0x47,0x54,0x73] +- +-vssrlrni.hu.w $vr27, $vr17, 7 +-# CHECK-INST: vssrlrni.hu.w $vr27, $vr17, 7 +-# CHECK-ENCODING: encoding: [0x3b,0x9e,0x54,0x73] +- +-vssrlrni.wu.d $vr3, $vr15, 56 +-# CHECK-INST: vssrlrni.wu.d $vr3, $vr15, 56 +-# CHECK-ENCODING: encoding: [0xe3,0xe1,0x55,0x73] +- +-vssrlrni.du.q $vr12, $vr10, 4 +-# CHECK-INST: vssrlrni.du.q $vr12, $vr10, 4 +-# CHECK-ENCODING: encoding: [0x4c,0x11,0x56,0x73] +diff --git a/llvm/test/MC/LoongArch/lsx/ssub.s b/llvm/test/MC/LoongArch/lsx/ssub.s +deleted file mode 100644 +index 603d26a05..000000000 +--- a/llvm/test/MC/LoongArch/lsx/ssub.s ++++ /dev/null +@@ -1,36 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vssub.b $vr10, $vr10, $vr11 +-# CHECK-INST: vssub.b $vr10, $vr10, $vr11 +-# CHECK-ENCODING: encoding: [0x4a,0x2d,0x48,0x70] +- +-vssub.h $vr2, $vr18, $vr5 +-# CHECK-INST: vssub.h $vr2, $vr18, $vr5 +-# CHECK-ENCODING: encoding: [0x42,0x96,0x48,0x70] +- +-vssub.w $vr28, $vr10, $vr2 +-# CHECK-INST: vssub.w $vr28, $vr10, $vr2 +-# CHECK-ENCODING: encoding: [0x5c,0x09,0x49,0x70] +- +-vssub.d $vr25, $vr3, $vr10 +-# CHECK-INST: vssub.d $vr25, $vr3, $vr10 +-# CHECK-ENCODING: encoding: [0x79,0xa8,0x49,0x70] +- +-vssub.bu $vr31, $vr13, $vr11 +-# CHECK-INST: vssub.bu $vr31, $vr13, $vr11 +-# CHECK-ENCODING: encoding: [0xbf,0x2d,0x4c,0x70] +- +-vssub.hu $vr15, $vr19, $vr9 +-# CHECK-INST: vssub.hu $vr15, $vr19, $vr9 +-# CHECK-ENCODING: encoding: [0x6f,0xa6,0x4c,0x70] +- +-vssub.wu $vr15, $vr12, $vr14 +-# CHECK-INST: vssub.wu $vr15, $vr12, $vr14 +-# CHECK-ENCODING: encoding: [0x8f,0x39,0x4d,0x70] +- +-vssub.du $vr29, $vr4, $vr11 +-# CHECK-INST: vssub.du $vr29, $vr4, $vr11 +-# CHECK-ENCODING: encoding: [0x9d,0xac,0x4d,0x70] +diff --git a/llvm/test/MC/LoongArch/lsx/st.s b/llvm/test/MC/LoongArch/lsx/st.s +deleted file mode 100644 +index e4e05aa2f..000000000 +--- a/llvm/test/MC/LoongArch/lsx/st.s ++++ /dev/null +@@ -1,12 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vst $vr9, $r17, 1700 +-# CHECK-INST: vst $vr9, $t5, 1700 +-# CHECK-ENCODING: encoding: [0x29,0x92,0x5a,0x2c] +- +-vstx $vr23, $r17, $r31 +-# CHECK-INST: vstx $vr23, $t5, $s8 +-# CHECK-ENCODING: encoding: [0x37,0x7e,0x44,0x38] +diff --git a/llvm/test/MC/LoongArch/lsx/stelm.s b/llvm/test/MC/LoongArch/lsx/stelm.s +deleted file mode 100644 +index 8935d9933..000000000 +--- a/llvm/test/MC/LoongArch/lsx/stelm.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vstelm.b $vr22, $r31, -90, 12 +-# CHECK-INST: vstelm.b $vr22, $s8, -90, 12 +-# CHECK-ENCODING: encoding: [0xf6,0x9b,0xb2,0x31] +- +-vstelm.h $vr28, $r2, 48, 7 +-# CHECK-INST: vstelm.h $vr28, $tp, 48, 7 +-# CHECK-ENCODING: encoding: [0x5c,0x60,0x5c,0x31] +- +-vstelm.w $vr18, $r12, -40, 2 +-# CHECK-INST: vstelm.w $vr18, $t0, -40, 2 +-# CHECK-ENCODING: encoding: [0x92,0xd9,0x2b,0x31] +- +-vstelm.d $vr4, $r23, -248, 1 +-# CHECK-INST: vstelm.d $vr4, $s0, -248, 1 +-# CHECK-ENCODING: encoding: [0xe4,0x86,0x17,0x31] +diff --git a/llvm/test/MC/LoongArch/lsx/sub.s b/llvm/test/MC/LoongArch/lsx/sub.s +deleted file mode 100644 +index 8f3c55a28..000000000 +--- a/llvm/test/MC/LoongArch/lsx/sub.s ++++ /dev/null +@@ -1,24 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsub.b $vr7, $vr21, $vr25 +-# CHECK-INST: vsub.b $vr7, $vr21, $vr25 +-# CHECK-ENCODING: encoding: [0xa7,0x66,0x0c,0x70] +- +-vsub.h $vr23, $vr7, $vr4 +-# CHECK-INST: vsub.h $vr23, $vr7, $vr4 +-# CHECK-ENCODING: encoding: [0xf7,0x90,0x0c,0x70] +- +-vsub.w $vr28, $vr27, $vr25 +-# CHECK-INST: vsub.w $vr28, $vr27, $vr25 +-# CHECK-ENCODING: encoding: [0x7c,0x67,0x0d,0x70] +- +-vsub.d $vr27, $vr11, $vr20 +-# CHECK-INST: vsub.d $vr27, $vr11, $vr20 +-# CHECK-ENCODING: encoding: [0x7b,0xd1,0x0d,0x70] +- +-vsub.q $vr8, $vr11, $vr15 +-# CHECK-INST: vsub.q $vr8, $vr11, $vr15 +-# CHECK-ENCODING: encoding: [0x68,0xbd,0x2d,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/subi.s b/llvm/test/MC/LoongArch/lsx/subi.s +deleted file mode 100644 +index d26f306b7..000000000 +--- a/llvm/test/MC/LoongArch/lsx/subi.s ++++ /dev/null +@@ -1,20 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsubi.bu $vr21, $vr1, 16 +-# CHECK-INST: vsubi.bu $vr21, $vr1, 16 +-# CHECK-ENCODING: encoding: [0x35,0x40,0x8c,0x72] +- +-vsubi.hu $vr10, $vr24, 8 +-# CHECK-INST: vsubi.hu $vr10, $vr24, 8 +-# CHECK-ENCODING: encoding: [0x0a,0xa3,0x8c,0x72] +- +-vsubi.wu $vr10, $vr13, 8 +-# CHECK-INST: vsubi.wu $vr10, $vr13, 8 +-# CHECK-ENCODING: encoding: [0xaa,0x21,0x8d,0x72] +- +-vsubi.du $vr27, $vr0, 29 +-# CHECK-INST: vsubi.du $vr27, $vr0, 29 +-# CHECK-ENCODING: encoding: [0x1b,0xf4,0x8d,0x72] +diff --git a/llvm/test/MC/LoongArch/lsx/subw.s b/llvm/test/MC/LoongArch/lsx/subw.s +deleted file mode 100644 +index 49fc2a02e..000000000 +--- a/llvm/test/MC/LoongArch/lsx/subw.s ++++ /dev/null +@@ -1,68 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vsubwev.h.b $vr21, $vr25, $vr20 +-# CHECK-INST: vsubwev.h.b $vr21, $vr25, $vr20 +-# CHECK-ENCODING: encoding: [0x35,0x53,0x20,0x70] +- +-vsubwev.w.h $vr11, $vr8, $vr10 +-# CHECK-INST: vsubwev.w.h $vr11, $vr8, $vr10 +-# CHECK-ENCODING: encoding: [0x0b,0xa9,0x20,0x70] +- +-vsubwev.d.w $vr30, $vr6, $vr24 +-# CHECK-INST: vsubwev.d.w $vr30, $vr6, $vr24 +-# CHECK-ENCODING: encoding: [0xde,0x60,0x21,0x70] +- +-vsubwev.q.d $vr4, $vr14, $vr23 +-# CHECK-INST: vsubwev.q.d $vr4, $vr14, $vr23 +-# CHECK-ENCODING: encoding: [0xc4,0xdd,0x21,0x70] +- +-vsubwev.h.bu $vr25, $vr20, $vr2 +-# CHECK-INST: vsubwev.h.bu $vr25, $vr20, $vr2 +-# CHECK-ENCODING: encoding: [0x99,0x0a,0x30,0x70] +- +-vsubwev.w.hu $vr1, $vr9, $vr28 +-# CHECK-INST: vsubwev.w.hu $vr1, $vr9, $vr28 +-# CHECK-ENCODING: encoding: [0x21,0xf1,0x30,0x70] +- +-vsubwev.d.wu $vr23, $vr13, $vr2 +-# CHECK-INST: vsubwev.d.wu $vr23, $vr13, $vr2 +-# CHECK-ENCODING: encoding: [0xb7,0x09,0x31,0x70] +- +-vsubwev.q.du $vr9, $vr28, $vr12 +-# CHECK-INST: vsubwev.q.du $vr9, $vr28, $vr12 +-# CHECK-ENCODING: encoding: [0x89,0xb3,0x31,0x70] +- +-vsubwod.h.b $vr9, $vr12, $vr26 +-# CHECK-INST: vsubwod.h.b $vr9, $vr12, $vr26 +-# CHECK-ENCODING: encoding: [0x89,0x69,0x24,0x70] +- +-vsubwod.w.h $vr31, $vr2, $vr10 +-# CHECK-INST: vsubwod.w.h $vr31, $vr2, $vr10 +-# CHECK-ENCODING: encoding: [0x5f,0xa8,0x24,0x70] +- +-vsubwod.d.w $vr6, $vr16, $vr15 +-# CHECK-INST: vsubwod.d.w $vr6, $vr16, $vr15 +-# CHECK-ENCODING: encoding: [0x06,0x3e,0x25,0x70] +- +-vsubwod.q.d $vr22, $vr0, $vr18 +-# CHECK-INST: vsubwod.q.d $vr22, $vr0, $vr18 +-# CHECK-ENCODING: encoding: [0x16,0xc8,0x25,0x70] +- +-vsubwod.h.bu $vr3, $vr17, $vr11 +-# CHECK-INST: vsubwod.h.bu $vr3, $vr17, $vr11 +-# CHECK-ENCODING: encoding: [0x23,0x2e,0x34,0x70] +- +-vsubwod.w.hu $vr9, $vr16, $vr26 +-# CHECK-INST: vsubwod.w.hu $vr9, $vr16, $vr26 +-# CHECK-ENCODING: encoding: [0x09,0xea,0x34,0x70] +- +-vsubwod.d.wu $vr23, $vr9, $vr8 +-# CHECK-INST: vsubwod.d.wu $vr23, $vr9, $vr8 +-# CHECK-ENCODING: encoding: [0x37,0x21,0x35,0x70] +- +-vsubwod.q.du $vr8, $vr15, $vr7 +-# CHECK-INST: vsubwod.q.du $vr8, $vr15, $vr7 +-# CHECK-ENCODING: encoding: [0xe8,0x9d,0x35,0x70] +diff --git a/llvm/test/MC/LoongArch/lsx/xor.s b/llvm/test/MC/LoongArch/lsx/xor.s +deleted file mode 100644 +index 4d8c6eedb..000000000 +--- a/llvm/test/MC/LoongArch/lsx/xor.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vxor.v $vr28, $vr16, $vr18 +-# CHECK-INST: vxor.v $vr28, $vr16, $vr18 +-# CHECK-ENCODING: encoding: [0x1c,0x4a,0x27,0x71] +diff --git a/llvm/test/MC/LoongArch/lsx/xori.s b/llvm/test/MC/LoongArch/lsx/xori.s +deleted file mode 100644 +index c06fb2179..000000000 +--- a/llvm/test/MC/LoongArch/lsx/xori.s ++++ /dev/null +@@ -1,8 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-vxori.b $vr13, $vr4, 74 +-# CHECK-INST: vxori.b $vr13, $vr4, 74 +-# CHECK-ENCODING: encoding: [0x8d,0x28,0xd9,0x73] +diff --git a/llvm/test/MC/LoongArch/lvz/lvz-err.s b/llvm/test/MC/LoongArch/lvz/lvz-err.s +deleted file mode 100644 +index 64b47a1fc..000000000 +--- a/llvm/test/MC/LoongArch/lvz/lvz-err.s ++++ /dev/null +@@ -1,31 +0,0 @@ +-# RUN: not llvm-mc --triple=loongarch64 %s 2>&1 | FileCheck %s +- +-gcsrrd $a0, 16384 +-# CHECK: :[[#@LINE-1]]:13: error: immediate must be an integer in the range [0, 16383] +- +-gcsrrd $a0, -1 +-# CHECK: :[[#@LINE-1]]:13: error: immediate must be an integer in the range [0, 16383] +- +-gcsrwr $a0, 16384 +-# CHECK: :[[#@LINE-1]]:13: error: immediate must be an integer in the range [0, 16383] +- +-gcsrwr $a0, -1 +-# CHECK: :[[#@LINE-1]]:13: error: immediate must be an integer in the range [0, 16383] +- +-gcsrxchg $a0, $a1, 16384 +-# CHECK: :[[#@LINE-1]]:20: error: immediate must be an integer in the range [0, 16383] +- +-gcsrxchg $a0, $a1, -1 +-# CHECK: :[[#@LINE-1]]:20: error: immediate must be an integer in the range [0, 16383] +- +-gcsrxchg $a0, $ra, 1 +-# CHECK: :[[#@LINE-1]]:16: error: must not be $r0 or $r1 +- +-gcsrxchg $a0, $zero, 1 +-# CHECK: :[[#@LINE-1]]:16: error: must not be $r0 or $r1 +- +-hvcl 32768 +-# CHECK: :[[#@LINE-1]]:6: error: immediate must be an integer in the range [0, 32767] +- +-hvcl -1 +-# CHECK: :[[#@LINE-1]]:6: error: immediate must be an integer in the range [0, 32767] +diff --git a/llvm/test/MC/LoongArch/lvz/lvz.s b/llvm/test/MC/LoongArch/lvz/lvz.s +deleted file mode 100644 +index 3727b2afe..000000000 +--- a/llvm/test/MC/LoongArch/lvz/lvz.s ++++ /dev/null +@@ -1,24 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch64 --show-encoding %s | \ +-# RUN: FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s | \ +-# RUN: llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-INST +- +-gcsrrd $a0, 1 +-# CHECK-INST: gcsrrd $a0, 1 +-# CHECK-ENCODING: encoding: [0x04,0x04,0x00,0x05] +- +-gcsrwr $a0, 1 +-# CHECK-INST: gcsrwr $a0, 1 +-# CHECK-ENCODING: encoding: [0x24,0x04,0x00,0x05] +- +-gcsrxchg $a0, $a1, 1 +-# CHECK-INST: gcsrxchg $a0, $a1, 1 +-# CHECK-ENCODING: encoding: [0xa4,0x04,0x00,0x05] +- +-gtlbflush +-# CHECK-INST: gtlbflush +-# CHECK-ENCODING: encoding: [0x01,0x24,0x48,0x06] +- +-hvcl 1 +-# CHECK-INST: hvcl 1 +-# CHECK-ENCODING: encoding: [0x01,0x80,0x2b,0x00] +diff --git a/llvm/test/MC/LoongArch/macro-la.s b/llvm/test/MC/LoongArch/macro-la.s +new file mode 100644 +index 000000000..136b8dc15 +--- /dev/null ++++ b/llvm/test/MC/LoongArch/macro-la.s +@@ -0,0 +1,207 @@ ++# RUN: llvm-mc %s -triple=loongarch64-unknown-linux-gnu -show-encoding | FileCheck %s ++# CHECK: la.pcrel $r4, symbol # encoding: [0x04,0x00,0x00,0x1c] ++# CHECK: # fixup A - offset: 0, value: (symbol)+2048, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup B - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup C - offset: 0, value: 0, kind: fixup_LARCH_SOP_SR ++# CHECK: # fixup D - offset: 0, value: 0, kind: fixup_LARCH_SOP_POP_32_S_5_20 ++# CHECK: # la expanded slot # encoding: [0x84,0x00,0xc0,0x02] ++# CHECK: # fixup A - offset: 0, value: (symbol)+4, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup B - offset: 0, value: (symbol)+2052, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup C - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup D - offset: 0, value: 0, kind: fixup_LARCH_SOP_SR ++# CHECK: # fixup E - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup F - offset: 0, value: 0, kind: fixup_LARCH_SOP_SL ++# CHECK: # fixup G - offset: 0, value: 0, kind: fixup_LARCH_SOP_SUB ++# CHECK: # fixup H - offset: 0, value: 0, kind: fixup_LARCH_SOP_POP_32_S_10_12 ++la.local $a0, symbol ++ ++# CHECK: la.local $r4, $r12, symbol # encoding: [0x04,0x00,0x00,0x1c] ++# CHECK: # fixup A - offset: 0, value: symbol, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup B - offset: 0, value: (symbol)+2147483648, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup C - offset: 0, value: 32, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup D - offset: 0, value: 0, kind: fixup_LARCH_SOP_SR ++# CHECK: # fixup E - offset: 0, value: 32, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup F - offset: 0, value: 0, kind: fixup_LARCH_SOP_SL ++# CHECK: # fixup G - offset: 0, value: 0, kind: fixup_LARCH_SOP_SUB ++# CHECK: # fixup H - offset: 0, value: 32, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup I - offset: 0, value: 0, kind: fixup_LARCH_SOP_SL ++# CHECK: # fixup J - offset: 0, value: 44, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup K - offset: 0, value: 0, kind: fixup_LARCH_SOP_SR ++# CHECK: # fixup L - offset: 0, value: 0, kind: fixup_LARCH_SOP_POP_32_S_5_20 ++# CHECK: # la expanded slot # encoding: [0x0c,0x00,0x80,0x03] ++# CHECK: # fixup A - offset: 0, value: (symbol)+4, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup B - offset: 0, value: (symbol)+2147483652, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup C - offset: 0, value: 32, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup D - offset: 0, value: 0, kind: fixup_LARCH_SOP_SR ++# CHECK: # fixup E - offset: 0, value: 32, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup F - offset: 0, value: 0, kind: fixup_LARCH_SOP_SL ++# CHECK: # fixup G - offset: 0, value: 0, kind: fixup_LARCH_SOP_SUB ++# CHECK: # fixup H - offset: 0, value: 4095, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup I - offset: 0, value: 0, kind: fixup_LARCH_SOP_AND ++# CHECK: # fixup J - offset: 0, value: 0, kind: fixup_LARCH_SOP_POP_32_U_10_12 ++# CHECK: # la expanded slot # encoding: [0x0c,0x00,0x00,0x16] ++# CHECK: # fixup A - offset: 0, value: (symbol)+2147483656, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup B - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup C - offset: 0, value: 0, kind: fixup_LARCH_SOP_SL ++# CHECK: # fixup D - offset: 0, value: 44, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup E - offset: 0, value: 0, kind: fixup_LARCH_SOP_SR ++# CHECK: # fixup F - offset: 0, value: 0, kind: fixup_LARCH_SOP_POP_32_S_5_20 ++# CHECK: # la expanded slot # encoding: [0x8c,0x01,0x00,0x03] ++# CHECK: # fixup A - offset: 0, value: (symbol)+2147483660, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup B - offset: 0, value: 52, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup C - offset: 0, value: 0, kind: fixup_LARCH_SOP_SR ++# CHECK: # fixup D - offset: 0, value: 0, kind: fixup_LARCH_SOP_POP_32_S_10_12 ++# CHECK: # la expanded slot # encoding: [0x84,0xb0,0x10,0x00] ++la.local $a0, $t0, symbol ++ ++# CHECK: la.got $r4, symbol # encoding: [0x04,0x00,0x00,0x1c] ++# CHECK: # fixup A - offset: 0, value: _GLOBAL_OFFSET_TABLE_+2048, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup B - offset: 0, value: symbol, kind: fixup_LARCH_SOP_PUSH_GPREL ++# CHECK: # fixup C - offset: 0, value: 0, kind: fixup_LARCH_SOP_ADD ++# CHECK: # fixup D - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup E - offset: 0, value: 0, kind: fixup_LARCH_SOP_SR ++# CHECK: # fixup F - offset: 0, value: 0, kind: fixup_LARCH_SOP_POP_32_S_5_20 ++# CHECK: # la expanded slot # encoding: [0x84,0x00,0xc0,0x28] ++# CHECK: # fixup A - offset: 0, value: _GLOBAL_OFFSET_TABLE_+4, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup B - offset: 0, value: symbol, kind: fixup_LARCH_SOP_PUSH_GPREL ++# CHECK: # fixup C - offset: 0, value: 0, kind: fixup_LARCH_SOP_ADD ++# CHECK: # fixup D - offset: 0, value: _GLOBAL_OFFSET_TABLE_+2052, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup E - offset: 0, value: symbol, kind: fixup_LARCH_SOP_PUSH_GPREL ++# CHECK: # fixup F - offset: 0, value: 0, kind: fixup_LARCH_SOP_ADD ++# CHECK: # fixup G - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup H - offset: 0, value: 0, kind: fixup_LARCH_SOP_SR ++# CHECK: # fixup I - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup J - offset: 0, value: 0, kind: fixup_LARCH_SOP_SL ++# CHECK: # fixup K - offset: 0, value: 0, kind: fixup_LARCH_SOP_SUB ++# CHECK: # fixup L - offset: 0, value: 0, kind: fixup_LARCH_SOP_POP_32_S_10_12 ++la.global $a0, symbol ++ ++# CHECK: la.pcrel $r4, symbol # encoding: [0x04,0x00,0x00,0x1c] ++# CHECK: # fixup A - offset: 0, value: (symbol)+2048, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup B - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup C - offset: 0, value: 0, kind: fixup_LARCH_SOP_SR ++# CHECK: # fixup D - offset: 0, value: 0, kind: fixup_LARCH_SOP_POP_32_S_5_20 ++# CHECK: # la expanded slot # encoding: [0x84,0x00,0xc0,0x02] ++# CHECK: # fixup A - offset: 0, value: (symbol)+4, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup B - offset: 0, value: (symbol)+2052, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup C - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup D - offset: 0, value: 0, kind: fixup_LARCH_SOP_SR ++# CHECK: # fixup E - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup F - offset: 0, value: 0, kind: fixup_LARCH_SOP_SL ++# CHECK: # fixup G - offset: 0, value: 0, kind: fixup_LARCH_SOP_SUB ++# CHECK: # fixup H - offset: 0, value: 0, kind: fixup_LARCH_SOP_POP_32_S_10_12 ++la.pcrel $a0, symbol ++ ++# CHECK: la.got $r4, symbol # encoding: [0x04,0x00,0x00,0x1c] ++# CHECK: # fixup A - offset: 0, value: _GLOBAL_OFFSET_TABLE_+2048, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup B - offset: 0, value: symbol, kind: fixup_LARCH_SOP_PUSH_GPREL ++# CHECK: # fixup C - offset: 0, value: 0, kind: fixup_LARCH_SOP_ADD ++# CHECK: # fixup D - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup E - offset: 0, value: 0, kind: fixup_LARCH_SOP_SR ++# CHECK: # fixup F - offset: 0, value: 0, kind: fixup_LARCH_SOP_POP_32_S_5_20 ++# CHECK: # la expanded slot # encoding: [0x84,0x00,0xc0,0x28] ++# CHECK: # fixup A - offset: 0, value: _GLOBAL_OFFSET_TABLE_+4, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup B - offset: 0, value: symbol, kind: fixup_LARCH_SOP_PUSH_GPREL ++# CHECK: # fixup C - offset: 0, value: 0, kind: fixup_LARCH_SOP_ADD ++# CHECK: # fixup D - offset: 0, value: _GLOBAL_OFFSET_TABLE_+2052, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup E - offset: 0, value: symbol, kind: fixup_LARCH_SOP_PUSH_GPREL ++# CHECK: # fixup F - offset: 0, value: 0, kind: fixup_LARCH_SOP_ADD ++# CHECK: # fixup G - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup H - offset: 0, value: 0, kind: fixup_LARCH_SOP_SR ++# CHECK: # fixup I - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup J - offset: 0, value: 0, kind: fixup_LARCH_SOP_SL ++# CHECK: # fixup K - offset: 0, value: 0, kind: fixup_LARCH_SOP_SUB ++# CHECK: # fixup L - offset: 0, value: 0, kind: fixup_LARCH_SOP_POP_32_S_10_12 ++la.got $a0, symbol ++ ++# CHECK: la.tls.le $r4, symbol # encoding: [0x04,0x00,0x00,0x14] ++# CHECK: # fixup A - offset: 0, value: symbol, kind: fixup_LARCH_SOP_PUSH_TLS_TPREL ++# CHECK: # fixup B - offset: 0, value: 32, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup C - offset: 0, value: 0, kind: fixup_LARCH_SOP_SL ++# CHECK: # fixup D - offset: 0, value: 44, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup E - offset: 0, value: 0, kind: fixup_LARCH_SOP_SR ++# CHECK: # fixup F - offset: 0, value: 0, kind: fixup_LARCH_SOP_POP_32_S_5_20 ++# CHECK: # la expanded slot # encoding: [0x84,0x00,0x80,0x03] ++# CHECK: # fixup A - offset: 0, value: symbol, kind: fixup_LARCH_SOP_PUSH_TLS_TPREL ++# CHECK: # fixup B - offset: 0, value: 4095, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup C - offset: 0, value: 0, kind: fixup_LARCH_SOP_AND ++# CHECK: # fixup D - offset: 0, value: 0, kind: fixup_LARCH_SOP_POP_32_U_10_12 ++# CHECK: # la expanded slot # encoding: [0x04,0x00,0x00,0x16] ++# CHECK: # fixup A - offset: 0, value: symbol, kind: fixup_LARCH_SOP_PUSH_TLS_TPREL ++# CHECK: # fixup B - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup C - offset: 0, value: 0, kind: fixup_LARCH_SOP_SL ++# CHECK: # fixup D - offset: 0, value: 44, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup E - offset: 0, value: 0, kind: fixup_LARCH_SOP_SR ++# CHECK: # fixup F - offset: 0, value: 0, kind: fixup_LARCH_SOP_POP_32_S_5_20 ++# CHECK: # la expanded slot # encoding: [0x84,0x00,0x00,0x03] ++# CHECK: # fixup A - offset: 0, value: symbol, kind: fixup_LARCH_SOP_PUSH_TLS_TPREL ++# CHECK: # fixup B - offset: 0, value: 52, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup C - offset: 0, value: 0, kind: fixup_LARCH_SOP_SR ++# CHECK: # fixup D - offset: 0, value: 0, kind: fixup_LARCH_SOP_POP_32_S_10_12 ++la.tls.le $a0, symbol ++ ++# CHECK: la.tls.ie $r4, symbol # encoding: [0x04,0x00,0x00,0x1c] ++# CHECK: # fixup A - offset: 0, value: _GLOBAL_OFFSET_TABLE_+2048, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup B - offset: 0, value: symbol, kind: fixup_LARCH_SOP_PUSH_TLS_GOT ++# CHECK: # fixup C - offset: 0, value: 0, kind: fixup_LARCH_SOP_ADD ++# CHECK: # fixup D - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup E - offset: 0, value: 0, kind: fixup_LARCH_SOP_SR ++# CHECK: # fixup F - offset: 0, value: 0, kind: fixup_LARCH_SOP_POP_32_S_5_20 ++# CHECK: # la expanded slot # encoding: [0x84,0x00,0xc0,0x28] ++# CHECK: # fixup A - offset: 0, value: _GLOBAL_OFFSET_TABLE_+4, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup B - offset: 0, value: symbol, kind: fixup_LARCH_SOP_PUSH_TLS_GOT ++# CHECK: # fixup C - offset: 0, value: 0, kind: fixup_LARCH_SOP_ADD ++# CHECK: # fixup D - offset: 0, value: _GLOBAL_OFFSET_TABLE_+2052, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup E - offset: 0, value: symbol, kind: fixup_LARCH_SOP_PUSH_TLS_GOT ++# CHECK: # fixup F - offset: 0, value: 0, kind: fixup_LARCH_SOP_ADD ++# CHECK: # fixup G - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup H - offset: 0, value: 0, kind: fixup_LARCH_SOP_SR ++# CHECK: # fixup I - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup J - offset: 0, value: 0, kind: fixup_LARCH_SOP_SL ++# CHECK: # fixup K - offset: 0, value: 0, kind: fixup_LARCH_SOP_SUB ++# CHECK: # fixup L - offset: 0, value: 0, kind: fixup_LARCH_SOP_POP_32_S_10_12 ++la.tls.ie $a0, symbol ++ ++# CHECK: la.tls.gd $r4, symbol # encoding: [0x04,0x00,0x00,0x1c] ++# CHECK: # fixup A - offset: 0, value: _GLOBAL_OFFSET_TABLE_+2048, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup B - offset: 0, value: symbol, kind: fixup_LARCH_SOP_PUSH_TLS_GD ++# CHECK: # fixup C - offset: 0, value: 0, kind: fixup_LARCH_SOP_ADD ++# CHECK: # fixup D - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup E - offset: 0, value: 0, kind: fixup_LARCH_SOP_SR ++# CHECK: # fixup F - offset: 0, value: 0, kind: fixup_LARCH_SOP_POP_32_S_5_20 ++# CHECK: # la expanded slot # encoding: [0x84,0x00,0xc0,0x02] ++# CHECK: # fixup A - offset: 0, value: _GLOBAL_OFFSET_TABLE_+4, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup B - offset: 0, value: symbol, kind: fixup_LARCH_SOP_PUSH_TLS_GD ++# CHECK: # fixup C - offset: 0, value: 0, kind: fixup_LARCH_SOP_ADD ++# CHECK: # fixup D - offset: 0, value: _GLOBAL_OFFSET_TABLE_+2052, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup E - offset: 0, value: symbol, kind: fixup_LARCH_SOP_PUSH_TLS_GD ++# CHECK: # fixup F - offset: 0, value: 0, kind: fixup_LARCH_SOP_ADD ++# CHECK: # fixup G - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup H - offset: 0, value: 0, kind: fixup_LARCH_SOP_SR ++# CHECK: # fixup I - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup J - offset: 0, value: 0, kind: fixup_LARCH_SOP_SL ++# CHECK: # fixup K - offset: 0, value: 0, kind: fixup_LARCH_SOP_SUB ++# CHECK: # fixup L - offset: 0, value: 0, kind: fixup_LARCH_SOP_POP_32_S_10_12 ++la.tls.ld $a0, symbol ++ ++# CHECK: la.tls.gd $r4, symbol # encoding: [0x04,0x00,0x00,0x1c] ++# CHECK: # fixup A - offset: 0, value: _GLOBAL_OFFSET_TABLE_+2048, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup B - offset: 0, value: symbol, kind: fixup_LARCH_SOP_PUSH_TLS_GD ++# CHECK: # fixup C - offset: 0, value: 0, kind: fixup_LARCH_SOP_ADD ++# CHECK: # fixup D - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup E - offset: 0, value: 0, kind: fixup_LARCH_SOP_SR ++# CHECK: # fixup F - offset: 0, value: 0, kind: fixup_LARCH_SOP_POP_32_S_5_20 ++# CHECK: # la expanded slot # encoding: [0x84,0x00,0xc0,0x02] ++# CHECK: # fixup A - offset: 0, value: _GLOBAL_OFFSET_TABLE_+4, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup B - offset: 0, value: symbol, kind: fixup_LARCH_SOP_PUSH_TLS_GD ++# CHECK: # fixup C - offset: 0, value: 0, kind: fixup_LARCH_SOP_ADD ++# CHECK: # fixup D - offset: 0, value: _GLOBAL_OFFSET_TABLE_+2052, kind: fixup_LARCH_SOP_PUSH_PCREL ++# CHECK: # fixup E - offset: 0, value: symbol, kind: fixup_LARCH_SOP_PUSH_TLS_GD ++# CHECK: # fixup F - offset: 0, value: 0, kind: fixup_LARCH_SOP_ADD ++# CHECK: # fixup G - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup H - offset: 0, value: 0, kind: fixup_LARCH_SOP_SR ++# CHECK: # fixup I - offset: 0, value: 12, kind: fixup_LARCH_SOP_PUSH_ABSOLUTE ++# CHECK: # fixup J - offset: 0, value: 0, kind: fixup_LARCH_SOP_SL ++# CHECK: # fixup K - offset: 0, value: 0, kind: fixup_LARCH_SOP_SUB ++# CHECK: # fixup L - offset: 0, value: 0, kind: fixup_LARCH_SOP_POP_32_S_10_12 ++la.tls.gd $a0, symbol +diff --git a/llvm/test/MC/LoongArch/macro-li.s b/llvm/test/MC/LoongArch/macro-li.s +new file mode 100644 +index 000000000..b1a7c58ba +--- /dev/null ++++ b/llvm/test/MC/LoongArch/macro-li.s +@@ -0,0 +1,773 @@ ++# RUN: llvm-mc %s -triple=loongarch64-unknown-linux-gnu | FileCheck %s ++li.w $a0, 0x00000000 # CHECK: ori $r4, $zero, 0 ++li.w $a0, 0x000007ff # CHECK: ori $r4, $zero, 2047 ++li.w $a0, 0x00000800 # CHECK: ori $r4, $zero, 2048 ++li.w $a0, 0x00000fff # CHECK: ori $r4, $zero, 4095 ++li.w $a0, 0x7ffff000 # CHECK: lu12i.w $r4, 524287 ++li.w $a0, 0x7ffff7ff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2047 ++li.w $a0, 0x7ffff800 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2048 ++li.w $a0, 0x7fffffff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 4095 ++li.w $a0, 0x80000000 # CHECK: lu12i.w $r4, -524288 ++li.w $a0, 0x800007ff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2047 ++li.w $a0, 0x80000800 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2048 ++li.w $a0, 0x80000fff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 4095 ++li.w $a0, 0xfffff000 # CHECK: lu12i.w $r4, -1 ++li.w $a0, 0xfffff7ff # CHECK: lu12i.w $r4, -1 ++ # CHECK: ori $r4, $r4, 2047 ++li.w $a0, 0xfffff800 # CHECK: addi.w $r4, $zero, -2048 ++li.w $a0, 0xffffffff # CHECK: addi.w $r4, $zero, -1 ++li.d $a0, 0x0000000000000000 # CHECK: addi.d $r4, $zero, 0 ++li.d $a0, 0x00000000000007ff # CHECK: addi.d $r4, $zero, 2047 ++li.d $a0, 0x0000000000000800 # CHECK: ori $r4, $zero, 2048 ++li.d $a0, 0x0000000000000fff # CHECK: ori $r4, $zero, 4095 ++li.d $a0, 0x000000007ffff000 # CHECK: lu12i.w $r4, 524287 ++li.d $a0, 0x000000007ffff7ff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2047 ++li.d $a0, 0x000000007ffff800 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2048 ++li.d $a0, 0x000000007fffffff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 4095 ++li.d $a0, 0x0000000080000000 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: lu32i.d $r4, 0 ++li.d $a0, 0x00000000800007ff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, 0 ++li.d $a0, 0x0000000080000800 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, 0 ++li.d $a0, 0x0000000080000fff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, 0 ++li.d $a0, 0x00000000fffff000 # CHECK: lu12i.w $r4, -1 ++ # CHECK: lu32i.d $r4, 0 ++li.d $a0, 0x00000000fffff7ff # CHECK: lu12i.w $r4, -1 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, 0 ++li.d $a0, 0x00000000fffff800 # CHECK: addi.w $r4, $zero, -2048 ++ # CHECK: lu32i.d $r4, 0 ++li.d $a0, 0x00000000ffffffff # CHECK: addi.w $r4, $zero, -1 ++ # CHECK: lu32i.d $r4, 0 ++li.d $a0, 0x0007ffff00000000 # CHECK: ori $r4, $zero, 0 ++ # CHECK: lu32i.d $r4, 524287 ++li.d $a0, 0x0007ffff000007ff # CHECK: ori $r4, $zero, 2047 ++ # CHECK: lu32i.d $r4, 524287 ++li.d $a0, 0x0007ffff00000800 # CHECK: ori $r4, $zero, 2048 ++ # CHECK: lu32i.d $r4, 524287 ++li.d $a0, 0x0007ffff00000fff # CHECK: ori $r4, $zero, 4095 ++ # CHECK: lu32i.d $r4, 524287 ++li.d $a0, 0x0007ffff7ffff000 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: lu32i.d $r4, 524287 ++li.d $a0, 0x0007ffff7ffff7ff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, 524287 ++li.d $a0, 0x0007ffff7ffff800 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, 524287 ++li.d $a0, 0x0007ffff7fffffff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, 524287 ++li.d $a0, 0x0007ffff80000000 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: lu32i.d $r4, 524287 ++li.d $a0, 0x0007ffff800007ff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, 524287 ++li.d $a0, 0x0007ffff80000800 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, 524287 ++li.d $a0, 0x0007ffff80000fff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, 524287 ++li.d $a0, 0x0007fffffffff000 # CHECK: lu12i.w $r4, -1 ++ # CHECK: lu32i.d $r4, 524287 ++li.d $a0, 0x0007fffffffff7ff # CHECK: lu12i.w $r4, -1 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, 524287 ++li.d $a0, 0x0007fffffffff800 # CHECK: addi.w $r4, $zero, -2048 ++ # CHECK: lu32i.d $r4, 524287 ++li.d $a0, 0x0007ffffffffffff # CHECK: addi.w $r4, $zero, -1 ++ # CHECK: lu32i.d $r4, 524287 ++li.d $a0, 0x0008000000000000 # CHECK: ori $r4, $zero, 0 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x00080000000007ff # CHECK: ori $r4, $zero, 2047 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x0008000000000800 # CHECK: ori $r4, $zero, 2048 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x0008000000000fff # CHECK: ori $r4, $zero, 4095 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x000800007ffff000 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x000800007ffff7ff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x000800007ffff800 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x000800007fffffff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x0008000080000000 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x00080000800007ff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x0008000080000800 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x0008000080000fff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x00080000fffff000 # CHECK: lu12i.w $r4, -1 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x00080000fffff7ff # CHECK: lu12i.w $r4, -1 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x00080000fffff800 # CHECK: addi.w $r4, $zero, -2048 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x00080000ffffffff # CHECK: addi.w $r4, $zero, -1 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x000fffff00000000 # CHECK: ori $r4, $zero, 0 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x000fffff000007ff # CHECK: ori $r4, $zero, 2047 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x000fffff00000800 # CHECK: ori $r4, $zero, 2048 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x000fffff00000fff # CHECK: ori $r4, $zero, 4095 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x000fffff7ffff000 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x000fffff7ffff7ff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x000fffff7ffff800 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x000fffff7fffffff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x000fffff80000000 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x000fffff800007ff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x000fffff80000800 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x000fffff80000fff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x000ffffffffff000 # CHECK: lu12i.w $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x000ffffffffff7ff # CHECK: lu12i.w $r4, -1 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x000ffffffffff800 # CHECK: addi.w $r4, $zero, -2048 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x000fffffffffffff # CHECK: addi.w $r4, $zero, -1 ++ # CHECK: lu52i.d $r4, $r4, 0 ++li.d $a0, 0x7ff0000000000000 # CHECK: lu52i.d $r4, $zero, 2047 ++li.d $a0, 0x7ff00000000007ff # CHECK: ori $r4, $zero, 2047 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff0000000000800 # CHECK: ori $r4, $zero, 2048 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff0000000000fff # CHECK: ori $r4, $zero, 4095 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff000007ffff000 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff000007ffff7ff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff000007ffff800 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff000007fffffff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff0000080000000 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff00000800007ff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff0000080000800 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff0000080000fff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff00000fffff000 # CHECK: lu12i.w $r4, -1 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff00000fffff7ff # CHECK: lu12i.w $r4, -1 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff00000fffff800 # CHECK: addi.w $r4, $zero, -2048 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff00000ffffffff # CHECK: addi.w $r4, $zero, -1 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff7ffff00000000 # CHECK: ori $r4, $zero, 0 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff7ffff000007ff # CHECK: ori $r4, $zero, 2047 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff7ffff00000800 # CHECK: ori $r4, $zero, 2048 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff7ffff00000fff # CHECK: ori $r4, $zero, 4095 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff7ffff7ffff000 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff7ffff7ffff7ff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff7ffff7ffff800 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff7ffff7fffffff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff7ffff80000000 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff7ffff800007ff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff7ffff80000800 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff7ffff80000fff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff7fffffffff000 # CHECK: lu12i.w $r4, -1 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff7fffffffff7ff # CHECK: lu12i.w $r4, -1 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff7fffffffff800 # CHECK: addi.w $r4, $zero, -2048 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff7ffffffffffff # CHECK: addi.w $r4, $zero, -1 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff8000000000000 # CHECK: ori $r4, $zero, 0 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff80000000007ff # CHECK: ori $r4, $zero, 2047 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff8000000000800 # CHECK: ori $r4, $zero, 2048 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff8000000000fff # CHECK: ori $r4, $zero, 4095 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff800007ffff000 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff800007ffff7ff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff800007ffff800 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff800007fffffff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff8000080000000 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff80000800007ff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff8000080000800 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff8000080000fff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff80000fffff000 # CHECK: lu12i.w $r4, -1 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff80000fffff7ff # CHECK: lu12i.w $r4, -1 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff80000fffff800 # CHECK: addi.w $r4, $zero, -2048 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ff80000ffffffff # CHECK: addi.w $r4, $zero, -1 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7fffffff00000000 # CHECK: ori $r4, $zero, 0 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7fffffff000007ff # CHECK: ori $r4, $zero, 2047 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7fffffff00000800 # CHECK: ori $r4, $zero, 2048 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7fffffff00000fff # CHECK: ori $r4, $zero, 4095 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7fffffff7ffff000 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7fffffff7ffff7ff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7fffffff7ffff800 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7fffffff7fffffff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7fffffff80000000 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7fffffff800007ff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7fffffff80000800 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7fffffff80000fff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ffffffffffff000 # CHECK: lu12i.w $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ffffffffffff7ff # CHECK: lu12i.w $r4, -1 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7ffffffffffff800 # CHECK: addi.w $r4, $zero, -2048 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x7fffffffffffffff # CHECK: addi.w $r4, $zero, -1 ++ # CHECK: lu52i.d $r4, $r4, 2047 ++li.d $a0, 0x8000000000000000 # CHECK: lu52i.d $r4, $zero, -2048 ++li.d $a0, 0x80000000000007ff # CHECK: ori $r4, $zero, 2047 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8000000000000800 # CHECK: ori $r4, $zero, 2048 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8000000000000fff # CHECK: ori $r4, $zero, 4095 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800000007ffff000 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800000007ffff7ff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800000007ffff800 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800000007fffffff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8000000080000000 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x80000000800007ff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8000000080000800 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8000000080000fff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x80000000fffff000 # CHECK: lu12i.w $r4, -1 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x80000000fffff7ff # CHECK: lu12i.w $r4, -1 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x80000000fffff800 # CHECK: addi.w $r4, $zero, -2048 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x80000000ffffffff # CHECK: addi.w $r4, $zero, -1 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8007ffff00000000 # CHECK: ori $r4, $zero, 0 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8007ffff000007ff # CHECK: ori $r4, $zero, 2047 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8007ffff00000800 # CHECK: ori $r4, $zero, 2048 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8007ffff00000fff # CHECK: ori $r4, $zero, 4095 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8007ffff7ffff000 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8007ffff7ffff7ff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8007ffff7ffff800 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8007ffff7fffffff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8007ffff80000000 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8007ffff800007ff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8007ffff80000800 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8007ffff80000fff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8007fffffffff000 # CHECK: lu12i.w $r4, -1 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8007fffffffff7ff # CHECK: lu12i.w $r4, -1 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8007fffffffff800 # CHECK: addi.w $r4, $zero, -2048 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8007ffffffffffff # CHECK: addi.w $r4, $zero, -1 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8008000000000000 # CHECK: ori $r4, $zero, 0 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x80080000000007ff # CHECK: ori $r4, $zero, 2047 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8008000000000800 # CHECK: ori $r4, $zero, 2048 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8008000000000fff # CHECK: ori $r4, $zero, 4095 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800800007ffff000 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800800007ffff7ff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800800007ffff800 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800800007fffffff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8008000080000000 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x80080000800007ff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8008000080000800 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x8008000080000fff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x80080000fffff000 # CHECK: lu12i.w $r4, -1 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x80080000fffff7ff # CHECK: lu12i.w $r4, -1 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x80080000fffff800 # CHECK: addi.w $r4, $zero, -2048 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x80080000ffffffff # CHECK: addi.w $r4, $zero, -1 ++ # CHECK: lu32i.d $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800fffff00000000 # CHECK: ori $r4, $zero, 0 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800fffff000007ff # CHECK: ori $r4, $zero, 2047 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800fffff00000800 # CHECK: ori $r4, $zero, 2048 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800fffff00000fff # CHECK: ori $r4, $zero, 4095 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800fffff7ffff000 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800fffff7ffff7ff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800fffff7ffff800 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800fffff7fffffff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800fffff80000000 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800fffff800007ff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800fffff80000800 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800fffff80000fff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800ffffffffff000 # CHECK: lu12i.w $r4, -1 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800ffffffffff7ff # CHECK: lu12i.w $r4, -1 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800ffffffffff800 # CHECK: addi.w $r4, $zero, -2048 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0x800fffffffffffff # CHECK: addi.w $r4, $zero, -1 ++ # CHECK: lu52i.d $r4, $r4, -2048 ++li.d $a0, 0xfff0000000000000 # CHECK: lu52i.d $r4, $zero, -1 ++li.d $a0, 0xfff00000000007ff # CHECK: ori $r4, $zero, 2047 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff0000000000800 # CHECK: ori $r4, $zero, 2048 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff0000000000fff # CHECK: ori $r4, $zero, 4095 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff000007ffff000 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff000007ffff7ff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff000007ffff800 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff000007fffffff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff0000080000000 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff00000800007ff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff0000080000800 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff0000080000fff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff00000fffff000 # CHECK: lu12i.w $r4, -1 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff00000fffff7ff # CHECK: lu12i.w $r4, -1 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff00000fffff800 # CHECK: addi.w $r4, $zero, -2048 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff00000ffffffff # CHECK: addi.w $r4, $zero, -1 ++ # CHECK: lu32i.d $r4, 0 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff7ffff00000000 # CHECK: ori $r4, $zero, 0 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff7ffff000007ff # CHECK: ori $r4, $zero, 2047 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff7ffff00000800 # CHECK: ori $r4, $zero, 2048 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff7ffff00000fff # CHECK: ori $r4, $zero, 4095 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff7ffff7ffff000 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff7ffff7ffff7ff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff7ffff7ffff800 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff7ffff7fffffff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff7ffff80000000 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff7ffff800007ff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff7ffff80000800 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff7ffff80000fff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff7fffffffff000 # CHECK: lu12i.w $r4, -1 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff7fffffffff7ff # CHECK: lu12i.w $r4, -1 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff7fffffffff800 # CHECK: addi.w $r4, $zero, -2048 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff7ffffffffffff # CHECK: addi.w $r4, $zero, -1 ++ # CHECK: lu32i.d $r4, 524287 ++ # CHECK: lu52i.d $r4, $r4, -1 ++li.d $a0, 0xfff8000000000000 # CHECK: ori $r4, $zero, 0 ++ # CHECK: lu32i.d $r4, -524288 ++li.d $a0, 0xfff80000000007ff # CHECK: ori $r4, $zero, 2047 ++ # CHECK: lu32i.d $r4, -524288 ++li.d $a0, 0xfff8000000000800 # CHECK: ori $r4, $zero, 2048 ++ # CHECK: lu32i.d $r4, -524288 ++li.d $a0, 0xfff8000000000fff # CHECK: ori $r4, $zero, 4095 ++ # CHECK: lu32i.d $r4, -524288 ++li.d $a0, 0xfff800007ffff000 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: lu32i.d $r4, -524288 ++li.d $a0, 0xfff800007ffff7ff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, -524288 ++li.d $a0, 0xfff800007ffff800 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, -524288 ++li.d $a0, 0xfff800007fffffff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, -524288 ++li.d $a0, 0xfff8000080000000 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: lu32i.d $r4, -524288 ++li.d $a0, 0xfff80000800007ff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, -524288 ++li.d $a0, 0xfff8000080000800 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, -524288 ++li.d $a0, 0xfff8000080000fff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, -524288 ++li.d $a0, 0xfff80000fffff000 # CHECK: lu12i.w $r4, -1 ++ # CHECK: lu32i.d $r4, -524288 ++li.d $a0, 0xfff80000fffff7ff # CHECK: lu12i.w $r4, -1 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, -524288 ++li.d $a0, 0xfff80000fffff800 # CHECK: addi.w $r4, $zero, -2048 ++ # CHECK: lu32i.d $r4, -524288 ++li.d $a0, 0xfff80000ffffffff # CHECK: addi.w $r4, $zero, -1 ++ # CHECK: lu32i.d $r4, -524288 ++li.d $a0, 0xffffffff00000000 # CHECK: ori $r4, $zero, 0 ++ # CHECK: lu32i.d $r4, -1 ++li.d $a0, 0xffffffff000007ff # CHECK: ori $r4, $zero, 2047 ++ # CHECK: lu32i.d $r4, -1 ++li.d $a0, 0xffffffff00000800 # CHECK: ori $r4, $zero, 2048 ++ # CHECK: lu32i.d $r4, -1 ++li.d $a0, 0xffffffff00000fff # CHECK: ori $r4, $zero, 4095 ++ # CHECK: lu32i.d $r4, -1 ++li.d $a0, 0xffffffff7ffff000 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: lu32i.d $r4, -1 ++li.d $a0, 0xffffffff7ffff7ff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2047 ++ # CHECK: lu32i.d $r4, -1 ++li.d $a0, 0xffffffff7ffff800 # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 2048 ++ # CHECK: lu32i.d $r4, -1 ++li.d $a0, 0xffffffff7fffffff # CHECK: lu12i.w $r4, 524287 ++ # CHECK: ori $r4, $r4, 4095 ++ # CHECK: lu32i.d $r4, -1 ++li.d $a0, 0xffffffff80000000 # CHECK: lu12i.w $r4, -524288 ++li.d $a0, 0xffffffff800007ff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2047 ++li.d $a0, 0xffffffff80000800 # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 2048 ++li.d $a0, 0xffffffff80000fff # CHECK: lu12i.w $r4, -524288 ++ # CHECK: ori $r4, $r4, 4095 ++li.d $a0, 0xfffffffffffff000 # CHECK: lu12i.w $r4, -1 ++li.d $a0, 0xfffffffffffff7ff # CHECK: lu12i.w $r4, -1 ++ # CHECK: ori $r4, $r4, 2047 ++li.d $a0, 0xfffffffffffff800 # CHECK: addi.d $r4, $zero, -2048 ++li.d $a0, 0xffffffffffffffff # CHECK: addi.d $r4, $zero, -1 +diff --git a/llvm/test/MC/LoongArch/Relocations/reloc-directive-err.s b/llvm/test/MC/LoongArch/reloc-directive-err.s +similarity index 100% +rename from llvm/test/MC/LoongArch/Relocations/reloc-directive-err.s +rename to llvm/test/MC/LoongArch/reloc-directive-err.s +diff --git a/llvm/test/MC/LoongArch/reloc-directive.s b/llvm/test/MC/LoongArch/reloc-directive.s +new file mode 100644 +index 000000000..282da7f28 +--- /dev/null ++++ b/llvm/test/MC/LoongArch/reloc-directive.s +@@ -0,0 +1,177 @@ ++# RUN: llvm-mc --triple=loongarch64 %s | FileCheck --check-prefix=PRINT %s ++# RUN: llvm-mc --filetype=obj --triple=loongarch64 %s \ ++# RUN: | llvm-readobj -r - | FileCheck %s ++ ++# PRINT: .reloc 0, R_LARCH_NONE, 0 ++# PRINT-NEXT: .reloc 1, R_LARCH_32, 1 ++# PRINT-NEXT: .reloc 2, R_LARCH_64, 2 ++# PRINT-NEXT: .reloc 3, R_LARCH_RELATIVE, 3 ++# PRINT-NEXT: .reloc 4, R_LARCH_COPY, 4 ++# PRINT-NEXT: .reloc 5, R_LARCH_JUMP_SLOT, 5 ++# PRINT-NEXT: .reloc 6, R_LARCH_TLS_DTPMOD32, 6 ++# PRINT-NEXT: .reloc 7, R_LARCH_TLS_DTPMOD64, 7 ++# PRINT-NEXT: .reloc 8, R_LARCH_TLS_DTPREL32, 8 ++# PRINT-NEXT: .reloc 9, R_LARCH_TLS_DTPREL64, 9 ++# PRINT-NEXT: .reloc 10, R_LARCH_TLS_TPREL32, 10 ++# PRINT-NEXT: .reloc 11, R_LARCH_TLS_TPREL64, 11 ++# PRINT-NEXT: .reloc 12, R_LARCH_IRELATIVE, 12 ++# PRINT-NEXT: .reloc 13, BFD_RELOC_NONE, 13 ++# PRINT-NEXT: .reloc 14, BFD_RELOC_32, 14 ++# PRINT-NEXT: .reloc 15, BFD_RELOC_64, 15 ++# PRINT-NEXT: .reloc 20, R_LARCH_MARK_LA, 20 ++# PRINT-NEXT: .reloc 21, R_LARCH_MARK_PCREL, 21 ++# PRINT-NEXT: .reloc 22, R_LARCH_SOP_PUSH_PCREL, 22 ++# PRINT-NEXT: .reloc 23, R_LARCH_SOP_PUSH_ABSOLUTE, 23 ++# PRINT-NEXT: .reloc 24, R_LARCH_SOP_PUSH_DUP, 24 ++# PRINT-NEXT: .reloc 25, R_LARCH_SOP_PUSH_GPREL, 25 ++# PRINT-NEXT: .reloc 26, R_LARCH_SOP_PUSH_TLS_TPREL, 26 ++# PRINT-NEXT: .reloc 27, R_LARCH_SOP_PUSH_TLS_GOT, 27 ++# PRINT-NEXT: .reloc 28, R_LARCH_SOP_PUSH_TLS_GD, 28 ++# PRINT-NEXT: .reloc 29, R_LARCH_SOP_PUSH_PLT_PCREL, 29 ++# PRINT-NEXT: .reloc 30, R_LARCH_SOP_ASSERT, 30 ++# PRINT-NEXT: .reloc 31, R_LARCH_SOP_NOT, 31 ++# PRINT-NEXT: .reloc 32, R_LARCH_SOP_SUB, 32 ++# PRINT-NEXT: .reloc 33, R_LARCH_SOP_SL, 33 ++# PRINT-NEXT: .reloc 34, R_LARCH_SOP_SR, 34 ++# PRINT-NEXT: .reloc 35, R_LARCH_SOP_ADD, 35 ++# PRINT-NEXT: .reloc 36, R_LARCH_SOP_AND, 36 ++# PRINT-NEXT: .reloc 37, R_LARCH_SOP_IF_ELSE, 37 ++# PRINT-NEXT: .reloc 38, R_LARCH_SOP_POP_32_S_10_5, 38 ++# PRINT-NEXT: .reloc 39, R_LARCH_SOP_POP_32_U_10_12, 39 ++# PRINT-NEXT: .reloc 40, R_LARCH_SOP_POP_32_S_10_12, 40 ++# PRINT-NEXT: .reloc 41, R_LARCH_SOP_POP_32_S_10_16, 41 ++# PRINT-NEXT: .reloc 42, R_LARCH_SOP_POP_32_S_10_16_S2, 42 ++# PRINT-NEXT: .reloc 43, R_LARCH_SOP_POP_32_S_5_20, 43 ++# PRINT-NEXT: .reloc 44, R_LARCH_SOP_POP_32_S_0_5_10_16_S2, 44 ++# PRINT-NEXT: .reloc 45, R_LARCH_SOP_POP_32_S_0_10_10_16_S2, 45 ++# PRINT-NEXT: .reloc 46, R_LARCH_SOP_POP_32_U, 46 ++# PRINT-NEXT: .reloc 47, R_LARCH_ADD8, 47 ++# PRINT-NEXT: .reloc 48, R_LARCH_ADD16, 48 ++# PRINT-NEXT: .reloc 49, R_LARCH_ADD24, 49 ++# PRINT-NEXT: .reloc 50, R_LARCH_ADD32, 50 ++# PRINT-NEXT: .reloc 51, R_LARCH_ADD64, 51 ++# PRINT-NEXT: .reloc 52, R_LARCH_SUB8, 52 ++# PRINT-NEXT: .reloc 53, R_LARCH_SUB16, 53 ++# PRINT-NEXT: .reloc 54, R_LARCH_SUB24, 54 ++# PRINT-NEXT: .reloc 55, R_LARCH_SUB32, 55 ++# PRINT-NEXT: .reloc 56, R_LARCH_SUB64, 56 ++# PRINT-NEXT: .reloc 57, R_LARCH_GNU_VTINHERIT, 57 ++# PRINT-NEXT: .reloc 58, R_LARCH_GNU_VTENTRY, 58 ++ ++.text ++ .fill 59, 1, 0x0 ++ .reloc 0, R_LARCH_NONE, 0 ++ .reloc 1, R_LARCH_32, 1 ++ .reloc 2, R_LARCH_64, 2 ++ .reloc 3, R_LARCH_RELATIVE, 3 ++ .reloc 4, R_LARCH_COPY, 4 ++ .reloc 5, R_LARCH_JUMP_SLOT, 5 ++ .reloc 6, R_LARCH_TLS_DTPMOD32, 6 ++ .reloc 7, R_LARCH_TLS_DTPMOD64, 7 ++ .reloc 8, R_LARCH_TLS_DTPREL32, 8 ++ .reloc 9, R_LARCH_TLS_DTPREL64, 9 ++ .reloc 10, R_LARCH_TLS_TPREL32, 10 ++ .reloc 11, R_LARCH_TLS_TPREL64, 11 ++ .reloc 12, R_LARCH_IRELATIVE, 12 ++ .reloc 13, BFD_RELOC_NONE, 13 ++ .reloc 14, BFD_RELOC_32, 14 ++ .reloc 15, BFD_RELOC_64, 15 ++ .reloc 20, R_LARCH_MARK_LA, 20 ++ .reloc 21, R_LARCH_MARK_PCREL, 21 ++ .reloc 22, R_LARCH_SOP_PUSH_PCREL, 22 ++ .reloc 23, R_LARCH_SOP_PUSH_ABSOLUTE, 23 ++ .reloc 24, R_LARCH_SOP_PUSH_DUP, 24 ++ .reloc 25, R_LARCH_SOP_PUSH_GPREL, 25 ++ .reloc 26, R_LARCH_SOP_PUSH_TLS_TPREL, 26 ++ .reloc 27, R_LARCH_SOP_PUSH_TLS_GOT, 27 ++ .reloc 28, R_LARCH_SOP_PUSH_TLS_GD, 28 ++ .reloc 29, R_LARCH_SOP_PUSH_PLT_PCREL, 29 ++ .reloc 30, R_LARCH_SOP_ASSERT, 30 ++ .reloc 31, R_LARCH_SOP_NOT, 31 ++ .reloc 32, R_LARCH_SOP_SUB, 32 ++ .reloc 33, R_LARCH_SOP_SL, 33 ++ .reloc 34, R_LARCH_SOP_SR, 34 ++ .reloc 35, R_LARCH_SOP_ADD, 35 ++ .reloc 36, R_LARCH_SOP_AND, 36 ++ .reloc 37, R_LARCH_SOP_IF_ELSE, 37 ++ .reloc 38, R_LARCH_SOP_POP_32_S_10_5, 38 ++ .reloc 39, R_LARCH_SOP_POP_32_U_10_12, 39 ++ .reloc 40, R_LARCH_SOP_POP_32_S_10_12, 40 ++ .reloc 41, R_LARCH_SOP_POP_32_S_10_16, 41 ++ .reloc 42, R_LARCH_SOP_POP_32_S_10_16_S2, 42 ++ .reloc 43, R_LARCH_SOP_POP_32_S_5_20, 43 ++ .reloc 44, R_LARCH_SOP_POP_32_S_0_5_10_16_S2, 44 ++ .reloc 45, R_LARCH_SOP_POP_32_S_0_10_10_16_S2, 45 ++ .reloc 46, R_LARCH_SOP_POP_32_U, 46 ++ .reloc 47, R_LARCH_ADD8, 47 ++ .reloc 48, R_LARCH_ADD16, 48 ++ .reloc 49, R_LARCH_ADD24, 49 ++ .reloc 50, R_LARCH_ADD32, 50 ++ .reloc 51, R_LARCH_ADD64, 51 ++ .reloc 52, R_LARCH_SUB8, 52 ++ .reloc 53, R_LARCH_SUB16, 53 ++ .reloc 54, R_LARCH_SUB24, 54 ++ .reloc 55, R_LARCH_SUB32, 55 ++ .reloc 56, R_LARCH_SUB64, 56 ++ .reloc 57, R_LARCH_GNU_VTINHERIT, 57 ++ .reloc 58, R_LARCH_GNU_VTENTRY, 58 ++ ++# CHECK: Relocations [ ++# CHECK-NEXT: Section ({{.*}}) .rela.text { ++# CHECK-NEXT: 0x0 R_LARCH_NONE - 0x0 ++# CHECK-NEXT: 0x1 R_LARCH_32 - 0x1 ++# CHECK-NEXT: 0x2 R_LARCH_64 - 0x2 ++# CHECK-NEXT: 0x3 R_LARCH_RELATIVE - 0x3 ++# CHECK-NEXT: 0x4 R_LARCH_COPY - 0x4 ++# CHECK-NEXT: 0x5 R_LARCH_JUMP_SLOT - 0x5 ++# CHECK-NEXT: 0x6 R_LARCH_TLS_DTPMOD32 - 0x6 ++# CHECK-NEXT: 0x7 R_LARCH_TLS_DTPMOD64 - 0x7 ++# CHECK-NEXT: 0x8 R_LARCH_TLS_DTPREL32 - 0x8 ++# CHECK-NEXT: 0x9 R_LARCH_TLS_DTPREL64 - 0x9 ++# CHECK-NEXT: 0xA R_LARCH_TLS_TPREL32 - 0xA ++# CHECK-NEXT: 0xB R_LARCH_TLS_TPREL64 - 0xB ++# CHECK-NEXT: 0xC R_LARCH_IRELATIVE - 0xC ++# CHECK-NEXT: 0xD R_LARCH_NONE - 0xD ++# CHECK-NEXT: 0xE R_LARCH_32 - 0xE ++# CHECK-NEXT: 0xF R_LARCH_64 - 0xF ++# CHECK-NEXT: 0x14 R_LARCH_MARK_LA - 0x14 ++# CHECK-NEXT: 0x15 R_LARCH_MARK_PCREL - 0x15 ++# CHECK-NEXT: 0x16 R_LARCH_SOP_PUSH_PCREL - 0x16 ++# CHECK-NEXT: 0x17 R_LARCH_SOP_PUSH_ABSOLUTE - 0x17 ++# CHECK-NEXT: 0x18 R_LARCH_SOP_PUSH_DUP - 0x18 ++# CHECK-NEXT: 0x19 R_LARCH_SOP_PUSH_GPREL - 0x19 ++# CHECK-NEXT: 0x1A R_LARCH_SOP_PUSH_TLS_TPREL - 0x1A ++# CHECK-NEXT: 0x1B R_LARCH_SOP_PUSH_TLS_GOT - 0x1B ++# CHECK-NEXT: 0x1C R_LARCH_SOP_PUSH_TLS_GD - 0x1C ++# CHECK-NEXT: 0x1D R_LARCH_SOP_PUSH_PLT_PCREL - 0x1D ++# CHECK-NEXT: 0x1E R_LARCH_SOP_ASSERT - 0x1E ++# CHECK-NEXT: 0x1F R_LARCH_SOP_NOT - 0x1F ++# CHECK-NEXT: 0x20 R_LARCH_SOP_SUB - 0x20 ++# CHECK-NEXT: 0x21 R_LARCH_SOP_SL - 0x21 ++# CHECK-NEXT: 0x22 R_LARCH_SOP_SR - 0x22 ++# CHECK-NEXT: 0x23 R_LARCH_SOP_ADD - 0x23 ++# CHECK-NEXT: 0x24 R_LARCH_SOP_AND - 0x24 ++# CHECK-NEXT: 0x25 R_LARCH_SOP_IF_ELSE - 0x25 ++# CHECK-NEXT: 0x26 R_LARCH_SOP_POP_32_S_10_5 - 0x26 ++# CHECK-NEXT: 0x27 R_LARCH_SOP_POP_32_U_10_12 - 0x27 ++# CHECK-NEXT: 0x28 R_LARCH_SOP_POP_32_S_10_12 - 0x28 ++# CHECK-NEXT: 0x29 R_LARCH_SOP_POP_32_S_10_16 - 0x29 ++# CHECK-NEXT: 0x2A R_LARCH_SOP_POP_32_S_10_16_S2 - 0x2A ++# CHECK-NEXT: 0x2B R_LARCH_SOP_POP_32_S_5_20 - 0x2B ++# CHECK-NEXT: 0x2C R_LARCH_SOP_POP_32_S_0_5_10_16_S2 - 0x2C ++# CHECK-NEXT: 0x2D R_LARCH_SOP_POP_32_S_0_10_10_16_S2 - 0x2D ++# CHECK-NEXT: 0x2E R_LARCH_SOP_POP_32_U - 0x2E ++# CHECK-NEXT: 0x2F R_LARCH_ADD8 - 0x2F ++# CHECK-NEXT: 0x30 R_LARCH_ADD16 - 0x30 ++# CHECK-NEXT: 0x31 R_LARCH_ADD24 - 0x31 ++# CHECK-NEXT: 0x32 R_LARCH_ADD32 - 0x32 ++# CHECK-NEXT: 0x33 R_LARCH_ADD64 - 0x33 ++# CHECK-NEXT: 0x34 R_LARCH_SUB8 - 0x34 ++# CHECK-NEXT: 0x35 R_LARCH_SUB16 - 0x35 ++# CHECK-NEXT: 0x36 R_LARCH_SUB24 - 0x36 ++# CHECK-NEXT: 0x37 R_LARCH_SUB32 - 0x37 ++# CHECK-NEXT: 0x38 R_LARCH_SUB64 - 0x38 ++# CHECK-NEXT: 0x39 R_LARCH_GNU_VTINHERIT - 0x39 ++# CHECK-NEXT: 0x3A R_LARCH_GNU_VTENTRY - 0x3A ++# CHECK-NEXT: } ++# CHECK-NEXT: ] +diff --git a/llvm/test/MC/LoongArch/unaligned-nops.s b/llvm/test/MC/LoongArch/unaligned-nops.s +new file mode 100644 +index 000000000..453e2cdca +--- /dev/null ++++ b/llvm/test/MC/LoongArch/unaligned-nops.s +@@ -0,0 +1,5 @@ ++# RUN: not --crash llvm-mc -filetype=obj -triple=loongarch64 %s -o %t ++.byte 1 ++# CHECK: LLVM ERROR: unable to write nop sequence of 3 bytes ++.p2align 2 ++foo: +diff --git a/llvm/test/MC/LoongArch/valid_12imm.s b/llvm/test/MC/LoongArch/valid_12imm.s +new file mode 100644 +index 000000000..ed44180bf +--- /dev/null ++++ b/llvm/test/MC/LoongArch/valid_12imm.s +@@ -0,0 +1,33 @@ ++# RUN: llvm-mc %s -triple=loongarch64-unknown-linux-gnu -show-encoding | FileCheck %s ++# CHECK: slti $r27, $ra, 235 ++# CHECK: encoding: [0x3b,0xac,0x03,0x02] ++slti $r27, $ra, 235 ++ ++# CHECK: sltui $zero, $r8, 162 ++# CHECK: encoding: [0x00,0x89,0x42,0x02] ++sltui $zero, $r8, 162 ++ ++# CHECK: addi.w $r5, $r7, 246 ++# CHECK: encoding: [0xe5,0xd8,0x83,0x02] ++addi.w $r5, $r7, 246 ++ ++# CHECK: addi.d $r28, $r6, 75 ++# CHECK: encoding: [0xdc,0x2c,0xc1,0x02] ++addi.d $r28, $r6, 75 ++ ++# CHECK: lu52i.d $r13, $r4, 195 ++# CHECK: encoding: [0x8d,0x0c,0x03,0x03] ++lu52i.d $r13, $r4, 195 ++ ++# CHECK: andi $r25, $zero, 106 ++# CHECK: encoding: [0x19,0xa8,0x41,0x03] ++andi $r25, $zero, 106 ++ ++# CHECK: ori $r17, $r5, 47 ++# CHECK: encoding: [0xb1,0xbc,0x80,0x03] ++ori $r17, $r5, 47 ++ ++# CHECK: xori $r18, $r23, 99 ++# CHECK: encoding: [0xf2,0x8e,0xc1,0x03] ++xori $r18, $r23, 99 ++ +diff --git a/llvm/test/MC/LoongArch/valid_4operands.s b/llvm/test/MC/LoongArch/valid_4operands.s +new file mode 100644 +index 000000000..1418bb677 +--- /dev/null ++++ b/llvm/test/MC/LoongArch/valid_4operands.s +@@ -0,0 +1,53 @@ ++# RUN: llvm-mc %s -triple=loongarch64-unknown-linux-gnu -show-encoding | FileCheck %s ++# CHECK: fmadd.s $f3, $f16, $f3, $f15 ++# CHECK: encoding: [0x03,0x8e,0x17,0x08] ++fmadd.s $f3, $f16, $f3, $f15 ++ ++# CHECK: fmadd.d $f21, $f24, $f28, $f24 ++# CHECK: encoding: [0x15,0x73,0x2c,0x08] ++fmadd.d $f21, $f24, $f28, $f24 ++ ++# CHECK: fmsub.s $f23, $f11, $f21, $f4 ++# CHECK: encoding: [0x77,0x55,0x52,0x08] ++fmsub.s $f23, $f11, $f21, $f4 ++ ++# CHECK: fmsub.d $f6, $f18, $f20, $f27 ++# CHECK: encoding: [0x46,0xd2,0x6d,0x08] ++fmsub.d $f6, $f18, $f20, $f27 ++ ++# CHECK: fnmadd.s $f29, $f1, $f24, $f20 ++# CHECK: encoding: [0x3d,0x60,0x9a,0x08] ++fnmadd.s $f29, $f1, $f24, $f20 ++ ++# CHECK: fnmadd.d $f25, $f13, $f19, $f30 ++# CHECK: encoding: [0xb9,0x4d,0xaf,0x08] ++fnmadd.d $f25, $f13, $f19, $f30 ++ ++# CHECK: fnmsub.s $f8, $f4, $f24, $f25 ++# CHECK: encoding: [0x88,0xe0,0xdc,0x08] ++fnmsub.s $f8, $f4, $f24, $f25 ++ ++# CHECK: fnmsub.d $f30, $f26, $f7, $f24 ++# CHECK: encoding: [0x5e,0x1f,0xec,0x08] ++fnmsub.d $f30, $f26, $f7, $f24 ++ ++# CHECK: fcmp.ceq.s $fcc7, $f17, $f29 ++# CHECK: encoding: [0x27,0x76,0x12,0x0c] ++fcmp.ceq.s $fcc7, $f17, $f29 ++ ++# CHECK: fcmp.ceq.d $fcc4, $f12, $f9 ++# CHECK: encoding: [0x84,0x25,0x22,0x0c] ++fcmp.ceq.d $fcc4, $f12, $f9 ++ ++# CHECK: fcmp.cult.s $fcc0, $f0, $f1 ++# CHECK: encoding: [0x00,0x04,0x15,0x0c] ++fcmp.cult.s $fcc0, $f0, $f1 ++ ++# CHECK: fcmp.cult.d $fcc2, $f3, $f4 ++# CHECK: encoding: [0x62,0x10,0x25,0x0c] ++fcmp.cult.d $fcc2, $f3, $f4 ++ ++# CHECK: fsel $f18, $f20, $f21, $fcc4 ++# CHECK: encoding: [0x92,0x56,0x02,0x0d] ++fsel $f18, $f20, $f21, $fcc4 ++ +diff --git a/llvm/test/MC/LoongArch/valid_bigimm.s b/llvm/test/MC/LoongArch/valid_bigimm.s +new file mode 100644 +index 000000000..d7b3bbb7d +--- /dev/null ++++ b/llvm/test/MC/LoongArch/valid_bigimm.s +@@ -0,0 +1,33 @@ ++# RUN: llvm-mc %s -triple=loongarch64-unknown-linux-gnu -show-encoding | FileCheck %s ++# CHECK: addu16i.d $r9, $r23, 23 ++# CHECK: encoding: [0xe9,0x5e,0x00,0x10] ++addu16i.d $r9, $r23, 23 ++ ++# CHECK: lu12i.w $r16, 49 ++# CHECK: encoding: [0x30,0x06,0x00,0x14] ++lu12i.w $r16, 49 ++ ++# CHECK: lu12i.w $r4, -1 ++# CHECK: encoding: [0xe4,0xff,0xff,0x15] ++lu12i.w $r4, -1 ++ ++# CHECK: lu32i.d $sp, 196 ++# CHECK: encoding: [0x83,0x18,0x00,0x16] ++lu32i.d $sp, 196 ++ ++# CHECK: pcaddi $r9, 187 ++# CHECK: encoding: [0x69,0x17,0x00,0x18] ++pcaddi $r9, 187 ++ ++# CHECK: pcalau12i $r10, 89 ++# CHECK: encoding: [0x2a,0x0b,0x00,0x1a] ++pcalau12i $r10, 89 ++ ++# CHECK: pcaddu12i $zero, 37 ++# CHECK: encoding: [0xa0,0x04,0x00,0x1c] ++pcaddu12i $zero, 37 ++ ++# CHECK: pcaddu18i $r12, 26 ++# CHECK: encoding: [0x4c,0x03,0x00,0x1e] ++pcaddu18i $r12, 26 ++ +diff --git a/llvm/test/MC/LoongArch/valid_branch.s b/llvm/test/MC/LoongArch/valid_branch.s +new file mode 100644 +index 000000000..8db9847e7 +--- /dev/null ++++ b/llvm/test/MC/LoongArch/valid_branch.s +@@ -0,0 +1,155 @@ ++# RUN: llvm-mc %s -triple=loongarch64-unknown-linux-gnu -show-encoding \ ++# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ,CHECK-ASM %s ++# RUN: llvm-mc %s -triple=loongarch64-unknown-linux-gnu -filetype=obj \ ++# RUN: | llvm-objdump --no-print-imm-hex -d - | FileCheck -check-prefix=CHECK-ASM-AND-OBJ %s ++ ++## random operands ++# CHECK-ASM-AND-OBJ: beqz $r9, 96 ++# CHECK-ASM: encoding: [0x20,0x61,0x00,0x40] ++beqz $r9, 96 ++ ++# CHECK-ASM-AND-OBJ: bnez $sp, 212 ++# CHECK-ASM: encoding: [0x60,0xd4,0x00,0x44] ++bnez $sp, 212 ++ ++# CHECK-ASM-AND-OBJ: bceqz $fcc6, 12 ++# CHECK-ASM: encoding: [0xc0,0x0c,0x00,0x48] ++bceqz $fcc6, 12 ++ ++# CHECK-ASM-AND-OBJ: bcnez $fcc6, 72 ++# CHECK-ASM: encoding: [0xc0,0x49,0x00,0x48] ++bcnez $fcc6, 72 ++ ++# CHECK-ASM-AND-OBJ: b 248 ++# CHECK-ASM: encoding: [0x00,0xf8,0x00,0x50] ++b 248 ++ ++# CHECK-ASM-AND-OBJ: bl 236 ++# CHECK-ASM: encoding: [0x00,0xec,0x00,0x54] ++bl 236 ++ ++# CHECK-ASM-AND-OBJ: beq $r10, $r7, 176 ++# CHECK-ASM: encoding: [0x47,0xb1,0x00,0x58] ++beq $r10, $r7, 176 ++ ++# CHECK-ASM-AND-OBJ: bne $r25, $ra, 136 ++# CHECK-ASM: encoding: [0x21,0x8b,0x00,0x5c] ++bne $r25, $ra, 136 ++ ++# CHECK-ASM-AND-OBJ: blt $r15, $r30, 168 ++# CHECK-ASM: encoding: [0xfe,0xa9,0x00,0x60] ++blt $r15, $r30, 168 ++ ++# CHECK-ASM-AND-OBJ: bge $r12, $r15, 148 ++# CHECK-ASM: encoding: [0x8f,0x95,0x00,0x64] ++bge $r12, $r15, 148 ++ ++# CHECK-ASM-AND-OBJ: bltu $r17, $r5, 4 ++# CHECK-ASM: encoding: [0x25,0x06,0x00,0x68] ++bltu $r17, $r5, 4 ++ ++# CHECK-ASM-AND-OBJ: bgeu $r6, $r23, 140 ++# CHECK-ASM: encoding: [0xd7,0x8c,0x00,0x6c] ++bgeu $r6, $r23, 140 ++ ++ ++## immediate lower/upper boundary ++### simm16 << 2 ++# CHECK-ASM-AND-OBJ: beq $r10, $r7, -131072 ++# CHECK-ASM: encoding: [0x47,0x01,0x00,0x5a] ++beq $r10, $r7, -0x20000 ++ ++# CHECK-ASM-AND-OBJ: beq $r10, $r7, 131068 ++# CHECK-ASM: encoding: [0x47,0xfd,0xff,0x59] ++beq $r10, $r7, 0x1FFFC ++ ++# CHECK-ASM-AND-OBJ: bne $r10, $r7, -131072 ++# CHECK-ASM: encoding: [0x47,0x01,0x00,0x5e] ++bne $r10, $r7, -0x20000 ++ ++# CHECK-ASM-AND-OBJ: bne $r10, $r7, 131068 ++# CHECK-ASM: encoding: [0x47,0xfd,0xff,0x5d] ++bne $r10, $r7, 0x1FFFC ++ ++# CHECK-ASM-AND-OBJ: blt $r10, $r7, -131072 ++# CHECK-ASM: encoding: [0x47,0x01,0x00,0x62] ++blt $r10, $r7, -0x20000 ++ ++# CHECK-ASM-AND-OBJ: blt $r10, $r7, 131068 ++# CHECK-ASM: encoding: [0x47,0xfd,0xff,0x61] ++blt $r10, $r7, 0x1FFFC ++ ++# CHECK-ASM-AND-OBJ: bge $r10, $r7, -131072 ++# CHECK-ASM: encoding: [0x47,0x01,0x00,0x66] ++bge $r10, $r7, -0x20000 ++ ++# CHECK-ASM-AND-OBJ: bge $r10, $r7, 131068 ++# CHECK-ASM: encoding: [0x47,0xfd,0xff,0x65] ++bge $r10, $r7, 0x1FFFC ++ ++# CHECK-ASM-AND-OBJ: bltu $r10, $r7, -131072 ++# CHECK-ASM: encoding: [0x47,0x01,0x00,0x6a] ++bltu $r10, $r7, -0x20000 ++ ++# CHECK-ASM-AND-OBJ: bltu $r10, $r7, 131068 ++# CHECK-ASM: encoding: [0x47,0xfd,0xff,0x69] ++bltu $r10, $r7, 0x1FFFC ++ ++# CHECK-ASM-AND-OBJ: bgeu $r10, $r7, -131072 ++# CHECK-ASM: encoding: [0x47,0x01,0x00,0x6e] ++bgeu $r10, $r7, -0x20000 ++ ++# CHECK-ASM-AND-OBJ: bgeu $r10, $r7, 131068 ++# CHECK-ASM: encoding: [0x47,0xfd,0xff,0x6d] ++bgeu $r10, $r7, 0x1FFFC ++ ++### simm21 << 2 ++# CHECK-ASM-AND-OBJ: beqz $r9, -4194304 ++# CHECK-ASM: encoding: [0x30,0x01,0x00,0x40] ++beqz $r9, -0x400000 ++ ++# CHECK-ASM-AND-OBJ: beqz $r9, 4194300 ++# CHECK-ASM: encoding: [0x2f,0xfd,0xff,0x43] ++beqz $r9, 0x3FFFFC ++ ++# CHECK-ASM-AND-OBJ: bnez $r9, -4194304 ++# CHECK-ASM: encoding: [0x30,0x01,0x00,0x44] ++bnez $r9, -0x400000 ++ ++# CHECK-ASM-AND-OBJ: bnez $r9, 4194300 ++# CHECK-ASM: encoding: [0x2f,0xfd,0xff,0x47] ++bnez $r9, 0x3FFFFC ++ ++# CHECK-ASM-AND-OBJ: bceqz $fcc6, -4194304 ++# CHECK-ASM: encoding: [0xd0,0x00,0x00,0x48] ++bceqz $fcc6, -0x400000 ++ ++# CHECK-ASM-AND-OBJ: bceqz $fcc6, 4194300 ++# CHECK-ASM: encoding: [0xcf,0xfc,0xff,0x4b] ++bceqz $fcc6, 0x3FFFFC ++ ++# CHECK-ASM-AND-OBJ: bcnez $fcc6, -4194304 ++# CHECK-ASM: encoding: [0xd0,0x01,0x00,0x48] ++bcnez $fcc6, -0x400000 ++ ++# CHECK-ASM-AND-OBJ: bcnez $fcc6, 4194300 ++# CHECK-ASM: encoding: [0xcf,0xfd,0xff,0x4b] ++bcnez $fcc6, 0x3FFFFC ++ ++### simm26 << 2 ++# CHECK-ASM-AND-OBJ: b -134217728 ++# CHECK-ASM: encoding: [0x00,0x02,0x00,0x50] ++b -0x8000000 ++ ++# CHECK-ASM-AND-OBJ: b 134217724 ++# CHECK-ASM: encoding: [0xff,0xfd,0xff,0x53] ++b 0x7FFFFFC ++ ++# CHECK-ASM-AND-OBJ: bl -134217728 ++# CHECK-ASM: encoding: [0x00,0x02,0x00,0x54] ++bl -0x8000000 ++ ++# CHECK-ASM-AND-OBJ: bl 134217724 ++# CHECK-ASM: encoding: [0xff,0xfd,0xff,0x57] ++bl 0x7FFFFFC ++ +diff --git a/llvm/test/MC/LoongArch/valid_float.s b/llvm/test/MC/LoongArch/valid_float.s +new file mode 100644 +index 000000000..edb75979d +--- /dev/null ++++ b/llvm/test/MC/LoongArch/valid_float.s +@@ -0,0 +1,313 @@ ++# RUN: llvm-mc %s -triple=loongarch64-unknown-linux-gnu -show-encoding | FileCheck %s ++# CHECK: fadd.s $f29, $f15, $f25 ++# CHECK: encoding: [0xfd,0xe5,0x00,0x01] ++fadd.s $f29, $f15, $f25 ++ ++# CHECK: fadd.d $f25, $f7, $f13 ++# CHECK: encoding: [0xf9,0x34,0x01,0x01] ++fadd.d $f25, $f7, $f13 ++ ++# CHECK: fsub.s $f14, $f6, $f31 ++# CHECK: encoding: [0xce,0xfc,0x02,0x01] ++fsub.s $f14, $f6, $f31 ++ ++# CHECK: fsub.d $f29, $f1, $f18 ++# CHECK: encoding: [0x3d,0x48,0x03,0x01] ++fsub.d $f29, $f1, $f18 ++ ++# CHECK: fmul.s $f0, $f7, $f17 ++# CHECK: encoding: [0xe0,0xc4,0x04,0x01] ++fmul.s $f0, $f7, $f17 ++ ++# CHECK: fmul.d $f4, $f30, $f7 ++# CHECK: encoding: [0xc4,0x1f,0x05,0x01] ++fmul.d $f4, $f30, $f7 ++ ++# CHECK: fdiv.s $f20, $f24, $f19 ++# CHECK: encoding: [0x14,0xcf,0x06,0x01] ++fdiv.s $f20, $f24, $f19 ++ ++# CHECK: fdiv.d $f3, $f25, $f28 ++# CHECK: encoding: [0x23,0x73,0x07,0x01] ++fdiv.d $f3, $f25, $f28 ++ ++# CHECK: fmax.s $f22, $f6, $f27 ++# CHECK: encoding: [0xd6,0xec,0x08,0x01] ++fmax.s $f22, $f6, $f27 ++ ++# CHECK: fmax.d $f11, $f26, $f13 ++# CHECK: encoding: [0x4b,0x37,0x09,0x01] ++fmax.d $f11, $f26, $f13 ++ ++# CHECK: fmin.s $f14, $f10, $f19 ++# CHECK: encoding: [0x4e,0xcd,0x0a,0x01] ++fmin.s $f14, $f10, $f19 ++ ++# CHECK: fmin.d $f1, $f13, $f27 ++# CHECK: encoding: [0xa1,0x6d,0x0b,0x01] ++fmin.d $f1, $f13, $f27 ++ ++# CHECK: fmaxa.s $f9, $f27, $f31 ++# CHECK: encoding: [0x69,0xff,0x0c,0x01] ++fmaxa.s $f9, $f27, $f31 ++ ++# CHECK: fmaxa.d $f24, $f13, $f4 ++# CHECK: encoding: [0xb8,0x11,0x0d,0x01] ++fmaxa.d $f24, $f13, $f4 ++ ++# CHECK: fmina.s $f15, $f18, $f1 ++# CHECK: encoding: [0x4f,0x86,0x0e,0x01] ++fmina.s $f15, $f18, $f1 ++ ++# CHECK: fmina.d $f18, $f10, $f0 ++# CHECK: encoding: [0x52,0x01,0x0f,0x01] ++fmina.d $f18, $f10, $f0 ++ ++# CHECK: fscaleb.s $f21, $f23, $f6 ++# CHECK: encoding: [0xf5,0x9a,0x10,0x01] ++fscaleb.s $f21, $f23, $f6 ++ ++# CHECK: fscaleb.d $f12, $f14, $f26 ++# CHECK: encoding: [0xcc,0x69,0x11,0x01] ++fscaleb.d $f12, $f14, $f26 ++ ++# CHECK: fcopysign.s $f13, $f24, $f23 ++# CHECK: encoding: [0x0d,0xdf,0x12,0x01] ++fcopysign.s $f13, $f24, $f23 ++ ++# CHECK: fcopysign.d $f16, $f26, $f6 ++# CHECK: encoding: [0x50,0x1b,0x13,0x01] ++fcopysign.d $f16, $f26, $f6 ++ ++# CHECK: fabs.s $f28, $f12 ++# CHECK: encoding: [0x9c,0x05,0x14,0x01] ++fabs.s $f28, $f12 ++ ++# CHECK: fabs.d $f23, $f3 ++# CHECK: encoding: [0x77,0x08,0x14,0x01] ++fabs.d $f23, $f3 ++ ++# CHECK: fneg.s $f21, $f24 ++# CHECK: encoding: [0x15,0x17,0x14,0x01] ++fneg.s $f21, $f24 ++ ++# CHECK: fneg.d $f11, $f26 ++# CHECK: encoding: [0x4b,0x1b,0x14,0x01] ++fneg.d $f11, $f26 ++ ++# CHECK: flogb.s $f31, $f23 ++# CHECK: encoding: [0xff,0x26,0x14,0x01] ++flogb.s $f31, $f23 ++ ++# CHECK: flogb.d $f21, $f29 ++# CHECK: encoding: [0xb5,0x2b,0x14,0x01] ++flogb.d $f21, $f29 ++ ++# CHECK: fclass.s $f20, $f9 ++# CHECK: encoding: [0x34,0x35,0x14,0x01] ++fclass.s $f20, $f9 ++ ++# CHECK: fclass.d $f19, $f2 ++# CHECK: encoding: [0x53,0x38,0x14,0x01] ++fclass.d $f19, $f2 ++ ++# CHECK: fsqrt.s $f27, $f18 ++# CHECK: encoding: [0x5b,0x46,0x14,0x01] ++fsqrt.s $f27, $f18 ++ ++# CHECK: fsqrt.d $f2, $f11 ++# CHECK: encoding: [0x62,0x49,0x14,0x01] ++fsqrt.d $f2, $f11 ++ ++# CHECK: frecip.s $f17, $f27 ++# CHECK: encoding: [0x71,0x57,0x14,0x01] ++frecip.s $f17, $f27 ++ ++# CHECK: frecip.d $f27, $f27 ++# CHECK: encoding: [0x7b,0x5b,0x14,0x01] ++frecip.d $f27, $f27 ++ ++# CHECK: frecipe.s $f0, $f0 ++# CHECK: encoding: [0x00,0x74,0x14,0x01] ++frecipe.s $fa0, $fa0 ++ ++# CHECK: frecipe.d $f0, $f0 ++# CHECK: encoding: [0x00,0x78,0x14,0x01] ++frecipe.d $fa0, $fa0 ++ ++# CHECK: frsqrt.s $f25, $f12 ++# CHECK: encoding: [0x99,0x65,0x14,0x01] ++frsqrt.s $f25, $f12 ++ ++# CHECK: frsqrt.d $f22, $f3 ++# CHECK: encoding: [0x76,0x68,0x14,0x01] ++frsqrt.d $f22, $f3 ++ ++# CHECK: frsqrte.s $f1, $f1 ++# CHECK: encoding: [0x21,0x84,0x14,0x01] ++frsqrte.s $fa1, $fa1 ++ ++# CHECK: frsqrte.d $f1, $f1 ++# CHECK: encoding: [0x21,0x88,0x14,0x01] ++frsqrte.d $fa1, $fa1 ++ ++# CHECK: fmov.s $f13, $f23 ++# CHECK: encoding: [0xed,0x96,0x14,0x01] ++fmov.s $f13, $f23 ++ ++# CHECK: fmov.d $f30, $f9 ++# CHECK: encoding: [0x3e,0x99,0x14,0x01] ++fmov.d $f30, $f9 ++ ++# CHECK: movgr2fr.w $f6, $tp ++# CHECK: encoding: [0x46,0xa4,0x14,0x01] ++movgr2fr.w $f6, $tp ++ ++# CHECK: movgr2fr.d $f30, $r11 ++# CHECK: encoding: [0x7e,0xa9,0x14,0x01] ++movgr2fr.d $f30, $r11 ++ ++# CHECK: movgr2frh.w $f23, $r26 ++# CHECK: encoding: [0x57,0xaf,0x14,0x01] ++movgr2frh.w $f23, $r26 ++ ++# CHECK: movfr2gr.s $r10, $f22 ++# CHECK: encoding: [0xca,0xb6,0x14,0x01] ++movfr2gr.s $r10, $f22 ++ ++# CHECK: movfr2gr.d $r26, $f17 ++# CHECK: encoding: [0x3a,0xba,0x14,0x01] ++movfr2gr.d $r26, $f17 ++ ++# CHECK: movfrh2gr.s $sp, $f26 ++# CHECK: encoding: [0x43,0xbf,0x14,0x01] ++movfrh2gr.s $sp, $f26 ++ ++# CHECK: movfr2cf $fcc4, $f11 ++# CHECK: encoding: [0x64,0xd1,0x14,0x01] ++movfr2cf $fcc4, $f11 ++ ++# CHECK: movcf2fr $f16, $fcc0 ++# CHECK: encoding: [0x10,0xd4,0x14,0x01] ++movcf2fr $f16, $fcc0 ++ ++# CHECK: movgr2cf $fcc5, $ra ++# CHECK: encoding: [0x25,0xd8,0x14,0x01] ++movgr2cf $fcc5, $ra ++ ++# CHECK: movcf2gr $r21, $fcc7 ++# CHECK: encoding: [0xf5,0xdc,0x14,0x01] ++movcf2gr $r21, $fcc7 ++ ++# CHECK: fcvt.s.d $f12, $f19 ++# CHECK: encoding: [0x6c,0x1a,0x19,0x01] ++fcvt.s.d $f12, $f19 ++ ++# CHECK: fcvt.d.s $f10, $f6 ++# CHECK: encoding: [0xca,0x24,0x19,0x01] ++fcvt.d.s $f10, $f6 ++ ++# CHECK: ftintrm.w.s $f16, $f16 ++# CHECK: encoding: [0x10,0x06,0x1a,0x01] ++ftintrm.w.s $f16, $f16 ++ ++# CHECK: ftintrm.w.d $f7, $f8 ++# CHECK: encoding: [0x07,0x09,0x1a,0x01] ++ftintrm.w.d $f7, $f8 ++ ++# CHECK: ftintrm.l.s $f24, $f10 ++# CHECK: encoding: [0x58,0x25,0x1a,0x01] ++ftintrm.l.s $f24, $f10 ++ ++# CHECK: ftintrm.l.d $f9, $f9 ++# CHECK: encoding: [0x29,0x29,0x1a,0x01] ++ftintrm.l.d $f9, $f9 ++ ++# CHECK: ftintrp.w.s $f14, $f31 ++# CHECK: encoding: [0xee,0x47,0x1a,0x01] ++ftintrp.w.s $f14, $f31 ++ ++# CHECK: ftintrp.w.d $f12, $f3 ++# CHECK: encoding: [0x6c,0x48,0x1a,0x01] ++ftintrp.w.d $f12, $f3 ++ ++# CHECK: ftintrp.l.s $f0, $f16 ++# CHECK: encoding: [0x00,0x66,0x1a,0x01] ++ftintrp.l.s $f0, $f16 ++ ++# CHECK: ftintrp.l.d $f4, $f29 ++# CHECK: encoding: [0xa4,0x6b,0x1a,0x01] ++ftintrp.l.d $f4, $f29 ++ ++# CHECK: ftintrz.w.s $f4, $f29 ++# CHECK: encoding: [0xa4,0x87,0x1a,0x01] ++ftintrz.w.s $f4, $f29 ++ ++# CHECK: ftintrz.w.d $f25, $f24 ++# CHECK: encoding: [0x19,0x8b,0x1a,0x01] ++ftintrz.w.d $f25, $f24 ++ ++# CHECK: ftintrz.l.s $f23, $f5 ++# CHECK: encoding: [0xb7,0xa4,0x1a,0x01] ++ftintrz.l.s $f23, $f5 ++ ++# CHECK: ftintrz.l.d $f3, $f10 ++# CHECK: encoding: [0x43,0xa9,0x1a,0x01] ++ftintrz.l.d $f3, $f10 ++ ++# CHECK: ftintrne.w.s $f4, $f17 ++# CHECK: encoding: [0x24,0xc6,0x1a,0x01] ++ftintrne.w.s $f4, $f17 ++ ++# CHECK: ftintrne.w.d $f31, $f12 ++# CHECK: encoding: [0x9f,0xc9,0x1a,0x01] ++ftintrne.w.d $f31, $f12 ++ ++# CHECK: ftintrne.l.s $f22, $f27 ++# CHECK: encoding: [0x76,0xe7,0x1a,0x01] ++ftintrne.l.s $f22, $f27 ++ ++# CHECK: ftintrne.l.d $f28, $f6 ++# CHECK: encoding: [0xdc,0xe8,0x1a,0x01] ++ftintrne.l.d $f28, $f6 ++ ++# CHECK: ftint.w.s $f21, $f13 ++# CHECK: encoding: [0xb5,0x05,0x1b,0x01] ++ftint.w.s $f21, $f13 ++ ++# CHECK: ftint.w.d $f3, $f14 ++# CHECK: encoding: [0xc3,0x09,0x1b,0x01] ++ftint.w.d $f3, $f14 ++ ++# CHECK: ftint.l.s $f31, $f24 ++# CHECK: encoding: [0x1f,0x27,0x1b,0x01] ++ftint.l.s $f31, $f24 ++ ++# CHECK: ftint.l.d $f16, $f24 ++# CHECK: encoding: [0x10,0x2b,0x1b,0x01] ++ftint.l.d $f16, $f24 ++ ++# CHECK: ffint.s.w $f30, $f5 ++# CHECK: encoding: [0xbe,0x10,0x1d,0x01] ++ffint.s.w $f30, $f5 ++ ++# CHECK: ffint.s.l $f6, $f5 ++# CHECK: encoding: [0xa6,0x18,0x1d,0x01] ++ffint.s.l $f6, $f5 ++ ++# CHECK: ffint.d.w $f24, $f18 ++# CHECK: encoding: [0x58,0x22,0x1d,0x01] ++ffint.d.w $f24, $f18 ++ ++# CHECK: ffint.d.l $f23, $f26 ++# CHECK: encoding: [0x57,0x2b,0x1d,0x01] ++ffint.d.l $f23, $f26 ++ ++# CHECK: frint.s $f5, $f17 ++# CHECK: encoding: [0x25,0x46,0x1e,0x01] ++frint.s $f5, $f17 ++ ++# CHECK: frint.d $f29, $f2 ++# CHECK: encoding: [0x5d,0x48,0x1e,0x01] ++frint.d $f29, $f2 ++ +diff --git a/llvm/test/MC/LoongArch/valid_integer.s b/llvm/test/MC/LoongArch/valid_integer.s +new file mode 100644 +index 000000000..cc78662d5 +--- /dev/null ++++ b/llvm/test/MC/LoongArch/valid_integer.s +@@ -0,0 +1,369 @@ ++# RUN: llvm-mc %s -triple=loongarch64-unknown-linux-gnu -show-encoding | FileCheck %s ++# CHECK: clo.w $ra, $sp ++# CHECK: encoding: [0x61,0x10,0x00,0x00] ++clo.w $ra, $sp ++ ++# CHECK: clz.w $r7, $r10 ++# CHECK: encoding: [0x47,0x15,0x00,0x00] ++clz.w $r7, $r10 ++ ++# CHECK: cto.w $tp, $r6 ++# CHECK: encoding: [0xc2,0x18,0x00,0x00] ++cto.w $tp, $r6 ++ ++# CHECK: ctz.w $r5, $r22 ++# CHECK: encoding: [0xc5,0x1e,0x00,0x00] ++ctz.w $r5, $r22 ++ ++# CHECK: clo.d $r29, $ra ++# CHECK: encoding: [0x3d,0x20,0x00,0x00] ++clo.d $r29, $ra ++ ++# CHECK: clz.d $r26, $r26 ++# CHECK: encoding: [0x5a,0x27,0x00,0x00] ++clz.d $r26, $r26 ++ ++# CHECK: cto.d $r18, $r20 ++# CHECK: encoding: [0x92,0x2a,0x00,0x00] ++cto.d $r18, $r20 ++ ++# CHECK: ctz.d $r17, $r10 ++# CHECK: encoding: [0x51,0x2d,0x00,0x00] ++ctz.d $r17, $r10 ++ ++# CHECK: revb.2h $r20, $r11 ++# CHECK: encoding: [0x74,0x31,0x00,0x00] ++revb.2h $r20, $r11 ++ ++# CHECK: revb.4h $r13, $r19 ++# CHECK: encoding: [0x6d,0x36,0x00,0x00] ++revb.4h $r13, $r19 ++ ++# CHECK: revb.2w $r28, $r27 ++# CHECK: encoding: [0x7c,0x3b,0x00,0x00] ++revb.2w $r28, $r27 ++ ++# CHECK: revb.d $zero, $r23 ++# CHECK: encoding: [0xe0,0x3e,0x00,0x00] ++revb.d $zero, $r23 ++ ++# CHECK: revh.2w $r28, $r10 ++# CHECK: encoding: [0x5c,0x41,0x00,0x00] ++revh.2w $r28, $r10 ++ ++# CHECK: revh.d $r9, $r7 ++# CHECK: encoding: [0xe9,0x44,0x00,0x00] ++revh.d $r9, $r7 ++ ++# CHECK: bitrev.4b $r21, $r27 ++# CHECK: encoding: [0x75,0x4b,0x00,0x00] ++bitrev.4b $r21, $r27 ++ ++# CHECK: bitrev.8b $r13, $r25 ++# CHECK: encoding: [0x2d,0x4f,0x00,0x00] ++bitrev.8b $r13, $r25 ++ ++# CHECK: bitrev.w $r25, $r5 ++# CHECK: encoding: [0xb9,0x50,0x00,0x00] ++bitrev.w $r25, $r5 ++ ++# CHECK: bitrev.d $r19, $r23 ++# CHECK: encoding: [0xf3,0x56,0x00,0x00] ++bitrev.d $r19, $r23 ++ ++# CHECK: ext.w.h $r23, $r23 ++# CHECK: encoding: [0xf7,0x5a,0x00,0x00] ++ext.w.h $r23, $r23 ++ ++# CHECK: ext.w.b $r20, $r18 ++# CHECK: encoding: [0x54,0x5e,0x00,0x00] ++ext.w.b $r20, $r18 ++ ++# CHECK: rdtimel.w $r24, $r4 ++# CHECK: encoding: [0x98,0x60,0x00,0x00] ++rdtimel.w $r24, $r4 ++ ++# CHECK: rdtimeh.w $r11, $r5 ++# CHECK: encoding: [0xab,0x64,0x00,0x00] ++rdtimeh.w $r11, $r5 ++ ++# CHECK: rdtime.d $tp, $ra ++# CHECK: encoding: [0x22,0x68,0x00,0x00] ++rdtime.d $tp, $ra ++ ++# CHECK: cpucfg $sp, $ra ++# CHECK: encoding: [0x23,0x6c,0x00,0x00] ++cpucfg $sp, $ra ++ ++# CHECK: asrtle.d $r21, $r19 ++# CHECK: encoding: [0xa0,0x4e,0x01,0x00] ++asrtle.d $r21, $r19 ++ ++# CHECK: asrtgt.d $ra, $r19 ++# CHECK: encoding: [0x20,0xcc,0x01,0x00] ++asrtgt.d $ra, $r19 ++ ++# CHECK: alsl.w $tp, $r17, $tp, 4 ++# CHECK: encoding: [0x22,0x8a,0x05,0x00] ++alsl.w $tp, $r17, $tp, 4 ++ ++# CHECK: bytepick.w $r29, $zero, $r16, 0 ++# CHECK: encoding: [0x1d,0x40,0x08,0x00] ++bytepick.w $r29, $zero, $r16, 0 ++ ++# CHECK: bytepick.d $r15, $r17, $r20, 4 ++# CHECK: encoding: [0x2f,0x52,0x0e,0x00] ++bytepick.d $r15, $r17, $r20, 4 ++ ++# CHECK: add.w $r9, $ra, $r31 ++# CHECK: encoding: [0x29,0x7c,0x10,0x00] ++add.w $r9, $ra, $r31 ++ ++# CHECK: add.d $tp, $r18, $r27 ++# CHECK: encoding: [0x42,0xee,0x10,0x00] ++add.d $tp, $r18, $r27 ++ ++# CHECK: sub.w $r21, $r25, $r19 ++# CHECK: encoding: [0x35,0x4f,0x11,0x00] ++sub.w $r21, $r25, $r19 ++ ++# CHECK: sub.d $r7, $r12, $r7 ++# CHECK: encoding: [0x87,0x9d,0x11,0x00] ++sub.d $r7, $r12, $r7 ++ ++# CHECK: slt $r29, $r26, $tp ++# CHECK: encoding: [0x5d,0x0b,0x12,0x00] ++slt $r29, $r26, $tp ++ ++# CHECK: sltu $r11, $r21, $r29 ++# CHECK: encoding: [0xab,0xf6,0x12,0x00] ++sltu $r11, $r21, $r29 ++ ++# CHECK: maskeqz $r20, $r11, $r18 ++# CHECK: encoding: [0x74,0x49,0x13,0x00] ++maskeqz $r20, $r11, $r18 ++ ++# CHECK: masknez $r20, $r13, $r26 ++# CHECK: encoding: [0xb4,0xe9,0x13,0x00] ++masknez $r20, $r13, $r26 ++ ++# CHECK: nor $r5, $r18, $r5 ++# CHECK: encoding: [0x45,0x16,0x14,0x00] ++nor $r5, $r18, $r5 ++ ++# CHECK: and $r19, $r31, $ra ++# CHECK: encoding: [0xf3,0x87,0x14,0x00] ++and $r19, $r31, $ra ++ ++# CHECK: or $r17, $r16, $r30 ++# CHECK: encoding: [0x11,0x7a,0x15,0x00] ++or $r17, $r16, $r30 ++ ++# CHECK: xor $r15, $r19, $r8 ++# CHECK: encoding: [0x6f,0xa2,0x15,0x00] ++xor $r15, $r19, $r8 ++ ++# CHECK: orn $tp, $sp, $r25 ++# CHECK: encoding: [0x62,0x64,0x16,0x00] ++orn $tp, $sp, $r25 ++ ++# CHECK: andn $r28, $r25, $r5 ++# CHECK: encoding: [0x3c,0x97,0x16,0x00] ++andn $r28, $r25, $r5 ++ ++# CHECK: sll.w $r24, $r27, $r23 ++# CHECK: encoding: [0x78,0x5f,0x17,0x00] ++sll.w $r24, $r27, $r23 ++ ++# CHECK: srl.w $r31, $r17, $r7 ++# CHECK: encoding: [0x3f,0x9e,0x17,0x00] ++srl.w $r31, $r17, $r7 ++ ++# CHECK: sra.w $r12, $r28, $r10 ++# CHECK: encoding: [0x8c,0x2b,0x18,0x00] ++sra.w $r12, $r28, $r10 ++ ++# CHECK: sll.d $r20, $r15, $sp ++# CHECK: encoding: [0xf4,0x8d,0x18,0x00] ++sll.d $r20, $r15, $sp ++ ++# CHECK: srl.d $r14, $r25, $zero ++# CHECK: encoding: [0x2e,0x03,0x19,0x00] ++srl.d $r14, $r25, $zero ++ ++# CHECK: sra.d $r7, $r22, $r31 ++# CHECK: encoding: [0xc7,0xfe,0x19,0x00] ++sra.d $r7, $r22, $r31 ++ ++# CHECK: rotr.w $ra, $r26, $r18 ++# CHECK: encoding: [0x41,0x4b,0x1b,0x00] ++rotr.w $ra, $r26, $r18 ++ ++# CHECK: rotr.d $r31, $sp, $ra ++# CHECK: encoding: [0x7f,0x84,0x1b,0x00] ++rotr.d $r31, $sp, $ra ++ ++# CHECK: mul.w $r4, $r18, $sp ++# CHECK: encoding: [0x44,0x0e,0x1c,0x00] ++mul.w $r4, $r18, $sp ++ ++# CHECK: mulh.w $r27, $r23, $zero ++# CHECK: encoding: [0xfb,0x82,0x1c,0x00] ++mulh.w $r27, $r23, $zero ++ ++# CHECK: mulh.wu $r10, $r17, $r24 ++# CHECK: encoding: [0x2a,0x62,0x1d,0x00] ++mulh.wu $r10, $r17, $r24 ++ ++# CHECK: mul.d $ra, $r14, $r24 ++# CHECK: encoding: [0xc1,0xe1,0x1d,0x00] ++mul.d $ra, $r14, $r24 ++ ++# CHECK: mulh.d $r28, $ra, $r27 ++# CHECK: encoding: [0x3c,0x6c,0x1e,0x00] ++mulh.d $r28, $ra, $r27 ++ ++# CHECK: mulh.du $r13, $r27, $r29 ++# CHECK: encoding: [0x6d,0xf7,0x1e,0x00] ++mulh.du $r13, $r27, $r29 ++ ++# CHECK: mulw.d.w $r27, $r6, $r17 ++# CHECK: encoding: [0xdb,0x44,0x1f,0x00] ++mulw.d.w $r27, $r6, $r17 ++ ++# CHECK: mulw.d.wu $r17, $r22, $r30 ++# CHECK: encoding: [0xd1,0xfa,0x1f,0x00] ++mulw.d.wu $r17, $r22, $r30 ++ ++# CHECK: div.w $r30, $r13, $r25 ++# CHECK: encoding: [0xbe,0x65,0x20,0x00] ++div.w $r30, $r13, $r25 ++ ++# CHECK: mod.w $ra, $r26, $r10 ++# CHECK: encoding: [0x41,0xab,0x20,0x00] ++mod.w $ra, $r26, $r10 ++ ++# CHECK: div.wu $r19, $r23, $zero ++# CHECK: encoding: [0xf3,0x02,0x21,0x00] ++div.wu $r19, $r23, $zero ++ ++# CHECK: mod.wu $r27, $r9, $r17 ++# CHECK: encoding: [0x3b,0xc5,0x21,0x00] ++mod.wu $r27, $r9, $r17 ++ ++# CHECK: div.d $r23, $r6, $r21 ++# CHECK: encoding: [0xd7,0x54,0x22,0x00] ++div.d $r23, $r6, $r21 ++ ++# CHECK: mod.d $r16, $sp, $r15 ++# CHECK: encoding: [0x70,0xbc,0x22,0x00] ++mod.d $r16, $sp, $r15 ++ ++# CHECK: div.du $r31, $r24, $r14 ++# CHECK: encoding: [0x1f,0x3b,0x23,0x00] ++div.du $r31, $r24, $r14 ++ ++# CHECK: mod.du $r25, $r23, $r24 ++# CHECK: encoding: [0xf9,0xe2,0x23,0x00] ++mod.du $r25, $r23, $r24 ++ ++# CHECK: crc.w.b.w $r24, $r7, $tp ++# CHECK: encoding: [0xf8,0x08,0x24,0x00] ++crc.w.b.w $r24, $r7, $tp ++ ++# CHECK: crc.w.h.w $r31, $r10, $r18 ++# CHECK: encoding: [0x5f,0xc9,0x24,0x00] ++crc.w.h.w $r31, $r10, $r18 ++ ++# CHECK: crc.w.w.w $r28, $r6, $r10 ++# CHECK: encoding: [0xdc,0x28,0x25,0x00] ++crc.w.w.w $r28, $r6, $r10 ++ ++# CHECK: crc.w.d.w $r28, $r11, $r31 ++# CHECK: encoding: [0x7c,0xfd,0x25,0x00] ++crc.w.d.w $r28, $r11, $r31 ++ ++# CHECK: crcc.w.b.w $r15, $r18, $sp ++# CHECK: encoding: [0x4f,0x0e,0x26,0x00] ++crcc.w.b.w $r15, $r18, $sp ++ ++# CHECK: crcc.w.h.w $r21, $r29, $r18 ++# CHECK: encoding: [0xb5,0xcb,0x26,0x00] ++crcc.w.h.w $r21, $r29, $r18 ++ ++# CHECK: crcc.w.w.w $r17, $r14, $r13 ++# CHECK: encoding: [0xd1,0x35,0x27,0x00] ++crcc.w.w.w $r17, $r14, $r13 ++ ++# CHECK: crcc.w.d.w $r30, $r21, $r27 ++# CHECK: encoding: [0xbe,0xee,0x27,0x00] ++crcc.w.d.w $r30, $r21, $r27 ++ ++# CHECK: break 23 ++# CHECK: encoding: [0x17,0x00,0x2a,0x00] ++break 23 ++ ++# CHECK: syscall 2 ++# CHECK: encoding: [0x02,0x00,0x2b,0x00] ++syscall 2 ++ ++# CHECK: alsl.d $r17, $r11, $r5, 3 ++# CHECK: encoding: [0x71,0x15,0x2d,0x00] ++alsl.d $r17, $r11, $r5, 3 ++ ++# CHECK: slli.w $r26, $r18, 0 ++# CHECK: encoding: [0x5a,0x82,0x40,0x00] ++slli.w $r26, $r18, 0 ++ ++# CHECK: slli.d $r10, $r31, 39 ++# CHECK: encoding: [0xea,0x9f,0x41,0x00] ++slli.d $r10, $r31, 39 ++ ++# CHECK: srli.w $r10, $r14, 30 ++# CHECK: encoding: [0xca,0xf9,0x44,0x00] ++srli.w $r10, $r14, 30 ++ ++# CHECK: srli.d $r31, $r22, 38 ++# CHECK: encoding: [0xdf,0x9a,0x45,0x00] ++srli.d $r31, $r22, 38 ++ ++# CHECK: srai.w $r8, $r17, 24 ++# CHECK: encoding: [0x28,0xe2,0x48,0x00] ++srai.w $r8, $r17, 24 ++ ++# CHECK: srai.d $r9, $r21, 27 ++# CHECK: encoding: [0xa9,0x6e,0x49,0x00] ++srai.d $r9, $r21, 27 ++ ++# CHECK: rotri.w $r23, $r20, 23 ++# CHECK: encoding: [0x97,0xde,0x4c,0x00] ++rotri.w $r23, $r20, 23 ++ ++# CHECK: rotri.d $r29, $zero, 7 ++# CHECK: encoding: [0x1d,0x1c,0x4d,0x00] ++rotri.d $r29, $zero, 7 ++ ++# CHECK: bstrins.w $r8, $r11, 7, 2 ++# CHECK: encoding: [0x68,0x09,0x67,0x00] ++bstrins.w $r8, $r11, 7, 2 ++ ++# CHECK: bstrins.d $r8, $r11, 7, 2 ++# CHECK: encoding: [0x68,0x09,0x87,0x00] ++bstrins.d $r8, $r11, 7, 2 ++ ++# CHECK: bstrpick.w $ra, $r9, 10, 4 ++# CHECK: encoding: [0x21,0x91,0x6a,0x00] ++bstrpick.w $ra, $r9, 10, 4 ++ ++# CHECK: bstrpick.d $r31, $r27, 39, 22 ++# CHECK: encoding: [0x7f,0x5b,0xe7,0x00] ++bstrpick.d $r31, $r27, 39, 22 ++ ++# CHECK: cpucfg $sp, $r8 ++# CHECK: encoding: [0x03,0x6d,0x00,0x00] ++cpucfg $sp, $r8 ++ ++# CHECK: alsl.wu $r19, $r8, $r25, 1 ++# CHECK: encoding: [0x13,0x65,0x06,0x00] ++alsl.wu $r19, $r8, $r25, 1 ++ +diff --git a/llvm/test/MC/LoongArch/valid_memory.s b/llvm/test/MC/LoongArch/valid_memory.s +new file mode 100644 +index 000000000..b4cfb3286 +--- /dev/null ++++ b/llvm/test/MC/LoongArch/valid_memory.s +@@ -0,0 +1,497 @@ ++# RUN: llvm-mc %s -triple=loongarch64-unknown-linux-gnu -show-encoding | FileCheck %s ++# CHECK: dbar 0 ++# CHECK: encoding: [0x00,0x00,0x72,0x38] ++dbar 0 ++ ++# CHECK: ibar 0 ++# CHECK: encoding: [0x00,0x80,0x72,0x38] ++ibar 0 ++ ++# CHECK: ll.w $tp, $r27, 220 ++# CHECK: encoding: [0x62,0xdf,0x00,0x20] ++ll.w $tp, $r27, 220 ++ ++# CHECK: sc.w $r19, $r14, 56 ++# CHECK: encoding: [0xd3,0x39,0x00,0x21] ++sc.w $r19, $r14, 56 ++ ++# CHECK: llacq.w $r13, $r14 ++# CHECK: encoding: [0xcd,0x81,0x57,0x38] ++llacq.w $t1, $t2 ++ ++# CHECK: screl.w $r13, $r14 ++# CHECK: encoding: [0xcd,0x85,0x57,0x38] ++screl.w $t1, $t2 ++ ++# CHECK: ll.d $r25, $r27, 16 ++# CHECK: encoding: [0x79,0x13,0x00,0x22] ++ll.d $r25, $r27, 16 ++ ++# CHECK: sc.d $r17, $r17, 244 ++# CHECK: encoding: [0x31,0xf6,0x00,0x23] ++sc.d $r17, $r17, 244 ++ ++# CHECK: sc.q $r19, $r14, $r17 ++# CHECK: encoding: [0x33,0x3a,0x57,0x38] ++sc.q $t7, $t2, $t5 ++ ++# CHECK: llacq.d $r13, $r14 ++# CHECK: encoding: [0xcd,0x89,0x57,0x38] ++llacq.d $t1, $t2 ++ ++# CHECK: screl.d $r13, $r14 ++# CHECK: encoding: [0xcd,0x8d,0x57,0x38] ++screl.d $t1, $t2 ++ ++# CHECK: ldptr.w $r26, $r6, 60 ++# CHECK: encoding: [0xda,0x3c,0x00,0x24] ++ldptr.w $r26, $r6, 60 ++ ++# CHECK: stptr.w $r28, $r5, 216 ++# CHECK: encoding: [0xbc,0xd8,0x00,0x25] ++stptr.w $r28, $r5, 216 ++ ++# CHECK: ldptr.d $r5, $r29, 244 ++# CHECK: encoding: [0xa5,0xf7,0x00,0x26] ++ldptr.d $r5, $r29, 244 ++ ++# CHECK: stptr.d $r14, $r24, 196 ++# CHECK: encoding: [0x0e,0xc7,0x00,0x27] ++stptr.d $r14, $r24, 196 ++ ++# CHECK: ld.b $r24, $r8, 21 ++# CHECK: encoding: [0x18,0x55,0x00,0x28] ++ld.b $r24, $r8, 21 ++ ++# CHECK: ld.h $r7, $r18, 80 ++# CHECK: encoding: [0x47,0x42,0x41,0x28] ++ld.h $r7, $r18, 80 ++ ++# CHECK: ld.w $r18, $r26, 92 ++# CHECK: encoding: [0x52,0x73,0x81,0x28] ++ld.w $r18, $r26, 92 ++ ++# CHECK: ld.d $r18, $r20, 159 ++# CHECK: encoding: [0x92,0x7e,0xc2,0x28] ++ld.d $r18, $r20, 159 ++ ++# CHECK: st.b $sp, $r7, 95 ++# CHECK: encoding: [0xe3,0x7c,0x01,0x29] ++st.b $sp, $r7, 95 ++ ++# CHECK: st.h $r25, $r16, 122 ++# CHECK: encoding: [0x19,0xea,0x41,0x29] ++st.h $r25, $r16, 122 ++ ++# CHECK: st.w $r13, $r13, 175 ++# CHECK: encoding: [0xad,0xbd,0x82,0x29] ++st.w $r13, $r13, 175 ++ ++# CHECK: st.d $r30, $r30, 60 ++# CHECK: encoding: [0xde,0xf3,0xc0,0x29] ++st.d $r30, $r30, 60 ++ ++# CHECK: ld.bu $r13, $r13, 150 ++# CHECK: encoding: [0xad,0x59,0x02,0x2a] ++ld.bu $r13, $r13, 150 ++ ++# CHECK: ld.hu $r18, $r29, 198 ++# CHECK: encoding: [0xb2,0x1b,0x43,0x2a] ++ld.hu $r18, $r29, 198 ++ ++# CHECK: ld.wu $r14, $r19, 31 ++# CHECK: encoding: [0x6e,0x7e,0x80,0x2a] ++ld.wu $r14, $r19, 31 ++ ++# CHECK: fld.s $f23, $r15, 250 ++# CHECK: encoding: [0xf7,0xe9,0x03,0x2b] ++fld.s $f23, $r15, 250 ++ ++# CHECK: fst.s $f30, $r19, 230 ++# CHECK: encoding: [0x7e,0x9a,0x43,0x2b] ++fst.s $f30, $r19, 230 ++ ++# CHECK: fld.d $f22, $r17, 114 ++# CHECK: encoding: [0x36,0xca,0x81,0x2b] ++fld.d $f22, $r17, 114 ++ ++# CHECK: fst.d $f28, $r7, 198 ++# CHECK: encoding: [0xfc,0x18,0xc3,0x2b] ++fst.d $f28, $r7, 198 ++ ++# CHECK: ldx.b $r24, $ra, $tp ++# CHECK: encoding: [0x38,0x08,0x00,0x38] ++ldx.b $r24, $ra, $tp ++ ++# CHECK: ldx.h $r22, $r22, $r17 ++# CHECK: encoding: [0xd6,0x46,0x04,0x38] ++ldx.h $r22, $r22, $r17 ++ ++# CHECK: ldx.w $r25, $r11, $r23 ++# CHECK: encoding: [0x79,0x5d,0x08,0x38] ++ldx.w $r25, $r11, $r23 ++ ++# CHECK: ldx.d $r18, $r23, $r20 ++# CHECK: encoding: [0xf2,0x52,0x0c,0x38] ++ldx.d $r18, $r23, $r20 ++ ++# CHECK: stx.b $r19, $ra, $sp ++# CHECK: encoding: [0x33,0x0c,0x10,0x38] ++stx.b $r19, $ra, $sp ++ ++# CHECK: stx.h $zero, $r28, $r26 ++# CHECK: encoding: [0x80,0x6b,0x14,0x38] ++stx.h $zero, $r28, $r26 ++ ++# CHECK: stx.w $r7, $r4, $r31 ++# CHECK: encoding: [0x87,0x7c,0x18,0x38] ++stx.w $r7, $r4, $r31 ++ ++# CHECK: stx.d $r7, $r31, $r10 ++# CHECK: encoding: [0xe7,0x2b,0x1c,0x38] ++stx.d $r7, $r31, $r10 ++ ++# CHECK: ldx.bu $r11, $r9, $r9 ++# CHECK: encoding: [0x2b,0x25,0x20,0x38] ++ldx.bu $r11, $r9, $r9 ++ ++# CHECK: ldx.hu $r22, $r23, $r27 ++# CHECK: encoding: [0xf6,0x6e,0x24,0x38] ++ldx.hu $r22, $r23, $r27 ++ ++# CHECK: ldx.wu $r8, $r24, $r28 ++# CHECK: encoding: [0x08,0x73,0x28,0x38] ++ldx.wu $r8, $r24, $r28 ++ ++# CHECK: fldx.s $f1, $r15, $r19 ++# CHECK: encoding: [0xe1,0x4d,0x30,0x38] ++fldx.s $f1, $r15, $r19 ++ ++# CHECK: fldx.d $f27, $r13, $r31 ++# CHECK: encoding: [0xbb,0x7d,0x34,0x38] ++fldx.d $f27, $r13, $r31 ++ ++# CHECK: fstx.s $f26, $sp, $r22 ++# CHECK: encoding: [0x7a,0x58,0x38,0x38] ++fstx.s $f26, $sp, $r22 ++ ++# CHECK: fstx.d $f6, $r15, $r17 ++# CHECK: encoding: [0xe6,0x45,0x3c,0x38] ++fstx.d $f6, $r15, $r17 ++ ++# CHECK: amswap_db.b $r6, $r12, $r24 ++# CHECK: encoding: [0x06,0x33,0x5e,0x38] ++amswap_db.b $a2, $t0, $s1 ++ ++# CHECK: amswap_db.h $tp, $r14, $r22 ++# CHECK: encoding: [0xc2,0xba,0x5e,0x38] ++amswap_db.h $tp, $t2, $fp ++ ++# CHECK: amswap_db.w $r6, $r12, $r24, 0 ++# CHECK: encoding: [0x06,0x33,0x69,0x38] ++amswap_db.w $r6, $r12, $r24, 0 ++ ++# CHECK: amswap_db.d $tp, $r14, $r22, 0 ++# CHECK: encoding: [0xc2,0xba,0x69,0x38] ++amswap_db.d $tp, $r14, $r22, 0 ++ ++# CHECK: amadd_db.b $zero, $zero, $r5 ++# CHECK: encoding: [0xa0,0x00,0x5f,0x38] ++amadd_db.b $zero, $zero, $a1 ++ ++# CHECK: amadd_db.h $r8, $r12, $r21 ++# CHECK: encoding: [0xa8,0xb2,0x5f,0x38] ++amadd_db.h $a4, $t0, $r21 ++ ++# CHECK: amadd_db.w $r8, $r12, $r21, 0 ++# CHECK: encoding: [0xa8,0x32,0x6a,0x38] ++amadd_db.w $r8, $r12, $r21, 0 ++ ++# CHECK: amadd_db.d $r5, $r17, $r29, 0 ++# CHECK: encoding: [0xa5,0xc7,0x6a,0x38] ++amadd_db.d $r5, $r17, $r29, 0 ++ ++# CHECK: amcas.b $r13, $r14, $r15 ++# CHECK: encoding: [0xed,0x39,0x58,0x38] ++amcas.b $t1, $t2, $t3 ++ ++# CHECK: amcas.h $r13, $r14, $r15 ++# CHECK: encoding: [0xed,0xb9,0x58,0x38] ++amcas.h $t1, $t2, $t3 ++ ++# CHECK: amcas.w $r13, $r14, $r15 ++# CHECK: encoding: [0xed,0x39,0x59,0x38] ++amcas.w $t1, $t2, $t3 ++ ++# CHECK: amcas.d $r13, $r14, $r15 ++# CHECK: encoding: [0xed,0xb9,0x59,0x38] ++amcas.d $t1, $t2, $t3 ++ ++# CHECK: amcas_db.b $r13, $r14, $r15 ++# CHECK: encoding: [0xed,0x39,0x5a,0x38] ++amcas_db.b $t1, $t2, $t3 ++ ++# CHECK: amcas_db.h $r13, $r14, $r15 ++# CHECK: encoding: [0xed,0xb9,0x5a,0x38] ++amcas_db.h $t1, $t2, $t3 ++ ++# CHECK: amcas_db.w $r13, $r14, $r15 ++# CHECK: encoding: [0xed,0x39,0x5b,0x38] ++amcas_db.w $t1, $t2, $t3 ++ ++# CHECK: amcas_db.d $r13, $r14, $r15 ++# CHECK: encoding: [0xed,0xb9,0x5b,0x38] ++amcas_db.d $t1, $t2, $t3 ++ ++# CHECK: amand_db.w $r4, $r19, $r22, 0 ++# CHECK: encoding: [0xc4,0x4e,0x6b,0x38] ++amand_db.w $r4, $r19, $r22, 0 ++ ++# CHECK: amand_db.d $r10, $r18, $r29, 0 ++# CHECK: encoding: [0xaa,0xcb,0x6b,0x38] ++amand_db.d $r10, $r18, $r29, 0 ++ ++# CHECK: amor_db.w $r6, $r16, $r23, 0 ++# CHECK: encoding: [0xe6,0x42,0x6c,0x38] ++amor_db.w $r6, $r16, $r23, 0 ++ ++# CHECK: amor_db.d $sp, $r16, $r24, 0 ++# CHECK: encoding: [0x03,0xc3,0x6c,0x38] ++amor_db.d $sp, $r16, $r24, 0 ++ ++# CHECK: amxor_db.w $tp, $r15, $r23, 0 ++# CHECK: encoding: [0xe2,0x3e,0x6d,0x38] ++amxor_db.w $tp, $r15, $r23, 0 ++ ++# CHECK: amxor_db.d $r8, $r20, $r28, 0 ++# CHECK: encoding: [0x88,0xd3,0x6d,0x38] ++amxor_db.d $r8, $r20, $r28, 0 ++ ++# CHECK: ammax_db.w $ra, $r11, $r23, 0 ++# CHECK: encoding: [0xe1,0x2e,0x6e,0x38] ++ammax_db.w $ra, $r11, $r23, 0 ++ ++# CHECK: ammax_db.d $r9, $r20, $r27, 0 ++# CHECK: encoding: [0x69,0xd3,0x6e,0x38] ++ammax_db.d $r9, $r20, $r27, 0 ++ ++# CHECK: ammin_db.w $r9, $r14, $r23, 0 ++# CHECK: encoding: [0xe9,0x3a,0x6f,0x38] ++ammin_db.w $r9, $r14, $r23, 0 ++ ++# CHECK: ammin_db.d $r9, $r13, $r22, 0 ++# CHECK: encoding: [0xc9,0xb6,0x6f,0x38] ++ammin_db.d $r9, $r13, $r22, 0 ++ ++# CHECK: ammax_db.wu $r9, $r11, $r22, 0 ++# CHECK: encoding: [0xc9,0x2e,0x70,0x38] ++ammax_db.wu $r9, $r11, $r22, 0 ++ ++# CHECK: ammax_db.du $r6, $r16, $r25, 0 ++# CHECK: encoding: [0x26,0xc3,0x70,0x38] ++ammax_db.du $r6, $r16, $r25, 0 ++ ++# CHECK: ammin_db.wu $r8, $r18, $r30, 0 ++# CHECK: encoding: [0xc8,0x4b,0x71,0x38] ++ammin_db.wu $r8, $r18, $r30, 0 ++ ++# CHECK: ammin_db.du $r7, $r16, $r25, 0 ++# CHECK: encoding: [0x27,0xc3,0x71,0x38] ++ammin_db.du $r7, $r16, $r25, 0 ++ ++# CHECK: amswap.b $r6, $r12, $r24, 0 ++# CHECK: encoding: [0x06,0x33,0x5c,0x38] ++amswap.b $a2, $t0, $s1, 0 ++ ++# CHECK: amswap.h $r6, $r12, $r24, 0 ++# CHECK: encoding: [0x06,0xb3,0x5c,0x38] ++amswap.h $a2, $t0, $s1, 0 ++ ++# CHECK: amswap.b $r6, $r12, $r24 ++# CHECK: encoding: [0x06,0x33,0x5c,0x38] ++amswap.b $a2, $t0, $s1 ++ ++# CHECK: amswap.h $r6, $r12, $r24 ++# CHECK: encoding: [0x06,0xb3,0x5c,0x38] ++amswap.h $a2, $t0, $s1 ++ ++# CHECK: amswap.w $r6, $r12, $r24, 0 ++# CHECK: encoding: [0x06,0x33,0x60,0x38] ++amswap.w $r6, $r12, $r24, 0 ++ ++# CHECK: amswap.d $tp, $r14, $r22, 0 ++# CHECK: encoding: [0xc2,0xba,0x60,0x38] ++amswap.d $tp, $r14, $r22, 0 ++ ++# CHECK: amadd.b $r8, $r12, $r21, 0 ++# CHECK: encoding: [0xa8,0x32,0x5d,0x38] ++amadd.b $a4, $t0, $r21 ++ ++# CHECK: amadd.h $r5, $r17, $r29, 0 ++# CHECK: encoding: [0xa5,0xc7,0x5d,0x38] ++amadd.h $a1, $t5, $s6 ++ ++# CHECK: amadd.w $r8, $r12, $r21, 0 ++# CHECK: encoding: [0xa8,0x32,0x61,0x38] ++amadd.w $r8, $r12, $r21, 0 ++ ++# CHECK: amadd.d $r5, $r17, $r29, 0 ++# CHECK: encoding: [0xa5,0xc7,0x61,0x38] ++amadd.d $r5, $r17, $r29, 0 ++ ++# CHECK: amand.w $r4, $r19, $r22, 0 ++# CHECK: encoding: [0xc4,0x4e,0x62,0x38] ++amand.w $r4, $r19, $r22, 0 ++ ++# CHECK: amand.d $r10, $r18, $r29, 0 ++# CHECK: encoding: [0xaa,0xcb,0x62,0x38] ++amand.d $r10, $r18, $r29, 0 ++ ++# CHECK: amor.w $r6, $r16, $r23, 0 ++# CHECK: encoding: [0xe6,0x42,0x63,0x38] ++amor.w $r6, $r16, $r23, 0 ++ ++# CHECK: amor.d $sp, $r16, $r24, 0 ++# CHECK: encoding: [0x03,0xc3,0x63,0x38] ++amor.d $sp, $r16, $r24, 0 ++ ++# CHECK: amxor.w $tp, $r15, $r23, 0 ++# CHECK: encoding: [0xe2,0x3e,0x64,0x38] ++amxor.w $tp, $r15, $r23, 0 ++ ++# CHECK: amxor.d $r8, $r20, $r28, 0 ++# CHECK: encoding: [0x88,0xd3,0x64,0x38] ++amxor.d $r8, $r20, $r28, 0 ++ ++# CHECK: ammax.w $ra, $r11, $r23, 0 ++# CHECK: encoding: [0xe1,0x2e,0x65,0x38] ++ammax.w $ra, $r11, $r23, 0 ++ ++# CHECK: ammax.d $r9, $r20, $r27, 0 ++# CHECK: encoding: [0x69,0xd3,0x65,0x38] ++ammax.d $r9, $r20, $r27, 0 ++ ++# CHECK: ammin.w $r9, $r14, $r23, 0 ++# CHECK: encoding: [0xe9,0x3a,0x66,0x38] ++ammin.w $r9, $r14, $r23, 0 ++ ++# CHECK: ammin.d $r9, $r13, $r22, 0 ++# CHECK: encoding: [0xc9,0xb6,0x66,0x38] ++ammin.d $r9, $r13, $r22, 0 ++ ++# CHECK: ammax.wu $r9, $r11, $r22, 0 ++# CHECK: encoding: [0xc9,0x2e,0x67,0x38] ++ammax.wu $r9, $r11, $r22, 0 ++ ++# CHECK: ammax.du $r6, $r16, $r25, 0 ++# CHECK: encoding: [0x26,0xc3,0x67,0x38] ++ammax.du $r6, $r16, $r25, 0 ++ ++# CHECK: ammin.wu $r8, $r18, $r30, 0 ++# CHECK: encoding: [0xc8,0x4b,0x68,0x38] ++ammin.wu $r8, $r18, $r30, 0 ++ ++# CHECK: ammin.du $r7, $r16, $r25, 0 ++# CHECK: encoding: [0x27,0xc3,0x68,0x38] ++ammin.du $r7, $r16, $r25, 0 ++ ++# CHECK: fldgt.s $f3, $r27, $r13 ++# CHECK: encoding: [0x63,0x37,0x74,0x38] ++fldgt.s $f3, $r27, $r13 ++ ++# CHECK: fldgt.d $f26, $r5, $r31 ++# CHECK: encoding: [0xba,0xfc,0x74,0x38] ++fldgt.d $f26, $r5, $r31 ++ ++# CHECK: fldle.s $f24, $r29, $r17 ++# CHECK: encoding: [0xb8,0x47,0x75,0x38] ++fldle.s $f24, $r29, $r17 ++ ++# CHECK: fldle.d $f3, $r15, $r22 ++# CHECK: encoding: [0xe3,0xd9,0x75,0x38] ++fldle.d $f3, $r15, $r22 ++ ++# CHECK: fstgt.s $f31, $r13, $r30 ++# CHECK: encoding: [0xbf,0x79,0x76,0x38] ++fstgt.s $f31, $r13, $r30 ++ ++# CHECK: fstgt.d $f13, $r11, $r26 ++# CHECK: encoding: [0x6d,0xe9,0x76,0x38] ++fstgt.d $f13, $r11, $r26 ++ ++# CHECK: fstle.s $f13, $r13, $r7 ++# CHECK: encoding: [0xad,0x1d,0x77,0x38] ++fstle.s $f13, $r13, $r7 ++ ++# CHECK: fstle.d $f18, $r9, $r13 ++# CHECK: encoding: [0x32,0xb5,0x77,0x38] ++fstle.d $f18, $r9, $r13 ++ ++# CHECK: preld 10, $zero, 23 ++# CHECK: encoding: [0x0a,0x5c,0xc0,0x2a] ++preld 10, $zero, 23 ++ ++# CHECK: ldgt.b $r6, $r6, $r29 ++# CHECK: encoding: [0xc6,0x74,0x78,0x38] ++ldgt.b $r6, $r6, $r29 ++ ++# CHECK: ldgt.h $r5, $r31, $ra ++# CHECK: encoding: [0xe5,0x87,0x78,0x38] ++ldgt.h $r5, $r31, $ra ++ ++# CHECK: ldgt.w $r15, $r26, $r8 ++# CHECK: encoding: [0x4f,0x23,0x79,0x38] ++ldgt.w $r15, $r26, $r8 ++ ++# CHECK: ldgt.d $r23, $r25, $r31 ++# CHECK: encoding: [0x37,0xff,0x79,0x38] ++ldgt.d $r23, $r25, $r31 ++ ++# CHECK: ldle.b $r9, $r12, $r15 ++# CHECK: encoding: [0x89,0x3d,0x7a,0x38] ++ldle.b $r9, $r12, $r15 ++ ++# CHECK: ldle.h $r11, $r11, $r23 ++# CHECK: encoding: [0x6b,0xdd,0x7a,0x38] ++ldle.h $r11, $r11, $r23 ++ ++# CHECK: ldle.w $r24, $tp, $tp ++# CHECK: encoding: [0x58,0x08,0x7b,0x38] ++ldle.w $r24, $tp, $tp ++ ++# CHECK: ldle.d $r20, $r15, $r16 ++# CHECK: encoding: [0xf4,0xc1,0x7b,0x38] ++ldle.d $r20, $r15, $r16 ++ ++# CHECK: stgt.b $r27, $r19, $r20 ++# CHECK: encoding: [0x7b,0x52,0x7c,0x38] ++stgt.b $r27, $r19, $r20 ++ ++# CHECK: stgt.h $r16, $r4, $r6 ++# CHECK: encoding: [0x90,0x98,0x7c,0x38] ++stgt.h $r16, $r4, $r6 ++ ++# CHECK: stgt.w $r31, $r28, $r14 ++# CHECK: encoding: [0x9f,0x3b,0x7d,0x38] ++stgt.w $r31, $r28, $r14 ++ ++# CHECK: stgt.d $r30, $r21, $r24 ++# CHECK: encoding: [0xbe,0xe2,0x7d,0x38] ++stgt.d $r30, $r21, $r24 ++ ++# CHECK: stle.b $r10, $r4, $r16 ++# CHECK: encoding: [0x8a,0x40,0x7e,0x38] ++stle.b $r10, $r4, $r16 ++ ++# CHECK: stle.h $r17, $r17, $r21 ++# CHECK: encoding: [0x31,0xd6,0x7e,0x38] ++stle.h $r17, $r17, $r21 ++ ++# CHECK: stle.w $r23, $r28, $r29 ++# CHECK: encoding: [0x97,0x77,0x7f,0x38] ++stle.w $r23, $r28, $r29 ++ ++# CHECK: stle.d $r25, $r24, $r29 ++# CHECK: encoding: [0x19,0xf7,0x7f,0x38] ++stle.d $r25, $r24, $r29 ++ +diff --git a/llvm/test/MC/LoongArch/valid_priv.s b/llvm/test/MC/LoongArch/valid_priv.s +new file mode 100644 +index 000000000..57a252a8d +--- /dev/null ++++ b/llvm/test/MC/LoongArch/valid_priv.s +@@ -0,0 +1,125 @@ ++# RUN: llvm-mc %s -triple=loongarch64-unknown-linux-gnu -show-encoding | FileCheck %s ++# CHECK: csrrd $r26, 30 ++# CHECK: encoding: [0x1a,0x78,0x00,0x04] ++csrrd $r26, 30 ++ ++# CHECK: csrwr $r24, 194 ++# CHECK: encoding: [0x38,0x08,0x03,0x04] ++csrwr $r24, 194 ++ ++# CHECK: csrxchg $r6, $r27, 214 ++# CHECK: encoding: [0x66,0x5b,0x03,0x04] ++csrxchg $r6, $r27, 214 ++ ++# CHECK: cacop 0, $r10, 27 ++# CHECK: encoding: [0x40,0x6d,0x00,0x06] ++cacop 0, $r10, 27 ++ ++# CHECK: lddir $r12, $r30, 92 ++# CHECK: encoding: [0xcc,0x73,0x41,0x06] ++lddir $r12, $r30, 92 ++ ++# CHECK: ldpte $r18, 200 ++# CHECK: encoding: [0x40,0x22,0x47,0x06] ++ldpte $r18, 200 ++ ++# CHECK: iocsrrd.b $r26, $r24 ++# CHECK: encoding: [0x1a,0x03,0x48,0x06] ++iocsrrd.b $r26, $r24 ++ ++# CHECK: iocsrrd.h $r5, $r27 ++# CHECK: encoding: [0x65,0x07,0x48,0x06] ++iocsrrd.h $r5, $r27 ++ ++# CHECK: iocsrrd.w $r10, $r20 ++# CHECK: encoding: [0x8a,0x0a,0x48,0x06] ++iocsrrd.w $r10, $r20 ++ ++# CHECK: iocsrrd.d $r17, $r25 ++# CHECK: encoding: [0x31,0x0f,0x48,0x06] ++iocsrrd.d $r17, $r25 ++ ++# CHECK: iocsrwr.b $r4, $r23 ++# CHECK: encoding: [0xe4,0x12,0x48,0x06] ++iocsrwr.b $r4, $r23 ++ ++# CHECK: iocsrwr.h $r11, $zero ++# CHECK: encoding: [0x0b,0x14,0x48,0x06] ++iocsrwr.h $r11, $zero ++ ++# CHECK: iocsrwr.w $r20, $r26 ++# CHECK: encoding: [0x54,0x1b,0x48,0x06] ++iocsrwr.w $r20, $r26 ++ ++# CHECK: iocsrwr.d $r20, $r7 ++# CHECK: encoding: [0xf4,0x1c,0x48,0x06] ++iocsrwr.d $r20, $r7 ++ ++# CHECK: tlbclr ++# CHECK: encoding: [0x00,0x20,0x48,0x06] ++tlbclr ++ ++# CHECK: tlbflush ++# CHECK: encoding: [0x00,0x24,0x48,0x06] ++tlbflush ++ ++# CHECK: tlbsrch ++# CHECK: encoding: [0x00,0x28,0x48,0x06] ++tlbsrch ++ ++# CHECK: tlbrd ++# CHECK: encoding: [0x00,0x2c,0x48,0x06] ++tlbrd ++ ++# CHECK: tlbwr ++# CHECK: encoding: [0x00,0x30,0x48,0x06] ++tlbwr ++ ++# CHECK: tlbfill ++# CHECK: encoding: [0x00,0x34,0x48,0x06] ++tlbfill ++ ++# CHECK: ertn ++# CHECK: encoding: [0x00,0x38,0x48,0x06] ++ertn ++ ++# CHECK: idle 204 ++# CHECK: encoding: [0xcc,0x80,0x48,0x06] ++idle 204 ++ ++# CHECK: invtlb 16, $r29, $r25 ++# CHECK: encoding: [0xb0,0xe7,0x49,0x06] ++invtlb 16, $r29, $r25 ++ ++# CHECK: rdtimel.w $r30, $r19 ++# CHECK: encoding: [0x7e,0x62,0x00,0x00] ++rdtimel.w $r30, $r19 ++ ++# CHECK: rdtimeh.w $r19, $r14 ++# CHECK: encoding: [0xd3,0x65,0x00,0x00] ++rdtimeh.w $r19, $r14 ++ ++# CHECK: rdtime.d $tp, $r15 ++# CHECK: encoding: [0xe2,0x69,0x00,0x00] ++rdtime.d $tp, $r15 ++ ++# CHECK: asrtle.d $r12, $r17 ++# CHECK: encoding: [0x80,0x45,0x01,0x00] ++asrtle.d $r12, $r17 ++ ++# CHECK: asrtgt.d $r20, $r20 ++# CHECK: encoding: [0x80,0xd2,0x01,0x00] ++asrtgt.d $r20, $r20 ++ ++# CHECK: break 199 ++# CHECK: encoding: [0xc7,0x00,0x2a,0x00] ++break 199 ++ ++# CHECK: dbcl 201 ++# CHECK: encoding: [0xc9,0x80,0x2a,0x00] ++dbcl 201 ++ ++# CHECK: syscall 100 ++# CHECK: encoding: [0x64,0x00,0x2b,0x00] ++syscall 100 ++ +diff --git a/llvm/test/MC/LoongArch/valid_simd.s b/llvm/test/MC/LoongArch/valid_simd.s +new file mode 100644 +index 000000000..2d3496403 +--- /dev/null ++++ b/llvm/test/MC/LoongArch/valid_simd.s +@@ -0,0 +1,5469 @@ ++# RUN: llvm-mc %s -triple=loongarch64-unknown-linux-gnu -show-encoding | FileCheck %s ++# CHECK: vfmadd.s $vr15, $vr22, $vr10, $vr18 ++# CHECK: encoding: [0xcf,0x2a,0x19,0x09] ++vfmadd.s $vr15, $vr22, $vr10, $vr18 ++ ++# CHECK: vfmadd.d $vr1, $vr0, $vr12, $vr10 ++# CHECK: encoding: [0x01,0x30,0x25,0x09] ++vfmadd.d $vr1, $vr0, $vr12, $vr10 ++ ++# CHECK: vfmsub.s $vr16, $vr18, $vr13, $vr8 ++# CHECK: encoding: [0x50,0x36,0x54,0x09] ++vfmsub.s $vr16, $vr18, $vr13, $vr8 ++ ++# CHECK: vfmsub.d $vr25, $vr13, $vr1, $vr20 ++# CHECK: encoding: [0xb9,0x05,0x6a,0x09] ++vfmsub.d $vr25, $vr13, $vr1, $vr20 ++ ++# CHECK: vfnmadd.s $vr22, $vr2, $vr17, $vr22 ++# CHECK: encoding: [0x56,0x44,0x9b,0x09] ++vfnmadd.s $vr22, $vr2, $vr17, $vr22 ++ ++# CHECK: vfnmadd.d $vr28, $vr29, $vr2, $vr14 ++# CHECK: encoding: [0xbc,0x0b,0xa7,0x09] ++vfnmadd.d $vr28, $vr29, $vr2, $vr14 ++ ++# CHECK: vfnmsub.s $vr19, $vr4, $vr17, $vr24 ++# CHECK: encoding: [0x93,0x44,0xdc,0x09] ++vfnmsub.s $vr19, $vr4, $vr17, $vr24 ++ ++# CHECK: vfnmsub.d $vr24, $vr22, $vr28, $vr30 ++# CHECK: encoding: [0xd8,0x72,0xef,0x09] ++vfnmsub.d $vr24, $vr22, $vr28, $vr30 ++ ++# CHECK: xvfmadd.s $xr15, $xr28, $xr9, $xr15 ++# CHECK: encoding: [0x8f,0xa7,0x17,0x0a] ++xvfmadd.s $xr15, $xr28, $xr9, $xr15 ++ ++# CHECK: xvfmadd.d $xr5, $xr24, $xr12, $xr10 ++# CHECK: encoding: [0x05,0x33,0x25,0x0a] ++xvfmadd.d $xr5, $xr24, $xr12, $xr10 ++ ++# CHECK: xvfmsub.s $xr20, $xr0, $xr27, $xr26 ++# CHECK: encoding: [0x14,0x6c,0x5d,0x0a] ++xvfmsub.s $xr20, $xr0, $xr27, $xr26 ++ ++# CHECK: xvfmsub.d $xr13, $xr8, $xr25, $xr26 ++# CHECK: encoding: [0x0d,0x65,0x6d,0x0a] ++xvfmsub.d $xr13, $xr8, $xr25, $xr26 ++ ++# CHECK: xvfnmadd.s $xr14, $xr14, $xr22, $xr8 ++# CHECK: encoding: [0xce,0x59,0x94,0x0a] ++xvfnmadd.s $xr14, $xr14, $xr22, $xr8 ++ ++# CHECK: xvfnmadd.d $xr25, $xr17, $xr0, $xr4 ++# CHECK: encoding: [0x39,0x02,0xa2,0x0a] ++xvfnmadd.d $xr25, $xr17, $xr0, $xr4 ++ ++# CHECK: xvfnmsub.s $xr11, $xr3, $xr0, $xr11 ++# CHECK: encoding: [0x6b,0x80,0xd5,0x0a] ++xvfnmsub.s $xr11, $xr3, $xr0, $xr11 ++ ++# CHECK: xvfnmsub.d $xr2, $xr3, $xr24, $xr22 ++# CHECK: encoding: [0x62,0x60,0xeb,0x0a] ++xvfnmsub.d $xr2, $xr3, $xr24, $xr22 ++ ++# CHECK: vfcmp.ceq.s $vr26, $vr15, $vr27 ++# CHECK: encoding: [0xfa,0x6d,0x52,0x0c] ++vfcmp.ceq.s $vr26, $vr15, $vr27 ++ ++# CHECK: vfcmp.ceq.d $vr21, $vr21, $vr1 ++# CHECK: encoding: [0xb5,0x06,0x62,0x0c] ++vfcmp.ceq.d $vr21, $vr21, $vr1 ++ ++# CHECK: xvfcmp.ceq.s $xr8, $xr9, $xr19 ++# CHECK: encoding: [0x28,0x4d,0x92,0x0c] ++xvfcmp.ceq.s $xr8, $xr9, $xr19 ++ ++# CHECK: xvfcmp.ceq.d $xr25, $xr16, $xr28 ++# CHECK: encoding: [0x19,0x72,0xa2,0x0c] ++xvfcmp.ceq.d $xr25, $xr16, $xr28 ++ ++# CHECK: vbitsel.v $vr20, $vr23, $vr29, $vr9 ++# CHECK: encoding: [0xf4,0xf6,0x14,0x0d] ++vbitsel.v $vr20, $vr23, $vr29, $vr9 ++ ++# CHECK: xvbitsel.v $xr7, $xr26, $xr28, $xr23 ++# CHECK: encoding: [0x47,0xf3,0x2b,0x0d] ++xvbitsel.v $xr7, $xr26, $xr28, $xr23 ++ ++# CHECK: vshuf.b $vr11, $vr4, $vr7, $vr9 ++# CHECK: encoding: [0x8b,0x9c,0x54,0x0d] ++vshuf.b $vr11, $vr4, $vr7, $vr9 ++ ++# CHECK: xvshuf.b $xr16, $xr21, $xr10, $xr12 ++# CHECK: encoding: [0xb0,0x2a,0x66,0x0d] ++xvshuf.b $xr16, $xr21, $xr10, $xr12 ++ ++# CHECK: vld $vr28, $r25, -510 ++# CHECK: encoding: [0x3c,0x0b,0x38,0x2c] ++vld $vr28, $r25, -510 ++ ++# CHECK: vst $vr28, $r14, 527 ++# CHECK: encoding: [0xdc,0x3d,0x48,0x2c] ++vst $vr28, $r14, 527 ++ ++# CHECK: xvld $xr11, $r6, 512 ++# CHECK: encoding: [0xcb,0x00,0x88,0x2c] ++xvld $xr11, $r6, 512 ++ ++# CHECK: xvst $xr13, $r7, 1215 ++# CHECK: encoding: [0xed,0xfc,0xd2,0x2c] ++xvst $xr13, $r7, 1215 ++ ++# CHECK: vldrepl.d $vr8, $r9, -1544 ++# CHECK: encoding: [0x28,0xfd,0x14,0x30] ++vldrepl.d $vr8, $r9, -1544 ++ ++# CHECK: vldrepl.w $vr2, $r9, -296 ++# CHECK: encoding: [0x22,0xd9,0x2e,0x30] ++vldrepl.w $vr2, $r9, -296 ++ ++# CHECK: vldrepl.h $vr28, $r23, 252 ++# CHECK: encoding: [0xfc,0xfa,0x41,0x30] ++vldrepl.h $vr28, $r23, 252 ++ ++# CHECK: vldrepl.b $vr5, $r9, -725 ++# CHECK: encoding: [0x25,0xad,0xb4,0x30] ++vldrepl.b $vr5, $r9, -725 ++ ++# CHECK: vstelm.d $vr23, $r26, 680, 1 ++# CHECK: encoding: [0x57,0x57,0x15,0x31] ++vstelm.d $vr23, $r26, 680, 1 ++ ++# CHECK: vstelm.w $vr30, $r23, -372, 1 ++# CHECK: encoding: [0xfe,0x8e,0x26,0x31] ++vstelm.w $vr30, $r23, -372, 1 ++ ++# CHECK: vstelm.h $vr11, $r6, 30, 7 ++# CHECK: encoding: [0xcb,0x3c,0x5c,0x31] ++vstelm.h $vr11, $r6, 30, 7 ++ ++# CHECK: vstelm.b $vr3, $r15, 44, 14 ++# CHECK: encoding: [0xe3,0xb1,0xb8,0x31] ++vstelm.b $vr3, $r15, 44, 14 ++ ++# CHECK: xvldrepl.d $xr24, $r8, 840 ++# CHECK: encoding: [0x18,0xa5,0x11,0x32] ++xvldrepl.d $xr24, $r8, 840 ++ ++# CHECK: xvldrepl.w $xr14, $r24, 492 ++# CHECK: encoding: [0x0e,0xef,0x21,0x32] ++xvldrepl.w $xr14, $r24, 492 ++ ++# CHECK: xvldrepl.h $xr18, $r9, 804 ++# CHECK: encoding: [0x32,0x49,0x46,0x32] ++xvldrepl.h $xr18, $r9, 804 ++ ++# CHECK: xvldrepl.b $xr6, $r29, 811 ++# CHECK: encoding: [0xa6,0xaf,0x8c,0x32] ++xvldrepl.b $xr6, $r29, 811 ++ ++# CHECK: xvstelm.d $xr21, $sp, -216, 0 ++# CHECK: encoding: [0x75,0x94,0x13,0x33] ++xvstelm.d $xr21, $sp, -216, 0 ++ ++# CHECK: xvstelm.w $xr31, $r29, 424, 0 ++# CHECK: encoding: [0xbf,0xab,0x21,0x33] ++xvstelm.w $xr31, $r29, 424, 0 ++ ++# CHECK: xvstelm.h $xr14, $r7, 90, 4 ++# CHECK: encoding: [0xee,0xb4,0x50,0x33] ++xvstelm.h $xr14, $r7, 90, 4 ++ ++# CHECK: xvstelm.b $xr21, $r24, -5, 8 ++# CHECK: encoding: [0x15,0xef,0xa3,0x33] ++xvstelm.b $xr21, $r24, -5, 8 ++ ++# CHECK: vldx $vr29, $r4, $r30 ++# CHECK: encoding: [0x9d,0x78,0x40,0x38] ++vldx $vr29, $r4, $r30 ++ ++# CHECK: vstx $vr31, $r28, $r29 ++# CHECK: encoding: [0x9f,0x77,0x44,0x38] ++vstx $vr31, $r28, $r29 ++ ++# CHECK: xvldx $xr8, $r30, $r24 ++# CHECK: encoding: [0xc8,0x63,0x48,0x38] ++xvldx $xr8, $r30, $r24 ++ ++# CHECK: xvstx $xr2, $r9, $r29 ++# CHECK: encoding: [0x22,0x75,0x4c,0x38] ++xvstx $xr2, $r9, $r29 ++ ++# CHECK: vseq.b $vr28, $vr26, $vr23 ++# CHECK: encoding: [0x5c,0x5f,0x00,0x70] ++vseq.b $vr28, $vr26, $vr23 ++ ++# CHECK: vseq.h $vr10, $vr1, $vr5 ++# CHECK: encoding: [0x2a,0x94,0x00,0x70] ++vseq.h $vr10, $vr1, $vr5 ++ ++# CHECK: vseq.w $vr3, $vr27, $vr17 ++# CHECK: encoding: [0x63,0x47,0x01,0x70] ++vseq.w $vr3, $vr27, $vr17 ++ ++# CHECK: vseq.d $vr5, $vr3, $vr3 ++# CHECK: encoding: [0x65,0x8c,0x01,0x70] ++vseq.d $vr5, $vr3, $vr3 ++ ++# CHECK: vsle.b $vr29, $vr9, $vr7 ++# CHECK: encoding: [0x3d,0x1d,0x02,0x70] ++vsle.b $vr29, $vr9, $vr7 ++ ++# CHECK: vsle.h $vr5, $vr24, $vr9 ++# CHECK: encoding: [0x05,0xa7,0x02,0x70] ++vsle.h $vr5, $vr24, $vr9 ++ ++# CHECK: vsle.w $vr17, $vr30, $vr20 ++# CHECK: encoding: [0xd1,0x53,0x03,0x70] ++vsle.w $vr17, $vr30, $vr20 ++ ++# CHECK: vsle.d $vr27, $vr6, $vr13 ++# CHECK: encoding: [0xdb,0xb4,0x03,0x70] ++vsle.d $vr27, $vr6, $vr13 ++ ++# CHECK: vsle.bu $vr30, $vr11, $vr10 ++# CHECK: encoding: [0x7e,0x29,0x04,0x70] ++vsle.bu $vr30, $vr11, $vr10 ++ ++# CHECK: vsle.hu $vr19, $vr29, $vr31 ++# CHECK: encoding: [0xb3,0xff,0x04,0x70] ++vsle.hu $vr19, $vr29, $vr31 ++ ++# CHECK: vsle.wu $vr16, $vr18, $vr20 ++# CHECK: encoding: [0x50,0x52,0x05,0x70] ++vsle.wu $vr16, $vr18, $vr20 ++ ++# CHECK: vsle.du $vr31, $vr17, $vr8 ++# CHECK: encoding: [0x3f,0xa2,0x05,0x70] ++vsle.du $vr31, $vr17, $vr8 ++ ++# CHECK: vslt.b $vr26, $vr7, $vr5 ++# CHECK: encoding: [0xfa,0x14,0x06,0x70] ++vslt.b $vr26, $vr7, $vr5 ++ ++# CHECK: vslt.h $vr14, $vr2, $vr20 ++# CHECK: encoding: [0x4e,0xd0,0x06,0x70] ++vslt.h $vr14, $vr2, $vr20 ++ ++# CHECK: vslt.w $vr14, $vr5, $vr25 ++# CHECK: encoding: [0xae,0x64,0x07,0x70] ++vslt.w $vr14, $vr5, $vr25 ++ ++# CHECK: vslt.d $vr26, $vr9, $vr25 ++# CHECK: encoding: [0x3a,0xe5,0x07,0x70] ++vslt.d $vr26, $vr9, $vr25 ++ ++# CHECK: vslt.bu $vr31, $vr18, $vr14 ++# CHECK: encoding: [0x5f,0x3a,0x08,0x70] ++vslt.bu $vr31, $vr18, $vr14 ++ ++# CHECK: vslt.hu $vr5, $vr15, $vr5 ++# CHECK: encoding: [0xe5,0x95,0x08,0x70] ++vslt.hu $vr5, $vr15, $vr5 ++ ++# CHECK: vslt.wu $vr31, $vr28, $vr13 ++# CHECK: encoding: [0x9f,0x37,0x09,0x70] ++vslt.wu $vr31, $vr28, $vr13 ++ ++# CHECK: vslt.du $vr11, $vr19, $vr22 ++# CHECK: encoding: [0x6b,0xda,0x09,0x70] ++vslt.du $vr11, $vr19, $vr22 ++ ++# CHECK: vadd.b $vr26, $vr20, $vr31 ++# CHECK: encoding: [0x9a,0x7e,0x0a,0x70] ++vadd.b $vr26, $vr20, $vr31 ++ ++# CHECK: vadd.h $vr11, $vr25, $vr29 ++# CHECK: encoding: [0x2b,0xf7,0x0a,0x70] ++vadd.h $vr11, $vr25, $vr29 ++ ++# CHECK: vadd.w $vr7, $vr25, $vr13 ++# CHECK: encoding: [0x27,0x37,0x0b,0x70] ++vadd.w $vr7, $vr25, $vr13 ++ ++# CHECK: vadd.d $vr16, $vr13, $vr16 ++# CHECK: encoding: [0xb0,0xc1,0x0b,0x70] ++vadd.d $vr16, $vr13, $vr16 ++ ++# CHECK: vsub.b $vr12, $vr3, $vr21 ++# CHECK: encoding: [0x6c,0x54,0x0c,0x70] ++vsub.b $vr12, $vr3, $vr21 ++ ++# CHECK: vsub.h $vr15, $vr13, $vr25 ++# CHECK: encoding: [0xaf,0xe5,0x0c,0x70] ++vsub.h $vr15, $vr13, $vr25 ++ ++# CHECK: vsub.w $vr20, $vr16, $vr25 ++# CHECK: encoding: [0x14,0x66,0x0d,0x70] ++vsub.w $vr20, $vr16, $vr25 ++ ++# CHECK: vsub.d $vr19, $vr3, $vr7 ++# CHECK: encoding: [0x73,0x9c,0x0d,0x70] ++vsub.d $vr19, $vr3, $vr7 ++ ++# CHECK: vsadd.b $vr14, $vr30, $vr5 ++# CHECK: encoding: [0xce,0x17,0x46,0x70] ++vsadd.b $vr14, $vr30, $vr5 ++ ++# CHECK: vsadd.h $vr10, $vr1, $vr15 ++# CHECK: encoding: [0x2a,0xbc,0x46,0x70] ++vsadd.h $vr10, $vr1, $vr15 ++ ++# CHECK: vsadd.w $vr19, $vr31, $vr10 ++# CHECK: encoding: [0xf3,0x2b,0x47,0x70] ++vsadd.w $vr19, $vr31, $vr10 ++ ++# CHECK: vsadd.d $vr26, $vr19, $vr28 ++# CHECK: encoding: [0x7a,0xf2,0x47,0x70] ++vsadd.d $vr26, $vr19, $vr28 ++ ++# CHECK: vssub.b $vr24, $vr3, $vr7 ++# CHECK: encoding: [0x78,0x1c,0x48,0x70] ++vssub.b $vr24, $vr3, $vr7 ++ ++# CHECK: vssub.h $vr31, $vr4, $vr24 ++# CHECK: encoding: [0x9f,0xe0,0x48,0x70] ++vssub.h $vr31, $vr4, $vr24 ++ ++# CHECK: vssub.w $vr29, $vr27, $vr12 ++# CHECK: encoding: [0x7d,0x33,0x49,0x70] ++vssub.w $vr29, $vr27, $vr12 ++ ++# CHECK: vssub.d $vr23, $vr16, $vr9 ++# CHECK: encoding: [0x17,0xa6,0x49,0x70] ++vssub.d $vr23, $vr16, $vr9 ++ ++# CHECK: vsadd.bu $vr26, $vr29, $vr4 ++# CHECK: encoding: [0xba,0x13,0x4a,0x70] ++vsadd.bu $vr26, $vr29, $vr4 ++ ++# CHECK: vsadd.hu $vr15, $vr7, $vr9 ++# CHECK: encoding: [0xef,0xa4,0x4a,0x70] ++vsadd.hu $vr15, $vr7, $vr9 ++ ++# CHECK: vsadd.wu $vr13, $vr18, $vr16 ++# CHECK: encoding: [0x4d,0x42,0x4b,0x70] ++vsadd.wu $vr13, $vr18, $vr16 ++ ++# CHECK: vsadd.du $vr4, $vr5, $vr0 ++# CHECK: encoding: [0xa4,0x80,0x4b,0x70] ++vsadd.du $vr4, $vr5, $vr0 ++ ++# CHECK: vssub.bu $vr27, $vr17, $vr13 ++# CHECK: encoding: [0x3b,0x36,0x4c,0x70] ++vssub.bu $vr27, $vr17, $vr13 ++ ++# CHECK: vssub.hu $vr5, $vr8, $vr1 ++# CHECK: encoding: [0x05,0x85,0x4c,0x70] ++vssub.hu $vr5, $vr8, $vr1 ++ ++# CHECK: vssub.wu $vr14, $vr8, $vr22 ++# CHECK: encoding: [0x0e,0x59,0x4d,0x70] ++vssub.wu $vr14, $vr8, $vr22 ++ ++# CHECK: vssub.du $vr17, $vr9, $vr8 ++# CHECK: encoding: [0x31,0xa1,0x4d,0x70] ++vssub.du $vr17, $vr9, $vr8 ++ ++# CHECK: vhaddw.h.b $vr23, $vr19, $vr2 ++# CHECK: encoding: [0x77,0x0a,0x54,0x70] ++vhaddw.h.b $vr23, $vr19, $vr2 ++ ++# CHECK: vhaddw.w.h $vr26, $vr16, $vr26 ++# CHECK: encoding: [0x1a,0xea,0x54,0x70] ++vhaddw.w.h $vr26, $vr16, $vr26 ++ ++# CHECK: vhaddw.d.w $vr0, $vr31, $vr27 ++# CHECK: encoding: [0xe0,0x6f,0x55,0x70] ++vhaddw.d.w $vr0, $vr31, $vr27 ++ ++# CHECK: vhaddw.q.d $vr25, $vr13, $vr25 ++# CHECK: encoding: [0xb9,0xe5,0x55,0x70] ++vhaddw.q.d $vr25, $vr13, $vr25 ++ ++# CHECK: vhsubw.h.b $vr9, $vr23, $vr5 ++# CHECK: encoding: [0xe9,0x16,0x56,0x70] ++vhsubw.h.b $vr9, $vr23, $vr5 ++ ++# CHECK: vhsubw.w.h $vr15, $vr29, $vr26 ++# CHECK: encoding: [0xaf,0xeb,0x56,0x70] ++vhsubw.w.h $vr15, $vr29, $vr26 ++ ++# CHECK: vhsubw.d.w $vr0, $vr28, $vr18 ++# CHECK: encoding: [0x80,0x4b,0x57,0x70] ++vhsubw.d.w $vr0, $vr28, $vr18 ++ ++# CHECK: vhsubw.q.d $vr14, $vr25, $vr8 ++# CHECK: encoding: [0x2e,0xa3,0x57,0x70] ++vhsubw.q.d $vr14, $vr25, $vr8 ++ ++# CHECK: vhaddw.hu.bu $vr1, $vr16, $vr21 ++# CHECK: encoding: [0x01,0x56,0x58,0x70] ++vhaddw.hu.bu $vr1, $vr16, $vr21 ++ ++# CHECK: vhaddw.wu.hu $vr28, $vr21, $vr29 ++# CHECK: encoding: [0xbc,0xf6,0x58,0x70] ++vhaddw.wu.hu $vr28, $vr21, $vr29 ++ ++# CHECK: vhaddw.du.wu $vr29, $vr20, $vr16 ++# CHECK: encoding: [0x9d,0x42,0x59,0x70] ++vhaddw.du.wu $vr29, $vr20, $vr16 ++ ++# CHECK: vhaddw.qu.du $vr2, $vr10, $vr28 ++# CHECK: encoding: [0x42,0xf1,0x59,0x70] ++vhaddw.qu.du $vr2, $vr10, $vr28 ++ ++# CHECK: vhsubw.hu.bu $vr31, $vr3, $vr30 ++# CHECK: encoding: [0x7f,0x78,0x5a,0x70] ++vhsubw.hu.bu $vr31, $vr3, $vr30 ++ ++# CHECK: vhsubw.wu.hu $vr5, $vr9, $vr11 ++# CHECK: encoding: [0x25,0xad,0x5a,0x70] ++vhsubw.wu.hu $vr5, $vr9, $vr11 ++ ++# CHECK: vhsubw.du.wu $vr23, $vr31, $vr22 ++# CHECK: encoding: [0xf7,0x5b,0x5b,0x70] ++vhsubw.du.wu $vr23, $vr31, $vr22 ++ ++# CHECK: vhsubw.qu.du $vr4, $vr28, $vr18 ++# CHECK: encoding: [0x84,0xcb,0x5b,0x70] ++vhsubw.qu.du $vr4, $vr28, $vr18 ++ ++# CHECK: vadda.b $vr18, $vr13, $vr11 ++# CHECK: encoding: [0xb2,0x2d,0x5c,0x70] ++vadda.b $vr18, $vr13, $vr11 ++ ++# CHECK: vadda.h $vr17, $vr14, $vr12 ++# CHECK: encoding: [0xd1,0xb1,0x5c,0x70] ++vadda.h $vr17, $vr14, $vr12 ++ ++# CHECK: vadda.w $vr22, $vr11, $vr3 ++# CHECK: encoding: [0x76,0x0d,0x5d,0x70] ++vadda.w $vr22, $vr11, $vr3 ++ ++# CHECK: vadda.d $vr24, $vr24, $vr15 ++# CHECK: encoding: [0x18,0xbf,0x5d,0x70] ++vadda.d $vr24, $vr24, $vr15 ++ ++# CHECK: vabsd.b $vr23, $vr19, $vr17 ++# CHECK: encoding: [0x77,0x46,0x60,0x70] ++vabsd.b $vr23, $vr19, $vr17 ++ ++# CHECK: vabsd.h $vr14, $vr31, $vr13 ++# CHECK: encoding: [0xee,0xb7,0x60,0x70] ++vabsd.h $vr14, $vr31, $vr13 ++ ++# CHECK: vabsd.w $vr24, $vr1, $vr9 ++# CHECK: encoding: [0x38,0x24,0x61,0x70] ++vabsd.w $vr24, $vr1, $vr9 ++ ++# CHECK: vabsd.d $vr31, $vr20, $vr0 ++# CHECK: encoding: [0x9f,0x82,0x61,0x70] ++vabsd.d $vr31, $vr20, $vr0 ++ ++# CHECK: vabsd.bu $vr23, $vr12, $vr29 ++# CHECK: encoding: [0x97,0x75,0x62,0x70] ++vabsd.bu $vr23, $vr12, $vr29 ++ ++# CHECK: vabsd.hu $vr18, $vr19, $vr1 ++# CHECK: encoding: [0x72,0x86,0x62,0x70] ++vabsd.hu $vr18, $vr19, $vr1 ++ ++# CHECK: vabsd.wu $vr13, $vr21, $vr28 ++# CHECK: encoding: [0xad,0x72,0x63,0x70] ++vabsd.wu $vr13, $vr21, $vr28 ++ ++# CHECK: vabsd.du $vr16, $vr26, $vr11 ++# CHECK: encoding: [0x50,0xaf,0x63,0x70] ++vabsd.du $vr16, $vr26, $vr11 ++ ++# CHECK: vavg.b $vr1, $vr21, $vr27 ++# CHECK: encoding: [0xa1,0x6e,0x64,0x70] ++vavg.b $vr1, $vr21, $vr27 ++ ++# CHECK: vavg.h $vr20, $vr26, $vr15 ++# CHECK: encoding: [0x54,0xbf,0x64,0x70] ++vavg.h $vr20, $vr26, $vr15 ++ ++# CHECK: vavg.w $vr29, $vr18, $vr3 ++# CHECK: encoding: [0x5d,0x0e,0x65,0x70] ++vavg.w $vr29, $vr18, $vr3 ++ ++# CHECK: vavg.d $vr19, $vr15, $vr31 ++# CHECK: encoding: [0xf3,0xfd,0x65,0x70] ++vavg.d $vr19, $vr15, $vr31 ++ ++# CHECK: vavg.bu $vr11, $vr11, $vr17 ++# CHECK: encoding: [0x6b,0x45,0x66,0x70] ++vavg.bu $vr11, $vr11, $vr17 ++ ++# CHECK: vavg.hu $vr30, $vr28, $vr13 ++# CHECK: encoding: [0x9e,0xb7,0x66,0x70] ++vavg.hu $vr30, $vr28, $vr13 ++ ++# CHECK: vavg.wu $vr7, $vr7, $vr10 ++# CHECK: encoding: [0xe7,0x28,0x67,0x70] ++vavg.wu $vr7, $vr7, $vr10 ++ ++# CHECK: vavg.du $vr25, $vr7, $vr12 ++# CHECK: encoding: [0xf9,0xb0,0x67,0x70] ++vavg.du $vr25, $vr7, $vr12 ++ ++# CHECK: vavgr.b $vr29, $vr13, $vr7 ++# CHECK: encoding: [0xbd,0x1d,0x68,0x70] ++vavgr.b $vr29, $vr13, $vr7 ++ ++# CHECK: vavgr.h $vr5, $vr28, $vr19 ++# CHECK: encoding: [0x85,0xcf,0x68,0x70] ++vavgr.h $vr5, $vr28, $vr19 ++ ++# CHECK: vavgr.w $vr19, $vr15, $vr14 ++# CHECK: encoding: [0xf3,0x39,0x69,0x70] ++vavgr.w $vr19, $vr15, $vr14 ++ ++# CHECK: vavgr.d $vr3, $vr0, $vr2 ++# CHECK: encoding: [0x03,0x88,0x69,0x70] ++vavgr.d $vr3, $vr0, $vr2 ++ ++# CHECK: vavgr.bu $vr23, $vr11, $vr31 ++# CHECK: encoding: [0x77,0x7d,0x6a,0x70] ++vavgr.bu $vr23, $vr11, $vr31 ++ ++# CHECK: vavgr.hu $vr25, $vr19, $vr8 ++# CHECK: encoding: [0x79,0xa2,0x6a,0x70] ++vavgr.hu $vr25, $vr19, $vr8 ++ ++# CHECK: vavgr.wu $vr30, $vr25, $vr12 ++# CHECK: encoding: [0x3e,0x33,0x6b,0x70] ++vavgr.wu $vr30, $vr25, $vr12 ++ ++# CHECK: vavgr.du $vr25, $vr20, $vr25 ++# CHECK: encoding: [0x99,0xe6,0x6b,0x70] ++vavgr.du $vr25, $vr20, $vr25 ++ ++# CHECK: vmax.b $vr28, $vr26, $vr26 ++# CHECK: encoding: [0x5c,0x6b,0x70,0x70] ++vmax.b $vr28, $vr26, $vr26 ++ ++# CHECK: vmax.h $vr8, $vr13, $vr11 ++# CHECK: encoding: [0xa8,0xad,0x70,0x70] ++vmax.h $vr8, $vr13, $vr11 ++ ++# CHECK: vmax.w $vr21, $vr28, $vr31 ++# CHECK: encoding: [0x95,0x7f,0x71,0x70] ++vmax.w $vr21, $vr28, $vr31 ++ ++# CHECK: vmax.d $vr1, $vr30, $vr26 ++# CHECK: encoding: [0xc1,0xeb,0x71,0x70] ++vmax.d $vr1, $vr30, $vr26 ++ ++# CHECK: vmin.b $vr10, $vr14, $vr9 ++# CHECK: encoding: [0xca,0x25,0x72,0x70] ++vmin.b $vr10, $vr14, $vr9 ++ ++# CHECK: vmin.h $vr10, $vr11, $vr21 ++# CHECK: encoding: [0x6a,0xd5,0x72,0x70] ++vmin.h $vr10, $vr11, $vr21 ++ ++# CHECK: vmin.w $vr26, $vr0, $vr12 ++# CHECK: encoding: [0x1a,0x30,0x73,0x70] ++vmin.w $vr26, $vr0, $vr12 ++ ++# CHECK: vmin.d $vr19, $vr18, $vr0 ++# CHECK: encoding: [0x53,0x82,0x73,0x70] ++vmin.d $vr19, $vr18, $vr0 ++ ++# CHECK: vmax.bu $vr2, $vr25, $vr28 ++# CHECK: encoding: [0x22,0x73,0x74,0x70] ++vmax.bu $vr2, $vr25, $vr28 ++ ++# CHECK: vmax.hu $vr9, $vr22, $vr30 ++# CHECK: encoding: [0xc9,0xfa,0x74,0x70] ++vmax.hu $vr9, $vr22, $vr30 ++ ++# CHECK: vmax.wu $vr21, $vr25, $vr27 ++# CHECK: encoding: [0x35,0x6f,0x75,0x70] ++vmax.wu $vr21, $vr25, $vr27 ++ ++# CHECK: vmax.du $vr3, $vr14, $vr25 ++# CHECK: encoding: [0xc3,0xe5,0x75,0x70] ++vmax.du $vr3, $vr14, $vr25 ++ ++# CHECK: vmin.bu $vr24, $vr7, $vr27 ++# CHECK: encoding: [0xf8,0x6c,0x76,0x70] ++vmin.bu $vr24, $vr7, $vr27 ++ ++# CHECK: vmin.hu $vr18, $vr28, $vr29 ++# CHECK: encoding: [0x92,0xf7,0x76,0x70] ++vmin.hu $vr18, $vr28, $vr29 ++ ++# CHECK: vmin.wu $vr26, $vr4, $vr2 ++# CHECK: encoding: [0x9a,0x08,0x77,0x70] ++vmin.wu $vr26, $vr4, $vr2 ++ ++# CHECK: vmin.du $vr13, $vr0, $vr4 ++# CHECK: encoding: [0x0d,0x90,0x77,0x70] ++vmin.du $vr13, $vr0, $vr4 ++ ++# CHECK: vmul.b $vr1, $vr21, $vr23 ++# CHECK: encoding: [0xa1,0x5e,0x84,0x70] ++vmul.b $vr1, $vr21, $vr23 ++ ++# CHECK: vmul.h $vr9, $vr21, $vr25 ++# CHECK: encoding: [0xa9,0xe6,0x84,0x70] ++vmul.h $vr9, $vr21, $vr25 ++ ++# CHECK: vmul.w $vr16, $vr8, $vr28 ++# CHECK: encoding: [0x10,0x71,0x85,0x70] ++vmul.w $vr16, $vr8, $vr28 ++ ++# CHECK: vmul.d $vr4, $vr17, $vr11 ++# CHECK: encoding: [0x24,0xae,0x85,0x70] ++vmul.d $vr4, $vr17, $vr11 ++ ++# CHECK: vmuh.b $vr12, $vr24, $vr8 ++# CHECK: encoding: [0x0c,0x23,0x86,0x70] ++vmuh.b $vr12, $vr24, $vr8 ++ ++# CHECK: vmuh.h $vr6, $vr21, $vr24 ++# CHECK: encoding: [0xa6,0xe2,0x86,0x70] ++vmuh.h $vr6, $vr21, $vr24 ++ ++# CHECK: vmuh.w $vr11, $vr29, $vr30 ++# CHECK: encoding: [0xab,0x7b,0x87,0x70] ++vmuh.w $vr11, $vr29, $vr30 ++ ++# CHECK: vmuh.d $vr1, $vr17, $vr25 ++# CHECK: encoding: [0x21,0xe6,0x87,0x70] ++vmuh.d $vr1, $vr17, $vr25 ++ ++# CHECK: vmuh.bu $vr29, $vr29, $vr10 ++# CHECK: encoding: [0xbd,0x2b,0x88,0x70] ++vmuh.bu $vr29, $vr29, $vr10 ++ ++# CHECK: vmuh.hu $vr24, $vr9, $vr21 ++# CHECK: encoding: [0x38,0xd5,0x88,0x70] ++vmuh.hu $vr24, $vr9, $vr21 ++ ++# CHECK: vmuh.wu $vr15, $vr20, $vr19 ++# CHECK: encoding: [0x8f,0x4e,0x89,0x70] ++vmuh.wu $vr15, $vr20, $vr19 ++ ++# CHECK: vmuh.du $vr0, $vr28, $vr1 ++# CHECK: encoding: [0x80,0x87,0x89,0x70] ++vmuh.du $vr0, $vr28, $vr1 ++ ++# CHECK: vmadd.b $vr27, $vr0, $vr4 ++# CHECK: encoding: [0x1b,0x10,0xa8,0x70] ++vmadd.b $vr27, $vr0, $vr4 ++ ++# CHECK: vmadd.h $vr19, $vr20, $vr28 ++# CHECK: encoding: [0x93,0xf2,0xa8,0x70] ++vmadd.h $vr19, $vr20, $vr28 ++ ++# CHECK: vmadd.w $vr15, $vr7, $vr3 ++# CHECK: encoding: [0xef,0x0c,0xa9,0x70] ++vmadd.w $vr15, $vr7, $vr3 ++ ++# CHECK: vmadd.d $vr25, $vr25, $vr30 ++# CHECK: encoding: [0x39,0xfb,0xa9,0x70] ++vmadd.d $vr25, $vr25, $vr30 ++ ++# CHECK: vmsub.b $vr24, $vr25, $vr26 ++# CHECK: encoding: [0x38,0x6b,0xaa,0x70] ++vmsub.b $vr24, $vr25, $vr26 ++ ++# CHECK: vmsub.h $vr12, $vr0, $vr13 ++# CHECK: encoding: [0x0c,0xb4,0xaa,0x70] ++vmsub.h $vr12, $vr0, $vr13 ++ ++# CHECK: vmsub.w $vr26, $vr16, $vr24 ++# CHECK: encoding: [0x1a,0x62,0xab,0x70] ++vmsub.w $vr26, $vr16, $vr24 ++ ++# CHECK: vmsub.d $vr13, $vr10, $vr8 ++# CHECK: encoding: [0x4d,0xa1,0xab,0x70] ++vmsub.d $vr13, $vr10, $vr8 ++ ++# CHECK: vdiv.b $vr18, $vr28, $vr21 ++# CHECK: encoding: [0x92,0x57,0xe0,0x70] ++vdiv.b $vr18, $vr28, $vr21 ++ ++# CHECK: vdiv.h $vr17, $vr24, $vr1 ++# CHECK: encoding: [0x11,0x87,0xe0,0x70] ++vdiv.h $vr17, $vr24, $vr1 ++ ++# CHECK: vdiv.w $vr3, $vr10, $vr22 ++# CHECK: encoding: [0x43,0x59,0xe1,0x70] ++vdiv.w $vr3, $vr10, $vr22 ++ ++# CHECK: vdiv.d $vr15, $vr13, $vr8 ++# CHECK: encoding: [0xaf,0xa1,0xe1,0x70] ++vdiv.d $vr15, $vr13, $vr8 ++ ++# CHECK: vmod.b $vr19, $vr25, $vr20 ++# CHECK: encoding: [0x33,0x53,0xe2,0x70] ++vmod.b $vr19, $vr25, $vr20 ++ ++# CHECK: vmod.h $vr2, $vr24, $vr22 ++# CHECK: encoding: [0x02,0xdb,0xe2,0x70] ++vmod.h $vr2, $vr24, $vr22 ++ ++# CHECK: vmod.w $vr31, $vr18, $vr0 ++# CHECK: encoding: [0x5f,0x02,0xe3,0x70] ++vmod.w $vr31, $vr18, $vr0 ++ ++# CHECK: vmod.d $vr31, $vr0, $vr2 ++# CHECK: encoding: [0x1f,0x88,0xe3,0x70] ++vmod.d $vr31, $vr0, $vr2 ++ ++# CHECK: vdiv.bu $vr15, $vr4, $vr3 ++# CHECK: encoding: [0x8f,0x0c,0xe4,0x70] ++vdiv.bu $vr15, $vr4, $vr3 ++ ++# CHECK: vdiv.hu $vr17, $vr7, $vr29 ++# CHECK: encoding: [0xf1,0xf4,0xe4,0x70] ++vdiv.hu $vr17, $vr7, $vr29 ++ ++# CHECK: vdiv.wu $vr27, $vr10, $vr3 ++# CHECK: encoding: [0x5b,0x0d,0xe5,0x70] ++vdiv.wu $vr27, $vr10, $vr3 ++ ++# CHECK: vdiv.du $vr8, $vr24, $vr26 ++# CHECK: encoding: [0x08,0xeb,0xe5,0x70] ++vdiv.du $vr8, $vr24, $vr26 ++ ++# CHECK: vmod.bu $vr10, $vr22, $vr24 ++# CHECK: encoding: [0xca,0x62,0xe6,0x70] ++vmod.bu $vr10, $vr22, $vr24 ++ ++# CHECK: vmod.hu $vr19, $vr31, $vr24 ++# CHECK: encoding: [0xf3,0xe3,0xe6,0x70] ++vmod.hu $vr19, $vr31, $vr24 ++ ++# CHECK: vmod.wu $vr26, $vr24, $vr13 ++# CHECK: encoding: [0x1a,0x37,0xe7,0x70] ++vmod.wu $vr26, $vr24, $vr13 ++ ++# CHECK: vmod.du $vr20, $vr19, $vr10 ++# CHECK: encoding: [0x74,0xaa,0xe7,0x70] ++vmod.du $vr20, $vr19, $vr10 ++ ++# CHECK: vsll.b $vr28, $vr18, $vr30 ++# CHECK: encoding: [0x5c,0x7a,0xe8,0x70] ++vsll.b $vr28, $vr18, $vr30 ++ ++# CHECK: vsll.h $vr22, $vr4, $vr30 ++# CHECK: encoding: [0x96,0xf8,0xe8,0x70] ++vsll.h $vr22, $vr4, $vr30 ++ ++# CHECK: vsll.w $vr1, $vr25, $vr8 ++# CHECK: encoding: [0x21,0x23,0xe9,0x70] ++vsll.w $vr1, $vr25, $vr8 ++ ++# CHECK: vsll.d $vr31, $vr18, $vr15 ++# CHECK: encoding: [0x5f,0xbe,0xe9,0x70] ++vsll.d $vr31, $vr18, $vr15 ++ ++# CHECK: vsrl.b $vr5, $vr12, $vr16 ++# CHECK: encoding: [0x85,0x41,0xea,0x70] ++vsrl.b $vr5, $vr12, $vr16 ++ ++# CHECK: vsrl.h $vr9, $vr5, $vr28 ++# CHECK: encoding: [0xa9,0xf0,0xea,0x70] ++vsrl.h $vr9, $vr5, $vr28 ++ ++# CHECK: vsrl.w $vr30, $vr16, $vr1 ++# CHECK: encoding: [0x1e,0x06,0xeb,0x70] ++vsrl.w $vr30, $vr16, $vr1 ++ ++# CHECK: vsrl.d $vr28, $vr23, $vr27 ++# CHECK: encoding: [0xfc,0xee,0xeb,0x70] ++vsrl.d $vr28, $vr23, $vr27 ++ ++# CHECK: vsra.b $vr15, $vr17, $vr25 ++# CHECK: encoding: [0x2f,0x66,0xec,0x70] ++vsra.b $vr15, $vr17, $vr25 ++ ++# CHECK: vsra.h $vr0, $vr8, $vr5 ++# CHECK: encoding: [0x00,0x95,0xec,0x70] ++vsra.h $vr0, $vr8, $vr5 ++ ++# CHECK: vsra.w $vr29, $vr9, $vr7 ++# CHECK: encoding: [0x3d,0x1d,0xed,0x70] ++vsra.w $vr29, $vr9, $vr7 ++ ++# CHECK: vsra.d $vr22, $vr3, $vr19 ++# CHECK: encoding: [0x76,0xcc,0xed,0x70] ++vsra.d $vr22, $vr3, $vr19 ++ ++# CHECK: vrotr.b $vr8, $vr16, $vr8 ++# CHECK: encoding: [0x08,0x22,0xee,0x70] ++vrotr.b $vr8, $vr16, $vr8 ++ ++# CHECK: vrotr.h $vr14, $vr5, $vr11 ++# CHECK: encoding: [0xae,0xac,0xee,0x70] ++vrotr.h $vr14, $vr5, $vr11 ++ ++# CHECK: vrotr.w $vr17, $vr28, $vr25 ++# CHECK: encoding: [0x91,0x67,0xef,0x70] ++vrotr.w $vr17, $vr28, $vr25 ++ ++# CHECK: vrotr.d $vr18, $vr28, $vr19 ++# CHECK: encoding: [0x92,0xcf,0xef,0x70] ++vrotr.d $vr18, $vr28, $vr19 ++ ++# CHECK: vsrlr.b $vr1, $vr27, $vr17 ++# CHECK: encoding: [0x61,0x47,0xf0,0x70] ++vsrlr.b $vr1, $vr27, $vr17 ++ ++# CHECK: vsrlr.h $vr26, $vr14, $vr10 ++# CHECK: encoding: [0xda,0xa9,0xf0,0x70] ++vsrlr.h $vr26, $vr14, $vr10 ++ ++# CHECK: vsrlr.w $vr3, $vr29, $vr24 ++# CHECK: encoding: [0xa3,0x63,0xf1,0x70] ++vsrlr.w $vr3, $vr29, $vr24 ++ ++# CHECK: vsrlr.d $vr23, $vr4, $vr10 ++# CHECK: encoding: [0x97,0xa8,0xf1,0x70] ++vsrlr.d $vr23, $vr4, $vr10 ++ ++# CHECK: vsrar.b $vr25, $vr2, $vr21 ++# CHECK: encoding: [0x59,0x54,0xf2,0x70] ++vsrar.b $vr25, $vr2, $vr21 ++ ++# CHECK: vsrar.h $vr4, $vr11, $vr20 ++# CHECK: encoding: [0x64,0xd1,0xf2,0x70] ++vsrar.h $vr4, $vr11, $vr20 ++ ++# CHECK: vsrar.w $vr11, $vr21, $vr29 ++# CHECK: encoding: [0xab,0x76,0xf3,0x70] ++vsrar.w $vr11, $vr21, $vr29 ++ ++# CHECK: vsrar.d $vr29, $vr5, $vr2 ++# CHECK: encoding: [0xbd,0x88,0xf3,0x70] ++vsrar.d $vr29, $vr5, $vr2 ++ ++# CHECK: vsrln.b.h $vr24, $vr14, $vr29 ++# CHECK: encoding: [0xd8,0xf5,0xf4,0x70] ++vsrln.b.h $vr24, $vr14, $vr29 ++ ++# CHECK: vsrln.h.w $vr26, $vr22, $vr16 ++# CHECK: encoding: [0xda,0x42,0xf5,0x70] ++vsrln.h.w $vr26, $vr22, $vr16 ++ ++# CHECK: vsrln.w.d $vr17, $vr31, $vr2 ++# CHECK: encoding: [0xf1,0x8b,0xf5,0x70] ++vsrln.w.d $vr17, $vr31, $vr2 ++ ++# CHECK: vsran.b.h $vr31, $vr0, $vr23 ++# CHECK: encoding: [0x1f,0xdc,0xf6,0x70] ++vsran.b.h $vr31, $vr0, $vr23 ++ ++# CHECK: vsran.h.w $vr20, $vr12, $vr29 ++# CHECK: encoding: [0x94,0x75,0xf7,0x70] ++vsran.h.w $vr20, $vr12, $vr29 ++ ++# CHECK: vsran.w.d $vr2, $vr1, $vr2 ++# CHECK: encoding: [0x22,0x88,0xf7,0x70] ++vsran.w.d $vr2, $vr1, $vr2 ++ ++# CHECK: vsrlrn.b.h $vr19, $vr28, $vr0 ++# CHECK: encoding: [0x93,0x83,0xf8,0x70] ++vsrlrn.b.h $vr19, $vr28, $vr0 ++ ++# CHECK: vsrlrn.h.w $vr23, $vr29, $vr14 ++# CHECK: encoding: [0xb7,0x3b,0xf9,0x70] ++vsrlrn.h.w $vr23, $vr29, $vr14 ++ ++# CHECK: vsrlrn.w.d $vr5, $vr26, $vr5 ++# CHECK: encoding: [0x45,0x97,0xf9,0x70] ++vsrlrn.w.d $vr5, $vr26, $vr5 ++ ++# CHECK: vsrarn.b.h $vr17, $vr15, $vr7 ++# CHECK: encoding: [0xf1,0x9d,0xfa,0x70] ++vsrarn.b.h $vr17, $vr15, $vr7 ++ ++# CHECK: vsrarn.h.w $vr12, $vr10, $vr29 ++# CHECK: encoding: [0x4c,0x75,0xfb,0x70] ++vsrarn.h.w $vr12, $vr10, $vr29 ++ ++# CHECK: vsrarn.w.d $vr24, $vr26, $vr27 ++# CHECK: encoding: [0x58,0xef,0xfb,0x70] ++vsrarn.w.d $vr24, $vr26, $vr27 ++ ++# CHECK: vssrln.b.h $vr1, $vr12, $vr14 ++# CHECK: encoding: [0x81,0xb9,0xfc,0x70] ++vssrln.b.h $vr1, $vr12, $vr14 ++ ++# CHECK: vssrln.h.w $vr11, $vr8, $vr18 ++# CHECK: encoding: [0x0b,0x49,0xfd,0x70] ++vssrln.h.w $vr11, $vr8, $vr18 ++ ++# CHECK: vssrln.w.d $vr31, $vr15, $vr6 ++# CHECK: encoding: [0xff,0x99,0xfd,0x70] ++vssrln.w.d $vr31, $vr15, $vr6 ++ ++# CHECK: vssran.b.h $vr13, $vr5, $vr24 ++# CHECK: encoding: [0xad,0xe0,0xfe,0x70] ++vssran.b.h $vr13, $vr5, $vr24 ++ ++# CHECK: vssran.h.w $vr4, $vr26, $vr7 ++# CHECK: encoding: [0x44,0x1f,0xff,0x70] ++vssran.h.w $vr4, $vr26, $vr7 ++ ++# CHECK: vssran.w.d $vr25, $vr10, $vr6 ++# CHECK: encoding: [0x59,0x99,0xff,0x70] ++vssran.w.d $vr25, $vr10, $vr6 ++ ++# CHECK: vssrlrn.b.h $vr28, $vr28, $vr6 ++# CHECK: encoding: [0x9c,0x9b,0x00,0x71] ++vssrlrn.b.h $vr28, $vr28, $vr6 ++ ++# CHECK: vssrlrn.h.w $vr15, $vr23, $vr17 ++# CHECK: encoding: [0xef,0x46,0x01,0x71] ++vssrlrn.h.w $vr15, $vr23, $vr17 ++ ++# CHECK: vssrlrn.w.d $vr12, $vr9, $vr2 ++# CHECK: encoding: [0x2c,0x89,0x01,0x71] ++vssrlrn.w.d $vr12, $vr9, $vr2 ++ ++# CHECK: vssrarn.b.h $vr1, $vr25, $vr17 ++# CHECK: encoding: [0x21,0xc7,0x02,0x71] ++vssrarn.b.h $vr1, $vr25, $vr17 ++ ++# CHECK: vssrarn.h.w $vr3, $vr9, $vr23 ++# CHECK: encoding: [0x23,0x5d,0x03,0x71] ++vssrarn.h.w $vr3, $vr9, $vr23 ++ ++# CHECK: vssrarn.w.d $vr14, $vr9, $vr27 ++# CHECK: encoding: [0x2e,0xed,0x03,0x71] ++vssrarn.w.d $vr14, $vr9, $vr27 ++ ++# CHECK: vssrln.bu.h $vr16, $vr24, $vr15 ++# CHECK: encoding: [0x10,0xbf,0x04,0x71] ++vssrln.bu.h $vr16, $vr24, $vr15 ++ ++# CHECK: vssrln.hu.w $vr21, $vr23, $vr30 ++# CHECK: encoding: [0xf5,0x7a,0x05,0x71] ++vssrln.hu.w $vr21, $vr23, $vr30 ++ ++# CHECK: vssrln.wu.d $vr12, $vr8, $vr30 ++# CHECK: encoding: [0x0c,0xf9,0x05,0x71] ++vssrln.wu.d $vr12, $vr8, $vr30 ++ ++# CHECK: vssran.bu.h $vr5, $vr18, $vr12 ++# CHECK: encoding: [0x45,0xb2,0x06,0x71] ++vssran.bu.h $vr5, $vr18, $vr12 ++ ++# CHECK: vssran.hu.w $vr0, $vr7, $vr28 ++# CHECK: encoding: [0xe0,0x70,0x07,0x71] ++vssran.hu.w $vr0, $vr7, $vr28 ++ ++# CHECK: vssran.wu.d $vr5, $vr11, $vr8 ++# CHECK: encoding: [0x65,0xa1,0x07,0x71] ++vssran.wu.d $vr5, $vr11, $vr8 ++ ++# CHECK: vssrlrn.bu.h $vr18, $vr25, $vr3 ++# CHECK: encoding: [0x32,0x8f,0x08,0x71] ++vssrlrn.bu.h $vr18, $vr25, $vr3 ++ ++# CHECK: vssrlrn.hu.w $vr19, $vr1, $vr20 ++# CHECK: encoding: [0x33,0x50,0x09,0x71] ++vssrlrn.hu.w $vr19, $vr1, $vr20 ++ ++# CHECK: vssrlrn.wu.d $vr6, $vr30, $vr18 ++# CHECK: encoding: [0xc6,0xcb,0x09,0x71] ++vssrlrn.wu.d $vr6, $vr30, $vr18 ++ ++# CHECK: vssrarn.bu.h $vr12, $vr13, $vr3 ++# CHECK: encoding: [0xac,0x8d,0x0a,0x71] ++vssrarn.bu.h $vr12, $vr13, $vr3 ++ ++# CHECK: vssrarn.hu.w $vr18, $vr5, $vr20 ++# CHECK: encoding: [0xb2,0x50,0x0b,0x71] ++vssrarn.hu.w $vr18, $vr5, $vr20 ++ ++# CHECK: vssrarn.wu.d $vr23, $vr8, $vr21 ++# CHECK: encoding: [0x17,0xd5,0x0b,0x71] ++vssrarn.wu.d $vr23, $vr8, $vr21 ++ ++# CHECK: vbitclr.b $vr14, $vr2, $vr31 ++# CHECK: encoding: [0x4e,0x7c,0x0c,0x71] ++vbitclr.b $vr14, $vr2, $vr31 ++ ++# CHECK: vbitclr.h $vr17, $vr25, $vr8 ++# CHECK: encoding: [0x31,0xa3,0x0c,0x71] ++vbitclr.h $vr17, $vr25, $vr8 ++ ++# CHECK: vbitclr.w $vr18, $vr11, $vr3 ++# CHECK: encoding: [0x72,0x0d,0x0d,0x71] ++vbitclr.w $vr18, $vr11, $vr3 ++ ++# CHECK: vbitclr.d $vr31, $vr15, $vr29 ++# CHECK: encoding: [0xff,0xf5,0x0d,0x71] ++vbitclr.d $vr31, $vr15, $vr29 ++ ++# CHECK: vbitset.b $vr8, $vr29, $vr16 ++# CHECK: encoding: [0xa8,0x43,0x0e,0x71] ++vbitset.b $vr8, $vr29, $vr16 ++ ++# CHECK: vbitset.h $vr5, $vr17, $vr17 ++# CHECK: encoding: [0x25,0xc6,0x0e,0x71] ++vbitset.h $vr5, $vr17, $vr17 ++ ++# CHECK: vbitset.w $vr5, $vr19, $vr5 ++# CHECK: encoding: [0x65,0x16,0x0f,0x71] ++vbitset.w $vr5, $vr19, $vr5 ++ ++# CHECK: vbitset.d $vr5, $vr27, $vr10 ++# CHECK: encoding: [0x65,0xab,0x0f,0x71] ++vbitset.d $vr5, $vr27, $vr10 ++ ++# CHECK: vbitrev.b $vr16, $vr5, $vr8 ++# CHECK: encoding: [0xb0,0x20,0x10,0x71] ++vbitrev.b $vr16, $vr5, $vr8 ++ ++# CHECK: vbitrev.h $vr12, $vr29, $vr12 ++# CHECK: encoding: [0xac,0xb3,0x10,0x71] ++vbitrev.h $vr12, $vr29, $vr12 ++ ++# CHECK: vbitrev.w $vr3, $vr14, $vr14 ++# CHECK: encoding: [0xc3,0x39,0x11,0x71] ++vbitrev.w $vr3, $vr14, $vr14 ++ ++# CHECK: vbitrev.d $vr31, $vr27, $vr14 ++# CHECK: encoding: [0x7f,0xbb,0x11,0x71] ++vbitrev.d $vr31, $vr27, $vr14 ++ ++# CHECK: vpackev.b $vr22, $vr24, $vr19 ++# CHECK: encoding: [0x16,0x4f,0x16,0x71] ++vpackev.b $vr22, $vr24, $vr19 ++ ++# CHECK: vpackev.h $vr28, $vr2, $vr18 ++# CHECK: encoding: [0x5c,0xc8,0x16,0x71] ++vpackev.h $vr28, $vr2, $vr18 ++ ++# CHECK: vpackev.w $vr21, $vr3, $vr4 ++# CHECK: encoding: [0x75,0x10,0x17,0x71] ++vpackev.w $vr21, $vr3, $vr4 ++ ++# CHECK: vpackev.d $vr24, $vr21, $vr11 ++# CHECK: encoding: [0xb8,0xae,0x17,0x71] ++vpackev.d $vr24, $vr21, $vr11 ++ ++# CHECK: vpackod.b $vr12, $vr31, $vr26 ++# CHECK: encoding: [0xec,0x6b,0x18,0x71] ++vpackod.b $vr12, $vr31, $vr26 ++ ++# CHECK: vpackod.h $vr25, $vr3, $vr16 ++# CHECK: encoding: [0x79,0xc0,0x18,0x71] ++vpackod.h $vr25, $vr3, $vr16 ++ ++# CHECK: vpackod.w $vr21, $vr18, $vr15 ++# CHECK: encoding: [0x55,0x3e,0x19,0x71] ++vpackod.w $vr21, $vr18, $vr15 ++ ++# CHECK: vpackod.d $vr2, $vr3, $vr0 ++# CHECK: encoding: [0x62,0x80,0x19,0x71] ++vpackod.d $vr2, $vr3, $vr0 ++ ++# CHECK: vilvl.b $vr8, $vr8, $vr28 ++# CHECK: encoding: [0x08,0x71,0x1a,0x71] ++vilvl.b $vr8, $vr8, $vr28 ++ ++# CHECK: vilvl.h $vr20, $vr0, $vr31 ++# CHECK: encoding: [0x14,0xfc,0x1a,0x71] ++vilvl.h $vr20, $vr0, $vr31 ++ ++# CHECK: vilvl.w $vr11, $vr10, $vr17 ++# CHECK: encoding: [0x4b,0x45,0x1b,0x71] ++vilvl.w $vr11, $vr10, $vr17 ++ ++# CHECK: vilvl.d $vr7, $vr7, $vr1 ++# CHECK: encoding: [0xe7,0x84,0x1b,0x71] ++vilvl.d $vr7, $vr7, $vr1 ++ ++# CHECK: vilvh.b $vr11, $vr11, $vr1 ++# CHECK: encoding: [0x6b,0x05,0x1c,0x71] ++vilvh.b $vr11, $vr11, $vr1 ++ ++# CHECK: vilvh.h $vr0, $vr31, $vr13 ++# CHECK: encoding: [0xe0,0xb7,0x1c,0x71] ++vilvh.h $vr0, $vr31, $vr13 ++ ++# CHECK: vilvh.w $vr28, $vr21, $vr7 ++# CHECK: encoding: [0xbc,0x1e,0x1d,0x71] ++vilvh.w $vr28, $vr21, $vr7 ++ ++# CHECK: vilvh.d $vr23, $vr3, $vr19 ++# CHECK: encoding: [0x77,0xcc,0x1d,0x71] ++vilvh.d $vr23, $vr3, $vr19 ++ ++# CHECK: vpickev.b $vr1, $vr21, $vr8 ++# CHECK: encoding: [0xa1,0x22,0x1e,0x71] ++vpickev.b $vr1, $vr21, $vr8 ++ ++# CHECK: vpickev.h $vr16, $vr1, $vr9 ++# CHECK: encoding: [0x30,0xa4,0x1e,0x71] ++vpickev.h $vr16, $vr1, $vr9 ++ ++# CHECK: vpickev.w $vr13, $vr13, $vr4 ++# CHECK: encoding: [0xad,0x11,0x1f,0x71] ++vpickev.w $vr13, $vr13, $vr4 ++ ++# CHECK: vpickev.d $vr11, $vr30, $vr30 ++# CHECK: encoding: [0xcb,0xfb,0x1f,0x71] ++vpickev.d $vr11, $vr30, $vr30 ++ ++# CHECK: vpickod.b $vr7, $vr11, $vr13 ++# CHECK: encoding: [0x67,0x35,0x20,0x71] ++vpickod.b $vr7, $vr11, $vr13 ++ ++# CHECK: vpickod.h $vr18, $vr3, $vr1 ++# CHECK: encoding: [0x72,0x84,0x20,0x71] ++vpickod.h $vr18, $vr3, $vr1 ++ ++# CHECK: vpickod.w $vr3, $vr16, $vr19 ++# CHECK: encoding: [0x03,0x4e,0x21,0x71] ++vpickod.w $vr3, $vr16, $vr19 ++ ++# CHECK: vpickod.d $vr12, $vr13, $vr21 ++# CHECK: encoding: [0xac,0xd5,0x21,0x71] ++vpickod.d $vr12, $vr13, $vr21 ++ ++# CHECK: vreplve.b $vr15, $vr17, $r19 ++# CHECK: encoding: [0x2f,0x4e,0x22,0x71] ++vreplve.b $vr15, $vr17, $r19 ++ ++# CHECK: vreplve.h $vr14, $vr23, $r4 ++# CHECK: encoding: [0xee,0x92,0x22,0x71] ++vreplve.h $vr14, $vr23, $r4 ++ ++# CHECK: vreplve.w $vr29, $vr19, $r27 ++# CHECK: encoding: [0x7d,0x6e,0x23,0x71] ++vreplve.w $vr29, $vr19, $r27 ++ ++# CHECK: vreplve.d $vr13, $vr20, $r20 ++# CHECK: encoding: [0x8d,0xd2,0x23,0x71] ++vreplve.d $vr13, $vr20, $r20 ++ ++# CHECK: vand.v $vr25, $vr2, $vr21 ++# CHECK: encoding: [0x59,0x54,0x26,0x71] ++vand.v $vr25, $vr2, $vr21 ++ ++# CHECK: vor.v $vr4, $vr27, $vr16 ++# CHECK: encoding: [0x64,0xc3,0x26,0x71] ++vor.v $vr4, $vr27, $vr16 ++ ++# CHECK: vxor.v $vr30, $vr25, $vr4 ++# CHECK: encoding: [0x3e,0x13,0x27,0x71] ++vxor.v $vr30, $vr25, $vr4 ++ ++# CHECK: vnor.v $vr9, $vr2, $vr22 ++# CHECK: encoding: [0x49,0xd8,0x27,0x71] ++vnor.v $vr9, $vr2, $vr22 ++ ++# CHECK: vandn.v $vr20, $vr26, $vr4 ++# CHECK: encoding: [0x54,0x13,0x28,0x71] ++vandn.v $vr20, $vr26, $vr4 ++ ++# CHECK: vorn.v $vr6, $vr21, $vr30 ++# CHECK: encoding: [0xa6,0xfa,0x28,0x71] ++vorn.v $vr6, $vr21, $vr30 ++ ++# CHECK: vfrstp.b $vr11, $vr9, $vr13 ++# CHECK: encoding: [0x2b,0x35,0x2b,0x71] ++vfrstp.b $vr11, $vr9, $vr13 ++ ++# CHECK: vfrstp.h $vr21, $vr26, $vr22 ++# CHECK: encoding: [0x55,0xdb,0x2b,0x71] ++vfrstp.h $vr21, $vr26, $vr22 ++ ++# CHECK: vadd.q $vr9, $vr7, $vr16 ++# CHECK: encoding: [0xe9,0x40,0x2d,0x71] ++vadd.q $vr9, $vr7, $vr16 ++ ++# CHECK: vsub.q $vr2, $vr1, $vr16 ++# CHECK: encoding: [0x22,0xc0,0x2d,0x71] ++vsub.q $vr2, $vr1, $vr16 ++ ++# CHECK: vsigncov.b $vr2, $vr2, $vr14 ++# CHECK: encoding: [0x42,0x38,0x2e,0x71] ++vsigncov.b $vr2, $vr2, $vr14 ++ ++# CHECK: vsigncov.h $vr21, $vr21, $vr13 ++# CHECK: encoding: [0xb5,0xb6,0x2e,0x71] ++vsigncov.h $vr21, $vr21, $vr13 ++ ++# CHECK: vsigncov.w $vr21, $vr7, $vr5 ++# CHECK: encoding: [0xf5,0x14,0x2f,0x71] ++vsigncov.w $vr21, $vr7, $vr5 ++ ++# CHECK: vsigncov.d $vr10, $vr10, $vr3 ++# CHECK: encoding: [0x4a,0x8d,0x2f,0x71] ++vsigncov.d $vr10, $vr10, $vr3 ++ ++# CHECK: vfadd.s $vr10, $vr4, $vr1 ++# CHECK: encoding: [0x8a,0x84,0x30,0x71] ++vfadd.s $vr10, $vr4, $vr1 ++ ++# CHECK: vfadd.d $vr15, $vr27, $vr2 ++# CHECK: encoding: [0x6f,0x0b,0x31,0x71] ++vfadd.d $vr15, $vr27, $vr2 ++ ++# CHECK: vfsub.s $vr14, $vr16, $vr9 ++# CHECK: encoding: [0x0e,0xa6,0x32,0x71] ++vfsub.s $vr14, $vr16, $vr9 ++ ++# CHECK: vfsub.d $vr4, $vr1, $vr8 ++# CHECK: encoding: [0x24,0x20,0x33,0x71] ++vfsub.d $vr4, $vr1, $vr8 ++ ++# CHECK: vfmul.s $vr0, $vr18, $vr6 ++# CHECK: encoding: [0x40,0x9a,0x38,0x71] ++vfmul.s $vr0, $vr18, $vr6 ++ ++# CHECK: vfmul.d $vr27, $vr31, $vr30 ++# CHECK: encoding: [0xfb,0x7b,0x39,0x71] ++vfmul.d $vr27, $vr31, $vr30 ++ ++# CHECK: vfdiv.s $vr3, $vr7, $vr6 ++# CHECK: encoding: [0xe3,0x98,0x3a,0x71] ++vfdiv.s $vr3, $vr7, $vr6 ++ ++# CHECK: vfdiv.d $vr16, $vr6, $vr30 ++# CHECK: encoding: [0xd0,0x78,0x3b,0x71] ++vfdiv.d $vr16, $vr6, $vr30 ++ ++# CHECK: vfmax.s $vr18, $vr30, $vr8 ++# CHECK: encoding: [0xd2,0xa3,0x3c,0x71] ++vfmax.s $vr18, $vr30, $vr8 ++ ++# CHECK: vfmax.d $vr19, $vr8, $vr24 ++# CHECK: encoding: [0x13,0x61,0x3d,0x71] ++vfmax.d $vr19, $vr8, $vr24 ++ ++# CHECK: vfmin.s $vr24, $vr26, $vr6 ++# CHECK: encoding: [0x58,0x9b,0x3e,0x71] ++vfmin.s $vr24, $vr26, $vr6 ++ ++# CHECK: vfmin.d $vr16, $vr25, $vr1 ++# CHECK: encoding: [0x30,0x07,0x3f,0x71] ++vfmin.d $vr16, $vr25, $vr1 ++ ++# CHECK: vfmaxa.s $vr8, $vr7, $vr14 ++# CHECK: encoding: [0xe8,0xb8,0x40,0x71] ++vfmaxa.s $vr8, $vr7, $vr14 ++ ++# CHECK: vfmaxa.d $vr10, $vr8, $vr4 ++# CHECK: encoding: [0x0a,0x11,0x41,0x71] ++vfmaxa.d $vr10, $vr8, $vr4 ++ ++# CHECK: vfmina.s $vr16, $vr6, $vr18 ++# CHECK: encoding: [0xd0,0xc8,0x42,0x71] ++vfmina.s $vr16, $vr6, $vr18 ++ ++# CHECK: vfmina.d $vr26, $vr7, $vr14 ++# CHECK: encoding: [0xfa,0x38,0x43,0x71] ++vfmina.d $vr26, $vr7, $vr14 ++ ++# CHECK: vfcvt.h.s $vr30, $vr4, $vr24 ++# CHECK: encoding: [0x9e,0x60,0x46,0x71] ++vfcvt.h.s $vr30, $vr4, $vr24 ++ ++# CHECK: vfcvt.s.d $vr16, $vr17, $vr4 ++# CHECK: encoding: [0x30,0x92,0x46,0x71] ++vfcvt.s.d $vr16, $vr17, $vr4 ++ ++# CHECK: vffint.s.l $vr25, $vr23, $vr10 ++# CHECK: encoding: [0xf9,0x2a,0x48,0x71] ++vffint.s.l $vr25, $vr23, $vr10 ++ ++# CHECK: vftint.w.d $vr9, $vr22, $vr27 ++# CHECK: encoding: [0xc9,0xee,0x49,0x71] ++vftint.w.d $vr9, $vr22, $vr27 ++ ++# CHECK: vftintrm.w.d $vr31, $vr10, $vr29 ++# CHECK: encoding: [0x5f,0x75,0x4a,0x71] ++vftintrm.w.d $vr31, $vr10, $vr29 ++ ++# CHECK: vftintrp.w.d $vr23, $vr13, $vr15 ++# CHECK: encoding: [0xb7,0xbd,0x4a,0x71] ++vftintrp.w.d $vr23, $vr13, $vr15 ++ ++# CHECK: vftintrz.w.d $vr18, $vr9, $vr6 ++# CHECK: encoding: [0x32,0x19,0x4b,0x71] ++vftintrz.w.d $vr18, $vr9, $vr6 ++ ++# CHECK: vftintrne.w.d $vr21, $vr12, $vr30 ++# CHECK: encoding: [0x95,0xf9,0x4b,0x71] ++vftintrne.w.d $vr21, $vr12, $vr30 ++ ++# CHECK: vshuf.h $vr3, $vr11, $vr2 ++# CHECK: encoding: [0x63,0x89,0x7a,0x71] ++vshuf.h $vr3, $vr11, $vr2 ++ ++# CHECK: vshuf.w $vr21, $vr4, $vr29 ++# CHECK: encoding: [0x95,0x74,0x7b,0x71] ++vshuf.w $vr21, $vr4, $vr29 ++ ++# CHECK: vshuf.d $vr11, $vr23, $vr18 ++# CHECK: encoding: [0xeb,0xca,0x7b,0x71] ++vshuf.d $vr11, $vr23, $vr18 ++ ++# CHECK: vseqi.b $vr27, $vr14, 7 ++# CHECK: encoding: [0xdb,0x1d,0x80,0x72] ++vseqi.b $vr27, $vr14, 7 ++ ++# CHECK: vseqi.h $vr23, $vr27, -6 ++# CHECK: encoding: [0x77,0xeb,0x80,0x72] ++vseqi.h $vr23, $vr27, -6 ++ ++# CHECK: vseqi.w $vr8, $vr8, -16 ++# CHECK: encoding: [0x08,0x41,0x81,0x72] ++vseqi.w $vr8, $vr8, -16 ++ ++# CHECK: vseqi.d $vr11, $vr5, 5 ++# CHECK: encoding: [0xab,0x94,0x81,0x72] ++vseqi.d $vr11, $vr5, 5 ++ ++# CHECK: vslei.b $vr8, $vr27, 7 ++# CHECK: encoding: [0x68,0x1f,0x82,0x72] ++vslei.b $vr8, $vr27, 7 ++ ++# CHECK: vslei.h $vr27, $vr29, -5 ++# CHECK: encoding: [0xbb,0xef,0x82,0x72] ++vslei.h $vr27, $vr29, -5 ++ ++# CHECK: vslei.w $vr23, $vr13, -3 ++# CHECK: encoding: [0xb7,0x75,0x83,0x72] ++vslei.w $vr23, $vr13, -3 ++ ++# CHECK: vslei.d $vr5, $vr15, -8 ++# CHECK: encoding: [0xe5,0xe1,0x83,0x72] ++vslei.d $vr5, $vr15, -8 ++ ++# CHECK: vslei.bu $vr29, $vr10, 9 ++# CHECK: encoding: [0x5d,0x25,0x84,0x72] ++vslei.bu $vr29, $vr10, 9 ++ ++# CHECK: vslei.hu $vr29, $vr18, 11 ++# CHECK: encoding: [0x5d,0xae,0x84,0x72] ++vslei.hu $vr29, $vr18, 11 ++ ++# CHECK: vslei.wu $vr8, $vr1, 2 ++# CHECK: encoding: [0x28,0x08,0x85,0x72] ++vslei.wu $vr8, $vr1, 2 ++ ++# CHECK: vslei.du $vr16, $vr5, 10 ++# CHECK: encoding: [0xb0,0xa8,0x85,0x72] ++vslei.du $vr16, $vr5, 10 ++ ++# CHECK: vslti.b $vr8, $vr4, -2 ++# CHECK: encoding: [0x88,0x78,0x86,0x72] ++vslti.b $vr8, $vr4, -2 ++ ++# CHECK: vslti.h $vr26, $vr7, -14 ++# CHECK: encoding: [0xfa,0xc8,0x86,0x72] ++vslti.h $vr26, $vr7, -14 ++ ++# CHECK: vslti.w $vr28, $vr8, 12 ++# CHECK: encoding: [0x1c,0x31,0x87,0x72] ++vslti.w $vr28, $vr8, 12 ++ ++# CHECK: vslti.d $vr4, $vr27, 9 ++# CHECK: encoding: [0x64,0xa7,0x87,0x72] ++vslti.d $vr4, $vr27, 9 ++ ++# CHECK: vslti.bu $vr10, $vr14, 18 ++# CHECK: encoding: [0xca,0x49,0x88,0x72] ++vslti.bu $vr10, $vr14, 18 ++ ++# CHECK: vslti.hu $vr28, $vr28, 30 ++# CHECK: encoding: [0x9c,0xfb,0x88,0x72] ++vslti.hu $vr28, $vr28, 30 ++ ++# CHECK: vslti.wu $vr15, $vr27, 27 ++# CHECK: encoding: [0x6f,0x6f,0x89,0x72] ++vslti.wu $vr15, $vr27, 27 ++ ++# CHECK: vslti.du $vr30, $vr17, 19 ++# CHECK: encoding: [0x3e,0xce,0x89,0x72] ++vslti.du $vr30, $vr17, 19 ++ ++# CHECK: vaddi.bu $vr6, $vr1, 18 ++# CHECK: encoding: [0x26,0x48,0x8a,0x72] ++vaddi.bu $vr6, $vr1, 18 ++ ++# CHECK: vaddi.hu $vr12, $vr14, 5 ++# CHECK: encoding: [0xcc,0x95,0x8a,0x72] ++vaddi.hu $vr12, $vr14, 5 ++ ++# CHECK: vaddi.wu $vr28, $vr0, 26 ++# CHECK: encoding: [0x1c,0x68,0x8b,0x72] ++vaddi.wu $vr28, $vr0, 26 ++ ++# CHECK: vaddi.du $vr10, $vr5, 2 ++# CHECK: encoding: [0xaa,0x88,0x8b,0x72] ++vaddi.du $vr10, $vr5, 2 ++ ++# CHECK: vsubi.bu $vr22, $vr28, 2 ++# CHECK: encoding: [0x96,0x0b,0x8c,0x72] ++vsubi.bu $vr22, $vr28, 2 ++ ++# CHECK: vsubi.hu $vr0, $vr22, 31 ++# CHECK: encoding: [0xc0,0xfe,0x8c,0x72] ++vsubi.hu $vr0, $vr22, 31 ++ ++# CHECK: vsubi.wu $vr20, $vr6, 5 ++# CHECK: encoding: [0xd4,0x14,0x8d,0x72] ++vsubi.wu $vr20, $vr6, 5 ++ ++# CHECK: vsubi.du $vr18, $vr11, 1 ++# CHECK: encoding: [0x72,0x85,0x8d,0x72] ++vsubi.du $vr18, $vr11, 1 ++ ++# CHECK: vbsll.v $vr4, $vr26, 4 ++# CHECK: encoding: [0x44,0x13,0x8e,0x72] ++vbsll.v $vr4, $vr26, 4 ++ ++# CHECK: vbsrl.v $vr7, $vr31, 15 ++# CHECK: encoding: [0xe7,0xbf,0x8e,0x72] ++vbsrl.v $vr7, $vr31, 15 ++ ++# CHECK: vmaxi.b $vr19, $vr15, 14 ++# CHECK: encoding: [0xf3,0x39,0x90,0x72] ++vmaxi.b $vr19, $vr15, 14 ++ ++# CHECK: vmaxi.h $vr25, $vr3, -12 ++# CHECK: encoding: [0x79,0xd0,0x90,0x72] ++vmaxi.h $vr25, $vr3, -12 ++ ++# CHECK: vmaxi.w $vr20, $vr25, 5 ++# CHECK: encoding: [0x34,0x17,0x91,0x72] ++vmaxi.w $vr20, $vr25, 5 ++ ++# CHECK: vmaxi.d $vr9, $vr10, 12 ++# CHECK: encoding: [0x49,0xb1,0x91,0x72] ++vmaxi.d $vr9, $vr10, 12 ++ ++# CHECK: vmini.b $vr30, $vr21, -4 ++# CHECK: encoding: [0xbe,0x72,0x92,0x72] ++vmini.b $vr30, $vr21, -4 ++ ++# CHECK: vmini.h $vr11, $vr28, -3 ++# CHECK: encoding: [0x8b,0xf7,0x92,0x72] ++vmini.h $vr11, $vr28, -3 ++ ++# CHECK: vmini.w $vr6, $vr25, -9 ++# CHECK: encoding: [0x26,0x5f,0x93,0x72] ++vmini.w $vr6, $vr25, -9 ++ ++# CHECK: vmini.d $vr28, $vr8, 2 ++# CHECK: encoding: [0x1c,0x89,0x93,0x72] ++vmini.d $vr28, $vr8, 2 ++ ++# CHECK: vmaxi.bu $vr13, $vr24, 19 ++# CHECK: encoding: [0x0d,0x4f,0x94,0x72] ++vmaxi.bu $vr13, $vr24, 19 ++ ++# CHECK: vmaxi.hu $vr3, $vr1, 22 ++# CHECK: encoding: [0x23,0xd8,0x94,0x72] ++vmaxi.hu $vr3, $vr1, 22 ++ ++# CHECK: vmaxi.wu $vr1, $vr3, 23 ++# CHECK: encoding: [0x61,0x5c,0x95,0x72] ++vmaxi.wu $vr1, $vr3, 23 ++ ++# CHECK: vmaxi.du $vr6, $vr18, 21 ++# CHECK: encoding: [0x46,0xd6,0x95,0x72] ++vmaxi.du $vr6, $vr18, 21 ++ ++# CHECK: vmini.bu $vr10, $vr2, 20 ++# CHECK: encoding: [0x4a,0x50,0x96,0x72] ++vmini.bu $vr10, $vr2, 20 ++ ++# CHECK: vmini.hu $vr17, $vr17, 15 ++# CHECK: encoding: [0x31,0xbe,0x96,0x72] ++vmini.hu $vr17, $vr17, 15 ++ ++# CHECK: vmini.wu $vr26, $vr27, 23 ++# CHECK: encoding: [0x7a,0x5f,0x97,0x72] ++vmini.wu $vr26, $vr27, 23 ++ ++# CHECK: vmini.du $vr12, $vr27, 8 ++# CHECK: encoding: [0x6c,0xa3,0x97,0x72] ++vmini.du $vr12, $vr27, 8 ++ ++# CHECK: vfrstpi.b $vr26, $vr8, 9 ++# CHECK: encoding: [0x1a,0x25,0x9a,0x72] ++vfrstpi.b $vr26, $vr8, 9 ++ ++# CHECK: vfrstpi.h $vr16, $vr2, 20 ++# CHECK: encoding: [0x50,0xd0,0x9a,0x72] ++vfrstpi.h $vr16, $vr2, 20 ++ ++# CHECK: vclo.b $vr5, $vr17 ++# CHECK: encoding: [0x25,0x02,0x9c,0x72] ++vclo.b $vr5, $vr17 ++ ++# CHECK: vclo.h $vr8, $vr4 ++# CHECK: encoding: [0x88,0x04,0x9c,0x72] ++vclo.h $vr8, $vr4 ++ ++# CHECK: vclo.w $vr1, $vr13 ++# CHECK: encoding: [0xa1,0x09,0x9c,0x72] ++vclo.w $vr1, $vr13 ++ ++# CHECK: vclo.d $vr0, $vr23 ++# CHECK: encoding: [0xe0,0x0e,0x9c,0x72] ++vclo.d $vr0, $vr23 ++ ++# CHECK: vclz.b $vr4, $vr25 ++# CHECK: encoding: [0x24,0x13,0x9c,0x72] ++vclz.b $vr4, $vr25 ++ ++# CHECK: vclz.h $vr1, $vr25 ++# CHECK: encoding: [0x21,0x17,0x9c,0x72] ++vclz.h $vr1, $vr25 ++ ++# CHECK: vclz.w $vr1, $vr5 ++# CHECK: encoding: [0xa1,0x18,0x9c,0x72] ++vclz.w $vr1, $vr5 ++ ++# CHECK: vclz.d $vr16, $vr17 ++# CHECK: encoding: [0x30,0x1e,0x9c,0x72] ++vclz.d $vr16, $vr17 ++ ++# CHECK: vpcnt.b $vr4, $vr3 ++# CHECK: encoding: [0x64,0x20,0x9c,0x72] ++vpcnt.b $vr4, $vr3 ++ ++# CHECK: vpcnt.h $vr15, $vr17 ++# CHECK: encoding: [0x2f,0x26,0x9c,0x72] ++vpcnt.h $vr15, $vr17 ++ ++# CHECK: vpcnt.w $vr13, $vr8 ++# CHECK: encoding: [0x0d,0x29,0x9c,0x72] ++vpcnt.w $vr13, $vr8 ++ ++# CHECK: vpcnt.d $vr0, $vr8 ++# CHECK: encoding: [0x00,0x2d,0x9c,0x72] ++vpcnt.d $vr0, $vr8 ++ ++# CHECK: vneg.b $vr14, $vr24 ++# CHECK: encoding: [0x0e,0x33,0x9c,0x72] ++vneg.b $vr14, $vr24 ++ ++# CHECK: vneg.h $vr24, $vr7 ++# CHECK: encoding: [0xf8,0x34,0x9c,0x72] ++vneg.h $vr24, $vr7 ++ ++# CHECK: vneg.w $vr19, $vr5 ++# CHECK: encoding: [0xb3,0x38,0x9c,0x72] ++vneg.w $vr19, $vr5 ++ ++# CHECK: vneg.d $vr3, $vr28 ++# CHECK: encoding: [0x83,0x3f,0x9c,0x72] ++vneg.d $vr3, $vr28 ++ ++# CHECK: vmskltz.b $vr31, $vr25 ++# CHECK: encoding: [0x3f,0x43,0x9c,0x72] ++vmskltz.b $vr31, $vr25 ++ ++# CHECK: vmskltz.h $vr9, $vr20 ++# CHECK: encoding: [0x89,0x46,0x9c,0x72] ++vmskltz.h $vr9, $vr20 ++ ++# CHECK: vmskltz.w $vr22, $vr26 ++# CHECK: encoding: [0x56,0x4b,0x9c,0x72] ++vmskltz.w $vr22, $vr26 ++ ++# CHECK: vmskltz.d $vr28, $vr10 ++# CHECK: encoding: [0x5c,0x4d,0x9c,0x72] ++vmskltz.d $vr28, $vr10 ++ ++# CHECK: vmskgez.b $vr7, $vr5 ++# CHECK: encoding: [0xa7,0x50,0x9c,0x72] ++vmskgez.b $vr7, $vr5 ++ ++# CHECK: vmsknz.b $vr20, $vr12 ++# CHECK: encoding: [0x94,0x61,0x9c,0x72] ++vmsknz.b $vr20, $vr12 ++ ++# CHECK: vseteqz.v $fcc5, $vr14 ++# CHECK: encoding: [0xc5,0x99,0x9c,0x72] ++vseteqz.v $fcc5, $vr14 ++ ++# CHECK: vsetnez.v $fcc2, $vr8 ++# CHECK: encoding: [0x02,0x9d,0x9c,0x72] ++vsetnez.v $fcc2, $vr8 ++ ++# CHECK: vsetanyeqz.b $fcc0, $vr20 ++# CHECK: encoding: [0x80,0xa2,0x9c,0x72] ++vsetanyeqz.b $fcc0, $vr20 ++ ++# CHECK: vsetanyeqz.h $fcc4, $vr16 ++# CHECK: encoding: [0x04,0xa6,0x9c,0x72] ++vsetanyeqz.h $fcc4, $vr16 ++ ++# CHECK: vsetanyeqz.w $fcc7, $vr2 ++# CHECK: encoding: [0x47,0xa8,0x9c,0x72] ++vsetanyeqz.w $fcc7, $vr2 ++ ++# CHECK: vsetanyeqz.d $fcc4, $vr12 ++# CHECK: encoding: [0x84,0xad,0x9c,0x72] ++vsetanyeqz.d $fcc4, $vr12 ++ ++# CHECK: vsetallnez.b $fcc7, $vr0 ++# CHECK: encoding: [0x07,0xb0,0x9c,0x72] ++vsetallnez.b $fcc7, $vr0 ++ ++# CHECK: vsetallnez.h $fcc2, $vr11 ++# CHECK: encoding: [0x62,0xb5,0x9c,0x72] ++vsetallnez.h $fcc2, $vr11 ++ ++# CHECK: vsetallnez.w $fcc6, $vr25 ++# CHECK: encoding: [0x26,0xbb,0x9c,0x72] ++vsetallnez.w $fcc6, $vr25 ++ ++# CHECK: vsetallnez.d $fcc7, $vr31 ++# CHECK: encoding: [0xe7,0xbf,0x9c,0x72] ++vsetallnez.d $fcc7, $vr31 ++ ++# CHECK: vflogb.s $vr14, $vr28 ++# CHECK: encoding: [0x8e,0xc7,0x9c,0x72] ++vflogb.s $vr14, $vr28 ++ ++# CHECK: vflogb.d $vr29, $vr9 ++# CHECK: encoding: [0x3d,0xc9,0x9c,0x72] ++vflogb.d $vr29, $vr9 ++ ++# CHECK: vfclass.s $vr3, $vr13 ++# CHECK: encoding: [0xa3,0xd5,0x9c,0x72] ++vfclass.s $vr3, $vr13 ++ ++# CHECK: vfclass.d $vr5, $vr15 ++# CHECK: encoding: [0xe5,0xd9,0x9c,0x72] ++vfclass.d $vr5, $vr15 ++ ++# CHECK: vfsqrt.s $vr19, $vr27 ++# CHECK: encoding: [0x73,0xe7,0x9c,0x72] ++vfsqrt.s $vr19, $vr27 ++ ++# CHECK: vfsqrt.d $vr31, $vr3 ++# CHECK: encoding: [0x7f,0xe8,0x9c,0x72] ++vfsqrt.d $vr31, $vr3 ++ ++# CHECK: vfrecip.s $vr24, $vr16 ++# CHECK: encoding: [0x18,0xf6,0x9c,0x72] ++vfrecip.s $vr24, $vr16 ++ ++# CHECK: vfrecip.d $vr23, $vr19 ++# CHECK: encoding: [0x77,0xfa,0x9c,0x72] ++vfrecip.d $vr23, $vr19 ++ ++# CHECK: vfrecipe.s $vr29, $vr14 ++# CHECK: encoding: [0xdd,0x15,0x9d,0x72] ++vfrecipe.s $vr29, $vr14 ++ ++# CHECK: vfrecipe.d $vr24, $vr9 ++# CHECK: encoding: [0x38,0x19,0x9d,0x72] ++vfrecipe.d $vr24, $vr9 ++ ++# CHECK: vfrsqrt.s $vr18, $vr15 ++# CHECK: encoding: [0xf2,0x05,0x9d,0x72] ++vfrsqrt.s $vr18, $vr15 ++ ++# CHECK: vfrsqrt.d $vr18, $vr31 ++# CHECK: encoding: [0xf2,0x0b,0x9d,0x72] ++vfrsqrt.d $vr18, $vr31 ++ ++# CHECK: vfrsqrte.s $vr19, $vr30 ++# CHECK: encoding: [0xd3,0x27,0x9d,0x72] ++vfrsqrte.s $vr19, $vr30 ++ ++# CHECK: vfrsqrte.d $vr1, $vr0 ++# CHECK: encoding: [0x01,0x28,0x9d,0x72] ++vfrsqrte.d $vr1, $vr0 ++ ++# CHECK: vfrint.s $vr26, $vr11 ++# CHECK: encoding: [0x7a,0x35,0x9d,0x72] ++vfrint.s $vr26, $vr11 ++ ++# CHECK: vfrint.d $vr24, $vr18 ++# CHECK: encoding: [0x58,0x3a,0x9d,0x72] ++vfrint.d $vr24, $vr18 ++ ++# CHECK: vfrintrm.s $vr5, $vr3 ++# CHECK: encoding: [0x65,0x44,0x9d,0x72] ++vfrintrm.s $vr5, $vr3 ++ ++# CHECK: vfrintrm.d $vr23, $vr10 ++# CHECK: encoding: [0x57,0x49,0x9d,0x72] ++vfrintrm.d $vr23, $vr10 ++ ++# CHECK: vfrintrp.s $vr20, $vr2 ++# CHECK: encoding: [0x54,0x54,0x9d,0x72] ++vfrintrp.s $vr20, $vr2 ++ ++# CHECK: vfrintrp.d $vr30, $vr17 ++# CHECK: encoding: [0x3e,0x5a,0x9d,0x72] ++vfrintrp.d $vr30, $vr17 ++ ++# CHECK: vfrintrz.s $vr19, $vr6 ++# CHECK: encoding: [0xd3,0x64,0x9d,0x72] ++vfrintrz.s $vr19, $vr6 ++ ++# CHECK: vfrintrz.d $vr16, $vr18 ++# CHECK: encoding: [0x50,0x6a,0x9d,0x72] ++vfrintrz.d $vr16, $vr18 ++ ++# CHECK: vfrintrne.s $vr8, $vr24 ++# CHECK: encoding: [0x08,0x77,0x9d,0x72] ++vfrintrne.s $vr8, $vr24 ++ ++# CHECK: vfrintrne.d $vr6, $vr5 ++# CHECK: encoding: [0xa6,0x78,0x9d,0x72] ++vfrintrne.d $vr6, $vr5 ++ ++# CHECK: vfcvtl.s.h $vr4, $vr6 ++# CHECK: encoding: [0xc4,0xe8,0x9d,0x72] ++vfcvtl.s.h $vr4, $vr6 ++ ++# CHECK: vfcvth.s.h $vr16, $vr7 ++# CHECK: encoding: [0xf0,0xec,0x9d,0x72] ++vfcvth.s.h $vr16, $vr7 ++ ++# CHECK: vfcvtl.d.s $vr16, $vr10 ++# CHECK: encoding: [0x50,0xf1,0x9d,0x72] ++vfcvtl.d.s $vr16, $vr10 ++ ++# CHECK: vfcvth.d.s $vr28, $vr25 ++# CHECK: encoding: [0x3c,0xf7,0x9d,0x72] ++vfcvth.d.s $vr28, $vr25 ++ ++# CHECK: vffint.s.w $vr28, $vr16 ++# CHECK: encoding: [0x1c,0x02,0x9e,0x72] ++vffint.s.w $vr28, $vr16 ++ ++# CHECK: vffint.s.wu $vr4, $vr31 ++# CHECK: encoding: [0xe4,0x07,0x9e,0x72] ++vffint.s.wu $vr4, $vr31 ++ ++# CHECK: vffint.d.l $vr18, $vr25 ++# CHECK: encoding: [0x32,0x0b,0x9e,0x72] ++vffint.d.l $vr18, $vr25 ++ ++# CHECK: vffint.d.lu $vr24, $vr17 ++# CHECK: encoding: [0x38,0x0e,0x9e,0x72] ++vffint.d.lu $vr24, $vr17 ++ ++# CHECK: vffintl.d.w $vr2, $vr27 ++# CHECK: encoding: [0x62,0x13,0x9e,0x72] ++vffintl.d.w $vr2, $vr27 ++ ++# CHECK: vffinth.d.w $vr4, $vr16 ++# CHECK: encoding: [0x04,0x16,0x9e,0x72] ++vffinth.d.w $vr4, $vr16 ++ ++# CHECK: vftint.w.s $vr17, $vr0 ++# CHECK: encoding: [0x11,0x30,0x9e,0x72] ++vftint.w.s $vr17, $vr0 ++ ++# CHECK: vftint.l.d $vr23, $vr18 ++# CHECK: encoding: [0x57,0x36,0x9e,0x72] ++vftint.l.d $vr23, $vr18 ++ ++# CHECK: vftintrm.w.s $vr23, $vr4 ++# CHECK: encoding: [0x97,0x38,0x9e,0x72] ++vftintrm.w.s $vr23, $vr4 ++ ++# CHECK: vftintrm.l.d $vr30, $vr14 ++# CHECK: encoding: [0xde,0x3d,0x9e,0x72] ++vftintrm.l.d $vr30, $vr14 ++ ++# CHECK: vftintrp.w.s $vr7, $vr0 ++# CHECK: encoding: [0x07,0x40,0x9e,0x72] ++vftintrp.w.s $vr7, $vr0 ++ ++# CHECK: vftintrp.l.d $vr28, $vr20 ++# CHECK: encoding: [0x9c,0x46,0x9e,0x72] ++vftintrp.l.d $vr28, $vr20 ++ ++# CHECK: vftintrz.w.s $vr28, $vr31 ++# CHECK: encoding: [0xfc,0x4b,0x9e,0x72] ++vftintrz.w.s $vr28, $vr31 ++ ++# CHECK: vftintrz.l.d $vr18, $vr0 ++# CHECK: encoding: [0x12,0x4c,0x9e,0x72] ++vftintrz.l.d $vr18, $vr0 ++ ++# CHECK: vftintrne.w.s $vr14, $vr17 ++# CHECK: encoding: [0x2e,0x52,0x9e,0x72] ++vftintrne.w.s $vr14, $vr17 ++ ++# CHECK: vftintrne.l.d $vr22, $vr18 ++# CHECK: encoding: [0x56,0x56,0x9e,0x72] ++vftintrne.l.d $vr22, $vr18 ++ ++# CHECK: vftint.wu.s $vr26, $vr25 ++# CHECK: encoding: [0x3a,0x5b,0x9e,0x72] ++vftint.wu.s $vr26, $vr25 ++ ++# CHECK: vftint.lu.d $vr9, $vr27 ++# CHECK: encoding: [0x69,0x5f,0x9e,0x72] ++vftint.lu.d $vr9, $vr27 ++ ++# CHECK: vftintrz.wu.s $vr26, $vr22 ++# CHECK: encoding: [0xda,0x72,0x9e,0x72] ++vftintrz.wu.s $vr26, $vr22 ++ ++# CHECK: vftintrz.lu.d $vr29, $vr20 ++# CHECK: encoding: [0x9d,0x76,0x9e,0x72] ++vftintrz.lu.d $vr29, $vr20 ++ ++# CHECK: vftintl.l.s $vr22, $vr1 ++# CHECK: encoding: [0x36,0x80,0x9e,0x72] ++vftintl.l.s $vr22, $vr1 ++ ++# CHECK: vftinth.l.s $vr13, $vr24 ++# CHECK: encoding: [0x0d,0x87,0x9e,0x72] ++vftinth.l.s $vr13, $vr24 ++ ++# CHECK: vftintrml.l.s $vr8, $vr27 ++# CHECK: encoding: [0x68,0x8b,0x9e,0x72] ++vftintrml.l.s $vr8, $vr27 ++ ++# CHECK: vftintrmh.l.s $vr18, $vr28 ++# CHECK: encoding: [0x92,0x8f,0x9e,0x72] ++vftintrmh.l.s $vr18, $vr28 ++ ++# CHECK: vftintrpl.l.s $vr27, $vr28 ++# CHECK: encoding: [0x9b,0x93,0x9e,0x72] ++vftintrpl.l.s $vr27, $vr28 ++ ++# CHECK: vftintrph.l.s $vr20, $vr7 ++# CHECK: encoding: [0xf4,0x94,0x9e,0x72] ++vftintrph.l.s $vr20, $vr7 ++ ++# CHECK: vftintrzl.l.s $vr6, $vr2 ++# CHECK: encoding: [0x46,0x98,0x9e,0x72] ++vftintrzl.l.s $vr6, $vr2 ++ ++# CHECK: vftintrzh.l.s $vr21, $vr6 ++# CHECK: encoding: [0xd5,0x9c,0x9e,0x72] ++vftintrzh.l.s $vr21, $vr6 ++ ++# CHECK: vftintrnel.l.s $vr25, $vr3 ++# CHECK: encoding: [0x79,0xa0,0x9e,0x72] ++vftintrnel.l.s $vr25, $vr3 ++ ++# CHECK: vftintrneh.l.s $vr7, $vr5 ++# CHECK: encoding: [0xa7,0xa4,0x9e,0x72] ++vftintrneh.l.s $vr7, $vr5 ++ ++# CHECK: vexth.h.b $vr9, $vr2 ++# CHECK: encoding: [0x49,0xe0,0x9e,0x72] ++vexth.h.b $vr9, $vr2 ++ ++# CHECK: vexth.w.h $vr4, $vr27 ++# CHECK: encoding: [0x64,0xe7,0x9e,0x72] ++vexth.w.h $vr4, $vr27 ++ ++# CHECK: vexth.d.w $vr23, $vr1 ++# CHECK: encoding: [0x37,0xe8,0x9e,0x72] ++vexth.d.w $vr23, $vr1 ++ ++# CHECK: vexth.q.d $vr15, $vr6 ++# CHECK: encoding: [0xcf,0xec,0x9e,0x72] ++vexth.q.d $vr15, $vr6 ++ ++# CHECK: vexth.hu.bu $vr3, $vr2 ++# CHECK: encoding: [0x43,0xf0,0x9e,0x72] ++vexth.hu.bu $vr3, $vr2 ++ ++# CHECK: vexth.wu.hu $vr31, $vr26 ++# CHECK: encoding: [0x5f,0xf7,0x9e,0x72] ++vexth.wu.hu $vr31, $vr26 ++ ++# CHECK: vexth.du.wu $vr10, $vr31 ++# CHECK: encoding: [0xea,0xfb,0x9e,0x72] ++vexth.du.wu $vr10, $vr31 ++ ++# CHECK: vexth.qu.du $vr28, $vr8 ++# CHECK: encoding: [0x1c,0xfd,0x9e,0x72] ++vexth.qu.du $vr28, $vr8 ++ ++# CHECK: vreplgr2vr.b $vr15, $sp ++# CHECK: encoding: [0x6f,0x00,0x9f,0x72] ++vreplgr2vr.b $vr15, $sp ++ ++# CHECK: vreplgr2vr.h $vr10, $r23 ++# CHECK: encoding: [0xea,0x06,0x9f,0x72] ++vreplgr2vr.h $vr10, $r23 ++ ++# CHECK: vreplgr2vr.w $vr25, $r16 ++# CHECK: encoding: [0x19,0x0a,0x9f,0x72] ++vreplgr2vr.w $vr25, $r16 ++ ++# CHECK: vreplgr2vr.d $vr27, $r7 ++# CHECK: encoding: [0xfb,0x0c,0x9f,0x72] ++vreplgr2vr.d $vr27, $r7 ++ ++# CHECK: vrotri.b $vr24, $vr24, 7 ++# CHECK: encoding: [0x18,0x3f,0xa0,0x72] ++vrotri.b $vr24, $vr24, 7 ++ ++# CHECK: vrotri.h $vr1, $vr5, 0 ++# CHECK: encoding: [0xa1,0x40,0xa0,0x72] ++vrotri.h $vr1, $vr5, 0 ++ ++# CHECK: vrotri.w $vr10, $vr8, 12 ++# CHECK: encoding: [0x0a,0xb1,0xa0,0x72] ++vrotri.w $vr10, $vr8, 12 ++ ++# CHECK: vrotri.d $vr30, $vr29, 42 ++# CHECK: encoding: [0xbe,0xab,0xa1,0x72] ++vrotri.d $vr30, $vr29, 42 ++ ++# CHECK: vsrlri.b $vr1, $vr16, 3 ++# CHECK: encoding: [0x01,0x2e,0xa4,0x72] ++vsrlri.b $vr1, $vr16, 3 ++ ++# CHECK: vsrlri.h $vr28, $vr21, 1 ++# CHECK: encoding: [0xbc,0x46,0xa4,0x72] ++vsrlri.h $vr28, $vr21, 1 ++ ++# CHECK: vsrlri.w $vr18, $vr4, 15 ++# CHECK: encoding: [0x92,0xbc,0xa4,0x72] ++vsrlri.w $vr18, $vr4, 15 ++ ++# CHECK: vsrlri.d $vr30, $vr3, 19 ++# CHECK: encoding: [0x7e,0x4c,0xa5,0x72] ++vsrlri.d $vr30, $vr3, 19 ++ ++# CHECK: vsrari.b $vr13, $vr0, 7 ++# CHECK: encoding: [0x0d,0x3c,0xa8,0x72] ++vsrari.b $vr13, $vr0, 7 ++ ++# CHECK: vsrari.h $vr17, $vr9, 6 ++# CHECK: encoding: [0x31,0x59,0xa8,0x72] ++vsrari.h $vr17, $vr9, 6 ++ ++# CHECK: vsrari.w $vr3, $vr28, 6 ++# CHECK: encoding: [0x83,0x9b,0xa8,0x72] ++vsrari.w $vr3, $vr28, 6 ++ ++# CHECK: vsrari.d $vr4, $vr2, 34 ++# CHECK: encoding: [0x44,0x88,0xa9,0x72] ++vsrari.d $vr4, $vr2, 34 ++ ++# CHECK: vinsgr2vr.b $vr8, $r8, 4 ++# CHECK: encoding: [0x08,0x91,0xeb,0x72] ++vinsgr2vr.b $vr8, $r8, 4 ++ ++# CHECK: vinsgr2vr.h $vr13, $r7, 1 ++# CHECK: encoding: [0xed,0xc4,0xeb,0x72] ++vinsgr2vr.h $vr13, $r7, 1 ++ ++# CHECK: vinsgr2vr.w $vr4, $r6, 3 ++# CHECK: encoding: [0xc4,0xec,0xeb,0x72] ++vinsgr2vr.w $vr4, $r6, 3 ++ ++# CHECK: vinsgr2vr.d $vr23, $r31, 0 ++# CHECK: encoding: [0xf7,0xf3,0xeb,0x72] ++vinsgr2vr.d $vr23, $r31, 0 ++ ++# CHECK: vpickve2gr.b $r24, $vr16, 10 ++# CHECK: encoding: [0x18,0xaa,0xef,0x72] ++vpickve2gr.b $r24, $vr16, 10 ++ ++# CHECK: vpickve2gr.h $r17, $vr25, 3 ++# CHECK: encoding: [0x31,0xcf,0xef,0x72] ++vpickve2gr.h $r17, $vr25, 3 ++ ++# CHECK: vpickve2gr.w $r30, $vr28, 2 ++# CHECK: encoding: [0x9e,0xeb,0xef,0x72] ++vpickve2gr.w $r30, $vr28, 2 ++ ++# CHECK: vpickve2gr.d $r25, $vr9, 1 ++# CHECK: encoding: [0x39,0xf5,0xef,0x72] ++vpickve2gr.d $r25, $vr9, 1 ++ ++# CHECK: vpickve2gr.bu $r31, $vr14, 2 ++# CHECK: encoding: [0xdf,0x89,0xf3,0x72] ++vpickve2gr.bu $r31, $vr14, 2 ++ ++# CHECK: vpickve2gr.hu $r12, $vr1, 6 ++# CHECK: encoding: [0x2c,0xd8,0xf3,0x72] ++vpickve2gr.hu $r12, $vr1, 6 ++ ++# CHECK: vpickve2gr.wu $r10, $vr17, 1 ++# CHECK: encoding: [0x2a,0xe6,0xf3,0x72] ++vpickve2gr.wu $r10, $vr17, 1 ++ ++# CHECK: vpickve2gr.du $r26, $vr8, 1 ++# CHECK: encoding: [0x1a,0xf5,0xf3,0x72] ++vpickve2gr.du $r26, $vr8, 1 ++ ++# CHECK: vreplvei.b $vr3, $vr6, 12 ++# CHECK: encoding: [0xc3,0xb0,0xf7,0x72] ++vreplvei.b $vr3, $vr6, 12 ++ ++# CHECK: vreplvei.h $vr22, $vr29, 7 ++# CHECK: encoding: [0xb6,0xdf,0xf7,0x72] ++vreplvei.h $vr22, $vr29, 7 ++ ++# CHECK: vreplvei.w $vr17, $vr26, 1 ++# CHECK: encoding: [0x51,0xe7,0xf7,0x72] ++vreplvei.w $vr17, $vr26, 1 ++ ++# CHECK: vreplvei.d $vr0, $vr17, 1 ++# CHECK: encoding: [0x20,0xf6,0xf7,0x72] ++vreplvei.d $vr0, $vr17, 1 ++ ++# CHECK: vsllwil.h.b $vr25, $vr14, 2 ++# CHECK: encoding: [0xd9,0x29,0x08,0x73] ++vsllwil.h.b $vr25, $vr14, 2 ++ ++# CHECK: vsllwil.w.h $vr24, $vr5, 1 ++# CHECK: encoding: [0xb8,0x44,0x08,0x73] ++vsllwil.w.h $vr24, $vr5, 1 ++ ++# CHECK: vsllwil.d.w $vr25, $vr14, 8 ++# CHECK: encoding: [0xd9,0xa1,0x08,0x73] ++vsllwil.d.w $vr25, $vr14, 8 ++ ++# CHECK: vextl.q.d $vr3, $vr22 ++# CHECK: encoding: [0xc3,0x02,0x09,0x73] ++vextl.q.d $vr3, $vr22 ++ ++# CHECK: vsllwil.hu.bu $vr11, $vr25, 3 ++# CHECK: encoding: [0x2b,0x2f,0x0c,0x73] ++vsllwil.hu.bu $vr11, $vr25, 3 ++ ++# CHECK: vsllwil.wu.hu $vr2, $vr26, 10 ++# CHECK: encoding: [0x42,0x6b,0x0c,0x73] ++vsllwil.wu.hu $vr2, $vr26, 10 ++ ++# CHECK: vsllwil.du.wu $vr18, $vr9, 28 ++# CHECK: encoding: [0x32,0xf1,0x0c,0x73] ++vsllwil.du.wu $vr18, $vr9, 28 ++ ++# CHECK: vextl.qu.du $vr13, $vr25 ++# CHECK: encoding: [0x2d,0x03,0x0d,0x73] ++vextl.qu.du $vr13, $vr25 ++ ++# CHECK: vbitclri.b $vr29, $vr24, 6 ++# CHECK: encoding: [0x1d,0x3b,0x10,0x73] ++vbitclri.b $vr29, $vr24, 6 ++ ++# CHECK: vbitclri.h $vr27, $vr15, 5 ++# CHECK: encoding: [0xfb,0x55,0x10,0x73] ++vbitclri.h $vr27, $vr15, 5 ++ ++# CHECK: vbitclri.w $vr11, $vr10, 8 ++# CHECK: encoding: [0x4b,0xa1,0x10,0x73] ++vbitclri.w $vr11, $vr10, 8 ++ ++# CHECK: vbitclri.d $vr4, $vr7, 15 ++# CHECK: encoding: [0xe4,0x3c,0x11,0x73] ++vbitclri.d $vr4, $vr7, 15 ++ ++# CHECK: vbitseti.b $vr24, $vr20, 3 ++# CHECK: encoding: [0x98,0x2e,0x14,0x73] ++vbitseti.b $vr24, $vr20, 3 ++ ++# CHECK: vbitseti.h $vr6, $vr8, 8 ++# CHECK: encoding: [0x06,0x61,0x14,0x73] ++vbitseti.h $vr6, $vr8, 8 ++ ++# CHECK: vbitseti.w $vr21, $vr9, 24 ++# CHECK: encoding: [0x35,0xe1,0x14,0x73] ++vbitseti.w $vr21, $vr9, 24 ++ ++# CHECK: vbitseti.d $vr28, $vr18, 30 ++# CHECK: encoding: [0x5c,0x7a,0x15,0x73] ++vbitseti.d $vr28, $vr18, 30 ++ ++# CHECK: vbitrevi.b $vr19, $vr31, 0 ++# CHECK: encoding: [0xf3,0x23,0x18,0x73] ++vbitrevi.b $vr19, $vr31, 0 ++ ++# CHECK: vbitrevi.h $vr18, $vr1, 0 ++# CHECK: encoding: [0x32,0x40,0x18,0x73] ++vbitrevi.h $vr18, $vr1, 0 ++ ++# CHECK: vbitrevi.w $vr25, $vr6, 18 ++# CHECK: encoding: [0xd9,0xc8,0x18,0x73] ++vbitrevi.w $vr25, $vr6, 18 ++ ++# CHECK: vbitrevi.d $vr8, $vr27, 22 ++# CHECK: encoding: [0x68,0x5b,0x19,0x73] ++vbitrevi.d $vr8, $vr27, 22 ++ ++# CHECK: vsat.b $vr21, $vr28, 2 ++# CHECK: encoding: [0x95,0x2b,0x24,0x73] ++vsat.b $vr21, $vr28, 2 ++ ++# CHECK: vsat.h $vr6, $vr5, 12 ++# CHECK: encoding: [0xa6,0x70,0x24,0x73] ++vsat.h $vr6, $vr5, 12 ++ ++# CHECK: vsat.w $vr3, $vr30, 16 ++# CHECK: encoding: [0xc3,0xc3,0x24,0x73] ++vsat.w $vr3, $vr30, 16 ++ ++# CHECK: vsat.d $vr0, $vr31, 24 ++# CHECK: encoding: [0xe0,0x63,0x25,0x73] ++vsat.d $vr0, $vr31, 24 ++ ++# CHECK: vsat.bu $vr20, $vr20, 2 ++# CHECK: encoding: [0x94,0x2a,0x28,0x73] ++vsat.bu $vr20, $vr20, 2 ++ ++# CHECK: vsat.hu $vr8, $vr6, 12 ++# CHECK: encoding: [0xc8,0x70,0x28,0x73] ++vsat.hu $vr8, $vr6, 12 ++ ++# CHECK: vsat.wu $vr18, $vr20, 26 ++# CHECK: encoding: [0x92,0xea,0x28,0x73] ++vsat.wu $vr18, $vr20, 26 ++ ++# CHECK: vsat.du $vr10, $vr6, 33 ++# CHECK: encoding: [0xca,0x84,0x29,0x73] ++vsat.du $vr10, $vr6, 33 ++ ++# CHECK: vslli.b $vr4, $vr19, 3 ++# CHECK: encoding: [0x64,0x2e,0x2c,0x73] ++vslli.b $vr4, $vr19, 3 ++ ++# CHECK: vslli.h $vr3, $vr23, 14 ++# CHECK: encoding: [0xe3,0x7a,0x2c,0x73] ++vslli.h $vr3, $vr23, 14 ++ ++# CHECK: vslli.w $vr22, $vr21, 6 ++# CHECK: encoding: [0xb6,0x9a,0x2c,0x73] ++vslli.w $vr22, $vr21, 6 ++ ++# CHECK: vslli.d $vr23, $vr15, 36 ++# CHECK: encoding: [0xf7,0x91,0x2d,0x73] ++vslli.d $vr23, $vr15, 36 ++ ++# CHECK: vsrli.b $vr5, $vr25, 4 ++# CHECK: encoding: [0x25,0x33,0x30,0x73] ++vsrli.b $vr5, $vr25, 4 ++ ++# CHECK: vsrli.h $vr9, $vr14, 9 ++# CHECK: encoding: [0xc9,0x65,0x30,0x73] ++vsrli.h $vr9, $vr14, 9 ++ ++# CHECK: vsrli.w $vr7, $vr24, 12 ++# CHECK: encoding: [0x07,0xb3,0x30,0x73] ++vsrli.w $vr7, $vr24, 12 ++ ++# CHECK: vsrli.d $vr15, $vr18, 63 ++# CHECK: encoding: [0x4f,0xfe,0x31,0x73] ++vsrli.d $vr15, $vr18, 63 ++ ++# CHECK: vsrai.b $vr6, $vr1, 3 ++# CHECK: encoding: [0x26,0x2c,0x34,0x73] ++vsrai.b $vr6, $vr1, 3 ++ ++# CHECK: vsrai.h $vr7, $vr29, 3 ++# CHECK: encoding: [0xa7,0x4f,0x34,0x73] ++vsrai.h $vr7, $vr29, 3 ++ ++# CHECK: vsrai.w $vr31, $vr27, 29 ++# CHECK: encoding: [0x7f,0xf7,0x34,0x73] ++vsrai.w $vr31, $vr27, 29 ++ ++# CHECK: vsrai.d $vr28, $vr30, 56 ++# CHECK: encoding: [0xdc,0xe3,0x35,0x73] ++vsrai.d $vr28, $vr30, 56 ++ ++# CHECK: vsrlni.b.h $vr2, $vr26, 2 ++# CHECK: encoding: [0x42,0x4b,0x40,0x73] ++vsrlni.b.h $vr2, $vr26, 2 ++ ++# CHECK: vsrlni.h.w $vr31, $vr14, 3 ++# CHECK: encoding: [0xdf,0x8d,0x40,0x73] ++vsrlni.h.w $vr31, $vr14, 3 ++ ++# CHECK: vsrlni.w.d $vr19, $vr4, 33 ++# CHECK: encoding: [0x93,0x84,0x41,0x73] ++vsrlni.w.d $vr19, $vr4, 33 ++ ++# CHECK: vsrlni.d.q $vr31, $vr3, 63 ++# CHECK: encoding: [0x7f,0xfc,0x42,0x73] ++vsrlni.d.q $vr31, $vr3, 63 ++ ++# CHECK: vsrlrni.b.h $vr26, $vr18, 0 ++# CHECK: encoding: [0x5a,0x42,0x44,0x73] ++vsrlrni.b.h $vr26, $vr18, 0 ++ ++# CHECK: vsrlrni.h.w $vr18, $vr22, 5 ++# CHECK: encoding: [0xd2,0x96,0x44,0x73] ++vsrlrni.h.w $vr18, $vr22, 5 ++ ++# CHECK: vsrlrni.w.d $vr24, $vr11, 21 ++# CHECK: encoding: [0x78,0x55,0x45,0x73] ++vsrlrni.w.d $vr24, $vr11, 21 ++ ++# CHECK: vsrlrni.d.q $vr6, $vr11, 37 ++# CHECK: encoding: [0x66,0x95,0x46,0x73] ++vsrlrni.d.q $vr6, $vr11, 37 ++ ++# CHECK: vssrlni.b.h $vr3, $vr21, 5 ++# CHECK: encoding: [0xa3,0x56,0x48,0x73] ++vssrlni.b.h $vr3, $vr21, 5 ++ ++# CHECK: vssrlni.h.w $vr6, $vr1, 16 ++# CHECK: encoding: [0x26,0xc0,0x48,0x73] ++vssrlni.h.w $vr6, $vr1, 16 ++ ++# CHECK: vssrlni.w.d $vr4, $vr21, 27 ++# CHECK: encoding: [0xa4,0x6e,0x49,0x73] ++vssrlni.w.d $vr4, $vr21, 27 ++ ++# CHECK: vssrlni.d.q $vr8, $vr18, 94 ++# CHECK: encoding: [0x48,0x7a,0x4b,0x73] ++vssrlni.d.q $vr8, $vr18, 94 ++ ++# CHECK: vssrlni.bu.h $vr6, $vr2, 5 ++# CHECK: encoding: [0x46,0x54,0x4c,0x73] ++vssrlni.bu.h $vr6, $vr2, 5 ++ ++# CHECK: vssrlni.hu.w $vr29, $vr29, 2 ++# CHECK: encoding: [0xbd,0x8b,0x4c,0x73] ++vssrlni.hu.w $vr29, $vr29, 2 ++ ++# CHECK: vssrlni.wu.d $vr28, $vr20, 47 ++# CHECK: encoding: [0x9c,0xbe,0x4d,0x73] ++vssrlni.wu.d $vr28, $vr20, 47 ++ ++# CHECK: vssrlni.du.q $vr22, $vr10, 82 ++# CHECK: encoding: [0x56,0x49,0x4f,0x73] ++vssrlni.du.q $vr22, $vr10, 82 ++ ++# CHECK: vssrlrni.b.h $vr17, $vr25, 10 ++# CHECK: encoding: [0x31,0x6b,0x50,0x73] ++vssrlrni.b.h $vr17, $vr25, 10 ++ ++# CHECK: vssrlrni.h.w $vr21, $vr29, 0 ++# CHECK: encoding: [0xb5,0x83,0x50,0x73] ++vssrlrni.h.w $vr21, $vr29, 0 ++ ++# CHECK: vssrlrni.w.d $vr9, $vr15, 63 ++# CHECK: encoding: [0xe9,0xfd,0x51,0x73] ++vssrlrni.w.d $vr9, $vr15, 63 ++ ++# CHECK: vssrlrni.d.q $vr4, $vr1, 117 ++# CHECK: encoding: [0x24,0xd4,0x53,0x73] ++vssrlrni.d.q $vr4, $vr1, 117 ++ ++# CHECK: vssrlrni.bu.h $vr25, $vr13, 3 ++# CHECK: encoding: [0xb9,0x4d,0x54,0x73] ++vssrlrni.bu.h $vr25, $vr13, 3 ++ ++# CHECK: vssrlrni.hu.w $vr30, $vr28, 7 ++# CHECK: encoding: [0x9e,0x9f,0x54,0x73] ++vssrlrni.hu.w $vr30, $vr28, 7 ++ ++# CHECK: vssrlrni.wu.d $vr16, $vr27, 11 ++# CHECK: encoding: [0x70,0x2f,0x55,0x73] ++vssrlrni.wu.d $vr16, $vr27, 11 ++ ++# CHECK: vssrlrni.du.q $vr20, $vr13, 63 ++# CHECK: encoding: [0xb4,0xfd,0x56,0x73] ++vssrlrni.du.q $vr20, $vr13, 63 ++ ++# CHECK: vsrani.b.h $vr3, $vr25, 4 ++# CHECK: encoding: [0x23,0x53,0x58,0x73] ++vsrani.b.h $vr3, $vr25, 4 ++ ++# CHECK: vsrani.h.w $vr12, $vr13, 17 ++# CHECK: encoding: [0xac,0xc5,0x58,0x73] ++vsrani.h.w $vr12, $vr13, 17 ++ ++# CHECK: vsrani.w.d $vr2, $vr6, 25 ++# CHECK: encoding: [0xc2,0x64,0x59,0x73] ++vsrani.w.d $vr2, $vr6, 25 ++ ++# CHECK: vsrani.d.q $vr12, $vr8, 105 ++# CHECK: encoding: [0x0c,0xa5,0x5b,0x73] ++vsrani.d.q $vr12, $vr8, 105 ++ ++# CHECK: vsrarni.b.h $vr27, $vr21, 2 ++# CHECK: encoding: [0xbb,0x4a,0x5c,0x73] ++vsrarni.b.h $vr27, $vr21, 2 ++ ++# CHECK: vsrarni.h.w $vr13, $vr3, 0 ++# CHECK: encoding: [0x6d,0x80,0x5c,0x73] ++vsrarni.h.w $vr13, $vr3, 0 ++ ++# CHECK: vsrarni.w.d $vr9, $vr31, 42 ++# CHECK: encoding: [0xe9,0xab,0x5d,0x73] ++vsrarni.w.d $vr9, $vr31, 42 ++ ++# CHECK: vsrarni.d.q $vr25, $vr5, 59 ++# CHECK: encoding: [0xb9,0xec,0x5e,0x73] ++vsrarni.d.q $vr25, $vr5, 59 ++ ++# CHECK: vssrani.b.h $vr8, $vr7, 12 ++# CHECK: encoding: [0xe8,0x70,0x60,0x73] ++vssrani.b.h $vr8, $vr7, 12 ++ ++# CHECK: vssrani.h.w $vr21, $vr18, 30 ++# CHECK: encoding: [0x55,0xfa,0x60,0x73] ++vssrani.h.w $vr21, $vr18, 30 ++ ++# CHECK: vssrani.w.d $vr23, $vr7, 51 ++# CHECK: encoding: [0xf7,0xcc,0x61,0x73] ++vssrani.w.d $vr23, $vr7, 51 ++ ++# CHECK: vssrani.d.q $vr12, $vr14, 8 ++# CHECK: encoding: [0xcc,0x21,0x62,0x73] ++vssrani.d.q $vr12, $vr14, 8 ++ ++# CHECK: vssrani.bu.h $vr19, $vr5, 12 ++# CHECK: encoding: [0xb3,0x70,0x64,0x73] ++vssrani.bu.h $vr19, $vr5, 12 ++ ++# CHECK: vssrani.hu.w $vr27, $vr25, 15 ++# CHECK: encoding: [0x3b,0xbf,0x64,0x73] ++vssrani.hu.w $vr27, $vr25, 15 ++ ++# CHECK: vssrani.wu.d $vr24, $vr28, 42 ++# CHECK: encoding: [0x98,0xab,0x65,0x73] ++vssrani.wu.d $vr24, $vr28, 42 ++ ++# CHECK: vssrani.du.q $vr4, $vr23, 63 ++# CHECK: encoding: [0xe4,0xfe,0x66,0x73] ++vssrani.du.q $vr4, $vr23, 63 ++ ++# CHECK: vssrarni.b.h $vr26, $vr8, 0 ++# CHECK: encoding: [0x1a,0x41,0x68,0x73] ++vssrarni.b.h $vr26, $vr8, 0 ++ ++# CHECK: vssrarni.h.w $vr4, $vr3, 25 ++# CHECK: encoding: [0x64,0xe4,0x68,0x73] ++vssrarni.h.w $vr4, $vr3, 25 ++ ++# CHECK: vssrarni.w.d $vr0, $vr25, 19 ++# CHECK: encoding: [0x20,0x4f,0x69,0x73] ++vssrarni.w.d $vr0, $vr25, 19 ++ ++# CHECK: vssrarni.d.q $vr20, $vr11, 106 ++# CHECK: encoding: [0x74,0xa9,0x6b,0x73] ++vssrarni.d.q $vr20, $vr11, 106 ++ ++# CHECK: vssrarni.bu.h $vr25, $vr28, 9 ++# CHECK: encoding: [0x99,0x67,0x6c,0x73] ++vssrarni.bu.h $vr25, $vr28, 9 ++ ++# CHECK: vssrarni.hu.w $vr20, $vr23, 12 ++# CHECK: encoding: [0xf4,0xb2,0x6c,0x73] ++vssrarni.hu.w $vr20, $vr23, 12 ++ ++# CHECK: vssrarni.wu.d $vr28, $vr23, 58 ++# CHECK: encoding: [0xfc,0xea,0x6d,0x73] ++vssrarni.wu.d $vr28, $vr23, 58 ++ ++# CHECK: vssrarni.du.q $vr1, $vr14, 93 ++# CHECK: encoding: [0xc1,0x75,0x6f,0x73] ++vssrarni.du.q $vr1, $vr14, 93 ++ ++# CHECK: vextrins.d $vr15, $vr27, 7 ++# CHECK: encoding: [0x6f,0x1f,0x80,0x73] ++vextrins.d $vr15, $vr27, 7 ++ ++# CHECK: vextrins.w $vr19, $vr0, 147 ++# CHECK: encoding: [0x13,0x4c,0x86,0x73] ++vextrins.w $vr19, $vr0, 147 ++ ++# CHECK: vextrins.h $vr29, $vr9, 69 ++# CHECK: encoding: [0x3d,0x15,0x89,0x73] ++vextrins.h $vr29, $vr9, 69 ++ ++# CHECK: vextrins.b $vr0, $vr21, 23 ++# CHECK: encoding: [0xa0,0x5e,0x8c,0x73] ++vextrins.b $vr0, $vr21, 23 ++ ++# CHECK: vshuf4i.b $vr19, $vr10, 188 ++# CHECK: encoding: [0x53,0xf1,0x92,0x73] ++vshuf4i.b $vr19, $vr10, 188 ++ ++# CHECK: vshuf4i.h $vr15, $vr1, 139 ++# CHECK: encoding: [0x2f,0x2c,0x96,0x73] ++vshuf4i.h $vr15, $vr1, 139 ++ ++# CHECK: vshuf4i.w $vr3, $vr5, 130 ++# CHECK: encoding: [0xa3,0x08,0x9a,0x73] ++vshuf4i.w $vr3, $vr5, 130 ++ ++# CHECK: vshuf4i.d $vr8, $vr29, 131 ++# CHECK: encoding: [0xa8,0x0f,0x9e,0x73] ++vshuf4i.d $vr8, $vr29, 131 ++ ++# CHECK: vbitseli.b $vr16, $vr25, 168 ++# CHECK: encoding: [0x30,0xa3,0xc6,0x73] ++vbitseli.b $vr16, $vr25, 168 ++ ++# CHECK: vandi.b $vr4, $vr23, 121 ++# CHECK: encoding: [0xe4,0xe6,0xd1,0x73] ++vandi.b $vr4, $vr23, 121 ++ ++# CHECK: vori.b $vr7, $vr10, 188 ++# CHECK: encoding: [0x47,0xf1,0xd6,0x73] ++vori.b $vr7, $vr10, 188 ++ ++# CHECK: vxori.b $vr9, $vr26, 216 ++# CHECK: encoding: [0x49,0x63,0xdb,0x73] ++vxori.b $vr9, $vr26, 216 ++ ++# CHECK: vnori.b $vr4, $vr28, 219 ++# CHECK: encoding: [0x84,0x6f,0xdf,0x73] ++vnori.b $vr4, $vr28, 219 ++ ++# CHECK: vldi $vr22, -3742 ++# CHECK: encoding: [0x56,0x2c,0xe2,0x73] ++vldi $vr22, -3742 ++ ++# CHECK: vpermi.w $vr14, $vr29, 16 ++# CHECK: encoding: [0xae,0x43,0xe4,0x73] ++vpermi.w $vr14, $vr29, 16 ++ ++# CHECK: xvseq.b $xr11, $xr23, $xr21 ++# CHECK: encoding: [0xeb,0x56,0x00,0x74] ++xvseq.b $xr11, $xr23, $xr21 ++ ++# CHECK: xvseq.h $xr6, $xr10, $xr27 ++# CHECK: encoding: [0x46,0xed,0x00,0x74] ++xvseq.h $xr6, $xr10, $xr27 ++ ++# CHECK: xvseq.w $xr19, $xr27, $xr21 ++# CHECK: encoding: [0x73,0x57,0x01,0x74] ++xvseq.w $xr19, $xr27, $xr21 ++ ++# CHECK: xvseq.d $xr18, $xr4, $xr2 ++# CHECK: encoding: [0x92,0x88,0x01,0x74] ++xvseq.d $xr18, $xr4, $xr2 ++ ++# CHECK: xvsle.b $xr19, $xr10, $xr5 ++# CHECK: encoding: [0x53,0x15,0x02,0x74] ++xvsle.b $xr19, $xr10, $xr5 ++ ++# CHECK: xvsle.h $xr10, $xr25, $xr14 ++# CHECK: encoding: [0x2a,0xbb,0x02,0x74] ++xvsle.h $xr10, $xr25, $xr14 ++ ++# CHECK: xvsle.w $xr17, $xr23, $xr18 ++# CHECK: encoding: [0xf1,0x4a,0x03,0x74] ++xvsle.w $xr17, $xr23, $xr18 ++ ++# CHECK: xvsle.d $xr15, $xr7, $xr9 ++# CHECK: encoding: [0xef,0xa4,0x03,0x74] ++xvsle.d $xr15, $xr7, $xr9 ++ ++# CHECK: xvsle.bu $xr5, $xr14, $xr15 ++# CHECK: encoding: [0xc5,0x3d,0x04,0x74] ++xvsle.bu $xr5, $xr14, $xr15 ++ ++# CHECK: xvsle.hu $xr9, $xr25, $xr25 ++# CHECK: encoding: [0x29,0xe7,0x04,0x74] ++xvsle.hu $xr9, $xr25, $xr25 ++ ++# CHECK: xvsle.wu $xr28, $xr31, $xr16 ++# CHECK: encoding: [0xfc,0x43,0x05,0x74] ++xvsle.wu $xr28, $xr31, $xr16 ++ ++# CHECK: xvsle.du $xr17, $xr24, $xr24 ++# CHECK: encoding: [0x11,0xe3,0x05,0x74] ++xvsle.du $xr17, $xr24, $xr24 ++ ++# CHECK: xvslt.b $xr18, $xr28, $xr25 ++# CHECK: encoding: [0x92,0x67,0x06,0x74] ++xvslt.b $xr18, $xr28, $xr25 ++ ++# CHECK: xvslt.h $xr29, $xr6, $xr2 ++# CHECK: encoding: [0xdd,0x88,0x06,0x74] ++xvslt.h $xr29, $xr6, $xr2 ++ ++# CHECK: xvslt.w $xr14, $xr10, $xr5 ++# CHECK: encoding: [0x4e,0x15,0x07,0x74] ++xvslt.w $xr14, $xr10, $xr5 ++ ++# CHECK: xvslt.d $xr19, $xr30, $xr15 ++# CHECK: encoding: [0xd3,0xbf,0x07,0x74] ++xvslt.d $xr19, $xr30, $xr15 ++ ++# CHECK: xvslt.bu $xr14, $xr6, $xr27 ++# CHECK: encoding: [0xce,0x6c,0x08,0x74] ++xvslt.bu $xr14, $xr6, $xr27 ++ ++# CHECK: xvslt.hu $xr27, $xr26, $xr5 ++# CHECK: encoding: [0x5b,0x97,0x08,0x74] ++xvslt.hu $xr27, $xr26, $xr5 ++ ++# CHECK: xvslt.wu $xr6, $xr9, $xr10 ++# CHECK: encoding: [0x26,0x29,0x09,0x74] ++xvslt.wu $xr6, $xr9, $xr10 ++ ++# CHECK: xvslt.du $xr13, $xr12, $xr28 ++# CHECK: encoding: [0x8d,0xf1,0x09,0x74] ++xvslt.du $xr13, $xr12, $xr28 ++ ++# CHECK: xvadd.b $xr0, $xr6, $xr3 ++# CHECK: encoding: [0xc0,0x0c,0x0a,0x74] ++xvadd.b $xr0, $xr6, $xr3 ++ ++# CHECK: xvadd.h $xr8, $xr11, $xr10 ++# CHECK: encoding: [0x68,0xa9,0x0a,0x74] ++xvadd.h $xr8, $xr11, $xr10 ++ ++# CHECK: xvadd.w $xr5, $xr6, $xr21 ++# CHECK: encoding: [0xc5,0x54,0x0b,0x74] ++xvadd.w $xr5, $xr6, $xr21 ++ ++# CHECK: xvadd.d $xr4, $xr21, $xr10 ++# CHECK: encoding: [0xa4,0xaa,0x0b,0x74] ++xvadd.d $xr4, $xr21, $xr10 ++ ++# CHECK: xvsub.b $xr16, $xr0, $xr30 ++# CHECK: encoding: [0x10,0x78,0x0c,0x74] ++xvsub.b $xr16, $xr0, $xr30 ++ ++# CHECK: xvsub.h $xr28, $xr11, $xr18 ++# CHECK: encoding: [0x7c,0xc9,0x0c,0x74] ++xvsub.h $xr28, $xr11, $xr18 ++ ++# CHECK: xvsub.w $xr13, $xr2, $xr13 ++# CHECK: encoding: [0x4d,0x34,0x0d,0x74] ++xvsub.w $xr13, $xr2, $xr13 ++ ++# CHECK: xvsub.d $xr0, $xr25, $xr21 ++# CHECK: encoding: [0x20,0xd7,0x0d,0x74] ++xvsub.d $xr0, $xr25, $xr21 ++ ++# CHECK: xvaddwev.h.b $xr8, $xr30, $xr11 ++# CHECK: encoding: [0xc8,0x2f,0x1e,0x74] ++xvaddwev.h.b $xr8, $xr30, $xr11 ++ ++# CHECK: xvaddwev.w.h $xr10, $xr30, $xr5 ++# CHECK: encoding: [0xca,0x97,0x1e,0x74] ++xvaddwev.w.h $xr10, $xr30, $xr5 ++ ++# CHECK: xvaddwev.d.w $xr20, $xr25, $xr1 ++# CHECK: encoding: [0x34,0x07,0x1f,0x74] ++xvaddwev.d.w $xr20, $xr25, $xr1 ++ ++# CHECK: xvaddwev.q.d $xr22, $xr24, $xr24 ++# CHECK: encoding: [0x16,0xe3,0x1f,0x74] ++xvaddwev.q.d $xr22, $xr24, $xr24 ++ ++# CHECK: xvsubwev.h.b $xr1, $xr25, $xr1 ++# CHECK: encoding: [0x21,0x07,0x20,0x74] ++xvsubwev.h.b $xr1, $xr25, $xr1 ++ ++# CHECK: xvsubwev.w.h $xr4, $xr30, $xr11 ++# CHECK: encoding: [0xc4,0xaf,0x20,0x74] ++xvsubwev.w.h $xr4, $xr30, $xr11 ++ ++# CHECK: xvsubwev.d.w $xr6, $xr2, $xr18 ++# CHECK: encoding: [0x46,0x48,0x21,0x74] ++xvsubwev.d.w $xr6, $xr2, $xr18 ++ ++# CHECK: xvsubwev.q.d $xr0, $xr11, $xr31 ++# CHECK: encoding: [0x60,0xfd,0x21,0x74] ++xvsubwev.q.d $xr0, $xr11, $xr31 ++ ++# CHECK: xvaddwod.h.b $xr4, $xr4, $xr25 ++# CHECK: encoding: [0x84,0x64,0x22,0x74] ++xvaddwod.h.b $xr4, $xr4, $xr25 ++ ++# CHECK: xvaddwod.w.h $xr12, $xr25, $xr29 ++# CHECK: encoding: [0x2c,0xf7,0x22,0x74] ++xvaddwod.w.h $xr12, $xr25, $xr29 ++ ++# CHECK: xvaddwod.d.w $xr16, $xr22, $xr19 ++# CHECK: encoding: [0xd0,0x4e,0x23,0x74] ++xvaddwod.d.w $xr16, $xr22, $xr19 ++ ++# CHECK: xvaddwod.q.d $xr23, $xr25, $xr14 ++# CHECK: encoding: [0x37,0xbb,0x23,0x74] ++xvaddwod.q.d $xr23, $xr25, $xr14 ++ ++# CHECK: xvsubwod.h.b $xr1, $xr16, $xr8 ++# CHECK: encoding: [0x01,0x22,0x24,0x74] ++xvsubwod.h.b $xr1, $xr16, $xr8 ++ ++# CHECK: xvsubwod.w.h $xr5, $xr11, $xr8 ++# CHECK: encoding: [0x65,0xa1,0x24,0x74] ++xvsubwod.w.h $xr5, $xr11, $xr8 ++ ++# CHECK: xvsubwod.d.w $xr20, $xr7, $xr0 ++# CHECK: encoding: [0xf4,0x00,0x25,0x74] ++xvsubwod.d.w $xr20, $xr7, $xr0 ++ ++# CHECK: xvsubwod.q.d $xr17, $xr23, $xr20 ++# CHECK: encoding: [0xf1,0xd2,0x25,0x74] ++xvsubwod.q.d $xr17, $xr23, $xr20 ++ ++# CHECK: xvaddwev.h.bu $xr15, $xr10, $xr31 ++# CHECK: encoding: [0x4f,0x7d,0x2e,0x74] ++xvaddwev.h.bu $xr15, $xr10, $xr31 ++ ++# CHECK: xvaddwev.w.hu $xr21, $xr24, $xr28 ++# CHECK: encoding: [0x15,0xf3,0x2e,0x74] ++xvaddwev.w.hu $xr21, $xr24, $xr28 ++ ++# CHECK: xvaddwev.d.wu $xr9, $xr31, $xr14 ++# CHECK: encoding: [0xe9,0x3b,0x2f,0x74] ++xvaddwev.d.wu $xr9, $xr31, $xr14 ++ ++# CHECK: xvaddwev.q.du $xr25, $xr1, $xr8 ++# CHECK: encoding: [0x39,0xa0,0x2f,0x74] ++xvaddwev.q.du $xr25, $xr1, $xr8 ++ ++# CHECK: xvsubwev.h.bu $xr30, $xr31, $xr13 ++# CHECK: encoding: [0xfe,0x37,0x30,0x74] ++xvsubwev.h.bu $xr30, $xr31, $xr13 ++ ++# CHECK: xvsubwev.w.hu $xr1, $xr28, $xr1 ++# CHECK: encoding: [0x81,0x87,0x30,0x74] ++xvsubwev.w.hu $xr1, $xr28, $xr1 ++ ++# CHECK: xvsubwev.d.wu $xr29, $xr23, $xr29 ++# CHECK: encoding: [0xfd,0x76,0x31,0x74] ++xvsubwev.d.wu $xr29, $xr23, $xr29 ++ ++# CHECK: xvsubwev.q.du $xr13, $xr16, $xr27 ++# CHECK: encoding: [0x0d,0xee,0x31,0x74] ++xvsubwev.q.du $xr13, $xr16, $xr27 ++ ++# CHECK: xvaddwod.h.bu $xr13, $xr29, $xr2 ++# CHECK: encoding: [0xad,0x0b,0x32,0x74] ++xvaddwod.h.bu $xr13, $xr29, $xr2 ++ ++# CHECK: xvaddwod.w.hu $xr14, $xr10, $xr13 ++# CHECK: encoding: [0x4e,0xb5,0x32,0x74] ++xvaddwod.w.hu $xr14, $xr10, $xr13 ++ ++# CHECK: xvaddwod.d.wu $xr30, $xr26, $xr10 ++# CHECK: encoding: [0x5e,0x2b,0x33,0x74] ++xvaddwod.d.wu $xr30, $xr26, $xr10 ++ ++# CHECK: xvaddwod.q.du $xr2, $xr13, $xr0 ++# CHECK: encoding: [0xa2,0x81,0x33,0x74] ++xvaddwod.q.du $xr2, $xr13, $xr0 ++ ++# CHECK: xvsubwod.h.bu $xr6, $xr22, $xr5 ++# CHECK: encoding: [0xc6,0x16,0x34,0x74] ++xvsubwod.h.bu $xr6, $xr22, $xr5 ++ ++# CHECK: xvsubwod.w.hu $xr19, $xr21, $xr8 ++# CHECK: encoding: [0xb3,0xa2,0x34,0x74] ++xvsubwod.w.hu $xr19, $xr21, $xr8 ++ ++# CHECK: xvsubwod.d.wu $xr16, $xr11, $xr30 ++# CHECK: encoding: [0x70,0x79,0x35,0x74] ++xvsubwod.d.wu $xr16, $xr11, $xr30 ++ ++# CHECK: xvsubwod.q.du $xr1, $xr26, $xr9 ++# CHECK: encoding: [0x41,0xa7,0x35,0x74] ++xvsubwod.q.du $xr1, $xr26, $xr9 ++ ++# CHECK: xvaddwev.h.bu.b $xr5, $xr13, $xr2 ++# CHECK: encoding: [0xa5,0x09,0x3e,0x74] ++xvaddwev.h.bu.b $xr5, $xr13, $xr2 ++ ++# CHECK: xvaddwev.w.hu.h $xr17, $xr21, $xr20 ++# CHECK: encoding: [0xb1,0xd2,0x3e,0x74] ++xvaddwev.w.hu.h $xr17, $xr21, $xr20 ++ ++# CHECK: xvaddwev.d.wu.w $xr11, $xr27, $xr19 ++# CHECK: encoding: [0x6b,0x4f,0x3f,0x74] ++xvaddwev.d.wu.w $xr11, $xr27, $xr19 ++ ++# CHECK: xvaddwev.q.du.d $xr20, $xr21, $xr29 ++# CHECK: encoding: [0xb4,0xf6,0x3f,0x74] ++xvaddwev.q.du.d $xr20, $xr21, $xr29 ++ ++# CHECK: xvaddwod.h.bu.b $xr1, $xr6, $xr14 ++# CHECK: encoding: [0xc1,0x38,0x40,0x74] ++xvaddwod.h.bu.b $xr1, $xr6, $xr14 ++ ++# CHECK: xvaddwod.w.hu.h $xr7, $xr29, $xr11 ++# CHECK: encoding: [0xa7,0xaf,0x40,0x74] ++xvaddwod.w.hu.h $xr7, $xr29, $xr11 ++ ++# CHECK: xvaddwod.d.wu.w $xr16, $xr10, $xr14 ++# CHECK: encoding: [0x50,0x39,0x41,0x74] ++xvaddwod.d.wu.w $xr16, $xr10, $xr14 ++ ++# CHECK: xvaddwod.q.du.d $xr10, $xr11, $xr23 ++# CHECK: encoding: [0x6a,0xdd,0x41,0x74] ++xvaddwod.q.du.d $xr10, $xr11, $xr23 ++ ++# CHECK: xvsadd.b $xr24, $xr10, $xr28 ++# CHECK: encoding: [0x58,0x71,0x46,0x74] ++xvsadd.b $xr24, $xr10, $xr28 ++ ++# CHECK: xvsadd.h $xr19, $xr18, $xr17 ++# CHECK: encoding: [0x53,0xc6,0x46,0x74] ++xvsadd.h $xr19, $xr18, $xr17 ++ ++# CHECK: xvsadd.w $xr2, $xr6, $xr12 ++# CHECK: encoding: [0xc2,0x30,0x47,0x74] ++xvsadd.w $xr2, $xr6, $xr12 ++ ++# CHECK: xvsadd.d $xr15, $xr18, $xr29 ++# CHECK: encoding: [0x4f,0xf6,0x47,0x74] ++xvsadd.d $xr15, $xr18, $xr29 ++ ++# CHECK: xvssub.b $xr15, $xr29, $xr16 ++# CHECK: encoding: [0xaf,0x43,0x48,0x74] ++xvssub.b $xr15, $xr29, $xr16 ++ ++# CHECK: xvssub.h $xr28, $xr3, $xr9 ++# CHECK: encoding: [0x7c,0xa4,0x48,0x74] ++xvssub.h $xr28, $xr3, $xr9 ++ ++# CHECK: xvssub.w $xr8, $xr20, $xr15 ++# CHECK: encoding: [0x88,0x3e,0x49,0x74] ++xvssub.w $xr8, $xr20, $xr15 ++ ++# CHECK: xvssub.d $xr23, $xr8, $xr19 ++# CHECK: encoding: [0x17,0xcd,0x49,0x74] ++xvssub.d $xr23, $xr8, $xr19 ++ ++# CHECK: xvsadd.bu $xr12, $xr4, $xr16 ++# CHECK: encoding: [0x8c,0x40,0x4a,0x74] ++xvsadd.bu $xr12, $xr4, $xr16 ++ ++# CHECK: xvsadd.hu $xr9, $xr26, $xr20 ++# CHECK: encoding: [0x49,0xd3,0x4a,0x74] ++xvsadd.hu $xr9, $xr26, $xr20 ++ ++# CHECK: xvsadd.wu $xr30, $xr15, $xr28 ++# CHECK: encoding: [0xfe,0x71,0x4b,0x74] ++xvsadd.wu $xr30, $xr15, $xr28 ++ ++# CHECK: xvsadd.du $xr15, $xr13, $xr28 ++# CHECK: encoding: [0xaf,0xf1,0x4b,0x74] ++xvsadd.du $xr15, $xr13, $xr28 ++ ++# CHECK: xvssub.bu $xr10, $xr3, $xr15 ++# CHECK: encoding: [0x6a,0x3c,0x4c,0x74] ++xvssub.bu $xr10, $xr3, $xr15 ++ ++# CHECK: xvssub.hu $xr0, $xr12, $xr2 ++# CHECK: encoding: [0x80,0x89,0x4c,0x74] ++xvssub.hu $xr0, $xr12, $xr2 ++ ++# CHECK: xvssub.wu $xr30, $xr10, $xr23 ++# CHECK: encoding: [0x5e,0x5d,0x4d,0x74] ++xvssub.wu $xr30, $xr10, $xr23 ++ ++# CHECK: xvssub.du $xr9, $xr30, $xr14 ++# CHECK: encoding: [0xc9,0xbb,0x4d,0x74] ++xvssub.du $xr9, $xr30, $xr14 ++ ++# CHECK: xvhaddw.h.b $xr25, $xr5, $xr18 ++# CHECK: encoding: [0xb9,0x48,0x54,0x74] ++xvhaddw.h.b $xr25, $xr5, $xr18 ++ ++# CHECK: xvhaddw.w.h $xr7, $xr20, $xr19 ++# CHECK: encoding: [0x87,0xce,0x54,0x74] ++xvhaddw.w.h $xr7, $xr20, $xr19 ++ ++# CHECK: xvhaddw.d.w $xr23, $xr5, $xr4 ++# CHECK: encoding: [0xb7,0x10,0x55,0x74] ++xvhaddw.d.w $xr23, $xr5, $xr4 ++ ++# CHECK: xvhaddw.q.d $xr17, $xr7, $xr25 ++# CHECK: encoding: [0xf1,0xe4,0x55,0x74] ++xvhaddw.q.d $xr17, $xr7, $xr25 ++ ++# CHECK: xvhsubw.h.b $xr29, $xr18, $xr19 ++# CHECK: encoding: [0x5d,0x4e,0x56,0x74] ++xvhsubw.h.b $xr29, $xr18, $xr19 ++ ++# CHECK: xvhsubw.w.h $xr30, $xr28, $xr3 ++# CHECK: encoding: [0x9e,0x8f,0x56,0x74] ++xvhsubw.w.h $xr30, $xr28, $xr3 ++ ++# CHECK: xvhsubw.d.w $xr5, $xr9, $xr13 ++# CHECK: encoding: [0x25,0x35,0x57,0x74] ++xvhsubw.d.w $xr5, $xr9, $xr13 ++ ++# CHECK: xvhsubw.q.d $xr20, $xr12, $xr29 ++# CHECK: encoding: [0x94,0xf5,0x57,0x74] ++xvhsubw.q.d $xr20, $xr12, $xr29 ++ ++# CHECK: xvhaddw.hu.bu $xr11, $xr10, $xr7 ++# CHECK: encoding: [0x4b,0x1d,0x58,0x74] ++xvhaddw.hu.bu $xr11, $xr10, $xr7 ++ ++# CHECK: xvhaddw.wu.hu $xr16, $xr21, $xr21 ++# CHECK: encoding: [0xb0,0xd6,0x58,0x74] ++xvhaddw.wu.hu $xr16, $xr21, $xr21 ++ ++# CHECK: xvhaddw.du.wu $xr17, $xr31, $xr8 ++# CHECK: encoding: [0xf1,0x23,0x59,0x74] ++xvhaddw.du.wu $xr17, $xr31, $xr8 ++ ++# CHECK: xvhaddw.qu.du $xr2, $xr4, $xr11 ++# CHECK: encoding: [0x82,0xac,0x59,0x74] ++xvhaddw.qu.du $xr2, $xr4, $xr11 ++ ++# CHECK: xvhsubw.hu.bu $xr21, $xr14, $xr8 ++# CHECK: encoding: [0xd5,0x21,0x5a,0x74] ++xvhsubw.hu.bu $xr21, $xr14, $xr8 ++ ++# CHECK: xvhsubw.wu.hu $xr25, $xr0, $xr27 ++# CHECK: encoding: [0x19,0xec,0x5a,0x74] ++xvhsubw.wu.hu $xr25, $xr0, $xr27 ++ ++# CHECK: xvhsubw.du.wu $xr4, $xr16, $xr30 ++# CHECK: encoding: [0x04,0x7a,0x5b,0x74] ++xvhsubw.du.wu $xr4, $xr16, $xr30 ++ ++# CHECK: xvhsubw.qu.du $xr11, $xr9, $xr6 ++# CHECK: encoding: [0x2b,0x99,0x5b,0x74] ++xvhsubw.qu.du $xr11, $xr9, $xr6 ++ ++# CHECK: xvadda.b $xr14, $xr21, $xr26 ++# CHECK: encoding: [0xae,0x6a,0x5c,0x74] ++xvadda.b $xr14, $xr21, $xr26 ++ ++# CHECK: xvadda.h $xr21, $xr30, $xr21 ++# CHECK: encoding: [0xd5,0xd7,0x5c,0x74] ++xvadda.h $xr21, $xr30, $xr21 ++ ++# CHECK: xvadda.w $xr31, $xr19, $xr19 ++# CHECK: encoding: [0x7f,0x4e,0x5d,0x74] ++xvadda.w $xr31, $xr19, $xr19 ++ ++# CHECK: xvadda.d $xr9, $xr4, $xr31 ++# CHECK: encoding: [0x89,0xfc,0x5d,0x74] ++xvadda.d $xr9, $xr4, $xr31 ++ ++# CHECK: xvabsd.b $xr20, $xr19, $xr13 ++# CHECK: encoding: [0x74,0x36,0x60,0x74] ++xvabsd.b $xr20, $xr19, $xr13 ++ ++# CHECK: xvabsd.h $xr20, $xr7, $xr10 ++# CHECK: encoding: [0xf4,0xa8,0x60,0x74] ++xvabsd.h $xr20, $xr7, $xr10 ++ ++# CHECK: xvabsd.w $xr23, $xr31, $xr0 ++# CHECK: encoding: [0xf7,0x03,0x61,0x74] ++xvabsd.w $xr23, $xr31, $xr0 ++ ++# CHECK: xvabsd.d $xr7, $xr17, $xr14 ++# CHECK: encoding: [0x27,0xba,0x61,0x74] ++xvabsd.d $xr7, $xr17, $xr14 ++ ++# CHECK: xvabsd.bu $xr12, $xr23, $xr6 ++# CHECK: encoding: [0xec,0x1a,0x62,0x74] ++xvabsd.bu $xr12, $xr23, $xr6 ++ ++# CHECK: xvabsd.hu $xr16, $xr30, $xr19 ++# CHECK: encoding: [0xd0,0xcf,0x62,0x74] ++xvabsd.hu $xr16, $xr30, $xr19 ++ ++# CHECK: xvabsd.wu $xr19, $xr5, $xr26 ++# CHECK: encoding: [0xb3,0x68,0x63,0x74] ++xvabsd.wu $xr19, $xr5, $xr26 ++ ++# CHECK: xvabsd.du $xr0, $xr12, $xr7 ++# CHECK: encoding: [0x80,0x9d,0x63,0x74] ++xvabsd.du $xr0, $xr12, $xr7 ++ ++# CHECK: xvavg.b $xr23, $xr31, $xr25 ++# CHECK: encoding: [0xf7,0x67,0x64,0x74] ++xvavg.b $xr23, $xr31, $xr25 ++ ++# CHECK: xvavg.h $xr27, $xr2, $xr27 ++# CHECK: encoding: [0x5b,0xec,0x64,0x74] ++xvavg.h $xr27, $xr2, $xr27 ++ ++# CHECK: xvavg.w $xr20, $xr0, $xr16 ++# CHECK: encoding: [0x14,0x40,0x65,0x74] ++xvavg.w $xr20, $xr0, $xr16 ++ ++# CHECK: xvavg.d $xr13, $xr9, $xr10 ++# CHECK: encoding: [0x2d,0xa9,0x65,0x74] ++xvavg.d $xr13, $xr9, $xr10 ++ ++# CHECK: xvavg.bu $xr31, $xr30, $xr4 ++# CHECK: encoding: [0xdf,0x13,0x66,0x74] ++xvavg.bu $xr31, $xr30, $xr4 ++ ++# CHECK: xvavg.hu $xr22, $xr17, $xr5 ++# CHECK: encoding: [0x36,0x96,0x66,0x74] ++xvavg.hu $xr22, $xr17, $xr5 ++ ++# CHECK: xvavg.wu $xr21, $xr29, $xr17 ++# CHECK: encoding: [0xb5,0x47,0x67,0x74] ++xvavg.wu $xr21, $xr29, $xr17 ++ ++# CHECK: xvavg.du $xr11, $xr5, $xr29 ++# CHECK: encoding: [0xab,0xf4,0x67,0x74] ++xvavg.du $xr11, $xr5, $xr29 ++ ++# CHECK: xvavgr.b $xr23, $xr13, $xr13 ++# CHECK: encoding: [0xb7,0x35,0x68,0x74] ++xvavgr.b $xr23, $xr13, $xr13 ++ ++# CHECK: xvavgr.h $xr30, $xr20, $xr31 ++# CHECK: encoding: [0x9e,0xfe,0x68,0x74] ++xvavgr.h $xr30, $xr20, $xr31 ++ ++# CHECK: xvavgr.w $xr29, $xr28, $xr9 ++# CHECK: encoding: [0x9d,0x27,0x69,0x74] ++xvavgr.w $xr29, $xr28, $xr9 ++ ++# CHECK: xvavgr.d $xr21, $xr20, $xr8 ++# CHECK: encoding: [0x95,0xa2,0x69,0x74] ++xvavgr.d $xr21, $xr20, $xr8 ++ ++# CHECK: xvavgr.bu $xr0, $xr9, $xr4 ++# CHECK: encoding: [0x20,0x11,0x6a,0x74] ++xvavgr.bu $xr0, $xr9, $xr4 ++ ++# CHECK: xvavgr.hu $xr3, $xr0, $xr27 ++# CHECK: encoding: [0x03,0xec,0x6a,0x74] ++xvavgr.hu $xr3, $xr0, $xr27 ++ ++# CHECK: xvavgr.wu $xr2, $xr30, $xr21 ++# CHECK: encoding: [0xc2,0x57,0x6b,0x74] ++xvavgr.wu $xr2, $xr30, $xr21 ++ ++# CHECK: xvavgr.du $xr22, $xr21, $xr17 ++# CHECK: encoding: [0xb6,0xc6,0x6b,0x74] ++xvavgr.du $xr22, $xr21, $xr17 ++ ++# CHECK: xvmax.b $xr1, $xr20, $xr19 ++# CHECK: encoding: [0x81,0x4e,0x70,0x74] ++xvmax.b $xr1, $xr20, $xr19 ++ ++# CHECK: xvmax.h $xr0, $xr17, $xr14 ++# CHECK: encoding: [0x20,0xba,0x70,0x74] ++xvmax.h $xr0, $xr17, $xr14 ++ ++# CHECK: xvmax.w $xr0, $xr8, $xr16 ++# CHECK: encoding: [0x00,0x41,0x71,0x74] ++xvmax.w $xr0, $xr8, $xr16 ++ ++# CHECK: xvmax.d $xr16, $xr23, $xr16 ++# CHECK: encoding: [0xf0,0xc2,0x71,0x74] ++xvmax.d $xr16, $xr23, $xr16 ++ ++# CHECK: xvmin.b $xr20, $xr6, $xr14 ++# CHECK: encoding: [0xd4,0x38,0x72,0x74] ++xvmin.b $xr20, $xr6, $xr14 ++ ++# CHECK: xvmin.h $xr4, $xr3, $xr24 ++# CHECK: encoding: [0x64,0xe0,0x72,0x74] ++xvmin.h $xr4, $xr3, $xr24 ++ ++# CHECK: xvmin.w $xr5, $xr2, $xr23 ++# CHECK: encoding: [0x45,0x5c,0x73,0x74] ++xvmin.w $xr5, $xr2, $xr23 ++ ++# CHECK: xvmin.d $xr31, $xr23, $xr26 ++# CHECK: encoding: [0xff,0xea,0x73,0x74] ++xvmin.d $xr31, $xr23, $xr26 ++ ++# CHECK: xvmax.bu $xr14, $xr13, $xr3 ++# CHECK: encoding: [0xae,0x0d,0x74,0x74] ++xvmax.bu $xr14, $xr13, $xr3 ++ ++# CHECK: xvmax.hu $xr22, $xr17, $xr4 ++# CHECK: encoding: [0x36,0x92,0x74,0x74] ++xvmax.hu $xr22, $xr17, $xr4 ++ ++# CHECK: xvmax.wu $xr17, $xr13, $xr29 ++# CHECK: encoding: [0xb1,0x75,0x75,0x74] ++xvmax.wu $xr17, $xr13, $xr29 ++ ++# CHECK: xvmax.du $xr13, $xr2, $xr0 ++# CHECK: encoding: [0x4d,0x80,0x75,0x74] ++xvmax.du $xr13, $xr2, $xr0 ++ ++# CHECK: xvmin.bu $xr18, $xr31, $xr27 ++# CHECK: encoding: [0xf2,0x6f,0x76,0x74] ++xvmin.bu $xr18, $xr31, $xr27 ++ ++# CHECK: xvmin.hu $xr2, $xr10, $xr14 ++# CHECK: encoding: [0x42,0xb9,0x76,0x74] ++xvmin.hu $xr2, $xr10, $xr14 ++ ++# CHECK: xvmin.wu $xr31, $xr8, $xr26 ++# CHECK: encoding: [0x1f,0x69,0x77,0x74] ++xvmin.wu $xr31, $xr8, $xr26 ++ ++# CHECK: xvmin.du $xr12, $xr26, $xr9 ++# CHECK: encoding: [0x4c,0xa7,0x77,0x74] ++xvmin.du $xr12, $xr26, $xr9 ++ ++# CHECK: xvmul.b $xr26, $xr2, $xr3 ++# CHECK: encoding: [0x5a,0x0c,0x84,0x74] ++xvmul.b $xr26, $xr2, $xr3 ++ ++# CHECK: xvmul.h $xr16, $xr29, $xr5 ++# CHECK: encoding: [0xb0,0x97,0x84,0x74] ++xvmul.h $xr16, $xr29, $xr5 ++ ++# CHECK: xvmul.w $xr19, $xr1, $xr3 ++# CHECK: encoding: [0x33,0x0c,0x85,0x74] ++xvmul.w $xr19, $xr1, $xr3 ++ ++# CHECK: xvmul.d $xr15, $xr15, $xr0 ++# CHECK: encoding: [0xef,0x81,0x85,0x74] ++xvmul.d $xr15, $xr15, $xr0 ++ ++# CHECK: xvmuh.b $xr9, $xr12, $xr9 ++# CHECK: encoding: [0x89,0x25,0x86,0x74] ++xvmuh.b $xr9, $xr12, $xr9 ++ ++# CHECK: xvmuh.h $xr8, $xr23, $xr16 ++# CHECK: encoding: [0xe8,0xc2,0x86,0x74] ++xvmuh.h $xr8, $xr23, $xr16 ++ ++# CHECK: xvmuh.w $xr29, $xr6, $xr11 ++# CHECK: encoding: [0xdd,0x2c,0x87,0x74] ++xvmuh.w $xr29, $xr6, $xr11 ++ ++# CHECK: xvmuh.d $xr3, $xr18, $xr7 ++# CHECK: encoding: [0x43,0x9e,0x87,0x74] ++xvmuh.d $xr3, $xr18, $xr7 ++ ++# CHECK: xvmuh.bu $xr3, $xr7, $xr19 ++# CHECK: encoding: [0xe3,0x4c,0x88,0x74] ++xvmuh.bu $xr3, $xr7, $xr19 ++ ++# CHECK: xvmuh.hu $xr13, $xr1, $xr18 ++# CHECK: encoding: [0x2d,0xc8,0x88,0x74] ++xvmuh.hu $xr13, $xr1, $xr18 ++ ++# CHECK: xvmuh.wu $xr15, $xr21, $xr16 ++# CHECK: encoding: [0xaf,0x42,0x89,0x74] ++xvmuh.wu $xr15, $xr21, $xr16 ++ ++# CHECK: xvmuh.du $xr11, $xr10, $xr19 ++# CHECK: encoding: [0x4b,0xcd,0x89,0x74] ++xvmuh.du $xr11, $xr10, $xr19 ++ ++# CHECK: xvmulwev.h.b $xr4, $xr12, $xr9 ++# CHECK: encoding: [0x84,0x25,0x90,0x74] ++xvmulwev.h.b $xr4, $xr12, $xr9 ++ ++# CHECK: xvmulwev.w.h $xr10, $xr3, $xr20 ++# CHECK: encoding: [0x6a,0xd0,0x90,0x74] ++xvmulwev.w.h $xr10, $xr3, $xr20 ++ ++# CHECK: xvmulwev.d.w $xr4, $xr22, $xr18 ++# CHECK: encoding: [0xc4,0x4a,0x91,0x74] ++xvmulwev.d.w $xr4, $xr22, $xr18 ++ ++# CHECK: xvmulwev.q.d $xr20, $xr21, $xr27 ++# CHECK: encoding: [0xb4,0xee,0x91,0x74] ++xvmulwev.q.d $xr20, $xr21, $xr27 ++ ++# CHECK: xvmulwod.h.b $xr5, $xr7, $xr0 ++# CHECK: encoding: [0xe5,0x00,0x92,0x74] ++xvmulwod.h.b $xr5, $xr7, $xr0 ++ ++# CHECK: xvmulwod.w.h $xr19, $xr28, $xr11 ++# CHECK: encoding: [0x93,0xaf,0x92,0x74] ++xvmulwod.w.h $xr19, $xr28, $xr11 ++ ++# CHECK: xvmulwod.d.w $xr19, $xr7, $xr16 ++# CHECK: encoding: [0xf3,0x40,0x93,0x74] ++xvmulwod.d.w $xr19, $xr7, $xr16 ++ ++# CHECK: xvmulwod.q.d $xr11, $xr12, $xr13 ++# CHECK: encoding: [0x8b,0xb5,0x93,0x74] ++xvmulwod.q.d $xr11, $xr12, $xr13 ++ ++# CHECK: xvmulwev.h.bu $xr22, $xr2, $xr1 ++# CHECK: encoding: [0x56,0x04,0x98,0x74] ++xvmulwev.h.bu $xr22, $xr2, $xr1 ++ ++# CHECK: xvmulwev.w.hu $xr2, $xr3, $xr4 ++# CHECK: encoding: [0x62,0x90,0x98,0x74] ++xvmulwev.w.hu $xr2, $xr3, $xr4 ++ ++# CHECK: xvmulwev.d.wu $xr2, $xr12, $xr25 ++# CHECK: encoding: [0x82,0x65,0x99,0x74] ++xvmulwev.d.wu $xr2, $xr12, $xr25 ++ ++# CHECK: xvmulwev.q.du $xr22, $xr29, $xr17 ++# CHECK: encoding: [0xb6,0xc7,0x99,0x74] ++xvmulwev.q.du $xr22, $xr29, $xr17 ++ ++# CHECK: xvmulwod.h.bu $xr9, $xr9, $xr0 ++# CHECK: encoding: [0x29,0x01,0x9a,0x74] ++xvmulwod.h.bu $xr9, $xr9, $xr0 ++ ++# CHECK: xvmulwod.w.hu $xr20, $xr2, $xr16 ++# CHECK: encoding: [0x54,0xc0,0x9a,0x74] ++xvmulwod.w.hu $xr20, $xr2, $xr16 ++ ++# CHECK: xvmulwod.d.wu $xr1, $xr11, $xr24 ++# CHECK: encoding: [0x61,0x61,0x9b,0x74] ++xvmulwod.d.wu $xr1, $xr11, $xr24 ++ ++# CHECK: xvmulwod.q.du $xr19, $xr2, $xr22 ++# CHECK: encoding: [0x53,0xd8,0x9b,0x74] ++xvmulwod.q.du $xr19, $xr2, $xr22 ++ ++# CHECK: xvmulwev.h.bu.b $xr22, $xr29, $xr24 ++# CHECK: encoding: [0xb6,0x63,0xa0,0x74] ++xvmulwev.h.bu.b $xr22, $xr29, $xr24 ++ ++# CHECK: xvmulwev.w.hu.h $xr1, $xr22, $xr11 ++# CHECK: encoding: [0xc1,0xae,0xa0,0x74] ++xvmulwev.w.hu.h $xr1, $xr22, $xr11 ++ ++# CHECK: xvmulwev.d.wu.w $xr12, $xr12, $xr12 ++# CHECK: encoding: [0x8c,0x31,0xa1,0x74] ++xvmulwev.d.wu.w $xr12, $xr12, $xr12 ++ ++# CHECK: xvmulwev.q.du.d $xr0, $xr17, $xr23 ++# CHECK: encoding: [0x20,0xde,0xa1,0x74] ++xvmulwev.q.du.d $xr0, $xr17, $xr23 ++ ++# CHECK: xvmulwod.h.bu.b $xr26, $xr16, $xr23 ++# CHECK: encoding: [0x1a,0x5e,0xa2,0x74] ++xvmulwod.h.bu.b $xr26, $xr16, $xr23 ++ ++# CHECK: xvmulwod.w.hu.h $xr31, $xr12, $xr9 ++# CHECK: encoding: [0x9f,0xa5,0xa2,0x74] ++xvmulwod.w.hu.h $xr31, $xr12, $xr9 ++ ++# CHECK: xvmulwod.d.wu.w $xr21, $xr27, $xr19 ++# CHECK: encoding: [0x75,0x4f,0xa3,0x74] ++xvmulwod.d.wu.w $xr21, $xr27, $xr19 ++ ++# CHECK: xvmulwod.q.du.d $xr7, $xr5, $xr11 ++# CHECK: encoding: [0xa7,0xac,0xa3,0x74] ++xvmulwod.q.du.d $xr7, $xr5, $xr11 ++ ++# CHECK: xvmadd.b $xr22, $xr11, $xr15 ++# CHECK: encoding: [0x76,0x3d,0xa8,0x74] ++xvmadd.b $xr22, $xr11, $xr15 ++ ++# CHECK: xvmadd.h $xr3, $xr30, $xr25 ++# CHECK: encoding: [0xc3,0xe7,0xa8,0x74] ++xvmadd.h $xr3, $xr30, $xr25 ++ ++# CHECK: xvmadd.w $xr1, $xr18, $xr5 ++# CHECK: encoding: [0x41,0x16,0xa9,0x74] ++xvmadd.w $xr1, $xr18, $xr5 ++ ++# CHECK: xvmadd.d $xr16, $xr21, $xr11 ++# CHECK: encoding: [0xb0,0xae,0xa9,0x74] ++xvmadd.d $xr16, $xr21, $xr11 ++ ++# CHECK: xvmsub.b $xr11, $xr12, $xr10 ++# CHECK: encoding: [0x8b,0x29,0xaa,0x74] ++xvmsub.b $xr11, $xr12, $xr10 ++ ++# CHECK: xvmsub.h $xr16, $xr11, $xr1 ++# CHECK: encoding: [0x70,0x85,0xaa,0x74] ++xvmsub.h $xr16, $xr11, $xr1 ++ ++# CHECK: xvmsub.w $xr15, $xr21, $xr21 ++# CHECK: encoding: [0xaf,0x56,0xab,0x74] ++xvmsub.w $xr15, $xr21, $xr21 ++ ++# CHECK: xvmsub.d $xr12, $xr11, $xr4 ++# CHECK: encoding: [0x6c,0x91,0xab,0x74] ++xvmsub.d $xr12, $xr11, $xr4 ++ ++# CHECK: xvmaddwev.h.b $xr21, $xr7, $xr6 ++# CHECK: encoding: [0xf5,0x18,0xac,0x74] ++xvmaddwev.h.b $xr21, $xr7, $xr6 ++ ++# CHECK: xvmaddwev.w.h $xr16, $xr29, $xr13 ++# CHECK: encoding: [0xb0,0xb7,0xac,0x74] ++xvmaddwev.w.h $xr16, $xr29, $xr13 ++ ++# CHECK: xvmaddwev.d.w $xr7, $xr25, $xr30 ++# CHECK: encoding: [0x27,0x7b,0xad,0x74] ++xvmaddwev.d.w $xr7, $xr25, $xr30 ++ ++# CHECK: xvmaddwev.q.d $xr19, $xr3, $xr8 ++# CHECK: encoding: [0x73,0xa0,0xad,0x74] ++xvmaddwev.q.d $xr19, $xr3, $xr8 ++ ++# CHECK: xvmaddwod.h.b $xr20, $xr27, $xr12 ++# CHECK: encoding: [0x74,0x33,0xae,0x74] ++xvmaddwod.h.b $xr20, $xr27, $xr12 ++ ++# CHECK: xvmaddwod.w.h $xr0, $xr21, $xr13 ++# CHECK: encoding: [0xa0,0xb6,0xae,0x74] ++xvmaddwod.w.h $xr0, $xr21, $xr13 ++ ++# CHECK: xvmaddwod.d.w $xr25, $xr13, $xr31 ++# CHECK: encoding: [0xb9,0x7d,0xaf,0x74] ++xvmaddwod.d.w $xr25, $xr13, $xr31 ++ ++# CHECK: xvmaddwod.q.d $xr26, $xr26, $xr16 ++# CHECK: encoding: [0x5a,0xc3,0xaf,0x74] ++xvmaddwod.q.d $xr26, $xr26, $xr16 ++ ++# CHECK: xvmaddwev.h.bu $xr18, $xr26, $xr21 ++# CHECK: encoding: [0x52,0x57,0xb4,0x74] ++xvmaddwev.h.bu $xr18, $xr26, $xr21 ++ ++# CHECK: xvmaddwev.w.hu $xr14, $xr16, $xr5 ++# CHECK: encoding: [0x0e,0x96,0xb4,0x74] ++xvmaddwev.w.hu $xr14, $xr16, $xr5 ++ ++# CHECK: xvmaddwev.d.wu $xr19, $xr29, $xr20 ++# CHECK: encoding: [0xb3,0x53,0xb5,0x74] ++xvmaddwev.d.wu $xr19, $xr29, $xr20 ++ ++# CHECK: xvmaddwev.q.du $xr15, $xr29, $xr17 ++# CHECK: encoding: [0xaf,0xc7,0xb5,0x74] ++xvmaddwev.q.du $xr15, $xr29, $xr17 ++ ++# CHECK: xvmaddwod.h.bu $xr13, $xr26, $xr1 ++# CHECK: encoding: [0x4d,0x07,0xb6,0x74] ++xvmaddwod.h.bu $xr13, $xr26, $xr1 ++ ++# CHECK: xvmaddwod.w.hu $xr15, $xr25, $xr16 ++# CHECK: encoding: [0x2f,0xc3,0xb6,0x74] ++xvmaddwod.w.hu $xr15, $xr25, $xr16 ++ ++# CHECK: xvmaddwod.d.wu $xr23, $xr4, $xr9 ++# CHECK: encoding: [0x97,0x24,0xb7,0x74] ++xvmaddwod.d.wu $xr23, $xr4, $xr9 ++ ++# CHECK: xvmaddwod.q.du $xr29, $xr22, $xr17 ++# CHECK: encoding: [0xdd,0xc6,0xb7,0x74] ++xvmaddwod.q.du $xr29, $xr22, $xr17 ++ ++# CHECK: xvmaddwev.h.bu.b $xr23, $xr1, $xr6 ++# CHECK: encoding: [0x37,0x18,0xbc,0x74] ++xvmaddwev.h.bu.b $xr23, $xr1, $xr6 ++ ++# CHECK: xvmaddwev.w.hu.h $xr4, $xr27, $xr12 ++# CHECK: encoding: [0x64,0xb3,0xbc,0x74] ++xvmaddwev.w.hu.h $xr4, $xr27, $xr12 ++ ++# CHECK: xvmaddwev.d.wu.w $xr0, $xr2, $xr5 ++# CHECK: encoding: [0x40,0x14,0xbd,0x74] ++xvmaddwev.d.wu.w $xr0, $xr2, $xr5 ++ ++# CHECK: xvmaddwev.q.du.d $xr9, $xr31, $xr1 ++# CHECK: encoding: [0xe9,0x87,0xbd,0x74] ++xvmaddwev.q.du.d $xr9, $xr31, $xr1 ++ ++# CHECK: xvmaddwod.h.bu.b $xr9, $xr19, $xr20 ++# CHECK: encoding: [0x69,0x52,0xbe,0x74] ++xvmaddwod.h.bu.b $xr9, $xr19, $xr20 ++ ++# CHECK: xvmaddwod.w.hu.h $xr7, $xr5, $xr13 ++# CHECK: encoding: [0xa7,0xb4,0xbe,0x74] ++xvmaddwod.w.hu.h $xr7, $xr5, $xr13 ++ ++# CHECK: xvmaddwod.d.wu.w $xr10, $xr27, $xr1 ++# CHECK: encoding: [0x6a,0x07,0xbf,0x74] ++xvmaddwod.d.wu.w $xr10, $xr27, $xr1 ++ ++# CHECK: xvmaddwod.q.du.d $xr25, $xr19, $xr0 ++# CHECK: encoding: [0x79,0x82,0xbf,0x74] ++xvmaddwod.q.du.d $xr25, $xr19, $xr0 ++ ++# CHECK: xvdiv.b $xr3, $xr31, $xr2 ++# CHECK: encoding: [0xe3,0x0b,0xe0,0x74] ++xvdiv.b $xr3, $xr31, $xr2 ++ ++# CHECK: xvdiv.h $xr1, $xr12, $xr17 ++# CHECK: encoding: [0x81,0xc5,0xe0,0x74] ++xvdiv.h $xr1, $xr12, $xr17 ++ ++# CHECK: xvdiv.w $xr13, $xr0, $xr12 ++# CHECK: encoding: [0x0d,0x30,0xe1,0x74] ++xvdiv.w $xr13, $xr0, $xr12 ++ ++# CHECK: xvdiv.d $xr17, $xr5, $xr11 ++# CHECK: encoding: [0xb1,0xac,0xe1,0x74] ++xvdiv.d $xr17, $xr5, $xr11 ++ ++# CHECK: xvmod.b $xr22, $xr17, $xr1 ++# CHECK: encoding: [0x36,0x06,0xe2,0x74] ++xvmod.b $xr22, $xr17, $xr1 ++ ++# CHECK: xvmod.h $xr28, $xr5, $xr12 ++# CHECK: encoding: [0xbc,0xb0,0xe2,0x74] ++xvmod.h $xr28, $xr5, $xr12 ++ ++# CHECK: xvmod.w $xr29, $xr19, $xr14 ++# CHECK: encoding: [0x7d,0x3a,0xe3,0x74] ++xvmod.w $xr29, $xr19, $xr14 ++ ++# CHECK: xvmod.d $xr17, $xr8, $xr6 ++# CHECK: encoding: [0x11,0x99,0xe3,0x74] ++xvmod.d $xr17, $xr8, $xr6 ++ ++# CHECK: xvdiv.bu $xr23, $xr6, $xr2 ++# CHECK: encoding: [0xd7,0x08,0xe4,0x74] ++xvdiv.bu $xr23, $xr6, $xr2 ++ ++# CHECK: xvdiv.hu $xr9, $xr31, $xr0 ++# CHECK: encoding: [0xe9,0x83,0xe4,0x74] ++xvdiv.hu $xr9, $xr31, $xr0 ++ ++# CHECK: xvdiv.wu $xr15, $xr1, $xr4 ++# CHECK: encoding: [0x2f,0x10,0xe5,0x74] ++xvdiv.wu $xr15, $xr1, $xr4 ++ ++# CHECK: xvdiv.du $xr14, $xr29, $xr11 ++# CHECK: encoding: [0xae,0xaf,0xe5,0x74] ++xvdiv.du $xr14, $xr29, $xr11 ++ ++# CHECK: xvmod.bu $xr4, $xr12, $xr31 ++# CHECK: encoding: [0x84,0x7d,0xe6,0x74] ++xvmod.bu $xr4, $xr12, $xr31 ++ ++# CHECK: xvmod.hu $xr22, $xr12, $xr11 ++# CHECK: encoding: [0x96,0xad,0xe6,0x74] ++xvmod.hu $xr22, $xr12, $xr11 ++ ++# CHECK: xvmod.wu $xr21, $xr23, $xr10 ++# CHECK: encoding: [0xf5,0x2a,0xe7,0x74] ++xvmod.wu $xr21, $xr23, $xr10 ++ ++# CHECK: xvmod.du $xr21, $xr21, $xr31 ++# CHECK: encoding: [0xb5,0xfe,0xe7,0x74] ++xvmod.du $xr21, $xr21, $xr31 ++ ++# CHECK: xvsll.b $xr16, $xr10, $xr11 ++# CHECK: encoding: [0x50,0x2d,0xe8,0x74] ++xvsll.b $xr16, $xr10, $xr11 ++ ++# CHECK: xvsll.h $xr12, $xr10, $xr27 ++# CHECK: encoding: [0x4c,0xed,0xe8,0x74] ++xvsll.h $xr12, $xr10, $xr27 ++ ++# CHECK: xvsll.w $xr30, $xr2, $xr26 ++# CHECK: encoding: [0x5e,0x68,0xe9,0x74] ++xvsll.w $xr30, $xr2, $xr26 ++ ++# CHECK: xvsll.d $xr8, $xr21, $xr17 ++# CHECK: encoding: [0xa8,0xc6,0xe9,0x74] ++xvsll.d $xr8, $xr21, $xr17 ++ ++# CHECK: xvsrl.b $xr27, $xr24, $xr18 ++# CHECK: encoding: [0x1b,0x4b,0xea,0x74] ++xvsrl.b $xr27, $xr24, $xr18 ++ ++# CHECK: xvsrl.h $xr17, $xr31, $xr24 ++# CHECK: encoding: [0xf1,0xe3,0xea,0x74] ++xvsrl.h $xr17, $xr31, $xr24 ++ ++# CHECK: xvsrl.w $xr5, $xr3, $xr4 ++# CHECK: encoding: [0x65,0x10,0xeb,0x74] ++xvsrl.w $xr5, $xr3, $xr4 ++ ++# CHECK: xvsrl.d $xr21, $xr6, $xr8 ++# CHECK: encoding: [0xd5,0xa0,0xeb,0x74] ++xvsrl.d $xr21, $xr6, $xr8 ++ ++# CHECK: xvsra.b $xr28, $xr28, $xr21 ++# CHECK: encoding: [0x9c,0x57,0xec,0x74] ++xvsra.b $xr28, $xr28, $xr21 ++ ++# CHECK: xvsra.h $xr19, $xr4, $xr26 ++# CHECK: encoding: [0x93,0xe8,0xec,0x74] ++xvsra.h $xr19, $xr4, $xr26 ++ ++# CHECK: xvsra.w $xr13, $xr20, $xr1 ++# CHECK: encoding: [0x8d,0x06,0xed,0x74] ++xvsra.w $xr13, $xr20, $xr1 ++ ++# CHECK: xvsra.d $xr0, $xr8, $xr18 ++# CHECK: encoding: [0x00,0xc9,0xed,0x74] ++xvsra.d $xr0, $xr8, $xr18 ++ ++# CHECK: xvrotr.b $xr8, $xr30, $xr28 ++# CHECK: encoding: [0xc8,0x73,0xee,0x74] ++xvrotr.b $xr8, $xr30, $xr28 ++ ++# CHECK: xvrotr.h $xr17, $xr19, $xr0 ++# CHECK: encoding: [0x71,0x82,0xee,0x74] ++xvrotr.h $xr17, $xr19, $xr0 ++ ++# CHECK: xvrotr.w $xr15, $xr28, $xr23 ++# CHECK: encoding: [0x8f,0x5f,0xef,0x74] ++xvrotr.w $xr15, $xr28, $xr23 ++ ++# CHECK: xvrotr.d $xr31, $xr2, $xr21 ++# CHECK: encoding: [0x5f,0xd4,0xef,0x74] ++xvrotr.d $xr31, $xr2, $xr21 ++ ++# CHECK: xvsrlr.b $xr20, $xr26, $xr11 ++# CHECK: encoding: [0x54,0x2f,0xf0,0x74] ++xvsrlr.b $xr20, $xr26, $xr11 ++ ++# CHECK: xvsrlr.h $xr13, $xr18, $xr7 ++# CHECK: encoding: [0x4d,0x9e,0xf0,0x74] ++xvsrlr.h $xr13, $xr18, $xr7 ++ ++# CHECK: xvsrlr.w $xr28, $xr1, $xr3 ++# CHECK: encoding: [0x3c,0x0c,0xf1,0x74] ++xvsrlr.w $xr28, $xr1, $xr3 ++ ++# CHECK: xvsrlr.d $xr6, $xr3, $xr14 ++# CHECK: encoding: [0x66,0xb8,0xf1,0x74] ++xvsrlr.d $xr6, $xr3, $xr14 ++ ++# CHECK: xvsrar.b $xr10, $xr8, $xr17 ++# CHECK: encoding: [0x0a,0x45,0xf2,0x74] ++xvsrar.b $xr10, $xr8, $xr17 ++ ++# CHECK: xvsrar.h $xr31, $xr2, $xr11 ++# CHECK: encoding: [0x5f,0xac,0xf2,0x74] ++xvsrar.h $xr31, $xr2, $xr11 ++ ++# CHECK: xvsrar.w $xr13, $xr8, $xr5 ++# CHECK: encoding: [0x0d,0x15,0xf3,0x74] ++xvsrar.w $xr13, $xr8, $xr5 ++ ++# CHECK: xvsrar.d $xr12, $xr18, $xr0 ++# CHECK: encoding: [0x4c,0x82,0xf3,0x74] ++xvsrar.d $xr12, $xr18, $xr0 ++ ++# CHECK: xvsrln.b.h $xr15, $xr6, $xr15 ++# CHECK: encoding: [0xcf,0xbc,0xf4,0x74] ++xvsrln.b.h $xr15, $xr6, $xr15 ++ ++# CHECK: xvsrln.h.w $xr22, $xr19, $xr17 ++# CHECK: encoding: [0x76,0x46,0xf5,0x74] ++xvsrln.h.w $xr22, $xr19, $xr17 ++ ++# CHECK: xvsrln.w.d $xr4, $xr7, $xr5 ++# CHECK: encoding: [0xe4,0x94,0xf5,0x74] ++xvsrln.w.d $xr4, $xr7, $xr5 ++ ++# CHECK: xvsran.b.h $xr3, $xr19, $xr23 ++# CHECK: encoding: [0x63,0xde,0xf6,0x74] ++xvsran.b.h $xr3, $xr19, $xr23 ++ ++# CHECK: xvsran.h.w $xr16, $xr6, $xr1 ++# CHECK: encoding: [0xd0,0x04,0xf7,0x74] ++xvsran.h.w $xr16, $xr6, $xr1 ++ ++# CHECK: xvsran.w.d $xr27, $xr16, $xr0 ++# CHECK: encoding: [0x1b,0x82,0xf7,0x74] ++xvsran.w.d $xr27, $xr16, $xr0 ++ ++# CHECK: xvsrlrn.b.h $xr2, $xr9, $xr9 ++# CHECK: encoding: [0x22,0xa5,0xf8,0x74] ++xvsrlrn.b.h $xr2, $xr9, $xr9 ++ ++# CHECK: xvsrlrn.h.w $xr16, $xr11, $xr19 ++# CHECK: encoding: [0x70,0x4d,0xf9,0x74] ++xvsrlrn.h.w $xr16, $xr11, $xr19 ++ ++# CHECK: xvsrlrn.w.d $xr29, $xr25, $xr15 ++# CHECK: encoding: [0x3d,0xbf,0xf9,0x74] ++xvsrlrn.w.d $xr29, $xr25, $xr15 ++ ++# CHECK: xvsrarn.b.h $xr13, $xr20, $xr13 ++# CHECK: encoding: [0x8d,0xb6,0xfa,0x74] ++xvsrarn.b.h $xr13, $xr20, $xr13 ++ ++# CHECK: xvsrarn.h.w $xr13, $xr22, $xr1 ++# CHECK: encoding: [0xcd,0x06,0xfb,0x74] ++xvsrarn.h.w $xr13, $xr22, $xr1 ++ ++# CHECK: xvsrarn.w.d $xr13, $xr12, $xr2 ++# CHECK: encoding: [0x8d,0x89,0xfb,0x74] ++xvsrarn.w.d $xr13, $xr12, $xr2 ++ ++# CHECK: xvssrln.b.h $xr19, $xr19, $xr10 ++# CHECK: encoding: [0x73,0xaa,0xfc,0x74] ++xvssrln.b.h $xr19, $xr19, $xr10 ++ ++# CHECK: xvssrln.h.w $xr12, $xr24, $xr17 ++# CHECK: encoding: [0x0c,0x47,0xfd,0x74] ++xvssrln.h.w $xr12, $xr24, $xr17 ++ ++# CHECK: xvssrln.w.d $xr7, $xr30, $xr14 ++# CHECK: encoding: [0xc7,0xbb,0xfd,0x74] ++xvssrln.w.d $xr7, $xr30, $xr14 ++ ++# CHECK: xvssran.b.h $xr6, $xr9, $xr23 ++# CHECK: encoding: [0x26,0xdd,0xfe,0x74] ++xvssran.b.h $xr6, $xr9, $xr23 ++ ++# CHECK: xvssran.h.w $xr13, $xr9, $xr2 ++# CHECK: encoding: [0x2d,0x09,0xff,0x74] ++xvssran.h.w $xr13, $xr9, $xr2 ++ ++# CHECK: xvssran.w.d $xr18, $xr26, $xr1 ++# CHECK: encoding: [0x52,0x87,0xff,0x74] ++xvssran.w.d $xr18, $xr26, $xr1 ++ ++# CHECK: xvssrlrn.b.h $xr24, $xr17, $xr23 ++# CHECK: encoding: [0x38,0xde,0x00,0x75] ++xvssrlrn.b.h $xr24, $xr17, $xr23 ++ ++# CHECK: xvssrlrn.h.w $xr10, $xr12, $xr8 ++# CHECK: encoding: [0x8a,0x21,0x01,0x75] ++xvssrlrn.h.w $xr10, $xr12, $xr8 ++ ++# CHECK: xvssrlrn.w.d $xr30, $xr27, $xr6 ++# CHECK: encoding: [0x7e,0x9b,0x01,0x75] ++xvssrlrn.w.d $xr30, $xr27, $xr6 ++ ++# CHECK: xvssrarn.b.h $xr20, $xr27, $xr31 ++# CHECK: encoding: [0x74,0xff,0x02,0x75] ++xvssrarn.b.h $xr20, $xr27, $xr31 ++ ++# CHECK: xvssrarn.h.w $xr24, $xr23, $xr23 ++# CHECK: encoding: [0xf8,0x5e,0x03,0x75] ++xvssrarn.h.w $xr24, $xr23, $xr23 ++ ++# CHECK: xvssrarn.w.d $xr8, $xr29, $xr25 ++# CHECK: encoding: [0xa8,0xe7,0x03,0x75] ++xvssrarn.w.d $xr8, $xr29, $xr25 ++ ++# CHECK: xvssrln.bu.h $xr14, $xr4, $xr17 ++# CHECK: encoding: [0x8e,0xc4,0x04,0x75] ++xvssrln.bu.h $xr14, $xr4, $xr17 ++ ++# CHECK: xvssrln.hu.w $xr28, $xr20, $xr10 ++# CHECK: encoding: [0x9c,0x2a,0x05,0x75] ++xvssrln.hu.w $xr28, $xr20, $xr10 ++ ++# CHECK: xvssrln.wu.d $xr10, $xr8, $xr20 ++# CHECK: encoding: [0x0a,0xd1,0x05,0x75] ++xvssrln.wu.d $xr10, $xr8, $xr20 ++ ++# CHECK: xvssran.bu.h $xr18, $xr28, $xr23 ++# CHECK: encoding: [0x92,0xdf,0x06,0x75] ++xvssran.bu.h $xr18, $xr28, $xr23 ++ ++# CHECK: xvssran.hu.w $xr25, $xr19, $xr24 ++# CHECK: encoding: [0x79,0x62,0x07,0x75] ++xvssran.hu.w $xr25, $xr19, $xr24 ++ ++# CHECK: xvssran.wu.d $xr16, $xr29, $xr18 ++# CHECK: encoding: [0xb0,0xcb,0x07,0x75] ++xvssran.wu.d $xr16, $xr29, $xr18 ++ ++# CHECK: xvssrlrn.bu.h $xr2, $xr19, $xr14 ++# CHECK: encoding: [0x62,0xba,0x08,0x75] ++xvssrlrn.bu.h $xr2, $xr19, $xr14 ++ ++# CHECK: xvssrlrn.hu.w $xr6, $xr0, $xr18 ++# CHECK: encoding: [0x06,0x48,0x09,0x75] ++xvssrlrn.hu.w $xr6, $xr0, $xr18 ++ ++# CHECK: xvssrlrn.wu.d $xr30, $xr4, $xr31 ++# CHECK: encoding: [0x9e,0xfc,0x09,0x75] ++xvssrlrn.wu.d $xr30, $xr4, $xr31 ++ ++# CHECK: xvssrarn.bu.h $xr16, $xr28, $xr8 ++# CHECK: encoding: [0x90,0xa3,0x0a,0x75] ++xvssrarn.bu.h $xr16, $xr28, $xr8 ++ ++# CHECK: xvssrarn.hu.w $xr11, $xr2, $xr6 ++# CHECK: encoding: [0x4b,0x18,0x0b,0x75] ++xvssrarn.hu.w $xr11, $xr2, $xr6 ++ ++# CHECK: xvssrarn.wu.d $xr22, $xr6, $xr12 ++# CHECK: encoding: [0xd6,0xb0,0x0b,0x75] ++xvssrarn.wu.d $xr22, $xr6, $xr12 ++ ++# CHECK: xvbitclr.b $xr4, $xr16, $xr16 ++# CHECK: encoding: [0x04,0x42,0x0c,0x75] ++xvbitclr.b $xr4, $xr16, $xr16 ++ ++# CHECK: xvbitclr.h $xr16, $xr31, $xr26 ++# CHECK: encoding: [0xf0,0xeb,0x0c,0x75] ++xvbitclr.h $xr16, $xr31, $xr26 ++ ++# CHECK: xvbitclr.w $xr24, $xr2, $xr20 ++# CHECK: encoding: [0x58,0x50,0x0d,0x75] ++xvbitclr.w $xr24, $xr2, $xr20 ++ ++# CHECK: xvbitclr.d $xr18, $xr12, $xr30 ++# CHECK: encoding: [0x92,0xf9,0x0d,0x75] ++xvbitclr.d $xr18, $xr12, $xr30 ++ ++# CHECK: xvbitset.b $xr26, $xr27, $xr23 ++# CHECK: encoding: [0x7a,0x5f,0x0e,0x75] ++xvbitset.b $xr26, $xr27, $xr23 ++ ++# CHECK: xvbitset.h $xr19, $xr19, $xr11 ++# CHECK: encoding: [0x73,0xae,0x0e,0x75] ++xvbitset.h $xr19, $xr19, $xr11 ++ ++# CHECK: xvbitset.w $xr7, $xr9, $xr18 ++# CHECK: encoding: [0x27,0x49,0x0f,0x75] ++xvbitset.w $xr7, $xr9, $xr18 ++ ++# CHECK: xvbitset.d $xr6, $xr30, $xr3 ++# CHECK: encoding: [0xc6,0x8f,0x0f,0x75] ++xvbitset.d $xr6, $xr30, $xr3 ++ ++# CHECK: xvbitrev.b $xr30, $xr13, $xr7 ++# CHECK: encoding: [0xbe,0x1d,0x10,0x75] ++xvbitrev.b $xr30, $xr13, $xr7 ++ ++# CHECK: xvbitrev.h $xr12, $xr3, $xr8 ++# CHECK: encoding: [0x6c,0xa0,0x10,0x75] ++xvbitrev.h $xr12, $xr3, $xr8 ++ ++# CHECK: xvbitrev.w $xr8, $xr20, $xr20 ++# CHECK: encoding: [0x88,0x52,0x11,0x75] ++xvbitrev.w $xr8, $xr20, $xr20 ++ ++# CHECK: xvbitrev.d $xr28, $xr7, $xr17 ++# CHECK: encoding: [0xfc,0xc4,0x11,0x75] ++xvbitrev.d $xr28, $xr7, $xr17 ++ ++# CHECK: xvpackev.b $xr29, $xr18, $xr12 ++# CHECK: encoding: [0x5d,0x32,0x16,0x75] ++xvpackev.b $xr29, $xr18, $xr12 ++ ++# CHECK: xvpackev.h $xr6, $xr11, $xr17 ++# CHECK: encoding: [0x66,0xc5,0x16,0x75] ++xvpackev.h $xr6, $xr11, $xr17 ++ ++# CHECK: xvpackev.w $xr2, $xr2, $xr30 ++# CHECK: encoding: [0x42,0x78,0x17,0x75] ++xvpackev.w $xr2, $xr2, $xr30 ++ ++# CHECK: xvpackev.d $xr26, $xr15, $xr21 ++# CHECK: encoding: [0xfa,0xd5,0x17,0x75] ++xvpackev.d $xr26, $xr15, $xr21 ++ ++# CHECK: xvpackod.b $xr19, $xr17, $xr17 ++# CHECK: encoding: [0x33,0x46,0x18,0x75] ++xvpackod.b $xr19, $xr17, $xr17 ++ ++# CHECK: xvpackod.h $xr15, $xr8, $xr3 ++# CHECK: encoding: [0x0f,0x8d,0x18,0x75] ++xvpackod.h $xr15, $xr8, $xr3 ++ ++# CHECK: xvpackod.w $xr13, $xr15, $xr12 ++# CHECK: encoding: [0xed,0x31,0x19,0x75] ++xvpackod.w $xr13, $xr15, $xr12 ++ ++# CHECK: xvpackod.d $xr5, $xr3, $xr26 ++# CHECK: encoding: [0x65,0xe8,0x19,0x75] ++xvpackod.d $xr5, $xr3, $xr26 ++ ++# CHECK: xvilvl.b $xr27, $xr9, $xr1 ++# CHECK: encoding: [0x3b,0x05,0x1a,0x75] ++xvilvl.b $xr27, $xr9, $xr1 ++ ++# CHECK: xvilvl.h $xr29, $xr8, $xr1 ++# CHECK: encoding: [0x1d,0x85,0x1a,0x75] ++xvilvl.h $xr29, $xr8, $xr1 ++ ++# CHECK: xvilvl.w $xr9, $xr8, $xr7 ++# CHECK: encoding: [0x09,0x1d,0x1b,0x75] ++xvilvl.w $xr9, $xr8, $xr7 ++ ++# CHECK: xvilvl.d $xr25, $xr7, $xr18 ++# CHECK: encoding: [0xf9,0xc8,0x1b,0x75] ++xvilvl.d $xr25, $xr7, $xr18 ++ ++# CHECK: xvilvh.b $xr7, $xr24, $xr26 ++# CHECK: encoding: [0x07,0x6b,0x1c,0x75] ++xvilvh.b $xr7, $xr24, $xr26 ++ ++# CHECK: xvilvh.h $xr6, $xr20, $xr28 ++# CHECK: encoding: [0x86,0xf2,0x1c,0x75] ++xvilvh.h $xr6, $xr20, $xr28 ++ ++# CHECK: xvilvh.w $xr13, $xr5, $xr12 ++# CHECK: encoding: [0xad,0x30,0x1d,0x75] ++xvilvh.w $xr13, $xr5, $xr12 ++ ++# CHECK: xvilvh.d $xr1, $xr21, $xr31 ++# CHECK: encoding: [0xa1,0xfe,0x1d,0x75] ++xvilvh.d $xr1, $xr21, $xr31 ++ ++# CHECK: xvpickev.b $xr17, $xr13, $xr31 ++# CHECK: encoding: [0xb1,0x7d,0x1e,0x75] ++xvpickev.b $xr17, $xr13, $xr31 ++ ++# CHECK: xvpickev.h $xr4, $xr8, $xr14 ++# CHECK: encoding: [0x04,0xb9,0x1e,0x75] ++xvpickev.h $xr4, $xr8, $xr14 ++ ++# CHECK: xvpickev.w $xr10, $xr8, $xr11 ++# CHECK: encoding: [0x0a,0x2d,0x1f,0x75] ++xvpickev.w $xr10, $xr8, $xr11 ++ ++# CHECK: xvpickev.d $xr26, $xr20, $xr8 ++# CHECK: encoding: [0x9a,0xa2,0x1f,0x75] ++xvpickev.d $xr26, $xr20, $xr8 ++ ++# CHECK: xvpickod.b $xr19, $xr21, $xr27 ++# CHECK: encoding: [0xb3,0x6e,0x20,0x75] ++xvpickod.b $xr19, $xr21, $xr27 ++ ++# CHECK: xvpickod.h $xr28, $xr5, $xr19 ++# CHECK: encoding: [0xbc,0xcc,0x20,0x75] ++xvpickod.h $xr28, $xr5, $xr19 ++ ++# CHECK: xvpickod.w $xr21, $xr18, $xr22 ++# CHECK: encoding: [0x55,0x5a,0x21,0x75] ++xvpickod.w $xr21, $xr18, $xr22 ++ ++# CHECK: xvpickod.d $xr28, $xr7, $xr18 ++# CHECK: encoding: [0xfc,0xc8,0x21,0x75] ++xvpickod.d $xr28, $xr7, $xr18 ++ ++# CHECK: xvreplve.b $xr6, $xr20, $r25 ++# CHECK: encoding: [0x86,0x66,0x22,0x75] ++xvreplve.b $xr6, $xr20, $r25 ++ ++# CHECK: xvreplve.h $xr27, $xr7, $r14 ++# CHECK: encoding: [0xfb,0xb8,0x22,0x75] ++xvreplve.h $xr27, $xr7, $r14 ++ ++# CHECK: xvreplve.w $xr1, $xr4, $r15 ++# CHECK: encoding: [0x81,0x3c,0x23,0x75] ++xvreplve.w $xr1, $xr4, $r15 ++ ++# CHECK: xvreplve.d $xr12, $xr12, $r16 ++# CHECK: encoding: [0x8c,0xc1,0x23,0x75] ++xvreplve.d $xr12, $xr12, $r16 ++ ++# CHECK: xvand.v $xr1, $xr3, $xr29 ++# CHECK: encoding: [0x61,0x74,0x26,0x75] ++xvand.v $xr1, $xr3, $xr29 ++ ++# CHECK: xvor.v $xr23, $xr11, $xr20 ++# CHECK: encoding: [0x77,0xd1,0x26,0x75] ++xvor.v $xr23, $xr11, $xr20 ++ ++# CHECK: xvxor.v $xr31, $xr1, $xr30 ++# CHECK: encoding: [0x3f,0x78,0x27,0x75] ++xvxor.v $xr31, $xr1, $xr30 ++ ++# CHECK: xvnor.v $xr29, $xr26, $xr13 ++# CHECK: encoding: [0x5d,0xb7,0x27,0x75] ++xvnor.v $xr29, $xr26, $xr13 ++ ++# CHECK: xvandn.v $xr9, $xr14, $xr0 ++# CHECK: encoding: [0xc9,0x01,0x28,0x75] ++xvandn.v $xr9, $xr14, $xr0 ++ ++# CHECK: xvorn.v $xr25, $xr8, $xr12 ++# CHECK: encoding: [0x19,0xb1,0x28,0x75] ++xvorn.v $xr25, $xr8, $xr12 ++ ++# CHECK: xvfrstp.b $xr21, $xr26, $xr26 ++# CHECK: encoding: [0x55,0x6b,0x2b,0x75] ++xvfrstp.b $xr21, $xr26, $xr26 ++ ++# CHECK: xvfrstp.h $xr4, $xr17, $xr2 ++# CHECK: encoding: [0x24,0x8a,0x2b,0x75] ++xvfrstp.h $xr4, $xr17, $xr2 ++ ++# CHECK: xvadd.q $xr29, $xr28, $xr17 ++# CHECK: encoding: [0x9d,0x47,0x2d,0x75] ++xvadd.q $xr29, $xr28, $xr17 ++ ++# CHECK: xvsub.q $xr29, $xr2, $xr27 ++# CHECK: encoding: [0x5d,0xec,0x2d,0x75] ++xvsub.q $xr29, $xr2, $xr27 ++ ++# CHECK: xvsigncov.b $xr18, $xr28, $xr7 ++# CHECK: encoding: [0x92,0x1f,0x2e,0x75] ++xvsigncov.b $xr18, $xr28, $xr7 ++ ++# CHECK: xvsigncov.h $xr18, $xr12, $xr17 ++# CHECK: encoding: [0x92,0xc5,0x2e,0x75] ++xvsigncov.h $xr18, $xr12, $xr17 ++ ++# CHECK: xvsigncov.w $xr26, $xr1, $xr0 ++# CHECK: encoding: [0x3a,0x00,0x2f,0x75] ++xvsigncov.w $xr26, $xr1, $xr0 ++ ++# CHECK: xvsigncov.d $xr10, $xr27, $xr14 ++# CHECK: encoding: [0x6a,0xbb,0x2f,0x75] ++xvsigncov.d $xr10, $xr27, $xr14 ++ ++# CHECK: xvfadd.s $xr15, $xr25, $xr8 ++# CHECK: encoding: [0x2f,0xa3,0x30,0x75] ++xvfadd.s $xr15, $xr25, $xr8 ++ ++# CHECK: xvfadd.d $xr19, $xr6, $xr21 ++# CHECK: encoding: [0xd3,0x54,0x31,0x75] ++xvfadd.d $xr19, $xr6, $xr21 ++ ++# CHECK: xvfsub.s $xr26, $xr6, $xr6 ++# CHECK: encoding: [0xda,0x98,0x32,0x75] ++xvfsub.s $xr26, $xr6, $xr6 ++ ++# CHECK: xvfsub.d $xr9, $xr0, $xr21 ++# CHECK: encoding: [0x09,0x54,0x33,0x75] ++xvfsub.d $xr9, $xr0, $xr21 ++ ++# CHECK: xvfmul.s $xr6, $xr8, $xr14 ++# CHECK: encoding: [0x06,0xb9,0x38,0x75] ++xvfmul.s $xr6, $xr8, $xr14 ++ ++# CHECK: xvfmul.d $xr11, $xr21, $xr26 ++# CHECK: encoding: [0xab,0x6a,0x39,0x75] ++xvfmul.d $xr11, $xr21, $xr26 ++ ++# CHECK: xvfdiv.s $xr11, $xr7, $xr6 ++# CHECK: encoding: [0xeb,0x98,0x3a,0x75] ++xvfdiv.s $xr11, $xr7, $xr6 ++ ++# CHECK: xvfdiv.d $xr0, $xr26, $xr4 ++# CHECK: encoding: [0x40,0x13,0x3b,0x75] ++xvfdiv.d $xr0, $xr26, $xr4 ++ ++# CHECK: xvfmax.s $xr7, $xr9, $xr4 ++# CHECK: encoding: [0x27,0x91,0x3c,0x75] ++xvfmax.s $xr7, $xr9, $xr4 ++ ++# CHECK: xvfmax.d $xr0, $xr26, $xr20 ++# CHECK: encoding: [0x40,0x53,0x3d,0x75] ++xvfmax.d $xr0, $xr26, $xr20 ++ ++# CHECK: xvfmin.s $xr8, $xr10, $xr26 ++# CHECK: encoding: [0x48,0xe9,0x3e,0x75] ++xvfmin.s $xr8, $xr10, $xr26 ++ ++# CHECK: xvfmin.d $xr2, $xr22, $xr25 ++# CHECK: encoding: [0xc2,0x66,0x3f,0x75] ++xvfmin.d $xr2, $xr22, $xr25 ++ ++# CHECK: xvfmaxa.s $xr17, $xr4, $xr1 ++# CHECK: encoding: [0x91,0x84,0x40,0x75] ++xvfmaxa.s $xr17, $xr4, $xr1 ++ ++# CHECK: xvfmaxa.d $xr27, $xr23, $xr9 ++# CHECK: encoding: [0xfb,0x26,0x41,0x75] ++xvfmaxa.d $xr27, $xr23, $xr9 ++ ++# CHECK: xvfmina.s $xr21, $xr3, $xr27 ++# CHECK: encoding: [0x75,0xec,0x42,0x75] ++xvfmina.s $xr21, $xr3, $xr27 ++ ++# CHECK: xvfmina.d $xr7, $xr6, $xr4 ++# CHECK: encoding: [0xc7,0x10,0x43,0x75] ++xvfmina.d $xr7, $xr6, $xr4 ++ ++# CHECK: xvfcvt.h.s $xr9, $xr10, $xr20 ++# CHECK: encoding: [0x49,0x51,0x46,0x75] ++xvfcvt.h.s $xr9, $xr10, $xr20 ++ ++# CHECK: xvfcvt.s.d $xr5, $xr23, $xr21 ++# CHECK: encoding: [0xe5,0xd6,0x46,0x75] ++xvfcvt.s.d $xr5, $xr23, $xr21 ++ ++# CHECK: xvffint.s.l $xr28, $xr24, $xr10 ++# CHECK: encoding: [0x1c,0x2b,0x48,0x75] ++xvffint.s.l $xr28, $xr24, $xr10 ++ ++# CHECK: xvftint.w.d $xr6, $xr24, $xr1 ++# CHECK: encoding: [0x06,0x87,0x49,0x75] ++xvftint.w.d $xr6, $xr24, $xr1 ++ ++# CHECK: xvftintrm.w.d $xr27, $xr26, $xr30 ++# CHECK: encoding: [0x5b,0x7b,0x4a,0x75] ++xvftintrm.w.d $xr27, $xr26, $xr30 ++ ++# CHECK: xvftintrp.w.d $xr31, $xr12, $xr1 ++# CHECK: encoding: [0x9f,0x85,0x4a,0x75] ++xvftintrp.w.d $xr31, $xr12, $xr1 ++ ++# CHECK: xvftintrz.w.d $xr11, $xr21, $xr21 ++# CHECK: encoding: [0xab,0x56,0x4b,0x75] ++xvftintrz.w.d $xr11, $xr21, $xr21 ++ ++# CHECK: xvftintrne.w.d $xr15, $xr8, $xr28 ++# CHECK: encoding: [0x0f,0xf1,0x4b,0x75] ++xvftintrne.w.d $xr15, $xr8, $xr28 ++ ++# CHECK: xvshuf.h $xr20, $xr21, $xr3 ++# CHECK: encoding: [0xb4,0x8e,0x7a,0x75] ++xvshuf.h $xr20, $xr21, $xr3 ++ ++# CHECK: xvshuf.w $xr22, $xr2, $xr31 ++# CHECK: encoding: [0x56,0x7c,0x7b,0x75] ++xvshuf.w $xr22, $xr2, $xr31 ++ ++# CHECK: xvshuf.d $xr15, $xr3, $xr26 ++# CHECK: encoding: [0x6f,0xe8,0x7b,0x75] ++xvshuf.d $xr15, $xr3, $xr26 ++ ++# CHECK: xvperm.w $xr21, $xr23, $xr24 ++# CHECK: encoding: [0xf5,0x62,0x7d,0x75] ++xvperm.w $xr21, $xr23, $xr24 ++ ++# CHECK: xvseqi.b $xr28, $xr5, 1 ++# CHECK: encoding: [0xbc,0x04,0x80,0x76] ++xvseqi.b $xr28, $xr5, 1 ++ ++# CHECK: xvseqi.h $xr19, $xr9, -5 ++# CHECK: encoding: [0x33,0xed,0x80,0x76] ++xvseqi.h $xr19, $xr9, -5 ++ ++# CHECK: xvseqi.w $xr8, $xr18, -2 ++# CHECK: encoding: [0x48,0x7a,0x81,0x76] ++xvseqi.w $xr8, $xr18, -2 ++ ++# CHECK: xvseqi.d $xr2, $xr22, -4 ++# CHECK: encoding: [0xc2,0xf2,0x81,0x76] ++xvseqi.d $xr2, $xr22, -4 ++ ++# CHECK: xvslei.b $xr4, $xr21, -10 ++# CHECK: encoding: [0xa4,0x5a,0x82,0x76] ++xvslei.b $xr4, $xr21, -10 ++ ++# CHECK: xvslei.h $xr17, $xr20, -12 ++# CHECK: encoding: [0x91,0xd2,0x82,0x76] ++xvslei.h $xr17, $xr20, -12 ++ ++# CHECK: xvslei.w $xr9, $xr20, -7 ++# CHECK: encoding: [0x89,0x66,0x83,0x76] ++xvslei.w $xr9, $xr20, -7 ++ ++# CHECK: xvslei.d $xr19, $xr30, 10 ++# CHECK: encoding: [0xd3,0xab,0x83,0x76] ++xvslei.d $xr19, $xr30, 10 ++ ++# CHECK: xvslei.bu $xr4, $xr26, 1 ++# CHECK: encoding: [0x44,0x07,0x84,0x76] ++xvslei.bu $xr4, $xr26, 1 ++ ++# CHECK: xvslei.hu $xr11, $xr8, 4 ++# CHECK: encoding: [0x0b,0x91,0x84,0x76] ++xvslei.hu $xr11, $xr8, 4 ++ ++# CHECK: xvslei.wu $xr18, $xr12, 31 ++# CHECK: encoding: [0x92,0x7d,0x85,0x76] ++xvslei.wu $xr18, $xr12, 31 ++ ++# CHECK: xvslei.du $xr30, $xr7, 26 ++# CHECK: encoding: [0xfe,0xe8,0x85,0x76] ++xvslei.du $xr30, $xr7, 26 ++ ++# CHECK: xvslti.b $xr11, $xr29, 2 ++# CHECK: encoding: [0xab,0x0b,0x86,0x76] ++xvslti.b $xr11, $xr29, 2 ++ ++# CHECK: xvslti.h $xr6, $xr27, 8 ++# CHECK: encoding: [0x66,0xa3,0x86,0x76] ++xvslti.h $xr6, $xr27, 8 ++ ++# CHECK: xvslti.w $xr21, $xr23, 1 ++# CHECK: encoding: [0xf5,0x06,0x87,0x76] ++xvslti.w $xr21, $xr23, 1 ++ ++# CHECK: xvslti.d $xr18, $xr31, -5 ++# CHECK: encoding: [0xf2,0xef,0x87,0x76] ++xvslti.d $xr18, $xr31, -5 ++ ++# CHECK: xvslti.bu $xr27, $xr12, 17 ++# CHECK: encoding: [0x9b,0x45,0x88,0x76] ++xvslti.bu $xr27, $xr12, 17 ++ ++# CHECK: xvslti.hu $xr18, $xr14, 12 ++# CHECK: encoding: [0xd2,0xb1,0x88,0x76] ++xvslti.hu $xr18, $xr14, 12 ++ ++# CHECK: xvslti.wu $xr4, $xr12, 14 ++# CHECK: encoding: [0x84,0x39,0x89,0x76] ++xvslti.wu $xr4, $xr12, 14 ++ ++# CHECK: xvslti.du $xr26, $xr0, 24 ++# CHECK: encoding: [0x1a,0xe0,0x89,0x76] ++xvslti.du $xr26, $xr0, 24 ++ ++# CHECK: xvaddi.bu $xr30, $xr2, 5 ++# CHECK: encoding: [0x5e,0x14,0x8a,0x76] ++xvaddi.bu $xr30, $xr2, 5 ++ ++# CHECK: xvaddi.hu $xr22, $xr17, 9 ++# CHECK: encoding: [0x36,0xa6,0x8a,0x76] ++xvaddi.hu $xr22, $xr17, 9 ++ ++# CHECK: xvaddi.wu $xr3, $xr26, 29 ++# CHECK: encoding: [0x43,0x77,0x8b,0x76] ++xvaddi.wu $xr3, $xr26, 29 ++ ++# CHECK: xvaddi.du $xr0, $xr20, 30 ++# CHECK: encoding: [0x80,0xfa,0x8b,0x76] ++xvaddi.du $xr0, $xr20, 30 ++ ++# CHECK: xvsubi.bu $xr0, $xr20, 7 ++# CHECK: encoding: [0x80,0x1e,0x8c,0x76] ++xvsubi.bu $xr0, $xr20, 7 ++ ++# CHECK: xvsubi.hu $xr4, $xr24, 18 ++# CHECK: encoding: [0x04,0xcb,0x8c,0x76] ++xvsubi.hu $xr4, $xr24, 18 ++ ++# CHECK: xvsubi.wu $xr1, $xr26, 26 ++# CHECK: encoding: [0x41,0x6b,0x8d,0x76] ++xvsubi.wu $xr1, $xr26, 26 ++ ++# CHECK: xvsubi.du $xr9, $xr28, 8 ++# CHECK: encoding: [0x89,0xa3,0x8d,0x76] ++xvsubi.du $xr9, $xr28, 8 ++ ++# CHECK: xvbsll.v $xr0, $xr21, 8 ++# CHECK: encoding: [0xa0,0x22,0x8e,0x76] ++xvbsll.v $xr0, $xr21, 8 ++ ++# CHECK: xvbsrl.v $xr4, $xr8, 28 ++# CHECK: encoding: [0x04,0xf1,0x8e,0x76] ++xvbsrl.v $xr4, $xr8, 28 ++ ++# CHECK: xvmaxi.b $xr8, $xr1, -14 ++# CHECK: encoding: [0x28,0x48,0x90,0x76] ++xvmaxi.b $xr8, $xr1, -14 ++ ++# CHECK: xvmaxi.h $xr19, $xr12, -16 ++# CHECK: encoding: [0x93,0xc1,0x90,0x76] ++xvmaxi.h $xr19, $xr12, -16 ++ ++# CHECK: xvmaxi.w $xr27, $xr1, 5 ++# CHECK: encoding: [0x3b,0x14,0x91,0x76] ++xvmaxi.w $xr27, $xr1, 5 ++ ++# CHECK: xvmaxi.d $xr6, $xr7, 3 ++# CHECK: encoding: [0xe6,0x8c,0x91,0x76] ++xvmaxi.d $xr6, $xr7, 3 ++ ++# CHECK: xvmini.b $xr10, $xr6, 5 ++# CHECK: encoding: [0xca,0x14,0x92,0x76] ++xvmini.b $xr10, $xr6, 5 ++ ++# CHECK: xvmini.h $xr8, $xr18, -12 ++# CHECK: encoding: [0x48,0xd2,0x92,0x76] ++xvmini.h $xr8, $xr18, -12 ++ ++# CHECK: xvmini.w $xr31, $xr13, -7 ++# CHECK: encoding: [0xbf,0x65,0x93,0x76] ++xvmini.w $xr31, $xr13, -7 ++ ++# CHECK: xvmini.d $xr15, $xr27, 9 ++# CHECK: encoding: [0x6f,0xa7,0x93,0x76] ++xvmini.d $xr15, $xr27, 9 ++ ++# CHECK: xvmaxi.bu $xr5, $xr17, 22 ++# CHECK: encoding: [0x25,0x5a,0x94,0x76] ++xvmaxi.bu $xr5, $xr17, 22 ++ ++# CHECK: xvmaxi.hu $xr6, $xr3, 4 ++# CHECK: encoding: [0x66,0x90,0x94,0x76] ++xvmaxi.hu $xr6, $xr3, 4 ++ ++# CHECK: xvmaxi.wu $xr26, $xr12, 17 ++# CHECK: encoding: [0x9a,0x45,0x95,0x76] ++xvmaxi.wu $xr26, $xr12, 17 ++ ++# CHECK: xvmaxi.du $xr30, $xr11, 30 ++# CHECK: encoding: [0x7e,0xf9,0x95,0x76] ++xvmaxi.du $xr30, $xr11, 30 ++ ++# CHECK: xvmini.bu $xr15, $xr8, 7 ++# CHECK: encoding: [0x0f,0x1d,0x96,0x76] ++xvmini.bu $xr15, $xr8, 7 ++ ++# CHECK: xvmini.hu $xr18, $xr25, 1 ++# CHECK: encoding: [0x32,0x87,0x96,0x76] ++xvmini.hu $xr18, $xr25, 1 ++ ++# CHECK: xvmini.wu $xr16, $xr28, 0 ++# CHECK: encoding: [0x90,0x03,0x97,0x76] ++xvmini.wu $xr16, $xr28, 0 ++ ++# CHECK: xvmini.du $xr10, $xr19, 29 ++# CHECK: encoding: [0x6a,0xf6,0x97,0x76] ++xvmini.du $xr10, $xr19, 29 ++ ++# CHECK: xvfrstpi.b $xr8, $xr25, 2 ++# CHECK: encoding: [0x28,0x0b,0x9a,0x76] ++xvfrstpi.b $xr8, $xr25, 2 ++ ++# CHECK: xvfrstpi.h $xr28, $xr19, 26 ++# CHECK: encoding: [0x7c,0xea,0x9a,0x76] ++xvfrstpi.h $xr28, $xr19, 26 ++ ++# CHECK: xvclo.b $xr2, $xr8 ++# CHECK: encoding: [0x02,0x01,0x9c,0x76] ++xvclo.b $xr2, $xr8 ++ ++# CHECK: xvclo.h $xr10, $xr9 ++# CHECK: encoding: [0x2a,0x05,0x9c,0x76] ++xvclo.h $xr10, $xr9 ++ ++# CHECK: xvclo.w $xr2, $xr31 ++# CHECK: encoding: [0xe2,0x0b,0x9c,0x76] ++xvclo.w $xr2, $xr31 ++ ++# CHECK: xvclo.d $xr21, $xr24 ++# CHECK: encoding: [0x15,0x0f,0x9c,0x76] ++xvclo.d $xr21, $xr24 ++ ++# CHECK: xvclz.b $xr13, $xr24 ++# CHECK: encoding: [0x0d,0x13,0x9c,0x76] ++xvclz.b $xr13, $xr24 ++ ++# CHECK: xvclz.h $xr4, $xr31 ++# CHECK: encoding: [0xe4,0x17,0x9c,0x76] ++xvclz.h $xr4, $xr31 ++ ++# CHECK: xvclz.w $xr7, $xr1 ++# CHECK: encoding: [0x27,0x18,0x9c,0x76] ++xvclz.w $xr7, $xr1 ++ ++# CHECK: xvclz.d $xr13, $xr22 ++# CHECK: encoding: [0xcd,0x1e,0x9c,0x76] ++xvclz.d $xr13, $xr22 ++ ++# CHECK: xvpcnt.b $xr9, $xr26 ++# CHECK: encoding: [0x49,0x23,0x9c,0x76] ++xvpcnt.b $xr9, $xr26 ++ ++# CHECK: xvpcnt.h $xr10, $xr3 ++# CHECK: encoding: [0x6a,0x24,0x9c,0x76] ++xvpcnt.h $xr10, $xr3 ++ ++# CHECK: xvpcnt.w $xr24, $xr7 ++# CHECK: encoding: [0xf8,0x28,0x9c,0x76] ++xvpcnt.w $xr24, $xr7 ++ ++# CHECK: xvpcnt.d $xr5, $xr8 ++# CHECK: encoding: [0x05,0x2d,0x9c,0x76] ++xvpcnt.d $xr5, $xr8 ++ ++# CHECK: xvneg.b $xr19, $xr11 ++# CHECK: encoding: [0x73,0x31,0x9c,0x76] ++xvneg.b $xr19, $xr11 ++ ++# CHECK: xvneg.h $xr21, $xr21 ++# CHECK: encoding: [0xb5,0x36,0x9c,0x76] ++xvneg.h $xr21, $xr21 ++ ++# CHECK: xvneg.w $xr19, $xr17 ++# CHECK: encoding: [0x33,0x3a,0x9c,0x76] ++xvneg.w $xr19, $xr17 ++ ++# CHECK: xvneg.d $xr31, $xr29 ++# CHECK: encoding: [0xbf,0x3f,0x9c,0x76] ++xvneg.d $xr31, $xr29 ++ ++# CHECK: xvmskltz.b $xr22, $xr27 ++# CHECK: encoding: [0x76,0x43,0x9c,0x76] ++xvmskltz.b $xr22, $xr27 ++ ++# CHECK: xvmskltz.h $xr5, $xr0 ++# CHECK: encoding: [0x05,0x44,0x9c,0x76] ++xvmskltz.h $xr5, $xr0 ++ ++# CHECK: xvmskltz.w $xr24, $xr28 ++# CHECK: encoding: [0x98,0x4b,0x9c,0x76] ++xvmskltz.w $xr24, $xr28 ++ ++# CHECK: xvmskltz.d $xr25, $xr2 ++# CHECK: encoding: [0x59,0x4c,0x9c,0x76] ++xvmskltz.d $xr25, $xr2 ++ ++# CHECK: xvmskgez.b $xr30, $xr30 ++# CHECK: encoding: [0xde,0x53,0x9c,0x76] ++xvmskgez.b $xr30, $xr30 ++ ++# CHECK: xvmsknz.b $xr5, $xr20 ++# CHECK: encoding: [0x85,0x62,0x9c,0x76] ++xvmsknz.b $xr5, $xr20 ++ ++# CHECK: xvseteqz.v $fcc1, $xr25 ++# CHECK: encoding: [0x21,0x9b,0x9c,0x76] ++xvseteqz.v $fcc1, $xr25 ++ ++# CHECK: xvsetnez.v $fcc5, $xr13 ++# CHECK: encoding: [0xa5,0x9d,0x9c,0x76] ++xvsetnez.v $fcc5, $xr13 ++ ++# CHECK: xvsetanyeqz.b $fcc0, $xr4 ++# CHECK: encoding: [0x80,0xa0,0x9c,0x76] ++xvsetanyeqz.b $fcc0, $xr4 ++ ++# CHECK: xvsetanyeqz.h $fcc0, $xr31 ++# CHECK: encoding: [0xe0,0xa7,0x9c,0x76] ++xvsetanyeqz.h $fcc0, $xr31 ++ ++# CHECK: xvsetanyeqz.w $fcc2, $xr30 ++# CHECK: encoding: [0xc2,0xab,0x9c,0x76] ++xvsetanyeqz.w $fcc2, $xr30 ++ ++# CHECK: xvsetanyeqz.d $fcc3, $xr31 ++# CHECK: encoding: [0xe3,0xaf,0x9c,0x76] ++xvsetanyeqz.d $fcc3, $xr31 ++ ++# CHECK: xvsetallnez.b $fcc1, $xr21 ++# CHECK: encoding: [0xa1,0xb2,0x9c,0x76] ++xvsetallnez.b $fcc1, $xr21 ++ ++# CHECK: xvsetallnez.h $fcc0, $xr21 ++# CHECK: encoding: [0xa0,0xb6,0x9c,0x76] ++xvsetallnez.h $fcc0, $xr21 ++ ++# CHECK: xvsetallnez.w $fcc0, $xr0 ++# CHECK: encoding: [0x00,0xb8,0x9c,0x76] ++xvsetallnez.w $fcc0, $xr0 ++ ++# CHECK: xvsetallnez.d $fcc1, $xr31 ++# CHECK: encoding: [0xe1,0xbf,0x9c,0x76] ++xvsetallnez.d $fcc1, $xr31 ++ ++# CHECK: xvflogb.s $xr21, $xr4 ++# CHECK: encoding: [0x95,0xc4,0x9c,0x76] ++xvflogb.s $xr21, $xr4 ++ ++# CHECK: xvflogb.d $xr8, $xr20 ++# CHECK: encoding: [0x88,0xca,0x9c,0x76] ++xvflogb.d $xr8, $xr20 ++ ++# CHECK: xvfclass.s $xr15, $xr29 ++# CHECK: encoding: [0xaf,0xd7,0x9c,0x76] ++xvfclass.s $xr15, $xr29 ++ ++# CHECK: xvfclass.d $xr7, $xr14 ++# CHECK: encoding: [0xc7,0xd9,0x9c,0x76] ++xvfclass.d $xr7, $xr14 ++ ++# CHECK: xvfsqrt.s $xr28, $xr19 ++# CHECK: encoding: [0x7c,0xe6,0x9c,0x76] ++xvfsqrt.s $xr28, $xr19 ++ ++# CHECK: xvfsqrt.d $xr11, $xr31 ++# CHECK: encoding: [0xeb,0xeb,0x9c,0x76] ++xvfsqrt.d $xr11, $xr31 ++ ++# CHECK: xvfrecip.s $xr6, $xr23 ++# CHECK: encoding: [0xe6,0xf6,0x9c,0x76] ++xvfrecip.s $xr6, $xr23 ++ ++# CHECK: xvfrecip.d $xr0, $xr24 ++# CHECK: encoding: [0x00,0xfb,0x9c,0x76] ++xvfrecip.d $xr0, $xr24 ++ ++# CHECK: xvfrecipe.s $xr3, $xr16 ++# CHECK: encoding: [0x03,0x16,0x9d,0x76] ++xvfrecipe.s $xr3, $xr16 ++ ++# CHECK: xvfrecipe.d $xr17, $xr24 ++# CHECK: encoding: [0x11,0x1b,0x9d,0x76] ++xvfrecipe.d $xr17, $xr24 ++ ++# CHECK: xvfrsqrt.s $xr8, $xr16 ++# CHECK: encoding: [0x08,0x06,0x9d,0x76] ++xvfrsqrt.s $xr8, $xr16 ++ ++# CHECK: xvfrsqrt.d $xr15, $xr17 ++# CHECK: encoding: [0x2f,0x0a,0x9d,0x76] ++xvfrsqrt.d $xr15, $xr17 ++ ++# CHECK: xvfrsqrte.s $xr31, $xr25 ++# CHECK: encoding: [0x3f,0x27,0x9d,0x76] ++xvfrsqrte.s $xr31, $xr25 ++ ++# CHECK: xvfrsqrte.d $xr14, $xr22 ++# CHECK: encoding: [0xce,0x2a,0x9d,0x76] ++xvfrsqrte.d $xr14, $xr22 ++ ++# CHECK: xvfrint.s $xr4, $xr25 ++# CHECK: encoding: [0x24,0x37,0x9d,0x76] ++xvfrint.s $xr4, $xr25 ++ ++# CHECK: xvfrint.d $xr1, $xr20 ++# CHECK: encoding: [0x81,0x3a,0x9d,0x76] ++xvfrint.d $xr1, $xr20 ++ ++# CHECK: xvfrintrm.s $xr29, $xr16 ++# CHECK: encoding: [0x1d,0x46,0x9d,0x76] ++xvfrintrm.s $xr29, $xr16 ++ ++# CHECK: xvfrintrm.d $xr4, $xr10 ++# CHECK: encoding: [0x44,0x49,0x9d,0x76] ++xvfrintrm.d $xr4, $xr10 ++ ++# CHECK: xvfrintrp.s $xr13, $xr31 ++# CHECK: encoding: [0xed,0x57,0x9d,0x76] ++xvfrintrp.s $xr13, $xr31 ++ ++# CHECK: xvfrintrp.d $xr20, $xr11 ++# CHECK: encoding: [0x74,0x59,0x9d,0x76] ++xvfrintrp.d $xr20, $xr11 ++ ++# CHECK: xvfrintrz.s $xr27, $xr13 ++# CHECK: encoding: [0xbb,0x65,0x9d,0x76] ++xvfrintrz.s $xr27, $xr13 ++ ++# CHECK: xvfrintrz.d $xr17, $xr25 ++# CHECK: encoding: [0x31,0x6b,0x9d,0x76] ++xvfrintrz.d $xr17, $xr25 ++ ++# CHECK: xvfrintrne.s $xr14, $xr8 ++# CHECK: encoding: [0x0e,0x75,0x9d,0x76] ++xvfrintrne.s $xr14, $xr8 ++ ++# CHECK: xvfrintrne.d $xr23, $xr26 ++# CHECK: encoding: [0x57,0x7b,0x9d,0x76] ++xvfrintrne.d $xr23, $xr26 ++ ++# CHECK: xvfcvtl.s.h $xr4, $xr23 ++# CHECK: encoding: [0xe4,0xea,0x9d,0x76] ++xvfcvtl.s.h $xr4, $xr23 ++ ++# CHECK: xvfcvth.s.h $xr14, $xr11 ++# CHECK: encoding: [0x6e,0xed,0x9d,0x76] ++xvfcvth.s.h $xr14, $xr11 ++ ++# CHECK: xvfcvtl.d.s $xr26, $xr31 ++# CHECK: encoding: [0xfa,0xf3,0x9d,0x76] ++xvfcvtl.d.s $xr26, $xr31 ++ ++# CHECK: xvfcvth.d.s $xr13, $xr28 ++# CHECK: encoding: [0x8d,0xf7,0x9d,0x76] ++xvfcvth.d.s $xr13, $xr28 ++ ++# CHECK: xvffint.s.w $xr14, $xr28 ++# CHECK: encoding: [0x8e,0x03,0x9e,0x76] ++xvffint.s.w $xr14, $xr28 ++ ++# CHECK: xvffint.s.wu $xr0, $xr8 ++# CHECK: encoding: [0x00,0x05,0x9e,0x76] ++xvffint.s.wu $xr0, $xr8 ++ ++# CHECK: xvffint.d.l $xr5, $xr27 ++# CHECK: encoding: [0x65,0x0b,0x9e,0x76] ++xvffint.d.l $xr5, $xr27 ++ ++# CHECK: xvffint.d.lu $xr29, $xr18 ++# CHECK: encoding: [0x5d,0x0e,0x9e,0x76] ++xvffint.d.lu $xr29, $xr18 ++ ++# CHECK: xvffintl.d.w $xr9, $xr20 ++# CHECK: encoding: [0x89,0x12,0x9e,0x76] ++xvffintl.d.w $xr9, $xr20 ++ ++# CHECK: xvffinth.d.w $xr11, $xr13 ++# CHECK: encoding: [0xab,0x15,0x9e,0x76] ++xvffinth.d.w $xr11, $xr13 ++ ++# CHECK: xvftint.w.s $xr6, $xr4 ++# CHECK: encoding: [0x86,0x30,0x9e,0x76] ++xvftint.w.s $xr6, $xr4 ++ ++# CHECK: xvftint.l.d $xr11, $xr22 ++# CHECK: encoding: [0xcb,0x36,0x9e,0x76] ++xvftint.l.d $xr11, $xr22 ++ ++# CHECK: xvftintrm.w.s $xr20, $xr21 ++# CHECK: encoding: [0xb4,0x3a,0x9e,0x76] ++xvftintrm.w.s $xr20, $xr21 ++ ++# CHECK: xvftintrm.l.d $xr28, $xr27 ++# CHECK: encoding: [0x7c,0x3f,0x9e,0x76] ++xvftintrm.l.d $xr28, $xr27 ++ ++# CHECK: xvftintrp.w.s $xr14, $xr16 ++# CHECK: encoding: [0x0e,0x42,0x9e,0x76] ++xvftintrp.w.s $xr14, $xr16 ++ ++# CHECK: xvftintrp.l.d $xr14, $xr25 ++# CHECK: encoding: [0x2e,0x47,0x9e,0x76] ++xvftintrp.l.d $xr14, $xr25 ++ ++# CHECK: xvftintrz.w.s $xr5, $xr30 ++# CHECK: encoding: [0xc5,0x4b,0x9e,0x76] ++xvftintrz.w.s $xr5, $xr30 ++ ++# CHECK: xvftintrz.l.d $xr11, $xr19 ++# CHECK: encoding: [0x6b,0x4e,0x9e,0x76] ++xvftintrz.l.d $xr11, $xr19 ++ ++# CHECK: xvftintrne.w.s $xr27, $xr23 ++# CHECK: encoding: [0xfb,0x52,0x9e,0x76] ++xvftintrne.w.s $xr27, $xr23 ++ ++# CHECK: xvftintrne.l.d $xr27, $xr13 ++# CHECK: encoding: [0xbb,0x55,0x9e,0x76] ++xvftintrne.l.d $xr27, $xr13 ++ ++# CHECK: xvftint.wu.s $xr28, $xr2 ++# CHECK: encoding: [0x5c,0x58,0x9e,0x76] ++xvftint.wu.s $xr28, $xr2 ++ ++# CHECK: xvftint.lu.d $xr27, $xr12 ++# CHECK: encoding: [0x9b,0x5d,0x9e,0x76] ++xvftint.lu.d $xr27, $xr12 ++ ++# CHECK: xvftintrz.wu.s $xr21, $xr29 ++# CHECK: encoding: [0xb5,0x73,0x9e,0x76] ++xvftintrz.wu.s $xr21, $xr29 ++ ++# CHECK: xvftintrz.lu.d $xr19, $xr2 ++# CHECK: encoding: [0x53,0x74,0x9e,0x76] ++xvftintrz.lu.d $xr19, $xr2 ++ ++# CHECK: xvftintl.l.s $xr2, $xr18 ++# CHECK: encoding: [0x42,0x82,0x9e,0x76] ++xvftintl.l.s $xr2, $xr18 ++ ++# CHECK: xvftinth.l.s $xr8, $xr30 ++# CHECK: encoding: [0xc8,0x87,0x9e,0x76] ++xvftinth.l.s $xr8, $xr30 ++ ++# CHECK: xvftintrml.l.s $xr13, $xr17 ++# CHECK: encoding: [0x2d,0x8a,0x9e,0x76] ++xvftintrml.l.s $xr13, $xr17 ++ ++# CHECK: xvftintrmh.l.s $xr30, $xr26 ++# CHECK: encoding: [0x5e,0x8f,0x9e,0x76] ++xvftintrmh.l.s $xr30, $xr26 ++ ++# CHECK: xvftintrpl.l.s $xr11, $xr26 ++# CHECK: encoding: [0x4b,0x93,0x9e,0x76] ++xvftintrpl.l.s $xr11, $xr26 ++ ++# CHECK: xvftintrph.l.s $xr30, $xr11 ++# CHECK: encoding: [0x7e,0x95,0x9e,0x76] ++xvftintrph.l.s $xr30, $xr11 ++ ++# CHECK: xvftintrzl.l.s $xr25, $xr7 ++# CHECK: encoding: [0xf9,0x98,0x9e,0x76] ++xvftintrzl.l.s $xr25, $xr7 ++ ++# CHECK: xvftintrzh.l.s $xr12, $xr5 ++# CHECK: encoding: [0xac,0x9c,0x9e,0x76] ++xvftintrzh.l.s $xr12, $xr5 ++ ++# CHECK: xvftintrnel.l.s $xr8, $xr24 ++# CHECK: encoding: [0x08,0xa3,0x9e,0x76] ++xvftintrnel.l.s $xr8, $xr24 ++ ++# CHECK: xvftintrneh.l.s $xr25, $xr24 ++# CHECK: encoding: [0x19,0xa7,0x9e,0x76] ++xvftintrneh.l.s $xr25, $xr24 ++ ++# CHECK: xvexth.h.b $xr23, $xr5 ++# CHECK: encoding: [0xb7,0xe0,0x9e,0x76] ++xvexth.h.b $xr23, $xr5 ++ ++# CHECK: xvexth.w.h $xr25, $xr6 ++# CHECK: encoding: [0xd9,0xe4,0x9e,0x76] ++xvexth.w.h $xr25, $xr6 ++ ++# CHECK: xvexth.d.w $xr7, $xr27 ++# CHECK: encoding: [0x67,0xeb,0x9e,0x76] ++xvexth.d.w $xr7, $xr27 ++ ++# CHECK: xvexth.q.d $xr14, $xr10 ++# CHECK: encoding: [0x4e,0xed,0x9e,0x76] ++xvexth.q.d $xr14, $xr10 ++ ++# CHECK: xvexth.hu.bu $xr0, $xr21 ++# CHECK: encoding: [0xa0,0xf2,0x9e,0x76] ++xvexth.hu.bu $xr0, $xr21 ++ ++# CHECK: xvexth.wu.hu $xr15, $xr22 ++# CHECK: encoding: [0xcf,0xf6,0x9e,0x76] ++xvexth.wu.hu $xr15, $xr22 ++ ++# CHECK: xvexth.du.wu $xr24, $xr15 ++# CHECK: encoding: [0xf8,0xf9,0x9e,0x76] ++xvexth.du.wu $xr24, $xr15 ++ ++# CHECK: xvexth.qu.du $xr4, $xr2 ++# CHECK: encoding: [0x44,0xfc,0x9e,0x76] ++xvexth.qu.du $xr4, $xr2 ++ ++# CHECK: xvreplgr2vr.b $xr21, $r6 ++# CHECK: encoding: [0xd5,0x00,0x9f,0x76] ++xvreplgr2vr.b $xr21, $r6 ++ ++# CHECK: xvreplgr2vr.h $xr11, $ra ++# CHECK: encoding: [0x2b,0x04,0x9f,0x76] ++xvreplgr2vr.h $xr11, $ra ++ ++# CHECK: xvreplgr2vr.w $xr13, $r22 ++# CHECK: encoding: [0xcd,0x0a,0x9f,0x76] ++xvreplgr2vr.w $xr13, $r22 ++ ++# CHECK: xvreplgr2vr.d $xr9, $r17 ++# CHECK: encoding: [0x29,0x0e,0x9f,0x76] ++xvreplgr2vr.d $xr9, $r17 ++ ++# CHECK: vext2xv.h.b $xr18, $xr16 ++# CHECK: encoding: [0x12,0x12,0x9f,0x76] ++vext2xv.h.b $xr18, $xr16 ++ ++# CHECK: vext2xv.w.b $xr3, $xr23 ++# CHECK: encoding: [0xe3,0x16,0x9f,0x76] ++vext2xv.w.b $xr3, $xr23 ++ ++# CHECK: vext2xv.d.b $xr30, $xr16 ++# CHECK: encoding: [0x1e,0x1a,0x9f,0x76] ++vext2xv.d.b $xr30, $xr16 ++ ++# CHECK: vext2xv.w.h $xr28, $xr23 ++# CHECK: encoding: [0xfc,0x1e,0x9f,0x76] ++vext2xv.w.h $xr28, $xr23 ++ ++# CHECK: vext2xv.d.h $xr4, $xr1 ++# CHECK: encoding: [0x24,0x20,0x9f,0x76] ++vext2xv.d.h $xr4, $xr1 ++ ++# CHECK: vext2xv.d.w $xr23, $xr12 ++# CHECK: encoding: [0x97,0x25,0x9f,0x76] ++vext2xv.d.w $xr23, $xr12 ++ ++# CHECK: vext2xv.hu.bu $xr0, $xr5 ++# CHECK: encoding: [0xa0,0x28,0x9f,0x76] ++vext2xv.hu.bu $xr0, $xr5 ++ ++# CHECK: vext2xv.wu.bu $xr1, $xr4 ++# CHECK: encoding: [0x81,0x2c,0x9f,0x76] ++vext2xv.wu.bu $xr1, $xr4 ++ ++# CHECK: vext2xv.du.bu $xr17, $xr11 ++# CHECK: encoding: [0x71,0x31,0x9f,0x76] ++vext2xv.du.bu $xr17, $xr11 ++ ++# CHECK: vext2xv.wu.hu $xr28, $xr0 ++# CHECK: encoding: [0x1c,0x34,0x9f,0x76] ++vext2xv.wu.hu $xr28, $xr0 ++ ++# CHECK: vext2xv.du.hu $xr26, $xr25 ++# CHECK: encoding: [0x3a,0x3b,0x9f,0x76] ++vext2xv.du.hu $xr26, $xr25 ++ ++# CHECK: vext2xv.du.wu $xr29, $xr14 ++# CHECK: encoding: [0xdd,0x3d,0x9f,0x76] ++vext2xv.du.wu $xr29, $xr14 ++ ++# CHECK: xvhseli.d $xr3, $xr22, 13 ++# CHECK: encoding: [0xc3,0xb6,0x9f,0x76] ++xvhseli.d $xr3, $xr22, 13 ++ ++# CHECK: xvrotri.b $xr0, $xr14, 2 ++# CHECK: encoding: [0xc0,0x29,0xa0,0x76] ++xvrotri.b $xr0, $xr14, 2 ++ ++# CHECK: xvrotri.h $xr0, $xr7, 11 ++# CHECK: encoding: [0xe0,0x6c,0xa0,0x76] ++xvrotri.h $xr0, $xr7, 11 ++ ++# CHECK: xvrotri.w $xr24, $xr1, 3 ++# CHECK: encoding: [0x38,0x8c,0xa0,0x76] ++xvrotri.w $xr24, $xr1, 3 ++ ++# CHECK: xvrotri.d $xr31, $xr7, 16 ++# CHECK: encoding: [0xff,0x40,0xa1,0x76] ++xvrotri.d $xr31, $xr7, 16 ++ ++# CHECK: xvsrlri.b $xr20, $xr19, 1 ++# CHECK: encoding: [0x74,0x26,0xa4,0x76] ++xvsrlri.b $xr20, $xr19, 1 ++ ++# CHECK: xvsrlri.h $xr28, $xr1, 11 ++# CHECK: encoding: [0x3c,0x6c,0xa4,0x76] ++xvsrlri.h $xr28, $xr1, 11 ++ ++# CHECK: xvsrlri.w $xr25, $xr2, 27 ++# CHECK: encoding: [0x59,0xec,0xa4,0x76] ++xvsrlri.w $xr25, $xr2, 27 ++ ++# CHECK: xvsrlri.d $xr29, $xr9, 6 ++# CHECK: encoding: [0x3d,0x19,0xa5,0x76] ++xvsrlri.d $xr29, $xr9, 6 ++ ++# CHECK: xvsrari.b $xr7, $xr5, 2 ++# CHECK: encoding: [0xa7,0x28,0xa8,0x76] ++xvsrari.b $xr7, $xr5, 2 ++ ++# CHECK: xvsrari.h $xr0, $xr10, 9 ++# CHECK: encoding: [0x40,0x65,0xa8,0x76] ++xvsrari.h $xr0, $xr10, 9 ++ ++# CHECK: xvsrari.w $xr17, $xr24, 10 ++# CHECK: encoding: [0x11,0xab,0xa8,0x76] ++xvsrari.w $xr17, $xr24, 10 ++ ++# CHECK: xvsrari.d $xr7, $xr14, 38 ++# CHECK: encoding: [0xc7,0x99,0xa9,0x76] ++xvsrari.d $xr7, $xr14, 38 ++ ++# CHECK: xvinsgr2vr.w $xr5, $r31, 1 ++# CHECK: encoding: [0xe5,0xc7,0xeb,0x76] ++xvinsgr2vr.w $xr5, $r31, 1 ++ ++# CHECK: xvinsgr2vr.d $xr5, $r26, 1 ++# CHECK: encoding: [0x45,0xe7,0xeb,0x76] ++xvinsgr2vr.d $xr5, $r26, 1 ++ ++# CHECK: xvpickve2gr.w $r18, $xr28, 2 ++# CHECK: encoding: [0x92,0xcb,0xef,0x76] ++xvpickve2gr.w $r18, $xr28, 2 ++ ++# CHECK: xvpickve2gr.d $r20, $xr10, 1 ++# CHECK: encoding: [0x54,0xe5,0xef,0x76] ++xvpickve2gr.d $r20, $xr10, 1 ++ ++# CHECK: xvpickve2gr.wu $r9, $xr12, 6 ++# CHECK: encoding: [0x89,0xd9,0xf3,0x76] ++xvpickve2gr.wu $r9, $xr12, 6 ++ ++# CHECK: xvpickve2gr.du $r9, $xr13, 2 ++# CHECK: encoding: [0xa9,0xe9,0xf3,0x76] ++xvpickve2gr.du $r9, $xr13, 2 ++ ++# CHECK: xvrepl128vei.b $xr1, $xr30, 5 ++# CHECK: encoding: [0xc1,0x97,0xf7,0x76] ++xvrepl128vei.b $xr1, $xr30, 5 ++ ++# CHECK: xvrepl128vei.h $xr13, $xr13, 7 ++# CHECK: encoding: [0xad,0xdd,0xf7,0x76] ++xvrepl128vei.h $xr13, $xr13, 7 ++ ++# CHECK: xvrepl128vei.w $xr7, $xr13, 2 ++# CHECK: encoding: [0xa7,0xe9,0xf7,0x76] ++xvrepl128vei.w $xr7, $xr13, 2 ++ ++# CHECK: xvrepl128vei.d $xr2, $xr31, 1 ++# CHECK: encoding: [0xe2,0xf7,0xf7,0x76] ++xvrepl128vei.d $xr2, $xr31, 1 ++ ++# CHECK: xvinsve0.w $xr4, $xr13, 3 ++# CHECK: encoding: [0xa4,0xcd,0xff,0x76] ++xvinsve0.w $xr4, $xr13, 3 ++ ++# CHECK: xvinsve0.d $xr27, $xr25, 0 ++# CHECK: encoding: [0x3b,0xe3,0xff,0x76] ++xvinsve0.d $xr27, $xr25, 0 ++ ++# CHECK: xvpickve.w $xr29, $xr19, 7 ++# CHECK: encoding: [0x7d,0xde,0x03,0x77] ++xvpickve.w $xr29, $xr19, 7 ++ ++# CHECK: xvpickve.d $xr19, $xr16, 3 ++# CHECK: encoding: [0x13,0xee,0x03,0x77] ++xvpickve.d $xr19, $xr16, 3 ++ ++# CHECK: xvreplve0.b $xr5, $xr5 ++# CHECK: encoding: [0xa5,0x00,0x07,0x77] ++xvreplve0.b $xr5, $xr5 ++ ++# CHECK: xvreplve0.h $xr14, $xr24 ++# CHECK: encoding: [0x0e,0x83,0x07,0x77] ++xvreplve0.h $xr14, $xr24 ++ ++# CHECK: xvreplve0.w $xr15, $xr13 ++# CHECK: encoding: [0xaf,0xc1,0x07,0x77] ++xvreplve0.w $xr15, $xr13 ++ ++# CHECK: xvreplve0.d $xr20, $xr20 ++# CHECK: encoding: [0x94,0xe2,0x07,0x77] ++xvreplve0.d $xr20, $xr20 ++ ++# CHECK: xvreplve0.q $xr5, $xr10 ++# CHECK: encoding: [0x45,0xf1,0x07,0x77] ++xvreplve0.q $xr5, $xr10 ++ ++# CHECK: xvsllwil.h.b $xr31, $xr0, 3 ++# CHECK: encoding: [0x1f,0x2c,0x08,0x77] ++xvsllwil.h.b $xr31, $xr0, 3 ++ ++# CHECK: xvsllwil.w.h $xr21, $xr24, 7 ++# CHECK: encoding: [0x15,0x5f,0x08,0x77] ++xvsllwil.w.h $xr21, $xr24, 7 ++ ++# CHECK: xvsllwil.d.w $xr26, $xr24, 18 ++# CHECK: encoding: [0x1a,0xcb,0x08,0x77] ++xvsllwil.d.w $xr26, $xr24, 18 ++ ++# CHECK: xvextl.q.d $xr5, $xr6 ++# CHECK: encoding: [0xc5,0x00,0x09,0x77] ++xvextl.q.d $xr5, $xr6 ++ ++# CHECK: xvsllwil.hu.bu $xr13, $xr31, 6 ++# CHECK: encoding: [0xed,0x3b,0x0c,0x77] ++xvsllwil.hu.bu $xr13, $xr31, 6 ++ ++# CHECK: xvsllwil.wu.hu $xr19, $xr20, 8 ++# CHECK: encoding: [0x93,0x62,0x0c,0x77] ++xvsllwil.wu.hu $xr19, $xr20, 8 ++ ++# CHECK: xvsllwil.du.wu $xr14, $xr13, 2 ++# CHECK: encoding: [0xae,0x89,0x0c,0x77] ++xvsllwil.du.wu $xr14, $xr13, 2 ++ ++# CHECK: xvextl.qu.du $xr10, $xr7 ++# CHECK: encoding: [0xea,0x00,0x0d,0x77] ++xvextl.qu.du $xr10, $xr7 ++ ++# CHECK: xvbitclri.b $xr31, $xr21, 5 ++# CHECK: encoding: [0xbf,0x36,0x10,0x77] ++xvbitclri.b $xr31, $xr21, 5 ++ ++# CHECK: xvbitclri.h $xr26, $xr4, 2 ++# CHECK: encoding: [0x9a,0x48,0x10,0x77] ++xvbitclri.h $xr26, $xr4, 2 ++ ++# CHECK: xvbitclri.w $xr21, $xr25, 15 ++# CHECK: encoding: [0x35,0xbf,0x10,0x77] ++xvbitclri.w $xr21, $xr25, 15 ++ ++# CHECK: xvbitclri.d $xr14, $xr0, 63 ++# CHECK: encoding: [0x0e,0xfc,0x11,0x77] ++xvbitclri.d $xr14, $xr0, 63 ++ ++# CHECK: xvbitseti.b $xr16, $xr1, 5 ++# CHECK: encoding: [0x30,0x34,0x14,0x77] ++xvbitseti.b $xr16, $xr1, 5 ++ ++# CHECK: xvbitseti.h $xr19, $xr30, 3 ++# CHECK: encoding: [0xd3,0x4f,0x14,0x77] ++xvbitseti.h $xr19, $xr30, 3 ++ ++# CHECK: xvbitseti.w $xr18, $xr22, 27 ++# CHECK: encoding: [0xd2,0xee,0x14,0x77] ++xvbitseti.w $xr18, $xr22, 27 ++ ++# CHECK: xvbitseti.d $xr15, $xr1, 40 ++# CHECK: encoding: [0x2f,0xa0,0x15,0x77] ++xvbitseti.d $xr15, $xr1, 40 ++ ++# CHECK: xvbitrevi.b $xr23, $xr5, 0 ++# CHECK: encoding: [0xb7,0x20,0x18,0x77] ++xvbitrevi.b $xr23, $xr5, 0 ++ ++# CHECK: xvbitrevi.h $xr5, $xr2, 7 ++# CHECK: encoding: [0x45,0x5c,0x18,0x77] ++xvbitrevi.h $xr5, $xr2, 7 ++ ++# CHECK: xvbitrevi.w $xr23, $xr6, 12 ++# CHECK: encoding: [0xd7,0xb0,0x18,0x77] ++xvbitrevi.w $xr23, $xr6, 12 ++ ++# CHECK: xvbitrevi.d $xr18, $xr14, 33 ++# CHECK: encoding: [0xd2,0x85,0x19,0x77] ++xvbitrevi.d $xr18, $xr14, 33 ++ ++# CHECK: xvsat.b $xr27, $xr26, 4 ++# CHECK: encoding: [0x5b,0x33,0x24,0x77] ++xvsat.b $xr27, $xr26, 4 ++ ++# CHECK: xvsat.h $xr4, $xr21, 5 ++# CHECK: encoding: [0xa4,0x56,0x24,0x77] ++xvsat.h $xr4, $xr21, 5 ++ ++# CHECK: xvsat.w $xr29, $xr27, 10 ++# CHECK: encoding: [0x7d,0xab,0x24,0x77] ++xvsat.w $xr29, $xr27, 10 ++ ++# CHECK: xvsat.d $xr14, $xr0, 60 ++# CHECK: encoding: [0x0e,0xf0,0x25,0x77] ++xvsat.d $xr14, $xr0, 60 ++ ++# CHECK: xvsat.bu $xr31, $xr25, 3 ++# CHECK: encoding: [0x3f,0x2f,0x28,0x77] ++xvsat.bu $xr31, $xr25, 3 ++ ++# CHECK: xvsat.hu $xr17, $xr4, 14 ++# CHECK: encoding: [0x91,0x78,0x28,0x77] ++xvsat.hu $xr17, $xr4, 14 ++ ++# CHECK: xvsat.wu $xr17, $xr17, 4 ++# CHECK: encoding: [0x31,0x92,0x28,0x77] ++xvsat.wu $xr17, $xr17, 4 ++ ++# CHECK: xvsat.du $xr11, $xr0, 43 ++# CHECK: encoding: [0x0b,0xac,0x29,0x77] ++xvsat.du $xr11, $xr0, 43 ++ ++# CHECK: xvslli.b $xr24, $xr24, 2 ++# CHECK: encoding: [0x18,0x2b,0x2c,0x77] ++xvslli.b $xr24, $xr24, 2 ++ ++# CHECK: xvslli.h $xr23, $xr9, 7 ++# CHECK: encoding: [0x37,0x5d,0x2c,0x77] ++xvslli.h $xr23, $xr9, 7 ++ ++# CHECK: xvslli.w $xr13, $xr12, 16 ++# CHECK: encoding: [0x8d,0xc1,0x2c,0x77] ++xvslli.w $xr13, $xr12, 16 ++ ++# CHECK: xvslli.d $xr11, $xr22, 17 ++# CHECK: encoding: [0xcb,0x46,0x2d,0x77] ++xvslli.d $xr11, $xr22, 17 ++ ++# CHECK: xvsrli.b $xr9, $xr14, 1 ++# CHECK: encoding: [0xc9,0x25,0x30,0x77] ++xvsrli.b $xr9, $xr14, 1 ++ ++# CHECK: xvsrli.h $xr22, $xr20, 15 ++# CHECK: encoding: [0x96,0x7e,0x30,0x77] ++xvsrli.h $xr22, $xr20, 15 ++ ++# CHECK: xvsrli.w $xr5, $xr30, 20 ++# CHECK: encoding: [0xc5,0xd3,0x30,0x77] ++xvsrli.w $xr5, $xr30, 20 ++ ++# CHECK: xvsrli.d $xr1, $xr16, 58 ++# CHECK: encoding: [0x01,0xea,0x31,0x77] ++xvsrli.d $xr1, $xr16, 58 ++ ++# CHECK: xvsrai.b $xr18, $xr6, 2 ++# CHECK: encoding: [0xd2,0x28,0x34,0x77] ++xvsrai.b $xr18, $xr6, 2 ++ ++# CHECK: xvsrai.h $xr21, $xr16, 12 ++# CHECK: encoding: [0x15,0x72,0x34,0x77] ++xvsrai.h $xr21, $xr16, 12 ++ ++# CHECK: xvsrai.w $xr13, $xr17, 17 ++# CHECK: encoding: [0x2d,0xc6,0x34,0x77] ++xvsrai.w $xr13, $xr17, 17 ++ ++# CHECK: xvsrai.d $xr3, $xr12, 51 ++# CHECK: encoding: [0x83,0xcd,0x35,0x77] ++xvsrai.d $xr3, $xr12, 51 ++ ++# CHECK: xvsrlni.b.h $xr1, $xr7, 4 ++# CHECK: encoding: [0xe1,0x50,0x40,0x77] ++xvsrlni.b.h $xr1, $xr7, 4 ++ ++# CHECK: xvsrlni.h.w $xr16, $xr21, 25 ++# CHECK: encoding: [0xb0,0xe6,0x40,0x77] ++xvsrlni.h.w $xr16, $xr21, 25 ++ ++# CHECK: xvsrlni.w.d $xr13, $xr10, 48 ++# CHECK: encoding: [0x4d,0xc1,0x41,0x77] ++xvsrlni.w.d $xr13, $xr10, 48 ++ ++# CHECK: xvsrlni.d.q $xr17, $xr12, 126 ++# CHECK: encoding: [0x91,0xf9,0x43,0x77] ++xvsrlni.d.q $xr17, $xr12, 126 ++ ++# CHECK: xvsrlrni.b.h $xr17, $xr19, 15 ++# CHECK: encoding: [0x71,0x7e,0x44,0x77] ++xvsrlrni.b.h $xr17, $xr19, 15 ++ ++# CHECK: xvsrlrni.h.w $xr21, $xr24, 14 ++# CHECK: encoding: [0x15,0xbb,0x44,0x77] ++xvsrlrni.h.w $xr21, $xr24, 14 ++ ++# CHECK: xvsrlrni.w.d $xr20, $xr31, 3 ++# CHECK: encoding: [0xf4,0x0f,0x45,0x77] ++xvsrlrni.w.d $xr20, $xr31, 3 ++ ++# CHECK: xvsrlrni.d.q $xr28, $xr24, 76 ++# CHECK: encoding: [0x1c,0x33,0x47,0x77] ++xvsrlrni.d.q $xr28, $xr24, 76 ++ ++# CHECK: xvssrlni.b.h $xr26, $xr7, 7 ++# CHECK: encoding: [0xfa,0x5c,0x48,0x77] ++xvssrlni.b.h $xr26, $xr7, 7 ++ ++# CHECK: xvssrlni.h.w $xr27, $xr28, 25 ++# CHECK: encoding: [0x9b,0xe7,0x48,0x77] ++xvssrlni.h.w $xr27, $xr28, 25 ++ ++# CHECK: xvssrlni.w.d $xr4, $xr8, 16 ++# CHECK: encoding: [0x04,0x41,0x49,0x77] ++xvssrlni.w.d $xr4, $xr8, 16 ++ ++# CHECK: xvssrlni.d.q $xr14, $xr17, 84 ++# CHECK: encoding: [0x2e,0x52,0x4b,0x77] ++xvssrlni.d.q $xr14, $xr17, 84 ++ ++# CHECK: xvssrlni.bu.h $xr17, $xr6, 2 ++# CHECK: encoding: [0xd1,0x48,0x4c,0x77] ++xvssrlni.bu.h $xr17, $xr6, 2 ++ ++# CHECK: xvssrlni.hu.w $xr6, $xr26, 3 ++# CHECK: encoding: [0x46,0x8f,0x4c,0x77] ++xvssrlni.hu.w $xr6, $xr26, 3 ++ ++# CHECK: xvssrlni.wu.d $xr10, $xr18, 54 ++# CHECK: encoding: [0x4a,0xda,0x4d,0x77] ++xvssrlni.wu.d $xr10, $xr18, 54 ++ ++# CHECK: xvssrlni.du.q $xr29, $xr26, 70 ++# CHECK: encoding: [0x5d,0x1b,0x4f,0x77] ++xvssrlni.du.q $xr29, $xr26, 70 ++ ++# CHECK: xvssrlrni.b.h $xr6, $xr9, 6 ++# CHECK: encoding: [0x26,0x59,0x50,0x77] ++xvssrlrni.b.h $xr6, $xr9, 6 ++ ++# CHECK: xvssrlrni.h.w $xr22, $xr8, 1 ++# CHECK: encoding: [0x16,0x85,0x50,0x77] ++xvssrlrni.h.w $xr22, $xr8, 1 ++ ++# CHECK: xvssrlrni.w.d $xr28, $xr9, 28 ++# CHECK: encoding: [0x3c,0x71,0x51,0x77] ++xvssrlrni.w.d $xr28, $xr9, 28 ++ ++# CHECK: xvssrlrni.d.q $xr20, $xr27, 104 ++# CHECK: encoding: [0x74,0xa3,0x53,0x77] ++xvssrlrni.d.q $xr20, $xr27, 104 ++ ++# CHECK: xvssrlrni.bu.h $xr25, $xr4, 12 ++# CHECK: encoding: [0x99,0x70,0x54,0x77] ++xvssrlrni.bu.h $xr25, $xr4, 12 ++ ++# CHECK: xvssrlrni.hu.w $xr21, $xr29, 5 ++# CHECK: encoding: [0xb5,0x97,0x54,0x77] ++xvssrlrni.hu.w $xr21, $xr29, 5 ++ ++# CHECK: xvssrlrni.wu.d $xr1, $xr16, 54 ++# CHECK: encoding: [0x01,0xda,0x55,0x77] ++xvssrlrni.wu.d $xr1, $xr16, 54 ++ ++# CHECK: xvssrlrni.du.q $xr29, $xr7, 25 ++# CHECK: encoding: [0xfd,0x64,0x56,0x77] ++xvssrlrni.du.q $xr29, $xr7, 25 ++ ++# CHECK: xvsrani.b.h $xr16, $xr25, 4 ++# CHECK: encoding: [0x30,0x53,0x58,0x77] ++xvsrani.b.h $xr16, $xr25, 4 ++ ++# CHECK: xvsrani.h.w $xr13, $xr10, 6 ++# CHECK: encoding: [0x4d,0x99,0x58,0x77] ++xvsrani.h.w $xr13, $xr10, 6 ++ ++# CHECK: xvsrani.w.d $xr7, $xr21, 53 ++# CHECK: encoding: [0xa7,0xd6,0x59,0x77] ++xvsrani.w.d $xr7, $xr21, 53 ++ ++# CHECK: xvsrani.d.q $xr26, $xr18, 55 ++# CHECK: encoding: [0x5a,0xde,0x5a,0x77] ++xvsrani.d.q $xr26, $xr18, 55 ++ ++# CHECK: xvsrarni.b.h $xr17, $xr21, 11 ++# CHECK: encoding: [0xb1,0x6e,0x5c,0x77] ++xvsrarni.b.h $xr17, $xr21, 11 ++ ++# CHECK: xvsrarni.h.w $xr15, $xr30, 2 ++# CHECK: encoding: [0xcf,0x8b,0x5c,0x77] ++xvsrarni.h.w $xr15, $xr30, 2 ++ ++# CHECK: xvsrarni.w.d $xr23, $xr11, 31 ++# CHECK: encoding: [0x77,0x7d,0x5d,0x77] ++xvsrarni.w.d $xr23, $xr11, 31 ++ ++# CHECK: xvsrarni.d.q $xr22, $xr25, 16 ++# CHECK: encoding: [0x36,0x43,0x5e,0x77] ++xvsrarni.d.q $xr22, $xr25, 16 ++ ++# CHECK: xvssrani.b.h $xr19, $xr20, 10 ++# CHECK: encoding: [0x93,0x6a,0x60,0x77] ++xvssrani.b.h $xr19, $xr20, 10 ++ ++# CHECK: xvssrani.h.w $xr25, $xr9, 22 ++# CHECK: encoding: [0x39,0xd9,0x60,0x77] ++xvssrani.h.w $xr25, $xr9, 22 ++ ++# CHECK: xvssrani.w.d $xr23, $xr2, 7 ++# CHECK: encoding: [0x57,0x1c,0x61,0x77] ++xvssrani.w.d $xr23, $xr2, 7 ++ ++# CHECK: xvssrani.d.q $xr6, $xr8, 127 ++# CHECK: encoding: [0x06,0xfd,0x63,0x77] ++xvssrani.d.q $xr6, $xr8, 127 ++ ++# CHECK: xvssrani.bu.h $xr27, $xr14, 5 ++# CHECK: encoding: [0xdb,0x55,0x64,0x77] ++xvssrani.bu.h $xr27, $xr14, 5 ++ ++# CHECK: xvssrani.hu.w $xr14, $xr1, 20 ++# CHECK: encoding: [0x2e,0xd0,0x64,0x77] ++xvssrani.hu.w $xr14, $xr1, 20 ++ ++# CHECK: xvssrani.wu.d $xr10, $xr4, 59 ++# CHECK: encoding: [0x8a,0xec,0x65,0x77] ++xvssrani.wu.d $xr10, $xr4, 59 ++ ++# CHECK: xvssrani.du.q $xr17, $xr1, 82 ++# CHECK: encoding: [0x31,0x48,0x67,0x77] ++xvssrani.du.q $xr17, $xr1, 82 ++ ++# CHECK: xvssrarni.b.h $xr27, $xr18, 15 ++# CHECK: encoding: [0x5b,0x7e,0x68,0x77] ++xvssrarni.b.h $xr27, $xr18, 15 ++ ++# CHECK: xvssrarni.h.w $xr16, $xr3, 15 ++# CHECK: encoding: [0x70,0xbc,0x68,0x77] ++xvssrarni.h.w $xr16, $xr3, 15 ++ ++# CHECK: xvssrarni.w.d $xr26, $xr25, 18 ++# CHECK: encoding: [0x3a,0x4b,0x69,0x77] ++xvssrarni.w.d $xr26, $xr25, 18 ++ ++# CHECK: xvssrarni.d.q $xr28, $xr25, 0 ++# CHECK: encoding: [0x3c,0x03,0x6a,0x77] ++xvssrarni.d.q $xr28, $xr25, 0 ++ ++# CHECK: xvssrarni.bu.h $xr1, $xr12, 8 ++# CHECK: encoding: [0x81,0x61,0x6c,0x77] ++xvssrarni.bu.h $xr1, $xr12, 8 ++ ++# CHECK: xvssrarni.hu.w $xr3, $xr27, 31 ++# CHECK: encoding: [0x63,0xff,0x6c,0x77] ++xvssrarni.hu.w $xr3, $xr27, 31 ++ ++# CHECK: xvssrarni.wu.d $xr24, $xr27, 52 ++# CHECK: encoding: [0x78,0xd3,0x6d,0x77] ++xvssrarni.wu.d $xr24, $xr27, 52 ++ ++# CHECK: xvssrarni.du.q $xr5, $xr3, 112 ++# CHECK: encoding: [0x65,0xc0,0x6f,0x77] ++xvssrarni.du.q $xr5, $xr3, 112 ++ ++# CHECK: xvextrins.d $xr21, $xr25, 163 ++# CHECK: encoding: [0x35,0x8f,0x82,0x77] ++xvextrins.d $xr21, $xr25, 163 ++ ++# CHECK: xvextrins.w $xr19, $xr17, 28 ++# CHECK: encoding: [0x33,0x72,0x84,0x77] ++xvextrins.w $xr19, $xr17, 28 ++ ++# CHECK: xvextrins.h $xr30, $xr7, 79 ++# CHECK: encoding: [0xfe,0x3c,0x89,0x77] ++xvextrins.h $xr30, $xr7, 79 ++ ++# CHECK: xvextrins.b $xr1, $xr31, 210 ++# CHECK: encoding: [0xe1,0x4b,0x8f,0x77] ++xvextrins.b $xr1, $xr31, 210 ++ ++# CHECK: xvshuf4i.b $xr3, $xr22, 148 ++# CHECK: encoding: [0xc3,0x52,0x92,0x77] ++xvshuf4i.b $xr3, $xr22, 148 ++ ++# CHECK: xvshuf4i.h $xr2, $xr22, 34 ++# CHECK: encoding: [0xc2,0x8a,0x94,0x77] ++xvshuf4i.h $xr2, $xr22, 34 ++ ++# CHECK: xvshuf4i.w $xr31, $xr19, 165 ++# CHECK: encoding: [0x7f,0x96,0x9a,0x77] ++xvshuf4i.w $xr31, $xr19, 165 ++ ++# CHECK: xvshuf4i.d $xr31, $xr17, 14 ++# CHECK: encoding: [0x3f,0x3a,0x9c,0x77] ++xvshuf4i.d $xr31, $xr17, 14 ++ ++# CHECK: xvbitseli.b $xr27, $xr0, 80 ++# CHECK: encoding: [0x1b,0x40,0xc5,0x77] ++xvbitseli.b $xr27, $xr0, 80 ++ ++# CHECK: xvandi.b $xr23, $xr2, 153 ++# CHECK: encoding: [0x57,0x64,0xd2,0x77] ++xvandi.b $xr23, $xr2, 153 ++ ++# CHECK: xvori.b $xr27, $xr28, 188 ++# CHECK: encoding: [0x9b,0xf3,0xd6,0x77] ++xvori.b $xr27, $xr28, 188 ++ ++# CHECK: xvxori.b $xr28, $xr1, 254 ++# CHECK: encoding: [0x3c,0xf8,0xdb,0x77] ++xvxori.b $xr28, $xr1, 254 ++ ++# CHECK: xvnori.b $xr4, $xr2, 36 ++# CHECK: encoding: [0x44,0x90,0xdc,0x77] ++xvnori.b $xr4, $xr2, 36 ++ ++# CHECK: xvldi $xr26, -2544 ++# CHECK: encoding: [0x1a,0xc2,0xe2,0x77] ++xvldi $xr26, -2544 ++ ++# CHECK: xvpermi.w $xr22, $xr24, 168 ++# CHECK: encoding: [0x16,0xa3,0xe6,0x77] ++xvpermi.w $xr22, $xr24, 168 ++ ++# CHECK: xvpermi.d $xr14, $xr31, 136 ++# CHECK: encoding: [0xee,0x23,0xea,0x77] ++xvpermi.d $xr14, $xr31, 136 ++ ++# CHECK: xvpermi.q $xr28, $xr14, 211 ++# CHECK: encoding: [0xdc,0x4d,0xef,0x77] ++xvpermi.q $xr28, $xr14, 211 ++ ++# CHECK: vaddwev.h.b $vr0, $vr31, $vr31 ++# CHECK: encoding: [0xe0,0x7f,0x1e,0x70] ++vaddwev.h.b $vr0, $vr31, $vr31 ++ ++# CHECK: vaddwev.w.h $vr3, $vr4, $vr23 ++# CHECK: encoding: [0x83,0xdc,0x1e,0x70] ++vaddwev.w.h $vr3, $vr4, $vr23 ++ ++# CHECK: vaddwev.d.w $vr30, $vr26, $vr11 ++# CHECK: encoding: [0x5e,0x2f,0x1f,0x70] ++vaddwev.d.w $vr30, $vr26, $vr11 ++ ++# CHECK: vaddwev.q.d $vr25, $vr29, $vr13 ++# CHECK: encoding: [0xb9,0xb7,0x1f,0x70] ++vaddwev.q.d $vr25, $vr29, $vr13 ++ ++# CHECK: vsubwev.h.b $vr11, $vr28, $vr1 ++# CHECK: encoding: [0x8b,0x07,0x20,0x70] ++vsubwev.h.b $vr11, $vr28, $vr1 ++ ++# CHECK: vsubwev.w.h $vr9, $vr15, $vr5 ++# CHECK: encoding: [0xe9,0x95,0x20,0x70] ++vsubwev.w.h $vr9, $vr15, $vr5 ++ ++# CHECK: vsubwev.d.w $vr17, $vr9, $vr10 ++# CHECK: encoding: [0x31,0x29,0x21,0x70] ++vsubwev.d.w $vr17, $vr9, $vr10 ++ ++# CHECK: vsubwev.q.d $vr26, $vr18, $vr11 ++# CHECK: encoding: [0x5a,0xae,0x21,0x70] ++vsubwev.q.d $vr26, $vr18, $vr11 ++ ++# CHECK: vaddwod.h.b $vr7, $vr11, $vr18 ++# CHECK: encoding: [0x67,0x49,0x22,0x70] ++vaddwod.h.b $vr7, $vr11, $vr18 ++ ++# CHECK: vaddwod.w.h $vr0, $vr7, $vr12 ++# CHECK: encoding: [0xe0,0xb0,0x22,0x70] ++vaddwod.w.h $vr0, $vr7, $vr12 ++ ++# CHECK: vaddwod.d.w $vr30, $vr27, $vr16 ++# CHECK: encoding: [0x7e,0x43,0x23,0x70] ++vaddwod.d.w $vr30, $vr27, $vr16 ++ ++# CHECK: vaddwod.q.d $vr2, $vr20, $vr29 ++# CHECK: encoding: [0x82,0xf6,0x23,0x70] ++vaddwod.q.d $vr2, $vr20, $vr29 ++ ++# CHECK: vsubwod.h.b $vr26, $vr7, $vr19 ++# CHECK: encoding: [0xfa,0x4c,0x24,0x70] ++vsubwod.h.b $vr26, $vr7, $vr19 ++ ++# CHECK: vsubwod.w.h $vr19, $vr3, $vr11 ++# CHECK: encoding: [0x73,0xac,0x24,0x70] ++vsubwod.w.h $vr19, $vr3, $vr11 ++ ++# CHECK: vsubwod.d.w $vr31, $vr28, $vr12 ++# CHECK: encoding: [0x9f,0x33,0x25,0x70] ++vsubwod.d.w $vr31, $vr28, $vr12 ++ ++# CHECK: vsubwod.q.d $vr1, $vr24, $vr16 ++# CHECK: encoding: [0x01,0xc3,0x25,0x70] ++vsubwod.q.d $vr1, $vr24, $vr16 ++ ++# CHECK: vaddwev.h.bu $vr3, $vr29, $vr29 ++# CHECK: encoding: [0xa3,0x77,0x2e,0x70] ++vaddwev.h.bu $vr3, $vr29, $vr29 ++ ++# CHECK: vaddwev.w.hu $vr10, $vr15, $vr10 ++# CHECK: encoding: [0xea,0xa9,0x2e,0x70] ++vaddwev.w.hu $vr10, $vr15, $vr10 ++ ++# CHECK: vaddwev.d.wu $vr24, $vr29, $vr4 ++# CHECK: encoding: [0xb8,0x13,0x2f,0x70] ++vaddwev.d.wu $vr24, $vr29, $vr4 ++ ++# CHECK: vaddwev.q.du $vr17, $vr23, $vr0 ++# CHECK: encoding: [0xf1,0x82,0x2f,0x70] ++vaddwev.q.du $vr17, $vr23, $vr0 ++ ++# CHECK: vsubwev.h.bu $vr25, $vr11, $vr20 ++# CHECK: encoding: [0x79,0x51,0x30,0x70] ++vsubwev.h.bu $vr25, $vr11, $vr20 ++ ++# CHECK: vsubwev.w.hu $vr17, $vr15, $vr20 ++# CHECK: encoding: [0xf1,0xd1,0x30,0x70] ++vsubwev.w.hu $vr17, $vr15, $vr20 ++ ++# CHECK: vsubwev.d.wu $vr10, $vr25, $vr5 ++# CHECK: encoding: [0x2a,0x17,0x31,0x70] ++vsubwev.d.wu $vr10, $vr25, $vr5 ++ ++# CHECK: vsubwev.q.du $vr29, $vr3, $vr8 ++# CHECK: encoding: [0x7d,0xa0,0x31,0x70] ++vsubwev.q.du $vr29, $vr3, $vr8 ++ ++# CHECK: vaddwod.h.bu $vr10, $vr0, $vr25 ++# CHECK: encoding: [0x0a,0x64,0x32,0x70] ++vaddwod.h.bu $vr10, $vr0, $vr25 ++ ++# CHECK: vaddwod.w.hu $vr2, $vr27, $vr23 ++# CHECK: encoding: [0x62,0xdf,0x32,0x70] ++vaddwod.w.hu $vr2, $vr27, $vr23 ++ ++# CHECK: vaddwod.d.wu $vr2, $vr0, $vr22 ++# CHECK: encoding: [0x02,0x58,0x33,0x70] ++vaddwod.d.wu $vr2, $vr0, $vr22 ++ ++# CHECK: vaddwod.q.du $vr0, $vr2, $vr3 ++# CHECK: encoding: [0x40,0x8c,0x33,0x70] ++vaddwod.q.du $vr0, $vr2, $vr3 ++ ++# CHECK: vsubwod.h.bu $vr14, $vr31, $vr3 ++# CHECK: encoding: [0xee,0x0f,0x34,0x70] ++vsubwod.h.bu $vr14, $vr31, $vr3 ++ ++# CHECK: vsubwod.w.hu $vr21, $vr2, $vr7 ++# CHECK: encoding: [0x55,0x9c,0x34,0x70] ++vsubwod.w.hu $vr21, $vr2, $vr7 ++ ++# CHECK: vsubwod.d.wu $vr11, $vr8, $vr18 ++# CHECK: encoding: [0x0b,0x49,0x35,0x70] ++vsubwod.d.wu $vr11, $vr8, $vr18 ++ ++# CHECK: vsubwod.q.du $vr30, $vr20, $vr0 ++# CHECK: encoding: [0x9e,0x82,0x35,0x70] ++vsubwod.q.du $vr30, $vr20, $vr0 ++ ++# CHECK: vaddwev.h.bu.b $vr19, $vr28, $vr17 ++# CHECK: encoding: [0x93,0x47,0x3e,0x70] ++vaddwev.h.bu.b $vr19, $vr28, $vr17 ++ ++# CHECK: vaddwev.w.hu.h $vr14, $vr15, $vr30 ++# CHECK: encoding: [0xee,0xf9,0x3e,0x70] ++vaddwev.w.hu.h $vr14, $vr15, $vr30 ++ ++# CHECK: vaddwev.d.wu.w $vr15, $vr7, $vr10 ++# CHECK: encoding: [0xef,0x28,0x3f,0x70] ++vaddwev.d.wu.w $vr15, $vr7, $vr10 ++ ++# CHECK: vaddwev.q.du.d $vr19, $vr14, $vr30 ++# CHECK: encoding: [0xd3,0xf9,0x3f,0x70] ++vaddwev.q.du.d $vr19, $vr14, $vr30 ++ ++# CHECK: vaddwod.h.bu.b $vr15, $vr18, $vr8 ++# CHECK: encoding: [0x4f,0x22,0x40,0x70] ++vaddwod.h.bu.b $vr15, $vr18, $vr8 ++ ++# CHECK: vaddwod.w.hu.h $vr19, $vr27, $vr6 ++# CHECK: encoding: [0x73,0x9b,0x40,0x70] ++vaddwod.w.hu.h $vr19, $vr27, $vr6 ++ ++# CHECK: vaddwod.d.wu.w $vr7, $vr11, $vr15 ++# CHECK: encoding: [0x67,0x3d,0x41,0x70] ++vaddwod.d.wu.w $vr7, $vr11, $vr15 ++ ++# CHECK: vaddwod.q.du.d $vr0, $vr0, $vr26 ++# CHECK: encoding: [0x00,0xe8,0x41,0x70] ++vaddwod.q.du.d $vr0, $vr0, $vr26 ++ ++# CHECK: vmulwev.h.b $vr24, $vr19, $vr21 ++# CHECK: encoding: [0x78,0x56,0x90,0x70] ++vmulwev.h.b $vr24, $vr19, $vr21 ++ ++# CHECK: vmulwev.w.h $vr13, $vr22, $vr18 ++# CHECK: encoding: [0xcd,0xca,0x90,0x70] ++vmulwev.w.h $vr13, $vr22, $vr18 ++ ++# CHECK: vmulwev.d.w $vr24, $vr22, $vr13 ++# CHECK: encoding: [0xd8,0x36,0x91,0x70] ++vmulwev.d.w $vr24, $vr22, $vr13 ++ ++# CHECK: vmulwev.q.d $vr4, $vr22, $vr30 ++# CHECK: encoding: [0xc4,0xfa,0x91,0x70] ++vmulwev.q.d $vr4, $vr22, $vr30 ++ ++# CHECK: vmulwod.h.b $vr22, $vr26, $vr24 ++# CHECK: encoding: [0x56,0x63,0x92,0x70] ++vmulwod.h.b $vr22, $vr26, $vr24 ++ ++# CHECK: vmulwod.w.h $vr17, $vr12, $vr4 ++# CHECK: encoding: [0x91,0x91,0x92,0x70] ++vmulwod.w.h $vr17, $vr12, $vr4 ++ ++# CHECK: vmulwod.d.w $vr16, $vr15, $vr26 ++# CHECK: encoding: [0xf0,0x69,0x93,0x70] ++vmulwod.d.w $vr16, $vr15, $vr26 ++ ++# CHECK: vmulwod.q.d $vr3, $vr16, $vr5 ++# CHECK: encoding: [0x03,0x96,0x93,0x70] ++vmulwod.q.d $vr3, $vr16, $vr5 ++ ++# CHECK: vmulwev.h.bu $vr31, $vr19, $vr19 ++# CHECK: encoding: [0x7f,0x4e,0x98,0x70] ++vmulwev.h.bu $vr31, $vr19, $vr19 ++ ++# CHECK: vmulwev.w.hu $vr22, $vr31, $vr5 ++# CHECK: encoding: [0xf6,0x97,0x98,0x70] ++vmulwev.w.hu $vr22, $vr31, $vr5 ++ ++# CHECK: vmulwev.d.wu $vr0, $vr4, $vr30 ++# CHECK: encoding: [0x80,0x78,0x99,0x70] ++vmulwev.d.wu $vr0, $vr4, $vr30 ++ ++# CHECK: vmulwev.q.du $vr31, $vr3, $vr20 ++# CHECK: encoding: [0x7f,0xd0,0x99,0x70] ++vmulwev.q.du $vr31, $vr3, $vr20 ++ ++# CHECK: vmulwod.h.bu $vr25, $vr7, $vr13 ++# CHECK: encoding: [0xf9,0x34,0x9a,0x70] ++vmulwod.h.bu $vr25, $vr7, $vr13 ++ ++# CHECK: vmulwod.w.hu $vr1, $vr12, $vr12 ++# CHECK: encoding: [0x81,0xb1,0x9a,0x70] ++vmulwod.w.hu $vr1, $vr12, $vr12 ++ ++# CHECK: vmulwod.d.wu $vr15, $vr15, $vr30 ++# CHECK: encoding: [0xef,0x79,0x9b,0x70] ++vmulwod.d.wu $vr15, $vr15, $vr30 ++ ++# CHECK: vmulwod.q.du $vr13, $vr28, $vr6 ++# CHECK: encoding: [0x8d,0x9b,0x9b,0x70] ++vmulwod.q.du $vr13, $vr28, $vr6 ++ ++# CHECK: vmulwev.h.bu.b $vr8, $vr26, $vr3 ++# CHECK: encoding: [0x48,0x0f,0xa0,0x70] ++vmulwev.h.bu.b $vr8, $vr26, $vr3 ++ ++# CHECK: vmulwev.w.hu.h $vr10, $vr25, $vr1 ++# CHECK: encoding: [0x2a,0x87,0xa0,0x70] ++vmulwev.w.hu.h $vr10, $vr25, $vr1 ++ ++# CHECK: vmulwev.d.wu.w $vr9, $vr0, $vr19 ++# CHECK: encoding: [0x09,0x4c,0xa1,0x70] ++vmulwev.d.wu.w $vr9, $vr0, $vr19 ++ ++# CHECK: vmulwev.q.du.d $vr13, $vr24, $vr23 ++# CHECK: encoding: [0x0d,0xdf,0xa1,0x70] ++vmulwev.q.du.d $vr13, $vr24, $vr23 ++ ++# CHECK: vmulwod.h.bu.b $vr20, $vr0, $vr14 ++# CHECK: encoding: [0x14,0x38,0xa2,0x70] ++vmulwod.h.bu.b $vr20, $vr0, $vr14 ++ ++# CHECK: vmulwod.w.hu.h $vr16, $vr20, $vr3 ++# CHECK: encoding: [0x90,0x8e,0xa2,0x70] ++vmulwod.w.hu.h $vr16, $vr20, $vr3 ++ ++# CHECK: vmulwod.d.wu.w $vr5, $vr23, $vr27 ++# CHECK: encoding: [0xe5,0x6e,0xa3,0x70] ++vmulwod.d.wu.w $vr5, $vr23, $vr27 ++ ++# CHECK: vmulwod.q.du.d $vr30, $vr30, $vr29 ++# CHECK: encoding: [0xde,0xf7,0xa3,0x70] ++vmulwod.q.du.d $vr30, $vr30, $vr29 ++ ++# CHECK: vmaddwev.h.b $vr18, $vr0, $vr8 ++# CHECK: encoding: [0x12,0x20,0xac,0x70] ++vmaddwev.h.b $vr18, $vr0, $vr8 ++ ++# CHECK: vmaddwev.w.h $vr29, $vr22, $vr7 ++# CHECK: encoding: [0xdd,0x9e,0xac,0x70] ++vmaddwev.w.h $vr29, $vr22, $vr7 ++ ++# CHECK: vmaddwev.d.w $vr28, $vr13, $vr31 ++# CHECK: encoding: [0xbc,0x7d,0xad,0x70] ++vmaddwev.d.w $vr28, $vr13, $vr31 ++ ++# CHECK: vmaddwev.q.d $vr5, $vr3, $vr13 ++# CHECK: encoding: [0x65,0xb4,0xad,0x70] ++vmaddwev.q.d $vr5, $vr3, $vr13 ++ ++# CHECK: vmaddwod.h.b $vr4, $vr1, $vr9 ++# CHECK: encoding: [0x24,0x24,0xae,0x70] ++vmaddwod.h.b $vr4, $vr1, $vr9 ++ ++# CHECK: vmaddwod.w.h $vr26, $vr9, $vr24 ++# CHECK: encoding: [0x3a,0xe1,0xae,0x70] ++vmaddwod.w.h $vr26, $vr9, $vr24 ++ ++# CHECK: vmaddwod.d.w $vr30, $vr3, $vr13 ++# CHECK: encoding: [0x7e,0x34,0xaf,0x70] ++vmaddwod.d.w $vr30, $vr3, $vr13 ++ ++# CHECK: vmaddwod.q.d $vr15, $vr13, $vr29 ++# CHECK: encoding: [0xaf,0xf5,0xaf,0x70] ++vmaddwod.q.d $vr15, $vr13, $vr29 ++ ++# CHECK: vmaddwev.h.bu $vr24, $vr20, $vr5 ++# CHECK: encoding: [0x98,0x16,0xb4,0x70] ++vmaddwev.h.bu $vr24, $vr20, $vr5 ++ ++# CHECK: vmaddwev.w.hu $vr3, $vr4, $vr8 ++# CHECK: encoding: [0x83,0xa0,0xb4,0x70] ++vmaddwev.w.hu $vr3, $vr4, $vr8 ++ ++# CHECK: vmaddwev.d.wu $vr27, $vr19, $vr4 ++# CHECK: encoding: [0x7b,0x12,0xb5,0x70] ++vmaddwev.d.wu $vr27, $vr19, $vr4 ++ ++# CHECK: vmaddwev.q.du $vr28, $vr27, $vr29 ++# CHECK: encoding: [0x7c,0xf7,0xb5,0x70] ++vmaddwev.q.du $vr28, $vr27, $vr29 ++ ++# CHECK: vmaddwod.h.bu $vr5, $vr20, $vr26 ++# CHECK: encoding: [0x85,0x6a,0xb6,0x70] ++vmaddwod.h.bu $vr5, $vr20, $vr26 ++ ++# CHECK: vmaddwod.w.hu $vr21, $vr30, $vr10 ++# CHECK: encoding: [0xd5,0xab,0xb6,0x70] ++vmaddwod.w.hu $vr21, $vr30, $vr10 ++ ++# CHECK: vmaddwod.d.wu $vr7, $vr11, $vr20 ++# CHECK: encoding: [0x67,0x51,0xb7,0x70] ++vmaddwod.d.wu $vr7, $vr11, $vr20 ++ ++# CHECK: vmaddwod.q.du $vr30, $vr18, $vr24 ++# CHECK: encoding: [0x5e,0xe2,0xb7,0x70] ++vmaddwod.q.du $vr30, $vr18, $vr24 ++ ++# CHECK: vmaddwev.h.bu.b $vr4, $vr1, $vr4 ++# CHECK: encoding: [0x24,0x10,0xbc,0x70] ++vmaddwev.h.bu.b $vr4, $vr1, $vr4 ++ ++# CHECK: vmaddwev.w.hu.h $vr25, $vr11, $vr15 ++# CHECK: encoding: [0x79,0xbd,0xbc,0x70] ++vmaddwev.w.hu.h $vr25, $vr11, $vr15 ++ ++# CHECK: vmaddwev.d.wu.w $vr10, $vr16, $vr20 ++# CHECK: encoding: [0x0a,0x52,0xbd,0x70] ++vmaddwev.d.wu.w $vr10, $vr16, $vr20 ++ ++# CHECK: vmaddwev.q.du.d $vr22, $vr20, $vr23 ++# CHECK: encoding: [0x96,0xde,0xbd,0x70] ++vmaddwev.q.du.d $vr22, $vr20, $vr23 ++ ++# CHECK: vmaddwod.h.bu.b $vr31, $vr25, $vr27 ++# CHECK: encoding: [0x3f,0x6f,0xbe,0x70] ++vmaddwod.h.bu.b $vr31, $vr25, $vr27 ++ ++# CHECK: vmaddwod.w.hu.h $vr8, $vr18, $vr24 ++# CHECK: encoding: [0x48,0xe2,0xbe,0x70] ++vmaddwod.w.hu.h $vr8, $vr18, $vr24 ++ ++# CHECK: vmaddwod.d.wu.w $vr18, $vr13, $vr10 ++# CHECK: encoding: [0xb2,0x29,0xbf,0x70] ++vmaddwod.d.wu.w $vr18, $vr13, $vr10 ++ ++# CHECK: vmaddwod.q.du.d $vr10, $vr5, $vr15 ++# CHECK: encoding: [0xaa,0xbc,0xbf,0x70] ++vmaddwod.q.du.d $vr10, $vr5, $vr15 ++ +diff --git a/llvm/test/MC/RISCV/cfi-advance.s b/llvm/test/MC/RISCV/cfi-advance.s +index c4af390be..d9224fd2a 100644 +--- a/llvm/test/MC/RISCV/cfi-advance.s ++++ b/llvm/test/MC/RISCV/cfi-advance.s +@@ -5,16 +5,12 @@ + + # CHECK: .rela.eh_frame { + # CHECK-NEXT: 0x1C R_RISCV_32_PCREL 0x0 +-# CHECK-NEXT: 0x35 R_RISCV_SET6 0x0 +-# CHECK-NEXT: 0x35 R_RISCV_SUB6 0x0 + # CHECK-NEXT: } + # CHECK-DWARFDUMP: DW_CFA_advance_loc1: 104 + # CHECK-DWARFDUMP-NEXT: DW_CFA_def_cfa_offset: +8 + # CHECK-DWARFDUMP-NEXT: DW_CFA_advance_loc2: 259 + # CHECK-DWARFDUMP-NEXT: DW_CFA_def_cfa_offset: +8 + # CHECK-DWARFDUMP-NEXT: DW_CFA_advance_loc4: 65539 +-# CHECK-DWARFDUMP-NEXT: DW_CFA_def_cfa_offset: +8 +-# CHECK-DWARFDUMP-NEXT: DW_CFA_advance_loc: 10 + # CHECK-DWARFDUMP-NEXT: DW_CFA_def_cfa_offset: +8 + .text + .globl test # -- Begin function test +@@ -32,7 +28,4 @@ test: + .zero 65535, 0x90 + .cfi_def_cfa_offset 8 + nop +- .p2align 3 +- .cfi_def_cfa_offset 8 +- nop + .cfi_endproc +diff --git a/llvm/test/MC/RISCV/fixups-expr.s b/llvm/test/MC/RISCV/fixups-expr.s +index 63e7f2e93..8a02d29de 100644 +--- a/llvm/test/MC/RISCV/fixups-expr.s ++++ b/llvm/test/MC/RISCV/fixups-expr.s +@@ -16,15 +16,11 @@ + + .globl G1 + .globl G2 +-.globl G3 + .L1: + G1: + call extern + .L2: + G2: +- .p2align 3 +-.L3: +-G3: + + .data + .dword .L2-.L1 +@@ -35,14 +31,6 @@ G3: + .half G2-G1 + .byte .L2-.L1 + .byte G2-G1 +-.dword .L3-.L2 +-.dword G3-G2 +-.word .L3-.L2 +-.word G3-G2 +-.half .L3-.L2 +-.half G3-G2 +-.byte .L3-.L2 +-.byte G3-G2 + # RELAX: .rela.data { + # RELAX-NEXT: 0x0 R_RISCV_ADD64 .L2 0x0 + # RELAX-NEXT: 0x0 R_RISCV_SUB64 .L1 0x0 +@@ -60,20 +48,4 @@ G3: + # RELAX-NEXT: 0x1C R_RISCV_SUB8 .L1 0x0 + # RELAX-NEXT: 0x1D R_RISCV_ADD8 G2 0x0 + # RELAX-NEXT: 0x1D R_RISCV_SUB8 G1 0x0 +-# RELAX-NEXT: 0x1E R_RISCV_ADD64 .L3 0x0 +-# RELAX-NEXT: 0x1E R_RISCV_SUB64 .L2 0x0 +-# RELAX-NEXT: 0x26 R_RISCV_ADD64 G3 0x0 +-# RELAX-NEXT: 0x26 R_RISCV_SUB64 G2 0x0 +-# RELAX-NEXT: 0x2E R_RISCV_ADD32 .L3 0x0 +-# RELAX-NEXT: 0x2E R_RISCV_SUB32 .L2 0x0 +-# RELAX-NEXT: 0x32 R_RISCV_ADD32 G3 0x0 +-# RELAX-NEXT: 0x32 R_RISCV_SUB32 G2 0x0 +-# RELAX-NEXT: 0x36 R_RISCV_ADD16 .L3 0x0 +-# RELAX-NEXT: 0x36 R_RISCV_SUB16 .L2 0x0 +-# RELAX-NEXT: 0x38 R_RISCV_ADD16 G3 0x0 +-# RELAX-NEXT: 0x38 R_RISCV_SUB16 G2 0x0 +-# RELAX-NEXT: 0x3A R_RISCV_ADD8 .L3 0x0 +-# RELAX-NEXT: 0x3A R_RISCV_SUB8 .L2 0x0 +-# RELAX-NEXT: 0x3B R_RISCV_ADD8 G3 0x0 +-# RELAX-NEXT: 0x3B R_RISCV_SUB8 G2 0x0 + # RELAX-NEXT: } +diff --git a/llvm/test/Object/LoongArch/elf-flags.yaml b/llvm/test/Object/LoongArch/elf-flags.yaml +new file mode 100644 +index 000000000..b313d3b2b +--- /dev/null ++++ b/llvm/test/Object/LoongArch/elf-flags.yaml +@@ -0,0 +1,22 @@ ++# RUN: yaml2obj %s > %t ++# RUN: llvm-readobj --file-headers %t | FileCheck --check-prefix=OBJ %s ++# RUN: obj2yaml %t | FileCheck --check-prefix=YAML %s ++ ++# OBJ: Flags [ (0x3) ++# OBJ-NEXT: EF_LARCH_ABI_LP64 (0x3) ++# OBJ-NEXT: ] ++ ++# YAML: FileHeader: ++# YAML-NEXT: Class: ELFCLASS64 ++# YAML-NEXT: Data: ELFDATA2LSB ++# YAML-NEXT: Type: ET_EXEC ++# YAML-NEXT: Machine: EM_LOONGARCH ++# YAML-NEXT: Flags: [ EF_LARCH_ABI_LP64 ] ++ ++--- !ELF ++FileHeader: ++ Class: ELFCLASS64 ++ Data: ELFDATA2LSB ++ Type: ET_EXEC ++ Machine: EM_LOONGARCH ++ Flags: [ EF_LARCH_ABI_LP64 ] +diff --git a/llvm/test/Object/LoongArch/elf-loongarch64-rel.yaml b/llvm/test/Object/LoongArch/elf-loongarch64-rel.yaml +new file mode 100644 +index 000000000..0bf2bedc5 +--- /dev/null ++++ b/llvm/test/Object/LoongArch/elf-loongarch64-rel.yaml +@@ -0,0 +1,193 @@ ++# RUN: yaml2obj %s > %t ++# RUN: llvm-readobj -r %t | FileCheck --check-prefix=OBJ %s ++# RUN: obj2yaml %t | FileCheck --check-prefix=YAML %s ++ ++# OBJ: Relocations [ ++# OBJ-NEXT: Section (2) .rela.text { ++# OBJ-NEXT: 0x40 R_LARCH_SOP_PUSH_PLT_PCREL foo 0x0 ++# OBJ-NEXT: 0x40 R_LARCH_SOP_POP_32_S_0_10_10_16_S2 - 0x0 ++# OBJ-NEXT: 0x44 R_LARCH_SOP_PUSH_PCREL _GLOBAL_OFFSET_TABLE_ 0x800 ++# OBJ-NEXT: 0x44 R_LARCH_SOP_PUSH_GPREL shared 0x0 ++# OBJ-NEXT: 0x44 R_LARCH_SOP_ADD - 0x0 ++# OBJ-NEXT: 0x44 R_LARCH_SOP_PUSH_ABSOLUTE - 0xC ++# OBJ-NEXT: 0x44 R_LARCH_SOP_SR - 0x0 ++# OBJ-NEXT: 0x44 R_LARCH_SOP_POP_32_S_5_20 - 0x0 ++# OBJ-NEXT: 0x48 R_LARCH_SOP_PUSH_PCREL _GLOBAL_OFFSET_TABLE_ 0x4 ++# OBJ-NEXT: 0x48 R_LARCH_SOP_PUSH_GPREL shared 0x0 ++# OBJ-NEXT: 0x48 R_LARCH_SOP_ADD - 0x0 ++# OBJ-NEXT: 0x48 R_LARCH_SOP_PUSH_PCREL _GLOBAL_OFFSET_TABLE_ 0x804 ++# OBJ-NEXT: 0x48 R_LARCH_SOP_PUSH_GPREL shared 0x0 ++# OBJ-NEXT: 0x48 R_LARCH_SOP_ADD - 0x0 ++# OBJ-NEXT: 0x48 R_LARCH_SOP_PUSH_ABSOLUTE - 0xC ++# OBJ-NEXT: 0x48 R_LARCH_SOP_SR - 0x0 ++# OBJ-NEXT: 0x48 R_LARCH_SOP_PUSH_ABSOLUTE - 0xC ++# OBJ-NEXT: 0x48 R_LARCH_SOP_SL - 0x0 ++# OBJ-NEXT: 0x48 R_LARCH_SOP_SUB - 0x0 ++# OBJ-NEXT: 0x48 R_LARCH_SOP_POP_32_S_10_12 - 0x0 ++# OBJ-NEXT: 0x50 R_LARCH_SOP_PUSH_PLT_PCREL swap 0x0 ++# OBJ-NEXT: 0x50 R_LARCH_SOP_POP_32_S_0_10_10_16_S2 - 0x0 ++# OBJ-NEXT: } ++# OBJ-NEXT: ] ++ ++# YAML: Relocations: ++# YAML-NEXT: - Offset: 0x40 ++# YAML-NEXT: Symbol: foo ++# YAML-NEXT: Type: R_LARCH_SOP_PUSH_PLT_PCREL ++# YAML-NEXT: - Offset: 0x40 ++# YAML-NEXT: Type: R_LARCH_SOP_POP_32_S_0_10_10_16_S2 ++# YAML-NEXT: - Offset: 0x44 ++# YAML-NEXT: Symbol: _GLOBAL_OFFSET_TABLE_ ++# YAML-NEXT: Type: R_LARCH_SOP_PUSH_PCREL ++# YAML-NEXT: Addend: 2048 ++# YAML-NEXT: - Offset: 0x44 ++# YAML-NEXT: Symbol: shared ++# YAML-NEXT: Type: R_LARCH_SOP_PUSH_GPREL ++# YAML-NEXT: - Offset: 0x44 ++# YAML-NEXT: Type: R_LARCH_SOP_ADD ++# YAML-NEXT: - Offset: 0x44 ++# YAML-NEXT: Type: R_LARCH_SOP_PUSH_ABSOLUTE ++# YAML-NEXT: Addend: 12 ++# YAML-NEXT: - Offset: 0x44 ++# YAML-NEXT: Type: R_LARCH_SOP_SR ++# YAML-NEXT: - Offset: 0x44 ++# YAML-NEXT: Type: R_LARCH_SOP_POP_32_S_5_20 ++# YAML-NEXT: - Offset: 0x48 ++# YAML-NEXT: Symbol: _GLOBAL_OFFSET_TABLE_ ++# YAML-NEXT: Type: R_LARCH_SOP_PUSH_PCREL ++# YAML-NEXT: Addend: 4 ++# YAML-NEXT: - Offset: 0x48 ++# YAML-NEXT: Symbol: shared ++# YAML-NEXT: Type: R_LARCH_SOP_PUSH_GPREL ++# YAML-NEXT: - Offset: 0x48 ++# YAML-NEXT: Type: R_LARCH_SOP_ADD ++# YAML-NEXT: - Offset: 0x48 ++# YAML-NEXT: Symbol: _GLOBAL_OFFSET_TABLE_ ++# YAML-NEXT: Type: R_LARCH_SOP_PUSH_PCREL ++# YAML-NEXT: Addend: 2052 ++# YAML-NEXT: - Offset: 0x48 ++# YAML-NEXT: Symbol: shared ++# YAML-NEXT: Type: R_LARCH_SOP_PUSH_GPREL ++# YAML-NEXT: - Offset: 0x48 ++# YAML-NEXT: Type: R_LARCH_SOP_ADD ++# YAML-NEXT: - Offset: 0x48 ++# YAML-NEXT: Type: R_LARCH_SOP_PUSH_ABSOLUTE ++# YAML-NEXT: Addend: 12 ++# YAML-NEXT: - Offset: 0x48 ++# YAML-NEXT: Type: R_LARCH_SOP_SR ++# YAML-NEXT: - Offset: 0x48 ++# YAML-NEXT: Type: R_LARCH_SOP_PUSH_ABSOLUTE ++# YAML-NEXT: Addend: 12 ++# YAML-NEXT: - Offset: 0x48 ++# YAML-NEXT: Type: R_LARCH_SOP_SL ++# YAML-NEXT: - Offset: 0x48 ++# YAML-NEXT: Type: R_LARCH_SOP_SUB ++# YAML-NEXT: - Offset: 0x48 ++# YAML-NEXT: Type: R_LARCH_SOP_POP_32_S_10_12 ++# YAML-NEXT: - Offset: 0x50 ++# YAML-NEXT: Symbol: swap ++# YAML-NEXT: Type: R_LARCH_SOP_PUSH_PLT_PCREL ++# YAML-NEXT: - Offset: 0x50 ++# YAML-NEXT: Type: R_LARCH_SOP_POP_32_S_0_10_10_16_S2 ++ ++--- !ELF ++FileHeader: ++ Class: ELFCLASS64 ++ Data: ELFDATA2LSB ++ Type: ET_REL ++ Machine: EM_LOONGARCH ++ Flags: [ EF_LARCH_ABI_LP64 ] ++Sections: ++ - Name: .text ++ Type: SHT_PROGBITS ++ Flags: [ SHF_ALLOC, SHF_EXECINSTR ] ++ AddressAlign: 0x10 ++ - Name: .rela.text ++ Type: SHT_RELA ++ Flags: [ SHF_INFO_LINK ] ++ AddressAlign: 0x8 ++ Info: .text ++ Relocations: ++ - Offset: 0x40 ++ Symbol: foo ++ Type: R_LARCH_SOP_PUSH_PLT_PCREL ++ - Offset: 0x40 ++ Type: R_LARCH_SOP_POP_32_S_0_10_10_16_S2 ++ - Offset: 0x44 ++ Symbol: _GLOBAL_OFFSET_TABLE_ ++ Type: R_LARCH_SOP_PUSH_PCREL ++ Addend: 2048 ++ - Offset: 0x44 ++ Symbol: shared ++ Type: R_LARCH_SOP_PUSH_GPREL ++ - Offset: 0x44 ++ Type: R_LARCH_SOP_ADD ++ - Offset: 0x44 ++ Type: R_LARCH_SOP_PUSH_ABSOLUTE ++ Addend: 12 ++ - Offset: 0x44 ++ Type: R_LARCH_SOP_SR ++ - Offset: 0x44 ++ Type: R_LARCH_SOP_POP_32_S_5_20 ++ - Offset: 0x48 ++ Symbol: _GLOBAL_OFFSET_TABLE_ ++ Type: R_LARCH_SOP_PUSH_PCREL ++ Addend: 4 ++ - Offset: 0x48 ++ Symbol: shared ++ Type: R_LARCH_SOP_PUSH_GPREL ++ - Offset: 0x48 ++ Type: R_LARCH_SOP_ADD ++ - Offset: 0x48 ++ Symbol: _GLOBAL_OFFSET_TABLE_ ++ Type: R_LARCH_SOP_PUSH_PCREL ++ Addend: 2052 ++ - Offset: 0x48 ++ Symbol: shared ++ Type: R_LARCH_SOP_PUSH_GPREL ++ - Offset: 0x48 ++ Type: R_LARCH_SOP_ADD ++ - Offset: 0x48 ++ Type: R_LARCH_SOP_PUSH_ABSOLUTE ++ Addend: 12 ++ - Offset: 0x48 ++ Type: R_LARCH_SOP_SR ++ - Offset: 0x48 ++ Type: R_LARCH_SOP_PUSH_ABSOLUTE ++ Addend: 12 ++ - Offset: 0x48 ++ Type: R_LARCH_SOP_SL ++ - Offset: 0x48 ++ Type: R_LARCH_SOP_SUB ++ - Offset: 0x48 ++ Type: R_LARCH_SOP_POP_32_S_10_12 ++ - Offset: 0x50 ++ Symbol: swap ++ Type: R_LARCH_SOP_PUSH_PLT_PCREL ++ - Offset: 0x50 ++ Type: R_LARCH_SOP_POP_32_S_0_10_10_16_S2 ++ - Name: .data ++ Type: SHT_PROGBITS ++ Flags: [ SHF_WRITE, SHF_ALLOC ] ++ AddressAlign: 0x10 ++ Content: '' ++ - Name: .bss ++ Type: SHT_NOBITS ++ Flags: [ SHF_WRITE, SHF_ALLOC ] ++ AddressAlign: 0x10 ++ ++Symbols: ++ - Name: a.c ++ Type: STT_FILE ++ - Name: _GLOBAL_OFFSET_TABLE_ ++ - Name: foo ++ Type: STT_FUNC ++ Section: .text ++ Size: 0x24 ++ - Name: main ++ Type: STT_FUNC ++ Section: .text ++ Value: 0x28 ++ Size: 0x4C ++ - Name: shared ++ - Name: swap ++... +diff --git a/llvm/test/Object/LoongArch/lit.local.cfg b/llvm/test/Object/LoongArch/lit.local.cfg +new file mode 100644 +index 000000000..2b5a4893e +--- /dev/null ++++ b/llvm/test/Object/LoongArch/lit.local.cfg +@@ -0,0 +1,2 @@ ++if not 'LoongArch' in config.root.targets: ++ config.unsupported = True +diff --git a/llvm/test/Transforms/AtomicExpand/LoongArch/atomicrmw-fp.ll b/llvm/test/Transforms/AtomicExpand/LoongArch/atomicrmw-fp.ll +deleted file mode 100644 +index 43fdd25e2..000000000 +--- a/llvm/test/Transforms/AtomicExpand/LoongArch/atomicrmw-fp.ll ++++ /dev/null +@@ -1,170 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +-; RUN: opt -S --mtriple=loongarch64 --atomic-expand --mattr=+d %s | FileCheck %s +- +-define float @atomicrmw_fadd_float(ptr %ptr, float %value) { +-; CHECK-LABEL: @atomicrmw_fadd_float( +-; CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[PTR:%.*]], align 4 +-; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] +-; CHECK: atomicrmw.start: +-; CHECK-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ] +-; CHECK-NEXT: [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]] +-; CHECK-NEXT: [[TMP2:%.*]] = bitcast float [[NEW]] to i32 +-; CHECK-NEXT: [[TMP3:%.*]] = bitcast float [[LOADED]] to i32 +-; CHECK-NEXT: [[TMP4:%.*]] = cmpxchg ptr [[PTR]], i32 [[TMP3]], i32 [[TMP2]] seq_cst seq_cst, align 4 +-; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1 +-; CHECK-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0 +-; CHECK-NEXT: [[TMP5]] = bitcast i32 [[NEWLOADED]] to float +-; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +-; CHECK: atomicrmw.end: +-; CHECK-NEXT: ret float [[TMP5]] +-; +- %res = atomicrmw fadd ptr %ptr, float %value seq_cst +- ret float %res +-} +- +-define float @atomicrmw_fsub_float(ptr %ptr, float %value) { +-; CHECK-LABEL: @atomicrmw_fsub_float( +-; CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[PTR:%.*]], align 4 +-; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] +-; CHECK: atomicrmw.start: +-; CHECK-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ] +-; CHECK-NEXT: [[NEW:%.*]] = fsub float [[LOADED]], [[VALUE:%.*]] +-; CHECK-NEXT: [[TMP2:%.*]] = bitcast float [[NEW]] to i32 +-; CHECK-NEXT: [[TMP3:%.*]] = bitcast float [[LOADED]] to i32 +-; CHECK-NEXT: [[TMP4:%.*]] = cmpxchg ptr [[PTR]], i32 [[TMP3]], i32 [[TMP2]] seq_cst seq_cst, align 4 +-; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1 +-; CHECK-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0 +-; CHECK-NEXT: [[TMP5]] = bitcast i32 [[NEWLOADED]] to float +-; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +-; CHECK: atomicrmw.end: +-; CHECK-NEXT: ret float [[TMP5]] +-; +- %res = atomicrmw fsub ptr %ptr, float %value seq_cst +- ret float %res +-} +- +-define float @atomicrmw_fmin_float(ptr %ptr, float %value) { +-; CHECK-LABEL: @atomicrmw_fmin_float( +-; CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[PTR:%.*]], align 4 +-; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] +-; CHECK: atomicrmw.start: +-; CHECK-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +-; CHECK-NEXT: [[TMP2:%.*]] = call float @llvm.minnum.f32(float [[LOADED]], float [[VALUE:%.*]]) +-; CHECK-NEXT: [[TMP3:%.*]] = bitcast float [[TMP2]] to i32 +-; CHECK-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +-; CHECK-NEXT: [[TMP5:%.*]] = cmpxchg ptr [[PTR]], i32 [[TMP4]], i32 [[TMP3]] seq_cst seq_cst, align 4 +-; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +-; CHECK-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +-; CHECK-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +-; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +-; CHECK: atomicrmw.end: +-; CHECK-NEXT: ret float [[TMP6]] +-; +- %res = atomicrmw fmin ptr %ptr, float %value seq_cst +- ret float %res +-} +- +-define float @atomicrmw_fmax_float(ptr %ptr, float %value) { +-; CHECK-LABEL: @atomicrmw_fmax_float( +-; CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[PTR:%.*]], align 4 +-; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] +-; CHECK: atomicrmw.start: +-; CHECK-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +-; CHECK-NEXT: [[TMP2:%.*]] = call float @llvm.maxnum.f32(float [[LOADED]], float [[VALUE:%.*]]) +-; CHECK-NEXT: [[TMP3:%.*]] = bitcast float [[TMP2]] to i32 +-; CHECK-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 +-; CHECK-NEXT: [[TMP5:%.*]] = cmpxchg ptr [[PTR]], i32 [[TMP4]], i32 [[TMP3]] seq_cst seq_cst, align 4 +-; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 +-; CHECK-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 +-; CHECK-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float +-; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +-; CHECK: atomicrmw.end: +-; CHECK-NEXT: ret float [[TMP6]] +-; +- %res = atomicrmw fmax ptr %ptr, float %value seq_cst +- ret float %res +-} +- +-define double @atomicrmw_fadd_double(ptr %ptr, double %value) { +-; CHECK-LABEL: @atomicrmw_fadd_double( +-; CHECK-NEXT: [[TMP1:%.*]] = load double, ptr [[PTR:%.*]], align 8 +-; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] +-; CHECK: atomicrmw.start: +-; CHECK-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ] +-; CHECK-NEXT: [[NEW:%.*]] = fadd double [[LOADED]], [[VALUE:%.*]] +-; CHECK-NEXT: [[TMP2:%.*]] = bitcast double [[NEW]] to i64 +-; CHECK-NEXT: [[TMP3:%.*]] = bitcast double [[LOADED]] to i64 +-; CHECK-NEXT: [[TMP4:%.*]] = cmpxchg ptr [[PTR]], i64 [[TMP3]], i64 [[TMP2]] seq_cst seq_cst, align 8 +-; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP4]], 1 +-; CHECK-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP4]], 0 +-; CHECK-NEXT: [[TMP5]] = bitcast i64 [[NEWLOADED]] to double +-; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +-; CHECK: atomicrmw.end: +-; CHECK-NEXT: ret double [[TMP5]] +-; +- %res = atomicrmw fadd ptr %ptr, double %value seq_cst +- ret double %res +-} +- +-define double @atomicrmw_fsub_double(ptr %ptr, double %value) { +-; CHECK-LABEL: @atomicrmw_fsub_double( +-; CHECK-NEXT: [[TMP1:%.*]] = load double, ptr [[PTR:%.*]], align 8 +-; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] +-; CHECK: atomicrmw.start: +-; CHECK-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ] +-; CHECK-NEXT: [[NEW:%.*]] = fsub double [[LOADED]], [[VALUE:%.*]] +-; CHECK-NEXT: [[TMP2:%.*]] = bitcast double [[NEW]] to i64 +-; CHECK-NEXT: [[TMP3:%.*]] = bitcast double [[LOADED]] to i64 +-; CHECK-NEXT: [[TMP4:%.*]] = cmpxchg ptr [[PTR]], i64 [[TMP3]], i64 [[TMP2]] seq_cst seq_cst, align 8 +-; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP4]], 1 +-; CHECK-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP4]], 0 +-; CHECK-NEXT: [[TMP5]] = bitcast i64 [[NEWLOADED]] to double +-; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +-; CHECK: atomicrmw.end: +-; CHECK-NEXT: ret double [[TMP5]] +-; +- %res = atomicrmw fsub ptr %ptr, double %value seq_cst +- ret double %res +-} +- +-define double @atomicrmw_fmin_double(ptr %ptr, double %value) { +-; CHECK-LABEL: @atomicrmw_fmin_double( +-; CHECK-NEXT: [[TMP1:%.*]] = load double, ptr [[PTR:%.*]], align 8 +-; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] +-; CHECK: atomicrmw.start: +-; CHECK-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +-; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.minnum.f64(double [[LOADED]], double [[VALUE:%.*]]) +-; CHECK-NEXT: [[TMP3:%.*]] = bitcast double [[TMP2]] to i64 +-; CHECK-NEXT: [[TMP4:%.*]] = bitcast double [[LOADED]] to i64 +-; CHECK-NEXT: [[TMP5:%.*]] = cmpxchg ptr [[PTR]], i64 [[TMP4]], i64 [[TMP3]] seq_cst seq_cst, align 8 +-; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1 +-; CHECK-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0 +-; CHECK-NEXT: [[TMP6]] = bitcast i64 [[NEWLOADED]] to double +-; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +-; CHECK: atomicrmw.end: +-; CHECK-NEXT: ret double [[TMP6]] +-; +- %res = atomicrmw fmin ptr %ptr, double %value seq_cst +- ret double %res +-} +- +-define double @atomicrmw_fmax_double(ptr %ptr, double %value) { +-; CHECK-LABEL: @atomicrmw_fmax_double( +-; CHECK-NEXT: [[TMP1:%.*]] = load double, ptr [[PTR:%.*]], align 8 +-; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] +-; CHECK: atomicrmw.start: +-; CHECK-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] +-; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.maxnum.f64(double [[LOADED]], double [[VALUE:%.*]]) +-; CHECK-NEXT: [[TMP3:%.*]] = bitcast double [[TMP2]] to i64 +-; CHECK-NEXT: [[TMP4:%.*]] = bitcast double [[LOADED]] to i64 +-; CHECK-NEXT: [[TMP5:%.*]] = cmpxchg ptr [[PTR]], i64 [[TMP4]], i64 [[TMP3]] seq_cst seq_cst, align 8 +-; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1 +-; CHECK-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0 +-; CHECK-NEXT: [[TMP6]] = bitcast i64 [[NEWLOADED]] to double +-; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] +-; CHECK: atomicrmw.end: +-; CHECK-NEXT: ret double [[TMP6]] +-; +- %res = atomicrmw fmax ptr %ptr, double %value seq_cst +- ret double %res +-} +diff --git a/llvm/test/Transforms/AtomicExpand/LoongArch/lit.local.cfg b/llvm/test/Transforms/AtomicExpand/LoongArch/lit.local.cfg +deleted file mode 100644 +index 356cb69d7..000000000 +--- a/llvm/test/Transforms/AtomicExpand/LoongArch/lit.local.cfg ++++ /dev/null +@@ -1,5 +0,0 @@ +-config.suffixes = [".ll"] +- +-targets = set(config.root.targets_to_build.split()) +-if not "LoongArch" in targets: +- config.unsupported = True +diff --git a/llvm/test/Transforms/AtomicExpand/LoongArch/load-store-atomic.ll b/llvm/test/Transforms/AtomicExpand/LoongArch/load-store-atomic.ll +deleted file mode 100644 +index b0875669b..000000000 +--- a/llvm/test/Transforms/AtomicExpand/LoongArch/load-store-atomic.ll ++++ /dev/null +@@ -1,119 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +-; RUN: opt -S --mtriple=loongarch32 --atomic-expand %s | FileCheck %s --check-prefix=LA32 +-; RUN: opt -S --mtriple=loongarch64 --atomic-expand %s | FileCheck %s --check-prefix=LA64 +- +-define i8 @load_acquire_i8(ptr %ptr) { +-; LA32-LABEL: @load_acquire_i8( +-; LA32-NEXT: [[VAL:%.*]] = load atomic i8, ptr [[PTR:%.*]] monotonic, align 1 +-; LA32-NEXT: fence acquire +-; LA32-NEXT: ret i8 [[VAL]] +-; +-; LA64-LABEL: @load_acquire_i8( +-; LA64-NEXT: [[VAL:%.*]] = load atomic i8, ptr [[PTR:%.*]] monotonic, align 1 +-; LA64-NEXT: fence acquire +-; LA64-NEXT: ret i8 [[VAL]] +-; +- %val = load atomic i8, ptr %ptr acquire, align 1 +- ret i8 %val +-} +- +-define i16 @load_acquire_i16(ptr %ptr) { +-; LA32-LABEL: @load_acquire_i16( +-; LA32-NEXT: [[VAL:%.*]] = load atomic i16, ptr [[PTR:%.*]] monotonic, align 2 +-; LA32-NEXT: fence acquire +-; LA32-NEXT: ret i16 [[VAL]] +-; +-; LA64-LABEL: @load_acquire_i16( +-; LA64-NEXT: [[VAL:%.*]] = load atomic i16, ptr [[PTR:%.*]] monotonic, align 2 +-; LA64-NEXT: fence acquire +-; LA64-NEXT: ret i16 [[VAL]] +-; +- %val = load atomic i16, ptr %ptr acquire, align 2 +- ret i16 %val +-} +- +-define i32 @load_acquire_i32(ptr %ptr) { +-; LA32-LABEL: @load_acquire_i32( +-; LA32-NEXT: [[VAL:%.*]] = load atomic i32, ptr [[PTR:%.*]] monotonic, align 4 +-; LA32-NEXT: fence acquire +-; LA32-NEXT: ret i32 [[VAL]] +-; +-; LA64-LABEL: @load_acquire_i32( +-; LA64-NEXT: [[VAL:%.*]] = load atomic i32, ptr [[PTR:%.*]] monotonic, align 4 +-; LA64-NEXT: fence acquire +-; LA64-NEXT: ret i32 [[VAL]] +-; +- %val = load atomic i32, ptr %ptr acquire, align 4 +- ret i32 %val +-} +- +-define i64 @load_acquire_i64(ptr %ptr) { +-; LA32-LABEL: @load_acquire_i64( +-; LA32-NEXT: [[TMP1:%.*]] = call i64 @__atomic_load_8(ptr [[PTR:%.*]], i32 2) +-; LA32-NEXT: ret i64 [[TMP1]] +-; +-; LA64-LABEL: @load_acquire_i64( +-; LA64-NEXT: [[VAL:%.*]] = load atomic i64, ptr [[PTR:%.*]] monotonic, align 8 +-; LA64-NEXT: fence acquire +-; LA64-NEXT: ret i64 [[VAL]] +-; +- %val = load atomic i64, ptr %ptr acquire, align 8 +- ret i64 %val +-} +- +-define void @store_release_i8(ptr %ptr, i8 signext %v) { +-; LA32-LABEL: @store_release_i8( +-; LA32-NEXT: fence release +-; LA32-NEXT: store atomic i8 [[V:%.*]], ptr [[PTR:%.*]] monotonic, align 1 +-; LA32-NEXT: ret void +-; +-; LA64-LABEL: @store_release_i8( +-; LA64-NEXT: fence release +-; LA64-NEXT: store atomic i8 [[V:%.*]], ptr [[PTR:%.*]] monotonic, align 1 +-; LA64-NEXT: ret void +-; +- store atomic i8 %v, ptr %ptr release, align 1 +- ret void +-} +- +-define void @store_release_i16(ptr %ptr, i16 signext %v) { +-; LA32-LABEL: @store_release_i16( +-; LA32-NEXT: fence release +-; LA32-NEXT: store atomic i16 [[V:%.*]], ptr [[PTR:%.*]] monotonic, align 2 +-; LA32-NEXT: ret void +-; +-; LA64-LABEL: @store_release_i16( +-; LA64-NEXT: fence release +-; LA64-NEXT: store atomic i16 [[V:%.*]], ptr [[PTR:%.*]] monotonic, align 2 +-; LA64-NEXT: ret void +-; +- store atomic i16 %v, ptr %ptr release, align 2 +- ret void +-} +- +-define void @store_release_i32(ptr %ptr, i32 signext %v) { +-; LA32-LABEL: @store_release_i32( +-; LA32-NEXT: fence release +-; LA32-NEXT: store atomic i32 [[V:%.*]], ptr [[PTR:%.*]] monotonic, align 4 +-; LA32-NEXT: ret void +-; +-; LA64-LABEL: @store_release_i32( +-; LA64-NEXT: store atomic i32 [[V:%.*]], ptr [[PTR:%.*]] release, align 4 +-; LA64-NEXT: ret void +-; +- store atomic i32 %v, ptr %ptr release, align 4 +- ret void +-} +- +-define void @store_release_i64(ptr %ptr, i64 %v) { +-; LA32-LABEL: @store_release_i64( +-; LA32-NEXT: call void @__atomic_store_8(ptr [[PTR:%.*]], i64 [[V:%.*]], i32 3) +-; LA32-NEXT: ret void +-; +-; LA64-LABEL: @store_release_i64( +-; LA64-NEXT: store atomic i64 [[V:%.*]], ptr [[PTR:%.*]] release, align 8 +-; LA64-NEXT: ret void +-; +- store atomic i64 %v, ptr %ptr release, align 8 +- ret void +-} +diff --git a/llvm/test/Transforms/LoopDataPrefetch/LoongArch/basic.ll b/llvm/test/Transforms/LoopDataPrefetch/LoongArch/basic.ll +deleted file mode 100644 +index 55a2a2970..000000000 +--- a/llvm/test/Transforms/LoopDataPrefetch/LoongArch/basic.ll ++++ /dev/null +@@ -1,25 +0,0 @@ +-;; Tag this 'XFAIL' because we need a few more TTIs and ISels. +-; XFAIL: * +-; RUN: opt --mtriple=loongarch64 --passes=loop-data-prefetch -loongarch-enable-loop-data-prefetch -S < %s | FileCheck %s +- +-define void @foo(ptr %a, ptr %b) { +-entry: +- br label %for.body +- +-; CHECK: for.body: +-for.body: ; preds = %for.body, %entry +- %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] +- %arrayidx = getelementptr inbounds double, ptr %b, i64 %indvars.iv +-; CHECK: call void @llvm.prefetch +- %0 = load double, ptr %arrayidx, align 8 +- %add = fadd double %0, 1.000000e+00 +- %arrayidx2 = getelementptr inbounds double, ptr %a, i64 %indvars.iv +- store double %add, ptr %arrayidx2, align 8 +- %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 +- %exitcond = icmp eq i64 %indvars.iv.next, 1600 +- br i1 %exitcond, label %for.end, label %for.body +- +-; CHECK: for.end: +-for.end: ; preds = %for.body +- ret void +-} +diff --git a/llvm/test/Transforms/LoopDataPrefetch/LoongArch/lit.local.cfg b/llvm/test/Transforms/LoopDataPrefetch/LoongArch/lit.local.cfg +deleted file mode 100644 +index cc24278ac..000000000 +--- a/llvm/test/Transforms/LoopDataPrefetch/LoongArch/lit.local.cfg ++++ /dev/null +@@ -1,2 +0,0 @@ +-if not "LoongArch" in config.root.targets: +- config.unsupported = True +diff --git a/llvm/test/Transforms/LoopVectorize/LoongArch/defaults.ll b/llvm/test/Transforms/LoopVectorize/LoongArch/defaults.ll +deleted file mode 100644 +index 7172f0907..000000000 +--- a/llvm/test/Transforms/LoopVectorize/LoongArch/defaults.ll ++++ /dev/null +@@ -1,65 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 +-; RUN: opt < %s -passes=loop-vectorize -mtriple loongarch64-linux-gnu -mattr=+lasx,+auto-vec -S | FileCheck %s +- +-;; This is a collection of tests whose only purpose is to show changes in the +-;; default configuration. Please keep these tests minimal - if you're testing +-;; functionality of some specific configuration, please place that in a +-;; seperate test file with a hard coded configuration (even if that +-;; configuration is the current default). +- +-target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128" +-target triple = "loongarch64" +- +-define void @vector_add(ptr noalias nocapture %a, i64 %v) { +-; CHECK-LABEL: define void @vector_add( +-; CHECK-SAME: ptr noalias nocapture [[A:%.*]], i64 [[V:%.*]]) #[[ATTR0:[0-9]+]] { +-; CHECK-NEXT: entry: +-; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +-; CHECK: vector.ph: +-; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i64> poison, i64 [[V]], i64 0 +-; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i64> [[BROADCAST_SPLATINSERT]], <4 x i64> poison, <4 x i32> zeroinitializer +-; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] +-; CHECK: vector.body: +-; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] +-; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 +-; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP0]] +-; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i32 0 +-; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i64>, ptr [[TMP2]], align 8 +-; CHECK-NEXT: [[TMP3:%.*]] = add <4 x i64> [[WIDE_LOAD]], [[BROADCAST_SPLAT]] +-; CHECK-NEXT: store <4 x i64> [[TMP3]], ptr [[TMP2]], align 8 +-; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4 +-; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1024 +-; CHECK-NEXT: br i1 [[TMP4]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] +-; CHECK: middle.block: +-; CHECK-NEXT: br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]] +-; CHECK: scalar.ph: +-; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1024, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ] +-; CHECK-NEXT: br label [[FOR_BODY:%.*]] +-; CHECK: for.body: +-; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_BODY]] ] +-; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]] +-; CHECK-NEXT: [[ELEM:%.*]] = load i64, ptr [[ARRAYIDX]], align 8 +-; CHECK-NEXT: [[ADD:%.*]] = add i64 [[ELEM]], [[V]] +-; CHECK-NEXT: store i64 [[ADD]], ptr [[ARRAYIDX]], align 8 +-; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 +-; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 1024 +-; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]] +-; CHECK: for.end: +-; CHECK-NEXT: ret void +-; +-entry: +- br label %for.body +- +-for.body: +- %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ] +- %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv +- %elem = load i64, ptr %arrayidx +- %add = add i64 %elem, %v +- store i64 %add, ptr %arrayidx +- %iv.next = add nuw nsw i64 %iv, 1 +- %exitcond.not = icmp eq i64 %iv.next, 1024 +- br i1 %exitcond.not, label %for.end, label %for.body +- +-for.end: +- ret void +-} +diff --git a/llvm/test/Transforms/LoopVectorize/LoongArch/lit.local.cfg b/llvm/test/Transforms/LoopVectorize/LoongArch/lit.local.cfg +deleted file mode 100644 +index 9570af17f..000000000 +--- a/llvm/test/Transforms/LoopVectorize/LoongArch/lit.local.cfg ++++ /dev/null +@@ -1,4 +0,0 @@ +-config.suffixes = [".ll"] +- +-if not "LoongArch" in config.root.targets: +- config.unsupported = True +diff --git a/llvm/test/Transforms/LowerTypeTests/function-weak.ll b/llvm/test/Transforms/LowerTypeTests/function-weak.ll +index 5f9041cd2..4765102b7 100644 +--- a/llvm/test/Transforms/LowerTypeTests/function-weak.ll ++++ b/llvm/test/Transforms/LowerTypeTests/function-weak.ll +@@ -130,7 +130,7 @@ define i1 @foo(ptr %p) { + ; X86: define private void @[[JT]]() #{{.*}} align 8 { + ; ARM: define private void @[[JT]]() #{{.*}} align 4 { + ; RISCV: define private void @[[JT]]() #{{.*}} align 8 { +-; LOONGARCH64: define private void @[[JT]]() #{{.*}} align 8 { ++; LOONGARCH64: define private void @[[JT]]() #{{.*}} align 4 { + + ; CHECK: define internal void @__cfi_global_var_init() section ".text.startup" { + ; CHECK-NEXT: entry: +diff --git a/llvm/test/Transforms/LowerTypeTests/function.ll b/llvm/test/Transforms/LowerTypeTests/function.ll +index a858aace8..6a6d18bcc 100644 +--- a/llvm/test/Transforms/LowerTypeTests/function.ll ++++ b/llvm/test/Transforms/LowerTypeTests/function.ll +@@ -35,7 +35,7 @@ target datalayout = "e-p:64:64" + ; THUMB: @g = internal alias void (), getelementptr inbounds ([2 x [4 x i8]], ptr @[[JT]], i64 0, i64 1) + ; THUMBV6M: @g = internal alias void (), getelementptr inbounds ([2 x [16 x i8]], ptr @[[JT]], i64 0, i64 1) + ; RISCV: @g = internal alias void (), getelementptr inbounds ([2 x [8 x i8]], ptr @[[JT]], i64 0, i64 1) +-; LOONGARCH64: @g = internal alias void (), getelementptr inbounds ([2 x [8 x i8]], ptr @[[JT]], i64 0, i64 1) ++; LOONGARCH64: @g = internal alias void (), getelementptr inbounds ([2 x [4 x i8]], ptr @[[JT]], i64 0, i64 1) + + ; NATIVE: define hidden void @f.cfi() + ; WASM32: define void @f() !type !{{[0-9]+}} !wasm.index ![[I0:[0-9]+]] +@@ -67,7 +67,7 @@ define i1 @foo(ptr %p) { + ; THUMB: define private void @[[JT]]() #[[ATTR:.*]] align 4 { + ; THUMBV6M: define private void @[[JT]]() #[[ATTR:.*]] align 16 { + ; RISCV: define private void @[[JT]]() #[[ATTR:.*]] align 8 { +-; LOONGARCH64: define private void @[[JT]]() #[[ATTR:.*]] align 8 { ++; LOONGARCH64: define private void @[[JT]]() #[[ATTR:.*]] align 4 { + + ; X86: jmp ${0:c}@plt + ; X86-SAME: int3 +@@ -102,10 +102,8 @@ define i1 @foo(ptr %p) { + ; RISCV: tail $0@plt + ; RISCV-SAME: tail $1@plt + +-; LOONGARCH64: pcalau12i $$t0, %pc_hi20($0) +-; LOONGARCH64-SAME: jirl $$r0, $$t0, %pc_lo12($0) +-; LOONGARCH64-SAME: pcalau12i $$t0, %pc_hi20($1) +-; LOONGARCH64-SAME: jirl $$r0, $$t0, %pc_lo12($1) ++; LOONGARCH64: b $0 ++; LOONGARCH64-SAME: b $1 + + ; NATIVE-SAME: "s,s"(ptr @f.cfi, ptr @g.cfi) + +diff --git a/llvm/test/Verifier/LoongArch/intrinsic-immarg.ll b/llvm/test/Verifier/LoongArch/intrinsic-immarg.ll +deleted file mode 100644 +index 488f77ff5..000000000 +--- a/llvm/test/Verifier/LoongArch/intrinsic-immarg.ll ++++ /dev/null +@@ -1,20 +0,0 @@ +-; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s +- +-declare ptr @llvm.frameaddress(i32 immarg) +-declare ptr @llvm.returnaddress(i32 immarg) +- +-define ptr @non_const_depth_frameaddress(i32 %x) nounwind { +- ; CHECK: immarg operand has non-immediate parameter +- ; CHECK-NEXT: i32 %x +- ; CHECK-NEXT: %1 = call ptr @llvm.frameaddress.p0(i32 %x) +- %1 = call ptr @llvm.frameaddress(i32 %x) +- ret ptr %1 +-} +- +-define ptr @non_const_depth_returnaddress(i32 %x) nounwind { +- ; CHECK: immarg operand has non-immediate parameter +- ; CHECK-NEXT: i32 %x +- ; CHECK-NEXT: %1 = call ptr @llvm.returnaddress(i32 %x) +- %1 = call ptr @llvm.returnaddress(i32 %x) +- ret ptr %1 +-} +diff --git a/llvm/test/Verifier/LoongArch/lit.local.cfg b/llvm/test/Verifier/LoongArch/lit.local.cfg +deleted file mode 100644 +index cc24278ac..000000000 +--- a/llvm/test/Verifier/LoongArch/lit.local.cfg ++++ /dev/null +@@ -1,2 +0,0 @@ +-if not "LoongArch" in config.root.targets: +- config.unsupported = True +diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_function_name.ll b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_function_name.ll +deleted file mode 100644 +index 058245269..000000000 +--- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_function_name.ll ++++ /dev/null +@@ -1,8 +0,0 @@ +-; Check that we accept functions with '$' in the name. +- +-; RUN: llc -mtriple=loongarch32-unknown-linux < %s | FileCheck %s +- +-define hidden i32 @"_Z54bar$ompvariant$bar"() { +-entry: +- ret i32 2 +-} +diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_function_name.ll.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_function_name.ll.expected +deleted file mode 100644 +index 060a6b397..000000000 +--- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_function_name.ll.expected ++++ /dev/null +@@ -1,13 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; Check that we accept functions with '$' in the name. +- +-; RUN: llc -mtriple=loongarch32-unknown-linux < %s | FileCheck %s +- +-define hidden i32 @"_Z54bar$ompvariant$bar"() { +-; CHECK-LABEL: _Z54bar$ompvariant$bar: +-; CHECK: # %bb.0: # %entry +-; CHECK-NEXT: ori $a0, $zero, 2 +-; CHECK-NEXT: ret +-entry: +- ret i32 2 +-} +diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll +deleted file mode 100644 +index 5de94d73d..000000000 +--- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll ++++ /dev/null +@@ -1,63 +0,0 @@ +-; RUN: llc --enable-machine-outliner --mtriple=loongarch32-unknown-linux < %s | FileCheck %s +-@x = dso_local global i32 0, align 4 +- +-define dso_local i32 @check_boundaries() #0 { +- %1 = alloca i32, align 4 +- %2 = alloca i32, align 4 +- %3 = alloca i32, align 4 +- %4 = alloca i32, align 4 +- %5 = alloca i32, align 4 +- store i32 0, ptr %1, align 4 +- store i32 0, ptr %2, align 4 +- %6 = load i32, ptr %2, align 4 +- %7 = icmp ne i32 %6, 0 +- br i1 %7, label %9, label %8 +- +- store i32 1, ptr %2, align 4 +- store i32 2, ptr %3, align 4 +- store i32 3, ptr %4, align 4 +- store i32 4, ptr %5, align 4 +- br label %10 +- +- store i32 1, ptr %4, align 4 +- br label %10 +- +- %11 = load i32, ptr %2, align 4 +- %12 = icmp ne i32 %11, 0 +- br i1 %12, label %14, label %13 +- +- store i32 1, ptr %2, align 4 +- store i32 2, ptr %3, align 4 +- store i32 3, ptr %4, align 4 +- store i32 4, ptr %5, align 4 +- br label %15 +- +- store i32 1, ptr %4, align 4 +- br label %15 +- +- ret i32 0 +-} +- +-define dso_local i32 @main() #0 { +- %1 = alloca i32, align 4 +- %2 = alloca i32, align 4 +- %3 = alloca i32, align 4 +- %4 = alloca i32, align 4 +- %5 = alloca i32, align 4 +- +- store i32 0, ptr %1, align 4 +- store i32 0, ptr @x, align 4 +- store i32 1, ptr %2, align 4 +- store i32 2, ptr %3, align 4 +- store i32 3, ptr %4, align 4 +- store i32 4, ptr %5, align 4 +- store i32 1, ptr @x, align 4 +- call void asm sideeffect "", "~{memory},~{dirflag},~{fpsr},~{flags}"() +- store i32 1, ptr %2, align 4 +- store i32 2, ptr %3, align 4 +- store i32 3, ptr %4, align 4 +- store i32 4, ptr %5, align 4 +- ret i32 0 +-} +- +-attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" } +diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected +deleted file mode 100644 +index e5bdc8b01..000000000 +--- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected ++++ /dev/null +@@ -1,146 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --include-generated-funcs +-; RUN: llc --enable-machine-outliner --mtriple=loongarch32-unknown-linux < %s | FileCheck %s +-@x = dso_local global i32 0, align 4 +- +-define dso_local i32 @check_boundaries() #0 { +- %1 = alloca i32, align 4 +- %2 = alloca i32, align 4 +- %3 = alloca i32, align 4 +- %4 = alloca i32, align 4 +- %5 = alloca i32, align 4 +- store i32 0, ptr %1, align 4 +- store i32 0, ptr %2, align 4 +- %6 = load i32, ptr %2, align 4 +- %7 = icmp ne i32 %6, 0 +- br i1 %7, label %9, label %8 +- +- store i32 1, ptr %2, align 4 +- store i32 2, ptr %3, align 4 +- store i32 3, ptr %4, align 4 +- store i32 4, ptr %5, align 4 +- br label %10 +- +- store i32 1, ptr %4, align 4 +- br label %10 +- +- %11 = load i32, ptr %2, align 4 +- %12 = icmp ne i32 %11, 0 +- br i1 %12, label %14, label %13 +- +- store i32 1, ptr %2, align 4 +- store i32 2, ptr %3, align 4 +- store i32 3, ptr %4, align 4 +- store i32 4, ptr %5, align 4 +- br label %15 +- +- store i32 1, ptr %4, align 4 +- br label %15 +- +- ret i32 0 +-} +- +-define dso_local i32 @main() #0 { +- %1 = alloca i32, align 4 +- %2 = alloca i32, align 4 +- %3 = alloca i32, align 4 +- %4 = alloca i32, align 4 +- %5 = alloca i32, align 4 +- +- store i32 0, ptr %1, align 4 +- store i32 0, ptr @x, align 4 +- store i32 1, ptr %2, align 4 +- store i32 2, ptr %3, align 4 +- store i32 3, ptr %4, align 4 +- store i32 4, ptr %5, align 4 +- store i32 1, ptr @x, align 4 +- call void asm sideeffect "", "~{memory},~{dirflag},~{fpsr},~{flags}"() +- store i32 1, ptr %2, align 4 +- store i32 2, ptr %3, align 4 +- store i32 3, ptr %4, align 4 +- store i32 4, ptr %5, align 4 +- ret i32 0 +-} +- +-attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" } +-; CHECK-LABEL: check_boundaries: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.w $sp, $sp, -32 +-; CHECK-NEXT: .cfi_def_cfa_offset 32 +-; CHECK-NEXT: st.w $ra, $sp, 28 # 4-byte Folded Spill +-; CHECK-NEXT: st.w $fp, $sp, 24 # 4-byte Folded Spill +-; CHECK-NEXT: .cfi_offset 1, -4 +-; CHECK-NEXT: .cfi_offset 22, -8 +-; CHECK-NEXT: addi.w $fp, $sp, 32 +-; CHECK-NEXT: .cfi_def_cfa 22, 0 +-; CHECK-NEXT: st.w $zero, $fp, -16 +-; CHECK-NEXT: st.w $zero, $fp, -12 +-; CHECK-NEXT: beqz $zero, .LBB0_3 +-; CHECK-NEXT: # %bb.1: +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: st.w $a0, $fp, -24 +-; CHECK-NEXT: ld.w $a0, $fp, -16 +-; CHECK-NEXT: beqz $a0, .LBB0_4 +-; CHECK-NEXT: .LBB0_2: +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: st.w $a0, $fp, -24 +-; CHECK-NEXT: b .LBB0_5 +-; CHECK-NEXT: .LBB0_3: +-; CHECK-NEXT: ori $a0, $zero, 2 +-; CHECK-NEXT: st.w $a0, $fp, -20 +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: st.w $a0, $fp, -16 +-; CHECK-NEXT: ori $a0, $zero, 3 +-; CHECK-NEXT: st.w $a0, $fp, -24 +-; CHECK-NEXT: ori $a0, $zero, 4 +-; CHECK-NEXT: st.w $a0, $fp, -28 +-; CHECK-NEXT: ld.w $a0, $fp, -16 +-; CHECK-NEXT: bnez $a0, .LBB0_2 +-; CHECK-NEXT: .LBB0_4: +-; CHECK-NEXT: ori $a0, $zero, 2 +-; CHECK-NEXT: st.w $a0, $fp, -20 +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: st.w $a0, $fp, -16 +-; CHECK-NEXT: ori $a0, $zero, 3 +-; CHECK-NEXT: st.w $a0, $fp, -24 +-; CHECK-NEXT: ori $a0, $zero, 4 +-; CHECK-NEXT: st.w $a0, $fp, -28 +-; CHECK-NEXT: .LBB0_5: +-; CHECK-NEXT: move $a0, $zero +-; CHECK-NEXT: ld.w $fp, $sp, 24 # 4-byte Folded Reload +-; CHECK-NEXT: ld.w $ra, $sp, 28 # 4-byte Folded Reload +-; CHECK-NEXT: addi.w $sp, $sp, 32 +-; CHECK-NEXT: ret +-; +-; CHECK-LABEL: main: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.w $sp, $sp, -32 +-; CHECK-NEXT: .cfi_def_cfa_offset 32 +-; CHECK-NEXT: st.w $ra, $sp, 28 # 4-byte Folded Spill +-; CHECK-NEXT: st.w $fp, $sp, 24 # 4-byte Folded Spill +-; CHECK-NEXT: .cfi_offset 1, -4 +-; CHECK-NEXT: .cfi_offset 22, -8 +-; CHECK-NEXT: addi.w $fp, $sp, 32 +-; CHECK-NEXT: .cfi_def_cfa 22, 0 +-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(x) +-; CHECK-NEXT: addi.w $a0, $a0, %pc_lo12(x) +-; CHECK-NEXT: ori $a1, $zero, 1 +-; CHECK-NEXT: st.w $a1, $a0, 0 +-; CHECK-NEXT: st.w $zero, $fp, -12 +-; CHECK-NEXT: st.w $a1, $fp, -16 +-; CHECK-NEXT: ori $a0, $zero, 2 +-; CHECK-NEXT: st.w $a0, $fp, -20 +-; CHECK-NEXT: ori $a2, $zero, 3 +-; CHECK-NEXT: st.w $a2, $fp, -24 +-; CHECK-NEXT: ori $a3, $zero, 4 +-; CHECK-NEXT: st.w $a3, $fp, -28 +-; CHECK-NEXT: #APP +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: st.w $a0, $fp, -20 +-; CHECK-NEXT: st.w $a1, $fp, -16 +-; CHECK-NEXT: st.w $a2, $fp, -24 +-; CHECK-NEXT: st.w $a3, $fp, -28 +-; CHECK-NEXT: move $a0, $zero +-; CHECK-NEXT: ld.w $fp, $sp, 24 # 4-byte Folded Reload +-; CHECK-NEXT: ld.w $ra, $sp, 28 # 4-byte Folded Reload +-; CHECK-NEXT: addi.w $sp, $sp, 32 +-; CHECK-NEXT: ret +diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected +deleted file mode 100644 +index 20e34cdf3..000000000 +--- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected ++++ /dev/null +@@ -1,145 +0,0 @@ +-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +-; RUN: llc --enable-machine-outliner --mtriple=loongarch32-unknown-linux < %s | FileCheck %s +-@x = dso_local global i32 0, align 4 +- +-define dso_local i32 @check_boundaries() #0 { +-; CHECK-LABEL: check_boundaries: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.w $sp, $sp, -32 +-; CHECK-NEXT: .cfi_def_cfa_offset 32 +-; CHECK-NEXT: st.w $ra, $sp, 28 # 4-byte Folded Spill +-; CHECK-NEXT: st.w $fp, $sp, 24 # 4-byte Folded Spill +-; CHECK-NEXT: .cfi_offset 1, -4 +-; CHECK-NEXT: .cfi_offset 22, -8 +-; CHECK-NEXT: addi.w $fp, $sp, 32 +-; CHECK-NEXT: .cfi_def_cfa 22, 0 +-; CHECK-NEXT: st.w $zero, $fp, -16 +-; CHECK-NEXT: st.w $zero, $fp, -12 +-; CHECK-NEXT: beqz $zero, .LBB0_3 +-; CHECK-NEXT: # %bb.1: +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: st.w $a0, $fp, -24 +-; CHECK-NEXT: ld.w $a0, $fp, -16 +-; CHECK-NEXT: beqz $a0, .LBB0_4 +-; CHECK-NEXT: .LBB0_2: +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: st.w $a0, $fp, -24 +-; CHECK-NEXT: b .LBB0_5 +-; CHECK-NEXT: .LBB0_3: +-; CHECK-NEXT: ori $a0, $zero, 2 +-; CHECK-NEXT: st.w $a0, $fp, -20 +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: st.w $a0, $fp, -16 +-; CHECK-NEXT: ori $a0, $zero, 3 +-; CHECK-NEXT: st.w $a0, $fp, -24 +-; CHECK-NEXT: ori $a0, $zero, 4 +-; CHECK-NEXT: st.w $a0, $fp, -28 +-; CHECK-NEXT: ld.w $a0, $fp, -16 +-; CHECK-NEXT: bnez $a0, .LBB0_2 +-; CHECK-NEXT: .LBB0_4: +-; CHECK-NEXT: ori $a0, $zero, 2 +-; CHECK-NEXT: st.w $a0, $fp, -20 +-; CHECK-NEXT: ori $a0, $zero, 1 +-; CHECK-NEXT: st.w $a0, $fp, -16 +-; CHECK-NEXT: ori $a0, $zero, 3 +-; CHECK-NEXT: st.w $a0, $fp, -24 +-; CHECK-NEXT: ori $a0, $zero, 4 +-; CHECK-NEXT: st.w $a0, $fp, -28 +-; CHECK-NEXT: .LBB0_5: +-; CHECK-NEXT: move $a0, $zero +-; CHECK-NEXT: ld.w $fp, $sp, 24 # 4-byte Folded Reload +-; CHECK-NEXT: ld.w $ra, $sp, 28 # 4-byte Folded Reload +-; CHECK-NEXT: addi.w $sp, $sp, 32 +-; CHECK-NEXT: ret +- %1 = alloca i32, align 4 +- %2 = alloca i32, align 4 +- %3 = alloca i32, align 4 +- %4 = alloca i32, align 4 +- %5 = alloca i32, align 4 +- store i32 0, ptr %1, align 4 +- store i32 0, ptr %2, align 4 +- %6 = load i32, ptr %2, align 4 +- %7 = icmp ne i32 %6, 0 +- br i1 %7, label %9, label %8 +- +- store i32 1, ptr %2, align 4 +- store i32 2, ptr %3, align 4 +- store i32 3, ptr %4, align 4 +- store i32 4, ptr %5, align 4 +- br label %10 +- +- store i32 1, ptr %4, align 4 +- br label %10 +- +- %11 = load i32, ptr %2, align 4 +- %12 = icmp ne i32 %11, 0 +- br i1 %12, label %14, label %13 +- +- store i32 1, ptr %2, align 4 +- store i32 2, ptr %3, align 4 +- store i32 3, ptr %4, align 4 +- store i32 4, ptr %5, align 4 +- br label %15 +- +- store i32 1, ptr %4, align 4 +- br label %15 +- +- ret i32 0 +-} +- +-define dso_local i32 @main() #0 { +-; CHECK-LABEL: main: +-; CHECK: # %bb.0: +-; CHECK-NEXT: addi.w $sp, $sp, -32 +-; CHECK-NEXT: .cfi_def_cfa_offset 32 +-; CHECK-NEXT: st.w $ra, $sp, 28 # 4-byte Folded Spill +-; CHECK-NEXT: st.w $fp, $sp, 24 # 4-byte Folded Spill +-; CHECK-NEXT: .cfi_offset 1, -4 +-; CHECK-NEXT: .cfi_offset 22, -8 +-; CHECK-NEXT: addi.w $fp, $sp, 32 +-; CHECK-NEXT: .cfi_def_cfa 22, 0 +-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(x) +-; CHECK-NEXT: addi.w $a0, $a0, %pc_lo12(x) +-; CHECK-NEXT: ori $a1, $zero, 1 +-; CHECK-NEXT: st.w $a1, $a0, 0 +-; CHECK-NEXT: st.w $zero, $fp, -12 +-; CHECK-NEXT: st.w $a1, $fp, -16 +-; CHECK-NEXT: ori $a0, $zero, 2 +-; CHECK-NEXT: st.w $a0, $fp, -20 +-; CHECK-NEXT: ori $a2, $zero, 3 +-; CHECK-NEXT: st.w $a2, $fp, -24 +-; CHECK-NEXT: ori $a3, $zero, 4 +-; CHECK-NEXT: st.w $a3, $fp, -28 +-; CHECK-NEXT: #APP +-; CHECK-NEXT: #NO_APP +-; CHECK-NEXT: st.w $a0, $fp, -20 +-; CHECK-NEXT: st.w $a1, $fp, -16 +-; CHECK-NEXT: st.w $a2, $fp, -24 +-; CHECK-NEXT: st.w $a3, $fp, -28 +-; CHECK-NEXT: move $a0, $zero +-; CHECK-NEXT: ld.w $fp, $sp, 24 # 4-byte Folded Reload +-; CHECK-NEXT: ld.w $ra, $sp, 28 # 4-byte Folded Reload +-; CHECK-NEXT: addi.w $sp, $sp, 32 +-; CHECK-NEXT: ret +- %1 = alloca i32, align 4 +- %2 = alloca i32, align 4 +- %3 = alloca i32, align 4 +- %4 = alloca i32, align 4 +- %5 = alloca i32, align 4 +- +- store i32 0, ptr %1, align 4 +- store i32 0, ptr @x, align 4 +- store i32 1, ptr %2, align 4 +- store i32 2, ptr %3, align 4 +- store i32 3, ptr %4, align 4 +- store i32 4, ptr %5, align 4 +- store i32 1, ptr @x, align 4 +- call void asm sideeffect "", "~{memory},~{dirflag},~{fpsr},~{flags}"() +- store i32 1, ptr %2, align 4 +- store i32 2, ptr %3, align 4 +- store i32 3, ptr %4, align 4 +- store i32 4, ptr %5, align 4 +- ret i32 0 +-} +- +-attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" } +diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/loongarch-function-name.test b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/loongarch-function-name.test +deleted file mode 100644 +index f1dc0989c..000000000 +--- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/loongarch-function-name.test ++++ /dev/null +@@ -1,5 +0,0 @@ +-# REQUIRES: loongarch-registered-target +-## Check that functions names with '$' are processed correctly +- +-# RUN: cp -f %S/Inputs/loongarch_function_name.ll %t.ll && %update_llc_test_checks %t.ll +-# RUN: diff -u %S/Inputs/loongarch_function_name.ll.expected %t.ll +diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/loongarch_generated_funcs.test b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/loongarch_generated_funcs.test +deleted file mode 100644 +index 2209d3036..000000000 +--- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/loongarch_generated_funcs.test ++++ /dev/null +@@ -1,17 +0,0 @@ +-# REQUIRES: loongarch-registered-target +- +-## Check that generated functions are included. +-# RUN: cp -f %S/Inputs/loongarch_generated_funcs.ll %t.ll && %update_llc_test_checks --include-generated-funcs %t.ll +-# RUN: diff -u %t.ll %S/Inputs/loongarch_generated_funcs.ll.generated.expected +- +-## Check that running the script again does not change the result: +-# RUN: %update_llc_test_checks --include-generated-funcs %t.ll +-# RUN: diff -u %t.ll %S/Inputs/loongarch_generated_funcs.ll.generated.expected +- +-## Check that generated functions are not included. +-# RUN: cp -f %S/Inputs/loongarch_generated_funcs.ll %t.ll && %update_llc_test_checks %t.ll +-# RUN: diff -u %t.ll %S/Inputs/loongarch_generated_funcs.ll.nogenerated.expected +- +-## Check that running the script again does not change the result: +-# RUN: %update_llc_test_checks %t.ll +-# RUN: diff -u %t.ll %S/Inputs/loongarch_generated_funcs.ll.nogenerated.expected +diff --git a/llvm/test/tools/llvm-objcopy/ELF/binary-output-target.test b/llvm/test/tools/llvm-objcopy/ELF/binary-output-target.test +index f88b75750..bcc7b6fbf 100644 +--- a/llvm/test/tools/llvm-objcopy/ELF/binary-output-target.test ++++ b/llvm/test/tools/llvm-objcopy/ELF/binary-output-target.test +@@ -42,12 +42,6 @@ + # RUN: llvm-objcopy -I binary -O elf32-hexagon %t.txt %t.hexagon.o + # RUN: llvm-readobj --file-headers %t.hexagon.o | FileCheck %s --check-prefixes=CHECK,LE,HEXAGON,32 + +-# RUN: llvm-objcopy -I binary -O elf32-loongarch %t.txt %t.la32.o +-# RUN: llvm-readobj --file-headers %t.la32.o | FileCheck %s --check-prefixes=CHECK,LE,LA32,32 +- +-# RUN: llvm-objcopy -I binary -O elf64-loongarch %t.txt %t.la64.o +-# RUN: llvm-readobj --file-headers %t.la64.o | FileCheck %s --check-prefixes=CHECK,LE,LA64,64 +- + # RUN: llvm-objcopy -I binary -O elf64-s390 %t.txt %t.s390x.o + # RUN: llvm-readobj --file-headers %t.s390x.o | FileCheck %s --check-prefixes=CHECK,BE,S390X,64 + +@@ -58,8 +52,6 @@ + # ARM-SAME: littlearm + # HEXAGON-SAME: hexagon + # I386-SAME: i386 +-# LA32-SAME: loongarch{{$}} +-# LA64-SAME: loongarch{{$}} + # MIPS-SAME: mips{{$}} + # RISCV32-SAME: riscv{{$}} + # RISCV64-SAME: riscv{{$}} +@@ -74,8 +66,6 @@ + # ARM-NEXT: Arch: arm + # HEXAGON-NEXT: Arch: hexagon + # I386-NEXT: Arch: i386 +-# LA32-NEXT: Arch: loongarch32 +-# LA64-NEXT: Arch: loongarch64 + # MIPS-NEXT: Arch: mips{{$}} + # PPC32BE-NEXT: Arch: powerpc{{$}} + # PPC32LE-NEXT: Arch: powerpcle{{$}} +@@ -112,8 +102,6 @@ + # ARM-NEXT: Machine: EM_ARM (0x28) + # HEXAGON-NEXT: Machine: EM_HEXAGON (0xA4) + # I386-NEXT: Machine: EM_386 (0x3) +-# LA32-NEXT: Machine: EM_LOONGARCH (0x102) +-# LA64-NEXT: Machine: EM_LOONGARCH (0x102) + # MIPS-NEXT: Machine: EM_MIPS (0x8) + # PPC32-NEXT: Machine: EM_PPC (0x14) + # PPC64-NEXT: Machine: EM_PPC64 (0x15) +diff --git a/llvm/test/tools/llvm-objcopy/ELF/cross-arch-headers.test b/llvm/test/tools/llvm-objcopy/ELF/cross-arch-headers.test +index 9a8128611..db7eb3707 100644 +--- a/llvm/test/tools/llvm-objcopy/ELF/cross-arch-headers.test ++++ b/llvm/test/tools/llvm-objcopy/ELF/cross-arch-headers.test +@@ -109,14 +109,6 @@ + # RUN: llvm-readobj --file-headers %t.elf32_hexagon.o | FileCheck %s --check-prefixes=CHECK,LE,HEXAGON,32,SYSV + # RUN: llvm-readobj --file-headers %t.elf32_hexagon.dwo | FileCheck %s --check-prefixes=CHECK,LE,HEXAGON,32,SYSV + +-# RUN: llvm-objcopy %t.o -O elf32-loongarch %t.elf32_loongarch.o --split-dwo=%t.elf32_loongarch.dwo +-# RUN: llvm-readobj --file-headers %t.elf32_loongarch.o | FileCheck %s --check-prefixes=CHECK,LE,LA32,32,SYSV +-# RUN: llvm-readobj --file-headers %t.elf32_loongarch.dwo | FileCheck %s --check-prefixes=CHECK,LE,LA32,32,SYSV +- +-# RUN: llvm-objcopy %t.o -O elf64-loongarch %t.elf64_loongarch.o --split-dwo=%t.elf64_loongarch.dwo +-# RUN: llvm-readobj --file-headers %t.elf64_loongarch.o | FileCheck %s --check-prefixes=CHECK,LE,LA64,64,SYSV +-# RUN: llvm-readobj --file-headers %t.elf64_loongarch.dwo | FileCheck %s --check-prefixes=CHECK,LE,LA64,64,SYSV +- + # RUN: llvm-objcopy %t.o -O elf64-s390 %t.elf64_s390.o --split-dwo=%t.elf64_s390.dwo + # RUN: llvm-readobj --file-headers %t.elf64_s390.o | FileCheck %s --check-prefixes=CHECK,BE,S390X,64,SYSV + # RUN: llvm-readobj --file-headers %t.elf64_s390.dwo | FileCheck %s --check-prefixes=CHECK,BE,S390X,64,SYSV +@@ -156,8 +148,6 @@ Symbols: + # AARCH-SAME: aarch64 + # ARM-SAME: littlearm + # HEXAGON-SAME: hexagon +-# LA32-SAME: loongarch{{$}} +-# LA64-SAME: loongarch{{$}} + # MIPS-SAME: mips + # PPCBE-SAME: powerpc{{$}} + # PPCLE-SAME: powerpcle{{$}} +@@ -173,8 +163,6 @@ Symbols: + # AARCH-NEXT: Arch: aarch64 + # ARM-NEXT: Arch: arm + # HEXAGON-NEXT: Arch: hexagon +-# LA32-NEXT: Arch: loongarch32 +-# LA64-NEXT: Arch: loongarch64 + # MIPSBE-NEXT: Arch: mips{{$}} + # MIPSLE-NEXT: Arch: mipsel{{$}} + # MIPS64BE-NEXT: Arch: mips64{{$}} +@@ -208,8 +196,6 @@ Symbols: + # HEXAGON: Machine: EM_HEXAGON (0xA4) + # I386: Machine: EM_386 (0x3) + # IAMCU: Machine: EM_IAMCU (0x6) +-# LA32: Machine: EM_LOONGARCH (0x102) +-# LA64: Machine: EM_LOONGARCH (0x102) + # MIPS: Machine: EM_MIPS (0x8) + # PPC32: Machine: EM_PPC (0x14) + # PPC64: Machine: EM_PPC64 (0x15) +diff --git a/llvm/test/tools/llvm-objdump/ELF/LoongArch/branches.s b/llvm/test/tools/llvm-objdump/ELF/LoongArch/branches.s +deleted file mode 100644 +index 8cb00aef9..000000000 +--- a/llvm/test/tools/llvm-objdump/ELF/LoongArch/branches.s ++++ /dev/null +@@ -1,76 +0,0 @@ +-# RUN: llvm-mc --triple=loongarch32 --filetype=obj < %s | \ +-# RUN: llvm-objdump -d --no-show-raw-insn - | FileCheck %s +-# RUN: llvm-mc --triple=loongarch64 --filetype=obj < %s | \ +-# RUN: llvm-objdump -d --no-show-raw-insn - | FileCheck %s +- +-# CHECK-LABEL: : +-foo: +-# CHECK: beq $a0, $a1, 108 +-beq $a0, $a1, .Llocal +-# CHECK: bne $a0, $a1, 104 +-bne $a0, $a1, .Llocal +-# CHECK: blt $a0, $a1, 100 +-blt $a0, $a1, .Llocal +-# CHECK: bltu $a0, $a1, 96 +-bltu $a0, $a1, .Llocal +-# CHECK: bge $a0, $a1, 92 +-bge $a0, $a1, .Llocal +-# CHECK: bgeu $a0, $a1, 88 +-bgeu $a0, $a1, .Llocal +-# CHECK: beqz $a0, 84 +-beqz $a0, .Llocal +-# CHECK: bnez $a0, 80 +-bnez $a0, .Llocal +-# CHECK: bceqz $fcc6, 76 +-bceqz $fcc6, .Llocal +-# CHECK: bcnez $fcc6, 72 +-bcnez $fcc6, .Llocal +- +-# CHECK: beq $a0, $a1, 76 +-beq $a0, $a1, bar +-# CHECK: bne $a0, $a1, 72 +-bne $a0, $a1, bar +-# CHECK: blt $a0, $a1, 68 +-blt $a0, $a1, bar +-# CHECK: bltu $a0, $a1, 64 +-bltu $a0, $a1, bar +-# CHECK: bge $a0, $a1, 60 +-bge $a0, $a1, bar +-# CHECK: bgeu $a0, $a1, 56 +-bgeu $a0, $a1, bar +-# CHECK: beqz $a0, 52 +-beqz $a0, bar +-# CHECK: bnez $a0, 48 +-bnez $a0, bar +-# CHECK: bceqz $fcc6, 44 +-bceqz $fcc6, bar +-# CHECK: bcnez $fcc6, 40 +-bcnez $fcc6, bar +- +-# CHECK: b 28 +-b .Llocal +-# CHECK: b 32 +-b bar +- +-# CHECK: bl 20 +-bl .Llocal +-# CHECK: bl 24 +-bl bar +- +-# CHECK: jirl $zero, $a0, 4{{$}} +-jirl $zero, $a0, 4 +-# CHECK: jirl $ra, $a0, 4{{$}} +-jirl $ra, $a0, 4 +-# CHECK: ret +-ret +- +-.Llocal: +-# CHECK: 6c: nop +-# CHECK: nop +-nop +-nop +- +-# CHECK-LABEL: : +-bar: +-# CHECK: 74: nop +-nop +diff --git a/llvm/test/tools/llvm-objdump/ELF/LoongArch/lit.local.cfg b/llvm/test/tools/llvm-objdump/ELF/LoongArch/lit.local.cfg +deleted file mode 100644 +index cc24278ac..000000000 +--- a/llvm/test/tools/llvm-objdump/ELF/LoongArch/lit.local.cfg ++++ /dev/null +@@ -1,2 +0,0 @@ +-if not "LoongArch" in config.root.targets: +- config.unsupported = True +diff --git a/llvm/test/tools/llvm-profgen/lit.local.cfg b/llvm/test/tools/llvm-profgen/lit.local.cfg +index c628a80ff..5d29b90e2 100644 +--- a/llvm/test/tools/llvm-profgen/lit.local.cfg ++++ b/llvm/test/tools/llvm-profgen/lit.local.cfg +@@ -3,5 +3,5 @@ import lit.util + + config.suffixes = [".test", ".ll", ".s", ".yaml"] + +-if not "X86" in config.root.targets: ++if not ('X86' in config.root.targets and 'LoongArch' in config.root.targets): + config.unsupported = True +diff --git a/llvm/test/tools/llvm-readobj/ELF/loongarch-eflags.test b/llvm/test/tools/llvm-readobj/ELF/loongarch-eflags.test +deleted file mode 100644 +index 824dcb2c0..000000000 +--- a/llvm/test/tools/llvm-readobj/ELF/loongarch-eflags.test ++++ /dev/null +@@ -1,103 +0,0 @@ +-## Check llvm-readobj's ability to decode all possible LoongArch e_flags field +-## values. +- +-## Not all combinations covered here exist in reality (such as the v0 ILP32* +-## objects) but they are included nevertheless for completeness. +- +-# RUN: yaml2obj %s -o %t-lp64s -DCLASS=64 -DABI_MODIFIER=SOFT -DOBJABI_VER=0 +-# RUN: llvm-readobj -h %t-lp64s | FileCheck --check-prefixes=READOBJ-LP64,READOBJ-SOFT-V0 %s +-# RUN: llvm-readelf -h %t-lp64s | FileCheck --check-prefixes=READELF-LP64,READELF-SOFT-V0 --match-full-lines %s +- +-# RUN: yaml2obj %s -o %t-lp64f -DCLASS=64 -DABI_MODIFIER=SINGLE -DOBJABI_VER=0 +-# RUN: llvm-readobj -h %t-lp64f | FileCheck --check-prefixes=READOBJ-LP64,READOBJ-SINGLE-V0 %s +-# RUN: llvm-readelf -h %t-lp64f | FileCheck --check-prefixes=READELF-LP64,READELF-SINGLE-V0 --match-full-lines %s +- +-# RUN: yaml2obj %s -o %t-lp64d -DCLASS=64 -DABI_MODIFIER=DOUBLE -DOBJABI_VER=0 +-# RUN: llvm-readobj -h %t-lp64d | FileCheck --check-prefixes=READOBJ-LP64,READOBJ-DOUBLE-V0 %s +-# RUN: llvm-readelf -h %t-lp64d | FileCheck --check-prefixes=READELF-LP64,READELF-DOUBLE-V0 --match-full-lines %s +- +-# RUN: yaml2obj %s -o %t-ilp32s -DCLASS=32 -DABI_MODIFIER=SOFT -DOBJABI_VER=0 +-# RUN: llvm-readobj -h %t-ilp32s | FileCheck --check-prefixes=READOBJ-ILP32,READOBJ-SOFT-V0 %s +-# RUN: llvm-readelf -h %t-ilp32s | FileCheck --check-prefixes=READELF-ILP32,READELF-SOFT-V0 --match-full-lines %s +- +-# RUN: yaml2obj %s -o %t-ilp32f -DCLASS=32 -DABI_MODIFIER=SINGLE -DOBJABI_VER=0 +-# RUN: llvm-readobj -h %t-ilp32f | FileCheck --check-prefixes=READOBJ-ILP32,READOBJ-SINGLE-V0 %s +-# RUN: llvm-readelf -h %t-ilp32f | FileCheck --check-prefixes=READELF-ILP32,READELF-SINGLE-V0 --match-full-lines %s +- +-# RUN: yaml2obj %s -o %t-ilp32d -DCLASS=32 -DABI_MODIFIER=DOUBLE -DOBJABI_VER=0 +-# RUN: llvm-readobj -h %t-ilp32d | FileCheck --check-prefixes=READOBJ-ILP32,READOBJ-DOUBLE-V0 %s +-# RUN: llvm-readelf -h %t-ilp32d | FileCheck --check-prefixes=READELF-ILP32,READELF-DOUBLE-V0 --match-full-lines %s +- +-# RUN: yaml2obj %s -o %t-lp64s -DCLASS=64 -DABI_MODIFIER=SOFT -DOBJABI_VER=1 +-# RUN: llvm-readobj -h %t-lp64s | FileCheck --check-prefixes=READOBJ-LP64,READOBJ-SOFT-V1 %s +-# RUN: llvm-readelf -h %t-lp64s | FileCheck --check-prefixes=READELF-LP64,READELF-SOFT-V1 --match-full-lines %s +- +-# RUN: yaml2obj %s -o %t-lp64f -DCLASS=64 -DABI_MODIFIER=SINGLE -DOBJABI_VER=1 +-# RUN: llvm-readobj -h %t-lp64f | FileCheck --check-prefixes=READOBJ-LP64,READOBJ-SINGLE-V1 %s +-# RUN: llvm-readelf -h %t-lp64f | FileCheck --check-prefixes=READELF-LP64,READELF-SINGLE-V1 --match-full-lines %s +- +-# RUN: yaml2obj %s -o %t-lp64d -DCLASS=64 -DABI_MODIFIER=DOUBLE -DOBJABI_VER=1 +-# RUN: llvm-readobj -h %t-lp64d | FileCheck --check-prefixes=READOBJ-LP64,READOBJ-DOUBLE-V1 %s +-# RUN: llvm-readelf -h %t-lp64d | FileCheck --check-prefixes=READELF-LP64,READELF-DOUBLE-V1 --match-full-lines %s +- +-# RUN: yaml2obj %s -o %t-ilp32s -DCLASS=32 -DABI_MODIFIER=SOFT -DOBJABI_VER=1 +-# RUN: llvm-readobj -h %t-ilp32s | FileCheck --check-prefixes=READOBJ-ILP32,READOBJ-SOFT-V1 %s +-# RUN: llvm-readelf -h %t-ilp32s | FileCheck --check-prefixes=READELF-ILP32,READELF-SOFT-V1 --match-full-lines %s +- +-# RUN: yaml2obj %s -o %t-ilp32f -DCLASS=32 -DABI_MODIFIER=SINGLE -DOBJABI_VER=1 +-# RUN: llvm-readobj -h %t-ilp32f | FileCheck --check-prefixes=READOBJ-ILP32,READOBJ-SINGLE-V1 %s +-# RUN: llvm-readelf -h %t-ilp32f | FileCheck --check-prefixes=READELF-ILP32,READELF-SINGLE-V1 --match-full-lines %s +- +-# RUN: yaml2obj %s -o %t-ilp32d -DCLASS=32 -DABI_MODIFIER=DOUBLE -DOBJABI_VER=1 +-# RUN: llvm-readobj -h %t-ilp32d | FileCheck --check-prefixes=READOBJ-ILP32,READOBJ-DOUBLE-V1 %s +-# RUN: llvm-readelf -h %t-ilp32d | FileCheck --check-prefixes=READELF-ILP32,READELF-DOUBLE-V1 --match-full-lines %s +- +-# READOBJ-LP64: Class: 64-bit (0x2) +-# READELF-LP64: Class: ELF64 +-# READOBJ-ILP32: Class: 32-bit (0x1) +-# READELF-ILP32: Class: ELF32 +- +-# READOBJ-SOFT-V0: Flags [ (0x1) +-# READOBJ-SOFT-V0-NEXT: EF_LOONGARCH_ABI_SOFT_FLOAT (0x1) +-# READOBJ-SOFT-V0-NEXT: ] +- +-# READOBJ-SINGLE-V0: Flags [ (0x2) +-# READOBJ-SINGLE-V0-NEXT: EF_LOONGARCH_ABI_SINGLE_FLOAT (0x2) +-# READOBJ-SINGLE-V0-NEXT: ] +- +-# READOBJ-DOUBLE-V0: Flags [ (0x3) +-# READOBJ-DOUBLE-V0-NEXT: EF_LOONGARCH_ABI_DOUBLE_FLOAT (0x3) +-# READOBJ-DOUBLE-V0-NEXT: ] +- +-# READOBJ-SOFT-V1: Flags [ (0x41) +-# READOBJ-SOFT-V1-NEXT: EF_LOONGARCH_ABI_SOFT_FLOAT (0x1) +-# READOBJ-SOFT-V1-NEXT: EF_LOONGARCH_OBJABI_V1 (0x40) +-# READOBJ-SOFT-V1-NEXT: ] +- +-# READOBJ-SINGLE-V1: Flags [ (0x42) +-# READOBJ-SINGLE-V1-NEXT: EF_LOONGARCH_ABI_SINGLE_FLOAT (0x2) +-# READOBJ-SINGLE-V1-NEXT: EF_LOONGARCH_OBJABI_V1 (0x40) +-# READOBJ-SINGLE-V1-NEXT: ] +- +-# READOBJ-DOUBLE-V1: Flags [ (0x43) +-# READOBJ-DOUBLE-V1-NEXT: EF_LOONGARCH_ABI_DOUBLE_FLOAT (0x3) +-# READOBJ-DOUBLE-V1-NEXT: EF_LOONGARCH_OBJABI_V1 (0x40) +-# READOBJ-DOUBLE-V1-NEXT: ] +- +-# READELF-SOFT-V0: Flags: 0x1, SOFT-FLOAT +-# READELF-SINGLE-V0: Flags: 0x2, SINGLE-FLOAT +-# READELF-DOUBLE-V0: Flags: 0x3, DOUBLE-FLOAT +-# READELF-SOFT-V1: Flags: 0x41, SOFT-FLOAT, OBJ-v1 +-# READELF-SINGLE-V1: Flags: 0x42, SINGLE-FLOAT, OBJ-v1 +-# READELF-DOUBLE-V1: Flags: 0x43, DOUBLE-FLOAT, OBJ-v1 +- +---- !ELF +-FileHeader: +- Class: ELFCLASS[[CLASS]] +- Data: ELFDATA2LSB +- Type: ET_EXEC +- Machine: EM_LOONGARCH +- Flags: [ +- EF_LOONGARCH_ABI_[[ABI_MODIFIER]]_FLOAT, +- EF_LOONGARCH_OBJABI_V[[OBJABI_VER]], +- ] +diff --git a/llvm/test/tools/llvm-readobj/ELF/reloc-types-loongarch64.test b/llvm/test/tools/llvm-readobj/ELF/reloc-types-loongarch64.test +deleted file mode 100644 +index 26c4e8f5c..000000000 +--- a/llvm/test/tools/llvm-readobj/ELF/reloc-types-loongarch64.test ++++ /dev/null +@@ -1,247 +0,0 @@ +-## Test that llvm-readobj/llvm-readelf shows proper relocation type +-## names and values for loongarch64 target. +- +-# RUN: yaml2obj %s -o %t-loongarch64.o +-# RUN: llvm-readobj -r --expand-relocs %t-loongarch64.o | FileCheck %s +- +-# CHECK: Type: R_LARCH_NONE (0) +-# CHECK: Type: R_LARCH_32 (1) +-# CHECK: Type: R_LARCH_64 (2) +-# CHECK: Type: R_LARCH_RELATIVE (3) +-# CHECK: Type: R_LARCH_COPY (4) +-# CHECK: Type: R_LARCH_JUMP_SLOT (5) +-# CHECK: Type: R_LARCH_TLS_DTPMOD32 (6) +-# CHECK: Type: R_LARCH_TLS_DTPMOD64 (7) +-# CHECK: Type: R_LARCH_TLS_DTPREL32 (8) +-# CHECK: Type: R_LARCH_TLS_DTPREL64 (9) +-# CHECK: Type: R_LARCH_TLS_TPREL32 (10) +-# CHECK: Type: R_LARCH_TLS_TPREL64 (11) +-# CHECK: Type: R_LARCH_IRELATIVE (12) +-# CHECK: Type: R_LARCH_TLS_DESC32 (13) +-# CHECK: Type: R_LARCH_TLS_DESC64 (14) +-# CHECK: Type: R_LARCH_MARK_LA (20) +-# CHECK: Type: R_LARCH_MARK_PCREL (21) +-# CHECK: Type: R_LARCH_SOP_PUSH_PCREL (22) +-# CHECK: Type: R_LARCH_SOP_PUSH_ABSOLUTE (23) +-# CHECK: Type: R_LARCH_SOP_PUSH_DUP (24) +-# CHECK: Type: R_LARCH_SOP_PUSH_GPREL (25) +-# CHECK: Type: R_LARCH_SOP_PUSH_TLS_TPREL (26) +-# CHECK: Type: R_LARCH_SOP_PUSH_TLS_GOT (27) +-# CHECK: Type: R_LARCH_SOP_PUSH_TLS_GD (28) +-# CHECK: Type: R_LARCH_SOP_PUSH_PLT_PCREL (29) +-# CHECK: Type: R_LARCH_SOP_ASSERT (30) +-# CHECK: Type: R_LARCH_SOP_NOT (31) +-# CHECK: Type: R_LARCH_SOP_SUB (32) +-# CHECK: Type: R_LARCH_SOP_SL (33) +-# CHECK: Type: R_LARCH_SOP_SR (34) +-# CHECK: Type: R_LARCH_SOP_ADD (35) +-# CHECK: Type: R_LARCH_SOP_AND (36) +-# CHECK: Type: R_LARCH_SOP_IF_ELSE (37) +-# CHECK: Type: R_LARCH_SOP_POP_32_S_10_5 (38) +-# CHECK: Type: R_LARCH_SOP_POP_32_U_10_12 (39) +-# CHECK: Type: R_LARCH_SOP_POP_32_S_10_12 (40) +-# CHECK: Type: R_LARCH_SOP_POP_32_S_10_16 (41) +-# CHECK: Type: R_LARCH_SOP_POP_32_S_10_16_S2 (42) +-# CHECK: Type: R_LARCH_SOP_POP_32_S_5_20 (43) +-# CHECK: Type: R_LARCH_SOP_POP_32_S_0_5_10_16_S2 (44) +-# CHECK: Type: R_LARCH_SOP_POP_32_S_0_10_10_16_S2 (45) +-# CHECK: Type: R_LARCH_SOP_POP_32_U (46) +-# CHECK: Type: R_LARCH_ADD8 (47) +-# CHECK: Type: R_LARCH_ADD16 (48) +-# CHECK: Type: R_LARCH_ADD24 (49) +-# CHECK: Type: R_LARCH_ADD32 (50) +-# CHECK: Type: R_LARCH_ADD64 (51) +-# CHECK: Type: R_LARCH_SUB8 (52) +-# CHECK: Type: R_LARCH_SUB16 (53) +-# CHECK: Type: R_LARCH_SUB24 (54) +-# CHECK: Type: R_LARCH_SUB32 (55) +-# CHECK: Type: R_LARCH_SUB64 (56) +-# CHECK: Type: R_LARCH_GNU_VTINHERIT (57) +-# CHECK: Type: R_LARCH_GNU_VTENTRY (58) +-# CHECK: Type: R_LARCH_B16 (64) +-# CHECK: Type: R_LARCH_B21 (65) +-# CHECK: Type: R_LARCH_B26 (66) +-# CHECK: Type: R_LARCH_ABS_HI20 (67) +-# CHECK: Type: R_LARCH_ABS_LO12 (68) +-# CHECK: Type: R_LARCH_ABS64_LO20 (69) +-# CHECK: Type: R_LARCH_ABS64_HI12 (70) +-# CHECK: Type: R_LARCH_PCALA_HI20 (71) +-# CHECK: Type: R_LARCH_PCALA_LO12 (72) +-# CHECK: Type: R_LARCH_PCALA64_LO20 (73) +-# CHECK: Type: R_LARCH_PCALA64_HI12 (74) +-# CHECK: Type: R_LARCH_GOT_PC_HI20 (75) +-# CHECK: Type: R_LARCH_GOT_PC_LO12 (76) +-# CHECK: Type: R_LARCH_GOT64_PC_LO20 (77) +-# CHECK: Type: R_LARCH_GOT64_PC_HI12 (78) +-# CHECK: Type: R_LARCH_GOT_HI20 (79) +-# CHECK: Type: R_LARCH_GOT_LO12 (80) +-# CHECK: Type: R_LARCH_GOT64_LO20 (81) +-# CHECK: Type: R_LARCH_GOT64_HI12 (82) +-# CHECK: Type: R_LARCH_TLS_LE_HI20 (83) +-# CHECK: Type: R_LARCH_TLS_LE_LO12 (84) +-# CHECK: Type: R_LARCH_TLS_LE64_LO20 (85) +-# CHECK: Type: R_LARCH_TLS_LE64_HI12 (86) +-# CHECK: Type: R_LARCH_TLS_IE_PC_HI20 (87) +-# CHECK: Type: R_LARCH_TLS_IE_PC_LO12 (88) +-# CHECK: Type: R_LARCH_TLS_IE64_PC_LO20 (89) +-# CHECK: Type: R_LARCH_TLS_IE64_PC_HI12 (90) +-# CHECK: Type: R_LARCH_TLS_IE_HI20 (91) +-# CHECK: Type: R_LARCH_TLS_IE_LO12 (92) +-# CHECK: Type: R_LARCH_TLS_IE64_LO20 (93) +-# CHECK: Type: R_LARCH_TLS_IE64_HI12 (94) +-# CHECK: Type: R_LARCH_TLS_LD_PC_HI20 (95) +-# CHECK: Type: R_LARCH_TLS_LD_HI20 (96) +-# CHECK: Type: R_LARCH_TLS_GD_PC_HI20 (97) +-# CHECK: Type: R_LARCH_TLS_GD_HI20 (98) +-# CHECK: Type: R_LARCH_32_PCREL (99) +-# CHECK: Type: R_LARCH_RELAX (100) +-# CHECK: Type: R_LARCH_ALIGN (102) +-# CHECK: Type: R_LARCH_PCREL20_S2 (103) +-# CHECK: Type: R_LARCH_ADD6 (105) +-# CHECK: Type: R_LARCH_SUB6 (106) +-# CHECK: Type: R_LARCH_ADD_ULEB128 (107) +-# CHECK: Type: R_LARCH_SUB_ULEB128 (108) +-# CHECK: Type: R_LARCH_64_PCREL (109) +-# CHECK: Type: R_LARCH_CALL36 (110) +-# CHECK: Type: R_LARCH_TLS_DESC_PC_HI20 (111) +-# CHECK: Type: R_LARCH_TLS_DESC_PC_LO12 (112) +-# CHECK: Type: R_LARCH_TLS_DESC64_PC_LO20 (113) +-# CHECK: Type: R_LARCH_TLS_DESC64_PC_HI12 (114) +-# CHECK: Type: R_LARCH_TLS_DESC_HI20 (115) +-# CHECK: Type: R_LARCH_TLS_DESC_LO12 (116) +-# CHECK: Type: R_LARCH_TLS_DESC64_LO20 (117) +-# CHECK: Type: R_LARCH_TLS_DESC64_HI12 (118) +-# CHECK: Type: R_LARCH_TLS_DESC_LD (119) +-# CHECK: Type: R_LARCH_TLS_DESC_CALL (120) +-# CHECK: Type: R_LARCH_TLS_LE_HI20_R (121) +-# CHECK: Type: R_LARCH_TLS_LE_ADD_R (122) +-# CHECK: Type: R_LARCH_TLS_LE_LO12_R (123) +-# CHECK: Type: R_LARCH_TLS_LD_PCREL20_S2 (124) +-# CHECK: Type: R_LARCH_TLS_GD_PCREL20_S2 (125) +-# CHECK: Type: R_LARCH_TLS_DESC_PCREL20_S2 (126) +- +---- !ELF +-FileHeader: +- Class: ELFCLASS64 +- Data: ELFDATA2LSB +- Type: ET_REL +- Machine: EM_LOONGARCH +-Sections: +- - Name: .rela.text +- Type: SHT_RELA +- Relocations: +- - Type: R_LARCH_NONE +- - Type: R_LARCH_32 +- - Type: R_LARCH_64 +- - Type: R_LARCH_RELATIVE +- - Type: R_LARCH_COPY +- - Type: R_LARCH_JUMP_SLOT +- - Type: R_LARCH_TLS_DTPMOD32 +- - Type: R_LARCH_TLS_DTPMOD64 +- - Type: R_LARCH_TLS_DTPREL32 +- - Type: R_LARCH_TLS_DTPREL64 +- - Type: R_LARCH_TLS_TPREL32 +- - Type: R_LARCH_TLS_TPREL64 +- - Type: R_LARCH_IRELATIVE +- - Type: R_LARCH_TLS_DESC32 +- - Type: R_LARCH_TLS_DESC64 +- - Type: R_LARCH_MARK_LA +- - Type: R_LARCH_MARK_PCREL +- - Type: R_LARCH_SOP_PUSH_PCREL +- - Type: R_LARCH_SOP_PUSH_ABSOLUTE +- - Type: R_LARCH_SOP_PUSH_DUP +- - Type: R_LARCH_SOP_PUSH_GPREL +- - Type: R_LARCH_SOP_PUSH_TLS_TPREL +- - Type: R_LARCH_SOP_PUSH_TLS_GOT +- - Type: R_LARCH_SOP_PUSH_TLS_GD +- - Type: R_LARCH_SOP_PUSH_PLT_PCREL +- - Type: R_LARCH_SOP_ASSERT +- - Type: R_LARCH_SOP_NOT +- - Type: R_LARCH_SOP_SUB +- - Type: R_LARCH_SOP_SL +- - Type: R_LARCH_SOP_SR +- - Type: R_LARCH_SOP_ADD +- - Type: R_LARCH_SOP_AND +- - Type: R_LARCH_SOP_IF_ELSE +- - Type: R_LARCH_SOP_POP_32_S_10_5 +- - Type: R_LARCH_SOP_POP_32_U_10_12 +- - Type: R_LARCH_SOP_POP_32_S_10_12 +- - Type: R_LARCH_SOP_POP_32_S_10_16 +- - Type: R_LARCH_SOP_POP_32_S_10_16_S2 +- - Type: R_LARCH_SOP_POP_32_S_5_20 +- - Type: R_LARCH_SOP_POP_32_S_0_5_10_16_S2 +- - Type: R_LARCH_SOP_POP_32_S_0_10_10_16_S2 +- - Type: R_LARCH_SOP_POP_32_U +- - Type: R_LARCH_ADD8 +- - Type: R_LARCH_ADD16 +- - Type: R_LARCH_ADD24 +- - Type: R_LARCH_ADD32 +- - Type: R_LARCH_ADD64 +- - Type: R_LARCH_SUB8 +- - Type: R_LARCH_SUB16 +- - Type: R_LARCH_SUB24 +- - Type: R_LARCH_SUB32 +- - Type: R_LARCH_SUB64 +- - Type: R_LARCH_GNU_VTINHERIT +- - Type: R_LARCH_GNU_VTENTRY +- - Type: R_LARCH_B16 +- - Type: R_LARCH_B21 +- - Type: R_LARCH_B26 +- - Type: R_LARCH_ABS_HI20 +- - Type: R_LARCH_ABS_LO12 +- - Type: R_LARCH_ABS64_LO20 +- - Type: R_LARCH_ABS64_HI12 +- - Type: R_LARCH_PCALA_HI20 +- - Type: R_LARCH_PCALA_LO12 +- - Type: R_LARCH_PCALA64_LO20 +- - Type: R_LARCH_PCALA64_HI12 +- - Type: R_LARCH_GOT_PC_HI20 +- - Type: R_LARCH_GOT_PC_LO12 +- - Type: R_LARCH_GOT64_PC_LO20 +- - Type: R_LARCH_GOT64_PC_HI12 +- - Type: R_LARCH_GOT_HI20 +- - Type: R_LARCH_GOT_LO12 +- - Type: R_LARCH_GOT64_LO20 +- - Type: R_LARCH_GOT64_HI12 +- - Type: R_LARCH_TLS_LE_HI20 +- - Type: R_LARCH_TLS_LE_LO12 +- - Type: R_LARCH_TLS_LE64_LO20 +- - Type: R_LARCH_TLS_LE64_HI12 +- - Type: R_LARCH_TLS_IE_PC_HI20 +- - Type: R_LARCH_TLS_IE_PC_LO12 +- - Type: R_LARCH_TLS_IE64_PC_LO20 +- - Type: R_LARCH_TLS_IE64_PC_HI12 +- - Type: R_LARCH_TLS_IE_HI20 +- - Type: R_LARCH_TLS_IE_LO12 +- - Type: R_LARCH_TLS_IE64_LO20 +- - Type: R_LARCH_TLS_IE64_HI12 +- - Type: R_LARCH_TLS_LD_PC_HI20 +- - Type: R_LARCH_TLS_LD_HI20 +- - Type: R_LARCH_TLS_GD_PC_HI20 +- - Type: R_LARCH_TLS_GD_HI20 +- - Type: R_LARCH_32_PCREL +- - Type: R_LARCH_RELAX +- - Type: R_LARCH_ALIGN +- - Type: R_LARCH_PCREL20_S2 +- - Type: R_LARCH_ADD6 +- - Type: R_LARCH_SUB6 +- - Type: R_LARCH_ADD_ULEB128 +- - Type: R_LARCH_SUB_ULEB128 +- - Type: R_LARCH_64_PCREL +- - Type: R_LARCH_CALL36 +- - Type: R_LARCH_TLS_DESC_PC_HI20 +- - Type: R_LARCH_TLS_DESC_PC_LO12 +- - Type: R_LARCH_TLS_DESC64_PC_LO20 +- - Type: R_LARCH_TLS_DESC64_PC_HI12 +- - Type: R_LARCH_TLS_DESC_HI20 +- - Type: R_LARCH_TLS_DESC_LO12 +- - Type: R_LARCH_TLS_DESC64_LO20 +- - Type: R_LARCH_TLS_DESC64_HI12 +- - Type: R_LARCH_TLS_DESC_LD +- - Type: R_LARCH_TLS_DESC_CALL +- - Type: R_LARCH_TLS_LE_HI20_R +- - Type: R_LARCH_TLS_LE_ADD_R +- - Type: R_LARCH_TLS_LE_LO12_R +- - Type: R_LARCH_TLS_LD_PCREL20_S2 +- - Type: R_LARCH_TLS_GD_PCREL20_S2 +- - Type: R_LARCH_TLS_DESC_PCREL20_S2 +diff --git a/llvm/test/tools/obj2yaml/ELF/loongarch-eflags.yaml b/llvm/test/tools/obj2yaml/ELF/loongarch-eflags.yaml +deleted file mode 100644 +index 2e4ee1dab..000000000 +--- a/llvm/test/tools/obj2yaml/ELF/loongarch-eflags.yaml ++++ /dev/null +@@ -1,51 +0,0 @@ +-## Check obj2yaml is able to decode all possible LoongArch e_flags field values. +- +-# RUN: yaml2obj %s -o %t-lp64s -DCLASS=64 -DABI_MODIFIER=SOFT -DOBJABI_VER=0 +-# RUN: obj2yaml %t-lp64s | FileCheck -DCLASS=64 -DABI_MODIFIER=SOFT -DOBJABI_VER=0 %s +- +-# RUN: yaml2obj %s -o %t-lp64f -DCLASS=64 -DABI_MODIFIER=SINGLE -DOBJABI_VER=0 +-# RUN: obj2yaml %t-lp64f | FileCheck -DCLASS=64 -DABI_MODIFIER=SINGLE -DOBJABI_VER=0 %s +- +-# RUN: yaml2obj %s -o %t-lp64d -DCLASS=64 -DABI_MODIFIER=DOUBLE -DOBJABI_VER=0 +-# RUN: obj2yaml %t-lp64d | FileCheck -DCLASS=64 -DABI_MODIFIER=DOUBLE -DOBJABI_VER=0 %s +- +-# RUN: yaml2obj %s -o %t-ilp32s -DCLASS=32 -DABI_MODIFIER=SOFT -DOBJABI_VER=0 +-# RUN: obj2yaml %t-ilp32s | FileCheck -DCLASS=32 -DABI_MODIFIER=SOFT -DOBJABI_VER=0 %s +- +-# RUN: yaml2obj %s -o %t-ilp32f -DCLASS=32 -DABI_MODIFIER=SINGLE -DOBJABI_VER=0 +-# RUN: obj2yaml %t-ilp32f | FileCheck -DCLASS=32 -DABI_MODIFIER=SINGLE -DOBJABI_VER=0 %s +- +-# RUN: yaml2obj %s -o %t-ilp32d -DCLASS=32 -DABI_MODIFIER=DOUBLE -DOBJABI_VER=0 +-# RUN: obj2yaml %t-ilp32d | FileCheck -DCLASS=32 -DABI_MODIFIER=DOUBLE -DOBJABI_VER=0 %s +- +-# RUN: yaml2obj %s -o %t-lp64s -DCLASS=64 -DABI_MODIFIER=SOFT -DOBJABI_VER=1 +-# RUN: obj2yaml %t-lp64s | FileCheck -DCLASS=64 -DABI_MODIFIER=SOFT -DOBJABI_VER=1 %s +- +-# RUN: yaml2obj %s -o %t-lp64f -DCLASS=64 -DABI_MODIFIER=SINGLE -DOBJABI_VER=1 +-# RUN: obj2yaml %t-lp64f | FileCheck -DCLASS=64 -DABI_MODIFIER=SINGLE -DOBJABI_VER=1 %s +- +-# RUN: yaml2obj %s -o %t-lp64d -DCLASS=64 -DABI_MODIFIER=DOUBLE -DOBJABI_VER=1 +-# RUN: obj2yaml %t-lp64d | FileCheck -DCLASS=64 -DABI_MODIFIER=DOUBLE -DOBJABI_VER=1 %s +- +-# RUN: yaml2obj %s -o %t-ilp32s -DCLASS=32 -DABI_MODIFIER=SOFT -DOBJABI_VER=1 +-# RUN: obj2yaml %t-ilp32s | FileCheck -DCLASS=32 -DABI_MODIFIER=SOFT -DOBJABI_VER=1 %s +- +-# RUN: yaml2obj %s -o %t-ilp32f -DCLASS=32 -DABI_MODIFIER=SINGLE -DOBJABI_VER=1 +-# RUN: obj2yaml %t-ilp32f | FileCheck -DCLASS=32 -DABI_MODIFIER=SINGLE -DOBJABI_VER=1 %s +- +-# RUN: yaml2obj %s -o %t-ilp32d -DCLASS=32 -DABI_MODIFIER=DOUBLE -DOBJABI_VER=1 +-# RUN: obj2yaml %t-ilp32d | FileCheck -DCLASS=32 -DABI_MODIFIER=DOUBLE -DOBJABI_VER=1 %s +- +-# CHECK: Class: ELFCLASS[[CLASS]] +-# CHECK: Flags: [ EF_LOONGARCH_ABI_[[ABI_MODIFIER]]_FLOAT, EF_LOONGARCH_OBJABI_V[[OBJABI_VER]] ] +- +---- !ELF +-FileHeader: +- Class: ELFCLASS[[CLASS]] +- Data: ELFDATA2LSB +- Type: ET_EXEC +- Machine: EM_LOONGARCH +- Flags: [ +- EF_LOONGARCH_ABI_[[ABI_MODIFIER]]_FLOAT, +- EF_LOONGARCH_OBJABI_V[[OBJABI_VER]], +- ] +diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp +index 387124ad5..2ca8877f3 100644 +--- a/llvm/tools/llvm-readobj/ELFDumper.cpp ++++ b/llvm/tools/llvm-readobj/ELFDumper.cpp +@@ -1739,20 +1739,19 @@ const EnumEntry ElfHeaderAVRFlags[] = { + ENUM_ENT(EF_AVR_LINKRELAX_PREPARED, "relaxable"), + }; + +-const EnumEntry ElfHeaderLoongArchFlags[] = { +- ENUM_ENT(EF_LOONGARCH_ABI_SOFT_FLOAT, "SOFT-FLOAT"), +- ENUM_ENT(EF_LOONGARCH_ABI_SINGLE_FLOAT, "SINGLE-FLOAT"), +- ENUM_ENT(EF_LOONGARCH_ABI_DOUBLE_FLOAT, "DOUBLE-FLOAT"), +- ENUM_ENT(EF_LOONGARCH_OBJABI_V0, "OBJ-v0"), +- ENUM_ENT(EF_LOONGARCH_OBJABI_V1, "OBJ-v1"), +-}; +- + static const EnumEntry ElfHeaderXtensaFlags[] = { + LLVM_READOBJ_ENUM_ENT(ELF, EF_XTENSA_MACH_NONE), + LLVM_READOBJ_ENUM_ENT(ELF, EF_XTENSA_XT_INSN), + LLVM_READOBJ_ENUM_ENT(ELF, EF_XTENSA_XT_LIT) + }; + ++static const EnumEntry ElfHeaderLoongArchFlags[] = { ++ ENUM_ENT(EF_LARCH_ABI_LP64, "LP64") ++ // FIXME: Change these and add more flags in future when all ABIs definition were finalized. ++ // See current definitions: ++ // https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html#_e_flags_identifies_abi_type_and_version ++}; ++ + const EnumEntry ElfSymOtherFlags[] = { + LLVM_READOBJ_ENUM_ENT(ELF, STV_INTERNAL), + LLVM_READOBJ_ENUM_ENT(ELF, STV_HIDDEN), +@@ -3649,10 +3648,6 @@ template void GNUELFDumper::printFileHeaders() { + else if (e.e_machine == EM_AVR) + ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderAVRFlags), + unsigned(ELF::EF_AVR_ARCH_MASK)); +- else if (e.e_machine == EM_LOONGARCH) +- ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderLoongArchFlags), +- unsigned(ELF::EF_LOONGARCH_ABI_MODIFIER_MASK), +- unsigned(ELF::EF_LOONGARCH_OBJABI_MASK)); + else if (e.e_machine == EM_XTENSA) + ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderXtensaFlags), + unsigned(ELF::EF_XTENSA_MACH)); +@@ -3681,6 +3676,8 @@ template void GNUELFDumper::printFileHeaders() { + break; + } + } ++ else if (e.e_machine == EM_LOONGARCH) ++ ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderLoongArchFlags)); + Str = "0x" + utohexstr(e.e_flags); + if (!ElfFlags.empty()) + Str = Str + ", " + ElfFlags; +@@ -6956,16 +6953,14 @@ template void LLVMELFDumper::printFileHeaders() { + else if (E.e_machine == EM_AVR) + W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderAVRFlags), + unsigned(ELF::EF_AVR_ARCH_MASK)); +- else if (E.e_machine == EM_LOONGARCH) +- W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderLoongArchFlags), +- unsigned(ELF::EF_LOONGARCH_ABI_MODIFIER_MASK), +- unsigned(ELF::EF_LOONGARCH_OBJABI_MASK)); + else if (E.e_machine == EM_XTENSA) + W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderXtensaFlags), + unsigned(ELF::EF_XTENSA_MACH)); + else if (E.e_machine == EM_CUDA) + W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderNVPTXFlags), + unsigned(ELF::EF_CUDA_SM)); ++ else if (E.e_machine == EM_LOONGARCH) ++ W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderLoongArchFlags)); + else + W.printFlags("Flags", E.e_flags); + W.printNumber("HeaderSize", E.e_ehsize); +diff --git a/llvm/unittests/ExecutionEngine/JITLink/StubsTests.cpp b/llvm/unittests/ExecutionEngine/JITLink/StubsTests.cpp +index 8fbede037..807f74ea3 100644 +--- a/llvm/unittests/ExecutionEngine/JITLink/StubsTests.cpp ++++ b/llvm/unittests/ExecutionEngine/JITLink/StubsTests.cpp +@@ -10,7 +10,6 @@ + #include "llvm/ExecutionEngine/JITLink/JITLink.h" + #include "llvm/ExecutionEngine/JITLink/aarch64.h" + #include "llvm/ExecutionEngine/JITLink/i386.h" +-#include "llvm/ExecutionEngine/JITLink/loongarch.h" + #include "llvm/ExecutionEngine/JITLink/x86_64.h" + #include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h" + #include "llvm/Support/Memory.h" +@@ -112,67 +111,3 @@ TEST(StubsTest, StubsGeneration_i386) { + EXPECT_EQ(StubSym.getBlock().getContent(), + ArrayRef(PointerJumpStubContent)); + } +- +-TEST(StubsTest, StubsGeneration_loongarch32) { +- const char PointerJumpStubContent[12] = { +- 0x14, +- 0x00, +- 0x00, +- 0x1a, // pcalau12i $t8, %page20(imm) +- static_cast(0x94), +- 0x02, +- static_cast(0x80), +- 0x28, // ld.d $t8, $t8, %pageoff12(imm) +- static_cast(0x80), +- 0x02, +- 0x00, +- 0x4c // jr $t8 +- }; +- LinkGraph G("foo", Triple("loongarch32"), 4, llvm::endianness::little, +- getGenericEdgeKindName); +- auto [PointerSym, StubSym] = GenerateStub(G, 4U, loongarch::Pointer32); +- +- EXPECT_EQ(std::distance(StubSym.getBlock().edges().begin(), +- StubSym.getBlock().edges().end()), +- 2U); +- auto &PageHighEdge = *StubSym.getBlock().edges().begin(); +- auto &PageLowEdge = *++StubSym.getBlock().edges().begin(); +- EXPECT_EQ(PageHighEdge.getKind(), loongarch::Page20); +- EXPECT_EQ(&PageHighEdge.getTarget(), &PointerSym); +- EXPECT_EQ(PageLowEdge.getKind(), loongarch::PageOffset12); +- EXPECT_EQ(&PageLowEdge.getTarget(), &PointerSym); +- EXPECT_EQ(StubSym.getBlock().getContent(), +- ArrayRef(PointerJumpStubContent)); +-} +- +-TEST(StubsTest, StubsGeneration_loongarch64) { +- const char PointerJumpStubContent[12] = { +- 0x14, +- 0x00, +- 0x00, +- 0x1a, // pcalau12i $t8, %page20(imm) +- static_cast(0x94), +- 0x02, +- static_cast(0xc0), +- 0x28, // ld.d $t8, $t8, %pageoff12(imm) +- static_cast(0x80), +- 0x02, +- 0x00, +- 0x4c // jr $t8 +- }; +- LinkGraph G("foo", Triple("loongarch64"), 8, llvm::endianness::little, +- getGenericEdgeKindName); +- auto [PointerSym, StubSym] = GenerateStub(G, 8U, loongarch::Pointer64); +- +- EXPECT_EQ(std::distance(StubSym.getBlock().edges().begin(), +- StubSym.getBlock().edges().end()), +- 2U); +- auto &PageHighEdge = *StubSym.getBlock().edges().begin(); +- auto &PageLowEdge = *++StubSym.getBlock().edges().begin(); +- EXPECT_EQ(PageHighEdge.getKind(), loongarch::Page20); +- EXPECT_EQ(&PageHighEdge.getTarget(), &PointerSym); +- EXPECT_EQ(PageLowEdge.getKind(), loongarch::PageOffset12); +- EXPECT_EQ(&PageLowEdge.getTarget(), &PointerSym); +- EXPECT_EQ(StubSym.getBlock().getContent(), +- ArrayRef(PointerJumpStubContent)); +-} +diff --git a/llvm/unittests/Object/ELFObjectFileTest.cpp b/llvm/unittests/Object/ELFObjectFileTest.cpp +index b344e8abb..7ef13b9d5 100644 +--- a/llvm/unittests/Object/ELFObjectFileTest.cpp ++++ b/llvm/unittests/Object/ELFObjectFileTest.cpp +@@ -267,16 +267,6 @@ TEST(ELFObjectFileTest, MachineTestForMSP430) { + checkFormatAndArch(Data, Formats[Idx], Triple::msp430); + } + +-TEST(ELFObjectFileTest, MachineTestForLoongArch) { +- std::array Formats = {"elf32-loongarch", "elf32-loongarch", +- "elf64-loongarch", "elf64-loongarch"}; +- std::array Archs = { +- Triple::loongarch32, Triple::loongarch32, Triple::loongarch64, +- Triple::loongarch64}; +- for (auto [Idx, Data] : enumerate(generateData(ELF::EM_LOONGARCH))) +- checkFormatAndArch(Data, Formats[Idx], Archs[Idx]); +-} +- + TEST(ELFObjectFileTest, MachineTestForCSKY) { + std::array Formats = {"elf32-csky", "elf32-csky", + "elf64-unknown", "elf64-unknown"}; +diff --git a/llvm/unittests/Object/ELFTest.cpp b/llvm/unittests/Object/ELFTest.cpp +index faf855c09..3a7f50b13 100644 +--- a/llvm/unittests/Object/ELFTest.cpp ++++ b/llvm/unittests/Object/ELFTest.cpp +@@ -52,208 +52,8 @@ TEST(ELFTest, getELFRelocationTypeNameForVE) { + EXPECT_EQ("R_VE_CALL_LO32", getELFRelocationTypeName(EM_VE, R_VE_CALL_LO32)); + } + +-TEST(ELFTest, getELFRelocationTypeNameForLoongArch) { +- EXPECT_EQ("R_LARCH_NONE", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_NONE)); +- EXPECT_EQ("R_LARCH_32", getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_32)); +- EXPECT_EQ("R_LARCH_64", getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_64)); +- EXPECT_EQ("R_LARCH_RELATIVE", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_RELATIVE)); +- EXPECT_EQ("R_LARCH_COPY", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_COPY)); +- EXPECT_EQ("R_LARCH_JUMP_SLOT", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_JUMP_SLOT)); +- EXPECT_EQ("R_LARCH_TLS_DTPMOD32", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_TLS_DTPMOD32)); +- EXPECT_EQ("R_LARCH_TLS_DTPMOD64", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_TLS_DTPMOD64)); +- EXPECT_EQ("R_LARCH_TLS_DTPREL32", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_TLS_DTPREL32)); +- EXPECT_EQ("R_LARCH_TLS_DTPREL64", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_TLS_DTPREL64)); +- EXPECT_EQ("R_LARCH_TLS_TPREL32", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_TLS_TPREL32)); +- EXPECT_EQ("R_LARCH_TLS_TPREL64", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_TLS_TPREL64)); +- EXPECT_EQ("R_LARCH_IRELATIVE", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_IRELATIVE)); +- +- EXPECT_EQ("R_LARCH_MARK_LA", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_MARK_LA)); +- EXPECT_EQ("R_LARCH_MARK_PCREL", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_MARK_PCREL)); +- EXPECT_EQ("R_LARCH_SOP_PUSH_PCREL", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_PUSH_PCREL)); +- EXPECT_EQ("R_LARCH_SOP_PUSH_ABSOLUTE", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_PUSH_ABSOLUTE)); +- EXPECT_EQ("R_LARCH_SOP_PUSH_DUP", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_PUSH_DUP)); +- EXPECT_EQ("R_LARCH_SOP_PUSH_GPREL", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_PUSH_GPREL)); +- EXPECT_EQ("R_LARCH_SOP_PUSH_TLS_TPREL", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_PUSH_TLS_TPREL)); +- EXPECT_EQ("R_LARCH_SOP_PUSH_TLS_GOT", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_PUSH_TLS_GOT)); +- EXPECT_EQ("R_LARCH_SOP_PUSH_TLS_GD", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_PUSH_TLS_GD)); +- EXPECT_EQ("R_LARCH_SOP_PUSH_PLT_PCREL", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_PUSH_PLT_PCREL)); +- EXPECT_EQ("R_LARCH_SOP_ASSERT", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_ASSERT)); +- EXPECT_EQ("R_LARCH_SOP_NOT", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_NOT)); +- EXPECT_EQ("R_LARCH_SOP_SUB", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_SUB)); +- EXPECT_EQ("R_LARCH_SOP_SL", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_SL)); +- EXPECT_EQ("R_LARCH_SOP_SR", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_SR)); +- EXPECT_EQ("R_LARCH_SOP_ADD", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_ADD)); +- EXPECT_EQ("R_LARCH_SOP_AND", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_AND)); +- EXPECT_EQ("R_LARCH_SOP_IF_ELSE", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_IF_ELSE)); +- EXPECT_EQ("R_LARCH_SOP_POP_32_S_10_5", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_POP_32_S_10_5)); +- EXPECT_EQ("R_LARCH_SOP_POP_32_U_10_12", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_POP_32_U_10_12)); +- EXPECT_EQ("R_LARCH_SOP_POP_32_S_10_12", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_POP_32_S_10_12)); +- EXPECT_EQ("R_LARCH_SOP_POP_32_S_10_16", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_POP_32_S_10_16)); +- EXPECT_EQ( +- "R_LARCH_SOP_POP_32_S_10_16_S2", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_POP_32_S_10_16_S2)); +- EXPECT_EQ("R_LARCH_SOP_POP_32_S_5_20", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_POP_32_S_5_20)); +- EXPECT_EQ("R_LARCH_SOP_POP_32_S_0_5_10_16_S2", +- getELFRelocationTypeName(EM_LOONGARCH, +- R_LARCH_SOP_POP_32_S_0_5_10_16_S2)); +- EXPECT_EQ("R_LARCH_SOP_POP_32_S_0_10_10_16_S2", +- getELFRelocationTypeName(EM_LOONGARCH, +- R_LARCH_SOP_POP_32_S_0_10_10_16_S2)); +- EXPECT_EQ("R_LARCH_SOP_POP_32_U", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SOP_POP_32_U)); +- EXPECT_EQ("R_LARCH_ADD8", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_ADD8)); +- EXPECT_EQ("R_LARCH_ADD16", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_ADD16)); +- EXPECT_EQ("R_LARCH_ADD24", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_ADD24)); +- EXPECT_EQ("R_LARCH_ADD32", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_ADD32)); +- EXPECT_EQ("R_LARCH_ADD64", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_ADD64)); +- EXPECT_EQ("R_LARCH_SUB8", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SUB8)); +- EXPECT_EQ("R_LARCH_SUB16", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SUB16)); +- EXPECT_EQ("R_LARCH_SUB24", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SUB24)); +- EXPECT_EQ("R_LARCH_SUB32", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SUB32)); +- EXPECT_EQ("R_LARCH_SUB64", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SUB64)); +- EXPECT_EQ("R_LARCH_GNU_VTINHERIT", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_GNU_VTINHERIT)); +- EXPECT_EQ("R_LARCH_GNU_VTENTRY", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_GNU_VTENTRY)); +- EXPECT_EQ("R_LARCH_B16", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_B16)); +- EXPECT_EQ("R_LARCH_B21", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_B21)); +- EXPECT_EQ("R_LARCH_B26", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_B26)); +- EXPECT_EQ("R_LARCH_ABS_HI20", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_ABS_HI20)); +- EXPECT_EQ("R_LARCH_ABS_LO12", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_ABS_LO12)); +- EXPECT_EQ("R_LARCH_ABS64_LO20", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_ABS64_LO20)); +- EXPECT_EQ("R_LARCH_ABS64_HI12", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_ABS64_HI12)); +- EXPECT_EQ("R_LARCH_PCALA_HI20", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_PCALA_HI20)); +- EXPECT_EQ("R_LARCH_PCALA_LO12", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_PCALA_LO12)); +- EXPECT_EQ("R_LARCH_PCALA64_LO20", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_PCALA64_LO20)); +- EXPECT_EQ("R_LARCH_PCALA64_HI12", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_PCALA64_HI12)); +- EXPECT_EQ("R_LARCH_GOT_PC_HI20", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_GOT_PC_HI20)); +- EXPECT_EQ("R_LARCH_GOT_PC_LO12", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_GOT_PC_LO12)); +- EXPECT_EQ("R_LARCH_GOT64_PC_LO20", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_GOT64_PC_LO20)); +- EXPECT_EQ("R_LARCH_GOT64_PC_HI12", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_GOT64_PC_HI12)); +- EXPECT_EQ("R_LARCH_GOT_HI20", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_GOT_HI20)); +- EXPECT_EQ("R_LARCH_GOT_LO12", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_GOT_LO12)); +- EXPECT_EQ("R_LARCH_GOT64_LO20", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_GOT64_LO20)); +- EXPECT_EQ("R_LARCH_GOT64_HI12", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_GOT64_HI12)); +- EXPECT_EQ("R_LARCH_TLS_LE_HI20", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_TLS_LE_HI20)); +- EXPECT_EQ("R_LARCH_TLS_LE_LO12", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_TLS_LE_LO12)); +- EXPECT_EQ("R_LARCH_TLS_LE64_LO20", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_TLS_LE64_LO20)); +- EXPECT_EQ("R_LARCH_TLS_LE64_HI12", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_TLS_LE64_HI12)); +- EXPECT_EQ("R_LARCH_TLS_IE_PC_HI20", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_TLS_IE_PC_HI20)); +- EXPECT_EQ("R_LARCH_TLS_IE_PC_LO12", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_TLS_IE_PC_LO12)); +- EXPECT_EQ("R_LARCH_TLS_IE64_PC_LO20", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_TLS_IE64_PC_LO20)); +- EXPECT_EQ("R_LARCH_TLS_IE64_PC_HI12", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_TLS_IE64_PC_HI12)); +- EXPECT_EQ("R_LARCH_TLS_IE_HI20", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_TLS_IE_HI20)); +- EXPECT_EQ("R_LARCH_TLS_IE_LO12", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_TLS_IE_LO12)); +- EXPECT_EQ("R_LARCH_TLS_IE64_LO20", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_TLS_IE64_LO20)); +- EXPECT_EQ("R_LARCH_TLS_IE64_HI12", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_TLS_IE64_HI12)); +- EXPECT_EQ("R_LARCH_TLS_LD_PC_HI20", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_TLS_LD_PC_HI20)); +- EXPECT_EQ("R_LARCH_TLS_LD_HI20", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_TLS_LD_HI20)); +- EXPECT_EQ("R_LARCH_TLS_GD_PC_HI20", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_TLS_GD_PC_HI20)); +- EXPECT_EQ("R_LARCH_TLS_GD_HI20", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_TLS_GD_HI20)); +- EXPECT_EQ("R_LARCH_32_PCREL", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_32_PCREL)); +- EXPECT_EQ("R_LARCH_RELAX", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_RELAX)); +- EXPECT_EQ("R_LARCH_ALIGN", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_ALIGN)); +- EXPECT_EQ("R_LARCH_PCREL20_S2", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_PCREL20_S2)); +- EXPECT_EQ("R_LARCH_ADD6", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_ADD6)); +- EXPECT_EQ("R_LARCH_SUB6", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SUB6)); +- EXPECT_EQ("R_LARCH_ADD_ULEB128", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_ADD_ULEB128)); +- EXPECT_EQ("R_LARCH_SUB_ULEB128", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_SUB_ULEB128)); +- EXPECT_EQ("R_LARCH_64_PCREL", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_64_PCREL)); +- EXPECT_EQ("R_LARCH_CALL36", +- getELFRelocationTypeName(EM_LOONGARCH, R_LARCH_CALL36)); +-} +- + TEST(ELFTest, getELFRelativeRelocationType) { + EXPECT_EQ(ELF::R_VE_RELATIVE, getELFRelativeRelocationType(EM_VE)); +- EXPECT_EQ(ELF::R_LARCH_RELATIVE, getELFRelativeRelocationType(EM_LOONGARCH)); + } + + // This is a test for the DataRegion helper struct, defined in ELF.h header. +diff --git a/llvm/unittests/Target/LoongArch/CMakeLists.txt b/llvm/unittests/Target/LoongArch/CMakeLists.txt +deleted file mode 100644 +index e6f8ec073..000000000 +--- a/llvm/unittests/Target/LoongArch/CMakeLists.txt ++++ /dev/null +@@ -1,26 +0,0 @@ +-include_directories( +- ${LLVM_MAIN_SRC_DIR}/lib/Target/LoongArch +- ${LLVM_BINARY_DIR}/lib/Target/LoongArch +- ) +- +-set(LLVM_LINK_COMPONENTS +- CodeGen +- CodeGenTypes +- Core +- LoongArchCodeGen +- LoongArchDesc +- LoongArchInfo +- MC +- MIRParser +- SelectionDAG +- Support +- Target +- TargetParser +- ) +- +-add_llvm_target_unittest(LoongArchTests +- InstSizes.cpp +- MCInstrAnalysisTest.cpp +- ) +- +-set_property(TARGET LoongArchTests PROPERTY FOLDER "Tests/UnitTests/TargetTests") +diff --git a/llvm/unittests/Target/LoongArch/InstSizes.cpp b/llvm/unittests/Target/LoongArch/InstSizes.cpp +deleted file mode 100644 +index f38af4a8d..000000000 +--- a/llvm/unittests/Target/LoongArch/InstSizes.cpp ++++ /dev/null +@@ -1,141 +0,0 @@ +-#include "LoongArchSubtarget.h" +-#include "LoongArchTargetMachine.h" +-#include "llvm/CodeGen/MIRParser/MIRParser.h" +-#include "llvm/CodeGen/MachineModuleInfo.h" +-#include "llvm/MC/TargetRegistry.h" +-#include "llvm/Support/MemoryBuffer.h" +-#include "llvm/Support/TargetSelect.h" +-#include +- +-#include "gtest/gtest.h" +- +-using namespace llvm; +- +-namespace { +-std::unique_ptr createTargetMachine() { +- auto TT(Triple::normalize("loongarch64--")); +- std::string CPU("generic-la64"); +- std::string FS("+64bit"); +- +- LLVMInitializeLoongArchTargetInfo(); +- LLVMInitializeLoongArchTarget(); +- LLVMInitializeLoongArchTargetMC(); +- +- std::string Error; +- const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error); +- +- return std::unique_ptr(static_cast( +- TheTarget->createTargetMachine(TT, CPU, FS, TargetOptions(), std::nullopt, +- std::nullopt, CodeGenOptLevel::Default))); +-} +- +-std::unique_ptr createInstrInfo(TargetMachine *TM) { +- LoongArchSubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()), +- std::string(TM->getTargetCPU()), +- std::string(TM->getTargetFeatureString()), "lp64d", +- *TM); +- return std::make_unique(ST); +-} +- +-/// The \p InputIRSnippet is only needed for things that can't be expressed in +-/// the \p InputMIRSnippet (global variables etc) +-/// Inspired by AArch64 +-void runChecks( +- LLVMTargetMachine *TM, LoongArchInstrInfo *II, +- const StringRef InputIRSnippet, const StringRef InputMIRSnippet, +- std::function Checks) { +- LLVMContext Context; +- +- auto MIRString = "--- |\n" +- " declare void @sizes()\n" + +- InputIRSnippet.str() + +- "...\n" +- "---\n" +- "name: sizes\n" +- "jumpTable:\n" +- " kind: block-address\n" +- " entries:\n" +- " - id: 0\n" +- " blocks: [ '%bb.0' ]\n" +- "body: |\n" +- " bb.0:\n" + +- InputMIRSnippet.str(); +- +- std::unique_ptr MBuffer = MemoryBuffer::getMemBuffer(MIRString); +- std::unique_ptr MParser = +- createMIRParser(std::move(MBuffer), Context); +- ASSERT_TRUE(MParser); +- +- std::unique_ptr M = MParser->parseIRModule(); +- ASSERT_TRUE(M); +- +- M->setTargetTriple(TM->getTargetTriple().getTriple()); +- M->setDataLayout(TM->createDataLayout()); +- +- MachineModuleInfo MMI(TM); +- bool Res = MParser->parseMachineFunctions(*M, MMI); +- ASSERT_FALSE(Res); +- +- auto F = M->getFunction("sizes"); +- ASSERT_TRUE(F != nullptr); +- auto &MF = MMI.getOrCreateMachineFunction(*F); +- +- Checks(*II, MF); +-} +- +-} // anonymous namespace +- +-TEST(InstSizes, INLINEASM_BR) { +- std::unique_ptr TM = createTargetMachine(); +- std::unique_ptr II = createInstrInfo(TM.get()); +- +- runChecks(TM.get(), II.get(), "", +- // clang-format off +- " INLINEASM_BR &nop, 1 /* sideeffect attdialect */, 13 /* imm */, %jump-table.0\n", +- // clang-format on +- [](LoongArchInstrInfo &II, MachineFunction &MF) { +- auto I = MF.begin()->begin(); +- EXPECT_EQ(4u, II.getInstSizeInBytes(*I)); +- }); +-} +- +-TEST(InstSizes, SPACE) { +- std::unique_ptr TM = createTargetMachine(); +- std::unique_ptr II = createInstrInfo(TM.get()); +- +- runChecks(TM.get(), II.get(), "", " INLINEASM &\".space 1024\", 1\n", +- [](LoongArchInstrInfo &II, MachineFunction &MF) { +- auto I = MF.begin()->begin(); +- EXPECT_EQ(1024u, II.getInstSizeInBytes(*I)); +- }); +-} +- +-TEST(InstSizes, AtomicPseudo) { +- std::unique_ptr TM = createTargetMachine(); +- std::unique_ptr II = createInstrInfo(TM.get()); +- +- runChecks( +- TM.get(), II.get(), "", +- // clang-format off +- " dead early-clobber renamable $r10, dead early-clobber renamable $r11 = PseudoMaskedAtomicLoadAdd32 renamable $r7, renamable $r6, renamable $r8, 4\n" +- " dead early-clobber renamable $r10, dead early-clobber renamable $r11 = PseudoAtomicLoadAdd32 renamable $r7, renamable $r6, renamable $r8\n" +- " dead early-clobber renamable $r5, dead early-clobber renamable $r9, dead early-clobber renamable $r10 = PseudoMaskedAtomicLoadUMax32 renamable $r7, renamable $r6, renamable $r8, 4\n" +- " early-clobber renamable $r9, dead early-clobber renamable $r10, dead early-clobber renamable $r11 = PseudoMaskedAtomicLoadMax32 killed renamable $r6, killed renamable $r5, killed renamable $r7, killed renamable $r8, 4\n" +- " dead early-clobber renamable $r5, dead early-clobber renamable $r9 = PseudoCmpXchg32 renamable $r7, renamable $r4, renamable $r6, 4\n" +- " dead early-clobber renamable $r5, dead early-clobber renamable $r9 = PseudoMaskedCmpXchg32 killed renamable $r7, killed renamable $r4, killed renamable $r6, killed renamable $r8, 4\n", +- // clang-format on +- [](LoongArchInstrInfo &II, MachineFunction &MF) { +- auto I = MF.begin()->begin(); +- EXPECT_EQ(36u, II.getInstSizeInBytes(*I)); +- ++I; +- EXPECT_EQ(24u, II.getInstSizeInBytes(*I)); +- ++I; +- EXPECT_EQ(48u, II.getInstSizeInBytes(*I)); +- ++I; +- EXPECT_EQ(56u, II.getInstSizeInBytes(*I)); +- ++I; +- EXPECT_EQ(36u, II.getInstSizeInBytes(*I)); +- ++I; +- EXPECT_EQ(44u, II.getInstSizeInBytes(*I)); +- }); +-} +diff --git a/llvm/unittests/Target/LoongArch/MCInstrAnalysisTest.cpp b/llvm/unittests/Target/LoongArch/MCInstrAnalysisTest.cpp +deleted file mode 100644 +index 468ee7961..000000000 +--- a/llvm/unittests/Target/LoongArch/MCInstrAnalysisTest.cpp ++++ /dev/null +@@ -1,121 +0,0 @@ +-//===- MCInstrAnalysisTest.cpp - LoongArchMCInstrAnalysis unit tests ------===// +-// +-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +-// See https://llvm.org/LICENSE.txt for license information. +-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +-// +-//===----------------------------------------------------------------------===// +- +-#include "llvm/MC/MCInstrAnalysis.h" +-#include "MCTargetDesc/LoongArchMCTargetDesc.h" +-#include "llvm/MC/MCInstBuilder.h" +-#include "llvm/MC/TargetRegistry.h" +-#include "llvm/Support/TargetSelect.h" +- +-#include "gtest/gtest.h" +- +-#include +- +-using namespace llvm; +- +-namespace { +- +-class InstrAnalysisTest : public testing::TestWithParam { +-protected: +- std::unique_ptr Info; +- std::unique_ptr Analysis; +- +- static void SetUpTestSuite() { +- LLVMInitializeLoongArchTargetInfo(); +- LLVMInitializeLoongArchTarget(); +- LLVMInitializeLoongArchTargetMC(); +- } +- +- InstrAnalysisTest() { +- std::string Error; +- const Target *TheTarget = +- TargetRegistry::lookupTarget(Triple::normalize(GetParam()), Error); +- Info = std::unique_ptr(TheTarget->createMCInstrInfo()); +- Analysis = std::unique_ptr( +- TheTarget->createMCInstrAnalysis(Info.get())); +- } +-}; +- +-} // namespace +- +-static MCInst beq() { +- return MCInstBuilder(LoongArch::BEQ) +- .addReg(LoongArch::R0) +- .addReg(LoongArch::R1) +- .addImm(32); +-} +- +-static MCInst b() { return MCInstBuilder(LoongArch::B).addImm(32); } +- +-static MCInst bl() { return MCInstBuilder(LoongArch::BL).addImm(32); } +- +-static MCInst jirl(unsigned RD, unsigned RJ = LoongArch::R10) { +- return MCInstBuilder(LoongArch::JIRL).addReg(RD).addReg(RJ).addImm(16); +-} +- +-TEST_P(InstrAnalysisTest, IsTerminator) { +- EXPECT_TRUE(Analysis->isTerminator(beq())); +- EXPECT_TRUE(Analysis->isTerminator(b())); +- EXPECT_FALSE(Analysis->isTerminator(bl())); +- EXPECT_TRUE(Analysis->isTerminator(jirl(LoongArch::R0))); +- EXPECT_FALSE(Analysis->isTerminator(jirl(LoongArch::R5))); +-} +- +-TEST_P(InstrAnalysisTest, IsCall) { +- EXPECT_FALSE(Analysis->isCall(beq())); +- EXPECT_FALSE(Analysis->isCall(b())); +- EXPECT_TRUE(Analysis->isCall(bl())); +- EXPECT_TRUE(Analysis->isCall(jirl(LoongArch::R1))); +- EXPECT_FALSE(Analysis->isCall(jirl(LoongArch::R0))); +-} +- +-TEST_P(InstrAnalysisTest, IsReturn) { +- EXPECT_FALSE(Analysis->isReturn(beq())); +- EXPECT_FALSE(Analysis->isReturn(b())); +- EXPECT_FALSE(Analysis->isReturn(bl())); +- EXPECT_TRUE(Analysis->isReturn(jirl(LoongArch::R0, LoongArch::R1))); +- EXPECT_FALSE(Analysis->isReturn(jirl(LoongArch::R0))); +- EXPECT_FALSE(Analysis->isReturn(jirl(LoongArch::R1))); +-} +- +-TEST_P(InstrAnalysisTest, IsBranch) { +- EXPECT_TRUE(Analysis->isBranch(beq())); +- EXPECT_TRUE(Analysis->isBranch(b())); +- EXPECT_FALSE(Analysis->isBranch(bl())); +- EXPECT_TRUE(Analysis->isBranch(jirl(LoongArch::R0))); +- EXPECT_FALSE(Analysis->isBranch(jirl(LoongArch::R1))); +- EXPECT_FALSE(Analysis->isBranch(jirl(LoongArch::R0, LoongArch::R1))); +-} +- +-TEST_P(InstrAnalysisTest, IsConditionalBranch) { +- EXPECT_TRUE(Analysis->isConditionalBranch(beq())); +- EXPECT_FALSE(Analysis->isConditionalBranch(b())); +- EXPECT_FALSE(Analysis->isConditionalBranch(bl())); +-} +- +-TEST_P(InstrAnalysisTest, IsUnconditionalBranch) { +- EXPECT_FALSE(Analysis->isUnconditionalBranch(beq())); +- EXPECT_TRUE(Analysis->isUnconditionalBranch(b())); +- EXPECT_FALSE(Analysis->isUnconditionalBranch(bl())); +- EXPECT_TRUE(Analysis->isUnconditionalBranch(jirl(LoongArch::R0))); +- EXPECT_FALSE(Analysis->isUnconditionalBranch(jirl(LoongArch::R1))); +- EXPECT_FALSE( +- Analysis->isUnconditionalBranch(jirl(LoongArch::R0, LoongArch::R1))); +-} +- +-TEST_P(InstrAnalysisTest, IsIndirectBranch) { +- EXPECT_FALSE(Analysis->isIndirectBranch(beq())); +- EXPECT_FALSE(Analysis->isIndirectBranch(b())); +- EXPECT_FALSE(Analysis->isIndirectBranch(bl())); +- EXPECT_TRUE(Analysis->isIndirectBranch(jirl(LoongArch::R0))); +- EXPECT_FALSE(Analysis->isIndirectBranch(jirl(LoongArch::R1))); +- EXPECT_FALSE(Analysis->isIndirectBranch(jirl(LoongArch::R0, LoongArch::R1))); +-} +- +-INSTANTIATE_TEST_SUITE_P(LA32And64, InstrAnalysisTest, +- testing::Values("loongarch32", "loongarch64")); +diff --git a/llvm/unittests/TargetParser/TripleTest.cpp b/llvm/unittests/TargetParser/TripleTest.cpp +index 4db54a08c..4b9db25ec 100644 +--- a/llvm/unittests/TargetParser/TripleTest.cpp ++++ b/llvm/unittests/TargetParser/TripleTest.cpp +@@ -540,78 +540,6 @@ TEST(TripleTest, ParsedIDs) { + EXPECT_EQ(Triple::Linux, T.getOS()); + EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment()); + +- T = Triple("loongarch32-unknown-unknown"); +- EXPECT_EQ(Triple::loongarch32, T.getArch()); +- EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); +- EXPECT_EQ(Triple::UnknownOS, T.getOS()); +- EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment()); +- +- T = Triple("loongarch32-unknown-linux-gnu"); +- EXPECT_EQ(Triple::loongarch32, T.getArch()); +- EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); +- EXPECT_EQ(Triple::Linux, T.getOS()); +- EXPECT_EQ(Triple::GNU, T.getEnvironment()); +- +- T = Triple("loongarch32-unknown-linux-gnuf32"); +- EXPECT_EQ(Triple::loongarch32, T.getArch()); +- EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); +- EXPECT_EQ(Triple::Linux, T.getOS()); +- EXPECT_EQ(Triple::GNUF32, T.getEnvironment()); +- +- T = Triple("loongarch32-unknown-linux-gnuf64"); +- EXPECT_EQ(Triple::loongarch32, T.getArch()); +- EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); +- EXPECT_EQ(Triple::Linux, T.getOS()); +- EXPECT_EQ(Triple::GNUF64, T.getEnvironment()); +- +- T = Triple("loongarch32-unknown-linux-gnusf"); +- EXPECT_EQ(Triple::loongarch32, T.getArch()); +- EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); +- EXPECT_EQ(Triple::Linux, T.getOS()); +- EXPECT_EQ(Triple::GNUSF, T.getEnvironment()); +- +- T = Triple("loongarch32-unknown-linux-musl"); +- EXPECT_EQ(Triple::loongarch32, T.getArch()); +- EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); +- EXPECT_EQ(Triple::Linux, T.getOS()); +- EXPECT_EQ(Triple::Musl, T.getEnvironment()); +- +- T = Triple("loongarch64-unknown-linux"); +- EXPECT_EQ(Triple::loongarch64, T.getArch()); +- EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); +- EXPECT_EQ(Triple::Linux, T.getOS()); +- EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment()); +- +- T = Triple("loongarch64-unknown-linux-gnu"); +- EXPECT_EQ(Triple::loongarch64, T.getArch()); +- EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); +- EXPECT_EQ(Triple::Linux, T.getOS()); +- EXPECT_EQ(Triple::GNU, T.getEnvironment()); +- +- T = Triple("loongarch64-unknown-linux-gnuf32"); +- EXPECT_EQ(Triple::loongarch64, T.getArch()); +- EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); +- EXPECT_EQ(Triple::Linux, T.getOS()); +- EXPECT_EQ(Triple::GNUF32, T.getEnvironment()); +- +- T = Triple("loongarch64-unknown-linux-gnuf64"); +- EXPECT_EQ(Triple::loongarch64, T.getArch()); +- EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); +- EXPECT_EQ(Triple::Linux, T.getOS()); +- EXPECT_EQ(Triple::GNUF64, T.getEnvironment()); +- +- T = Triple("loongarch64-unknown-linux-gnusf"); +- EXPECT_EQ(Triple::loongarch64, T.getArch()); +- EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); +- EXPECT_EQ(Triple::Linux, T.getOS()); +- EXPECT_EQ(Triple::GNUSF, T.getEnvironment()); +- +- T = Triple("loongarch64-unknown-linux-musl"); +- EXPECT_EQ(Triple::loongarch64, T.getArch()); +- EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); +- EXPECT_EQ(Triple::Linux, T.getOS()); +- EXPECT_EQ(Triple::Musl, T.getEnvironment()); +- + T = Triple("riscv32-unknown-unknown"); + EXPECT_EQ(Triple::riscv32, T.getArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); +@@ -1357,20 +1285,6 @@ TEST(TripleTest, BitWidthPredicates) { + EXPECT_FALSE(T.isArch64Bit()); + EXPECT_TRUE(T.isCSKY()); + +- T.setArch(Triple::loongarch32); +- EXPECT_FALSE(T.isArch16Bit()); +- EXPECT_TRUE(T.isArch32Bit()); +- EXPECT_FALSE(T.isArch64Bit()); +- EXPECT_TRUE(T.isLoongArch()); +- EXPECT_TRUE(T.isLoongArch32()); +- +- T.setArch(Triple::loongarch64); +- EXPECT_FALSE(T.isArch16Bit()); +- EXPECT_FALSE(T.isArch32Bit()); +- EXPECT_TRUE(T.isArch64Bit()); +- EXPECT_TRUE(T.isLoongArch()); +- EXPECT_TRUE(T.isLoongArch64()); +- + T.setArch(Triple::dxil); + EXPECT_FALSE(T.isArch16Bit()); + EXPECT_TRUE(T.isArch32Bit()); +@@ -1528,14 +1442,6 @@ TEST(TripleTest, BitWidthArchVariants) { + EXPECT_EQ(Triple::csky, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::UnknownArch, T.get64BitArchVariant().getArch()); + +- T.setArch(Triple::loongarch32); +- EXPECT_EQ(Triple::loongarch32, T.get32BitArchVariant().getArch()); +- EXPECT_EQ(Triple::loongarch64, T.get64BitArchVariant().getArch()); +- +- T.setArch(Triple::loongarch64); +- EXPECT_EQ(Triple::loongarch32, T.get32BitArchVariant().getArch()); +- EXPECT_EQ(Triple::loongarch64, T.get64BitArchVariant().getArch()); +- + T.setArch(Triple::thumbeb); + EXPECT_EQ(Triple::thumbeb, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::aarch64_be, T.get64BitArchVariant().getArch()); +@@ -1722,16 +1628,6 @@ TEST(TripleTest, EndianArchVariants) { + EXPECT_EQ(Triple::UnknownArch, T.getBigEndianArchVariant().getArch()); + EXPECT_EQ(Triple::csky, T.getLittleEndianArchVariant().getArch()); + +- T.setArch(Triple::loongarch32); +- EXPECT_TRUE(T.isLittleEndian()); +- EXPECT_EQ(Triple::UnknownArch, T.getBigEndianArchVariant().getArch()); +- EXPECT_EQ(Triple::loongarch32, T.getLittleEndianArchVariant().getArch()); +- +- T.setArch(Triple::loongarch64); +- EXPECT_TRUE(T.isLittleEndian()); +- EXPECT_EQ(Triple::UnknownArch, T.getBigEndianArchVariant().getArch()); +- EXPECT_EQ(Triple::loongarch64, T.getLittleEndianArchVariant().getArch()); +- + T.setArch(Triple::dxil); + EXPECT_TRUE(T.isLittleEndian()); + EXPECT_EQ(Triple::UnknownArch, T.getBigEndianArchVariant().getArch()); +@@ -2026,10 +1922,6 @@ TEST(TripleTest, FileFormat) { + EXPECT_EQ(Triple::SPIRV, Triple("spirv32-unknown-unknown").getObjectFormat()); + EXPECT_EQ(Triple::SPIRV, Triple("spirv64-unknown-unknown").getObjectFormat()); + +- EXPECT_EQ(Triple::ELF, +- Triple("loongarch32-unknown-unknown").getObjectFormat()); +- EXPECT_EQ(Triple::ELF, Triple("loongarch64-unknown-linux").getObjectFormat()); +- + Triple MSVCNormalized(Triple::normalize("i686-pc-windows-msvc-elf")); + EXPECT_EQ(Triple::ELF, MSVCNormalized.getObjectFormat()); + +diff --git a/llvm/utils/gn/secondary/compiler-rt/lib/builtins/BUILD.gn b/llvm/utils/gn/secondary/compiler-rt/lib/builtins/BUILD.gn +index 63285ef7f..2fc5705e9 100644 +--- a/llvm/utils/gn/secondary/compiler-rt/lib/builtins/BUILD.gn ++++ b/llvm/utils/gn/secondary/compiler-rt/lib/builtins/BUILD.gn +@@ -545,10 +545,6 @@ static_library("builtins") { + "hexagon/umodsi3.S", + ] + } +- if (current_cpu == "loongarch" || current_cpu == "loongarch64") { +- sources -= [ "fp_mode.c" ] +- sources += [ "loongarch/fp_mode.c" ] +- } + + if (current_cpu == "ppc64") { + sources += [ +diff --git a/llvm/utils/gn/secondary/compiler-rt/lib/tsan/rtl/BUILD.gn b/llvm/utils/gn/secondary/compiler-rt/lib/tsan/rtl/BUILD.gn +index ce5f86315..57d653a2b 100644 +--- a/llvm/utils/gn/secondary/compiler-rt/lib/tsan/rtl/BUILD.gn ++++ b/llvm/utils/gn/secondary/compiler-rt/lib/tsan/rtl/BUILD.gn +@@ -121,8 +121,6 @@ target(tsan_target_type, "rtl") { + sources += [ "tsan_rtl_amd64.S" ] + } else if (target_cpu == "arm64") { + sources += [ "tsan_rtl_aarch64.S" ] +- } else if (target_cpu == "loongarch64") { +- sources += [ "tsan_rtl_loongarch64.S" ] + } else if (target_cpu == "mips64") { + sources += [ "tsan_rtl_mips64.S" ] + } else if (target_cpu == "powerpc64") { +diff --git a/llvm/utils/gn/secondary/lld/ELF/BUILD.gn b/llvm/utils/gn/secondary/lld/ELF/BUILD.gn +index bd4a4f5d9..94d54c63d 100644 +--- a/llvm/utils/gn/secondary/lld/ELF/BUILD.gn ++++ b/llvm/utils/gn/secondary/lld/ELF/BUILD.gn +@@ -31,7 +31,6 @@ static_library("ELF") { + "Arch/ARM.cpp", + "Arch/AVR.cpp", + "Arch/Hexagon.cpp", +- "Arch/LoongArch.cpp", + "Arch/MSP430.cpp", + "Arch/Mips.cpp", + "Arch/MipsArchTree.cpp", +diff --git a/llvm/utils/gn/secondary/lldb/source/Plugins/Process/Linux/BUILD.gn b/llvm/utils/gn/secondary/lldb/source/Plugins/Process/Linux/BUILD.gn +index 978f1867c..de4a30a73 100644 +--- a/llvm/utils/gn/secondary/lldb/source/Plugins/Process/Linux/BUILD.gn ++++ b/llvm/utils/gn/secondary/lldb/source/Plugins/Process/Linux/BUILD.gn +@@ -25,7 +25,6 @@ static_library("Linux") { + "NativeRegisterContextLinux.cpp", + "NativeRegisterContextLinux_arm.cpp", + "NativeRegisterContextLinux_arm64.cpp", +- "NativeRegisterContextLinux_loongarch64.cpp", + "NativeRegisterContextLinux_ppc64le.cpp", + "NativeRegisterContextLinux_riscv64.cpp", + "NativeRegisterContextLinux_s390x.cpp", +diff --git a/llvm/utils/gn/secondary/lldb/source/Plugins/Process/Utility/BUILD.gn b/llvm/utils/gn/secondary/lldb/source/Plugins/Process/Utility/BUILD.gn +index 4d98de81f..16f1146d2 100644 +--- a/llvm/utils/gn/secondary/lldb/source/Plugins/Process/Utility/BUILD.gn ++++ b/llvm/utils/gn/secondary/lldb/source/Plugins/Process/Utility/BUILD.gn +@@ -55,7 +55,6 @@ static_library("Utility") { + "RegisterContextOpenBSD_x86_64.cpp", + "RegisterContextPOSIX_arm.cpp", + "RegisterContextPOSIX_arm64.cpp", +- "RegisterContextPOSIX_loongarch64.cpp", + "RegisterContextPOSIX_mips64.cpp", + "RegisterContextPOSIX_powerpc.cpp", + "RegisterContextPOSIX_ppc64le.cpp", +@@ -69,7 +68,6 @@ static_library("Utility") { + "RegisterFlagsLinux_arm64.cpp", + "RegisterInfoPOSIX_arm.cpp", + "RegisterInfoPOSIX_arm64.cpp", +- "RegisterInfoPOSIX_loongarch64.cpp", + "RegisterInfoPOSIX_ppc64le.cpp", + "RegisterInfoPOSIX_riscv64.cpp", + "RegisterInfos_x86_64_with_base_shared.cpp", +diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/BUILD.gn +index 6e0efc548..e89db5200 100644 +--- a/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/BUILD.gn ++++ b/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/BUILD.gn +@@ -1,30 +1,56 @@ + import("//llvm/utils/TableGen/tablegen.gni") + ++tablegen("LoongArchGenCallingConv") { ++ visibility = [ ":LLVMLoongArchCodeGen" ] ++ args = [ "-gen-callingconv" ] ++ td_file = "LoongArch.td" ++} ++ + tablegen("LoongArchGenDAGISel") { + visibility = [ ":LLVMLoongArchCodeGen" ] + args = [ "-gen-dag-isel" ] + td_file = "LoongArch.td" + } + ++tablegen("LoongArchGenFastISel") { ++ visibility = [ ":LLVMLoongArchCodeGen" ] ++ args = [ "-gen-fast-isel" ] ++ td_file = "LoongArch.td" ++} ++ ++tablegen("LoongArchGenGlobalISel") { ++ visibility = [ ":LLVMLoongArchCodeGen" ] ++ args = [ "-gen-global-isel" ] ++ td_file = "LoongArch.td" ++} ++ + tablegen("LoongArchGenMCPseudoLowering") { + visibility = [ ":LLVMLoongArchCodeGen" ] + args = [ "-gen-pseudo-lowering" ] + td_file = "LoongArch.td" + } + ++tablegen("LoongArchGenRegisterBank") { ++ visibility = [ ":LLVMLoongArchCodeGen" ] ++ args = [ "-gen-register-bank" ] ++ td_file = "LoongArch.td" ++} ++ + static_library("LLVMLoongArchCodeGen") { + deps = [ ++ ":LoongArchGenCallingConv", + ":LoongArchGenDAGISel", ++ ":LoongArchGenFastISel", ++ ":LoongArchGenGlobalISel", + ":LoongArchGenMCPseudoLowering", +- +- # See https://reviews.llvm.org/D137532 +- "AsmParser:LoongArchGenAsmMatcher", ++ ":LoongArchGenRegisterBank", + "MCTargetDesc", + "TargetInfo", + "//llvm/include/llvm/Config:llvm-config", + "//llvm/lib/Analysis", + "//llvm/lib/CodeGen", + "//llvm/lib/CodeGen/AsmPrinter", ++ "//llvm/lib/CodeGen/GlobalISel", + "//llvm/lib/CodeGen/SelectionDAG", + "//llvm/lib/IR", + "//llvm/lib/MC", +@@ -33,18 +59,29 @@ static_library("LLVMLoongArchCodeGen") { + ] + include_dirs = [ "." ] + sources = [ ++ "LoongArchAnalyzeImmediate.cpp", + "LoongArchAsmPrinter.cpp", +- "LoongArchExpandAtomicPseudoInsts.cpp", +- "LoongArchExpandPseudoInsts.cpp", ++ "LoongArchCCState.cpp", ++ "LoongArchCallLowering.cpp", ++ "LoongArchConstantIslandPass.cpp", ++ "LoongArchDelaySlotFiller.cpp", ++ "LoongArchExpandPseudo.cpp", + "LoongArchFrameLowering.cpp", + "LoongArchISelDAGToDAG.cpp", + "LoongArchISelLowering.cpp", + "LoongArchInstrInfo.cpp", ++ "LoongArchInstructionSelector.cpp", ++ "LoongArchLegalizerInfo.cpp", + "LoongArchMCInstLower.cpp", ++ "LoongArchMachineFunction.cpp", ++ "LoongArchModuleISelDAGToDAG.cpp", ++ "LoongArchOptimizePICCall.cpp", ++ "LoongArchPreLegalizerCombiner.cpp", ++ "LoongArchRegisterBankInfo.cpp", + "LoongArchRegisterInfo.cpp", + "LoongArchSubtarget.cpp", + "LoongArchTargetMachine.cpp", +- "LoongArchTargetTransformInfo.cpp", ++ "LoongArchTargetObjectFile.cpp", + ] + } + +diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/MCTargetDesc/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/MCTargetDesc/BUILD.gn +index 29aeba47e..f0b96c965 100644 +--- a/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/MCTargetDesc/BUILD.gn ++++ b/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/MCTargetDesc/BUILD.gn +@@ -7,7 +7,7 @@ tablegen("LoongArchGenAsmWriter") { + } + + tablegen("LoongArchGenInstrInfo") { +- visibility = [ ":MCTargetDesc" ] ++ visibility = [ ":tablegen" ] + args = [ "-gen-instr-info" ] + td_file = "../LoongArch.td" + } +@@ -19,40 +19,47 @@ tablegen("LoongArchGenMCCodeEmitter") { + } + + tablegen("LoongArchGenRegisterInfo") { +- visibility = [ ":MCTargetDesc" ] ++ visibility = [ ":tablegen" ] + args = [ "-gen-register-info" ] + td_file = "../LoongArch.td" + } + + tablegen("LoongArchGenSubtargetInfo") { +- visibility = [ ":MCTargetDesc" ] ++ visibility = [ ":tablegen" ] + args = [ "-gen-subtarget" ] + td_file = "../LoongArch.td" + } + +-static_library("MCTargetDesc") { +- output_name = "LLVMLoongArchDesc" +- +- # This should contain tablegen targets generating .inc files included +- # by other targets. .inc files only used by .cpp files in this directory +- # should be in deps instead. ++# This should contain tablegen targets generating .inc files included ++# by other targets. .inc files only used by .cpp files in this directory ++# should be in deps on the static_library instead. ++group("tablegen") { ++ visibility = [ ++ ":MCTargetDesc", ++ "../TargetInfo", ++ ] + public_deps = [ + ":LoongArchGenInstrInfo", + ":LoongArchGenRegisterInfo", + ":LoongArchGenSubtargetInfo", + ] ++} ++ ++static_library("MCTargetDesc") { ++ output_name = "LLVMLoongArchDesc" ++ public_deps = [ ":tablegen" ] + deps = [ + ":LoongArchGenAsmWriter", + ":LoongArchGenMCCodeEmitter", + "//llvm/lib/MC", + "//llvm/lib/Support", + "//llvm/lib/Target/LoongArch/TargetInfo", +- "//llvm/lib/TargetParser", + ] + include_dirs = [ ".." ] + sources = [ ++ "LoongArchABIFlagsSection.cpp", ++ "LoongArchABIInfo.cpp", + "LoongArchAsmBackend.cpp", +- "LoongArchBaseInfo.cpp", + "LoongArchELFObjectWriter.cpp", + "LoongArchELFStreamer.cpp", + "LoongArchInstPrinter.cpp", +@@ -60,7 +67,8 @@ static_library("MCTargetDesc") { + "LoongArchMCCodeEmitter.cpp", + "LoongArchMCExpr.cpp", + "LoongArchMCTargetDesc.cpp", +- "LoongArchMatInt.cpp", ++ "LoongArchNaClELFStreamer.cpp", ++ "LoongArchOptionRecord.cpp", + "LoongArchTargetStreamer.cpp", + ] + } +diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/TargetInfo/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/TargetInfo/BUILD.gn +index 9512d414d..a476bdd5f 100644 +--- a/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/TargetInfo/BUILD.gn ++++ b/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/TargetInfo/BUILD.gn +@@ -2,5 +2,8 @@ static_library("TargetInfo") { + output_name = "LLVMLoongArchInfo" + deps = [ "//llvm/lib/Support" ] + include_dirs = [ ".." ] +- sources = [ "LoongArchTargetInfo.cpp" ] ++ sources = [ ++ # Make `gn format` not collapse this, for sync_source_lists_from_cmake.py. ++ "LoongArchTargetInfo.cpp", ++ ] + } +diff --git a/llvm/utils/gn/secondary/llvm/unittests/Target/LoongArch/BUILD.gn b/llvm/utils/gn/secondary/llvm/unittests/Target/LoongArch/BUILD.gn +deleted file mode 100644 +index 8435d33c0..000000000 +--- a/llvm/utils/gn/secondary/llvm/unittests/Target/LoongArch/BUILD.gn ++++ /dev/null +@@ -1,17 +0,0 @@ +-import("//third-party/unittest/unittest.gni") +- +-unittest("LoongArchTests") { +- deps = [ +- "//llvm/lib/CodeGen/MIRParser", +- "//llvm/lib/Support", +- "//llvm/lib/Target", +- "//llvm/lib/Target/LoongArch:LLVMLoongArchCodeGen", +- "//llvm/lib/Target/LoongArch/MCTargetDesc", +- "//llvm/lib/Target/LoongArch/TargetInfo", +- ] +- include_dirs = [ "//llvm/lib/Target/LoongArch" ] +- sources = [ +- "InstSizes.cpp", +- "MCInstrAnalysisTest.cpp", +- ] +-} diff --git a/llvm.spec b/llvm.spec index 3b4cadb70a29550bde11ee3d82cd6e11a759632e..398e87b0ed79335ac9cb561ec31e1453ea4eff0d 100644 --- a/llvm.spec +++ b/llvm.spec @@ -1,3 +1,4 @@ +%define anolis_release .0.1 %bcond_with snapshot_build %if %{with snapshot_build} @@ -68,7 +69,7 @@ %endif %if 0%{?rhel} -%global targets_to_build "X86;AMDGPU;PowerPC;NVPTX;SystemZ;AArch64;ARM;Mips;BPF;WebAssembly" +%global targets_to_build "X86;AMDGPU;PowerPC;NVPTX;SystemZ;AArch64;ARM;Mips;BPF;WebAssembly;LoongArch" %global experimental_targets_to_build "" %else %global targets_to_build "all" @@ -118,7 +119,7 @@ Name: %{pkg_name} Version: %{maj_ver}.%{min_ver}.%{patch_ver}%{?rc_ver:~rc%{rc_ver}}%{?llvm_snapshot_version_suffix:~%{llvm_snapshot_version_suffix}} -Release: 3%{?dist} +Release: 3%{anolis_release}%{?dist} Summary: The Low Level Virtual Machine License: Apache-2.0 WITH LLVM-exception OR NCSA @@ -142,6 +143,7 @@ Source6: release-keys.asc # https://github.com/llvm/llvm-project/pull/99273 # Fixes RHEL-54336 Patch001: 99273.patch +Patch002: 0002-Support-LoongArch.patch # RHEL-specific patch to avoid unwanted python3-myst-parser dep Patch101: 0101-Deactivate-markdown-doc.patch @@ -642,6 +644,9 @@ fi %endif %changelog +* Tue Nov 26 2024 Chen Li - 18.1.8-3.0.1 +- Add support for LoongArch + * Fri Oct 18 2024 Tom Stellard - 18.1.8-3 - Remove stray fi from postun scriptlet